ファイル
btrc-hub/frontend/src/lib/materials.ts
T
2026-06-26 00:21:33 +09:00

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})