mirror of
https://github.com/documize/community.git
synced 2025-07-22 14:49:42 +02:00
Make copy/move process use dropdowns for selection
We currently use keyword searching to find target documents. Replace this with space and document list dropdown for quicker and easier target document selection.
This commit is contained in:
parent
a90c5834fa
commit
82ddcc057d
4 changed files with 106 additions and 139 deletions
|
@ -26,10 +26,9 @@ export default Component.extend(Notifier, ModalMixin, {
|
||||||
deleteChildren: false,
|
deleteChildren: false,
|
||||||
blockTitle: "",
|
blockTitle: "",
|
||||||
blockExcerpt: "",
|
blockExcerpt: "",
|
||||||
// canEdit: false,
|
targetSpace: null,
|
||||||
canDelete: false,
|
targetDocs: null,
|
||||||
canMove: false,
|
targetDoc: null,
|
||||||
docSearchFilter: '',
|
|
||||||
|
|
||||||
// eslint-disable-next-line ember/no-observers
|
// eslint-disable-next-line ember/no-observers
|
||||||
onKeywordChange: observer('docSearchFilter', function() {
|
onKeywordChange: observer('docSearchFilter', function() {
|
||||||
|
@ -39,12 +38,6 @@ export default Component.extend(Notifier, ModalMixin, {
|
||||||
emptySearch: computed('docSearchResults', function() {
|
emptySearch: computed('docSearchResults', function() {
|
||||||
return this.get('docSearchResults.length') === 0;
|
return this.get('docSearchResults.length') === 0;
|
||||||
}),
|
}),
|
||||||
hasMenuPermissions: computed('permissions.{documentCopy,documentTemplate}', 'userPendingItem', 'canEdit', 'canMove', 'canDelete', function() {
|
|
||||||
let permissions = this.get('permissions');
|
|
||||||
|
|
||||||
return permissions.get('documentCopy') || permissions.get('documentTemplate') ||
|
|
||||||
this.get('canEdit') || this.get('canMove') || this.get('canDelete');
|
|
||||||
}),
|
|
||||||
canEdit: computed('permissions', 'document', 'pages', function() {
|
canEdit: computed('permissions', 'document', 'pages', function() {
|
||||||
let constants = this.get('constants');
|
let constants = this.get('constants');
|
||||||
let permissions = this.get('permissions');
|
let permissions = this.get('permissions');
|
||||||
|
@ -59,7 +52,7 @@ export default Component.extend(Notifier, ModalMixin, {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.docSearchResults = [];
|
|
||||||
this.state = {
|
this.state = {
|
||||||
actionablePage: false,
|
actionablePage: false,
|
||||||
upDisabled: true,
|
upDisabled: true,
|
||||||
|
@ -74,11 +67,6 @@ export default Component.extend(Notifier, ModalMixin, {
|
||||||
this._super(...arguments);
|
this._super(...arguments);
|
||||||
this.modalInputFocus('#publish-page-modal-' + this.get('page.id'), '#block-title-' + this.get('page.id'));
|
this.modalInputFocus('#publish-page-modal-' + this.get('page.id'), '#block-title-' + this.get('page.id'));
|
||||||
|
|
||||||
let permissions = this.get('permissions');
|
|
||||||
// this.set('canEdit', permissions.get('documentEdit'));
|
|
||||||
this.set('canDelete', permissions.get('documentDelete'));
|
|
||||||
this.set('canMove', permissions.get('documentMove'));
|
|
||||||
|
|
||||||
this.setState(this.get('page.id'));
|
this.setState(this.get('page.id'));
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -101,19 +89,12 @@ export default Component.extend(Notifier, ModalMixin, {
|
||||||
},
|
},
|
||||||
|
|
||||||
willDestroyElement() {
|
willDestroyElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
let clip = this.get('clip');
|
let clip = this.get('clip');
|
||||||
if (!_.isUndefined(clip)) clip.destroy();
|
if (!_.isUndefined(clip)) clip.destroy();
|
||||||
},
|
},
|
||||||
|
|
||||||
searchDocs() {
|
|
||||||
let payload = { keywords: this.get('docSearchFilter').trim(), doc: true };
|
|
||||||
if (payload.keywords.length == 0) return;
|
|
||||||
|
|
||||||
this.get('searchService').find(payload).then((response)=> {
|
|
||||||
this.set('docSearchResults', response);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// Controls what user can do with the toc enty for this page
|
// Controls what user can do with the toc enty for this page
|
||||||
setState(pageId) {
|
setState(pageId) {
|
||||||
let toc = this.get('pages');
|
let toc = this.get('pages');
|
||||||
|
@ -196,45 +177,55 @@ export default Component.extend(Notifier, ModalMixin, {
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onSelectSearchResult(documentId) {
|
onShowCopyModal() {
|
||||||
let results = this.get('docSearchResults');
|
this.send('onSelectSpace', this.get('folder'));
|
||||||
results.forEach((d) => {
|
this.modalOpen('#copy-page-modal-' + this.get('page.id'), {show:true});
|
||||||
d.set('selected', d.get('documentId') === documentId);
|
},
|
||||||
});
|
|
||||||
this.set('docSearchResults', results);
|
onShowMoveModal() {
|
||||||
|
this.send('onSelectSpace', this.get('folder'));
|
||||||
|
this.modalOpen('#move-page-modal-' + this.get('page.id'), {show:true});
|
||||||
},
|
},
|
||||||
|
|
||||||
onCopyPage() {
|
onCopyPage() {
|
||||||
let item = this.get('docSearchResults').findBy('selected', true);
|
let targetDoc = this.get('targetDoc');
|
||||||
let documentId = !_.isUndefined(item) ? item.get('documentId') : '';
|
if (_.isNull(targetDoc)) return;
|
||||||
|
|
||||||
if (_.isEmpty(documentId)) return;
|
|
||||||
|
|
||||||
this.modalClose('#copy-page-modal-' + this.get('page.id'));
|
this.modalClose('#copy-page-modal-' + this.get('page.id'));
|
||||||
|
|
||||||
let cb = this.get('onCopyPage');
|
this.get('onCopyPage')(targetDoc.get('id'));
|
||||||
cb(documentId);
|
this.get('refresh')();
|
||||||
|
|
||||||
let refresh = this.get('refresh');
|
|
||||||
refresh();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onMovePage() {
|
onMovePage() {
|
||||||
let item = this.get('docSearchResults').findBy('selected', true);
|
let targetDoc = this.get('targetDoc');
|
||||||
let documentId = !_.isUndefined(item) ? item.get('documentId') : '';
|
if (_.isNull(targetDoc)) return;
|
||||||
|
|
||||||
if (_.isEmpty(documentId)) return;
|
|
||||||
|
|
||||||
// can't move into self
|
|
||||||
if (documentId === this.get('document.id')) return;
|
|
||||||
|
|
||||||
this.modalClose('#move-page-modal-' + this.get('page.id'));
|
this.modalClose('#move-page-modal-' + this.get('page.id'));
|
||||||
|
|
||||||
let cb = this.get('onMovePage');
|
this.get('onMovePage')(targetDoc.get('id'));
|
||||||
cb(documentId);
|
this.get('refresh')();
|
||||||
|
},
|
||||||
|
|
||||||
let refresh = this.get('refresh');
|
// Load up documents for selected space and select the first one.
|
||||||
refresh();
|
onSelectSpace(space) {
|
||||||
|
this.set('targetSpace', space);
|
||||||
|
|
||||||
|
this.get('documentService').getAllBySpace(space.get('id')).then((docs) => {
|
||||||
|
this.set('targetDocs', docs);
|
||||||
|
|
||||||
|
if (space.get('id') === this.get('folder.id')) {
|
||||||
|
this.set('targetDoc', this.get('document'));
|
||||||
|
} else {
|
||||||
|
if (docs.length > 0) {
|
||||||
|
this.set('targetDoc', docs[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
onSelectDoc(doc) {
|
||||||
|
this.set('targetDoc', doc);
|
||||||
},
|
},
|
||||||
|
|
||||||
// Page up -- above pages shunt down
|
// Page up -- above pages shunt down
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
pages=pages
|
pages=pages
|
||||||
roles=roles
|
roles=roles
|
||||||
folder=folder
|
folder=folder
|
||||||
|
folders=folders
|
||||||
blocks=blocks
|
blocks=blocks
|
||||||
tabMode=tabMode
|
tabMode=tabMode
|
||||||
pending=pending
|
pending=pending
|
||||||
|
|
|
@ -10,32 +10,35 @@
|
||||||
<div class="grid-cell-2 grid-cell-right grid-cell-middle">
|
<div class="grid-cell-2 grid-cell-right grid-cell-middle">
|
||||||
<div class="section-heading no-print" id="page-toolbar-{{ page.id }}">
|
<div class="section-heading no-print" id="page-toolbar-{{ page.id }}">
|
||||||
<div class="section-toolbar">
|
<div class="section-toolbar">
|
||||||
{{#unless (eq document.protection constants.ProtectionType.Lock)}}
|
|
||||||
{{#if canEdit}}
|
{{#if canEdit}}
|
||||||
<i class="add-section dicon {{constants.Icon.Plus}}" {{action "onShowSectionWizard" page}}>
|
<i class="add-section dicon {{constants.Icon.Plus}}" {{action "onShowSectionWizard" page}}>
|
||||||
{{#attach-tooltip showDelay=1000}}Insert section above{{/attach-tooltip}}
|
{{#attach-tooltip showDelay=1000}}Insert section above{{/attach-tooltip}}
|
||||||
</i>
|
</i>
|
||||||
<div class="gap"/>
|
<div class="gap"/>
|
||||||
<i class="dicon {{constants.Icon.Edit}}" {{action "onEdit"}} />
|
<i class="dicon {{constants.Icon.Edit}}" {{action "onEdit"}} />
|
||||||
{{/if}}
|
|
||||||
{{#if hasMenuPermissions}}
|
|
||||||
<div class="gap"/>
|
<div class="gap"/>
|
||||||
|
{{/if}}
|
||||||
<i class="dicon {{constants.Icon.Settings}}">
|
<i class="dicon {{constants.Icon.Settings}}">
|
||||||
{{#attach-popover class="ember-attacher-popper" hideOn="clickout click" showOn="click" isShown=false}}
|
{{#attach-popover class="ember-attacher-popper" hideOn="clickout click" showOn="click" isShown=false}}
|
||||||
<div class="menu">
|
<div class="menu">
|
||||||
|
<a class="item" href="#" id="page-copy-link-{{page.id}}" {{action "onCopyLink"}}>Copy link</a>
|
||||||
|
{{#if (or canEdit permissions.documentCopy permissions.documentMove permissions.documentTemplate)}}
|
||||||
|
<div class="divider"></div>
|
||||||
|
{{/if}}
|
||||||
{{#if canEdit}}
|
{{#if canEdit}}
|
||||||
<a class="item" href="#" id={{concat "edit-page-button-" page.id}} {{action "onEdit"}}>Edit</a>
|
<a class="item" href="#" id={{concat "edit-page-button-" page.id}} {{action "onEdit"}}>Edit</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if permissions.documentCopy}}
|
{{#if permissions.documentCopy}}
|
||||||
<a class="item" href="#" id={{concat "copy-page-button-" page.id}} data-toggle="modal" data-target={{concat "#copy-page-modal-" page.id}} data-backdrop="static">Copy</a>
|
<a class="item" href="#" id={{concat "copy-page-button-" page.id}} {{action "onShowCopyModal"}}>Copy</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if canMove}}
|
{{#if permissions.documentMove}}
|
||||||
<a class="item" href="#" id={{concat "move-page-button-" page.id}} data-toggle="modal" data-target={{concat "#move-page-modal-" page.id}} data-backdrop="static">Move</a>
|
<a class="item" href="#" id={{concat "move-page-button-" page.id}} {{action "onShowMoveModal"}}>Move</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if permissions.documentTemplate}}
|
{{#if permissions.documentTemplate}}
|
||||||
<a class="item" href="#" id={{concat "publish-page-button-" page.id}} data-toggle="modal" data-target={{concat "#publish-page-modal-" page.id}} data-backdrop="static">Publish</a>
|
<a class="item" href="#" id={{concat "publish-page-button-" page.id}} data-toggle="modal" data-target={{concat "#publish-page-modal-" page.id}} data-backdrop="static">Publish</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if canDelete}}
|
{{#if permissions.documentDelete}}
|
||||||
|
<div class="divider"></div>
|
||||||
<a class="item red" href="#" id={{concat "delete-page-button-" page.id}} data-toggle="modal" data-target={{concat "#delete-page-modal-" page.id}} data-backdrop="static">Delete</a>
|
<a class="item red" href="#" id={{concat "delete-page-button-" page.id}} data-toggle="modal" data-target={{concat "#delete-page-modal-" page.id}} data-backdrop="static">Delete</a>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
{{#if (and canEdit state.actionablePage)}}
|
{{#if (and canEdit state.actionablePage)}}
|
||||||
|
@ -56,12 +59,6 @@
|
||||||
</div>
|
</div>
|
||||||
{{/attach-popover}}
|
{{/attach-popover}}
|
||||||
</i>
|
</i>
|
||||||
{{/if}}
|
|
||||||
{{/unless}}
|
|
||||||
<div class="gap"/>
|
|
||||||
<i id="page-copy-link-{{page.id}}" class="dicon {{constants.Icon.Link}}" {{action "onCopyLink"}}>
|
|
||||||
{{#attach-tooltip showDelay=1000}}Copy link{{/attach-tooltip}}
|
|
||||||
</i>
|
|
||||||
<div class="gap"/>
|
<div class="gap"/>
|
||||||
<i class="dicon {{constants.Icon.Expand}} {{unless expanded "expand"}}" {{action "onExpand"}}>
|
<i class="dicon {{constants.Icon.Expand}} {{unless expanded "expand"}}" {{action "onExpand"}}>
|
||||||
{{#attach-tooltip showDelay=1000}}Show/hide{{/attach-tooltip}}
|
{{#attach-tooltip showDelay=1000}}Show/hide{{/attach-tooltip}}
|
||||||
|
@ -73,31 +70,19 @@
|
||||||
|
|
||||||
{{#if permissions.documentCopy}}
|
{{#if permissions.documentCopy}}
|
||||||
<div id={{concat "copy-page-modal-" page.id}} class="modal" tabindex="-1" role="dialog">
|
<div id={{concat "copy-page-modal-" page.id}} class="modal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog modal-50" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">Copy Section</div>
|
<div class="modal-header">Copy Destination</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<div class="form-group">
|
<p>This section and all nested sections will be copied to the selected document.</p>
|
||||||
<label>Destination Document</label>
|
|
||||||
{{focus-input type="text" value=docSearchFilter class="form-control" placeholder="a OR b, x AND y, 'phrase mat*'"}}
|
|
||||||
</div>
|
|
||||||
<Ui::UiSpacer @size="100" />
|
<Ui::UiSpacer @size="100" />
|
||||||
<div class="document-copy-move">
|
<div class="form-group">
|
||||||
{{#if emptySearch}}
|
<label>Space</label>
|
||||||
<p>No matching documents found.</p>
|
{{ui/ui-select content=folders optionValuePath="id" optionLabelPath="name" selection=targetSpace action=(action "onSelectSpace")}}
|
||||||
{{/if}}
|
</div>
|
||||||
<ul class="documents-list">
|
<div class="form-group">
|
||||||
{{#each docSearchResults key="id" as |result|}}
|
<label>Document</label>
|
||||||
<li class="document {{if result.selected "selected"}}" {{action "onSelectSearchResult" result.documentId}}>
|
{{ui/ui-select content=targetDocs optionValuePath="id" optionLabelPath="name" selection=targetDoc action=(action "onSelectDoc")}}
|
||||||
<div class="title">{{result.document}}</div>
|
|
||||||
<div class="space">{{result.space}}</div>
|
|
||||||
<div class="snippet">{{result.excerpt}}</div>
|
|
||||||
{{#if result.selected}}
|
|
||||||
<i class="dicon {{constants.Icon.Tick}}" />
|
|
||||||
{{/if}}
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
@ -112,30 +97,19 @@
|
||||||
|
|
||||||
{{#if permissions.documentMove}}
|
{{#if permissions.documentMove}}
|
||||||
<div id={{concat "move-page-modal-" page.id}} class="modal" tabindex="-1" role="dialog">
|
<div id={{concat "move-page-modal-" page.id}} class="modal" tabindex="-1" role="dialog">
|
||||||
<div class="modal-dialog" role="document">
|
<div class="modal-dialog modal-50" role="document">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">Move Section</div>
|
<div class="modal-header">Move Destination</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
<p>This section and all nested sections will be moved to the selected document.</p>
|
||||||
|
<Ui::UiSpacer @size="100" />
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label>Destination Document</label>
|
<label>Space</label>
|
||||||
{{focus-input type="text" value=docSearchFilter class="form-control" placeholder="a OR b, x AND y, 'phrase mat*'"}}
|
{{ui/ui-select content=folders optionValuePath="id" optionLabelPath="name" selection=targetSpace action=(action "onSelectSpace")}}
|
||||||
</div>
|
</div>
|
||||||
<div class="document-copy-move">
|
<div class="form-group">
|
||||||
{{#if emptySearch}}
|
<label>Document</label>
|
||||||
<p>No matching documents found.</p>
|
{{ui/ui-select content=targetDocs optionValuePath="id" optionLabelPath="name" selection=targetDoc action=(action "onSelectDoc")}}
|
||||||
{{/if}}
|
|
||||||
<ul class="documents-list">
|
|
||||||
{{#each docSearchResults key="id" as |result|}}
|
|
||||||
<li class="document {{if result.selected "selected"}}" {{action "onSelectSearchResult" result.documentId}}>
|
|
||||||
<div class="title">{{result.document}}</div>
|
|
||||||
<div class="space">{{result.space}}</div>
|
|
||||||
<div class="snippet">{{result.excerpt}}</div>
|
|
||||||
{{#if result.selected}}
|
|
||||||
<i class="dicon {{constants.Icon.Tick}}" />
|
|
||||||
{{/if}}
|
|
||||||
</li>
|
|
||||||
{{/each}}
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
roles=roles
|
roles=roles
|
||||||
pages=pages
|
pages=pages
|
||||||
folder=folder
|
folder=folder
|
||||||
|
folders=folders
|
||||||
toEdit=toEdit
|
toEdit=toEdit
|
||||||
blocks=blocks
|
blocks=blocks
|
||||||
page=item.page
|
page=item.page
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue