mirror of
https://github.com/strapi/strapi.git
synced 2025-12-27 23:24:03 +00:00
add many relations preview route
This commit is contained in:
parent
66dd23deab
commit
0d9812db95
@ -24,6 +24,8 @@ const RESERVED_ATTRIBUTE_NAMES = [
|
||||
'attributes',
|
||||
'relations',
|
||||
'changed',
|
||||
'page',
|
||||
'pageSize',
|
||||
|
||||
// list found here https://mongoosejs.com/docs/api.html#schema_Schema.reserved
|
||||
'_posts',
|
||||
|
||||
@ -66,7 +66,6 @@
|
||||
"policies": []
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/relations/:model/:targetField",
|
||||
@ -85,7 +84,6 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/single-types/:model",
|
||||
@ -155,7 +153,18 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/collection-types/:model/:id/:targetField",
|
||||
"handler": "collection-types.previewManyRelations",
|
||||
"config": {
|
||||
"policies": [
|
||||
"routing",
|
||||
"admin::isAuthenticatedAdmin",
|
||||
["plugins::content-manager.hasPermissions", ["plugins::content-manager.explorer.read"]]
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"method": "GET",
|
||||
"path": "/collection-types/:model",
|
||||
@ -245,7 +254,7 @@
|
||||
{
|
||||
"method": "POST",
|
||||
"path": "/collection-types/:model/actions/bulkDelete",
|
||||
"handler": "collection-types.bulkdDelete",
|
||||
"handler": "collection-types.bulkDelete",
|
||||
"config": {
|
||||
"policies": [
|
||||
"routing",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
|
||||
const { has, pipe } = require('lodash/fp');
|
||||
const { has, pipe, prop, pick } = require('lodash/fp');
|
||||
|
||||
const {
|
||||
getService,
|
||||
@ -8,6 +8,7 @@ const {
|
||||
setCreatorFields,
|
||||
pickWritableAttributes,
|
||||
} = require('../utils');
|
||||
const { MANY_RELATIONS } = require('../services/constants');
|
||||
const { validateBulkDeleteInput } = require('./validation');
|
||||
|
||||
module.exports = {
|
||||
@ -198,7 +199,7 @@ module.exports = {
|
||||
ctx.body = permissionChecker.sanitizeOutput(result);
|
||||
},
|
||||
|
||||
async bulkdDelete(ctx) {
|
||||
async bulkDelete(ctx) {
|
||||
const { userAbility } = ctx.state;
|
||||
const { model } = ctx.params;
|
||||
const { query, body } = ctx.request;
|
||||
@ -225,4 +226,57 @@ module.exports = {
|
||||
|
||||
ctx.body = results.map(result => permissionChecker.sanitizeOutput(result));
|
||||
},
|
||||
|
||||
async previewManyRelations(ctx) {
|
||||
const { userAbility } = ctx.state;
|
||||
const { model, id, targetField } = ctx.params;
|
||||
const { pageSize = 10, page = 1 } = ctx.request.query;
|
||||
|
||||
const contentTypeService = getService('content-types');
|
||||
const entityManager = getService('entity-manager');
|
||||
const permissionChecker = getService('permission-checker').create({ userAbility, model });
|
||||
|
||||
if (permissionChecker.cannot.read()) {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
const modelDef = strapi.getModel(model);
|
||||
const assoc = modelDef.associations.find(a => a.alias === targetField);
|
||||
|
||||
if (!assoc || !MANY_RELATIONS.includes(assoc.nature)) {
|
||||
return ctx.badRequest('Invalid target field');
|
||||
}
|
||||
|
||||
const entity = await entityManager.findOneWithCreatorRoles(id, model);
|
||||
|
||||
if (!entity) {
|
||||
return ctx.notFound();
|
||||
}
|
||||
|
||||
if (permissionChecker.cannot.read(entity, targetField)) {
|
||||
return ctx.forbidden();
|
||||
}
|
||||
|
||||
let relationList;
|
||||
if (assoc.nature === 'manyWay') {
|
||||
const populatedEntity = await entityManager.findOne(id, model, [targetField]);
|
||||
const relationsListIds = populatedEntity[targetField].map(prop('id'));
|
||||
relationList = await entityManager.findPage(
|
||||
{ page, pageSize, id_in: relationsListIds },
|
||||
assoc.targetUid
|
||||
);
|
||||
} else {
|
||||
relationList = await entityManager.findPage(
|
||||
{ page, pageSize, [assoc.via]: entity.id },
|
||||
assoc.targetUid
|
||||
);
|
||||
}
|
||||
|
||||
const { settings } = await contentTypeService.findConfiguration({ uid: assoc.targetUid });
|
||||
|
||||
ctx.body = {
|
||||
pagination: relationList.pagination,
|
||||
results: relationList.results.map(pick(['id', 'ids', settings.mainField])),
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
@ -0,0 +1,7 @@
|
||||
'use strict';
|
||||
|
||||
const MANY_RELATIONS = ['oneToMany', 'manyToMany', 'manyWay'];
|
||||
|
||||
module.exports = {
|
||||
MANY_RELATIONS,
|
||||
};
|
||||
@ -44,32 +44,32 @@ module.exports = {
|
||||
return assoc(`${CREATED_BY_ATTRIBUTE}.roles`, roles, entity);
|
||||
},
|
||||
|
||||
find(params, model) {
|
||||
return strapi.entityService.find({ params }, { model });
|
||||
find(params, model, populate) {
|
||||
return strapi.entityService.find({ params, populate }, { model });
|
||||
},
|
||||
|
||||
findPage(params, model) {
|
||||
return strapi.entityService.findPage({ params }, { model });
|
||||
findPage(params, model, populate) {
|
||||
return strapi.entityService.findPage({ params, populate }, { model });
|
||||
},
|
||||
|
||||
search(params, model) {
|
||||
return strapi.entityService.search({ params }, { model });
|
||||
search(params, model, populate) {
|
||||
return strapi.entityService.search({ params, populate }, { model });
|
||||
},
|
||||
|
||||
searchPage(params, model) {
|
||||
return strapi.entityService.searchPage({ params }, { model });
|
||||
searchPage(params, model, populate) {
|
||||
return strapi.entityService.searchPage({ params, populate }, { model });
|
||||
},
|
||||
|
||||
count(params, model) {
|
||||
return strapi.entityService.count({ params }, { model });
|
||||
},
|
||||
|
||||
async findOne(id, model) {
|
||||
return strapi.entityService.findOne({ params: { id } }, { model });
|
||||
async findOne(id, model, populate) {
|
||||
return strapi.entityService.findOne({ params: { id }, populate }, { model });
|
||||
},
|
||||
|
||||
async findOneWithCreatorRoles(id, model) {
|
||||
const entity = await this.findOne(id, model);
|
||||
async findOneWithCreatorRoles(id, model, populate) {
|
||||
const entity = await this.findOne(id, model, populate);
|
||||
|
||||
if (!entity) {
|
||||
return entity;
|
||||
|
||||
@ -17,12 +17,12 @@ const createPermissionChecker = ({ userAbility, model }) => {
|
||||
|
||||
const toSubject = entity => (entity ? permissionsManager.toSubject(entity, model) : model);
|
||||
|
||||
const can = (action, entity) => {
|
||||
return userAbility.can(action, toSubject(entity));
|
||||
const can = (action, entity, field) => {
|
||||
return userAbility.can(action, toSubject(entity), field);
|
||||
};
|
||||
|
||||
const cannot = (action, entity) => {
|
||||
return userAbility.cannot(action, toSubject(entity));
|
||||
const cannot = (action, entity, field) => {
|
||||
return userAbility.cannot(action, toSubject(entity), field);
|
||||
};
|
||||
|
||||
const sanitizeOutput = (data, { action = ACTIONS.read } = {}) => {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user