mirror of
https://github.com/TryGhost/Ghost.git
synced 2024-12-23 02:41:50 +03:00
Hid snippet management UI from staff users without permissions
no issue - snippets can only be created and deleted by owners/admins/editors - added a property in the editor controller to determine if the logged in user has sufficient permissions, then only pass the appropriate save/delete snippet actions to the editor component if the check is passed - updates koenig menus and toolbars to skip rendering of buttons if the associated action function is not available
This commit is contained in:
parent
2edb7226e1
commit
c6753a0efd
@ -4,8 +4,8 @@ import boundOneWay from 'ghost-admin/utils/bound-one-way';
|
||||
import config from 'ghost-admin/config/environment';
|
||||
import isNumber from 'ghost-admin/utils/isNumber';
|
||||
import moment from 'moment';
|
||||
import {action, computed} from '@ember/object';
|
||||
import {alias, mapBy} from '@ember/object/computed';
|
||||
import {computed} from '@ember/object';
|
||||
import {inject as controller} from '@ember/controller';
|
||||
import {get} from '@ember/object';
|
||||
import {htmlSafe} from '@ember/string';
|
||||
@ -147,6 +147,14 @@ export default Controller.extend({
|
||||
return this._snippets.reject(snippet => snippet.get('isNew'));
|
||||
}),
|
||||
|
||||
canManageSnippets: computed('session.user.{isOwnerOrAdmin,isEditor}', function () {
|
||||
let {user} = this.session;
|
||||
if (user.get('isOwnerOrAdmin') || user.get('isEditor')) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}),
|
||||
|
||||
_autosaveRunning: computed('_autosave.isRunning', '_timedSave.isRunning', function () {
|
||||
let autosave = this.get('_autosave.isRunning');
|
||||
let timedsave = this.get('_timedSave.isRunning');
|
||||
@ -290,9 +298,10 @@ export default Controller.extend({
|
||||
|
||||
updateWordCount(counts) {
|
||||
this.set('wordCount', counts);
|
||||
}
|
||||
},
|
||||
|
||||
saveSnippet(snippet) {
|
||||
saveSnippet: action(function (snippet) {
|
||||
let snippetRecord = this.store.createRecord('snippet', snippet);
|
||||
return snippetRecord.save().then(() => {
|
||||
this.notifications.closeAlerts('snippet.save');
|
||||
@ -311,16 +320,15 @@ export default Controller.extend({
|
||||
snippetRecord.rollbackAttributes();
|
||||
throw error;
|
||||
});
|
||||
},
|
||||
}),
|
||||
|
||||
toggleDeleteSnippetModal(snippet) {
|
||||
toggleDeleteSnippetModal: action(function (snippet) {
|
||||
this.set('snippetToDelete', snippet);
|
||||
},
|
||||
}),
|
||||
|
||||
deleteSnippet(snippet) {
|
||||
deleteSnippet: action(function (snippet) {
|
||||
return snippet.destroyRecord();
|
||||
}
|
||||
},
|
||||
}),
|
||||
|
||||
/* Public tasks ----------------------------------------------------------*/
|
||||
|
||||
@ -613,11 +621,11 @@ export default Controller.extend({
|
||||
let membersResponse = yield this.store.query('member', {limit: 1, filter: 'subscribed:true'});
|
||||
this.set('memberCount', get(membersResponse, 'meta.pagination.total'));
|
||||
}
|
||||
|
||||
yield this.store.query('snippet', {limit: 'all'});
|
||||
} catch (error) {
|
||||
this.set('memberCount', 0);
|
||||
}
|
||||
|
||||
yield this.store.query('snippet', {limit: 'all'});
|
||||
}).restartable(),
|
||||
|
||||
/* Public methods --------------------------------------------------------*/
|
||||
|
5
ghost/admin/app/helpers/noop.js
Normal file
5
ghost/admin/app/helpers/noop.js
Normal file
@ -0,0 +1,5 @@
|
||||
import {helper} from '@ember/component/helper';
|
||||
|
||||
export default helper(function noop() {
|
||||
return () => {};
|
||||
});
|
@ -82,8 +82,8 @@
|
||||
@onEditorCreated={{action "setKoenigEditor"}}
|
||||
@onWordCountChange={{action "updateWordCount"}}
|
||||
@snippets={{this.snippets}}
|
||||
@saveSnippet={{action "saveSnippet"}}
|
||||
@deleteSnippet={{action "toggleDeleteSnippetModal"}}
|
||||
@saveSnippet={{if this.canManageSnippets this.saveSnippet}}
|
||||
@deleteSnippet={{if this.canManageSnippets this.toggleDeleteSnippetModal}}
|
||||
/>
|
||||
|
||||
<div class="absolute flex items-center br3 bg-white {{if editor.headerClass "right-4 bottom-4" "right-6 bottom-6"}}">
|
||||
@ -139,8 +139,8 @@
|
||||
<GhFullscreenModal
|
||||
@modal="delete-snippet"
|
||||
@model={{this.snippetToDelete}}
|
||||
@confirm={{action "deleteSnippet"}}
|
||||
@close={{action "toggleDeleteSnippetModal"}}
|
||||
@confirm={{this.deleteSnippet}}
|
||||
@close={{this.toggleDeletePostModal}}
|
||||
@modifier="action wide"
|
||||
/>
|
||||
{{/if}}
|
||||
|
@ -12,7 +12,7 @@
|
||||
@toggleSection={{action "toggleSection"}}
|
||||
@toggleHeaderSection={{action "toggleHeaderSection"}}
|
||||
@editLink={{action "editLink"}}
|
||||
@addSnippet={{this.addSnippet}}
|
||||
@addSnippet={{this.addSnippetIfPossible}}
|
||||
/>
|
||||
|
||||
{{!-- pop-up link hover toolbar --}}
|
||||
@ -86,7 +86,7 @@
|
||||
deselectCard=(action "deselectCard" card)
|
||||
editCard=(action "editCard" card)
|
||||
deleteCard=(action "deleteCard" card)
|
||||
saveAsSnippet=(action "saveCardAsSnippet" card)
|
||||
saveAsSnippet=this.saveCardAsSnippetIfPossible
|
||||
moveCursorToPrevSection=(action "moveCursorToPrevSection" card)
|
||||
moveCursorToNextSection=(action "moveCursorToNextSection" card)
|
||||
addParagraphAfterCard=(action "addParagraphAfterCard" card)
|
||||
|
@ -233,6 +233,14 @@ export default Component.extend({
|
||||
}, options);
|
||||
}),
|
||||
|
||||
addSnippetIfPossible: computed('saveSnippet', function () {
|
||||
return this.saveSnippet ? this.addSnippet : undefined;
|
||||
}),
|
||||
|
||||
saveCardAsSnippetIfPossible: computed('saveSnippet', function () {
|
||||
return this.saveSnippet ? this.saveCardAsSnippet : undefined;
|
||||
}),
|
||||
|
||||
/* lifecycle hooks ------------------------------------------------------ */
|
||||
|
||||
init() {
|
||||
@ -618,12 +626,6 @@ export default Component.extend({
|
||||
this.deleteCard(card, cursorMovement);
|
||||
},
|
||||
|
||||
saveCardAsSnippet(card) {
|
||||
let section = this.getSectionFromCard(card);
|
||||
this.set('snippetRect', card.component.element.getBoundingClientRect());
|
||||
this.set('snippetRange', section.toRange());
|
||||
},
|
||||
|
||||
moveCursorToPrevSection(card) {
|
||||
let section = this.getSectionFromCard(card);
|
||||
|
||||
@ -681,6 +683,12 @@ export default Component.extend({
|
||||
this.set('snippetRange', selectedRange);
|
||||
}),
|
||||
|
||||
saveCardAsSnippet: action(function (card) {
|
||||
let section = this.getSectionFromCard(card);
|
||||
this.set('snippetRect', card.component.element.getBoundingClientRect());
|
||||
this.set('snippetRange', section.toRange());
|
||||
}),
|
||||
|
||||
cancelAddSnippet: action(function () {
|
||||
this.set('snippetRange', null);
|
||||
this.set('snippetRect', null);
|
||||
|
@ -49,17 +49,20 @@ export default Component.extend({
|
||||
};
|
||||
|
||||
snippets.forEach((snippet) => {
|
||||
snippetsSection.items.push({
|
||||
let snippetItem = {
|
||||
label: snippet.name,
|
||||
icon: snippetIcon(snippet),
|
||||
type: 'snippet',
|
||||
matches: [snippet.name.toLowerCase()],
|
||||
deleteClicked: (event) => {
|
||||
matches: [snippet.name.toLowerCase()]
|
||||
};
|
||||
if (this.deleteSnippet) {
|
||||
snippetItem.deleteClicked = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.deleteSnippet(snippet);
|
||||
};
|
||||
}
|
||||
});
|
||||
snippetsSection.items.push(snippetItem);
|
||||
});
|
||||
|
||||
itemSections.push(snippetsSection);
|
||||
|
@ -68,17 +68,20 @@ export default class KoenigSlashMenuComponent extends Component {
|
||||
};
|
||||
|
||||
snippets.forEach((snippet) => {
|
||||
snippetsSection.items.push({
|
||||
let snippetItem = {
|
||||
label: snippet.name,
|
||||
icon: snippetIcon(snippet),
|
||||
type: 'snippet',
|
||||
matches: [snippet.name.toLowerCase()],
|
||||
deleteClicked: (event) => {
|
||||
matches: [snippet.name.toLowerCase()]
|
||||
};
|
||||
if (this.args.deleteSnippet) {
|
||||
snippetItem.deleteClicked = (event) => {
|
||||
event.preventDefault();
|
||||
event.stopImmediatePropagation();
|
||||
this.args.deleteSnippet(snippet);
|
||||
};
|
||||
}
|
||||
});
|
||||
snippetsSection.items.push(snippetItem);
|
||||
});
|
||||
|
||||
itemSections.push(snippetsSection);
|
||||
|
@ -67,7 +67,7 @@
|
||||
</button>
|
||||
</li>
|
||||
|
||||
{{#if (enable-developer-experiments)}}
|
||||
{{#if (and @addSnippet (enable-developer-experiments))}}
|
||||
{{#unless this.basicOnly}}
|
||||
<li class="ma0 lh-solid kg-action-bar-divider bg-darkgrey-l2 h5" role="separator"></li>
|
||||
<li class="ma0 lh-solid">
|
||||
|
Loading…
Reference in New Issue
Block a user