Improved logo upload. Also show logo at login page.
This commit is contained in:
parent
4f74a73017
commit
8636466f87
12 changed files with 204 additions and 64 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
)
|
||||
|
||||
|
|
|
@ -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 )
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
end
|
2
config/initializers/logo.rb
Normal file
2
config/initializers/logo.rb
Normal file
|
@ -0,0 +1,2 @@
|
|||
# sync logo to fs
|
||||
StaticAssets.sync
|
|
@ -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
|
25
db/migrate/20141119000001_update_setting2.rb
Normal file
25
db/migrate/20141119000001_update_setting2.rb
Normal 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
|
18
db/seeds.rb
18
db/seeds.rb
|
@ -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
75
lib/static_assets.rb
Normal 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
|
Loading…
Reference in a new issue