@esic-lab/data-core-ui 0.0.64 → 0.0.66
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/assets/STO-logo.svg +92 -92
- package/dist/index.css +49 -2
- package/dist/index.d.mts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +185 -178
- package/dist/index.mjs +190 -178
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -555,9 +555,9 @@ function Checkbox({ label, checked, onChange, disabled }) {
|
|
|
555
555
|
/* @__PURE__ */ jsx7(
|
|
556
556
|
"div",
|
|
557
557
|
{
|
|
558
|
-
className: `flex justify-center items-center border-[1px] border-
|
|
559
|
-
${checked ? "bg-
|
|
560
|
-
${disabled ? "pointer-events-none" : ""}`,
|
|
558
|
+
className: `flex justify-center items-center border-[1px] border-gray-400 w-[24px] h-[24px] rounded-[8px] transition-colors duration-100
|
|
559
|
+
${checked ? "bg-primary-500 text-white border-primary-500" : "bg-white text-black"}
|
|
560
|
+
${disabled ? "pointer-events-none !bg-gray-300" : ""}`,
|
|
561
561
|
children: /* @__PURE__ */ jsx7(
|
|
562
562
|
"span",
|
|
563
563
|
{
|
|
@@ -3823,7 +3823,7 @@ function AntDModal({ children, isOpen, width, onCancel }) {
|
|
|
3823
3823
|
}
|
|
3824
3824
|
|
|
3825
3825
|
// src/Indicator/Indicator/Indicator.tsx
|
|
3826
|
-
import { IconCheck as IconCheck3, IconCirclePlus as IconCirclePlus2,
|
|
3826
|
+
import { IconCheck as IconCheck3, IconCirclePlus as IconCirclePlus2, IconTrash as IconTrash4, IconX as IconX3 } from "@tabler/icons-react";
|
|
3827
3827
|
import { useState as useState16 } from "react";
|
|
3828
3828
|
import { Input as Input4 } from "antd";
|
|
3829
3829
|
import { Fragment as Fragment7, jsx as jsx41, jsxs as jsxs32 } from "react/jsx-runtime";
|
|
@@ -4077,7 +4077,7 @@ function Indicator({
|
|
|
4077
4077
|
}
|
|
4078
4078
|
),
|
|
4079
4079
|
/* @__PURE__ */ jsx41(IconX3, { className: "cursor-pointer text-red-600", onClick: handleCancelEditIndicator })
|
|
4080
|
-
] }) : void 0 :
|
|
4080
|
+
] }) : void 0 : false }),
|
|
4081
4081
|
/* @__PURE__ */ jsx41("div", { className: "body-1 mt-2 cursor-pointer", children: /* @__PURE__ */ jsx41(
|
|
4082
4082
|
IconTrash4,
|
|
4083
4083
|
{
|
|
@@ -4733,14 +4733,21 @@ import { useEffect as useEffect11, useRef as useRef10, useState as useState20 }
|
|
|
4733
4733
|
import * as d33 from "d3";
|
|
4734
4734
|
import {
|
|
4735
4735
|
format as format4,
|
|
4736
|
-
getWeek,
|
|
4737
4736
|
eachWeekOfInterval,
|
|
4738
4737
|
startOfYear,
|
|
4739
4738
|
endOfYear,
|
|
4740
4739
|
startOfDay,
|
|
4741
4740
|
addDays,
|
|
4742
|
-
eachHourOfInterval
|
|
4741
|
+
eachHourOfInterval,
|
|
4742
|
+
getQuarter
|
|
4743
4743
|
} from "date-fns";
|
|
4744
|
+
import { th } from "date-fns/locale";
|
|
4745
|
+
import {
|
|
4746
|
+
IconCircleX,
|
|
4747
|
+
IconClockExclamation,
|
|
4748
|
+
IconHourglassEmpty,
|
|
4749
|
+
IconRosetteDiscountCheck
|
|
4750
|
+
} from "@tabler/icons-react";
|
|
4744
4751
|
import { jsx as jsx48, jsxs as jsxs39 } from "react/jsx-runtime";
|
|
4745
4752
|
var LAYOUT = {
|
|
4746
4753
|
barHeight: 40,
|
|
@@ -4758,31 +4765,33 @@ var VIEW_MODE_SCALE = {
|
|
|
4758
4765
|
week: 10
|
|
4759
4766
|
};
|
|
4760
4767
|
var STATUS_META = {
|
|
4761
|
-
|
|
4762
|
-
|
|
4763
|
-
|
|
4764
|
-
}
|
|
4765
|
-
|
|
4766
|
-
|
|
4767
|
-
|
|
4768
|
-
|
|
4769
|
-
|
|
4770
|
-
|
|
4771
|
-
|
|
4772
|
-
|
|
4773
|
-
|
|
4774
|
-
|
|
4775
|
-
|
|
4776
|
-
|
|
4777
|
-
|
|
4768
|
+
IN_PROGRESS: {
|
|
4769
|
+
color: "#FFC654",
|
|
4770
|
+
label: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23",
|
|
4771
|
+
icon: /* @__PURE__ */ jsx48(IconHourglassEmpty, { className: "text-[#FFC654]" })
|
|
4772
|
+
},
|
|
4773
|
+
CANCEL: {
|
|
4774
|
+
color: "#D2D5DB",
|
|
4775
|
+
label: "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",
|
|
4776
|
+
icon: /* @__PURE__ */ jsx48(IconCircleX, { className: "text-[#D2D5DB]" })
|
|
4777
|
+
},
|
|
4778
|
+
SUCCESS: {
|
|
4779
|
+
color: "#81CF92",
|
|
4780
|
+
label: "\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27\u0E40\u0E2A\u0E23\u0E47\u0E08",
|
|
4781
|
+
icon: /* @__PURE__ */ jsx48(IconRosetteDiscountCheck, { className: "text-[#81CF92]" })
|
|
4782
|
+
},
|
|
4783
|
+
COMPLETE: {
|
|
4784
|
+
color: "#81CF92",
|
|
4785
|
+
label: "\u0E40\u0E2A\u0E23\u0E47\u0E08\u0E2A\u0E34\u0E49\u0E19",
|
|
4786
|
+
icon: /* @__PURE__ */ jsx48(IconRosetteDiscountCheck, { className: "text-[#81CF92]" })
|
|
4787
|
+
},
|
|
4788
|
+
DELAY: {
|
|
4789
|
+
color: "#F4827E",
|
|
4790
|
+
label: "\u0E25\u0E48\u0E32\u0E0A\u0E49\u0E32",
|
|
4791
|
+
icon: /* @__PURE__ */ jsx48(IconClockExclamation, { className: "text-[#F4827E]" })
|
|
4792
|
+
}
|
|
4778
4793
|
};
|
|
4779
|
-
var THAI_DAYS = ["\u0E2D\u0E32.", "\u0E08.", "\u0E2D.", "\u0E1E.", "\u0E1E\u0E24.", "\u0E28.", "\u0E2A."];
|
|
4780
4794
|
var roundedRectPath = (x, y, width, height, radius) => `M${x + radius},${y} H${x + width} V${y + height} H${x + radius} A${radius},${radius},0,0,1,${x},${y + height - radius} V${y + radius} A${radius},${radius},0,0,1,${x + radius},${y}`;
|
|
4781
|
-
var formatThaiMonth = (date) => {
|
|
4782
|
-
const monthName = format4(date, "MMMM");
|
|
4783
|
-
return THAI_MONTHS[monthName] || monthName;
|
|
4784
|
-
};
|
|
4785
|
-
var formatThaiDate = (date) => date ? date.toLocaleDateString("th-TH", { day: "numeric", month: "short" }) : "-";
|
|
4786
4795
|
var isDateOnlyValue = (dt) => {
|
|
4787
4796
|
const localZero = dt.getHours() === 0 && dt.getMinutes() === 0 && dt.getSeconds() === 0 && dt.getMilliseconds() === 0;
|
|
4788
4797
|
const utcZero = dt.getUTCHours() === 0 && dt.getUTCMinutes() === 0 && dt.getUTCSeconds() === 0 && dt.getUTCMilliseconds() === 0;
|
|
@@ -4812,60 +4821,46 @@ var getAdjustedEnd = (d) => {
|
|
|
4812
4821
|
}
|
|
4813
4822
|
return startOfDay(/* @__PURE__ */ new Date());
|
|
4814
4823
|
};
|
|
4815
|
-
var getStatusColor = (status2) => STATUS_META[status2]?.color ?? STATUS_META.
|
|
4816
|
-
var getStatusLabel = (status2) => STATUS_META[status2]?.label ?? STATUS_META.
|
|
4817
|
-
var ProjectRow = ({ element, barHeight, barSpacing }) => {
|
|
4824
|
+
var getStatusColor = (status2) => STATUS_META[status2]?.color ?? STATUS_META.IN_PROGRESS.color;
|
|
4825
|
+
var getStatusLabel = (status2) => STATUS_META[status2]?.label ?? STATUS_META.IN_PROGRESS.label;
|
|
4826
|
+
var ProjectRow = ({ element, barHeight, barSpacing, mode }) => {
|
|
4818
4827
|
const safeStartDate = element.startDate instanceof Date ? element.startDate : null;
|
|
4819
4828
|
const safeEndDate = element.endDate instanceof Date ? element.endDate : null;
|
|
4820
4829
|
const safeStatus = element.status || "pending";
|
|
4821
4830
|
const statusColor = getStatusColor(safeStatus);
|
|
4822
4831
|
const statusLabel = getStatusLabel(safeStatus);
|
|
4832
|
+
const statusIcon = STATUS_META[safeStatus]?.icon;
|
|
4833
|
+
const toBuddhistDate = (d) => new Date(d.getFullYear() + 543, d.getMonth(), d.getDate());
|
|
4823
4834
|
return /* @__PURE__ */ jsxs39(
|
|
4824
4835
|
"div",
|
|
4825
4836
|
{
|
|
4826
4837
|
style: {
|
|
4827
|
-
display: "grid",
|
|
4828
|
-
gridTemplateColumns: "200px 100px 100px 100px",
|
|
4829
4838
|
alignItems: "center",
|
|
4830
4839
|
height: `${barHeight}px`,
|
|
4831
|
-
|
|
4832
|
-
|
|
4840
|
+
marginBottom: `${barSpacing}px`,
|
|
4841
|
+
fontSize: "12px"
|
|
4833
4842
|
},
|
|
4843
|
+
className: "body-1 grid grid-cols-[1fr_100px_130px] px-8 gap-2",
|
|
4834
4844
|
children: [
|
|
4835
|
-
/* @__PURE__ */ jsxs39("div", {
|
|
4836
|
-
/* @__PURE__ */ jsx48(
|
|
4837
|
-
"
|
|
4845
|
+
/* @__PURE__ */ jsxs39("div", { className: `grid ${mode === "project" ? "grid-cols-[10px_1fr]" : "grid-cols-[1fr]"} items-center gap-2`, children: [
|
|
4846
|
+
mode === "project" && /* @__PURE__ */ jsx48(
|
|
4847
|
+
"div",
|
|
4838
4848
|
{
|
|
4839
4849
|
style: {
|
|
4840
|
-
|
|
4841
|
-
|
|
4842
|
-
|
|
4843
|
-
borderRadius: "50%",
|
|
4844
|
-
backgroundColor: element.color || "#999"
|
|
4845
|
-
}
|
|
4850
|
+
backgroundColor: element.color || "#E9E9E9"
|
|
4851
|
+
},
|
|
4852
|
+
className: "w-[10px] h-[10px] rounded-full"
|
|
4846
4853
|
}
|
|
4847
4854
|
),
|
|
4848
|
-
/* @__PURE__ */ jsx48("
|
|
4855
|
+
/* @__PURE__ */ jsx48("div", { className: "line-clamp-1 break-words text-[#333]", title: element.label, children: element.label })
|
|
4849
4856
|
] }),
|
|
4850
|
-
/* @__PURE__ */ jsx48("div", {
|
|
4851
|
-
|
|
4852
|
-
|
|
4853
|
-
|
|
4854
|
-
|
|
4855
|
-
|
|
4856
|
-
|
|
4857
|
-
minWidth: "100%",
|
|
4858
|
-
padding: "4px 8px",
|
|
4859
|
-
borderRadius: "4px",
|
|
4860
|
-
fontSize: "11px",
|
|
4861
|
-
backgroundColor: statusColor,
|
|
4862
|
-
color: "#000",
|
|
4863
|
-
border: "none",
|
|
4864
|
-
cursor: "pointer"
|
|
4865
|
-
},
|
|
4866
|
-
children: statusLabel
|
|
4867
|
-
}
|
|
4868
|
-
)
|
|
4857
|
+
mode === "project" ? /* @__PURE__ */ jsx48("div", { children: safeEndDate ? format4(toBuddhistDate(safeEndDate), "dd MMM yyyy", { locale: th }) : "-" }) : /* @__PURE__ */ jsx48("div", { children: `Q${getQuarter(
|
|
4858
|
+
safeEndDate ?? /* @__PURE__ */ new Date()
|
|
4859
|
+
)}/${(safeEndDate?.getFullYear() ?? 0) + 543}` }),
|
|
4860
|
+
/* @__PURE__ */ jsxs39("button", { className: "rounded-md subtitile-1 flex gap-2 align-start", children: [
|
|
4861
|
+
statusIcon,
|
|
4862
|
+
statusLabel
|
|
4863
|
+
] })
|
|
4869
4864
|
]
|
|
4870
4865
|
},
|
|
4871
4866
|
element.id
|
|
@@ -4880,42 +4875,52 @@ var RowOverlay = ({ data, barHeight, barSpacing, totalHeaderHeight }) => /* @__P
|
|
|
4880
4875
|
left: 0,
|
|
4881
4876
|
right: 0,
|
|
4882
4877
|
height: `${data.length * (barHeight + barSpacing)}px`,
|
|
4883
|
-
pointerEvents: "none"
|
|
4884
|
-
zIndex: 5
|
|
4878
|
+
pointerEvents: "none"
|
|
4885
4879
|
},
|
|
4886
|
-
children: data.map((
|
|
4880
|
+
children: data.map((_, i) => {
|
|
4887
4881
|
if (i === 0) return null;
|
|
4882
|
+
console.log("rendering row line", i);
|
|
4888
4883
|
const yPos = i * (barHeight + barSpacing) - barSpacing / 2;
|
|
4889
4884
|
return /* @__PURE__ */ jsx48(
|
|
4890
4885
|
"div",
|
|
4891
4886
|
{
|
|
4887
|
+
className: "",
|
|
4892
4888
|
style: {
|
|
4893
4889
|
position: "absolute",
|
|
4894
4890
|
top: `${yPos}px`,
|
|
4895
4891
|
left: 0,
|
|
4896
4892
|
right: 0,
|
|
4897
4893
|
height: "1px",
|
|
4898
|
-
backgroundColor: "#
|
|
4894
|
+
backgroundColor: "#E9E9E9"
|
|
4899
4895
|
}
|
|
4900
4896
|
},
|
|
4901
|
-
`row-line-${
|
|
4897
|
+
`row-line-${i}`
|
|
4902
4898
|
);
|
|
4903
4899
|
})
|
|
4904
4900
|
}
|
|
4905
4901
|
);
|
|
4906
|
-
var GanttChart = ({
|
|
4902
|
+
var GanttChart = ({
|
|
4903
|
+
data,
|
|
4904
|
+
width,
|
|
4905
|
+
mode
|
|
4906
|
+
}) => {
|
|
4907
4907
|
const svgRef = useRef10(null);
|
|
4908
4908
|
const leftPanelRef = useRef10(null);
|
|
4909
4909
|
const dataContainerRef = useRef10(null);
|
|
4910
4910
|
const [viewMode] = useState20("year");
|
|
4911
|
-
const {
|
|
4911
|
+
const {
|
|
4912
|
+
barHeight,
|
|
4913
|
+
barSpacing,
|
|
4914
|
+
headersGroupLayer1Height,
|
|
4915
|
+
headersGroupLayer2Height
|
|
4916
|
+
} = LAYOUT;
|
|
4912
4917
|
const totalHeaderHeight = headersGroupLayer1Height + headersGroupLayer2Height;
|
|
4913
4918
|
useEffect11(() => {
|
|
4914
4919
|
if (!data || !svgRef.current) return;
|
|
4915
4920
|
const margin = { top: 0, right: 20, bottom: 20, left: 20 };
|
|
4916
4921
|
const chartHeight = data.length * (barHeight + barSpacing) + margin.top + margin.bottom;
|
|
4917
4922
|
const containerWidth = width * 2;
|
|
4918
|
-
const containerHeight = totalHeaderHeight + chartHeight;
|
|
4923
|
+
const containerHeight = totalHeaderHeight + chartHeight > 585 ? totalHeaderHeight + chartHeight : 585;
|
|
4919
4924
|
const borderRadius = 5;
|
|
4920
4925
|
if (leftPanelRef.current) {
|
|
4921
4926
|
leftPanelRef.current.style.height = `${containerHeight}px`;
|
|
@@ -4928,23 +4933,31 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
4928
4933
|
const chartGroup = svg.append("g").attr("transform", `translate(${margin.left}, ${totalHeaderHeight})`);
|
|
4929
4934
|
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
4930
4935
|
const domainStart = startOfDay(startOfYear(new Date(currentYear, 0, 1)));
|
|
4931
|
-
const domainEnd = startOfDay(
|
|
4936
|
+
const domainEnd = startOfDay(
|
|
4937
|
+
addDays(endOfYear(new Date(currentYear, 0, 1)), 1)
|
|
4938
|
+
);
|
|
4932
4939
|
const xScale = d33.scaleTime().domain([domainStart, domainEnd]).range([0, containerWidth - margin.left - margin.right]);
|
|
4933
4940
|
const buildTimeBuckets = (domain) => ({
|
|
4934
4941
|
uniqueYears: d33.timeYear.every(1)?.range(domain[0], domain[1]) || [],
|
|
4935
4942
|
uniqueMonths: d33.timeMonth.every(1)?.range(domain[0], domain[1]) || [],
|
|
4936
|
-
uniqueWeeks: eachWeekOfInterval(
|
|
4937
|
-
|
|
4943
|
+
uniqueWeeks: eachWeekOfInterval(
|
|
4944
|
+
{ start: domain[0], end: domain[1] },
|
|
4945
|
+
{ weekStartsOn: 1 }
|
|
4946
|
+
),
|
|
4947
|
+
uniqueDays: d33.timeDay.range(
|
|
4948
|
+
startOfDay(domain[0]),
|
|
4949
|
+
startOfDay(addDays(domain[1], 1))
|
|
4950
|
+
) || []
|
|
4938
4951
|
});
|
|
4939
4952
|
const renderYearHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
4940
4953
|
layer1.selectAll(".year-bg").data(buckets.uniqueYears).enter().append("rect").attr("class", "year-bg").attr("x", (d) => newXScale(d)).attr("y", -totalHeaderHeight).attr("width", (d) => {
|
|
4941
4954
|
const nextYearStart = startOfDay(new Date(d.getFullYear() + 1, 0, 1));
|
|
4942
4955
|
return newXScale(nextYearStart) - newXScale(d);
|
|
4943
|
-
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#
|
|
4956
|
+
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#E9E9E9").style("stroke-width", 1);
|
|
4944
4957
|
layer1.selectAll(".year-label").data(buckets.uniqueYears).enter().append("text").attr("class", "year-label").attr("x", (d) => {
|
|
4945
4958
|
const nextYear = new Date(d.getFullYear() + 1, 0, 1);
|
|
4946
4959
|
return newXScale(d) + (newXScale(nextYear) - newXScale(d)) / 2;
|
|
4947
|
-
}).attr("y", -totalHeaderHeight + headersGroupLayer1Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer1}px`).style("font-weight", "
|
|
4960
|
+
}).attr("y", -totalHeaderHeight + headersGroupLayer1Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer1 + 2}px`).style("font-weight", "regular").style("fill", "#000").text((d) => `${d.getFullYear() + 543}`);
|
|
4948
4961
|
const quarters2 = [];
|
|
4949
4962
|
buckets.uniqueYears.forEach((year) => {
|
|
4950
4963
|
for (let q = 0; q < 4; q++) {
|
|
@@ -4952,75 +4965,36 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
4952
4965
|
}
|
|
4953
4966
|
});
|
|
4954
4967
|
layer2.selectAll(".quarter-bg").data(quarters2).enter().append("rect").attr("class", "quarter-bg").attr("x", (d) => newXScale(d)).attr("y", -headersGroupLayer2Height).attr("width", (d) => {
|
|
4955
|
-
const nextQuarter = startOfDay(
|
|
4968
|
+
const nextQuarter = startOfDay(
|
|
4969
|
+
new Date(d.getFullYear(), d.getMonth() + 3, 1)
|
|
4970
|
+
);
|
|
4956
4971
|
return newXScale(nextQuarter) - newXScale(d);
|
|
4957
|
-
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#
|
|
4972
|
+
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#E9E9E9").style("stroke-width", 1);
|
|
4958
4973
|
layer2.selectAll(".quarter-label").data(quarters2).enter().append("text").attr("class", "quarter-label").attr("x", (d) => {
|
|
4959
|
-
const nextQuarter = startOfDay(
|
|
4974
|
+
const nextQuarter = startOfDay(
|
|
4975
|
+
new Date(d.getFullYear(), d.getMonth() + 3, 1)
|
|
4976
|
+
);
|
|
4960
4977
|
return newXScale(d) + (newXScale(nextQuarter) - newXScale(d)) / 2;
|
|
4961
|
-
}).attr("y", -headersGroupLayer2Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer2}px`).style("font-weight", "
|
|
4962
|
-
};
|
|
4963
|
-
const renderMonthHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
4964
|
-
layer1.selectAll(".month-bg").data(buckets.uniqueMonths).enter().append("rect").attr("class", "month-bg").attr("x", (d) => newXScale(d)).attr("y", -totalHeaderHeight).attr("width", (d) => {
|
|
4965
|
-
const nextMonth = startOfDay(new Date(d.getFullYear(), d.getMonth() + 1, 1));
|
|
4966
|
-
return newXScale(nextMonth) - newXScale(d) + 11;
|
|
4967
|
-
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
4968
|
-
layer1.selectAll(".month-label").data(buckets.uniqueMonths).enter().append("text").attr("class", "month-label").attr("x", (d) => {
|
|
4969
|
-
const nextMonth = startOfDay(new Date(d.getFullYear(), d.getMonth() + 1, 1));
|
|
4970
|
-
return newXScale(d) + (newXScale(nextMonth) - newXScale(d)) / 2;
|
|
4971
|
-
}).attr("y", -totalHeaderHeight + headersGroupLayer1Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer1}px`).style("font-weight", "bold").style("fill", "#0066cc").text((d) => `${formatThaiMonth(d)} ${d.getFullYear() + 543}`);
|
|
4972
|
-
layer2.selectAll(".week-bg").data(buckets.uniqueWeeks).enter().append("rect").attr("class", "week-bg").attr("x", (d) => newXScale(d)).attr("y", -headersGroupLayer2Height).attr("width", (d) => {
|
|
4973
|
-
const weekEnd = startOfDay(addDays(d, 7));
|
|
4974
|
-
return newXScale(weekEnd) - newXScale(d) + 1;
|
|
4975
|
-
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
4976
|
-
layer2.selectAll(".week-label").data(buckets.uniqueWeeks).enter().append("text").attr("class", "week-label").attr("x", (d) => {
|
|
4977
|
-
const weekEnd = startOfDay(addDays(d, 7));
|
|
4978
|
-
return newXScale(d) + (newXScale(weekEnd) - newXScale(d)) / 2;
|
|
4979
|
-
}).attr("y", -headersGroupLayer2Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer2}px`).style("font-weight", "bold").style("fill", "#0088cc").text((d) => `\u0E2A\u0E31\u0E1B\u0E14\u0E32\u0E2B\u0E4C\u0E17\u0E35\u0E48 ${getWeek(d, { weekStartsOn: 1 })}`);
|
|
4980
|
-
};
|
|
4981
|
-
const renderWeekHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
4982
|
-
layer1.selectAll(".week-bg").data(buckets.uniqueWeeks).enter().append("rect").attr("class", "week-bg").attr("x", (d) => newXScale(d)).attr("y", -totalHeaderHeight).attr("width", (d) => {
|
|
4983
|
-
const weekEnd = startOfDay(addDays(d, 7));
|
|
4984
|
-
return newXScale(weekEnd) - newXScale(d);
|
|
4985
|
-
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
4986
|
-
layer1.selectAll(".week-label").data(buckets.uniqueWeeks).enter().append("text").attr("class", "week-label").attr("x", (d) => {
|
|
4987
|
-
const weekEnd = startOfDay(addDays(d, 7));
|
|
4988
|
-
return newXScale(d) + (newXScale(weekEnd) - newXScale(d)) / 2;
|
|
4989
|
-
}).attr("y", -totalHeaderHeight + headersGroupLayer1Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer1}px`).style("font-weight", "bold").style("fill", "#0066cc").text((d) => `\u0E2A\u0E31\u0E1B\u0E14\u0E32\u0E2B\u0E4C\u0E17\u0E35\u0E48 ${getWeek(d, { weekStartsOn: 1 })}`);
|
|
4990
|
-
layer2.selectAll(".day-bg").data(buckets.uniqueDays).enter().append("rect").attr("class", "day-bg").attr("x", (d) => newXScale(d)).attr("y", -headersGroupLayer2Height).attr("width", (d) => {
|
|
4991
|
-
const nextDay = startOfDay(addDays(d, 1));
|
|
4992
|
-
return newXScale(nextDay) - newXScale(d);
|
|
4993
|
-
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
4994
|
-
layer2.selectAll(".day-of-week").data(buckets.uniqueDays).enter().append("text").attr("class", "day-of-week").attr("x", (d) => {
|
|
4995
|
-
const nextDay = startOfDay(addDays(d, 1));
|
|
4996
|
-
return newXScale(d) + (newXScale(nextDay) - newXScale(d)) / 2;
|
|
4997
|
-
}).attr("y", -headersGroupLayer2Height / 2).attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer2}px`).style("font-weight", "bold").style("fill", "#0088cc").each(function(d) {
|
|
4998
|
-
const textElement = d33.select(this);
|
|
4999
|
-
textElement.text("");
|
|
5000
|
-
textElement.append("tspan").text(THAI_DAYS[d.getDay()]).attr("x", textElement.attr("x")).attr("dy", "-0.3em");
|
|
5001
|
-
textElement.append("tspan").text(format4(d, "d")).attr("x", textElement.attr("x")).attr("dy", "1.2em");
|
|
5002
|
-
});
|
|
4978
|
+
}).attr("y", -headersGroupLayer2Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer2 + 3}px`).style("font-weight", "regular").style("fill", "#000").text((d) => `\u0E44\u0E15\u0E23\u0E21\u0E32\u0E2A ${Math.floor(d.getMonth() / 3) + 1}`);
|
|
5003
4979
|
};
|
|
5004
4980
|
const drawHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
5005
|
-
|
|
5006
|
-
if (viewMode === "month") return renderMonthHeaders(layer1, layer2, newXScale, buckets);
|
|
5007
|
-
return renderWeekHeaders(layer1, layer2, newXScale, buckets);
|
|
4981
|
+
return renderYearHeaders(layer1, layer2, newXScale, buckets);
|
|
5008
4982
|
};
|
|
5009
|
-
const getGridlineData = (
|
|
5010
|
-
if (
|
|
5011
|
-
if (
|
|
5012
|
-
if (
|
|
4983
|
+
const getGridlineData = (mode2, buckets, domain) => {
|
|
4984
|
+
if (mode2 === "year") return buckets.uniqueMonths;
|
|
4985
|
+
if (mode2 === "month") return buckets.uniqueWeeks;
|
|
4986
|
+
if (mode2 === "week") return buckets.uniqueDays;
|
|
5013
4987
|
return eachHourOfInterval({ start: domain[0], end: domain[1] });
|
|
5014
4988
|
};
|
|
5015
4989
|
const drawGridlines = (group, gridlineData, newXScale) => {
|
|
5016
|
-
group.selectAll(".gridline").data(gridlineData).enter().append("line").attr("class", "gridline").attr("x1", (d) => newXScale(d)).attr("x2", (d) => newXScale(d)).attr("y1", 0).attr("y2",
|
|
4990
|
+
group.selectAll(".gridline").data(gridlineData).enter().append("line").attr("class", "gridline").attr("x1", (d) => newXScale(d)).attr("x2", (d) => newXScale(d)).attr("y1", 0).attr("y2", containerHeight).attr("stroke", "#E9E9E9").attr("stroke-width", 1);
|
|
5017
4991
|
};
|
|
5018
4992
|
const drawRowSeparators = (group, getYPosition) => {
|
|
5019
4993
|
const rowSeparatorGroup = group.append("g").attr("class", "row-separators");
|
|
5020
4994
|
data.forEach((_d, i) => {
|
|
5021
4995
|
if (i === 0) return;
|
|
5022
4996
|
const y = getYPosition(i) - barSpacing / 2;
|
|
5023
|
-
rowSeparatorGroup.append("line").attr("x1", 0).attr("x2", containerWidth - margin.left - margin.right).attr("y1", y).attr("y2", y).attr("stroke", "#
|
|
4997
|
+
rowSeparatorGroup.append("line").attr("x1", 0).attr("x2", containerWidth - margin.left - margin.right).attr("y1", y).attr("y2", y).attr("stroke", "#E9E9E9").attr("stroke-width", 1).style("pointer-events", "none");
|
|
5024
4998
|
});
|
|
5025
4999
|
rowSeparatorGroup.lower();
|
|
5026
5000
|
};
|
|
@@ -5028,16 +5002,27 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5028
5002
|
const barsGroup = group.append("g").attr("class", "bars-group");
|
|
5029
5003
|
const renderBarHeight = barHeight;
|
|
5030
5004
|
const labelPadding = 10;
|
|
5031
|
-
barsGroup.selectAll(".bar-background").data(data).enter().append("rect").attr("class", "bar-background").attr("x", (d) => newXScale(getAdjustedStart(d))).attr("y", (_d, i) => getYPosition(i)).attr("height", renderBarHeight).attr(
|
|
5032
|
-
|
|
5033
|
-
|
|
5034
|
-
|
|
5035
|
-
|
|
5036
|
-
|
|
5037
|
-
|
|
5038
|
-
|
|
5005
|
+
barsGroup.selectAll(".bar-background").data(data).enter().append("rect").attr("class", "bar-background").attr("x", (d) => newXScale(getAdjustedStart(d))).attr("y", (_d, i) => getYPosition(i)).attr("height", renderBarHeight).attr(
|
|
5006
|
+
"width",
|
|
5007
|
+
(d) => newXScale(getAdjustedEnd(d)) - newXScale(getAdjustedStart(d))
|
|
5008
|
+
).attr("fill", (d) => getStatusColor(d.status)).attr("rx", borderRadius).attr("ry", borderRadius);
|
|
5009
|
+
{
|
|
5010
|
+
mode === "project" && barsGroup.selectAll(".bar-head").data(data).enter().append("path").attr("class", "bar-head").attr("fill", (d) => d.color).attr("d", (d, i) => {
|
|
5011
|
+
const x = newXScale(getAdjustedStart(d));
|
|
5012
|
+
const y = getYPosition(i);
|
|
5013
|
+
const barWidth = newXScale(getAdjustedEnd(d)) - newXScale(getAdjustedStart(d));
|
|
5014
|
+
const headWidth = Math.min(barWidth * 0.5, 20);
|
|
5015
|
+
return roundedRectPath(
|
|
5016
|
+
x,
|
|
5017
|
+
y,
|
|
5018
|
+
headWidth,
|
|
5019
|
+
renderBarHeight,
|
|
5020
|
+
borderRadius
|
|
5021
|
+
);
|
|
5022
|
+
});
|
|
5023
|
+
}
|
|
5039
5024
|
const labels = group.append("g").attr("class", "labels");
|
|
5040
|
-
const labelSelection = labels.selectAll(".label").data(data).enter().append("text").attr("class", "label").attr("y", (_d, i) => getYPosition(i) + renderBarHeight / 2).attr("dy", "0.35em").text((d) => d.label).style("fill", "black").style("font-
|
|
5025
|
+
const labelSelection = labels.selectAll(".label").data(data).enter().append("text").attr("class", "label").attr("y", (_d, i) => getYPosition(i) + renderBarHeight / 2).attr("dy", "0.35em").text((d) => d.label).style("fill", "black").style("font-weight", "400").style("pointer-events", "none");
|
|
5041
5026
|
labelSelection.each(function(d) {
|
|
5042
5027
|
const barWidth = newXScale(getAdjustedEnd(d)) - newXScale(getAdjustedStart(d));
|
|
5043
5028
|
const headWidth = Math.min(barWidth * 0.5, 20);
|
|
@@ -5060,8 +5045,17 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5060
5045
|
const timeBuckets = buildTimeBuckets(newXScale.domain());
|
|
5061
5046
|
const headersGroupLayer1 = chartGroup.append("g");
|
|
5062
5047
|
const headersGroupLayer2 = chartGroup.append("g");
|
|
5063
|
-
drawHeaders(
|
|
5064
|
-
|
|
5048
|
+
drawHeaders(
|
|
5049
|
+
headersGroupLayer1,
|
|
5050
|
+
headersGroupLayer2,
|
|
5051
|
+
newXScale,
|
|
5052
|
+
timeBuckets
|
|
5053
|
+
);
|
|
5054
|
+
const gridlineData = getGridlineData(
|
|
5055
|
+
viewMode,
|
|
5056
|
+
timeBuckets,
|
|
5057
|
+
newXScale.domain()
|
|
5058
|
+
);
|
|
5065
5059
|
drawGridlines(headersGroupLayer2, gridlineData, newXScale);
|
|
5066
5060
|
drawRowSeparators(chartGroup, getYPosition);
|
|
5067
5061
|
drawBarsAndLabels(chartGroup, newXScale, getYPosition);
|
|
@@ -5079,7 +5073,6 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5079
5073
|
}, [
|
|
5080
5074
|
data,
|
|
5081
5075
|
width,
|
|
5082
|
-
height,
|
|
5083
5076
|
viewMode,
|
|
5084
5077
|
barHeight,
|
|
5085
5078
|
barSpacing,
|
|
@@ -5090,13 +5083,13 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5090
5083
|
return /* @__PURE__ */ jsx48(
|
|
5091
5084
|
"div",
|
|
5092
5085
|
{
|
|
5086
|
+
className: "body-1",
|
|
5093
5087
|
style: {
|
|
5094
5088
|
display: "flex",
|
|
5095
5089
|
flexDirection: "column",
|
|
5096
|
-
padding: "20px",
|
|
5097
5090
|
width: `${width}px`,
|
|
5098
|
-
height:
|
|
5099
|
-
border: "1px solid #
|
|
5091
|
+
height: `587px`,
|
|
5092
|
+
border: "1px solid #E9E9E9",
|
|
5100
5093
|
borderRadius: "10px",
|
|
5101
5094
|
backgroundColor: "#fff",
|
|
5102
5095
|
overflow: "hidden"
|
|
@@ -5112,49 +5105,69 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5112
5105
|
position: "relative"
|
|
5113
5106
|
},
|
|
5114
5107
|
children: [
|
|
5115
|
-
/* @__PURE__ */ jsx48(
|
|
5108
|
+
/* @__PURE__ */ jsx48("div", { className: "z-2", children: /* @__PURE__ */ jsx48(
|
|
5109
|
+
RowOverlay,
|
|
5110
|
+
{
|
|
5111
|
+
data: data.length > 10 ? data : ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
|
|
5112
|
+
barHeight,
|
|
5113
|
+
barSpacing,
|
|
5114
|
+
totalHeaderHeight
|
|
5115
|
+
}
|
|
5116
|
+
) }),
|
|
5116
5117
|
/* @__PURE__ */ jsxs39(
|
|
5117
5118
|
"div",
|
|
5118
5119
|
{
|
|
5119
5120
|
ref: leftPanelRef,
|
|
5121
|
+
className: "border-r",
|
|
5120
5122
|
style: {
|
|
5121
5123
|
width: "520px",
|
|
5122
5124
|
minWidth: "500px",
|
|
5123
5125
|
display: "flex",
|
|
5124
5126
|
flexDirection: "column",
|
|
5125
5127
|
backgroundColor: "#fff",
|
|
5126
|
-
borderRight: "1px solid #ddd",
|
|
5127
5128
|
zIndex: 2
|
|
5128
5129
|
},
|
|
5129
5130
|
children: [
|
|
5130
|
-
/* @__PURE__ */ jsxs39(
|
|
5131
|
-
|
|
5132
|
-
|
|
5133
|
-
|
|
5134
|
-
|
|
5135
|
-
|
|
5136
|
-
|
|
5137
|
-
|
|
5138
|
-
|
|
5139
|
-
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5144
|
-
|
|
5145
|
-
|
|
5146
|
-
|
|
5147
|
-
|
|
5131
|
+
/* @__PURE__ */ jsxs39("div", { ref: dataContainerRef, children: [
|
|
5132
|
+
/* @__PURE__ */ jsxs39(
|
|
5133
|
+
"div",
|
|
5134
|
+
{
|
|
5135
|
+
className: "grid body-2 grid-cols-[1fr_100px_130px] gap-2 px-8 border-b bg-white",
|
|
5136
|
+
style: {
|
|
5137
|
+
height: `${totalHeaderHeight}px`,
|
|
5138
|
+
marginBottom: "10px",
|
|
5139
|
+
position: "sticky",
|
|
5140
|
+
top: 0,
|
|
5141
|
+
alignItems: "center",
|
|
5142
|
+
zIndex: 5
|
|
5143
|
+
},
|
|
5144
|
+
children: [
|
|
5145
|
+
/* @__PURE__ */ jsx48("div", { children: "\u0E42\u0E04\u0E23\u0E07\u0E01\u0E32\u0E23" }),
|
|
5146
|
+
/* @__PURE__ */ jsx48("div", { children: "\u0E01\u0E33\u0E2B\u0E19\u0E14\u0E2A\u0E48\u0E07" }),
|
|
5147
|
+
/* @__PURE__ */ jsx48("div", { children: "\u0E2A\u0E16\u0E32\u0E19\u0E30" })
|
|
5148
|
+
]
|
|
5149
|
+
}
|
|
5150
|
+
),
|
|
5151
|
+
data.map((element) => /* @__PURE__ */ jsx48(
|
|
5152
|
+
ProjectRow,
|
|
5153
|
+
{
|
|
5154
|
+
mode,
|
|
5155
|
+
element,
|
|
5156
|
+
barHeight,
|
|
5157
|
+
barSpacing
|
|
5148
5158
|
},
|
|
5149
|
-
|
|
5150
|
-
|
|
5151
|
-
|
|
5152
|
-
|
|
5153
|
-
|
|
5154
|
-
|
|
5159
|
+
element.id
|
|
5160
|
+
))
|
|
5161
|
+
] }),
|
|
5162
|
+
/* @__PURE__ */ jsx48("div", { className: "z-3", children: /* @__PURE__ */ jsx48(
|
|
5163
|
+
RowOverlay,
|
|
5164
|
+
{
|
|
5165
|
+
data,
|
|
5166
|
+
barHeight,
|
|
5167
|
+
barSpacing,
|
|
5168
|
+
totalHeaderHeight
|
|
5155
5169
|
}
|
|
5156
|
-
)
|
|
5157
|
-
/* @__PURE__ */ jsx48("div", { ref: dataContainerRef, children: data.map((element) => /* @__PURE__ */ jsx48(ProjectRow, { element, barHeight, barSpacing }, element.id)) })
|
|
5170
|
+
) })
|
|
5158
5171
|
]
|
|
5159
5172
|
}
|
|
5160
5173
|
),
|
|
@@ -5236,7 +5249,7 @@ function CardKPI({
|
|
|
5236
5249
|
/* @__PURE__ */ jsx49(ProgressBar, { percent: overallPercent, type: "line", checkpoints: [0] })
|
|
5237
5250
|
] }),
|
|
5238
5251
|
/* @__PURE__ */ jsxs40("div", { className: "border-b", children: [
|
|
5239
|
-
/* @__PURE__ */ jsx49("span", { className: "body-2 ", children: "\
|
|
5252
|
+
/* @__PURE__ */ jsx49("span", { className: "body-2 ", children: "\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" }),
|
|
5240
5253
|
indicator.filter((ind) => ind.indicatorType === "TARGET").map((item, index) => {
|
|
5241
5254
|
if (index === 2) return;
|
|
5242
5255
|
return /* @__PURE__ */ jsx49(KPIRow, { item });
|
|
@@ -5249,7 +5262,6 @@ function CardKPI({
|
|
|
5249
5262
|
return /* @__PURE__ */ jsx49(KPIRow, { item });
|
|
5250
5263
|
})
|
|
5251
5264
|
] }),
|
|
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
5265
|
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
5266
|
IconDots,
|
|
5255
5267
|
{
|