diff --git a/gui/app/components/document/document-toc.js b/gui/app/components/document/document-toc.js index bbd1c304..87e3c0a6 100644 --- a/gui/app/components/document/document-toc.js +++ b/gui/app/components/document/document-toc.js @@ -63,7 +63,7 @@ export default Component.extend(TooltipMixin, { this.removeTooltips(); }, - onDocumentPageAdded(pageId) { // eslint-disable-line no-unused-vars + onDocumentPageAdded(pageId) { schedule('afterRender', () => { this.setState(pageId); }); diff --git a/gui/app/components/document/page-heading.js b/gui/app/components/document/page-heading.js index 12e66dd0..f3829f26 100644 --- a/gui/app/components/document/page-heading.js +++ b/gui/app/components/document/page-heading.js @@ -14,6 +14,7 @@ import { computed } from '@ember/object'; import { debounce } from '@ember/runloop'; import { inject as service } from '@ember/service'; import ModalMixin from '../../mixins/modal'; +import tocUtil from '../../utils/toc'; import Component from '@ember/component'; export default Component.extend(ModalMixin, { @@ -23,7 +24,7 @@ export default Component.extend(ModalMixin, { deleteChildren: false, blockTitle: "", blockExcerpt: "", - canEdit: false, + // canEdit: false, canDelete: false, canMove: false, docSearchFilter: '', @@ -39,10 +40,29 @@ export default Component.extend(ModalMixin, { return permissions.get('documentCopy') || permissions.get('documentTemplate') || this.get('canEdit') || this.get('canMove') || this.get('canDelete'); }), + canEdit: computed('permissions', 'document', 'pages', function() { + let constants = this.get('constants'); + let permissions = this.get('permissions'); + let authenticated = this.get('session.authenticated'); + let notEmpty = this.get('pages.length') > 0; + + if (notEmpty && authenticated && permissions.get('documentEdit') && this.get('document.protection') === constants.ProtectionType.None) return true; + if (notEmpty && authenticated && permissions.get('documentApprove') && this.get('document.protection') === constants.ProtectionType.Review) return true; + + return false; + }), init() { this._super(...arguments); this.docSearchResults = []; + this.state = { + actionablePage: false, + upDisabled: true, + downDisabled: true, + indentDisabled: true, + outdentDisabled: true, + pageId: '' + }; }, didReceiveAttrs() { @@ -50,11 +70,13 @@ export default Component.extend(ModalMixin, { this.modalInputFocus('#publish-page-modal-' + this.get('page.id'), '#block-title-' + this.get('page.id')); let permissions = this.get('permissions'); - this.set('canEdit', permissions.get('documentEdit')); + // this.set('canEdit', permissions.get('documentEdit')); this.set('canDelete', permissions.get('documentDelete')); this.set('canMove', permissions.get('documentMove')); + + this.setState(this.get('page.id')); }, - + searchDocs() { let payload = { keywords: this.get('docSearchFilter').trim(), doc: true }; if (payload.keywords.length == 0) return; @@ -64,6 +86,20 @@ export default Component.extend(ModalMixin, { }); }, + // Controls what user can do with the toc enty for this page + setState(pageId) { + let toc = this.get('pages'); + let page = _.find(toc, function(i) { return i.get('page.id') === pageId; }); + let state = tocUtil.getState(toc, page.get('page')); + + if (!this.get('canEdit')) { + state.actionablePage = false; + state.upDisabled = state.downDisabled = state.indentDisabled = state.outdentDisabled = true; + } + + this.set('state', state); + }, + actions: { onEdit() { let page = this.get('page'); @@ -168,5 +204,72 @@ export default Component.extend(ModalMixin, { let refresh = this.get('refresh'); refresh(); }, + + // Page up -- above pages shunt down + pageUp() { + let state = this.get('state'); + + if (state.upDisabled || this.get('document.protection') !== this.get('constants').ProtectionType.None) { + return; + } + + let pages = this.get('pages'); + let page = _.find(pages, function(i) { return i.get('page.id') === state.pageId; }); + if (is.not.undefined(page)) page = page.get('page'); + + let pendingChanges = tocUtil.moveUp(state, pages, page); + if (pendingChanges.length > 0) { + let cb = this.get('onPageSequenceChange'); + cb(state.pageId, pendingChanges); + } + }, + + // Move down -- pages below shift up + pageDown() { + if (!this.get('canEdit')) return; + + let state = this.get('state'); + let pages = this.get('pages'); + let page = _.find(pages, function(i) { return i.get('page.id') === state.pageId; }); + if (is.not.undefined(page)) page = page.get('page'); + + let pendingChanges = tocUtil.moveDown(state, pages, page); + if (pendingChanges.length > 0) { + let cb = this.get('onPageSequenceChange'); + cb(state.pageId, pendingChanges); + } + }, + + // Indent -- changes a page from H2 to H3, etc. + pageIndent() { + if (!this.get('canEdit')) return; + + let state = this.get('state'); + let pages = this.get('pages'); + let page = _.find(pages, function(i) { return i.get('page.id') === state.pageId; }); + if (is.not.undefined(page)) page = page.get('page'); + + let pendingChanges = tocUtil.indent(state, pages, page); + if (pendingChanges.length > 0) { + let cb = this.get('onPageLevelChange'); + cb(state.pageId, pendingChanges); + } + }, + + // Outdent -- changes a page from H3 to H2, etc. + pageOutdent() { + if (!this.get('canEdit')) return; + + let state = this.get('state'); + let pages = this.get('pages'); + let page = _.find(pages, function(i) { return i.get('page.id') === state.pageId; }); + if (is.not.undefined(page)) page = page.get('page'); + + let pendingChanges = tocUtil.outdent(state, pages, page); + if (pendingChanges.length > 0) { + let cb = this.get('onPageLevelChange'); + cb(state.pageId, pendingChanges); + } + } } }); diff --git a/gui/app/pods/document/index/controller.js b/gui/app/pods/document/index/controller.js index 8896a9db..9b32d2cc 100644 --- a/gui/app/pods/document/index/controller.js +++ b/gui/app/pods/document/index/controller.js @@ -198,19 +198,25 @@ export default Controller.extend(Tooltips, Notifier, { }, onPageSequenceChange(currentPageId, changes) { + this.showWait(); this.set('currentPageId', currentPageId); + this.get('documentService').changePageSequence(this.get('document.id'), changes).then(() => { this.get('documentService').fetchPages(this.get('document.id'), this.get('session.user.id')).then( (pages) => { this.set('pages', pages); + this.showDone(); }); }); }, onPageLevelChange(currentPageId, changes) { + this.showWait(); this.set('currentPageId', currentPageId); + this.get('documentService').changePageLevel(this.get('document.id'), changes).then(() => { this.get('documentService').fetchPages(this.get('document.id'), this.get('session.user.id')).then( (pages) => { this.set('pages', pages); + this.showDone(); }); }); }, diff --git a/gui/app/pods/document/index/template.hbs b/gui/app/pods/document/index/template.hbs index 70c8b494..b7a9b6af 100644 --- a/gui/app/pods/document/index/template.hbs +++ b/gui/app/pods/document/index/template.hbs @@ -16,17 +16,17 @@ {{#layout/middle-zone-content}} {{toolbar/for-document - document=document - spaces=folders - space=folder - permissions=permissions - roles=roles tab=tab + roles=roles + space=folder + spaces=folders + document=document versions=versions - onDocumentDelete=(action 'onDocumentDelete') + permissions=permissions + refresh=(action 'refresh') onSaveTemplate=(action 'onSaveTemplate') onSaveDocument=(action 'onSaveDocument') - refresh=(action 'refresh')}} + onDocumentDelete=(action 'onDocumentDelete')}}
Are you sure you want to delete this re-usable content block?
-{{/ui/ui-dialog}} {{/if}} +{{/if}} + +{{#if permissions.documentTemplate}} + {{#ui/ui-dialog title="Delete Content Block" confirmCaption="Delete" buttonType="btn-danger" show=showDeleteBlockDialog onAction=(action 'onDeleteBlock')}} +Are you sure you want to delete this re-usable content block?
+ {{/ui/ui-dialog}} +{{/if}}