@esic-lab/data-core-ui 0.0.62 → 0.0.64

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.mts CHANGED
@@ -19,8 +19,9 @@ interface PrimaryButtonProps {
19
19
  colorPrimary?: string;
20
20
  colorPrimaryHover?: string;
21
21
  textColor?: string;
22
+ className?: string;
22
23
  }
23
- declare function PrimaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, }: PrimaryButtonProps): react_jsx_runtime.JSX.Element;
24
+ declare function PrimaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, className, }: PrimaryButtonProps): react_jsx_runtime.JSX.Element;
24
25
 
25
26
  interface SecondaryButtonProps {
26
27
  title: string;
@@ -33,8 +34,9 @@ interface SecondaryButtonProps {
33
34
  defaultHoverBorderColor?: string;
34
35
  defaultHoverColor?: string;
35
36
  textColor?: string;
37
+ className?: string;
36
38
  }
37
- declare function SecondaryButton({ title, onClick, disabled, iconPlacement, size, colorBgContainer, defaultHoverBorderColor, defaultHoverColor, textColor, icon, }: SecondaryButtonProps): react_jsx_runtime.JSX.Element;
39
+ declare function SecondaryButton({ title, onClick, disabled, iconPlacement, size, colorBgContainer, defaultHoverBorderColor, defaultHoverColor, textColor, icon, className, }: SecondaryButtonProps): react_jsx_runtime.JSX.Element;
38
40
 
39
41
  interface GhostButtonProps {
40
42
  title: string;
@@ -66,8 +68,9 @@ interface TertiaryButtonProps {
66
68
  colorPrimary?: string;
67
69
  colorPrimaryHover?: string;
68
70
  textColor?: string;
71
+ className?: string;
69
72
  }
70
- declare function TertiaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, }: TertiaryButtonProps): react_jsx_runtime.JSX.Element;
73
+ declare function TertiaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, className, }: TertiaryButtonProps): react_jsx_runtime.JSX.Element;
71
74
 
72
75
  interface LoaderProps {
73
76
  size?: number;
@@ -271,8 +274,11 @@ interface InputFieldNumberProps {
271
274
  changeOnWheel?: boolean;
272
275
  formatter?: InputNumberProps["formatter"];
273
276
  parser?: InputNumberProps["parser"];
277
+ decimal?: boolean;
278
+ decimalScale?: number;
279
+ format?: "number" | "currency";
274
280
  }
275
- declare function InputFieldNumber({ value, onChange, placeholder, label, required, disabled, error, addonBefore, addonAfter, defaultValue, className, max, min, controls, size, changeOnWheel, formatter, parser, }: InputFieldNumberProps): react_jsx_runtime.JSX.Element;
281
+ declare function InputFieldNumber({ value, onChange, placeholder, label, required, disabled, error, addonBefore, addonAfter, defaultValue, className, max, min, controls, size, changeOnWheel, formatter, parser, decimal, decimalScale, format, }: InputFieldNumberProps): react_jsx_runtime.JSX.Element;
276
282
 
277
283
  interface DatePickerBasicProps {
278
284
  value: Date | null;
@@ -555,7 +561,7 @@ interface IndicatorProps {
555
561
  value: string;
556
562
  label: string;
557
563
  }[];
558
- type: "OUTPUT" | "OUTCOME";
564
+ type: "OUTPUT" | "OUTCOME" | "TARGET";
559
565
  arrayData: IndicatorArray[];
560
566
  canEdit?: boolean;
561
567
  setArrayData: (data: IndicatorArray[]) => void;
@@ -566,7 +572,7 @@ interface IndicatorProps {
566
572
  }) => void;
567
573
  }
568
574
  interface IndicatorArray {
569
- indicatorType: "OUTPUT" | "OUTCOME";
575
+ indicatorType: "OUTPUT" | "OUTCOME" | "TARGET";
570
576
  inputType: "TEXT" | "NUMBER";
571
577
  textValue: string;
572
578
  numberValue?: number;
@@ -665,4 +671,19 @@ interface GanttChartProps {
665
671
  }
666
672
  declare const GanttChart: react.FC<GanttChartProps>;
667
673
 
668
- export { AntDModal, AntDataTable, BarChart, Breadcrumbs, Calendar, Checkbox, CheckboxGroup, ColorPalettePickerBasic, ColorPickerBasic, DataTable, DatePickerBasic, DatePickerRange, FileUploader, FilterPopUp, GanttChart, GhostButton, HeadingPage, Indicator, InputField, InputFieldNumber, KpiSection, Loader, MenuNavBar, type MenuNavBarProps, PieChart, PrimaryButton, ProfileSelect, ProgressBar, QRCodeGenerator, Radio, RadioGroup, SecondaryButton, SelectCustom, SelectField, SelectFieldGroup, SelectFieldStatus, SelectFieldStatusReport, SelectFieldTag, Sidebar, SortFilter, Switch, SwitchSelect, TabProject, TabSelectionButton, TertiaryButton, TextAreaInput, TextInput, TopNavBar, messageError, messageInfo, messageLoading, messageSuccess, messageWarning, setMessageApi };
674
+ type CardKPIProps = {
675
+ dataItem: {
676
+ id: string;
677
+ projectId: string;
678
+ name: string;
679
+ percent: number;
680
+ projectColor: string;
681
+ };
682
+ indicator: any[];
683
+ projectId: string;
684
+ overallPercent: number;
685
+ onDetailsClick: (key: string) => void;
686
+ };
687
+ declare function CardKPI({ dataItem, overallPercent, onDetailsClick, indicator, projectId, }: CardKPIProps): react_jsx_runtime.JSX.Element;
688
+
689
+ export { AntDModal, AntDataTable, BarChart, Breadcrumbs, Calendar, CardKPI, Checkbox, CheckboxGroup, ColorPalettePickerBasic, ColorPickerBasic, DataTable, DatePickerBasic, DatePickerRange, FileUploader, FilterPopUp, GanttChart, GhostButton, HeadingPage, Indicator, InputField, InputFieldNumber, KpiSection, Loader, MenuNavBar, type MenuNavBarProps, PieChart, PrimaryButton, ProfileSelect, ProgressBar, QRCodeGenerator, Radio, RadioGroup, SecondaryButton, SelectCustom, SelectField, SelectFieldGroup, SelectFieldStatus, SelectFieldStatusReport, SelectFieldTag, Sidebar, SortFilter, Switch, SwitchSelect, TabProject, TabSelectionButton, TertiaryButton, TextAreaInput, TextInput, TopNavBar, messageError, messageInfo, messageLoading, messageSuccess, messageWarning, setMessageApi };
package/dist/index.d.ts CHANGED
@@ -19,8 +19,9 @@ interface PrimaryButtonProps {
19
19
  colorPrimary?: string;
20
20
  colorPrimaryHover?: string;
21
21
  textColor?: string;
22
+ className?: string;
22
23
  }
23
- declare function PrimaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, }: PrimaryButtonProps): react_jsx_runtime.JSX.Element;
24
+ declare function PrimaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, className, }: PrimaryButtonProps): react_jsx_runtime.JSX.Element;
24
25
 
25
26
  interface SecondaryButtonProps {
26
27
  title: string;
@@ -33,8 +34,9 @@ interface SecondaryButtonProps {
33
34
  defaultHoverBorderColor?: string;
34
35
  defaultHoverColor?: string;
35
36
  textColor?: string;
37
+ className?: string;
36
38
  }
37
- declare function SecondaryButton({ title, onClick, disabled, iconPlacement, size, colorBgContainer, defaultHoverBorderColor, defaultHoverColor, textColor, icon, }: SecondaryButtonProps): react_jsx_runtime.JSX.Element;
39
+ declare function SecondaryButton({ title, onClick, disabled, iconPlacement, size, colorBgContainer, defaultHoverBorderColor, defaultHoverColor, textColor, icon, className, }: SecondaryButtonProps): react_jsx_runtime.JSX.Element;
38
40
 
39
41
  interface GhostButtonProps {
40
42
  title: string;
@@ -66,8 +68,9 @@ interface TertiaryButtonProps {
66
68
  colorPrimary?: string;
67
69
  colorPrimaryHover?: string;
68
70
  textColor?: string;
71
+ className?: string;
69
72
  }
70
- declare function TertiaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, }: TertiaryButtonProps): react_jsx_runtime.JSX.Element;
73
+ declare function TertiaryButton({ title, onClick, disabled, iconPlacement, size, colorPrimary, colorPrimaryHover, textColor, icon, className, }: TertiaryButtonProps): react_jsx_runtime.JSX.Element;
71
74
 
72
75
  interface LoaderProps {
73
76
  size?: number;
@@ -271,8 +274,11 @@ interface InputFieldNumberProps {
271
274
  changeOnWheel?: boolean;
272
275
  formatter?: InputNumberProps["formatter"];
273
276
  parser?: InputNumberProps["parser"];
277
+ decimal?: boolean;
278
+ decimalScale?: number;
279
+ format?: "number" | "currency";
274
280
  }
275
- declare function InputFieldNumber({ value, onChange, placeholder, label, required, disabled, error, addonBefore, addonAfter, defaultValue, className, max, min, controls, size, changeOnWheel, formatter, parser, }: InputFieldNumberProps): react_jsx_runtime.JSX.Element;
281
+ declare function InputFieldNumber({ value, onChange, placeholder, label, required, disabled, error, addonBefore, addonAfter, defaultValue, className, max, min, controls, size, changeOnWheel, formatter, parser, decimal, decimalScale, format, }: InputFieldNumberProps): react_jsx_runtime.JSX.Element;
276
282
 
277
283
  interface DatePickerBasicProps {
278
284
  value: Date | null;
@@ -555,7 +561,7 @@ interface IndicatorProps {
555
561
  value: string;
556
562
  label: string;
557
563
  }[];
558
- type: "OUTPUT" | "OUTCOME";
564
+ type: "OUTPUT" | "OUTCOME" | "TARGET";
559
565
  arrayData: IndicatorArray[];
560
566
  canEdit?: boolean;
561
567
  setArrayData: (data: IndicatorArray[]) => void;
@@ -566,7 +572,7 @@ interface IndicatorProps {
566
572
  }) => void;
567
573
  }
568
574
  interface IndicatorArray {
569
- indicatorType: "OUTPUT" | "OUTCOME";
575
+ indicatorType: "OUTPUT" | "OUTCOME" | "TARGET";
570
576
  inputType: "TEXT" | "NUMBER";
571
577
  textValue: string;
572
578
  numberValue?: number;
@@ -665,4 +671,19 @@ interface GanttChartProps {
665
671
  }
666
672
  declare const GanttChart: react.FC<GanttChartProps>;
667
673
 
668
- export { AntDModal, AntDataTable, BarChart, Breadcrumbs, Calendar, Checkbox, CheckboxGroup, ColorPalettePickerBasic, ColorPickerBasic, DataTable, DatePickerBasic, DatePickerRange, FileUploader, FilterPopUp, GanttChart, GhostButton, HeadingPage, Indicator, InputField, InputFieldNumber, KpiSection, Loader, MenuNavBar, type MenuNavBarProps, PieChart, PrimaryButton, ProfileSelect, ProgressBar, QRCodeGenerator, Radio, RadioGroup, SecondaryButton, SelectCustom, SelectField, SelectFieldGroup, SelectFieldStatus, SelectFieldStatusReport, SelectFieldTag, Sidebar, SortFilter, Switch, SwitchSelect, TabProject, TabSelectionButton, TertiaryButton, TextAreaInput, TextInput, TopNavBar, messageError, messageInfo, messageLoading, messageSuccess, messageWarning, setMessageApi };
674
+ type CardKPIProps = {
675
+ dataItem: {
676
+ id: string;
677
+ projectId: string;
678
+ name: string;
679
+ percent: number;
680
+ projectColor: string;
681
+ };
682
+ indicator: any[];
683
+ projectId: string;
684
+ overallPercent: number;
685
+ onDetailsClick: (key: string) => void;
686
+ };
687
+ declare function CardKPI({ dataItem, overallPercent, onDetailsClick, indicator, projectId, }: CardKPIProps): react_jsx_runtime.JSX.Element;
688
+
689
+ export { AntDModal, AntDataTable, BarChart, Breadcrumbs, Calendar, CardKPI, Checkbox, CheckboxGroup, ColorPalettePickerBasic, ColorPickerBasic, DataTable, DatePickerBasic, DatePickerRange, FileUploader, FilterPopUp, GanttChart, GhostButton, HeadingPage, Indicator, InputField, InputFieldNumber, KpiSection, Loader, MenuNavBar, type MenuNavBarProps, PieChart, PrimaryButton, ProfileSelect, ProgressBar, QRCodeGenerator, Radio, RadioGroup, SecondaryButton, SelectCustom, SelectField, SelectFieldGroup, SelectFieldStatus, SelectFieldStatusReport, SelectFieldTag, Sidebar, SortFilter, Switch, SwitchSelect, TabProject, TabSelectionButton, TertiaryButton, TextAreaInput, TextInput, TopNavBar, messageError, messageInfo, messageLoading, messageSuccess, messageWarning, setMessageApi };
package/dist/index.js CHANGED
@@ -360,6 +360,7 @@ __export(index_exports, {
360
360
  BarChart: () => BarChart,
361
361
  Breadcrumbs: () => Breadcrumbs,
362
362
  Calendar: () => Calendar,
363
+ CardKPI: () => CardKPI,
363
364
  Checkbox: () => Checkbox,
364
365
  CheckboxGroup: () => CheckboxGroup,
365
366
  ColorPalettePickerBasic: () => ColorPalettePickerBasic,
@@ -423,7 +424,8 @@ function PrimaryButton({
423
424
  colorPrimary = "#4e61f6",
424
425
  colorPrimaryHover = "#8895f9",
425
426
  textColor = "#ffffff",
426
- icon
427
+ icon,
428
+ className
427
429
  }) {
428
430
  const textClass = size === "large" ? "body-1" : "body-3";
429
431
  return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
@@ -442,7 +444,7 @@ function PrimaryButton({
442
444
  size,
443
445
  onClick,
444
446
  type: "primary",
445
- className: textClass,
447
+ className: `${textClass} ${className ?? ""}`,
446
448
  disabled,
447
449
  icon,
448
450
  iconPosition: iconPlacement,
@@ -466,7 +468,8 @@ function SecondaryButton({
466
468
  defaultHoverBorderColor = "#7181f8",
467
469
  defaultHoverColor = "#7181f8",
468
470
  textColor = "rgba(0,0,0,0.88)",
469
- icon
471
+ icon,
472
+ className
470
473
  }) {
471
474
  const textClass = size === "large" ? "body-1" : "body-3";
472
475
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
@@ -490,7 +493,7 @@ function SecondaryButton({
490
493
  size,
491
494
  onClick,
492
495
  type: "default",
493
- className: textClass,
496
+ className: `${textClass} ${className ?? ""}`,
494
497
  disabled,
495
498
  icon,
496
499
  iconPosition: iconPlacement,
@@ -548,7 +551,8 @@ function TertiaryButton({
548
551
  colorPrimary = "#000",
549
552
  colorPrimaryHover = "#4d5461",
550
553
  textColor = "white",
551
- icon
554
+ icon,
555
+ className
552
556
  }) {
553
557
  const textClass = size === "large" ? "body-1" : "body-3";
554
558
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
@@ -567,7 +571,7 @@ function TertiaryButton({
567
571
  size,
568
572
  onClick,
569
573
  type: "primary",
570
- className: textClass,
574
+ className: `${textClass} ${className ?? ""}`,
571
575
  disabled,
572
576
  icon,
573
577
  iconPosition: iconPlacement,
@@ -1339,8 +1343,26 @@ function InputFieldNumber({
1339
1343
  size,
1340
1344
  changeOnWheel,
1341
1345
  formatter,
1342
- parser
1346
+ parser,
1347
+ decimal = false,
1348
+ decimalScale = 2,
1349
+ format: format5 = "number"
1343
1350
  }) {
1351
+ const safeScale = Math.max(0, Math.min(decimalScale, 10));
1352
+ const addComma = (s) => s.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1353
+ const defaultFormatter = (v) => {
1354
+ if (v === void 0 || v === null || v === "") return "";
1355
+ const num = Number(v);
1356
+ if (Number.isNaN(num)) return "";
1357
+ const base = !decimal ? Math.trunc(num).toString() : num.toFixed(safeScale);
1358
+ return format5 === "currency" ? addComma(base) : base;
1359
+ };
1360
+ const defaultParser = (v) => {
1361
+ if (!v) return "";
1362
+ const raw = v.replace(/,/g, "").replace(/\s/g, "");
1363
+ if (!decimal) return raw.split(".")[0];
1364
+ return raw.replace(/[^\d.]/g, "");
1365
+ };
1344
1366
  return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
1345
1367
  import_antd7.ConfigProvider,
1346
1368
  {
@@ -1371,17 +1393,9 @@ function InputFieldNumber({
1371
1393
  controls,
1372
1394
  size,
1373
1395
  changeOnWheel,
1374
- formatter: formatter ?? ((value2) => {
1375
- if (value2 === void 0 || value2 === null || value2 === "")
1376
- return "";
1377
- const num = Number(value2);
1378
- if (isNaN(num)) return "";
1379
- return num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1380
- }),
1381
- parser: parser ?? ((value2) => {
1382
- if (!value2) return "";
1383
- return value2.replace(/,/g, "");
1384
- })
1396
+ formatter: formatter ?? defaultFormatter,
1397
+ parser: parser ?? defaultParser,
1398
+ precision: decimal ? safeScale : 0
1385
1399
  }
1386
1400
  ),
1387
1401
  error && /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("p", { className: "text-red-500 caption-1", children: error })
@@ -3952,7 +3966,6 @@ function Indicator({
3952
3966
  ...prev,
3953
3967
  [key]: value
3954
3968
  }));
3955
- console.log(cacheData);
3956
3969
  };
3957
3970
  const handleClick = (active) => {
3958
3971
  handleChangeCashData("inputType", active);
@@ -4004,7 +4017,6 @@ function Indicator({
4004
4017
  ...prev,
4005
4018
  [name]: value
4006
4019
  }));
4007
- console.log(cacheEditData);
4008
4020
  };
4009
4021
  return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "w-full", children: [
4010
4022
  /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
@@ -4012,27 +4024,18 @@ function Indicator({
4012
4024
  {
4013
4025
  className: `space-x-2 grid ${valueSwitch === "TEXT" ? `grid-cols-[140px_1fr_50px]` : `grid-cols-[140px_1fr_200px_200px_50px]`} items-start`,
4014
4026
  children: [
4015
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4016
- SwitchSelect,
4017
- {
4018
- option,
4019
- onClick: handleClick,
4020
- value: valueSwitch,
4021
- label: "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17",
4022
- required: true
4023
- }
4024
- ),
4027
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(SwitchSelect, { option, onClick: handleClick, value: valueSwitch, label: "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17", required: true }),
4025
4028
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4026
4029
  InputField,
4027
4030
  {
4028
- label: `\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4031
+ label: type === "TARGET" ? "\u0E0A\u0E37\u0E48\u0E2D\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4029
4032
  value: cacheData.textValue,
4030
4033
  className: "h-[32px]",
4031
4034
  onChange: (val) => {
4032
4035
  handleChangeCashData("textValue", val ?? "");
4033
4036
  setAddError((p) => ({ ...p, textValue: void 0 }));
4034
4037
  },
4035
- placeholder: `\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4038
+ placeholder: type === "TARGET" ? "\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4036
4039
  required: true,
4037
4040
  error: addError.textValue
4038
4041
  }
@@ -4041,7 +4044,7 @@ function Indicator({
4041
4044
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4042
4045
  InputFieldNumber,
4043
4046
  {
4044
- label: `\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4047
+ label: type === "TARGET" ? "\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4045
4048
  value: cacheData.numberValue ?? 0,
4046
4049
  className: "h-[32px]",
4047
4050
  onChange: (val) => {
@@ -4049,7 +4052,7 @@ function Indicator({
4049
4052
  setAddError((p) => ({ ...p, numberValue: void 0 }));
4050
4053
  },
4051
4054
  min: 0,
4052
- placeholder: `\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4055
+ placeholder: type === "TARGET" ? "\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
4053
4056
  required: true,
4054
4057
  error: addError.numberValue
4055
4058
  }
@@ -4070,14 +4073,7 @@ function Indicator({
4070
4073
  }
4071
4074
  )
4072
4075
  ] }),
4073
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4074
- import_icons_react12.IconCirclePlus,
4075
- {
4076
- onClick: handleAddIndicator,
4077
- className: "mt-8 cursor-pointer",
4078
- size: 32
4079
- }
4080
- )
4076
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_icons_react12.IconCirclePlus, { onClick: handleAddIndicator, className: "mt-8 cursor-pointer", size: 32 })
4081
4077
  ]
4082
4078
  }
4083
4079
  ),
@@ -4146,20 +4142,8 @@ function Indicator({
4146
4142
  onClick: () => handleConfirmEditIndicator(index)
4147
4143
  }
4148
4144
  ),
4149
- /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4150
- import_icons_react12.IconX,
4151
- {
4152
- className: "cursor-pointer text-red-600",
4153
- onClick: handleCancelEditIndicator
4154
- }
4155
- )
4156
- ] }) : void 0 : canEdit && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4157
- import_icons_react12.IconPencil,
4158
- {
4159
- className: "cursor-pointer",
4160
- onClick: () => handleEditIndicator(index)
4161
- }
4162
- ) }),
4145
+ /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_icons_react12.IconX, { className: "cursor-pointer text-red-600", onClick: handleCancelEditIndicator })
4146
+ ] }) : void 0 : canEdit && /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_icons_react12.IconPencil, { className: "cursor-pointer", onClick: () => handleEditIndicator(index) }) }),
4163
4147
  /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "body-1 mt-2 cursor-pointer", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
4164
4148
  import_icons_react12.IconTrash,
4165
4149
  {
@@ -5260,6 +5244,116 @@ var GanttChart = ({ data, width, height }) => {
5260
5244
  }
5261
5245
  );
5262
5246
  };
5247
+
5248
+ // src/CardKPI/CardKPI/CardKPI.tsx
5249
+ var import_icons_react15 = require("@tabler/icons-react");
5250
+ var import_react25 = require("react");
5251
+ var import_jsx_runtime49 = require("react/jsx-runtime");
5252
+ function KPIRow({ item }) {
5253
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
5254
+ "div",
5255
+ {
5256
+ className: `w-full grid body-3 py-2 items-center pl-2 ${item.inputType === "NUMBER" ? "grid-cols-[1fr_100px_50px]" : "grid-cols-[1fr_50px]"}`,
5257
+ children: [
5258
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "line-clamp-2", children: item.textValue }),
5259
+ item.inputType === "NUMBER" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "flex", children: `${item.currentValue}/${item.numberValue} ${item.unit}` }),
5260
+ item.inputType === "NUMBER" ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ProgressBar, { percent: Math.floor(item.currentValue * 100 / (item.numberValue ?? 1)), type: "circle", checkpoints: [0] }) }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_jsx_runtime49.Fragment, { children: item.currentValue !== 0 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_icons_react15.IconCheckbox, { className: "text-green-500 flex justify-center w-full", size: 30 }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_icons_react15.IconSquare, { className: "text-gray-200 flex justify-center w-full", size: 30 }) })
5261
+ ]
5262
+ }
5263
+ );
5264
+ }
5265
+ function CardKPI({
5266
+ dataItem,
5267
+ overallPercent,
5268
+ onDetailsClick,
5269
+ indicator,
5270
+ projectId
5271
+ }) {
5272
+ const [isOpen, setIsOpen] = (0, import_react25.useState)(false);
5273
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
5274
+ "div",
5275
+ {
5276
+ className: `border-10 p-4 rounded-md w-[420px] h-[450px] relative`,
5277
+ style: { borderColor: dataItem.projectColor },
5278
+ children: [
5279
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "grid grid-cols-[1fr_70px] justify-between items-center", children: [
5280
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "line-clamp-2 subtitle-2 ", children: dataItem.name }),
5281
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5282
+ "button",
5283
+ {
5284
+ type: "button",
5285
+ className: "underline hover:text-primary-800 body-3 cursor-pointer ",
5286
+ onClick: () => onDetailsClick(projectId),
5287
+ children: "\u0E23\u0E32\u0E22\u0E25\u0E30\u0E40\u0E2D\u0E35\u0E22\u0E14"
5288
+ }
5289
+ ) })
5290
+ ] }),
5291
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "my-2 body-1", children: [
5292
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "translate-y-2", children: "\u0E23\u0E49\u0E2D\u0E22\u0E25\u0E30\u0E02\u0E2D\u0E07\u0E01\u0E34\u0E08\u0E01\u0E23\u0E23\u0E21" }),
5293
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ProgressBar, { percent: overallPercent, type: "line", checkpoints: [0] })
5294
+ ] }),
5295
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "border-b", children: [
5296
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "body-2 ", children: "\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C" }),
5297
+ indicator.filter((ind) => ind.indicatorType === "TARGET").map((item, index) => {
5298
+ if (index === 2) return;
5299
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(KPIRow, { item });
5300
+ })
5301
+ ] }),
5302
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "pt-2", children: [
5303
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "body-2 ", children: "\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" }),
5304
+ indicator.filter((ind) => ind.indicatorType === "OUTPUT").map((item, index) => {
5305
+ if (index === 2) return;
5306
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(KPIRow, { item });
5307
+ })
5308
+ ] }),
5309
+ indicator.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "text-sm text-gray-500 italic", children: "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E42\u0E04\u0E23\u0E07\u0E01\u0E32\u0E23" }),
5310
+ indicator.filter((item) => item.indicatorType === "TARGET").length > 2 || indicator.filter((item) => item.indicatorType === "OUTPUT").length > 2 ? /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "bottom-0 right-1/2 absolute text-gray-300", children: /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5311
+ import_icons_react15.IconDots,
5312
+ {
5313
+ className: "cursor-pointer",
5314
+ onClick: () => setIsOpen(true)
5315
+ }
5316
+ ) }) : void 0,
5317
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5318
+ AntDModal,
5319
+ {
5320
+ isOpen,
5321
+ onCancel: () => setIsOpen(false),
5322
+ width: 600,
5323
+ children: /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "mt-10", children: [
5324
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "grid grid-cols-[1fr_100px] justify-between items-center subtitle-2 ", children: [
5325
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "font-medium line-clamp-2", children: dataItem.name }),
5326
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
5327
+ "button",
5328
+ {
5329
+ type: "button",
5330
+ className: "underline hover:text-primary-800 body-3 cursor-pointer",
5331
+ onClick: () => onDetailsClick(dataItem.projectId),
5332
+ children: "\u0E23\u0E32\u0E22\u0E25\u0E30\u0E40\u0E2D\u0E35\u0E22\u0E14"
5333
+ }
5334
+ )
5335
+ ] }),
5336
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "p-4", children: [
5337
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { children: [
5338
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "body-1 border-b", children: "\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" }),
5339
+ indicator.filter((ind) => ind.indicatorType === "TARGET").map((item, index) => {
5340
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(KPIRow, { item });
5341
+ })
5342
+ ] }),
5343
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { children: [
5344
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "body-1 border-b", children: "\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" }),
5345
+ indicator.filter((ind) => ind.indicatorType === "OUTPUT").map((item, index) => {
5346
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(KPIRow, { item });
5347
+ })
5348
+ ] })
5349
+ ] })
5350
+ ] })
5351
+ }
5352
+ )
5353
+ ]
5354
+ }
5355
+ );
5356
+ }
5263
5357
  // Annotate the CommonJS export names for ESM import in node:
5264
5358
  0 && (module.exports = {
5265
5359
  AntDModal,
@@ -5267,6 +5361,7 @@ var GanttChart = ({ data, width, height }) => {
5267
5361
  BarChart,
5268
5362
  Breadcrumbs,
5269
5363
  Calendar,
5364
+ CardKPI,
5270
5365
  Checkbox,
5271
5366
  CheckboxGroup,
5272
5367
  ColorPalettePickerBasic,
package/dist/index.mjs CHANGED
@@ -358,7 +358,8 @@ function PrimaryButton({
358
358
  colorPrimary = "#4e61f6",
359
359
  colorPrimaryHover = "#8895f9",
360
360
  textColor = "#ffffff",
361
- icon
361
+ icon,
362
+ className
362
363
  }) {
363
364
  const textClass = size === "large" ? "body-1" : "body-3";
364
365
  return /* @__PURE__ */ jsx(
@@ -377,7 +378,7 @@ function PrimaryButton({
377
378
  size,
378
379
  onClick,
379
380
  type: "primary",
380
- className: textClass,
381
+ className: `${textClass} ${className ?? ""}`,
381
382
  disabled,
382
383
  icon,
383
384
  iconPosition: iconPlacement,
@@ -401,7 +402,8 @@ function SecondaryButton({
401
402
  defaultHoverBorderColor = "#7181f8",
402
403
  defaultHoverColor = "#7181f8",
403
404
  textColor = "rgba(0,0,0,0.88)",
404
- icon
405
+ icon,
406
+ className
405
407
  }) {
406
408
  const textClass = size === "large" ? "body-1" : "body-3";
407
409
  return /* @__PURE__ */ jsx2(
@@ -425,7 +427,7 @@ function SecondaryButton({
425
427
  size,
426
428
  onClick,
427
429
  type: "default",
428
- className: textClass,
430
+ className: `${textClass} ${className ?? ""}`,
429
431
  disabled,
430
432
  icon,
431
433
  iconPosition: iconPlacement,
@@ -483,7 +485,8 @@ function TertiaryButton({
483
485
  colorPrimary = "#000",
484
486
  colorPrimaryHover = "#4d5461",
485
487
  textColor = "white",
486
- icon
488
+ icon,
489
+ className
487
490
  }) {
488
491
  const textClass = size === "large" ? "body-1" : "body-3";
489
492
  return /* @__PURE__ */ jsx5(
@@ -502,7 +505,7 @@ function TertiaryButton({
502
505
  size,
503
506
  onClick,
504
507
  type: "primary",
505
- className: textClass,
508
+ className: `${textClass} ${className ?? ""}`,
506
509
  disabled,
507
510
  icon,
508
511
  iconPosition: iconPlacement,
@@ -1274,8 +1277,26 @@ function InputFieldNumber({
1274
1277
  size,
1275
1278
  changeOnWheel,
1276
1279
  formatter,
1277
- parser
1280
+ parser,
1281
+ decimal = false,
1282
+ decimalScale = 2,
1283
+ format: format5 = "number"
1278
1284
  }) {
1285
+ const safeScale = Math.max(0, Math.min(decimalScale, 10));
1286
+ const addComma = (s) => s.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1287
+ const defaultFormatter = (v) => {
1288
+ if (v === void 0 || v === null || v === "") return "";
1289
+ const num = Number(v);
1290
+ if (Number.isNaN(num)) return "";
1291
+ const base = !decimal ? Math.trunc(num).toString() : num.toFixed(safeScale);
1292
+ return format5 === "currency" ? addComma(base) : base;
1293
+ };
1294
+ const defaultParser = (v) => {
1295
+ if (!v) return "";
1296
+ const raw = v.replace(/,/g, "").replace(/\s/g, "");
1297
+ if (!decimal) return raw.split(".")[0];
1298
+ return raw.replace(/[^\d.]/g, "");
1299
+ };
1279
1300
  return /* @__PURE__ */ jsx23(
1280
1301
  ConfigProvider7,
1281
1302
  {
@@ -1306,17 +1327,9 @@ function InputFieldNumber({
1306
1327
  controls,
1307
1328
  size,
1308
1329
  changeOnWheel,
1309
- formatter: formatter ?? ((value2) => {
1310
- if (value2 === void 0 || value2 === null || value2 === "")
1311
- return "";
1312
- const num = Number(value2);
1313
- if (isNaN(num)) return "";
1314
- return num.toFixed(2).replace(/\B(?=(\d{3})+(?!\d))/g, ",");
1315
- }),
1316
- parser: parser ?? ((value2) => {
1317
- if (!value2) return "";
1318
- return value2.replace(/,/g, "");
1319
- })
1330
+ formatter: formatter ?? defaultFormatter,
1331
+ parser: parser ?? defaultParser,
1332
+ precision: decimal ? safeScale : 0
1320
1333
  }
1321
1334
  ),
1322
1335
  error && /* @__PURE__ */ jsx23("p", { className: "text-red-500 caption-1", children: error })
@@ -3810,13 +3823,7 @@ function AntDModal({ children, isOpen, width, onCancel }) {
3810
3823
  }
3811
3824
 
3812
3825
  // src/Indicator/Indicator/Indicator.tsx
3813
- import {
3814
- IconCheck as IconCheck3,
3815
- IconCirclePlus as IconCirclePlus2,
3816
- IconPencil as IconPencil2,
3817
- IconTrash as IconTrash4,
3818
- IconX as IconX3
3819
- } from "@tabler/icons-react";
3826
+ import { IconCheck as IconCheck3, IconCirclePlus as IconCirclePlus2, IconPencil as IconPencil2, IconTrash as IconTrash4, IconX as IconX3 } from "@tabler/icons-react";
3820
3827
  import { useState as useState16 } from "react";
3821
3828
  import { Input as Input4 } from "antd";
3822
3829
  import { Fragment as Fragment7, jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
@@ -3893,7 +3900,6 @@ function Indicator({
3893
3900
  ...prev,
3894
3901
  [key]: value
3895
3902
  }));
3896
- console.log(cacheData);
3897
3903
  };
3898
3904
  const handleClick = (active) => {
3899
3905
  handleChangeCashData("inputType", active);
@@ -3945,7 +3951,6 @@ function Indicator({
3945
3951
  ...prev,
3946
3952
  [name]: value
3947
3953
  }));
3948
- console.log(cacheEditData);
3949
3954
  };
3950
3955
  return /* @__PURE__ */ jsxs32("div", { className: "w-full", children: [
3951
3956
  /* @__PURE__ */ jsxs32(
@@ -3953,27 +3958,18 @@ function Indicator({
3953
3958
  {
3954
3959
  className: `space-x-2 grid ${valueSwitch === "TEXT" ? `grid-cols-[140px_1fr_50px]` : `grid-cols-[140px_1fr_200px_200px_50px]`} items-start`,
3955
3960
  children: [
3956
- /* @__PURE__ */ jsx41(
3957
- SwitchSelect,
3958
- {
3959
- option,
3960
- onClick: handleClick,
3961
- value: valueSwitch,
3962
- label: "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17",
3963
- required: true
3964
- }
3965
- ),
3961
+ /* @__PURE__ */ jsx41(SwitchSelect, { option, onClick: handleClick, value: valueSwitch, label: "\u0E1B\u0E23\u0E30\u0E40\u0E20\u0E17", required: true }),
3966
3962
  /* @__PURE__ */ jsx41(
3967
3963
  InputField,
3968
3964
  {
3969
- label: `\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3965
+ label: type === "TARGET" ? "\u0E0A\u0E37\u0E48\u0E2D\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3970
3966
  value: cacheData.textValue,
3971
3967
  className: "h-[32px]",
3972
3968
  onChange: (val) => {
3973
3969
  handleChangeCashData("textValue", val ?? "");
3974
3970
  setAddError((p) => ({ ...p, textValue: void 0 }));
3975
3971
  },
3976
- placeholder: `\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3972
+ placeholder: type === "TARGET" ? "\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E23\u0E30\u0E1A\u0E38\u0E0A\u0E37\u0E48\u0E2D\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3977
3973
  required: true,
3978
3974
  error: addError.textValue
3979
3975
  }
@@ -3982,7 +3978,7 @@ function Indicator({
3982
3978
  /* @__PURE__ */ jsx41(
3983
3979
  InputFieldNumber,
3984
3980
  {
3985
- label: `\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3981
+ label: type === "TARGET" ? "\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3986
3982
  value: cacheData.numberValue ?? 0,
3987
3983
  className: "h-[32px]",
3988
3984
  onChange: (val) => {
@@ -3990,7 +3986,7 @@ function Indicator({
3990
3986
  setAddError((p) => ({ ...p, numberValue: void 0 }));
3991
3987
  },
3992
3988
  min: 0,
3993
- placeholder: `\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3989
+ placeholder: type === "TARGET" ? "\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" : `\u0E23\u0E30\u0E1A\u0E38\u0E04\u0E48\u0E32\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22${type === "OUTPUT" ? "\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" : "\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C"}`,
3994
3990
  required: true,
3995
3991
  error: addError.numberValue
3996
3992
  }
@@ -4011,14 +4007,7 @@ function Indicator({
4011
4007
  }
4012
4008
  )
4013
4009
  ] }),
4014
- /* @__PURE__ */ jsx41(
4015
- IconCirclePlus2,
4016
- {
4017
- onClick: handleAddIndicator,
4018
- className: "mt-8 cursor-pointer",
4019
- size: 32
4020
- }
4021
- )
4010
+ /* @__PURE__ */ jsx41(IconCirclePlus2, { onClick: handleAddIndicator, className: "mt-8 cursor-pointer", size: 32 })
4022
4011
  ]
4023
4012
  }
4024
4013
  ),
@@ -4087,20 +4076,8 @@ function Indicator({
4087
4076
  onClick: () => handleConfirmEditIndicator(index)
4088
4077
  }
4089
4078
  ),
4090
- /* @__PURE__ */ jsx41(
4091
- IconX3,
4092
- {
4093
- className: "cursor-pointer text-red-600",
4094
- onClick: handleCancelEditIndicator
4095
- }
4096
- )
4097
- ] }) : void 0 : canEdit && /* @__PURE__ */ jsx41(
4098
- IconPencil2,
4099
- {
4100
- className: "cursor-pointer",
4101
- onClick: () => handleEditIndicator(index)
4102
- }
4103
- ) }),
4079
+ /* @__PURE__ */ jsx41(IconX3, { className: "cursor-pointer text-red-600", onClick: handleCancelEditIndicator })
4080
+ ] }) : void 0 : canEdit && /* @__PURE__ */ jsx41(IconPencil2, { className: "cursor-pointer", onClick: () => handleEditIndicator(index) }) }),
4104
4081
  /* @__PURE__ */ jsx41("div", { className: "body-1 mt-2 cursor-pointer", children: /* @__PURE__ */ jsx41(
4105
4082
  IconTrash4,
4106
4083
  {
@@ -5210,12 +5187,123 @@ var GanttChart = ({ data, width, height }) => {
5210
5187
  }
5211
5188
  );
5212
5189
  };
5190
+
5191
+ // src/CardKPI/CardKPI/CardKPI.tsx
5192
+ import { IconCheckbox, IconDots, IconSquare } from "@tabler/icons-react";
5193
+ import { useState as useState21 } from "react";
5194
+ import { Fragment as Fragment9, jsx as jsx49, jsxs as jsxs40 } from "react/jsx-runtime";
5195
+ function KPIRow({ item }) {
5196
+ return /* @__PURE__ */ jsxs40(
5197
+ "div",
5198
+ {
5199
+ className: `w-full grid body-3 py-2 items-center pl-2 ${item.inputType === "NUMBER" ? "grid-cols-[1fr_100px_50px]" : "grid-cols-[1fr_50px]"}`,
5200
+ children: [
5201
+ /* @__PURE__ */ jsx49("div", { className: "line-clamp-2", children: item.textValue }),
5202
+ item.inputType === "NUMBER" && /* @__PURE__ */ jsx49("span", { className: "flex", children: `${item.currentValue}/${item.numberValue} ${item.unit}` }),
5203
+ item.inputType === "NUMBER" ? /* @__PURE__ */ jsx49("div", { className: "flex", children: /* @__PURE__ */ jsx49(ProgressBar, { percent: Math.floor(item.currentValue * 100 / (item.numberValue ?? 1)), type: "circle", checkpoints: [0] }) }) : /* @__PURE__ */ jsx49(Fragment9, { children: item.currentValue !== 0 ? /* @__PURE__ */ jsx49(IconCheckbox, { className: "text-green-500 flex justify-center w-full", size: 30 }) : /* @__PURE__ */ jsx49(IconSquare, { className: "text-gray-200 flex justify-center w-full", size: 30 }) })
5204
+ ]
5205
+ }
5206
+ );
5207
+ }
5208
+ function CardKPI({
5209
+ dataItem,
5210
+ overallPercent,
5211
+ onDetailsClick,
5212
+ indicator,
5213
+ projectId
5214
+ }) {
5215
+ const [isOpen, setIsOpen] = useState21(false);
5216
+ return /* @__PURE__ */ jsxs40(
5217
+ "div",
5218
+ {
5219
+ className: `border-10 p-4 rounded-md w-[420px] h-[450px] relative`,
5220
+ style: { borderColor: dataItem.projectColor },
5221
+ children: [
5222
+ /* @__PURE__ */ jsxs40("div", { className: "grid grid-cols-[1fr_70px] justify-between items-center", children: [
5223
+ /* @__PURE__ */ jsx49("div", { className: "line-clamp-2 subtitle-2 ", children: dataItem.name }),
5224
+ /* @__PURE__ */ jsx49("div", { className: "flex justify-end", children: /* @__PURE__ */ jsx49(
5225
+ "button",
5226
+ {
5227
+ type: "button",
5228
+ className: "underline hover:text-primary-800 body-3 cursor-pointer ",
5229
+ onClick: () => onDetailsClick(projectId),
5230
+ children: "\u0E23\u0E32\u0E22\u0E25\u0E30\u0E40\u0E2D\u0E35\u0E22\u0E14"
5231
+ }
5232
+ ) })
5233
+ ] }),
5234
+ /* @__PURE__ */ jsxs40("div", { className: "my-2 body-1", children: [
5235
+ /* @__PURE__ */ jsx49("div", { className: "translate-y-2", children: "\u0E23\u0E49\u0E2D\u0E22\u0E25\u0E30\u0E02\u0E2D\u0E07\u0E01\u0E34\u0E08\u0E01\u0E23\u0E23\u0E21" }),
5236
+ /* @__PURE__ */ jsx49(ProgressBar, { percent: overallPercent, type: "line", checkpoints: [0] })
5237
+ ] }),
5238
+ /* @__PURE__ */ jsxs40("div", { className: "border-b", children: [
5239
+ /* @__PURE__ */ jsx49("span", { className: "body-2 ", children: "\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14\u0E1C\u0E25\u0E25\u0E31\u0E1E\u0E18\u0E4C" }),
5240
+ indicator.filter((ind) => ind.indicatorType === "TARGET").map((item, index) => {
5241
+ if (index === 2) return;
5242
+ return /* @__PURE__ */ jsx49(KPIRow, { item });
5243
+ })
5244
+ ] }),
5245
+ /* @__PURE__ */ jsxs40("div", { className: "pt-2", children: [
5246
+ /* @__PURE__ */ jsx49("span", { className: "body-2 ", children: "\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" }),
5247
+ indicator.filter((ind) => ind.indicatorType === "OUTPUT").map((item, index) => {
5248
+ if (index === 2) return;
5249
+ return /* @__PURE__ */ jsx49(KPIRow, { item });
5250
+ })
5251
+ ] }),
5252
+ indicator.length === 0 && /* @__PURE__ */ jsx49("div", { className: "text-sm text-gray-500 italic", children: "\u0E44\u0E21\u0E48\u0E21\u0E35\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E42\u0E04\u0E23\u0E07\u0E01\u0E32\u0E23" }),
5253
+ indicator.filter((item) => item.indicatorType === "TARGET").length > 2 || indicator.filter((item) => item.indicatorType === "OUTPUT").length > 2 ? /* @__PURE__ */ jsx49("div", { className: "bottom-0 right-1/2 absolute text-gray-300", children: /* @__PURE__ */ jsx49(
5254
+ IconDots,
5255
+ {
5256
+ className: "cursor-pointer",
5257
+ onClick: () => setIsOpen(true)
5258
+ }
5259
+ ) }) : void 0,
5260
+ /* @__PURE__ */ jsx49(
5261
+ AntDModal,
5262
+ {
5263
+ isOpen,
5264
+ onCancel: () => setIsOpen(false),
5265
+ width: 600,
5266
+ children: /* @__PURE__ */ jsxs40("div", { className: "mt-10", children: [
5267
+ /* @__PURE__ */ jsxs40("div", { className: "grid grid-cols-[1fr_100px] justify-between items-center subtitle-2 ", children: [
5268
+ /* @__PURE__ */ jsx49("div", { className: "font-medium line-clamp-2", children: dataItem.name }),
5269
+ /* @__PURE__ */ jsx49(
5270
+ "button",
5271
+ {
5272
+ type: "button",
5273
+ className: "underline hover:text-primary-800 body-3 cursor-pointer",
5274
+ onClick: () => onDetailsClick(dataItem.projectId),
5275
+ children: "\u0E23\u0E32\u0E22\u0E25\u0E30\u0E40\u0E2D\u0E35\u0E22\u0E14"
5276
+ }
5277
+ )
5278
+ ] }),
5279
+ /* @__PURE__ */ jsxs40("div", { className: "p-4", children: [
5280
+ /* @__PURE__ */ jsxs40("div", { children: [
5281
+ /* @__PURE__ */ jsx49("span", { className: "body-1 border-b", children: "\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" }),
5282
+ indicator.filter((ind) => ind.indicatorType === "TARGET").map((item, index) => {
5283
+ return /* @__PURE__ */ jsx49(KPIRow, { item });
5284
+ })
5285
+ ] }),
5286
+ /* @__PURE__ */ jsxs40("div", { children: [
5287
+ /* @__PURE__ */ jsx49("span", { className: "body-1 border-b", children: "\u0E15\u0E31\u0E27\u0E0A\u0E35\u0E49\u0E27\u0E31\u0E14\u0E1C\u0E25\u0E1C\u0E25\u0E34\u0E15" }),
5288
+ indicator.filter((ind) => ind.indicatorType === "OUTPUT").map((item, index) => {
5289
+ return /* @__PURE__ */ jsx49(KPIRow, { item });
5290
+ })
5291
+ ] })
5292
+ ] })
5293
+ ] })
5294
+ }
5295
+ )
5296
+ ]
5297
+ }
5298
+ );
5299
+ }
5213
5300
  export {
5214
5301
  AntDModal,
5215
5302
  AntDataTable,
5216
5303
  BarChart,
5217
5304
  Breadcrumbs,
5218
5305
  Calendar,
5306
+ CardKPI,
5219
5307
  Checkbox,
5220
5308
  CheckboxGroup,
5221
5309
  ColorPalettePickerBasic,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esic-lab/data-core-ui",
3
- "version": "0.0.62",
3
+ "version": "0.0.64",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.mjs",
6
6
  "types": "dist/index.d.ts",