110 lines
2.9 KiB
TypeScript
110 lines
2.9 KiB
TypeScript
|
|
/**
|
||
|
|
* Custom field definitions API hooks — CRUD for entity-level field definitions.
|
||
|
|
*/
|
||
|
|
|
||
|
|
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
|
||
|
|
import { apiGet, apiPost, apiPatch, apiDelete } from './client';
|
||
|
|
|
||
|
|
export type CustomFieldType = 'text' | 'number' | 'date' | 'select' | 'multiselect' | 'boolean';
|
||
|
|
|
||
|
|
export type CustomFieldEntity = 'contact' | 'company';
|
||
|
|
|
||
|
|
export interface CustomFieldDefinition {
|
||
|
|
id: string;
|
||
|
|
tenant_id: string;
|
||
|
|
entity: string;
|
||
|
|
name: string;
|
||
|
|
label: string;
|
||
|
|
field_type: CustomFieldType;
|
||
|
|
options: string[];
|
||
|
|
default_value: any;
|
||
|
|
required: boolean;
|
||
|
|
is_active: boolean;
|
||
|
|
sort_order: number;
|
||
|
|
created_at: string;
|
||
|
|
updated_at: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CustomFieldDefinitionCreate {
|
||
|
|
entity: string;
|
||
|
|
name: string;
|
||
|
|
label: string;
|
||
|
|
field_type: CustomFieldType;
|
||
|
|
options?: string[];
|
||
|
|
default_value?: any;
|
||
|
|
required?: boolean;
|
||
|
|
is_active?: boolean;
|
||
|
|
sort_order?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CustomFieldDefinitionUpdate {
|
||
|
|
name?: string;
|
||
|
|
label?: string;
|
||
|
|
field_type?: CustomFieldType;
|
||
|
|
options?: string[];
|
||
|
|
default_value?: any;
|
||
|
|
required?: boolean;
|
||
|
|
is_active?: boolean;
|
||
|
|
sort_order?: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface CustomFieldDefinitionsResponse {
|
||
|
|
items: CustomFieldDefinition[];
|
||
|
|
total: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Fetch custom field definitions, optionally filtered by entity.
|
||
|
|
*/
|
||
|
|
export function useCustomFieldDefinitions(entity?: string) {
|
||
|
|
return useQuery({
|
||
|
|
queryKey: ['custom-field-definitions', entity ?? 'all'],
|
||
|
|
queryFn: () => {
|
||
|
|
const params = entity ? `?entity=${encodeURIComponent(entity)}` : '';
|
||
|
|
return apiGet<CustomFieldDefinitionsResponse>(`/custom-fields/definitions${params}`);
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Create a new custom field definition.
|
||
|
|
*/
|
||
|
|
export function useCreateCustomFieldDefinition() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (data: CustomFieldDefinitionCreate) =>
|
||
|
|
apiPost<CustomFieldDefinition>('/custom-fields/definitions', data),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: ['custom-field-definitions'] });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Update an existing custom field definition.
|
||
|
|
*/
|
||
|
|
export function useUpdateCustomFieldDefinition() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: ({ id, data }: { id: string; data: CustomFieldDefinitionUpdate }) =>
|
||
|
|
apiPatch<CustomFieldDefinition>(`/custom-fields/definitions/${id}`, data),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: ['custom-field-definitions'] });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|
||
|
|
|
||
|
|
/**
|
||
|
|
* Delete a custom field definition.
|
||
|
|
*/
|
||
|
|
export function useDeleteCustomFieldDefinition() {
|
||
|
|
const queryClient = useQueryClient();
|
||
|
|
return useMutation({
|
||
|
|
mutationFn: (id: string) =>
|
||
|
|
apiDelete<void>(`/custom-fields/definitions/${id}`),
|
||
|
|
onSuccess: () => {
|
||
|
|
queryClient.invalidateQueries({ queryKey: ['custom-field-definitions'] });
|
||
|
|
},
|
||
|
|
});
|
||
|
|
}
|