client: rename 'mass tag' to 'bulk edit tags'
That way other bulk operations will be easier to name. This also changes the privilege name.
This commit is contained in:
parent
eda6d6d02a
commit
0e4e994431
8 changed files with 67 additions and 58 deletions
|
@ -17,6 +17,8 @@ form
|
||||||
.input li:first-child
|
.input li:first-child
|
||||||
padding-top: 0
|
padding-top: 0
|
||||||
margin-top: 0
|
margin-top: 0
|
||||||
|
|
||||||
|
form:not(.horizontal)
|
||||||
.hint
|
.hint
|
||||||
margin-top: 0.2em
|
margin-top: 0.2em
|
||||||
margin-bottom: 0
|
margin-bottom: 0
|
||||||
|
|
|
@ -54,7 +54,7 @@
|
||||||
.icon:not(:first-of-type)
|
.icon:not(:first-of-type)
|
||||||
margin-left: 1em
|
margin-left: 1em
|
||||||
|
|
||||||
.masstag
|
.tag-flipper
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 0.5em
|
top: 0.5em
|
||||||
left: 0.5em
|
left: 0.5em
|
||||||
|
@ -117,24 +117,24 @@
|
||||||
margin-right: 0.25em
|
margin-right: 0.25em
|
||||||
input[name=search-text]
|
input[name=search-text]
|
||||||
width: 25em
|
width: 25em
|
||||||
input[name=masstag]
|
|
||||||
width: 12em
|
|
||||||
.masstag-hint, .open-masstag
|
|
||||||
margin-right: 1em
|
|
||||||
.append
|
.append
|
||||||
font-size: 0.95em
|
font-size: 0.95em
|
||||||
color: $inactive-link-color
|
color: $inactive-link-color
|
||||||
.masstag
|
.bulk-edit-tags
|
||||||
&:not(.active)
|
&:not(.active)
|
||||||
[type=text],
|
[type=text],
|
||||||
.start-tagging,
|
.start-tagging,
|
||||||
.stop-tagging
|
.stop-tagging
|
||||||
display: none
|
display: none
|
||||||
.masstag-hint
|
.hint
|
||||||
display: none
|
display: none
|
||||||
&.active
|
&.active
|
||||||
.open-masstag
|
.open
|
||||||
display: none
|
display: none
|
||||||
|
input[name=tag]
|
||||||
|
width: 12em
|
||||||
|
.hint, .open
|
||||||
|
margin-right: 1em
|
||||||
|
|
||||||
.safety
|
.safety
|
||||||
margin-right: 0.25em
|
margin-right: 0.25em
|
||||||
|
|
|
@ -9,13 +9,13 @@
|
||||||
%><input data-safety=unsafe type='button' class='mousetrap safety safety-unsafe <%- ctx.settings.listPosts.unsafe ? '' : 'disabled' %>'/><%
|
%><input data-safety=unsafe type='button' class='mousetrap safety safety-unsafe <%- ctx.settings.listPosts.unsafe ? '' : 'disabled' %>'/><%
|
||||||
%><wbr/><%
|
%><wbr/><%
|
||||||
%><a class='mousetrap button append' href='<%- ctx.formatClientLink('help', 'search', 'posts') %>'>Syntax help</a><%
|
%><a class='mousetrap button append' href='<%- ctx.formatClientLink('help', 'search', 'posts') %>'>Syntax help</a><%
|
||||||
%><% if (ctx.canMassTag) { %><%
|
%><% if (ctx.canBulkEditTags) { %><%
|
||||||
%><wbr/><%
|
%><wbr/><%
|
||||||
%><span class='masstag'><%
|
%><span class='bulk-edit-tags'><%
|
||||||
%><span class='append masstag-hint'>Tagging with:</span><%
|
%><span class='append hint'>Tagging with:</span><%
|
||||||
%><a href class='mousetrap button append open-masstag'>Mass tag</a><%
|
%><a href class='mousetrap button append open'>Mass tag</a><%
|
||||||
%><wbr/><%
|
%><wbr/><%
|
||||||
%><%= ctx.makeTextInput({name: 'masstag', value: ctx.parameters.tag}) %><%
|
%><%= ctx.makeTextInput({name: 'tag', value: ctx.parameters.tag}) %><%
|
||||||
%><input class='mousetrap start-tagging' type='submit' value='Start tagging'/><%
|
%><input class='mousetrap start-tagging' type='submit' value='Start tagging'/><%
|
||||||
%><a href class='mousetrap button append stop-tagging'>Stop tagging</a><%
|
%><a href class='mousetrap button append stop-tagging'>Stop tagging</a><%
|
||||||
%></span><%
|
%></span><%
|
||||||
|
|
|
@ -33,8 +33,8 @@
|
||||||
</span>
|
</span>
|
||||||
<% } %>
|
<% } %>
|
||||||
</a>
|
</a>
|
||||||
<% if (ctx.canMassTag && ctx.parameters && ctx.parameters.tag) { %>
|
<% if (ctx.canBulkEditTags && ctx.parameters && ctx.parameters.tag) { %>
|
||||||
<a href data-post-id='<%= post.id %>' class='masstag'>
|
<a href data-post-id='<%= post.id %>' class='tag-flipper'>
|
||||||
</a>
|
</a>
|
||||||
<% } %>
|
<% } %>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -31,8 +31,10 @@ class PostListController {
|
||||||
this._headerView = new PostsHeaderView({
|
this._headerView = new PostsHeaderView({
|
||||||
hostNode: this._pageController.view.pageHeaderHolderNode,
|
hostNode: this._pageController.view.pageHeaderHolderNode,
|
||||||
parameters: ctx.parameters,
|
parameters: ctx.parameters,
|
||||||
canMassTag: api.hasPrivilege('tags:masstag'),
|
canBulkEditTags: api.hasPrivilege('posts:bulkEdit:tags'),
|
||||||
massTagTags: this._massTagTags,
|
bulkEdit: {
|
||||||
|
tags: this._bulkEditTags
|
||||||
|
},
|
||||||
});
|
});
|
||||||
this._headerView.addEventListener(
|
this._headerView.addEventListener(
|
||||||
'navigate', e => this._evtNavigate(e));
|
'navigate', e => this._evtNavigate(e));
|
||||||
|
@ -44,7 +46,7 @@ class PostListController {
|
||||||
this._pageController.showSuccess(message);
|
this._pageController.showSuccess(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
get _massTagTags() {
|
get _bulkEditTags() {
|
||||||
return (this._ctx.parameters.tag || '').split(/\s+/).filter(s => s);
|
return (this._ctx.parameters.tag || '').split(/\s+/).filter(s => s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,14 +60,14 @@ class PostListController {
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtTag(e) {
|
_evtTag(e) {
|
||||||
for (let tag of this._massTagTags) {
|
for (let tag of this._bulkEditTags) {
|
||||||
e.detail.post.addTag(tag);
|
e.detail.post.addTag(tag);
|
||||||
}
|
}
|
||||||
e.detail.post.save().catch(error => window.alert(error.message));
|
e.detail.post.save().catch(error => window.alert(error.message));
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtUntag(e) {
|
_evtUntag(e) {
|
||||||
for (let tag of this._massTagTags) {
|
for (let tag of this._bulkEditTags) {
|
||||||
e.detail.post.removeTag(tag);
|
e.detail.post.removeTag(tag);
|
||||||
}
|
}
|
||||||
e.detail.post.save().catch(error => window.alert(error.message));
|
e.detail.post.save().catch(error => window.alert(error.message));
|
||||||
|
@ -103,8 +105,10 @@ class PostListController {
|
||||||
pageRenderer: pageCtx => {
|
pageRenderer: pageCtx => {
|
||||||
Object.assign(pageCtx, {
|
Object.assign(pageCtx, {
|
||||||
canViewPosts: api.hasPrivilege('posts:view'),
|
canViewPosts: api.hasPrivilege('posts:view'),
|
||||||
canMassTag: api.hasPrivilege('tags:masstag'),
|
canBulkEditTags: api.hasPrivilege('posts:bulkEdit:tags'),
|
||||||
massTagTags: this._massTagTags,
|
bulkEdit: {
|
||||||
|
tags: this._bulkEditTags,
|
||||||
|
},
|
||||||
});
|
});
|
||||||
const view = new PostsPageView(pageCtx);
|
const view = new PostsPageView(pageCtx);
|
||||||
view.addEventListener('tag', e => this._evtTag(e));
|
view.addEventListener('tag', e => this._evtTag(e));
|
||||||
|
|
|
@ -23,10 +23,6 @@ class PostsHeaderView extends events.EventTarget {
|
||||||
this._queryAutoCompleteControl = new TagAutoCompleteControl(
|
this._queryAutoCompleteControl = new TagAutoCompleteControl(
|
||||||
this._queryInputNode,
|
this._queryInputNode,
|
||||||
{addSpace: true, transform: misc.escapeSearchTerm});
|
{addSpace: true, transform: misc.escapeSearchTerm});
|
||||||
if (this._massTagInputNode) {
|
|
||||||
this._masstagAutoCompleteControl = new TagAutoCompleteControl(
|
|
||||||
this._massTagInputNode, {addSpace: false});
|
|
||||||
}
|
|
||||||
|
|
||||||
keyboard.bind('p', () => this._focusFirstPostNode());
|
keyboard.bind('p', () => this._focusFirstPostNode());
|
||||||
search.searchInputNodeFocusHelper(this._queryInputNode);
|
search.searchInputNodeFocusHelper(this._queryInputNode);
|
||||||
|
@ -38,19 +34,21 @@ class PostsHeaderView extends events.EventTarget {
|
||||||
this._formNode.addEventListener(
|
this._formNode.addEventListener(
|
||||||
'submit', e => this._evtFormSubmit(e));
|
'submit', e => this._evtFormSubmit(e));
|
||||||
|
|
||||||
if (this._massTagInputNode) {
|
if (this._bulkEditTagsInputNode) {
|
||||||
if (this._openMassTagLinkNode) {
|
this._bulkEditTagsAutoCompleteControl = new TagAutoCompleteControl(
|
||||||
this._openMassTagLinkNode.addEventListener(
|
this._bulkEditTagsInputNode, {addSpace: false});
|
||||||
'click', e => this._evtMassTagClick(e));
|
if (this._openBulkEditTagsLinkNode) {
|
||||||
|
this._openBulkEditTagsLinkNode.addEventListener(
|
||||||
|
'click', e => this._evtBulkEditTagsClick(e));
|
||||||
}
|
}
|
||||||
this._stopMassTagLinkNode.addEventListener(
|
this._stopBulkEditTagsLinkNode.addEventListener(
|
||||||
'click', e => this._evtStopTaggingClick(e));
|
'click', e => this._evtStopTaggingClick(e));
|
||||||
this._toggleMassTagVisibility(!!ctx.parameters.tag);
|
this._toggleBulkEditTagsVisibility(!!ctx.parameters.tag);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_toggleMassTagVisibility(state) {
|
_toggleBulkEditTagsVisibility(state) {
|
||||||
this._formNode.querySelector('.masstag')
|
this._formNode.querySelector('.bulk-edit-tags')
|
||||||
.classList.toggle('active', state);
|
.classList.toggle('active', state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,27 +64,28 @@ class PostsHeaderView extends events.EventTarget {
|
||||||
return this._hostNode.querySelector('form [name=search-text]');
|
return this._hostNode.querySelector('form [name=search-text]');
|
||||||
}
|
}
|
||||||
|
|
||||||
get _massTagInputNode() {
|
get _bulkEditTagsInputNode() {
|
||||||
return this._hostNode.querySelector('form [name=masstag]');
|
return this._hostNode.querySelector('form .bulk-edit-tags [name=tag]');
|
||||||
}
|
}
|
||||||
|
|
||||||
get _openMassTagLinkNode() {
|
get _openBulkEditTagsLinkNode() {
|
||||||
return this._hostNode.querySelector('form .open-masstag');
|
return this._hostNode.querySelector('form .bulk-edit-tags .open');
|
||||||
}
|
}
|
||||||
|
|
||||||
get _stopMassTagLinkNode() {
|
get _stopBulkEditTagsLinkNode() {
|
||||||
return this._hostNode.querySelector('form .stop-tagging');
|
return this._hostNode.querySelector(
|
||||||
|
'form .bulk-edit-tags .stop-tagging');
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtMassTagClick(e) {
|
_evtBulkEditTagsClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._toggleMassTagVisibility(true);
|
this._toggleBulkEditTagsVisibility(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtStopTaggingClick(e) {
|
_evtStopTaggingClick(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._massTagInputNode.value = '';
|
this._bulkEditTagsInputNode.value = '';
|
||||||
this._toggleMassTagVisibility(false);
|
this._toggleBulkEditTagsVisibility(false);
|
||||||
this.dispatchEvent(new CustomEvent('navigate', {detail: {parameters: {
|
this.dispatchEvent(new CustomEvent('navigate', {detail: {parameters: {
|
||||||
query: this._ctx.parameters.query,
|
query: this._ctx.parameters.query,
|
||||||
offset: this._ctx.parameters.offset,
|
offset: this._ctx.parameters.offset,
|
||||||
|
@ -116,15 +115,15 @@ class PostsHeaderView extends events.EventTarget {
|
||||||
_evtFormSubmit(e) {
|
_evtFormSubmit(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
this._queryAutoCompleteControl.hide();
|
this._queryAutoCompleteControl.hide();
|
||||||
if (this._masstagAutoCompleteControl) {
|
if (this._bulkEditTagsAutoCompleteControl) {
|
||||||
this._masstagAutoCompleteControl.hide();
|
this._bulkEditTagsAutoCompleteControl.hide();
|
||||||
}
|
}
|
||||||
let parameters = {query: this._queryInputNode.value};
|
let parameters = {query: this._queryInputNode.value};
|
||||||
parameters.offset = parameters.query === this._ctx.parameters.query ?
|
parameters.offset = parameters.query === this._ctx.parameters.query ?
|
||||||
this._ctx.parameters.offset : 0;
|
this._ctx.parameters.offset : 0;
|
||||||
if (this._massTagInputNode) {
|
if (this._bulkEditTagsInputNode) {
|
||||||
parameters.tag = this._massTagInputNode.value;
|
parameters.tag = this._bulkEditTagsInputNode.value;
|
||||||
this._massTagInputNode.blur();
|
this._bulkEditTagsInputNode.blur();
|
||||||
} else {
|
} else {
|
||||||
parameters.tag = null;
|
parameters.tag = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,36 +19,40 @@ class PostsPageView extends events.EventTarget {
|
||||||
}
|
}
|
||||||
|
|
||||||
this._postIdToLinkNode = {};
|
this._postIdToLinkNode = {};
|
||||||
for (let linkNode of this._hostNode.querySelectorAll('.masstag')) {
|
for (let linkNode of this._tagFlipperNodes) {
|
||||||
const postId = linkNode.getAttribute('data-post-id');
|
const postId = linkNode.getAttribute('data-post-id');
|
||||||
const post = this._postIdToPost[postId];
|
const post = this._postIdToPost[postId];
|
||||||
this._postIdToLinkNode[postId] = linkNode;
|
this._postIdToLinkNode[postId] = linkNode;
|
||||||
linkNode.addEventListener(
|
linkNode.addEventListener(
|
||||||
'click', e => this._evtMassTagClick(e, post));
|
'click', e => this._evtBulkEditTagsClick(e, post));
|
||||||
}
|
}
|
||||||
|
|
||||||
this._syncMassTagHighlights();
|
this._syncBulkEditTagsHighlights();
|
||||||
|
}
|
||||||
|
|
||||||
|
get _tagFlipperNodes() {
|
||||||
|
return this._hostNode.querySelectorAll('.tag-flipper');
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtPostChange(e) {
|
_evtPostChange(e) {
|
||||||
const linkNode = this._postIdToLinkNode[e.detail.post.id];
|
const linkNode = this._postIdToLinkNode[e.detail.post.id];
|
||||||
linkNode.removeAttribute('data-disabled');
|
linkNode.removeAttribute('data-disabled');
|
||||||
this._syncMassTagHighlights();
|
this._syncBulkEditTagsHighlights();
|
||||||
}
|
}
|
||||||
|
|
||||||
_syncMassTagHighlights() {
|
_syncBulkEditTagsHighlights() {
|
||||||
for (let linkNode of this._hostNode.querySelectorAll('.masstag')) {
|
for (let linkNode of this._tagFlipperNodes) {
|
||||||
const postId = linkNode.getAttribute('data-post-id');
|
const postId = linkNode.getAttribute('data-post-id');
|
||||||
const post = this._postIdToPost[postId];
|
const post = this._postIdToPost[postId];
|
||||||
let tagged = true;
|
let tagged = true;
|
||||||
for (let tag of this._ctx.massTagTags) {
|
for (let tag of this._ctx.bulkEdit.tags) {
|
||||||
tagged = tagged & post.isTaggedWith(tag);
|
tagged = tagged & post.isTaggedWith(tag);
|
||||||
}
|
}
|
||||||
linkNode.classList.toggle('tagged', tagged);
|
linkNode.classList.toggle('tagged', tagged);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_evtMassTagClick(e, post) {
|
_evtBulkEditTagsClick(e, post) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
const linkNode = e.target;
|
const linkNode = e.target;
|
||||||
if (linkNode.getAttribute('data-disabled')) {
|
if (linkNode.getAttribute('data-disabled')) {
|
||||||
|
|
|
@ -89,6 +89,7 @@ privileges:
|
||||||
'posts:score': regular
|
'posts:score': regular
|
||||||
'posts:merge': moderator
|
'posts:merge': moderator
|
||||||
'posts:favorite': regular
|
'posts:favorite': regular
|
||||||
|
'posts:bulk-edit:tags': power
|
||||||
|
|
||||||
'tags:create': regular
|
'tags:create': regular
|
||||||
'tags:edit:names': power
|
'tags:edit:names': power
|
||||||
|
@ -98,7 +99,6 @@ privileges:
|
||||||
'tags:edit:suggestions': power
|
'tags:edit:suggestions': power
|
||||||
'tags:list': regular # note: will be available as data_url/tags.json anyway
|
'tags:list': regular # note: will be available as data_url/tags.json anyway
|
||||||
'tags:view': anonymous
|
'tags:view': anonymous
|
||||||
'tags:masstag': power
|
|
||||||
'tags:merge': moderator
|
'tags:merge': moderator
|
||||||
'tags:delete': moderator
|
'tags:delete': moderator
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue