149 行
3.8 KiB
TypeScript
149 行
3.8 KiB
TypeScript
import {
|
|
apiGet,
|
|
isApiError,
|
|
apiPost,
|
|
apiPut,
|
|
} from '@/lib/api'
|
|
|
|
import type {
|
|
Material,
|
|
MaterialVersion,
|
|
FetchMaterialsParams,
|
|
MaterialFilter,
|
|
MaterialSyncSuppression,
|
|
MaterialSidebarTag,
|
|
MaterialTagTree,
|
|
} from '@/types'
|
|
|
|
export type FetchMaterialTreeParams = {
|
|
parentId?: number | null
|
|
materialFilter: MaterialFilter
|
|
}
|
|
|
|
export type MaterialIndexResponse = {
|
|
materials: Material[]
|
|
count: number
|
|
}
|
|
|
|
export type MaterialSyncSuppressionResponse = {
|
|
suppressions: MaterialSyncSuppression[]
|
|
}
|
|
|
|
export type MaterialChangesResponse = {
|
|
versions: MaterialVersion[]
|
|
count: number
|
|
}
|
|
|
|
const MATERIAL_FILTERS: MaterialFilter[] = ['present', 'missing', 'any']
|
|
|
|
|
|
export const parseMaterialFilter = (
|
|
value: unknown,
|
|
fallback: MaterialFilter = 'present'): MaterialFilter =>
|
|
typeof value === 'string' && MATERIAL_FILTERS.includes (value as MaterialFilter)
|
|
? value as MaterialFilter
|
|
: fallback
|
|
|
|
|
|
export const fetchMaterials = async (
|
|
{ q, tagState, mediaKind, createdFrom, createdTo,
|
|
updatedFrom, updatedTo, sort, direction, page,
|
|
limit }: FetchMaterialsParams): Promise<MaterialIndexResponse> =>
|
|
await apiGet ('/materials', { params: {
|
|
...(q && { q }),
|
|
tag_state: tagState,
|
|
media_kind: mediaKind,
|
|
...(createdFrom && { created_from: createdFrom }),
|
|
...(createdTo && { created_to: createdTo }),
|
|
...(updatedFrom && { updated_from: updatedFrom }),
|
|
...(updatedTo && { updated_to: updatedTo }),
|
|
sort,
|
|
direction,
|
|
page,
|
|
limit} })
|
|
|
|
|
|
export const fetchMaterial = async (id: string): Promise<Material | null> => {
|
|
try
|
|
{
|
|
return await apiGet (`/materials/${ id }`)
|
|
}
|
|
catch (error)
|
|
{
|
|
if (isApiError (error) && error.response?.status === 404)
|
|
return null
|
|
throw error
|
|
}
|
|
}
|
|
|
|
|
|
export const fetchMaterialChanges = async (
|
|
{ materialId, tag, eventType, page, limit }: {
|
|
materialId?: string
|
|
tag?: string
|
|
eventType?: string
|
|
page: number
|
|
limit: number
|
|
}): Promise<MaterialChangesResponse> =>
|
|
await apiGet ('/materials/versions', { params: {
|
|
...(materialId && { material_id: materialId }),
|
|
...(tag && { tag }),
|
|
...(eventType && { event_type: eventType }),
|
|
page,
|
|
limit} })
|
|
|
|
|
|
export const fetchMaterialTagTree = async (
|
|
{ parentId, materialFilter }: FetchMaterialTreeParams): Promise<MaterialSidebarTag[]> =>
|
|
await apiGet ('/tags/with-depth', { params: {
|
|
...(parentId != null && { parent: String (parentId) }),
|
|
material_filter: materialFilter} })
|
|
|
|
|
|
export const fetchMaterialTagByName = async (
|
|
name: string,
|
|
materialFilter: MaterialFilter): Promise<MaterialTagTree | null> => {
|
|
try
|
|
{
|
|
return await apiGet (`/tags/name/${ encodeURIComponent (name) }/materials`,
|
|
{ params: { material_filter: materialFilter } })
|
|
}
|
|
catch (error)
|
|
{
|
|
if (isApiError (error) && error.response?.status === 404)
|
|
return null
|
|
throw error
|
|
}
|
|
}
|
|
|
|
|
|
export const createMaterial = async (formData: FormData): Promise<Material> =>
|
|
await apiPost ('/materials', formData)
|
|
|
|
|
|
export const updateMaterial = async (
|
|
id: string,
|
|
formData: FormData): Promise<Material> =>
|
|
await apiPut (`/materials/${ id }`, formData)
|
|
|
|
|
|
export const fetchMaterialSyncSuppressions =
|
|
async (): Promise<MaterialSyncSuppressionResponse> =>
|
|
await apiGet ('/materials/suppressions')
|
|
|
|
|
|
export const createMaterialSyncSuppression = async (
|
|
payload: {
|
|
sourceKind: string
|
|
sourceUri?: string
|
|
drivePath?: string
|
|
driveFileId?: string
|
|
reason: string
|
|
}): Promise<MaterialSyncSuppression> =>
|
|
await apiPost ('/materials/suppressions', {
|
|
source_kind: payload.sourceKind,
|
|
source_uri: payload.sourceUri,
|
|
drive_path: payload.drivePath,
|
|
drive_file_id: payload.driveFileId,
|
|
reason: payload.reason})
|