diff --git a/gui/app/components/document/section-attachment.js b/gui/app/components/document/section-attachment.js new file mode 100644 index 00000000..27132e2b --- /dev/null +++ b/gui/app/components/document/section-attachment.js @@ -0,0 +1,108 @@ +// Copyright 2016 Documize Inc. . 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 . +// +// https://documize.com + +import { inject as service } from '@ember/service'; +import { computed } from '@ember/object'; +import Modals from '../../mixins/modal'; +import Notifier from '../../mixins/notifier'; +import Component from '@ember/component'; + +export default Component.extend(Modals, Notifier, { + appMeta: service(), + session: service(), + editMode: false, + downloadQuery: '', + uploadId: computed('page', function () { + let page = this.get('page'); + return `page-uploader-${page.id}`; + }), + uploadLabel: 'Upload Attachments', + uploaderReady: false, + + didReceiveAttrs() { + this._super(...arguments); + + // For authenticated users we send server auth token. + let qry = ''; + if (this.get('session.hasSecureToken')) { + qry = '?secure=' + this.get('session.secureToken'); + } else if (this.get('session.authenticated')) { + qry = '?token=' + this.get('session.authToken'); + } + this.set('downloadQuery', qry); + }, + + didRender() { + this._super(...arguments); + + // We don't setup uploader if not edit mode. + if (!this.get('editMode') || this.get('uploaderReady')) { + return; + } + + let self = this; + let documentId = this.get('document.id'); + let pageId = this.get('page.id'); + let url = this.get('appMeta.endpoint'); + let uploadUrl = `${url}/documents/${documentId}/attachments?page=${pageId}`; + let uploadId = this.get('uploadId'); + + // Handle upload clicks on button and anything inside that button. + let sel = ['#' + uploadId, '#' + uploadId + ' > div']; + for (var i=0; i < 2; i++) { + let dzone = new Dropzone(sel[i], { + headers: { + 'Authorization': 'Bearer ' + self.get('session.authToken') + }, + url: uploadUrl, + method: "post", + paramName: 'attachment', + clickable: true, + maxFilesize: 250, + parallelUploads: 5, + uploadMultiple: false, + addRemoveLinks: false, + autoProcessQueue: true, + + init: function () { + this.on("success", function (/*file, response*/ ) { + }); + + this.on("queuecomplete", function () { + self.notifySuccess('Uploaded file'); + self.get('onAttachmentUpload')(); + }); + + this.on("addedfile", function ( /*file*/ ) { + }); + + this.on("error", function (error, msg) { + self.notifyError(msg); + self.notifyError(error); + }); + } + }); + + dzone.on("complete", function (file) { + dzone.removeFile(file); + }); + } + + this.set('uploaderReady', true); + }, + + actions: { + onDelete(attachment) { + this.notifySuccess('File deleted'); + this.get('onAttachmentDelete')(attachment.id); + } + } +}); diff --git a/gui/app/components/section/base-editor-inline.js b/gui/app/components/section/base-editor-inline.js index d23a99e2..e88ebb3a 100644 --- a/gui/app/components/section/base-editor-inline.js +++ b/gui/app/components/section/base-editor-inline.js @@ -10,7 +10,7 @@ // https://documize.com import $ from 'jquery'; -import { empty, notEmpty } from '@ember/object/computed'; +import { empty } from '@ember/object/computed'; import { computed } from '@ember/object'; import { inject as service } from '@ember/service'; import Modals from '../../mixins/modal'; @@ -26,17 +26,12 @@ export default Component.extend(Modals, Notifier, { showLinkModal: false, files: null, downloadQuery: '', - hasAttachments: notEmpty('files'), hasNameError: empty('page.title'), hasDescError: empty('page.excerpt'), pageId: computed('page', function () { let page = this.get('page'); return `page-editor-${page.id}`; }), - uploadId: computed('page', function () { - let page = this.get('page'); - return `page-uploader-${page.id}`; - }), previewText: 'Preview', pageTitle: '', @@ -70,67 +65,6 @@ export default Component.extend(Modals, Notifier, { }); }, - didInsertElement() { - this._super(...arguments); - - let self = this; - let documentId = this.get('document.id'); - let pageId = this.get('page.id'); - let url = this.get('appMeta.endpoint'); - let uploadUrl = `${url}/documents/${documentId}/attachments?page=${pageId}`; - let uploadId = this.get('uploadId'); - - // Handle upload clicks on button and anything inside that button. - let sel = ['#' + uploadId, '#' + uploadId + ' > div']; - for (var i=0; i < 2; i++) { - let dzone = new Dropzone(sel[i], { - headers: { - 'Authorization': 'Bearer ' + self.get('session.authToken') - }, - url: uploadUrl, - method: "post", - paramName: 'attachment', - clickable: true, - maxFilesize: 250, - parallelUploads: 5, - uploadMultiple: false, - addRemoveLinks: false, - autoProcessQueue: true, - - init: function () { - this.on("success", function (/*file, response*/ ) { - }); - - this.on("queuecomplete", function () { - self.notifySuccess('Uploaded file'); - self.getAttachments(); - }); - - this.on("addedfile", function ( /*file*/ ) { - }); - - this.on("error", function (error, msg) { - self.notifyError(msg); - self.notifyError(error); - }); - } - }); - - dzone.on("complete", function (file) { - dzone.removeFile(file); - }); - } - - // For authenticated users we send server auth token. - let qry = ''; - if (this.get('session.hasSecureToken')) { - qry = '?secure=' + this.get('session.secureToken'); - } else if (this.get('session.authenticated')) { - qry = '?token=' + this.get('session.authToken'); - } - this.set('downloadQuery', qry); - }, - willDestroyElement() { this._super(...arguments); this.set('showLinkModal', false); @@ -142,12 +76,6 @@ export default Component.extend(Modals, Notifier, { } }, - getAttachments() { - this.get('documentSvc').getAttachments(this.get('document.id')).then((files) => { - this.set('files', files); - }); - }, - actions: { onAction() { if (this.get('busy') || _.isEmpty(this.get('pageTitle'))) { diff --git a/gui/app/models/page.js b/gui/app/models/page.js index e015c5d9..9f9df8a4 100644 --- a/gui/app/models/page.js +++ b/gui/app/models/page.js @@ -36,7 +36,7 @@ export default Model.extend({ }), tocIndent: computed('level', function () { - return (this.get('level') - 1) * 20; + return (this.get('level') - 1) * 10; }), tocIndentCss: computed('tocIndent', function () { diff --git a/gui/app/pods/document/index/controller.js b/gui/app/pods/document/index/controller.js index 9214c8d2..525db9b9 100644 --- a/gui/app/pods/document/index/controller.js +++ b/gui/app/pods/document/index/controller.js @@ -222,6 +222,20 @@ export default Controller.extend(Notifier, { this.get('router').transitionTo('document.settings', {queryParams: {tab: 'general'}}); }, + onAttachmentUpload() { + this.get('documentService').getAttachments(this.get('document.id')).then((files) => { + this.set('attachments', files); + }); + }, + + onAttachmentDelete(attachmentId) { + this.get('documentService').deleteAttachment(this.get('document.id'), attachmentId).then(() => { + this.get('documentService').getAttachments(this.get('document.id')).then((files) => { + this.set('attachments', files); + }); + }); + }, + refresh(reloadPage) { return new EmberPromise((resolve) => { this.get('documentService').fetchDocumentData(this.get('document.id')).then((data) => { @@ -232,6 +246,7 @@ export default Controller.extend(Notifier, { this.set('roles', data.roles); this.set('links', data.links); this.set('versions', data.versions); + this.set('attachments', data.attachments); this.get('documentService').fetchPages(this.get('document.id'), this.get('session.user.id')).then((data) => { this.set('pages', data); diff --git a/gui/app/pods/document/index/template.hbs b/gui/app/pods/document/index/template.hbs index 19807877..c126e5b8 100644 --- a/gui/app/pods/document/index/template.hbs +++ b/gui/app/pods/document/index/template.hbs @@ -121,6 +121,7 @@ sections=sections document=document permissions=permissions + attachments=attachments currentPageId=currentPageId refresh=(action "refresh") onSavePage=(action "onSavePage") @@ -130,5 +131,7 @@ onInsertSection=(action "onInsertSection") onSavePageAsBlock=(action "onSavePageAsBlock") onPageLevelChange=(action "onPageLevelChange") - onPageSequenceChange=(action "onPageSequenceChange")}} + onPageSequenceChange=(action "onPageSequenceChange") + onAttachmentUpload=(action "onAttachmentUpload") + onAttachmentDelete=(action "onAttachmentDelete")}} {{/layout/master-content}} diff --git a/gui/app/styles/core/view/document/section-editor.scss b/gui/app/styles/core/view/document/section-editor.scss index c3915a4a..cb09e3c8 100644 --- a/gui/app/styles/core/view/document/section-editor.scss +++ b/gui/app/styles/core/view/document/section-editor.scss @@ -4,10 +4,6 @@ box-shadow: 0 0 0 0.75pt map-get($gray-shades, 200),0 0 3pt 0.75pt map-get($gray-shades, 200); border: 1px solid map-get($gray-shades, 200); } - - > .attachments { - - } } .content-linker-modal-container { diff --git a/gui/app/styles/core/view/document/sidebar-attachment.scss b/gui/app/styles/core/view/document/sidebar-attachment.scss index 5c813f2b..bb931a5f 100644 --- a/gui/app/styles/core/view/document/sidebar-attachment.scss +++ b/gui/app/styles/core/view/document/sidebar-attachment.scss @@ -4,10 +4,6 @@ } } -.dz-preview, .dz-processing { - display: none !important; -} - .document-sidebar-attachment { > .files { margin: 0; @@ -44,3 +40,40 @@ } } } + +.dz-preview, .dz-processing { + display: none !important; +} +.section-attachments { + margin: 1.5rem 0 0 0; + padding: 0; + + > .file { + list-style-type: none; + margin: 0; + padding: 0; + width: 100%; + font-size: 1rem; + position: relative; + + > a { + display: inline-block; + font-size: 1rem; + vertical-align: text-top; + margin-right: 10px; + width: 90%; + @extend .text-truncate; + color: map-get($green-shades, 800); + + &:hover { + color: map-get($green-shades, 900); + } + } + + > .menu { + position: absolute; + right: -10px; + top: 0; + } + } +} diff --git a/gui/app/templates/components/document/document-editor.hbs b/gui/app/templates/components/document/document-editor.hbs index 818731ad..98d4d5d6 100644 --- a/gui/app/templates/components/document/document-editor.hbs +++ b/gui/app/templates/components/document/document-editor.hbs @@ -1 +1,7 @@ -{{component editorType document=document folder=folder page=page meta=meta onCancel=(action "onCancel") onAction=(action "onAction")}} +{{component editorType + document=document + folder=folder + page=page + meta=meta + attachments=attachments + onCancel=(action "onCancel") onAction=(action "onAction")}} diff --git a/gui/app/templates/components/document/document-page.hbs b/gui/app/templates/components/document/document-page.hbs index 84e5bd63..5c7db2af 100644 --- a/gui/app/templates/components/document/document-page.hbs +++ b/gui/app/templates/components/document/document-page.hbs @@ -6,6 +6,7 @@ folder=folder page=editPage meta=editMeta + attachments=attachments onCancel=(action "onCancelEdit") onAction=(action "onSavePage")}} @@ -35,4 +36,9 @@ {{section/base-renderer page=page}} {{/if}} + + {{document/section-attachment uploadLabel="Upload Attachments" + editMode=editMode page=page document=document files=attachments + onAttachmentUpload=(action onAttachmentUpload) + onAttachmentDelete=(action onAttachmentDelete)}} diff --git a/gui/app/templates/components/document/section-attachment.hbs b/gui/app/templates/components/document/section-attachment.hbs new file mode 100644 index 00000000..1331134f --- /dev/null +++ b/gui/app/templates/components/document/section-attachment.hbs @@ -0,0 +1,39 @@ +{{#if editMode}} + {{ui/ui-spacer size=200}} + {{ui/ui-button color=constants.Color.Gray label=uploadLabel id=uploadId}} +{{/if}} + + + +{{#ui/ui-dialog title="Delete Attachment" confirmCaption="Delete" buttonColor=constants.Color.Red show=showDialog onAction=(action "onDelete")}} +

Are you sure you want to delete this attachment?

+{{/ui/ui-dialog}} diff --git a/gui/app/templates/components/document/sidebar-attachment.hbs b/gui/app/templates/components/document/sidebar-attachment.hbs index 1b7fd155..c5e18f5f 100644 --- a/gui/app/templates/components/document/sidebar-attachment.hbs +++ b/gui/app/templates/components/document/sidebar-attachment.hbs @@ -11,31 +11,32 @@
    {{#each files key="id" as |file|}} -
  • - - {{file.filename}} - - {{#if canEdit}} - - {{/if}} -
  • + {{#if (eq file.pageId '')}} +
  • + + {{file.filename}} + + {{#if canEdit}} + + {{/if}} +
  • + {{/if}} {{/each}}
diff --git a/gui/app/templates/components/document/view-content.hbs b/gui/app/templates/components/document/view-content.hbs index 8bdb1a5f..f4f5bf99 100644 --- a/gui/app/templates/components/document/view-content.hbs +++ b/gui/app/templates/components/document/view-content.hbs @@ -12,13 +12,16 @@ document=document pending=item.pending permissions=permissions + attachments=attachments refresh=(action refresh) + onAttachmentUpload=(action onAttachmentUpload) + onAttachmentDelete=(action onAttachmentDelete) onSavePage=(action "onSavePage") onCopyPage=(action "onCopyPage") onMovePage=(action "onMovePage") onDeletePage=(action "onDeletePage") onSavePageAsBlock=(action "onSavePageAsBlock") - onPageLevelChange=(action onPageLevelChange) + onPageLevelChange=(action onPageLevelChange) onPageSequenceChange=(action onPageSequenceChange) onShowSectionWizard=(action "onShowSectionWizard")}} {{/each}} diff --git a/gui/app/templates/components/section/base-editor-inline.hbs b/gui/app/templates/components/section/base-editor-inline.hbs index 5cac5bcb..1a12de52 100644 --- a/gui/app/templates/components/section/base-editor-inline.hbs +++ b/gui/app/templates/components/section/base-editor-inline.hbs @@ -41,12 +41,6 @@
{{yield}}
- -
- {{ui/ui-spacer size=100}} - {{ui/ui-button color=constants.Color.Gray label="Upload" id=uploadId}} - {{ui/ui-spacer size=100}} -