mirror of
https://github.com/documize/community.git
synced 2025-07-29 10:09:43 +02:00
Merge pull request #83 from documize/metreon
Problem: document UX is not that intuitive and impactful
This commit is contained in:
commit
b394d926fc
278 changed files with 24758 additions and 23376 deletions
|
@ -6,6 +6,7 @@
|
||||||
"-Promise",
|
"-Promise",
|
||||||
"moment",
|
"moment",
|
||||||
"$",
|
"$",
|
||||||
|
"jQuery",
|
||||||
"_",
|
"_",
|
||||||
"is",
|
"is",
|
||||||
"Mousetrap",
|
"Mousetrap",
|
||||||
|
@ -19,7 +20,8 @@
|
||||||
"Dropzone",
|
"Dropzone",
|
||||||
"Sortable",
|
"Sortable",
|
||||||
"datetimepicker",
|
"datetimepicker",
|
||||||
"Waypoint"
|
"Waypoint",
|
||||||
|
"velocity"
|
||||||
],
|
],
|
||||||
"browser": true,
|
"browser": true,
|
||||||
"boss": true,
|
"boss": true,
|
||||||
|
|
|
@ -31,6 +31,10 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
{ label: 'Attachment', selected: false },
|
{ label: 'Attachment', selected: false },
|
||||||
{ label: 'Search', selected: false }
|
{ label: 'Search', selected: false }
|
||||||
],
|
],
|
||||||
|
contentLinkerButtonId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `content-linker-button-${page.id}`;
|
||||||
|
}),
|
||||||
|
|
||||||
showSections: Ember.computed('tabs.@each.selected', function () {
|
showSections: Ember.computed('tabs.@each.selected', function () {
|
||||||
return this.get('tabs').findBy('label', 'Section').selected;
|
return this.get('tabs').findBy('label', 'Section').selected;
|
|
@ -1,68 +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';
|
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
|
||||||
sortedItems: [],
|
|
||||||
|
|
||||||
didReceiveAttrs() {
|
|
||||||
let editors = this.get('activity.editors');
|
|
||||||
let viewers = this.get('activity.viewers');
|
|
||||||
let pages = this.get('pages');
|
|
||||||
let sorted = [];
|
|
||||||
|
|
||||||
if (is.null(editors)) {
|
|
||||||
editors = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is.null(viewers)) {
|
|
||||||
viewers = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
viewers.forEach((item) => {
|
|
||||||
Ember.set(item, 'changeLabel', "viewed");
|
|
||||||
Ember.set(item, "viewed", true);
|
|
||||||
sorted.pushObject({ date: item.created, item: item });
|
|
||||||
});
|
|
||||||
|
|
||||||
editors.forEach(function (item) {
|
|
||||||
Ember.set(item, "added", item.action === "add-page");
|
|
||||||
Ember.set(item, "changed", item.action === "update-page");
|
|
||||||
Ember.set(item, "deleted", item.action === "remove-page");
|
|
||||||
|
|
||||||
let page = pages.findBy('id', item.pageId);
|
|
||||||
let title = "";
|
|
||||||
|
|
||||||
if (item.deleted || is.undefined(page)) {
|
|
||||||
title = "removed section";
|
|
||||||
} else {
|
|
||||||
if (item.added) {
|
|
||||||
title = "added " + page.get('title');
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.changed) {
|
|
||||||
title = "changed " + page.get('title');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ember.set(item, 'changeLabel', title);
|
|
||||||
|
|
||||||
let exists = sorted.findBy('item.pageId', item.pageId);
|
|
||||||
|
|
||||||
if (is.undefined(exists)) {
|
|
||||||
sorted.pushObject({ date: item.created, item: item });
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
this.set('sortedItems', _.sortBy(sorted, 'date').reverse());
|
|
||||||
}
|
|
||||||
});
|
|
53
app/app/components/document/document-heading.js
Normal file
53
app/app/components/document/document-heading.js
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
// 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';
|
||||||
|
import TooltipMixin from '../../mixins/tooltip';
|
||||||
|
|
||||||
|
const {
|
||||||
|
computed,
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
|
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
documentService: Ember.inject.service('document'),
|
||||||
|
editMode: false,
|
||||||
|
docName: '',
|
||||||
|
docExcerpt: '',
|
||||||
|
|
||||||
|
hasNameError: computed.empty('docName'),
|
||||||
|
hasExcerptError: computed.empty('docExcerpt'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
toggleEdit() {
|
||||||
|
this.set('docName', this.get('document.name'));
|
||||||
|
this.set('docExcerpt', this.get('document.excerpt'));
|
||||||
|
this.set('editMode', true);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSaveDocument() {
|
||||||
|
if (this.get('hasNameError') || this.get('hasExcerptError')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('document.name', this.get('docName'));
|
||||||
|
this.set('document.excerpt', this.get('docExcerpt'));
|
||||||
|
this.showNotification('Saved');
|
||||||
|
this.get('documentService').save(this.get('document'));
|
||||||
|
|
||||||
|
this.set('editMode', false);
|
||||||
|
},
|
||||||
|
|
||||||
|
cancel() {
|
||||||
|
this.set('editMode', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -12,7 +12,7 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
revision: {},
|
revision: null,
|
||||||
hasDiff: Ember.computed('diff', function () {
|
hasDiff: Ember.computed('diff', function () {
|
||||||
return this.get('diff').length > 0;
|
return this.get('diff').length > 0;
|
||||||
}),
|
}),
|
||||||
|
@ -20,38 +20,28 @@ export default Ember.Component.extend({
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
let revisions = this.get('revisions');
|
let revisions = this.get('revisions');
|
||||||
|
|
||||||
revisions.forEach((revision) => {
|
revisions.forEach((r) => {
|
||||||
Ember.set(revision, 'deleted', revision.revisions === 0);
|
Ember.set(r, 'deleted', r.revisions === 0);
|
||||||
|
Ember.set(r, 'label', `${r.created} - ${r.firstname} ${r.lastname} - ${r.title}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (revisions.length > 0 && is.null(this.get('revision'))) {
|
||||||
|
this.send('onSelectRevision', revisions[0]);
|
||||||
|
}
|
||||||
|
|
||||||
this.set('revisions', revisions);
|
this.set('revisions', revisions);
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
|
||||||
this._super(...arguments);
|
|
||||||
|
|
||||||
this.eventBus.subscribe('resized', this, 'sizeSidebar');
|
|
||||||
this.sizeSidebar();
|
|
||||||
},
|
|
||||||
|
|
||||||
willDestroyElement() {
|
|
||||||
this.eventBus.unsubscribe('resized');
|
|
||||||
},
|
|
||||||
|
|
||||||
sizeSidebar() {
|
|
||||||
let size = $(window).height() - 200;
|
|
||||||
this.$('.document-history > .sidebar').css('height', size + "px");
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
getDiff(revision) {
|
onSelectRevision(revision) {
|
||||||
this.set('revision', revision);
|
this.set('revision', revision);
|
||||||
|
|
||||||
if (!revision.deleted) {
|
if (!revision.deleted) {
|
||||||
this.attrs.onFetchDiff(revision.pageId, revision.id);
|
this.attrs.onFetchDiff(revision.pageId, revision.id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
rollback() {
|
onRollback() {
|
||||||
let revision = this.get('revision');
|
let revision = this.get('revision');
|
||||||
this.attrs.onRollback(revision.pageId, revision.id);
|
this.attrs.onRollback(revision.pageId, revision.id);
|
||||||
}
|
}
|
||||||
|
|
84
app/app/components/document/document-page.js
Normal file
84
app/app/components/document/document-page.js
Normal file
|
@ -0,0 +1,84 @@
|
||||||
|
// 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';
|
||||||
|
import TooltipMixin from '../../mixins/tooltip';
|
||||||
|
|
||||||
|
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
documentService: Ember.inject.service('document'),
|
||||||
|
sectionService: Ember.inject.service('section'),
|
||||||
|
editMode: false,
|
||||||
|
|
||||||
|
didReceiveAttrs() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
let page = this.get('page');
|
||||||
|
|
||||||
|
this.get('documentService').getPageMeta(page.get('documentId'), page.get('id')).then((meta) => {
|
||||||
|
this.set('meta', meta);
|
||||||
|
if (this.get('toEdit') === this.get('page.id') && this.get('isEditor')) {
|
||||||
|
this.send('onEdit');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onSavePage(page, meta) {
|
||||||
|
this.set('page', page);
|
||||||
|
this.set('meta', meta);
|
||||||
|
this.set('editMode', false);
|
||||||
|
this.get('onSavePage')(page, meta);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSavePageAsBlock(block) {
|
||||||
|
this.attrs.onSavePageAsBlock(block);
|
||||||
|
},
|
||||||
|
|
||||||
|
onCopyPage(documentId) {
|
||||||
|
this.attrs.onCopyPage(this.get('page.id'), documentId);
|
||||||
|
},
|
||||||
|
|
||||||
|
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);
|
||||||
|
},
|
||||||
|
|
||||||
|
onEdit() {
|
||||||
|
if (this.get('editMode')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get('toEdit', '');
|
||||||
|
// this.set('pageId', this.get('page.id'));
|
||||||
|
this.set('editMode', true);
|
||||||
|
},
|
||||||
|
|
||||||
|
onCancelEdit() {
|
||||||
|
this.set('editMode', false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -1,124 +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 TooltipMixin from '../../mixins/tooltip';
|
|
||||||
import NotifierMixin from '../../mixins/notifier';
|
|
||||||
|
|
||||||
export default Ember.Component.extend(TooltipMixin, NotifierMixin, {
|
|
||||||
documentService: Ember.inject.service('document'),
|
|
||||||
sectionService: Ember.inject.service('section'),
|
|
||||||
document: {},
|
|
||||||
folder: {},
|
|
||||||
showToc: true,
|
|
||||||
showSections: false,
|
|
||||||
showScrollTool: false,
|
|
||||||
showingSections: false,
|
|
||||||
|
|
||||||
init() {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.get('sectionService').getSpaceBlocks(this.get('folder.id')).then((b) => {
|
|
||||||
this.set('blocks', b);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
didRender() {
|
|
||||||
if (this.session.authenticated) {
|
|
||||||
this.addTooltip(document.getElementById("section-tool"));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
didInsertElement() {
|
|
||||||
this.eventBus.subscribe('resized', this, 'positionTool');
|
|
||||||
this.eventBus.subscribe('scrolled', this, 'positionTool');
|
|
||||||
},
|
|
||||||
|
|
||||||
willDestroyElement() {
|
|
||||||
this.eventBus.unsubscribe('resized');
|
|
||||||
this.eventBus.unsubscribe('scrolled');
|
|
||||||
this.destroyTooltips();
|
|
||||||
},
|
|
||||||
|
|
||||||
positionTool() {
|
|
||||||
if (this.get('isDestroyed') || this.get('isDestroying')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let s = $(".scroll-tool");
|
|
||||||
let windowpos = $(window).scrollTop();
|
|
||||||
|
|
||||||
if (windowpos >= 300) {
|
|
||||||
this.set('showScrollTool', true);
|
|
||||||
s.addClass("stuck-tool");
|
|
||||||
s.css('left', parseInt($(".zone-navigation").css('width')) + parseInt($(".zone-sidebar").css('width')) - 16 + 'px');
|
|
||||||
} else {
|
|
||||||
this.set('showScrollTool', false);
|
|
||||||
s.removeClass("stuck-tool");
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
// Page up - above pages shunt down.
|
|
||||||
onPageSequenceChange(pendingChanges) {
|
|
||||||
this.attrs.changePageSequence(pendingChanges);
|
|
||||||
},
|
|
||||||
|
|
||||||
// Move down - pages below shift up.
|
|
||||||
onPageLevelChange(pendingChanges) {
|
|
||||||
this.attrs.changePageLevel(pendingChanges);
|
|
||||||
},
|
|
||||||
|
|
||||||
gotoPage(id) {
|
|
||||||
return this.attrs.gotoPage(id);
|
|
||||||
},
|
|
||||||
|
|
||||||
showToc() {
|
|
||||||
this.set('showToc', true);
|
|
||||||
this.set('showSections', false);
|
|
||||||
this.set('showingSections', false);
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
showSections() {
|
|
||||||
this.set('showToc', false);
|
|
||||||
this.set('showSections', true);
|
|
||||||
this.set('showingSections', true);
|
|
||||||
},
|
|
||||||
|
|
||||||
onCancel() {
|
|
||||||
this.send('showToc');
|
|
||||||
this.set('showingSections', false);
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddSection(section) {
|
|
||||||
this.send('showToc');
|
|
||||||
this.attrs.onAddSection(section);
|
|
||||||
},
|
|
||||||
|
|
||||||
onInsertBlock(block) {
|
|
||||||
this.send('showToc');
|
|
||||||
this.attrs.onInsertBlock(block);
|
|
||||||
},
|
|
||||||
|
|
||||||
onDeleteBlock(id) {
|
|
||||||
this.set('blocks', this.get('blocks').filter((item) => item.get('id') !== id));
|
|
||||||
this.attrs.onDeleteBlock(id);
|
|
||||||
},
|
|
||||||
|
|
||||||
scrollTop() {
|
|
||||||
this.set('showScrollTool', false);
|
|
||||||
|
|
||||||
$("html,body").animate({
|
|
||||||
scrollTop: 0
|
|
||||||
}, 500, "linear");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -19,52 +19,63 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
editMode: false,
|
editMode: false,
|
||||||
|
|
||||||
didReceiveAttrs(){
|
didReceiveAttrs(){
|
||||||
if (this.get('mode') === 'edit') {
|
|
||||||
this.send('onEdit');
|
|
||||||
}
|
|
||||||
|
|
||||||
this.audit.record("viewed-document-section-" + this.get('model.page.contentType'));
|
this.audit.record("viewed-document-section-" + this.get('model.page.contentType'));
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
let self = this;
|
this.get('sectionService').refresh(this.get('document.id')).then((changes) => {
|
||||||
this.get('sectionService').refresh(this.get('model.document.id')).then(function (changes) {
|
if (this.get('isDestroyed') || this.get('isDestroying')) {
|
||||||
changes.forEach(function (newPage) {
|
return;
|
||||||
let oldPage = self.get('model.page');
|
}
|
||||||
if (!_.isUndefined(oldPage) && oldPage.get('id') === newPage.get('id')) {
|
|
||||||
|
let oldPage = this.get('page');
|
||||||
|
|
||||||
|
if (is.undefined(changes) || is.undefined(oldPage)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
changes.forEach((newPage) => {
|
||||||
|
if (oldPage.get('id') === newPage.get('id')) {
|
||||||
oldPage.set('body', newPage.get('body'));
|
oldPage.set('body', newPage.get('body'));
|
||||||
oldPage.set('revised', newPage.get('revised'));
|
oldPage.set('revised', newPage.get('revised'));
|
||||||
self.showNotification(`Refreshed ${oldPage.get('title')}`);
|
this.showNotification(`Refreshed ${oldPage.get('title')}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onEdit() {
|
onExpand() {
|
||||||
this.set('viewMode', false);
|
this.set('pageId', this.get('page.id'));
|
||||||
this.set('editMode', true);
|
this.set('expanded', !this.get('expanded'));
|
||||||
this.set('mode', 'edit');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onView() {
|
onSavePageAsBlock(block) {
|
||||||
this.set('viewMode', true);
|
this.attrs.onSavePageAsBlock(block);
|
||||||
this.set('editMode', false);
|
|
||||||
this.set('mode', 'view');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancel() {
|
onCopyPage(documentId) {
|
||||||
this.send('onView');
|
this.attrs.onCopyPage(this.get('page.id'), documentId);
|
||||||
},
|
},
|
||||||
|
|
||||||
onAction(page, meta) {
|
onMovePage(documentId) {
|
||||||
this.get('onAction')(page, meta);
|
this.attrs.onMovePage(this.get('page.id'), documentId);
|
||||||
this.send('onView');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onDelete() {
|
onDeletePage(deleteChildren) {
|
||||||
this.get('onDelete')(this.get('model.document'), this.get('model.page'));
|
let page = this.get('page');
|
||||||
return true;
|
|
||||||
|
if (is.undefined(page)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let params = {
|
||||||
|
id: page.get('id'),
|
||||||
|
title: page.get('title'),
|
||||||
|
children: deleteChildren
|
||||||
|
};
|
||||||
|
|
||||||
|
this.attrs.onDeletePage(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,25 +13,61 @@ import Ember from 'ember';
|
||||||
import NotifierMixin from '../../mixins/notifier';
|
import NotifierMixin from '../../mixins/notifier';
|
||||||
import TooltipMixin from '../../mixins/tooltip';
|
import TooltipMixin from '../../mixins/tooltip';
|
||||||
|
|
||||||
|
const {
|
||||||
|
computed,
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
documentService: Ember.inject.service('document'),
|
documentService: Ember.inject.service('document'),
|
||||||
sectionService: Ember.inject.service('section'),
|
sectionService: Ember.inject.service('section'),
|
||||||
appMeta: Ember.inject.service(),
|
appMeta: Ember.inject.service(),
|
||||||
link: Ember.inject.service(),
|
link: Ember.inject.service(),
|
||||||
document: null,
|
hasPages: computed.notEmpty('pages'),
|
||||||
folder: null,
|
newSectionName: '',
|
||||||
folders: [],
|
newSectionNameMissing: computed.empty('newSectionName'),
|
||||||
isEditor: false,
|
newSectionLocation: '',
|
||||||
|
beforePage: '',
|
||||||
|
toEdit: '',
|
||||||
|
|
||||||
noSections: Ember.computed('pages', function () {
|
didReceiveAttrs() {
|
||||||
return this.get('pages.length') === 0;
|
this._super(...arguments);
|
||||||
}),
|
|
||||||
|
this.loadBlocks();
|
||||||
|
|
||||||
|
Ember.run.schedule('afterRender', () => {
|
||||||
|
let jumpTo = "#page-" + this.get('pageId');
|
||||||
|
if (!$(jumpTo).inView()) {
|
||||||
|
$(jumpTo).velocity("scroll", { duration: 250, offset: -100 });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
didRender() {
|
didRender() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
this.contentLinkHandler();
|
this.contentLinkHandler();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
$(".start-section:not(.start-section-empty-state)").hoverIntent({interval: 100, over: function() {
|
||||||
|
// in
|
||||||
|
$(this).find('.start-button').velocity("transition.slideDownIn", {duration: 300});
|
||||||
|
}, out: function() {
|
||||||
|
// out
|
||||||
|
$(this).find('.start-button').velocity("transition.slideUpOut", {duration: 300});
|
||||||
|
} });
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
$(".tooltipped").each(function(i, el) {
|
||||||
|
self.addTooltip(el);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
this.destroyTooltips();
|
this.destroyTooltips();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -45,7 +81,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
// local link? exists?
|
// local link? exists?
|
||||||
if ((link.linkType === "section" || link.linkType === "tab") && link.documentId === doc.get('id')) {
|
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)) {
|
if (_.isUndefined(exists)) {
|
||||||
link.orphan = true;
|
link.orphan = true;
|
||||||
|
@ -69,9 +105,58 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addSection(model) {
|
||||||
|
// calculate sequence of page (position in document)
|
||||||
|
let sequence = 0;
|
||||||
|
let level = 1;
|
||||||
|
let beforePage = this.get('beforePage');
|
||||||
|
|
||||||
|
if (is.not.null(beforePage)) {
|
||||||
|
level = beforePage.get('level');
|
||||||
|
|
||||||
|
// get any page before the beforePage so we can insert this new section between them
|
||||||
|
let index = _.findIndex(this.get('pages'), function(p) { return p.get('id') === beforePage.get('id'); });
|
||||||
|
|
||||||
|
if (index !== -1) {
|
||||||
|
let beforeBeforePage = this.get('pages')[index-1];
|
||||||
|
|
||||||
|
if (is.not.undefined(beforeBeforePage)) {
|
||||||
|
sequence = (beforePage.get('sequence') + beforeBeforePage.get('sequence')) / 2;
|
||||||
|
} else {
|
||||||
|
sequence = beforePage.get('sequence') / 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model.page.sequence = sequence;
|
||||||
|
model.page.level = level;
|
||||||
|
|
||||||
|
this.send('onHideSectionWizard');
|
||||||
|
|
||||||
|
return this.get('onInsertSection')(model);
|
||||||
|
},
|
||||||
|
|
||||||
|
loadBlocks() {
|
||||||
|
this.get('sectionService').getSpaceBlocks(this.get('folder.id')).then((blocks) => {
|
||||||
|
if (this.get('isDestroyed') || this.get('isDestroying')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('blocks', blocks);
|
||||||
|
this.set('hasBlocks', blocks.get('length') > 0);
|
||||||
|
|
||||||
|
blocks.forEach((b) => {
|
||||||
|
b.set('deleteId', `delete-block-button-${b.id}`);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onAddBlock(block) {
|
onSavePageAsBlock(block) {
|
||||||
this.attrs.onAddBlock(block);
|
const promise = this.attrs.onSavePageAsBlock(block);
|
||||||
|
promise.then(() => {
|
||||||
|
this.loadBlocks();
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onCopyPage(pageId, documentId) {
|
onCopyPage(pageId, documentId) {
|
||||||
|
@ -82,26 +167,145 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
this.attrs.onMovePage(pageId, documentId);
|
this.attrs.onMovePage(pageId, documentId);
|
||||||
},
|
},
|
||||||
|
|
||||||
onDeletePage(id, deleteChildren) {
|
onDeletePage(params) {
|
||||||
let page = this.get('pages').findBy("id", id);
|
|
||||||
|
|
||||||
if (is.undefined(page)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let params = {
|
|
||||||
id: id,
|
|
||||||
title: page.get('title'),
|
|
||||||
children: deleteChildren
|
|
||||||
};
|
|
||||||
|
|
||||||
this.attrs.onDeletePage(params);
|
this.attrs.onDeletePage(params);
|
||||||
},
|
},
|
||||||
|
|
||||||
onTagChange(tags) {
|
onSavePage(page, meta) {
|
||||||
let doc = this.get('document');
|
this.attrs.onSavePage(page, meta);
|
||||||
doc.set('tags', tags);
|
},
|
||||||
this.get('documentService').save(doc);
|
|
||||||
|
// Section wizard related
|
||||||
|
onShowSectionWizard(page) {
|
||||||
|
if (is.undefined(page)) {
|
||||||
|
page = { id: '0' };
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('pageId', '');
|
||||||
|
|
||||||
|
let beforePage = this.get('beforePage');
|
||||||
|
if (is.not.null(beforePage) && $("#new-section-wizard").is(':visible') && beforePage.get('id') === page.id) {
|
||||||
|
this.send('onHideSectionWizard');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('newSectionLocation', page.id);
|
||||||
|
|
||||||
|
if (page.id === '0') {
|
||||||
|
// this handles add section at the end of the document
|
||||||
|
// because we are not before another page
|
||||||
|
this.set('beforePage', null);
|
||||||
|
} else {
|
||||||
|
this.set('beforePage', page);
|
||||||
|
}
|
||||||
|
|
||||||
|
$("#new-section-wizard").insertAfter(`#add-section-button-${page.id}`);
|
||||||
|
$("#new-section-wizard").velocity("transition.slideDownIn", {duration: 300, complete:
|
||||||
|
function() {
|
||||||
|
$("#new-section-name").focus();
|
||||||
|
}});
|
||||||
|
},
|
||||||
|
|
||||||
|
onHideSectionWizard() {
|
||||||
|
this.set('newSectionLocation', '');
|
||||||
|
this.set('beforePage', null);
|
||||||
|
$("#new-section-wizard").velocity("transition.slideUpOut", { duration: 300 });
|
||||||
|
},
|
||||||
|
|
||||||
|
onInsertSection(section) {
|
||||||
|
let sectionName = this.get('newSectionName');
|
||||||
|
if (is.empty(sectionName)) {
|
||||||
|
$("#new-section-name").focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let page = {
|
||||||
|
documentId: this.get('document.id'),
|
||||||
|
title: sectionName,
|
||||||
|
level: 1,
|
||||||
|
sequence: 0, // calculated elsewhere
|
||||||
|
body: "",
|
||||||
|
contentType: section.get('contentType'),
|
||||||
|
pageType: section.get('pageType')
|
||||||
|
};
|
||||||
|
|
||||||
|
let meta = {
|
||||||
|
documentId: this.get('document.id'),
|
||||||
|
rawBody: "",
|
||||||
|
config: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
let model = {
|
||||||
|
page: page,
|
||||||
|
meta: meta
|
||||||
|
};
|
||||||
|
|
||||||
|
this.audit.record("added-section-" + page.contentType);
|
||||||
|
|
||||||
|
const promise = this.addSection(model);
|
||||||
|
promise.then((id) => {
|
||||||
|
this.set('pageId', id);
|
||||||
|
|
||||||
|
if (model.page.pageType === 'section') {
|
||||||
|
this.set('toEdit', id);
|
||||||
|
} else {
|
||||||
|
this.set('toEdit', '');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onInsertBlock(block) {
|
||||||
|
let sectionName = this.get('newSectionName');
|
||||||
|
if (is.empty(sectionName)) {
|
||||||
|
$("#new-section-name").focus();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let page = {
|
||||||
|
documentId: this.get('document.id'),
|
||||||
|
title: `${block.get('title')}`,
|
||||||
|
level: 1,
|
||||||
|
sequence: 0, // calculated elsewhere
|
||||||
|
body: block.get('body'),
|
||||||
|
contentType: block.get('contentType'),
|
||||||
|
pageType: block.get('pageType'),
|
||||||
|
blockId: block.get('id')
|
||||||
|
};
|
||||||
|
|
||||||
|
let meta = {
|
||||||
|
documentId: this.get('document.id'),
|
||||||
|
rawBody: block.get('rawBody'),
|
||||||
|
config: block.get('config'),
|
||||||
|
externalSource: block.get('externalSource')
|
||||||
|
};
|
||||||
|
|
||||||
|
let model = {
|
||||||
|
page: page,
|
||||||
|
meta: meta
|
||||||
|
};
|
||||||
|
|
||||||
|
this.audit.record("added-content-block-" + block.get('contentType'));
|
||||||
|
|
||||||
|
const promise = this.addSection(model);
|
||||||
|
promise.then((id) => {
|
||||||
|
this.set('pageId', id);
|
||||||
|
|
||||||
|
// if (model.page.pageType === 'section') {
|
||||||
|
// this.set('toEdit', id);
|
||||||
|
// } else {
|
||||||
|
// this.set('toEdit', '');
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onDeleteBlock(id) {
|
||||||
|
const promise = this.attrs.onDeleteBlock(id);
|
||||||
|
|
||||||
|
promise.then(() => {
|
||||||
|
this.loadBlocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,86 +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';
|
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
|
||||||
documentService: Ember.inject.service('document'),
|
|
||||||
|
|
||||||
revisions: [],
|
|
||||||
diffReport: "",
|
|
||||||
busy: false,
|
|
||||||
currentRevisionId: "",
|
|
||||||
|
|
||||||
didReceiveAttrs() {
|
|
||||||
if (is.undefined(this.get('model'))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
this.get('documentService').getPageRevisions(this.get('model.documentId'), this.get('model.pageId')).then(function(response) {
|
|
||||||
if (is.array(response)) {
|
|
||||||
self.set('revisions', response);
|
|
||||||
if (response.length > 0) {
|
|
||||||
self.send('produceReport', response[0].id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
didRender() {
|
|
||||||
let self = this;
|
|
||||||
Ember.run.schedule('afterRender', function() {
|
|
||||||
Mousetrap.bind('esc', function() {
|
|
||||||
self.send('cancelAction');
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
produceReport(revisionId) {
|
|
||||||
this.set('busy', true);
|
|
||||||
this.set('diffReport', "");
|
|
||||||
this.set('currentRevisionId', revisionId);
|
|
||||||
|
|
||||||
// visually mark active revision
|
|
||||||
let revisions = this.get('revisions');
|
|
||||||
|
|
||||||
revisions.forEach(function(revision) {
|
|
||||||
Ember.set(revision, 'selected', false);
|
|
||||||
});
|
|
||||||
|
|
||||||
let revision = _.findWhere(revisions, {
|
|
||||||
id: revisionId
|
|
||||||
});
|
|
||||||
Ember.set(revision, 'selected', true);
|
|
||||||
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
this.get('documentService').getPageRevisionDiff(this.get('model.documentId'),
|
|
||||||
this.get('model.pageId'), revisionId).then(function(response) {
|
|
||||||
self.set('busy', false);
|
|
||||||
self.set('diffReport', Ember.String.htmlSafe(response));
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
cancelAction() {
|
|
||||||
this.attrs.editorClose();
|
|
||||||
},
|
|
||||||
|
|
||||||
primaryAction() {
|
|
||||||
if (this.session.isEditor) {
|
|
||||||
this.attrs.editorAction(this.get('model.pageId'), this.get('currentRevisionId'));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -73,21 +73,10 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
didRender() {
|
didRender() {
|
||||||
if (this.get('isEditor')) {
|
|
||||||
let self = this;
|
|
||||||
$(".page-action-button").each(function (i, el) {
|
|
||||||
self.addTooltip(el);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$("#" + this.get('blockTitleId')).removeClass('error');
|
$("#" + this.get('blockTitleId')).removeClass('error');
|
||||||
$("#" + this.get('blockExcerptId')).removeClass('error');
|
$("#" + this.get('blockExcerptId')).removeClass('error');
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
|
||||||
this.destroyTooltips();
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onMenuOpen() {
|
onMenuOpen() {
|
||||||
if ($('#' + this.get('publishDialogId')).is( ":visible" )) {
|
if ($('#' + this.get('publishDialogId')).is( ":visible" )) {
|
||||||
|
@ -103,15 +92,16 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
this.set('menuOpen', !this.get('menuOpen'));
|
this.set('menuOpen', !this.get('menuOpen'));
|
||||||
},
|
},
|
||||||
|
|
||||||
editPage(id) {
|
onEdit() {
|
||||||
this.attrs.onEditPage(id);
|
this.attrs.onEdit();
|
||||||
},
|
},
|
||||||
|
|
||||||
deletePage(id) {
|
deletePage() {
|
||||||
this.attrs.onDeletePage(id, this.get('deleteChildren'));
|
this.attrs.onDeletePage(this.get('deleteChildren'));
|
||||||
},
|
},
|
||||||
|
|
||||||
onAddBlock(page) {
|
onSavePageAsBlock() {
|
||||||
|
let page = this.get('page');
|
||||||
let titleElem = '#' + this.get('blockTitleId');
|
let titleElem = '#' + this.get('blockTitleId');
|
||||||
let blockTitle = this.get('blockTitle');
|
let blockTitle = this.get('blockTitle');
|
||||||
if (is.empty(blockTitle)) {
|
if (is.empty(blockTitle)) {
|
||||||
|
@ -140,7 +130,8 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
externalSource: pm.get('externalSource')
|
externalSource: pm.get('externalSource')
|
||||||
};
|
};
|
||||||
|
|
||||||
this.attrs.onAddBlock(block);
|
this.attrs.onSavePageAsBlock(block);
|
||||||
|
|
||||||
this.set('menuOpen', false);
|
this.set('menuOpen', false);
|
||||||
this.set('blockTitle', '');
|
this.set('blockTitle', '');
|
||||||
this.set('blockExcerpt', '');
|
this.set('blockExcerpt', '');
|
||||||
|
@ -169,7 +160,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
this.set('selectedDocument', d);
|
this.set('selectedDocument', d);
|
||||||
},
|
},
|
||||||
|
|
||||||
onCopyPage(page) {
|
onCopyPage() {
|
||||||
// can't proceed if no data
|
// can't proceed if no data
|
||||||
if (this.get('documentList.length') === 0) {
|
if (this.get('documentList.length') === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -180,11 +171,11 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
targetDocumentId = this.get('selectedDocument.id');
|
targetDocumentId = this.get('selectedDocument.id');
|
||||||
}
|
}
|
||||||
|
|
||||||
this.attrs.onCopyPage(page.get('id'), targetDocumentId);
|
this.attrs.onCopyPage(targetDocumentId);
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
onMovePage(page) {
|
onMovePage() {
|
||||||
// can't proceed if no data
|
// can't proceed if no data
|
||||||
if (this.get('documentListOthers.length') === 0) {
|
if (this.get('documentListOthers.length') === 0) {
|
||||||
return;
|
return;
|
||||||
|
@ -196,7 +187,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
|
|
||||||
let targetDocumentId = this.get('selectedDocument.id');
|
let targetDocumentId = this.get('selectedDocument.id');
|
||||||
|
|
||||||
this.attrs.onMovePage(page.get('id'), targetDocumentId);
|
this.attrs.onMovePage(targetDocumentId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,67 +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.Component.extend(NotifierMixin, {
|
|
||||||
display: 'section', // which CSS to use
|
|
||||||
hasTemplates: false,
|
|
||||||
hasBlocks: false,
|
|
||||||
blockMode: false,
|
|
||||||
|
|
||||||
didReceiveAttrs() {
|
|
||||||
let blocks = this.get('blocks');
|
|
||||||
let blockMode = is.not.undefined(blocks);
|
|
||||||
|
|
||||||
this.set('blockMode', blockMode);
|
|
||||||
if (!blockMode) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.set('hasBlocks', blocks.get('length') > 0);
|
|
||||||
|
|
||||||
blocks.forEach((b) => {
|
|
||||||
b.set('deleteId', `delete-block-button-${b.id}`);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
didRender() {
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
Mousetrap.bind('esc', function () {
|
|
||||||
if (self.get('isDestroyed') || self.get('isDestroying')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.send('onCancel');
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
onCancel() {
|
|
||||||
this.attrs.onCancel();
|
|
||||||
},
|
|
||||||
|
|
||||||
addSection(section) {
|
|
||||||
this.attrs.onAddSection(section);
|
|
||||||
},
|
|
||||||
|
|
||||||
onDeleteBlock(id) {
|
|
||||||
this.attrs.onDeleteBlock(id);
|
|
||||||
},
|
|
||||||
|
|
||||||
onInsertBlock(block) {
|
|
||||||
this.attrs.onInsertBlock(block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
76
app/app/components/document/sidebar-view-activity.js
Normal file
76
app/app/components/document/sidebar-view-activity.js
Normal file
|
@ -0,0 +1,76 @@
|
||||||
|
// 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';
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
documentService: Ember.inject.service('document'),
|
||||||
|
appMeta: Ember.inject.service(),
|
||||||
|
sortedItems: [],
|
||||||
|
|
||||||
|
didReceiveAttrs() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
this.get('documentService').getMeta(this.get('document.id')).then((activity) => {
|
||||||
|
this.set('activity', activity);
|
||||||
|
|
||||||
|
let editors = this.get('activity.editors');
|
||||||
|
let viewers = this.get('activity.viewers');
|
||||||
|
let pages = this.get('pages');
|
||||||
|
let sorted = [];
|
||||||
|
|
||||||
|
if (is.null(editors)) {
|
||||||
|
editors = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is.null(viewers)) {
|
||||||
|
viewers = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
viewers.forEach((item) => {
|
||||||
|
Ember.set(item, 'changeLabel', "viewed");
|
||||||
|
Ember.set(item, "viewed", true);
|
||||||
|
sorted.pushObject({ date: item.created, item: item });
|
||||||
|
});
|
||||||
|
|
||||||
|
editors.forEach(function (item) {
|
||||||
|
Ember.set(item, "added", item.action === "add-page");
|
||||||
|
Ember.set(item, "changed", item.action === "update-page");
|
||||||
|
Ember.set(item, "deleted", item.action === "remove-page");
|
||||||
|
|
||||||
|
let page = pages.findBy('id', item.pageId);
|
||||||
|
let title = "";
|
||||||
|
|
||||||
|
if (item.deleted || is.undefined(page)) {
|
||||||
|
title = "removed section";
|
||||||
|
} else {
|
||||||
|
if (item.added) {
|
||||||
|
title = "added " + page.get('title');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (item.changed) {
|
||||||
|
title = "changed " + page.get('title');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ember.set(item, 'changeLabel', title);
|
||||||
|
|
||||||
|
let exists = sorted.findBy('item.pageId', item.pageId);
|
||||||
|
|
||||||
|
if (is.undefined(exists)) {
|
||||||
|
sorted.pushObject({ date: item.created, item: item });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set('sortedItems', _.sortBy(sorted, 'date').reverse());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
|
@ -14,17 +14,24 @@ import NotifierMixin from '../../mixins/notifier';
|
||||||
import TooltipMixin from '../../mixins/tooltip';
|
import TooltipMixin from '../../mixins/tooltip';
|
||||||
|
|
||||||
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
documentService: Ember.inject.service('document'),
|
||||||
appMeta: Ember.inject.service(),
|
appMeta: Ember.inject.service(),
|
||||||
drop: null,
|
drop: null,
|
||||||
|
emptyState: Ember.computed.empty('files'),
|
||||||
deleteAttachment: {
|
deleteAttachment: {
|
||||||
id: "",
|
id: "",
|
||||||
name: "",
|
name: "",
|
||||||
},
|
},
|
||||||
emptyState: Ember.computed('files', function () {
|
|
||||||
return this.get('files.length') === 0;
|
init() {
|
||||||
}),
|
this._super(...arguments);
|
||||||
|
|
||||||
|
this.getAttachments();
|
||||||
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
if (!this.get('isEditor')) {
|
if (!this.get('isEditor')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -54,7 +61,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on("queuecomplete", function () {
|
this.on("queuecomplete", function () {
|
||||||
self.attrs.onUpload();
|
self.getAttachments();
|
||||||
});
|
});
|
||||||
|
|
||||||
this.on("addedfile", function ( /*file*/ ) {
|
this.on("addedfile", function ( /*file*/ ) {
|
||||||
|
@ -71,15 +78,22 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
let drop = this.get('drop');
|
this._super(...arguments);
|
||||||
|
|
||||||
|
let drop = this.get('drop');
|
||||||
if (is.not.null(drop)) {
|
if (is.not.null(drop)) {
|
||||||
drop.destroy();
|
drop.destroy();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getAttachments() {
|
||||||
|
this.get('documentService').getAttachments(this.get('document.id')).then((files) => {
|
||||||
|
this.set('files', files);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
confirmDeleteAttachment(id, name) {
|
onConfirmDelete(id, name) {
|
||||||
this.set('deleteAttachment', {
|
this.set('deleteAttachment', {
|
||||||
id: id,
|
id: id,
|
||||||
name: name
|
name: name
|
||||||
|
@ -103,7 +117,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
this.set('drop', drop);
|
this.set('drop', drop);
|
||||||
},
|
},
|
||||||
|
|
||||||
cancel() {
|
onCancel() {
|
||||||
let drop = this.get('drop');
|
let drop = this.get('drop');
|
||||||
drop.close();
|
drop.close();
|
||||||
|
|
||||||
|
@ -113,17 +127,20 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteAttachment() {
|
onDelete() {
|
||||||
let attachment = this.get('deleteAttachment');
|
let attachment = this.get('deleteAttachment');
|
||||||
let drop = this.get('drop');
|
let drop = this.get('drop');
|
||||||
drop.close();
|
drop.close();
|
||||||
|
|
||||||
this.attrs.onDelete(this.get('deleteAttachment').id, attachment.name);
|
this.showNotification(`Deleted ${name}`);
|
||||||
|
|
||||||
|
this.get('documentService').deleteAttachment(this.get('document.id'), attachment.id).then(() => {
|
||||||
|
this.getAttachments();
|
||||||
this.set('deleteAttachment', {
|
this.set('deleteAttachment', {
|
||||||
id: "",
|
id: "",
|
||||||
name: ""
|
name: ""
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
|
@ -18,7 +18,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
document: {},
|
document: {},
|
||||||
folder: {},
|
folder: {},
|
||||||
pages: [],
|
pages: [],
|
||||||
page: "",
|
currentPageId: "",
|
||||||
state: {
|
state: {
|
||||||
actionablePage: false,
|
actionablePage: false,
|
||||||
upDisabled: true,
|
upDisabled: true,
|
||||||
|
@ -31,13 +31,18 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
}),
|
}),
|
||||||
|
|
||||||
didReceiveAttrs: function () {
|
didReceiveAttrs: function () {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
this.set('showToc', is.not.undefined(this.get('pages')) && this.get('pages').get('length') > 0);
|
this.set('showToc', is.not.undefined(this.get('pages')) && this.get('pages').get('length') > 0);
|
||||||
if (is.not.null(this.get('page'))) {
|
|
||||||
this.send('onEntryClick', this.get('page'));
|
if (is.not.null(this.get('currentPageId'))) {
|
||||||
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
didRender: function () {
|
didRender: function () {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
if (this.session.authenticated) {
|
if (this.session.authenticated) {
|
||||||
this.addTooltip(document.getElementById("toc-up-button"));
|
this.addTooltip(document.getElementById("toc-up-button"));
|
||||||
this.addTooltip(document.getElementById("toc-down-button"));
|
this.addTooltip(document.getElementById("toc-down-button"));
|
||||||
|
@ -47,10 +52,14 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded');
|
this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded');
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
this.eventBus.unsubscribe('documentPageAdded');
|
this.eventBus.unsubscribe('documentPageAdded');
|
||||||
this.destroyTooltips();
|
this.destroyTooltips();
|
||||||
},
|
},
|
||||||
|
@ -62,7 +71,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
// Controls what user can do with the toc (left sidebar).
|
// Controls what user can do with the toc (left sidebar).
|
||||||
// Identifies the target pages.
|
// Identifies the target pages.
|
||||||
setState(pageId) {
|
setState(pageId) {
|
||||||
this.set('page', pageId);
|
this.set('currentPageId', pageId);
|
||||||
|
|
||||||
let toc = this.get('pages');
|
let toc = this.get('pages');
|
||||||
let page = _.findWhere(toc, { id: pageId });
|
let page = _.findWhere(toc, { id: pageId });
|
||||||
|
@ -85,13 +94,13 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
let state = this.get('state');
|
let state = this.get('state');
|
||||||
let pages = this.get('pages');
|
let pages = this.get('pages');
|
||||||
let page = _.findWhere(pages, { id: this.get('page') });
|
let page = _.findWhere(pages, { id: this.get('currentPageId') });
|
||||||
let pendingChanges = tocUtil.moveUp(state, pages, page);
|
let pendingChanges = tocUtil.moveUp(state, pages, page);
|
||||||
|
|
||||||
if (pendingChanges.length > 0) {
|
if (pendingChanges.length > 0) {
|
||||||
this.attrs.changePageSequence(pendingChanges);
|
this.attrs.onPageSequenceChange(pendingChanges);
|
||||||
|
|
||||||
this.send('onEntryClick', this.get('page'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
this.audit.record("moved-page-up");
|
this.audit.record("moved-page-up");
|
||||||
this.showNotification("Moved up");
|
this.showNotification("Moved up");
|
||||||
}
|
}
|
||||||
|
@ -105,13 +114,13 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
let state = this.get('state');
|
let state = this.get('state');
|
||||||
var pages = this.get('pages');
|
var pages = this.get('pages');
|
||||||
var page = _.findWhere(pages, { id: this.get('page') });
|
var page = _.findWhere(pages, { id: this.get('currentPageId') });
|
||||||
let pendingChanges = tocUtil.moveDown(state, pages, page);
|
let pendingChanges = tocUtil.moveDown(state, pages, page);
|
||||||
|
|
||||||
if (pendingChanges.length > 0) {
|
if (pendingChanges.length > 0) {
|
||||||
this.attrs.changePageSequence(pendingChanges);
|
this.attrs.onPageSequenceChange(pendingChanges);
|
||||||
|
|
||||||
this.send('onEntryClick', this.get('page'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
this.audit.record("moved-page-down");
|
this.audit.record("moved-page-down");
|
||||||
this.showNotification("Moved down");
|
this.showNotification("Moved down");
|
||||||
}
|
}
|
||||||
|
@ -125,15 +134,15 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
let state = this.get('state');
|
let state = this.get('state');
|
||||||
var pages = this.get('pages');
|
var pages = this.get('pages');
|
||||||
var page = _.findWhere(pages, { id: this.get('page') });
|
var page = _.findWhere(pages, { id: this.get('currentPageId') });
|
||||||
let pendingChanges = tocUtil.indent(state, pages, page);
|
let pendingChanges = tocUtil.indent(state, pages, page);
|
||||||
|
|
||||||
if (pendingChanges.length > 0) {
|
if (pendingChanges.length > 0) {
|
||||||
this.attrs.changePageLevel(pendingChanges);
|
this.attrs.onPageLevelChange(pendingChanges);
|
||||||
|
|
||||||
this.showNotification("Indent");
|
this.showNotification("Indent");
|
||||||
this.audit.record("changed-page-sequence");
|
this.audit.record("changed-page-sequence");
|
||||||
this.send('onEntryClick', this.get('page'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -145,21 +154,21 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
|
|
||||||
let state = this.get('state');
|
let state = this.get('state');
|
||||||
var pages = this.get('pages');
|
var pages = this.get('pages');
|
||||||
var page = _.findWhere(pages, { id: this.get('page') });
|
var page = _.findWhere(pages, { id: this.get('currentPageId') });
|
||||||
let pendingChanges = tocUtil.outdent(state, pages, page);
|
let pendingChanges = tocUtil.outdent(state, pages, page);
|
||||||
|
|
||||||
if (pendingChanges.length > 0) {
|
if (pendingChanges.length > 0) {
|
||||||
this.attrs.changePageLevel(pendingChanges);
|
this.attrs.onPageLevelChange(pendingChanges);
|
||||||
|
|
||||||
this.showNotification("Outdent");
|
this.showNotification("Outdent");
|
||||||
this.audit.record("changed-page-sequence");
|
this.audit.record("changed-page-sequence");
|
||||||
this.send('onEntryClick', this.get('page'));
|
this.send('onEntryClick', this.get('currentPageId'));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onEntryClick(id) {
|
onEntryClick(id) {
|
||||||
this.setState(id);
|
this.setState(id);
|
||||||
this.attrs.gotoPage(id);
|
this.attrs.onGotoPage(id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -10,114 +10,83 @@
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import NotifierMixin from '../../mixins/notifier';
|
|
||||||
import TooltipMixin from '../../mixins/tooltip';
|
import TooltipMixin from '../../mixins/tooltip';
|
||||||
|
import NotifierMixin from '../../mixins/notifier';
|
||||||
|
|
||||||
export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
export default Ember.Component.extend(TooltipMixin, NotifierMixin, {
|
||||||
|
documentService: Ember.inject.service('document'),
|
||||||
|
sectionService: Ember.inject.service('section'),
|
||||||
appMeta: Ember.inject.service(),
|
appMeta: Ember.inject.service(),
|
||||||
userService: Ember.inject.service('user'),
|
userService: Ember.inject.service('user'),
|
||||||
localStorage: Ember.inject.service(),
|
localStorage: Ember.inject.service(),
|
||||||
pinned: Ember.inject.service(),
|
pinned: Ember.inject.service(),
|
||||||
drop: null,
|
|
||||||
users: [],
|
|
||||||
menuOpen: false,
|
menuOpen: false,
|
||||||
saveTemplate: {
|
|
||||||
name: "",
|
|
||||||
description: ""
|
|
||||||
},
|
|
||||||
pinState : {
|
pinState : {
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinId: '',
|
pinId: '',
|
||||||
newName: '',
|
newName: '',
|
||||||
},
|
},
|
||||||
|
saveTemplate: {
|
||||||
didReceiveAttrs() {
|
name: "",
|
||||||
this.set('saveTemplate.name', this.get('document.name'));
|
description: ""
|
||||||
this.set('saveTemplate.description', this.get('document.excerpt'));
|
|
||||||
|
|
||||||
let doc = this.get('document');
|
|
||||||
|
|
||||||
this.set('layoutLabel', doc.get('layout') === 'doc' ? 'Wiki style' : 'Document style');
|
|
||||||
|
|
||||||
this.set('pinState.pinId', this.get('pinned').isDocumentPinned(doc.get('id')));
|
|
||||||
this.set('pinState.isPinned', this.get('pinState.pinId') !== '');
|
|
||||||
this.set('pinState.newName', doc.get('name').substring(0,3).toUpperCase());
|
|
||||||
},
|
},
|
||||||
|
tab: '',
|
||||||
|
|
||||||
didRender() {
|
init() {
|
||||||
if (this.session.isEditor) {
|
this._super(...arguments);
|
||||||
this.addTooltip(document.getElementById("add-document-tab"));
|
|
||||||
|
if (is.empty(this.get('tab')) || is.undefined(this.get('tab'))) {
|
||||||
|
this.set('tab', 'index');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
didReceiveAttrs() {
|
||||||
this.destroyTooltips();
|
this._super(...arguments);
|
||||||
|
|
||||||
|
this.set('saveTemplate.name', this.get('document.name'));
|
||||||
|
this.set('saveTemplate.description', this.get('document.excerpt'));
|
||||||
|
|
||||||
|
this.set('pinState.pinId', this.get('pinned').isDocumentPinned(this.get('document.id')));
|
||||||
|
this.set('pinState.isPinned', this.get('pinState.pinId') !== '');
|
||||||
|
this.set('pinState.newName', this.get('document.name').substring(0,3).toUpperCase());
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
onChangeTab(tab) {
|
||||||
|
this.set('tab', tab);
|
||||||
|
},
|
||||||
|
|
||||||
|
onTagChange(tags) {
|
||||||
|
let doc = this.get('document');
|
||||||
|
doc.set('tags', tags);
|
||||||
|
this.get('documentService').save(doc);
|
||||||
|
},
|
||||||
|
|
||||||
onMenuOpen() {
|
onMenuOpen() {
|
||||||
this.set('menuOpen', !this.get('menuOpen'));
|
this.set('menuOpen', !this.get('menuOpen'));
|
||||||
},
|
},
|
||||||
|
|
||||||
deleteDocument() {
|
onDeleteDocument() {
|
||||||
this.attrs.onDocumentDelete();
|
this.attrs.onDocumentDelete();
|
||||||
},
|
},
|
||||||
|
|
||||||
printDocument() {
|
onPrintDocument() {
|
||||||
window.print();
|
window.print();
|
||||||
},
|
},
|
||||||
|
|
||||||
changeLayout() {
|
onPageSequenceChange(changes) {
|
||||||
let doc = this.get('document');
|
this.get('onPageSequenceChange')(changes);
|
||||||
let layout = doc.get('layout') === 'doc' ? 'wiki' : 'doc';
|
|
||||||
|
|
||||||
doc.set('layout', layout);
|
|
||||||
|
|
||||||
this.attrs.onSaveMeta(doc);
|
|
||||||
|
|
||||||
this.set('layoutLabel', doc.get('layout') === 'doc' ? 'Wiki style' : 'Document style');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
saveTemplate() {
|
onPageLevelChange(changes) {
|
||||||
var name = this.get('saveTemplate.name');
|
this.get('onPageLevelChange')(changes);
|
||||||
var excerpt = this.get('saveTemplate.description');
|
|
||||||
|
|
||||||
if (is.empty(name)) {
|
|
||||||
$("#new-template-name").addClass("error").focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is.empty(excerpt)) {
|
|
||||||
$("#new-template-desc").addClass("error").focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.showNotification('Template saved');
|
|
||||||
this.attrs.onSaveTemplate(name, excerpt);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
saveMeta() {
|
onGotoPage(id) {
|
||||||
let doc = this.get('document');
|
this.get('onGotoPage')(id);
|
||||||
|
|
||||||
if (is.empty(doc.get('name'))) {
|
|
||||||
$("#meta-name").addClass("error").focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is.empty(doc.get('excerpt'))) {
|
|
||||||
$("#meta-excerpt").addClass("error").focus();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
doc.set('excerpt', doc.get('excerpt').substring(0, 250));
|
|
||||||
|
|
||||||
this.attrs.onSaveMeta(doc);
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
unpin() {
|
onUnpin() {
|
||||||
this.audit.record('unpinned-document');
|
this.audit.record('unpinned-document');
|
||||||
|
|
||||||
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
this.get('pinned').unpinItem(this.get('pinState.pinId')).then(() => {
|
||||||
|
@ -127,7 +96,7 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
pin() {
|
onPin() {
|
||||||
let pin = {
|
let pin = {
|
||||||
pin: this.get('pinState.newName'),
|
pin: this.get('pinState.newName'),
|
||||||
documentId: this.get('document.id'),
|
documentId: this.get('document.id'),
|
||||||
|
@ -147,6 +116,26 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, {
|
||||||
this.eventBus.publish('pinChange');
|
this.eventBus.publish('pinChange');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
|
||||||
|
onSaveTemplate() {
|
||||||
|
var name = this.get('saveTemplate.name');
|
||||||
|
var excerpt = this.get('saveTemplate.description');
|
||||||
|
|
||||||
|
if (is.empty(name)) {
|
||||||
|
$("#new-template-name").addClass("error").focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is.empty(excerpt)) {
|
||||||
|
$("#new-template-desc").addClass("error").focus();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.showNotification('Template saved');
|
||||||
|
this.attrs.onSaveTemplate(name, excerpt);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -10,7 +10,18 @@
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import NotifierMixin from '../../../mixins/notifier';
|
import NotifierMixin from '../../mixins/notifier';
|
||||||
|
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
const {
|
||||||
|
inject: { service }
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
|
export default Ember.Component.extend(NotifierMixin, {
|
||||||
|
appMeta :service(),
|
||||||
|
|
||||||
|
didRender() {
|
||||||
|
if (this.get('appMeta').invalidLicense()) {
|
||||||
|
this.showNotification(`!! Expired or invalid license !!`);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
129
app/app/components/section/base-editor-inline.js
Normal file
129
app/app/components/section/base-editor-inline.js
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
// 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';
|
||||||
|
|
||||||
|
const {
|
||||||
|
computed,
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
|
|
||||||
|
export default Ember.Component.extend({
|
||||||
|
drop: null,
|
||||||
|
busy: false,
|
||||||
|
|
||||||
|
hasNameError: computed.empty('page.title'),
|
||||||
|
pageId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `page-editor-${page.id}`;
|
||||||
|
}),
|
||||||
|
cancelId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `cancel-edits-button-${page.id}`;
|
||||||
|
}),
|
||||||
|
dialogId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `discard-edits-dialog-${page.id}`;
|
||||||
|
}),
|
||||||
|
contentLinkerButtonId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `content-linker-button-${page.id}`;
|
||||||
|
}),
|
||||||
|
previewButtonId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `content-preview-button-${page.id}`;
|
||||||
|
}),
|
||||||
|
|
||||||
|
didRender() {
|
||||||
|
let self = this;
|
||||||
|
Mousetrap.bind('esc', function () {
|
||||||
|
self.send('onCancel');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
Mousetrap.bind(['ctrl+s', 'command+s'], function () {
|
||||||
|
self.send('onAction');
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#' + this.get('pageId')).focus(function() {
|
||||||
|
$(this).select();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
let drop = this.get('drop');
|
||||||
|
|
||||||
|
if (is.not.null(drop)) {
|
||||||
|
drop.destroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
Mousetrap.unbind('esc');
|
||||||
|
Mousetrap.unbind(['ctrl+s', 'command+s']);
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onCancel() {
|
||||||
|
if (this.attrs.isDirty() !== null && this.attrs.isDirty()) {
|
||||||
|
$('#' + this.get('dialogId')).css("display", "block");
|
||||||
|
|
||||||
|
let drop = new Drop({
|
||||||
|
target: $('#' + this.get('cancelId'))[0],
|
||||||
|
content: $('#' + this.get('dialogId'))[0],
|
||||||
|
classes: 'drop-theme-basic',
|
||||||
|
position: "bottom right",
|
||||||
|
openOn: "always",
|
||||||
|
constrainToWindow: true,
|
||||||
|
constrainToScrollParent: false,
|
||||||
|
tetherOptions: {
|
||||||
|
offset: "5px 0",
|
||||||
|
targetOffset: "10px 0"
|
||||||
|
},
|
||||||
|
remove: false
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set('drop', drop);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.attrs.onCancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
onAction() {
|
||||||
|
if (this.get('busy') || is.empty(this.get('page.title'))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.get('isDestroyed') || this.get('isDestroying')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.attrs.onAction(this.get('page.title'));
|
||||||
|
},
|
||||||
|
|
||||||
|
keepEditing() {
|
||||||
|
let drop = this.get('drop');
|
||||||
|
drop.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
discardEdits() {
|
||||||
|
this.attrs.onCancel();
|
||||||
|
},
|
||||||
|
|
||||||
|
onInsertLink(selection) {
|
||||||
|
return this.get('onInsertLink')(selection);
|
||||||
|
},
|
||||||
|
|
||||||
|
onPreview() {
|
||||||
|
return this.get('onPreview')();
|
||||||
|
},
|
||||||
|
}
|
||||||
|
});
|
|
@ -12,7 +12,4 @@
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
didReceiveAttrs() {
|
|
||||||
this.set('rendererType', 'section/' + this.get('page.contentType') + '/type-renderer');
|
|
||||||
},
|
|
||||||
});
|
});
|
|
@ -15,9 +15,17 @@ import TooltipMixin from '../../../mixins/tooltip';
|
||||||
export default Ember.Component.extend(TooltipMixin, {
|
export default Ember.Component.extend(TooltipMixin, {
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
pageBody: "",
|
pageBody: "",
|
||||||
codeEditor: null,
|
|
||||||
syntaxOptions: [],
|
syntaxOptions: [],
|
||||||
codeSyntax: null,
|
codeSyntax: null,
|
||||||
|
codeEditor: null,
|
||||||
|
editorId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `code-editor-${page.id}`;
|
||||||
|
}),
|
||||||
|
syntaxId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `code-editor-syntax-${page.id}`;
|
||||||
|
}),
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
@ -31,7 +39,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
cleanBody = cleanBody.replace('<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="', "");
|
cleanBody = cleanBody.replace('<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="', "");
|
||||||
let startPos = cleanBody.indexOf('">');
|
let startPos = cleanBody.indexOf('">');
|
||||||
let syntax = {
|
let syntax = {
|
||||||
mode: "html",
|
mode: "htmlmixed",
|
||||||
name: "HTML"
|
name: "HTML"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -45,10 +53,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
let opts = [];
|
let opts = [];
|
||||||
|
|
||||||
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), function(item) {
|
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), function(item) {
|
||||||
let i = {
|
let i = { mode: item.mode, name: item.name };
|
||||||
mode: item.mode,
|
|
||||||
name: item.name
|
|
||||||
};
|
|
||||||
opts.pushObject(i);
|
opts.pushObject(i);
|
||||||
|
|
||||||
if (item.mode === syntax) {
|
if (item.mode === syntax) {
|
||||||
|
@ -60,16 +65,12 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
|
|
||||||
// default check
|
// default check
|
||||||
if (is.null(this.get("codeSyntax"))) {
|
if (is.null(this.get("codeSyntax"))) {
|
||||||
this.set("codeSyntax", opts.findBy("mode", "html"));
|
this.set("codeSyntax", opts.findBy("mode", "htmlmixed"));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
didRender() {
|
|
||||||
this.addTooltip(document.getElementById("set-syntax-zone"));
|
|
||||||
},
|
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
var editor = CodeMirror.fromTextArea(document.getElementById("code-editor"), {
|
var editor = CodeMirror.fromTextArea(document.getElementById(this.get('editorId')), {
|
||||||
theme: "solarized dark",
|
theme: "solarized dark",
|
||||||
lineNumbers: true,
|
lineNumbers: true,
|
||||||
lineWrapping: true,
|
lineWrapping: true,
|
||||||
|
@ -79,12 +80,13 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
dragDrop: false
|
dragDrop: false
|
||||||
});
|
});
|
||||||
|
|
||||||
editor.setSize("100%", $(document).height() - $(".document-editor > .toolbar").height() - 180);
|
CodeMirror.commands.save = function(/*instance*/){
|
||||||
|
Mousetrap.trigger('ctrl+s');
|
||||||
|
};
|
||||||
|
|
||||||
this.set('codeEditor', editor);
|
this.set('codeEditor', editor);
|
||||||
|
|
||||||
let syntax = this.get("codeSyntax");
|
let syntax = this.get("codeSyntax");
|
||||||
|
|
||||||
if (is.not.undefined(syntax)) {
|
if (is.not.undefined(syntax)) {
|
||||||
CodeMirror.autoLoadMode(editor, syntax.mode);
|
CodeMirror.autoLoadMode(editor, syntax.mode);
|
||||||
editor.setOption("mode", syntax.mode);
|
editor.setOption("mode", syntax.mode);
|
||||||
|
@ -92,7 +94,6 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
this.destroyTooltips();
|
|
||||||
this.set('codeEditor', null);
|
this.set('codeEditor', null);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -115,7 +116,7 @@ export default Ember.Component.extend(TooltipMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
isDirty() {
|
isDirty() {
|
||||||
return this.get('isDirty');
|
return this.get('isDirty') || (this.get('codeEditor').getDoc().isClean() === false);
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
|
|
@ -16,6 +16,11 @@ export default Ember.Component.extend({
|
||||||
codeSyntax: "htmlmixed",
|
codeSyntax: "htmlmixed",
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
|
this._super(...arguments);
|
||||||
|
if (this.get('isDestroyed') || this.get('isDestroying')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
|
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
|
||||||
|
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
|
@ -27,9 +32,22 @@ export default Ember.Component.extend({
|
||||||
this.set('codeSyntax', cleanBody.substring(0, startPos));
|
this.set('codeSyntax', cleanBody.substring(0, startPos));
|
||||||
this.set('codeBody', cleanBody.substring(startPos + 2));
|
this.set('codeBody', cleanBody.substring(startPos + 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), (item) => {
|
||||||
|
let i = { mode: item.mode, name: item.name };
|
||||||
|
|
||||||
|
if (item.mode === this.get('codeSyntax')) {
|
||||||
|
this.set('codeSyntax', i);
|
||||||
|
}
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
didRender() {
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
if (this.get('isDestroyed') || this.get('isDestroying')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let elem = `page-${page.id}-code`;
|
let elem = `page-${page.id}-code`;
|
||||||
|
|
||||||
|
@ -44,14 +62,18 @@ export default Ember.Component.extend({
|
||||||
readOnly: true
|
readOnly: true
|
||||||
});
|
});
|
||||||
|
|
||||||
let syntax = this.get("codeSyntax");
|
|
||||||
CodeMirror.autoLoadMode(editor, syntax);
|
|
||||||
editor.setOption("mode", syntax);
|
|
||||||
|
|
||||||
this.set('codeEditor', editor);
|
this.set('codeEditor', editor);
|
||||||
|
|
||||||
|
let syntax = this.get("codeSyntax");
|
||||||
|
if (is.not.undefined(syntax)) {
|
||||||
|
CodeMirror.autoLoadMode(editor, syntax.mode);
|
||||||
|
editor.setOption("mode", syntax.mode);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
this.set('codeEditor', null);
|
this.set('codeEditor', null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -110,11 +110,16 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin,
|
||||||
|
|
||||||
this.get('sectionService').fetch(page, "items", this.get('config'))
|
this.get('sectionService').fetch(page, "items", this.get('config'))
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
// console.log(response);
|
if (self.get('isDestroyed') || self.get('isDestroying')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.set('items', response);
|
self.set('items', response);
|
||||||
self.set('config.itemCount', response.length);
|
self.set('config.itemCount', response.length);
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
}, function (reason) { //jshint ignore: line
|
}, function (reason) { //jshint ignore: line
|
||||||
|
if (self.get('isDestroyed') || self.get('isDestroying')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
self.set('items', []);
|
self.set('items', []);
|
||||||
self.set('waiting', false);
|
self.set('waiting', false);
|
||||||
});
|
});
|
||||||
|
|
|
@ -10,68 +10,141 @@
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
import Ember from 'ember';
|
import Ember from 'ember';
|
||||||
import miscUtil from '../../../utils/misc';
|
import TooltipMixin from '../../../mixins/tooltip';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
inject: { service }
|
inject: { service }
|
||||||
} = Ember;
|
} = Ember;
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend(TooltipMixin, {
|
||||||
link: service(),
|
link: service(),
|
||||||
editMode: true,
|
|
||||||
isDirty: false,
|
|
||||||
pageBody: "",
|
pageBody: "",
|
||||||
pagePreview: "",
|
pagePreview: "",
|
||||||
height: $(document).height() - 450,
|
editMode: true,
|
||||||
|
codeSyntax: null,
|
||||||
|
codeEditor: null,
|
||||||
|
editorId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `markdown-editor-${page.id}`;
|
||||||
|
}),
|
||||||
|
previewId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `markdown-preview-${page.id}`;
|
||||||
|
}),
|
||||||
|
|
||||||
didReceiveAttrs() {
|
init() {
|
||||||
this.set("pageBody", this.get("meta.rawBody"));
|
this._super(...arguments);
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
CodeMirror.modeURL = "/codemirror/mode/%N/%N.js";
|
||||||
|
|
||||||
|
let rawBody = this.get('meta.rawBody');
|
||||||
|
let cleanBody = rawBody.replace("</pre>", "");
|
||||||
|
|
||||||
|
cleanBody = cleanBody.replace('<pre class="code-mirror cm-s-solarized cm-s-dark" data-lang="', "");
|
||||||
|
let startPos = cleanBody.indexOf('">');
|
||||||
|
let syntax = {
|
||||||
|
mode: "markdown",
|
||||||
|
name: "Markdown"
|
||||||
|
};
|
||||||
|
|
||||||
|
if (startPos !== -1) {
|
||||||
|
syntax = cleanBody.substring(0, startPos);
|
||||||
|
cleanBody = cleanBody.substring(startPos + 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('pageBody', cleanBody);
|
||||||
|
|
||||||
|
let opts = [];
|
||||||
|
|
||||||
|
_.each(_.sortBy(CodeMirror.modeInfo, 'name'), function(item) {
|
||||||
|
let i = {
|
||||||
|
mode: item.mode,
|
||||||
|
name: item.name
|
||||||
|
};
|
||||||
|
opts.pushObject(i);
|
||||||
|
|
||||||
|
if (item.mode === syntax) {
|
||||||
|
self.set('codeSyntax', i);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this.set('syntaxOptions', opts);
|
||||||
|
|
||||||
|
// default check
|
||||||
|
if (is.null(this.get("codeSyntax"))) {
|
||||||
|
this.set("codeSyntax", opts.findBy("mode", "markdown"));
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
$("#section-markdown-editor").css("height", this.get('height'));
|
this.attachEditor();
|
||||||
$("#section-markdown-preview").css("height", this.get('height'));
|
|
||||||
|
|
||||||
$("#section-markdown-editor").off("keyup").on("keyup", () => {
|
|
||||||
this.set('isDirty', true);
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
$("#section-markdown-editor").off("keyup");
|
this.set('codeEditor', null);
|
||||||
|
this.destroyTooltips();
|
||||||
|
},
|
||||||
|
|
||||||
|
getBody() {
|
||||||
|
return this.get('codeEditor').getDoc().getValue();
|
||||||
|
},
|
||||||
|
|
||||||
|
didRender() {
|
||||||
|
this.addTooltip(document.getElementById(this.get('tooltipId')));
|
||||||
|
},
|
||||||
|
|
||||||
|
attachEditor() {
|
||||||
|
var editor = CodeMirror.fromTextArea(document.getElementById(this.get('editorId')), {
|
||||||
|
theme: "solarized light",
|
||||||
|
lineNumbers: true,
|
||||||
|
lineWrapping: true,
|
||||||
|
indentUnit: 4,
|
||||||
|
tabSize: 4,
|
||||||
|
value: "",
|
||||||
|
dragDrop: false,
|
||||||
|
extraKeys: {"Enter": "newlineAndIndentContinueMarkdownList"}
|
||||||
|
});
|
||||||
|
|
||||||
|
CodeMirror.commands.save = function(/*instance*/){
|
||||||
|
Mousetrap.trigger('ctrl+s');
|
||||||
|
};
|
||||||
|
|
||||||
|
this.set('codeEditor', editor);
|
||||||
|
|
||||||
|
let syntax = this.get("codeSyntax");
|
||||||
|
|
||||||
|
if (is.not.undefined(syntax)) {
|
||||||
|
CodeMirror.autoLoadMode(editor, syntax.mode);
|
||||||
|
editor.setOption("mode", syntax.mode);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
toggleMode() {
|
onPreview() {
|
||||||
this.set('editMode', !this.get('editMode'));
|
this.set('editMode', !this.get('editMode'));
|
||||||
|
|
||||||
Ember.run.schedule('afterRender', () => {
|
Ember.run.schedule('afterRender', () => {
|
||||||
if (this.get('editMode')) {
|
if (this.get('editMode')) {
|
||||||
$("#section-markdown-editor").off("keyup").on("keyup", () => {
|
this.attachEditor();
|
||||||
this.set('isDirty', true);
|
|
||||||
});
|
|
||||||
$("#section-markdown-editor").css("height", this.get('height'));
|
|
||||||
} else {
|
} else {
|
||||||
let md = window.markdownit({ linkify: true });
|
let md = window.markdownit({ linkify: true });
|
||||||
let result = md.render(this.get("pageBody"));
|
let result = md.render(this.getBody());
|
||||||
|
|
||||||
this.set('pagePreview', result);
|
this.set('pagePreview', result);
|
||||||
$("#section-markdown-preview").css("height", this.get('height'));
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onInsertLink(link) {
|
onInsertLink(link) {
|
||||||
let linkMarkdown = this.get('link').buildLink(link);
|
let linkMarkdown = this.get('link').buildLink(link);
|
||||||
|
this.get('codeEditor').getDoc().replaceSelection(linkMarkdown);
|
||||||
miscUtil.insertAtCursor($("#section-markdown-editor")[0], linkMarkdown);
|
|
||||||
this.set('pageBody', $("#section-markdown-editor").val());
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
isDirty() {
|
isDirty() {
|
||||||
return this.get('isDirty');
|
return this.get('codeEditor').getDoc().isClean() === false;
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
@ -82,7 +155,7 @@ export default Ember.Component.extend({
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let meta = this.get('meta');
|
let meta = this.get('meta');
|
||||||
page.set('title', title);
|
page.set('title', title);
|
||||||
meta.set('rawBody', this.get("pageBody"));
|
meta.set('rawBody', this.getBody());
|
||||||
|
|
||||||
this.attrs.onAction(page, meta);
|
this.attrs.onAction(page, meta);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,6 @@ export default Ember.Component.extend(SectionMixin, NotifierMixin, TooltipMixin,
|
||||||
self.set('authenticated', true);
|
self.set('authenticated', true);
|
||||||
self.set('items', response);
|
self.set('items', response);
|
||||||
self.set('config.APIToken', '********'); // reset the api token once it has been sent to the host
|
self.set('config.APIToken', '********'); // reset the api token once it has been sent to the host
|
||||||
console.log("auth token OK");
|
|
||||||
|
|
||||||
self.get('sectionService').fetch(page, "options", config)
|
self.get('sectionService').fetch(page, "options", config)
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
|
|
|
@ -14,6 +14,10 @@ import Ember from 'ember';
|
||||||
export default Ember.Component.extend({
|
export default Ember.Component.extend({
|
||||||
isDirty: false,
|
isDirty: false,
|
||||||
pageBody: "",
|
pageBody: "",
|
||||||
|
editorId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `table-editor-${page.id}`;
|
||||||
|
}),
|
||||||
defaultTable: '<table class="wysiwyg-table" style="width: 100%;"><thead><tr><th><br></th><th><br></th><th><br></th><th><br></th></tr></thead><tbody><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr></tbody></table>',
|
defaultTable: '<table class="wysiwyg-table" style="width: 100%;"><thead><tr><th><br></th><th><br></th><th><br></th><th><br></th></tr></thead><tbody><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr><tr><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td><td style="width: 25.0000%;"><br></td></tr></tbody></table>',
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
|
@ -25,23 +29,20 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
$('#table-editor').froalaEditor({
|
let id = '#' + this.get('editorId');
|
||||||
|
$(id).froalaEditor({
|
||||||
toolbarButtons: [],
|
toolbarButtons: [],
|
||||||
height: $(document).height() - 400,
|
|
||||||
toolbarInline: true,
|
toolbarInline: true,
|
||||||
tableResizerOffset: 10
|
tableResizerOffset: 10
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#table-editor').on('froalaEditor.contentChanged', () => {
|
$(id).on('froalaEditor.contentChanged', () => {
|
||||||
this.set('isDirty', true);
|
this.set('isDirty', true);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
$('#table-editor').off('froalaEditor.contentChanged');
|
$('#' + this.get('editorId')).off('froalaEditor.contentChanged');
|
||||||
// if ($('#table-editor').data('froala.editor')) {
|
|
||||||
// $('#table-editor').froalaEditor('destroy');
|
|
||||||
// }
|
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
@ -57,7 +58,7 @@ export default Ember.Component.extend({
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let meta = this.get('meta');
|
let meta = this.get('meta');
|
||||||
|
|
||||||
let body = $("#table-editor").froalaEditor('html.get', true);
|
let body = $('#' + this.get('editorId')).froalaEditor('html.get', true);
|
||||||
page.set('title', title);
|
page.set('title', title);
|
||||||
|
|
||||||
if (is.empty(body)) {
|
if (is.empty(body)) {
|
||||||
|
|
|
@ -19,29 +19,32 @@ export default Ember.Component.extend({
|
||||||
appMeta: service(),
|
appMeta: service(),
|
||||||
link: service(),
|
link: service(),
|
||||||
pageBody: "",
|
pageBody: "",
|
||||||
|
editorId: Ember.computed('page', function () {
|
||||||
|
let page = this.get('page');
|
||||||
|
return `wysiwyg-editor-${page.id}`;
|
||||||
|
}),
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this.set('pageBody', this.get('meta.rawBody'));
|
this.set('pageBody', this.get('meta.rawBody'));
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
let maxHeight = $(document).height() - 450;
|
|
||||||
|
|
||||||
let options = {
|
let options = {
|
||||||
selector: "#rich-text-editor",
|
selector: "#" + this.get('editorId'),
|
||||||
relative_urls: false,
|
relative_urls: false,
|
||||||
cache_suffix: "?v=443",
|
cache_suffix: "?v=443",
|
||||||
browser_spellcheck: false,
|
browser_spellcheck: false,
|
||||||
gecko_spellcheck: false,
|
gecko_spellcheck: false,
|
||||||
theme: "modern",
|
theme: "modern",
|
||||||
|
skin: 'documize',
|
||||||
statusbar: false,
|
statusbar: false,
|
||||||
height: maxHeight,
|
inline: true,
|
||||||
entity_encoding: "raw",
|
entity_encoding: "raw",
|
||||||
paste_data_images: true,
|
paste_data_images: true,
|
||||||
image_advtab: true,
|
image_advtab: true,
|
||||||
image_caption: true,
|
image_caption: true,
|
||||||
media_live_embeds: true,
|
media_live_embeds: true,
|
||||||
fontsize_formats: "8px 10px 12px 14px 18px 24px 36px 40px 50px 60px",
|
fontsize_formats: "8px 10px 12px 14px 17px 18px 24px 36px 40px 50px 60px",
|
||||||
formats: {
|
formats: {
|
||||||
bold: {
|
bold: {
|
||||||
inline: 'b'
|
inline: 'b'
|
||||||
|
@ -50,6 +53,17 @@ export default Ember.Component.extend({
|
||||||
inline: 'i'
|
inline: 'i'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
codesample_languages: [
|
||||||
|
{text: 'HTML/XML', value: 'markup'},
|
||||||
|
{text: 'JavaScript', value: 'javascript'},
|
||||||
|
{text: 'CSS', value: 'css'},
|
||||||
|
{text: 'PHP', value: 'php'},
|
||||||
|
{text: 'Ruby', value: 'ruby'},
|
||||||
|
{text: 'Python', value: 'python'},
|
||||||
|
{text: 'Java', value: 'java'},
|
||||||
|
{text: 'C', value: 'c'},
|
||||||
|
{text: 'C#', value: 'csharp'},
|
||||||
|
{text: 'C++', value: 'cpp'}],
|
||||||
extended_valid_elements: "b,i,b/strong,i/em",
|
extended_valid_elements: "b,i,b/strong,i/em",
|
||||||
plugins: [
|
plugins: [
|
||||||
'advlist autolink lists link image charmap print preview hr anchor pagebreak',
|
'advlist autolink lists link image charmap print preview hr anchor pagebreak',
|
||||||
|
@ -59,8 +73,8 @@ export default Ember.Component.extend({
|
||||||
],
|
],
|
||||||
menu: {},
|
menu: {},
|
||||||
menubar: false,
|
menubar: false,
|
||||||
toolbar1: "bold italic underline strikethrough superscript subscript | outdent indent bullist numlist forecolor backcolor | alignleft aligncenter alignright alignjustify | link unlink | table image media codesample",
|
toolbar1: "formatselect fontsizeselect | bold italic underline strikethrough superscript subscript | forecolor backcolor link unlink",
|
||||||
toolbar2: "formatselect fontselect fontsizeselect",
|
toolbar2: "outdent indent bullist numlist | alignleft aligncenter alignright alignjustify | table image media codesample",
|
||||||
save_onsavecallback: function () {
|
save_onsavecallback: function () {
|
||||||
Mousetrap.trigger('ctrl+s');
|
Mousetrap.trigger('ctrl+s');
|
||||||
}
|
}
|
||||||
|
@ -79,25 +93,27 @@ export default Ember.Component.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
tinymce.remove();
|
tinymce.EditorManager.execCommand('mceRemoveEditor', true, this.get('editorId'));
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onInsertLink(link) {
|
onInsertLink(link) {
|
||||||
let userSelection = tinymce.activeEditor.selection.getContent();
|
let editor = tinymce.EditorManager.get(this.get('editorId'));
|
||||||
|
let userSelection = editor.selection.getContent();
|
||||||
|
|
||||||
if (is.not.empty(userSelection)) {
|
if (is.not.empty(userSelection)) {
|
||||||
Ember.set(link, 'title', userSelection);
|
Ember.set(link, 'title', userSelection);
|
||||||
}
|
}
|
||||||
|
|
||||||
let linkHTML = this.get('link').buildLink(link);
|
let linkHTML = this.get('link').buildLink(link);
|
||||||
tinymce.activeEditor.insertContent(linkHTML);
|
editor.insertContent(linkHTML);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
||||||
isDirty() {
|
isDirty() {
|
||||||
return is.not.undefined(tinymce) && is.not.undefined(tinymce.activeEditor) && tinymce.activeEditor.isDirty();
|
let editor = tinymce.EditorManager.get(this.get('editorId'));
|
||||||
|
return is.not.undefined(tinymce) && is.not.undefined(editor) && editor.isDirty();
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancel() {
|
onCancel() {
|
||||||
|
@ -107,9 +123,10 @@ export default Ember.Component.extend({
|
||||||
onAction(title) {
|
onAction(title) {
|
||||||
let page = this.get('page');
|
let page = this.get('page');
|
||||||
let meta = this.get('meta');
|
let meta = this.get('meta');
|
||||||
|
let editor = tinymce.EditorManager.get(this.get('editorId'));
|
||||||
|
|
||||||
page.set('title', title);
|
page.set('title', title);
|
||||||
meta.set('rawBody', tinymce.activeEditor.getContent());
|
meta.set('rawBody', editor.getContent());
|
||||||
|
|
||||||
this.attrs.onAction(page, meta);
|
this.attrs.onAction(page, meta);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
{{content-for 'head'}}
|
{{content-for 'head'}}
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
@ -17,7 +16,6 @@
|
||||||
<link rel="stylesheet" href="/assets/documize.css">
|
<link rel="stylesheet" href="/assets/documize.css">
|
||||||
{{content-for 'head-footer'}}
|
{{content-for 'head-footer'}}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
{{content-for 'body'}}
|
{{content-for 'body'}}
|
||||||
<script src="/assets/vendor.js"></script>
|
<script src="/assets/vendor.js"></script>
|
||||||
|
@ -29,5 +27,4 @@
|
||||||
<script src="/codemirror/addon/runmode/colorize.js"></script>
|
<script src="/codemirror/addon/runmode/colorize.js"></script>
|
||||||
{{content-for 'body-footer'}}
|
{{content-for 'body-footer'}}
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -25,7 +25,6 @@ export default Model.extend({
|
||||||
userId: attr('string'),
|
userId: attr('string'),
|
||||||
tags: attr('string'),
|
tags: attr('string'),
|
||||||
template: attr('boolean'),
|
template: attr('boolean'),
|
||||||
layout: attr('string'),
|
|
||||||
|
|
||||||
// client-side property
|
// client-side property
|
||||||
selected: attr('boolean', { defaultValue: false }),
|
selected: attr('boolean', { defaultValue: false }),
|
||||||
|
|
|
@ -29,7 +29,8 @@ export default Model.extend({
|
||||||
meta: attr(),
|
meta: attr(),
|
||||||
|
|
||||||
tagName: Ember.computed('level', function () {
|
tagName: Ember.computed('level', function () {
|
||||||
return "h" + (this.get('level') + 1);
|
return "h2";
|
||||||
|
// return "h" + (this.get('level') + 1);
|
||||||
}),
|
}),
|
||||||
|
|
||||||
tocIndent: Ember.computed('level', function () {
|
tocIndent: Ember.computed('level', function () {
|
||||||
|
|
|
@ -1,33 +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'),
|
|
||||||
|
|
||||||
model() {
|
|
||||||
this.audit.record("viewed-document-activity");
|
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
|
||||||
folders: this.modelFor('document').folders,
|
|
||||||
folder: this.modelFor('document').folder,
|
|
||||||
document: this.modelFor('document').document,
|
|
||||||
isEditor: this.modelFor('document').isEditor,
|
|
||||||
pages: this.modelFor('document').allPages,
|
|
||||||
tabs: this.modelFor('document').tabs,
|
|
||||||
activity: this.get('documentService').getMeta(this.modelFor('document').document.get('id')).then((activity) => {
|
|
||||||
return activity;
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1 +0,0 @@
|
||||||
{{document/document-activity document=model.document pages=model.pages activity=model.activity}}
|
|
|
@ -16,31 +16,23 @@ export default Ember.Controller.extend({
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onCancel( /*page*/ ) {
|
onCancel( /*page*/ ) {
|
||||||
this.transitionToRoute('document', {
|
this.transitionToRoute('document');
|
||||||
queryParams: {
|
|
||||||
page: this.get('model.page.id')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onAction(page, meta) {
|
onAction(page, meta) {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
let block = this.get('model.block');
|
let b = this.get('model.block');
|
||||||
block.set('title', page.get('title'));
|
b.set('title', page.get('title'));
|
||||||
block.set('body', page.get('body'));
|
b.set('body', page.get('body'));
|
||||||
block.set('excerpt', page.get('excerpt'));
|
b.set('excerpt', page.get('excerpt'));
|
||||||
block.set('rawBody', meta.get('rawBody'));
|
b.set('rawBody', meta.get('rawBody'));
|
||||||
block.set('config', meta.get('config'));
|
b.set('config', meta.get('config'));
|
||||||
block.set('externalSource', meta.get('externalSource'));
|
b.set('externalSource', meta.get('externalSource'));
|
||||||
|
|
||||||
this.get('sectionService').updateBlock(block).then(function () {
|
this.get('sectionService').updateBlock(b).then(function () {
|
||||||
self.audit.record("edited-block");
|
self.audit.record("edited-block");
|
||||||
self.transitionToRoute('document', {
|
self.transitionToRoute('document');
|
||||||
queryParams: {
|
|
||||||
page: page.get('id')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,5 +27,13 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
document: self.modelFor('document').document,
|
document: self.modelFor('document').document,
|
||||||
block: self.get('sectionService').getBlock(params.block_id),
|
block: self.get('sectionService').getBlock(params.block_id),
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
activate() {
|
||||||
|
$('body').addClass('background-color-off-white');
|
||||||
|
},
|
||||||
|
|
||||||
|
deactivate() {
|
||||||
|
$('body').removeClass('background-color-off-white');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1 +1,20 @@
|
||||||
{{document/block-editor document=model.document folder=model.folder block=model.block onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
<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/block-editor document=model.document folder=model.folder block=model.block onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,196 +13,4 @@ import Ember from 'ember';
|
||||||
import NotifierMixin from '../../mixins/notifier';
|
import NotifierMixin from '../../mixins/notifier';
|
||||||
|
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
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: [],
|
|
||||||
|
|
||||||
// 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', []);
|
|
||||||
this.set('model.pages', pages);
|
|
||||||
this.get('target.router').refresh();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
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');
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddSection(section) {
|
|
||||||
this.audit.record("added-section-" + section.get('contentType'));
|
|
||||||
|
|
||||||
let page = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
title: `${section.get('title')}`,
|
|
||||||
level: 1,
|
|
||||||
sequence: 0,
|
|
||||||
body: "",
|
|
||||||
contentType: section.get('contentType'),
|
|
||||||
pageType: section.get('pageType')
|
|
||||||
};
|
|
||||||
|
|
||||||
let meta = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
rawBody: "",
|
|
||||||
config: ""
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
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'));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,43 +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';
|
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
|
||||||
documentService: Ember.inject.service('document'),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
onCancel( /*page*/ ) {
|
|
||||||
this.transitionToRoute('document', {
|
|
||||||
queryParams: {
|
|
||||||
page: this.get('model.page.id')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onAction(page, meta) {
|
|
||||||
let self = this;
|
|
||||||
let model = {
|
|
||||||
page: page.toJSON({ includeId: true }),
|
|
||||||
meta: meta.toJSON({ includeId: true })
|
|
||||||
};
|
|
||||||
|
|
||||||
this.get('documentService').updatePage(page.get('documentId'), page.get('id'), model).then(function () {
|
|
||||||
self.audit.record("edited-page");
|
|
||||||
self.transitionToRoute('document', {
|
|
||||||
queryParams: {
|
|
||||||
page: page.get('id')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,31 +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'),
|
|
||||||
folderService: Ember.inject.service('folder'),
|
|
||||||
|
|
||||||
model(params) {
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
this.audit.record("edited-page");
|
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
|
||||||
folder: self.modelFor('document').folder,
|
|
||||||
document: self.modelFor('document').document,
|
|
||||||
page: self.get('documentService').getPage(self.paramsFor('document').document_id, params.page_id),
|
|
||||||
meta: self.get('documentService').getPageMeta(self.paramsFor('document').document_id, params.page_id)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1 +0,0 @@
|
||||||
{{document/document-editor document=model.document folder=model.folder page=model.page meta=model.meta onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
|
|
@ -1,40 +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'),
|
|
||||||
|
|
||||||
getAttachments() {
|
|
||||||
let self = this;
|
|
||||||
this.get('documentService').getAttachments(this.get('model.document.id')).then(function (files) {
|
|
||||||
self.set('model.files', files);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
onUpload() {
|
|
||||||
this.getAttachments();
|
|
||||||
},
|
|
||||||
|
|
||||||
onDelete(id, name) {
|
|
||||||
let self = this;
|
|
||||||
|
|
||||||
this.showNotification(`Deleted ${name}`);
|
|
||||||
|
|
||||||
this.get('documentService').deleteAttachment(this.get('model.document.id'), id).then(function () {
|
|
||||||
self.getAttachments();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,31 +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'),
|
|
||||||
|
|
||||||
model() {
|
|
||||||
this.audit.record("viewed-document-attachments");
|
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
|
||||||
folders: this.modelFor('document').folders,
|
|
||||||
folder: this.modelFor('document').folder,
|
|
||||||
document: this.modelFor('document').document,
|
|
||||||
isEditor: this.modelFor('document').isEditor,
|
|
||||||
pages: this.modelFor('document').allPages,
|
|
||||||
tabs: this.modelFor('document').tabs,
|
|
||||||
files: this.get('documentService').getAttachments(this.modelFor('document').document.get('id'))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1 +0,0 @@
|
||||||
{{document/document-files document=model.document files=model.files isEditor=model.isEditor onUpload=(action 'onUpload') onDelete=(action 'onDelete')}}
|
|
|
@ -17,11 +17,11 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
this.audit.record("restored-page");
|
this.audit.record("restored-page");
|
||||||
|
|
||||||
this.get('documentService').rollbackPage(this.get('model.document.id'), pageId, revisionId).then(() => {
|
this.get('documentService').rollbackPage(this.get('model.document.id'), pageId, revisionId).then(() => {
|
||||||
this.transitionToRoute('document', {
|
this.transitionToRoute('document.index',
|
||||||
queryParams: {
|
this.get('model.folder.id'),
|
||||||
page: pageId
|
this.get('model.folder.slug'),
|
||||||
}
|
this.get('model.document.id'),
|
||||||
});
|
this.get('model.document.slug'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,2 +1,21 @@
|
||||||
{{document/document-history document=model.document folder=model.folder pages=model.pages revisions=model.revisions diff=model.diff
|
<div class="zone-document-history">
|
||||||
onFetchDiff=(action 'onFetchDiff') onRollback=(action 'onRollback')}}
|
<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-history document=model.document folder=model.folder pages=model.pages
|
||||||
|
revisions=model.revisions diff=model.diff onFetchDiff=(action 'onFetchDiff') onRollback=(action 'onRollback')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,39 +14,176 @@ import NotifierMixin from '../../../mixins/notifier';
|
||||||
|
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
export default Ember.Controller.extend(NotifierMixin, {
|
||||||
documentService: Ember.inject.service('document'),
|
documentService: Ember.inject.service('document'),
|
||||||
|
templateService: Ember.inject.service('template'),
|
||||||
sectionService: Ember.inject.service('section'),
|
sectionService: Ember.inject.service('section'),
|
||||||
queryParams: ['page'],
|
folder: {},
|
||||||
|
pages: [],
|
||||||
|
toggled: false,
|
||||||
|
queryParams: ['pageId', 'tab'],
|
||||||
|
pageId: '',
|
||||||
|
tab: 'index',
|
||||||
|
|
||||||
// Jump to the right part of the document.
|
actions: {
|
||||||
scrollToPage(pageId) {
|
toggleSidebar() {
|
||||||
Ember.run.schedule('afterRender', function () {
|
this.set('toggled', !this.get('toggled'));
|
||||||
let dest;
|
},
|
||||||
let target = "#page-title-" + pageId;
|
|
||||||
let targetOffset = $(target).offset();
|
|
||||||
|
|
||||||
if (is.undefined(targetOffset)) {
|
onSaveDocument(doc) {
|
||||||
return;
|
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.set('pageId', '');
|
||||||
|
this.get('target.router').refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
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: {
|
onMovePage(pageId, targetDocumentId) {
|
||||||
gotoPage(pageId) {
|
let documentId = this.get('model.document.id');
|
||||||
if (is.null(pageId)) {
|
|
||||||
return;
|
this.get('documentService').copyPage(documentId, pageId, targetDocumentId).then(() => {
|
||||||
|
this.showNotification("Moved");
|
||||||
|
this.send('onPageDeleted', { id: pageId, children: false });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSavePage(page, meta) {
|
||||||
|
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(() => {
|
||||||
|
this.set('pageId', page.get('id'));
|
||||||
|
});
|
||||||
|
|
||||||
|
this.audit.record("edited-page");
|
||||||
|
},
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.scrollToPage(pageId);
|
pendingChanges.push({
|
||||||
|
pageId: pages[i].get('id'),
|
||||||
|
level: pages[i].get('level') - 1
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.set('pageId', '');
|
||||||
|
|
||||||
|
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.transitionToRoute('document.index',
|
||||||
|
this.get('model.folder.id'),
|
||||||
|
this.get('model.folder.slug'),
|
||||||
|
this.get('model.document.id'),
|
||||||
|
this.get('model.document.slug'));
|
||||||
|
});
|
||||||
|
} 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.set('pageId', newPage.id);
|
||||||
|
|
||||||
|
this.get('documentService').getPages(this.get('model.document.id')).then((pages) => {
|
||||||
|
this.set('model.pages', pages);
|
||||||
|
|
||||||
|
if (newPage.pageType === 'tab') {
|
||||||
|
this.transitionToRoute('document.section',
|
||||||
|
this.get('model.folder.id'),
|
||||||
|
this.get('model.folder.slug'),
|
||||||
|
this.get('model.document.id'),
|
||||||
|
this.get('model.document.slug'),
|
||||||
|
newPage.id);
|
||||||
|
} else {
|
||||||
|
resolve(newPage.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onDeleteBlock(blockId) {
|
||||||
|
return new Ember.RSVP.Promise((resolve) => {
|
||||||
|
this.get('sectionService').deleteBlock(blockId).then(() => {
|
||||||
|
this.audit.record("deleted-block");
|
||||||
|
this.send("showNotification", "Deleted");
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSavePageAsBlock(block) {
|
||||||
|
return new Ember.RSVP.Promise((resolve) => {
|
||||||
|
this.get('sectionService').addBlock(block).then(() => {
|
||||||
|
this.showNotification("Published");
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
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'));
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSaveTemplate(name, desc) {
|
||||||
|
this.get('templateService').saveAsTemplate(this.get('model.document.id'), name, desc).then(function () {});
|
||||||
},
|
},
|
||||||
|
|
||||||
onPageSequenceChange(changes) {
|
onPageSequenceChange(changes) {
|
||||||
|
@ -80,92 +217,15 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
|
|
||||||
let pages = this.get('model.pages');
|
let pages = this.get('model.pages');
|
||||||
pages = pages.sortBy('sequence');
|
pages = pages.sortBy('sequence');
|
||||||
|
this.set('model.pages', []);
|
||||||
this.set('model.pages', pages);
|
this.set('model.pages', pages);
|
||||||
|
|
||||||
this.get('target.router').refresh();
|
this.get('target.router').refresh();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onAddBlock(block) {
|
onGotoPage(id) {
|
||||||
this.get('sectionService').addBlock(block).then(() => {
|
if (this.get('pageId') !== id && id !== '') {
|
||||||
this.showNotification("Published");
|
this.set('pageId', id);
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
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 });
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,50 +17,20 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
linkService: Ember.inject.service('link'),
|
linkService: Ember.inject.service('link'),
|
||||||
folderService: Ember.inject.service('folder'),
|
folderService: Ember.inject.service('folder'),
|
||||||
userService: Ember.inject.service('user'),
|
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() {
|
model() {
|
||||||
this.browser.setTitle(this.get('document.name'));
|
let document = this.modelFor('document').document;
|
||||||
this.browser.setMetaDescription(this.get('document.excerpt'));
|
this.browser.setTitle(document.get('name'));
|
||||||
|
this.browser.setMetaDescription(document.get('excerpt'));
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folders: this.get('folders'),
|
folders: this.modelFor('document').folders,
|
||||||
folder: this.get('folder'),
|
folder: this.modelFor('document').folder,
|
||||||
document: this.get('document'),
|
document: this.modelFor('document').document,
|
||||||
page: this.get('pageId'),
|
pages: this.get('documentService').getPages(this.modelFor('document').document.get('id')),
|
||||||
isEditor: this.get('folderService').get('canEditCurrentFolder'),
|
links: this.modelFor('document').links,
|
||||||
allPages: this.get('allPages'),
|
sections: this.modelFor('document').sections,
|
||||||
pages: this.get('pages'),
|
isEditor: this.get('folderService').get('canEditCurrentFolder')
|
||||||
tabs: this.get('tabs'),
|
|
||||||
links: this.get('linkService').getDocumentLinks(this.get('documentId'))
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,2 +1,45 @@
|
||||||
{{document/document-view document=model.document links=model.links allPages=model.allPages tabs=model.tabs pages=model.pages folder=model.folder folders=model.folders isEditor=model.isEditor
|
<div id="wrapper" class={{if toggled 'toggled'}}>
|
||||||
gotoPage=(action 'gotoPage') onAddBlock=(action 'onAddBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')}}
|
|
||||||
|
<div id="sidebar-wrapper">
|
||||||
|
{{document/sidebar-zone folders=model.folders folder=model.folder document=model.document
|
||||||
|
pages=model.pages sections=model.section links=model.links isEditor=model.isEditor tab=tab
|
||||||
|
onDocumentDelete=(action 'onDocumentDelete') onSaveTemplate=(action 'onSaveTemplate')
|
||||||
|
onPageSequenceChange=(action 'onPageSequenceChange') onPageLevelChange=(action 'onPageLevelChange') onGotoPage=(action 'onGotoPage')}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="page-content-wrapper">
|
||||||
|
<div class="{{if toggled 'container' '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 pages=model.pages
|
||||||
|
folder=model.folder folders=model.folders sections=model.sections isEditor=model.isEditor pageId=pageId
|
||||||
|
onSavePage=(action 'onSavePage') onInsertSection=(action 'onInsertSection')
|
||||||
|
onSavePageAsBlock=(action 'onSavePageAsBlock') onDeleteBlock=(action 'onDeleteBlock')
|
||||||
|
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')}}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
|
@ -16,6 +16,7 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
sectionService: Ember.inject.service('section'),
|
sectionService: Ember.inject.service('section'),
|
||||||
documentService: Ember.inject.service('document'),
|
documentService: Ember.inject.service('document'),
|
||||||
folderService: Ember.inject.service('folder'),
|
folderService: Ember.inject.service('folder'),
|
||||||
|
linkService: Ember.inject.service('link'),
|
||||||
|
|
||||||
beforeModel(transition) {
|
beforeModel(transition) {
|
||||||
this.set('pageId', is.not.undefined(transition.queryParams.page) ? transition.queryParams.page : "");
|
this.set('pageId', is.not.undefined(transition.queryParams.page) ? transition.queryParams.page : "");
|
||||||
|
@ -34,18 +35,12 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
|
||||||
this.get('folderService').setCurrentFolder(folder).then(() => {
|
this.get('folderService').setCurrentFolder(folder).then(() => {
|
||||||
this.set('isEditor', this.get('folderService').get('canEditCurrentFolder'));
|
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'));
|
|
||||||
resolve();
|
resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
model() {
|
model() {
|
||||||
|
@ -55,15 +50,19 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
document: this.get('document'),
|
document: this.get('document'),
|
||||||
page: this.get('pageId'),
|
page: this.get('pageId'),
|
||||||
isEditor: this.get('isEditor'),
|
isEditor: this.get('isEditor'),
|
||||||
allPages: this.get('allPages'),
|
links: this.get('linkService').getDocumentLinks(this.get('documentId')),
|
||||||
pages: this.get('pages'),
|
sections: this.get('sectionService').getAll()
|
||||||
tabs: this.get('tabs'),
|
|
||||||
sections: this.get('sectionService').getAll().then((sections) => {
|
|
||||||
return sections.filterBy('pageType', 'section');
|
|
||||||
}),
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
activate() {
|
||||||
|
$('body').addClass('background-color-off-white');
|
||||||
|
},
|
||||||
|
|
||||||
|
deactivate() {
|
||||||
|
$('body').removeClass('background-color-off-white');
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
error(error /*, transition*/ ) {
|
error(error /*, transition*/ ) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
|
|
|
@ -14,12 +14,19 @@ import NotifierMixin from '../../../mixins/notifier';
|
||||||
|
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
export default Ember.Controller.extend(NotifierMixin, {
|
||||||
documentService: Ember.inject.service('document'),
|
documentService: Ember.inject.service('document'),
|
||||||
queryParams: ['mode'],
|
|
||||||
mode: null,
|
|
||||||
|
|
||||||
actions: {
|
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'),
|
||||||
|
{ queryParams: { pageId: this.get('model.page.id') }});
|
||||||
|
},
|
||||||
|
|
||||||
onAction(page, meta) {
|
onAction(page, meta) {
|
||||||
this.showNotification("Saving");
|
this.showNotification("Saved");
|
||||||
|
|
||||||
let model = {
|
let model = {
|
||||||
page: page.toJSON({ includeId: true }),
|
page: page.toJSON({ includeId: true }),
|
||||||
|
@ -30,17 +37,14 @@ export default Ember.Controller.extend(NotifierMixin, {
|
||||||
this.audit.record("edited-page");
|
this.audit.record("edited-page");
|
||||||
let data = this.get('store').normalize('page', page);
|
let data = this.get('store').normalize('page', page);
|
||||||
this.get('store').push(data);
|
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'),
|
||||||
|
{ queryParams: { pageId: page.get('id')}});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
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();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -16,28 +16,25 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
|
||||||
documentService: Ember.inject.service('document'),
|
documentService: Ember.inject.service('document'),
|
||||||
folderService: Ember.inject.service('folder'),
|
folderService: Ember.inject.service('folder'),
|
||||||
userService: Ember.inject.service('user'),
|
userService: Ember.inject.service('user'),
|
||||||
pageId: '',
|
|
||||||
queryParams: {
|
|
||||||
mode: {
|
|
||||||
refreshModel: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
beforeModel(transition) {
|
|
||||||
this.set('mode', !_.isUndefined(transition.queryParams.mode) ? transition.queryParams.mode : '');
|
|
||||||
},
|
|
||||||
|
|
||||||
model(params) {
|
model(params) {
|
||||||
return Ember.RSVP.hash({
|
return Ember.RSVP.hash({
|
||||||
folders: this.modelFor('document').folders,
|
folders: this.modelFor('document').folders,
|
||||||
folder: this.modelFor('document').folder,
|
folder: this.modelFor('document').folder,
|
||||||
document: this.modelFor('document').document,
|
document: this.modelFor('document').document,
|
||||||
pages: this.modelFor('document').pages,
|
isEditor: this.get('folderService').get('canEditCurrentFolder'),
|
||||||
tabs: this.get('documentService').getPages(this.modelFor('document').document.get('id')).then((pages) => {
|
links: this.modelFor('document').links,
|
||||||
return pages.filterBy('pageType', 'tab');
|
sections: this.modelFor('document').sections,
|
||||||
}),
|
|
||||||
page: this.get('documentService').getPage(this.modelFor('document').document.get('id'), params.page_id),
|
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)
|
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,13 +1,2 @@
|
||||||
{{layout/zone-navigation}}
|
{{layout/zone-navigation}}
|
||||||
|
{{outlet}}
|
||||||
{{#layout/zone-sidebar}}
|
|
||||||
{{document/document-sidebar document=model.document folder=model.folder pages=model.pages page=model.page isEditor=model.isEditor sections=model.sections
|
|
||||||
onAddSection=(action 'onAddSection') onInsertBlock=(action 'onInsertBlock') onDeleteBlock=(action 'onDeleteBlock') changePageSequence=(action 'onPageSequenceChange') changePageLevel=(action 'onPageLevelChange') gotoPage=(action 'gotoPage')}}
|
|
||||||
{{/layout/zone-sidebar}}
|
|
||||||
|
|
||||||
{{#layout/zone-content}}
|
|
||||||
{{document/document-toolbar document=model.document pages=model.pages tabs=model.tabs folder=model.folder isEditor=model.isEditor
|
|
||||||
onSaveTemplate=(action 'onSaveTemplate') onSaveMeta=(action 'onSaveMeta') onDocumentDelete=(action 'onDocumentDelete')}}
|
|
||||||
|
|
||||||
{{outlet}}
|
|
||||||
{{/layout/zone-content}}
|
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
import Ember from 'ember';
|
|
||||||
import NotifierMixin from '../../../mixins/notifier';
|
|
||||||
|
|
||||||
export default Ember.Controller.extend(NotifierMixin, {
|
|
||||||
documentService: Ember.inject.service('document'),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
onCancel() {
|
|
||||||
this.transitionToRoute('document');
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddSection(section) {
|
|
||||||
this.audit.record("added-section-" + section.get('contentType'));
|
|
||||||
|
|
||||||
let page = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
title: `${section.get('title')}`,
|
|
||||||
level: 1,
|
|
||||||
sequence: 0,
|
|
||||||
body: "",
|
|
||||||
contentType: section.get('contentType'),
|
|
||||||
pageType: section.get('pageType')
|
|
||||||
};
|
|
||||||
|
|
||||||
let meta = {
|
|
||||||
documentId: this.get('model.document.id'),
|
|
||||||
rawBody: "",
|
|
||||||
config: "",
|
|
||||||
externaleSource: true
|
|
||||||
};
|
|
||||||
|
|
||||||
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(() => {
|
|
||||||
let options = {};
|
|
||||||
options['mode'] = 'edit';
|
|
||||||
this.transitionToRoute('document.section', newPage.id, { queryParams: options });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1,21 +0,0 @@
|
||||||
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'),
|
|
||||||
folderService: Ember.inject.service('folder'),
|
|
||||||
sectionService: Ember.inject.service('section'),
|
|
||||||
|
|
||||||
model() {
|
|
||||||
return Ember.RSVP.hash({
|
|
||||||
folders: this.modelFor('document').folders,
|
|
||||||
folder: this.modelFor('document').folder,
|
|
||||||
document: this.modelFor('document').document,
|
|
||||||
pages: this.modelFor('document').pages,
|
|
||||||
tabs: this.modelFor('document').tabs,
|
|
||||||
sections: this.get('sectionService').getAll().then(function (sections) {
|
|
||||||
return sections.filterBy('pageType', 'tab');
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
|
@ -1 +0,0 @@
|
||||||
{{document/page-wizard display='tab' document=model.document folder=model.folder sections=model.sections onCancel=(action 'onCancel') onAddSection=(action 'onAddSection')}}
|
|
|
@ -32,27 +32,15 @@ export default Router.map(function () {
|
||||||
this.route('document', {
|
this.route('document', {
|
||||||
path: 's/:folder_id/:folder_slug/d/:document_id/:document_slug'
|
path: 's/:folder_id/:folder_slug/d/:document_id/:document_slug'
|
||||||
}, function () {
|
}, function () {
|
||||||
this.route('files', {
|
|
||||||
path: 'files'
|
|
||||||
});
|
|
||||||
this.route('activity', {
|
|
||||||
path: 'activity'
|
|
||||||
});
|
|
||||||
this.route('section', {
|
this.route('section', {
|
||||||
path: 'section/:page_id'
|
path: 'section/:page_id'
|
||||||
});
|
});
|
||||||
this.route('edit', {
|
this.route('block', {
|
||||||
path: 'edit/:page_id'
|
path: 'block/:block_id'
|
||||||
});
|
|
||||||
this.route('wizard', {
|
|
||||||
path: 'add'
|
|
||||||
});
|
});
|
||||||
this.route('history', {
|
this.route('history', {
|
||||||
path: 'history'
|
path: 'history'
|
||||||
});
|
});
|
||||||
this.route('block', {
|
|
||||||
path: 'block/:block_id'
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.route('customize', {
|
this.route('customize', {
|
||||||
|
|
|
@ -211,6 +211,9 @@ export default Ember.Service.extend({
|
||||||
getMeta(documentId) {
|
getMeta(documentId) {
|
||||||
return this.get('ajax').request(`documents/${documentId}/meta`, {
|
return this.get('ajax').request(`documents/${documentId}/meta`, {
|
||||||
method: "GET"
|
method: "GET"
|
||||||
|
}).then((response) => {
|
||||||
|
return response;
|
||||||
|
}).catch(() => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -232,7 +235,6 @@ export default Ember.Service.extend({
|
||||||
|
|
||||||
// Returns all document pages with content
|
// Returns all document pages with content
|
||||||
getPages(documentId) {
|
getPages(documentId) {
|
||||||
|
|
||||||
return this.get('ajax').request(`documents/${documentId}/pages`, {
|
return this.get('ajax').request(`documents/${documentId}/pages`, {
|
||||||
method: 'GET'
|
method: 'GET'
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
|
@ -266,6 +268,7 @@ export default Ember.Service.extend({
|
||||||
}).then((response) => {
|
}).then((response) => {
|
||||||
let data = this.get('store').normalize('page-meta', response);
|
let data = this.get('store').normalize('page-meta', response);
|
||||||
return this.get('store').push(data);
|
return this.get('store').push(data);
|
||||||
|
}).catch(() => {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -112,21 +112,13 @@ export default Ember.Service.extend({
|
||||||
let documentSlug = is.null(targetDocument) ? "d" : targetDocument.get('slug');
|
let documentSlug = is.null(targetDocument) ? "d" : targetDocument.get('slug');
|
||||||
|
|
||||||
// handle section link
|
// handle section link
|
||||||
if (link.linkType === "section") {
|
if (link.linkType === "section" || link.linkType === "tab") {
|
||||||
let options = {};
|
let options = {};
|
||||||
options['page'] = link.targetId;
|
options['pageId'] = link.targetId;
|
||||||
router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug, { queryParams: options });
|
router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug, { queryParams: options });
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle tab link
|
|
||||||
if (link.linkType === "tab") {
|
|
||||||
let options = {};
|
|
||||||
options['mode'] = 'view';
|
|
||||||
router.transitionTo('document.section', link.targetId, { queryParams: options });
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// handle document link
|
// handle document link
|
||||||
if (link.linkType === "document") {
|
if (link.linkType === "document") {
|
||||||
router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug);
|
router.transitionTo('document', link.folderId, folderSlug, link.documentId, documentSlug);
|
||||||
|
|
|
@ -21,6 +21,7 @@ export default Ember.Service.extend({
|
||||||
appMeta: service(),
|
appMeta: service(),
|
||||||
store: service(),
|
store: service(),
|
||||||
pins: [],
|
pins: [],
|
||||||
|
initialized: false,
|
||||||
|
|
||||||
getUserPins() {
|
getUserPins() {
|
||||||
let userId = this.get('session.user.id');
|
let userId = this.get('session.user.id');
|
||||||
|
@ -41,6 +42,7 @@ export default Ember.Service.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
this.set('pins', pins);
|
this.set('pins', pins);
|
||||||
|
this.set('initialized', true);
|
||||||
|
|
||||||
return pins;
|
return pins;
|
||||||
});
|
});
|
||||||
|
@ -102,6 +104,9 @@ export default Ember.Service.extend({
|
||||||
|
|
||||||
isDocumentPinned(documentId) {
|
isDocumentPinned(documentId) {
|
||||||
let userId = this.get('session.user.id');
|
let userId = this.get('session.user.id');
|
||||||
|
|
||||||
|
if (this.get('initialized') === false) {
|
||||||
|
this.getUserPins().then(() => {
|
||||||
let pins = this.get('pins');
|
let pins = this.get('pins');
|
||||||
let pinId = '';
|
let pinId = '';
|
||||||
|
|
||||||
|
@ -112,6 +117,19 @@ export default Ember.Service.extend({
|
||||||
});
|
});
|
||||||
|
|
||||||
return pinId;
|
return pinId;
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
let pins = this.get('pins');
|
||||||
|
let pinId = '';
|
||||||
|
|
||||||
|
pins.forEach((pin) => {
|
||||||
|
if (pin.get('userId') === userId && pin.get('documentId') === documentId) {
|
||||||
|
pinId = pin.get('id');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return pinId;
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
isSpacePinned(spaceId) {
|
isSpacePinned(spaceId) {
|
||||||
|
|
|
@ -67,6 +67,9 @@ export default BaseService.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages;
|
return pages;
|
||||||
|
}).catch((/*error*/) => {
|
||||||
|
// we ignore any error to cater for anon users who don't
|
||||||
|
// have permissions to perform refresh
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
411
app/app/snippets.txt
Normal file
411
app/app/snippets.txt
Normal file
|
@ -0,0 +1,411 @@
|
||||||
|
**********************************
|
||||||
|
**********************************
|
||||||
|
***** document
|
||||||
|
**********************************
|
||||||
|
**********************************
|
||||||
|
|
||||||
|
{{layout/zone-navigation}}
|
||||||
|
|
||||||
|
{{#layout/zone-sidebar}}
|
||||||
|
{{document/document-sidebar document=model.document folder=model.folder pages=model.pages page=model.page isEditor=model.isEditor sections=model.sections
|
||||||
|
onAddSection=(action 'onAddSection') onInsertBlock=(action 'onInsertBlock') onDeleteBlock=(action 'onDeleteBlock') changePageSequence=(action 'onPageSequenceChange') changePageLevel=(action 'onPageLevelChange') gotoPage=(action 'gotoPage')}}
|
||||||
|
{{/layout/zone-sidebar}}
|
||||||
|
|
||||||
|
{{#layout/zone-content}}
|
||||||
|
{{document/document-toolbar document=model.document pages=model.pages tabs=model.tabs folder=model.folder isEditor=model.isEditor
|
||||||
|
onSaveTemplate=(action 'onSaveTemplate') onSaveMeta=(action 'onSaveMeta') onDocumentDelete=(action 'onDocumentDelete')}}
|
||||||
|
|
||||||
|
{{outlet}}
|
||||||
|
{{/layout/zone-content}}
|
||||||
|
|
||||||
|
// 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: [],
|
||||||
|
|
||||||
|
// 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', []);
|
||||||
|
this.set('model.pages', pages);
|
||||||
|
this.get('target.router').refresh();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
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');
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onAddSection(section) {
|
||||||
|
this.audit.record("added-section-" + section.get('contentType'));
|
||||||
|
|
||||||
|
let page = {
|
||||||
|
documentId: this.get('model.document.id'),
|
||||||
|
title: `${section.get('title')}`,
|
||||||
|
level: 1,
|
||||||
|
sequence: 0,
|
||||||
|
body: "",
|
||||||
|
contentType: section.get('contentType'),
|
||||||
|
pageType: section.get('pageType')
|
||||||
|
};
|
||||||
|
|
||||||
|
let meta = {
|
||||||
|
documentId: this.get('model.document.id'),
|
||||||
|
rawBody: "",
|
||||||
|
config: ""
|
||||||
|
};
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
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'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
**********************************
|
||||||
|
**********************************
|
||||||
|
***** document/index
|
||||||
|
**********************************
|
||||||
|
**********************************
|
||||||
|
|
||||||
|
{{document/document-view document=model.document links=model.links allPages=model.allPages tabs=model.tabs pages=model.pages folder=model.folder folders=model.folders isEditor=model.isEditor gotoPage=(action 'gotoPage') onAddBlock=(action 'onAddBlock') onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')}}
|
||||||
|
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onAddBlock(block) {
|
||||||
|
this.get('sectionService').addBlock(block).then(() => {
|
||||||
|
this.showNotification("Published");
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
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 });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -32,3 +32,4 @@
|
||||||
@import "section/table.scss";
|
@import "section/table.scss";
|
||||||
@import "section/code.scss";
|
@import "section/code.scss";
|
||||||
@import "section/papertrail.scss";
|
@import "section/papertrail.scss";
|
||||||
|
@import "section/wysiwyg.scss";
|
||||||
|
|
|
@ -199,7 +199,7 @@ $i: 150;
|
||||||
$i: 100;
|
$i: 100;
|
||||||
@while $i > 0 {
|
@while $i > 0 {
|
||||||
.width-#{$i} {
|
.width-#{$i} {
|
||||||
width: #{$i}#{"%"};
|
width: #{$i}#{"%"} !important;
|
||||||
}
|
}
|
||||||
$i: $i - 1;
|
$i: $i - 1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ $color-symbol-icon: #a4b8be;
|
||||||
|
|
||||||
$color-table-border: #e1e1e1;
|
$color-table-border: #e1e1e1;
|
||||||
$color-table-header: #f5f5f5;
|
$color-table-header: #f5f5f5;
|
||||||
|
$color-toolbar: #eeeeee;
|
||||||
|
$color-wysiwyg: #3c3c3c;
|
||||||
|
|
||||||
.color-white {
|
.color-white {
|
||||||
color: $color-white !important;
|
color: $color-white !important;
|
||||||
|
@ -76,6 +78,9 @@ $color-table-header: #f5f5f5;
|
||||||
.background-color-white {
|
.background-color-white {
|
||||||
background-color: $color-white !important;
|
background-color: $color-white !important;
|
||||||
}
|
}
|
||||||
|
.background-color-off-white {
|
||||||
|
background-color: $color-off-white !important;
|
||||||
|
}
|
||||||
.background-color-primary {
|
.background-color-primary {
|
||||||
background-color: $color-primary !important;
|
background-color: $color-primary !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,38 +1,10 @@
|
||||||
.font-fixed-width {
|
.font-fixed-width {
|
||||||
font-family: 'courier new', courier;
|
font-family: 'courier new', courier;
|
||||||
}
|
}
|
||||||
@font-face {
|
|
||||||
font-family: 'open_sansbold';
|
|
||||||
src: url('font/opensans/opensans-bold-webfont.eot');
|
|
||||||
src: url('font/opensans/opensans-bold-webfont.eot?#iefix') format('embedded-opentype'), url('font/opensans/opensans-bold-webfont.woff2') format('woff2'), url('font/opensans/opensans-bold-webfont.woff') format('woff'), url('font/opensans/opensans-bold-webfont.ttf') format('truetype'), url('font/opensans/opensans-bold-webfont.svg#open_sansbold') format('svg');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'open_sanslight';
|
|
||||||
src: url('font/opensans/opensans-light-webfont.eot');
|
|
||||||
src: url('font/opensans/opensans-light-webfont.eot?#iefix') format('embedded-opentype'), url('font/opensans/opensans-light-webfont.woff2') format('woff2'), url('font/opensans/opensans-light-webfont.woff') format('woff'), url('font/opensans/opensans-light-webfont.ttf') format('truetype'), url('font/opensans/opensans-light-webfont.svg#open_sanslight') format('svg');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'open_sansregular';
|
|
||||||
src: url('font/opensans/opensans-regular-webfont.eot');
|
|
||||||
src: url('font/opensans/opensans-regular-webfont.eot?#iefix') format('embedded-opentype'), url('font/opensans/opensans-regular-webfont.woff2') format('woff2'), url('font/opensans/opensans-regular-webfont.woff') format('woff'), url('font/opensans/opensans-regular-webfont.ttf') format('truetype'), url('font/opensans/opensans-regular-webfont.svg#open_sansregular') format('svg');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
@font-face {
|
|
||||||
font-family: 'open_sanssemibold';
|
|
||||||
src: url('font/opensans/opensans-semibold-webfont.eot');
|
|
||||||
src: url('font/opensans/opensans-semibold-webfont.eot?#iefix') format('embedded-opentype'), url('font/opensans/opensans-semibold-webfont.woff2') format('woff2'), url('font/opensans/opensans-semibold-webfont.woff') format('woff'), url('font/opensans/opensans-semibold-webfont.ttf') format('truetype'), url('font/opensans/opensans-semibold-webfont.svg#open_sanssemibold') format('svg');
|
|
||||||
font-weight: normal;
|
|
||||||
font-style: normal;
|
|
||||||
}
|
|
||||||
|
|
||||||
$font-regular: 'open_sansregular';
|
$font-regular: Helvetica;
|
||||||
$font-semibold: 'open_sanssemibold';
|
$font-semibold: Helvetica;
|
||||||
$font-light: 'open_sanslight';
|
$font-light: Helvetica;
|
||||||
|
|
||||||
@font-face {
|
@font-face {
|
||||||
font-family: "Material Icons";
|
font-family: "Material Icons";
|
||||||
|
|
|
@ -11,31 +11,30 @@
|
||||||
@media print {
|
@media print {
|
||||||
.non-printable,
|
.non-printable,
|
||||||
.zone-navigation,
|
.zone-navigation,
|
||||||
.zone-sidebar {
|
.zone-sidebar,
|
||||||
|
#sidebar-wrapper,
|
||||||
|
.document-heading,
|
||||||
|
.edit-document-heading,
|
||||||
|
#sidebar-toggle,
|
||||||
|
.back-to-space,
|
||||||
|
.start-section,
|
||||||
|
.new-section-wizard {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zone-content {
|
#page-content-wrapper, #wrapper {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
margin: 0 !important;
|
||||||
|
|
||||||
.document-view {
|
|
||||||
.attachment-zone,
|
|
||||||
.document-summary,
|
|
||||||
.document-tags,
|
|
||||||
.page-toolbar {
|
|
||||||
display: none !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.non-printable-message,
|
.non-printable-message,
|
||||||
.print-title {
|
.print-title {
|
||||||
display: block !important;
|
display: block !important;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.doc-layout {
|
.is-a-tab, .is-a-page {
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
box-shadow: none !important;
|
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,11 @@
|
||||||
|
.section-code-editor {
|
||||||
|
margin-top: 6px;
|
||||||
|
|
||||||
|
> .syntax-selector {
|
||||||
|
margin-bottom: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* BASICS */
|
/* BASICS */
|
||||||
.CodeMirror {
|
.CodeMirror {
|
||||||
/* Set height, width, borders, and global font properties here */
|
/* Set height, width, borders, and global font properties here */
|
||||||
|
|
|
@ -1,13 +1,15 @@
|
||||||
#section-markdown-editor {
|
.section-markdown-preview {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
resize: none;
|
margin: 0;
|
||||||
padding: 10px;
|
padding: 0;
|
||||||
background-color: white;
|
@extend .no-outline;
|
||||||
|
margin-top: -10px;
|
||||||
|
border: none;
|
||||||
|
@extend .no-outline;
|
||||||
}
|
}
|
||||||
|
|
||||||
#section-markdown-preview {
|
.section-markdown-preview-button {
|
||||||
width: 100%;
|
position: absolute;
|
||||||
padding: 10px;
|
top: 18px;
|
||||||
background-color: white;
|
right: 118px;
|
||||||
overflow: auto;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
.table-editor-wrapper {
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
.fr-element,
|
.fr-element,
|
||||||
.fr-element:focus {
|
.fr-element:focus {
|
||||||
outline: 0px solid transparent;
|
outline: 0px solid transparent;
|
||||||
|
@ -1165,12 +1169,12 @@ table th.fr-selected-cell {
|
||||||
* Video style
|
* Video style
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
.fr-view table {
|
// .fr-view table {
|
||||||
border: none;
|
// border: none;
|
||||||
border-collapse: collapse;
|
// border-collapse: collapse;
|
||||||
empty-cells: show;
|
// empty-cells: show;
|
||||||
max-width: 100%;
|
// max-width: 100%;
|
||||||
}
|
// }
|
||||||
.fr-view table.fr-dashed-borders td,
|
.fr-view table.fr-dashed-borders td,
|
||||||
.fr-view table.fr-dashed-borders th {
|
.fr-view table.fr-dashed-borders th {
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
|
@ -1178,25 +1182,25 @@ table th.fr-selected-cell {
|
||||||
.fr-view table.fr-alternate-rows tbody tr:nth-child(2n) {
|
.fr-view table.fr-alternate-rows tbody tr:nth-child(2n) {
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
}
|
}
|
||||||
.fr-view table td,
|
// .fr-view table td,
|
||||||
.fr-view table th {
|
// .fr-view table th {
|
||||||
border: 1px solid #dddddd;
|
// border: 1px solid #dddddd;
|
||||||
}
|
// }
|
||||||
.fr-view table td:empty,
|
// .fr-view table td:empty,
|
||||||
.fr-view table th:empty {
|
// .fr-view table th:empty {
|
||||||
height: 20px;
|
// height: 20px;
|
||||||
}
|
// }
|
||||||
.fr-view table td.fr-highlighted,
|
// .fr-view table td.fr-highlighted,
|
||||||
.fr-view table th.fr-highlighted {
|
// .fr-view table th.fr-highlighted {
|
||||||
border: 1px double red;
|
// border: 1px double red;
|
||||||
}
|
// }
|
||||||
.fr-view table td.fr-thick,
|
// .fr-view table td.fr-thick,
|
||||||
.fr-view table th.fr-thick {
|
// .fr-view table th.fr-thick {
|
||||||
border-width: 2px;
|
// border-width: 2px;
|
||||||
}
|
// }
|
||||||
.fr-view table th {
|
// .fr-view table th {
|
||||||
background: #e6e6e6;
|
// background: #e6e6e6;
|
||||||
}
|
// }
|
||||||
.fr-view hr {
|
.fr-view hr {
|
||||||
clear: both;
|
clear: both;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
6
app/app/styles/section/wysiwyg.scss
Normal file
6
app/app/styles/section/wysiwyg.scss
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
.wysiwyg-editor {
|
||||||
|
@extend .no-outline;
|
||||||
|
font-family: Helvetica,Arial,Verdana,sans-serif;
|
||||||
|
margin-top: -10px;
|
||||||
|
color: $color-black;
|
||||||
|
}
|
File diff suppressed because it is too large
Load diff
|
@ -3,15 +3,13 @@
|
||||||
|
|
||||||
> .empty-state {
|
> .empty-state {
|
||||||
margin: 30px 0;
|
margin: 30px 0;
|
||||||
font-size: 2rem;
|
font-size: 1.2rem;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
font-family: 'open_sanslight';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
> .normal-state {
|
> .normal-state {
|
||||||
margin: 10px;
|
margin: 10px;
|
||||||
font-size: 2rem;
|
font-size: 1.2rem;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
font-family: 'open_sanslight';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,139 +0,0 @@
|
||||||
.document-activity {
|
|
||||||
> .metrics {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0 0 30px;
|
|
||||||
padding: 0;
|
|
||||||
width: 100%;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
> .metric {
|
|
||||||
padding: 0 30px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: center;
|
|
||||||
|
|
||||||
.label {
|
|
||||||
padding: 0 0 10px;
|
|
||||||
font-family: $font-regular;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
color: $color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.number {
|
|
||||||
font-family: $font-light;
|
|
||||||
font-size: 2rem;
|
|
||||||
color: $color-off-black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .items {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
> .item {
|
|
||||||
padding: 20px 0;
|
|
||||||
width: 100%;
|
|
||||||
border-bottom: 1px solid $color-border;
|
|
||||||
|
|
||||||
&:last-of-type {
|
|
||||||
border-bottom: none !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .avatar-box {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 3px 10px 0 0;
|
|
||||||
width: 5%;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .name {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-family: $font-light;
|
|
||||||
color: $color-off-black;
|
|
||||||
width: 25%;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .detail {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-family: $font-regular;
|
|
||||||
color: $color-off-black;
|
|
||||||
width: 45%;
|
|
||||||
|
|
||||||
.viewed {
|
|
||||||
color: $color-goldy;
|
|
||||||
}
|
|
||||||
|
|
||||||
.added {
|
|
||||||
color: $color-green;
|
|
||||||
}
|
|
||||||
|
|
||||||
.changed {
|
|
||||||
color: $color-blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
.deleted {
|
|
||||||
color: $color-red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .date {
|
|
||||||
display: inline-block;
|
|
||||||
font-family: $font-light;
|
|
||||||
font-size: 1rem;
|
|
||||||
float: right;
|
|
||||||
width: 15%;
|
|
||||||
padding-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.meta-editors {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
> .items {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
> .item {
|
|
||||||
margin: 15px 0;
|
|
||||||
overflow-x: hidden;
|
|
||||||
white-space: nowrap;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
width: 90%;
|
|
||||||
|
|
||||||
.avatar-box {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 3px 10px 0 0;
|
|
||||||
vertical-align: top;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
.name {
|
|
||||||
font-size: 1rem;
|
|
||||||
color: $color-off-black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.changed {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.deleted {
|
|
||||||
font-size: 0.9rem;
|
|
||||||
color: $color-red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.date {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,10 +1,11 @@
|
||||||
@import "activity.scss";
|
@import "content-linker.scss";
|
||||||
@import "content.scss";
|
|
||||||
@import "edit-tools.scss";
|
|
||||||
@import "editor.scss";
|
|
||||||
@import "files.scss";
|
|
||||||
@import "history.scss";
|
@import "history.scss";
|
||||||
@import "sidebar.scss";
|
@import "inline-editor.scss";
|
||||||
@import "toolbar.scss";
|
@import "layout.scss";
|
||||||
@import "wizard.scss";
|
@import "section-editor.scss";
|
||||||
|
@import "sidebar-view-activity.scss";
|
||||||
|
@import "sidebar-view-attachments.scss";
|
||||||
|
@import "sidebar-view-index.scss";
|
||||||
|
@import "sidebar-zone.scss";
|
||||||
|
@import "view.scss";
|
||||||
@import "wysiwyg.scss";
|
@import "wysiwyg.scss";
|
||||||
|
|
|
@ -1,18 +1,3 @@
|
||||||
.edit-tools {
|
|
||||||
margin: 0 0 0 20px;
|
|
||||||
min-height: 600px;
|
|
||||||
|
|
||||||
> .toolbar {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
> .item {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0 0 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-counter-dialog {
|
.content-counter-dialog {
|
||||||
width: 200px;
|
width: 200px;
|
||||||
height: 200px;
|
height: 200px;
|
||||||
|
@ -20,7 +5,7 @@
|
||||||
|
|
||||||
.content-linker-dialog {
|
.content-linker-dialog {
|
||||||
width: 350px;
|
width: 350px;
|
||||||
height: 500px;
|
height: 350px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
.link-list {
|
.link-list {
|
|
@ -1,69 +0,0 @@
|
||||||
.wiki-layout {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.doc-layout {
|
|
||||||
padding: 60px 50px;
|
|
||||||
box-shadow: 0 0 0 0.75pt $color-stroke,0 0 3pt 0.75pt $color-stroke;
|
|
||||||
margin: 30px 40px 50px 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.document-view {
|
|
||||||
.print-title {
|
|
||||||
display: none;
|
|
||||||
font-size: 2.3em;
|
|
||||||
font-weight: bold;
|
|
||||||
color:$color-black;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.non-printable-message {
|
|
||||||
display: none;
|
|
||||||
font-size: 1em;
|
|
||||||
font-style: italic;
|
|
||||||
color: $color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-template {
|
|
||||||
color: $color-goldy;
|
|
||||||
font-weight: bold;
|
|
||||||
font-size: 1.5em;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
padding-bottom: 5px;
|
|
||||||
border-bottom: 1px dotted $color-goldy;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .pages {
|
|
||||||
margin: 30px 0 50px 0;
|
|
||||||
|
|
||||||
> .wysiwyg {
|
|
||||||
> .is-a-page {
|
|
||||||
@extend .transition-all;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.page-title {
|
|
||||||
> .page-toolbar {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.page-title {
|
|
||||||
> .page-toolbar {
|
|
||||||
opacity: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-state-document {
|
|
||||||
margin-top: 150px;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dropdown-page-toolbar {
|
|
||||||
width: 300px;
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
.document-editor {
|
|
||||||
> .toolbar {
|
|
||||||
width: 100%;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
> .title {
|
|
||||||
width: 50%;
|
|
||||||
|
|
||||||
> .input-control {
|
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
> input {
|
|
||||||
margin: 0 0 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .buttons {
|
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .canvas {
|
|
||||||
padding: 40px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.cancel-edits-dialog {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +1,27 @@
|
||||||
.document-history {
|
.zone-document-history {
|
||||||
|
margin-left: 60px;
|
||||||
|
padding: 20px 60px;
|
||||||
|
z-index: 777;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
> .sidebar {
|
.diff-zone {
|
||||||
position: relative;
|
@extend .transition-all;
|
||||||
overflow-y: scroll;
|
@include border-radius(2px);
|
||||||
|
|
||||||
> .heading {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-family: $font-light;
|
|
||||||
color: $color-off-black;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .line {
|
|
||||||
width: 2px;
|
|
||||||
background-color: $color-stroke;
|
|
||||||
height: 100%;
|
|
||||||
position: absolute;
|
|
||||||
left: 17px;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .items {
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 20px 0 10px;
|
|
||||||
white-space: nowrap;
|
|
||||||
|
|
||||||
> .item {
|
|
||||||
margin: 0;
|
|
||||||
padding: 10px 0;
|
|
||||||
width: 100%;
|
|
||||||
color: $color-off-black;
|
|
||||||
@include ease-in();
|
@include ease-in();
|
||||||
cursor: pointer;
|
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;
|
||||||
|
|
||||||
> .avatar-box {
|
> .canvas {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.revision-picker {
|
||||||
|
width: 300px;
|
||||||
|
float: left;
|
||||||
|
margin-top: 10px;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
|
|
||||||
> .date {
|
|
||||||
display: inline-block;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-family: $font-light;
|
|
||||||
margin-left: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .detail {
|
|
||||||
display: block;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
font-family: $font-semibold;
|
|
||||||
margin-left: 65px;
|
|
||||||
overflow: hidden;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .deleted {
|
|
||||||
color: $color-red;
|
|
||||||
cursor: not-allowed;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-red;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
41
app/app/styles/view/document/inline-editor.scss
Normal file
41
app/app/styles/view/document/inline-editor.scss
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
.document-editor {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> .toolbar {
|
||||||
|
width: 100%;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
> .edit-title {
|
||||||
|
width: 70%;
|
||||||
|
|
||||||
|
> input {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin: 16px 0 10px 0;
|
||||||
|
color: $color-wysiwyg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .buttons {
|
||||||
|
margin-top: 17px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .canvas {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cancel-edits-dialog {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-editor-full {
|
||||||
|
@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;
|
||||||
|
}
|
80
app/app/styles/view/document/layout.scss
Normal file
80
app/app/styles/view/document/layout.scss
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
$document-sidebar-width: 400px;
|
||||||
|
|
||||||
|
#wrapper {
|
||||||
|
padding-right: 0;
|
||||||
|
margin-left: 60px;
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
background-color: $color-off-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
// #wrapper.toggled {
|
||||||
|
// padding-right: $document-sidebar-width;
|
||||||
|
// }
|
||||||
|
|
||||||
|
#sidebar-wrapper {
|
||||||
|
// z-index: 1000;
|
||||||
|
z-index: 888;
|
||||||
|
position: fixed;
|
||||||
|
right: $document-sidebar-width;
|
||||||
|
width: 0;
|
||||||
|
height: 100%;
|
||||||
|
margin-right: -$document-sidebar-width;
|
||||||
|
overflow-y: auto;
|
||||||
|
background: $color-off-white;
|
||||||
|
-webkit-transition: all 0.5s ease;
|
||||||
|
-moz-transition: all 0.5s ease;
|
||||||
|
-o-transition: all 0.5s ease;
|
||||||
|
transition: all 0.5s ease;
|
||||||
|
border-left: 1px solid $color-stroke;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper.toggled #sidebar-wrapper {
|
||||||
|
width: $document-sidebar-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-content-wrapper {
|
||||||
|
width: 100%;
|
||||||
|
position: absolute;
|
||||||
|
padding: 30px 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper.toggled #page-content-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
margin-left: -$document-sidebar-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media(min-width:768px) {
|
||||||
|
#wrapper {
|
||||||
|
padding-right: $document-sidebar-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper.toggled {
|
||||||
|
padding-left: 0;
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#sidebar-wrapper {
|
||||||
|
width: $document-sidebar-width;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper.toggled #sidebar-wrapper {
|
||||||
|
width: 0;
|
||||||
|
|
||||||
|
.document-sidebar-toolbar {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#page-content-wrapper {
|
||||||
|
padding: 20px 60px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper.toggled #page-content-wrapper {
|
||||||
|
position: relative;
|
||||||
|
margin-left: 0;
|
||||||
|
}
|
||||||
|
}
|
29
app/app/styles/view/document/section-editor.scss
Normal file
29
app/app/styles/view/document/section-editor.scss
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
.zone-section-editor {
|
||||||
|
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
52
app/app/styles/view/document/sidebar-view-activity.scss
Normal file
52
app/app/styles/view/document/sidebar-view-activity.scss
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
.document-sidebar-view-activity {
|
||||||
|
> .items {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
> .item {
|
||||||
|
margin: 0;
|
||||||
|
padding: 10px 0;
|
||||||
|
width: 100%;
|
||||||
|
|
||||||
|
> .avatar-box {
|
||||||
|
display: inline-block;
|
||||||
|
margin: 0 10px 0 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .name {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: $color-gray;
|
||||||
|
width: 200px;
|
||||||
|
@extend .truncate;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .detail {
|
||||||
|
display: block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
color: $color-off-black;
|
||||||
|
margin-left: 50px;
|
||||||
|
width: 200px;
|
||||||
|
@extend .truncate;
|
||||||
|
|
||||||
|
.viewed {
|
||||||
|
color: $color-goldy;
|
||||||
|
}
|
||||||
|
|
||||||
|
.added {
|
||||||
|
color: $color-green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.changed {
|
||||||
|
color: $color-blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
.deleted {
|
||||||
|
color: $color-red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,17 +1,16 @@
|
||||||
.document-files {
|
.document-sidebar-view-attachments {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
||||||
> .upload-document-files {
|
> .upload-document-files {
|
||||||
width: 50%;
|
width: 100%;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
margin: 0 auto;
|
margin-bottom: 20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
border: 2px dotted $color-gray;
|
border: 1px solid $color-stroke;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-size: 1rem;
|
font-size: 0.9rem;
|
||||||
line-height: 1.7rem;
|
line-height: 1.7rem;
|
||||||
@include border-radius(10px);
|
|
||||||
@include ease-in();
|
@include ease-in();
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -31,11 +30,10 @@
|
||||||
|
|
||||||
> .item {
|
> .item {
|
||||||
color: $color-off-black;
|
color: $color-off-black;
|
||||||
margin-top: 10px;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 10px 0;
|
||||||
|
font-size: 0.9rem;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
border-bottom: 1px solid $color-border;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
|
|
||||||
&:last-of-type {
|
&:last-of-type {
|
||||||
border-bottom: none !important;
|
border-bottom: none !important;
|
||||||
|
@ -46,6 +44,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
|
@extend .truncate;
|
||||||
|
width: 200px;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
|
@ -53,7 +53,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
> .file {
|
> .file {
|
||||||
font-size: 1rem;
|
@extend .truncate;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
width: 200px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
57
app/app/styles/view/document/sidebar-view-index.scss
Normal file
57
app/app/styles/view/document/sidebar-view-index.scss
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
.document-sidebar-view-index {
|
||||||
|
margin: 0;
|
||||||
|
|
||||||
|
>.structure {
|
||||||
|
> .toc-controls {
|
||||||
|
margin: 0;
|
||||||
|
color: $color-gray;
|
||||||
|
|
||||||
|
> .round-button-mono {
|
||||||
|
> .material-icons {
|
||||||
|
color: $color-link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .disabled {
|
||||||
|
@extend .cursor-not-allowed;
|
||||||
|
color: $color-stroke;
|
||||||
|
border-color: $color-stroke;
|
||||||
|
|
||||||
|
> .material-icons {
|
||||||
|
color: $color-stroke;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .index-list {
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
font-size: 13px;
|
||||||
|
overflow-x: hidden;
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 20px 0 0;
|
||||||
|
|
||||||
|
.item {
|
||||||
|
padding: 4px 0;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
word-wrap: break-word;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
@extend .no-select;
|
||||||
|
|
||||||
|
> .link {
|
||||||
|
color: $color-off-black;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-link;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .selected {
|
||||||
|
color: $color-link;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
66
app/app/styles/view/document/sidebar-zone.scss
Normal file
66
app/app/styles/view/document/sidebar-zone.scss
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
.document-sidebar-common {
|
||||||
|
display: inline-block;
|
||||||
|
width: 340px;
|
||||||
|
padding: 40px 20px 40px 20px;
|
||||||
|
|
||||||
|
> .pinner {
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
> .material-icons {
|
||||||
|
color: $color-primary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .template-header {
|
||||||
|
color: $color-goldy;
|
||||||
|
font-size: 1.5em;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-sidebar-toolbar {
|
||||||
|
display: inline-block;
|
||||||
|
width: 60px;
|
||||||
|
background-color: $color-toolbar;
|
||||||
|
text-align: center;
|
||||||
|
position: fixed;
|
||||||
|
right: 0;
|
||||||
|
top: 0;
|
||||||
|
height: 100%;
|
||||||
|
padding: 50px 0 0 0;
|
||||||
|
|
||||||
|
> .selected {
|
||||||
|
background-color: $color-off-black !important;
|
||||||
|
border: none;
|
||||||
|
|
||||||
|
> .material-icons {
|
||||||
|
color: $color-white !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .round-button-mono {
|
||||||
|
> .material-icons {
|
||||||
|
color: $color-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-sidebar-wrapper {
|
||||||
|
padding: 40px 20px 40px 20px;
|
||||||
|
margin-right: 60px;
|
||||||
|
|
||||||
|
.document-sidebar-panel {
|
||||||
|
width: 300px;
|
||||||
|
// top: 0;
|
||||||
|
// bottom: 0;
|
||||||
|
// position: fixed;
|
||||||
|
// overflow-y: scroll;
|
||||||
|
// overflow-x: hidden;
|
||||||
|
|
||||||
|
> .title {
|
||||||
|
color: $color-primary;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin-bottom: 30px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,115 +0,0 @@
|
||||||
.document-sidebar {
|
|
||||||
@extend .no-select;
|
|
||||||
width: 100%;
|
|
||||||
|
|
||||||
.stuck-toc {
|
|
||||||
position: fixed;
|
|
||||||
top: 20px;
|
|
||||||
-webkit-animation: fadein 1s;
|
|
||||||
-moz-animation: fadein 1s;
|
|
||||||
-ms-animation: fadein 1s;
|
|
||||||
-o-animation: fadein 1s;
|
|
||||||
animation: fadein 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.section-tool {
|
|
||||||
position: absolute;
|
|
||||||
top: 130px;
|
|
||||||
right: -18px;
|
|
||||||
z-index: 999;
|
|
||||||
}
|
|
||||||
|
|
||||||
.scroll-tool {
|
|
||||||
position: absolute;
|
|
||||||
top: 130px;
|
|
||||||
right: -18px;
|
|
||||||
z-index: 999;
|
|
||||||
-webkit-animation: fadein 1s;
|
|
||||||
-moz-animation: fadein 1s;
|
|
||||||
-ms-animation: fadein 1s;
|
|
||||||
-o-animation: fadein 1s;
|
|
||||||
animation: fadein 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stuck-tool {
|
|
||||||
position: fixed !important;
|
|
||||||
top: 130px !important;
|
|
||||||
right: 0;
|
|
||||||
left: 0;
|
|
||||||
-webkit-animation: fadein 1s;
|
|
||||||
-moz-animation: fadein 1s;
|
|
||||||
-ms-animation: fadein 1s;
|
|
||||||
-o-animation: fadein 1s;
|
|
||||||
animation: fadein 1s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-action {
|
|
||||||
float: right;
|
|
||||||
|
|
||||||
> .round-button-mono {
|
|
||||||
color: $color-stroke;
|
|
||||||
border-color: $color-stroke;
|
|
||||||
|
|
||||||
> .material-icons {
|
|
||||||
color: $color-stroke;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.document-structure {
|
|
||||||
> .toc-controls {
|
|
||||||
margin: 0;
|
|
||||||
color: $color-gray;
|
|
||||||
|
|
||||||
> .round-button-mono {
|
|
||||||
color: $color-green;
|
|
||||||
border-color: $color-green;
|
|
||||||
|
|
||||||
> .material-icons {
|
|
||||||
color: $color-green;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .disabled {
|
|
||||||
@extend .cursor-not-allowed;
|
|
||||||
color: $color-stroke;
|
|
||||||
border-color: $color-stroke;
|
|
||||||
|
|
||||||
> .material-icons {
|
|
||||||
color: $color-stroke;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.entries {
|
|
||||||
padding: 0;
|
|
||||||
list-style: none;
|
|
||||||
font-size: 13px;
|
|
||||||
overflow-x: hidden;
|
|
||||||
list-style-type: none;
|
|
||||||
margin: 20px 0 0;
|
|
||||||
font-family: $font-semibold;
|
|
||||||
|
|
||||||
.item {
|
|
||||||
padding: 4px 0;
|
|
||||||
text-overflow: ellipsis;
|
|
||||||
word-wrap: break-word;
|
|
||||||
white-space: nowrap;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
> .link {
|
|
||||||
color: $color-gray;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .selected {
|
|
||||||
color: $color-link;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
.document-toolbar {
|
|
||||||
position: relative;
|
|
||||||
margin: -30px 0 40px;
|
|
||||||
height: 60px;
|
|
||||||
padding: 5px 30px 0;
|
|
||||||
background-color: $color-sidebar;
|
|
||||||
@include border-radius-bottom-right(5px);
|
|
||||||
@include border-radius-bottom-left(5px);
|
|
||||||
@extend .no-select;
|
|
||||||
|
|
||||||
> .tabs {
|
|
||||||
width: 70%;
|
|
||||||
height: 50px;
|
|
||||||
margin-top: 15px;
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
> .tab {
|
|
||||||
list-style-type: none;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 20px 0 0;
|
|
||||||
padding: 0;
|
|
||||||
color: $color-gray;
|
|
||||||
font-family: $font-semibold;
|
|
||||||
cursor: pointer;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
|
|
||||||
> a {
|
|
||||||
color: $color-gray;
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .active {
|
|
||||||
color: $color-link;
|
|
||||||
|
|
||||||
> .add-tab {
|
|
||||||
> i {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-tab {
|
|
||||||
display: inline-block;
|
|
||||||
vertical-align: text-top;
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
> i {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
color: $color-gray;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .options {
|
|
||||||
width: 30%;
|
|
||||||
height: 50px;
|
|
||||||
margin-top: 15px;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: right;
|
|
||||||
float: right;
|
|
||||||
|
|
||||||
> .option {
|
|
||||||
list-style-type: none;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 0 0 20px;
|
|
||||||
padding: 0;
|
|
||||||
color: $color-gray;
|
|
||||||
cursor: pointer;
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .pinned {
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> a {
|
|
||||||
display: inline-block;
|
|
||||||
|
|
||||||
> .option {
|
|
||||||
list-style-type: none;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 0 0 20px;
|
|
||||||
padding: 0;
|
|
||||||
color: $color-gray;
|
|
||||||
cursor: pointer;
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .pinned {
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
349
app/app/styles/view/document/view.scss
Normal file
349
app/app/styles/view/document/view.scss
Normal file
|
@ -0,0 +1,349 @@
|
||||||
|
.zone-document {
|
||||||
|
min-height: 500px; //ensure dropdowns render in viewport
|
||||||
|
height: 100%;
|
||||||
|
margin-left: 60px;
|
||||||
|
padding: 30px 70px;
|
||||||
|
z-index: 777;
|
||||||
|
}
|
||||||
|
|
||||||
|
.zone-document-content {
|
||||||
|
> .back-to-space {
|
||||||
|
margin: 10px 0;
|
||||||
|
|
||||||
|
> a {
|
||||||
|
vertical-align: middle;
|
||||||
|
color: $color-primary;
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
> .material-icons {
|
||||||
|
font-size: 1rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-title {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin: 30px 0 10px;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-excerpt {
|
||||||
|
font-size: 1rem;
|
||||||
|
color: $color-gray;
|
||||||
|
margin: 0 0 45px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-document-heading {
|
||||||
|
margin: 30px 0 0 0;
|
||||||
|
|
||||||
|
.edit-doc-title {
|
||||||
|
> input {
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
color: $color-wysiwyg;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.edit-doc-excerpt {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin: 0 0 10px;
|
||||||
|
color: $color-gray;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-view {
|
||||||
|
margin: 0 0 50px 0;
|
||||||
|
|
||||||
|
.is-a-page {
|
||||||
|
@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;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.page-title {
|
||||||
|
> .page-toolbar {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
> .page-toolbar {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-a-tab {
|
||||||
|
@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: default;
|
||||||
|
|
||||||
|
.page-title {
|
||||||
|
> .page-toolbar {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tab-max {
|
||||||
|
padding: 25px 50px;
|
||||||
|
height: auto;
|
||||||
|
overflow: auto;
|
||||||
|
cursor: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
.section-divider {
|
||||||
|
height: 60px;
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-section {
|
||||||
|
@extend .no-select;
|
||||||
|
height: 60px;
|
||||||
|
background-color: transparent;
|
||||||
|
position: relative;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
> .start-button {
|
||||||
|
display: none;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 20px;
|
||||||
|
color: $color-green;
|
||||||
|
font-size: 1rem;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
> .round-button {
|
||||||
|
opacity: 0.6 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .label {
|
||||||
|
display: inline-block;
|
||||||
|
margin-left: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .line {
|
||||||
|
display: inline-block;
|
||||||
|
height: 1px;
|
||||||
|
border: 1px solid $color-green;
|
||||||
|
width: 100px;
|
||||||
|
margin: 0 20px 0 20px;
|
||||||
|
opacity: 0.2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
height: 30px;
|
||||||
|
|
||||||
|
> .start-button {
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.start-section-empty-state {
|
||||||
|
> .start-button {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-section-wizard {
|
||||||
|
@include border-radius(2px);
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
padding: 30px;
|
||||||
|
border: 1px solid $color-stroke;
|
||||||
|
background-color: $color-off-white;
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
.section-name {
|
||||||
|
font-weight: bold;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
color: $color-black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.template-caption {
|
||||||
|
color: $color-gray;
|
||||||
|
margin: 10px 0 10px 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .list-wrapper {
|
||||||
|
height: 440px;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
> .preset-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
> .item {
|
||||||
|
@include ease-in();
|
||||||
|
@include border-radius(4px);
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid $color-stroke;
|
||||||
|
background-color: $color-white;
|
||||||
|
margin: 0 20px 20px 0;
|
||||||
|
padding: 15px 0 0 20px;
|
||||||
|
width: 200px;
|
||||||
|
height: 60px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@include ease-in();
|
||||||
|
border-color: $color-link;
|
||||||
|
}
|
||||||
|
|
||||||
|
.icon {
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
width: 40px;
|
||||||
|
margin-right: 10px;
|
||||||
|
float: left;
|
||||||
|
|
||||||
|
> .img {
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
height: 30px;
|
||||||
|
width: 30px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: normal;
|
||||||
|
color: $color-off-black;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-top: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .block-list {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
> .item {
|
||||||
|
@include ease-in();
|
||||||
|
@include border-radius(4px);
|
||||||
|
list-style: none;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid $color-stroke;
|
||||||
|
background-color: $color-white;
|
||||||
|
margin: 0 20px 20px 0;
|
||||||
|
padding: 12px 0 0 20px;
|
||||||
|
width: 423px;
|
||||||
|
height: 60px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
@include ease-in();
|
||||||
|
border-color: $color-link;
|
||||||
|
|
||||||
|
> .block-actions {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .block-actions {
|
||||||
|
@include ease-in();
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 10px;
|
||||||
|
right: 8px;
|
||||||
|
|
||||||
|
.material-icons {
|
||||||
|
color: $color-stroke;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
> .details {
|
||||||
|
width: 350px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
> .title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: normal;
|
||||||
|
color: $color-off-black;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-top: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .desc {
|
||||||
|
color: $color-gray;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
margin-top: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdown-page-toolbar {
|
||||||
|
width: 300px;
|
||||||
|
}
|
|
@ -1,172 +0,0 @@
|
||||||
.section-wizard {
|
|
||||||
margin: 20px 0 30px;
|
|
||||||
|
|
||||||
> .canvas {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
> .divider {
|
|
||||||
margin: 30px 0 20px 0;
|
|
||||||
border-top: 1px dotted $color-gray;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .template-caption {
|
|
||||||
text-align: center;
|
|
||||||
color: $color-gray;
|
|
||||||
padding-bottom: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .list {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
> .min-height {
|
|
||||||
min-height: 87px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .item {
|
|
||||||
list-style: none;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 10px 0;
|
|
||||||
margin: 5px 0;
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
>.icon {
|
|
||||||
.actions {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .details {
|
|
||||||
> .title {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .desc {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
|
||||||
width: 50px;
|
|
||||||
|
|
||||||
> .img {
|
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .actions {
|
|
||||||
display: none;
|
|
||||||
vertical-align: top;
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 5px;
|
|
||||||
opacity: 0.5;
|
|
||||||
|
|
||||||
> .material-icons, a {
|
|
||||||
color: $color-gray;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
color: $color-link;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .details {
|
|
||||||
vertical-align: top;
|
|
||||||
display: inline-block;
|
|
||||||
width: 80%;
|
|
||||||
|
|
||||||
> .title {
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: $color-off-black;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .desc {
|
|
||||||
color: $color-gray;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.tab-wizard {
|
|
||||||
margin: 20px 0 30px;
|
|
||||||
|
|
||||||
> .canvas {
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
> .list {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
|
|
||||||
> .item {
|
|
||||||
list-style: none;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 20px;
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
@include ease-in();
|
|
||||||
|
|
||||||
> .details {
|
|
||||||
> .title {
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .desc {
|
|
||||||
color: $color-primary;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
|
||||||
width: 50px;
|
|
||||||
margin-right: 10px;
|
|
||||||
float: left;
|
|
||||||
|
|
||||||
> .img {
|
|
||||||
float: left;
|
|
||||||
text-align: center;
|
|
||||||
display: inline-block;
|
|
||||||
height: 40px;
|
|
||||||
width: 40px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .details {
|
|
||||||
vertical-align: top;
|
|
||||||
display: inline-block;
|
|
||||||
float: left;
|
|
||||||
|
|
||||||
> .title {
|
|
||||||
font-size: 1rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: $color-off-black;
|
|
||||||
letter-spacing: 0.5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .desc {
|
|
||||||
color: $color-gray;
|
|
||||||
font-size: 0.9rem;
|
|
||||||
margin-top: 5px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,115 +1,100 @@
|
||||||
.wysiwyg {
|
.wysiwyg {
|
||||||
// font-size: 1rem;
|
font-size: 17px;
|
||||||
font-size: 15px;
|
|
||||||
line-height: 30px;
|
line-height: 30px;
|
||||||
color: #3c3c3c;
|
color: $color-wysiwyg;
|
||||||
|
|
||||||
table
|
|
||||||
{
|
|
||||||
// width: auto !important;
|
|
||||||
|
|
||||||
|
table {
|
||||||
@include border(1px);
|
@include border(1px);
|
||||||
|
|
||||||
td
|
td {
|
||||||
{
|
|
||||||
padding: 5px 7px !important;
|
padding: 5px 7px !important;
|
||||||
@include border(1px);
|
@include border(1px);
|
||||||
|
|
||||||
p
|
p {
|
||||||
{
|
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ol, ul
|
ol,
|
||||||
{
|
ul {
|
||||||
margin: 15px 0;
|
margin: 15px 0;
|
||||||
padding: 0 0 0 40px;
|
padding: 0 0 0 40px;
|
||||||
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
ul
|
ol {
|
||||||
{
|
li {
|
||||||
li
|
list-style-type: decimal;
|
||||||
{
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
li {
|
||||||
list-style-type: disc;
|
list-style-type: disc;
|
||||||
|
line-height: 20px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
b
|
|
||||||
{
|
|
||||||
font-family: $font-semibold;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-size: 2em;
|
font-size: 1.7rem;
|
||||||
font-family: $font-semibold;
|
font-weight: bold;
|
||||||
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// h1
|
h2 {
|
||||||
// {
|
|
||||||
// font-size: 1.6em;
|
|
||||||
// font-family: open_sanslight;
|
|
||||||
// color:$color-off-black;
|
|
||||||
// margin: 0 0 20px 0;
|
|
||||||
// }
|
|
||||||
|
|
||||||
h2
|
|
||||||
{
|
|
||||||
font-size: 1.7em;
|
|
||||||
margin: 30px 0 20px 0;
|
|
||||||
font-family: $font-regular;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3
|
|
||||||
{
|
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
margin: 30px 0 20px 0;
|
font-weight: bold;
|
||||||
font-family: $font-regular;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h4
|
h3 {
|
||||||
{
|
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
margin: 30px 0 20px 0;
|
font-weight: bold;
|
||||||
font-family: $font-regular;
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h5, h6, h7, h8, h9
|
h4,
|
||||||
{
|
h5,
|
||||||
font-size: 1.3rem;
|
h6,
|
||||||
margin: 30px 0 20px 0;
|
h7,
|
||||||
font-family: $font-regular;
|
h8,
|
||||||
|
h9 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 16px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2, h3, h4, h5, h6, h7, h8, h9
|
h2,
|
||||||
{
|
h3,
|
||||||
.page-title
|
h4,
|
||||||
{
|
h5,
|
||||||
color:$color-off-black;
|
h6,
|
||||||
font-family: $font-regular;
|
h7,
|
||||||
|
h8,
|
||||||
|
h9 {
|
||||||
|
.page-title {
|
||||||
|
color: $color-off-black;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pre
|
pre {
|
||||||
{
|
|
||||||
background-color: $color-off-white;
|
background-color: $color-off-white;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: 1px solid $color-border;
|
border: 1px solid $color-border;
|
||||||
@include border-radius(3px);
|
@include border-radius(3px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-mirror
|
.code-mirror {
|
||||||
{
|
|
||||||
background-color: none;
|
background-color: none;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
border: none;
|
border: none;
|
||||||
@include border-radius(0px);
|
@include border-radius(0px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.wysiwyg-table
|
.wysiwyg-table {
|
||||||
{
|
|
||||||
border: none;
|
border: none;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
empty-cells: show;
|
empty-cells: show;
|
||||||
|
@ -120,26 +105,32 @@
|
||||||
.fr-dashed-borders th {
|
.fr-dashed-borders th {
|
||||||
border-style: dashed;
|
border-style: dashed;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fr-alternate-rows tbody tr:nth-child(2n) {
|
.fr-alternate-rows tbody tr:nth-child(2n) {
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
}
|
}
|
||||||
|
|
||||||
td,
|
td,
|
||||||
th {
|
th {
|
||||||
border: 1px solid #f3f5f8;
|
border: 1px solid #f3f5f8;
|
||||||
padding: 5px 7px !important;
|
padding: 5px 7px !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
td:empty,
|
td:empty,
|
||||||
th:empty {
|
th:empty {
|
||||||
height: 20px;
|
height: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.fr-highlighted,
|
td.fr-highlighted,
|
||||||
th.fr-highlighted {
|
th.fr-highlighted {
|
||||||
border: 1px double red;
|
border: 1px double red;
|
||||||
}
|
}
|
||||||
|
|
||||||
td.fr-thick,
|
td.fr-thick,
|
||||||
th.fr-thick {
|
th.fr-thick {
|
||||||
border-width: 2px;
|
border-width: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
th {
|
th {
|
||||||
background: #f7f6f6;
|
background: #f7f6f6;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,14 @@
|
||||||
.zone-navigation {
|
.zone-navigation {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
margin: 0;
|
top: 0;
|
||||||
padding: 0;
|
|
||||||
width: 60px;
|
width: 60px;
|
||||||
min-height: 100%;
|
min-height: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: $color-primary;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
z-index: 999;
|
z-index: 999;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
background-color: $color-primary;
|
||||||
|
|
||||||
> .bottom-zone,
|
> .bottom-zone,
|
||||||
> .top-zone {
|
> .top-zone {
|
||||||
|
@ -80,7 +81,6 @@
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
line-height: 2.6rem;
|
line-height: 2.6rem;
|
||||||
font-family: open_sansregular;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@
|
||||||
> .pin {
|
> .pin {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
margin: 20px 0 20px 9px;
|
margin: 20px 0 20px 9px;
|
||||||
padding: 11px 3px;
|
padding: 14px 3px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
width: 40px;
|
width: 40px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
background-color: $color-gray;
|
background-color: $color-gray;
|
||||||
@include border-radius(20px);
|
@include border-radius(20px);
|
||||||
@include ease-in();
|
@include ease-in();
|
||||||
padding: 7px 0 0 0;
|
padding: 10px 0 0 0;
|
||||||
letter-spacing: 1px;
|
letter-spacing: 1px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
height: 35px;
|
height: 35px;
|
||||||
|
|
|
@ -138,6 +138,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.round-button-small {
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
line-height: 20px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
.square-button {
|
.square-button {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -217,6 +224,13 @@
|
||||||
@include button-hover-state($color-white);
|
@include button-hover-state($color-white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.button-black {
|
||||||
|
border: none;
|
||||||
|
background-color: $color-off-black;
|
||||||
|
color: $color-white;
|
||||||
|
@include button-hover-state($color-black);
|
||||||
|
}
|
||||||
|
|
||||||
.button-transparent {
|
.button-transparent {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
padding: 0;
|
padding: 0;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
line-height: 0;
|
line-height: 0;
|
||||||
margin-right: 5px;
|
margin: 0 5px 10px 0;
|
||||||
background-color: $color-chip;
|
background-color: $color-chip;
|
||||||
color: $color-chip-text;
|
color: $color-chip-text;
|
||||||
|
|
||||||
|
|
|
@ -81,7 +81,7 @@
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $color-link;
|
color: $color-link;
|
||||||
font-weight: bold;
|
// font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
a, a:visited {
|
a, a:visited {
|
||||||
|
@ -92,7 +92,7 @@
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $color-link;
|
color: $color-link;
|
||||||
font-weight: bold;
|
// font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: $color-red;
|
color: $color-red;
|
||||||
font-weight: bold;
|
// font-weight: bold;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
> .tip {
|
> .tip {
|
||||||
color: $color-input;
|
color: $color-gray;
|
||||||
font-size: 1em;
|
font-size: 0.9em;
|
||||||
margin: 5px 0 10px;
|
margin: 5px 0 10px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
@ -161,6 +161,18 @@
|
||||||
box-shadow: none !important;
|
box-shadow: none !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.error-inline {
|
||||||
|
border-left: 3px solid $color-red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-transparent {
|
||||||
|
background-color: transparent !important;
|
||||||
|
|
||||||
|
> input, textarea {
|
||||||
|
background-color: transparent !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-bordered {
|
.form-bordered {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
{{component editorType document=document folder=folder page=page meta=meta onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
{{component editorType document=document folder=folder page=page meta=meta blockMode=true onCancel=(action 'onCancel') onAction=(action 'onAction')}}
|
||||||
|
|
72
app/app/templates/components/document/content-linker.hbs
Normal file
72
app/app/templates/components/document/content-linker.hbs
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
{{#dropdown-dialog target=contentLinkerButtonId position="bottom right" button="Insert" color="flat-blue" onAction=(action 'onInsertLink')}}
|
||||||
|
<div class="content-linker-dialog">
|
||||||
|
<form>
|
||||||
|
{{ui/ui-tab tabs=tabs onTabSelect=(action 'onTabSelect')}}
|
||||||
|
|
||||||
|
<div class="margin-top-40" />
|
||||||
|
|
||||||
|
{{#if showSections}}
|
||||||
|
<ul class="link-list">
|
||||||
|
{{#each candidates.pages as |p|}}
|
||||||
|
<li class="link-item" {{ action 'setSelection' p }}>
|
||||||
|
{{#ui/ui-selection selected=p.selected}}
|
||||||
|
{{p.title}}
|
||||||
|
{{/ui/ui-selection}}
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if showAttachments}}
|
||||||
|
<ul class="link-list">
|
||||||
|
{{#each candidates.attachments as |a|}}
|
||||||
|
<li class="link-item" {{ action 'setSelection' a }}>
|
||||||
|
{{#ui/ui-selection selected=a.selected}}
|
||||||
|
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
|
||||||
|
{{ a.title }}
|
||||||
|
{{/ui/ui-selection}}
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if showSearch}}
|
||||||
|
<div class="input-control">
|
||||||
|
<label>Search</label>
|
||||||
|
<div class="tip">For content or attachments</div>
|
||||||
|
{{focus-input id="content-linker-search" type="input" value=keywords placeholder="keyword search" autocomplete="off"}}
|
||||||
|
</div>
|
||||||
|
{{#unless hasMatches}}
|
||||||
|
Nothing found.
|
||||||
|
{{/unless}}
|
||||||
|
<ul class="link-list">
|
||||||
|
{{#each matches.documents as |m|}}
|
||||||
|
<li class="link-item" {{ action 'setSelection' m }}>
|
||||||
|
{{#ui/ui-selection selected=m.selected}}
|
||||||
|
{{m.title}}
|
||||||
|
{{/ui/ui-selection}}
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
{{#each matches.pages as |m|}}
|
||||||
|
<li class="link-item" {{ action 'setSelection' m }}>
|
||||||
|
{{#ui/ui-selection selected=m.selected}}
|
||||||
|
{{m.title}}<br/><span class="color-gray">{{m.context}}</span>
|
||||||
|
{{/ui/ui-selection}}
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
{{#each matches.attachments as |a|}}
|
||||||
|
<li class="link-item" {{ action 'setSelection' a }}>
|
||||||
|
{{#ui/ui-selection selected=a.selected}}
|
||||||
|
<img class="icon" src="/assets/img/attachments/{{document/file-icon a.context}}" />
|
||||||
|
{{ a.title }}
|
||||||
|
{{/ui/ui-selection}}
|
||||||
|
</li>
|
||||||
|
{{/each}}
|
||||||
|
</ul>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
<div class="hide regular-button button-blue pull-right" {{ action 'onInsertLink' }}>Insert</div>
|
||||||
|
<div class="hide clearfix" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
{{/dropdown-dialog}}
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue