1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-19 13:19:43 +02:00

[WIP] moved start-document functionality, reworked folder view

WIP -- import files still BROKEN
This commit is contained in:
Harvey Kandola 2017-09-25 19:14:33 +01:00
parent 8f80673cde
commit a0a1dd396a
20 changed files with 2820 additions and 2039 deletions

View file

@ -14,43 +14,13 @@ import Ember from 'ember';
export default Ember.Component.extend({
folderService: Ember.inject.service('folder'),
moveTarget: null,
emptyState: Ember.computed('documents', function() {
return this.get('documents.length') === 0;
}),
didReceiveAttrs() {
this._super(...arguments);
this.set('canCreate', this.get('permissions.documentAdd'));
this.set('deleteTargets', this.get('folders').rejectBy('id', this.get('folder.id')));
},
didUpdateAttrs() {
this._super(...arguments);
this.setupAddWizard();
},
didInsertElement() {
this._super(...arguments);
this.setupAddWizard();
},
setupAddWizard() {
Ember.run.schedule('afterRender', () => {
$('.start-document:not(.start-document-empty-state)').off('.hoverIntent');
$('.start-document:not(.start-document-empty-state)').hoverIntent({interval: 100, over: function() {
// in
$(this).find('.start-button').velocity("transition.slideDownIn", {duration: 300});
}, out: function() {
// out
$(this).find('.start-button').velocity("transition.slideUpOut", {duration: 300});
} });
});
},
actions: {
selectDocument(documentId) {
let doc = this.get('documents').findBy('id', documentId);
@ -65,39 +35,6 @@ export default Ember.Component.extend({
}
this.set('selectedDocuments', list);
},
onDelete() {
this.get("onDeleteSpace")();
},
onImport() {
this.get('onImport')();
},
onShowDocumentWizard(docId) {
if ($("#new-document-wizard").is(':visible') && this.get('docId') === docId) {
this.send('onHideDocumentWizard');
return;
}
this.set('docId', docId);
if (docId === '') {
$("#new-document-wizard").insertAfter('#wizard-placeholder');
} else {
$("#new-document-wizard").insertAfter(`#document-${docId}`);
}
$("#new-document-wizard").velocity("transition.slideDownIn", { duration: 300, complete:
function() {
$("#new-document-name").focus();
}});
},
onHideDocumentWizard() {
$("#new-document-wizard").insertAfter('#wizard-placeholder');
$("#new-document-wizard").velocity("transition.slideUpOut", { duration: 300 });
}
}
});

View file

@ -81,6 +81,10 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
} else {
this.addTooltip(document.getElementById("space-pin-button"));
}
if (this.get('permissions.documentAdd')) {
this.addTooltip(document.getElementById("document-add-button"));
}
}
},
@ -170,6 +174,10 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
this.attrs.onMoveDocument(this.get('moveFolderId'));
return true;
},
onStartDocument() {
this.attrs.onStartDocument();
}
}
});

View file

@ -0,0 +1,91 @@
// 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 Ember from 'ember';
import NotifierMixin from '../../mixins/notifier';
import TooltipMixin from '../../mixins/tooltip';
import AuthMixin from '../../mixins/auth';
const {
inject: { service }
} = Ember;
export default Ember.Component.extend(NotifierMixin, TooltipMixin, AuthMixin, {
router: service(),
documentService: service('document'),
folderService: service('folder'),
localStorage: service('localStorage'),
selectedDocuments: [],
hasSelectedDocuments: Ember.computed.gt('selectedDocuments.length', 0),
showStartDocument: false,
actions: {
onMoveDocument(folder) {
let self = this;
let documents = this.get('selectedDocuments');
documents.forEach(function (documentId) {
self.get('documentService').getDocument(documentId).then(function (doc) {
doc.set('folderId', folder);
doc.set('selected', !doc.get('selected'));
self.get('documentService').save(doc).then(function () {
self.attrs.onRefresh();
});
});
});
this.set('selectedDocuments', []);
this.send("showNotification", "Moved");
},
onDeleteDocument() {
let documents = this.get('selectedDocuments');
let self = this;
let promises = [];
documents.forEach(function (document, index) {
promises[index] = self.get('documentService').deleteDocument(document);
});
Ember.RSVP.all(promises).then(() => {
let documents = this.get('documents');
documents.forEach(function (document) {
document.set('selected', false);
});
this.set('documents', documents);
this.set('selectedDocuments', []);
this.send("showNotification", "Deleted");
this.attrs.onRefresh();
});
},
onDeleteSpace() {
this.get('folderService').delete(this.get('folder.id')).then(() => { /* jshint ignore:line */
this.showNotification("Deleted");
this.get('localStorage').clearSessionItem('folder');
this.get('router').transitionTo('application');
});
},
onImport() {
// this.attrs.onRefresh();
},
onStartDocument() {
this.set('showStartDocument', !this.get('showStartDocument'));
},
onHideStartDocument() {
this.set('showStartDocument', false);
}
}
});

View file

@ -14,54 +14,66 @@ import NotifierMixin from '../../mixins/notifier';
const {
computed,
inject: { service }
} = Ember;
export default Ember.Component.extend(NotifierMixin, {
localStorage: Ember.inject.service(),
appMeta: Ember.inject.service(),
templateService: Ember.inject.service('template'),
canEditTemplate: "",
localStorage: service(),
appMeta: service(),
templateService: service('template'),
importedDocuments: [],
savedTemplates: [],
drop: null,
newDocumentName: 'New Document',
dropzone: null,
newDocumentName: '',
newDocumentNameMissing: computed.empty('newDocumentName'),
didInsertElement() {
this.setupImport();
},
didReceiveAttrs() {
this._super(...arguments);
this.setupTemplates();
Ember.run.schedule('afterRender', ()=> {
this.setupImport();
});
},
willDestroyElement() {
if (is.not.null(this.get('drop'))) {
this.get('drop').destroy();
this.set('drop', null);
this._super(...arguments);
if (is.not.null(this.get('dropzone'))) {
this.get('dropzone').destroy();
this.set('dropzone', null);
}
},
setupTemplates() {
let templates = this.get('templates');
if (is.undefined(templates.findBy('id', '0'))) {
let emptyTemplate = {
id: "0",
title: "Empty",
title: "Blank",
description: "An empty canvas for your words",
layout: "doc",
locked: true
};
templates.unshiftObject(emptyTemplate);
}
this.set('savedTemplates', templates);
Ember.run.schedule('afterRender', () => {
$('#new-document-name').select();
});
},
setupImport() {
console.log("setting up import");
// already done init?
if (is.not.null(this.get('drop'))) {
this.get('drop').destroy();
this.set('drop', null);
if (is.not.null(this.get('dropzone'))) {
this.get('dropzone').destroy();
this.set('dropzone', null);
}
let self = this;
@ -70,9 +82,7 @@ export default Ember.Component.extend(NotifierMixin, {
let importUrl = `${url}/import/folder/${folderId}`;
let dzone = new Dropzone("#import-document-button", {
headers: {
'Authorization': 'Bearer ' + self.get('session.session.content.authenticated.token')
},
headers: { 'Authorization': 'Bearer ' + self.get('session.session.content.authenticated.token') },
url: importUrl,
method: "post",
paramName: 'attachment',
@ -90,7 +100,7 @@ export default Ember.Component.extend(NotifierMixin, {
});
this.on("error", function (x) {
console.log("Conversion failed for ", x.name, " obj ", x); // eslint-disable-line no-console
console.log("Conversion failed for", x.name, x); // eslint-disable-line no-console
});
this.on("queuecomplete", function () {});
@ -105,12 +115,12 @@ export default Ember.Component.extend(NotifierMixin, {
dzone.removeFile(file);
});
this.set('drop', dzone);
this.set('dropzone', dzone);
},
actions: {
onHideDocumentWizard() {
this.get('onHideDocumentWizard')();
onHideStartDocument() {
this.get('onHideStartDocument')();
},
editTemplate(template) {
@ -120,6 +130,12 @@ export default Ember.Component.extend(NotifierMixin, {
},
startDocument(template) {
if (this.get('newDocumentNameMissing')) {
this.$("#new-document-name").addClass('error').focus();
return;
}
this.$("#new-document-name").removeClass('error');
this.send("showNotification", "Creating");
this.get('templateService').importSavedTemplate(this.folder.get('id'), template.id, this.get('newDocumentName')).then((document) => {
@ -130,26 +146,30 @@ export default Ember.Component.extend(NotifierMixin, {
},
onDocumentImporting(filename) {
if (this.isDestroyed) { return; }
this.send("showNotification", `Importing ${filename}`);
this.get('onHideDocumentWizard')();
this.get('onHideStartDocument')();
let documents = this.get('importedDocuments');
documents.push(filename);
if (this.isDestroyed) { return; }
this.set('importedDocuments', documents);
},
onDocumentImported(filename /*, document*/ ) {
if (this.isDestroyed) { return; }
this.send("showNotification", `${filename} ready`);
let documents = this.get('importedDocuments');
documents.pop(filename);
if (this.isDestroyed) { return; }
this.set('importedDocuments', documents);
this.get('onImport')();
if (documents.length === 0) {
// this.get('showDocument')(this.get('folder'), document);
}
},
}
});

View file

@ -10,58 +10,19 @@
// https://documize.com
import Ember from 'ember';
import NotifierMixin from '../../../mixins/notifier';
export default Ember.Controller.extend(NotifierMixin, {
documentService: Ember.inject.service('document'),
folderService: Ember.inject.service('folder'),
localStorage: Ember.inject.service('localStorage'),
selectedDocuments: [],
hasSelectedDocuments: Ember.computed.gt('selectedDocuments.length', 0),
const {
inject: { service }
} = Ember;
export default Ember.Controller.extend({
documentService: service('document'),
folderService: service('folder'),
localStorage: service('localStorage'),
queryParams: ['tab'],
tab: 'index',
actions: {
onMoveDocument(folder) {
let self = this;
let documents = this.get('selectedDocuments');
documents.forEach(function (documentId) {
self.get('documentService').getDocument(documentId).then(function (doc) {
doc.set('folderId', folder);
doc.set('selected', !doc.get('selected'));
self.get('documentService').save(doc).then(function () {
self.get('target._routerMicrolib').refresh();
});
});
});
this.set('selectedDocuments', []);
this.send("showNotification", "Moved");
},
onDeleteDocument() {
let documents = this.get('selectedDocuments');
let self = this;
let promises = [];
documents.forEach(function (document, index) {
promises[index] = self.get('documentService').deleteDocument(document);
});
Ember.RSVP.all(promises).then(() => {
let documents = this.get('model.documents');
documents.forEach(function (document) {
document.set('selected', false);
});
this.set('model.documents', documents);
this.set('selectedDocuments', []);
this.send("showNotification", "Deleted");
this.get('target._routerMicrolib').refresh();
});
},
onAddSpace(payload) {
let self = this;
this.showNotification("Added");
@ -72,15 +33,7 @@ export default Ember.Controller.extend(NotifierMixin, {
});
},
onDeleteSpace() {
this.get('folderService').delete(this.get('model.folder.id')).then(() => { /* jshint ignore:line */
this.showNotification("Deleted");
this.get('localStorage').clearSessionItem('folder');
this.transitionToRoute('application');
});
},
onImport() {
onRefresh() {
this.get('target._routerMicrolib').refresh();
}
}

View file

@ -21,7 +21,12 @@ export default Ember.Route.extend(AuthenticatedRouteMixin, {
permissions: this.modelFor('folder').permissions,
folders: this.modelFor('folder').folders,
documents: this.modelFor('folder').documents,
templates: this.modelFor('folder').templates
templates: this.modelFor('folder').templates,
showStartDocument: false,
});
},
activate() {
this.set('model.showStartDocument', false);
}
});

View file

@ -1,21 +1,20 @@
{{#layout/zone-container}}
{{#layout/zone-sidebar}}
{{folder/sidebar-zone folders=model.folders folder=model.folder
permissions=model.permissions tab=tab onAddSpace=(action 'onAddSpace')}}
{{/layout/zone-sidebar}}
{{#layout/zone-content}}
{{folder/folder-heading folder=model.folder permissions=model.permissions}}
{{folder/space-view
folders=model.folders
folder=model.folder
templates=model.templates
permissions=model.permissions
documents=model.documents
onRefresh=(action 'onRefresh')}}
{{folder/folder-toolbar folders=model.folders folder=model.folder
permissions=model.permissions hasSelectedDocuments=hasSelectedDocuments
onDeleteDocument=(action 'onDeleteDocument') onMoveDocument=(action 'onMoveDocument')
onDeleteSpace=(action 'onDeleteSpace')}}
<div class="margin-bottom-20 clearfix" />
{{folder/documents-list documents=model.documents folders=model.folders folder=model.folder templates=model.templates
permissions=model.permissions selectedDocuments=(mut selectedDocuments)
onDeleteSpace=(action 'onDeleteSpace') onImport=(action 'onImport')}}
{{/layout/zone-content}}
{{/layout/zone-container}}

View file

@ -37,16 +37,15 @@ $color-link: #0092d3;
$color-border: #f3f5f8;
$color-checkbox: #0092d3;
$color-card-active: #f7fcff;
$color-nav-button: #f2faff;
$color-nav-button-text: #2667af;
$color-nav-button-border: #dff0f9;
$color-sidebar: #f2faff;
$color-sidebar-border: #dff0f9;
$color-sidebar-text: $color-off-black;
$color-sidebar-link: $color-link;
$color-selected-item: $color-sidebar;
$color-nav-button: $color-sidebar;
$color-nav-button-text: #2667af;
$color-nav-button-border: #dff0f9;
// Color utility classes for direct usage in HTML
.color-white {

View file

@ -22,9 +22,11 @@
}
.documents-list {
.document-item {
@include content-container();
.document-item {
margin: 0;
padding: 25px 15px;
position: relative;
transition: 0.3s;
@ -48,7 +50,7 @@
position: absolute;
display: none;
top: 10px;
right: 20px;
right: 10px;
cursor: pointer;
> .material-icons {
@ -82,18 +84,8 @@
}
}
.wizard-item {
margin: 0;
padding: 0;
}
.no-wizard-item {
margin: 50px 0;
padding: 0;
}
.selected-card {
background-color: $color-card-active !important;
background-color: $color-selected-item !important;
> .checkbox {
display: block;
@ -101,8 +93,7 @@
}
}
.move-document-options,
.start-document-options {
.move-document-options {
height: 200px;
overflow-y: auto;
margin: 0;

View file

@ -1,66 +1,5 @@
.start-document {
@extend .no-select;
height: 60px;
background-color: transparent;
position: relative;
cursor: pointer;
> .start-button {
display: none;
text-align: center;
padding-top: 20px;
color: $color-green;
font-size: 1rem;
position: relative;
> .round-button {
opacity: 0.6 !important;
}
> .label {
display: inline-block;
margin-left: 10px;
}
> .line {
display: inline-block;
height: 1px;
border: 1px solid $color-green;
width: 100px;
margin: 0 20px 0 20px;
opacity: 0.2;
}
}
&:first-of-type {
height: 30px;
> .start-button {
padding-top: 0;
}
}
}
.start-document-empty-state {
> .start-button {
display: block;
}
}
.new-document-wizard {
@include border-radius(2px);
margin: 0 0 30px 0;
padding: 30px;
border: 1px solid $color-stroke;
background-color: $color-off-white;
display: none;
.document-name {
font-weight: bold;
font-size: 1.5rem;
margin: 0 0 30px 0;
color: $color-black;
}
@include content-container();
.import-document-button {
width: 100%;
@ -68,11 +7,13 @@
margin: 0 0 30px 0;
text-align: center;
color: $color-gray;
border: 1px solid $color-stroke;
cursor: pointer;
font-size: 1rem;
font-size: 1.2rem;
line-height: 1.7rem;
@include ease-in();
@extend .no-select;
border: 1px solid $color-stroke;
background-color: $color-off-white;
&:hover {
border-color: $color-link;
@ -85,22 +26,19 @@
}
}
> .input-control {
> .list-wrapper {
// height: 440px;
// overflow-y: auto;
> .template-list {
margin: 0;
padding: 0;
> .item {
.item {
@include ease-in();
@include border-radius(4px);
list-style: none;
cursor: pointer;
display: inline-block;
border: 1px solid $color-stroke;
background-color: $color-white;
background-color: $color-blue;
margin: 0 20px 20px 0;
padding: 12px 0 0 20px;
width: 423px;
@ -138,7 +76,7 @@
> .title {
font-size: 1rem;
font-weight: normal;
color: $color-off-black;
color: $color-white;
letter-spacing: 0.5px;
margin-top: 0;
overflow: hidden;
@ -147,7 +85,7 @@
}
> .desc {
color: $color-gray;
color: $color-white;
font-size: 0.8rem;
margin-top: 5px;
overflow: hidden;
@ -158,5 +96,6 @@
}
}
}
}
}

View file

@ -6,8 +6,8 @@
&:hover {
@extend .z-depth-half;
background-color: $color-card-active;
border-color: $color-card-active;
background-color: $color-selected-item;
border-color: $color-selected-item;
transition: 0.2s all ease;
}
}

View file

@ -21,7 +21,7 @@
}
> .selected {
background-color: $color-card-active !important;
background-color: $color-selected-item !important;
color: $color-primary !important;
> i.material-icons {

View file

@ -12,7 +12,7 @@
<div class="caption">Category</div>
{{#each selectedCategories as |cat|}}
<div class="regular-button button-nav">{{cat.category}}</div>
<div class="regular-button button-blue">{{cat.category}}</div>
{{else}}
{{#if canAddCategory}}
{{#link-to 'folder.settings.category' folder.id folder.slug}}Manage{{/link-to}}

View file

@ -17,39 +17,6 @@
</div>
{{/if}}
</div>
{{#if canCreate}}
<div class="wizard-item start-document" {{action 'onShowDocumentWizard' document.id}}>
<div class="start-button">
<div class="round-button round-button-small button-green">
<i class="material-icons">add</i>
</div>
<div class="label">document</div>
</div>
</div>
{{else}}
<div class="no-wizard-item" />
{{/if}}
</div>
{{/each}}
</div>
{{folder/start-document folder=folder templates=templates permissions=permissions onImport=(action 'onImport') onHideDocumentWizard=(action 'onHideDocumentWizard')}}
{{#if emptyState}}
{{#if canCreate}}
<div class="start-document start-document-empty-state" {{action 'onShowDocumentWizard' ''}}>
<div class="start-button">
<div class="round-button round-button-small button-green">
<i class="material-icons">add</i>
</div>
<div class="label">document</div>
</div>
</div>
{{/if}}
{{/if}}
<div id="wizard-placeholder" class="hide" />
{{#if emptyState}}
<div class="regular-button button-red margin-top-50" {{action 'onDelete'}}>delete space</div>
{{/if}}

View file

@ -41,6 +41,13 @@
{{else}}
{{#if permissions.documentAdd}}
<div class="round-button button-green" id="document-add-button" data-tooltip="Create document" data-tooltip-position="top center" {{action 'onStartDocument'}}>
<i class="material-icons">add</i>
</div>
<div class="button-gap"></div>
{{/if}}
{{#if pinState.isPinned}}
<div class="round-button button-gray" id="space-unpin-button" data-tooltip="Remove favorite" data-tooltip-position="top center" {{action 'onUnpin'}}>
<i class="material-icons">favorite</i>
@ -62,7 +69,7 @@
{{#if permissions.spaceOwner}}
<div class="button-gap"></div>
<div class="round-button button-red" id="space-delete-button" data-tooltip="Delete everything" data-tooltip-position="top center">
<div class="round-button button-gray" id="space-delete-button" data-tooltip="Delete everything" data-tooltip-position="top center">
<i class="material-icons">delete</i>
</div>
{{/if}}

View file

@ -0,0 +1,17 @@
{{folder/space-heading folder=folder permissions=permissions}}
{{folder/space-toolbar folders=folders folder=folder
permissions=permissions hasSelectedDocuments=hasSelectedDocuments
onDeleteDocument=(action 'onDeleteDocument') onMoveDocument=(action 'onMoveDocument')
onDeleteSpace=(action 'onDeleteSpace') onStartDocument=(action 'onStartDocument')}}
<div class="margin-bottom-20 clearfix" />
{{#if showStartDocument}}
{{folder/start-document folder=folder templates=templates permissions=permissions
onImport=(action 'onImport') onHideStartDocument=(action 'onHideStartDocument')}}
{{else}}
{{folder/documents-list documents=documents folders=folders folder=folder
templates=templates permissions=permissions selectedDocuments=(mut selectedDocuments)
onImport=(action 'onImport')}}
{{/if}}

View file

@ -1,16 +1,18 @@
<div id="new-document-wizard" class="new-document-wizard">
<div class="input-inline input-transparent pull-left width-80">
{{input type="text" id="new-document-name" value=newDocumentName class=(if newDocumentNameMissing 'document-name error-inline' 'document-name mousetrap') placeholder="Name" autocomplete="off"}}
<div class="input-control pull-left width-80">
<label>Document Name</label>
<div class="tip">Provide a concise name for the new document</div>
{{focus-input type="text" id="new-document-name" value=newDocumentName class=(if newDocumentNameMissing 'document-name error-inline' 'document-name mousetrap') autocomplete="off"}}
</div>
<div class="round-button-mono pull-right" {{action 'onHideDocumentWizard'}}>
<div class="round-button-mono pull-right" {{action 'onHideStartDocument'}}>
<i class="material-icons color-gray">close</i>
</div>
<div class="clearfix" />
<div id="import-document-button" class="import-document-button">
Drag-drop or click to select .doc, .docx, .md, .markdown files
</div>
<div class="input-control">
<label>Select Template</label>
<div class="tip">Start a blank document or pick a template</div>
<div class="list-wrapper">
<ul class="template-list">
@ -31,5 +33,10 @@
{{/each}}
</ul>
</div>
</div>
<div id="import-document-button" class="import-document-button">
Alternatively, click to select or drag-drop files <br/>(doc, docx, md, markdown)
</div>
</div>

2533
gui/vendor/dropzone.js vendored

File diff suppressed because it is too large Load diff