Merge branch '90-pull' into 90-separate-issues-and-pull-requests
This commit is contained in:
commit
37c9a906c4
Binary file not shown.
After Width: | Height: | Size: 621 B |
Binary file not shown.
After Width: | Height: | Size: 380 B |
|
@ -0,0 +1,17 @@
|
||||||
|
$(document).ready(function() {
|
||||||
|
|
||||||
|
$(".div-filter-labels").live('click', function() {
|
||||||
|
var flag = this.id;
|
||||||
|
flag = flag.replace("label-","flag-");
|
||||||
|
var bg = $("#"+flag).css("background-color");
|
||||||
|
var checkbox = $(this).find(':checkbox');
|
||||||
|
if ($(this).css("background-color") != bg) {
|
||||||
|
$(this).css("background-color",bg).css("color","#FFFFFF");
|
||||||
|
checkbox.attr('checked', 'checked');
|
||||||
|
} else {
|
||||||
|
$(this).css("background-color","rgb(247, 247, 247)").css("color","#565657");
|
||||||
|
checkbox.removeAttr('checked');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
|
@ -30,19 +30,6 @@ $(document).ready(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
$("div.div-tracker-labels").live('click', function() {
|
$("div.div-tracker-labels").live('click', function() {
|
||||||
var flag = this.id;
|
|
||||||
flag = flag.replace("label-","flag-");
|
|
||||||
var bg = $("#"+flag).css("background-color");
|
|
||||||
var checkbox = $(this).find(':checkbox');
|
|
||||||
if ($(this).css("background-color") != bg) {
|
|
||||||
$(this).css("background-color",bg);
|
|
||||||
$(this).css("color","#FFFFFF");
|
|
||||||
checkbox.attr('checked', 'checked');
|
|
||||||
} else {
|
|
||||||
$(this).css("background-color","rgb(247, 247, 247)");
|
|
||||||
$(this).css("color","#565657");
|
|
||||||
checkbox.removeAttr('checked');
|
|
||||||
}
|
|
||||||
return send_index_tracker_request('GET');
|
return send_index_tracker_request('GET');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -698,48 +698,19 @@ div.toolbar a.button {
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.toolbar div.legend {
|
div.toolbar, table.dataTable {
|
||||||
float: left;
|
> .group_owner, > .user_owner, > .group, > .user { margin-right: 15px; }
|
||||||
margin-left: 50px;
|
.group_owner, .user_owner, .group, .user { padding-left: 20px; }
|
||||||
padding: 4px 0 6px;
|
.user_owner { background: image-url('user16g.png') no-repeat 0 0 transparent; }
|
||||||
|
.group_owner { background: image-url('group16g.png') no-repeat 0 0 transparent; }
|
||||||
|
.user { background: image-url('user16.png') no-repeat 0 0 transparent; }
|
||||||
|
.group { background: image-url('group16.png') no-repeat 0 0 transparent; }
|
||||||
}
|
}
|
||||||
|
|
||||||
table.dataTable tr td.rights span.group,
|
.div-filter-labels {
|
||||||
div.toolbar div.legend.rights span.group {
|
.group { background: image-url('group16b.png') no-repeat 0 0 transparent; }
|
||||||
background: image-url('group16.png') no-repeat 0 0 transparent;
|
.user { background: image-url('user16b.png') no-repeat 0 0 transparent; }
|
||||||
}
|
.user, .group { padding-left: 20px; }
|
||||||
|
|
||||||
table.dataTable tr td.rights span.user,
|
|
||||||
div.toolbar div.legend.rights span.user {
|
|
||||||
background: image-url('user16.png') no-repeat 0 0 transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.dataTable tr td.rights span.group_owner,
|
|
||||||
div.toolbar div.legend.rights span.group_owner {
|
|
||||||
background: image-url('group16g.png') no-repeat 0 0 transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.dataTable tr td.rights span.user_owner,
|
|
||||||
div.toolbar div.legend.rights span.user_owner {
|
|
||||||
background: image-url('user16g.png') no-repeat 0 0 transparent;
|
|
||||||
}
|
|
||||||
|
|
||||||
table.dataTable tr td.rights span.group_owner,
|
|
||||||
div.toolbar div.legend.rights span.group_owner,
|
|
||||||
table.dataTable tr td.rights span.user_owner,
|
|
||||||
div.toolbar div.legend.rights span.user_owner,
|
|
||||||
table.dataTable tr td.rights span.group,
|
|
||||||
div.toolbar div.legend.rights span.group,
|
|
||||||
table.dataTable tr td.rights span.user,
|
|
||||||
div.toolbar div.legend.rights span.user {
|
|
||||||
padding-left: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.toolbar div.legend.rights span.group_owner,
|
|
||||||
div.toolbar div.legend.rights span.user_owner,
|
|
||||||
div.toolbar div.legend.rights span.group,
|
|
||||||
div.toolbar div.legend.rights span.user {
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.root {
|
.root {
|
||||||
|
|
|
@ -1931,7 +1931,7 @@ a.button.width100 {
|
||||||
width: 100px;
|
width: 100px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.div-tracker-labels {
|
.div-filter-labels {
|
||||||
margin: 2px 13px 2px 0px;
|
margin: 2px 13px 2px 0px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
# -*- encoding : utf-8 -*-
|
# -*- encoding : utf-8 -*-
|
||||||
class Projects::ProjectsController < Projects::BaseController
|
class Projects::ProjectsController < Projects::BaseController
|
||||||
|
include ProjectsHelper
|
||||||
before_filter :authenticate_user!
|
before_filter :authenticate_user!
|
||||||
load_and_authorize_resource :id_param => :project_name # to force member actions load
|
load_and_authorize_resource :id_param => :project_name # to force member actions load
|
||||||
|
|
||||||
|
@ -7,8 +8,17 @@ class Projects::ProjectsController < Projects::BaseController
|
||||||
@projects = Project.accessible_by(current_ability, :membered)
|
@projects = Project.accessible_by(current_ability, :membered)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { @projects = @projects.recent.paginate(:page => params[:page], :per_page => 25) }
|
format.html {
|
||||||
format.json { @projects = prepare_list(@projects) }
|
@all_projects = @projects
|
||||||
|
@groups = current_user.groups
|
||||||
|
@owners = User.where(:id => @projects.where(:owner_type => 'User').uniq.pluck(:owner_id))
|
||||||
|
@projects = @projects.recent.paginate(:page => params[:page], :per_page => 25)
|
||||||
|
}
|
||||||
|
format.json {
|
||||||
|
selected_groups = params[:groups] || []
|
||||||
|
selected_owners = params[:users] || []
|
||||||
|
@projects = prepare_list(@projects, selected_groups, selected_owners)
|
||||||
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -99,7 +109,7 @@ class Projects::ProjectsController < Projects::BaseController
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def prepare_list(projects)
|
def prepare_list(projects, groups, owners)
|
||||||
res = {}
|
res = {}
|
||||||
|
|
||||||
colName = ['name']
|
colName = ['name']
|
||||||
|
@ -108,7 +118,13 @@ class Projects::ProjectsController < Projects::BaseController
|
||||||
order = "#{colName[sort_col.to_i]} #{sort_dir}"
|
order = "#{colName[sort_col.to_i]} #{sort_dir}"
|
||||||
|
|
||||||
res[:total_count] = projects.count
|
res[:total_count] = projects.count
|
||||||
|
|
||||||
|
if groups.present? || owners.present?
|
||||||
|
projects = projects.by_owners(groups, owners)
|
||||||
|
end
|
||||||
|
|
||||||
projects = projects.search(params[:sSearch]).search_order if params[:sSearch].present?
|
projects = projects.search(params[:sSearch]).search_order if params[:sSearch].present?
|
||||||
|
|
||||||
res[:filtered_count] = projects.count
|
res[:filtered_count] = projects.count
|
||||||
|
|
||||||
projects = projects.order(order)
|
projects = projects.order(order)
|
||||||
|
|
|
@ -5,7 +5,7 @@ class Projects::PullRequestsController < Projects::BaseController
|
||||||
load_resource :project
|
load_resource :project
|
||||||
|
|
||||||
load_and_authorize_resource :issue, :through => :project, :find_by => :serial_id, :parent => false, :except => :autocomplete_base_project
|
load_and_authorize_resource :issue, :through => :project, :find_by => :serial_id, :parent => false, :except => :autocomplete_base_project
|
||||||
before_filter :load_pull, :except => :autocomplete_base_project
|
load_resource :instance_name => :pull, :through => :issue, :singleton => true
|
||||||
|
|
||||||
def new
|
def new
|
||||||
base_project = (Project.find(params[:base_project_id]) if params[:base_project_id]) || @project.root
|
base_project = (Project.find(params[:base_project_id]) if params[:base_project_id]) || @project.root
|
||||||
|
@ -131,12 +131,6 @@ class Projects::PullRequestsController < Projects::BaseController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_pull
|
|
||||||
if params[:action].to_sym != :index
|
|
||||||
@pull = @project.pull_requests.where(:issue_id => @issue.id).first
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_diff_commits_data
|
def load_diff_commits_data
|
||||||
repo = Grit::Repo.new(@pull.path)
|
repo = Grit::Repo.new(@pull.path)
|
||||||
@base_commit = @pull.common_ancestor
|
@base_commit = @pull.common_ancestor
|
||||||
|
|
|
@ -1,5 +1,25 @@
|
||||||
# -*- encoding : utf-8 -*-
|
# -*- encoding : utf-8 -*-
|
||||||
module ProjectsHelper
|
module ProjectsHelper
|
||||||
|
def options_for_filters(all_projects, groups, owners)
|
||||||
|
projects_count_by_groups = all_projects.where(:owner_id => groups, :owner_type => 'Group').
|
||||||
|
group(:owner_id).count
|
||||||
|
projects_count_by_owners = all_projects.where(:owner_id => owners, :owner_type => 'User').
|
||||||
|
group(:owner_id).count
|
||||||
|
(groups + owners).map do |o|
|
||||||
|
class_name = o.class.name
|
||||||
|
{
|
||||||
|
:id => "#{class_name.downcase}-#{o.id}",
|
||||||
|
:color => '0054a6',
|
||||||
|
:selected => false,
|
||||||
|
:check_box_name => class_name.downcase.pluralize,
|
||||||
|
:check_box_value => o.id,
|
||||||
|
:name => content_tag(:div, content_tag(:span, o.uname, :class => class_name.downcase)),
|
||||||
|
:uname => o.uname, # only for sorting
|
||||||
|
:count => o.is_a?(User) ? projects_count_by_owners[o.id] : projects_count_by_groups[o.id]
|
||||||
|
}
|
||||||
|
end.sort_by{ |f| f[:uname] }
|
||||||
|
end
|
||||||
|
|
||||||
def git_repo_url(name)
|
def git_repo_url(name)
|
||||||
if current_user
|
if current_user
|
||||||
"#{request.protocol}#{current_user.uname}@#{request.host_with_port}/#{name}.git"
|
"#{request.protocol}#{current_user.uname}@#{request.host_with_port}/#{name}.git"
|
||||||
|
|
|
@ -116,17 +116,17 @@ class Ability
|
||||||
|
|
||||||
can :read, Issue, :project => {:owner_type => 'User', :owner_id => user.id}
|
can :read, Issue, :project => {:owner_type => 'User', :owner_id => user.id}
|
||||||
can :read, Issue, :project => {:owner_type => 'Group', :owner_id => user.group_ids}
|
can :read, Issue, :project => {:owner_type => 'Group', :owner_id => user.group_ids}
|
||||||
can(:read, Issue, read_relations_for('issues', 'projects')) {|issue| can? :read, issue.project rescue nil}
|
can([:read, :autocomplete_base_project], Issue, read_relations_for('issues', 'projects')) {|issue| can? :read, issue.project rescue nil}
|
||||||
can(:merge, Issue) {|issue| can? :write, issue.project}
|
can(:merge, Issue) {|issue| can? :write, issue.project}
|
||||||
can(:create, Issue) {|issue| can? :read, issue.project}
|
can(:create, Issue) {|issue| can? :read, issue.project}
|
||||||
can([:update, :destroy], Issue) {|issue| issue.user_id == user.id or local_admin?(issue.project)}
|
can([:update, :destroy], Issue) {|issue| issue.user_id == user.id or local_admin?(issue.project)}
|
||||||
cannot :manage, Issue, :project => {:has_issues => false} # switch off issues
|
cannot(:manage, Issue) {|issue| !issue.pull_request && !issue.project.has_issues? } # switch off issues
|
||||||
can(:autocomplete_base_project, Issue, read_relations_for('issues', 'projects')) {|issue| can? :read, issue.project rescue nil}
|
|
||||||
|
|
||||||
can(:create, Comment) {|comment| can? :read, comment.project}
|
can(:create, Comment) {|comment| can? :read, comment.project}
|
||||||
can(:update, Comment) {|comment| comment.user == user or comment.project.owner == user or local_admin?(comment.project)}
|
can(:update, Comment) {|comment| comment.user == user or comment.project.owner == user or local_admin?(comment.project)}
|
||||||
cannot :manage, Comment, :commentable_type => 'Issue', :commentable => {:project => {:has_issues => false}} # switch off issues
|
cannot :manage, Comment do |c|
|
||||||
|
c.commentable_type == 'Issue' && !c.project.has_issues && !c.commentable.pull_request # when switch off issues
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# Shared cannot rights for all users (registered, admin)
|
# Shared cannot rights for all users (registered, admin)
|
||||||
|
|
|
@ -50,6 +50,10 @@ class Project < ActiveRecord::Base
|
||||||
WHERE (ptr.repository_id = #{ repository_id })
|
WHERE (ptr.repository_id = #{ repository_id })
|
||||||
)
|
)
|
||||||
) }
|
) }
|
||||||
|
scope :by_owners, lambda { |group_owner_ids, user_owner_ids|
|
||||||
|
where("(projects.owner_id in (?) AND projects.owner_type = 'Group') OR (projects.owner_id in (?) AND projects.owner_type = 'User')", group_owner_ids, user_owner_ids)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
before_create :set_maintainer
|
before_create :set_maintainer
|
||||||
after_save :attach_to_personal_repository
|
after_save :attach_to_personal_repository
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
|
- is_group = owner.class == Group ? "(#{t 'activerecord.models.group'})" : ''
|
||||||
%p.center
|
%p.center
|
||||||
=t 'layout.projects.already_exists'
|
=t 'layout.projects.already_exists'
|
||||||
=link_to "#{@project.name_with_owner} #{is_group}", project_path(owner, @project.name)
|
=link_to "#{owner.uname}/#{@project.name} #{is_group}", project_path(owner, @project.name)
|
||||||
- else
|
- else
|
||||||
= form_for @project, :url => fork_project_path(@project), :html => { :class => :form, :multipart => true, :method => :post } do |f|
|
= form_for @project, :url => fork_project_path(@project), :html => { :class => :form, :multipart => true, :method => :post } do |f|
|
||||||
= hidden_field_tag :group, owner.id if owner.class == Group
|
= hidden_field_tag :group, owner.id if owner.class == Group
|
||||||
|
|
|
@ -3,16 +3,15 @@
|
||||||
#labels-stock
|
#labels-stock
|
||||||
=form_tag project_issues_path(@project), :id => 'filter_labels', :method => :get do
|
=form_tag project_issues_path(@project), :id => 'filter_labels', :method => :get do
|
||||||
- @project.labels.each_with_index do |label, index|
|
- @project.labels.each_with_index do |label, index|
|
||||||
.div-tracker-labels{:id => "label-#{label.name.parameterize}", :style => @labels.include?(label.name) ? "background-color:##{label.color};color:#FFF" : ''}
|
=render 'projects/shared/filter_label',
|
||||||
.div-label-left
|
:id => label.name.parameterize,
|
||||||
.label
|
:selected => @labels.include?(label.name),
|
||||||
.flag{:id => "flag-#{label.name.parameterize}", :style => "background-color: ##{label.color};"}
|
:extra_classes => 'div-tracker-labels',
|
||||||
.labeltext=label.name
|
:color => label.color,
|
||||||
=check_box_tag 'labels[]', label.name, @labels.include?(label.name), :style => 'display:none'
|
:check_box_name => 'labels',
|
||||||
.both
|
:check_box_value => label.name,
|
||||||
.div-label-right=Labeling.joins(:label).where(:labels => {:name => label.name, :project_id => @project.id}).count
|
:name => label.name,
|
||||||
.both
|
:count => Labeling.joins(:label).where(:labels => {:name => label.name, :project_id => @project.id}).count
|
||||||
.both
|
|
||||||
- if can? :write, @project
|
- if can? :write, @project
|
||||||
%a#manage-labels.button.tmargin10{:href => "#labels-stock"}=t('layout.issues.label_manage')
|
%a#manage-labels.button.tmargin10{:href => "#labels-stock"}=t('layout.issues.label_manage')
|
||||||
#labels-edit{:style => "display: none;"}
|
#labels-edit{:style => "display: none;"}
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
-content_for :sidebar do
|
||||||
|
- if current_user
|
||||||
|
=form_tag projects_path, :id => 'filter_projects', :method => :get do
|
||||||
|
.bordered.bpadding20
|
||||||
|
=tracker_search_field(:search, t('layout.find_project'))
|
||||||
|
- if can?(:create, Project)
|
||||||
|
.bordered.bpadding20
|
||||||
|
= link_to t('layout.projects.new'), new_project_path, :class => 'button'
|
||||||
|
.bordered.bpadding20
|
||||||
|
%h3=t('layout.relations.filters')
|
||||||
|
- options_for_filters(@all_projects, @groups, @owners).each do |options|
|
||||||
|
=render 'projects/shared/filter_label', options
|
|
@ -1,12 +1,8 @@
|
||||||
-set_meta_tags :title => t('layout.projects.list_header')
|
-set_meta_tags :title => t('layout.projects.list_header')
|
||||||
|
-render 'filters'
|
||||||
.toolbar
|
.toolbar
|
||||||
= link_to t('layout.projects.new'), new_project_path, :class => 'button' if can?(:create, Project)
|
-%w(user_owner group_owner user group).each do |el|
|
||||||
|
%span{:class => el}=t "layout.relations.#{el}"
|
||||||
.legend.rights
|
|
||||||
%span.user_owner= t("layout.relations.user_owner")
|
|
||||||
%span.group_owner= t("layout.relations.group_owner")
|
|
||||||
%span.user= t("layout.relations.user")
|
|
||||||
%span.group= t("layout.relations.group")
|
|
||||||
.both
|
.both
|
||||||
- columns = [{:type => 'html'},
|
- columns = [{:type => 'html'},
|
||||||
{:type => 'html', :sortable => false, :searchable => false},
|
{:type => 'html', :sortable => false, :searchable => false},
|
||||||
|
@ -29,15 +25,11 @@
|
||||||
%th.th2= t("activerecord.attributes.project.description")
|
%th.th2= t("activerecord.attributes.project.description")
|
||||||
%th.th3= t("layout.projects.role")
|
%th.th3= t("layout.projects.role")
|
||||||
%th.th4= t("layout.projects.remove_user")
|
%th.th4= t("layout.projects.remove_user")
|
||||||
%tr.search
|
|
||||||
%th{:colspan => 4}
|
|
||||||
<input class="gray" type="text" value="#{ t('layout.find_project') }">
|
|
||||||
|
|
||||||
%tbody= render :partial => 'projects/projects/project', :collection => @projects
|
%tbody= render :partial => 'projects/projects/project', :collection => @projects
|
||||||
|
|
||||||
:javascript
|
:javascript
|
||||||
$(document).ready(function() {
|
$(document).ready(function() {
|
||||||
|
var isUpdateDataTable = null;
|
||||||
var JsonParser = function (json) {
|
var JsonParser = function (json) {
|
||||||
|
|
||||||
var firstColumn = function(row) {
|
var firstColumn = function(row) {
|
||||||
|
@ -99,16 +91,17 @@
|
||||||
#{ format_columns_for_datatable(columns) }
|
#{ format_columns_for_datatable(columns) }
|
||||||
],
|
],
|
||||||
"fnServerData": function ( sSource, aoData, fnCallback ) {
|
"fnServerData": function ( sSource, aoData, fnCallback ) {
|
||||||
$.getJSON( sSource, aoData, function (json) {
|
if (isUpdateDataTable != null) { isUpdateDataTable.abort(); }
|
||||||
|
_.each($('#filter_projects').serializeArray(), function(dv) { aoData.push(dv); });
|
||||||
|
isUpdateDataTable = $.getJSON( sSource, aoData, function (json) {
|
||||||
json.aaData = JsonParser(json);
|
json.aaData = JsonParser(json);
|
||||||
fnCallback(json);
|
fnCallback(json);
|
||||||
} );
|
} );
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
$('#datatable_wrapper').append("<div class='both'></div>");
|
|
||||||
|
|
||||||
var $search = $('tr.search input[type="text"]');
|
var $search = $('#search');
|
||||||
$search.live('blur', function() {
|
$search.live('blur', function() {
|
||||||
$this = $(this);
|
$this = $(this);
|
||||||
if ($this.val() == '') {
|
if ($this.val() == '') {
|
||||||
|
@ -128,6 +121,9 @@
|
||||||
$search.live('keyup', function() {
|
$search.live('keyup', function() {
|
||||||
oTable.fnFilter(this.value);
|
oTable.fnFilter(this.value);
|
||||||
});
|
});
|
||||||
|
$(".div-filter-labels").live('click', function() {
|
||||||
|
oTable.dataTable().fnDraw();
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
=# will_paginate
|
=# will_paginate
|
||||||
|
|
|
@ -14,6 +14,6 @@
|
||||||
=render "projects/comments/add", :project => @project, :commentable => @issue if current_user
|
=render "projects/comments/add", :project => @project, :commentable => @issue if current_user
|
||||||
.pull_status
|
.pull_status
|
||||||
=render 'status'
|
=render 'status'
|
||||||
=render 'diff_commits_tabs' if @pull.status != 'already'
|
=render 'diff_commits_tabs' unless @pull.already?
|
||||||
=hidden_field_tag :preview_url, project_md_preview_path(@project)
|
=hidden_field_tag :preview_url, project_md_preview_path(@project)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
- extra_classes ||= ''
|
||||||
|
.div-filter-labels{:id => "label-#{id}", :class => extra_classes, :style => selected ? "background-color:##{color};color:#FFF" : ''}
|
||||||
|
.div-label-left
|
||||||
|
.label
|
||||||
|
.flag{:id => "flag-#{id}", :style => "background-color: ##{color};"}
|
||||||
|
.labeltext=name
|
||||||
|
=check_box_tag "#{check_box_name}[]", check_box_value, selected, :style => 'display:none'
|
||||||
|
.both
|
||||||
|
.div-label-right=count
|
||||||
|
.both
|
||||||
|
.both
|
|
@ -1,6 +1,7 @@
|
||||||
en:
|
en:
|
||||||
layout:
|
layout:
|
||||||
relations:
|
relations:
|
||||||
|
filters: Filters
|
||||||
user_owner: I'm owner
|
user_owner: I'm owner
|
||||||
group_owner: I'm member of owner group
|
group_owner: I'm member of owner group
|
||||||
user: I'm collaborator
|
user: I'm collaborator
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
ru:
|
ru:
|
||||||
layout:
|
layout:
|
||||||
relations:
|
relations:
|
||||||
|
filters: Фильтры
|
||||||
user_owner: Я - владелец
|
user_owner: Я - владелец
|
||||||
group_owner: Я состою в группе-владельце
|
group_owner: Я состою в группе-владельце
|
||||||
user: Я - участник
|
user: Я - участник
|
||||||
|
|
Loading…
Reference in New Issue