feat: modules dependencies
This commit is contained in:
		@@ -8,5 +8,6 @@ export type ModuleSchema = {
 | 
				
			|||||||
    label: string;
 | 
					    label: string;
 | 
				
			||||||
    iconName?: (string | null);
 | 
					    iconName?: (string | null);
 | 
				
			||||||
    isDeleted: boolean;
 | 
					    isDeleted: boolean;
 | 
				
			||||||
 | 
					    dependsOn?: Array<ModuleSchema>;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,8 +6,9 @@ import { IconGripHorizontal } from "@tabler/icons-react";
 | 
				
			|||||||
import { useDebouncedValue } from "@mantine/hooks";
 | 
					import { useDebouncedValue } from "@mantine/hooks";
 | 
				
			||||||
import { notifications } from "../../../../shared/lib/notifications.ts";
 | 
					import { notifications } from "../../../../shared/lib/notifications.ts";
 | 
				
			||||||
import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
					import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
				
			||||||
import isModuleInProject, { Modules } from "../../../../modules/utils/isModuleInProject.ts";
 | 
					import isModuleInProject from "../../../../modules/utils/isModuleInProject.ts";
 | 
				
			||||||
import CardTags from "../CardTags/CardTags.tsx";
 | 
					import CardTags from "../CardTags/CardTags.tsx";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../../../../modules/modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
    cards: CardSummary[];
 | 
					    cards: CardSummary[];
 | 
				
			||||||
@@ -19,7 +20,7 @@ export const CardGroupView: FC<Props> = ({ cards, group }) => {
 | 
				
			|||||||
    const [name, setName] = useState<string>(group.name || "");
 | 
					    const [name, setName] = useState<string>(group.name || "");
 | 
				
			||||||
    const [debouncedName] = useDebouncedValue(name, 200);
 | 
					    const [debouncedName] = useDebouncedValue(name, 200);
 | 
				
			||||||
    const { selectedProject } = useProjectsContext();
 | 
					    const { selectedProject } = useProjectsContext();
 | 
				
			||||||
    const isServicesAndProductsIncluded = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, selectedProject);
 | 
					    const isServicesAndProductsIncluded = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedProject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const totalPrice = useMemo(() => cards.reduce((acc, card) => acc + card.totalPrice, 0), [cards]);
 | 
					    const totalPrice = useMemo(() => cards.reduce((acc, card) => acc + card.totalPrice, 0), [cards]);
 | 
				
			||||||
    const totalProducts = useMemo(() => cards.reduce((acc, card) => acc + card.totalProducts, 0), [cards]);
 | 
					    const totalProducts = useMemo(() => cards.reduce((acc, card) => acc + card.totalProducts, 0), [cards]);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,10 +9,11 @@ import { faCheck } from "@fortawesome/free-solid-svg-icons";
 | 
				
			|||||||
import { IconCheck, IconLayoutGridRemove, IconTrash } from "@tabler/icons-react";
 | 
					import { IconCheck, IconLayoutGridRemove, IconTrash } from "@tabler/icons-react";
 | 
				
			||||||
import { useContextMenu } from "mantine-contextmenu";
 | 
					import { useContextMenu } from "mantine-contextmenu";
 | 
				
			||||||
import useCardSummaryState from "./useCardSummaryState.tsx";
 | 
					import useCardSummaryState from "./useCardSummaryState.tsx";
 | 
				
			||||||
import isModuleInProject, { Modules } from "../../../../modules/utils/isModuleInProject.ts";
 | 
					import isModuleInProject from "../../../../modules/utils/isModuleInProject.ts";
 | 
				
			||||||
import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
					import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
				
			||||||
import CardTags from "../CardTags/CardTags.tsx";
 | 
					import CardTags from "../CardTags/CardTags.tsx";
 | 
				
			||||||
import CardAttributesInSummaryItem from "../CardAttributesInSummaryItem/CardAttributesInSummaryItem.tsx";
 | 
					import CardAttributesInSummaryItem from "../CardAttributesInSummaryItem/CardAttributesInSummaryItem.tsx";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../../../../modules/modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
    cardSummary: CardSummary;
 | 
					    cardSummary: CardSummary;
 | 
				
			||||||
@@ -25,8 +26,8 @@ const CardSummaryItem: FC<Props> = ({ cardSummary, color }) => {
 | 
				
			|||||||
    const { setSelectedCard } = useCardPageContext();
 | 
					    const { setSelectedCard } = useCardPageContext();
 | 
				
			||||||
    const { onDelete, onComplete, onDeleteFromGroup } = useCardSummaryState();
 | 
					    const { onDelete, onComplete, onDeleteFromGroup } = useCardSummaryState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const isServicesAndProductsIncluded = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, selectedProject);
 | 
					    const isServicesAndProductsIncluded = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedProject);
 | 
				
			||||||
    const isClientIncluded = isModuleInProject(Modules.CLIENTS, selectedProject);
 | 
					    const isClientIncluded = isModuleInProject(ModuleNames.CLIENTS, selectedProject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const onCardSummaryClick = () => {
 | 
					    const onCardSummaryClick = () => {
 | 
				
			||||||
        CardService.getCardById({ cardId: cardSummary.id }).then(card => {
 | 
					        CardService.getCardById({ cardId: cardSummary.id }).then(card => {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,8 +9,9 @@ import { groupBy, has, uniq } from "lodash";
 | 
				
			|||||||
import { CardGroupView } from "../CardGroupView/CardGroupView.tsx";
 | 
					import { CardGroupView } from "../CardGroupView/CardGroupView.tsx";
 | 
				
			||||||
import CreateDealsFromFileButton from "../CreateCardsFromFileButton/CreateDealsFromFileButton.tsx";
 | 
					import CreateDealsFromFileButton from "../CreateCardsFromFileButton/CreateDealsFromFileButton.tsx";
 | 
				
			||||||
import DragState from "../../../../pages/CardsPage/enums/DragState.ts";
 | 
					import DragState from "../../../../pages/CardsPage/enums/DragState.ts";
 | 
				
			||||||
import isModuleInProject, { Modules } from "../../../../modules/utils/isModuleInProject.ts";
 | 
					import isModuleInProject from "../../../../modules/utils/isModuleInProject.ts";
 | 
				
			||||||
import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
					import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../../../../modules/modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
    status: StatusSchema;
 | 
					    status: StatusSchema;
 | 
				
			||||||
@@ -28,7 +29,7 @@ export const CardsDndColumn: FC<Props> = ({
 | 
				
			|||||||
                                              withCreateButton = false,
 | 
					                                              withCreateButton = false,
 | 
				
			||||||
                                          }) => {
 | 
					                                          }) => {
 | 
				
			||||||
    const { selectedProject } = useProjectsContext();
 | 
					    const { selectedProject } = useProjectsContext();
 | 
				
			||||||
    const isCreatingDealFromFileEnabled = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, selectedProject);
 | 
					    const isCreatingDealFromFileEnabled = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedProject);
 | 
				
			||||||
    const isDropDisabled = dragState !== DragState.DRAG_CARD;
 | 
					    const isDropDisabled = dragState !== DragState.DRAG_CARD;
 | 
				
			||||||
    const droppableId = status.id.toString();
 | 
					    const droppableId = status.id.toString();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,8 +7,9 @@ import { CardService, StatusSchema } from "../../../../client";
 | 
				
			|||||||
import { useQueryClient } from "@tanstack/react-query";
 | 
					import { useQueryClient } from "@tanstack/react-query";
 | 
				
			||||||
import { dateWithoutTimezone } from "../../../../shared/lib/date.ts";
 | 
					import { dateWithoutTimezone } from "../../../../shared/lib/date.ts";
 | 
				
			||||||
import { usePrefillCardContext } from "../../../../pages/CardsPage/contexts/PrefillCardContext.tsx";
 | 
					import { usePrefillCardContext } from "../../../../pages/CardsPage/contexts/PrefillCardContext.tsx";
 | 
				
			||||||
import isModuleInProject, { Modules } from "../../../../modules/utils/isModuleInProject.ts";
 | 
					import isModuleInProject from "../../../../modules/utils/isModuleInProject.ts";
 | 
				
			||||||
import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
					import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../../../../modules/modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
    status: StatusSchema;
 | 
					    status: StatusSchema;
 | 
				
			||||||
@@ -21,7 +22,7 @@ const CreateCardButton = ({ status }: Props) => {
 | 
				
			|||||||
    const { prefillCard, setPrefillCard } = usePrefillCardContext();
 | 
					    const { prefillCard, setPrefillCard } = usePrefillCardContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const { selectedProject } = useProjectsContext();
 | 
					    const { selectedProject } = useProjectsContext();
 | 
				
			||||||
    const isPrefillingDealEnabled = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, selectedProject);
 | 
					    const isPrefillingDealEnabled = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedProject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div
 | 
					        <div
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,8 +9,9 @@ import ShippingWarehouseAutocomplete
 | 
				
			|||||||
    from "../../../Selects/ShippingWarehouseAutocomplete/ShippingWarehouseAutocomplete.tsx";
 | 
					    from "../../../Selects/ShippingWarehouseAutocomplete/ShippingWarehouseAutocomplete.tsx";
 | 
				
			||||||
import BaseMarketplaceSelect from "../../../Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
 | 
					import BaseMarketplaceSelect from "../../../Selects/BaseMarketplaceSelect/BaseMarketplaceSelect.tsx";
 | 
				
			||||||
import { usePrefillCardContext } from "../../../../pages/CardsPage/contexts/PrefillCardContext.tsx";
 | 
					import { usePrefillCardContext } from "../../../../pages/CardsPage/contexts/PrefillCardContext.tsx";
 | 
				
			||||||
import isModuleInProject, { Modules } from "../../../../modules/utils/isModuleInProject.ts";
 | 
					import isModuleInProject from "../../../../modules/utils/isModuleInProject.ts";
 | 
				
			||||||
import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
					import { useProjectsContext } from "../../../../contexts/ProjectsContext.tsx";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../../../../modules/modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
    onSubmit: (quickDeal: QuickCard) => void;
 | 
					    onSubmit: (quickDeal: QuickCard) => void;
 | 
				
			||||||
@@ -19,11 +20,11 @@ type Props = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const CreateCardForm: FC<Props> = ({ onSubmit, onCancel }) => {
 | 
					const CreateCardForm: FC<Props> = ({ onSubmit, onCancel }) => {
 | 
				
			||||||
    const { selectedProject } = useProjectsContext();
 | 
					    const { selectedProject } = useProjectsContext();
 | 
				
			||||||
    const isPrefillingEnabled = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, selectedProject);
 | 
					    const isPrefillingEnabled = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedProject);
 | 
				
			||||||
    const { prefillOnOpen, prefillCard } = usePrefillCardContext();
 | 
					    const { prefillOnOpen, prefillCard } = usePrefillCardContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const isServicesAndProductsIncluded = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, selectedProject);
 | 
					    const isServicesAndProductsIncluded = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedProject);
 | 
				
			||||||
    const isClientsIncluded = isModuleInProject(Modules.CLIENTS, selectedProject);
 | 
					    const isClientsIncluded = isModuleInProject(ModuleNames.CLIENTS, selectedProject);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const form = useForm<QuickCard>({
 | 
					    const form = useForm<QuickCard>({
 | 
				
			||||||
        initialValues: {
 | 
					        initialValues: {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,9 +9,10 @@ import DragState from "../../../../pages/CardsPage/enums/DragState.ts";
 | 
				
			|||||||
import { useContextMenu } from "mantine-contextmenu";
 | 
					import { useContextMenu } from "mantine-contextmenu";
 | 
				
			||||||
import { IconEdit, IconTrash } from "@tabler/icons-react";
 | 
					import { IconEdit, IconTrash } from "@tabler/icons-react";
 | 
				
			||||||
import useStatus from "./hooks/useStatus.tsx";
 | 
					import useStatus from "./hooks/useStatus.tsx";
 | 
				
			||||||
import isModuleInProject, { Modules } from "../../../../modules/utils/isModuleInProject.ts";
 | 
					import isModuleInProject from "../../../../modules/utils/isModuleInProject.ts";
 | 
				
			||||||
import { useEqualHeightsContext } from "./contexts/EqualHeightContext.tsx";
 | 
					import { useEqualHeightsContext } from "./contexts/EqualHeightContext.tsx";
 | 
				
			||||||
import { useBoardsContext } from "../../../../contexts/BoardsContext.tsx";
 | 
					import { useBoardsContext } from "../../../../contexts/BoardsContext.tsx";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../../../../modules/modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
@@ -27,7 +28,7 @@ const Status = ({ summaries, status, dragState, index }: Props) => {
 | 
				
			|||||||
    } = useBoardsContext();
 | 
					    } = useBoardsContext();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const isDropDisabled = dragState !== DragState.DRAG_STATUS;
 | 
					    const isDropDisabled = dragState !== DragState.DRAG_STATUS;
 | 
				
			||||||
    const isServicesAndProductsIncluded = isModuleInProject(Modules.SERVICES_AND_PRODUCTS, selectedBoard?.project);
 | 
					    const isServicesAndProductsIncluded = isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, selectedBoard?.project);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    const {
 | 
					    const {
 | 
				
			||||||
        divRefs,
 | 
					        divRefs,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,21 +1,7 @@
 | 
				
			|||||||
import { ProjectSchema } from "../../client";
 | 
					import { ProjectSchema } from "../../client";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export enum Modules {
 | 
					const isModuleInProject = (module: ModuleNames, project?: ProjectSchema | null) => {
 | 
				
			||||||
    SERVICES_AND_PRODUCTS = "servicesAndProducts",
 | 
					 | 
				
			||||||
    SHIPMENT = "shipment",
 | 
					 | 
				
			||||||
    EMPLOYEES = "employees",
 | 
					 | 
				
			||||||
    CLIENTS = "clients",
 | 
					 | 
				
			||||||
    MANAGERS = "managers",
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
const isModuleInProject = (module: Modules, project?: ProjectSchema | null) => {
 | 
					 | 
				
			||||||
    // if servicesAndProducts included, then clients also included
 | 
					 | 
				
			||||||
    if (module === Modules.CLIENTS) {
 | 
					 | 
				
			||||||
        if (project?.modules.findIndex(m => m.key === Modules.SERVICES_AND_PRODUCTS.toString()) !== -1) {
 | 
					 | 
				
			||||||
            return true;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return project?.modules.findIndex(m => m.key === module.toString()) !== -1;
 | 
					    return project?.modules.findIndex(m => m.key === module.toString()) !== -1;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,7 +2,8 @@ import { useForm } from "@mantine/form";
 | 
				
			|||||||
import { useEffect, useState } from "react";
 | 
					import { useEffect, useState } from "react";
 | 
				
			||||||
import { BaseMarketplaceSchema } from "../../../../../client";
 | 
					import { BaseMarketplaceSchema } from "../../../../../client";
 | 
				
			||||||
import { useCardSummariesFull } from "../../../hooks/useCardSummaries.tsx";
 | 
					import { useCardSummariesFull } from "../../../hooks/useCardSummaries.tsx";
 | 
				
			||||||
import isModuleInProject, { Modules } from "../../../../../modules/utils/isModuleInProject.ts";
 | 
					import isModuleInProject from "../../../../../modules/utils/isModuleInProject.ts";
 | 
				
			||||||
 | 
					import { ModuleNames } from "../../../../../modules/modules.tsx";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type State = {
 | 
					type State = {
 | 
				
			||||||
    idOrName: string | null;
 | 
					    idOrName: string | null;
 | 
				
			||||||
@@ -22,7 +23,7 @@ const usePrefillCard = () => {
 | 
				
			|||||||
    const applyFilters = () => {
 | 
					    const applyFilters = () => {
 | 
				
			||||||
        let result = objects;
 | 
					        let result = objects;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        result = result.filter(obj => isModuleInProject(Modules.SERVICES_AND_PRODUCTS, obj.board.project));
 | 
					        result = result.filter(obj => isModuleInProject(ModuleNames.SERVICES_AND_PRODUCTS, obj.board.project));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (form.values.idOrName) {
 | 
					        if (form.values.idOrName) {
 | 
				
			||||||
            if (isNaN(parseInt(form.values.idOrName))) {
 | 
					            if (isNaN(parseInt(form.values.idOrName))) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,8 @@
 | 
				
			|||||||
import { useMemo } from "react";
 | 
					import { useMemo } from "react";
 | 
				
			||||||
import { MRT_ColumnDef } from "mantine-react-table";
 | 
					import { MRT_ColumnDef } from "mantine-react-table";
 | 
				
			||||||
import { ModuleSchema } from "../../../../../../../client";
 | 
					import { ModuleSchema } from "../../../../../../../client";
 | 
				
			||||||
import { Center, Checkbox } from "@mantine/core";
 | 
					import { Center, Checkbox, em, Group, Tooltip } from "@mantine/core";
 | 
				
			||||||
 | 
					import { IconInfoCircle } from "@tabler/icons-react";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type Props = {
 | 
					type Props = {
 | 
				
			||||||
@@ -32,7 +33,25 @@ const useModulesTableColumns = ({ selectedModules }: Props) => {
 | 
				
			|||||||
            {
 | 
					            {
 | 
				
			||||||
                header: "Название",
 | 
					                header: "Название",
 | 
				
			||||||
                accessorKey: "label",
 | 
					                accessorKey: "label",
 | 
				
			||||||
 | 
					                size: 200,
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                header: "",
 | 
				
			||||||
 | 
					                Header: (
 | 
				
			||||||
 | 
					                    <Group gap={"sm"}>
 | 
				
			||||||
 | 
					                        <>Зависит от модулей</>
 | 
				
			||||||
 | 
					                        <Tooltip label={"Зависимости автоматически подключатся при сохранении"}>
 | 
				
			||||||
 | 
					                            <IconInfoCircle size={em(20)} />
 | 
				
			||||||
 | 
					                        </Tooltip>
 | 
				
			||||||
 | 
					                    </Group>
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					                accessorKey: "dependsOn",
 | 
				
			||||||
                size: 10000,
 | 
					                size: 10000,
 | 
				
			||||||
 | 
					                Cell: ({ row }) => (
 | 
				
			||||||
 | 
					                    <>
 | 
				
			||||||
 | 
					                        {row.original.dependsOn?.map(module => module.label).join(", ")}
 | 
				
			||||||
 | 
					                    </>
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        [selectedModules],
 | 
					        [selectedModules],
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user