mirror of
https://github.com/documize/community.git
synced 2025-07-19 21:29:42 +02:00
add/edit smart sections
This commit is contained in:
parent
be4a95df96
commit
a7ac034d2c
33 changed files with 1209 additions and 603 deletions
|
@ -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;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
|
|
200
app/app/components/document/tab-heading.js
Normal file
200
app/app/components/document/tab-heading.js
Normal file
|
@ -0,0 +1,200 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. 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 <sales@documize.com>.
|
||||
//
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,6 +1,5 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
{{content-for 'head'}}
|
||||
<meta charset="utf-8">
|
||||
|
@ -17,7 +16,6 @@
|
|||
<link rel="stylesheet" href="/assets/documize.css">
|
||||
{{content-for 'head-footer'}}
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{content-for 'body'}}
|
||||
<script src="/assets/vendor.js"></script>
|
||||
|
@ -29,5 +27,4 @@
|
|||
<script src="/codemirror/addon/runmode/colorize.js"></script>
|
||||
{{content-for 'body-footer'}}
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
|
|
@ -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");
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
});
|
||||
|
||||
/*
|
||||
|
|
321
app/app/pods/document/index/controller.js
Normal file
321
app/app/pods/document/index/controller.js
Normal file
|
@ -0,0 +1,321 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. 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 <sales@documize.com>.
|
||||
//
|
||||
// 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'));
|
||||
});
|
||||
}
|
||||
|
||||
*/
|
46
app/app/pods/document/index/route.js
Normal file
46
app/app/pods/document/index/route.js
Normal file
|
@ -0,0 +1,46 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. 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 <sales@documize.com>.
|
||||
//
|
||||
// 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
|
||||
});
|
||||
}
|
||||
});
|
73
app/app/pods/document/index/template.hbs
Normal file
73
app/app/pods/document/index/template.hbs
Normal file
|
@ -0,0 +1,73 @@
|
|||
<div id="wrapper" class={{if toggled 'toggled'}}>
|
||||
<div id="sidebar-wrapper">
|
||||
<div class="document-sidebar-content">
|
||||
{{#if model.document.template}}
|
||||
<div class="is-template">TEMPLATE</div>
|
||||
{{/if}}
|
||||
{{document/tag-editor documentTags=model.document.tags isEditor=model.isEditor onChange=(action 'onTagChange')}}
|
||||
{{#layout/zone-document-sidebar}}
|
||||
{{/layout/zone-document-sidebar}}
|
||||
</div>
|
||||
<div class="document-sidebar-toolbar">
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">more_horiz</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">view_headline</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">attach_file</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">timeline</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">person</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">chat_bubble</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">share</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="page-content-wrapper">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{{#if toggled}}
|
||||
<div id="sidebar-toggle" class="pull-right" {{action 'toggleSidebar'}}>
|
||||
<div class="round-button button-black">
|
||||
<i class="material-icons">keyboard_arrow_left</i>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div id="sidebar-toggle" class="pull-right" {{action 'toggleSidebar'}}>
|
||||
<div class="round-button button-black">
|
||||
<i class="material-icons">keyboard_arrow_right</i>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div id="zone-document-content" class="zone-document-content">
|
||||
<div class="back-to-space">
|
||||
{{#link-to 'folder' model.folder.id model.folder.slug}}
|
||||
<i class="material-icons">arrow_back</i> {{model.folder.name}}
|
||||
{{/link-to}}
|
||||
</div>
|
||||
{{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')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
|
@ -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*/ ) {
|
||||
|
|
|
@ -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();
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
});
|
||||
|
|
|
@ -1 +1,17 @@
|
|||
{{document/document-tab mode=mode model=model onAction=(action 'onAction') onDelete=(action 'onDelete')}}
|
||||
<div class="zone-section-editor">
|
||||
<div class="container">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
|
||||
<div id="zone-document-content" class="zone-document-content">
|
||||
<div class="back-to-space">
|
||||
{{#link-to 'document.index' model.folder.id model.folder.slug model.document.id model.document.slug}}
|
||||
<i class="material-icons">arrow_back</i> {{model.document.name}}
|
||||
{{/link-to}}
|
||||
</div>
|
||||
{{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')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,75 +1,2 @@
|
|||
{{layout/zone-navigation}}
|
||||
|
||||
<div id="wrapper" class={{if toggled 'toggled'}}>
|
||||
<div id="sidebar-wrapper">
|
||||
<div class="document-sidebar-content">
|
||||
{{#if model.document.template}}
|
||||
<div class="is-template">TEMPLATE</div>
|
||||
{{/if}}
|
||||
{{document/tag-editor documentTags=model.document.tags isEditor=model.isEditor onChange=(action 'onTagChange')}}
|
||||
{{#layout/zone-document-sidebar}}
|
||||
{{/layout/zone-document-sidebar}}
|
||||
</div>
|
||||
<div class="document-sidebar-toolbar">
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">more_horiz</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">view_headline</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">attach_file</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">timeline</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">person</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">chat_bubble</i>
|
||||
</div>
|
||||
<div class="margin-top-20"></div>
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">share</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="page-content-wrapper">
|
||||
<div class="container-fluid">
|
||||
<div class="row">
|
||||
<div class="col-lg-12">
|
||||
{{#if toggled}}
|
||||
<div id="sidebar-toggle" class="pull-right" {{action 'toggleSidebar'}}>
|
||||
<div class="round-button button-black">
|
||||
<i class="material-icons">keyboard_arrow_left</i>
|
||||
</div>
|
||||
</div>
|
||||
{{else}}
|
||||
<div id="sidebar-toggle" class="pull-right" {{action 'toggleSidebar'}}>
|
||||
<div class="round-button button-black">
|
||||
<i class="material-icons">keyboard_arrow_right</i>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div id="zone-document-content" class="zone-document-content">
|
||||
<div class="back-to-space">
|
||||
{{#link-to 'folder' model.folder.id model.folder.slug}}
|
||||
<i class="material-icons">arrow_back</i> {{model.folder.name}}
|
||||
{{/link-to}}
|
||||
</div>
|
||||
{{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')}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{outlet}}
|
||||
|
|
|
@ -1,91 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. 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 <sales@documize.com>.
|
||||
//
|
||||
// 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();
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
}
|
||||
});
|
|
@ -1,66 +0,0 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. 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 <sales@documize.com>.
|
||||
//
|
||||
// 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'))
|
||||
});
|
||||
}
|
||||
});
|
|
@ -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'
|
||||
});
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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";
|
||||
|
|
33
app/app/styles/view/document/section-editor.scss
Normal file
33
app/app/styles/view/document/section-editor.scss
Normal file
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
.document-section {
|
||||
> .toolbar {
|
||||
margin-bottom: 10px;
|
||||
|
||||
> .buttons {
|
||||
margin: 10px 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
<div id="page-{{ page.id }}" class="is-a-page" data-id="{{ page.id }}" data-type="{{ page.contentType }}">
|
||||
{{#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}}
|
||||
|
|
|
@ -1,31 +1,7 @@
|
|||
<div class="document-section">
|
||||
{{#if viewMode}}
|
||||
<div class="wysiwyg">
|
||||
<div>
|
||||
<h1 class="pull-left">{{model.page.title}}</h1>
|
||||
<div class="toolbar pull-right">
|
||||
<div class="buttons">
|
||||
<div class="round-button-mono" {{action 'onEdit'}}>
|
||||
<i class="material-icons color-gray">edit</i>
|
||||
</div>
|
||||
<div class="button-gap"></div>
|
||||
<div class="round-button-mono" id="delete-section-button">
|
||||
<i class="material-icons color-gray">delete</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix" />
|
||||
{{#dropdown-dialog target="delete-section-button" position="bottom right" button="Delete" color="flat-red" onAction=(action 'onDelete')}}
|
||||
<p>Are you sure you want to delete this section?</p>
|
||||
<p>There is no undo!</p>
|
||||
{{/dropdown-dialog}}
|
||||
|
||||
{{section/base-renderer page=model.page}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if editMode}}
|
||||
{{document/document-editor document=model.document folder=model.folder page=model.page meta=model.meta onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
||||
<div id="page-{{ page.id }}" class="is-a-tab {{if expanded 'tab-max' 'tab-min'}}" data-id="{{ page.id }}" data-type="{{ page.contentType }}">
|
||||
{{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}}
|
||||
</div>
|
||||
|
|
|
@ -12,10 +12,18 @@
|
|||
{{else}}
|
||||
<div class="section-divider" />
|
||||
{{/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!
|
||||
<div class="empty-state-document">
|
||||
|
|
92
app/app/templates/components/document/tab-heading.hbs
Normal file
92
app/app/templates/components/document/tab-heading.hbs
Normal file
|
@ -0,0 +1,92 @@
|
|||
<div class="page-title">
|
||||
<div class="icon">
|
||||
<img class="img" src="/sections/{{page.contentType}}.png" srcset="/sections/{{page.contentType}}@2x.png" />
|
||||
</div>
|
||||
<span id="page-title-{{ page.id }}">{{ page.title }}</span>
|
||||
<div id="page-toolbar-{{ page.id }}" class="pull-right page-toolbar hidden-xs hidden-sm">
|
||||
{{#unless expanded}}
|
||||
<div class="round-button-mono" {{action 'toggleExpand'}}>
|
||||
<i class="material-icons color-gray">expand_more</i>
|
||||
</div>
|
||||
{{else}}
|
||||
{{#if isEditor}}
|
||||
{{#link-to 'document.section' page.id}}
|
||||
<div class="round-button-mono">
|
||||
<i class="material-icons color-gray">mode_edit</i>
|
||||
</div>
|
||||
{{/link-to}}
|
||||
<div class="round-button-mono" id="page-menu-{{page.id}}">
|
||||
<i class="material-icons color-gray">more_vert</i>
|
||||
</div>
|
||||
<div class="round-button-mono" {{action 'toggleExpand'}}>
|
||||
<i class="material-icons color-gray">expand_less</i>
|
||||
</div>
|
||||
|
||||
{{#dropdown-menu target=menuTarget position="top right" open="click" onOpenCallback=(action 'onMenuOpen') onCloseCallback=(action 'onMenuOpen')}}
|
||||
<ul class="menu">
|
||||
<li class="item" id={{copyButtonId}}>Copy</li>
|
||||
<li class="item" id={{moveButtonId}}>Move</li>
|
||||
<li class="item" id={{publishButtonId}}>Publish</li>
|
||||
<li class="divider"></li>
|
||||
<li class="item danger" id={{deleteButtonId}}>Delete</li>
|
||||
</ul>
|
||||
{{/dropdown-menu}}
|
||||
|
||||
{{#if menuOpen}}
|
||||
{{#dropdown-dialog target=deleteButtonId position="bottom right" button="Delete" color="flat-red" onAction=(action 'deletePage')}}
|
||||
<p>Are you sure you want to delete <span class="bold">{{page.title}}?</span></p>
|
||||
<p>
|
||||
{{input type="checkbox" id=checkId class="margin-left-20" checked=deleteChildren}}
|
||||
<label for="{{checkId}}"> Delete child pages</label>
|
||||
</p>
|
||||
{{/dropdown-dialog}}
|
||||
{{#dropdown-dialog id=publishDialogId target=publishButtonId position="bottom right" button="Publish" color="flat-green" focusOn=blockTitleId onAction=(action 'onSavePageAsBlock')}}
|
||||
<div class="form-header">
|
||||
<div class="tip">
|
||||
<span class="bold">{{folder.name}}:</span> Content Block
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-control">
|
||||
<label>Name</label>
|
||||
<div class="tip">Short title for reusable content block</div>
|
||||
{{input type="text" value=blockTitle id=blockTitleId}}
|
||||
</div>
|
||||
<div class="input-control">
|
||||
<label>Name</label>
|
||||
<div class="tip">Short description to help others understand<br/>the reusable content block</div>
|
||||
{{textarea rows="3" value=blockExcerpt id=blockExcerptId}}
|
||||
</div>
|
||||
{{/dropdown-dialog}}
|
||||
{{#dropdown-dialog id=copyDialogId target=copyButtonId position="bottom right" button="Copy" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onCopyPage')}}
|
||||
<div class="form-header">
|
||||
<div class="tip">
|
||||
<span class="bold">Copy:</span> {{page.title}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-control">
|
||||
<label>Target</label>
|
||||
<div class="tip">Select where the content should be copied to</div>
|
||||
{{ui-select cssClass="dropdown-page-toolbar" content=documentList action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name" selection=document}}
|
||||
</div>
|
||||
{{/dropdown-dialog}}
|
||||
{{#dropdown-dialog id=moveDialogId target=moveButtonId position="bottom right" button="Move" color="flat-green" onOpenCallback=(action 'onCopyDialogOpen') onAction=(action 'onMovePage')}}
|
||||
<div class="form-header">
|
||||
<div class="tip">
|
||||
<span class="bold">move:</span> {{page.title}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-control">
|
||||
<label>Target</label>
|
||||
<div class="tip">Select where the content should be moved to</div>
|
||||
{{ui-select cssClass="dropdown-page-toolbar" content=documentListOthers action=(action 'onTargetChange') optionValuePath="id" optionLabelPath="name"}}
|
||||
</div>
|
||||
{{/dropdown-dialog}}
|
||||
{{/if}}
|
||||
{{else}}
|
||||
<div class="round-button-mono" {{action 'toggleExpand'}}>
|
||||
<i class="material-icons color-gray">expand_less</i>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
|
@ -1,44 +1,33 @@
|
|||
<div class="document-editor form-bordered">
|
||||
<div class="toolbar">
|
||||
<div class="title pull-left">
|
||||
<div class="input-control">
|
||||
<label>Title</label>
|
||||
<div class="tip">{{tip}}</div>
|
||||
{{focus-input type='text' id="page-title" value=page.title class="mousetrap"}}
|
||||
</div>
|
||||
{{#if hasExcerpt}}
|
||||
<div class="margin-top-30">
|
||||
<div class="input-control">
|
||||
<label>Excerpt</label>
|
||||
<div class="tip">Short description</div>
|
||||
{{textarea rows="3" id="page-excerpt" value=page.excerpt class="mousetrap"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<div class="section-editor">
|
||||
<div class="buttons">
|
||||
{{#if busy}}
|
||||
<img src="/assets/img/busy-gray.gif" class="busy-indicator" />
|
||||
{{/if}}
|
||||
<div id="editor-cancel" class="flat-button flat-gray" {{action 'onCancel'}}>{{cancelLabel}}</div>
|
||||
<div class="button-gap" />
|
||||
<div class="regular-button button-green" {{action 'onAction'}}>{{actionLabel}}</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="title">
|
||||
<div class="input-control">
|
||||
<label>Title</label>
|
||||
<div class="tip">{{tip}}</div>
|
||||
{{focus-input type='text' id="page-title" value=page.title class="mousetrap"}}
|
||||
</div>
|
||||
<div class="buttons pull-right">
|
||||
{{#if busy}}
|
||||
<img src="/assets/img/busy-gray.gif" class="busy-indicator" />
|
||||
{{/if}}
|
||||
<div id="editor-cancel" class="flat-button flat-gray" {{action 'onCancel'}}>{{cancelLabel}}</div>
|
||||
<div class="button-gap" />
|
||||
<div class="regular-button button-green" {{action 'onAction'}}>{{actionLabel}}</div>
|
||||
</div>
|
||||
<div class="dropdown-dialog cancel-edits-dialog">
|
||||
<div class="content">
|
||||
<p>Do you want to cancel editing and lose unsaved changes?</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="flat-button" {{action 'keepEditing'}}>
|
||||
no
|
||||
</div>
|
||||
<div class="flat-button flat-red" {{action 'discardEdits'}}>
|
||||
yes
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<div class="dropdown-dialog cancel-edits-dialog">
|
||||
<div class="content">
|
||||
<p>Do you want to cancel editing and lose unsaved changes?</p>
|
||||
</div>
|
||||
<div class="actions">
|
||||
<div class="flat-button" {{action 'keepEditing'}}>
|
||||
no
|
||||
</div>
|
||||
<div class="flat-button flat-red" {{action 'discardEdits'}}>
|
||||
yes
|
||||
</div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="canvas">
|
||||
{{yield}}
|
||||
|
|
|
@ -21,7 +21,7 @@ import (
|
|||
// the HTML that is rendered by this section.
|
||||
const renderTemplate = `
|
||||
{{if .Authenticated}}
|
||||
<p class="margin-left-20">The Gemini workspace <a href="{{.Config.URL}}/workspace/{{.Config.WorkspaceID}}/items">{{.Config.WorkspaceName}}</a> contains {{.Config.ItemCount}} items.</p>
|
||||
<p>The Gemini workspace <a href="{{.Config.URL}}/workspace/{{.Config.WorkspaceID}}/items">{{.Config.WorkspaceName}}</a> contains {{.Config.ItemCount}} items.</p>
|
||||
<table class="basic-table section-gemini-table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
|
@ -16,7 +16,7 @@ import "strings"
|
|||
// the HTML that is rendered by this section.
|
||||
const renderTemplate = `
|
||||
{{if .HasData}}
|
||||
<p class="margin-left-20">The <a href="https://papertrailapp.com">Papertrail log</a> for query <em>{{.Config.Query}}</em> contains {{.Count}} entries.</p>
|
||||
<p >The <a href="https://papertrailapp.com">Papertrail log</a> for query <em>{{.Config.Query}}</em> contains {{.Count}} entries.</p>
|
||||
<table class="basic-table section-papertrail-table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue