diff --git a/README.md b/README.md index 001dc690..3eb81fdc 100644 --- a/README.md +++ b/README.md @@ -42,7 +42,7 @@ Integrations for embedding SaaS data within documents. ## Latest version -v1.54.1 +v1.55.0 ## OS support @@ -56,8 +56,8 @@ Documize runs on the following: Documize is built with the following technologies: -- EmberJS (v2.15.0) -- Go (v1.9.0) +- EmberJS (v2.16.2) +- Go (v1.9.2) ...and supports the following databases: diff --git a/edition/community.go b/edition/community.go index 41f17c66..1ebdffcc 100644 --- a/edition/community.go +++ b/edition/community.go @@ -41,8 +41,8 @@ func main() { // product details rt.Product = env.ProdInfo{} rt.Product.Major = "1" - rt.Product.Minor = "54" - rt.Product.Patch = "1" + rt.Product.Minor = "55" + rt.Product.Patch = "0" rt.Product.Version = fmt.Sprintf("%s.%s.%s", rt.Product.Major, rt.Product.Minor, rt.Product.Patch) rt.Product.Edition = "Community" rt.Product.Title = fmt.Sprintf("%s Edition", rt.Product.Edition) diff --git a/gui/app/components/layout/nav-bar.js b/gui/app/components/layout/nav-bar.js new file mode 100644 index 00000000..a214f967 --- /dev/null +++ b/gui/app/components/layout/nav-bar.js @@ -0,0 +1,85 @@ +// 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 Component from '@ember/component'; +import { notEmpty } from '@ember/object/computed'; +import { inject as service } from '@ember/service'; +import constants from '../../utils/constants'; + +export default Component.extend({ + folderService: service('folder'), + appMeta: service(), + session: service(), + store: service(), + pinned: service(), + enableLogout: true, + pins: [], + hasPins: notEmpty('pins'), + hasSpacePins: notEmpty('spacePins'), + hasDocumentPins: notEmpty('documentPins'), + + init() { + this._super(...arguments); + + if (this.get('appMeta.authProvider') === constants.AuthProvider.Keycloak) { + let config = this.get('appMeta.authConfig'); + config = JSON.parse(config); + this.set('enableLogout', !config.disableLogout); + } + }, + + didInsertElement() { + this._super(...arguments); + + if (this.get("session.authenticated")) { + this.eventBus.subscribe('pinChange', this, 'setupPins'); + this.setupPins(); + } + }, + + setupPins() { + if (this.get('isDestroyed') || this.get('isDestroying')) { + return; + } + + this.get('pinned').getUserPins().then((pins) => { + if (this.get('isDestroyed') || this.get('isDestroying')) { + return; + } + this.set('pins', pins); + this.set('spacePins', pins.filterBy('isSpace', true)); + this.set('documentPins', pins.filterBy('isDocument', true)); + }); + }, + + willDestroyElement() { + this._super(...arguments); + + this.eventBus.unsubscribe('pinChange'); + }, + + actions: { + jumpToPin(pin) { + let folderId = pin.get('folderId'); + let documentId = pin.get('documentId'); + + if (_.isEmpty(documentId)) { + // jump to space + let folder = this.get('store').peekRecord('folder', folderId); + this.get('router').transitionTo('folder', folderId, folder.get('slug')); + } else { + // jump to doc + let folder = this.get('store').peekRecord('folder', folderId); + this.get('router').transitionTo('document', folderId, folder.get('slug'), documentId, 'document'); + } + } + } +}); diff --git a/gui/app/components/layout/zone-sidebar.js b/gui/app/components/layout/zone-sidebar.js index b28f9b11..2e83c74c 100644 --- a/gui/app/components/layout/zone-sidebar.js +++ b/gui/app/components/layout/zone-sidebar.js @@ -8,74 +8,7 @@ // by contacting . // // https://documize.com - -import { notEmpty } from '@ember/object/computed'; - import Component from '@ember/component'; -import { inject as service } from '@ember/service'; -import constants from '../../utils/constants'; export default Component.extend({ - folderService: service('folder'), - appMeta: service(), - session: service(), - store: service(), - pinned: service(), - enableLogout: true, - pins: [], - hasPins: notEmpty('pins'), - - init() { - this._super(...arguments); - - if (this.get('appMeta.authProvider') === constants.AuthProvider.Keycloak) { - let config = this.get('appMeta.authConfig'); - config = JSON.parse(config); - this.set('enableLogout', !config.disableLogout); - } - }, - - didInsertElement() { - this._super(...arguments); - - if (this.get("session.authenticated")) { - this.eventBus.subscribe('pinChange', this, 'setupPins'); - this.setupPins(); - } - }, - - setupPins() { - if (this.get('isDestroyed') || this.get('isDestroying')) { - return; - } - - this.get('pinned').getUserPins().then((pins) => { - if (this.get('isDestroyed') || this.get('isDestroying')) { - return; - } - - this.set('pins', pins); - }); - }, - - willDestroyElement() { - this.eventBus.unsubscribe('pinChange'); - }, - - actions: { - jumpToPin(pin) { - let folderId = pin.get('folderId'); - let documentId = pin.get('documentId'); - - if (_.isEmpty(documentId)) { - // jump to space - let folder = this.get('store').peekRecord('folder', folderId); - this.get('router').transitionTo('folder', folderId, folder.get('slug')); - } else { - // jump to doc - let folder = this.get('store').peekRecord('folder', folderId); - this.get('router').transitionTo('document', folderId, folder.get('slug'), documentId, 'document'); - } - } - } }); diff --git a/gui/app/components/spaces/space-list.js b/gui/app/components/spaces/space-list.js new file mode 100644 index 00000000..885fc2d2 --- /dev/null +++ b/gui/app/components/spaces/space-list.js @@ -0,0 +1,54 @@ +// 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 Component from '@ember/component'; +import constants from '../../utils/constants'; +import TooltipMixin from '../../mixins/tooltip'; +import NotifierMixin from '../../mixins/notifier'; +import AuthMixin from '../../mixins/auth'; + +export default Component.extend(TooltipMixin, NotifierMixin, AuthMixin, { + publicFolders: [], + protectedFolders: [], + privateFolders: [], + hasPublicFolders: false, + hasProtectedFolders: false, + hasPrivateFolders: false, + + didReceiveAttrs() { + let folders = this.get('spaces'); + let publicFolders = []; + let protectedFolders = []; + let privateFolders = []; + + _.each(folders, folder => { + if (folder.get('folderType') === constants.FolderType.Public) { + publicFolders.pushObject(folder); + } + if (folder.get('folderType') === constants.FolderType.Private) { + privateFolders.pushObject(folder); + } + if (folder.get('folderType') === constants.FolderType.Protected) { + protectedFolders.pushObject(folder); + } + }); + + this.set('publicFolders', publicFolders); + this.set('protectedFolders', protectedFolders); + this.set('privateFolders', privateFolders); + this.set('hasPublicFolders', this.get('publicFolders.length') > 0); + this.set('hasPrivateFolders', this.get('privateFolders.length') > 0); + this.set('hasProtectedFolders', this.get('protectedFolders.length') > 0); + }, + + actions: { + } +}); diff --git a/gui/app/models/pin.js b/gui/app/models/pin.js index afbafd34..ae7bb6f1 100644 --- a/gui/app/models/pin.js +++ b/gui/app/models/pin.js @@ -11,6 +11,7 @@ import Model from 'ember-data/model'; import attr from 'ember-data/attr'; +import { computed } from '@ember/object'; export default Model.extend({ orgId: attr('string'), @@ -20,5 +21,12 @@ export default Model.extend({ sequence: attr('number', { defaultValue: 99 }), pin: attr('string'), created: attr(), - revised: attr() + revised: attr(), + + isSpace: computed('documentId', function() { + return this.get('documentId') === ''; + }), + isDocument: computed('documentId', function() { + return this.get('documentId') !== ''; + }) }); diff --git a/gui/app/pods/folders/route.js b/gui/app/pods/folders/route.js index f0f532fa..0af10b53 100644 --- a/gui/app/pods/folders/route.js +++ b/gui/app/pods/folders/route.js @@ -10,7 +10,6 @@ // https://documize.com import Route from '@ember/routing/route'; - import { inject as service } from '@ember/service'; import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin'; diff --git a/gui/app/pods/folders/template.hbs b/gui/app/pods/folders/template.hbs index a29d8212..b81f7696 100644 --- a/gui/app/pods/folders/template.hbs +++ b/gui/app/pods/folders/template.hbs @@ -1,7 +1,22 @@ +{{layout/nav-bar}} + +
+
+
+
+ {{spaces/space-list spaces=model}} +
+
+
+
+ +
{{#layout/zone-container}} + {{#layout/zone-sidebar}} {{folder/sidebar-zone folders=model noFolder=true onAddSpace=(action 'onAddSpace')}} {{/layout/zone-sidebar}} {{#layout/zone-content}} {{/layout/zone-content}} {{/layout/zone-container}} +
diff --git a/gui/app/styles/app.scss b/gui/app/styles/app.scss index 4e23179d..e8fdb3df 100644 --- a/gui/app/styles/app.scss +++ b/gui/app/styles/app.scss @@ -14,7 +14,7 @@ @import "base.scss"; @import "bootstrap.scss"; @import "widget/widget.scss"; -@import "view/layout-sidebar.scss"; +@import "view/layout.scss"; @import "view/page-search.scss"; @import "view/page-profile.scss"; @import "view/page-customize.scss"; @@ -24,6 +24,9 @@ @import "view/folder/all.scss"; @import "view/document/all.scss"; @import "view/common.scss"; + +@import "view/views.scss"; + @import "vendor.scss"; @import "responsive.scss"; @import "print.scss"; diff --git a/gui/app/styles/bootstrap.scss b/gui/app/styles/bootstrap.scss index ac901edb..7f272c3c 100644 --- a/gui/app/styles/bootstrap.scss +++ b/gui/app/styles/bootstrap.scss @@ -14,6 +14,9 @@ // Variable overrides // +// font +// $font-family-sans-serif: "Helvetica", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; + // colors $blue: $color-primary; $red: $color-red; @@ -36,24 +39,21 @@ $modal-backdrop-opacity: 0.7; $modal-header-border-color: $color-white; $modal-footer-border-color: $color-white; .modal-header { - background-color: $color-gray; + background-color: $color-primary; color: $color-off-white; font-size: 1.2rem; } // rounded corners -// $border-radius: 0rem; -// $border-radius-lg: 0rem; -// $border-radius-sm: 0rem; $border-radius: .125rem; $border-radius-lg: .15rem; $border-radius-sm: .1rem; // dropdown $dropdown-link-color: $color-off-black; -$dropdown-link-hover-color: $color-primary; +$dropdown-link-hover-color: $color-link; $dropdown-link-hover-bg: $color-white; -$dropdown-link-active-color: $color-primary; +$dropdown-link-active-color: $color-link; $dropdown-link-active-bg: $color-white; // form @@ -65,10 +65,13 @@ $input-focus-color: $color-off-black; $input-placeholder-color: $color-gray; $input-focus-border-color: $color-stroke; $input-btn-focus-width: .2rem; -$input-btn-focus-color: rgba($color-gray, .25); +$input-btn-focus-color: rgba($color-primary, .25); -// font -// $font-family-sans-serif: "Helvetica", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"; +// links +$link-color: $color-link; +$link-decoration: none; +$link-hover-color: darken($link-color, 15%) !default; +$link-hover-decoration: none; // diff --git a/gui/app/styles/color.scss b/gui/app/styles/color.scss index 8567cd38..53291f01 100644 --- a/gui/app/styles/color.scss +++ b/gui/app/styles/color.scss @@ -10,20 +10,22 @@ // https://documize.com // Theme colors -$color-primary: #2667af; -$color-link: #0092d3; -$color-border: #f3f5f8; +$color-primary: #351056; +$color-primary-light: #F7F2FF; +$color-link: #1b701e; // Theme-neutral colors -$color-off-white: #f5f5f5; -$color-off-black: #111111; $color-black: #000000; -$color-white: #ffffff; +$color-off-black: #111111; +$color-dark: #434343; +$color-gray: #8b9096; -$color-red: #d04134; -$color-green: #4caf50; +$color-white: #ffffff; +$color-off-white: #f5f5f5; + +$color-red: #b1251b; +$color-green: #1b701e; $color-blue: #2667af; -$color-gray: #8e969e; //8b9096 $color-goldy: #cc9933; $color-table-border: #e1e1e1; @@ -31,6 +33,8 @@ $color-table-header: #f5f5f5; $color-toolbar: #eeeeee; $color-wysiwyg: #3c3c3c; +$color-card: #F9F9F9; +$color-border: #f3f5f8; $color-input: #5a5a5a; $color-stroke: #e1e1e1; $color-tooltip: #a1a1a1; @@ -39,7 +43,7 @@ $color-symbol-box: #dce5e8; $color-symbol-icon: #a4b8be; $color-checkbox: #0092d3; -// gray sidebar +// gray sidebar -- DEAD $color-sidebar: #f5f5f5; $color-sidebar-border: #e1e1e1; $color-sidebar-text: $color-black; @@ -52,31 +56,6 @@ $color-sidebar-navigation: #f2faff; $color-sidebar-navigation-border: #dff0f9; $color-sidebar-toolbar: $color-sidebar-border; -// lightblue sidebar -// $color-sidebar: #f2faff; -// $color-sidebar-border: #dff0f9; -// $color-sidebar-text: $color-black; -// $color-sidebar-link: $color-link; -// $color-nav-button: $color-sidebar; -// $color-nav-button-text: #2667af; -// $color-nav-button-border: #dff0f9; -// $color-selected-item: $color-sidebar; -// $color-sidebar-navigation: $color-gray; -// $color-sidebar-toolbar: $color-sidebar-border; - -// black sidebar -// $color-sidebar: $color-off-black; -// $color-sidebar-border: $color-black; -// $color-sidebar-text: $color-white; -// $color-sidebar-link: orange; -// $color-nav-button: orange; -// $color-nav-button-text: $color-off-black; -// $color-nav-button-border: $color-black; -// $color-selected-item: orange; -// $color-sidebar-navigation: orange; -// $color-sidebar-navigation-border: orange; -// $color-sidebar-toolbar: orange; - // Color utility classes for direct usage in HTML .color-white { color: $color-white !important; diff --git a/gui/app/styles/mixins.scss b/gui/app/styles/mixins.scss index a7d81dfe..b0334188 100644 --- a/gui/app/styles/mixins.scss +++ b/gui/app/styles/mixins.scss @@ -33,3 +33,13 @@ box-shadow: 0 0 0 0.75pt $color-stroke,0 0 3pt 0.75pt $color-stroke; background-color: $color-white; } + +@mixin card() { + background-color: $color-card; + box-shadow: 1px 1px 3px 0px rgba(211,211,211,1); + + &:hover { + background-color: darken($color-card, 3%); + color: $color-link; + } +} diff --git a/gui/app/styles/view/folder/all.scss b/gui/app/styles/view/folder/all.scss index 86ae57c4..64e09e83 100644 --- a/gui/app/styles/view/folder/all.scss +++ b/gui/app/styles/view/folder/all.scss @@ -1,4 +1,3 @@ @import "document.scss"; -@import "folder.scss"; @import "wizard.scss"; @import "settings.scss"; diff --git a/gui/app/styles/view/folder/folder.scss b/gui/app/styles/view/folder/folder.scss deleted file mode 100644 index f14eb625..00000000 --- a/gui/app/styles/view/folder/folder.scss +++ /dev/null @@ -1,45 +0,0 @@ -.folders-list { - > .section { - margin: 30px 0 10px; - - > .heading { - font-size: 0.9rem; - font-weight: bold; - color: $color-gray; - padding-bottom: 5px; - } - - > .message { - font-size: 0.8rem; - color: $color-gray; - margin-top: 10px; - } - - > .list { - padding: 0; - margin: 5px 0 0 15px; - - > .link { - font-size: 1rem; - color: $color-sidebar-text; - text-decoration: none; - - &:hover { - color: $color-sidebar-link; - } - - > .item { - list-style-type: none; - list-style: none; - margin: 0 0 5px; - padding: 0; - } - } - - > .selected { - color: $color-sidebar-link; - font-weight: bold; - } - } - } -} diff --git a/gui/app/styles/view/layout-sidebar.scss b/gui/app/styles/view/layout.scss similarity index 90% rename from gui/app/styles/view/layout-sidebar.scss rename to gui/app/styles/view/layout.scss index e8a2799a..520ecffe 100644 --- a/gui/app/styles/view/layout-sidebar.scss +++ b/gui/app/styles/view/layout.scss @@ -1,3 +1,35 @@ +.nav-bar { + background-color: $color-primary; + padding: 10px 20px; + color: $color-white; + font-size: 1rem; + + .nav-link, .nav-link:visited { + color: $color-white; + + &:hover { + color: darken($color-white, 15%); + } + } + + .nav-title { + font-size: 1.4rem; + font-weight: bold; + } + + .nav-msg { + font-size: 0.875rem; + } + + .nav-right { + float: right; + } +} + + + + +// pre-nov17 UX $sidebar-width: 400px; #wrapper { diff --git a/gui/app/styles/view/spaces.scss b/gui/app/styles/view/spaces.scss new file mode 100644 index 00000000..b284e74b --- /dev/null +++ b/gui/app/styles/view/spaces.scss @@ -0,0 +1,38 @@ +.view-spaces { + > .heading { + font-size: 1.3rem; + font-weight: bold; + color: $color-dark; + text-transform: uppercase; + + > .counter { + font-size: 0.9rem; + font-weight: normal; + color: $color-gray; + display: inline-block; + margin-left: 10px; + } + } + + > .list { + margin: 30px 0; + padding: 0; + + > a { + color: $color-black; + + > .item { + @include card(); + @include ease-in(); + list-style-type: none; + float: left; + margin: 0 20px 20px 0; + padding: 10px; + width: 250px; + height: 100px; + font-size: 1.1rem; + overflow: hidden; + } + } + } +} diff --git a/gui/app/styles/view/views.scss b/gui/app/styles/view/views.scss new file mode 100644 index 00000000..51a5cd46 --- /dev/null +++ b/gui/app/styles/view/views.scss @@ -0,0 +1 @@ +@import "spaces.scss"; diff --git a/gui/app/styles/widget/widget-button.scss b/gui/app/styles/widget/widget-button.scss index 84c976ad..ae0169a3 100644 --- a/gui/app/styles/widget/widget-button.scss +++ b/gui/app/styles/widget/widget-button.scss @@ -320,3 +320,46 @@ display: inline-block; @extend .no-select; } + +.button-icon-white { + display: inline-block; + cursor: default; + @include ease-in(); + + > i { + color: $color-white; + font-size: 2rem; + @include ease-in(); + } + + &:hover { + > i { + color: darken($color-white, 15%); + } + } +} + +.button-icon-gap { + display: inline-block; + margin-left: 5px; +} + +.button-gravatar-white { + display: inline-block; + cursor: default; + position: relative; + overflow: hidden; + width: 35px; + height: 35px; + line-height: 34px; + padding: 0; + border-radius: 50%; + text-align: center; + color: $color-primary; + background-color: $color-white; + @include ease-in(); + + &:hover { + background-color: darken($color-white, 15%); + } +} diff --git a/gui/app/templates/components/layout/nav-bar.hbs b/gui/app/templates/components/layout/nav-bar.hbs new file mode 100644 index 00000000..cb31a688 --- /dev/null +++ b/gui/app/templates/components/layout/nav-bar.hbs @@ -0,0 +1,68 @@ +