mirror of
https://github.com/documize/community.git
synced 2025-07-20 13:49:42 +02:00
Streamline document meta view and editing experience
Meta data: 1. Condensed layout. 2. Unified editing. Co-Authored-By: Saul S <sauls8t@users.noreply.github.com>
This commit is contained in:
parent
f70d4b33a3
commit
27fde0dac8
26 changed files with 2389 additions and 1956 deletions
|
@ -58,9 +58,9 @@ Space view.
|
||||||
|
|
||||||
## Latest version
|
## Latest version
|
||||||
|
|
||||||
[Community edition: v1.65.1](https://github.com/documize/community/releases)
|
[Community edition: v1.65.2](https://github.com/documize/community/releases)
|
||||||
|
|
||||||
[Enterprise edition: v1.67.1](https://documize.com/downloads)
|
[Enterprise edition: v1.67.2](https://documize.com/downloads)
|
||||||
|
|
||||||
## OS support
|
## OS support
|
||||||
|
|
||||||
|
|
|
@ -10,36 +10,18 @@
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
import $ from 'jquery';
|
import $ from 'jquery';
|
||||||
|
import { A } from '@ember/array';
|
||||||
import { computed } from '@ember/object';
|
import { computed } from '@ember/object';
|
||||||
import { notEmpty } from '@ember/object/computed';
|
import { notEmpty } from '@ember/object/computed';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
import { A } from '@ember/array';
|
import Modals from '../../mixins/modal';
|
||||||
import { schedule } from '@ember/runloop';
|
import Tooltips from '../../mixins/tooltip';
|
||||||
import ModalMixin from '../../mixins/modal';
|
|
||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend(ModalMixin, {
|
export default Component.extend(Modals, Tooltips, {
|
||||||
documentService: service('document'),
|
documentService: service('document'),
|
||||||
categoryService: service('category'),
|
|
||||||
sessionService: service('session'),
|
sessionService: service('session'),
|
||||||
|
categoryService: service('category'),
|
||||||
categories: A([]),
|
|
||||||
newCategory: '',
|
|
||||||
showCategoryModal: false,
|
|
||||||
hasCategories: computed('categories', function() {
|
|
||||||
return this.get('categories').length > 0;
|
|
||||||
}),
|
|
||||||
canSelectCategory: computed('categories', function() {
|
|
||||||
return (this.get('categories').length > 0 && this.get('permissions.documentEdit'));
|
|
||||||
}),
|
|
||||||
canAddCategory: computed('categories', function() {
|
|
||||||
return this.get('permissions.spaceOwner') || this.get('permissions.spaceManage');
|
|
||||||
}),
|
|
||||||
|
|
||||||
maxTags: 3,
|
|
||||||
tagz: A([]),
|
|
||||||
tagzModal: A([]),
|
|
||||||
newTag: '',
|
|
||||||
|
|
||||||
contributorMsg: '',
|
contributorMsg: '',
|
||||||
approverMsg: '',
|
approverMsg: '',
|
||||||
|
@ -91,67 +73,56 @@ export default Component.extend(ModalMixin, {
|
||||||
|
|
||||||
didReceiveAttrs() {
|
didReceiveAttrs() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.load();
|
|
||||||
this.workflowStatus();
|
this.workflowStatus();
|
||||||
|
this.popovers();
|
||||||
|
this.load();
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
$('#document-tags-modal').on('show.bs.modal', (event) => { // eslint-disable-line no-unused-vars
|
this.popovers();
|
||||||
schedule('afterRender', () => {
|
this.renderTooltips();
|
||||||
$("#add-tag-field").focus();
|
|
||||||
|
|
||||||
$("#add-tag-field").off("keydown").on("keydown", function(e) {
|
|
||||||
if (e.shiftKey) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.which === 13 || e.which === 45 || e.which === 189 || e.which === 8 || e.which === 127 || (e.which >= 65 && e.which <= 90) || (e.which >= 97 && e.which <= 122) || (e.which >= 48 && e.which <= 57)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
|
|
||||||
// make copy of tags for editing
|
|
||||||
this.set('tagzEdit', this.get('tagz'));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
$("#add-tag-field").off("keydown");
|
|
||||||
},
|
|
||||||
|
|
||||||
load() {
|
$('#document-lifecycle-popover').popover('dispose');
|
||||||
this.get('categoryService').getUserVisible(this.get('folder.id')).then((categories) => {
|
$('#document-protection-popover').popover('dispose');
|
||||||
let cats = A(categories);
|
this.removeTooltips();
|
||||||
this.set('categories', cats);
|
},
|
||||||
this.get('categoryService').getDocumentCategories(this.get('document.id')).then((selected) => {
|
|
||||||
this.set('selectedCategories', selected);
|
popovers() {
|
||||||
selected.forEach((s) => {
|
let constants = this.get('constants');
|
||||||
let cat = cats.findBy('id', s.id);
|
|
||||||
if (is.not.undefined(cat)) {
|
$('#document-lifecycle-popover').popover('dispose');
|
||||||
cat.set('selected', true);
|
$('#document-protection-popover').popover('dispose');
|
||||||
this.set('categories', cats);
|
|
||||||
}
|
$('#document-lifecycle-popover').popover({
|
||||||
});
|
html: true,
|
||||||
});
|
title: 'Lifecycle',
|
||||||
|
content: "<p>Draft — restricted visiblity and not searchable</p><p>Live — document visible to all</p><p>Archived — not visible or searchable</p>",
|
||||||
|
placement: 'top'
|
||||||
});
|
});
|
||||||
|
|
||||||
let tagz = [];
|
let ccMsg = `<p>${this.changeControlMsg}</p>`;
|
||||||
if (!_.isUndefined(this.get('document.tags')) && this.get('document.tags').length > 1) {
|
|
||||||
let tags = this.get('document.tags').split('#');
|
|
||||||
_.each(tags, function(tag) {
|
|
||||||
if (tag.length > 0) {
|
|
||||||
tagz.pushObject(tag);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.set('tagz', A(tagz));
|
if (this.get('document.protection') === constants.ProtectionType.Review) {
|
||||||
|
ccMsg += '<ul>'
|
||||||
|
ccMsg += `<li>${this.approvalMsg}</li>`;
|
||||||
|
if (this.get('userChanges')) ccMsg += `<li>Your contributions: ${this.contributorMsg}</li>`;
|
||||||
|
if (this.get('isApprover') && this.get('approverMsg.length') > 0) ccMsg += `<li>${this.approverMsg}</li>`;
|
||||||
|
ccMsg += '</ul>'
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#document-protection-popover').popover({
|
||||||
|
html: true,
|
||||||
|
title: 'Change Control',
|
||||||
|
content: ccMsg,
|
||||||
|
placement: 'top'
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
workflowStatus() {
|
workflowStatus() {
|
||||||
|
@ -184,97 +155,38 @@ export default Component.extend(ModalMixin, {
|
||||||
let label = approverPendingCount === 1 ? 'change' : 'changes';
|
let label = approverPendingCount === 1 ? 'change' : 'changes';
|
||||||
approverMsg = `${approverPendingCount} ${label} progressing, ${approverReviewCount} awaiting review, ${approverRejectedCount} rejected`;
|
approverMsg = `${approverPendingCount} ${label} progressing, ${approverReviewCount} awaiting review, ${approverRejectedCount} rejected`;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('approverMsg', approverMsg);
|
this.set('approverMsg', approverMsg);
|
||||||
|
this.set('selectedVersion', this.get('versions').findBy('documentId', this.get('document.id')));
|
||||||
|
|
||||||
|
this.popovers();
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
load() {
|
||||||
onShowCategoryModal() {
|
this.get('categoryService').getDocumentCategories(this.get('document.id')).then((selected) => {
|
||||||
this.set('showCategoryModal', true);
|
this.set('selectedCategories', selected);
|
||||||
},
|
});
|
||||||
|
|
||||||
onSaveCategory() {
|
let tagz = [];
|
||||||
let docId = this.get('document.id');
|
if (!_.isUndefined(this.get('document.tags')) && this.get('document.tags').length > 1) {
|
||||||
let folderId = this.get('folder.id');
|
let tags = this.get('document.tags').split('#');
|
||||||
let link = this.get('categories').filterBy('selected', true);
|
|
||||||
let unlink = this.get('categories').filterBy('selected', false);
|
|
||||||
let toLink = [];
|
|
||||||
let toUnlink = [];
|
|
||||||
|
|
||||||
// prepare links associated with document
|
|
||||||
link.forEach((l) => {
|
|
||||||
let t = {
|
|
||||||
folderId: folderId,
|
|
||||||
documentId: docId,
|
|
||||||
categoryId: l.get('id')
|
|
||||||
};
|
|
||||||
|
|
||||||
toLink.push(t);
|
|
||||||
});
|
|
||||||
|
|
||||||
// prepare links no longer associated with document
|
|
||||||
unlink.forEach((l) => {
|
|
||||||
let t = {
|
|
||||||
folderId: folderId,
|
|
||||||
documentId: docId,
|
|
||||||
categoryId: l.get('id')
|
|
||||||
};
|
|
||||||
|
|
||||||
toUnlink.pushObject(t);
|
|
||||||
});
|
|
||||||
|
|
||||||
this.set('showCategoryModal', false);
|
|
||||||
|
|
||||||
this.get('categoryService').setCategoryMembership(toUnlink, 'unlink').then(() => {
|
|
||||||
this.get('categoryService').setCategoryMembership(toLink, 'link').then(() => {
|
|
||||||
this.load();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
return true;
|
|
||||||
},
|
|
||||||
|
|
||||||
onAddTag(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
let tags = this.get("tagzEdit");
|
|
||||||
let tag = this.get('newTag');
|
|
||||||
tag = tag.toLowerCase().trim();
|
|
||||||
|
|
||||||
// empty or dupe?
|
|
||||||
if (tag.length === 0 || _.contains(tags, tag) || tags.length >= this.get('maxTags') || tag.startsWith('-')) {
|
|
||||||
$('#add-tag-field').addClass('is-invalid');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
tags.pushObject(tag);
|
|
||||||
this.set('tagzEdit', tags);
|
|
||||||
this.set('newTag', '');
|
|
||||||
$('#add-tag-field').removeClass('is-invalid');
|
|
||||||
},
|
|
||||||
|
|
||||||
onRemoveTag(tagToRemove) {
|
|
||||||
this.set('tagzEdit', _.without(this.get("tagzEdit"), tagToRemove));
|
|
||||||
},
|
|
||||||
|
|
||||||
onSaveTags() {
|
|
||||||
let tags = this.get("tagzEdit");
|
|
||||||
|
|
||||||
let save = "#";
|
|
||||||
_.each(tags, function(tag) {
|
_.each(tags, function(tag) {
|
||||||
save = save + tag + "#";
|
if (tag.length > 0) {
|
||||||
});
|
tagz.pushObject(tag);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
let doc = this.get('document');
|
this.set('tagz', A(tagz));
|
||||||
doc.set('tags', save);
|
},
|
||||||
|
|
||||||
let cb = this.get('onSaveDocument');
|
actions: {
|
||||||
cb(doc);
|
onSelectVersion(version) {
|
||||||
|
let space = this.get('folder');
|
||||||
|
|
||||||
this.load();
|
this.get('router').transitionTo('document',
|
||||||
this.set('newTag', '');
|
space.get('id'), space.get('slug'),
|
||||||
|
version.documentId, this.get('document.slug'));
|
||||||
$('#document-tags-modal').modal('hide');
|
|
||||||
$('#document-tags-modal').modal('dispose');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -9,31 +9,29 @@
|
||||||
//
|
//
|
||||||
// https://documize.com
|
// https://documize.com
|
||||||
|
|
||||||
import $ from 'jquery';
|
|
||||||
import { empty } from '@ember/object/computed';
|
import { empty } from '@ember/object/computed';
|
||||||
import { computed } from '@ember/object';
|
import { computed } from '@ember/object';
|
||||||
import { schedule } from '@ember/runloop';
|
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
|
import Notifier from '../../mixins/notifier';
|
||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend(Notifier, {
|
||||||
documentService: service('document'),
|
documentSvc: service('document'),
|
||||||
editMode: false,
|
|
||||||
docName: '',
|
docName: '',
|
||||||
docExcerpt: '',
|
docExcerpt: '',
|
||||||
hasNameError: empty('docName'),
|
hasNameError: empty('docName'),
|
||||||
|
|
||||||
canEdit: computed('permssions', 'document', function() {
|
noEdits: computed('permssions', 'document', function() {
|
||||||
let constants = this.get('constants');
|
let constants = this.get('constants');
|
||||||
let permissions = this.get('permissions');
|
let permissions = this.get('permissions');
|
||||||
|
|
||||||
if (permissions.get('documentEdit') && this.get('document.protection') === constants.ProtectionType.None) {
|
if (permissions.get('documentEdit') && this.get('document.protection') !== constants.ProtectionType.None) {
|
||||||
return true;
|
return false;
|
||||||
} else if (permissions.get('documentApprove') && this.get('document.protection') === constants.ProtectionType.Review) {
|
} else if (permissions.get('documentApprove') && this.get('document.protection') === constants.ProtectionType.Review) {
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return true;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
keyUp(e) {
|
keyUp(e) {
|
||||||
|
@ -42,30 +40,31 @@ export default Component.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
didReceiveAttrs() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
this.set('docName', this.get('document.name'));
|
||||||
|
this.set('docExcerpt', this.get('document.excerpt'));
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
toggleEdit() {
|
|
||||||
this.set('docName', this.get('document.name'));
|
|
||||||
this.set('docExcerpt', this.get('document.excerpt'));
|
|
||||||
this.set('editMode', true);
|
|
||||||
|
|
||||||
schedule('afterRender', () => {
|
|
||||||
$('#document-name').select();
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onSave() {
|
onSave() {
|
||||||
if (this.get('hasNameError')) return;
|
if (this.get('hasNameError')) return;
|
||||||
|
|
||||||
|
let constants = this.get('constants');
|
||||||
|
|
||||||
this.set('document.name', this.get('docName'));
|
this.set('document.name', this.get('docName'));
|
||||||
this.set('document.excerpt', this.get('docExcerpt').trim());
|
this.set('document.excerpt', this.get('docExcerpt').trim());
|
||||||
this.set('editMode', false);
|
|
||||||
|
let lifecycle = this.get('lifecycle.selected');
|
||||||
|
this.set('document.lifecycle', lifecycle);
|
||||||
|
|
||||||
let cb = this.get('onSaveDocument');
|
let cb = this.get('onSaveDocument');
|
||||||
cb(this.get('document'));
|
cb(this.get('document'));
|
||||||
},
|
|
||||||
|
|
||||||
onCancel() {
|
if (lifecycle === constants.Lifecycle.Draft) {
|
||||||
this.set('editMode', false);
|
this.get('activitySvc').clearChangeHistory(this.get('document.id'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
173
gui/app/components/document/settings-meta.js
Normal file
173
gui/app/components/document/settings-meta.js
Normal file
|
@ -0,0 +1,173 @@
|
||||||
|
// 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 $ from 'jquery';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
import { A } from '@ember/array';
|
||||||
|
import { computed } from '@ember/object';
|
||||||
|
import { schedule } from '@ember/runloop';
|
||||||
|
import Notifier from '../../mixins/notifier';
|
||||||
|
import Component from '@ember/component';
|
||||||
|
|
||||||
|
export default Component.extend(Notifier, {
|
||||||
|
documentSvc: service('document'),
|
||||||
|
categoryService: service('category'),
|
||||||
|
|
||||||
|
categories: A([]),
|
||||||
|
newCategory: '',
|
||||||
|
showCategoryModal: false,
|
||||||
|
hasCategories: computed('categories', function() {
|
||||||
|
return this.get('categories').length > 0;
|
||||||
|
}),
|
||||||
|
canSelectCategory: computed('categories', function() {
|
||||||
|
return (this.get('categories').length > 0 && this.get('permissions.documentEdit'));
|
||||||
|
}),
|
||||||
|
canAddCategory: computed('categories', function() {
|
||||||
|
return this.get('permissions.spaceOwner') || this.get('permissions.spaceManage');
|
||||||
|
}),
|
||||||
|
|
||||||
|
maxTags: 3,
|
||||||
|
tag1: '',
|
||||||
|
tag2: '',
|
||||||
|
tag3: '',
|
||||||
|
|
||||||
|
didReceiveAttrs() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.load();
|
||||||
|
},
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
schedule('afterRender', () => {
|
||||||
|
$("#add-tag-field0").focus();
|
||||||
|
|
||||||
|
$(".tag-input").off("keydown").on("keydown", function(e) {
|
||||||
|
if (e.shiftKey && e.which === 9) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.shiftKey) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.which === 9 || e.which === 13 || e.which === 16 || e.which === 45 || e.which === 189 || e.which === 8 || e.which === 127 || (e.which >= 65 && e.which <= 90) || (e.which >= 97 && e.which <= 122) || (e.which >= 48 && e.which <= 57)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
willDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
$(".tag-input").off("keydown");
|
||||||
|
},
|
||||||
|
|
||||||
|
load() {
|
||||||
|
this.get('categoryService').getUserVisible(this.get('space.id')).then((categories) => {
|
||||||
|
let cats = A(categories);
|
||||||
|
this.set('categories', cats);
|
||||||
|
this.get('categoryService').getDocumentCategories(this.get('document.id')).then((selected) => {
|
||||||
|
this.set('selectedCategories', selected);
|
||||||
|
selected.forEach((s) => {
|
||||||
|
let cat = cats.findBy('id', s.id);
|
||||||
|
if (is.not.undefined(cat)) {
|
||||||
|
cat.set('selected', true);
|
||||||
|
this.set('categories', cats);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!_.isUndefined(this.get('document.tags')) && this.get('document.tags').length > 1) {
|
||||||
|
let tags = this.get('document.tags').split('#');
|
||||||
|
let counter = 1;
|
||||||
|
_.each(tags, (tag) => {
|
||||||
|
tag = tag.trim();
|
||||||
|
if (tag.length > 0) {
|
||||||
|
this.set('tag' + counter, tag);
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onSave() {
|
||||||
|
this.showWait();
|
||||||
|
|
||||||
|
let docId = this.get('document.id');
|
||||||
|
let folderId = this.get('space.id');
|
||||||
|
let link = this.get('categories').filterBy('selected', true);
|
||||||
|
let unlink = this.get('categories').filterBy('selected', false);
|
||||||
|
let toLink = [];
|
||||||
|
let toUnlink = [];
|
||||||
|
|
||||||
|
// prepare links associated with document
|
||||||
|
link.forEach((l) => {
|
||||||
|
let t = {
|
||||||
|
folderId: folderId,
|
||||||
|
documentId: docId,
|
||||||
|
categoryId: l.get('id')
|
||||||
|
};
|
||||||
|
|
||||||
|
toLink.push(t);
|
||||||
|
});
|
||||||
|
|
||||||
|
// prepare links no longer associated with document
|
||||||
|
unlink.forEach((l) => {
|
||||||
|
let t = {
|
||||||
|
folderId: folderId,
|
||||||
|
documentId: docId,
|
||||||
|
categoryId: l.get('id')
|
||||||
|
};
|
||||||
|
|
||||||
|
toUnlink.pushObject(t);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.get('categoryService').setCategoryMembership(toUnlink, 'unlink').then(() => {
|
||||||
|
this.get('categoryService').setCategoryMembership(toLink, 'link').then(() => {
|
||||||
|
this.showDone();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let tag1 = this.get("tag1").toLowerCase().trim();
|
||||||
|
let tag2 = this.get("tag2").toLowerCase().trim();
|
||||||
|
let tag3 = this.get("tag3").toLowerCase().trim();
|
||||||
|
let save = "#";
|
||||||
|
|
||||||
|
if (tag1.startsWith('-')) {
|
||||||
|
$('#add-tag-field1').addClass('is-invalid');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tag2.startsWith('-')) {
|
||||||
|
$('#add-tag-field2').addClass('is-invalid');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (tag3.startsWith('-')) {
|
||||||
|
$('#add-tag-field3').addClass('is-invalid');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
(tag1.length > 0 ) ? save += (tag1 + "#") : this.set('tag1', '');
|
||||||
|
(tag2.length > 0 && tag2 !== tag1) ? save += (tag2 + "#") : this.set('tag2', '');
|
||||||
|
(tag3.length > 0 && tag3 !== tag1 && tag3 !== tag2) ? save += (tag3 + "#") : this.set('tag3', '');
|
||||||
|
|
||||||
|
let doc = this.get('document');
|
||||||
|
doc.set('tags', save);
|
||||||
|
|
||||||
|
this.get('onSaveDocument')(doc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
|
@ -15,7 +15,6 @@ import { inject as service } from '@ember/service';
|
||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
classNames: ['row d-print-none'],
|
|
||||||
documentService: service('document'),
|
documentService: service('document'),
|
||||||
appMeta: service(),
|
appMeta: service(),
|
||||||
hasAttachments: notEmpty('files'),
|
hasAttachments: notEmpty('files'),
|
||||||
|
@ -26,12 +25,12 @@ export default Component.extend({
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.getAttachments();
|
this.deleteAttachment = { id: '', name: '' };
|
||||||
|
},
|
||||||
|
|
||||||
this.deleteAttachment = {
|
didReceiveAttrs() {
|
||||||
id: "",
|
this._super(...arguments);
|
||||||
name: "",
|
this.getAttachments();
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
didInsertElement() {
|
didInsertElement() {
|
||||||
|
|
|
@ -33,7 +33,6 @@ export default Component.extend(TooltipMixin, Notifier, {
|
||||||
}),
|
}),
|
||||||
voteThanks: false,
|
voteThanks: false,
|
||||||
showLikes: false,
|
showLikes: false,
|
||||||
|
|
||||||
showDeleteBlockDialog: false,
|
showDeleteBlockDialog: false,
|
||||||
deleteBlockId: '',
|
deleteBlockId: '',
|
||||||
|
|
||||||
|
@ -107,6 +106,16 @@ export default Component.extend(TooltipMixin, Notifier, {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
addSection(model) {
|
||||||
|
let constants = this.get('constants');
|
||||||
|
|
||||||
|
if (this.get('document.protection') === constants.ProtectionType.Review) {
|
||||||
|
model.page.set('status', model.page.get('relativeId') === '' ? constants.ChangeState.PendingNew : constants.ChangeState.Pending);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.get('onInsertSection')(model);
|
||||||
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onSavePageAsBlock(block) {
|
onSavePageAsBlock(block) {
|
||||||
let cb = this.get('onSavePageAsBlock');
|
let cb = this.get('onSavePageAsBlock');
|
||||||
|
|
|
@ -17,7 +17,6 @@ import ModalMixin from '../../mixins/modal';
|
||||||
import Component from '@ember/component';
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Component.extend(ModalMixin, TooltipMixin, AuthMixin, {
|
export default Component.extend(ModalMixin, TooltipMixin, AuthMixin, {
|
||||||
userSvc: service('user'),
|
|
||||||
store: service(),
|
store: service(),
|
||||||
spaceSvc: service('folder'),
|
spaceSvc: service('folder'),
|
||||||
session: service(),
|
session: service(),
|
||||||
|
@ -26,6 +25,7 @@ export default Component.extend(ModalMixin, TooltipMixin, AuthMixin, {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
|
|
||||||
this.pinState = {
|
this.pinState = {
|
||||||
isPinned: false,
|
isPinned: false,
|
||||||
pinId: '',
|
pinId: '',
|
||||||
|
|
|
@ -35,5 +35,4 @@ export default Mixin.create({
|
||||||
removePopovers() {
|
removePopovers() {
|
||||||
$('[data-toggle="tooltip"]').popover('dispose');
|
$('[data-toggle="tooltip"]').popover('dispose');
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
import { Promise as EmberPromise } from 'rsvp';
|
import { Promise as EmberPromise } from 'rsvp';
|
||||||
import { inject as service } from '@ember/service';
|
import { inject as service } from '@ember/service';
|
||||||
|
import { computed } from '@ember/object';
|
||||||
import Tooltips from '../../../mixins/tooltip';
|
import Tooltips from '../../../mixins/tooltip';
|
||||||
import Notifier from '../../../mixins/notifier';
|
import Notifier from '../../../mixins/notifier';
|
||||||
import Controller from '@ember/controller';
|
import Controller from '@ember/controller';
|
||||||
|
@ -22,6 +23,12 @@ export default Controller.extend(Tooltips, Notifier, {
|
||||||
linkService: service('link'),
|
linkService: service('link'),
|
||||||
tab: 'content',
|
tab: 'content',
|
||||||
queryParams: ['currentPageId'],
|
queryParams: ['currentPageId'],
|
||||||
|
showRevisions: computed('permissions', 'document.protection', function() {
|
||||||
|
if (this.get('document.protection') === this.get('constants').ProtectionType.None) return true;
|
||||||
|
if (this.get('document.protection') === this.get('constants').ProtectionType.Review && this.get('permissions.documentApprove')) return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
onTabChange(tab) {
|
onTabChange(tab) {
|
||||||
|
@ -229,7 +236,7 @@ export default Controller.extend(Tooltips, Notifier, {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
refresh() {
|
refresh(reloadPage) {
|
||||||
return new EmberPromise((resolve) => {
|
return new EmberPromise((resolve) => {
|
||||||
this.get('documentService').fetchDocumentData(this.get('document.id')).then((data) => {
|
this.get('documentService').fetchDocumentData(this.get('document.id')).then((data) => {
|
||||||
this.set('document', data.document);
|
this.set('document', data.document);
|
||||||
|
@ -247,7 +254,11 @@ export default Controller.extend(Tooltips, Notifier, {
|
||||||
this.set('blocks', data);
|
this.set('blocks', data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (reloadPage) {
|
||||||
|
window.location.reload();
|
||||||
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -32,16 +32,24 @@
|
||||||
<ul class="tabnav-control">
|
<ul class="tabnav-control">
|
||||||
<li class="tab {{if (eq tab 'content') 'selected'}}" {{action 'onTabChange' 'content'}}>Content</li>
|
<li class="tab {{if (eq tab 'content') 'selected'}}" {{action 'onTabChange' 'content'}}>Content</li>
|
||||||
{{#if session.authenticated}}
|
{{#if session.authenticated}}
|
||||||
<li class="tab {{if (eq tab 'revision') 'selected'}}" {{action 'onTabChange' 'revision'}}>Revisions</li>
|
{{#if showRevisions}}
|
||||||
|
<li class="tab {{if (eq tab 'revision') 'selected'}}" {{action 'onTabChange' 'revision'}}>Revisions</li>
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{document/document-heading
|
<div class="view-document">
|
||||||
document=document
|
<div class="document-heading">
|
||||||
versions=versions
|
<h1 class="doc-title">
|
||||||
permissions=permissions
|
{{#if document.template}}
|
||||||
onSaveDocument=(action 'onSaveDocument')}}
|
<span class="bg-warning p-1 pr-2 pl-2">Template</span>
|
||||||
|
{{/if}}
|
||||||
|
{{document.name}}
|
||||||
|
</h1>
|
||||||
|
<div class="doc-excerpt">{{document.excerpt}}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{{document/document-meta
|
{{document/document-meta
|
||||||
pages=pages
|
pages=pages
|
||||||
|
@ -76,12 +84,14 @@
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{#if (eq tab 'revision')}}
|
{{#if (eq tab 'revision')}}
|
||||||
{{document/view-revision
|
{{#if showRevisions}}
|
||||||
pages=pages
|
{{document/view-revision
|
||||||
folder=folder
|
pages=pages
|
||||||
document=document
|
folder=folder
|
||||||
permissions=permissions
|
document=document
|
||||||
onRollback=(action 'onRollback')}}
|
permissions=permissions
|
||||||
|
onRollback=(action 'onRollback')}}
|
||||||
|
{{/if}}
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
{{/layout/middle-zone-content}}
|
{{/layout/middle-zone-content}}
|
||||||
|
|
42
gui/app/pods/document/settings/controller.js
Normal file
42
gui/app/pods/document/settings/controller.js
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
// 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 { inject as service } from '@ember/service';
|
||||||
|
import Notifier from '../../../mixins/notifier';
|
||||||
|
import Controller from '@ember/controller';
|
||||||
|
|
||||||
|
export default Controller.extend(Notifier, {
|
||||||
|
router: service(),
|
||||||
|
folderService: service('folder'),
|
||||||
|
documentService: service('document'),
|
||||||
|
localStorage: service('localStorage'),
|
||||||
|
tab: 'general',
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onTab(view) {
|
||||||
|
this.set('tab', view);
|
||||||
|
},
|
||||||
|
|
||||||
|
onSaveDocument(doc) {
|
||||||
|
this.showWait();
|
||||||
|
this.get('documentService').save(doc).then(() => {
|
||||||
|
this.showDone();
|
||||||
|
});
|
||||||
|
|
||||||
|
this.get('browser').setTitle(doc.get('name'));
|
||||||
|
this.get('browser').setMetaDescription(doc.get('excerpt'));
|
||||||
|
},
|
||||||
|
|
||||||
|
onRefresh() {
|
||||||
|
this.get('target._routerMicrolib').refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
35
gui/app/pods/document/settings/route.js
Normal file
35
gui/app/pods/document/settings/route.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// 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 { hash } from 'rsvp';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
import Route from '@ember/routing/route';
|
||||||
|
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||||
|
|
||||||
|
export default Route.extend(AuthenticatedRouteMixin, {
|
||||||
|
documentService: service('document'),
|
||||||
|
folderService: service('folder'),
|
||||||
|
userService: service('user'),
|
||||||
|
|
||||||
|
model(/*params*/) {
|
||||||
|
return hash({
|
||||||
|
folders: this.modelFor('document').folders,
|
||||||
|
folder: this.modelFor('document').folder,
|
||||||
|
document: this.modelFor('document').document,
|
||||||
|
links: this.modelFor('document').links,
|
||||||
|
sections: this.modelFor('document').sections,
|
||||||
|
permissions: this.modelFor('document').permissions,
|
||||||
|
roles: this.modelFor('document').roles,
|
||||||
|
blocks: this.modelFor('document').blocks,
|
||||||
|
versions: this.modelFor('document').versions
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
49
gui/app/pods/document/settings/template.hbs
Normal file
49
gui/app/pods/document/settings/template.hbs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
{{#layout/top-bar}}
|
||||||
|
<li class="item">
|
||||||
|
{{#link-to "folder.index" model.folder.id model.folder.slug class='link'}}
|
||||||
|
{{model.folder.name}}
|
||||||
|
{{/link-to}}
|
||||||
|
</li>
|
||||||
|
<li class="item">
|
||||||
|
{{#link-to 'document.index' model.folder.id model.folder.slug model.document.id model.document.slug class="link"}}
|
||||||
|
{{model.document.name}}
|
||||||
|
{{/link-to}}
|
||||||
|
</li>
|
||||||
|
<li class="item">
|
||||||
|
{{#link-to "document.settings" model.folder.id model.folder.slug class='link selected'}}
|
||||||
|
Settings
|
||||||
|
{{/link-to}}
|
||||||
|
</li>
|
||||||
|
{{/layout/top-bar}}
|
||||||
|
|
||||||
|
{{#layout/middle-zone}}
|
||||||
|
{{#layout/middle-zone-content}}
|
||||||
|
{{#if (eq tab 'general')}}
|
||||||
|
{{document/settings-general
|
||||||
|
space=model.folder
|
||||||
|
document=model.document
|
||||||
|
permissions=model.permissions
|
||||||
|
onSaveDocument=(action 'onSaveDocument')}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
|
{{#if (eq tab 'meta')}}
|
||||||
|
{{document/settings-meta
|
||||||
|
space=model.folder
|
||||||
|
document=model.document
|
||||||
|
permissions=model.permissions
|
||||||
|
onSaveDocument=(action 'onSaveDocument')}}
|
||||||
|
{{/if}}
|
||||||
|
{{/layout/middle-zone-content}}
|
||||||
|
|
||||||
|
{{#layout/middle-zone-sidebar}}
|
||||||
|
<div id="sidebar" class="sidebar">
|
||||||
|
<ul class="tabnav-control tabnav-control-centered w-75">
|
||||||
|
<li class="tab tab-vertical {{if (eq tab 'general') 'selected'}}" {{action 'onTab' 'general'}}>General</li>
|
||||||
|
<li class="tab tab-vertical {{if (eq tab 'permissions') 'selected'}}" {{action 'onTab' 'meta'}}>Categories & Tags</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{{/layout/middle-zone-sidebar}}
|
||||||
|
{{/layout/middle-zone}}
|
||||||
|
|
||||||
|
{{#layout/bottom-bar}}
|
||||||
|
{{/layout/bottom-bar}}
|
|
@ -56,6 +56,9 @@ export default Router.map(function () {
|
||||||
this.route('section', {
|
this.route('section', {
|
||||||
path: 'section/:page_id'
|
path: 'section/:page_id'
|
||||||
});
|
});
|
||||||
|
this.route('settings', {
|
||||||
|
path: 'settings'
|
||||||
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
33
gui/app/styles/bootstrap.scss
vendored
33
gui/app/styles/bootstrap.scss
vendored
|
@ -26,18 +26,19 @@ $light: $color-white;
|
||||||
$dark: $color-off-black;
|
$dark: $color-off-black;
|
||||||
|
|
||||||
// popover
|
// popover
|
||||||
$popover-bg: $color-off-white;
|
$popover-bg: $color-white;
|
||||||
$popover-header-bg: $color-off-white;
|
$popover-header-bg: $color-dark;
|
||||||
$popover-header-color: $color-off-black;
|
$popover-header-color: $color-white;
|
||||||
|
|
||||||
// tooltip
|
// tooltip
|
||||||
$tooltip-bg: $color-off-white;
|
$tooltip-bg: $color-dark;
|
||||||
$tooltip-color: $color-off-black;
|
$tooltip-color: $color-white;
|
||||||
|
|
||||||
// modal
|
// modal
|
||||||
$modal-backdrop-opacity: 0.7;
|
$modal-backdrop-opacity: 0.7;
|
||||||
$modal-header-border-color: $color-white;
|
$modal-header-border-color: $color-white;
|
||||||
$modal-footer-border-color: $color-white;
|
$modal-footer-border-color: $color-white;
|
||||||
|
|
||||||
.modal-header {
|
.modal-header {
|
||||||
background-color: $color-primary;
|
background-color: $color-primary;
|
||||||
color: $color-off-white;
|
color: $color-off-white;
|
||||||
|
@ -102,11 +103,9 @@ $link-hover-decoration: none;
|
||||||
@import "node_modules/bootstrap/scss/badge";
|
@import "node_modules/bootstrap/scss/badge";
|
||||||
|
|
||||||
// Boostrap overrides
|
// Boostrap overrides
|
||||||
|
|
||||||
.modal-80 {
|
.modal-80 {
|
||||||
max-width: 80% !important;
|
max-width: 80% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.modal-open {
|
body.modal-open {
|
||||||
padding-right: 0 !important;
|
padding-right: 0 !important;
|
||||||
|
|
||||||
|
@ -114,7 +113,6 @@ body.modal-open {
|
||||||
// See: https://stackoverflow.com/questions/21604674/bootstrap-modal-background-jumps-to-top-on-toggle/21881894
|
// See: https://stackoverflow.com/questions/21604674/bootstrap-modal-background-jumps-to-top-on-toggle/21881894
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
.modal-header-white {
|
.modal-header-white {
|
||||||
background-color: $color-white !important;
|
background-color: $color-white !important;
|
||||||
border: none !important;
|
border: none !important;
|
||||||
|
@ -130,6 +128,25 @@ body.modal-open {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.popover-header {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
.popover-body {
|
||||||
|
font-size: 1rem;
|
||||||
|
|
||||||
|
> p {
|
||||||
|
margin: 0.5rem 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
> ul {
|
||||||
|
margin: 10px 0 10px 25px;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
list-style: square;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Bootstrap override that removes gutter space on smaller screens
|
// Bootstrap override that removes gutter space on smaller screens
|
||||||
// @media (max-width: 1200px) {
|
// @media (max-width: 1200px) {
|
||||||
// .container {
|
// .container {
|
||||||
|
|
|
@ -9,57 +9,90 @@
|
||||||
.doc-excerpt {
|
.doc-excerpt {
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
color: $color-gray;
|
color: $color-gray;
|
||||||
margin: 0 0 45px;
|
margin: 0 0 20px;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
> .document-heading-edit {
|
|
||||||
margin-top: 3.5rem;
|
|
||||||
margin-bottom: 3rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
> .document-customfields {
|
|
||||||
margin-bottom: 4rem;
|
|
||||||
background-color: $color-off-white;
|
|
||||||
border: 1px solid $color-border;
|
|
||||||
padding: 20px 40px;
|
|
||||||
@include border-radius(3px);
|
|
||||||
|
|
||||||
.row {
|
|
||||||
padding: 5px 0;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
.action-button {
|
|
||||||
visibility: visible;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.heading {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-weight: 700;
|
|
||||||
color: $color-dark;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.action-button {
|
|
||||||
visibility: hidden;
|
|
||||||
margin-left: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-weight: normal;
|
|
||||||
color: $color-black;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value-static {
|
|
||||||
font-size: 1.1rem;
|
|
||||||
font-weight: bold;
|
|
||||||
color: $color-gray;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.document-lifecycle-live {
|
||||||
|
@include border-radius(3px);
|
||||||
|
@include ease-in();
|
||||||
|
display: inline-block;
|
||||||
|
border: 2px solid $color-green;
|
||||||
|
padding: 2px 10px;
|
||||||
|
color: $color-gray;
|
||||||
|
background-color: $color-off-white;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 1rem;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-lifecycle-draft {
|
||||||
|
@extend .document-lifecycle-live;
|
||||||
|
border: 2px solid $color-orange;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-orange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-protection-unlocked {
|
||||||
|
@include border-radius(3px);
|
||||||
|
@include ease-in();
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px 10px;
|
||||||
|
font-weight: 800;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: $color-gray;
|
||||||
|
background-color: $color-off-white;
|
||||||
|
border: 2px solid $color-gray;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-dark;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-protection-review {
|
||||||
|
@extend .document-protection-unlocked;
|
||||||
|
border: 2px solid $color-orange;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-orange;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-protection-locked {
|
||||||
|
@extend .document-protection-unlocked;
|
||||||
|
border: 2px solid $color-red;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-red;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-category {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: $color-gray;
|
||||||
|
background-color: $color-off-white;
|
||||||
|
border: 2px solid $color-gray;
|
||||||
|
border-left: 13px solid $color-gray;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.document-tag {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 2px 0;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
font-style: italic;
|
||||||
|
color: $color-gray;
|
||||||
|
margin-right: 20px;
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
.view-attachment {
|
.view-attachment {
|
||||||
> .upload-document-files {
|
> .upload-document-files {
|
||||||
margin: 10px 0 0 0;
|
|
||||||
@include ease-in();
|
@include ease-in();
|
||||||
|
margin: 50px 0 10px 0;
|
||||||
|
|
||||||
> .dz-preview, .dz-processing {
|
> .dz-preview, .dz-processing {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
|
@ -9,21 +9,29 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
> .list {
|
> .list {
|
||||||
margin: 0;
|
margin: 10px 0 0 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
> .item {
|
> .item {
|
||||||
color: $color-off-black;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
font-size: 1rem;
|
font-size: 1.1rem;
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
|
border-left: 6px solid $color-gray-light;
|
||||||
|
padding-left: 15px;
|
||||||
|
margin-left: 3px;
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
|
@include ease-in();
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
font-size: 1rem;
|
font-size: 1.1rem;
|
||||||
vertical-align: text-top;
|
vertical-align: text-top;
|
||||||
margin-right: 10px;
|
margin-right: 10px;
|
||||||
|
color: $color-gray;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: $color-link;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
> .delete {
|
> .delete {
|
||||||
|
|
|
@ -41,3 +41,25 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.widget-list-choice {
|
||||||
|
text-align: left;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
display: inline-block;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
margin: 0 20px 0 0;
|
||||||
|
padding: 0;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 1.3rem;
|
||||||
|
font-weight: 700;
|
||||||
|
color: $color-gray;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
> .selected {
|
||||||
|
color: $color-green;
|
||||||
|
border-bottom: 1px solid $color-green;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
{{#unless editMode}}
|
|
||||||
<div class="view-document">
|
|
||||||
<div class="document-heading {{if canEdit 'cursor-pointer'}}" onclick={{if canEdit (action 'toggleEdit')}}>
|
|
||||||
<h1 class="doc-title">
|
|
||||||
{{#if document.template}}
|
|
||||||
<span class="bg-warning p-1 pr-2 pl-2">Template</span>
|
|
||||||
{{/if}}
|
|
||||||
{{document.name}}
|
|
||||||
</h1>
|
|
||||||
<div class="doc-excerpt">{{document.excerpt}}</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{else}}
|
|
||||||
<form class="view-document" {{action "onSave" on="submit"}}>
|
|
||||||
<div class="document-heading-edit">
|
|
||||||
<div class="form-group">
|
|
||||||
{{focus-input id="document-name" type="text" value=docName class=(if hasNameError 'form-control mousetrap is-invalid' 'form-control mousetrap') placeholder="Title" autocomplete="off"}}
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
|
||||||
{{textarea id="document-excerpt" rows="2" value=docExcerpt class='form-control mousetrap' placeholder="Excerpt" autocomplete="off"}}
|
|
||||||
</div>
|
|
||||||
<button type="button" class="btn btn-outline-secondary" {{action "onCancel"}}>Cancel</button>
|
|
||||||
<button type="submit" class="btn btn-success" {{action "onSave"}}>Save</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
{{/unless}}
|
|
|
@ -1,119 +1,42 @@
|
||||||
<div class="view-document">
|
{{#if (eq document.lifecycle constants.Lifecycle.Live)}}
|
||||||
<div class="document-customfields">
|
<div id="document-lifecycle-popover" class="document-lifecycle-live text-uppercase">{{document.lifecycleLabel}}</div>
|
||||||
|
{{/if}}
|
||||||
|
{{#if (eq document.lifecycle constants.Lifecycle.Draft)}}
|
||||||
|
<div id="document-lifecycle-popover" class="document-lifecycle-draft text-uppercase">{{document.lifecycleLabel}}</div>
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<div class="row {{if (eq selectedCategories.length 0) 'd-print-none'}}">
|
<div class="d-block d-sm-none margin-top-20" />
|
||||||
<div class="col-12 col-sm-3 heading">Categories</div>
|
<div class="d-sm-inline-block margin-left-20" />
|
||||||
<div class="col-12 col-sm-9 value">
|
|
||||||
{{#each selectedCategories as |cat|}}
|
|
||||||
{{#link-to 'folder' folder.id folder.slug (query-params category=cat.id)}}
|
|
||||||
{{cat.category}}
|
|
||||||
{{/link-to}}
|
|
||||||
|
|
||||||
{{else}}
|
|
||||||
{{#if canAddCategory}}
|
|
||||||
{{#if canSelectCategory}}
|
|
||||||
<a href="#" class="d-print-none" {{action 'onShowCategoryModal'}}><select></a>
|
|
||||||
{{else}}
|
|
||||||
{{#link-to 'folder.category' folder.id folder.slug class='d-print-none'}}<manage>{{/link-to}}
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{/each}}
|
|
||||||
{{#if canSelectCategory}}
|
|
||||||
<div class="action-button button-icon-gray button-icon-small align-middle d-print-none" {{action 'onShowCategoryModal'}}>
|
|
||||||
<i class="material-icons align-middle">edit</i>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row {{if (eq tagz.length 0) 'd-print-none'}}">
|
{{#if (eq document.protection constants.ProtectionType.None)}}
|
||||||
<div class="col-12 col-sm-3 heading">Tags</div>
|
<div id="document-protection-popover" class="document-protection-unlocked text-uppercase">OPEN</div>
|
||||||
<div class="col-12 col-sm-9 value">
|
{{/if}}
|
||||||
{{#each tagz as |t index|}}
|
{{#if (eq document.protection constants.ProtectionType.Review)}}
|
||||||
{{#link-to 'search' (query-params filter=t matchTag=true matchDoc=false matchContent=false matchFile=false)}}
|
<div id="document-protection-popover" class="document-protection-review text-uppercase">PROTECTED</div>
|
||||||
{{concat '#' t}}
|
{{/if}}
|
||||||
{{/link-to}}
|
{{#if (eq document.protection constants.ProtectionType.Lock)}}
|
||||||
{{/each}}
|
<div id="document-protection-popover" class="document-protection-locked text-uppercase">LOCKED</div>
|
||||||
{{#if permissions.documentEdit}}
|
{{/if}}
|
||||||
<div class="action-button button-icon-gray button-icon-small align-middle d-print-none" data-toggle="modal" data-target="#document-tags-modal" data-backdrop="static">
|
|
||||||
<i class="material-icons align-middle">edit</i>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="row d-print-none">
|
<div class="d-block d-sm-none margin-top-20" />
|
||||||
<div class="col-12 col-sm-3 heading">Change Control</div>
|
<div class="d-sm-inline-block margin-left-20" />
|
||||||
<div class="col-12 col-sm-9 value-static">
|
|
||||||
<span>{{changeControlMsg}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if (eq document.protection constants.ProtectionType.Review)}}
|
|
||||||
<div class="row d-print-none">
|
|
||||||
<div class="col-12 col-sm-3 heading">Approval Process</div>
|
|
||||||
<div class="col-12 col-sm-9 value-static">
|
|
||||||
<span>{{approvalMsg}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{{#if userChanges}}
|
|
||||||
<div class="row d-print-none">
|
|
||||||
<div class="col-12 col-sm-3 heading">Your Contributions</div>
|
|
||||||
<div class="col-12 col-sm-9 value-static">
|
|
||||||
<span>{{contributorMsg}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{#if isApprover}}
|
|
||||||
<div class="row d-print-none">
|
|
||||||
<div class="col-12 col-sm-3 heading">Approver Status</div>
|
|
||||||
<div class="col-12 col-sm-9 value-static">
|
|
||||||
<span>{{approverMsg}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
{{document/view-attachment document=document permissions=permissions}}
|
|
||||||
|
|
||||||
|
{{#each selectedCategories as |cat|}}
|
||||||
|
<div class="document-category" data-toggle="tooltip" data-placement="top" title="Category">
|
||||||
|
{{cat.category}}
|
||||||
</div>
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
<div class="d-block d-sm-none margin-top-20" />
|
||||||
|
|
||||||
|
{{#each tagz as |t index|}}
|
||||||
|
<div class="document-tag" data-toggle="tooltip" data-placement="top" title="Tag">
|
||||||
|
{{concat '#' t}}
|
||||||
|
</div>
|
||||||
|
{{/each}}
|
||||||
|
|
||||||
|
<div class="document-meta">
|
||||||
|
{{document/view-attachment document=document permissions=permissions}}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#if permissions.documentEdit}}
|
<div class="margin-top-70" />
|
||||||
{{#ui/ui-dialog title="Document Categories" confirmCaption="Select" buttonType="btn-success" show=showCategoryModal onAction=(action 'onSaveCategory')}}
|
|
||||||
<p>Select who can view documents within category</p>
|
|
||||||
{{ui/ui-list-picker items=categories nameField='category' singleSelect=false}}
|
|
||||||
{{/ui/ui-dialog}}
|
|
||||||
|
|
||||||
<div id="document-tags-modal" class="modal" tabindex="-1" role="dialog">
|
|
||||||
<div class="modal-dialog" role="document">
|
|
||||||
<div class="modal-content">
|
|
||||||
<div class="modal-header">Document Tags</div>
|
|
||||||
<div class="modal-body">
|
|
||||||
<form onsubmit={{action 'onAddTag'}}>
|
|
||||||
<div class="form-group">
|
|
||||||
<label for="add-tag-field">Specify up to three tags per document</label>
|
|
||||||
{{#each tagzEdit as |t|}}
|
|
||||||
<div class="m-3 text-secondary">
|
|
||||||
<div class="button-icon-danger button-icon-small align-middle" {{action 'onRemoveTag' t}}>
|
|
||||||
<i class="material-icons">clear</i>
|
|
||||||
</div>
|
|
||||||
{{concat '#' t}}
|
|
||||||
</div>
|
|
||||||
{{/each}}
|
|
||||||
{{focus-input type='text' id="add-tag-field" class="form-control mousetrap" placeholder="Tag name" value=newTag}}
|
|
||||||
<small class="form-text text-success">Press ENTER to add tag</small>
|
|
||||||
<small class="form-text text-muted">Lowercase, characters, numbers, hyphens only</small>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-footer">
|
|
||||||
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Cancel</button>
|
|
||||||
<button type="button" class="btn btn-success" onclick={{action 'onSaveTags'}}>Save</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
|
|
21
gui/app/templates/components/document/settings-general.hbs
Normal file
21
gui/app/templates/components/document/settings-general.hbs
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
<div class="content-zone">
|
||||||
|
<div class="explainer-header">General Options</div>
|
||||||
|
<p class="explainer-text explainer-gap">Set name, excerpt and lifecycle stage</p>
|
||||||
|
|
||||||
|
<form class="view-document">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="document-name">Name</label>
|
||||||
|
{{focus-input id="document-name" type="text" value=docName
|
||||||
|
class=(if hasNameError 'form-control mousetrap is-invalid' 'form-control mousetrap') placeholder="Title" autocomplete="off" disabled=noEdits}}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="document-excerpt">Excerpt</label>
|
||||||
|
{{textarea id="document-excerpt" rows="4" value=docExcerpt class='form-control mousetrap' placeholder="Excerpt" autocomplete="off" disabled=noEdits}}
|
||||||
|
<small class="form-text text-muted">Optional description explaining content</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-success text-uppercase font-weight-bold mt-5" {{action "onSave"}}>Save</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
45
gui/app/templates/components/document/settings-meta.hbs
Normal file
45
gui/app/templates/components/document/settings-meta.hbs
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
<div class="content-zone">
|
||||||
|
<div class="explainer-header">Categories & Tags</div>
|
||||||
|
<p class="explainer-text explainer-gap">Categorize your content, assign tags to suppliment</p>
|
||||||
|
|
||||||
|
<h1>Specify up to three tags</h1>
|
||||||
|
<p class="form-text text-muted">Lowercase, characters, numbers, hyphens only</p>
|
||||||
|
<form>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">#</span>
|
||||||
|
</div>
|
||||||
|
{{input type='text' id='add-tag-field1' class="form-control mousetrap tag-input" placeholder="Tag name" value=tag1}}
|
||||||
|
</div>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">#</span>
|
||||||
|
</div>
|
||||||
|
{{input type='text' id='add-tag-field2' class="form-control mousetrap tag-input" placeholder="Tag name" value=tag2}}
|
||||||
|
</div>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<span class="input-group-text">#</span>
|
||||||
|
</div>
|
||||||
|
{{input type='text' id='add-tag-field3' class="form-control mousetrap tag-input" placeholder="Tag name" value=tag3}}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
<div class="mt-5" />
|
||||||
|
|
||||||
|
<h1>Assign categories</h1>
|
||||||
|
<p class="form-text text-muted">Categories allow you divide a space into logical chunks</p>
|
||||||
|
|
||||||
|
{{ui/ui-list-picker items=categories nameField='category' singleSelect=false}}
|
||||||
|
{{#unless selectedCategories}}
|
||||||
|
<p class="text-danger">This space has no categories defined yet.</p>
|
||||||
|
{{#if canAddCategory}}
|
||||||
|
<p>
|
||||||
|
{{#link-to 'folder.category' space.id space.slug class="btn btn-secondary font-weight-bold"}}Manage categories{{/link-to}}
|
||||||
|
</p>
|
||||||
|
{{/if}}
|
||||||
|
{{/unless}}
|
||||||
|
|
||||||
|
<button type="submit" class="btn btn-success text-uppercase font-weight-bold mt-5" {{action "onSave"}}>Save</button>
|
||||||
|
</div>
|
||||||
|
|
|
@ -1,5 +1,9 @@
|
||||||
<div class="col-12 col-sm-3 heading">Attachments</div>
|
<div class="view-attachment d-print-none">
|
||||||
<div class="col-12 col-sm-9 view-attachment">
|
{{#if canEdit}}
|
||||||
|
<div class="upload-document-files">
|
||||||
|
<div id="upload-document-files" class="btn btn-secondary text-uppercase font-weight-bold">+ Attachments</div>
|
||||||
|
</div>
|
||||||
|
{{/if}}
|
||||||
{{#if hasAttachments}}
|
{{#if hasAttachments}}
|
||||||
<ul class="list">
|
<ul class="list">
|
||||||
{{#each files key="id" as |a index|}}
|
{{#each files key="id" as |a index|}}
|
||||||
|
@ -18,11 +22,6 @@
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</ul>
|
</ul>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if canEdit}}
|
|
||||||
<div class="upload-document-files">
|
|
||||||
<div id="upload-document-files" class="btn btn-outline-secondary">Upload</div>
|
|
||||||
</div>
|
|
||||||
{{/if}}
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{#ui/ui-dialog title="Delete Attachment" confirmCaption="Delete" buttonType="btn-danger" show=showDialog onAction=(action 'onDelete')}}
|
{{#ui/ui-dialog title="Delete Attachment" confirmCaption="Delete" buttonType="btn-danger" show=showDialog onAction=(action 'onDelete')}}
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
<div class="text-right non-printable">
|
<div class="text-right non-printable">
|
||||||
{{#if session.authenticated}}
|
{{#if session.authenticated}}
|
||||||
|
{{#if permissions.documentEdit}}
|
||||||
|
{{#link-to 'document.settings' space.id space.slug document.id document.slug class="button-icon-gray align-middle"}}
|
||||||
|
<i class="material-icons" data-toggle="tooltip" data-placement="top" title="Meta, Lifecycle, Change Control">settings</i>
|
||||||
|
{{/link-to}}
|
||||||
|
<div class="button-icon-gap" />
|
||||||
|
{{/if}}
|
||||||
{{#if permissions.documentAdd}}
|
{{#if permissions.documentAdd}}
|
||||||
<div id="document-template-button" class="button-icon-gray align-middle" data-toggle="tooltip" data-placement="top" title="Save as template">
|
<div id="document-template-button" class="button-icon-gray align-middle" data-toggle="tooltip" data-placement="top" title="Save as template">
|
||||||
<i class="material-icons" data-toggle="modal" data-target="#document-template-modal" data-backdrop="static">content_copy</i>
|
<i class="material-icons" data-toggle="modal" data-target="#document-template-modal" data-backdrop="static">content_copy</i>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "documize",
|
"name": "documize",
|
||||||
"version": "1.65.1",
|
"version": "1.65.2",
|
||||||
"description": "The Document IDE",
|
"description": "The Document IDE",
|
||||||
"private": true,
|
"private": true,
|
||||||
"repository": "",
|
"repository": "",
|
||||||
|
|
3230
gui/vendor/underscore.js
vendored
3230
gui/vendor/underscore.js
vendored
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue