фильтры
This commit is contained in:
@@ -9,7 +9,7 @@ export interface CreateTemplateOutput {
|
||||
}
|
||||
|
||||
export interface GetTemplatesOutput {
|
||||
templates: ApiTemplate[]
|
||||
templates: ApiTemplateWithAttributes[]
|
||||
}
|
||||
|
||||
export interface GetTemplateOutput {
|
||||
@@ -24,6 +24,10 @@ export interface PatchTemplateInput {
|
||||
name?: string | null
|
||||
description?: string | null
|
||||
elements?: Record<string, any> | null
|
||||
attributes?: Array<{
|
||||
attribute_id: string
|
||||
value: string | null
|
||||
}> | null
|
||||
}
|
||||
|
||||
export interface PatchTemplateOutput {
|
||||
@@ -126,6 +130,7 @@ export function templateToPatchInput(template: Template): PatchTemplateInput {
|
||||
name: template.name,
|
||||
description: template.description,
|
||||
elements,
|
||||
// attributes будут добавлены отдельно в TemplateContext при необходимости
|
||||
}
|
||||
}
|
||||
|
||||
@@ -178,7 +183,7 @@ export async function getTemplatesApi(): Promise<GetTemplatesOutput> {
|
||||
|
||||
// API получение конкретного шаблона
|
||||
export async function getTemplateApi(
|
||||
templateId: UUID
|
||||
templateId: string
|
||||
): Promise<GetTemplateOutput> {
|
||||
try {
|
||||
const response = await fetch(`/api/templates/${templateId}`, {
|
||||
@@ -202,18 +207,15 @@ export async function getTemplateApi(
|
||||
|
||||
// API получение шаблона с атрибутами
|
||||
export async function getTemplateWithAttributesApi(
|
||||
templateId: UUID
|
||||
templateId: string
|
||||
): Promise<GetTemplateWithAttributesOutput> {
|
||||
try {
|
||||
const response = await fetch(
|
||||
`/api/templates/${templateId}/with-attributes`,
|
||||
{
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
}
|
||||
)
|
||||
const response = await fetch(`/api/templates/${templateId}`, {
|
||||
method: 'GET',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
@@ -260,3 +262,73 @@ export async function updateTemplate(
|
||||
const patchInput = templateToPatchInput(template)
|
||||
return patchTemplateApi(template.id, patchInput)
|
||||
}
|
||||
|
||||
// Интерфейсы для копирования шаблона
|
||||
export interface CopyTemplateInput {
|
||||
template_id: string
|
||||
new_name: string
|
||||
new_description?: string | null
|
||||
new_attributes?: Array<{
|
||||
attribute_id: string
|
||||
value: string | null
|
||||
}> | null
|
||||
}
|
||||
|
||||
export interface CopyTemplateOutput {
|
||||
new_template_id: string
|
||||
}
|
||||
|
||||
// Интерфейсы для удаления шаблона
|
||||
export interface DeleteTemplateOutput {
|
||||
success: boolean
|
||||
template_id: string
|
||||
}
|
||||
|
||||
// API копирование шаблона
|
||||
export async function copyTemplateApi(
|
||||
input: CopyTemplateInput
|
||||
): Promise<CopyTemplateOutput> {
|
||||
try {
|
||||
const response = await fetch('/api/templates/copy', {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(input),
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: CopyTemplateOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при копировании шаблона:', error)
|
||||
throw new Error('Ошибка при копировании шаблона на сервере')
|
||||
}
|
||||
}
|
||||
|
||||
// API удаление шаблона
|
||||
export async function deleteTemplateApi(
|
||||
templateId: string
|
||||
): Promise<DeleteTemplateOutput> {
|
||||
try {
|
||||
const response = await fetch(`/api/templates/${templateId}`, {
|
||||
method: 'DELETE',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`)
|
||||
}
|
||||
|
||||
const result: DeleteTemplateOutput = await response.json()
|
||||
return result
|
||||
} catch (error) {
|
||||
console.error('Ошибка при удалении шаблона:', error)
|
||||
throw new Error('Ошибка при удалении шаблона на сервере')
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
import {
|
||||
apiTemplateToTemplate,
|
||||
apiTemplateWithAttributesToTemplate,
|
||||
copyTemplateApi,
|
||||
CopyTemplateInput,
|
||||
createTemplateApi,
|
||||
deleteTemplateApi,
|
||||
getTemplateApi,
|
||||
getTemplatesApi,
|
||||
patchTemplateApi,
|
||||
@@ -26,8 +30,17 @@ interface TemplateContextType {
|
||||
addTemplate: (
|
||||
data: Omit<Template, 'id' | 'createdAt' | 'updatedAt'>
|
||||
) => Promise<Template>
|
||||
updateTemplate: (template: Template) => Promise<Template>
|
||||
deleteTemplate: (id: UUID) => Promise<string>
|
||||
updateTemplate: (
|
||||
template: Template,
|
||||
attributes?: Array<{ attributeId: string; value: string | null }>
|
||||
) => Promise<Template>
|
||||
deleteTemplate: (id: string) => Promise<string>
|
||||
copyTemplate: (
|
||||
templateId: string,
|
||||
newName: string,
|
||||
newDescription?: string,
|
||||
attributes?: Array<{ attributeId: string; value: string | null }>
|
||||
) => Promise<Template>
|
||||
}
|
||||
|
||||
const TemplateContext = createContext<TemplateContextType | undefined>(
|
||||
@@ -48,7 +61,7 @@ export const TemplateProvider: React.FC<{ children: ReactNode }> = ({
|
||||
queryKey: ['templates'],
|
||||
queryFn: async () => {
|
||||
const { templates: apiList } = await getTemplatesApi()
|
||||
return apiList.map(apiTemplateToTemplate)
|
||||
return apiList.map(apiTemplateWithAttributesToTemplate)
|
||||
},
|
||||
})
|
||||
|
||||
@@ -68,8 +81,20 @@ export const TemplateProvider: React.FC<{ children: ReactNode }> = ({
|
||||
})
|
||||
|
||||
const updateMutation = useMutation({
|
||||
mutationFn: async (template: Template) => {
|
||||
mutationFn: async ({
|
||||
template,
|
||||
attributes,
|
||||
}: {
|
||||
template: Template
|
||||
attributes?: Array<{ attributeId: string; value: string | null }>
|
||||
}) => {
|
||||
const input = templateToPatchInput(template)
|
||||
if (attributes) {
|
||||
input.attributes = attributes.map(attr => ({
|
||||
attribute_id: attr.attributeId,
|
||||
value: attr.value,
|
||||
}))
|
||||
}
|
||||
await patchTemplateApi(template.id, input)
|
||||
return template
|
||||
},
|
||||
@@ -84,7 +109,10 @@ export const TemplateProvider: React.FC<{ children: ReactNode }> = ({
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
mutationFn: async (id: string) => {
|
||||
// TODO: deleteTemplateApi
|
||||
const result = await deleteTemplateApi(id)
|
||||
if (!result.success) {
|
||||
throw new Error('Не удалось удалить шаблон')
|
||||
}
|
||||
return id
|
||||
},
|
||||
onSuccess: id => {
|
||||
@@ -95,6 +123,38 @@ export const TemplateProvider: React.FC<{ children: ReactNode }> = ({
|
||||
},
|
||||
})
|
||||
|
||||
const copyMutation = useMutation({
|
||||
mutationFn: async ({
|
||||
templateId,
|
||||
newName,
|
||||
newDescription,
|
||||
attributes,
|
||||
}: {
|
||||
templateId: string
|
||||
newName: string
|
||||
newDescription?: string
|
||||
attributes?: Array<{ attributeId: string; value: string | null }>
|
||||
}) => {
|
||||
const input: CopyTemplateInput = {
|
||||
template_id: templateId,
|
||||
new_name: newName,
|
||||
new_description: newDescription || null,
|
||||
new_attributes:
|
||||
attributes?.map(attr => ({
|
||||
attribute_id: attr.attributeId,
|
||||
value: attr.value,
|
||||
})) || null,
|
||||
}
|
||||
const { new_template_id } = await copyTemplateApi(input)
|
||||
const { template: apiTpl } = await getTemplateApi(new_template_id)
|
||||
if (!apiTpl) throw new Error('Copied template not found')
|
||||
return apiTemplateToTemplate(apiTpl)
|
||||
},
|
||||
onSuccess: () => {
|
||||
client.invalidateQueries({ queryKey: ['templates'] })
|
||||
},
|
||||
})
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
templates,
|
||||
@@ -102,17 +162,38 @@ export const TemplateProvider: React.FC<{ children: ReactNode }> = ({
|
||||
listStatus === 'pending' ||
|
||||
createMutation.status === 'pending' ||
|
||||
updateMutation.status === 'pending' ||
|
||||
deleteMutation.status === 'pending',
|
||||
deleteMutation.status === 'pending' ||
|
||||
copyMutation.status === 'pending',
|
||||
error:
|
||||
(errorList as Error) ||
|
||||
(createMutation.error as Error) ||
|
||||
(updateMutation.error as Error) ||
|
||||
(deleteMutation.error as Error) ||
|
||||
(copyMutation.error as Error) ||
|
||||
null,
|
||||
refetchTemplates: refetch,
|
||||
addTemplate: createMutation.mutateAsync,
|
||||
updateTemplate: updateMutation.mutateAsync,
|
||||
updateTemplate: async (
|
||||
template: Template,
|
||||
attributes?: Array<{ attributeId: string; value: string | null }>
|
||||
) =>
|
||||
updateMutation.mutateAsync({
|
||||
template,
|
||||
attributes,
|
||||
}),
|
||||
deleteTemplate: deleteMutation.mutateAsync,
|
||||
copyTemplate: async (
|
||||
templateId: string,
|
||||
newName: string,
|
||||
newDescription?: string,
|
||||
attributes?: Array<{ attributeId: string; value: string | null }>
|
||||
) =>
|
||||
copyMutation.mutateAsync({
|
||||
templateId,
|
||||
newName,
|
||||
newDescription,
|
||||
attributes,
|
||||
}),
|
||||
}),
|
||||
[
|
||||
templates,
|
||||
@@ -124,10 +205,13 @@ export const TemplateProvider: React.FC<{ children: ReactNode }> = ({
|
||||
updateMutation.error,
|
||||
deleteMutation.status,
|
||||
deleteMutation.error,
|
||||
copyMutation.status,
|
||||
copyMutation.error,
|
||||
refetch,
|
||||
createMutation.mutateAsync,
|
||||
updateMutation.mutateAsync,
|
||||
deleteMutation.mutateAsync,
|
||||
copyMutation.mutateAsync,
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user