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

document tag editor

This commit is contained in:
Harvey Kandola 2017-12-05 10:46:53 +00:00
parent 8415f11303
commit 666ab3151e
6 changed files with 122 additions and 200 deletions

View file

@ -13,13 +13,18 @@ import { computed } from '@ember/object';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import { A } from "@ember/array"
import { schedule } from '@ember/runloop';
export default Component.extend({
documentService: service('document'),
categoryService: service('category'),
sessionService: service('session'),
newCategory: '',
maxTags: 3,
categories: A([]),
newCategory: '',
tagz: A([]),
tagzModal: A([]),
newTag: '',
showCategoryModal: false,
hasCategories: computed('categories', function() {
return this.get('categories').length > 0;
@ -36,6 +41,36 @@ export default Component.extend({
this.load();
},
didInsertElement() {
this._super(...arguments);
$('#document-tags-modal').on('show.bs.modal', (event) => { // eslint-disable-line no-unused-vars
schedule('afterRender', () => {
$("#add-tag-field").focus();
$("#add-tag-field").off("keydown").on("keydown", function(e) {
if (e.shiftKey) {
return false;
}
if (e.which === 13 || e.which === 45 || e.which === 189 || e.which === 8 || e.which === 127 || (e.which >= 65 && e.which <= 90) || (e.which >= 97 && e.which <= 122) || (e.which >= 48 && e.which <= 57)) {
return true;
}
return false;
});
// make copy of tags for editing
this.set('tagzEdit', this.get('tagz'));
});
});
},
willDestroyElement() {
this._super(...arguments);
$("#add-tag-field").off("keydown");
},
load() {
this.get('categoryService').getUserVisible(this.get('folder.id')).then((categories) => {
let cats = A(categories);
@ -109,6 +144,48 @@ export default Component.extend({
});
return true;
}
}
},
onAddTag(e) {
e.preventDefault();
let tags = this.get("tagzEdit");
let tag = this.get('newTag');
tag = tag.toLowerCase().trim();
// empty or dupe?
if (tag.length === 0 || _.contains(tags, tag) || tags.length >= this.get('maxTags') || tag.startsWith('-')) {
$('#add-tag-field').addClass('is-invalid');
return;
}
tags.pushObject(tag);
this.set('tagzEdit', tags);
this.set('newTag', '');
$('#add-tag-field').removeClass('is-invalid');
},
onRemoveTag(tagToRemove) {
this.set('tagzEdit', _.without(this.get("tagzEdit"), tagToRemove));
},
onSaveTags() {
let tags = this.get("tagzEdit");
let save = "#";
_.each(tags, function(tag) {
save = save + tag + "#";
});
let doc = this.get('document');
doc.set('tags', save);
this.attrs.onSaveDocument(doc);
this.load();
this.set('newTag', '');
$('#document-tags-modal').modal('hide');
$('#document-tags-modal').modal('dispose');
},
}
});

View file

@ -1,112 +0,0 @@
// 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 { computed } from '@ember/object';
import Component from '@ember/component';
export default Component.extend({
documentTags: [],
tagz: [],
newTag: "",
maxTags: 3,
canAdd: false,
emptyState: computed('tagz', function() {
return (this.get('tagz').length === 0 && !this.get('permissions.documentEdit'));
}),
init() {
this._super(...arguments);
let tagz = [];
if (!_.isUndefined(this.get('documentTags')) && this.get('documentTags').length > 1) {
let tags = this.get('documentTags').split('#');
_.each(tags, function(tag) {
if (tag.length > 0) {
tagz.pushObject(tag);
}
});
}
this.set('tagz', tagz);
this.set('canAdd', this.get('permissions.documentEdit') && this.get('tagz').get('length') < 3);
},
didUpdateAttrs() {
this._super(...arguments);
this.set('canAdd', this.get('permissions.documentEdit') && this.get('tagz').get('length') < 3);
},
willDestroyElement() {
this._super(...arguments);
$("#add-tag-field").off("keydown");
},
actions: {
onTagEditor() {
$("#add-tag-field").off("keydown").on("keydown", function(e) {
if (e.shiftKey) {
return false;
}
if (e.which === 13 || e.which === 45 || e.which === 189 || e.which === 8 || e.which === 127 || (e.which >= 65 && e.which <= 90) || (e.which >= 97 && e.which <= 122) || (e.which >= 48 && e.which <= 57)) {
return true;
}
return false;
});
},
addTag() {
let tags = this.get("tagz");
let tag = this.get('newTag');
tag = tag.toLowerCase().trim();
// empty or dupe?
if (tag.length === 0 || _.contains(tags, tag) || tags.length >= this.get('maxTags') || tag.startsWith('-')) {
return false;
}
tags.pushObject(tag);
this.set('tagz', tags);
this.set('newTag', '');
let save = "#";
_.each(tags, function(tag) {
save = save + tag + "#";
});
this.get('onChange')(save);
return true;
},
// removeTag removes specified tag from the list of tags associated with this document.
removeTag(tagToRemove) {
let tags = this.get("tagz");
let save = "";
tags = _.without(tags, tagToRemove);
_.each(tags, function(tag) {
save = save + tag + "#";
});
if (save.length) {
save = "#" + save;
}
this.set('tagz', tags);
this.get('onChange')(save);
},
}
});

View file

@ -9,8 +9,7 @@
{{/toolbar/t-toolbar}}
{{document/document-heading document=model.document permissions=model.permissions onSaveDocument=(action 'onSaveDocument')}}
{{document/document-meta document=model.document folder=model.folder folders=model.folders permissions=model.permissions}}
{{document/tag-editor documentTags=model.document.tags permissions=model.permissions onChange=(action 'onTagChange')}}
{{document/document-meta document=model.document folder=model.folder folders=model.folders permissions=model.permissions onSaveDocument=(action 'onSaveDocument')}}
<div id="zone-document-content" class="zone-document-content">
<div class="document-header-zone">

View file

@ -54,49 +54,3 @@
}
}
}
.document-category {
display: inline-block;
margin: 0 0 0 30px;
> .regular-button {
margin-right: 10px;
}
> .caption {
text-transform: uppercase;
color: $color-gray;
font-weight: bold;
font-size: 1.0rem;
margin: 0 0 10px 0;
}
}
.document-category-dialog {
height: 200px;
overflow-y: auto;
margin: 0;
padding: 0;
}
.document-tags {
margin: 20px 0 0 0;
> .caption {
text-transform: uppercase;
color: $color-gray;
font-weight: bold;
font-size: 1.0rem;
margin: 0 0 10px 0;
}
> .regular-button {
margin-right: 10px;
text-transform: lowercase;
}
> .none {
color: $color-gray;
font-size: 0.9rem;
}
}

View file

@ -2,13 +2,7 @@
<div class="document-customfields">
<div class="row">
<div class="col-2 heading">Categories
{{#if canSelectCategory}}
<div class="action-button button-icon-green button-icon-small align-middle" {{action 'onShowCategoryModal'}}>
<i class="material-icons align-middle">edit</i>
</div>
{{/if}}
</div>
<div class="col-2 heading">Categories</div>
<div class="col-10 value">
{{#each selectedCategories as |cat|}}
{{#link-to 'folder' folder.id folder.slug (query-params category=cat.id)}}
@ -24,6 +18,11 @@
{{/if}}
{{/if}}
{{/each}}
{{#if canSelectCategory}}
<div class="action-button button-icon-gray button-icon-small align-middle" {{action 'onShowCategoryModal'}}>
<i class="material-icons align-middle">edit</i>
</div>
{{/if}}
</div>
</div>
@ -33,6 +32,11 @@
{{#each tagz as |t index|}}
<a href="/search?tag={{t}}">{{concat '#' t}}</a>&nbsp;&nbsp;
{{/each}}
{{#if canSelectCategory}}
<div class="action-button button-icon-gray button-icon-small align-middle" data-toggle="modal" data-target="#document-tags-modal" data-backdrop="static">
<i class="material-icons align-middle">edit</i>
</div>
{{/if}}
</div>
</div>
@ -40,9 +44,37 @@
</div>
{{#if permissions.documentEdit}}
{{#ui/ui-dialog title="Set Document Cateogories" confirmCaption="Select" buttonType="btn-outline-success" show=showCategoryModal onAction=(action 'onSaveCategory')}}
{{#ui/ui-dialog title="Document Categories" confirmCaption="Select" buttonType="btn-outline-success" show=showCategoryModal onAction=(action 'onSaveCategory')}}
<p>Select who can view documents within category</p>
{{ui/ui-list-picker items=categories nameField='category' singleSelect=false}}
{{/ui/ui-dialog}}
{{/if}}
<div id="document-tags-modal" class="modal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">Document Tags</div>
<div class="modal-body">
<form onsubmit={{action 'onAddTag'}}>
<div class="form-group">
<label for="add-tag-field">Specify up to three tags per document</label>
{{#each tagzEdit as |t|}}
<div class="m-3 text-secondary">
<div class="button-icon-danger button-icon-small align-middle" {{action 'onRemoveTag' t}}>
<i class="material-icons">clear</i>
</div>
{{concat '#' t}}
</div>
{{/each}}
{{focus-input type='text' id="add-tag-field" class="form-control mousetrap" placeholder="Tag name" value=newTag}}
<small class="form-text text-muted">Lowercase, characters, numbers, hyphens only</small>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-outline-secondary" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-outline-success" onclick={{action 'onSaveTags'}}>Save</button>
</div>
</div>
</div>
</div>
{{/if}}

View file

@ -1,28 +0,0 @@
<div class="document-tags">
<div class="caption">Tag</div>
{{#each tagz as |t index|}}
<div class="regular-button button-gray {{unless permissions.documentEdit 'cursor-auto'}}" id="{{concat 'delete-tag-' index}}">{{concat '#' t}}</div>
{{/each}}
{{#if canAdd}}
<div class="regular-button button-white" id="document-tag-button">
<i class="material-icons">add</i>
</div>
{{#dropdown-dialog tagName="span" target="document-tag-button" position="bottom left" button="Add" color="flat-green" onAction=(action 'addTag') focusOn="add-tag-field" onOpenCallback=(action 'onTagEditor') targetOffset="20px 0"}}
<div class="input-control">
<label>Tag</label>
<div class="tip">Lowercase letters, numbers, dashes</div>
{{focus-input id="add-tag-field" value=newTag type="text"}}
</div>
{{/dropdown-dialog}}
{{/if}}
{{#if permissions.documentEdit}}
{{#each tagz as |t index|}}
{{#dropdown-dialog target=(concat 'delete-tag-' index) position="bottom left" button="Delete" color="flat-red" onAction=(action 'removeTag' t)}}
<p>Are you sure you want delete this tag?</p>
{{/dropdown-dialog}}
{{/each}}
{{/if}}
{{#if emptyState}}
<div class="none">none</div>
{{/if}}
</div>