[issue #347] Added backbone. Changed collaborators page.
This commit is contained in:
parent
851fd9d722
commit
71c8efabf9
2
Gemfile
2
Gemfile
|
@ -44,6 +44,8 @@ gem 'rails3-jquery-autocomplete', '~> 1.0.6'
|
|||
gem 'will_paginate', '~> 3.0.3'
|
||||
gem 'meta-tags', '~> 1.2.5', :require => 'meta_tags'
|
||||
gem "haml-rails", '~> 0.3.4'
|
||||
gem 'ruby-haml-js'
|
||||
gem 'rails-backbone'
|
||||
gem 'jquery-rails', '~> 2.0.1'
|
||||
|
||||
group :assets do
|
||||
|
|
10
Gemfile.lock
10
Gemfile.lock
|
@ -110,6 +110,7 @@ GEM
|
|||
warden (~> 1.1.1)
|
||||
diff-display (0.0.1)
|
||||
diff-lcs (1.1.3)
|
||||
ejs (1.0.0)
|
||||
erubis (2.7.0)
|
||||
eventmachine (0.12.10)
|
||||
eventmachine (0.12.10-java)
|
||||
|
@ -218,6 +219,10 @@ GEM
|
|||
activesupport (= 3.2.2)
|
||||
bundler (~> 1.0)
|
||||
railties (= 3.2.2)
|
||||
rails-backbone (0.7.1)
|
||||
coffee-script (~> 2.2.0)
|
||||
ejs (~> 1.0.0)
|
||||
railties (>= 3.1.0)
|
||||
rails3-generators (0.17.4)
|
||||
railties (>= 3.0.0)
|
||||
rails3-jquery-autocomplete (1.0.6)
|
||||
|
@ -249,6 +254,9 @@ GEM
|
|||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec (~> 2.9.0)
|
||||
ruby-haml-js (0.0.2)
|
||||
execjs
|
||||
sprockets (>= 2.0.0)
|
||||
ruby-openid (2.1.8)
|
||||
russian (0.6.0)
|
||||
i18n (>= 0.5.0)
|
||||
|
@ -351,6 +359,7 @@ DEPENDENCIES
|
|||
paperclip (~> 2.7.0)
|
||||
pg (~> 0.13.2)
|
||||
rails (= 3.2.2)
|
||||
rails-backbone
|
||||
rails3-generators
|
||||
rails3-jquery-autocomplete (~> 1.0.6)
|
||||
rdiscount
|
||||
|
@ -358,6 +367,7 @@ DEPENDENCIES
|
|||
redhillonrails_core!
|
||||
rr (~> 1.0.4)
|
||||
rspec-rails (~> 2.9.0)
|
||||
ruby-haml-js
|
||||
russian (~> 0.6.0)
|
||||
sass-rails (~> 3.2.5)
|
||||
shotgun
|
||||
|
|
|
@ -6,6 +6,12 @@
|
|||
//= require jquery.dataTables_ext
|
||||
//= require_tree ./design
|
||||
//= require_tree ./extra
|
||||
|
||||
//= require underscore
|
||||
//= require backbone
|
||||
//= require backbone_rails_sync
|
||||
//= require backbone_datalink
|
||||
//= require backbone/rosa
|
||||
//= require_self
|
||||
|
||||
function disableNotifierCbx(global_cbx) {
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
Rosa.bootstrapedData.ROLES = <%= Relation::ROLES.to_json %>;
|
|
@ -0,0 +1,52 @@
|
|||
Rosa.Models.Collaborator = Backbone.Model.extend({
|
||||
paramRoot: 'collaborator',
|
||||
|
||||
defaults: {
|
||||
id: null,
|
||||
name: null,
|
||||
role: null,
|
||||
removed: false
|
||||
},
|
||||
|
||||
changeRole: function(r) {
|
||||
this._prevState = this.get('role');
|
||||
this.save({role: r},
|
||||
{wait: true,
|
||||
error: function(model, response) {
|
||||
model.set({role: model._prevState});
|
||||
}
|
||||
});
|
||||
return this;
|
||||
},
|
||||
toggleRemoved: function() {
|
||||
if (this.get('removed') === false) {
|
||||
this.set({removed: true});
|
||||
} else {
|
||||
this.set({removed: false});
|
||||
}
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
Rosa.Collections.CollaboratorsCollection = Backbone.Collection.extend({
|
||||
model: Rosa.Models.Collaborator,
|
||||
|
||||
initialize: function() {
|
||||
this.url = window.location.pathname;
|
||||
this.on('change:removed add', this.sort, this);
|
||||
},
|
||||
comparator: function(m) {
|
||||
return ((m.get('removed') === true) ? '0' : '1') + m.get('name');
|
||||
},
|
||||
|
||||
removeMarked: function(params) {
|
||||
var marked = this.where({removed: true});
|
||||
if (params['type'] !== undefined) {
|
||||
marked = marked.where({type: params['type']});
|
||||
}
|
||||
marked.forEach(function(el) {
|
||||
el.destroy({wait: true, silent: true});
|
||||
});
|
||||
// this.trigger('reset');
|
||||
}
|
||||
});
|
|
@ -0,0 +1,15 @@
|
|||
//= require_self
|
||||
//= require ./additionals
|
||||
//= require_tree ./templates
|
||||
//= require_tree ./models
|
||||
//= require_tree ./views
|
||||
//= require_tree ./routers
|
||||
|
||||
window.Rosa = {
|
||||
Models: {},
|
||||
Collections: {},
|
||||
Routers: {},
|
||||
Views: {},
|
||||
|
||||
bootstrapedData: {}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
Rosa.Routers.CollaboratorsRouter = Backbone.Router.extend({
|
||||
routes: {},
|
||||
|
||||
initialize: function() {
|
||||
this.collaboratorsCollection = new Rosa.Collections.CollaboratorsCollection(Rosa.bootstrapedData.collaborators);
|
||||
this.usersView = new Rosa.Views.CollaboratorsView({collection_type: 'user', collection: this.collaboratorsCollection});
|
||||
this.groupsView = new Rosa.Views.CollaboratorsView({collection_type: 'group', collection: this.collaboratorsCollection});
|
||||
|
||||
this.usersView.render();
|
||||
this.groupsView.render();
|
||||
}
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
%td
|
||||
%span#niceCheckbox1.nicecheck-main{ style: "background-position: 0px 0px; "}
|
||||
- if (removed === true) {
|
||||
%input{ type: 'checkbox', value: 1, id: type + '_remove_' + id + '_', name: type + '_remove[' + id + '][]', checked: 'checked' }
|
||||
- } else {
|
||||
%input{ type: 'checkbox', value: 1, id: type + '_remove_' + id + '_', name: type + '_remove[' + id + '][]' }
|
||||
- }
|
||||
%td
|
||||
- if (type === 'user') {
|
||||
.img
|
||||
%img{src: avatar, alt: avatar}
|
||||
- }
|
||||
.forimg
|
||||
%a{href: collaborator_link}
|
||||
= name
|
||||
- var ROLES = Rosa.bootstrapedData.ROLES;
|
||||
- for (var i = 0; i < ROLES.length; i++) {
|
||||
%td
|
||||
.radio
|
||||
- var radio_id = type + '_' + id + '_' + ROLES[i];
|
||||
- var radio_type = type + '[' + id + ']';
|
||||
- if (ROLES[i] === role) {
|
||||
- if ( removed ) {
|
||||
%input.niceRadio{type: 'radio', value: ROLES[i], id: radio_id, name: radio_type, disabled: 'disabled', checked: 'checked'}
|
||||
- } else {
|
||||
%input.niceRadio{type: 'radio', value: ROLES[i], id: radio_id, name: radio_type, checked: 'checked'}
|
||||
- };
|
||||
- } else {
|
||||
- if ( removed ) {
|
||||
%input.niceRadio{type: 'radio', value: ROLES[i], id: radio_id, name: radio_type, disabled: 'disabled' }
|
||||
- } else {
|
||||
%input.niceRadio{type: 'radio', value: ROLES[i], id: radio_id, name: radio_type }
|
||||
- };
|
||||
- }
|
||||
.forradio
|
||||
%label{for: radio_id}
|
||||
= ROLES[i]
|
||||
- }
|
|
@ -0,0 +1,39 @@
|
|||
Rosa.Views.CollaboratorView = Backbone.View.extend({
|
||||
template: JST['backbone/templates/collaborators/collaborator'],
|
||||
tagName: 'tr',
|
||||
|
||||
events: {
|
||||
'change input[type="radio"]': 'changeRole',
|
||||
'change input[type="checkbox"]': 'toggleRemoved'
|
||||
},
|
||||
|
||||
initialize: function() {
|
||||
this.$el.attr('id', 'admin-table-members-row' + this.options.model.get('id') + this.options.model.get('type'));
|
||||
this.model.on('change', this.render, this);
|
||||
this.model.on('destroy', this.hide, this);
|
||||
},
|
||||
|
||||
render: function() {
|
||||
if (this.model.get('removed')) {
|
||||
this.$el.addClass('removed');
|
||||
} else {
|
||||
this.$el.removeClass('removed');
|
||||
};
|
||||
this.$el.html(this.template(this.model.toJSON()));
|
||||
return this;
|
||||
},
|
||||
|
||||
changeRole: function(e) {
|
||||
this.model.changeRole(e.target.value);
|
||||
},
|
||||
|
||||
toggleRemoved: function(e) {
|
||||
//var mod = this.model
|
||||
//this.$el.addClass('removed').fadeOut(1000, function() { mod.toggleRemoved() });
|
||||
this.model.toggleRemoved();
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
this.remove();
|
||||
}
|
||||
});
|
|
@ -0,0 +1,38 @@
|
|||
Rosa.Views.CollaboratorsView = Backbone.View.extend({
|
||||
initialize: function() {
|
||||
this._type = this.options['collection_type'];
|
||||
this.setupDeleter();
|
||||
this.$el = $('#' + this._type + 's_collaborators > tbody');
|
||||
this.collection.on('add', this.addOne, this);
|
||||
this.collection.on('reset', this.render, this);
|
||||
},
|
||||
|
||||
addOne: function(collaborator) {
|
||||
if (collaborator.get('type') === this._type) {
|
||||
var cView = new Rosa.Views.CollaboratorView({ model: collaborator });
|
||||
this.$el.append(cView.render().el);
|
||||
};
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.empty();
|
||||
var col = new Rosa.Collections.CollaboratorsCollection(this.collection.where({type: this._type}));
|
||||
col.forEach(this.addOne, this);
|
||||
if (col.where({ removed: true }).length > 0) {
|
||||
this._$deleter.show();
|
||||
} else {
|
||||
this._$deleter.hide();
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
setupDeleter: function() {
|
||||
this._$deleter = $('#' + this._type + 's_deleter');
|
||||
this._$deleter.on('click.deleter', '', {context: this}, this.deleterClick);
|
||||
this._$deleter.attr('title', 'Remove selected rows');
|
||||
},
|
||||
|
||||
deleterClick: function(e) {
|
||||
e.data['context'].collection.removeMarked({type: this._type});
|
||||
}
|
||||
});
|
|
@ -76,7 +76,9 @@ function changeRadioStart(el) {
|
|||
}
|
||||
|
||||
el.next().bind("mousedown", function(e) {
|
||||
changeRadio($(this));
|
||||
if (e.which === 0) {
|
||||
changeRadio($(this));
|
||||
};
|
||||
$(this).find("input:radio").change();
|
||||
});
|
||||
if($.browser.msie) {
|
||||
|
|
|
@ -1,9 +1,13 @@
|
|||
// PUT custom styles here ONLY
|
||||
|
||||
span.error {
|
||||
span.error, .hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.centered {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
a#manage-labels {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
@ -456,10 +460,12 @@ table.tablesorter tr td.buttons {
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
table.tablesorter tr td.buttons a span.delete {
|
||||
table.tablesorter tr td.buttons a span.delete,
|
||||
span.delete {
|
||||
background: image-url('x.png') no-repeat 0 0 transparent;
|
||||
width: 12px;
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
#fork-and-edit {display:block;}
|
||||
|
@ -764,3 +770,7 @@ div.tos_sidebar ul li a {
|
|||
padding-top: 5px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
table.tablesorter tbody tr.removed td {
|
||||
background-color: #FFECEC;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
class CollaboratorsController < ApplicationController
|
||||
respond_to :html, :json
|
||||
|
||||
before_filter :authenticate_user!
|
||||
|
||||
before_filter :find_project
|
||||
|
@ -10,7 +12,9 @@ class CollaboratorsController < ApplicationController
|
|||
before_filter :authorize_collaborators
|
||||
|
||||
def index
|
||||
redirect_to edit_project_collaborators_path(@project)
|
||||
# redirect_to edit_project_collaborators_path(@project)
|
||||
@collaborators = Collaborator.find_by_project(@project)
|
||||
respond_with @collaborators
|
||||
end
|
||||
|
||||
def show
|
||||
|
@ -30,38 +34,44 @@ class CollaboratorsController < ApplicationController
|
|||
end
|
||||
|
||||
def update
|
||||
params['user'].keys.each { |user_id|
|
||||
role = params['user'][user_id]
|
||||
|
||||
if relation = @project.relations.find_by_object_id_and_object_type(user_id, 'User')
|
||||
unless @project.owner_type == 'User' and @project.owner_id.to_i == user_id.to_i
|
||||
relation.update_attribute(:role, role)
|
||||
end
|
||||
else
|
||||
relation = @project.relations.build(:object_id => user_id, :object_type => 'User', :role => role)
|
||||
relation.save
|
||||
end
|
||||
} if params['user']
|
||||
|
||||
params['group'].keys.each { |group_id|
|
||||
role = params['group'][group_id]
|
||||
if relation = @project.relations.find_by_object_id_and_object_type(group_id, 'Group')
|
||||
unless @project.owner_type == 'Group' and @project.owner_id.to_i == group_id.to_i
|
||||
relation.update_attribute(:role, role)
|
||||
end
|
||||
else
|
||||
relation = @project.relations.build(:object_id => user_id, :object_type => 'Group', :role => role)
|
||||
relation.save
|
||||
end
|
||||
} if params['group']
|
||||
|
||||
if @project.save
|
||||
flash[:notice] = t("flash.collaborators.successfully_changed")
|
||||
@c = Collaborator.new(params[:collaborator])
|
||||
if @c.save
|
||||
respond_with @c
|
||||
else
|
||||
flash[:error] = t("flash.collaborators.error_in_changing")
|
||||
raise
|
||||
end
|
||||
|
||||
redirect_to edit_project_collaborators_path(@project)
|
||||
# params['user'].keys.each { |user_id|
|
||||
# role = params['user'][user_id]
|
||||
#
|
||||
# if relation = @project.relations.find_by_object_id_and_object_type(user_id, 'User')
|
||||
# unless @project.owner_type == 'User' and @project.owner_id.to_i == user_id.to_i
|
||||
# relation.update_attribute(:role, role)
|
||||
# end
|
||||
# else
|
||||
# relation = @project.relations.build(:object_id => user_id, :object_type => 'User', :role => role)
|
||||
# relation.save
|
||||
# end
|
||||
# } if params['user']
|
||||
#
|
||||
# params['group'].keys.each { |group_id|
|
||||
# role = params['group'][group_id]
|
||||
# if relation = @project.relations.find_by_object_id_and_object_type(group_id, 'Group')
|
||||
# unless @project.owner_type == 'Group' and @project.owner_id.to_i == group_id.to_i
|
||||
# relation.update_attribute(:role, role)
|
||||
# end
|
||||
# else
|
||||
# relation = @project.relations.build(:object_id => user_id, :object_type => 'Group', :role => role)
|
||||
# relation.save
|
||||
# end
|
||||
# } if params['group']
|
||||
#
|
||||
# if @project.save
|
||||
# flash[:notice] = t("flash.collaborators.successfully_changed")
|
||||
# else
|
||||
# flash[:error] = t("flash.collaborators.error_in_changing")
|
||||
# end
|
||||
#
|
||||
# redirect_to edit_project_collaborators_path(@project)
|
||||
end
|
||||
|
||||
def remove
|
||||
|
@ -88,6 +98,12 @@ class CollaboratorsController < ApplicationController
|
|||
redirect_to edit_project_collaborators_path(@project) + "##{params['user_remove'].present? ? 'users' : 'groups'}"
|
||||
end
|
||||
|
||||
def destroy
|
||||
@cb = Collaborator.find_by_project(@project, :id => params[:id])
|
||||
@cb.destroy if @cb
|
||||
respond_with @cb
|
||||
end
|
||||
|
||||
def add
|
||||
# TODO: Here is used Chelyabinsk method to display Flash messages.
|
||||
|
||||
|
@ -120,7 +136,7 @@ class CollaboratorsController < ApplicationController
|
|||
end
|
||||
|
||||
# if add an anchor, adding will be more pleasant, but flash message wouldn't be shown.
|
||||
redirect_to edit_project_collaborators_path(@project) # + "##{(params['member_id'].present?) ? 'users' : 'groups'}"
|
||||
redirect_to project_collaborators_path(@project) # + "##{(params['member_id'].present?) ? 'users' : 'groups'}"
|
||||
end
|
||||
|
||||
protected
|
||||
|
|
|
@ -30,4 +30,8 @@ module ProjectsHelper
|
|||
def alone_member?(project)
|
||||
Relation.by_target(project).by_object(current_user).size > 0
|
||||
end
|
||||
|
||||
def participant_path(participant)
|
||||
participant.kind_of?(User) ? user_path(participant) : group_path(participant)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
# -*- encoding : utf-8 -*-
|
||||
class Collaborator
|
||||
include ActiveModel::Conversion
|
||||
include ActiveModel::Validations
|
||||
include ActiveModel::Serializers::JSON
|
||||
include ActiveModel::MassAssignmentSecurity
|
||||
|
||||
attr_accessor :role, :actor, :project
|
||||
attr_reader :id, :type, :name, :project_id
|
||||
|
||||
attr_accessible :role
|
||||
|
||||
delegate :new_record?, :to => :relation
|
||||
|
||||
class << self
|
||||
def find_by_project(project, opts = {})
|
||||
(id, type) = if opts[:id].present?
|
||||
if opts[:type].present?
|
||||
[opts[:id], opts[:type]]
|
||||
else
|
||||
opts[:id].split('-', 2)
|
||||
end
|
||||
else
|
||||
[nil, nil]
|
||||
end
|
||||
puts id
|
||||
puts type
|
||||
if id.present? and type.present?
|
||||
rel = project.relations.where(:object_id => id, :object_type => type.classify).first
|
||||
puts rel.inspect
|
||||
res = from_relation(project.relations.where(:object_id => id, :object_type => type.classify).first)
|
||||
else
|
||||
res = []
|
||||
project.relations.each do |r|
|
||||
res << from_relation(r) unless project.owner_id == r.object_id and project.owner_type == r.object_type
|
||||
end
|
||||
end
|
||||
return res
|
||||
end
|
||||
|
||||
def from_relation(relation)
|
||||
return self.new(:relation => relation, :id => relation.object_id,
|
||||
:type => relation.object_type, :project_id => relation.target_id)
|
||||
end
|
||||
end
|
||||
|
||||
def initialize(args = {})
|
||||
args.to_options!
|
||||
acc_options = args.select{ |(k, v)| k.in? [:actor, :project] }
|
||||
acc_options.each_pair do |name, value|
|
||||
send("#{name}=", value)
|
||||
end
|
||||
|
||||
if @project.nil? and args[:project_id].present?
|
||||
@project = Project.find(args[:project_id])
|
||||
end
|
||||
|
||||
if @actor.nil? and args[:type].present? and args[:id].present?
|
||||
@actor = args[:type].classify.constantize.find(args[:id].to_s.split('-', 2).first.to_i) rescue nil
|
||||
end
|
||||
|
||||
if args[:relation]
|
||||
@relation = args[:relation]
|
||||
else
|
||||
setup_relation
|
||||
end
|
||||
|
||||
@relation.role = args[:role] if args[:role]
|
||||
end
|
||||
|
||||
def update_attributes(attributes, options = {})
|
||||
sanitize_for_mass_assignment(attributes, options[:as]).each_pair do |k, v|
|
||||
send("#{k}=", v)
|
||||
end
|
||||
save
|
||||
end
|
||||
|
||||
def actor=(model)
|
||||
@actor = model
|
||||
|
||||
setup_relation
|
||||
end
|
||||
|
||||
def project=(model)
|
||||
@project = model
|
||||
|
||||
setup_relation
|
||||
end
|
||||
|
||||
def id
|
||||
@actor.try(:id)
|
||||
end
|
||||
|
||||
def type
|
||||
@actor.class.to_s.underscore
|
||||
end
|
||||
|
||||
def name
|
||||
if @actor.present?
|
||||
@actor.instance_of?(User) ? "#{@actor.uname} (#{@actor.name})" : @actor.uname
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
|
||||
def project_id
|
||||
@project.try(:id)
|
||||
end
|
||||
|
||||
def role
|
||||
@relation.role
|
||||
end
|
||||
|
||||
def role=(arg)
|
||||
@relation.role = arg
|
||||
end
|
||||
|
||||
def save
|
||||
@relation.try(:save)
|
||||
end
|
||||
|
||||
def save!
|
||||
@relation.try(:save!)
|
||||
end
|
||||
|
||||
def destroy
|
||||
@relation.try(:destroy)
|
||||
end
|
||||
|
||||
def attributes
|
||||
%w{ id type name project_id role}.inject({}) do |h, e|
|
||||
h.merge(e => send(e))
|
||||
end
|
||||
end
|
||||
|
||||
def persisted?
|
||||
false
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def relation
|
||||
setup_relation
|
||||
@relation
|
||||
end
|
||||
|
||||
def setup_relation
|
||||
if @actor.present? and @project.present?
|
||||
@relation = Relation.by_object(@actor).by_target(@project).limit(1).first
|
||||
@relation ||= Relation.new(:object_id => @actor.id, :object_type => @actor.class.to_s.underscore,
|
||||
:target_id => @project.id, :target_type => 'Project')
|
||||
else
|
||||
@relation = Relation.new
|
||||
@relation.object = @actor
|
||||
@relation.target = @project
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
Collaborator.include_root_in_json = false
|
|
@ -0,0 +1,5 @@
|
|||
json.id collaborator.id.to_s + '-' + collaborator.type
|
||||
json.name collaborator.name
|
||||
json.type collaborator.type
|
||||
json.project_id collaborator.project_id
|
||||
json.role collaborator.role
|
|
@ -0,0 +1,9 @@
|
|||
json.array!(collaborators) do |json, cb|
|
||||
json.id cb.id.to_s + '-' + cb.type
|
||||
json.name cb.name
|
||||
json.collaborator_link participant_path(cb.actor)
|
||||
json.avatar avatar_url(cb.actor) if cb.actor.kind_of?(User)
|
||||
json.type cb.type
|
||||
json.project_id cb.project_id
|
||||
json.role cb.role
|
||||
end
|
|
@ -0,0 +1,100 @@
|
|||
-set_meta_tags :title => [title_object(@project), t('layout.projects.members')]
|
||||
= render :partial => 'projects/sidebar'
|
||||
= render :partial => 'projects/submenu'
|
||||
|
||||
%a{:name => 'users'}
|
||||
%h3= t("layout.users.list_header")
|
||||
|
||||
= form_tag add_project_collaborators_path(@project) do
|
||||
.admin-search
|
||||
= autocomplete_field_tag 'member_id', params[:member_id], autocomplete_user_uname_users_path, :id_element => '#member_id_field'
|
||||
.admin-role
|
||||
.lineForm
|
||||
= select_tag 'role', options_for_collaborators_roles_select
|
||||
= hidden_field_tag 'member_id', nil, :id => 'member_id_field'
|
||||
= submit_tag t("layout.add"), :class => 'button'
|
||||
.both
|
||||
|
||||
= form_tag project_collaborators_path(@project), :id => 'members_form', :delete_url => remove_project_collaborators_path(@project) do
|
||||
= hidden_field_tag "_method", "post"
|
||||
%table#users_collaborators.tablesorter{:cellpadding => "0", :cellspacing => "0"}
|
||||
%thead
|
||||
%tr
|
||||
%th.centered
|
||||
%span#users_deleter.hidden
|
||||
%span.delete
|
||||
%th
|
||||
= t("layout.collaborators.members")
|
||||
%th{:colspan => "3"}
|
||||
= t("layout.collaborators.roles")
|
||||
%tbody
|
||||
-# @users.each_with_index do |user, num|
|
||||
%tr{:id => "admin-table-members-row#{num}"}
|
||||
%td
|
||||
%span#niceCheckbox1.niceCheck-main{ :style => "background-position: 0px 0px; "}
|
||||
= check_box_tag "user_remove[#{user.id}][]"
|
||||
%td
|
||||
.img
|
||||
= image_tag avatar_url(user)
|
||||
.forimg= link_to "#{user.uname} (#{user.name})", user_path(user)
|
||||
- Relation::ROLES.each_with_index do |role, i|
|
||||
%td
|
||||
.radio
|
||||
= radio_button_tag "user[#{user.id}]", role, ((@project.relations.exists? :object_id => user.id, :object_type => 'User', :role => role) ? :checked : nil), :class => 'niceRadio'
|
||||
.forradio= t("layout.collaborators.role_names.#{ role }")
|
||||
=# link_to_function t("layout.delete_selected"), "deleteAdminMember();", :class => 'button'
|
||||
=# link_to_function t("layout.save"), "saveAdminMember();", :class => 'button right_floated'
|
||||
.both
|
||||
%br
|
||||
|
||||
.hr.bottom
|
||||
.both
|
||||
|
||||
%a{:name => 'groups'}
|
||||
%h3= t("layout.groups.list_header")
|
||||
|
||||
= form_tag add_project_collaborators_path(@project) do
|
||||
.admin-search
|
||||
= autocomplete_field_tag 'group_id', params[:group_id], autocomplete_group_uname_groups_path, :id_element => '#group_id_field'
|
||||
.admin-role
|
||||
.lineForm
|
||||
= select_tag 'role', options_for_collaborators_roles_select, :id => 'group_role'
|
||||
= hidden_field_tag 'group_id', nil, :id => 'group_id_field'
|
||||
= submit_tag t("layout.add"), :class => 'button'
|
||||
.both
|
||||
|
||||
= form_tag project_collaborators_path(@project), :id => 'groups_form', :delete_url => remove_project_collaborators_path(@project) do
|
||||
= hidden_field_tag "_method", "post", :id => 'groups_method'
|
||||
%table#groups_collaborators.tablesorter{:cellpadding => "0", :cellspacing => "0"}
|
||||
%thead
|
||||
%tr
|
||||
%th.centered
|
||||
%span#groups_deleter.hidden
|
||||
%span.delete
|
||||
%th
|
||||
= t("layout.collaborators.members")
|
||||
%th{:colspan => "3"}
|
||||
= t("layout.collaborators.roles")
|
||||
%tbody
|
||||
-# @groups.each_with_index do |group, num|
|
||||
%tr{:id => "admin-table-members-row#{num + @users.size + 1}"}
|
||||
%td
|
||||
%span#niceCheckbox1.niceCheck-main{ :style => "background-position: 0px 0px; "}
|
||||
= check_box_tag "group_remove[#{group.id}][]"
|
||||
%td
|
||||
.forimg= link_to "#{group.uname}", group_path(group)
|
||||
- Relation::ROLES.each_with_index do |role, i|
|
||||
%td
|
||||
.radio
|
||||
= radio_button_tag "group[#{group.id}]", role, ((@project.relations.exists? :object_id => group.id, :object_type => 'Group', :role => role) ? :checked : nil), :class => 'niceRadio'
|
||||
.forradio= t("layout.collaborators.role_names.#{ role }")
|
||||
=# link_to_function t("layout.delete_selected"), "deleteAdminGroup();", :class => 'button'
|
||||
=# link_to_function t("layout.save"), "saveAdminGroup();", :class => 'button right_floated'
|
||||
.both
|
||||
.both
|
||||
|
||||
:javascript
|
||||
$(function() {
|
||||
Rosa.bootstrapedData.collaborators = #{ render :partial => 'collaborators.json.jbuilder', :locals => {:collaborators => @collaborators } };
|
||||
var r = new Rosa.Routers.CollaboratorsRouter();
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
json.partial! 'collaborators', :collaborators => @collaborators
|
|
@ -33,7 +33,7 @@ Rosa::Application.configure do
|
|||
config.assets.compress = false
|
||||
|
||||
# Expands the lines which load the assets
|
||||
config.assets.debug = false
|
||||
config.assets.debug = true
|
||||
|
||||
# Raise exception on mass assignment protection for Active Record models
|
||||
config.active_record.mass_assignment_sanitizer = :strict
|
||||
|
|
|
@ -110,7 +110,7 @@ Rosa::Application.routes.draw do
|
|||
resources :build_lists, :only => [:index, :new, :create] do
|
||||
collection { post :search }
|
||||
end
|
||||
resources :collaborators, :only => [:index, :edit, :update, :add] do
|
||||
resources :collaborators, :only => [:index, :edit, :update, :add, :destroy] do
|
||||
collection do
|
||||
get :edit
|
||||
post :update
|
||||
|
|
Loading…
Reference in New Issue