Skip to content
Snippets Groups Projects
Commit 6b3e3aeb authored by Phil Hughes's avatar Phil Hughes
Browse files

Sidebar details update when changing

Need to get working the subscription
Styling updates
parent 6cece3f4
No related branches found
No related tags found
No related merge requests found
Showing
with 254 additions and 49 deletions
Loading
Loading
@@ -5,6 +5,7 @@
//= require_tree ./stores
//= require_tree ./services
//= require_tree ./mixins
//= require_tree ./filters
//= require ./components/board
//= require ./components/board_sidebar
//= require ./components/new_list_dropdown
Loading
Loading
Loading
Loading
@@ -5,6 +5,9 @@
window.gl.issueBoards = window.gl.issueBoards || {};
 
gl.issueBoards.BoardSidebar = Vue.extend({
props: {
currentUser: Object
},
data() {
return {
detail: Store.detail,
Loading
Loading
@@ -26,9 +29,12 @@
issue () {
if (this.showSidebar) {
this.$nextTick(() => {
new IssuableContext();
new IssuableContext(this.currentUser);
new MilestoneSelect();
new DueDateSelect();
new LabelsSelect();
new Sidebar();
new Subscription('.subscription')
});
} else {
$('.right-sidebar').getNiceScroll().remove();
Loading
Loading
Vue.filter('due-date', (value) => {
const date = new Date(value.replace(new RegExp('-', 'g'), ','));
return $.datepicker.formatDate('M d, yy', date);
});
Loading
Loading
@@ -4,6 +4,7 @@ class ListIssue {
this.title = obj.title;
this.confidential = obj.confidential;
this.dueDate = obj.due_date;
this.subscribed = true;
this.labels = [];
 
if (obj.assignee) {
Loading
Loading
@@ -46,4 +47,17 @@ class ListIssue {
getLists () {
return gl.issueBoards.BoardsStore.state.lists.filter( list => list.findIssue(this.id) );
}
update (url) {
const data = {
issue: {
milestone_id: this.milestone ? this.milestone.id : null,
due_date: this.dueDate,
assignee_id: this.assignee ? this.assignee.id : null,
label_ids: this.labels.map((label) => label.id )
}
};
return Vue.http.patch(url, data);
}
}
class BoardService {
constructor (root) {
Vue.http.options.root = root;
this.lists = Vue.resource(`${root}/lists{/id}`, {}, {
generate: {
method: 'POST',
Loading
Loading
Loading
Loading
@@ -38,6 +38,19 @@
return $value.css('display', '');
}
});
var updateIssueBoardIssue = function () {
$dropdown.trigger('loading.gl.dropdown');
$selectbox.hide();
$value.css('display', '');
$loading.fadeIn();
gl.issueBoards.BoardsStore.detail.issue.update(issueUpdateURL)
.then(function () {
$loading.fadeOut();
});
}
addDueDate = function(isDropdown) {
var data, date, mediumDate, value;
// Create the post date
Loading
Loading
@@ -83,15 +96,25 @@
};
$block.on('click', '.js-remove-due-date', function(e) {
e.preventDefault();
$("input[name='" + fieldName + "']").val('');
return addDueDate(false);
if ($dropdown.hasClass('js-issue-boards-due-date')) {
gl.issueBoards.BoardsStore.detail.issue.dueDate = '';
updateIssueBoardIssue();
} else {
$("input[name='" + fieldName + "']").val('');
return addDueDate(false);
}
});
return $datePicker.datepicker({
dateFormat: 'yy-mm-dd',
defaultDate: $("input[name='" + fieldName + "']").val(),
altField: "input[name='" + fieldName + "']",
onSelect: function() {
return addDueDate(true);
if ($dropdown.hasClass('js-issue-boards-due-date')) {
gl.issueBoards.BoardsStore.detail.issue.dueDate = $("input[name='" + fieldName + "']").val();
updateIssueBoardIssue();
} else {
return addDueDate(true);
}
}
});
});
Loading
Loading
Loading
Loading
@@ -22,7 +22,7 @@
abilityName = $dropdown.data('ability-name');
$selectbox = $dropdown.closest('.selectbox');
$block = $selectbox.closest('.block');
$form = $dropdown.closest('form');
$form = $dropdown.closest('.js-issuable-update');
$sidebarCollapsedValue = $block.find('.sidebar-collapsed-icon span');
$sidebarLabelTooltip = $block.find('.js-sidebar-labels-tooltip');
$value = $block.find('.value');
Loading
Loading
@@ -334,7 +334,7 @@
page = $('body').data('page');
isIssueIndex = page === 'projects:issues:index';
isMRIndex = page === 'projects:merge_requests:index';
if (page === 'projects:boards:show') {
if (page === 'projects:boards:show' && !$dropdown.hasClass('js-issue-boards-label')) {
if (label.isAny) {
gl.issueBoards.BoardsStore.state.filters['label_name'] = [];
}
Loading
Loading
@@ -362,6 +362,30 @@
else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
}
else if ($dropdown.hasClass('js-issue-boards-label')) {
if ($el.hasClass('is-active')) {
gl.issueBoards.BoardsStore.detail.issue.labels.push(new ListLabel({
id: label.id,
title: label.title,
color: label.color[0],
textColor: '#fff'
}));
}
else {
var labels = gl.issueBoards.BoardsStore.detail.issue.labels;
labels = labels.filter(function (selectedLabel) {
return selectedLabel.id !== label.id;
});
gl.issueBoards.BoardsStore.detail.issue.labels = labels;
}
$loading.fadeIn();
gl.issueBoards.BoardsStore.detail.issue.update(issueUpdateURL)
.then(function () {
$loading.fadeOut();
});
}
else {
if ($dropdown.hasClass('js-multiselect')) {
 
Loading
Loading
Loading
Loading
@@ -110,7 +110,7 @@
e.preventDefault();
return;
}
if (page === 'projects:boards:show') {
if (page === 'projects:boards:show' && !$dropdown.hasClass('js-issue-board-sidebar')) {
gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = selected.name;
gl.issueBoards.BoardsStore.updateFiltersUrl();
e.preventDefault();
Loading
Loading
@@ -123,6 +123,24 @@
return Issuable.filterResults($dropdown.closest('form'));
} else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
} else if ($dropdown.hasClass('js-issue-board-sidebar')) {
if (selected.id !== -1) {
Vue.set(gl.issueBoards.BoardsStore.detail.issue, 'milestone', new ListMilestone({
id: selected.id,
title: selected.name
}));
} else {
Vue.delete(gl.issueBoards.BoardsStore.detail.issue, 'milestone');
}
$dropdown.trigger('loading.gl.dropdown');
$loading.fadeIn();
gl.issueBoards.BoardsStore.detail.issue.update(issueUpdateURL)
.then(function () {
$dropdown.trigger('loaded.gl.dropdown');
$loading.fadeOut();
});
} else {
selected = $selectbox.find('input[type="hidden"]').val();
data = {};
Loading
Loading
Loading
Loading
@@ -22,13 +22,18 @@
return function() {
var status;
btn.removeClass('disabled');
status = current_status === 'subscribed' ? 'unsubscribed' : 'subscribed';
_this.subscription_status.attr('data-status', status);
action = status === 'subscribed' ? 'Unsubscribe' : 'Subscribe';
btn.find('span').text(action);
_this.subscription_status.find('>div').toggleClass('hidden');
if (btn.attr('data-original-title')) {
return btn.tooltip('hide').attr('data-original-title', action).tooltip('fixTitle');
if ($('body').data('page') === 'projects:boards:show') {
Vue.set(gl.issueBoards.BoardsStore.detail.issue, 'subscribed', !gl.issueBoards.BoardsStore.detail.issue.subscribed);
} else {
status = current_status === 'subscribed' ? 'unsubscribed' : 'subscribed';
_this.subscription_status.attr('data-status', status);
action = status === 'subscribed' ? 'Unsubscribe' : 'Subscribe';
btn.find('span').text(action);
_this.subscription_status.find('>div').toggleClass('hidden');
if (btn.attr('data-original-title')) {
return btn.tooltip('hide').attr('data-original-title', action).tooltip('fixTitle');
}
}
};
})(this));
Loading
Loading
Loading
Loading
@@ -9,7 +9,11 @@
this.usersPath = "/autocomplete/users.json";
this.userPath = "/autocomplete/users/:id.json";
if (currentUser != null) {
this.currentUser = JSON.parse(currentUser);
if (typeof currentUser === 'object') {
this.currentUser = currentUser;
} else {
this.currentUser = JSON.parse(currentUser);
}
}
$('.js-user-search').each((function(_this) {
return function(i, dropdown) {
Loading
Loading
@@ -32,9 +36,30 @@
$value = $block.find('.value');
$collapsedSidebar = $block.find('.sidebar-collapsed-user');
$loading = $block.find('.block-loading').fadeOut();
var updateIssueBoardsIssue = function () {
$loading.fadeIn();
gl.issueBoards.BoardsStore.detail.issue.update(issueURL)
.then(function () {
$loading.fadeOut();
});
};
$block.on('click', '.js-assign-yourself', function(e) {
e.preventDefault();
return assignTo(_this.currentUser.id);
if ($dropdown.hasClass('js-issue-board-assignee')) {
Vue.set(gl.issueBoards.BoardsStore.detail.issue, 'assignee', new ListUser({
id: _this.currentUser.id,
username: _this.currentUser.username,
name: _this.currentUser.name,
avatar_url: _this.currentUser.avatar_url
}));
updateIssueBoardsIssue();
} else {
return assignTo(_this.currentUser.id);
}
});
assignTo = function(selected) {
var data;
Loading
Loading
@@ -160,7 +185,7 @@
selectedId = user.id;
return;
}
if (page === 'projects:boards:show') {
if (page === 'projects:boards:show' && !$dropdown.hasClass('js-issue-board-assignee')) {
selectedId = user.id;
gl.issueBoards.BoardsStore.state.filters[$dropdown.data('field-name')] = user.id;
gl.issueBoards.BoardsStore.updateFiltersUrl();
Loading
Loading
@@ -170,6 +195,19 @@
return Issuable.filterResults($dropdown.closest('form'));
} else if ($dropdown.hasClass('js-filter-submit')) {
return $dropdown.closest('form').submit();
} else if ($dropdown.hasClass('js-issue-board-assignee')) {
if (user.id) {
Vue.set(gl.issueBoards.BoardsStore.detail.issue, 'assignee', new ListUser({
id: user.id,
username: user.username,
name: user.name,
avatar_url: user.avatar_url
}));
} else {
Vue.delete(gl.issueBoards.BoardsStore.detail.issue, 'assignee');
}
updateIssueBoardsIssue();
} else {
selected = $dropdown.closest('.selectbox').find("input[name='" + ($dropdown.data('field-name')) + "']").val();
return assignTo(selected);
Loading
Loading
Loading
Loading
@@ -46,6 +46,15 @@ lex
.page-with-sidebar {
padding-bottom: 0;
}
.issues-filters {
position: relative;
z-index: 999999;
}
}
.boards-app {
position: relative;
}
 
.boards-app-loading {
Loading
Loading
@@ -265,3 +274,9 @@ lex
border-width: 1px 0 1px 1px;
}
}
.right-sidebar.issue-boards-sidebar {
position: absolute;
top: 0;
bottom: 0;
}
%board-sidebar{ "inline-template" => true }
%aside.right-sidebar.right-sidebar-expanded{ "v-if" => "showSidebar" }
%board-sidebar{ "inline-template" => true,
":current-user" => "#{current_user.to_json(only: [:username, :id, :name], methods: [:avatar_url]) if current_user}" }
%aside.right-sidebar.right-sidebar-expanded.issue-boards-sidebar{ "v-if" => "showSidebar" }
.issuable-sidebar
.block.issuable-sidebar-header
%span.issuable-header-text.hide-collapsed.pull-left
Loading
Loading
@@ -14,8 +15,9 @@
"@click" => "closeSidebar",
aria: { label: "Toggle sidebar" } }
= icon("times")
= render "projects/boards/components/sidebar/assignee"
= render "projects/boards/components/sidebar/milestone"
= render "projects/boards/components/sidebar/due_date"
= render "projects/boards/components/sidebar/labels"
= render "projects/boards/components/sidebar/notifications"
.js-issuable-update
= render "projects/boards/components/sidebar/assignee"
= render "projects/boards/components/sidebar/milestone"
= render "projects/boards/components/sidebar/due_date"
= render "projects/boards/components/sidebar/labels"
= render "projects/boards/components/sidebar/notifications"
Loading
Loading
@@ -20,3 +20,21 @@
%span.username
= precede "@" do
{{ issue.assignee.username }}
- if can?(current_user, :admin_issue, @project)
.selectbox.hide-collapsed
%input{ type: "hidden",
name: "issue[assignee_id]",
id: "issue_assignee_id",
":value" => "issue.assignee.id",
"v-if" => "issue.assignee" }
.dropdown
%button.dropdown-menu-toggle.js-user-search.js-author-search.js-issue-board-assignee{ data: { toggle: "dropdown", field_name: "issue[assignee_id]", first_user: (current_user.username if current_user), current_user: "true", project_id: @project.id, field_name: "issue[assignee_id]", null_user: "true" },
":data-issuable-id" => "issue.id",
":data-issue-update" => "'/root/issue-boards/issues/' + issue.id + '.json'" }
Select assignee
= icon("chevron-down")
.dropdown-menu.dropdown-menu-user.dropdown-menu-selectable.dropdown-menu-author
= dropdown_title("Assign to")
= dropdown_filter("Search users")
= dropdown_content
= dropdown_loading
.block.due_date
.title.hide-collapsed
.title
Due date
= icon("spinner spin", class: "block-loading")
- if can?(current_user, :admin_issue, @project)
= link_to "Edit", "#", class: "edit-link pull-right"
.value.hide-collapsed
.value
.value-content
%span.no-value{ "v-if" => "!issue.dueDate" }
No due date
%span.bold{ "v-if" => "issue.dueDate" }
{{ issue.dueDate }}
{{ issue.dueDate | due-date }}
%span.no-value.js-remove-due-date-holder{ "v-if" => "issue.dueDate" }
\-
%a.js-remove-due-date{ href: "#", role: "button" }
remove due date
- if can?(current_user, :admin_issue, @project)
.selectbox
%input{ type: "hidden",
name: "issue[due_date]",
":value" => "issue.dueDate" }
.dropdown
%button.dropdown-menu-toggle.js-due-date-select.js-issue-boards-due-date{ type: 'button',
data: { toggle: 'dropdown', field_name: "issue[due_date]", ability_name: "issue" },
":data-issue-update" => "'/root/issue-boards/issues/' + issue.id + '.json'" }
%span.dropdown-toggle-text Due date
= icon('chevron-down')
.dropdown-menu.dropdown-menu-due-date
= dropdown_title('Due date')
= dropdown_content do
.js-due-date-calendar
.block.labels
.title.hide-collapsed
.title
Labels
= icon("spinner spin", class: "block-loading")
- if can?(current_user, :admin_issue, @project)
= link_to "Edit", "#", class: "edit-link pull-right"
.value.issuable-show-labels.hide-collapsed
.value.issuable-show-labels
%span.no-value{ "v-if" => "issue.labels.length === 0" }
None
%a{ href: "#",
"v-for" => "label in issue.labels" }
%span.label.color-label.has-tooltip{ ":style" => "{ backgroundColor: label.color, color: label.textColor }" }
{{ label.title }}
.selectbox.hide-collapsed
%input{ type: "hidden",
name: "issue[label_names][]",
"v-for" => "label in issue.labels",
":value" => "label.id" }
- if can?(current_user, :admin_issue, @project)
.selectbox
%input{ type: "hidden",
name: "issue[label_names][]",
"v-for" => "label in issue.labels",
":value" => "label.id" }
.dropdown
%button.dropdown-menu-toggle.js-label-select.js-multiselect.js-issue-boards-label{ type: "button",
data: { toggle: "dropdown", field_name: "issue[label_names][]", show_no: "true", show_any: "true", project_id: @project.id, labels: namespace_project_labels_path(@project.namespace, @project, :json) },
":data-issue-update" => "'/root/issue-boards/issues/' + issue.id + '.json'" }
%span.dropdown-toggle-text
Label
= icon('chevron-down')
.dropdown-menu.dropdown-select.dropdown-menu-paging.dropdown-menu-labels.dropdown-menu-selectable
= render partial: "shared/issuable/label_page_default"
- if can? current_user, :admin_label, @project and @project
= render partial: "shared/issuable/label_page_create"
.block.milestone
.title.hide-collapsed
.title
Milestone
= icon("spinner spin", class: "block-loading")
- if can?(current_user, :admin_issue, @project)
Loading
Loading
@@ -9,8 +9,20 @@
None
%span.bold.has-tooltip{ "v-if" => "issue.milestone" }
{{ issue.milestone.title }}
.selectbox
.dropdown
%button.dropdown-menu-toggle
Milestone
-# = dropdown_tag('Milestone', options: { title: 'Assign milestone', toggle_class: 'js-milestone-select js-extra-options', filter: true, dropdown_class: 'dropdown-menu-selectable', placeholder: 'Search milestones', data: { show_no: true, field_name: "issue[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: "issue", use_id: true }})
- if can?(current_user, :admin_issue, @project)
.selectbox
%input{ type: "hidden",
":value" => "issue.milestone.id",
name: "issue[milestone_id]",
"v-if" => "issue.milestone" }
.dropdown
%button.dropdown-menu-toggle.js-milestone-select.js-issue-board-sidebar{ data: { toggle: "dropdown", show_no: "true", field_name: "issue[milestone_id]", project_id: @project.id, milestones: namespace_project_milestones_path(@project.namespace, @project, :json), ability_name: "issue", use_id: "true" },
":data-issuable-id" => "issue.id",
":data-issue-update" => "'/root/issue-boards/issues/' + issue.id + '.json'" }
Milestone
= icon("chevron-down")
.dropdown-menu.dropdown-select.dropdown-menu-selectable
= dropdown_title("Assignee milestone")
= dropdown_filter("Search milestones")
= dropdown_content
= dropdown_loading
- if current_user
.block.light.subscription{ data: { url: '' } }
.title.hide-collapsed
.block.light.subscription{ ":data-url" => "'#{namespace_project_issues_path(@project.namespace, @project)}/' + issue.id + '/toggle_subscription'" }
.title
Notifications
%button.btn.btn-block.btn-default.js-subscribe-button.issuable-subscribe-button.hide-collapsed{ type: "button" }
Unsubscribe
.subscription-status.hide-collapsed{ data: { status: '' } }
.unsubscribed{class: ( 'hidden' if true )}
{{ issue.subscribed ? 'Unsubscribe' : 'Subscribe' }}
.subscription-status{ ":data-status" => "issue.subscribed ? 'subscribed' : 'unsubscribed'" }
.unsubscribed{ "v-show" => "!issue.subscribed" }
You're not receiving notifications from this thread.
.subscribed{class: ( 'hidden' unless true )}
.subscribed{ "v-show" => "issue.subscribed" }
You're receiving notifications because you're subscribed to this thread.
Loading
Loading
@@ -10,7 +10,7 @@
 
= render 'shared/issuable/filter', type: :boards
 
#board-app{ "v-cloak" => true,
#board-app.boards-app{ "v-cloak" => true,
"data-endpoint" => "#{namespace_project_board_path(@project.namespace, @project)}",
"data-disabled" => "#{!can?(current_user, :admin_list, @project)}",
"data-issue-link-base" => "#{namespace_project_issues_path(@project.namespace, @project)}" }
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment