このコミットが含まれているのは:
@@ -0,0 +1,114 @@
|
||||
import {
|
||||
apiGet,
|
||||
isApiError,
|
||||
apiPatch,
|
||||
apiPost,
|
||||
apiPut,
|
||||
} from '@/lib/api'
|
||||
|
||||
import type {
|
||||
Material,
|
||||
MaterialFilter,
|
||||
MaterialSidebarTag,
|
||||
MaterialTagTree,
|
||||
} from '@/types'
|
||||
|
||||
export type FetchMaterialsParams = {
|
||||
page?: number
|
||||
limit?: number
|
||||
tagId?: number | null
|
||||
parentId?: number | null
|
||||
unclassified?: boolean
|
||||
}
|
||||
|
||||
export type FetchMaterialTreeParams = {
|
||||
parentId?: number | null
|
||||
materialFilter: MaterialFilter
|
||||
}
|
||||
|
||||
export type MaterialIndexResponse = {
|
||||
materials: Material[]
|
||||
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 (
|
||||
{ page, limit, tagId, parentId, unclassified }: FetchMaterialsParams,
|
||||
): Promise<MaterialIndexResponse> =>
|
||||
await apiGet ('/materials', { params: {
|
||||
...(page != null && { page }),
|
||||
...(limit != null && { limit }),
|
||||
...(tagId != null && { tag_id: tagId }),
|
||||
...(parentId != null && { parent_id: parentId }),
|
||||
...(unclassified && { unclassified: '1' }),
|
||||
} })
|
||||
|
||||
|
||||
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 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 suppressMaterialFile = async (
|
||||
id: string,
|
||||
payload: { reason: string; purge?: boolean },
|
||||
): Promise<Material> =>
|
||||
await apiPatch (`/materials/${ id }/suppress_file`, payload)
|
||||
新しい課題から参照
ユーザをブロックする