diff --git a/api/registry/types.ts b/api/registry/types.ts index 9316710..fdd01f7 100644 --- a/api/registry/types.ts +++ b/api/registry/types.ts @@ -8,5 +8,9 @@ export type { OnMoveCollectionsListSuccess, OnUpdateCollectionError, OnUpdateCollectionSuccess, + OnDeleteCollectionError, + OnDeleteCollectionSuccess, + OnDeleteCollectionsListError, + OnDeleteCollectionsListSuccess, } from '../../src/registry/common/utils/controllers-callbacks/collections'; export type {GatewayApi} from '../../src/registry'; diff --git a/src/controllers/collections/delete.ts b/src/controllers/collections/delete.ts new file mode 100644 index 0000000..5d84940 --- /dev/null +++ b/src/controllers/collections/delete.ts @@ -0,0 +1,54 @@ +import {Request, Response} from 'express'; + +import {prepareResponseAsync} from '../../components/response-presenter'; +import {makeSchemaValidator} from '../../components/validation-schema-compiler'; +import {deleteCollections} from '../../services/new/collection'; +import {formatCollectionModelsList} from '../../services/new/collection/formatters'; + +export type DeleteCollectionReqParams = { + collectionId: string; +}; + +const validateParams = makeSchemaValidator({ + type: 'object', + required: ['collectionId'], + properties: { + collectionId: { + type: 'string', + }, + }, +}); + +export const deleteCollectionController = async (req: Request, res: Response) => { + const params = validateParams(req.params) as DeleteCollectionReqParams; + + const registry = req.ctx.get('registry'); + const { + controllersCallbacks: {onDeleteCollectionError, onDeleteCollectionSuccess}, + } = registry.common.functions.get(); + + try { + const result = await deleteCollections( + {ctx: req.ctx}, + { + collectionIds: [params.collectionId], + }, + ); + + onDeleteCollectionSuccess({ + ctx: req.ctx, + reqParams: params, + collections: result.collections, + }); + + const formattedResponse = formatCollectionModelsList(result); + + const {code, response} = await prepareResponseAsync({data: formattedResponse}); + + res.status(code).send(response); + } catch (error) { + onDeleteCollectionError({ctx: req.ctx, reqParams: params, error}); + + throw error; + } +}; diff --git a/src/controllers/collections/deleteList.ts b/src/controllers/collections/deleteList.ts new file mode 100644 index 0000000..fb4d8b3 --- /dev/null +++ b/src/controllers/collections/deleteList.ts @@ -0,0 +1,59 @@ +import {Request, Response} from 'express'; + +import {prepareResponseAsync} from '../../components/response-presenter'; +import {makeSchemaValidator} from '../../components/validation-schema-compiler'; +import {deleteCollections} from '../../services/new/collection'; +import {formatCollectionModelsList} from '../../services/new/collection/formatters'; + +export type DeleteCollectionsListReqBody = { + collectionIds: string[]; +}; + +const validateBody = makeSchemaValidator({ + type: 'object', + required: ['collectionIds'], + properties: { + collectionIds: { + type: 'array', + items: {type: 'string'}, + }, + }, +}); + +export const deleteListController = async (req: Request, res: Response) => { + const body = validateBody(req.body); + + const registry = req.ctx.get('registry'); + const { + controllersCallbacks: {onDeleteCollectionsListError, onDeleteCollectionsListSuccess}, + } = registry.common.functions.get(); + + try { + const result = await deleteCollections( + {ctx: req.ctx}, + { + collectionIds: body.collectionIds, + }, + ); + + onDeleteCollectionsListSuccess({ + ctx: req.ctx, + reqBody: body, + collections: result.collections, + }); + + const formattedResponse = formatCollectionModelsList(result); + + const {code, response} = await prepareResponseAsync({data: formattedResponse}); + + res.status(code).send(response); + } catch (error) { + onDeleteCollectionsListError({ + ctx: req.ctx, + reqBody: body, + error, + }); + + throw error; + } +}; diff --git a/src/controllers/collections/get.ts b/src/controllers/collections/get.ts new file mode 100644 index 0000000..bc7a8eb --- /dev/null +++ b/src/controllers/collections/get.ts @@ -0,0 +1,24 @@ +import {Request, Response} from '@gravity-ui/expresskit'; + +import {prepareResponseAsync} from '../../components/response-presenter'; +import {getCollection} from '../../services/new/collection'; +import {formatCollection} from '../../services/new/collection/formatters'; +import Utils from '../../utils'; + +export const getCollectionController = async (req: Request, res: Response) => { + const {params, query} = req; + + const result = await getCollection( + {ctx: req.ctx}, + { + collectionId: params.collectionId, + includePermissionsInfo: Utils.isTrueArg(query.includePermissionsInfo), + }, + ); + + const formattedResponse = formatCollection(result); + + const {code, response} = await prepareResponseAsync({data: formattedResponse}); + + res.status(code).send(response); +}; diff --git a/src/controllers/collections/getBreadcrumbs.ts b/src/controllers/collections/getBreadcrumbs.ts new file mode 100644 index 0000000..4d108c0 --- /dev/null +++ b/src/controllers/collections/getBreadcrumbs.ts @@ -0,0 +1,24 @@ +import {Request, Response} from '@gravity-ui/expresskit'; + +import {prepareResponseAsync} from '../../components/response-presenter'; +import {getCollectionBreadcrumbs} from '../../services/new/collection'; +import {formatGetCollectionBreadcrumbs} from '../../services/new/collection/formatters'; +import Utils from '../../utils'; + +export const getCollectionBreadcrumbsController = async (req: Request, res: Response) => { + const {params, query} = req; + + const result = await getCollectionBreadcrumbs( + {ctx: req.ctx}, + { + collectionId: params.collectionId, + includePermissionsInfo: Utils.isTrueArg(query.includePermissionsInfo), + }, + ); + + const formattedResponse = formatGetCollectionBreadcrumbs(result); + + const {code, response} = await prepareResponseAsync({data: formattedResponse}); + + res.status(code).send(response); +}; diff --git a/src/controllers/collections/getCollectionsListByIds.ts b/src/controllers/collections/getCollectionsListByIds.ts new file mode 100644 index 0000000..a13b0e8 --- /dev/null +++ b/src/controllers/collections/getCollectionsListByIds.ts @@ -0,0 +1,20 @@ +import {Request, Response} from '@gravity-ui/expresskit'; + +import {prepareResponseAsync} from '../../components/response-presenter'; +import {getCollectionsListByIds} from '../../services/new/collection'; +import {formatCollectionModel} from '../../services/new/collection/formatters'; + +export const getCollectionsListByIdsController = async (req: Request, res: Response) => { + const {body} = req; + + const result = await getCollectionsListByIds( + {ctx: req.ctx}, + { + collectionIds: body.collectionIds, + }, + ); + + const formattedResponse = result.map((instance) => formatCollectionModel(instance.model)); + const {code, response} = await prepareResponseAsync({data: formattedResponse}); + res.status(code).send(response); +}; diff --git a/src/controllers/collections/getContent.ts b/src/controllers/collections/getContent.ts new file mode 100644 index 0000000..6a7a504 --- /dev/null +++ b/src/controllers/collections/getContent.ts @@ -0,0 +1,60 @@ +import {Request, Response} from '@gravity-ui/expresskit'; + +import {prepareResponseAsync} from '../../components/response-presenter'; +import { + Mode, + OrderDirection, + OrderField, + getCollectionContent, +} from '../../services/new/collection'; +import {formatCollectionContent} from '../../services/new/collection/formatters'; +import Utils from '../../utils'; + +/** + * @deprecated for structureItemsController.getStructureItems, + * @todo remove, after successful deploy with UI. + * Exists for reverse compatibility. + */ +export const getCollectionContentController = async (req: Request, res: Response) => { + const {query} = req; + + let collectionsPage: Optional>; + if (query.collectionsPage === 'null') { + collectionsPage = null; + } else { + collectionsPage = query.collectionsPage + ? parseInt(query.collectionsPage as string, 10) + : undefined; + } + + let workbooksPage: Optional>; + if (query.workbooksPage === 'null') { + workbooksPage = null; + } else { + workbooksPage = query.workbooksPage + ? parseInt(query.workbooksPage as string, 10) + : undefined; + } + + const result = await getCollectionContent( + {ctx: req.ctx}, + { + collectionId: (query.collectionId as Optional) ?? null, + includePermissionsInfo: Utils.isTrueArg(query.includePermissionsInfo), + filterString: query.filterString as Optional, + collectionsPage, + workbooksPage, + pageSize: query.pageSize ? parseInt(query.pageSize as string, 10) : undefined, + orderField: query.orderField as Optional, + orderDirection: query.orderDirection as Optional, + onlyMy: Utils.isTrueArg(query.onlyMy), + mode: query.mode as Optional, + }, + ); + + const formattedResponse = formatCollectionContent(result); + + const {code, response} = await prepareResponseAsync({data: formattedResponse}); + + res.status(code).send(response); +}; diff --git a/src/controllers/collections/getRootPermissions.ts b/src/controllers/collections/getRootPermissions.ts new file mode 100644 index 0000000..d02bd13 --- /dev/null +++ b/src/controllers/collections/getRootPermissions.ts @@ -0,0 +1,12 @@ +import {Request, Response} from '@gravity-ui/expresskit'; + +import {prepareResponseAsync} from '../../components/response-presenter'; +import {getRootCollectionPermissions} from '../../services/new/collection'; + +export const getRootCollectionPermissionsController = async (req: Request, res: Response) => { + const result = await getRootCollectionPermissions({ctx: req.ctx}); + + const {code, response} = await prepareResponseAsync({data: result}); + + res.status(code).send(response); +}; diff --git a/src/controllers/collections/index.ts b/src/controllers/collections/index.ts index 26f5afe..341c35a 100644 --- a/src/controllers/collections/index.ts +++ b/src/controllers/collections/index.ts @@ -1,196 +1,40 @@ -import {Request, Response} from '@gravity-ui/expresskit'; - -import {prepareResponseAsync} from '../../components/response-presenter'; -import { - Mode, - OrderDirection, - OrderField, - deleteCollections, - getCollection, - getCollectionBreadcrumbs, - getCollectionContent, - getCollectionsListByIds, - getRootCollectionPermissions, - updateCollection, -} from '../../services/new/collection'; -import { - formatCollection, - formatCollectionContent, - formatCollectionModel, - formatCollectionModelsList, - formatGetCollectionBreadcrumbs, -} from '../../services/new/collection/formatters'; -import Utils from '../../utils'; - import {createCollectionController} from './create'; +import {deleteCollectionController} from './delete'; +import {deleteListController} from './deleteList'; +import {getCollectionController} from './get'; +import {getCollectionBreadcrumbsController} from './getBreadcrumbs'; +import {getCollectionsListByIdsController} from './getCollectionsListByIds'; +import {getCollectionContentController} from './getContent'; +import {getRootCollectionPermissionsController} from './getRootPermissions'; import {moveCollectionController} from './move'; import {moveCollectionsListController} from './moveList'; +import {updateCollectionController} from './update'; export default { create: createCollectionController, - get: async (req: Request, res: Response) => { - const {params, query} = req; - - const result = await getCollection( - {ctx: req.ctx}, - { - collectionId: params.collectionId, - includePermissionsInfo: Utils.isTrueArg(query.includePermissionsInfo), - }, - ); - - const formattedResponse = formatCollection(result); - - const {code, response} = await prepareResponseAsync({data: formattedResponse}); - - res.status(code).send(response); - }, - - getCollectionsListByIds: async (req: Request, res: Response) => { - const {body} = req; - - const result = await getCollectionsListByIds( - {ctx: req.ctx}, - { - collectionIds: body.collectionIds, - }, - ); + get: getCollectionController, - const formattedResponse = result.map((instance) => formatCollectionModel(instance.model)); - const {code, response} = await prepareResponseAsync({data: formattedResponse}); - res.status(code).send(response); - }, + getCollectionsListByIds: getCollectionsListByIdsController, /** * @deprecated for structureItemsController.getStructureItems, * @todo remove, after successful deploy with UI. * Exists for reverse compatibility. */ - getContent: async (req: Request, res: Response) => { - const {query} = req; - - let collectionsPage: Optional>; - if (query.collectionsPage === 'null') { - collectionsPage = null; - } else { - collectionsPage = query.collectionsPage - ? parseInt(query.collectionsPage as string, 10) - : undefined; - } - - let workbooksPage: Optional>; - if (query.workbooksPage === 'null') { - workbooksPage = null; - } else { - workbooksPage = query.workbooksPage - ? parseInt(query.workbooksPage as string, 10) - : undefined; - } - - const result = await getCollectionContent( - {ctx: req.ctx}, - { - collectionId: (query.collectionId as Optional) ?? null, - includePermissionsInfo: Utils.isTrueArg(query.includePermissionsInfo), - filterString: query.filterString as Optional, - collectionsPage, - workbooksPage, - pageSize: query.pageSize ? parseInt(query.pageSize as string, 10) : undefined, - orderField: query.orderField as Optional, - orderDirection: query.orderDirection as Optional, - onlyMy: Utils.isTrueArg(query.onlyMy), - mode: query.mode as Optional, - }, - ); - - const formattedResponse = formatCollectionContent(result); - - const {code, response} = await prepareResponseAsync({data: formattedResponse}); - - res.status(code).send(response); - }, - - getRootPermissions: async (req: Request, res: Response) => { - const result = await getRootCollectionPermissions({ctx: req.ctx}); - - const {code, response} = await prepareResponseAsync({data: result}); + getContent: getCollectionContentController, - res.status(code).send(response); - }, + getRootPermissions: getRootCollectionPermissionsController, - getBreadcrumbs: async (req: Request, res: Response) => { - const {params, query} = req; + getBreadcrumbs: getCollectionBreadcrumbsController, - const result = await getCollectionBreadcrumbs( - {ctx: req.ctx}, - { - collectionId: params.collectionId, - includePermissionsInfo: Utils.isTrueArg(query.includePermissionsInfo), - }, - ); + delete: deleteCollectionController, - const formattedResponse = formatGetCollectionBreadcrumbs(result); - - const {code, response} = await prepareResponseAsync({data: formattedResponse}); - - res.status(code).send(response); - }, - - delete: async (req: Request, res: Response) => { - const {params} = req; - - const result = await deleteCollections( - {ctx: req.ctx}, - { - collectionIds: [params.collectionId], - }, - ); - - const formattedResponse = formatCollectionModelsList(result); - - const {code, response} = await prepareResponseAsync({data: formattedResponse}); - - res.status(code).send(response); - }, - - deleteList: async (req: Request, res: Response) => { - const {body} = req; - - const result = await deleteCollections( - {ctx: req.ctx}, - { - collectionIds: body.collectionIds, - }, - ); - - const formattedResponse = formatCollectionModelsList(result); - - const {code, response} = await prepareResponseAsync({data: formattedResponse}); - - res.status(code).send(response); - }, + deleteList: deleteListController, move: moveCollectionController, moveList: moveCollectionsListController, - update: async (req: Request, res: Response) => { - const {params, body} = req; - - const result = await updateCollection( - {ctx: req.ctx}, - { - collectionId: params.collectionId, - title: body.title as Optional, - description: body.description as Optional, - }, - ); - - const formattedResponse = formatCollectionModel(result); - - const {code, response} = await prepareResponseAsync({data: formattedResponse}); - - res.status(code).send(response); - }, + update: updateCollectionController, }; diff --git a/src/registry/common/functions-map.ts b/src/registry/common/functions-map.ts index b532db2..6be80b0 100644 --- a/src/registry/common/functions-map.ts +++ b/src/registry/common/functions-map.ts @@ -8,6 +8,10 @@ import type {ColorPalettesAdminValidator} from './utils/color-palettes/types'; import type { OnCreateCollectionError, OnCreateCollectionSuccess, + OnDeleteCollectionError, + OnDeleteCollectionSuccess, + OnDeleteCollectionsListError, + OnDeleteCollectionsListSuccess, OnMoveCollectionError, OnMoveCollectionSuccess, OnMoveCollectionsListError, @@ -43,5 +47,9 @@ export const commonFunctionsMap = { onMoveCollectionsListSuccess: makeFunctionTemplate(), onUpdateCollectionError: makeFunctionTemplate(), onUpdateCollectionSuccess: makeFunctionTemplate(), + onDeleteCollectionError: makeFunctionTemplate(), + onDeleteCollectionSuccess: makeFunctionTemplate(), + onDeleteCollectionsListError: makeFunctionTemplate(), + onDeleteCollectionsListSuccess: makeFunctionTemplate(), }, } as const; diff --git a/src/registry/common/utils/controllers-callbacks/collections.ts b/src/registry/common/utils/controllers-callbacks/collections.ts index 61b7640..7a566f3 100644 --- a/src/registry/common/utils/controllers-callbacks/collections.ts +++ b/src/registry/common/utils/controllers-callbacks/collections.ts @@ -1,6 +1,8 @@ import type {AppContext} from '@gravity-ui/nodekit'; import type {CreateCollectionReqBody} from '../../../../controllers/collections/create'; +import type {DeleteCollectionReqParams} from '../../../../controllers/collections/delete'; +import type {DeleteCollectionsListReqBody} from '../../../../controllers/collections/deleteList'; import type { MoveCollectionReqBody, MoveCollectionReqParams, @@ -63,3 +65,27 @@ export type OnMoveCollectionsListError = (args: { reqBody: MoveCollectionsListReqBody; error: unknown; }) => void; + +export type OnDeleteCollectionSuccess = (args: { + ctx: AppContext; + reqParams: DeleteCollectionReqParams; + collections: CollectionModel[]; +}) => void; + +export type OnDeleteCollectionError = (args: { + ctx: AppContext; + reqParams: DeleteCollectionReqParams; + error: unknown; +}) => void; + +export type OnDeleteCollectionsListSuccess = (args: { + ctx: AppContext; + reqBody: DeleteCollectionsListReqBody; + collections: CollectionModel[]; +}) => void; + +export type OnDeleteCollectionsListError = (args: { + ctx: AppContext; + reqBody: DeleteCollectionsListReqBody; + error: unknown; +}) => void;