1
0
Fork 0
mirror of https://github.com/documize/community.git synced 2025-07-24 15:49:44 +02:00

Pinned documents

Closes #278

Pin documents to the top of each space.
This commit is contained in:
sauls8t 2020-02-03 21:00:35 +00:00
parent 2b66d0096a
commit e014f5b5c1
18 changed files with 541 additions and 88 deletions

View file

@ -31,6 +31,9 @@ export default Component.extend({
hasDocumentActions: computed('permissions.{documentDelete,documentMove}', function() {
return this.get('permissions.documentDelete') || this.get('permissions.documentMove');
}),
hasCategoryFilter: computed('categoryFilter', function() {
return !_.isEmpty(this.get('categoryFilter'));
}),
didReceiveAttrs() {
this._super(...arguments);
@ -53,7 +56,7 @@ export default Component.extend({
let viewDensity = this.get('localStorage').getSessionItem('space.density');
if (!_.isNull(viewDensity) && !_.isUndefined(viewDensity)) {
this.set('viewDensity', viewDensity);
}
}
},
actions: {
@ -86,7 +89,7 @@ export default Component.extend({
},
// eslint-disable-next-line no-unused-vars
onSortBy(attacher) {
onSortBy(attacher) {
// attacher.hide();
this.get('onFiltered')(this.get('documents'));
},
@ -161,6 +164,18 @@ export default Component.extend({
this.set('selectedCaption', list.length > 1 ? 'documents' : 'document');
this.set('selectedDocuments', A(list));
}
},
onPin(documentId) {
this.get('onPin')(documentId);
},
onUnpin(documentId) {
this.get('onUnpin')(documentId);
},
onPinSequence(documentId, direction) {
this.get('onPinSequence')(documentId, direction);
},
}
});

View file

@ -36,7 +36,7 @@ export default Component.extend(AuthMixin, {
this.setup();
},
didReceiveAttrs() {
didUpdateAttrs() {
this._super(...arguments);
this.setup();
},
@ -138,6 +138,7 @@ export default Component.extend(AuthMixin, {
this.set('selectedFilter', filter);
this.set('categories', categories);
this.get('onFiltered')(filtered);
}
}

View file

@ -15,6 +15,8 @@ import EmberObject from "@ember/object";
// let constants = this.get('constants');
let constants = EmberObject.extend({
Unsequenced: 99999,
SpaceType: { // eslint-disable-line ember/avoid-leaking-state-in-ember-objects
Public: 1,
Private: 2,

View file

@ -30,6 +30,7 @@ export default Model.extend({
versioned: attr('boolean'),
versionId: attr('string'),
versionOrder: attr('number', { defaultValue: 0 }),
sequence: attr('number', { defaultValue: 99999 }),
groupId: attr('string'),
created: attr(),
revised: attr(),
@ -46,12 +47,12 @@ export default Model.extend({
isDraft: computed('lifecycle', function () {
let constants = this.get('constants');
return this.get('lifecycle') == constants.Lifecycle.Draft;
return this.get('lifecycle') === constants.Lifecycle.Draft;
}),
isLive: computed('lifecycle', function () {
let constants = this.get('constants');
return this.get('lifecycle') == constants.Lifecycle.Live;
return this.get('lifecycle') === constants.Lifecycle.Live;
}),
lifecycleLabel: computed('lifecycle', function () {
@ -77,5 +78,10 @@ export default Model.extend({
let after = moment().subtract(7, 'days');
return moment(this.get('revised')).isSameOrAfter(after) &&
moment(this.get('created')).isBefore(after);
})
}),
isSequenced: computed('sequence', function () {
let constants = this.get('constants');
return this.get('sequence') !== constants.Unsequenced;
}),
});

View file

@ -95,29 +95,54 @@ export default Controller.extend(NotifierMixin, {
onFiltered(docs) {
let ls = this.get('localStorage');
let sortBy = this.get('sortBy');
let constants = this.get('constants');
if (_.isNull(docs)) return;
let pinned = _.filter(docs, function(d) { return d.get('sequence') !== constants.Unsequenced; })
let unpinned = _.filter(docs, function(d) { return d.get('sequence') === constants.Unsequenced; })
if (sortBy.name) {
docs = docs.sortBy('name');
unpinned = unpinned.sortBy('name');
ls.storeSessionItem('space.sortBy', 'name');
}
if (sortBy.created) {
docs = docs.sortBy('created');
unpinned = unpinned.sortBy('created');
ls.storeSessionItem('space.sortBy', 'created');
}
if (sortBy.updated) {
docs = docs.sortBy('revised');
unpinned = unpinned.sortBy('revised');
ls.storeSessionItem('space.sortBy', 'updated');
}
if (sortBy.desc) {
docs = docs.reverseObjects();
unpinned = unpinned.reverseObjects();
ls.storeSessionItem('space.sortOrder', 'desc');
} else {
ls.storeSessionItem('space.sortOrder', 'asc');
}
this.set('filteredDocs', docs);
}
this.set('filteredDocs', _.concat(pinned, unpinned));
},
onPin(documentId) {
this.get('documentSvc').pin(documentId).then(() => {
this.notifySuccess('Pinned');
this.send('onRefresh');
});
},
onUnpin(documentId) {
this.get('documentSvc').unpin(documentId).then(() => {
this.notifySuccess('Unpinned');
this.send('onRefresh');
});
},
onPinSequence(documentId, direction) {
this.get('documentSvc').onPinSequence(documentId, direction).then(() => {
this.notifySuccess('Moved');
this.send('onRefresh');
});
},
}
});

View file

@ -71,7 +71,11 @@
space=model.folder
templates=model.templates
permissions=model.permissions
categoryFilter=category
sortBy=sortBy
onPin=(action "onPin")
onUnpin=(action "onUnpin")
onPinSequence=(action "onPinSequence")
onFiltered=(action "onFiltered")
onExportDocument=(action "onExportDocument")
onDeleteDocument=(action "onDeleteDocument")

View file

@ -567,7 +567,37 @@ export default Service.extend({
}).catch((error) => {
return error;
});
}
},
//**************************************************
// Pinning documents inside spaces.
//**************************************************
// Pin document
pin(documentId) {
return this.get('ajax').request(`document/pin/${documentId}`, {
method: 'POST'
}).then((response) => {
return response;
});
},
// Unpin document
unpin(documentId) {
return this.get('ajax').request(`document/unpin/${documentId}`, {
method: 'DELETE'
}).then((response) => {
return response;
});
},
onPinSequence(documentId, direction) {
return this.get('ajax').request(`document/pinmove/${documentId}?direction=${direction}`, {
method: 'POST'
}).then((response) => {
return response;
});
}
});
function isObject(a) {

View file

@ -34,6 +34,10 @@
> .checkbox {
display: block;
}
> .sequence {
display: block;
}
}
> .checkbox {
@ -51,6 +55,21 @@
}
}
> .sequence {
position: absolute;
display: none;
top: 10px;
right: 40px;
cursor: pointer;
> .dicon {
color: map-get($yellow-shades, 700);
cursor: pointer;
font-weight: 600;
font-size: 20px;
}
}
> .actions {
position: absolute;
display: none;
@ -68,6 +87,17 @@
font-size: 1.3rem;
font-weight: 700;
color: map-get($gray-shades, 800);
> .pinned {
display: inline-block;
margin-left: 10px;
> .dicon {
font-size: 0.9rem;
font-weight: 500;
color: map-get($gray-shades, 600);
}
}
}
> .desc {
@ -168,6 +198,10 @@
display: block;
}
> .sequence {
display: block;
}
> .actions {
display: block;
}

View file

@ -63,13 +63,22 @@
{{#each documents key="id" as |document|}}
<li class="document {{if document.selected "selected"}}" id="document-{{document.id}}">
{{#link-to "document.index" space.id space.slug document.id document.slug class="info"}}
<div class="name">{{ document.name }}</div>
<div class="name">
{{ document.name }}
{{#if document.isSequenced}}
<div class="pinned">
<i class="dicon {{constants.Icon.TickDouble}}">
{{#attach-tooltip showDelay=250}}Pinned{{/attach-tooltip}}
</i>
</div>
{{/if}}
</div>
{{#if (not-eq viewDensity "3")}}
<div class="desc">{{ document.excerpt }}</div>
{{/if}}
{{#if (eq viewDensity "1")}}
<div class="meta">
<div class="lifecycle">
<div class="lifecycle">
<div class="{{if (eq document.lifecycle constants.Lifecycle.Draft) "draft"}}
{{if (eq document.lifecycle constants.Lifecycle.Live) "live"}}
{{if (eq document.lifecycle constants.Lifecycle.Archived) "archived"}}">
@ -83,6 +92,25 @@
{{/link-to}}
{{#if hasDocumentActions}}
<div class="sequence">
{{#if document.isSequenced}}
{{#unless hasCategoryFilter}}
<i class="dicon {{constants.Icon.ArrowSmallUp}}" {{action "onPinSequence" document.id "u"}}>
{{#attach-tooltip showDelay=250}}Move up{{/attach-tooltip}}
</i>
<i class="dicon {{constants.Icon.ArrowSmallDown}}" {{action "onPinSequence" document.id "d"}}>
{{#attach-tooltip showDelay=250}}Move down{{/attach-tooltip}}
</i>
{{/unless}}
<i class="dicon {{constants.Icon.Cross}}" {{action "onUnpin" document.id}}>
{{#attach-tooltip showDelay=250}}Unpin{{/attach-tooltip}}
</i>
{{else}}
<i class="dicon {{constants.Icon.ArrowSmallUp}}" {{action "onPin" document.id}}>
{{#attach-tooltip showDelay=250}}Pin{{/attach-tooltip}}
</i>
{{/if}}
</div>
<div class="checkbox" {{action "selectDocument" document.id}}>
{{#if document.selected}}
<i class="dicon {{constants.Icon.CheckboxChecked}}"/>