Improved logo upload. Also show logo at login page.

This commit is contained in:
Martin Edenhofer 2014-11-19 23:22:13 +01:00
parent 4f74a73017
commit 8636466f87
12 changed files with 204 additions and 64 deletions

View file

@ -216,9 +216,13 @@ class Base extends App.ControllerContent
else
url = "#{http_type}://#{fqdn}"
logoFile = App.Config.get('product_logo')
logoUrl = App.Config.get('image_path') + "/#{logoFile}"
organization = App.Config.get('organization')
@html App.view('getting_started/base')(
url: url
logoUrl: logoUrl
organization: organization
)
@$("input, select").first().focus()
@ -237,7 +241,7 @@ class Base extends App.ControllerContent
if !file
return
maxSiteInMb = 3
maxSiteInMb = 8
if file.size && file.size > 1024 * 1024 * maxSiteInMb
@showAlert( 'logo', App.i18n.translateInline( 'File too big, max. %s MB allowed.', maxSiteInMb ) )
@logoPreview.attr( 'src', '' )
@ -250,8 +254,15 @@ class Base extends App.ControllerContent
# get params
params = @formParam(e.target)
# add logo
params['logo'] = @logoPreview.attr('src')
# add resized image
if params['logo']
resizeLogo = new App.ImageService( params['logo'] )
params['logo_resize'] = resizeLogo.toDataURLForApp( @logoPreview.width(), @logoPreview.height() )
@hideAlerts()
@disable(e)

View file

@ -50,11 +50,15 @@ class Index extends App.ControllerContent
}
auth_providers = []
for key, provider of auth_provider_all
if @Config.get( provider.config ) is true || @Config.get( provider.config ) is "true"
if @Config.get( provider.config ) is true || @Config.get( provider.config ) is 'true'
auth_providers.push provider
logoFile = App.Config.get('product_logo')
logoUrl = App.Config.get('image_path') + "/#{logoFile}"
@html App.view('login')(
item: data
logoUrl: logoUrl
auth_providers: auth_providers
)

View file

@ -0,0 +1,46 @@
class App.ImageService
constructor: (url) ->
@orgDataURL = url
src: (url) =>
@orgDataURL = url
resize: ( x = 'auto', y = 'auto') =>
@canvas = document.createElement('canvas')
context = @canvas.getContext('2d')
# load image from data url
imageObject = new Image()
imageObject.src = @orgDataURL
imageWidth = imageObject.width
imageHeight = imageObject.height
if y is 'auto' && x is 'auto'
x = imageWidth
y = imageHeight
# get auto dimensions
if y is 'auto'
factor = imageWidth / x
y = imageHeight / factor
if x is 'auto'
factor = imageWidth / y
x = imageHeight / factor
console.log('BB', x, y)
# set canvas dimensions
@canvas.width = x
@canvas.height = y
# draw image on canvas and set image dimensions
context.drawImage( imageObject, 0, 0, x, y )
@canvas
toDataURL: (type, quallity = 1) =>
#@resize()
@canvas.toDataURL( type, quallity )
toDataURLForApp: ( x, y ) =>
@resize( x * 2, y * 2 )
@toDataURL( 'image/jpeg', 0.7 )

View file

@ -13,7 +13,7 @@
<div class="form-group">
<label><%- @T('Logo') %></label>
<div class="alert alert--danger hide" role="alert"></div>
<img class="logo-preview" src="">
<img class="logo-preview" src="<%= @logoUrl %>">
<div class="logo-preview-placeholder"><%- @T('Your Logo') %></div>
<div class="btn btn--success fileUpload"><%- @T('Upload') %><input type="file" class="js-upload" name="logo" accept="image/*"></div>
</div>

View file

@ -3,7 +3,7 @@
<p><%- @T( 'Login with %s', @C( 'fqdn' ) ) %></p>
<div class="hero-unit">
<img class="company-logo" src="<%= @C('api_path') + '/sessions/logo' %>" alt="<%= @C( 'product_name' ) %>">
<img class="company-logo" src="<%= @logoUrl %>" alt="<%= @C( 'product_name' ) %>">
<form id="login">
<div class="form-group">
<label for="username"><%- @Ti( 'Username / email' ) %></label>

View file

