client/tags: add setting default tag category

This commit is contained in:
rr- 2016-05-22 18:50:27 +02:00
parent 77998f1660
commit 7aaa28f9de
5 changed files with 110 additions and 63 deletions

View file

@ -29,5 +29,6 @@ $button-disabled-text-color = #666
$button-disabled-background-color = #CCC
$new-tag-background-color = #DFC
$new-tag-text-color = black
$default-tag-category-background-color = $active-tab-background-color
$duplicate-tag-background-color = #FDC
$duplicate-tag-text-color = black

View file

@ -57,23 +57,20 @@
.content-wrapper.tag-categories
width: 100%
max-width: 35em
max-width: 40em
table
border-spacing: 0
width: 100%
tr.default td
background: $default-tag-category-background-color
td, th
padding: .2em
&:first-child
padding-left: 0
&:last-child
padding-right: 0
&.name
width: 35%
padding: .4em
&.color
text-align: center
width: 35%
&.usages
text-align: center
width: 10%
&.remove, &.set-default
white-space: pre
tfoot
display: none
.messages, form

View file

@ -11,7 +11,11 @@
</thead>
<tbody>
<% _.each(ctx.tagCategories, category => { %>
<% if (category.default) { %>
<tr data-category='<%= category.name %>' class='default'>
<% } else { %>
<tr data-category='<%= category.name %>'>
<% } %>
<td class='name'>
<% if (ctx.canEditName) { %>
<%= ctx.makeTextInput({value: category.name, required: true}) %>
@ -32,14 +36,19 @@
</a>
</td>
<% if (ctx.canDelete) { %>
<td>
<td class='remove'>
<% if (category.usages) { %>
<a class='inactive remove' title="Can't delete category in use">Remove</a>
<a class='inactive' title="Can't delete category in use">Remove</a>
<% } else { %>
<a href='#' class='remove'>Remove</a>
<a href='#'>Remove</a>
<% } %>
</td>
<% } %>
<% if (ctx.canSetDefault) { %>
<td class='set-default'>
<a href='#'>Make default</a>
</td>
<% } %>
</tr>
<% }) %>
</tbody>
@ -54,8 +63,11 @@
<td class='usages'>
0
</td>
<td>
<a href='#' class='remove'>Remove</a>
<td class='remove'>
<a href='#'>Remove</a>
</td>
<td class='set-default'>
<a href='#'>Make default</a>
</td>
</tr>
</tfoot>

View file

@ -42,7 +42,11 @@ class TagsController {
(ctx, next) => { this._listTagsRoute(ctx, next); });
}
_saveTagCategories(addedCategories, changedCategories, removedCategories) {
_saveTagCategories(
addedCategories,
changedCategories,
removedCategories,
defaultCategory) {
let promises = [];
for (let category of addedCategories) {
promises.push(api.post('/tag-categories/', category));
@ -54,7 +58,18 @@ class TagsController {
for (let name of removedCategories) {
promises.push(api.delete('/tag-category/' + name));
}
Promise.all(promises).then(
Promise.all(promises)
.then(
() => {
if (!defaultCategory) {
return Promise.resolve();
}
return api.put(
'/tag-category/' + defaultCategory + '/default');
}, response => {
return Promise.reject(response);
})
.then(
() => {
events.notify(events.TagsChange);
events.notify(events.Success, 'Changes saved.');
@ -165,6 +180,7 @@ class TagsController {
canEditColor: api.hasPrivilege('tagCategories:edit:color'),
canDelete: api.hasPrivilege('tagCategories:delete'),
canCreate: api.hasPrivilege('tagCategories:create'),
canSetDefault: api.hasPrivilege('tagCategories:setDefault'),
saveChanges: (...args) => {
return this._saveTagCategories(...args);
},

View file

@ -8,7 +8,41 @@ class TagListHeaderView {
this._template = views.getTemplate('tag-categories');
}
_saveButtonClickHandler(e, ctx, target) {
render(ctx) {
const target = document.getElementById('content-holder');
const source = this._template(ctx);
const form = source.querySelector('form');
const newRowTemplate = source.querySelector('.add-template');
const tableBody = source.querySelector('tbody');
const addLink = source.querySelector('a.add');
const saveButton = source.querySelector('button.save');
newRowTemplate.parentNode.removeChild(newRowTemplate);
views.decorateValidator(form);
for (let row of tableBody.querySelectorAll('tr')) {
this._addRowHandlers(row);
}
if (addLink) {
addLink.addEventListener('click', e => {
e.preventDefault();
let newRow = newRowTemplate.cloneNode(true);
tableBody.appendChild(newRow);
this._addRowHandlers(row);
});
}
form.addEventListener('submit', e => {
this._evtSaveButtonClick(e, ctx, target);
});
views.listenToMessages(source);
views.showView(target, source);
}
_evtSaveButtonClick(e, ctx, target) {
e.preventDefault();
views.clearMessages(target);
@ -20,6 +54,7 @@ class TagListHeaderView {
existingCategories[category.name] = category;
}
let defaultCategory = null;
let addedCategories = [];
let removedCategories = [];
let changedCategories = [];
@ -31,6 +66,9 @@ class TagListHeaderView {
name: row.querySelector('.name input').value,
color: row.querySelector('.color input').value,
};
if (row.classList.contains('default')) {
defaultCategory = category.name;
}
if (!name) {
if (category.name) {
addedCategories.push(category);
@ -50,11 +88,14 @@ class TagListHeaderView {
}
}
ctx.saveChanges(
addedCategories, changedCategories, removedCategories);
addedCategories,
changedCategories,
removedCategories,
defaultCategory);
});
}
_removeButtonClickHandler(e, row, link) {
_evtRemoveButtonClick(e, row, link) {
e.preventDefault();
if (link.classList.contains('inactive')) {
return;
@ -62,47 +103,27 @@ class TagListHeaderView {
row.parentNode.removeChild(row);
}
_addRemoveButtonClickHandler(row) {
const link = row.querySelector('a.remove');
if (!link) {
return;
}
link.addEventListener(
'click', e => this._removeButtonClickHandler(e, row, link));
}
render(ctx) {
const target = document.getElementById('content-holder');
const source = this._template(ctx);
const form = source.querySelector('form');
const newRowTemplate = source.querySelector('.add-template');
const tableBody = source.querySelector('tbody');
const addLink = source.querySelector('a.add');
const saveButton = source.querySelector('button.save');
newRowTemplate.parentNode.removeChild(newRowTemplate);
views.decorateValidator(form);
for (let row of tableBody.querySelectorAll('tr')) {
this._addRemoveButtonClickHandler(row);
}
if (addLink) {
addLink.addEventListener('click', e => {
_evtSetDefaultButtonClick(e, row) {
e.preventDefault();
let newRow = newRowTemplate.cloneNode(true);
tableBody.appendChild(newRow);
this._addRemoveButtonClickHandler(newRow);
});
const oldRowNode = row.parentNode.querySelector('tr.default');
if (oldRowNode) {
oldRowNode.classList.remove('default');
}
row.classList.add('default');
}
form.addEventListener('submit', e => {
this._saveButtonClickHandler(e, ctx, target);
});
_addRowHandlers(row) {
const removeLink = row.querySelector('.remove a');
if (removeLink) {
removeLink.addEventListener(
'click', e => this._evtRemoveButtonClick(e, row, removeLink));
}
views.listenToMessages(source);
views.showView(target, source);
const defaultLink = row.querySelector('.set-default a');
if (defaultLink) {
defaultLink.addEventListener(
'click', e => this._evtSetDefaultButtonClick(e, row));
}
}
}