mirror of
https://github.com/documize/community.git
synced 2025-08-04 21:15:24 +02:00
Per space label, icon, description
Labels introduce visual grouping and filtering of spaces.
This commit is contained in:
parent
fe8068965c
commit
a211ba051a
106 changed files with 3280 additions and 1008 deletions
|
@ -1,6 +1,6 @@
|
|||
{{layout/logo-heading
|
||||
title="Spaces"
|
||||
desc="Delete spaces, take ownership of shared and orphaned spaces"
|
||||
icon=constants.Icon.Grid1}}
|
||||
icon=constants.Icon.Grid}}
|
||||
|
||||
{{customize/space-admin}}
|
47
gui/app/pods/customize/labels/controller.js
Normal file
47
gui/app/pods/customize/labels/controller.js
Normal file
|
@ -0,0 +1,47 @@
|
|||
// 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 Notifier from '../../../mixins/notifier';
|
||||
import Controller from '@ember/controller';
|
||||
|
||||
export default Controller.extend(Notifier, {
|
||||
labelSvc: service('label'),
|
||||
|
||||
load() {
|
||||
this.get('labelSvc').getAll().then((labels) => {
|
||||
this.set('model', labels);
|
||||
});
|
||||
},
|
||||
|
||||
actions: {
|
||||
onAdd(label) {
|
||||
this.get('labelSvc').add(label).then(() => {
|
||||
this.load();
|
||||
this.notifySuccess('Label added');
|
||||
});
|
||||
},
|
||||
|
||||
onDelete(id) {
|
||||
this.get('labelSvc').delete(id).then(() => {
|
||||
this.load();
|
||||
this.notifySuccess('Label deleted');
|
||||
});
|
||||
},
|
||||
|
||||
onUpdate(label) {
|
||||
this.get('labelSvc').update(label).then(() => {
|
||||
this.load();
|
||||
this.notifySuccess('Label saved');
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
34
gui/app/pods/customize/labels/route.js
Normal file
34
gui/app/pods/customize/labels/route.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
// 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 AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default Route.extend(AuthenticatedRouteMixin, {
|
||||
labelSvc: service('label'),
|
||||
appMeta: service(),
|
||||
session: service(),
|
||||
|
||||
beforeModel() {
|
||||
if (!this.get("session.isAdmin")) {
|
||||
this.transitionTo('auth.login');
|
||||
}
|
||||
},
|
||||
|
||||
model() {
|
||||
return this.get('labelSvc').getAll();
|
||||
},
|
||||
|
||||
activate() {
|
||||
this.get('browser').setTitle('Space Labels');
|
||||
}
|
||||
});
|
10
gui/app/pods/customize/labels/template.hbs
Normal file
10
gui/app/pods/customize/labels/template.hbs
Normal file
|
@ -0,0 +1,10 @@
|
|||
{{layout/logo-heading
|
||||
title="Labels"
|
||||
desc="Group and navigate spaces with visual labels"
|
||||
icon=constants.Icon.Checkbox}}
|
||||
|
||||
{{customize/space-labels
|
||||
labels=model
|
||||
onAdd=(action "onAdd")
|
||||
onDelete=(action "onDelete")
|
||||
onUpdate=(action "onUpdate")}}
|
|
@ -8,6 +8,22 @@
|
|||
<i class={{concat "dicon " constants.Icon.Settings}} />
|
||||
<div class="name">General</div>
|
||||
{{/link-to}}
|
||||
{{#link-to "customize.labels" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Checkbox}} />
|
||||
<div class="name">Labels</div>
|
||||
{{/link-to}}
|
||||
{{#link-to "customize.folders" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Grid}} />
|
||||
<div class="name">Spaces</div>
|
||||
{{/link-to}}
|
||||
{{#link-to "customize.users" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Person}} />
|
||||
<div class="name">User Management</div>
|
||||
{{/link-to}}
|
||||
{{#link-to "customize.groups" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.People}} />
|
||||
<div class="name">User Groups</div>
|
||||
{{/link-to}}
|
||||
{{#link-to "customize.integrations" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Integrations}} />
|
||||
<div class="name">Integrations</div>
|
||||
|
@ -17,26 +33,10 @@
|
|||
<i class={{concat "dicon " constants.Icon.Send}} />
|
||||
<div class="name">Mail Server</div>
|
||||
{{/link-to}}
|
||||
{{/if}}
|
||||
{{#link-to "customize.users" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Person}} />
|
||||
<div class="name">User Management</div>
|
||||
{{/link-to}}
|
||||
{{#link-to "customize.groups" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.People}} />
|
||||
<div class="name">User Groups</div>
|
||||
{{/link-to}}
|
||||
{{#if session.isGlobalAdmin}}
|
||||
{{#link-to "customize.auth" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Locked}} />
|
||||
<div class="name">Authentication</div>
|
||||
{{/link-to}}
|
||||
{{/if}}
|
||||
{{#link-to "customize.folders" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Grid1}} />
|
||||
<div class="name">Spaces</div>
|
||||
{{/link-to}}
|
||||
{{#if session.isGlobalAdmin}}
|
||||
{{#link-to "customize.search" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Search}} />
|
||||
<div class="name">Search</div>
|
||||
|
@ -60,7 +60,7 @@
|
|||
{{/if}}
|
||||
{{#link-to "customize.product" activeClass="selected" class="item" tagName="div"}}
|
||||
<i class={{concat "dicon " constants.Icon.Announce}} />
|
||||
<div class="name">Documize Changelog</div>
|
||||
<div class="name">Changelog</div>
|
||||
{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
<div class="section">
|
||||
{{document/sidebar-meta
|
||||
tab=tab
|
||||
roles=roles
|
||||
pages=pages
|
||||
space=folder
|
||||
|
@ -17,11 +16,15 @@
|
|||
{{ui/ui-spacer size=300}}
|
||||
|
||||
<div class="text-center">
|
||||
{{#ui/ui-toolbar dark=true light=true raised=true large=false bordered=true}}
|
||||
{{#ui/ui-toolbar dark=false light=true raised=true large=false bordered=true}}
|
||||
{{ui/ui-toolbar-icon icon=constants.Icon.Index color=constants.Color.Gray tooltip="Table of contents"
|
||||
selected=(eq sidebarTab "toc") onClick=(action "onSidebarChange" "toc")}}
|
||||
{{ui/ui-toolbar-icon icon=constants.Icon.Attachment color=constants.Color.Gray tooltip="Attachments"
|
||||
selected=(eq sidebarTab "files") onClick=(action "onSidebarChange" "files")}}
|
||||
{{#if (eq appMeta.edition constants.Product.EnterpriseEdition)}}
|
||||
{{ui/ui-toolbar-icon icon=constants.Icon.Chat color=constants.Color.Gray tooltip="Comments & Feedback"
|
||||
selected=(eq sidebarTab "feedback") onClick=(action "onSidebarChange" "feedback")}}
|
||||
{{/if}}
|
||||
{{/ui/ui-toolbar}}
|
||||
</div>
|
||||
</div>
|
||||
|
@ -30,7 +33,6 @@
|
|||
|
||||
{{#if (eq sidebarTab "toc")}}
|
||||
{{document/sidebar-toc
|
||||
tab=tab
|
||||
page=page
|
||||
roles=roles
|
||||
pages=pages
|
||||
|
@ -42,11 +44,18 @@
|
|||
onPageLevelChange=(action "onPageLevelChange")
|
||||
onPageSequenceChange=(action "onPageSequenceChange")}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq sidebarTab "files")}}
|
||||
{{document/sidebar-attachment
|
||||
document=document
|
||||
permissions=permissions}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq sidebarTab "feedback")}}
|
||||
{{enterprise/sidebar-feedback
|
||||
document=document
|
||||
permissions=permissions}}
|
||||
{{/if}}
|
||||
{{/layout/master-sidebar}}
|
||||
|
||||
{{#layout/master-content}}
|
||||
|
|
|
@ -21,6 +21,20 @@
|
|||
<i class={{concat "dicon " constants.Icon.Tag}} />
|
||||
<div class="name">Tags</div>
|
||||
</div>
|
||||
{{#if (eq appMeta.edition constants.Product.EnterpriseEdition)}}
|
||||
{{#if model.permissions.documentApprove}}
|
||||
<div class="item {{if (eq tab "protection") "selected"}}" {{action "onTab" "protection"}}>
|
||||
<i class={{concat "dicon " constants.Icon.Locked}} />
|
||||
<div class="name">Change Control</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{#if model.permissions.documentVersion}}
|
||||
<div class="item {{if (eq tab "versions") "selected"}}" {{action "onTab" "versions"}}>
|
||||
<i class={{concat "dicon " constants.Icon.Copy}} />
|
||||
<div class="name">Versions</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
{{/layout/master-sidebar}}
|
||||
|
@ -49,4 +63,25 @@
|
|||
permissions=model.permissions
|
||||
onSaveDocument=(action "onSaveDocument")}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq tab "protection")}}
|
||||
{{document/settings-protection
|
||||
space=model.folder
|
||||
spaces=model.folders
|
||||
document=model.document
|
||||
permissions=model.permissions
|
||||
onRefresh=(action "onRefresh")
|
||||
onSaveDocument=(action "onSaveDocument")}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq tab "versions")}}
|
||||
{{enterprise/settings-version
|
||||
space=model.folder
|
||||
spaces=model.folders
|
||||
document=model.document
|
||||
permissions=model.permissions
|
||||
versions=model.versions
|
||||
onRefresh=(action "onRefresh")
|
||||
onSaveDocument=(action "onSaveDocument")}}
|
||||
{{/if}}
|
||||
{{/layout/master-content}}
|
||||
|
|
|
@ -47,6 +47,7 @@ export default Route.extend(AuthenticatedRouteMixin, {
|
|||
return hash({
|
||||
folder: this.modelFor('folder').folder,
|
||||
permissions: this.modelFor('folder').permissions,
|
||||
labels: this.modelFor('folder').labels,
|
||||
folders: folders,
|
||||
documents: documents,
|
||||
documentsDraft: _.filter(documents, function(d) { return d.get('lifecycle') === constants.Lifecycle.Draft; }),
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
{{folder/space-sidebar
|
||||
spaces=model.folders
|
||||
space=model.folder
|
||||
labels=model.labels
|
||||
templates=model.templates
|
||||
permissions=model.permissions
|
||||
documents=model.documents
|
||||
|
@ -19,8 +20,10 @@
|
|||
{{#layout/master-content}}
|
||||
<div class="grid-container-6-4">
|
||||
<div class="grid-cell-1">
|
||||
{{layout/page-heading title=model.folder.name}}
|
||||
{{layout/page-desc desc="some space desc"}}
|
||||
{{layout/logo-heading
|
||||
title=model.folder.name
|
||||
desc=model.folder.desc
|
||||
meta=model.folder.icon}}
|
||||
</div>
|
||||
<div class="grid-cell-2 grid-cell-right">
|
||||
{{folder/space-toolbar
|
||||
|
@ -35,8 +38,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=400}}
|
||||
|
||||
{{folder/documents-list
|
||||
documents=filteredDocs
|
||||
spaces=model.folders
|
||||
|
|
|
@ -11,14 +11,15 @@
|
|||
|
||||
import { Promise as EmberPromise, hash } from 'rsvp';
|
||||
import { inject as service } from '@ember/service';
|
||||
import Route from '@ember/routing/route';
|
||||
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||
import Route from '@ember/routing/route';
|
||||
|
||||
export default Route.extend(AuthenticatedRouteMixin, {
|
||||
documentService: service('document'),
|
||||
folderService: service('folder'),
|
||||
templateService: service('template'),
|
||||
session: service(''),
|
||||
labelSvc: service('label'),
|
||||
|
||||
beforeModel() {
|
||||
this.set('folderId', this.paramsFor('folder').folder_id)
|
||||
|
@ -41,7 +42,8 @@ export default Route.extend(AuthenticatedRouteMixin, {
|
|||
permissions: this.get('permissions'),
|
||||
folders: this.get('folderService').getAll(),
|
||||
documents: this.get('documentService').getAllBySpace(params.folder_id),
|
||||
templates: this.get('templateService').getSavedTemplates(params.folder_id)
|
||||
templates: this.get('templateService').getSavedTemplates(params.folder_id),
|
||||
labels: this.get('labelSvc').getAll()
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-rout
|
|||
import Route from '@ember/routing/route';
|
||||
|
||||
export default Route.extend(AuthenticatedRouteMixin, {
|
||||
|
||||
model() {
|
||||
this.get('browser').setTitle(this.modelFor('folder').folder.get('name'));
|
||||
|
||||
|
@ -23,6 +22,7 @@ export default Route.extend(AuthenticatedRouteMixin, {
|
|||
folders: this.modelFor('folder').folders,
|
||||
permissions: this.modelFor('folder').permissions,
|
||||
templates: this.modelFor('folder').templates,
|
||||
labels: this.modelFor('folder').labels,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
<div class="list">
|
||||
<div class="item {{if (eq tab "general") "selected"}}" {{action "onTab" "general"}}>
|
||||
<i class={{concat "dicon " constants.Icon.Settings}} />
|
||||
<div class="name">Options</div>
|
||||
<div class="name">Meta</div>
|
||||
</div>
|
||||
<div class="item {{if (eq tab "categories") "selected"}}" {{action "onTab" "categories"}}>
|
||||
<i class={{concat "dicon " constants.Icon.Category}} />
|
||||
|
@ -44,7 +44,7 @@
|
|||
|
||||
{{#layout/master-content}}
|
||||
{{#if (eq tab "general")}}
|
||||
{{folder/settings-general permissions=model.permissions space=model.folder}}
|
||||
{{folder/settings-general permissions=model.permissions space=model.folder labels=model.labels}}
|
||||
{{/if}}
|
||||
|
||||
{{#if (eq tab "permissions")}}
|
||||
|
|
|
@ -78,7 +78,7 @@ export default Controller.extend(AuthMixin, Modals, {
|
|||
|
||||
switch(view) {
|
||||
case 'all':
|
||||
this.set('selectedSpaces', this.get('model'));
|
||||
this.set('selectedSpaces', this.get('model.spaces'));
|
||||
break;
|
||||
case 'public':
|
||||
this.set('selectedSpaces', this.get('publicSpaces'));
|
||||
|
@ -89,6 +89,9 @@ export default Controller.extend(AuthMixin, Modals, {
|
|||
case 'personal':
|
||||
this.set('selectedSpaces', this.get('personalSpaces'));
|
||||
break;
|
||||
default:
|
||||
this.set('selectedSpaces', this.get(view));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
//
|
||||
// https://documize.com
|
||||
|
||||
import { hash } from 'rsvp';
|
||||
import Route from '@ember/routing/route';
|
||||
import { inject as service } from '@ember/service';
|
||||
import AuthenticatedRouteMixin from 'ember-simple-auth/mixins/authenticated-route-mixin';
|
||||
|
@ -17,6 +18,7 @@ export default Route.extend(AuthenticatedRouteMixin, {
|
|||
appMeta: service(),
|
||||
folderService: service('folder'),
|
||||
localStorage: service(),
|
||||
labelSvc: service('label'),
|
||||
|
||||
beforeModel() {
|
||||
if (this.get('appMeta.setupMode')) {
|
||||
|
@ -26,19 +28,22 @@ export default Route.extend(AuthenticatedRouteMixin, {
|
|||
},
|
||||
|
||||
model() {
|
||||
return this.get('folderService').getAll();
|
||||
return hash({
|
||||
spaces: this.get('folderService').getAll(),
|
||||
labels: this.get('labelSvc').getAll()
|
||||
});
|
||||
},
|
||||
|
||||
setupController(controller, model) {
|
||||
this._super(controller, model);
|
||||
controller.set('selectedSpaces', model);
|
||||
controller.set('selectedSpaces', model.spaces);
|
||||
|
||||
let constants = this.get('constants');
|
||||
let publicSpaces = [];
|
||||
let protectedSpaces = [];
|
||||
let personalSpaces = [];
|
||||
|
||||
_.each(model, space => {
|
||||
_.each(model.spaces, space => {
|
||||
if (space.get('spaceType') === constants.SpaceType.Public) {
|
||||
publicSpaces.pushObject(space);
|
||||
}
|
||||
|
@ -50,6 +55,14 @@ export default Route.extend(AuthenticatedRouteMixin, {
|
|||
}
|
||||
});
|
||||
|
||||
_.each(model.labels, label => {
|
||||
let spaces = _.where(model.spaces, {labelId: label.get('id')});
|
||||
label.set('count', spaces.length);
|
||||
controller.set(label.get('id'), spaces);
|
||||
});
|
||||
|
||||
controller.set('labels', model.labels);
|
||||
controller.set('spaces', publicSpaces);
|
||||
controller.set('publicSpaces', publicSpaces);
|
||||
controller.set('protectedSpaces', protectedSpaces);
|
||||
controller.set('personalSpaces', personalSpaces);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
<div class="list">
|
||||
<div class="item {{if (eq selectedView "all") "selected"}}" {{action "onSelect" "all"}}>
|
||||
<i class={{concat "dicon " constants.Icon.All}} />
|
||||
<div class="name">All ({{model.length}})</div>
|
||||
<div class="name">All ({{model.spaces.length}})</div>
|
||||
</div>
|
||||
<div class="item {{if (eq selectedView "public") "selected"}}" {{action "onSelect" "public"}}>
|
||||
<i class={{concat "dicon " constants.Icon.World}} />
|
||||
|
@ -24,6 +24,25 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{ui/ui-spacer size=300}}
|
||||
|
||||
<div class="section">
|
||||
<div class="title">label</div>
|
||||
{{#if labels}}
|
||||
<div class="list">
|
||||
{{#each labels as |label|}}
|
||||
<div class="item {{if (eq selectedView label.id) "selected"}}" {{action "onSelect" label.id}}>
|
||||
<i class={{concat "dicon " constants.Icon.Checkbox}}
|
||||
style={{label.bgfgColor}}/>
|
||||
<div class="name">{{label.name}} ({{label.count}})</div>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="empty">No labels</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/layout/master-sidebar}}
|
||||
|
||||
{{#layout/master-content}}
|
||||
|
@ -46,7 +65,7 @@
|
|||
|
||||
{{ui/ui-spacer size=400}}
|
||||
|
||||
{{spaces/space-list spaces=selectedSpaces}}
|
||||
{{spaces/space-list spaces=selectedSpaces labels=labels}}
|
||||
|
||||
<div class="modal" tabindex="-1" role="dialog" id="add-space-modal">
|
||||
<div class="modal-dialog" role="document">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue