mirror of
https://github.com/documize/community.git
synced 2025-07-22 06:39:43 +02:00
Provide per section attachments
Upload and delete attachments on a per section basis.
This commit is contained in:
parent
166aeba09b
commit
61d0086337
13 changed files with 248 additions and 116 deletions
108
gui/app/components/document/section-attachment.js
Normal file
108
gui/app/components/document/section-attachment.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
// Copyright 2016 Documize Inc. <legal@documize.com>. All rights reserved.
|
||||
//
|
||||
// This software (Documize Community Edition) is licensed under
|
||||
// GNU AGPL v3 http://www.gnu.org/licenses/agpl-3.0.en.html
|
||||
//
|
||||
// You can operate outside the AGPL restrictions by purchasing
|
||||
// Documize Enterprise Edition and obtaining a commercial license
|
||||
// by contacting <sales@documize.com>.
|
||||
//
|
||||
// https://documize.com
|
||||
|
||||
import { inject as service } from '@ember/service';
|
||||
import { 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);
|
||||
}
|
||||
}
|
||||
});
|
|
@ -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'))) {
|
||||
|
|
|
@ -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 () {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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")}}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
folder=folder
|
||||
page=editPage
|
||||
meta=editMeta
|
||||
attachments=attachments
|
||||
onCancel=(action "onCancelEdit")
|
||||
onAction=(action "onSavePage")}}
|
||||
</div>
|
||||
|
@ -35,4 +36,9 @@
|
|||
{{section/base-renderer page=page}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{document/section-attachment uploadLabel="Upload Attachments"
|
||||
editMode=editMode page=page document=document files=attachments
|
||||
onAttachmentUpload=(action onAttachmentUpload)
|
||||
onAttachmentDelete=(action onAttachmentDelete)}}
|
||||
</div>
|
||||
|
|
39
gui/app/templates/components/document/section-attachment.hbs
Normal file
39
gui/app/templates/components/document/section-attachment.hbs
Normal file
|
@ -0,0 +1,39 @@
|
|||
{{#if editMode}}
|
||||
{{ui/ui-spacer size=200}}
|
||||
{{ui/ui-button color=constants.Color.Gray label=uploadLabel id=uploadId}}
|
||||
{{/if}}
|
||||
|
||||
<ul class="section-attachments">
|
||||
{{#each files key="id" as |file|}}
|
||||
{{#if (eq file.pageId page.id)}}
|
||||
<li class="file">
|
||||
<a href="{{appMeta.endpoint}}/public/attachment/{{appMeta.orgId}}/{{file.id}}{{downloadQuery}}">
|
||||
{{file.filename}}
|
||||
</a>
|
||||
{{#if editMode}}
|
||||
<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}}
|
||||
{{#attach-popover class="ember-attacher-popper" hideOn="escapekey, clickout" showOn="click" isShown=false}}
|
||||
<div class="form">
|
||||
<p>Are you sure you want to delete this file?</p>
|
||||
{{ui/ui-spacer size=100}}
|
||||
{{ui/ui-button
|
||||
light=false
|
||||
label=constants.Label.Delete
|
||||
color=constants.Color.Red
|
||||
onClick=(action "onDelete" file)}}
|
||||
</div>
|
||||
{{/attach-popover}}
|
||||
{{/ui/ui-toolbar-icon}}
|
||||
{{/ui/ui-toolbar}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
|
||||
{{#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 this attachment?</p>
|
||||
{{/ui/ui-dialog}}
|
|
@ -11,31 +11,32 @@
|
|||
<div class="document-sidebar-attachment">
|
||||
<ul class="files">
|
||||
{{#each files key="id" as |file|}}
|
||||
<li class="file">
|
||||
<a href="{{appMeta.endpoint}}/public/attachment/{{appMeta.orgId}}/{{file.id}}{{downloadQuery}}">
|
||||
{{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}}
|
||||
{{#attach-popover class="ember-attacher-popper" hideOn="escapekey, clickout" showOn="click" isShown=false}}
|
||||
<div class="form">
|
||||
<p>Are you sure you want to delete this file?</p>
|
||||
{{ui/ui-spacer size=100}}
|
||||
{{ui/ui-button
|
||||
light=false
|
||||
label=constants.Label.Delete
|
||||
color=constants.Color.Red
|
||||
onClick=(action "onDelete" file)}}
|
||||
</div>
|
||||
{{/attach-popover}}
|
||||
{{/ui/ui-toolbar-icon}}
|
||||
|
||||
{{/ui/ui-toolbar}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{#if (eq file.pageId '')}}
|
||||
<li class="file">
|
||||
<a href="{{appMeta.endpoint}}/public/attachment/{{appMeta.orgId}}/{{file.id}}{{downloadQuery}}">
|
||||
{{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}}
|
||||
{{#attach-popover class="ember-attacher-popper" hideOn="escapekey, clickout" showOn="click" isShown=false}}
|
||||
<div class="form">
|
||||
<p>Are you sure you want to delete this file?</p>
|
||||
{{ui/ui-spacer size=100}}
|
||||
{{ui/ui-button
|
||||
light=false
|
||||
label=constants.Label.Delete
|
||||
color=constants.Color.Red
|
||||
onClick=(action "onDelete" file)}}
|
||||
</div>
|
||||
{{/attach-popover}}
|
||||
{{/ui/ui-toolbar-icon}}
|
||||
{{/ui/ui-toolbar}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</li>
|
||||
{{/if}}
|
||||
{{/each}}
|
||||
</ul>
|
||||
</div>
|
||||
|
|
|
@ -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}}
|
||||
|
|
|
@ -41,12 +41,6 @@
|
|||
<div class="canvas">
|
||||
{{yield}}
|
||||
</div>
|
||||
|
||||
<div class="attachments">
|
||||
{{ui/ui-spacer size=100}}
|
||||
{{ui/ui-button color=constants.Color.Gray label="Upload" id=uploadId}}
|
||||
{{ui/ui-spacer size=100}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue