From a7ac034d2cfe4ce8690db6f671459df1c142b6f8 Mon Sep 17 00:00:00 2001 From: Harvey Kandola Date: Fri, 3 Mar 2017 20:17:49 +0000 Subject: [PATCH] add/edit smart sections --- app/app/components/document/document-tab.js | 49 +- app/app/components/document/document-view.js | 12 +- app/app/components/document/tab-heading.js | 200 ++++++++ app/app/index.html | 3 - app/app/pods/document/controller.js | 454 +++++++++--------- app/app/pods/document/index/controller.js | 321 +++++++++++++ app/app/pods/document/index/route.js | 46 ++ app/app/pods/document/index/template.hbs | 73 +++ app/app/pods/document/route.js | 22 +- app/app/pods/document/section/controller.js | 24 +- app/app/pods/document/section/route.js | 15 +- app/app/pods/document/section/template.hbs | 18 +- app/app/pods/document/template.hbs | 75 +-- app/app/pods/document/zindex/controller.js | 91 ---- app/app/pods/document/zindex/route.js | 66 --- app/app/pods/document/zindex/template.hbs | 0 .../{wizard => zwizard}/controller.js | 0 .../document/{wizard => zwizard}/route.js | 0 .../document/{wizard => zwizard}/template.hbs | 0 app/app/router.js | 6 +- app/app/styles/color.scss | 3 + app/app/styles/view/document/all.scss | 3 +- .../{editor.scss => inline-editor.scss} | 0 .../styles/view/document/section-editor.scss | 33 ++ app/app/styles/view/document/section.scss | 9 - app/app/styles/view/document/view.scss | 70 ++- .../components/document/document-page.hbs | 8 +- .../components/document/document-tab.hbs | 34 +- .../components/document/document-view.hbs | 16 +- .../components/document/tab-heading.hbs | 92 ++++ .../components/section/base-editor.hbs | 65 ++- core/section/gemini/model.go | 2 +- core/section/papertrail/model.go | 2 +- 33 files changed, 1209 insertions(+), 603 deletions(-) create mode 100644 app/app/components/document/tab-heading.js create mode 100644 app/app/pods/document/index/controller.js create mode 100644 app/app/pods/document/index/route.js create mode 100644 app/app/pods/document/index/template.hbs delete mode 100644 app/app/pods/document/zindex/controller.js delete mode 100644 app/app/pods/document/zindex/route.js delete mode 100644 app/app/pods/document/zindex/template.hbs rename app/app/pods/document/{wizard => zwizard}/controller.js (100%) rename app/app/pods/document/{wizard => zwizard}/route.js (100%) rename app/app/pods/document/{wizard => zwizard}/template.hbs (100%) rename app/app/styles/view/document/{editor.scss => inline-editor.scss} (100%) create mode 100644 app/app/styles/view/document/section-editor.scss delete mode 100644 app/app/styles/view/document/section.scss create mode 100644 app/app/templates/components/document/tab-heading.hbs diff --git a/app/app/components/document/document-tab.js b/app/app/components/document/document-tab.js index 56b28fca..06ca19ac 100644 --- a/app/app/components/document/document-tab.js +++ b/app/app/components/document/document-tab.js @@ -19,18 +19,14 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { editMode: false, didReceiveAttrs(){ - if (this.get('mode') === 'edit') { - this.send('onEdit'); - } - this.audit.record("viewed-document-section-" + this.get('model.page.contentType')); }, didInsertElement() { let self = this; - this.get('sectionService').refresh(this.get('model.document.id')).then(function (changes) { + this.get('sectionService').refresh(this.get('document.id')).then(function (changes) { changes.forEach(function (newPage) { - let oldPage = self.get('model.page'); + let oldPage = self.get('page'); if (!_.isUndefined(oldPage) && oldPage.get('id') === newPage.get('id')) { oldPage.set('body', newPage.get('body')); oldPage.set('revised', newPage.get('revised')); @@ -41,30 +37,37 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { }, actions: { - onEdit() { - this.set('viewMode', false); - this.set('editMode', true); - this.set('mode', 'edit'); + onExpand() { + this.set('expanded', !this.get('expanded')); }, - onView() { - this.set('viewMode', true); - this.set('editMode', false); - this.set('mode', 'view'); + onSavePageAsBlock(block) { + this.attrs.onSavePageAsBlock(block); }, - onCancel() { - this.send('onView'); + onCopyPage(documentId) { + this.attrs.onCopyPage(this.get('page.id'), documentId); }, - onAction(page, meta) { - this.get('onAction')(page, meta); - this.send('onView'); + onMovePage(documentId) { + this.attrs.onMovePage(this.get('page.id'), documentId); + }, + + onDeletePage(deleteChildren) { + let page = this.get('page'); + + if (is.undefined(page)) { + return; + } + + let params = { + id: page.get('id'), + title: page.get('title'), + children: deleteChildren + }; + + this.attrs.onDeletePage(params); }, - onDelete() { - this.get('onDelete')(this.get('model.document'), this.get('model.page')); - return true; - } } }); diff --git a/app/app/components/document/document-view.js b/app/app/components/document/document-view.js index e62c8606..46584c5b 100644 --- a/app/app/components/document/document-view.js +++ b/app/app/components/document/document-view.js @@ -30,6 +30,10 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { toEdit: '', didReceiveAttrs() { + if (this.get('isDestroyed') || this.get('isDestroying')) { + return; + } + this.get('sectionService').getSpaceBlocks(this.get('folder.id')).then((blocks) => { this.set('blocks', blocks); this.set('hasBlocks', blocks.get('length') > 0); @@ -73,7 +77,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { // local link? exists? if ((link.linkType === "section" || link.linkType === "tab") && link.documentId === doc.get('id')) { - let exists = self.get('allPages').findBy('id', link.targetId); + let exists = self.get('pages').findBy('id', link.targetId); if (_.isUndefined(exists)) { link.orphan = true; @@ -120,7 +124,11 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { const promise = this.get('onInsertSection')(model); promise.then((id) => { - this.set('toEdit', id); + if (model.page.contentType === 'section') { + this.set('toEdit', id); + } else { + this.get('onEditSection')(id); + } }); }, diff --git a/app/app/components/document/tab-heading.js b/app/app/components/document/tab-heading.js new file mode 100644 index 00000000..d086eef0 --- /dev/null +++ b/app/app/components/document/tab-heading.js @@ -0,0 +1,200 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +import Ember from 'ember'; +import TooltipMixin from '../../mixins/tooltip'; + +const { + computed, + inject: { service } +} = Ember; + +export default Ember.Component.extend(TooltipMixin, { + documentService: service('document'), + expanded: false, + deleteChildren: false, + menuOpen: false, + blockTitle: "", + blockExcerpt: "", + documentList: [], //includes the current document + documentListOthers: [], //excludes the current document + selectedDocument: null, + + checkId: computed('page', function () { + let id = this.get('page.id'); + return `delete-check-button-${id}`; + }), + menuTarget: computed('page', function () { + let id = this.get('page.id'); + return `page-menu-${id}`; + }), + deleteButtonId: computed('page', function () { + let id = this.get('page.id'); + return `delete-page-button-${id}`; + }), + publishButtonId: computed('page', function () { + let id = this.get('page.id'); + return `publish-button-${id}`; + }), + publishDialogId: computed('page', function () { + let id = this.get('page.id'); + return `publish-dialog-${id}`; + }), + blockTitleId: computed('page', function () { + let id = this.get('page.id'); + return `block-title-${id}`; + }), + blockExcerptId: computed('page', function () { + let id = this.get('page.id'); + return `block-excerpt-${id}`; + }), + copyButtonId: computed('page', function () { + let id = this.get('page.id'); + return `copy-page-button-${id}`; + }), + copyDialogId: computed('page', function () { + let id = this.get('page.id'); + return `copy-dialog-${id}`; + }), + moveButtonId: computed('page', function () { + let id = this.get('page.id'); + return `move-page-button-${id}`; + }), + moveDialogId: computed('page', function () { + let id = this.get('page.id'); + return `move-dialog-${id}`; + }), + + didRender() { + $("#" + this.get('blockTitleId')).removeClass('error'); + $("#" + this.get('blockExcerptId')).removeClass('error'); + }, + + actions: { + toggleExpand() { + this.set('expanded', !this.get('expanded')); + this.get('onExpand')(); + }, + + onMenuOpen() { + if ($('#' + this.get('publishDialogId')).is( ":visible" )) { + return; + } + if ($('#' + this.get('copyDialogId')).is( ":visible" )) { + return; + } + if ($('#' + this.get('moveDialogId')).is( ":visible" )) { + return; + } + + this.set('menuOpen', !this.get('menuOpen')); + }, + + onEdit() { + this.attrs.onEdit(); + }, + + deletePage() { + this.attrs.onDeletePage(this.get('deleteChildren')); + }, + + onSavePageAsBlock() { + let page = this.get('page'); + let titleElem = '#' + this.get('blockTitleId'); + let blockTitle = this.get('blockTitle'); + if (is.empty(blockTitle)) { + $(titleElem).addClass('error'); + return; + } + + let excerptElem = '#' + this.get('blockExcerptId'); + let blockExcerpt = this.get('blockExcerpt'); + blockExcerpt = blockExcerpt.replace(/\n/g, ""); + if (is.empty(blockExcerpt)) { + $(excerptElem).addClass('error'); + return; + } + + this.get('documentService').getPageMeta(this.get('document.id'), page.get('id')).then((pm) => { + let block = { + folderId: this.get('folder.id'), + contentType: page.get('contentType'), + pageType: page.get('pageType'), + title: blockTitle, + body: page.get('body'), + excerpt: blockExcerpt, + rawBody: pm.get('rawBody'), + config: pm.get('config'), + externalSource: pm.get('externalSource') + }; + + this.attrs.onSavePageAsBlock(block); + + this.set('menuOpen', false); + this.set('blockTitle', ''); + this.set('blockExcerpt', ''); + $(titleElem).removeClass('error'); + $(excerptElem).removeClass('error'); + + return true; + }); + }, + + // Copy/move actions + onCopyDialogOpen() { + // Fetch document targets once. + if (this.get('documentList').length > 0) { + return; + } + + this.get('documentService').getPageMoveCopyTargets().then((d) => { + let me = this.get('document'); + this.set('documentList', d); + this.set('documentListOthers', d.filter((item) => item.get('id') !== me.get('id'))); + }); + }, + + onTargetChange(d) { + this.set('selectedDocument', d); + }, + + onCopyPage() { + // can't proceed if no data + if (this.get('documentList.length') === 0) { + return; + } + + let targetDocumentId = this.get('document.id'); + if (is.not.null(this.get('selectedDocument'))) { + targetDocumentId = this.get('selectedDocument.id'); + } + + this.attrs.onCopyPage(targetDocumentId); + return true; + }, + + onMovePage() { + // can't proceed if no data + if (this.get('documentListOthers.length') === 0) { + return; + } + + if (is.null(this.get('selectedDocument'))) { + this.set('selectedDocument', this.get('documentListOthers')[0]); + } + + let targetDocumentId = this.get('selectedDocument.id'); + + this.attrs.onMovePage(targetDocumentId); + return true; + } + } +}); diff --git a/app/app/index.html b/app/app/index.html index 66d8284c..31f22f0f 100644 --- a/app/app/index.html +++ b/app/app/index.html @@ -1,6 +1,5 @@ - {{content-for 'head'}} @@ -17,7 +16,6 @@ {{content-for 'head-footer'}} - {{content-for 'body'}} @@ -29,5 +27,4 @@ {{content-for 'body-footer'}} - diff --git a/app/app/pods/document/controller.js b/app/app/pods/document/controller.js index 407e0ad3..5db64f2c 100644 --- a/app/app/pods/document/controller.js +++ b/app/app/pods/document/controller.js @@ -13,233 +13,233 @@ import Ember from 'ember'; import NotifierMixin from '../../mixins/notifier'; export default Ember.Controller.extend(NotifierMixin, { - documentService: Ember.inject.service('document'), - templateService: Ember.inject.service('template'), - sectionService: Ember.inject.service('section'), - page: null, - folder: {}, - pages: [], - toggled: false, - - // to test - // to test - // Jump to the right part of the document. - scrollToPage(pageId) { - Ember.run.schedule('afterRender', function () { - let dest; - let target = "#page-title-" + pageId; - let targetOffset = $(target).offset(); - - if (is.undefined(targetOffset)) { - return; - } - - dest = targetOffset.top > $(document).height() - $(window).height() ? $(document).height() - $(window).height() : targetOffset.top; - // small correction to ensure we also show page title - dest = dest > 50 ? dest - 74 : dest; - - $("html,body").animate({ - scrollTop: dest - }, 500, "linear"); - $(".toc-index-item").removeClass("selected"); - $("#index-" + pageId).addClass("selected"); - }); - }, - - actions: { - toggleSidebar() { - this.set('toggled', !this.get('toggled')); - }, - - onTagChange(tags) { - let doc = this.get('model.document'); - doc.set('tags', tags); - this.get('documentService').save(doc); - }, - - onSaveDocument(doc) { - this.get('documentService').save(doc); - this.showNotification('Saved'); - }, - - onCopyPage(pageId, targetDocumentId) { - let documentId = this.get('model.document.id'); - this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => { - this.showNotification("Copied"); - - // refresh data if copied to same document - if (documentId === targetDocumentId) { - this.get('target.router').refresh(); - } - }); - }, - - onMovePage(pageId, targetDocumentId) { - let documentId = this.get('model.document.id'); - - this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => { - this.showNotification("Moved"); - - this.send('onPageDeleted', { id: pageId, children: false }); - }); - }, - - onSavePage(page, meta) { - let self = this; - let documentId = this.get('model.document.id'); - let model = { - page: page.toJSON({ includeId: true }), - meta: meta.toJSON({ includeId: true }) - }; - - this.get('documentService').updatePage(documentId, page.get('id'), model).then(function () { - self.audit.record("edited-page"); - self.get('documentService').getPages(documentId).then((pages) => { - self.set('model.allPages', pages); - self.set('model.pages', pages.filterBy('pageType', 'section')); - self.set('model.tabs', pages.filterBy('pageType', 'tab')); - }); - - }); - }, - - onPageDeleted(deletePage) { - let documentId = this.get('model.document.id'); - let pages = this.get('model.pages'); - let deleteId = deletePage.id; - let deleteChildren = deletePage.children; - let page = _.findWhere(pages, { - id: deleteId - }); - let pageIndex = _.indexOf(pages, page, false); - let pendingChanges = []; - - this.audit.record("deleted-page"); - - // select affected pages - for (var i = pageIndex + 1; i < pages.get('length'); i++) { - if (pages[i].get('level') <= page.get('level')) { - break; - } - - pendingChanges.push({ - pageId: pages[i].get('id'), - level: pages[i].get('level') - 1 - }); - } - - if (deleteChildren) { - // nuke of page tree - pendingChanges.push({ - pageId: deleteId - }); - - this.get('documentService').deletePages(documentId, deleteId, pendingChanges).then(() => { - // update our models so we don't have to reload from db - for (var i = 0; i < pendingChanges.length; i++) { - let pageId = pendingChanges[i].pageId; - this.set('model.pages', _.reject(pages, function (p) { //jshint ignore: line - return p.get('id') === pageId; - })); - } - - this.set('model.pages', _.sortBy(pages, "sequence")); - this.get('target.router').refresh(); - }); - } else { - // page delete followed by re-leveling child pages - this.get('documentService').deletePage(documentId, deleteId).then(() => { - this.set('model.pages', _.reject(pages, function (p) { - return p.get('id') === deleteId; - })); - - this.send('onPageLevelChange', pendingChanges); - }); - } - }, - - onInsertSection(data) { - return new Ember.RSVP.Promise((resolve) => { - this.get('documentService').addPage(this.get('model.document.id'), data).then((newPage) => { - let data = this.get('store').normalize('page', newPage); - this.get('store').push(data); - - this.get('documentService').getPages(this.get('model.document.id')).then((pages) => { - this.set('model.allPages', pages); - this.set('model.pages', pages.filterBy('pageType', 'section')); - this.set('model.tabs', pages.filterBy('pageType', 'tab')); - - resolve(newPage.id); - - // this.get('documentService').getPageMeta(this.get('model.document.id'), newPage.id).then(() => { - // console.log("ready to edit"); - // // this.transitionToRoute('document.edit', - // // this.get('model.folder.id'), - // // this.get('model.folder.slug'), - // // this.get('model.document.id'), - // // this.get('model.document.slug'), - // // newPage.id); - // }); - }); - }); - }); - }, - - // to test - onPageSequenceChange(changes) { - this.get('documentService').changePageSequence(this.get('model.document.id'), changes).then(() => { - _.each(changes, (change) => { - let pageContent = _.findWhere(this.get('model.pages'), { - id: change.pageId - }); - - if (is.not.undefined(pageContent)) { - pageContent.set('sequence', change.sequence); - } - }); - - this.set('model.pages', this.get('model.pages').sortBy('sequence')); - this.get('target.router').refresh(); - }); - }, - - // to test - onPageLevelChange(changes) { - this.get('documentService').changePageLevel(this.get('model.document.id'), changes).then(() => { - _.each(changes, (change) => { - let pageContent = _.findWhere(this.get('model.pages'), { - id: change.pageId - }); - - if (is.not.undefined(pageContent)) { - pageContent.set('level', change.level); - } - }); - - let pages = this.get('model.pages'); - pages = pages.sortBy('sequence'); - this.set('model.pages', []); - this.set('model.pages', pages); - this.get('target.router').refresh(); - }); - }, - - // to test - gotoPage(pageId) { - if (is.null(pageId)) { - return; - } - - this.scrollToPage(pageId); - }, - - // to test - onSavePageAsBlock(block) { - this.get('sectionService').addBlock(block).then(() => { - this.showNotification("Published"); - }); - } - } + // documentService: Ember.inject.service('document'), + // templateService: Ember.inject.service('template'), + // sectionService: Ember.inject.service('section'), + // page: null, + // folder: {}, + // pages: [], + // toggled: false, + // + // // to test + // // to test + // // Jump to the right part of the document. + // scrollToPage(pageId) { + // Ember.run.schedule('afterRender', function () { + // let dest; + // let target = "#page-title-" + pageId; + // let targetOffset = $(target).offset(); + // + // if (is.undefined(targetOffset)) { + // return; + // } + // + // dest = targetOffset.top > $(document).height() - $(window).height() ? $(document).height() - $(window).height() : targetOffset.top; + // // small correction to ensure we also show page title + // dest = dest > 50 ? dest - 74 : dest; + // + // $("html,body").animate({ + // scrollTop: dest + // }, 500, "linear"); + // $(".toc-index-item").removeClass("selected"); + // $("#index-" + pageId).addClass("selected"); + // }); + // }, + // + // actions: { + // toggleSidebar() { + // this.set('toggled', !this.get('toggled')); + // }, + // + // onTagChange(tags) { + // let doc = this.get('model.document'); + // doc.set('tags', tags); + // this.get('documentService').save(doc); + // }, + // + // onSaveDocument(doc) { + // this.get('documentService').save(doc); + // this.showNotification('Saved'); + // }, + // + // onCopyPage(pageId, targetDocumentId) { + // let documentId = this.get('model.document.id'); + // this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => { + // this.showNotification("Copied"); + // + // // refresh data if copied to same document + // if (documentId === targetDocumentId) { + // this.get('target.router').refresh(); + // } + // }); + // }, + // + // onMovePage(pageId, targetDocumentId) { + // let documentId = this.get('model.document.id'); + // + // this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => { + // this.showNotification("Moved"); + // + // this.send('onPageDeleted', { id: pageId, children: false }); + // }); + // }, + // + // onSavePage(page, meta) { + // let self = this; + // let documentId = this.get('model.document.id'); + // let model = { + // page: page.toJSON({ includeId: true }), + // meta: meta.toJSON({ includeId: true }) + // }; + // + // this.get('documentService').updatePage(documentId, page.get('id'), model).then(function () { + // self.audit.record("edited-page"); + // self.get('documentService').getPages(documentId).then((pages) => { + // self.set('model.allPages', pages); + // self.set('model.pages', pages.filterBy('pageType', 'section')); + // self.set('model.tabs', pages.filterBy('pageType', 'tab')); + // }); + // + // }); + // }, + // + // onPageDeleted(deletePage) { + // let documentId = this.get('model.document.id'); + // let pages = this.get('model.pages'); + // let deleteId = deletePage.id; + // let deleteChildren = deletePage.children; + // let page = _.findWhere(pages, { + // id: deleteId + // }); + // let pageIndex = _.indexOf(pages, page, false); + // let pendingChanges = []; + // + // this.audit.record("deleted-page"); + // + // // select affected pages + // for (var i = pageIndex + 1; i < pages.get('length'); i++) { + // if (pages[i].get('level') <= page.get('level')) { + // break; + // } + // + // pendingChanges.push({ + // pageId: pages[i].get('id'), + // level: pages[i].get('level') - 1 + // }); + // } + // + // if (deleteChildren) { + // // nuke of page tree + // pendingChanges.push({ + // pageId: deleteId + // }); + // + // this.get('documentService').deletePages(documentId, deleteId, pendingChanges).then(() => { + // // update our models so we don't have to reload from db + // for (var i = 0; i < pendingChanges.length; i++) { + // let pageId = pendingChanges[i].pageId; + // this.set('model.pages', _.reject(pages, function (p) { //jshint ignore: line + // return p.get('id') === pageId; + // })); + // } + // + // this.set('model.pages', _.sortBy(pages, "sequence")); + // this.get('target.router').refresh(); + // }); + // } else { + // // page delete followed by re-leveling child pages + // this.get('documentService').deletePage(documentId, deleteId).then(() => { + // this.set('model.pages', _.reject(pages, function (p) { + // return p.get('id') === deleteId; + // })); + // + // this.send('onPageLevelChange', pendingChanges); + // }); + // } + // }, + // + // onInsertSection(data) { + // return new Ember.RSVP.Promise((resolve) => { + // this.get('documentService').addPage(this.get('model.document.id'), data).then((newPage) => { + // let data = this.get('store').normalize('page', newPage); + // this.get('store').push(data); + // + // this.get('documentService').getPages(this.get('model.document.id')).then((pages) => { + // this.set('model.allPages', pages); + // this.set('model.pages', pages.filterBy('pageType', 'section')); + // this.set('model.tabs', pages.filterBy('pageType', 'tab')); + // + // resolve(newPage.id); + // + // // this.get('documentService').getPageMeta(this.get('model.document.id'), newPage.id).then(() => { + // // console.log("ready to edit"); + // // // this.transitionToRoute('document.edit', + // // // this.get('model.folder.id'), + // // // this.get('model.folder.slug'), + // // // this.get('model.document.id'), + // // // this.get('model.document.slug'), + // // // newPage.id); + // // }); + // }); + // }); + // }); + // }, + // + // // to test + // onPageSequenceChange(changes) { + // this.get('documentService').changePageSequence(this.get('model.document.id'), changes).then(() => { + // _.each(changes, (change) => { + // let pageContent = _.findWhere(this.get('model.pages'), { + // id: change.pageId + // }); + // + // if (is.not.undefined(pageContent)) { + // pageContent.set('sequence', change.sequence); + // } + // }); + // + // this.set('model.pages', this.get('model.pages').sortBy('sequence')); + // this.get('target.router').refresh(); + // }); + // }, + // + // // to test + // onPageLevelChange(changes) { + // this.get('documentService').changePageLevel(this.get('model.document.id'), changes).then(() => { + // _.each(changes, (change) => { + // let pageContent = _.findWhere(this.get('model.pages'), { + // id: change.pageId + // }); + // + // if (is.not.undefined(pageContent)) { + // pageContent.set('level', change.level); + // } + // }); + // + // let pages = this.get('model.pages'); + // pages = pages.sortBy('sequence'); + // this.set('model.pages', []); + // this.set('model.pages', pages); + // this.get('target.router').refresh(); + // }); + // }, + // + // // to test + // gotoPage(pageId) { + // if (is.null(pageId)) { + // return; + // } + // + // this.scrollToPage(pageId); + // }, + // + // // to test + // onSavePageAsBlock(block) { + // this.get('sectionService').addBlock(block).then(() => { + // this.showNotification("Published"); + // }); + // } + // } }); /* diff --git a/app/app/pods/document/index/controller.js b/app/app/pods/document/index/controller.js new file mode 100644 index 00000000..2361d1cb --- /dev/null +++ b/app/app/pods/document/index/controller.js @@ -0,0 +1,321 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +import Ember from 'ember'; +import NotifierMixin from '../../../mixins/notifier'; + +export default Ember.Controller.extend(NotifierMixin, { + documentService: Ember.inject.service('document'), + templateService: Ember.inject.service('template'), + sectionService: Ember.inject.service('section'), + page: null, + folder: {}, + pages: [], + toggled: false, + + // to test + // to test + // Jump to the right part of the document. + scrollToPage(pageId) { + Ember.run.schedule('afterRender', function () { + let dest; + let target = "#page-title-" + pageId; + let targetOffset = $(target).offset(); + + if (is.undefined(targetOffset)) { + return; + } + + dest = targetOffset.top > $(document).height() - $(window).height() ? $(document).height() - $(window).height() : targetOffset.top; + // small correction to ensure we also show page title + dest = dest > 50 ? dest - 74 : dest; + + $("html,body").animate({ + scrollTop: dest + }, 500, "linear"); + $(".toc-index-item").removeClass("selected"); + $("#index-" + pageId).addClass("selected"); + }); + }, + + actions: { + toggleSidebar() { + this.set('toggled', !this.get('toggled')); + }, + + onTagChange(tags) { + let doc = this.get('model.document'); + doc.set('tags', tags); + this.get('documentService').save(doc); + }, + + onSaveDocument(doc) { + this.get('documentService').save(doc); + this.showNotification('Saved'); + }, + + onCopyPage(pageId, targetDocumentId) { + let documentId = this.get('model.document.id'); + this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => { + this.showNotification("Copied"); + + // refresh data if copied to same document + if (documentId === targetDocumentId) { + this.get('target.router').refresh(); + } + }); + }, + + onMovePage(pageId, targetDocumentId) { + let documentId = this.get('model.document.id'); + + this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => { + this.showNotification("Moved"); + + this.send('onPageDeleted', { id: pageId, children: false }); + }); + }, + + onSavePage(page, meta) { + let self = this; + let documentId = this.get('model.document.id'); + let model = { + page: page.toJSON({ includeId: true }), + meta: meta.toJSON({ includeId: true }) + }; + + this.get('documentService').updatePage(documentId, page.get('id'), model).then(function () { + self.audit.record("edited-page"); + self.get('documentService').getPages(documentId).then((pages) => { + self.set('model.pages', pages); + }); + + }); + }, + + onPageDeleted(deletePage) { + let documentId = this.get('model.document.id'); + let pages = this.get('model.pages'); + let deleteId = deletePage.id; + let deleteChildren = deletePage.children; + let page = _.findWhere(pages, { + id: deleteId + }); + let pageIndex = _.indexOf(pages, page, false); + let pendingChanges = []; + + this.audit.record("deleted-page"); + + // select affected pages + for (var i = pageIndex + 1; i < pages.get('length'); i++) { + if (pages[i].get('level') <= page.get('level')) { + break; + } + + pendingChanges.push({ + pageId: pages[i].get('id'), + level: pages[i].get('level') - 1 + }); + } + + if (deleteChildren) { + // nuke of page tree + pendingChanges.push({ + pageId: deleteId + }); + + this.get('documentService').deletePages(documentId, deleteId, pendingChanges).then(() => { + // update our models so we don't have to reload from db + for (var i = 0; i < pendingChanges.length; i++) { + let pageId = pendingChanges[i].pageId; + this.set('model.pages', _.reject(pages, function (p) { //jshint ignore: line + return p.get('id') === pageId; + })); + } + + this.set('model.pages', _.sortBy(pages, "sequence")); + this.get('target.router').refresh(); + }); + } else { + // page delete followed by re-leveling child pages + this.get('documentService').deletePage(documentId, deleteId).then(() => { + this.set('model.pages', _.reject(pages, function (p) { + return p.get('id') === deleteId; + })); + + this.send('onPageLevelChange', pendingChanges); + }); + } + }, + + onInsertSection(data) { + return new Ember.RSVP.Promise((resolve) => { + this.get('documentService').addPage(this.get('model.document.id'), data).then((newPage) => { + let data = this.get('store').normalize('page', newPage); + this.get('store').push(data); + + this.get('documentService').getPages(this.get('model.document.id')).then((pages) => { + this.set('model.pages', pages); + resolve(newPage.id); + }); + }); + }); + }, + + onEditSection(pageId) { + this.transitionToRoute('document.section', + this.get('model.folder.id'), + this.get('model.folder.slug'), + this.get('model.document.id'), + this.get('model.document.slug'), + pageId); + }, + + // to test + onPageSequenceChange(changes) { + this.get('documentService').changePageSequence(this.get('model.document.id'), changes).then(() => { + _.each(changes, (change) => { + let pageContent = _.findWhere(this.get('model.pages'), { + id: change.pageId + }); + + if (is.not.undefined(pageContent)) { + pageContent.set('sequence', change.sequence); + } + }); + + this.set('model.pages', this.get('model.pages').sortBy('sequence')); + this.get('target.router').refresh(); + }); + }, + + // to test + onPageLevelChange(changes) { + this.get('documentService').changePageLevel(this.get('model.document.id'), changes).then(() => { + _.each(changes, (change) => { + let pageContent = _.findWhere(this.get('model.pages'), { + id: change.pageId + }); + + if (is.not.undefined(pageContent)) { + pageContent.set('level', change.level); + } + }); + + let pages = this.get('model.pages'); + pages = pages.sortBy('sequence'); + this.set('model.pages', []); + this.set('model.pages', pages); + this.get('target.router').refresh(); + }); + }, + + // to test + gotoPage(pageId) { + if (is.null(pageId)) { + return; + } + + this.scrollToPage(pageId); + }, + + // to test + onSavePageAsBlock(block) { + this.get('sectionService').addBlock(block).then(() => { + this.showNotification("Published"); + }); + } + } +}); + +/* +gotoPage(pageId) { + if (is.null(pageId)) { + return; + } + + this.scrollToPage(pageId); +}, + + +onSaveTemplate(name, desc) { + this.get('templateService').saveAsTemplate(this.get('model.document.id'), name, desc).then(function () {}); +}, + +onSaveMeta(doc) { + this.get('documentService').save(doc).then(() => { + this.transitionToRoute('document.index'); + }); +}, + +onInsertBlock(block) { + this.audit.record("added-content-block-" + block.get('contentType')); + + let page = { + documentId: this.get('model.document.id'), + title: `${block.get('title')}`, + level: 1, + sequence: 0, + body: block.get('body'), + contentType: block.get('contentType'), + pageType: block.get('pageType'), + blockId: block.get('id') + }; + + let meta = { + documentId: this.get('model.document.id'), + rawBody: block.get('rawBody'), + config: block.get('config'), + externalSource: block.get('externalSource') + }; + + let model = { + page: page, + meta: meta + }; + + this.get('documentService').addPage(this.get('model.document.id'), model).then((newPage) => { + let data = this.get('store').normalize('page', newPage); + this.get('store').push(data); + + this.get('documentService').getPages(this.get('model.document.id')).then((pages) => { + this.set('model.pages', pages.filterBy('pageType', 'section')); + this.set('model.tabs', pages.filterBy('pageType', 'tab')); + + this.get('documentService').getPageMeta(this.get('model.document.id'), newPage.id).then(() => { + this.transitionToRoute('document.edit', + this.get('model.folder.id'), + this.get('model.folder.slug'), + this.get('model.document.id'), + this.get('model.document.slug'), + newPage.id); + }); + }); + }); +}, + +onDeleteBlock(blockId) { + this.get('sectionService').deleteBlock(blockId).then(() => { + this.audit.record("deleted-block"); + this.send("showNotification", "Deleted"); + this.transitionToRoute('document.index'); + }); +}, + +onDocumentDelete() { + this.get('documentService').deleteDocument(this.get('model.document.id')).then(() => { + this.audit.record("deleted-page"); + this.send("showNotification", "Deleted"); + this.transitionToRoute('folder', this.get('model.folder.id'), this.get('model.folder.slug')); + }); +} + +*/ diff --git a/app/app/pods/document/index/route.js b/app/app/pods/document/index/route.js new file mode 100644 index 00000000..ab1bf024 --- /dev/null +++ b/app/app/pods/document/index/route.js @@ -0,0 +1,46 @@ +// Copyright 2016 Documize Inc. . All rights reserved. +// +// This software (Documize Community Edition) is licensed under +// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html +// +// You can operate outside the AGPL restrictions by purchasing +// Documize Enterprise Edition and obtaining a commercial license +// by contacting . +// +// https://documize.com + +import Ember from 'ember'; +import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; + +export default Ember.Route.extend(AuthenticatedRouteMixin, { + documentService: Ember.inject.service('document'), + linkService: Ember.inject.service('link'), + folderService: Ember.inject.service('folder'), + userService: Ember.inject.service('user'), + queryParams: { + page: { + refreshModel: false + } + }, + + beforeModel(transition) { + this.set('pageId', is.not.undefined(transition.queryParams.page) ? transition.queryParams.page : ""); + }, + + model() { + let document = this.modelFor('document').document; + this.browser.setTitle(document.get('name')); + this.browser.setMetaDescription(document.get('excerpt')); + + return Ember.RSVP.hash({ + folders: this.modelFor('document').folders, + folder: this.modelFor('document').folder, + document: this.modelFor('document').document, + page: this.get('pageId'), + isEditor: this.get('folderService').get('canEditCurrentFolder'), + pages: this.modelFor('document').pages, + links: this.modelFor('document').links, + sections: this.modelFor('document').sections + }); + } +}); diff --git a/app/app/pods/document/index/template.hbs b/app/app/pods/document/index/template.hbs new file mode 100644 index 00000000..13ba291b --- /dev/null +++ b/app/app/pods/document/index/template.hbs @@ -0,0 +1,73 @@ +
+ + +
+
+
+
+ {{#if toggled}} + + {{else}} + + {{/if}} +
+
+ {{#link-to 'folder' model.folder.id model.folder.slug}} + arrow_back {{model.folder.name}} + {{/link-to}} +
+ {{document/document-heading document=model.document isEditor=model.isEditor onSaveDocument=(action 'onSaveDocument')}} + {{document/document-view document=model.document links=model.links pages=model.pages + folder=model.folder folders=model.folders sections=model.sections isEditor=model.isEditor onSavePage=(action 'onSavePage') gotoPage=(action 'gotoPage') onInsertSection=(action 'onInsertSection') onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted') onEditSection=(action 'onEditSection')}} +
+
+
+
+
+
diff --git a/app/app/pods/document/route.js b/app/app/pods/document/route.js index 03c8d4f5..11ec2ed6 100644 --- a/app/app/pods/document/route.js +++ b/app/app/pods/document/route.js @@ -16,6 +16,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, { sectionService: Ember.inject.service('section'), documentService: Ember.inject.service('document'), folderService: Ember.inject.service('folder'), + linkService: Ember.inject.service('link'), beforeModel(transition) { this.set('pageId', is.not.undefined(transition.queryParams.page) ? transition.queryParams.page : ""); @@ -36,9 +37,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, { this.set('isEditor', this.get('folderService').get('canEditCurrentFolder')); this.get('documentService').getPages(this.get('documentId')).then((pages) => { - this.set('allPages', pages); - this.set('pages', pages.filterBy('pageType', 'section')); - this.set('tabs', pages.filterBy('pageType', 'tab')); + this.set('pages', pages); resolve(); }); }); @@ -55,16 +54,19 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, { document: this.get('document'), page: this.get('pageId'), isEditor: this.get('isEditor'), - allPages: this.get('allPages'), pages: this.get('pages'), - tabs: this.get('tabs'), - sections: this.get('sectionService').getAll().then((sections) => { - return sections; - // return sections.filterBy('pageType', 'section'); - // return sections.filterBy('pageType', 'tab'); - }), + links: this.get('linkService').getDocumentLinks(this.get('documentId')), + sections: this.get('sectionService').getAll() }); }, + + activate() { + $('body').addClass('background-color-off-white'); + }, + + deactivate() { + $('body').removeClass('background-color-off-white'); + }, actions: { error(error /*, transition*/ ) { diff --git a/app/app/pods/document/section/controller.js b/app/app/pods/document/section/controller.js index fac8ed73..64bcc8ba 100644 --- a/app/app/pods/document/section/controller.js +++ b/app/app/pods/document/section/controller.js @@ -18,6 +18,14 @@ export default Ember.Controller.extend(NotifierMixin, { mode: null, actions: { + onCancel() { + this.transitionToRoute('document.index', + this.get('model.folder.id'), + this.get('model.folder.slug'), + this.get('model.document.id'), + this.get('model.document.slug')); + }, + onAction(page, meta) { this.showNotification("Saving"); @@ -30,17 +38,13 @@ export default Ember.Controller.extend(NotifierMixin, { this.audit.record("edited-page"); let data = this.get('store').normalize('page', page); this.get('store').push(data); - this.get('target.router').refresh(); + + this.transitionToRoute('document.index', + this.get('model.folder.id'), + this.get('model.folder.slug'), + this.get('model.document.id'), + this.get('model.document.slug')); }); }, - - onDelete(document, page) { - this.get('documentService').deletePage(document.get('id'), page.get('id')).then(() => { - this.audit.record("deleted-page"); - this.showNotification('Deleted'); - this.transitionToRoute('document'); - this.get('target.router').refresh(); - }); - } } }); diff --git a/app/app/pods/document/section/route.js b/app/app/pods/document/section/route.js index 79aab403..68d3f7f2 100644 --- a/app/app/pods/document/section/route.js +++ b/app/app/pods/document/section/route.js @@ -32,12 +32,21 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, { folders: this.modelFor('document').folders, folder: this.modelFor('document').folder, document: this.modelFor('document').document, + pageId: this.modelFor('document').page, + isEditor: this.get('folderService').get('canEditCurrentFolder'), pages: this.modelFor('document').pages, - tabs: this.get('documentService').getPages(this.modelFor('document').document.get('id')).then((pages) => { - return pages.filterBy('pageType', 'tab'); - }), + links: this.modelFor('document').links, + sections: this.modelFor('document').sections, page: this.get('documentService').getPage(this.modelFor('document').document.get('id'), params.page_id), meta: this.get('documentService').getPageMeta(this.modelFor('document').document.get('id'), params.page_id) }); }, + + activate() { + $('body').addClass('background-color-off-white'); + }, + + deactivate() { + $('body').removeClass('background-color-off-white'); + } }); diff --git a/app/app/pods/document/section/template.hbs b/app/app/pods/document/section/template.hbs index 5c381c71..5076ce87 100644 --- a/app/app/pods/document/section/template.hbs +++ b/app/app/pods/document/section/template.hbs @@ -1 +1,17 @@ -{{document/document-tab mode=mode model=model onAction=(action 'onAction') onDelete=(action 'onDelete')}} +
+
+
+
+
+
+ {{#link-to 'document.index' model.folder.id model.folder.slug model.document.id model.document.slug}} + arrow_back {{model.document.name}} + {{/link-to}} +
+ {{document/document-heading document=model.document isEditor=false}} + {{document/document-editor document=model.document folder=model.folder page=model.page meta=model.meta onCancel=(action 'onCancel') onAction=(action 'onAction')}} +
+
+
+
+
diff --git a/app/app/pods/document/template.hbs b/app/app/pods/document/template.hbs index 61bfb15d..6583eac5 100644 --- a/app/app/pods/document/template.hbs +++ b/app/app/pods/document/template.hbs @@ -1,75 +1,2 @@ {{layout/zone-navigation}} - -
- - -
-
-
-
- {{#if toggled}} - - {{else}} - - {{/if}} -
-
- {{#link-to 'folder' model.folder.id model.folder.slug}} - arrow_back {{model.folder.name}} - {{/link-to}} -
- {{document/document-heading document=model.document isEditor=model.isEditor onSaveDocument=(action 'onSaveDocument')}} - {{document/document-view document=model.document links=model.links allPages=model.allPages tabs=model.tabs pages=model.pages - folder=model.folder folders=model.folders sections=model.sections isEditor=model.isEditor onSavePage=(action 'onSavePage') gotoPage=(action 'gotoPage') onInsertSection=(action 'onInsertSection') onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')}} -
-
-
-
-
-
+{{outlet}} diff --git a/app/app/pods/document/zindex/controller.js b/app/app/pods/document/zindex/controller.js deleted file mode 100644 index 2eabd9a4..00000000 --- a/app/app/pods/document/zindex/controller.js +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2016 Documize Inc. . All rights reserved. -// -// This software (Documize Community Edition) is licensed under -// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html -// -// You can operate outside the AGPL restrictions by purchasing -// Documize Enterprise Edition and obtaining a commercial license -// by contacting . -// -// https://documize.com - -import Ember from 'ember'; -import NotifierMixin from '../../../mixins/notifier'; - -export default Ember.Controller.extend(NotifierMixin, { - documentService: Ember.inject.service('document'), - sectionService: Ember.inject.service('section'), - queryParams: ['page'], - - // Jump to the right part of the document. - scrollToPage(pageId) { - Ember.run.schedule('afterRender', function () { - let dest; - let target = "#page-title-" + pageId; - let targetOffset = $(target).offset(); - - if (is.undefined(targetOffset)) { - return; - } - - dest = targetOffset.top > $(document).height() - $(window).height() ? $(document).height() - $(window).height() : targetOffset.top; - // small correction to ensure we also show page title - dest = dest > 50 ? dest - 74 : dest; - - $("html,body").animate({ - scrollTop: dest - }, 500, "linear"); - $(".toc-index-item").removeClass("selected"); - $("#index-" + pageId).addClass("selected"); - }); - }, - - actions: { - gotoPage(pageId) { - if (is.null(pageId)) { - return; - } - - this.scrollToPage(pageId); - }, - - onPageSequenceChange(changes) { - this.get('documentService').changePageSequence(this.get('model.document.id'), changes).then(() => { - _.each(changes, (change) => { - let pageContent = _.findWhere(this.get('model.pages'), { - id: change.pageId - }); - - if (is.not.undefined(pageContent)) { - pageContent.set('sequence', change.sequence); - } - }); - - this.set('model.pages', this.get('model.pages').sortBy('sequence')); - this.get('target.router').refresh(); - }); - }, - - onPageLevelChange(changes) { - this.get('documentService').changePageLevel(this.get('model.document.id'), changes).then(() => { - _.each(changes, (change) => { - let pageContent = _.findWhere(this.get('model.pages'), { - id: change.pageId - }); - - if (is.not.undefined(pageContent)) { - pageContent.set('level', change.level); - } - }); - - let pages = this.get('model.pages'); - pages = pages.sortBy('sequence'); - this.set('model.pages', pages); - - this.get('target.router').refresh(); - }); - }, - - - } -}); diff --git a/app/app/pods/document/zindex/route.js b/app/app/pods/document/zindex/route.js deleted file mode 100644 index 1bb91b2f..00000000 --- a/app/app/pods/document/zindex/route.js +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2016 Documize Inc. . All rights reserved. -// -// This software (Documize Community Edition) is licensed under -// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html -// -// You can operate outside the AGPL restrictions by purchasing -// Documize Enterprise Edition and obtaining a commercial license -// by contacting . -// -// https://documize.com - -import Ember from 'ember'; -import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; - -export default Ember.Route.extend(AuthenticatedRouteMixin, { - documentService: Ember.inject.service('document'), - linkService: Ember.inject.service('link'), - folderService: Ember.inject.service('folder'), - userService: Ember.inject.service('user'), - queryParams: { - page: { - refreshModel: false - } - }, - - beforeModel(transition) { - this.set('pageId', is.not.undefined(transition.queryParams.page) ? transition.queryParams.page : ""); - this.set('folderId', this.paramsFor('document').folder_id); - this.set('documentId', this.paramsFor('document').document_id); - - let folders = this.get('store').peekAll('folder'); - let folder = this.get('store').peekRecord('folder', this.get('folderId')); - let document = this.get('store').peekRecord('document', this.get('documentId')); - - this.set('document', document); - this.set('folders', folders); - this.set('folder', folder); - - return new Ember.RSVP.Promise((resolve) => { - this.get('documentService').getPages(this.get('documentId')).then((pages) => { - this.set('allPages', pages); - this.set('pages', pages.filterBy('pageType', 'section')); - this.set('tabs', pages.filterBy('pageType', 'tab')); - resolve(); - }); - }); - - }, - - model() { - this.browser.setTitle(this.get('document.name')); - this.browser.setMetaDescription(this.get('document.excerpt')); - - return Ember.RSVP.hash({ - folders: this.get('folders'), - folder: this.get('folder'), - document: this.get('document'), - page: this.get('pageId'), - isEditor: this.get('folderService').get('canEditCurrentFolder'), - allPages: this.get('allPages'), - pages: this.get('pages'), - tabs: this.get('tabs'), - links: this.get('linkService').getDocumentLinks(this.get('documentId')) - }); - } -}); diff --git a/app/app/pods/document/zindex/template.hbs b/app/app/pods/document/zindex/template.hbs deleted file mode 100644 index e69de29b..00000000 diff --git a/app/app/pods/document/wizard/controller.js b/app/app/pods/document/zwizard/controller.js similarity index 100% rename from app/app/pods/document/wizard/controller.js rename to app/app/pods/document/zwizard/controller.js diff --git a/app/app/pods/document/wizard/route.js b/app/app/pods/document/zwizard/route.js similarity index 100% rename from app/app/pods/document/wizard/route.js rename to app/app/pods/document/zwizard/route.js diff --git a/app/app/pods/document/wizard/template.hbs b/app/app/pods/document/zwizard/template.hbs similarity index 100% rename from app/app/pods/document/wizard/template.hbs rename to app/app/pods/document/zwizard/template.hbs diff --git a/app/app/router.js b/app/app/router.js index 9fff32c0..56f9303d 100644 --- a/app/app/router.js +++ b/app/app/router.js @@ -44,9 +44,9 @@ export default Router.map(function () { // this.route('edit', { // path: 'edit/:page_id' // }); - this.route('wizard', { - path: 'add' - }); + // this.route('wizard', { + // path: 'add' + // }); this.route('history', { path: 'history' }); diff --git a/app/app/styles/color.scss b/app/app/styles/color.scss index 7c75ac12..42e57285 100644 --- a/app/app/styles/color.scss +++ b/app/app/styles/color.scss @@ -78,6 +78,9 @@ $color-wysiwyg: #3c3c3c; .background-color-white { background-color: $color-white !important; } +.background-color-off-white { + background-color: $color-off-white !important; +} .background-color-primary { background-color: $color-primary !important; } diff --git a/app/app/styles/view/document/all.scss b/app/app/styles/view/document/all.scss index 44aa501b..6c20d016 100644 --- a/app/app/styles/view/document/all.scss +++ b/app/app/styles/view/document/all.scss @@ -1,9 +1,10 @@ @import "activity.scss"; @import "edit-tools.scss"; -@import "editor.scss"; @import "files.scss"; @import "history.scss"; +@import "inline-editor.scss"; @import "layout.scss"; +@import "section-editor.scss"; @import "sidebar.scss"; @import "toolbar.scss"; @import "view.scss"; diff --git a/app/app/styles/view/document/editor.scss b/app/app/styles/view/document/inline-editor.scss similarity index 100% rename from app/app/styles/view/document/editor.scss rename to app/app/styles/view/document/inline-editor.scss diff --git a/app/app/styles/view/document/section-editor.scss b/app/app/styles/view/document/section-editor.scss new file mode 100644 index 00000000..f58dfc31 --- /dev/null +++ b/app/app/styles/view/document/section-editor.scss @@ -0,0 +1,33 @@ +.zone-section-editor { + // min-height: 500px; //ensure dropdowns render in viewport + // height: 100%; + margin-left: 60px; + padding: 20px 60px; + z-index: 777; + position: relative; + + + .section-editor { + @extend .transition-all; + @include border-radius(2px); + @include ease-in(); + position: relative; + padding: 25px 50px; + box-shadow: 0 0 0 0.75pt $color-stroke,0 0 3pt 0.75pt $color-stroke; + background-color: $color-white; + + + > .buttons { + margin-top: 17px; + float: right; + } + + > .canvas { + padding: 0; + } + + .cancel-edits-dialog { + display: none; + } + } +} diff --git a/app/app/styles/view/document/section.scss b/app/app/styles/view/document/section.scss deleted file mode 100644 index e17965e1..00000000 --- a/app/app/styles/view/document/section.scss +++ /dev/null @@ -1,9 +0,0 @@ -.document-section { - > .toolbar { - margin-bottom: 10px; - - > .buttons { - margin: 10px 0; - } - } -} diff --git a/app/app/styles/view/document/view.scss b/app/app/styles/view/document/view.scss index bdae9389..fc0da62f 100644 --- a/app/app/styles/view/document/view.scss +++ b/app/app/styles/view/document/view.scss @@ -4,7 +4,6 @@ margin-left: 60px; padding: 30px 70px; z-index: 777; - background-color: $color-off-white; } .zone-document-content { @@ -56,13 +55,12 @@ .document-view { margin: 0 0 50px 0; - max-width: 1200px; .is-a-page { @extend .transition-all; @include border-radius(2px); @include ease-in(); - padding: 50px; + padding: 25px 50px; box-shadow: 0 0 0 0.75pt $color-stroke,0 0 3pt 0.75pt $color-stroke; background-color: $color-white; @@ -81,6 +79,72 @@ } } + .is-a-tab { + // @extend .transition-all; + @include border-radius(2px); + @include ease-in(); + padding: 25px 50px; + box-shadow: 0 0 0 0.75pt $color-stroke,0 0 3pt 0.75pt $color-stroke; + background-color: $color-white; + + .icon { + text-align: center; + display: inline-block; + width: 40px; + vertical-align: bottom; + margin-right: 5px; + + > .img { + text-align: center; + display: inline-block; + height: 30px; + width: 30px; + } + } + + > .title { + font-size: 1.3rem; + font-weight: normal; + color: $color-off-black; + letter-spacing: 0.5px; + margin-top: 8px; + } + + &:hover { + .page-title { + > .page-toolbar { + opacity: 1; + } + } + } + + .page-title { + > .page-toolbar { + opacity: 0; + } + } + } + + .tab-min { + padding: 0px 50px; + height: 65px; + overflow: hidden; + cursor: normal; + + .page-title { + > .page-toolbar { + opacity: 1; + } + } + } + + .tab-max { + padding: 25px 50px; + height: auto; + overflow: auto; + cursor: normal; + } + .section-divider { height: 60px; background-color: transparent; diff --git a/app/app/templates/components/document/document-page.hbs b/app/app/templates/components/document/document-page.hbs index c32ebc82..3ee8f85e 100644 --- a/app/app/templates/components/document/document-page.hbs +++ b/app/app/templates/components/document/document-page.hbs @@ -1,9 +1,9 @@
{{#unless editMode}} - {{document/page-heading tagName=page.tagName document=document folder=folder page=page isEditor=isEditor - onEdit=(action 'onEdit') - onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}} - {{section/base-renderer page=page}} + {{document/page-heading tagName=page.tagName document=document folder=folder page=page isEditor=isEditor tabMode=tabMode + onEdit=(action 'onEdit') + onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}} + {{section/base-renderer page=page}} {{else}} {{document/document-editor document=document folder=folder page=page meta=meta onCancel=(action 'onCancelEdit') onAction=(action 'onSavePage')}} {{/unless}} diff --git a/app/app/templates/components/document/document-tab.hbs b/app/app/templates/components/document/document-tab.hbs index 82553d27..f7e20273 100644 --- a/app/app/templates/components/document/document-tab.hbs +++ b/app/app/templates/components/document/document-tab.hbs @@ -1,31 +1,7 @@ -
- {{#if viewMode}} -
-
-

{{model.page.title}}

-
-
-
- edit -
-
-
- delete -
-
-
-
-
- {{#dropdown-dialog target="delete-section-button" position="bottom right" button="Delete" color="flat-red" onAction=(action 'onDelete')}} -

Are you sure you want to delete this section?

-

There is no undo!

- {{/dropdown-dialog}} - - {{section/base-renderer page=model.page}} -
- {{/if}} - - {{#if editMode}} - {{document/document-editor document=model.document folder=model.folder page=model.page meta=model.meta onCancel=(action 'onCancel') onAction=(action 'onAction')}} +
+ {{document/tab-heading tagName=page.tagName document=document folder=folder page=page isEditor=isEditor + onExpand=(action 'onExpand') onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}} + {{#if expanded}} + {{section/base-renderer page=page}} {{/if}}
diff --git a/app/app/templates/components/document/document-view.hbs b/app/app/templates/components/document/document-view.hbs index 68f2f4b5..9a9e6da9 100644 --- a/app/app/templates/components/document/document-view.hbs +++ b/app/app/templates/components/document/document-view.hbs @@ -12,10 +12,18 @@ {{else}}
{{/if}} - {{#document/document-page document=document folder=folder page=page isEditor=isEditor toEdit=toEdit - onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock') - onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}} - {{/document/document-page}} + {{#if (is-equal page.pageType 'section')}} + {{#document/document-page document=document folder=folder page=page isEditor=isEditor toEdit=toEdit + onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock') + onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}} + {{/document/document-page}} + {{/if}} + {{#if (is-equal page.pageType 'tab')}} + {{#document/document-tab document=document folder=folder page=page isEditor=isEditor + onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock') + onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage')}} + {{/document/document-tab}} + {{/if}} {{else}} no sections!
diff --git a/app/app/templates/components/document/tab-heading.hbs b/app/app/templates/components/document/tab-heading.hbs new file mode 100644 index 00000000..18e07ff8 --- /dev/null +++ b/app/app/templates/components/document/tab-heading.hbs @@ -0,0 +1,92 @@ +
+
+ +
+ {{ page.title }} + +
diff --git a/app/app/templates/components/section/base-editor.hbs b/app/app/templates/components/section/base-editor.hbs index 7add5190..feaf29b8 100644 --- a/app/app/templates/components/section/base-editor.hbs +++ b/app/app/templates/components/section/base-editor.hbs @@ -1,44 +1,33 @@ -
-
-
-
- -
{{tip}}
- {{focus-input type='text' id="page-title" value=page.title class="mousetrap"}} -
- {{#if hasExcerpt}} -
-
- -
Short description
- {{textarea rows="3" id="page-excerpt" value=page.excerpt class="mousetrap"}} -
-
- {{/if}} +
+
+ {{#if busy}} + + {{/if}} +
{{cancelLabel}}
+
+
{{actionLabel}}
+
+
+
+
+ +
{{tip}}
+ {{focus-input type='text' id="page-title" value=page.title class="mousetrap"}}
-
- {{#if busy}} - - {{/if}} -
{{cancelLabel}}
-
-
{{actionLabel}}
+
+
{{yield}} diff --git a/core/section/gemini/model.go b/core/section/gemini/model.go index 9db08a93..6c10158e 100644 --- a/core/section/gemini/model.go +++ b/core/section/gemini/model.go @@ -21,7 +21,7 @@ import ( // the HTML that is rendered by this section. const renderTemplate = ` {{if .Authenticated}} -

The Gemini workspace {{.Config.WorkspaceName}} contains {{.Config.ItemCount}} items.

+

The Gemini workspace {{.Config.WorkspaceName}} contains {{.Config.ItemCount}} items.

diff --git a/core/section/papertrail/model.go b/core/section/papertrail/model.go index 914ce855..e61f056f 100644 --- a/core/section/papertrail/model.go +++ b/core/section/papertrail/model.go @@ -16,7 +16,7 @@ import "strings" // the HTML that is rendered by this section. const renderTemplate = ` {{if .HasData}} -

The Papertrail log for query {{.Config.Query}} contains {{.Count}} entries.

+

The Papertrail log for query {{.Config.Query}} contains {{.Count}} entries.