feat: printing attributes in cards on dashboard
This commit is contained in:
@@ -7,6 +7,7 @@ export type AttributeSchema = {
|
|||||||
label: string;
|
label: string;
|
||||||
name: string;
|
name: string;
|
||||||
isApplicableToGroup: boolean;
|
isApplicableToGroup: boolean;
|
||||||
|
isShownOnDashboard: boolean;
|
||||||
isNullable: boolean;
|
isNullable: boolean;
|
||||||
defaultValue: (boolean | number | string | null);
|
defaultValue: (boolean | number | string | null);
|
||||||
typeId: number;
|
typeId: number;
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export type BaseAttributeSchema = {
|
|||||||
label: string;
|
label: string;
|
||||||
name: string;
|
name: string;
|
||||||
isApplicableToGroup: boolean;
|
isApplicableToGroup: boolean;
|
||||||
|
isShownOnDashboard: boolean;
|
||||||
isNullable: boolean;
|
isNullable: boolean;
|
||||||
defaultValue: (boolean | number | string | null);
|
defaultValue: (boolean | number | string | null);
|
||||||
typeId: number;
|
typeId: number;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
/* eslint-disable */
|
/* eslint-disable */
|
||||||
import type { BaseMarketplaceSchema } from './BaseMarketplaceSchema';
|
import type { BaseMarketplaceSchema } from './BaseMarketplaceSchema';
|
||||||
import type { BoardSchema } from './BoardSchema';
|
import type { BoardSchema } from './BoardSchema';
|
||||||
|
import type { CardAttributeSchema } from './CardAttributeSchema';
|
||||||
import type { CardBillRequestSchema } from './CardBillRequestSchema';
|
import type { CardBillRequestSchema } from './CardBillRequestSchema';
|
||||||
import type { CardGroupSchema } from './CardGroupSchema';
|
import type { CardGroupSchema } from './CardGroupSchema';
|
||||||
import type { CardTagSchema } from './CardTagSchema';
|
import type { CardTagSchema } from './CardTagSchema';
|
||||||
@@ -20,6 +21,7 @@ export type CardSummary = {
|
|||||||
baseMarketplace?: (BaseMarketplaceSchema | null);
|
baseMarketplace?: (BaseMarketplaceSchema | null);
|
||||||
totalProducts: number;
|
totalProducts: number;
|
||||||
tags: Array<CardTagSchema>;
|
tags: Array<CardTagSchema>;
|
||||||
|
attributes: Array<CardAttributeSchema>;
|
||||||
shipmentWarehouseId: (number | null);
|
shipmentWarehouseId: (number | null);
|
||||||
shipmentWarehouseName: (string | null);
|
shipmentWarehouseName: (string | null);
|
||||||
billRequest?: (CardBillRequestSchema | null);
|
billRequest?: (CardBillRequestSchema | null);
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { CardService, CardSummary } from "../../../../client";
|
import { CardAttributeSchema, CardService, CardSummary } from "../../../../client";
|
||||||
import styles from "./CardSummaryItem.module.css";
|
import styles from "./CardSummaryItem.module.css";
|
||||||
|
|
||||||
import { ActionIcon, Badge, CopyButton, Flex, Image, Popover, rem, Text, ThemeIcon, Tooltip } from "@mantine/core";
|
import { ActionIcon, Badge, CopyButton, Flex, Image, Popover, rem, Text, ThemeIcon, Tooltip } from "@mantine/core";
|
||||||
@@ -12,6 +12,7 @@ import useCardSummaryState from "./useCardSummaryState.tsx";
|
|||||||
import isModuleInProject, { Modules } from "../../../../modules/utils/isModuleInProject.ts";
|
import isModuleInProject, { Modules } 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 { formatDate, formatDateTime } from "../../../../types/utils.ts";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
cardSummary: CardSummary;
|
cardSummary: CardSummary;
|
||||||
@@ -38,6 +39,40 @@ const CardSummaryItem: FC<Props> = ({ cardSummary, color }) => {
|
|||||||
const isLockedInsideGroup = () => {
|
const isLockedInsideGroup = () => {
|
||||||
return cardSummary.group && !cardSummary.group.billRequest;
|
return cardSummary.group && !cardSummary.group.billRequest;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const attributeValues = () => {
|
||||||
|
return (
|
||||||
|
<Flex direction={"column"}>
|
||||||
|
{cardSummary.attributes
|
||||||
|
.filter(cardAttr => cardAttr.attribute.isShownOnDashboard && cardAttr.value !== null)
|
||||||
|
.map(cardAttr => (
|
||||||
|
<Text c={"gray.6"} size={"sm"}>
|
||||||
|
{cardAttr.attribute.label}: {getAttrValueValue(cardAttr)}
|
||||||
|
</Text>
|
||||||
|
))
|
||||||
|
}
|
||||||
|
</Flex>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getAttrValueValue = (cardAttr: CardAttributeSchema) => {
|
||||||
|
const value = cardAttr.value;
|
||||||
|
if (value === null) return;
|
||||||
|
|
||||||
|
const type = cardAttr.attribute.type.type;
|
||||||
|
if (type === "datetime") {
|
||||||
|
return formatDateTime(value as string);
|
||||||
|
}
|
||||||
|
if (type === "date") {
|
||||||
|
return formatDate(value as string);
|
||||||
|
}
|
||||||
|
if (type === "bool") {
|
||||||
|
return value ? "да" : "нет";
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onContextMenu={showContextMenu([
|
onContextMenu={showContextMenu([
|
||||||
@@ -101,8 +136,9 @@ const CardSummaryItem: FC<Props> = ({ cardSummary, color }) => {
|
|||||||
</Text>
|
</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
)}
|
)}
|
||||||
|
{attributeValues()}
|
||||||
{!cardSummary.group?.id && (
|
{!cardSummary.group?.id && (
|
||||||
<CardTags cardId={cardSummary.id} tags={cardSummary.tags}/>
|
<CardTags cardId={cardSummary.id} tags={cardSummary.tags} />
|
||||||
)}
|
)}
|
||||||
<Flex align={"center"} justify={"space-between"}>
|
<Flex align={"center"} justify={"space-between"}>
|
||||||
<Flex align={"center"} gap={rem(5)}>
|
<Flex align={"center"} gap={rem(5)}>
|
||||||
|
|||||||
@@ -47,6 +47,15 @@ const useAttributesTableColumns = () => {
|
|||||||
<IconX />
|
<IconX />
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
header: "Вывод на дашборде",
|
||||||
|
accessorKey: "isShownOnDashboard",
|
||||||
|
Cell: ({ cell }) => cell.getValue() ? (
|
||||||
|
<IconCheck />
|
||||||
|
) : (
|
||||||
|
<IconX />
|
||||||
|
),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
header: "Может быть пустым",
|
header: "Может быть пустым",
|
||||||
accessorKey: "isNullable",
|
accessorKey: "isNullable",
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const AttributeModal = ({
|
|||||||
name: "",
|
name: "",
|
||||||
type: undefined,
|
type: undefined,
|
||||||
isApplicableToGroup: false,
|
isApplicableToGroup: false,
|
||||||
|
isShownOnDashboard: false,
|
||||||
isNullable: false,
|
isNullable: false,
|
||||||
defaultValue: null,
|
defaultValue: null,
|
||||||
description: "",
|
description: "",
|
||||||
@@ -143,6 +144,10 @@ const AttributeModal = ({
|
|||||||
label={"Значение синхронизировано в группе"}
|
label={"Значение синхронизировано в группе"}
|
||||||
{...form.getInputProps("isApplicableToGroup", { type: "checkbox" })}
|
{...form.getInputProps("isApplicableToGroup", { type: "checkbox" })}
|
||||||
/>
|
/>
|
||||||
|
<Checkbox
|
||||||
|
label={"Значение выводится на дашборде"}
|
||||||
|
{...form.getInputProps("isShownOnDashboard", { type: "checkbox" })}
|
||||||
|
/>
|
||||||
{isNullableInputShown && (
|
{isNullableInputShown && (
|
||||||
<Checkbox
|
<Checkbox
|
||||||
label={"Может быть пустым"}
|
label={"Может быть пустым"}
|
||||||
|
|||||||
@@ -41,26 +41,6 @@ const useAttributesTableColumns = ({ selectedAttributes }: Props) => {
|
|||||||
accessorKey: "type.name",
|
accessorKey: "type.name",
|
||||||
size: 120,
|
size: 120,
|
||||||
},
|
},
|
||||||
// {
|
|
||||||
// header: " ",
|
|
||||||
// Cell: ({ row }) => {
|
|
||||||
// const description = row.original.description ? `Описание: ${row.original.description}` : "";
|
|
||||||
// const info = (
|
|
||||||
// <Box>
|
|
||||||
// <Text>Может быть пустым: {row.original.isNullable ? "да" : "нет"}</Text>
|
|
||||||
// <Text>{defaultValueToStr(row.original.defaultValue, row.original.type.type)}</Text>
|
|
||||||
// <Text>Синхронизировано в группе: {row.original.isApplicableToGroup ? "да" : "нет"}</Text>
|
|
||||||
// <Text>{description}</Text>
|
|
||||||
// </Box>
|
|
||||||
// );
|
|
||||||
// return (
|
|
||||||
// <Tooltip label={info} multiline w={rem(300)}>
|
|
||||||
// <IconInfoCircle />
|
|
||||||
// </Tooltip>
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// size: 5,
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
header: "Значение по умолчанию",
|
header: "Значение по умолчанию",
|
||||||
accessorKey: "defaultValue",
|
accessorKey: "defaultValue",
|
||||||
@@ -93,6 +73,16 @@ const useAttributesTableColumns = ({ selectedAttributes }: Props) => {
|
|||||||
),
|
),
|
||||||
size: 120,
|
size: 120,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
header: "Вывод на дашборде",
|
||||||
|
accessorKey: "isShownOnDashboard",
|
||||||
|
Cell: ({ cell }) => cell.getValue() ? (
|
||||||
|
<IconCheck />
|
||||||
|
) : (
|
||||||
|
<IconX />
|
||||||
|
),
|
||||||
|
size: 130,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
header: "Может быть пустым",
|
header: "Может быть пустым",
|
||||||
accessorKey: "isNullable",
|
accessorKey: "isNullable",
|
||||||
|
|||||||
Reference in New Issue
Block a user