mirror of
https://github.com/wekan/wekan.git
synced 2025-12-18 00:10:13 +01:00
Replace the component bounded cachedValue by a global UnsavedEdits
This new draft saving system is currently only implemented for the card description and comment. We need better a component inheritance/composition model to support this for all editable fields. Fixes #186
This commit is contained in:
parent
cc88e78483
commit
d644cba38f
13 changed files with 252 additions and 95 deletions
82
client/lib/unsavedEdits.js
Normal file
82
client/lib/unsavedEdits.js
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
Meteor.subscribe('unsaved-edits');
|
||||
|
||||
// `UnsavedEdits` is a global key-value store used to save drafts of user
|
||||
// inputs. We used to have the notion of a `cachedValue` that was local to a
|
||||
// component but the global store has multiple advantages:
|
||||
// 1. When the component is unmounted (ie, destroyed) the draft isn't lost
|
||||
// 2. The drafts are synced across multiple computers
|
||||
// 3. The drafts are synced across multiple browser tabs
|
||||
// XXX This currently doesn't work in purely offline mode since the sync is
|
||||
// handled with the DDP connection to the server. To solve this, we could use
|
||||
// something like GroundDB that syncs using localstorage.
|
||||
//
|
||||
// The key is a dictionary composed of two fields:
|
||||
// * a `fieldName` which identifies the particular field. Since this is a global
|
||||
// identifier a good practice would be to compose it with the collection name
|
||||
// and the document field, eg. `boardTitle`, `cardDescription`.
|
||||
// * a `docId` which identifies the appropriate document. In general we use
|
||||
// MongoDB `_id` field.
|
||||
//
|
||||
// The value is a string containing the draft.
|
||||
|
||||
UnsavedEdits = {
|
||||
// XXX Wanted to have the collection has an instance variable, but
|
||||
// unfortunately the collection isn't defined yet at this point. We need ES6
|
||||
// modules to solve the file order issue!
|
||||
//
|
||||
// _collection: UnsavedEditCollection,
|
||||
|
||||
get({ fieldName, docId }, defaultTo = '') {
|
||||
let unsavedValue = this._getCollectionDocument(fieldName, docId);
|
||||
if (unsavedValue) {
|
||||
return unsavedValue.value
|
||||
} else {
|
||||
return defaultTo;
|
||||
}
|
||||
},
|
||||
|
||||
has({ fieldName, docId }) {
|
||||
return Boolean(this.get({fieldName, docId}));
|
||||
},
|
||||
|
||||
set({ fieldName, docId }, value) {
|
||||
let currentDoc = this._getCollectionDocument(fieldName, docId);
|
||||
if (currentDoc) {
|
||||
UnsavedEditCollection.update(currentDoc._id, {
|
||||
$set: {
|
||||
value: value
|
||||
}
|
||||
});
|
||||
} else {
|
||||
UnsavedEditCollection.insert({
|
||||
fieldName,
|
||||
docId,
|
||||
value,
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
reset({ fieldName, docId }) {
|
||||
let currentDoc = this._getCollectionDocument(fieldName, docId);
|
||||
if (currentDoc) {
|
||||
UnsavedEditCollection.remove(currentDoc._id);
|
||||
}
|
||||
},
|
||||
|
||||
_getCollectionDocument(fieldName, docId) {
|
||||
return UnsavedEditCollection.findOne({fieldName, docId});
|
||||
}
|
||||
}
|
||||
|
||||
Blaze.registerHelper('getUnsavedValue', (fieldName, docId, defaultTo) => {
|
||||
// Workaround some blaze feature that ass a list of keywords arguments as the
|
||||
// last parameter (even if the caller didn't specify any).
|
||||
if (! _.isString(defaultTo)) {
|
||||
defaultTo = '';
|
||||
}
|
||||
return UnsavedEdits.get({ fieldName, docId }, defaultTo);
|
||||
});
|
||||
|
||||
Blaze.registerHelper('hasUnsavedValue', (fieldName, docId) => {
|
||||
return UnsavedEdits.has({ fieldName, docId });
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue