diff --git a/.gitattributes b/.gitattributes index 72e11d631..0e9b00b8b 100644 --- a/.gitattributes +++ b/.gitattributes @@ -2,4 +2,11 @@ * text=auto # These files are text and should be normalized (convert crlf > lf) -*.hbs text \ No newline at end of file +*.hbs text eol=lf +*.js text eol=lf +*.html text eol=lf +*.go text eol=lf +*.sql text eol=lf +*.scss text eol=lf +*.js text eol=lf +*.json text eol=lf diff --git a/app/.editorconfig b/app/.editorconfig index 219985c22..deb893209 100644 --- a/app/.editorconfig +++ b/app/.editorconfig @@ -10,8 +10,8 @@ end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true -indent_style = space -indent_size = 2 +indent_style = tab +indent_size = 4 [*.hbs] insert_final_newline = false diff --git a/app/.jshintrc b/app/.jshintrc index 767b6edf1..cee569be4 100644 --- a/app/.jshintrc +++ b/app/.jshintrc @@ -18,7 +18,8 @@ "Drop", "Dropzone", "dragula", - "datetimepicker" + "datetimepicker", + "Waypoint" ], "browser": true, "boss": true, diff --git a/app/app/components/layout/button-home.js b/app/app/components/back-to-home.js similarity index 90% rename from app/app/components/layout/button-home.js rename to app/app/components/back-to-home.js index f62de8900..cb25c125c 100644 --- a/app/app/components/layout/button-home.js +++ b/app/app/components/back-to-home.js @@ -11,4 +11,5 @@ import Ember from 'ember'; -export default Ember.Component.extend({}); +export default Ember.Component.extend({ +}); diff --git a/app/app/components/back-to-space.js b/app/app/components/back-to-space.js new file mode 100644 index 000000000..cb25c125c --- /dev/null +++ b/app/app/components/back-to-space.js @@ -0,0 +1,15 @@ +// 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 Ember from 'ember'; + +export default Ember.Component.extend({ +}); diff --git a/app/app/components/document/document-sidebar-toc.js b/app/app/components/document/document-sidebar-toc.js index 3cc285b06..435ea3413 100644 --- a/app/app/components/document/document-sidebar-toc.js +++ b/app/app/components/document/document-sidebar-toc.js @@ -45,27 +45,29 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { didInsertElement() { this.eventBus.subscribe('documentPageAdded', this, 'onDocumentPageAdded'); - - var s = $(".document-structure"); - var pos = s.position(); - - $(window).scroll(function() { - var windowpos = $(window).scrollTop(); - if (windowpos - 200 >= pos.top) { - s.addClass("stick"); - s.css('width', s.parent().width()); - } else { - s.removeClass("stick"); - s.css('width', 'auto'); - } - }); - }, + }, willDestroyElement() { this.eventBus.unsubscribe('documentPageAdded'); this.destroyTooltips(); }, + // positionToc() { + // let s = $(".document-structure"); + // let pos = s.position(); + // + // $(window).scroll(_.throttle(function() { + // let windowpos = $(window).scrollTop(); + // if (windowpos - 200 >= pos.top) { + // s.addClass("stuck-toc"); + // s.css('width', s.parent().width()); + // } else { + // s.removeClass("stuck-toc"); + // s.css('width', 'auto'); + // } + // }, 50)); + // }, + onDocumentPageAdded(pageId) { this.send('onEntryClick', pageId); }, diff --git a/app/app/components/document/document-sidebar.js b/app/app/components/document/document-sidebar.js index 0c1107b19..350e94826 100644 --- a/app/app/components/document/document-sidebar.js +++ b/app/app/components/document/document-sidebar.js @@ -11,23 +11,51 @@ import Ember from 'ember'; import TooltipMixin from '../../mixins/tooltip'; +import NotifierMixin from '../../mixins/notifier'; -export default Ember.Component.extend(TooltipMixin, { +export default Ember.Component.extend(TooltipMixin, NotifierMixin, { documentService: Ember.inject.service('document'), document: {}, folder: {}, showToc: true, showViews: false, showContributions: false, + showSections: false, + showScrollTool: false, + showingSections: false, didRender() { if (this.session.authenticated) { this.addTooltip(document.getElementById("owner-avatar")); + this.addTooltip(document.getElementById("section-tool")); } }, - willDestroyElements() { - this.destroyElements(); + didInsertElement() { + this.eventBus.subscribe('resized', this, 'positionTool'); + this.eventBus.subscribe('scrolled', this, 'positionTool'); + }, + + willDestroyElement() { + this.destroyTooltips(); + }, + + positionTool() { + if (this.get('isDestroyed') || this.get('isDestroying')) { + return; + } + + let s = $(".scroll-tool"); + let windowpos = $(window).scrollTop(); + + if (windowpos >= 300) { + this.set('showScrollTool', true); + s.addClass("stuck-tool"); + s.css('left', parseInt($(".zone-sidebar").css('width')) - 18 + 'px'); + } else { + this.set('showScrollTool', false); + s.removeClass("stuck-tool"); + } }, actions: { @@ -45,27 +73,55 @@ export default Ember.Component.extend(TooltipMixin, { return this.attrs.gotoPage(id); }, - // close dialog - close() { - return true; - }, - showToc() { this.set('showToc', true); this.set('showViews', false); this.set('showContributions', false); + this.set('showSections', false); + this.set('showingSections', false); }, showViews() { this.set('showToc', false); this.set('showViews', true); this.set('showContributions', false); + this.set('showSections', false); + this.set('showingSections', false); }, showContributions() { this.set('showToc', false); this.set('showViews', false); this.set('showContributions', true); + this.set('showSections', false); + this.set('showingSections', false); + }, + + showSections() { + this.set('showToc', false); + this.set('showViews', false); + this.set('showContributions', false); + this.set('showSections', true); + this.set('showingSections', true); + }, + + onCancel() { + this.send('showToc'); + this.set('showingSections', false); + }, + + onAddSection(section) { + this.attrs.onAddSection(section); + + this.set('showingSections', false); + }, + + scrollTop() { + this.set('showScrollTool', false); + + $("html,body").animate({ + scrollTop: 0 + }, 500, "linear"); } } }); diff --git a/app/app/components/document/document-toolbar.js b/app/app/components/document/document-toolbar.js index 1fec9d383..4f19a868b 100644 --- a/app/app/components/document/document-toolbar.js +++ b/app/app/components/document/document-toolbar.js @@ -35,7 +35,6 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { this.addTooltip(document.getElementById("save-template-button")); this.addTooltip(document.getElementById("set-meta-button")); this.addTooltip(document.getElementById("delete-document-button")); - this.addTooltip(document.getElementById("add-section-button")); } this.addTooltip(document.getElementById("print-document-button")); @@ -139,4 +138,4 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { return true; }, } -}); \ No newline at end of file +}); diff --git a/app/app/components/document/document-view.js b/app/app/components/document/document-view.js index ed539429b..5efb80c9d 100644 --- a/app/app/components/document/document-view.js +++ b/app/app/components/document/document-view.js @@ -133,4 +133,4 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { this.get('documentService').save(doc); } } -}); \ No newline at end of file +}); diff --git a/app/app/components/document/page-wizard.js b/app/app/components/document/page-wizard.js index 493a49e3b..36d6477f1 100644 --- a/app/app/components/document/page-wizard.js +++ b/app/app/components/document/page-wizard.js @@ -13,9 +13,18 @@ import Ember from 'ember'; import NotifierMixin from '../../mixins/notifier'; export default Ember.Component.extend(NotifierMixin, { + sectionService: Ember.inject.service('section'), + + didReceiveAttrs() { + let self = this; + this.get('sectionService').getAll().then(function(sections) { + self.set('sections', sections); + }); + }, didRender() { let self = this; + Mousetrap.bind('esc', function() { self.send('onCancel'); return false; @@ -28,12 +37,6 @@ export default Ember.Component.extend(NotifierMixin, { }, addSection(section) { - - if (section.preview) { - this.showNotification("Coming soon!"); - return; - } - this.attrs.onAction(section); } } diff --git a/app/app/components/folder/folder-toolbar.js b/app/app/components/folder/folder-toolbar.js index ea1140c1f..d8a06bc56 100644 --- a/app/app/components/folder/folder-toolbar.js +++ b/app/app/components/folder/folder-toolbar.js @@ -18,32 +18,24 @@ const { } = Ember; export default Ember.Component.extend(NotifierMixin, TooltipMixin, { + folderService: Ember.inject.service('folder'), documentService: Ember.inject.service('document'), - templateService: Ember.inject.service('template'), - folderService: Ember.inject.service('folder'), session: Ember.inject.service(), + appMeta: Ember.inject.service(), + showToolbar: false, folder: {}, busy: false, importedDocuments: [], - savedTemplates: [], isFolderOwner: computed.equal('folder.userId', 'session.user.id'), moveFolderId: "", + drop: null, didReceiveAttrs() { this.set('isFolderOwner', this.get('folder.userId') === this.get("session.user.id")); - let self = this; - - this.get('templateService').getSavedTemplates().then(function(saved) { - let emptyTemplate = { - id: "0", - title: "Empty document", - selected: true - }; - saved.unshiftObject(emptyTemplate); - self.set('savedTemplates', saved); - }); + let show = this.get('isFolderOwner') || this.get('hasSelectedDocuments') || this.get('folderService').get('canEditCurrentFolder'); + this.set('showToolbar', show); let targets = _.reject(this.get('folders'), { id: this.get('folder').get('id') @@ -62,34 +54,67 @@ export default Ember.Component.extend(NotifierMixin, TooltipMixin, { this.addTooltip(document.getElementById("folder-settings-button")); } if (this.get('folderService').get('canEditCurrentFolder')) { - this.addTooltip(document.getElementById("start-document-button")); + this.addTooltip(document.getElementById("import-document-button")); } } - }, + + if (this.get('folderService').get('canEditCurrentFolder')) { + let self = this; + let folderId = this.get('folder.id'); + let url = this.get('appMeta.endpoint'); + let importUrl = `${url}/import/folder/${folderId}`; + + let dzone = new Dropzone("#import-document-button > i", { + headers: { + 'Authorization': 'Bearer ' + self.get('session.session.content.authenticated.token') + }, + url: importUrl, + method: "post", + paramName: 'attachment', + acceptedFiles: ".doc,.docx,.txt,.md,.markdown", + clickable: true, + maxFilesize: 10, + parallelUploads: 3, + uploadMultiple: false, + addRemoveLinks: false, + autoProcessQueue: true, + + init: function () { + this.on("success", function (document) { + self.send('onDocumentImported', document.name, document); + }); + + this.on("error", function (x) { + console.log("Conversion failed for ", x.name, " obj ", x); // TODO proper error handling + }); + + this.on("queuecomplete", function () {}); + + this.on("addedfile", function (file) { + self.send('onDocumentImporting', file.name); + self.audit.record('converted-document'); + }); + } + }); + + dzone.on("complete", function (file) { + dzone.removeFile(file); + }); + + this.set('drop', dzone); + } + }, willDestroyElement() { - this.destroyTooltips(); - }, + if (is.not.null(this.get('drop'))) { + this.get('drop').destroy(); + this.set('drop', null); + } - navigateToDocument(document) { - this.attrs.showDocument(this.get('folder'), document); + this.destroyTooltips(); }, actions: { - onEditTemplate(template) { - this.navigateToDocument(template); - }, - - onDocumentTemplate(id /*, title, type*/ ) { - let self = this; - - this.send("showNotification", "Creating"); - - this.get('templateService').importSavedTemplate(this.folder.get('id'), id).then(function(document) { - self.navigateToDocument(document); - }); - }, - onDocumentImporting(filename) { this.send("showNotification", `Importing ${filename}`); diff --git a/app/app/components/folder/folders-list.js b/app/app/components/folder/folders-list.js index 31a61e44f..137758050 100644 --- a/app/app/components/folder/folders-list.js +++ b/app/app/components/folder/folders-list.js @@ -12,24 +12,55 @@ import Ember from 'ember'; import constants from '../../utils/constants'; import TooltipMixin from '../../mixins/tooltip'; +import NotifierMixin from '../../mixins/notifier'; -export default Ember.Component.extend(TooltipMixin, { +export default Ember.Component.extend(TooltipMixin, NotifierMixin, { folderService: Ember.inject.service('folder'), + templateService: Ember.inject.service('template'), publicFolders: [], protectedFolders: [], privateFolders: [], + savedTemplates: [], hasPublicFolders: false, hasProtectedFolders: false, hasPrivateFolders: false, newFolder: "", + showScrollTool: false, + showingDocument: false, + showingList: true, - didInsertElement() { + init() { this._super(...arguments); - if (this.session.authenticated) { - this.addTooltip(document.getElementById("add-folder-button")); + + let _this = this; + this.get('templateService').getSavedTemplates().then(function(saved) { + let emptyTemplate = { + id: "0", + title: "Empty", + description: "An empty canvas for your words", + img: "template-blank", + }; + + saved.forEach(function(t) { + t.img = "template-saved"; + }); + + saved.unshiftObject(emptyTemplate); + _this.set('savedTemplates', saved); + }); + }, + + didRender() { + if (this.get('folderService').get('canEditCurrentFolder')) { + this.addTooltip(document.getElementById("start-document-button")); } }, + didInsertElement() { + this.eventBus.subscribe('resized', this, 'positionTool'); + this.eventBus.subscribe('scrolled', this, 'positionTool'); + }, + didReceiveAttrs() { let folders = this.get('folders'); @@ -65,7 +96,37 @@ export default Ember.Component.extend(TooltipMixin, { this.destroyTooltips(); }, + positionTool() { + if (this.get('isDestroyed') || this.get('isDestroying')) { + return; + } + + let s = $(".scroll-space-tool"); + let windowpos = $(window).scrollTop(); + + if (windowpos >= 300) { + this.set('showScrollTool', true); + s.addClass("stuck-space-tool"); + s.css('left', parseInt($(".zone-sidebar").css('width')) - 18 + 'px'); + } else { + this.set('showScrollTool', false); + s.removeClass("stuck-space-tool"); + } + }, + + navigateToDocument(document) { + this.attrs.showDocument(this.get('folder'), document); + }, + actions: { + scrollTop() { + this.set('showScrollTool', false); + + $("html,body").animate({ + scrollTop: 0 + }, 500, "linear"); + }, + addFolder() { var folderName = this.get('newFolder'); @@ -78,6 +139,30 @@ export default Ember.Component.extend(TooltipMixin, { this.set('newFolder', ""); return true; - } + }, + + showDocument() { + this.set('showingDocument', true); + this.set('showingList', false); + }, + + showList() { + this.set('showingDocument', false); + this.set('showingList', true); + }, + + onEditTemplate(template) { + this.navigateToDocument(template); + }, + + onDocumentTemplate(id /*, title, type*/ ) { + let self = this; + + this.send("showNotification", "Creating"); + + this.get('templateService').importSavedTemplate(this.folder.get('id'), id).then(function(document) { + self.navigateToDocument(document); + }); + } } }); diff --git a/app/app/components/folder/start-document.js b/app/app/components/folder/start-document.js index 30638575b..93a60577d 100644 --- a/app/app/components/folder/start-document.js +++ b/app/app/components/folder/start-document.js @@ -14,108 +14,21 @@ import NotifierMixin from '../../mixins/notifier'; export default Ember.Component.extend(NotifierMixin, { localStorage: Ember.inject.service(), - tagName: 'span', - selectedTemplate: { - id: "0" - }, canEditTemplate: "", - drop: null, - appMeta: Ember.inject.service(), - - didReceiveAttrs() { - this.send('setTemplate', this.get('savedTemplates')[0]); - }, - - willDestroyElement() { - if (is.not.null(this.get('drop'))) { - this.get('drop').destroy(); - this.set('drop', null); - } - }, actions: { - setTemplate(chosen) { - if (is.undefined(chosen)) { - return; - } - - this.set('selectedTemplate', chosen); - this.set('canEditTemplate', chosen.id !== "0" ? "Edit" : ""); - - let templates = this.get('savedTemplates'); - - templates.forEach(template => { - Ember.set(template, 'selected', template.id === chosen.id); - }); - }, - - editTemplate() { - let template = this.get('selectedTemplate'); - + editTemplate(template) { this.audit.record('edited-saved-template'); this.attrs.onEditTemplate(template); return true; }, - startDocument() { - let template = this.get('selectedTemplate'); - + startDocument(template) { this.audit.record('used-saved-template'); this.attrs.onDocumentTemplate(template.id, template.title, "private"); - return true; - }, - - onOpenCallback() { - if (is.not.null(this.get('drop'))) { - return; - } - - let self = this; - let folderId = this.get('folder.id'); - let url = this.get('appMeta.endpoint'); - let importUrl = `${url}/import/folder/${folderId}`; - - Dropzone.options.uploadDocuments = false; - - let dzone = new Dropzone("#upload-documents", { - headers: { - 'Authorization': 'Bearer ' + self.get('session.session.content.authenticated.token') - }, - url: importUrl, - method: "post", - paramName: 'attachment', - acceptedFiles: ".doc,.docx,.txt,.md,.markdown", - clickable: true, - maxFilesize: 10, - parallelUploads: 3, - uploadMultiple: false, - addRemoveLinks: false, - autoProcessQueue: true, - - init: function () { - this.on("success", function (document) { - self.attrs.onDocumentImported(document.name, document); - }); - this.on("error", function (x) { - console.log("Conversion failed for ", x.name, " obj ", x); // TODO proper error handling - }); - - this.on("queuecomplete", function () {}); - - this.on("addedfile", function (file) { - self.attrs.onDocumentImporting(file.name); - self.audit.record('converted-document'); - }); - } - }); - - dzone.on("complete", function (file) { - dzone.removeFile(file); - }); - - this.set('drop', dzone); + return true; } } -}); \ No newline at end of file +}); diff --git a/app/app/helpers/document/file-icon.js b/app/app/helpers/document/file-icon.js index 1d1d69049..5a0221914 100644 --- a/app/app/helpers/document/file-icon.js +++ b/app/app/helpers/document/file-icon.js @@ -107,7 +107,7 @@ export function documentFileIcon(params) { case "xslt": } - return new Ember.Handlebars.SafeString(html); + return new Ember.String.htmlSafe(html); } export default Ember.Helper.helper(documentFileIcon); diff --git a/app/app/models/.gitkeep b/app/app/models/.gitkeep deleted file mode 100644 index e69de29bb..000000000 diff --git a/app/app/pods/customize/template.hbs b/app/app/pods/customize/template.hbs index ae1e4594d..b386b6ecb 100644 --- a/app/app/pods/customize/template.hbs +++ b/app/app/pods/customize/template.hbs @@ -1,12 +1,8 @@ {{#layout/zone-container}} {{layout/zone-navigation}} - - {{#layout/zone-header title="Documize Settings" message="General options, space management, user management"}} - {{layout/button-home}} - {{/layout/zone-header}} - {{#layout/zone-sidebar}} + {{back-to-home}} + {{/if}} + + + - + diff --git a/app/app/templates/components/folder/start-document.hbs b/app/app/templates/components/folder/start-document.hbs index eb7e0f234..a527bf210 100644 --- a/app/app/templates/components/folder/start-document.hbs +++ b/app/app/templates/components/folder/start-document.hbs @@ -1,20 +1,19 @@ -{{#dropdown-dialog target="start-document-button" position="bottom right" button="Start" color="flat-green" onAction=(action 'startDocument') button2=canEditTemplate color2="flat-blue" onAction2=(action 'editTemplate') onOpenCallback=(action 'onOpenCallback')}} -
-
Import Word / Markdown
-
+ -

Or use a template:

- -