Portal/rsconcept/frontend/src/features/library/backend/api.ts

270 lines
8.1 KiB
TypeScript
Raw Normal View History

2025-01-23 19:41:31 +03:00
import { queryOptions } from '@tanstack/react-query';
2025-02-04 23:33:35 +03:00
import { z } from 'zod';
2025-01-23 19:41:31 +03:00
2025-01-28 23:23:03 +03:00
import { axiosDelete, axiosGet, axiosPatch, axiosPost } from '@/backend/apiTransport';
2025-01-23 19:41:31 +03:00
import { DELAYS } from '@/backend/configuration';
import { ossApi } from '@/features/oss/backend/api';
import { IRSFormDTO, rsformsApi } from '@/features/rsform/backend/api';
import { UserID } from '@/features/users/models/user';
2025-02-04 23:33:35 +03:00
import { errors, information } from '@/utils/labels';
2025-01-23 19:41:31 +03:00
import { AccessPolicy, ILibraryItem, IVersionInfo, LibraryItemID, LibraryItemType, VersionID } from '../models/library';
import { validateLocation } from '../models/libraryAPI';
2025-01-23 19:41:31 +03:00
/**
* Represents update data for renaming Location.
*/
export interface IRenameLocationDTO {
target: string;
new_location: string;
}
/**
* Represents data, used for cloning {@link IRSForm}.
*/
export const schemaCloneLibraryItem = z.object({
2025-02-08 19:07:43 +03:00
id: z.number(),
item_type: z.nativeEnum(LibraryItemType),
title: z.string().nonempty(errors.requiredField),
alias: z.string().nonempty(errors.requiredField),
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean(),
location: z.string().refine(data => validateLocation(data), { message: errors.invalidLocation }),
access_policy: z.nativeEnum(AccessPolicy),
items: z.array(z.number()).optional()
});
/**
* Represents data, used for cloning {@link IRSForm}.
*/
export type ICloneLibraryItemDTO = z.infer<typeof schemaCloneLibraryItem>;
2025-01-23 19:41:31 +03:00
/**
* Represents data, used for creating {@link IRSForm}.
*/
export const schemaCreateLibraryItem = z
2025-02-04 23:33:35 +03:00
.object({
item_type: z.nativeEnum(LibraryItemType),
title: z.string().optional(),
alias: z.string().optional(),
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean(),
2025-02-08 19:07:43 +03:00
location: z.string().refine(data => validateLocation(data), { message: errors.invalidLocation }),
2025-02-04 23:33:35 +03:00
access_policy: z.nativeEnum(AccessPolicy),
file: z.instanceof(File).optional(),
fileName: z.string().optional()
})
.refine(data => !!data.file || !!data.title, {
path: ['title'],
message: errors.requiredField
})
.refine(data => !!data.file || !!data.alias, {
path: ['alias'],
message: errors.requiredField
});
/**
* Represents data, used for creating {@link IRSForm}.
*/
export type ICreateLibraryItemDTO = z.infer<typeof schemaCreateLibraryItem>;
2025-01-23 19:41:31 +03:00
/**
* Represents update data for editing {@link ILibraryItem}.
*/
export const schemaUpdateLibraryItem = z.object({
id: z.number(),
item_type: z.nativeEnum(LibraryItemType),
title: z.string().nonempty(errors.requiredField),
alias: z.string().nonempty(errors.requiredField),
comment: z.string(),
visible: z.boolean(),
read_only: z.boolean()
});
/**
* Represents update data for editing {@link ILibraryItem}.
*/
export type IUpdateLibraryItemDTO = z.infer<typeof schemaUpdateLibraryItem>;
2025-01-23 19:41:31 +03:00
/**
* Create version metadata in persistent storage.
*/
export const schemaVersionCreate = z.object({
2025-02-06 14:09:20 +03:00
version: z.string(),
description: z.string(),
items: z.array(z.number()).optional()
});
/**
* Create version metadata in persistent storage.
*/
export type IVersionCreateDTO = z.infer<typeof schemaVersionCreate>;
2025-01-23 19:41:31 +03:00
/**
* Represents data response when creating {@link IVersionInfo}.
*/
export interface IVersionCreatedResponse {
version: number;
schema: IRSFormDTO;
2025-01-23 19:41:31 +03:00
}
2025-02-07 15:21:40 +03:00
/**
* Represents version data, intended to update version metadata in persistent storage.
*/
export const schemaVersionUpdate = z.object({
2025-02-07 15:21:40 +03:00
id: z.number(),
version: z.string().nonempty(errors.requiredField),
description: z.string()
});
/**
* Represents version data, intended to update version metadata in persistent storage.
*/
export type IVersionUpdateDTO = z.infer<typeof schemaVersionUpdate>;
2025-02-07 15:21:40 +03:00
2025-01-23 19:41:31 +03:00
export const libraryApi = {
baseKey: 'library',
libraryListKey: ['library', 'list'],
getItemQueryOptions: ({ itemID, itemType }: { itemID: LibraryItemID; itemType: LibraryItemType }) => {
return itemType === LibraryItemType.RSFORM
? rsformsApi.getRSFormQueryOptions({ itemID })
: ossApi.getOssQueryOptions({ itemID });
},
2025-01-23 19:41:31 +03:00
getLibraryQueryOptions: ({ isAdmin }: { isAdmin: boolean }) =>
queryOptions({
2025-01-29 23:18:08 +03:00
queryKey: [...libraryApi.libraryListKey, isAdmin ? 'admin' : 'user'],
2025-01-23 19:41:31 +03:00
staleTime: DELAYS.staleMedium,
queryFn: meta =>
axiosGet<ILibraryItem[]>({
endpoint: isAdmin ? '/api/library/all' : '/api/library/active',
options: { signal: meta.signal }
})
2025-01-23 19:41:31 +03:00
}),
getTemplatesQueryOptions: () =>
queryOptions({
queryKey: [libraryApi.baseKey, 'templates'],
staleTime: DELAYS.staleMedium,
queryFn: meta =>
axiosGet<ILibraryItem[]>({
endpoint: '/api/library/templates',
options: { signal: meta.signal }
})
2025-01-23 19:41:31 +03:00
}),
2025-02-04 23:33:35 +03:00
createItem: (data: ICreateLibraryItemDTO) =>
axiosPost<ICreateLibraryItemDTO, ILibraryItem>({
endpoint: !data.file ? '/api/library' : '/api/rsforms/create-detailed',
request: {
data: data,
successMessage: information.newLibraryItem
},
options: !data.file
? undefined
: {
2025-01-23 19:41:31 +03:00
headers: {
'Content-Type': 'multipart/form-data'
}
}
}),
2025-02-04 23:33:35 +03:00
updateItem: (data: IUpdateLibraryItemDTO) =>
axiosPatch<IUpdateLibraryItemDTO, ILibraryItem>({
endpoint: `/api/library/${data.id}`,
request: {
data: data,
successMessage: information.changesSaved
}
}),
setOwner: ({ itemID, owner }: { itemID: LibraryItemID; owner: UserID }) =>
axiosPatch({
endpoint: `/api/library/${itemID}/set-owner`,
request: {
data: { user: owner },
successMessage: information.changesSaved
}
}),
setLocation: ({ itemID, location }: { itemID: LibraryItemID; location: string }) =>
axiosPatch({
endpoint: `/api/library/${itemID}/set-location`,
request: {
data: { location: location },
successMessage: information.moveComplete
}
}),
setAccessPolicy: ({ itemID, policy }: { itemID: LibraryItemID; policy: AccessPolicy }) =>
axiosPatch({
endpoint: `/api/library/${itemID}/set-access-policy`,
request: {
data: { access_policy: policy },
successMessage: information.changesSaved
}
}),
setEditors: ({ itemID, editors }: { itemID: LibraryItemID; editors: UserID[] }) =>
axiosPatch({
endpoint: `/api/library/${itemID}/set-editors`,
request: {
data: { users: editors },
successMessage: information.changesSaved
}
}),
2025-01-23 19:41:31 +03:00
deleteItem: (target: LibraryItemID) =>
axiosDelete({
endpoint: `/api/library/${target}`,
request: {
successMessage: information.itemDestroyed
}
}),
2025-02-06 14:09:20 +03:00
cloneItem: (data: ICloneLibraryItemDTO) =>
axiosPost<ICloneLibraryItemDTO, IRSFormDTO>({
endpoint: `/api/library/${data.id}/clone`,
request: {
data: data,
successMessage: newSchema => information.cloneComplete(newSchema.alias)
}
}),
2025-01-23 19:41:31 +03:00
renameLocation: (data: IRenameLocationDTO) =>
axiosPatch({
endpoint: '/api/library/rename-location',
request: {
data: data,
successMessage: information.locationRenamed
}
}),
2025-01-23 19:41:31 +03:00
2025-02-06 14:09:20 +03:00
versionCreate: ({ itemID, data }: { itemID: LibraryItemID; data: IVersionCreateDTO }) =>
axiosPost<IVersionCreateDTO, IVersionCreatedResponse>({
endpoint: `/api/library/${itemID}/create-version`,
request: {
data: data,
successMessage: information.newVersion(data.version)
}
}),
versionRestore: ({ versionID }: { versionID: VersionID }) =>
axiosPatch<undefined, IRSFormDTO>({
endpoint: `/api/versions/${versionID}/restore`,
request: {
successMessage: information.versionRestored
}
}),
2025-02-07 15:21:40 +03:00
versionUpdate: (data: IVersionUpdateDTO) =>
axiosPatch<IVersionUpdateDTO, IVersionInfo>({
endpoint: `/api/versions/${data.id}`,
request: {
data: data,
successMessage: information.changesSaved
}
}),
2025-01-23 19:41:31 +03:00
versionDelete: (data: { itemID: LibraryItemID; versionID: VersionID }) =>
axiosDelete({
endpoint: `/api/versions/${data.versionID}`,
request: {
successMessage: information.versionDestroyed
}
})
2025-01-23 19:41:31 +03:00
};