@ -106,27 +106,28 @@ curl http://localhost/api/v1/getting_started -v -u #{login}:#{password}
# save image
if params[:logo] && !params[:logo].empty?
content_type = nil
content = nil
# data:image/png;base64
if params[:logo] =~ /^data:(.+?);base64,(.+?)$/
content_type = $1
content = Base64.decode64($2)
end
Store.remove( :object => 'System::Logo', :o_id => 1 )
Store.add(
:object => 'System::Logo',
:o_id => 1,
:data => content,
:filename => 'image',
:preferences => {
'Content-Type' => content_type
},
# :created_by_id => self.updated_by_id,
)
file = StaticAssets.data_url_attributes( params[:logo] )
# store image 1:1
StaticAssets.store_raw( file[:content], file[:content_type] )
end
if params[:logo_resize] && !params[:logo_resize].empty?
# data:image/png;base64
file = StaticAssets.data_url_attributes( params[:logo_resize] )
# store image 1:1
settings[:product_logo] = StaticAssets.store( file[:content], file[:content_type] )
end
# set changed settings
settings.each {|key, value|
Setting.set(key, value)
}
render :json => {
:result => 'ok',
:settings => settings,

View file

@ -279,45 +279,4 @@ class SessionsController < ApplicationController
render :json => {}
end
=begin
Resource:
GET /api/v1/sessions/logo
Response:
<IMAGE>
Test:
curl http://localhost/api/v1/sessions/logo
=end
def logo
# cache image
#response.headers['Expires'] = 1.year.from_now.httpdate
#response.headers["Cache-Control"] = "cache, store, max-age=31536000, must-revalidate"
#response.headers["Pragma"] = "cache"
# find logo
list = Store.list( :object => 'System::Logo', :o_id => 2 )
if list && list[0]
file = Store.find( list[0] )
send_data(
file.content,
:filename => file.filename,
:type => file.preferences['Content-Type'],
:disposition => 'inline'
)
return
end
# serve default image
send_data(
'',
:filename => '',
:type => 'image/gif',
:disposition => 'inline'
)
end
end

View file

@ -0,0 +1,2 @@
# sync logo to fs
StaticAssets.sync

View file

@ -15,7 +15,6 @@ Zammad::Application.routes.draw do
match api_path + '/sessions/switch/:id', :to => 'sessions#switch_to_user', :via => :get
match api_path + '/sessions/switch_back', :to => 'sessions#switch_back_to_user', :via => :get
match api_path + '/sessions', :to => 'sessions#list', :via => :get
match api_path + '/sessions/logo', :to => 'sessions#logo', :via => :get
match api_path + '/sessions/:id', :to => 'sessions#delete', :via => :delete
end

View file

@ -0,0 +1,25 @@
class UpdateSetting2 < ActiveRecord::Migration
def up
Setting.create_if_not_exists(
:title => 'Logo',
:name => 'product_logo',
:area => 'System::CI',
:description => 'Defines the logo of the application, shown in the web interface.',
:options => {
:form => [
{
:display => '',
:null => false,
:name => 'product_logo',
:tag => 'input',
},
],
},
:state => 'logo.svg',
:frontend => true
)
end
def down
end
end

View file

@ -33,6 +33,24 @@ Setting.create_if_not_exists(
:state => 'Zammad',
:frontend => true
)
Setting.create_if_not_exists(
:title => 'Logo',
:name => 'product_logo',
:area => 'System::CI',
:description => 'Defines the logo of the application, shown in the web interface.',
:options => {
:form => [
{
:display => '',
:null => false,
:name => 'product_logo',
:tag => 'input',
},
],
},
:state => 'logo.svg',
:frontend => true
)
Setting.create_if_not_exists(
:title => 'Organization',

75
lib/static_assets.rb Normal file
View file

@ -0,0 +1,75 @@
module StaticAssets
def self.data_url_attributes( data_url )
data = {}
if data_url =~ /^data:(.+?);base64,(.+?)$/
data[:content_type] = $1
data[:content] = Base64.decode64($2)
return data
end
raise "Unable to parse data url: #{data_url.substr(0,100)}"
end
# store image 1:1
def self.store_raw( content, content_type )
Store.remove( :object => 'System::Logo', :o_id => 1 )
Store.add(
:object => 'System::Logo',
:o_id => 1,
:data => content,
:filename => 'image',
:preferences => {
'Content-Type' => content_type
},
)
Digest::MD5.hexdigest( content )
end
# read raw 1:1
def self.read_raw
list = Store.list( :object => 'System::Logo', :o_id => 1 )
if list && list[0]
return Store.find( list[0] )
end
raise "No such raw logo!"
end
# store image in right size
def self.store( content, content_type )
Store.remove( :object => 'System::Logo', :o_id => 2 )
Store.add(
:object => 'System::Logo',
:o_id => 2,
:data => content,
:filename => 'image',
:preferences => {
'Content-Type' => content_type
},
)
StaticAssets.sync
Digest::MD5.hexdigest( content )
end
# read image
def self.read
list = Store.list( :object => 'System::Logo', :o_id => 2 )
if list && list[0]
file = Store.find( list[0] )
hash = Digest::MD5.hexdigest( file.content )
Setting.set('product_logo', hash)
return file
end
end
# sync image to fs
def self.sync
file = read
return if !file
hash = Digest::MD5.hexdigest( file.content )
path = "#{Rails.root.to_s}/public/assets/#{hash}"
File.open( path, 'wb' ) do |f|
f.puts file.content
end
end
end