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

Revamp document view using new layout

New master page system and UI framework implemented on document view.

Sidebar contains ToC and Attachments.
This commit is contained in:
Harvey Kandola 2018-12-18 19:03:34 +00:00
parent b4b3dbcb4c
commit 7cdf97aa86
27 changed files with 348 additions and 263 deletions

View file

@ -18,6 +18,7 @@ import Component from '@ember/component';
export default Component.extend(Modals, Notifier, {
documentService: service('document'),
browserSvc: service('browser'),
appMeta: service(),
hasAttachments: notEmpty('files'),
canEdit: computed('permissions.documentEdit', 'document.protection', function() {
@ -114,6 +115,15 @@ export default Component.extend(Modals, Notifier, {
});
return true;
},
onExport() {
this.get('documentSvc').export({}).then((htmlExport) => {
this.get('browserSvc').downloadFile(htmlExport, this.get('space.slug') + '.html');
this.notifySuccess('Exported');
});
this.modalClose("#space-export-modal");
}
}
});

View file

@ -16,6 +16,7 @@ import tocUtil from '../../utils/toc';
import Component from '@ember/component';
export default Component.extend({
classNames: ["section"],
documentService: service('document'),
emptyState: computed('pages', function () {
return this.get('pages.length') === 0;

View file

@ -11,7 +11,6 @@
import { A } from '@ember/array';
import { inject as service } from '@ember/service';
import { schedule } from '@ember/runloop';
import { computed } from '@ember/object';
import { empty } from '@ember/object/computed';
import AuthMixin from '../../mixins/auth';

View file

@ -16,7 +16,6 @@ export default Component.extend({
tagName: 'div',
classNames: [],
classNameBindings: ['calcClass'],
where: 'right',
calcClass: computed(function() {
return `dmz-button-gap-${this.where}`;

View file

@ -62,8 +62,8 @@ export default Component.extend({
}),
click(e) {
e.preventDefault();
if (is.not.undefined(this.onClick)) {
e.preventDefault();
this.onClick(e);
}
}

View file

@ -18,17 +18,19 @@ export default Component.extend({
tagName: 'i',
classNames: ['dicon'],
classNameBindings: ['calcClass'],
color: '',
icon: '',
tooltip: '',
selected: false,
calcClass: computed(function() {
calcClass: computed('selected', function() {
let c = '';
let icon = this.icon;
if (this.color !== '') c += this.color + ' ';
if (this.selected === true) c += 'icon-selected' + ' ';
if (icon !== '') c += icon + ' ';
return c.trim();

View file

@ -18,7 +18,6 @@ export default Component.extend({
tagName: 'div',
classNames: ['label'],
classNameBindings: ['calcClass'],
color: '',
label: '',
tooltip: '',

View file

@ -260,6 +260,7 @@ let constants = EmberObject.extend({
Close: 'Close',
Delete: 'Delete',
Export: 'Export',
File: 'File',
Insert: 'Insert',
Invite: 'Invite',
Join: 'Join',
@ -272,6 +273,7 @@ let constants = EmberObject.extend({
Search: 'Search',
SignIn: 'Sign In',
Update: 'Update',
Upload: 'Upload'
}
});

View file

@ -21,6 +21,7 @@ export default Controller.extend(Notifier, {
sectionService: service('section'),
linkService: service('link'),
router: service(),
sidebarTab: 'toc',
tab: 'content',
queryParams: ['currentPageId', 'source'],
showRevisions: computed('permissions', 'document.protection', function() {
@ -32,6 +33,10 @@ export default Controller.extend(Notifier, {
}),
actions: {
onSidebarChange(tab) {
this.set('sidebarTab', tab);
},
onTabChange(tab) {
this.set('tab', tab);
if (tab === 'content') {

View file

@ -1,20 +1,62 @@
{{#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}}
{{#layout/master-sidebar}}
{{ui/ui-spacer size=300}}
{{#layout/middle-zone}}
<div class="section">
<div class="title">status</div>
{{#layout/middle-zone-content}}
<div class="{{if (eq document.lifecycle constants.Lifecycle.Draft) "label-draft"}}
{{if (eq document.lifecycle constants.Lifecycle.Live) "label-live"}}
{{if (eq document.lifecycle constants.Lifecycle.Archived) "label-archived"}}">
{{document.lifecycleLabel}}
{{#attach-tooltip showDelay=1000}}Lifecycle: Draft &middot; Live &middot; Archived{{/attach-tooltip}}
</div>
<div class="label-approval">
{{#if (eq document.protection constants.ProtectionType.None)}}OPEN{{/if}}
{{#if (eq document.protection constants.ProtectionType.Review)}}PROTECTED{{/if}}
{{#if (eq document.protection constants.ProtectionType.Lock)}}LOCKED{{/if}}
{{#attach-tooltip showDelay=1000}}Change Control: Open &middot; Protected &middot; Locked{{/attach-tooltip}}
</div>
{{ui/ui-spacer size=200}}
<div class="text-center">
{{#ui/ui-toolbar dark=true light=true raised=true large=false bordered=true}}
{{ui/ui-toolbar-icon icon=constants.Icon.Index color=constants.Color.Gray tooltip="Table of contents"
selected=(eq sidebarTab "toc") onClick=(action "onSidebarChange" "toc")}}
{{ui/ui-toolbar-icon icon=constants.Icon.Attachment color=constants.Color.Gray tooltip="Attachments"
selected=(eq sidebarTab "files") onClick=(action "onSidebarChange" "files")}}
{{/ui/ui-toolbar}}
</div>
</div>
{{ui/ui-spacer size=200}}
{{#if (eq sidebarTab "toc")}}
{{document/sidebar-toc
tab=tab
page=page
roles=roles
pages=pages
folder=folder
document=document
permissions=permissions
currentPageId=currentPageId
onShowPage=(action "onShowPage")
onPageLevelChange=(action "onPageLevelChange")
onPageSequenceChange=(action "onPageSequenceChange")}}
{{/if}}
{{#if (eq sidebarTab "files")}}
{{document/sidebar-attachment
document=document
permissions=permissions}}
{{/if}}
{{/layout/master-sidebar}}
{{#layout/master-content}}
<div class="grid-container-6-4">
<div class="grid-cell-1">
</div>
<div class="grid-cell-2 grid-cell-right">
{{toolbar/for-document
tab=tab
roles=roles
@ -27,6 +69,10 @@
onSaveTemplate=(action "onSaveTemplate")
onSaveDocument=(action "onSaveDocument")
onDocumentDelete=(action "onDocumentDelete")}}
</div>
</div>
{{ui/ui-spacer size=400}}
<div class="text-center non-printable document-tabnav">
<ul class="tabnav-control">
@ -94,26 +140,5 @@
{{/if}}
{{/if}}
{{/layout/middle-zone-content}}
{{/layout/master-content}}
{{#layout/middle-zone-sidebar}}
{{document/document-toc
tab=tab
page=page
roles=roles
pages=pages
folder=folder
document=document
permissions=permissions
currentPageId=currentPageId
onShowPage=(action "onShowPage")
onPageLevelChange=(action "onPageLevelChange")
onPageSequenceChange=(action "onPageSequenceChange")}}
{{/layout/middle-zone-sidebar}}
{{/layout/middle-zone}}
{{#layout/bottom-bar}}
{{/layout/bottom-bar}}

View file

@ -43,7 +43,7 @@
@import "widget/widget.scss";
@import "ui/all.scss";
@import "view/toolbar.scss";
@import "view/views.scss";
@import "view/all.scss";
@import "vendor/all.scss";
@import "print.scss";

View file

@ -17,7 +17,7 @@
display: block;
height: auto;
width: 100%;
// z-index: 1041; // reequired if we want to show modals from inside sidebar
z-index: 1041; // reequired if we want to show modals from inside sidebar
.master-navbar {
display: block;

View file

@ -13,6 +13,10 @@
color: map-get($gray-shades, 700);
}
> .center {
text-align: center;
}
> .text {
margin: 10px 0;
font-size: 1rem;
@ -21,14 +25,15 @@
}
> .label {
@include border-radius(3px);
@extend .no-select;
display: inline-block;
margin: 10px 0 13px 0;
padding: 0.3rem 0.7rem;
font-size: 1.1rem;
font-weight: 500;
font-weight: 400;
background-color: map-get($gray-shades, 600);
color: map-get($gray-shades, 100);
@include border-radius(3px);
}
> .list {

View file

@ -28,6 +28,10 @@
}
}
> .icon-selected {
color: map-get($yellow-shades, 600);
}
> .label {
font-size: 14px;
font-weight: 500;

View file

@ -105,3 +105,9 @@ a.broken-link {
.text-center {
text-align: center;
}
@media print {
.no-print {
display: none !important;
}
}

View file

@ -6,4 +6,4 @@
@import "customize.scss";
@import "search.scss";
@import "auth.scss";
@import "document/document.scss"
@import "document/all.scss"

View file

@ -2,9 +2,10 @@
@import "copy-move.scss";
@import "doc-meta.scss";
@import "doc-structure.scss";
@import "doc-toc.scss";
@import "section-editor.scss";
@import "view-attachment.scss";
@import "sidebar.scss";
@import "sidebar-toc.scss";
@import "sidebar-attachment.scss";
@import "view-activity.scss";
@import "view-revision.scss";
@import "vote-likes.scss";

View file

@ -1,67 +0,0 @@
.document-sidebar {
> .document-toc {
@include border-radius(3px);
@include ease-in();
margin: 0;
padding: 0 20px 20px 20px;
display: block;
> .header {
top: 0;
padding-top: 20px;
margin: 0;
> .toc-controls {
margin: 0 0 0 0;
text-align: center;
> .disabled {
cursor: not-allowed !important;
> .material-icons {
color: map-get($gray-shades, 300);
}
}
}
}
> .index-list {
padding: 0;
list-style: none;
font-size: 0.9rem;
overflow-x: hidden;
list-style-type: none;
margin: 0 0 0 0;
.item {
@extend .no-select;
padding: 4px 0;
text-overflow: ellipsis;
word-wrap: break-word;
white-space: nowrap;
overflow: hidden;
> .link {
color: map-get($gray-shades, 800);
font-weight: bold;
&:hover {
color: $color-link;
}
> .numbering {
color: map-get($gray-shades, 600);
font-weight: bold;
display: inline-block;
margin-right: 10px;
}
}
> .selected {
color: $color-link;
}
}
}
}
}

View file

@ -0,0 +1,40 @@
.document-sidebar-attachment {
.dz-preview, .dz-processing {
display: none !important;
}
> .files {
margin: 0;
padding: 0;
> .file {
@include card();
list-style-type: none;
margin: 10px 0 0 0;
padding: 5px;
width: 100%;
font-size: 0.9rem;
position: relative;
> a {
display: inline-block;
font-size: 0.9rem;
vertical-align: text-top;
margin-right: 10px;
width: 90%;
@extend .text-truncate;
color: map-get($gray-shades, 800);
&:hover {
color: map-get($gray-shades, 900);
}
}
> .menu {
position: absolute;
right: -10px;
top: 0;
}
}
}
}

View file

@ -0,0 +1,63 @@
.document-sidebar-toc {
> .controls {
margin: 5px 0 10px 0;
text-align: center;
> .arrow {
margin: 0 5px;
display: inline-block;
> i {
font-size: 2rem;
color: map-get($yellow-shades, 600);
}
}
> .disabled {
cursor: not-allowed !important;
> i {
color: map-get($gray-shades, 400);
}
}
}
> .index-list {
padding: 0;
list-style: none;
font-size: 0.9rem;
overflow-x: hidden;
list-style-type: none;
margin: 0 0 0 0;
.item {
@extend .no-select;
padding: 4px 0;
text-overflow: ellipsis;
word-wrap: break-word;
white-space: nowrap;
overflow: hidden;
> .link {
color: map-get($gray-shades, 800);
font-weight: 400;
&:hover {
color: map-get($yellow-shades, 600);
}
> .numbering {
color: map-get($gray-shades, 600);
font-weight: 500;
display: inline-block;
margin-right: 10px;
}
}
> .selected {
color: map-get($yellow-shades, 600);
font-weight: 600;
}
}
}
}

View file

@ -0,0 +1,52 @@
.label-approval {
@include border-radius(3px);
@extend .no-select;
display: inline-block;
margin: 10px 5px 13px 0;
padding: 0.3rem 0.7rem;
font-size: 1.1rem;
font-weight: 400;
background-color: map-get($gray-shades, 700);
color: map-get($gray-shades, 100);
text-transform: uppercase;
}
.label-draft {
@include border-radius(3px);
@extend .no-select;
display: inline-block;
margin: 10px 5px 13px 0;
padding: 0.3rem 0.7rem;
font-size: 1.1rem;
font-weight: 400;
background-color: map-get($yellow-shades, 500);
color: map-get($gray-shades, 100);
text-transform: uppercase;
}
.label-live {
@include border-radius(3px);
@extend .no-select;
display: inline-block;
margin: 10px 5px 13px 0;
padding: 0.3rem 0.7rem;
font-size: 1.1rem;
font-weight: 400;
background-color: map-get($green-shades, 500);
color: map-get($gray-shades, 100);
text-transform: uppercase;
}
.label-archived {
@include border-radius(3px);
@extend .no-select;
display: inline-block;
margin: 10px 5px 13px 0;
padding: 0.3rem 0.7rem;
font-size: 1.1rem;
font-weight: 400;
background-color: map-get($red-shades, 300);
color: map-get($gray-shades, 800);
text-transform: uppercase;
}

View file

@ -1,49 +0,0 @@
.view-attachment {
> .upload-document-files {
@include ease-in();
margin: 50px 0 10px 0;
> .dz-preview, .dz-processing {
display: none !important;
}
}
> .list {
margin: 10px 0 0 0;
padding: 0;
> .item {
margin: 0;
padding: 0;
font-size: 1.1rem;
list-style-type: none;
border-left: 6px solid map-get($gray-shades, 300);
padding-left: 15px;
margin-left: 3px;
> a {
@include ease-in();
display: inline-block;
font-size: 1.1rem;
vertical-align: text-top;
margin-right: 10px;
color: map-get($gray-shades, 600);
&:hover {
color: $color-link;
}
}
> .delete {
display: inline-block;
visibility: hidden;
}
&:hover {
> .delete {
visibility: visible;
}
}
}
}
}

View file

@ -36,9 +36,3 @@
{{concat "#" t}}
</div>
{{/each}}
<div class="document-meta">
{{document/view-attachment document=document permissions=permissions}}
</div>
<div class="margin-top-70" />

View file

@ -1,53 +0,0 @@
<div id="sidebar" class="sidebar-white document-sidebar">
<div class="sidebar-view-switcher d-flex align-items-center justify-content-center">
<i class="material-icons">reorder</i>
</div>
<div id="doc-toc" class="document-toc">
<div class="header">
{{#if canEdit}}
<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"}}>
<i class="material-icons">arrow_upward</i>
</div>
<div class="button-icon-gap" />
<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>
</div>
<div class="button-icon-gap" />
<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>
</div>
<div class="button-icon-gap" />
<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>
</div>
</div>
{{/if}}
</div>
<ul class="index-list">
{{#each pages key="id" as |item|}}
<li class="item">
<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"}}"
title={{item.page.title}}>
<span class="numbering">{{item.page.numbering}}</span>
{{#if (or item.userHasChangePending userHasNewPagePending)}}
<span class="color-red-600" >[*]&nbsp;</span>
{{#attach-tooltip showDelay=1000}}Pending changes{{/attach-tooltip}}
{{/if}}
{{#if (or permissions.documentApprove roles.documentApprove)}}
{{#if item.changeAwaitingReview}}
<span class="color-green-700">[*]&nbsp;</span>
{{#attach-tooltip showDelay=1000}}Awaiting approval{{/attach-tooltip}}
{{/if}}
{{/if}}
{{item.page.title}}
</a>
</li>
{{/each}}
</ul>
</div>
</div>

View file

@ -0,0 +1,34 @@
{{#if canEdit}}
<div class="text-center">
{{#ui/ui-toolbar dark=true raised=true large=false bordered=true}}
{{ui/ui-toolbar-label color=constants.Color.Gray label="Upload Files" id="upload-document-files"}}
{{/ui/ui-toolbar}}
{{ui/ui-spacer size=100}}
</div>
{{/if}}
{{#if hasAttachments}}
<div class="document-sidebar-attachment">
<ul class="files">
{{#each files key="id" as |file|}}
<li class="file">
<a href="{{appMeta.endpoint}}/public/attachments/{{appMeta.orgId}}/{{file.id}}">
{{file.filename}}
</a>
{{#if canEdit}}
<div class="menu">
{{#ui/ui-toolbar dark=false light=false raised=false large=false bordered=false}}
{{ui/ui-toolbar-icon icon=constants.Icon.Delete color=constants.Color.Red
onClick=(action "onShowDialog" file.id file.filename)}}
{{/ui/ui-toolbar}}
</div>
{{/if}}
</li>
{{/each}}
</ul>
</div>
{{/if}}
{{#ui/ui-dialog title="Delete Attachment" confirmCaption="Delete" buttonColor=constants.Color.Red show=showDialog onAction=(action "onDelete")}}
<p>Are you sure you want to delete {{deleteAttachment.name}}?</p>
{{/ui/ui-dialog}}

View file

@ -0,0 +1,44 @@
<div class="title center">table of contents</div>
{{#if canEdit}}
<div class="document-sidebar-toc">
<div class="controls {{if state.actionablePage "current-page"}}">
<div id="toc-up-button" class="arrow {{if state.upDisabled "disabled"}}" {{action "pageUp"}}>
<i class="dicon {{constants.Icon.ArrowSmallUp}}" />
</div>
<div id="toc-down-button" class="arrow {{if state.downDisabled "disabled"}}" {{action "pageDown"}}>
<i class="dicon {{constants.Icon.ArrowSmallDown}}" />
</div>
<div id="toc-outdent-button" class="arrow {{if state.outdentDisabled "disabled"}}" {{action "pageOutdent"}}>
<i class="dicon {{constants.Icon.ArrowSmallLeft}}" />
</div>
<div id="toc-indent-button" class="arrow {{if state.indentDisabled "disabled"}}" {{action "pageIndent"}}>
<i class="dicon {{constants.Icon.ArrowSmallRight}}" />
</div>
</div>
</div>
{{/if}}
<div class="document-sidebar-toc">
<ul class="index-list">
{{#each pages key="id" as |item|}}
<li class="item">
<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"}}"
title={{item.page.title}}>
<span class="numbering">{{item.page.numbering}}</span>
{{#if (or item.userHasChangePending userHasNewPagePending)}}
<span class="color-red-600" >[*]&nbsp;</span>
{{#attach-tooltip showDelay=1000}}Pending changes{{/attach-tooltip}}
{{/if}}
{{#if (or permissions.documentApprove roles.documentApprove)}}
{{#if item.changeAwaitingReview}}
<span class="color-green-700">[*]&nbsp;</span>
{{#attach-tooltip showDelay=1000}}Awaiting approval{{/attach-tooltip}}
{{/if}}
{{/if}}
{{item.page.title}}
</a>
</li>
{{/each}}
</ul>
</div>

View file

@ -1,31 +0,0 @@
<div class="view-attachment d-print-none">
{{#if canEdit}}
<div class="upload-document-files">
<div id="upload-document-files" class="btn btn-secondary text-uppercase bold-700">+ Attachments</div>
</div>
{{else}}
<div class="margin-top-50" />
{{/if}}
{{#if hasAttachments}}
<ul class="list">
{{#each files key="id" as |file|}}
<li class="item">
<a href="{{appMeta.endpoint}}/public/attachments/{{appMeta.orgId}}/{{file.id}}">
{{file.filename}}
</a>
{{#if canEdit}}
<div class="delete">
<div class="button-icon-danger button-icon-small align-middle" {{action "onShowDialog" file.id file.filename}}>
<i class="material-icons">delete</i>
</div>
</div>
{{/if}}
</li>
{{/each}}
</ul>
{{/if}}
</div>
{{#ui/ui-dialog title="Delete Attachment" confirmCaption="Delete" buttonColor=constants.Color.Red show=showDialog onAction=(action "onDelete")}}
<p>Are you sure you want to delete {{deleteAttachment.name}}?</p>
{{/ui/ui-dialog}}