Add file ordering

Signed-off-by: Alexandre Bodin <bodin.alex@gmail.com>
This commit is contained in:
Alexandre Bodin 2020-03-16 23:50:15 +01:00
parent 3187c08087
commit df14b08618
2 changed files with 94 additions and 125 deletions

View File

@ -302,6 +302,7 @@ module.exports = ({ models, target }, ctx) => {
: strapi.models[details.model]; : strapi.models[details.model];
const globalId = `${model.collectionName}_morph`; const globalId = `${model.collectionName}_morph`;
const filter = _.get(model, ['attributes', details.via, 'filter'], 'field');
loadedModel[name] = function() { loadedModel[name] = function() {
return this.morphOne( return this.morphOne(
@ -309,7 +310,7 @@ module.exports = ({ models, target }, ctx) => {
details.via, details.via,
`${definition.collectionName}` `${definition.collectionName}`
).query(qb => { ).query(qb => {
qb.where(_.get(model, ['attributes', details.via, 'filter'], 'field'), name); qb.where(filter, name);
}); });
}; };
break; break;
@ -320,6 +321,7 @@ module.exports = ({ models, target }, ctx) => {
: strapi.models[details.collection]; : strapi.models[details.collection];
const globalId = `${collection.collectionName}_morph`; const globalId = `${collection.collectionName}_morph`;
const filter = _.get(model, ['attributes', details.via, 'filter'], 'field');
loadedModel[name] = function() { loadedModel[name] = function() {
return this.morphMany( return this.morphMany(
@ -327,7 +329,7 @@ module.exports = ({ models, target }, ctx) => {
details.via, details.via,
`${definition.collectionName}` `${definition.collectionName}`
).query(qb => { ).query(qb => {
qb.where(_.get(model, ['attributes', details.via, 'filter'], 'field'), name); qb.where(filter, name).orderBy('order');
}); });
}; };
break; break;

View File

@ -42,6 +42,39 @@ const getModel = (model, plugin) => {
const removeUndefinedKeys = obj => _.pickBy(obj, _.negate(_.isUndefined)); const removeUndefinedKeys = obj => _.pickBy(obj, _.negate(_.isUndefined));
const addRelationMorph = async (model, { params, transacting } = {}) => {
return await model.morph.forge().save(
{
[`${model.collectionName}_id`]: params.id,
[`${params.alias}_id`]: params.refId,
[`${params.alias}_type`]: params.ref,
field: params.field,
order: params.order,
},
{ transacting }
);
};
const removeRelationMorph = async (model, { params, transacting } = {}) => {
return await model.morph
.forge()
.where(
_.omitBy(
{
[`${model.collectionName}_id`]: params.id,
[`${params.alias}_id`]: params.refId,
[`${params.alias}_type`]: params.ref,
field: params.field,
},
_.isUndefined
)
)
.destroy({
require: false,
transacting,
});
};
module.exports = { module.exports = {
async findOne(params, populate, { transacting } = {}) { async findOne(params, populate, { transacting } = {}) {
const record = await this.forge({ const record = await this.forge({
@ -236,11 +269,7 @@ module.exports = {
if (Array.isArray(refs) && refs.length === 0) { if (Array.isArray(refs) && refs.length === 0) {
// clear related // clear related
relationUpdates.push( relationUpdates.push(
module.exports.removeRelationMorph.call( removeRelationMorph(this, { params: { id: primaryKeyValue }, transacting })
this,
{ id: primaryKeyValue },
{ transacting }
)
); );
break; break;
} }
@ -259,97 +288,84 @@ module.exports = {
// can be related to this field. // can be related to this field.
if (reverseAssoc && reverseAssoc.nature === 'oneToManyMorph') { if (reverseAssoc && reverseAssoc.nature === 'oneToManyMorph') {
relationUpdates.push( relationUpdates.push(
module.exports.removeRelationMorph removeRelationMorph(this, {
.call( params: {
this,
{
alias: association.alias,
ref: targetModel.collectionName,
refId: obj.refId,
field: obj.field,
},
{ transacting }
)
.then(() =>
module.exports.addRelationMorph.call(
this,
{
id: response[this.primaryKey],
alias: association.alias,
ref: targetModel.collectionName,
refId: obj.refId,
field: obj.field,
},
{ transacting }
)
)
);
} else {
relationUpdates.push(
module.exports.addRelationMorph.call(
this,
{
id: response[this.primaryKey],
alias: association.alias, alias: association.alias,
ref: targetModel.collectionName, ref: targetModel.collectionName,
refId: obj.refId, refId: obj.refId,
field: obj.field, field: obj.field,
}, },
{ transacting } transacting,
}).then(() =>
addRelationMorph(this, {
params: {
id: response[this.primaryKey],
alias: association.alias,
ref: targetModel.collectionName,
refId: obj.refId,
field: obj.field,
},
transacting,
})
) )
); );
return;
} }
// TODO: recompute the order when adding a ref
relationUpdates.push(
addRelationMorph(this, {
params: {
id: response[this.primaryKey],
alias: association.alias,
ref: targetModel.collectionName,
refId: obj.refId,
field: obj.field,
},
transacting,
})
);
}); });
break; break;
} }
case 'oneToManyMorph': case 'oneToManyMorph':
case 'manyToManyMorph': { case 'manyToManyMorph': {
// Compare array of ID to find deleted files. const currentValue = transformToArrayID(
const currentValue = transformToArrayID(response[current], association).map(id =>
id.toString()
);
const storedValue = transformToArrayID(
params.values[current], params.values[current],
association association
).map(id => id.toString()); ).map(id => id.toString());
const toAdd = _.difference(storedValue, currentValue);
const toRemove = _.difference(currentValue, storedValue);
const model = getModel(details.collection || details.model, details.plugin); const model = getModel(details.collection || details.model, details.plugin);
toAdd.forEach(id => { const promise = removeRelationMorph(model, {
relationUpdates.push( params: {
module.exports.addRelationMorph.call( alias: association.via,
model, ref: this.collectionName,
{ refId: response.id,
id, field: association.alias,
alias: association.via, },
ref: this.collectionName, transacting,
refId: response.id, }).then(() => {
field: association.alias, return Promise.all(
}, currentValue.map((id, idx) => {
{ transacting } return addRelationMorph(model, {
) params: {
id,
alias: association.via,
ref: this.collectionName,
refId: response.id,
field: association.alias,
order: idx + 1,
},
transacting,
});
})
); );
}); });
// Update the relational array. relationUpdates.push(promise);
toRemove.forEach(id => {
relationUpdates.push(
module.exports.removeRelationMorph.call(
model,
{
id,
alias: association.via,
ref: this.collectionName,
refId: response.id,
field: association.alias,
},
{ transacting }
)
);
});
break; break;
} }
case 'oneMorphToOne': case 'oneMorphToOne':
@ -382,53 +398,4 @@ module.exports = {
return result && result.toJSON ? result.toJSON() : result; return result && result.toJSON ? result.toJSON() : result;
}, },
async addRelationMorph(params, { transacting } = {}) {
const record = await this.morph
.forge()
.where({
[`${this.collectionName}_id`]: params.id,
[`${params.alias}_id`]: params.refId,
[`${params.alias}_type`]: params.ref,
field: params.field,
})
.fetch({
transacting,
});
const entry = record ? record.toJSON() : record;
if (entry) {
return Promise.resolve();
}
return await this.morph
.forge({
[`${this.collectionName}_id`]: params.id,
[`${params.alias}_id`]: params.refId,
[`${params.alias}_type`]: params.ref,
field: params.field,
})
.save(null, { transacting });
},
async removeRelationMorph(params, { transacting } = {}) {
return await this.morph
.forge()
.where(
_.omitBy(
{
[`${this.collectionName}_id`]: params.id,
[`${params.alias}_id`]: params.refId,
[`${params.alias}_type`]: params.ref,
field: params.field,
},
_.isUndefined
)
)
.destroy({
require: false,
transacting,
});
},
}; };