the screen for editing site has been refactored
This commit is contained in:
parent
35012ca2b2
commit
5d271239b7
@ -0,0 +1,13 @@
|
||||
class Locomotive.Models.Membership extends Backbone.Model
|
||||
|
||||
toJSONForSave: ->
|
||||
_.tap {}, (hash) =>
|
||||
for key, value of @.toJSON()
|
||||
hash[key] = value if _.include(['id', 'role', '_destroy'], key)
|
||||
|
||||
class Locomotive.Models.MembershipsCollection extends Backbone.Collection
|
||||
|
||||
model: Locomotive.Models.Membership
|
||||
|
||||
toJSONForSave: ->
|
||||
@map (model) => model.toJSONForSave()
|
@ -1,6 +1,6 @@
|
||||
class Locomotive.Models.Site extends Backbone.Model
|
||||
|
||||
paramRoot: 'page'
|
||||
paramRoot: 'site'
|
||||
|
||||
urlRoot: "#{Locomotive.mount_on}/sites"
|
||||
|
||||
@ -9,10 +9,23 @@ class Locomotive.Models.Site extends Backbone.Model
|
||||
domains = _.map @get('domains_without_subdomain'), (name) =>
|
||||
new Locomotive.Models.Domain(name: name)
|
||||
|
||||
@set domains: domains
|
||||
memberships = new Locomotive.Models.MembershipsCollection(@get('memberships'))
|
||||
|
||||
@set domains: domains, memberships: memberships
|
||||
|
||||
includes_domain: (name) ->
|
||||
name == @domain_with_domain() || _.any(@get('domains'), (domain) -> domain.get('name') == name)
|
||||
|
||||
domain_with_domain: ->
|
||||
"#{@get('subdomain')}.#{@get('domain_name')}"
|
||||
|
||||
toJSON: ->
|
||||
_.tap super, (hash) =>
|
||||
hash.memberships = @get('memberships').toJSONForSave() if @get('memberships')
|
||||
hash.domains = _.map(@get('domains'), (domain) -> domain.get('name'))
|
||||
|
||||
class Locomotive.Models.CurrentSite extends Locomotive.Models.Site
|
||||
|
||||
urlRoot: "#{Locomotive.mount_on}/current_site"
|
||||
url: "#{Locomotive.mount_on}/current_site"
|
||||
|
||||
|
||||
|
@ -8,7 +8,7 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form
|
||||
el: '#content'
|
||||
|
||||
events:
|
||||
'click .memberships a.remove': 'remove_membership'
|
||||
'submit': 'save'
|
||||
|
||||
initialize: ->
|
||||
@model = new Locomotive.Models.CurrentSite(@options.site)
|
||||
@ -20,17 +20,22 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form
|
||||
render: ->
|
||||
super()
|
||||
|
||||
@render_domain_entries()
|
||||
@render_domains()
|
||||
|
||||
@render_memberships()
|
||||
|
||||
@enable_liquid_editing()
|
||||
|
||||
@enable_ui_effects()
|
||||
|
||||
render_domain_entries: ->
|
||||
render_domains: ->
|
||||
@domains_view = new Locomotive.Views.Site.DomainsView model: @model, errors: @options.errors
|
||||
|
||||
@$('#site_domains_input label').after(@domains_view.render().el)
|
||||
|
||||
render_memberships: ->
|
||||
@memberships_view = new Locomotive.Views.Site.MembershipsView model: @model
|
||||
|
||||
@$('#site_memberships_input').append(@memberships_view.render().el)
|
||||
|
||||
enable_liquid_editing: ->
|
||||
input = @$('#site_robots_txt')
|
||||
@editor = CodeMirror.fromTextArea input.get()[0],
|
||||
@ -42,12 +47,18 @@ class Locomotive.Views.CurrentSite.EditView extends Locomotive.Views.Shared.Form
|
||||
theme: 'default'
|
||||
onChange: (editor) => @model.set(robots_txt: editor.getValue())
|
||||
|
||||
enable_ui_effects: ->
|
||||
@$('#site_domains_input .domain input[type=text]').editableField()
|
||||
@$('.memberships .entry .role select').editableField()
|
||||
save: (event) ->
|
||||
if @model.includes_domain(window.location.host)
|
||||
@save_in_ajax(event)
|
||||
|
||||
remove_membership: (event) ->
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
entry = $(event.target).parents('.entry').hide()
|
||||
entry.find('input[type=hidden]').val(1)
|
||||
show_error: (attribute, message, html) ->
|
||||
if attribute == 'domains'
|
||||
@domains_view.show_error(message)
|
||||
else
|
||||
super
|
||||
|
||||
remove: ->
|
||||
@domains_view.remove()
|
||||
@memberships_view.remove()
|
||||
super
|
||||
|
||||
|
@ -29,8 +29,6 @@ class Locomotive.Views.EditableElements.EditAllView extends Backbone.View
|
||||
|
||||
refresh: ->
|
||||
_.each @_editable_elements_views, (view) =>
|
||||
foo = @collection.get(view.model.get('id'))
|
||||
console.log(foo.cid)
|
||||
view.model = @collection.get(view.model.get('id'))
|
||||
view.refresh()
|
||||
|
||||
|
@ -7,8 +7,6 @@ class Locomotive.Views.Pages.EditView extends Locomotive.Views.Pages.FormView
|
||||
|
||||
@clear_errors()
|
||||
|
||||
console.log('saving')
|
||||
|
||||
@model.save {},
|
||||
success: (model, response, xhr) =>
|
||||
model._normalize()
|
||||
|
@ -18,6 +18,32 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
||||
save: (event) ->
|
||||
# by default, follow the default behaviour
|
||||
|
||||
save_in_ajax: (event, options) ->
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
|
||||
@clear_errors()
|
||||
|
||||
options ||= { on_success: null, on_error: null }
|
||||
|
||||
previous_attributes = _.clone @model.attributes
|
||||
|
||||
@model.save {},
|
||||
success: (model, response, xhr) =>
|
||||
$.growl('success', xhr.getResponseHeader('X-Message'))
|
||||
|
||||
model.attributes = previous_attributes
|
||||
|
||||
options.on_success(response) if options.on_success
|
||||
|
||||
error: (model, xhr) =>
|
||||
$.growl('error', xhr.getResponseHeader('X-Message'))
|
||||
|
||||
errors = JSON.parse(xhr.responseText)
|
||||
|
||||
@show_errors errors
|
||||
|
||||
options.on_error() if options.on_error
|
||||
|
||||
make_title_editable: ->
|
||||
title = @$('h2 a.editable')
|
||||
|
||||
@ -49,7 +75,7 @@ class Locomotive.Views.Shared.FormView extends Backbone.View
|
||||
# overide this method if necessary
|
||||
|
||||
clear_errors: ->
|
||||
@$('div.inline-errors').remove()
|
||||
@$('.inline-errors').remove()
|
||||
|
||||
show_errors: (errors) ->
|
||||
for attribute, message of errors
|
||||
|
@ -1,4 +1,4 @@
|
||||
Locomotive.Views.CurrentSite ||= {}
|
||||
Locomotive.Views.Site ||= {}
|
||||
|
||||
class Locomotive.Views.Site.DomainEntryView extends Backbone.View
|
||||
|
||||
|
@ -17,6 +17,8 @@ class Locomotive.Views.Site.DomainsView extends Backbone.View
|
||||
|
||||
@render_entries()
|
||||
|
||||
@enable_ui_effects()
|
||||
|
||||
return @
|
||||
|
||||
add_entry: (event) ->
|
||||
@ -53,11 +55,22 @@ class Locomotive.Views.Site.DomainsView extends Backbone.View
|
||||
@$('.empty').show()
|
||||
else
|
||||
_.each @model.get('domains'), (domain) =>
|
||||
_.each @options.errors.domain || [], (message) =>
|
||||
domain.error = message if message.test /^#{domain.get('name')} /
|
||||
|
||||
@_insert_entry(domain)
|
||||
|
||||
@show_errors()
|
||||
|
||||
show_errors: ->
|
||||
_.each @options.errors.domain || [], (message) => @show_error(message)
|
||||
|
||||
show_error: (message) ->
|
||||
_.each (@_entry_views || []), (view) ->
|
||||
if new RegExp("^#{view.model.get('name')}").test message
|
||||
html = $('<span></span>').addClass('inline-errors').html(message)
|
||||
view.$('input[type=text].path').after(html)
|
||||
|
||||
enable_ui_effects: ->
|
||||
@$('.domain input[type=text]').editableField()
|
||||
|
||||
_insert_entry: (domain) ->
|
||||
view = new Locomotive.Views.Site.DomainEntryView model: domain, parent_view: @
|
||||
|
||||
|
@ -0,0 +1,29 @@
|
||||
Locomotive.Views.Site ||= {}
|
||||
|
||||
class Locomotive.Views.Site.MembershipEntryView extends Backbone.View
|
||||
|
||||
className: 'entry'
|
||||
|
||||
events:
|
||||
'change select' : 'change'
|
||||
'click a.remove': 'remove'
|
||||
|
||||
render: ->
|
||||
data = @model.toJSON()
|
||||
data.index = @options.index
|
||||
|
||||
$(@el).html(ich.membership_entry(data))
|
||||
|
||||
@$('select').val(@model.get('role'))
|
||||
|
||||
return @
|
||||
|
||||
change: (event) ->
|
||||
value = $(event.target).val()
|
||||
@options.parent_view.change_entry(@model, value)
|
||||
|
||||
remove: (event) ->
|
||||
event.stopPropagation() & event.preventDefault()
|
||||
@$('select').editableField('destroy')
|
||||
@options.parent_view.remove_entry(@model)
|
||||
super()
|
@ -0,0 +1,41 @@
|
||||
Locomotive.Views.Site ||= {}
|
||||
|
||||
class Locomotive.Views.Site.MembershipsView extends Backbone.View
|
||||
|
||||
tagName: 'div'
|
||||
|
||||
className: 'list'
|
||||
|
||||
_entry_views = []
|
||||
|
||||
render: ->
|
||||
@render_entries()
|
||||
|
||||
@enable_ui_effects()
|
||||
|
||||
return @
|
||||
|
||||
change_entry: (membership, value) ->
|
||||
membership.set role: value
|
||||
|
||||
remove_entry: (membership) ->
|
||||
membership.set _destroy: true
|
||||
|
||||
render_entries: ->
|
||||
@model.get('memberships').each (membership, index) =>
|
||||
@_insert_entry(membership, index)
|
||||
|
||||
enable_ui_effects: ->
|
||||
@$('.entry select').editableField()
|
||||
|
||||
_insert_entry: (membership, index) ->
|
||||
view = new Locomotive.Views.Site.MembershipEntryView model: membership, parent_view: @, index: index
|
||||
|
||||
(@_entry_views ||= []).push(view)
|
||||
|
||||
$(@el).append(view.render().el)
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -95,6 +95,16 @@ form.formtastic {
|
||||
}
|
||||
}
|
||||
|
||||
span.inline-errors {
|
||||
margin-left: 10px;
|
||||
padding: 2px 3px;
|
||||
|
||||
background: #FFE5E5;
|
||||
|
||||
color: #CE2525;
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
span.actions {
|
||||
position: absolute;
|
||||
top: 0px;
|
||||
@ -323,8 +333,11 @@ form.formtastic {
|
||||
margin-top: 10px;
|
||||
margin-bottom: 0px;
|
||||
}
|
||||
}
|
||||
} // li.no-label
|
||||
|
||||
&.memberships {
|
||||
&#site_memberships_input {
|
||||
.entry {
|
||||
em.email {
|
||||
margin-left: 10px;
|
||||
}
|
||||
@ -357,10 +370,8 @@ form.formtastic {
|
||||
}
|
||||
}
|
||||
}
|
||||
} // li.no-label .list.memberships
|
||||
}
|
||||
|
||||
} // li.no-label
|
||||
} // > li#site_memberships_input
|
||||
|
||||
} // > li
|
||||
|
||||
|
@ -31,7 +31,7 @@ module Locomotive
|
||||
sign_in(account)
|
||||
redirect_to admin_pages_path
|
||||
else
|
||||
redirect_to new_admin_session_path, :alert => t('fash.locomotive.cross_domain_sessions.create.alert')
|
||||
redirect_to new_admin_session_path, :alert => t('flash.locomotive.cross_domain_sessions.create.alert')
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -106,5 +106,17 @@ module Locomotive::BaseHelper
|
||||
end
|
||||
end
|
||||
|
||||
# memberships
|
||||
|
||||
def options_for_membership_roles(options = {})
|
||||
list = (unless options[:skip_admin]
|
||||
Locomotive::Ability::ROLES.map { |r| [t("locomotive.memberships.roles.#{r}"), r] }
|
||||
else
|
||||
(Locomotive::Ability::ROLES - ['admin']).map { |r| [t("locomotive.memberships.roles.#{r}"), r] }
|
||||
end)
|
||||
|
||||
options_for_select(list)
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
@ -1,11 +1,11 @@
|
||||
module Locomotive::SitesHelper
|
||||
|
||||
def error_on_domain(site, name)
|
||||
if (error = (site.errors[:domains] || []).detect { |n| n.include?(name) })
|
||||
content_tag(:span, error, :class => 'inline-errors')
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
# def error_on_domain(site, name)
|
||||
# if (error = (site.errors[:domains] || []).detect { |n| n.include?(name) })
|
||||
# content_tag(:span, error, :class => 'inline-errors')
|
||||
# else
|
||||
# ''
|
||||
# end
|
||||
# end
|
||||
|
||||
end
|
||||
|
@ -9,6 +9,12 @@ module Locomotive
|
||||
end
|
||||
end
|
||||
|
||||
def wrapper_html_options
|
||||
super.tap do |opts|
|
||||
opts[:class] += ' no-label' unless render_label?
|
||||
end
|
||||
end
|
||||
|
||||
def error_html
|
||||
""
|
||||
end
|
||||
@ -17,13 +23,5 @@ module Locomotive
|
||||
false
|
||||
end
|
||||
|
||||
# def hint_html
|
||||
# ""
|
||||
# end
|
||||
#
|
||||
# def hint?
|
||||
# false
|
||||
# end
|
||||
|
||||
end
|
||||
end
|
@ -51,6 +51,10 @@ module Locomotive
|
||||
@ability ||= Ability.new(self.account, self.site)
|
||||
end
|
||||
|
||||
def as_json(options = {})
|
||||
Locomotive::MembershipPresenter.new(self, options).as_json
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def define_role
|
||||
|
@ -50,7 +50,7 @@ module Locomotive
|
||||
end
|
||||
|
||||
def as_json(options = {})
|
||||
Locomotive::SitePresenter.new(self).as_json
|
||||
Locomotive::SitePresenter.new(self, options).as_json
|
||||
end
|
||||
|
||||
protected
|
||||
|
@ -5,18 +5,27 @@ class Locomotive::BasePresenter
|
||||
include ActionView::Helpers::TextHelper
|
||||
include ActionView::Helpers::NumberHelper
|
||||
|
||||
attr_reader :source
|
||||
attr_reader :source, :options, :ability
|
||||
|
||||
delegate :created_at, :updated_at, :to => :source
|
||||
|
||||
def initialize(object)
|
||||
def initialize(object, options = {})
|
||||
@source = object
|
||||
@options = options
|
||||
|
||||
if @options && @options[:current_account] && @options[:current_site]
|
||||
@ability = Locomotive::Ability.new @options[:current_account], @options[:current_site]
|
||||
end
|
||||
end
|
||||
|
||||
def id
|
||||
@source._id.to_s
|
||||
end
|
||||
|
||||
def ability?
|
||||
self.ability.present?
|
||||
end
|
||||
|
||||
def included_methods
|
||||
%w(id created_at updated_at)
|
||||
end
|
||||
|
33
app/presenters/locomotive/membership_presenter.rb
Normal file
33
app/presenters/locomotive/membership_presenter.rb
Normal file
@ -0,0 +1,33 @@
|
||||
module Locomotive
|
||||
class MembershipPresenter < BasePresenter
|
||||
|
||||
delegate :role, :to => :source
|
||||
|
||||
def name
|
||||
self.source.account.name
|
||||
end
|
||||
|
||||
def role_name
|
||||
I18n.t("locomotive.memberships.roles.#{self.source.role}")
|
||||
end
|
||||
|
||||
def email
|
||||
self.source.account.email
|
||||
end
|
||||
|
||||
def can_update
|
||||
return nil unless self.ability?
|
||||
self.ability.can? :update, self.source
|
||||
end
|
||||
|
||||
def grant_admin
|
||||
return nil unless self.ability?
|
||||
self.ability.can? :grant_admin, self.source
|
||||
end
|
||||
|
||||
def included_methods
|
||||
super + %w(name email role role_name can_update grant_admin)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
@ -1,10 +1,18 @@
|
||||
module Locomotive
|
||||
class SitePresenter < BasePresenter
|
||||
|
||||
delegate :name, :subdomain, :domains, :robots_txt, :seo_title, :meta_keywords, :meta_description, :domains_without_subdomain, :memberships, :to => :source
|
||||
delegate :name, :subdomain, :domains, :robots_txt, :seo_title, :meta_keywords, :meta_description, :domains_without_subdomain, :to => :source
|
||||
|
||||
def domain_name
|
||||
Locomotive.config.domain
|
||||
end
|
||||
|
||||
def memberships
|
||||
self.source.memberships.map { |membership| membership.as_json(self.options) }
|
||||
end
|
||||
|
||||
def included_methods
|
||||
super + %w(name subdomain domains robots_txt seo_title meta_keywords meta_description domains_without_subdomain memberships)
|
||||
super + %w(name domain_name subdomain domains robots_txt seo_title meta_keywords meta_description domains_without_subdomain memberships)
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -1,9 +1,10 @@
|
||||
- content_for :head do
|
||||
= render 'locomotive/sites/domains'
|
||||
= render 'locomotive/sites/memberships'
|
||||
|
||||
- content_for :backbone_view_data do
|
||||
:plain
|
||||
{ site: #{@site.to_json}, errors: #{@site.errors.to_json} }
|
||||
{ site: #{@site.to_json(:current_account => current_locomotive_account, :current_site => current_site)}, errors: #{@site.errors.to_json} }
|
||||
|
||||
= f.inputs :name => :information, :style => "#{'display: none' unless @site.new_record?}" do
|
||||
= f.input :name, :required => false
|
||||
@ -24,32 +25,7 @@
|
||||
- if can?(:index, Locomotive::Membership)
|
||||
|
||||
= f.inputs :name => :memberships do
|
||||
%li{ :class => 'input empty no-label' }
|
||||
.list.memberships
|
||||
= f.semantic_fields_for :memberships do |fm|
|
||||
|
||||
- membership, account = fm.object, fm.object.account
|
||||
|
||||
.entry
|
||||
= fm.hidden_field :_destroy
|
||||
|
||||
%strong= account.name
|
||||
|
||||
%em.email= account.email
|
||||
|
||||
- if can?(:update, membership)
|
||||
.role
|
||||
- if can?(:grant_admin, membership)
|
||||
= fm.select :role, Locomotive::Ability::ROLES.map { |r| [t("locomotive.memberships.roles.#{r}"), r] }, :include_blank => false
|
||||
- else
|
||||
= fm.select :role, (Locomotive::Ability::ROLES - ['admin']).map { |r| [t("locomotive.memberships.roles.#{r}"), r] }, :include_blank => false
|
||||
|
||||
%span.actions
|
||||
= link_to 'x', '#', :class => 'remove'
|
||||
|
||||
- else
|
||||
.role
|
||||
%em.locked= t("locomotive.memberships.roles.#{membership.role}")
|
||||
= f.input :memberships, :as => :'Locomotive::Empty', :label => false, :wrapper_html => { :id => 'site_memberships_input' }
|
||||
|
||||
- if can?(:manage, current_site)
|
||||
|
||||
|
@ -18,9 +18,5 @@
|
||||
%em http://
|
||||
= text_field_tag 'site[domains][]', '{{name}}', :id => '', :class => 'path'
|
||||
|
||||
{{#if error}}
|
||||
%span.inline-errors {{error}}
|
||||
{{/if}}
|
||||
|
||||
%span.actions
|
||||
= link_to 'x', '#', :class => 'remove'
|
25
app/views/locomotive/sites/_memberships.html.haml
Normal file
25
app/views/locomotive/sites/_memberships.html.haml
Normal file
@ -0,0 +1,25 @@
|
||||
%script{ :type => 'text/html', :id => 'membership_entry' }
|
||||
|
||||
= hidden_field_tag 'site[memberships_attributes][{{index}}][id]', '{{id}}'
|
||||
= hidden_field_tag 'site[memberships_attributes][{{index}}][_destroy]'
|
||||
|
||||
%strong {{name}}
|
||||
|
||||
%em.email {{email}}
|
||||
|
||||
{{#if can_update}}
|
||||
.role
|
||||
{{#if grant_admin}}
|
||||
= select_tag 'site[memberships_attributes][{{index}}][role]', options_for_membership_roles
|
||||
{{else}}
|
||||
= select_tag 'site[memberships_attributes][{{index}}][role]', options_for_membership_roles(:skip_admin => true)
|
||||
{{/if}}
|
||||
|
||||
%span.actions
|
||||
= link_to 'x', '#', :class => 'remove'
|
||||
|
||||
{{else}}
|
||||
.role
|
||||
%em.locked {{role_name}}
|
||||
|
||||
{{/if}}
|
@ -157,7 +157,7 @@ en:
|
||||
|
||||
memberships:
|
||||
roles:
|
||||
locomotive: Administrator
|
||||
admin: Administrator
|
||||
designer: Designer
|
||||
author: Author
|
||||
new:
|
||||
|
@ -150,7 +150,7 @@ es:
|
||||
|
||||
memberships:
|
||||
roles:
|
||||
locomotive: Administrador
|
||||
admin: Administrador
|
||||
designer: Diseñador
|
||||
author: Autor
|
||||
new:
|
||||
|
@ -155,7 +155,7 @@ fr:
|
||||
|
||||
memberships:
|
||||
roles:
|
||||
locomotive: Administrateur
|
||||
admin: Administrateur
|
||||
designer: Designeur
|
||||
author: Auteur
|
||||
new:
|
||||
|
@ -150,7 +150,7 @@ it:
|
||||
|
||||
memberships:
|
||||
roles:
|
||||
locomotive: Amministratore
|
||||
admin: Amministratore
|
||||
designer: Designer
|
||||
author: Autore
|
||||
new:
|
||||
|
@ -152,7 +152,7 @@
|
||||
|
||||
memberships:
|
||||
roles:
|
||||
locomotive: Administrator
|
||||
admin: Administrator
|
||||
designer: Designer
|
||||
author: Forfatter
|
||||
new:
|
||||
|
@ -152,7 +152,7 @@ ru:
|
||||
|
||||
memberships:
|
||||
roles:
|
||||
locomotive: Администратор
|
||||
admin: Администратор
|
||||
designer: Дизайнер
|
||||
author: Автор
|
||||
new:
|
||||
|
11
doc/TODO
11
doc/TODO
@ -15,18 +15,19 @@ x menu / submenu in full css3 (no images)
|
||||
x fix css in firefox
|
||||
x update page in ajax
|
||||
- fix other sections
|
||||
- edit my site
|
||||
x edit my site
|
||||
x css
|
||||
x robots.txt
|
||||
- domains
|
||||
- roles
|
||||
- save
|
||||
|
||||
x domains
|
||||
x roles
|
||||
x save
|
||||
- create a new site
|
||||
- edit my account
|
||||
- theme assets
|
||||
- content types
|
||||
|
||||
- install a site by default at the first installation (without asking)
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user