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