feat: modules and module-editor pages
This commit is contained in:
@ -16,6 +16,7 @@ import {
|
||||
import { theme } from "@/theme";
|
||||
import "@/app/global.css";
|
||||
import { ContextMenuProvider } from "mantine-contextmenu";
|
||||
import { DatesProvider } from "@mantine/dates";
|
||||
import { ModalsProvider } from "@mantine/modals";
|
||||
import { Notifications } from "@mantine/notifications";
|
||||
import { ProjectsContextProvider } from "@/app/deals/contexts/ProjectsContext";
|
||||
@ -71,31 +72,33 @@ export default function RootLayout({ children }: Props) {
|
||||
<ModalsProvider
|
||||
labels={{ confirm: "Да", cancel: "Нет" }}
|
||||
modals={modals}>
|
||||
<DrawersContextProvider>
|
||||
<ProjectsContextProvider>
|
||||
<AppShell
|
||||
layout={"alt"}
|
||||
withBorder={false}
|
||||
navbar={{
|
||||
width: 220,
|
||||
breakpoint: "sm",
|
||||
collapsed: {
|
||||
desktop: false,
|
||||
mobile: true,
|
||||
},
|
||||
}}>
|
||||
<AppShellNavbarWrapper>
|
||||
<Navbar />
|
||||
</AppShellNavbarWrapper>
|
||||
<AppShellMainWrapper>
|
||||
{children}
|
||||
</AppShellMainWrapper>
|
||||
<AppShellFooterWrapper>
|
||||
<Footer />
|
||||
</AppShellFooterWrapper>
|
||||
</AppShell>
|
||||
</ProjectsContextProvider>
|
||||
</DrawersContextProvider>
|
||||
<DatesProvider settings={{ locale: "ru" }}>
|
||||
<DrawersContextProvider>
|
||||
<ProjectsContextProvider>
|
||||
<AppShell
|
||||
layout={"alt"}
|
||||
withBorder={false}
|
||||
navbar={{
|
||||
width: 220,
|
||||
breakpoint: "sm",
|
||||
collapsed: {
|
||||
desktop: false,
|
||||
mobile: true,
|
||||
},
|
||||
}}>
|
||||
<AppShellNavbarWrapper>
|
||||
<Navbar />
|
||||
</AppShellNavbarWrapper>
|
||||
<AppShellMainWrapper>
|
||||
{children}
|
||||
</AppShellMainWrapper>
|
||||
<AppShellFooterWrapper>
|
||||
<Footer />
|
||||
</AppShellFooterWrapper>
|
||||
</AppShell>
|
||||
</ProjectsContextProvider>
|
||||
</DrawersContextProvider>
|
||||
</DatesProvider>
|
||||
</ModalsProvider>
|
||||
</ReduxProvider>
|
||||
<Notifications position="bottom-right" />
|
||||
|
||||
12
src/app/module-editor/[moduleId]/ModuleEditor.module.css
Normal file
12
src/app/module-editor/[moduleId]/ModuleEditor.module.css
Normal file
@ -0,0 +1,12 @@
|
||||
.container {
|
||||
padding: var(--mantine-spacing-sm);
|
||||
border: dashed 1px var(--mantine-color-default-border);
|
||||
border-radius: var(--mantine-radius-lg);
|
||||
}
|
||||
|
||||
.module-attr-container {
|
||||
@mixin light {
|
||||
background-color: var(--color-light-gray-blue);
|
||||
border: 1px dashed var(--color-light-aqua);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,68 @@
|
||||
import { FC, useCallback, useMemo } from "react";
|
||||
import {
|
||||
IconArrowRight,
|
||||
IconEdit,
|
||||
IconTrash,
|
||||
IconX,
|
||||
} from "@tabler/icons-react";
|
||||
import { Center, Flex } from "@mantine/core";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||
import { AttributeSchema } from "@/lib/client";
|
||||
|
||||
type Props = {
|
||||
attribute: AttributeSchema;
|
||||
};
|
||||
|
||||
const AttributeTableActions: FC<Props> = ({ attribute }) => {
|
||||
const { attributeActions, module } = useModuleEditorContext();
|
||||
const usedAttributeIds = useMemo(
|
||||
() => new Set(module?.attributes.map(a => a.id)),
|
||||
[module]
|
||||
);
|
||||
|
||||
const toggleAttributeInModule = useCallback(
|
||||
(attribute: AttributeSchema) => {
|
||||
if (usedAttributeIds.has(attribute.id)) {
|
||||
attributeActions.removeAttributeFromModule(attribute);
|
||||
} else {
|
||||
attributeActions.addAttributeToModule(attribute);
|
||||
}
|
||||
},
|
||||
[usedAttributeIds]
|
||||
);
|
||||
|
||||
return (
|
||||
<Center>
|
||||
<Flex gap={"xs"}>
|
||||
<ActionIconWithTip
|
||||
onClick={() => attributeActions.onUpdate(attribute)}
|
||||
disabled={attribute.isBuiltIn}
|
||||
tipLabel={"Редактировать"}>
|
||||
<IconEdit />
|
||||
</ActionIconWithTip>
|
||||
<ActionIconWithTip
|
||||
onClick={() => attributeActions.onDelete(attribute)}
|
||||
disabled={attribute.isBuiltIn}
|
||||
tipLabel={"Удалить"}>
|
||||
<IconTrash />
|
||||
</ActionIconWithTip>
|
||||
<ActionIconWithTip
|
||||
onClick={() => toggleAttributeInModule(attribute)}
|
||||
tipLabel={
|
||||
usedAttributeIds.has(attribute.id)
|
||||
? "Удалить из модуля"
|
||||
: "Добавить в модуль"
|
||||
}>
|
||||
{usedAttributeIds.has(attribute.id) ? (
|
||||
<IconX />
|
||||
) : (
|
||||
<IconArrowRight />
|
||||
)}
|
||||
</ActionIconWithTip>
|
||||
</Flex>
|
||||
</Center>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttributeTableActions;
|
||||
@ -0,0 +1,21 @@
|
||||
import useAttributeTypesList from "@/app/module-editor/[moduleId]/hooks/useAttributeTypesList";
|
||||
import ObjectSelect, {
|
||||
ObjectSelectProps,
|
||||
} from "@/components/selects/ObjectSelect/ObjectSelect";
|
||||
import { AttributeTypeSchema } from "@/lib/client";
|
||||
|
||||
type Props = Omit<ObjectSelectProps<AttributeTypeSchema>, "data">;
|
||||
|
||||
const AttributeTypeSelect = (props: Props) => {
|
||||
const { attributeTypes } = useAttributeTypesList();
|
||||
|
||||
return (
|
||||
<ObjectSelect
|
||||
label={"Тип атрибута"}
|
||||
data={attributeTypes}
|
||||
{...props}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttributeTypeSelect;
|
||||
@ -0,0 +1,34 @@
|
||||
import { Box, Center, Text } from "@mantine/core";
|
||||
import useAttributesTableColumns from "@/app/module-editor/[moduleId]/components/shared/AttributesTable/useAttributesTableColumns";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
||||
|
||||
const AttributesTable = () => {
|
||||
const { attributes } = useModuleEditorContext();
|
||||
const columns = useAttributesTableColumns();
|
||||
|
||||
if (attributes.length === 0) {
|
||||
return (
|
||||
<Center my={"md"}>
|
||||
<Text>Нет атрибутов</Text>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Box
|
||||
h="100%"
|
||||
style={{ overflow: "auto" }}>
|
||||
<BaseTable
|
||||
withTableBorder
|
||||
columns={columns}
|
||||
records={attributes}
|
||||
verticalSpacing={"md"}
|
||||
groups={undefined}
|
||||
styles={{ table: { width: "100%" } }}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttributesTable;
|
||||
@ -0,0 +1,37 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { DataTableColumn } from "mantine-datatable";
|
||||
import { Center } from "@mantine/core";
|
||||
import AttributeTableActions from "@/app/module-editor/[moduleId]/components/shared/AttributeTableActions/AttributeTableActions";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import { AttributeSchema } from "@/lib/client";
|
||||
|
||||
const useAttributesTableColumns = () => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
[
|
||||
{
|
||||
title: "Название",
|
||||
accessor: "label",
|
||||
},
|
||||
{
|
||||
title: "Тип",
|
||||
accessor: "type.name",
|
||||
},
|
||||
{
|
||||
accessor: "actions",
|
||||
title: <Center>Действия</Center>,
|
||||
width: "0%",
|
||||
render: attribute => (
|
||||
<AttributeTableActions attribute={attribute} />
|
||||
),
|
||||
},
|
||||
] as DataTableColumn<AttributeSchema>[],
|
||||
[isMobile]
|
||||
);
|
||||
};
|
||||
|
||||
export default useAttributesTableColumns;
|
||||
@ -0,0 +1,18 @@
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import InlineButton from "@/components/ui/InlineButton/InlineButton";
|
||||
|
||||
const CreateAttributeButton = () => {
|
||||
const {
|
||||
attributeActions: { onCreate },
|
||||
} = useModuleEditorContext();
|
||||
|
||||
return (
|
||||
<InlineButton
|
||||
onClick={onCreate}
|
||||
w={"100%"}>
|
||||
Создать атрибут
|
||||
</InlineButton>
|
||||
);
|
||||
};
|
||||
|
||||
export default CreateAttributeButton;
|
||||
@ -0,0 +1,90 @@
|
||||
import { Checkbox, NumberInput, TextInput } from "@mantine/core";
|
||||
import { DatePickerInput, DateTimePicker } from "@mantine/dates";
|
||||
import { UseFormReturnType } from "@mantine/form";
|
||||
import { UpdateAttributeSchema } from "@/lib/client";
|
||||
|
||||
type Props = {
|
||||
form: UseFormReturnType<Partial<UpdateAttributeSchema>>;
|
||||
};
|
||||
|
||||
const DefaultAttributeValueInput = ({ form }: Props) => {
|
||||
const type = form.values.type?.type;
|
||||
const label = "Значение по умолчанию";
|
||||
const inputName = "defaultValue";
|
||||
|
||||
const value = form.getValues().defaultValue?.value;
|
||||
|
||||
if (type === "bool") {
|
||||
return (
|
||||
<Checkbox
|
||||
label={label}
|
||||
{...form.getInputProps(inputName, { type: "checkbox" })}
|
||||
checked={value as boolean}
|
||||
onChange={e =>
|
||||
form.setFieldValue("defaultValue", {
|
||||
value: e.currentTarget.checked,
|
||||
})
|
||||
}
|
||||
/>
|
||||
);
|
||||
} else if (type === "date") {
|
||||
return (
|
||||
<DatePickerInput
|
||||
label={label}
|
||||
{...form.getInputProps(inputName)}
|
||||
value={
|
||||
form.values.defaultValue?.value
|
||||
? new Date(String(form.values.defaultValue.value))
|
||||
: null
|
||||
}
|
||||
onChange={value =>
|
||||
form.setFieldValue("defaultValue", { value })
|
||||
}
|
||||
clearable
|
||||
locale={"ru"}
|
||||
valueFormat={"DD.MM.YYYY"}
|
||||
/>
|
||||
);
|
||||
} else if (type === "datetime") {
|
||||
return (
|
||||
<DateTimePicker
|
||||
label={label}
|
||||
{...form.getInputProps(inputName)}
|
||||
value={
|
||||
form.values.defaultValue?.value
|
||||
? new Date(String(form.values.defaultValue.value))
|
||||
: null
|
||||
}
|
||||
onChange={value =>
|
||||
form.setFieldValue("defaultValue", { value })
|
||||
}
|
||||
clearable
|
||||
locale={"ru"}
|
||||
valueFormat={"DD.MM.YYYY HH:mm"}
|
||||
/>
|
||||
);
|
||||
} else if (type === "str") {
|
||||
return (
|
||||
<TextInput
|
||||
label={label}
|
||||
{...form.getInputProps(inputName)}
|
||||
/>
|
||||
);
|
||||
} else if (type === "int" || type === "float") {
|
||||
return (
|
||||
<NumberInput
|
||||
allowDecimal={type === "float"}
|
||||
label={label}
|
||||
{...form.getInputProps(inputName)}
|
||||
value={Number(form.values.defaultValue?.value)}
|
||||
onChange={value =>
|
||||
form.setFieldValue("defaultValue", { value: Number(value) })
|
||||
}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <></>;
|
||||
};
|
||||
|
||||
export default DefaultAttributeValueInput;
|
||||
@ -0,0 +1,68 @@
|
||||
import { FC } from "react";
|
||||
import { IconEdit, IconX } from "@tabler/icons-react";
|
||||
import { Card, Group, Stack, Text, Title } from "@mantine/core";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import styles from "@/app/module-editor/[moduleId]/ModuleEditor.module.css";
|
||||
import ActionIconWithTip from "@/components/ui/ActionIconWithTip/ActionIconWithTip";
|
||||
import { ModuleAttributeSchema } from "@/lib/client";
|
||||
|
||||
type Props = {
|
||||
attribute: ModuleAttributeSchema;
|
||||
};
|
||||
|
||||
const ModuleAttribute: FC<Props> = ({ attribute }) => {
|
||||
const {
|
||||
attributeActions: { removeAttributeFromModule, onEditAttributeLabel },
|
||||
} = useModuleEditorContext();
|
||||
|
||||
const getAttrLabelText = () => {
|
||||
const order = 6;
|
||||
|
||||
if (attribute.label === attribute.originalLabel) {
|
||||
return <Title order={order}>Название: {attribute.label}</Title>;
|
||||
}
|
||||
return (
|
||||
<Group gap={"xs"}>
|
||||
<Title order={order}>Название: {attribute.label}</Title>{" "}
|
||||
<Text>(Ориг. {attribute.originalLabel})</Text>
|
||||
</Group>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<Card
|
||||
flex={1}
|
||||
className={styles["module-attr-container"]}>
|
||||
<Group
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
justify={"space-between"}
|
||||
align={"center"}>
|
||||
<Stack gap={7}>
|
||||
<>{getAttrLabelText()}</>
|
||||
<Text>Тип: {attribute.type.name}</Text>
|
||||
</Stack>
|
||||
<Group
|
||||
justify={"end"}
|
||||
wrap={"nowrap"}
|
||||
w={"100%"}
|
||||
gap={"xs"}>
|
||||
<ActionIconWithTip
|
||||
tipLabel={
|
||||
"Редактировать название (только для данного модуля)"
|
||||
}
|
||||
onClick={() => onEditAttributeLabel(attribute)}>
|
||||
<IconEdit />
|
||||
</ActionIconWithTip>
|
||||
<ActionIconWithTip
|
||||
tipLabel={"Удалить из модуля"}
|
||||
onClick={() => removeAttributeFromModule(attribute)}>
|
||||
<IconX />
|
||||
</ActionIconWithTip>
|
||||
</Group>
|
||||
</Group>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModuleAttribute;
|
||||
@ -0,0 +1,41 @@
|
||||
import React, { ReactNode } from "react";
|
||||
import { Flex } from "@mantine/core";
|
||||
import ModuleAttribute from "@/app/module-editor/[moduleId]/components/shared/ModuleAttribute/ModuleAttribute";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import FormFlexRow from "@/components/ui/FormFlexRow/FormFlexRow";
|
||||
|
||||
const ModuleAttributesEditor = () => {
|
||||
const { module } = useModuleEditorContext();
|
||||
|
||||
const getAttributesRows = () => {
|
||||
if (!module?.attributes) return [];
|
||||
|
||||
const rows: ReactNode[] = [];
|
||||
for (let i = 0; i < module.attributes.length; i += 2) {
|
||||
const rightIdx = i + 1;
|
||||
|
||||
rows.push(
|
||||
<FormFlexRow key={i}>
|
||||
<ModuleAttribute attribute={module.attributes[i]} />
|
||||
{rightIdx < module.attributes.length && (
|
||||
<ModuleAttribute
|
||||
attribute={module.attributes[rightIdx]}
|
||||
/>
|
||||
)}
|
||||
</FormFlexRow>
|
||||
);
|
||||
}
|
||||
|
||||
return rows;
|
||||
};
|
||||
|
||||
return (
|
||||
<Flex
|
||||
gap={"xs"}
|
||||
direction={"column"}>
|
||||
{getAttributesRows()}
|
||||
</Flex>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModuleAttributesEditor;
|
||||
@ -0,0 +1,52 @@
|
||||
import { Button, Flex, Group, Textarea, TextInput } from "@mantine/core";
|
||||
import { useForm } from "@mantine/form";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import { ModuleInfo } from "../../../hooks/useModulesActions";
|
||||
|
||||
const ModuleCommonInfoEditor = () => {
|
||||
const {
|
||||
module,
|
||||
moduleActions: { updateCommonInfo },
|
||||
} = useModuleEditorContext();
|
||||
|
||||
const form = useForm<ModuleInfo>({
|
||||
initialValues: module ?? {
|
||||
label: "",
|
||||
description: "",
|
||||
},
|
||||
validate: {
|
||||
label: label => !label && "Введите название модуля",
|
||||
},
|
||||
});
|
||||
|
||||
const onSubmit = (values: ModuleInfo) => {
|
||||
updateCommonInfo(values, form.resetDirty);
|
||||
};
|
||||
|
||||
return (
|
||||
<form onSubmit={form.onSubmit(onSubmit)}>
|
||||
<Flex
|
||||
gap={"xs"}
|
||||
direction={"column"}>
|
||||
<TextInput
|
||||
label={"Название"}
|
||||
{...form.getInputProps("label")}
|
||||
/>
|
||||
<Textarea
|
||||
label={"Описание"}
|
||||
{...form.getInputProps("description")}
|
||||
/>
|
||||
<Group>
|
||||
<Button
|
||||
variant={"default"}
|
||||
disabled={!form.isDirty()}
|
||||
type={"submit"}>
|
||||
Сохранить
|
||||
</Button>
|
||||
</Group>
|
||||
</Flex>
|
||||
</form>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModuleCommonInfoEditor;
|
||||
@ -0,0 +1,59 @@
|
||||
"use client";
|
||||
|
||||
import { Box, Fieldset, Flex, Stack } from "@mantine/core";
|
||||
import AttributesTable from "@/app/module-editor/[moduleId]/components/shared/AttributesTable/AttributesTable";
|
||||
import CreateAttributeButton from "@/app/module-editor/[moduleId]/components/shared/CreateAttributeButton/CreateAttributeButton";
|
||||
import ModuleAttributesEditor from "@/app/module-editor/[moduleId]/components/shared/ModuleAttributesEditor/ModuleAttributesEditor";
|
||||
import ModuleCommonInfoEditor from "@/app/module-editor/[moduleId]/components/shared/ModuleCommonInfoEditor/ModuleCommonInfoEditor";
|
||||
import { useModuleEditorContext } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||
|
||||
const PageBody = () => {
|
||||
const { module } = useModuleEditorContext();
|
||||
|
||||
return (
|
||||
<Stack h={"100%"}>
|
||||
<PageBlock
|
||||
style={{ flex: 1, minHeight: 0 }}
|
||||
fullScreenMobile>
|
||||
<Flex
|
||||
w={"100%"}
|
||||
h={"100%"}
|
||||
flex={3}
|
||||
style={{ overflow: "auto" }}
|
||||
gap={"md"}>
|
||||
<Fieldset
|
||||
flex={1}
|
||||
legend={"Атрибуты"}>
|
||||
<Flex
|
||||
direction={"column"}
|
||||
h={"100%"}
|
||||
gap={"xs"}>
|
||||
<Box style={{ flex: 1, minHeight: 0 }}>
|
||||
<AttributesTable />
|
||||
</Box>
|
||||
<CreateAttributeButton />
|
||||
</Flex>
|
||||
</Fieldset>
|
||||
<Flex
|
||||
gap={"xs"}
|
||||
flex={2}
|
||||
direction={"column"}>
|
||||
<Fieldset
|
||||
flex={1}
|
||||
legend={"Общие данные модуля"}>
|
||||
{module && <ModuleCommonInfoEditor />}
|
||||
</Fieldset>
|
||||
<Fieldset
|
||||
flex={3}
|
||||
legend={"Атрибуты модуля"}>
|
||||
<ModuleAttributesEditor />
|
||||
</Fieldset>
|
||||
</Flex>
|
||||
</Flex>
|
||||
</PageBlock>
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default PageBody;
|
||||
@ -0,0 +1,71 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect } from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import useAttributesActions, {
|
||||
AttributesActions,
|
||||
} from "@/app/module-editor/[moduleId]/hooks/useAttributesActions";
|
||||
import useAttributesList from "@/app/module-editor/[moduleId]/hooks/useAttributesList";
|
||||
import useModulesActions, {
|
||||
ModulesActions,
|
||||
} from "@/app/module-editor/[moduleId]/hooks/useModulesActions";
|
||||
import { AttributeSchema, ModuleWithAttributesSchema } from "@/lib/client";
|
||||
import { getModuleWithAttributesOptions } from "@/lib/client/@tanstack/react-query.gen";
|
||||
import makeContext from "@/lib/contextFactory/contextFactory";
|
||||
|
||||
type ModuleEditorContextState = {
|
||||
module?: ModuleWithAttributesSchema;
|
||||
refetchModule: () => void;
|
||||
attributes: AttributeSchema[];
|
||||
refetchAttributes: () => void;
|
||||
attributeActions: AttributesActions;
|
||||
moduleActions: ModulesActions;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
moduleId: number;
|
||||
};
|
||||
|
||||
const useModuleEditorContextState = ({
|
||||
moduleId,
|
||||
}: Props): ModuleEditorContextState => {
|
||||
const { data, refetch: refetchModule } = useQuery(
|
||||
getModuleWithAttributesOptions({ path: { pk: moduleId } })
|
||||
);
|
||||
const module = data?.entity;
|
||||
|
||||
const { attributes, refetch: refetchAttributes } = useAttributesList();
|
||||
|
||||
useEffect(() => {
|
||||
if (module?.isBuiltIn) {
|
||||
redirect("modules");
|
||||
}
|
||||
}, [module]);
|
||||
|
||||
const attributeActions = useAttributesActions({
|
||||
module,
|
||||
refetchModule,
|
||||
refetchAttributes,
|
||||
});
|
||||
|
||||
const moduleActions = useModulesActions({
|
||||
module,
|
||||
refetchModule,
|
||||
});
|
||||
|
||||
return {
|
||||
module,
|
||||
refetchModule,
|
||||
attributes,
|
||||
refetchAttributes,
|
||||
attributeActions,
|
||||
moduleActions,
|
||||
};
|
||||
};
|
||||
|
||||
export const [ModuleEditorContextProvider, useModuleEditorContext] =
|
||||
makeContext<ModuleEditorContextState, Props>(
|
||||
useModuleEditorContextState,
|
||||
"ModuleEditor"
|
||||
);
|
||||
@ -0,0 +1,13 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getAttributeTypesOptions } from "@/lib/client/@tanstack/react-query.gen";
|
||||
|
||||
const useAttributeTypesList = () => {
|
||||
const { data, refetch } = useQuery(getAttributeTypesOptions());
|
||||
|
||||
return {
|
||||
attributeTypes: data?.items ?? [],
|
||||
refetch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useAttributeTypesList;
|
||||
214
src/app/module-editor/[moduleId]/hooks/useAttributesActions.tsx
Normal file
214
src/app/module-editor/[moduleId]/hooks/useAttributesActions.tsx
Normal file
@ -0,0 +1,214 @@
|
||||
import React from "react";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { AxiosError } from "axios";
|
||||
import { Text } from "@mantine/core";
|
||||
import { modals } from "@mantine/modals";
|
||||
import {
|
||||
AttributeSchema,
|
||||
HttpValidationError,
|
||||
ModuleSchemaOutput,
|
||||
} from "@/lib/client";
|
||||
import {
|
||||
addAttributeToModuleMutation,
|
||||
createAttributeMutation,
|
||||
deleteAttributeMutation,
|
||||
removeAttributeFromModuleMutation,
|
||||
updateAttributeLabelMutation,
|
||||
updateAttributeMutation,
|
||||
} from "@/lib/client/@tanstack/react-query.gen";
|
||||
import { notifications } from "@/lib/notifications";
|
||||
|
||||
export type AttributesActions = {
|
||||
addAttributeToModule: (attribute: AttributeSchema) => void;
|
||||
removeAttributeFromModule: (attribute: AttributeSchema) => void;
|
||||
onEditAttributeLabel: (attribute: AttributeSchema) => void;
|
||||
onCreate: () => void;
|
||||
onUpdate: (attribute: AttributeSchema) => void;
|
||||
onDelete: (attribute: AttributeSchema) => void;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
module?: ModuleSchemaOutput;
|
||||
refetchModule: () => void;
|
||||
refetchAttributes: () => void;
|
||||
};
|
||||
|
||||
const useAttributesActions = ({
|
||||
module,
|
||||
refetchModule,
|
||||
refetchAttributes,
|
||||
}: Props): AttributesActions => {
|
||||
const onError = (error: AxiosError<HttpValidationError>) => {
|
||||
console.error(error);
|
||||
notifications.error({
|
||||
message: error.response?.data?.detail as string | undefined,
|
||||
});
|
||||
};
|
||||
|
||||
const addAttrToModuleMutation = useMutation({
|
||||
...addAttributeToModuleMutation(),
|
||||
onError,
|
||||
});
|
||||
|
||||
const removeAttrFromModuleMutation = useMutation({
|
||||
...removeAttributeFromModuleMutation(),
|
||||
onError,
|
||||
});
|
||||
|
||||
const toggleAttributeInModule = (
|
||||
attribute: AttributeSchema,
|
||||
isAdding: boolean
|
||||
) => {
|
||||
if (!module) return;
|
||||
const mutation = isAdding
|
||||
? addAttrToModuleMutation
|
||||
: removeAttrFromModuleMutation;
|
||||
|
||||
mutation.mutate(
|
||||
{
|
||||
body: {
|
||||
moduleId: module.id,
|
||||
attributeId: attribute.id,
|
||||
},
|
||||
},
|
||||
{
|
||||
onSuccess: ({ message }) => {
|
||||
notifications.success({ message });
|
||||
refetchModule();
|
||||
refetchAttributes();
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
const addAttributeToModule = (attribute: AttributeSchema) =>
|
||||
toggleAttributeInModule(attribute, true);
|
||||
|
||||
const removeAttributeFromModule = (attribute: AttributeSchema) => {
|
||||
modals.openConfirmModal({
|
||||
title: "Удаление атрибута из модуля",
|
||||
children: (
|
||||
<Text>
|
||||
Вы уверены, что хотите удалить атрибут "{attribute.label}"
|
||||
из модуля?
|
||||
</Text>
|
||||
),
|
||||
confirmProps: { color: "red" },
|
||||
onConfirm: () => toggleAttributeInModule(attribute, false),
|
||||
});
|
||||
};
|
||||
|
||||
const updateAttributeLabel = useMutation({
|
||||
...updateAttributeLabelMutation(),
|
||||
onError,
|
||||
onSuccess: refetchModule,
|
||||
});
|
||||
|
||||
const onEditAttributeLabel = (attribute: AttributeSchema) => {
|
||||
if (!module) return;
|
||||
|
||||
modals.openContextModal({
|
||||
modal: "enterNameModal",
|
||||
title: "Редактирование имени атрибута в модуле",
|
||||
withCloseButton: true,
|
||||
innerProps: {
|
||||
onChange: values =>
|
||||
updateAttributeLabel.mutate({
|
||||
body: {
|
||||
moduleId: module.id,
|
||||
attributeId: attribute.id,
|
||||
label: values.name,
|
||||
},
|
||||
}),
|
||||
value: { name: attribute.label },
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const createAttribute = useMutation({
|
||||
...createAttributeMutation(),
|
||||
onError,
|
||||
onSuccess: refetchAttributes,
|
||||
});
|
||||
|
||||
const onCreate = () => {
|
||||
modals.openContextModal({
|
||||
modal: "attributeEditorModal",
|
||||
title: "Создание атрибута",
|
||||
withCloseButton: true,
|
||||
innerProps: {
|
||||
onCreate: values =>
|
||||
createAttribute.mutate({
|
||||
body: {
|
||||
entity: values,
|
||||
},
|
||||
}),
|
||||
isEditing: false,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const updateAttribute = useMutation({
|
||||
...updateAttributeMutation(),
|
||||
onError,
|
||||
onSuccess: () => {
|
||||
refetchAttributes();
|
||||
refetchModule();
|
||||
},
|
||||
});
|
||||
|
||||
const onUpdate = (attribute: AttributeSchema) => {
|
||||
modals.openContextModal({
|
||||
modal: "attributeEditorModal",
|
||||
title: "Редактирование атрибута",
|
||||
withCloseButton: true,
|
||||
innerProps: {
|
||||
onChange: values =>
|
||||
updateAttribute.mutate({
|
||||
path: {
|
||||
pk: attribute.id,
|
||||
},
|
||||
body: {
|
||||
entity: values,
|
||||
},
|
||||
}),
|
||||
entity: attribute,
|
||||
isEditing: true,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
const deleteAttribute = useMutation({
|
||||
...deleteAttributeMutation(),
|
||||
onError,
|
||||
onSuccess: () => {
|
||||
refetchModule();
|
||||
refetchAttributes();
|
||||
},
|
||||
});
|
||||
|
||||
const onDelete = (attribute: AttributeSchema) => {
|
||||
modals.openConfirmModal({
|
||||
title: "Удаление атрибута",
|
||||
children: (
|
||||
<Text>
|
||||
Вы уверены, что хотите удалить атрибут "{attribute.label}"?
|
||||
</Text>
|
||||
),
|
||||
confirmProps: { color: "red" },
|
||||
onConfirm: () =>
|
||||
deleteAttribute.mutate({ path: { pk: attribute.id } }),
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
addAttributeToModule,
|
||||
removeAttributeFromModule,
|
||||
onEditAttributeLabel,
|
||||
onCreate,
|
||||
onUpdate,
|
||||
onDelete,
|
||||
};
|
||||
};
|
||||
|
||||
export default useAttributesActions;
|
||||
32
src/app/module-editor/[moduleId]/hooks/useAttributesList.ts
Normal file
32
src/app/module-editor/[moduleId]/hooks/useAttributesList.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { useQuery, useQueryClient } from "@tanstack/react-query";
|
||||
import { AttributeSchema } from "@/lib/client";
|
||||
import {
|
||||
getAttributesOptions,
|
||||
getProjectsQueryKey,
|
||||
} from "@/lib/client/@tanstack/react-query.gen";
|
||||
|
||||
const useAttributesList = () => {
|
||||
const queryClient = useQueryClient();
|
||||
const { data, refetch } = useQuery(getAttributesOptions());
|
||||
|
||||
const queryKey = getProjectsQueryKey();
|
||||
|
||||
const setAttributes = (attributes: AttributeSchema[]) => {
|
||||
queryClient.setQueryData(
|
||||
queryKey,
|
||||
(old: { items: AttributeSchema[] }) => ({
|
||||
...old,
|
||||
items: attributes,
|
||||
})
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
attributes: data?.items ?? [],
|
||||
setAttributes,
|
||||
refetch,
|
||||
queryKey,
|
||||
};
|
||||
};
|
||||
|
||||
export default useAttributesList;
|
||||
51
src/app/module-editor/[moduleId]/hooks/useModulesActions.tsx
Normal file
51
src/app/module-editor/[moduleId]/hooks/useModulesActions.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { ModuleSchemaOutput } from "@/lib/client";
|
||||
import { updateModuleMutation } from "@/lib/client/@tanstack/react-query.gen";
|
||||
|
||||
export type ModuleInfo = {
|
||||
label: string;
|
||||
description: string | null;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
module?: ModuleSchemaOutput;
|
||||
refetchModule: () => void;
|
||||
};
|
||||
|
||||
export type ModulesActions = {
|
||||
updateCommonInfo: (values: ModuleInfo, onSuccess?: () => void) => void;
|
||||
};
|
||||
|
||||
const useModulesActions = ({
|
||||
module,
|
||||
refetchModule,
|
||||
}: Props): ModulesActions => {
|
||||
const updateCommonInfoMutation = useMutation(updateModuleMutation());
|
||||
|
||||
const updateCommonInfo = (values: ModuleInfo, onSuccess?: () => void) => {
|
||||
if (!module) return;
|
||||
|
||||
updateCommonInfoMutation.mutate(
|
||||
{
|
||||
path: {
|
||||
pk: module.id,
|
||||
},
|
||||
body: {
|
||||
entity: values,
|
||||
},
|
||||
},
|
||||
{
|
||||
onSuccess: () => {
|
||||
refetchModule();
|
||||
onSuccess && onSuccess();
|
||||
},
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
return {
|
||||
updateCommonInfo,
|
||||
};
|
||||
};
|
||||
|
||||
export default useModulesActions;
|
||||
138
src/app/module-editor/[moduleId]/modals/AttributeEditorModal.tsx
Normal file
138
src/app/module-editor/[moduleId]/modals/AttributeEditorModal.tsx
Normal file
@ -0,0 +1,138 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { Checkbox, Stack, Textarea, TextInput } from "@mantine/core";
|
||||
import { useForm } from "@mantine/form";
|
||||
import { ContextModalProps } from "@mantine/modals";
|
||||
import AttributeTypeSelect from "@/app/module-editor/[moduleId]/components/shared/AttributeTypeSelect/AttributeTypeSelect";
|
||||
import DefaultAttributeValueInput from "@/app/module-editor/[moduleId]/components/shared/DefaultAttributeValueInput/DefaultAttributeValueInput";
|
||||
import {
|
||||
AttributeSchema,
|
||||
CreateAttributeSchema,
|
||||
UpdateAttributeSchema,
|
||||
} from "@/lib/client";
|
||||
import BaseFormModal, {
|
||||
CreateEditFormProps,
|
||||
} from "@/modals/base/BaseFormModal/BaseFormModal";
|
||||
|
||||
type Props = CreateEditFormProps<
|
||||
AttributeSchema,
|
||||
CreateAttributeSchema,
|
||||
UpdateAttributeSchema
|
||||
>;
|
||||
|
||||
const AttributeEditorModal = ({
|
||||
context,
|
||||
id,
|
||||
innerProps,
|
||||
}: ContextModalProps<Props>) => {
|
||||
const [isInitial, setIsInitial] = useState(true);
|
||||
const [isNullableInputShown, setIsNullableInputShown] = useState(true);
|
||||
const [copyTypeId, setCopyTypeId] = useState<number>();
|
||||
|
||||
const form = useForm<Partial<UpdateAttributeSchema>>({
|
||||
initialValues: innerProps.isEditing
|
||||
? innerProps.entity
|
||||
: ({
|
||||
label: "",
|
||||
name: "",
|
||||
typeId: undefined,
|
||||
type: undefined,
|
||||
isApplicableToGroup: false,
|
||||
isShownOnDashboard: false,
|
||||
isHighlightIfExpired: false,
|
||||
isNullable: false,
|
||||
defaultValue: null,
|
||||
description: "",
|
||||
} as Partial<CreateAttributeSchema>),
|
||||
validate: {
|
||||
label: label => !label?.trim() && "Название не заполнено",
|
||||
type: type => !type && "Тип атрибута не выбран",
|
||||
defaultValue: (defaultValue, values) => {
|
||||
if (defaultValue === null && !values.isNullable) {
|
||||
return "Укажите значение по умолчанию или разрешите пустое значение.";
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
const type = form.values.type?.type;
|
||||
setIsNullableInputShown(type !== "bool");
|
||||
|
||||
if (!isInitial) {
|
||||
if (type === "bool") {
|
||||
form.setFieldValue("isNullable", false);
|
||||
form.setFieldValue("defaultValue", { value: false });
|
||||
} else {
|
||||
form.setFieldValue("defaultValue", null);
|
||||
}
|
||||
}
|
||||
setIsInitial(false);
|
||||
setCopyTypeId(form.values.type?.id);
|
||||
}, [form.values.type?.id]);
|
||||
|
||||
return (
|
||||
<BaseFormModal
|
||||
{...innerProps}
|
||||
closeOnSubmit
|
||||
form={form}
|
||||
onClose={() => context.closeContextModal(id)}>
|
||||
<Stack gap={"md"}>
|
||||
<TextInput
|
||||
withAsterisk
|
||||
label={"Название"}
|
||||
{...form.getInputProps("label")}
|
||||
/>
|
||||
<AttributeTypeSelect
|
||||
withAsterisk
|
||||
disabled={innerProps.isEditing}
|
||||
{...form.getInputProps("type")}
|
||||
onChange={type => {
|
||||
form.setFieldValue("type", type);
|
||||
form.setFieldValue("typeId", type.id);
|
||||
}}
|
||||
/>
|
||||
<Checkbox
|
||||
label={"Значение синхронизировано в группе"}
|
||||
{...form.getInputProps("isApplicableToGroup", {
|
||||
type: "checkbox",
|
||||
})}
|
||||
/>
|
||||
<Checkbox
|
||||
label={"Значение выводится на дашборде"}
|
||||
{...form.getInputProps("isShownOnDashboard", {
|
||||
type: "checkbox",
|
||||
})}
|
||||
/>
|
||||
{(form.values.type?.type === "datetime" ||
|
||||
form.values.type?.type === "date") && (
|
||||
<Checkbox
|
||||
label={"Подсветка, если просрочено"}
|
||||
{...form.getInputProps("isHighlightIfExpired", {
|
||||
type: "checkbox",
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{isNullableInputShown && (
|
||||
<Checkbox
|
||||
label={"Может быть пустым"}
|
||||
{...form.getInputProps("isNullable", {
|
||||
type: "checkbox",
|
||||
})}
|
||||
/>
|
||||
)}
|
||||
{form.values.type && copyTypeId === form.values.type.id && (
|
||||
<DefaultAttributeValueInput form={form} />
|
||||
)}
|
||||
<Textarea
|
||||
label={"Описание"}
|
||||
{...form.getInputProps("description")}
|
||||
/>
|
||||
</Stack>
|
||||
</BaseFormModal>
|
||||
);
|
||||
};
|
||||
|
||||
export default AttributeEditorModal;
|
||||
39
src/app/module-editor/[moduleId]/page.tsx
Normal file
39
src/app/module-editor/[moduleId]/page.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import { Suspense } from "react";
|
||||
import { NextResponse } from "next/server";
|
||||
import { Center, Loader } from "@mantine/core";
|
||||
import PageBody from "@/app/module-editor/[moduleId]/components/shared/PageBody/PageBody";
|
||||
import { ModuleEditorContextProvider } from "@/app/module-editor/[moduleId]/contexts/ModuleEditorContext";
|
||||
import PageContainer from "@/components/layout/PageContainer/PageContainer";
|
||||
|
||||
type Params = {
|
||||
params: Promise<{
|
||||
moduleId: string;
|
||||
}>;
|
||||
};
|
||||
|
||||
export default async function ModuleEditorPage({ params }: Params) {
|
||||
const { moduleId } = await params;
|
||||
|
||||
const id = Number(moduleId);
|
||||
if (isNaN(id)) {
|
||||
return NextResponse.json(
|
||||
{ error: "Некорректный ID модуля. ID должен быть числом." },
|
||||
{ status: 400 }
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Suspense
|
||||
fallback={
|
||||
<Center h="50vh">
|
||||
<Loader size="lg" />
|
||||
</Center>
|
||||
}>
|
||||
<PageContainer>
|
||||
<ModuleEditorContextProvider moduleId={id}>
|
||||
<PageBody />
|
||||
</ModuleEditorContextProvider>
|
||||
</PageContainer>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
38
src/app/modules/components/InnerAttributesTable.tsx
Normal file
38
src/app/modules/components/InnerAttributesTable.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import { Center, Text } from "@mantine/core";
|
||||
import useAttributesInnerTableColumns from "@/app/modules/hooks/useAttributesInnerTableColumns";
|
||||
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
||||
import { ModuleAttributeSchema } from "@/lib/client";
|
||||
|
||||
type Props = {
|
||||
attributes: ModuleAttributeSchema[];
|
||||
moduleId: number;
|
||||
};
|
||||
|
||||
const InnerAttributesTable: FC<Props> = ({ attributes, moduleId }) => {
|
||||
const innerColumns = useAttributesInnerTableColumns();
|
||||
|
||||
if (attributes.length === 0) {
|
||||
return (
|
||||
<Center my={"md"}>
|
||||
<Text>В модуле нет атрибутов</Text>
|
||||
</Center>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<BaseTable
|
||||
key={moduleId}
|
||||
withTableBorder
|
||||
columns={innerColumns}
|
||||
records={attributes}
|
||||
verticalSpacing={"md"}
|
||||
groups={undefined}
|
||||
styles={{ table: { width: "100%" } }}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default InnerAttributesTable;
|
||||
24
src/app/modules/components/ModulesHeader.tsx
Normal file
24
src/app/modules/components/ModulesHeader.tsx
Normal file
@ -0,0 +1,24 @@
|
||||
"use client";
|
||||
|
||||
import { FC } from "react";
|
||||
import { Group } from "@mantine/core";
|
||||
import InlineButton from "@/components/ui/InlineButton/InlineButton";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
|
||||
const ModulesHeader: FC = () => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
return (
|
||||
<Group
|
||||
wrap={"nowrap"}
|
||||
justify={"space-between"}
|
||||
mt={isMobile ? "xs" : ""}
|
||||
mx={isMobile ? "xs" : ""}>
|
||||
<InlineButton w={isMobile ? "100%" : ""}>
|
||||
Создать модуль
|
||||
</InlineButton>
|
||||
</Group>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModulesHeader;
|
||||
46
src/app/modules/components/ModulesTable.tsx
Normal file
46
src/app/modules/components/ModulesTable.tsx
Normal file
@ -0,0 +1,46 @@
|
||||
"use client";
|
||||
|
||||
import { FC, useState } from "react";
|
||||
import { useModulesContext } from "@/app/modules/contexts/ModulesContext";
|
||||
import useModulesTableColumns from "@/app/modules/hooks/useModulesTableColumns";
|
||||
import BaseTable from "@/components/ui/BaseTable/BaseTable";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import InnerAttributesTable from "@/app/modules/components/InnerAttributesTable";
|
||||
|
||||
const ModulesTable: FC = () => {
|
||||
const isMobile = useIsMobile();
|
||||
const { modules } = useModulesContext();
|
||||
|
||||
const [expandedModuleIds, setExpandedModuleIds] = useState<number[]>([]);
|
||||
|
||||
const outerColumns = useModulesTableColumns({
|
||||
expandedModuleIds,
|
||||
setExpandedModuleIds,
|
||||
});
|
||||
|
||||
return (
|
||||
<BaseTable
|
||||
columns={outerColumns}
|
||||
groups={undefined}
|
||||
records={modules}
|
||||
withTableBorder
|
||||
verticalSpacing={"md"}
|
||||
rowExpansion={{
|
||||
allowMultiple: true,
|
||||
expanded: {
|
||||
recordIds: expandedModuleIds,
|
||||
onRecordIdsChange: setExpandedModuleIds,
|
||||
},
|
||||
content: ({ record }) => (
|
||||
<InnerAttributesTable
|
||||
attributes={record.attributes}
|
||||
moduleId={record.id}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
mx={isMobile ? "xs" : 0}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export default ModulesTable;
|
||||
26
src/app/modules/components/PageBody.tsx
Normal file
26
src/app/modules/components/PageBody.tsx
Normal file
@ -0,0 +1,26 @@
|
||||
"use client";
|
||||
|
||||
import ModulesTable from "@/app/modules/components/ModulesTable";
|
||||
import PageBlock from "@/components/layout/PageBlock/PageBlock";
|
||||
import ModulesHeader from "./ModulesHeader";
|
||||
|
||||
const PageBody = () => (
|
||||
<PageBlock
|
||||
style={{ flex: 1, minHeight: 0 }}
|
||||
fullScreenMobile>
|
||||
<div
|
||||
style={{
|
||||
height: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "var(--mantine-spacing-md)",
|
||||
}}>
|
||||
<ModulesHeader />
|
||||
<div style={{ flex: 1, overflow: "auto" }}>
|
||||
<ModulesTable />
|
||||
</div>
|
||||
</div>
|
||||
</PageBlock>
|
||||
);
|
||||
|
||||
export default PageBody;
|
||||
22
src/app/modules/contexts/ModulesContext.tsx
Normal file
22
src/app/modules/contexts/ModulesContext.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
"use client";
|
||||
|
||||
import useModulesWithAttrsList from "@/app/modules/hooks/useModulesWithAttrsList";
|
||||
import { ModuleWithAttributesSchema } from "@/lib/client";
|
||||
import makeContext from "@/lib/contextFactory/contextFactory";
|
||||
|
||||
type ModulesContextState = {
|
||||
modules: ModuleWithAttributesSchema[];
|
||||
refetchModules: () => void;
|
||||
};
|
||||
|
||||
const useModulesContextState = (): ModulesContextState => {
|
||||
const { modules, refetch } = useModulesWithAttrsList();
|
||||
|
||||
return {
|
||||
modules,
|
||||
refetchModules: refetch,
|
||||
};
|
||||
};
|
||||
|
||||
export const [ModulesContextProvider, useModulesContext] =
|
||||
makeContext<ModulesContextState>(useModulesContextState, "Modules");
|
||||
82
src/app/modules/hooks/useAttributesInnerTableColumns.tsx
Normal file
82
src/app/modules/hooks/useAttributesInnerTableColumns.tsx
Normal file
@ -0,0 +1,82 @@
|
||||
"use client";
|
||||
|
||||
import { useMemo } from "react";
|
||||
import { IconCheck, IconX } from "@tabler/icons-react";
|
||||
import { DataTableColumn } from "mantine-datatable";
|
||||
import { Box } from "@mantine/core";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import { ModuleAttributeSchema } from "@/lib/client";
|
||||
import {
|
||||
utcDateTimeToLocalString,
|
||||
utcDateToLocalString,
|
||||
} from "@/utils/datetime";
|
||||
|
||||
const useAttributesInnerTableColumns = () => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
const renderCheck = (value: boolean) => (value ? <IconCheck /> : <IconX />);
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
[
|
||||
{
|
||||
title: "Название атрибута",
|
||||
accessor: "label",
|
||||
},
|
||||
{
|
||||
title: "Тип",
|
||||
accessor: "type.name",
|
||||
},
|
||||
{
|
||||
title: "Значение по умолчанию",
|
||||
accessor: "defaultValue",
|
||||
render: attr => {
|
||||
if (!attr.defaultValue) return <>-</>;
|
||||
const value = attr.defaultValue.value;
|
||||
if (value === null) return <>-</>;
|
||||
|
||||
const type = attr.type.type;
|
||||
if (type === "datetime") {
|
||||
return utcDateTimeToLocalString(value as string);
|
||||
}
|
||||
if (type === "date") {
|
||||
return utcDateToLocalString(value as string);
|
||||
}
|
||||
if (type === "bool") {
|
||||
return value ? <IconCheck /> : <IconX />;
|
||||
}
|
||||
|
||||
return <>{value}</>;
|
||||
},
|
||||
},
|
||||
{
|
||||
title: "Синхронизировано в группе",
|
||||
accessor: "isApplicableToGroup",
|
||||
render: attr => renderCheck(attr.isApplicableToGroup),
|
||||
},
|
||||
{
|
||||
title: "Вывод на дашборде",
|
||||
accessor: "isShownOnDashboard",
|
||||
render: attr => renderCheck(attr.isShownOnDashboard),
|
||||
},
|
||||
{
|
||||
title: "Подсветка, если просрочен",
|
||||
accessor: "isHighlightIfExpired",
|
||||
render: attr => renderCheck(attr.isHighlightIfExpired),
|
||||
},
|
||||
{
|
||||
title: "Может быть пустым",
|
||||
accessor: "isNullable",
|
||||
render: attr => renderCheck(attr.isNullable),
|
||||
},
|
||||
{
|
||||
title: "Описаниие",
|
||||
accessor: "description",
|
||||
render: attr => <Box>{attr.description}</Box>,
|
||||
},
|
||||
] as DataTableColumn<ModuleAttributeSchema>[],
|
||||
[isMobile]
|
||||
);
|
||||
};
|
||||
|
||||
export default useAttributesInnerTableColumns;
|
||||
57
src/app/modules/hooks/useModulesTableActions.tsx
Normal file
57
src/app/modules/hooks/useModulesTableActions.tsx
Normal file
@ -0,0 +1,57 @@
|
||||
import React from "react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { useMutation } from "@tanstack/react-query";
|
||||
import { AxiosError } from "axios";
|
||||
import { Text } from "@mantine/core";
|
||||
import { modals } from "@mantine/modals";
|
||||
import { HttpValidationError, ModuleSchemaOutput } from "@/lib/client";
|
||||
import { deleteModuleMutation } from "@/lib/client/@tanstack/react-query.gen";
|
||||
import { notifications } from "@/lib/notifications";
|
||||
|
||||
export type ModulesActions = {
|
||||
onUpdate: (module: ModuleSchemaOutput) => void;
|
||||
onDelete: (module: ModuleSchemaOutput) => void;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
refetchModules: () => void;
|
||||
};
|
||||
|
||||
const useModulesActions = ({ refetchModules }: Props): ModulesActions => {
|
||||
const onUpdate = (module: ModuleSchemaOutput) => {
|
||||
redirect(`/module-editor/${module.id}`);
|
||||
};
|
||||
|
||||
const onError = (error: AxiosError<HttpValidationError>, _: any) => {
|
||||
console.error(error);
|
||||
notifications.error({
|
||||
message: error.response?.data?.detail as string | undefined,
|
||||
});
|
||||
};
|
||||
|
||||
const deleteMutation = useMutation({
|
||||
...deleteModuleMutation(),
|
||||
onError,
|
||||
onSuccess: refetchModules,
|
||||
});
|
||||
|
||||
const onDelete = (module: ModuleSchemaOutput) => {
|
||||
modals.openConfirmModal({
|
||||
title: "Удаление услуги из сделки",
|
||||
children: (
|
||||
<Text>
|
||||
Вы уверены, что хотите удалить модуль "{module.label}"?
|
||||
</Text>
|
||||
),
|
||||
confirmProps: { color: "red" },
|
||||
onConfirm: () => deleteMutation.mutate({ path: { pk: module.id } }),
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
onUpdate,
|
||||
onDelete,
|
||||
};
|
||||
};
|
||||
|
||||
export default useModulesActions;
|
||||
112
src/app/modules/hooks/useModulesTableColumns.tsx
Normal file
112
src/app/modules/hooks/useModulesTableColumns.tsx
Normal file
@ -0,0 +1,112 @@
|
||||
import { useMemo } from "react";
|
||||
import {
|
||||
IconChevronDown,
|
||||
IconChevronsDown,
|
||||
IconChevronsRight,
|
||||
IconChevronsUp,
|
||||
IconChevronUp,
|
||||
} from "@tabler/icons-react";
|
||||
import { DataTableColumn } from "mantine-datatable";
|
||||
import { Box, Group, Text, Tooltip } from "@mantine/core";
|
||||
import useModulesActions from "@/app/modules/hooks/useModulesTableActions";
|
||||
import UpdateDeleteTableActions from "@/components/ui/BaseTable/components/UpdateDeleteTableActions";
|
||||
import useIsMobile from "@/hooks/utils/useIsMobile";
|
||||
import { ModuleWithAttributesSchema } from "@/lib/client";
|
||||
import { useModulesContext } from "../contexts/ModulesContext";
|
||||
|
||||
type Props = {
|
||||
expandedModuleIds: number[];
|
||||
setExpandedModuleIds: (ids: number[]) => void;
|
||||
};
|
||||
|
||||
const useModulesTableColumns = ({
|
||||
expandedModuleIds,
|
||||
setExpandedModuleIds,
|
||||
}: Props) => {
|
||||
const isMobile = useIsMobile();
|
||||
const { modules, refetchModules } = useModulesContext();
|
||||
const { onUpdate, onDelete } = useModulesActions({ refetchModules });
|
||||
|
||||
const onExpandAllClick = () => {
|
||||
if (expandedModuleIds.length !== modules.length) {
|
||||
setExpandedModuleIds(modules.map(c => c.id));
|
||||
return;
|
||||
}
|
||||
setExpandedModuleIds([]);
|
||||
};
|
||||
|
||||
const getExpandAllIcon = () => {
|
||||
if (expandedModuleIds.length === modules.length)
|
||||
return <IconChevronsUp />;
|
||||
if (expandedModuleIds.length === 0) return <IconChevronsDown />;
|
||||
return <IconChevronsRight />;
|
||||
};
|
||||
|
||||
return useMemo(
|
||||
() =>
|
||||
[
|
||||
{
|
||||
accessor: "",
|
||||
title: (
|
||||
<Group>
|
||||
<Box
|
||||
style={{ cursor: "pointer" }}
|
||||
onClick={onExpandAllClick}>
|
||||
{getExpandAllIcon()}
|
||||
</Box>
|
||||
Модуль
|
||||
</Group>
|
||||
),
|
||||
render: ({ id, label }) => (
|
||||
<Group
|
||||
key={id}
|
||||
wrap={"nowrap"}>
|
||||
{expandedModuleIds.includes(id) ? (
|
||||
<IconChevronUp />
|
||||
) : (
|
||||
<IconChevronDown />
|
||||
)}
|
||||
<Text>{label}</Text>
|
||||
</Group>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: "Описание",
|
||||
accessor: "description",
|
||||
},
|
||||
{
|
||||
title: "Зависит от модулей",
|
||||
accessor: "dependsOn",
|
||||
render: module => (
|
||||
<Text>
|
||||
{module.dependsOn?.map(m => m.label).join(", ")}
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
{
|
||||
accessor: "actions",
|
||||
title: isMobile ? "" : "Действия",
|
||||
sortable: false,
|
||||
textAlign: "center",
|
||||
width: "0%",
|
||||
render: module => (
|
||||
<Tooltip
|
||||
label={
|
||||
module.isBuiltIn
|
||||
? "Нельзя изменять встроенные модули"
|
||||
: null
|
||||
}>
|
||||
<UpdateDeleteTableActions
|
||||
onDelete={() => onDelete(module)}
|
||||
onChange={() => onUpdate(module)}
|
||||
disabled={module.isBuiltIn}
|
||||
/>
|
||||
</Tooltip>
|
||||
),
|
||||
},
|
||||
] as DataTableColumn<ModuleWithAttributesSchema>[],
|
||||
[expandedModuleIds, modules, isMobile]
|
||||
);
|
||||
};
|
||||
|
||||
export default useModulesTableColumns;
|
||||
13
src/app/modules/hooks/useModulesWithAttrsList.ts
Normal file
13
src/app/modules/hooks/useModulesWithAttrsList.ts
Normal file
@ -0,0 +1,13 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { getModulesWithAttributesOptions } from "@/lib/client/@tanstack/react-query.gen";
|
||||
|
||||
const useModulesWithAttrsList = () => {
|
||||
const { data, refetch } = useQuery(getModulesWithAttributesOptions());
|
||||
|
||||
return {
|
||||
modules: data?.items ?? [],
|
||||
refetch,
|
||||
};
|
||||
};
|
||||
|
||||
export default useModulesWithAttrsList;
|
||||
22
src/app/modules/page.tsx
Normal file
22
src/app/modules/page.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { Suspense } from "react";
|
||||
import { Center, Loader } from "@mantine/core";
|
||||
import PageBody from "@/app/modules/components/PageBody";
|
||||
import { ModulesContextProvider } from "@/app/modules/contexts/ModulesContext";
|
||||
import PageContainer from "@/components/layout/PageContainer/PageContainer";
|
||||
|
||||
export default async function ModulesPage() {
|
||||
return (
|
||||
<Suspense
|
||||
fallback={
|
||||
<Center h="50vh">
|
||||
<Loader size="lg" />
|
||||
</Center>
|
||||
}>
|
||||
<PageContainer>
|
||||
<ModulesContextProvider>
|
||||
<PageBody />
|
||||
</ModulesContextProvider>
|
||||
</PageContainer>
|
||||
</Suspense>
|
||||
);
|
||||
}
|
||||
@ -1,4 +1,5 @@
|
||||
import {
|
||||
IconApps,
|
||||
IconBox,
|
||||
IconColumns,
|
||||
IconFileBarcode,
|
||||
@ -15,6 +16,12 @@ const linksData: LinkData[] = [
|
||||
href: "/deals",
|
||||
moduleName: undefined,
|
||||
},
|
||||
{
|
||||
icon: IconApps,
|
||||
label: "Модули",
|
||||
href: "/modules",
|
||||
moduleName: undefined,
|
||||
},
|
||||
{
|
||||
icon: IconUsers,
|
||||
label: "Клиенты",
|
||||
|
||||
@ -19,6 +19,7 @@ type Props = {
|
||||
otherActions?: ActionData[];
|
||||
dotsForMobile?: boolean;
|
||||
style?: CSSProperties;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
const UpdateDeleteTableActions: FC<Props> = ({
|
||||
@ -27,6 +28,7 @@ const UpdateDeleteTableActions: FC<Props> = ({
|
||||
otherActions,
|
||||
style,
|
||||
dotsForMobile = false,
|
||||
disabled = false,
|
||||
}) => {
|
||||
const isMobile = useIsMobile();
|
||||
|
||||
@ -45,6 +47,7 @@ const UpdateDeleteTableActions: FC<Props> = ({
|
||||
onClick={onChange}
|
||||
icon={<IconEdit />}
|
||||
label={"Редактировать"}
|
||||
disabled={disabled}
|
||||
/>
|
||||
{otherActions?.map(
|
||||
action =>
|
||||
@ -54,6 +57,7 @@ const UpdateDeleteTableActions: FC<Props> = ({
|
||||
icon={action.icon}
|
||||
label={action.label}
|
||||
key={action.label}
|
||||
disabled={disabled}
|
||||
/>
|
||||
)
|
||||
)}
|
||||
@ -61,6 +65,7 @@ const UpdateDeleteTableActions: FC<Props> = ({
|
||||
onClick={onDelete}
|
||||
icon={<IconTrash />}
|
||||
label={"Удалить"}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</Menu.Dropdown>
|
||||
</Menu>
|
||||
@ -76,6 +81,7 @@ const UpdateDeleteTableActions: FC<Props> = ({
|
||||
e.stopPropagation();
|
||||
onChange();
|
||||
}}
|
||||
disabled={disabled}
|
||||
tipLabel={"Редактировать"}>
|
||||
<IconEdit />
|
||||
</ActionIconWithTip>
|
||||
@ -87,6 +93,7 @@ const UpdateDeleteTableActions: FC<Props> = ({
|
||||
e.stopPropagation();
|
||||
action.onClick();
|
||||
}}
|
||||
disabled={disabled}
|
||||
key={action.label}
|
||||
tipLabel={action.label}>
|
||||
{action.icon}
|
||||
@ -99,6 +106,7 @@ const UpdateDeleteTableActions: FC<Props> = ({
|
||||
e.stopPropagation();
|
||||
onDelete();
|
||||
}}
|
||||
disabled={disabled}
|
||||
tipLabel={"Удалить"}>
|
||||
<IconTrash />
|
||||
</ActionIconWithTip>
|
||||
|
||||
@ -5,16 +5,25 @@ type Props = {
|
||||
onClick: MouseEventHandler<HTMLButtonElement>;
|
||||
icon: ReactNode;
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
};
|
||||
|
||||
const DropdownMenuItem: FC<Props> = ({ icon, label, onClick }) => {
|
||||
const DropdownMenuItem: FC<Props> = ({
|
||||
icon,
|
||||
label,
|
||||
onClick,
|
||||
disabled = false,
|
||||
}) => {
|
||||
const onClickWrapper: MouseEventHandler<HTMLButtonElement> = e => {
|
||||
e.stopPropagation();
|
||||
if (disabled) return;
|
||||
onClick(e);
|
||||
};
|
||||
|
||||
return (
|
||||
<Menu.Item onClick={onClickWrapper}>
|
||||
<Menu.Item
|
||||
onClick={onClickWrapper}
|
||||
disabled={disabled}>
|
||||
<Group wrap={"nowrap"}>
|
||||
{icon}
|
||||
<Text>{label}</Text>
|
||||
|
||||
@ -10,8 +10,10 @@ import {
|
||||
import type { AxiosError } from "axios";
|
||||
import { client as _heyApiClient } from "../client.gen";
|
||||
import {
|
||||
addAttributeToModule,
|
||||
addKitToDeal,
|
||||
addKitToDealProduct,
|
||||
createAttribute,
|
||||
createBarcodeTemplate,
|
||||
createBoard,
|
||||
createClient,
|
||||
@ -28,6 +30,7 @@ import {
|
||||
createServiceCategory,
|
||||
createServicesKit,
|
||||
createStatus,
|
||||
deleteAttribute,
|
||||
deleteBarcodeTemplate,
|
||||
deleteBoard,
|
||||
deleteClient,
|
||||
@ -38,6 +41,7 @@ import {
|
||||
deleteDealService,
|
||||
deleteDealTag,
|
||||
deleteMarketplace,
|
||||
deleteModule,
|
||||
deleteProduct,
|
||||
deleteProductBarcodeImage,
|
||||
deleteProject,
|
||||
@ -46,6 +50,8 @@ import {
|
||||
deleteServicesKit,
|
||||
deleteStatus,
|
||||
duplicateProductServices,
|
||||
getAttributes,
|
||||
getAttributeTypes,
|
||||
getBarcodeTemplateAttributes,
|
||||
getBarcodeTemplates,
|
||||
getBarcodeTemplateSizes,
|
||||
@ -59,6 +65,8 @@ import {
|
||||
getDealTags,
|
||||
getMarketplaces,
|
||||
getModules,
|
||||
getModulesWithAttributes,
|
||||
getModuleWithAttributes,
|
||||
getProductBarcodePdf,
|
||||
getProducts,
|
||||
getProjects,
|
||||
@ -67,7 +75,10 @@ import {
|
||||
getServicesKits,
|
||||
getStatuses,
|
||||
getStatusHistory,
|
||||
removeAttributeFromModule,
|
||||
switchDealTag,
|
||||
updateAttribute,
|
||||
updateAttributeLabel,
|
||||
updateBarcodeTemplate,
|
||||
updateBoard,
|
||||
updateClient,
|
||||
@ -79,6 +90,7 @@ import {
|
||||
updateDealsInGroup,
|
||||
updateDealTag,
|
||||
updateMarketplace,
|
||||
updateModule,
|
||||
updateProduct,
|
||||
updateProject,
|
||||
updateService,
|
||||
@ -90,12 +102,18 @@ import {
|
||||
type Options,
|
||||
} from "../sdk.gen";
|
||||
import type {
|
||||
AddAttributeToModuleData,
|
||||
AddAttributeToModuleError,
|
||||
AddAttributeToModuleResponse,
|
||||
AddKitToDealData,
|
||||
AddKitToDealError,
|
||||
AddKitToDealProductData,
|
||||
AddKitToDealProductError,
|
||||
AddKitToDealProductResponse,
|
||||
AddKitToDealResponse,
|
||||
CreateAttributeData,
|
||||
CreateAttributeError,
|
||||
CreateAttributeResponse2,
|
||||
CreateBarcodeTemplateData,
|
||||
CreateBarcodeTemplateError,
|
||||
CreateBarcodeTemplateResponse2,
|
||||
@ -144,6 +162,9 @@ import type {
|
||||
CreateStatusData,
|
||||
CreateStatusError,
|
||||
CreateStatusResponse2,
|
||||
DeleteAttributeData,
|
||||
DeleteAttributeError,
|
||||
DeleteAttributeResponse2,
|
||||
DeleteBarcodeTemplateData,
|
||||
DeleteBarcodeTemplateError,
|
||||
DeleteBarcodeTemplateResponse2,
|
||||
@ -174,6 +195,9 @@ import type {
|
||||
DeleteMarketplaceData,
|
||||
DeleteMarketplaceError,
|
||||
DeleteMarketplaceResponse2,
|
||||
DeleteModuleData,
|
||||
DeleteModuleError,
|
||||
DeleteModuleResponse2,
|
||||
DeleteProductBarcodeImageData,
|
||||
DeleteProductBarcodeImageError,
|
||||
DeleteProductBarcodeImageResponse,
|
||||
@ -198,6 +222,8 @@ import type {
|
||||
DuplicateProductServicesData,
|
||||
DuplicateProductServicesError,
|
||||
DuplicateProductServicesResponse,
|
||||
GetAttributesData,
|
||||
GetAttributeTypesData,
|
||||
GetBarcodeTemplateAttributesData,
|
||||
GetBarcodeTemplatesData,
|
||||
GetBarcodeTemplateSizesData,
|
||||
@ -214,6 +240,8 @@ import type {
|
||||
GetDealTagsData,
|
||||
GetMarketplacesData,
|
||||
GetModulesData,
|
||||
GetModulesWithAttributesData,
|
||||
GetModuleWithAttributesData,
|
||||
GetProductBarcodePdfData,
|
||||
GetProductBarcodePdfError,
|
||||
GetProductBarcodePdfResponse2,
|
||||
@ -226,9 +254,18 @@ import type {
|
||||
GetServicesKitsData,
|
||||
GetStatusesData,
|
||||
GetStatusHistoryData,
|
||||
RemoveAttributeFromModuleData,
|
||||
RemoveAttributeFromModuleError,
|
||||
RemoveAttributeFromModuleResponse,
|
||||
SwitchDealTagData,
|
||||
SwitchDealTagError,
|
||||
SwitchDealTagResponse2,
|
||||
UpdateAttributeData,
|
||||
UpdateAttributeError,
|
||||
UpdateAttributeLabelData,
|
||||
UpdateAttributeLabelError,
|
||||
UpdateAttributeLabelResponse2,
|
||||
UpdateAttributeResponse2,
|
||||
UpdateBarcodeTemplateData,
|
||||
UpdateBarcodeTemplateError,
|
||||
UpdateBarcodeTemplateResponse2,
|
||||
@ -262,6 +299,9 @@ import type {
|
||||
UpdateMarketplaceData,
|
||||
UpdateMarketplaceError,
|
||||
UpdateMarketplaceResponse2,
|
||||
UpdateModuleData,
|
||||
UpdateModuleError,
|
||||
UpdateModuleResponse,
|
||||
UpdateProductData,
|
||||
UpdateProductError,
|
||||
UpdateProductResponse2,
|
||||
@ -324,6 +364,207 @@ const createQueryKey = <TOptions extends Options>(
|
||||
return [params];
|
||||
};
|
||||
|
||||
export const getAttributesQueryKey = (options?: Options<GetAttributesData>) =>
|
||||
createQueryKey("getAttributes", options);
|
||||
|
||||
/**
|
||||
* Get Attributes
|
||||
*/
|
||||
export const getAttributesOptions = (options?: Options<GetAttributesData>) => {
|
||||
return queryOptions({
|
||||
queryFn: async ({ queryKey, signal }) => {
|
||||
const { data } = await getAttributes({
|
||||
...options,
|
||||
...queryKey[0],
|
||||
signal,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
queryKey: getAttributesQueryKey(options),
|
||||
});
|
||||
};
|
||||
|
||||
export const createAttributeQueryKey = (
|
||||
options: Options<CreateAttributeData>
|
||||
) => createQueryKey("createAttribute", options);
|
||||
|
||||
/**
|
||||
* Create Attribute
|
||||
*/
|
||||
export const createAttributeOptions = (
|
||||
options: Options<CreateAttributeData>
|
||||
) => {
|
||||
return queryOptions({
|
||||
queryFn: async ({ queryKey, signal }) => {
|
||||
const { data } = await createAttribute({
|
||||
...options,
|
||||
...queryKey[0],
|
||||
signal,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
queryKey: createAttributeQueryKey(options),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create Attribute
|
||||
*/
|
||||
export const createAttributeMutation = (
|
||||
options?: Partial<Options<CreateAttributeData>>
|
||||
): UseMutationOptions<
|
||||
CreateAttributeResponse2,
|
||||
AxiosError<CreateAttributeError>,
|
||||
Options<CreateAttributeData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
CreateAttributeResponse2,
|
||||
AxiosError<CreateAttributeError>,
|
||||
Options<CreateAttributeData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await createAttribute({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete Attribute
|
||||
*/
|
||||
export const deleteAttributeMutation = (
|
||||
options?: Partial<Options<DeleteAttributeData>>
|
||||
): UseMutationOptions<
|
||||
DeleteAttributeResponse2,
|
||||
AxiosError<DeleteAttributeError>,
|
||||
Options<DeleteAttributeData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
DeleteAttributeResponse2,
|
||||
AxiosError<DeleteAttributeError>,
|
||||
Options<DeleteAttributeData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await deleteAttribute({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Update Attribute
|
||||
*/
|
||||
export const updateAttributeMutation = (
|
||||
options?: Partial<Options<UpdateAttributeData>>
|
||||
): UseMutationOptions<
|
||||
UpdateAttributeResponse2,
|
||||
AxiosError<UpdateAttributeError>,
|
||||
Options<UpdateAttributeData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
UpdateAttributeResponse2,
|
||||
AxiosError<UpdateAttributeError>,
|
||||
Options<UpdateAttributeData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await updateAttribute({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
export const updateAttributeLabelQueryKey = (
|
||||
options: Options<UpdateAttributeLabelData>
|
||||
) => createQueryKey("updateAttributeLabel", options);
|
||||
|
||||
/**
|
||||
* Update Attribute Label
|
||||
*/
|
||||
export const updateAttributeLabelOptions = (
|
||||
options: Options<UpdateAttributeLabelData>
|
||||
) => {
|
||||
return queryOptions({
|
||||
queryFn: async ({ queryKey, signal }) => {
|
||||
const { data } = await updateAttributeLabel({
|
||||
...options,
|
||||
...queryKey[0],
|
||||
signal,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
queryKey: updateAttributeLabelQueryKey(options),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update Attribute Label
|
||||
*/
|
||||
export const updateAttributeLabelMutation = (
|
||||
options?: Partial<Options<UpdateAttributeLabelData>>
|
||||
): UseMutationOptions<
|
||||
UpdateAttributeLabelResponse2,
|
||||
AxiosError<UpdateAttributeLabelError>,
|
||||
Options<UpdateAttributeLabelData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
UpdateAttributeLabelResponse2,
|
||||
AxiosError<UpdateAttributeLabelError>,
|
||||
Options<UpdateAttributeLabelData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await updateAttributeLabel({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
export const getAttributeTypesQueryKey = (
|
||||
options?: Options<GetAttributeTypesData>
|
||||
) => createQueryKey("getAttributeTypes", options);
|
||||
|
||||
/**
|
||||
* Get Attribute Types
|
||||
*/
|
||||
export const getAttributeTypesOptions = (
|
||||
options?: Options<GetAttributeTypesData>
|
||||
) => {
|
||||
return queryOptions({
|
||||
queryFn: async ({ queryKey, signal }) => {
|
||||
const { data } = await getAttributeTypes({
|
||||
...options,
|
||||
...queryKey[0],
|
||||
signal,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
queryKey: getAttributeTypesQueryKey(options),
|
||||
});
|
||||
};
|
||||
|
||||
export const getBoardsQueryKey = (options: Options<GetBoardsData>) =>
|
||||
createQueryKey("getBoards", options);
|
||||
|
||||
@ -1054,6 +1295,186 @@ export const getModulesOptions = (options?: Options<GetModulesData>) => {
|
||||
});
|
||||
};
|
||||
|
||||
export const getModulesWithAttributesQueryKey = (
|
||||
options?: Options<GetModulesWithAttributesData>
|
||||
) => createQueryKey("getModulesWithAttributes", options);
|
||||
|
||||
/**
|
||||
* Get Modules With Attributes
|
||||
*/
|
||||
export const getModulesWithAttributesOptions = (
|
||||
options?: Options<GetModulesWithAttributesData>
|
||||
) => {
|
||||
return queryOptions({
|
||||
queryFn: async ({ queryKey, signal }) => {
|
||||
const { data } = await getModulesWithAttributes({
|
||||
...options,
|
||||
...queryKey[0],
|
||||
signal,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
queryKey: getModulesWithAttributesQueryKey(options),
|
||||
});
|
||||
};
|
||||
|
||||
export const getModuleWithAttributesQueryKey = (
|
||||
options: Options<GetModuleWithAttributesData>
|
||||
) => createQueryKey("getModuleWithAttributes", options);
|
||||
|
||||
/**
|
||||
* Get Module With Attributes
|
||||
*/
|
||||
export const getModuleWithAttributesOptions = (
|
||||
options: Options<GetModuleWithAttributesData>
|
||||
) => {
|
||||
return queryOptions({
|
||||
queryFn: async ({ queryKey, signal }) => {
|
||||
const { data } = await getModuleWithAttributes({
|
||||
...options,
|
||||
...queryKey[0],
|
||||
signal,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
queryKey: getModuleWithAttributesQueryKey(options),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update Module Common Info
|
||||
*/
|
||||
export const updateModuleMutation = (
|
||||
options?: Partial<Options<UpdateModuleData>>
|
||||
): UseMutationOptions<
|
||||
UpdateModuleResponse,
|
||||
AxiosError<UpdateModuleError>,
|
||||
Options<UpdateModuleData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
UpdateModuleResponse,
|
||||
AxiosError<UpdateModuleError>,
|
||||
Options<UpdateModuleData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await updateModule({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete Module
|
||||
*/
|
||||
export const deleteModuleMutation = (
|
||||
options?: Partial<Options<DeleteModuleData>>
|
||||
): UseMutationOptions<
|
||||
DeleteModuleResponse2,
|
||||
AxiosError<DeleteModuleError>,
|
||||
Options<DeleteModuleData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
DeleteModuleResponse2,
|
||||
AxiosError<DeleteModuleError>,
|
||||
Options<DeleteModuleData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await deleteModule({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove Attribute From Module
|
||||
*/
|
||||
export const removeAttributeFromModuleMutation = (
|
||||
options?: Partial<Options<RemoveAttributeFromModuleData>>
|
||||
): UseMutationOptions<
|
||||
RemoveAttributeFromModuleResponse,
|
||||
AxiosError<RemoveAttributeFromModuleError>,
|
||||
Options<RemoveAttributeFromModuleData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
RemoveAttributeFromModuleResponse,
|
||||
AxiosError<RemoveAttributeFromModuleError>,
|
||||
Options<RemoveAttributeFromModuleData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await removeAttributeFromModule({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
export const addAttributeToModuleQueryKey = (
|
||||
options: Options<AddAttributeToModuleData>
|
||||
) => createQueryKey("addAttributeToModule", options);
|
||||
|
||||
/**
|
||||
* Add Attribute To Module
|
||||
*/
|
||||
export const addAttributeToModuleOptions = (
|
||||
options: Options<AddAttributeToModuleData>
|
||||
) => {
|
||||
return queryOptions({
|
||||
queryFn: async ({ queryKey, signal }) => {
|
||||
const { data } = await addAttributeToModule({
|
||||
...options,
|
||||
...queryKey[0],
|
||||
signal,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
queryKey: addAttributeToModuleQueryKey(options),
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add Attribute To Module
|
||||
*/
|
||||
export const addAttributeToModuleMutation = (
|
||||
options?: Partial<Options<AddAttributeToModuleData>>
|
||||
): UseMutationOptions<
|
||||
AddAttributeToModuleResponse,
|
||||
AxiosError<AddAttributeToModuleError>,
|
||||
Options<AddAttributeToModuleData>
|
||||
> => {
|
||||
const mutationOptions: UseMutationOptions<
|
||||
AddAttributeToModuleResponse,
|
||||
AxiosError<AddAttributeToModuleError>,
|
||||
Options<AddAttributeToModuleData>
|
||||
> = {
|
||||
mutationFn: async localOptions => {
|
||||
const { data } = await addAttributeToModule({
|
||||
...options,
|
||||
...localOptions,
|
||||
throwOnError: true,
|
||||
});
|
||||
return data;
|
||||
},
|
||||
};
|
||||
return mutationOptions;
|
||||
};
|
||||
|
||||
export const getClientsQueryKey = (options?: Options<GetClientsData>) =>
|
||||
createQueryKey("getClients", options);
|
||||
|
||||
|
||||
@ -8,12 +8,18 @@ import {
|
||||
} from "./client";
|
||||
import { client as _heyApiClient } from "./client.gen";
|
||||
import type {
|
||||
AddAttributeToModuleData,
|
||||
AddAttributeToModuleErrors,
|
||||
AddAttributeToModuleResponses,
|
||||
AddKitToDealData,
|
||||
AddKitToDealErrors,
|
||||
AddKitToDealProductData,
|
||||
AddKitToDealProductErrors,
|
||||
AddKitToDealProductResponses,
|
||||
AddKitToDealResponses,
|
||||
CreateAttributeData,
|
||||
CreateAttributeErrors,
|
||||
CreateAttributeResponses,
|
||||
CreateBarcodeTemplateData,
|
||||
CreateBarcodeTemplateErrors,
|
||||
CreateBarcodeTemplateResponses,
|
||||
@ -62,6 +68,9 @@ import type {
|
||||
CreateStatusData,
|
||||
CreateStatusErrors,
|
||||
CreateStatusResponses,
|
||||
DeleteAttributeData,
|
||||
DeleteAttributeErrors,
|
||||
DeleteAttributeResponses,
|
||||
DeleteBarcodeTemplateData,
|
||||
DeleteBarcodeTemplateErrors,
|
||||
DeleteBarcodeTemplateResponses,
|
||||
@ -92,6 +101,9 @@ import type {
|
||||
DeleteMarketplaceData,
|
||||
DeleteMarketplaceErrors,
|
||||
DeleteMarketplaceResponses,
|
||||
DeleteModuleData,
|
||||
DeleteModuleErrors,
|
||||
DeleteModuleResponses,
|
||||
DeleteProductBarcodeImageData,
|
||||
DeleteProductBarcodeImageErrors,
|
||||
DeleteProductBarcodeImageResponses,
|
||||
@ -116,6 +128,10 @@ import type {
|
||||
DuplicateProductServicesData,
|
||||
DuplicateProductServicesErrors,
|
||||
DuplicateProductServicesResponses,
|
||||
GetAttributesData,
|
||||
GetAttributesResponses,
|
||||
GetAttributeTypesData,
|
||||
GetAttributeTypesResponses,
|
||||
GetBarcodeTemplateAttributesData,
|
||||
GetBarcodeTemplateAttributesResponses,
|
||||
GetBarcodeTemplatesData,
|
||||
@ -149,6 +165,11 @@ import type {
|
||||
GetMarketplacesResponses,
|
||||
GetModulesData,
|
||||
GetModulesResponses,
|
||||
GetModulesWithAttributesData,
|
||||
GetModulesWithAttributesResponses,
|
||||
GetModuleWithAttributesData,
|
||||
GetModuleWithAttributesErrors,
|
||||
GetModuleWithAttributesResponses,
|
||||
GetProductBarcodePdfData,
|
||||
GetProductBarcodePdfErrors,
|
||||
GetProductBarcodePdfResponses,
|
||||
@ -169,9 +190,18 @@ import type {
|
||||
GetStatusHistoryData,
|
||||
GetStatusHistoryErrors,
|
||||
GetStatusHistoryResponses,
|
||||
RemoveAttributeFromModuleData,
|
||||
RemoveAttributeFromModuleErrors,
|
||||
RemoveAttributeFromModuleResponses,
|
||||
SwitchDealTagData,
|
||||
SwitchDealTagErrors,
|
||||
SwitchDealTagResponses,
|
||||
UpdateAttributeData,
|
||||
UpdateAttributeErrors,
|
||||
UpdateAttributeLabelData,
|
||||
UpdateAttributeLabelErrors,
|
||||
UpdateAttributeLabelResponses,
|
||||
UpdateAttributeResponses,
|
||||
UpdateBarcodeTemplateData,
|
||||
UpdateBarcodeTemplateErrors,
|
||||
UpdateBarcodeTemplateResponses,
|
||||
@ -205,6 +235,9 @@ import type {
|
||||
UpdateMarketplaceData,
|
||||
UpdateMarketplaceErrors,
|
||||
UpdateMarketplaceResponses,
|
||||
UpdateModuleData,
|
||||
UpdateModuleErrors,
|
||||
UpdateModuleResponses,
|
||||
UpdateProductData,
|
||||
UpdateProductErrors,
|
||||
UpdateProductResponses,
|
||||
@ -231,10 +264,14 @@ import type {
|
||||
UploadProductImageResponses,
|
||||
} from "./types.gen";
|
||||
import {
|
||||
zAddAttributeToModuleData,
|
||||
zAddAttributeToModuleResponse,
|
||||
zAddKitToDealData,
|
||||
zAddKitToDealProductData,
|
||||
zAddKitToDealProductResponse,
|
||||
zAddKitToDealResponse,
|
||||
zCreateAttributeData,
|
||||
zCreateAttributeResponse2,
|
||||
zCreateBarcodeTemplateData,
|
||||
zCreateBarcodeTemplateResponse2,
|
||||
zCreateBoardData,
|
||||
@ -267,6 +304,8 @@ import {
|
||||
zCreateServicesKitResponse2,
|
||||
zCreateStatusData,
|
||||
zCreateStatusResponse2,
|
||||
zDeleteAttributeData,
|
||||
zDeleteAttributeResponse2,
|
||||
zDeleteBarcodeTemplateData,
|
||||
zDeleteBarcodeTemplateResponse2,
|
||||
zDeleteBoardData,
|
||||
@ -287,6 +326,8 @@ import {
|
||||
zDeleteDealTagResponse2,
|
||||
zDeleteMarketplaceData,
|
||||
zDeleteMarketplaceResponse2,
|
||||
zDeleteModuleData,
|
||||
zDeleteModuleResponse2,
|
||||
zDeleteProductBarcodeImageData,
|
||||
zDeleteProductBarcodeImageResponse,
|
||||
zDeleteProductData,
|
||||
@ -303,6 +344,10 @@ import {
|
||||
zDeleteStatusResponse2,
|
||||
zDuplicateProductServicesData,
|
||||
zDuplicateProductServicesResponse,
|
||||
zGetAttributesData,
|
||||
zGetAttributesResponse,
|
||||
zGetAttributeTypesData,
|
||||
zGetAttributeTypesResponse,
|
||||
zGetBarcodeTemplateAttributesData,
|
||||
zGetBarcodeTemplateAttributesResponse,
|
||||
zGetBarcodeTemplatesData,
|
||||
@ -329,6 +374,10 @@ import {
|
||||
zGetMarketplacesResponse2,
|
||||
zGetModulesData,
|
||||
zGetModulesResponse,
|
||||
zGetModulesWithAttributesData,
|
||||
zGetModulesWithAttributesResponse,
|
||||
zGetModuleWithAttributesData,
|
||||
zGetModuleWithAttributesResponse,
|
||||
zGetProductBarcodePdfData,
|
||||
zGetProductBarcodePdfResponse2,
|
||||
zGetProductsData,
|
||||
@ -345,8 +394,14 @@ import {
|
||||
zGetStatusesResponse2,
|
||||
zGetStatusHistoryData,
|
||||
zGetStatusHistoryResponse2,
|
||||
zRemoveAttributeFromModuleData,
|
||||
zRemoveAttributeFromModuleResponse,
|
||||
zSwitchDealTagData,
|
||||
zSwitchDealTagResponse2,
|
||||
zUpdateAttributeData,
|
||||
zUpdateAttributeLabelData,
|
||||
zUpdateAttributeLabelResponse2,
|
||||
zUpdateAttributeResponse2,
|
||||
zUpdateBarcodeTemplateData,
|
||||
zUpdateBarcodeTemplateResponse2,
|
||||
zUpdateBoardData,
|
||||
@ -369,6 +424,8 @@ import {
|
||||
zUpdateDealTagResponse2,
|
||||
zUpdateMarketplaceData,
|
||||
zUpdateMarketplaceResponse2,
|
||||
zUpdateModuleData,
|
||||
zUpdateModuleResponse,
|
||||
zUpdateProductData,
|
||||
zUpdateProductResponse2,
|
||||
zUpdateProjectData,
|
||||
@ -404,6 +461,156 @@ export type Options<
|
||||
meta?: Record<string, unknown>;
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Attributes
|
||||
*/
|
||||
export const getAttributes = <ThrowOnError extends boolean = false>(
|
||||
options?: Options<GetAttributesData, ThrowOnError>
|
||||
) => {
|
||||
return (options?.client ?? _heyApiClient).get<
|
||||
GetAttributesResponses,
|
||||
unknown,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zGetAttributesData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zGetAttributesResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/attribute/",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Create Attribute
|
||||
*/
|
||||
export const createAttribute = <ThrowOnError extends boolean = false>(
|
||||
options: Options<CreateAttributeData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).post<
|
||||
CreateAttributeResponses,
|
||||
CreateAttributeErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zCreateAttributeData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zCreateAttributeResponse2.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/attribute/",
|
||||
...options,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete Attribute
|
||||
*/
|
||||
export const deleteAttribute = <ThrowOnError extends boolean = false>(
|
||||
options: Options<DeleteAttributeData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).delete<
|
||||
DeleteAttributeResponses,
|
||||
DeleteAttributeErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zDeleteAttributeData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zDeleteAttributeResponse2.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/attribute/{pk}",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update Attribute
|
||||
*/
|
||||
export const updateAttribute = <ThrowOnError extends boolean = false>(
|
||||
options: Options<UpdateAttributeData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).patch<
|
||||
UpdateAttributeResponses,
|
||||
UpdateAttributeErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zUpdateAttributeData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zUpdateAttributeResponse2.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/attribute/{pk}",
|
||||
...options,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update Attribute Label
|
||||
*/
|
||||
export const updateAttributeLabel = <ThrowOnError extends boolean = false>(
|
||||
options: Options<UpdateAttributeLabelData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).post<
|
||||
UpdateAttributeLabelResponses,
|
||||
UpdateAttributeLabelErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zUpdateAttributeLabelData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zUpdateAttributeLabelResponse2.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/attribute/label",
|
||||
...options,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Attribute Types
|
||||
*/
|
||||
export const getAttributeTypes = <ThrowOnError extends boolean = false>(
|
||||
options?: Options<GetAttributeTypesData, ThrowOnError>
|
||||
) => {
|
||||
return (options?.client ?? _heyApiClient).get<
|
||||
GetAttributeTypesResponses,
|
||||
unknown,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zGetAttributeTypesData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zGetAttributeTypesResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/attribute/type",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Boards
|
||||
*/
|
||||
@ -876,11 +1083,161 @@ export const getModules = <ThrowOnError extends boolean = false>(
|
||||
responseValidator: async data => {
|
||||
return await zGetModulesResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/module/built-in/",
|
||||
url: "/crm/v1/module/",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Modules With Attributes
|
||||
*/
|
||||
export const getModulesWithAttributes = <ThrowOnError extends boolean = false>(
|
||||
options?: Options<GetModulesWithAttributesData, ThrowOnError>
|
||||
) => {
|
||||
return (options?.client ?? _heyApiClient).get<
|
||||
GetModulesWithAttributesResponses,
|
||||
unknown,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zGetModulesWithAttributesData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zGetModulesWithAttributesResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/module/with-attributes",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Module With Attributes
|
||||
*/
|
||||
export const getModuleWithAttributes = <ThrowOnError extends boolean = false>(
|
||||
options: Options<GetModuleWithAttributesData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).get<
|
||||
GetModuleWithAttributesResponses,
|
||||
GetModuleWithAttributesErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zGetModuleWithAttributesData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zGetModuleWithAttributesResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/module/{pk}/with-attributes",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Update Module Common Info
|
||||
*/
|
||||
export const updateModule = <ThrowOnError extends boolean = false>(
|
||||
options: Options<UpdateModuleData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).patch<
|
||||
UpdateModuleResponses,
|
||||
UpdateModuleErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zUpdateModuleData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zUpdateModuleResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/module/{pk}/common-info",
|
||||
...options,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Delete Module
|
||||
*/
|
||||
export const deleteModule = <ThrowOnError extends boolean = false>(
|
||||
options: Options<DeleteModuleData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).delete<
|
||||
DeleteModuleResponses,
|
||||
DeleteModuleErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zDeleteModuleData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zDeleteModuleResponse2.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/module/{pk}",
|
||||
...options,
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Remove Attribute From Module
|
||||
*/
|
||||
export const removeAttributeFromModule = <ThrowOnError extends boolean = false>(
|
||||
options: Options<RemoveAttributeFromModuleData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).delete<
|
||||
RemoveAttributeFromModuleResponses,
|
||||
RemoveAttributeFromModuleErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zRemoveAttributeFromModuleData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zRemoveAttributeFromModuleResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/module/attribute",
|
||||
...options,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Add Attribute To Module
|
||||
*/
|
||||
export const addAttributeToModule = <ThrowOnError extends boolean = false>(
|
||||
options: Options<AddAttributeToModuleData, ThrowOnError>
|
||||
) => {
|
||||
return (options.client ?? _heyApiClient).post<
|
||||
AddAttributeToModuleResponses,
|
||||
AddAttributeToModuleErrors,
|
||||
ThrowOnError
|
||||
>({
|
||||
requestValidator: async data => {
|
||||
return await zAddAttributeToModuleData.parseAsync(data);
|
||||
},
|
||||
responseType: "json",
|
||||
responseValidator: async data => {
|
||||
return await zAddAttributeToModuleResponse.parseAsync(data);
|
||||
},
|
||||
url: "/crm/v1/module/attribute",
|
||||
...options,
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
...options.headers,
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Get Clients
|
||||
*/
|
||||
|
||||
@ -1,5 +1,96 @@
|
||||
// This file is auto-generated by @hey-api/openapi-ts
|
||||
|
||||
/**
|
||||
* AddAttributeRequest
|
||||
*/
|
||||
export type AddAttributeRequest = {
|
||||
/**
|
||||
* Attributeid
|
||||
*/
|
||||
attributeId: number;
|
||||
/**
|
||||
* Moduleid
|
||||
*/
|
||||
moduleId: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* AddAttributeResponse
|
||||
*/
|
||||
export type AddAttributeResponse = {
|
||||
/**
|
||||
* Message
|
||||
*/
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* AttributeSchema
|
||||
*/
|
||||
export type AttributeSchema = {
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Isapplicabletogroup
|
||||
*/
|
||||
isApplicableToGroup: boolean;
|
||||
/**
|
||||
* Isshownondashboard
|
||||
*/
|
||||
isShownOnDashboard: boolean;
|
||||
/**
|
||||
* Ishighlightifexpired
|
||||
*/
|
||||
isHighlightIfExpired: boolean;
|
||||
/**
|
||||
* Isnullable
|
||||
*/
|
||||
isNullable: boolean;
|
||||
/**
|
||||
* Defaultvalue
|
||||
*/
|
||||
defaultValue: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* Typeid
|
||||
*/
|
||||
typeId: number;
|
||||
/**
|
||||
* Id
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* Isbuiltin
|
||||
*/
|
||||
isBuiltIn: boolean;
|
||||
type: AttributeTypeSchema;
|
||||
};
|
||||
|
||||
/**
|
||||
* AttributeTypeSchema
|
||||
*/
|
||||
export type AttributeTypeSchema = {
|
||||
/**
|
||||
* Id
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* Type
|
||||
*/
|
||||
type: string;
|
||||
/**
|
||||
* Name
|
||||
*/
|
||||
name: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* BarcodeTemplateAttributeSchema
|
||||
*/
|
||||
@ -186,6 +277,63 @@ export type ClientSchema = {
|
||||
isDeleted?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* CreateAttributeRequest
|
||||
*/
|
||||
export type CreateAttributeRequest = {
|
||||
entity: CreateAttributeSchema;
|
||||
};
|
||||
|
||||
/**
|
||||
* CreateAttributeResponse
|
||||
*/
|
||||
export type CreateAttributeResponse = {
|
||||
/**
|
||||
* Message
|
||||
*/
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* CreateAttributeSchema
|
||||
*/
|
||||
export type CreateAttributeSchema = {
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Isapplicabletogroup
|
||||
*/
|
||||
isApplicableToGroup: boolean;
|
||||
/**
|
||||
* Isshownondashboard
|
||||
*/
|
||||
isShownOnDashboard: boolean;
|
||||
/**
|
||||
* Ishighlightifexpired
|
||||
*/
|
||||
isHighlightIfExpired: boolean;
|
||||
/**
|
||||
* Isnullable
|
||||
*/
|
||||
isNullable: boolean;
|
||||
/**
|
||||
* Defaultvalue
|
||||
*/
|
||||
defaultValue: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* Typeid
|
||||
*/
|
||||
typeId: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* CreateBarcodeTemplateRequest
|
||||
*/
|
||||
@ -1020,6 +1168,30 @@ export type DealTagSchema = {
|
||||
tagColor: DealTagColorSchema;
|
||||
};
|
||||
|
||||
/**
|
||||
* DeleteAttributeRequest
|
||||
*/
|
||||
export type DeleteAttributeRequest = {
|
||||
/**
|
||||
* Attributeid
|
||||
*/
|
||||
attributeId: number;
|
||||
/**
|
||||
* Moduleid
|
||||
*/
|
||||
moduleId: number;
|
||||
};
|
||||
|
||||
/**
|
||||
* DeleteAttributeResponse
|
||||
*/
|
||||
export type DeleteAttributeResponse = {
|
||||
/**
|
||||
* Message
|
||||
*/
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* DeleteBarcodeImageResponse
|
||||
*/
|
||||
@ -1120,6 +1292,16 @@ export type DeleteMarketplaceResponse = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* DeleteModuleResponse
|
||||
*/
|
||||
export type DeleteModuleResponse = {
|
||||
/**
|
||||
* Message
|
||||
*/
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* DeleteProductResponse
|
||||
*/
|
||||
@ -1190,6 +1372,26 @@ export type DeleteStatusResponse = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetAllAttributeTypesResponse
|
||||
*/
|
||||
export type GetAllAttributeTypesResponse = {
|
||||
/**
|
||||
* Items
|
||||
*/
|
||||
items: Array<AttributeTypeSchema>;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetAllAttributesResponse
|
||||
*/
|
||||
export type GetAllAttributesResponse = {
|
||||
/**
|
||||
* Items
|
||||
*/
|
||||
items: Array<AttributeSchema>;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetAllModulesResponse
|
||||
*/
|
||||
@ -1200,6 +1402,16 @@ export type GetAllModulesResponse = {
|
||||
items: Array<ModuleSchemaOutput>;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetAllWithAttributesResponse
|
||||
*/
|
||||
export type GetAllWithAttributesResponse = {
|
||||
/**
|
||||
* Items
|
||||
*/
|
||||
items: Array<ModuleWithAttributesSchema>;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetBarcodeAttributesResponse
|
||||
*/
|
||||
@ -1250,6 +1462,13 @@ export type GetBoardsResponse = {
|
||||
items: Array<BoardSchema>;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetByIdWithAttributesResponse
|
||||
*/
|
||||
export type GetByIdWithAttributesResponse = {
|
||||
entity: ModuleWithAttributesSchema;
|
||||
};
|
||||
|
||||
/**
|
||||
* GetClientsResponse
|
||||
*/
|
||||
@ -1464,6 +1683,59 @@ export type MarketplaceSchema = {
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* ModuleAttributeSchema
|
||||
*/
|
||||
export type ModuleAttributeSchema = {
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Isapplicabletogroup
|
||||
*/
|
||||
isApplicableToGroup: boolean;
|
||||
/**
|
||||
* Isshownondashboard
|
||||
*/
|
||||
isShownOnDashboard: boolean;
|
||||
/**
|
||||
* Ishighlightifexpired
|
||||
*/
|
||||
isHighlightIfExpired: boolean;
|
||||
/**
|
||||
* Isnullable
|
||||
*/
|
||||
isNullable: boolean;
|
||||
/**
|
||||
* Defaultvalue
|
||||
*/
|
||||
defaultValue: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* Typeid
|
||||
*/
|
||||
typeId: number;
|
||||
/**
|
||||
* Id
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* Isbuiltin
|
||||
*/
|
||||
isBuiltIn: boolean;
|
||||
type: AttributeTypeSchema;
|
||||
/**
|
||||
* Originallabel
|
||||
*/
|
||||
originalLabel: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* ModuleSchema
|
||||
*/
|
||||
@ -1483,7 +1755,11 @@ export type ModuleSchemaInput = {
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description: string;
|
||||
description: string | null;
|
||||
/**
|
||||
* Isbuiltin
|
||||
*/
|
||||
isBuiltIn: boolean;
|
||||
/**
|
||||
* Dependson
|
||||
*/
|
||||
@ -1513,7 +1789,11 @@ export type ModuleSchemaOutput = {
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description: string;
|
||||
description: string | null;
|
||||
/**
|
||||
* Isbuiltin
|
||||
*/
|
||||
isBuiltIn: boolean;
|
||||
/**
|
||||
* Dependson
|
||||
*/
|
||||
@ -1550,6 +1830,44 @@ export type ModuleTabSchema = {
|
||||
device: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* ModuleWithAttributesSchema
|
||||
*/
|
||||
export type ModuleWithAttributesSchema = {
|
||||
/**
|
||||
* Id
|
||||
*/
|
||||
id: number;
|
||||
/**
|
||||
* Key
|
||||
*/
|
||||
key: string;
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description: string | null;
|
||||
/**
|
||||
* Isbuiltin
|
||||
*/
|
||||
isBuiltIn: boolean;
|
||||
/**
|
||||
* Dependson
|
||||
*/
|
||||
dependsOn: Array<ModuleSchemaOutput>;
|
||||
/**
|
||||
* Tabs
|
||||
*/
|
||||
tabs: Array<ModuleTabSchema>;
|
||||
/**
|
||||
* Attributes
|
||||
*/
|
||||
attributes: Array<ModuleAttributeSchema>;
|
||||
};
|
||||
|
||||
/**
|
||||
* PaginationInfoSchema
|
||||
*/
|
||||
@ -1932,6 +2250,88 @@ export type SwitchDealTagResponse = {
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateAttributeLabelRequest
|
||||
*/
|
||||
export type UpdateAttributeLabelRequest = {
|
||||
/**
|
||||
* Moduleid
|
||||
*/
|
||||
moduleId: number;
|
||||
/**
|
||||
* Attributeid
|
||||
*/
|
||||
attributeId: number;
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateAttributeLabelResponse
|
||||
*/
|
||||
export type UpdateAttributeLabelResponse = {
|
||||
/**
|
||||
* Message
|
||||
*/
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateAttributeRequest
|
||||
*/
|
||||
export type UpdateAttributeRequest = {
|
||||
entity: UpdateAttributeSchema;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateAttributeResponse
|
||||
*/
|
||||
export type UpdateAttributeResponse = {
|
||||
/**
|
||||
* Message
|
||||
*/
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateAttributeSchema
|
||||
*/
|
||||
export type UpdateAttributeSchema = {
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label?: string | null;
|
||||
/**
|
||||
* Isapplicabletogroup
|
||||
*/
|
||||
isApplicableToGroup?: boolean | null;
|
||||
/**
|
||||
* Isshownondashboard
|
||||
*/
|
||||
isShownOnDashboard?: boolean | null;
|
||||
/**
|
||||
* Ishighlightifexpired
|
||||
*/
|
||||
isHighlightIfExpired?: boolean | null;
|
||||
/**
|
||||
* Isnullable
|
||||
*/
|
||||
isNullable?: boolean | null;
|
||||
/**
|
||||
* Defaultvalue
|
||||
*/
|
||||
defaultValue?: {
|
||||
[key: string]: unknown;
|
||||
} | null;
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description?: string | null;
|
||||
type?: AttributeTypeSchema | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateBarcodeTemplateRequest
|
||||
*/
|
||||
@ -2259,6 +2659,37 @@ export type UpdateMarketplaceSchema = {
|
||||
} | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateModuleCommonInfoRequest
|
||||
*/
|
||||
export type UpdateModuleCommonInfoRequest = {
|
||||
entity: UpdateModuleCommonInfoSchema;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateModuleCommonInfoResponse
|
||||
*/
|
||||
export type UpdateModuleCommonInfoResponse = {
|
||||
/**
|
||||
* Message
|
||||
*/
|
||||
message: string;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateModuleCommonInfoSchema
|
||||
*/
|
||||
export type UpdateModuleCommonInfoSchema = {
|
||||
/**
|
||||
* Label
|
||||
*/
|
||||
label: string;
|
||||
/**
|
||||
* Description
|
||||
*/
|
||||
description: string | null;
|
||||
};
|
||||
|
||||
/**
|
||||
* UpdateProductRequest
|
||||
*/
|
||||
@ -2563,6 +2994,158 @@ export type ValidationError = {
|
||||
type: string;
|
||||
};
|
||||
|
||||
export type GetAttributesData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/attribute/";
|
||||
};
|
||||
|
||||
export type GetAttributesResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: GetAllAttributesResponse;
|
||||
};
|
||||
|
||||
export type GetAttributesResponse =
|
||||
GetAttributesResponses[keyof GetAttributesResponses];
|
||||
|
||||
export type CreateAttributeData = {
|
||||
body: CreateAttributeRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/attribute/";
|
||||
};
|
||||
|
||||
export type CreateAttributeErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type CreateAttributeError =
|
||||
CreateAttributeErrors[keyof CreateAttributeErrors];
|
||||
|
||||
export type CreateAttributeResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: CreateAttributeResponse;
|
||||
};
|
||||
|
||||
export type CreateAttributeResponse2 =
|
||||
CreateAttributeResponses[keyof CreateAttributeResponses];
|
||||
|
||||
export type DeleteAttributeData = {
|
||||
body?: never;
|
||||
path: {
|
||||
/**
|
||||
* Pk
|
||||
*/
|
||||
pk: number;
|
||||
};
|
||||
query?: never;
|
||||
url: "/crm/v1/attribute/{pk}";
|
||||
};
|
||||
|
||||
export type DeleteAttributeErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type DeleteAttributeError =
|
||||
DeleteAttributeErrors[keyof DeleteAttributeErrors];
|
||||
|
||||
export type DeleteAttributeResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: DeleteAttributeResponse;
|
||||
};
|
||||
|
||||
export type DeleteAttributeResponse2 =
|
||||
DeleteAttributeResponses[keyof DeleteAttributeResponses];
|
||||
|
||||
export type UpdateAttributeData = {
|
||||
body: UpdateAttributeRequest;
|
||||
path: {
|
||||
/**
|
||||
* Pk
|
||||
*/
|
||||
pk: number;
|
||||
};
|
||||
query?: never;
|
||||
url: "/crm/v1/attribute/{pk}";
|
||||
};
|
||||
|
||||
export type UpdateAttributeErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type UpdateAttributeError =
|
||||
UpdateAttributeErrors[keyof UpdateAttributeErrors];
|
||||
|
||||
export type UpdateAttributeResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: UpdateAttributeResponse;
|
||||
};
|
||||
|
||||
export type UpdateAttributeResponse2 =
|
||||
UpdateAttributeResponses[keyof UpdateAttributeResponses];
|
||||
|
||||
export type UpdateAttributeLabelData = {
|
||||
body: UpdateAttributeLabelRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/attribute/label";
|
||||
};
|
||||
|
||||
export type UpdateAttributeLabelErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type UpdateAttributeLabelError =
|
||||
UpdateAttributeLabelErrors[keyof UpdateAttributeLabelErrors];
|
||||
|
||||
export type UpdateAttributeLabelResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: UpdateAttributeLabelResponse;
|
||||
};
|
||||
|
||||
export type UpdateAttributeLabelResponse2 =
|
||||
UpdateAttributeLabelResponses[keyof UpdateAttributeLabelResponses];
|
||||
|
||||
export type GetAttributeTypesData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/attribute/type";
|
||||
};
|
||||
|
||||
export type GetAttributeTypesResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: GetAllAttributeTypesResponse;
|
||||
};
|
||||
|
||||
export type GetAttributeTypesResponse =
|
||||
GetAttributeTypesResponses[keyof GetAttributeTypesResponses];
|
||||
|
||||
export type GetBoardsData = {
|
||||
body?: never;
|
||||
path: {
|
||||
@ -3120,7 +3703,7 @@ export type GetModulesData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/module/built-in/";
|
||||
url: "/crm/v1/module/";
|
||||
};
|
||||
|
||||
export type GetModulesResponses = {
|
||||
@ -3132,6 +3715,171 @@ export type GetModulesResponses = {
|
||||
|
||||
export type GetModulesResponse = GetModulesResponses[keyof GetModulesResponses];
|
||||
|
||||
export type GetModulesWithAttributesData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/module/with-attributes";
|
||||
};
|
||||
|
||||
export type GetModulesWithAttributesResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: GetAllWithAttributesResponse;
|
||||
};
|
||||
|
||||
export type GetModulesWithAttributesResponse =
|
||||
GetModulesWithAttributesResponses[keyof GetModulesWithAttributesResponses];
|
||||
|
||||
export type GetModuleWithAttributesData = {
|
||||
body?: never;
|
||||
path: {
|
||||
/**
|
||||
* Pk
|
||||
*/
|
||||
pk: number;
|
||||
};
|
||||
query?: never;
|
||||
url: "/crm/v1/module/{pk}/with-attributes";
|
||||
};
|
||||
|
||||
export type GetModuleWithAttributesErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type GetModuleWithAttributesError =
|
||||
GetModuleWithAttributesErrors[keyof GetModuleWithAttributesErrors];
|
||||
|
||||
export type GetModuleWithAttributesResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: GetByIdWithAttributesResponse;
|
||||
};
|
||||
|
||||
export type GetModuleWithAttributesResponse =
|
||||
GetModuleWithAttributesResponses[keyof GetModuleWithAttributesResponses];
|
||||
|
||||
export type UpdateModuleData = {
|
||||
body: UpdateModuleCommonInfoRequest;
|
||||
path: {
|
||||
/**
|
||||
* Pk
|
||||
*/
|
||||
pk: number;
|
||||
};
|
||||
query?: never;
|
||||
url: "/crm/v1/module/{pk}/common-info";
|
||||
};
|
||||
|
||||
export type UpdateModuleErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type UpdateModuleError = UpdateModuleErrors[keyof UpdateModuleErrors];
|
||||
|
||||
export type UpdateModuleResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: UpdateModuleCommonInfoResponse;
|
||||
};
|
||||
|
||||
export type UpdateModuleResponse =
|
||||
UpdateModuleResponses[keyof UpdateModuleResponses];
|
||||
|
||||
export type DeleteModuleData = {
|
||||
body?: never;
|
||||
path: {
|
||||
/**
|
||||
* Pk
|
||||
*/
|
||||
pk: number;
|
||||
};
|
||||
query?: never;
|
||||
url: "/crm/v1/module/{pk}";
|
||||
};
|
||||
|
||||
export type DeleteModuleErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type DeleteModuleError = DeleteModuleErrors[keyof DeleteModuleErrors];
|
||||
|
||||
export type DeleteModuleResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: DeleteModuleResponse;
|
||||
};
|
||||
|
||||
export type DeleteModuleResponse2 =
|
||||
DeleteModuleResponses[keyof DeleteModuleResponses];
|
||||
|
||||
export type RemoveAttributeFromModuleData = {
|
||||
body: DeleteAttributeRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/module/attribute";
|
||||
};
|
||||
|
||||
export type RemoveAttributeFromModuleErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type RemoveAttributeFromModuleError =
|
||||
RemoveAttributeFromModuleErrors[keyof RemoveAttributeFromModuleErrors];
|
||||
|
||||
export type RemoveAttributeFromModuleResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: DeleteAttributeResponse;
|
||||
};
|
||||
|
||||
export type RemoveAttributeFromModuleResponse =
|
||||
RemoveAttributeFromModuleResponses[keyof RemoveAttributeFromModuleResponses];
|
||||
|
||||
export type AddAttributeToModuleData = {
|
||||
body: AddAttributeRequest;
|
||||
path?: never;
|
||||
query?: never;
|
||||
url: "/crm/v1/module/attribute";
|
||||
};
|
||||
|
||||
export type AddAttributeToModuleErrors = {
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type AddAttributeToModuleError =
|
||||
AddAttributeToModuleErrors[keyof AddAttributeToModuleErrors];
|
||||
|
||||
export type AddAttributeToModuleResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: AddAttributeResponse;
|
||||
};
|
||||
|
||||
export type AddAttributeToModuleResponse =
|
||||
AddAttributeToModuleResponses[keyof AddAttributeToModuleResponses];
|
||||
|
||||
export type GetClientsData = {
|
||||
body?: never;
|
||||
path?: never;
|
||||
|
||||
@ -2,6 +2,47 @@
|
||||
|
||||
import { z } from "zod";
|
||||
|
||||
/**
|
||||
* AddAttributeRequest
|
||||
*/
|
||||
export const zAddAttributeRequest = z.object({
|
||||
attributeId: z.int(),
|
||||
moduleId: z.int(),
|
||||
});
|
||||
|
||||
/**
|
||||
* AddAttributeResponse
|
||||
*/
|
||||
export const zAddAttributeResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* AttributeTypeSchema
|
||||
*/
|
||||
export const zAttributeTypeSchema = z.object({
|
||||
id: z.int(),
|
||||
type: z.string(),
|
||||
name: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* AttributeSchema
|
||||
*/
|
||||
export const zAttributeSchema = z.object({
|
||||
label: z.string(),
|
||||
isApplicableToGroup: z.boolean(),
|
||||
isShownOnDashboard: z.boolean(),
|
||||
isHighlightIfExpired: z.boolean(),
|
||||
isNullable: z.boolean(),
|
||||
defaultValue: z.union([z.object({}), z.null()]),
|
||||
description: z.string(),
|
||||
typeId: z.int(),
|
||||
id: z.int(),
|
||||
isBuiltIn: z.boolean(),
|
||||
type: zAttributeTypeSchema,
|
||||
});
|
||||
|
||||
/**
|
||||
* BarcodeTemplateAttributeSchema
|
||||
*/
|
||||
@ -95,6 +136,34 @@ export const zClientSchema = z.object({
|
||||
isDeleted: z.optional(z.boolean()).default(false),
|
||||
});
|
||||
|
||||
/**
|
||||
* CreateAttributeSchema
|
||||
*/
|
||||
export const zCreateAttributeSchema = z.object({
|
||||
label: z.string(),
|
||||
isApplicableToGroup: z.boolean(),
|
||||
isShownOnDashboard: z.boolean(),
|
||||
isHighlightIfExpired: z.boolean(),
|
||||
isNullable: z.boolean(),
|
||||
defaultValue: z.union([z.object({}), z.null()]),
|
||||
description: z.string(),
|
||||
typeId: z.int(),
|
||||
});
|
||||
|
||||
/**
|
||||
* CreateAttributeRequest
|
||||
*/
|
||||
export const zCreateAttributeRequest = z.object({
|
||||
entity: zCreateAttributeSchema,
|
||||
});
|
||||
|
||||
/**
|
||||
* CreateAttributeResponse
|
||||
*/
|
||||
export const zCreateAttributeResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* CreateBarcodeTemplateSchema
|
||||
*/
|
||||
@ -579,7 +648,8 @@ export const zModuleSchemaOutput = z.object({
|
||||
id: z.int(),
|
||||
key: z.string(),
|
||||
label: z.string(),
|
||||
description: z.string(),
|
||||
description: z.union([z.string(), z.null()]),
|
||||
isBuiltIn: z.boolean(),
|
||||
get dependsOn() {
|
||||
return z.array(
|
||||
z.lazy((): any => {
|
||||
@ -751,6 +821,21 @@ export const zDealProductAddKitResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* DeleteAttributeRequest
|
||||
*/
|
||||
export const zDeleteAttributeRequest = z.object({
|
||||
attributeId: z.int(),
|
||||
moduleId: z.int(),
|
||||
});
|
||||
|
||||
/**
|
||||
* DeleteAttributeResponse
|
||||
*/
|
||||
export const zDeleteAttributeResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* DeleteBarcodeImageResponse
|
||||
*/
|
||||
@ -821,6 +906,13 @@ export const zDeleteMarketplaceResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* DeleteModuleResponse
|
||||
*/
|
||||
export const zDeleteModuleResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* DeleteProductResponse
|
||||
*/
|
||||
@ -870,6 +962,20 @@ export const zDeleteStatusResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* GetAllAttributeTypesResponse
|
||||
*/
|
||||
export const zGetAllAttributeTypesResponse = z.object({
|
||||
items: z.array(zAttributeTypeSchema),
|
||||
});
|
||||
|
||||
/**
|
||||
* GetAllAttributesResponse
|
||||
*/
|
||||
export const zGetAllAttributesResponse = z.object({
|
||||
items: z.array(zAttributeSchema),
|
||||
});
|
||||
|
||||
/**
|
||||
* GetAllModulesResponse
|
||||
*/
|
||||
@ -877,6 +983,45 @@ export const zGetAllModulesResponse = z.object({
|
||||
items: z.array(zModuleSchemaOutput),
|
||||
});
|
||||
|
||||
/**
|
||||
* ModuleAttributeSchema
|
||||
*/
|
||||
export const zModuleAttributeSchema = z.object({
|
||||
label: z.string(),
|
||||
isApplicableToGroup: z.boolean(),
|
||||
isShownOnDashboard: z.boolean(),
|
||||
isHighlightIfExpired: z.boolean(),
|
||||
isNullable: z.boolean(),
|
||||
defaultValue: z.union([z.object({}), z.null()]),
|
||||
description: z.string(),
|
||||
typeId: z.int(),
|
||||
id: z.int(),
|
||||
isBuiltIn: z.boolean(),
|
||||
type: zAttributeTypeSchema,
|
||||
originalLabel: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* ModuleWithAttributesSchema
|
||||
*/
|
||||
export const zModuleWithAttributesSchema = z.object({
|
||||
id: z.int(),
|
||||
key: z.string(),
|
||||
label: z.string(),
|
||||
description: z.union([z.string(), z.null()]),
|
||||
isBuiltIn: z.boolean(),
|
||||
dependsOn: z.array(zModuleSchemaOutput),
|
||||
tabs: z.array(zModuleTabSchema),
|
||||
attributes: z.array(zModuleAttributeSchema),
|
||||
});
|
||||
|
||||
/**
|
||||
* GetAllWithAttributesResponse
|
||||
*/
|
||||
export const zGetAllWithAttributesResponse = z.object({
|
||||
items: z.array(zModuleWithAttributesSchema),
|
||||
});
|
||||
|
||||
/**
|
||||
* GetBarcodeAttributesResponse
|
||||
*/
|
||||
@ -912,6 +1057,13 @@ export const zGetBoardsResponse = z.object({
|
||||
items: z.array(zBoardSchema),
|
||||
});
|
||||
|
||||
/**
|
||||
* GetByIdWithAttributesResponse
|
||||
*/
|
||||
export const zGetByIdWithAttributesResponse = z.object({
|
||||
entity: zModuleWithAttributesSchema,
|
||||
});
|
||||
|
||||
/**
|
||||
* GetClientsResponse
|
||||
*/
|
||||
@ -1074,7 +1226,8 @@ export const zModuleSchemaInput = z.object({
|
||||
id: z.int(),
|
||||
key: z.string(),
|
||||
label: z.string(),
|
||||
description: z.string(),
|
||||
description: z.union([z.string(), z.null()]),
|
||||
isBuiltIn: z.boolean(),
|
||||
get dependsOn() {
|
||||
return z.array(
|
||||
z.lazy((): any => {
|
||||
@ -1127,6 +1280,50 @@ export const zSwitchDealTagResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateAttributeLabelRequest
|
||||
*/
|
||||
export const zUpdateAttributeLabelRequest = z.object({
|
||||
moduleId: z.int(),
|
||||
attributeId: z.int(),
|
||||
label: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateAttributeLabelResponse
|
||||
*/
|
||||
export const zUpdateAttributeLabelResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateAttributeSchema
|
||||
*/
|
||||
export const zUpdateAttributeSchema = z.object({
|
||||
label: z.optional(z.union([z.string(), z.null()])),
|
||||
isApplicableToGroup: z.optional(z.union([z.boolean(), z.null()])),
|
||||
isShownOnDashboard: z.optional(z.union([z.boolean(), z.null()])),
|
||||
isHighlightIfExpired: z.optional(z.union([z.boolean(), z.null()])),
|
||||
isNullable: z.optional(z.union([z.boolean(), z.null()])),
|
||||
defaultValue: z.optional(z.union([z.object({}), z.null()])),
|
||||
description: z.optional(z.union([z.string(), z.null()])),
|
||||
type: z.optional(z.union([zAttributeTypeSchema, z.null()])),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateAttributeRequest
|
||||
*/
|
||||
export const zUpdateAttributeRequest = z.object({
|
||||
entity: zUpdateAttributeSchema,
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateAttributeResponse
|
||||
*/
|
||||
export const zUpdateAttributeResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateBarcodeTemplateSchema
|
||||
*/
|
||||
@ -1352,6 +1549,28 @@ export const zUpdateMarketplaceResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateModuleCommonInfoSchema
|
||||
*/
|
||||
export const zUpdateModuleCommonInfoSchema = z.object({
|
||||
label: z.string(),
|
||||
description: z.union([z.string(), z.null()]),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateModuleCommonInfoRequest
|
||||
*/
|
||||
export const zUpdateModuleCommonInfoRequest = z.object({
|
||||
entity: zUpdateModuleCommonInfoSchema,
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateModuleCommonInfoResponse
|
||||
*/
|
||||
export const zUpdateModuleCommonInfoResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
/**
|
||||
* UpdateProductSchema
|
||||
*/
|
||||
@ -1526,6 +1745,76 @@ export const zUpdateStatusResponse = z.object({
|
||||
message: z.string(),
|
||||
});
|
||||
|
||||
export const zGetAttributesData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.optional(z.never()),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zGetAttributesResponse = zGetAllAttributesResponse;
|
||||
|
||||
export const zCreateAttributeData = z.object({
|
||||
body: zCreateAttributeRequest,
|
||||
path: z.optional(z.never()),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zCreateAttributeResponse2 = zCreateAttributeResponse;
|
||||
|
||||
export const zDeleteAttributeData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.object({
|
||||
pk: z.int(),
|
||||
}),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zDeleteAttributeResponse2 = zDeleteAttributeResponse;
|
||||
|
||||
export const zUpdateAttributeData = z.object({
|
||||
body: zUpdateAttributeRequest,
|
||||
path: z.object({
|
||||
pk: z.int(),
|
||||
}),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zUpdateAttributeResponse2 = zUpdateAttributeResponse;
|
||||
|
||||
export const zUpdateAttributeLabelData = z.object({
|
||||
body: zUpdateAttributeLabelRequest,
|
||||
path: z.optional(z.never()),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zUpdateAttributeLabelResponse2 = zUpdateAttributeLabelResponse;
|
||||
|
||||
export const zGetAttributeTypesData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.optional(z.never()),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zGetAttributeTypesResponse = zGetAllAttributeTypesResponse;
|
||||
|
||||
export const zGetBoardsData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.object({
|
||||
@ -1769,6 +2058,78 @@ export const zGetModulesData = z.object({
|
||||
*/
|
||||
export const zGetModulesResponse = zGetAllModulesResponse;
|
||||
|
||||
export const zGetModulesWithAttributesData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.optional(z.never()),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zGetModulesWithAttributesResponse = zGetAllWithAttributesResponse;
|
||||
|
||||
export const zGetModuleWithAttributesData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.object({
|
||||
pk: z.int(),
|
||||
}),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zGetModuleWithAttributesResponse = zGetByIdWithAttributesResponse;
|
||||
|
||||
export const zUpdateModuleData = z.object({
|
||||
body: zUpdateModuleCommonInfoRequest,
|
||||
path: z.object({
|
||||
pk: z.int(),
|
||||
}),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zUpdateModuleResponse = zUpdateModuleCommonInfoResponse;
|
||||
|
||||
export const zDeleteModuleData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.object({
|
||||
pk: z.int(),
|
||||
}),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zDeleteModuleResponse2 = zDeleteModuleResponse;
|
||||
|
||||
export const zRemoveAttributeFromModuleData = z.object({
|
||||
body: zDeleteAttributeRequest,
|
||||
path: z.optional(z.never()),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zRemoveAttributeFromModuleResponse = zDeleteAttributeResponse;
|
||||
|
||||
export const zAddAttributeToModuleData = z.object({
|
||||
body: zAddAttributeRequest,
|
||||
path: z.optional(z.never()),
|
||||
query: z.optional(z.never()),
|
||||
});
|
||||
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
export const zAddAttributeToModuleResponse = zAddAttributeResponse;
|
||||
|
||||
export const zGetClientsData = z.object({
|
||||
body: z.optional(z.never()),
|
||||
path: z.optional(z.never()),
|
||||
|
||||
@ -5,11 +5,13 @@ import ColorPickerModal from "@/app/deals/modals/ColorPickerModal/ColorPickerMod
|
||||
import DealsBoardFiltersModal from "@/app/deals/modals/DealsBoardFiltersModal/DealsBoardFiltersModal";
|
||||
import DealsScheduleFiltersModal from "@/app/deals/modals/DealsScheduleFiltersModal/DealsScheduleFiltersModal";
|
||||
import DealsTableFiltersModal from "@/app/deals/modals/DealsTableFiltersModal/DealsTableFiltersModal";
|
||||
import AttributeEditorModal from "@/app/module-editor/[moduleId]/modals/AttributeEditorModal";
|
||||
import {
|
||||
ServiceCategoryEditorModal,
|
||||
ServiceEditorModal,
|
||||
ServicesKitEditorModal,
|
||||
} from "@/app/services/modals";
|
||||
import DealTagModal from "@/drawers/common/ProjectEditorDrawer/tabs/TagsTab/modals/DealTagModal";
|
||||
import EnterNameModal from "@/modals/EnterNameModal/EnterNameModal";
|
||||
import {
|
||||
DealProductEditorModal,
|
||||
@ -20,7 +22,6 @@ import {
|
||||
ProductServiceEditorModal,
|
||||
ServicesKitSelectModal,
|
||||
} from "@/modules/dealModularEditorTabs/FulfillmentBase/shared/modals";
|
||||
import DealTagModal from "@/drawers/common/ProjectEditorDrawer/tabs/TagsTab/modals/DealTagModal";
|
||||
|
||||
export const modals = {
|
||||
enterNameModal: EnterNameModal,
|
||||
@ -42,4 +43,5 @@ export const modals = {
|
||||
statusColorPickerModal: ColorPickerModal,
|
||||
marketplaceEditorModal: MarketplaceEditorModal,
|
||||
dealTagModal: DealTagModal,
|
||||
attributeEditorModal: AttributeEditorModal,
|
||||
};
|
||||
|
||||
@ -117,10 +117,12 @@ const ProductView: FC<Props> = ({ dealProduct }) => {
|
||||
)}
|
||||
<Title order={3}>{dealProduct.product.name}</Title>
|
||||
<ProductFieldsList product={dealProduct.product} />
|
||||
<Text>
|
||||
Штрихкоды:
|
||||
{dealProduct.product.barcodes.join(", ")}
|
||||
</Text>
|
||||
{dealProduct.product.barcodes && (
|
||||
<Text>
|
||||
Штрихкоды:
|
||||
{dealProduct.product.barcodes.join(", ")}
|
||||
</Text>
|
||||
)}
|
||||
<NumberInput
|
||||
suffix={" шт."}
|
||||
value={dealProduct.quantity}
|
||||
|
||||
22
src/theme.ts
22
src/theme.ts
@ -82,5 +82,27 @@ export const theme = createTheme({
|
||||
radius,
|
||||
},
|
||||
},
|
||||
Fieldset: {
|
||||
defaultProps: {
|
||||
radius: "xl",
|
||||
bg: "transparent",
|
||||
bd: "dashed 1px var(--mantine-color-default-border)",
|
||||
},
|
||||
},
|
||||
DateTimePicker: {
|
||||
defaultProps: {
|
||||
radius,
|
||||
},
|
||||
},
|
||||
DatePickerInput: {
|
||||
defaultProps: {
|
||||
radius,
|
||||
},
|
||||
},
|
||||
ActionIcon: {
|
||||
defaultProps: {
|
||||
bg: "light-dark(var(--mantine-color-gray-1), var(--mantine-color-default))",
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@ -18,3 +18,10 @@ export const utcDateTimeToLocalString = (
|
||||
const res = localDateTimeToString(utcDateToLocal(datetime));
|
||||
return withSeconds ? res : res.substring(0, 17);
|
||||
};
|
||||
|
||||
export const utcDateToLocalString = (
|
||||
datetime: string | Date,
|
||||
) => {
|
||||
const res = localDateTimeToString(utcDateToLocal(datetime));
|
||||
return res.substring(0, 11);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user