1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-21 22:29:41 +02:00

WIP new document UX/UI

This commit is contained in:
Harvey Kandola 2018-05-29 18:26:04 +01:00
parent 21ba55a58f
commit 36be6243ad
23 changed files with 910 additions and 4231 deletions

View file

@ -9,17 +9,15 @@
// //
// https://documize.com // https://documize.com
import $ from 'jquery';
import { computed } from '@ember/object'; import { computed } from '@ember/object';
import { schedule } from '@ember/runloop'; import { schedule } from '@ember/runloop';
import { inject as service } from '@ember/service'; import { inject as service } from '@ember/service';
import Component from '@ember/component';
import tocUtil from '../../utils/toc'; import tocUtil from '../../utils/toc';
import TooltipMixin from '../../mixins/tooltip'; import TooltipMixin from '../../mixins/tooltip';
import Component from '@ember/component';
export default Component.extend(TooltipMixin, { export default Component.extend(TooltipMixin, {
documentService: service('document'), documentService: service('document'),
isDesktop: false,
emptyState: computed('pages', function () { emptyState: computed('pages', function () {
return this.get('pages.length') === 0; return this.get('pages.length') === 0;
}), }),
@ -56,135 +54,21 @@ export default Component.extend(TooltipMixin, {
didInsertElement() { didInsertElement() {
this._super(...arguments); this._super(...arguments);
this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded'); this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded');
this.eventBus.subscribe('resized', this, 'setSize');
this.setSize();
this.renderTooltips(); this.renderTooltips();
}, },
willDestroyElement() { willDestroyElement() {
this._super(...arguments); this._super(...arguments);
this.eventBus.unsubscribe('documentPageAdded'); this.eventBus.unsubscribe('documentPageAdded');
this.eventBus.unsubscribe('resized');
let t = '#doc-toc';
if (interact.isSet(t)) interact(t).unset();
this.removeTooltips(); this.removeTooltips();
}, },
onDocumentPageAdded(pageId) { // eslint-disable-line no-unused-vars onDocumentPageAdded(pageId) { // eslint-disable-line no-unused-vars
this.setSize();
schedule('afterRender', () => { schedule('afterRender', () => {
this.setState(pageId); this.setState(pageId);
}); });
}, },
setSize() {
schedule('afterRender', () => {
let isDesktop = $(window).width() >= 1800;
this.set('isDesktop', isDesktop);
if (isDesktop) {
let h = $(window).height() - $("#nav-bar").height() - 140;
$("#doc-toc").css('max-height', h);
let i = $("#doc-view").offset();
if (is.not.undefined(i)) {
let l = i.left - 100;
if (l > 350) l = 350;
$("#doc-toc").width(l);
$("#doc-toc").css({
'display': 'inline-block',
'position': 'fixed',
'width': l+'px',
'height': 'auto',
'transform': '',
});
this.attachResizer();
}
} else {
$("#doc-toc").css({
'display': 'block',
'position': 'relative',
'width': '100%',
'height': '500px',
'transform': 'none',
});
}
});
},
attachResizer() {
schedule('afterRender', () => {
let t = '#doc-toc';
if (interact.isSet(t)) {
interact(t).unset();
}
interact('#doc-toc')
.draggable({
autoScroll: true,
inertia: false,
onmove: dragMoveListener,
// restrict: {
// restriction: "body",
// endOnly: true,
// elementRect: { top: 0, left: 0, bottom: 1, right: 1 }
// }
})
.resizable({
// resize from all edges and corners
edges: { left: true, right: true, bottom: true, top: true },
// keep the edges inside the parent
// restrictEdges: {
// outer: 'parent',
// endOnly: true,
// },
// minimum size
// restrictSize: {
// min: { width: 250, height: 65 },
// }
})
.on('resizemove', function (event) {
var target = event.target,
x = (parseFloat(target.getAttribute('data-x')) || 0),
y = (parseFloat(target.getAttribute('data-y')) || 0);
// update the element's style
target.style.width = event.rect.width + 'px';
target.style.height = event.rect.height + 'px';
// translate when resizing from top or left edges
x += event.deltaRect.left;
y += event.deltaRect.top;
target.style.webkitTransform = target.style.transform = 'translate(' + x + 'px,' + y + 'px)';
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
target.style.position = 'fixed';
});
});
function dragMoveListener (event) {
var target = event.target,
// keep the dragged position in the data-x/data-y attributes
x = (parseFloat(target.getAttribute('data-x')) || 0) + event.dx,
y = (parseFloat(target.getAttribute('data-y')) || 0) + event.dy;
// translate the element
target.style.webkitTransform = target.style.transform = 'translate(' + x + 'px, ' + y + 'px)';
// update the posiion attributes
target.setAttribute('data-x', x);
target.setAttribute('data-y', y);
target.style.position = 'fixed';
}
},
// Controls what user can do with the toc (left sidebar) // Controls what user can do with the toc (left sidebar)
setState(pageId) { setState(pageId) {
let toc = this.get('pages'); let toc = this.get('pages');

View file

@ -82,6 +82,7 @@ export default Component.extend({
getAttachments() { getAttachments() {
this.get('documentService').getAttachments(this.get('document.id')).then((files) => { this.get('documentService').getAttachments(this.get('document.id')).then((files) => {
this.set('files', files); this.set('files', files);
this.get('onReady')(files.length);
}); });
}, },

View file

@ -9,11 +9,34 @@
// //
// https://documize.com // https://documize.com
import $ from 'jquery';
import { inject as service } from '@ember/service'; 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: ['layout-footer'], classNames: ['layout-footer'],
tagName: 'footer', tagName: 'footer',
appMeta: service() appMeta: service(),
init() {
this._super(...arguments);
this.eventBus.subscribe('notifyUser', this, 'handleEvent');
},
handleEvent(msg) {
if (msg === 'wait') {
this.set('showWait', true);
this.set('showDone', false);
}
if (msg === 'done') {
$('.progress-done').removeClass('zoomOut').addClass('zoomIn');
this.set('showWait', false);
this.set('showDone', true);
setTimeout(function() {
$('.progress-done').removeClass('zoomIn').addClass('zoomOut');
}, 3000);
}
}
}); });

View file

@ -38,7 +38,7 @@ export default Component.extend({
schedule('afterRender', () => { schedule('afterRender', () => {
let options = { let options = {
cache_suffix: '?v=476', cache_suffix: '?v=4713',
selector: '#' + this.get('editorId'), selector: '#' + this.get('editorId'),
relative_urls: false, relative_urls: false,
browser_spellcheck: true, browser_spellcheck: true,
@ -117,7 +117,7 @@ export default Component.extend({
}; };
if (typeof tinymce === 'undefined') { if (typeof tinymce === 'undefined') {
$.getScript('/tinymce/tinymce.min.js?v=476', function () { $.getScript('/tinymce/tinymce.min.js?v=4713', function () {
window.tinymce.dom.Event.domLoaded = true; window.tinymce.dom.Event.domLoaded = true;
tinymce.baseURL = '//' + window.location.host + '/tinymce'; tinymce.baseURL = '//' + window.location.host + '/tinymce';
tinymce.suffix = '.min'; tinymce.suffix = '.min';

View file

@ -14,16 +14,18 @@ import Component from '@ember/component';
import miscUtil from '../utils/misc'; import miscUtil from '../utils/misc';
export default Component.extend({ export default Component.extend({
notifications : null,
init() { init() {
this._super(...arguments); this._super(...arguments);
}, },
didInsertElement() { didInsertElement() {
this.eventBus.subscribe('notifyUser', this, 'showNotification'); // this.eventBus.subscribe('notifyUser', this, 'showNotification');
}, },
willDestroyElement() { willDestroyElement() {
this.eventBus.unsubscribe('notifyUser'); // this.eventBus.unsubscribe('notifyUser');
}, },
showNotification(msg) { showNotification(msg) {

View file

@ -14,7 +14,15 @@ import Mixin from '@ember/object/mixin';
export default Mixin.create({ export default Mixin.create({
showNotification(msg) { showNotification(msg) {
this.eventBus.publish('notifyUser', msg); this.eventBus.publish('notifyUser', msg);
}, },
showWait() {
this.eventBus.publish('notifyUser', 'wait');
},
showDone() {
this.eventBus.publish('notifyUser', 'done');
},
actions: { actions: {
showNotification(msg) { showNotification(msg) {

View file

@ -11,16 +11,18 @@
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 Tooltips from '../../../mixins/tooltip';
import Notifier from '../../../mixins/notifier';
import Controller from '@ember/controller'; import Controller from '@ember/controller';
import TooltipMixin from '../../../mixins/tooltip';
export default Controller.extend(TooltipMixin, { export default Controller.extend(Tooltips, Notifier, {
documentService: service('document'), documentService: service('document'),
templateService: service('template'), templateService: service('template'),
sectionService: service('section'), sectionService: service('section'),
linkService: service('link'), linkService: service('link'),
// currentPageId: '', // currentPageId: '',
tab: 'content', tab: 'content',
tabCount: 0, // how many items inside the tab?
queryParams: ['currentPageId'], queryParams: ['currentPageId'],
actions: { actions: {
@ -37,7 +39,10 @@ export default Controller.extend(TooltipMixin, {
}, },
onSaveDocument(doc) { onSaveDocument(doc) {
this.get('documentService').save(doc); this.showWait();
this.get('documentService').save(doc).then(() => {
this.showDone();
});
this.get('browser').setTitle(doc.get('name')); this.get('browser').setTitle(doc.get('name'));
this.get('browser').setMetaDescription(doc.get('excerpt')); this.get('browser').setMetaDescription(doc.get('excerpt'));
}, },
@ -67,6 +72,8 @@ export default Controller.extend(TooltipMixin, {
}, },
onSavePage(page, meta) { onSavePage(page, meta) {
this.showWait();
let document = this.get('document'); let document = this.get('document');
let documentId = document.get('id'); let documentId = document.get('id');
let constants = this.get('constants'); let constants = this.get('constants');
@ -84,6 +91,8 @@ export default Controller.extend(TooltipMixin, {
}; };
this.get('documentService').updatePage(documentId, page.get('id'), model).then((/*up*/) => { this.get('documentService').updatePage(documentId, page.get('id'), model).then((/*up*/) => {
this.showDone();
this.get('documentService').fetchPages(documentId, this.get('session.user.id')).then((pages) => { this.get('documentService').fetchPages(documentId, this.get('session.user.id')).then((pages) => {
this.set('pages', pages); this.set('pages', pages);
this.get('linkService').getDocumentLinks(documentId).then((links) => { this.get('linkService').getDocumentLinks(documentId).then((links) => {
@ -131,10 +140,13 @@ export default Controller.extend(TooltipMixin, {
}, },
onInsertSection(data) { onInsertSection(data) {
this.showWait();
return new EmberPromise((resolve) => { return new EmberPromise((resolve) => {
this.get('documentService').addPage(this.get('document.id'), data).then((newPage) => { this.get('documentService').addPage(this.get('document.id'), data).then((newPage) => {
let data = this.get('store').normalize('page', newPage); let data = this.get('store').normalize('page', newPage);
this.get('store').push(data); this.get('store').push(data);
this.showDone();
this.get('documentService').fetchPages(this.get('document.id'), this.get('session.user.id')).then((pages) => { this.get('documentService').fetchPages(this.get('document.id'), this.get('session.user.id')).then((pages) => {
this.set('pages', pages); this.set('pages', pages);
@ -179,7 +191,11 @@ export default Controller.extend(TooltipMixin, {
}, },
onSaveTemplate(name, desc) { onSaveTemplate(name, desc) {
this.get('templateService').saveAsTemplate(this.get('document.id'), name, desc).then(function () {}); this.showWait();
this.get('templateService').saveAsTemplate(this.get('document.id'), name, desc).then(function () {
this.showDone();
});
}, },
onPageSequenceChange(currentPageId, changes) { onPageSequenceChange(currentPageId, changes) {
@ -201,9 +217,13 @@ export default Controller.extend(TooltipMixin, {
}, },
onTagChange(tags) { onTagChange(tags) {
this.showDone();
let doc = this.get('document'); let doc = this.get('document');
doc.set('tags', tags); doc.set('tags', tags);
this.get('documentService').save(doc); this.get('documentService').save(doc).then(()=> {
this.showWait();
});
}, },
onRollback(pageId, revisionId) { onRollback(pageId, revisionId) {
@ -225,6 +245,10 @@ export default Controller.extend(TooltipMixin, {
resolve(); resolve();
}); });
}); });
},
onReady(count) {
this.set('tabCount', count);
} }
} }
}); });

View file

@ -1,58 +1,93 @@
{{toolbar/nav-bar}} {{#layout/top-bar}}
<li class="item">
{{#link-to "folder.index" folder.id folder.slug class='link'}}
{{folder.name}}
{{/link-to}}
</li>
<li class="item">
{{#link-to 'document.index' folder.id folder.slug document.id document.slug class="link selected"}}
{{document.name}}
{{/link-to}}
</li>
{{/layout/top-bar}}
{{toolbar/for-document document=document spaces=folders space=folder {{#layout/middle-zone}}
permissions=permissions roles=roles tab=tab versions=versions {{#layout/middle-zone-content}}
onDocumentDelete=(action 'onDocumentDelete')
onSaveTemplate=(action 'onSaveTemplate')
onSaveDocument=(action 'onSaveDocument')
refresh=(action 'refresh')}}
<div id="doc-view" class="container"> {{toolbar/for-document
<div class="row"> document=document
<div class="col-12"> spaces=folders
{{document/document-heading document=document permissions=permissions space=folder
versions=versions permissions=permissions
onSaveDocument=(action 'onSaveDocument')}} roles=roles
{{document/document-meta document=document folder=folder folders=folders tab=tab
permissions=permissions pages=pages versions=versions versions=versions
onSaveDocument=(action 'onSaveDocument')}} onDocumentDelete=(action 'onDocumentDelete')
onSaveTemplate=(action 'onSaveTemplate')
onSaveDocument=(action 'onSaveDocument')
refresh=(action 'refresh')}}
{{document/document-heading
document=document
permissions=permissions
versions=versions
onSaveDocument=(action 'onSaveDocument')}}
{{document/document-meta
document=document
folder=folder
folders=folders
permissions=permissions
pages=pages
versions=versions
onSaveDocument=(action 'onSaveDocument')}}
<div class="text-center non-printable document-tabnav">
<ul class="tabnav-control">
<li class="tab {{if (eq tab 'content') 'selected'}}" {{action 'onTabChange' 'content'}}>Content</li>
<li class="tab {{if (eq tab 'attachment') 'selected'}}" {{action 'onTabChange' 'attachment'}}>
Attachments
({{tabCount}})
</li>
{{#if session.authenticated}}
<li class="tab {{if (eq tab 'revision') 'selected'}}" {{action 'onTabChange' 'revision'}}>Revisions</li>
{{/if}}
</ul>
</div> </div>
</div>
<div class="row">
<div class="col-12">
{{document/document-toc document=document folder=folder pages=pages page=page
permissions=permissions roles=roles tab=tab currentPageId=currentPageId onShowPage=(action 'onShowPage')
onPageSequenceChange=(action 'onPageSequenceChange') onPageLevelChange=(action 'onPageLevelChange')}}
</div>
</div>
<div class="row no-gutters mb-5"> {{#if (eq tab 'content')}}
<div class="col-12"> {{document/view-content
<div class="text-center non-printable document-tabnav"> document=document links=links pages=pages blocks=blocks currentPageId=currentPageId
<ul class="tabnav-control"> folder=folder folders=folders sections=sections permissions=permissions roles=roles
<li class="tab {{if (eq tab 'content') 'selected'}}" {{action 'onTabChange' 'content'}}>Content</li> onSavePage=(action 'onSavePage') onInsertSection=(action 'onInsertSection')
<li class="tab {{if (eq tab 'attachment') 'selected'}}" {{action 'onTabChange' 'attachment'}}>Attachments</li> onSavePageAsBlock=(action 'onSavePageAsBlock') onDeleteBlock=(action 'onDeleteBlock')
{{#if session.authenticated}} onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted')
<li class="tab {{if (eq tab 'revision') 'selected'}}" {{action 'onTabChange' 'revision'}}>Revisions</li> refresh=(action 'refresh')}}
{{/if}} {{/if}}
</ul> {{#if (eq tab 'attachment')}}
</div> {{document/view-attachment document=document permissions=permissions onReady=(action 'onReady')}}
{{/if}}
{{#if (eq tab 'revision')}}
{{document/view-revision document=document folder=folder pages=pages permissions=permissions onRollback=(action 'onRollback')}}
{{/if}}
{{#if (eq tab 'content')}} {{/layout/middle-zone-content}}
{{document/view-content
document=document links=links pages=pages blocks=blocks currentPageId=currentPageId {{#layout/middle-zone-sidebar}}
folder=folder folders=folders sections=sections permissions=permissions roles=roles {{document/document-toc
onSavePage=(action 'onSavePage') onInsertSection=(action 'onInsertSection') document=document
onSavePageAsBlock=(action 'onSavePageAsBlock') onDeleteBlock=(action 'onDeleteBlock') folder=folder
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onPageDeleted') pages=pages
refresh=(action 'refresh')}} page=page
{{/if}} permissions=permissions
{{#if (eq tab 'attachment')}} roles=roles
{{document/view-attachment document=document permissions=permissions}} tab=tab
{{/if}} currentPageId=currentPageId
{{#if (eq tab 'revision')}} onShowPage=(action 'onShowPage')
{{document/view-revision document=document folder=folder pages=pages permissions=permissions onRollback=(action 'onRollback')}} onPageSequenceChange=(action 'onPageSequenceChange')
{{/if}} onPageLevelChange=(action 'onPageLevelChange')}}
</div> {{/layout/middle-zone-sidebar}}
</div> {{/layout/middle-zone}}
</div>
{{#layout/bottom-bar}}
{{/layout/bottom-bar}}

View file

@ -1,20 +1,43 @@
footer { footer {
background-color: $color-off-white;
background-color: $color-primary-light; background-color: $color-primary-light;
color: $color-dark; color: $color-gray;
font-weight: 500; font-weight: 500;
font-size: 0.9rem; font-size: 1rem;
padding: 10px 2rem; padding: 5px 2rem;
} }
.footer { .footer {
display: flex;
overflow: hidden;
a, a:visited { a, a:visited {
@include ease-in(); @include ease-in();
color: $color-primary; color: $color-gray;
text-decoration: none; text-decoration: none;
&:hover { &:hover {
text-decoration: underline; text-decoration: underline;
} }
} }
> .progress {
display: inline-block;
> img {
padding: 0;
margin: 0;
height: 20px;
width: 20px;
}
}
> .progress-done {
background-color: $color-green;
color: $color-white;
text-align: center;
font-size: 1rem;
height: 20px;
width: 20px;
@include border-radius(20px);
}
} }

View file

@ -32,46 +32,82 @@ footer {
position: sticky; position: sticky;
} }
@media (min-width: 720px) { @media (min-width: 900px) {
.layout-body { .layout-body {
flex-direction: row; flex-direction: row;
} }
.layout-content { .layout-sidebar {
// Content area cannot exceed 1200px flex: 0 0 200px;
// but can shrink as required
// (was flex: 1;).
flex: 0 1 1000px;
// flex: 1;
padding: 0 2rem;
margin: 0;
} }
.layout-sidebar { .layout-content {
flex: 0 0 20rem; flex: 0 1 700px;
// height: calc(100vh - 145px); padding: 0 2rem;
// overflow-x: hidden; margin: 0;
// overflow-y: auto;
} }
} }
@media (min-width: 1200px) { @media (min-width: 1200px) {
.layout-body {
flex-direction: row;
}
.layout-sidebar { .layout-sidebar {
flex: 0 0 30rem; flex: 0 0 300px;
} }
.layout-content { .layout-content {
flex: 0 1 1000px;
margin: 0;
padding: 0 2rem 0 3rem;
}
}
@media (min-width: 1400px) {
.layout-body {
flex-direction: row;
}
.layout-sidebar {
flex: 0 0 400px;
}
.layout-content {
flex: 0 1 1000px;
margin: 0;
padding: 0 2rem 0 3rem;
}
}
@media (min-width: 1600px) {
.layout-body {
flex-direction: row;
}
.layout-sidebar {
flex: 0 0 450px;
}
.layout-content {
flex: 0 1 1200px;
margin: 0;
padding: 0 2rem 0 3rem; padding: 0 2rem 0 3rem;
} }
} }
@media (min-width: 1800px) { @media (min-width: 1800px) {
.layout-body {
flex-direction: row;
}
.layout-sidebar { .layout-sidebar {
flex: 0 0 35rem; flex: 0 0 500px;
} }
.layout-content { .layout-content {
flex: 0 1 1300px;
margin: 0;
padding: 0 2rem 0 4rem; padding: 0 2rem 0 4rem;
} }
} }

View file

@ -6,9 +6,6 @@
position: -o-sticky; position: -o-sticky;
position: -webkit-sticky; position: -webkit-sticky;
position: sticky; position: sticky;
display: flex;
z-index: 999;
width: 100%;
} }
@mixin border-radius($radius) @mixin border-radius($radius)

View file

@ -5,352 +5,357 @@
margin-bottom: 15px; 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 */
font-family: monospace; font-family: monospace;
height: 300px; height: 300px;
color: black; color: black;
direction: ltr; direction: ltr;
}
/* PADDING */
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
} }
}
/* See issue #2901 */ /* PADDING */
.cm-tab-wrap-hack:after { content: ''; }
.CodeMirror-lines {
padding: 4px 0; /* Vertical padding around content */
}
.CodeMirror pre {
padding: 0 4px; /* Horizontal padding of content */
}
.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
background-color: white; /* The little square between H and V scrollbars */
}
/* GUTTER */
.CodeMirror-gutters {
border-right: 1px solid #ddd;
background-color: #f7f7f7;
white-space: nowrap;
}
.CodeMirror-linenumbers {}
.CodeMirror-linenumber {
padding: 0 3px 0 5px;
min-width: 20px;
text-align: right;
color: #999;
white-space: nowrap;
}
.CodeMirror-guttermarker { color: black; }
.CodeMirror-guttermarker-subtle { color: #999; }
/* CURSOR */
.CodeMirror-cursor {
border-left: 1px solid black;
border-right: none;
width: 0;
}
/* Shown when moving in bi-directional text */
.CodeMirror div.CodeMirror-secondarycursor {
border-left: 1px solid silver;
}
.cm-fat-cursor .CodeMirror-cursor {
width: auto;
border: 0 !important;
background: #7e7;
}
.cm-fat-cursor div.CodeMirror-cursors {
z-index: 1;
}
.cm-fat-cursor-mark {
background-color: rgba(20, 255, 20, 0.5);
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
}
.cm-animate-fat-cursor {
width: auto;
border: 0;
-webkit-animation: blink 1.06s steps(1) infinite;
-moz-animation: blink 1.06s steps(1) infinite;
animation: blink 1.06s steps(1) infinite;
background-color: #7e7;
}
@-moz-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@-webkit-keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
@keyframes blink {
0% {}
50% { background-color: transparent; }
100% {}
}
/* Can style cursor different in overwrite (non-insert) mode */
.CodeMirror-overwrite .CodeMirror-cursor {}
.cm-tab { display: inline-block; text-decoration: inherit; }
.CodeMirror-rulers {
position: absolute;
left: 0; right: 0; top: -50px; bottom: -20px;
overflow: hidden;
}
.CodeMirror-ruler {
border-left: 1px solid #ccc;
top: 0; bottom: 0;
position: absolute;
}
/* DEFAULT THEME */
.cm-s-default .cm-header {color: blue;}
.cm-s-default .cm-quote {color: #090;}
.cm-negative {color: #d44;}
.cm-positive {color: #292;}
.cm-header, .cm-strong {font-weight: bold;}
.cm-em {font-style: italic;}
.cm-link {text-decoration: underline;}
.cm-strikethrough {text-decoration: line-through;}
.cm-s-default .cm-keyword {color: #708;}
.cm-s-default .cm-atom {color: #219;}
.cm-s-default .cm-number {color: #164;}
.cm-s-default .cm-def {color: #00f;}
.cm-s-default .cm-variable,
.cm-s-default .cm-punctuation,
.cm-s-default .cm-property,
.cm-s-default .cm-operator {}
.cm-s-default .cm-variable-2 {color: #05a;}
.cm-s-default .cm-variable-3, .cm-s-default .cm-type {color: #085;}
.cm-s-default .cm-comment {color: #a50;}
.cm-s-default .cm-string {color: #a11;}
.cm-s-default .cm-string-2 {color: #f50;}
.cm-s-default .cm-meta {color: #555;}
.cm-s-default .cm-qualifier {color: #555;}
.cm-s-default .cm-builtin {color: #30a;}
.cm-s-default .cm-bracket {color: #997;}
.cm-s-default .cm-tag {color: #170;}
.cm-s-default .cm-attribute {color: #00c;}
.cm-s-default .cm-hr {color: #999;}
.cm-s-default .cm-link {color: #00c;}
.cm-s-default .cm-error {color: #f00;}
.cm-invalidchar {color: #f00;}
.CodeMirror-composing { border-bottom: 2px solid; }
/* Default styles for common addons */
div.CodeMirror span.CodeMirror-matchingbracket {color: #0b0;}
div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #a22;}
.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
.CodeMirror-activeline-background {background: #e8f2ff;}
/* STOP */
/* The rest of this file contains styles related to the mechanics of
the editor. You probably shouldn't touch them. */
.CodeMirror {
position: relative;
overflow: hidden;
background: white;
}
.CodeMirror-scroll {
overflow: scroll !important; /* Things will break if this is overridden */
/* 30px is the magic margin used to hide the element's real scrollbars */
/* See overflow: hidden in .CodeMirror */
margin-bottom: -30px; margin-right: -30px;
padding-bottom: 30px;
height: 100%;
outline: none; /* Prevent dragging from highlighting the element */
position: relative;
}
.CodeMirror-sizer {
position: relative;
border-right: 30px solid transparent;
}
/* The fake, visible scrollbars. Used to force redraw during scrolling
before actual scrolling happens, thus preventing shaking and
flickering artifacts. */
.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
position: absolute;
z-index: 6;
display: none;
}
.CodeMirror-vscrollbar {
right: 0; top: 0;
overflow-x: hidden;
overflow-y: scroll;
}
.CodeMirror-hscrollbar {
bottom: 0; left: 0;
overflow-y: hidden;
overflow-x: scroll;
}
.CodeMirror-scrollbar-filler {
right: 0; bottom: 0;
}
.CodeMirror-gutter-filler {
left: 0; bottom: 0;
}
.CodeMirror-gutters {
position: absolute; left: 0; top: 0;
min-height: 100%;
z-index: 3;
}
.CodeMirror-gutter {
white-space: normal;
height: 100%;
display: inline-block;
vertical-align: top;
margin-bottom: -30px;
}
.CodeMirror-gutter-wrapper {
position: absolute;
z-index: 4;
background: none !important;
border: none !important;
}
.CodeMirror-gutter-background {
position: absolute;
top: 0; bottom: 0;
z-index: 4;
}
.CodeMirror-gutter-elt {
position: absolute;
cursor: default;
z-index: 4;
}
.CodeMirror-gutter-wrapper ::selection { background-color: transparent }
.CodeMirror-gutter-wrapper ::-moz-selection { background-color: transparent }
.CodeMirror-lines {
cursor: text;
min-height: 1px; /* prevents collapsing before first draw */
}
.CodeMirror pre {
/* Reset some styles that the rest of the page might have set */
-moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
border-width: 0;
background: transparent;
font-family: inherit;
font-size: inherit;
margin: 0;
white-space: pre;
word-wrap: normal;
line-height: inherit;
color: inherit;
z-index: 2;
position: relative;
overflow: visible;
-webkit-tap-highlight-color: transparent;
-webkit-font-variant-ligatures: contextual;
font-variant-ligatures: contextual;
}
.CodeMirror-wrap pre {
word-wrap: break-word;
white-space: pre-wrap;
word-break: normal;
}
.CodeMirror-linebackground {
position: absolute;
left: 0; right: 0; top: 0; bottom: 0;
z-index: 0;
}
.CodeMirror-linewidget {
position: relative;
z-index: 2;
overflow: auto;
}
.CodeMirror-widget {}
.CodeMirror-rtl pre { direction: rtl; }
.CodeMirror-code {
outline: none;
}
/* Force content-box sizing for the elements where we expect it */
.CodeMirror-scroll,
.CodeMirror-sizer,
.CodeMirror-gutter,
.CodeMirror-gutters,
.CodeMirror-linenumber {
-moz-box-sizing: content-box;
box-sizing: content-box;
}
.CodeMirror-measure {
position: absolute;
width: 100%;
height: 0;
overflow: hidden;
visibility: hidden;
}
.CodeMirror-cursor {
position: absolute;
pointer-events: none;
}
.CodeMirror-measure pre { position: static; }
div.CodeMirror-cursors {
visibility: hidden;
position: relative;
z-index: 3;
}
div.CodeMirror-dragcursors {
visibility: visible;
}
.CodeMirror-focused div.CodeMirror-cursors {
visibility: visible;
}
.CodeMirror-selected { background: #d9d9d9; }
.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
.CodeMirror-crosshair { cursor: crosshair; }
.CodeMirror-line::selection, .CodeMirror-line > span::selection, .CodeMirror-line > span > span::selection { background: #d7d4f0; }
.CodeMirror-line::-moz-selection, .CodeMirror-line > span::-moz-selection, .CodeMirror-line > span > span::-moz-selection { background: #d7d4f0; }
.cm-searching {
background-color: #ffa;
background-color: rgba(255, 255, 0, .4);
}
/* Used to force a border model for a node */
.cm-force-border { padding-right: .1px; }
@media print {
/* Hide the cursor when printing */
.CodeMirror div.CodeMirror-cursors {
visibility: hidden;
}
}
/* See issue #2901 */
.cm-tab-wrap-hack:after { content: ''; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
/* Help users use markselection to safely style text background */
span.CodeMirror-selectedtext { background: none; }
/* /*

View file

@ -2,6 +2,8 @@
margin-top: 6px; margin-top: 6px;
} }
.fr-element, .fr-element,
.fr-element:focus { .fr-element:focus {
outline: 0px solid transparent; outline: 0px solid transparent;

File diff suppressed because one or more lines are too long

View file

@ -7,7 +7,7 @@
> .start-button { > .start-button {
text-align: center; text-align: center;
margin: 60px 0; margin: 30px 0 20px 0;
position: relative; position: relative;
color: $color-gray-light; color: $color-gray-light;

View file

@ -20,6 +20,10 @@
> .document-customfields { > .document-customfields {
margin-bottom: 4rem; margin-bottom: 4rem;
background-color: $color-off-white;
border: 1px solid $color-border;
padding: 20px 40px;
@include border-radius(3px);
.row { .row {
padding: 5px 0; padding: 5px 0;
@ -33,8 +37,8 @@
.heading { .heading {
font-size: 1.1rem; font-size: 1.1rem;
font-weight: bold; font-weight: 700;
color: $color-off-black; color: $color-dark;
text-align: left; text-align: left;
} }

View file

@ -1,96 +1,72 @@
.document-toc { .document-sidebar {
@include border-radius(3px); background-color: $color-white;
@include ease-in(); margin: 20px 20px;
margin: 0;
padding: 0 20px 20px 20px;
background-color: $color-off-white;
border: 1px solid $color-border;
// overflow: scroll;
overflow-y: scroll;
overflow-x: hidden;
box-sizing: border-box; // ensures width/height properties (and min/max properties) includes content, padding and border
z-index: 777;
display: block;
position: relative; //
width: 100%; //
height: 500px;
transform: none; //
> .header { > .document-toc {
@include sticky(); @include border-radius(3px);
flex-direction: column; @include ease-in();
top: 0; @include sticky();
padding-top: 20px; margin: 0;
margin: 0; padding: 0 20px 20px 20px;
background-color: $color-off-white; display: block;
// height: calc(100vh - 180px);
> .title { > .header {
color: $color-gray; top: 0;
font-weight: bold; padding-top: 20px;
font-size: 1.1rem; margin: 0;
margin-bottom: 20px;
text-align: center;
}
> .toc-controls { > .toc-controls {
margin: 0 0 0 0; margin: 0 0 0 0;
text-align: center; text-align: center;
> .disabled { > .disabled {
cursor: not-allowed !important; cursor: not-allowed !important;
> .material-icons { > .material-icons {
color: $color-gray-light; color: $color-gray-light;
} }
} }
} }
} }
> .index-list { > .index-list {
padding: 0; padding: 0;
list-style: none; list-style: none;
font-size: 0.9rem; font-size: 0.9rem;
overflow-x: hidden; overflow-x: hidden;
list-style-type: none; list-style-type: none;
margin: 0 0 0 0; margin: 0 0 0 0;
.item { .item {
@extend .no-select; @extend .no-select;
padding: 4px 0; padding: 4px 0;
text-overflow: ellipsis; text-overflow: ellipsis;
word-wrap: break-word; word-wrap: break-word;
white-space: nowrap; white-space: nowrap;
overflow: hidden; overflow: hidden;
> .link { > .link {
color: $color-dark; color: $color-dark;
font-weight: bold; font-weight: bold;
&:hover { &:hover {
color: $color-link; color: $color-link;
} }
> .numbering { > .numbering {
color: $color-gray; color: $color-gray;
font-weight: bold; font-weight: bold;
display: inline-block; display: inline-block;
margin-right: 10px; margin-right: 10px;
} }
} }
> .selected { > .selected {
color: $color-link; color: $color-link;
} }
} }
} }
}
} }
.document-toc-desktop {
margin: 30px 0 30px 0;
display: inline-block;
position: fixed;
top: 150px;
right: 30px;
-webkit-transform: translate(0px, 0px);
transform: translate(0px, 0px);
}

View file

@ -42,6 +42,10 @@
vertical-align: text-top; vertical-align: text-top;
} }
} }
> .delete {
text-align: right;
}
} }
} }
} }

View file

@ -1,46 +1,47 @@
{{#unless emptyState}} {{#unless emptyState}}
<div id="doc-toc" class="document-toc {{if isDesktop 'document-toc-desktop'}}"> <div id="sidebar" class="document-sidebar">
<div class="header"> <div id="doc-toc" class="document-toc {{if isDesktop 'document-toc-desktop'}}">
<div class="title">Contents</div> <div class="header">
{{#if canEdit}} {{#if canEdit}}
<div id="tocToolbar" class="toc-controls {{if state.actionablePage 'current-page'}}"> <div id="tocToolbar" class="toc-controls {{if state.actionablePage 'current-page'}}">
<div id="toc-up-button" class="button-icon-green button-icon-small {{if state.upDisabled 'disabled'}}" {{action 'pageUp'}}> <div id="toc-up-button" class="button-icon-green button-icon-small {{if state.upDisabled 'disabled'}}" {{action 'pageUp'}}>
<i class="material-icons">arrow_upward</i> <i class="material-icons">arrow_upward</i>
</div> </div>
<div class="button-icon-gap" /> <div class="button-icon-gap" />
<div id="toc-down-button" class="button-icon-green button-icon-small {{if state.downDisabled 'disabled'}}" {{action 'pageDown'}}> <div id="toc-down-button" class="button-icon-green button-icon-small {{if state.downDisabled 'disabled'}}" {{action 'pageDown'}}>
<i class="material-icons">arrow_downward</i> <i class="material-icons">arrow_downward</i>
</div> </div>
<div class="button-icon-gap" /> <div class="button-icon-gap" />
<div id="toc-outdent-button" class="button-icon-green button-icon-small {{if state.outdentDisabled 'disabled'}}" {{action 'pageOutdent'}}> <div id="toc-outdent-button" class="button-icon-green button-icon-small {{if state.outdentDisabled 'disabled'}}" {{action 'pageOutdent'}}>
<i class="material-icons">arrow_back</i> <i class="material-icons">arrow_back</i>
</div> </div>
<div class="button-icon-gap" /> <div class="button-icon-gap" />
<div id="toc-indent-button" class="button-icon-green button-icon-small {{if state.indentDisabled 'disabled'}}" {{action 'pageIndent'}}> <div id="toc-indent-button" class="button-icon-green button-icon-small {{if state.indentDisabled 'disabled'}}" {{action 'pageIndent'}}>
<i class="material-icons">arrow_forward</i> <i class="material-icons">arrow_forward</i>
</div> </div>
</div> </div>
{{/if}} {{/if}}
</div> </div>
<ul class="index-list"> <ul class="index-list">
{{#each pages key="id" as |item index|}} {{#each pages key="id" as |item index|}}
<li class="item"> <li class="item">
<a id="index-{{item.page.id}}" {{action 'onGotoPage' item.page.id}} <a id="index-{{item.page.id}}" {{action 'onGotoPage' item.page.id}}
class="link toc-index-item {{item.page.tocIndentCss}} {{if (eq item.page.id state.pageId) 'selected'}}"> class="link toc-index-item {{item.page.tocIndentCss}} {{if (eq item.page.id state.pageId) 'selected'}}">
<span class="numbering">{{item.page.numbering}}</span> <span class="numbering">{{item.page.numbering}}</span>
{{#if (or item.userHasChangePending userHasNewPagePending)}} {{#if (or item.userHasChangePending userHasNewPagePending)}}
<span class="color-red" title="Pending approval" data-toggle="tooltip" data-placement="top">[*]&nbsp;</span> <span class="color-red" title="Pending approval" data-toggle="tooltip" data-placement="top">[*]&nbsp;</span>
{{/if}} {{/if}}
{{#if (or permissions.documentApprove roles.documentApprove)}} {{#if (or permissions.documentApprove roles.documentApprove)}}
{{#if item.changeAwaitingReview}} {{#if item.changeAwaitingReview}}
<span class="color-green" title="Awaiting approval" data-toggle="tooltip" data-placement="top">[*]&nbsp;</span> <span class="color-green" title="Awaiting approval" data-toggle="tooltip" data-placement="top">[*]&nbsp;</span>
{{/if}} {{/if}}
{{/if}} {{/if}}
{{item.page.title}} {{item.page.title}}
</a> </a>
</li> </li>
{{/each}} {{/each}}
</ul> </ul>
</div> </div>
</div>
{{/unless}} {{/unless}}

View file

@ -8,8 +8,10 @@
<span class="file">{{ a.filename }}</span> <span class="file">{{ a.filename }}</span>
</a> </a>
{{#if canEdit}} {{#if canEdit}}
<div class="button-icon-danger align-middle action" {{action 'onShowDialog' a.id a.filename}}> <div class="delete">
<i class="material-icons">delete</i> <div class="button-icon-danger align-middle action" {{action 'onShowDialog' a.id a.filename}}>
<i class="material-icons">delete</i>
</div>
</div> </div>
{{/if}} {{/if}}
</li> </li>

View file

@ -1,131 +1,115 @@
{{#if hasPages}} {{#if hasPages}} {{#each pages key="id" as |item index|}} {{#if canEdit}}
{{#each pages key="id" as |item index|}} <div class="start-section" data-index={{index}} data-before-id={{item.page.id}} id="add-section-button-{{item.page.id}}"
{{#if canEdit}} {{action 'onShowSectionWizard' item.page}}>
<div class="start-section" data-index={{index}} data-before-id={{item.page.id}} id="add-section-button-{{item.page.id}}" {{action 'onShowSectionWizard' item.page}}> <div class="start-button">
<div class="start-button"> <div class="cta">+ SECTION</div>
<div class="cta">+ SECTION</div> </div>
</div> </div>
</div> {{else}}
{{else}} <div class="section-divider" /> {{/if}} {{document/document-page document=document folder=folder page=item.page meta=item.meta pending=item.pending permissions=permissions
<div class="section-divider" /> toEdit=toEdit roles=roles blocks=blocks onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock') onCopyPage=(action
{{/if}} 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage') refresh=(action refresh)}} {{/each}}
{{document/document-page document=document folder=folder page=item.page meta=item.meta pending=item.pending
permissions=permissions toEdit=toEdit roles=roles blocks=blocks
onSavePage=(action 'onSavePage') onSavePageAsBlock=(action 'onSavePageAsBlock')
onCopyPage=(action 'onCopyPage') onMovePage=(action 'onMovePage') onDeletePage=(action 'onDeletePage') refresh=(action refresh)}}
{{/each}}
{{#if canEdit}}
<div class="start-section" data-index="0" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
<div class="start-button">
<div class="cta">+ SECTION</div>
</div>
</div>
{{/if}}
{{#if showLikes}}
<div class=" d-flex justify-content-center">
<div class="vote-box">
{{#unless voteThanks}}
<div class="prompt">
{{folder.likes}}
</div>
<div class="buttons">
<button type="button" class="btn btn-outline-success font-weight-bold" {{action 'onVote' 1}}>Yes, thanks!</button>&nbsp;&nbsp;
<button type="button" class="btn btn-outline-secondary font-weight-bold" {{action 'onVote' 2}}>Not really</button>
</div>
{{else}}
<div class="ack">Thanks for the feedback!</div>
{{/unless}}
</div>
</div>
{{/if}}
{{/if}}
{{#unless hasPages}}
{{#if canEdit}}
<div class="start-section" data-index="-1" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
<div class="start-button">
<div class="cta">+ SECTION</div>
</div>
</div>
{{/if}}
{{/unless}}
{{#if canEdit}} {{#if canEdit}}
<div id="wizard-placeholder" class="hide margin-top-50" /> <div class="start-section" data-index="0" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
<div id="new-section-wizard" class="new-section-wizard"> <div class="start-button">
<div class="container box"> <div class="cta">+ SECTION</div>
<div class="row clearfix"> </div>
<div class="col-12 clearfix"> </div>
<div class="float-right mb-5"> {{/if}} {{#if showLikes}}
<button type="button" class="btn btn-secondary" {{action 'onHideSectionWizard'}}>Close</button> <div class=" d-flex justify-content-center">
</div> <div class="vote-box">
{{#unless voteThanks}}
<div class="prompt">
{{folder.likes}}
</div>
<div class="buttons">
<button type="button" class="btn btn-outline-success font-weight-bold" {{action 'onVote' 1}}>Yes, thanks!</button>&nbsp;&nbsp;
<button type="button" class="btn btn-outline-secondary font-weight-bold" {{action 'onVote' 2}}>Not really</button>
</div>
{{else}}
<div class="ack">Thanks for the feedback!</div>
{{/unless}}
</div>
</div>
{{/if}} {{/if}} {{#unless hasPages}} {{#if canEdit}}
<div class="start-section" data-index="-1" data-before-id="0" id="add-section-button-0" {{action 'onShowSectionWizard'}}>
<div class="start-button">
<div class="cta">+ SECTION</div>
</div>
</div>
{{/if}} {{/unless}} {{#if canEdit}}
<div id="wizard-placeholder" class="hide margin-top-50" />
<div id="new-section-wizard" class="new-section-wizard">
<div class="container box">
<div class="row clearfix">
<div class="col-12 clearfix">
<div class="float-right mb-5">
<button type="button" class="btn btn-secondary" {{action 'onHideSectionWizard'}}>Close</button>
</div> </div>
</div> </div>
<div class="row"> </div>
<div class="col-12"> <div class="row">
<div class="form-group"> <div class="col-12">
{{input type="text" id="new-section-name" value=newSectionName class=(if newSectionNameMissing 'mousetrap form-control form-control-lg is-invalid' 'mousetrap form-control form-control-lg') placeholder="Enter section name" autocomplete="off"}} <div class="form-group">
</div> {{input type="text" id="new-section-name" value=newSectionName class=(if newSectionNameMissing 'mousetrap form-control form-control-lg
is-invalid' 'mousetrap form-control form-control-lg') placeholder="Enter section name" autocomplete="off"}}
</div> </div>
</div> </div>
</div>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
<div class="form-group"> <div class="form-group">
<div class="new-section-caption">Insert section type</div> <div class="new-section-caption">Insert section type</div>
<ul class="preset-list"> <ul class="preset-list">
{{#each sections as |section|}} {{#each sections as |section|}}
<li class="item" {{action 'onInsertSection' section}}> <li class="item" {{action 'onInsertSection' section}}>
<div class="icon"> <div class="icon">
<img class="img" src="/sections/{{section.contentType}}.png" srcset="/sections/{{section.contentType}}@2x.png" /> <img class="img" src="/sections/{{section.contentType}}.png" srcset="/sections/{{section.contentType}}@2x.png" />
</div> </div>
<div class='title'>{{section.title}}</div> <div class='title'>{{section.title}}</div>
</li> </li>
{{/each}} {{/each}}
</ul> </ul>
</div>
</div> </div>
</div> </div>
</div>
<div class="row"> <div class="row">
<div class="col-12"> <div class="col-12">
{{#if hasBlocks}} {{#if hasBlocks}}
<div class="new-section-caption">Insert re-usable content</div> <div class="new-section-caption">Insert re-usable content</div>
<ul class="block-list"> <ul class="block-list">
{{#each blocks as |block|}} {{#each blocks as |block|}}
<li class="item" title="{{block.firstname}} {{block.lastname}}, {{time-ago block.created}}, used: {{ block.used }}" data-toggle="tooltip" data-placement="top"> <li class="item" title="{{block.firstname}} {{block.lastname}}, {{time-ago block.created}}, used: {{ block.used }}" data-toggle="tooltip"
<div class="actions"> data-placement="top">
{{#if permissions.documentTemplate}} <div class="actions">
{{#link-to 'document.block' folder.id folder.slug document.id document.slug block.id class="button-icon-green button-icon-small align-middle"}} {{#if permissions.documentTemplate}} {{#link-to 'document.block' folder.id folder.slug document.id document.slug block.id
<i class="material-icons">edit</i> class="button-icon-gray button-icon-small align-middle"}}
{{/link-to}} <i class="material-icons">edit</i>
<div class="button-icon-gap" /> {{/link-to}}
<div id={{concat 'delete-block-button-' block.id}} class="button-icon-red button-icon-small align-middle" {{action 'onShowDeleteBlockModal' block.id}}> <div class="button-icon-gap" />
<i class="material-icons">delete</i> <div id={{concat 'delete-block-button-' block.id}} class="button-icon-danger button-icon-small align-middle" {{action
</div> 'onShowDeleteBlockModal' block.id}}>
{{/if}} <i class="material-icons">delete</i>
</div> </div>
<div class="details" {{action 'onInsertBlock' block}}> {{/if}}
<div class="title text-truncate">{{block.title}}</div> </div>
<div class="desc text-truncate">{{block.excerpt}}</div> <div class="details" {{action 'onInsertBlock' block}}>
</div> <div class="title text-truncate">{{block.title}}</div>
</li> <div class="desc text-truncate">{{block.excerpt}}</div>
{{/each}} </div>
</ul> </li>
{{else}} {{/each}}
<div class="template-caption">You have no reusable content &mdash; publish any section as a template</div> </ul>
{{/if}} {{else}}
</div> <div class="template-caption">You have no reusable content &mdash; publish any section as a template</div>
{{/if}}
</div> </div>
</div> </div>
</div> </div>
{{/if}} </div>
{{/if}} {{#if permissions.documentTemplate}} {{#ui/ui-dialog title="Delete Content Block" confirmCaption="Delete" buttonType="btn-danger"
{{#if permissions.documentTemplate}} show=showDeleteBlockDialog onAction=(action 'onDeleteBlock')}}
{{#ui/ui-dialog title="Delete Content Block" confirmCaption="Delete" buttonType="btn-danger" show=showDeleteBlockDialog onAction=(action 'onDeleteBlock')}} <p>Are you sure you want to delete this re-usable content block?</p>
<p>Are you sure you want to delete this re-usable content block?</p> {{/ui/ui-dialog}} {{/if}}
{{/ui/ui-dialog}}
{{/if}}

View file

@ -1,11 +1,19 @@
<div class="row no-gutters"> <div class="row no-gutters d-flex align-items-center">
<div class="col"> <div class="col d-flex justify-content-start">
<div class="d-flex justify-content-start"> <div class="footer">
{{yield}} {{#if showWait}}
<div class="progress progress-wait">
<img src="/assets/img/busy-gray.gif" />
</div>
{{/if}}
{{#if showDone}}
<div class="progress progress-done animated zoomIn">&check;</div>
{{/if}}
</div> </div>
{{yield}}
</div> </div>
<div class="col"> <div class="col d-flex justify-content-end">
<div class="footer d-flex justify-content-end"> <div class="footer">
<a href="https://documize.com?ref=af">Documize {{appMeta.version}}</a> <a href="https://documize.com?ref=af">Documize {{appMeta.version}}</a>
</div> </div>
</div> </div>

View file

@ -1,86 +1,76 @@
{{#toolbar/t-toolbar}} <div class="text-right">
{{#toolbar/t-links}}
{{#link-to "folder" space.id space.slug class="link selected" tagName="li"}}{{space.name}}{{/link-to}}
{{#if showDocumentLink}}
{{#link-to 'document.index' space.id space.slug document.id document.slug class="link"}}{{document.name}}{{/link-to}}
{{/if}}
{{/toolbar/t-links}}
{{#if showTools}} {{#if showTools}}
{{#toolbar/t-actions}} {{#if session.authenticated}}
{{#if session.authenticated}} {{#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> </div>
</div> <div class="button-icon-gap" />
<div class="button-icon-gap" />
<div id="document-template-modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">Save as Template</div>
<div class="modal-body">
<form onsubmit={{action 'onSaveTemplate'}}>
<div class="form-group">
<label for="new-template-name">Name</label>
{{input id="new-template-name" value=saveTemplate.name type='email' class="form-control mousetrap" placeholder="Template name"}}
<small class="form-text text-muted">Good template name conveys document type</small>
</div>
<div class="form-group">
<label for="new-template-desc">Description</label>
{{textarea id="new-template-desc" value=saveTemplate.description class="form-control" rows="5"}}
<small class="form-text text-muted">Explain use case for this template</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 'onSaveTemplate'}}>Save</button>
</div>
</div>
</div>
</div>
{{/if}}
{{/if}} {{/if}}
{{/if}}
<div id="document-print-button" class="button-icon-gray align-middle" data-toggle="tooltip" data-placement="top" title="Print" {{action 'onPrintDocument'}}> <div id="document-print-button" class="button-icon-gray align-middle" data-toggle="tooltip" data-placement="top" title="Print" {{action 'onPrintDocument'}}>
<i class="material-icons">print</i> <i class="material-icons">print</i>
</div>
<div class="button-icon-gap" />
{{#if pinState.isPinned}}
<div id="document-pin-button" class="button-icon-gold align-middle" data-toggle="tooltip" data-placement="top" title="Remove favorite" {{action 'onUnpin'}}>
<i class="material-icons">star</i>
</div> </div>
<div class="button-icon-gap" /> <div class="button-icon-gap" />
{{else if session.authenticated}}
<div id="document-pin-button" class="button-icon-gray align-middle" data-toggle="tooltip" data-placement="top" title="Save favorite" {{action 'onPin'}}>
<i class="material-icons">star</i>
</div>
<div class="button-icon-gap" />
{{/if}}
{{#if pinState.isPinned}} {{#if permissions.documentDelete}}
<div id="document-pin-button" class="button-icon-gold align-middle" data-toggle="tooltip" data-placement="top" title="Remove favorite" {{action 'onUnpin'}}> <div id="document-delete-button" class="button-icon-danger align-middle" data-toggle="tooltip" data-placement="top" title="Delete document">
<i class="material-icons">star</i> <i class="material-icons" data-toggle="modal" data-target="#document-delete-modal" data-backdrop="static">delete</i>
</div> </div>
<div class="button-icon-gap" /> {{/if}}
{{else if session.authenticated}}
<div id="document-pin-button" class="button-icon-gray align-middle" data-toggle="tooltip" data-placement="top" title="Save favorite" {{action 'onPin'}}>
<i class="material-icons">star</i>
</div>
<div class="button-icon-gap" />
{{/if}}
{{#if permissions.documentDelete}}
<div id="document-delete-button" class="button-icon-danger align-middle" data-toggle="tooltip" data-placement="top" title="Delete document">
<i class="material-icons" data-toggle="modal" data-target="#document-delete-modal" data-backdrop="static">delete</i>
</div>
<div class="button-icon-gap" />
<div id="document-delete-modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">Delete Document</div>
<div class="modal-body">
<p>Are you sure you want to delete this document?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger" onclick={{action 'onDocumentDelete'}}>Delete</button>
</div>
</div>
</div>
</div>
{{/if}}
{{/toolbar/t-actions}}
{{/if}} {{/if}}
</div>
{{/toolbar/t-toolbar}} <div id="document-template-modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">Save as Template</div>
<div class="modal-body">
<form onsubmit={{action 'onSaveTemplate'}}>
<div class="form-group">
<label for="new-template-name">Name</label>
{{input id="new-template-name" value=saveTemplate.name type='email' class="form-control mousetrap" placeholder="Template name"}}
<small class="form-text text-muted">Good template name conveys document type</small>
</div>
<div class="form-group">
<label for="new-template-desc">Description</label>
{{textarea id="new-template-desc" value=saveTemplate.description class="form-control" rows="5"}}
<small class="form-text text-muted">Explain use case for this template</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 'onSaveTemplate'}}>Save</button>
</div>
</div>
</div>
</div>
<div id="document-delete-modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">Delete Document</div>
<div class="modal-body">
<p>Are you sure you want to delete this document?</p>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-danger" onclick={{action 'onDocumentDelete'}}>Delete</button>
</div>
</div>
</div>
</div>