@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.js
CHANGED
|
@@ -621,9 +621,9 @@ function Checkbox({ label, checked, onChange, disabled }) {
|
|
|
621
621
|
/* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
622
622
|
"div",
|
|
623
623
|
{
|
|
624
|
-
className: `flex justify-center items-center border-[1px] border-
|
|
625
|
-
${checked ? "bg-
|
|
626
|
-
${disabled ? "pointer-events-none" : ""}`,
|
|
624
|
+
className: `flex justify-center items-center border-[1px] border-gray-400 w-[24px] h-[24px] rounded-[8px] transition-colors duration-100
|
|
625
|
+
${checked ? "bg-primary-500 text-white border-primary-500" : "bg-white text-black"}
|
|
626
|
+
${disabled ? "pointer-events-none !bg-gray-300" : ""}`,
|
|
627
627
|
children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
|
|
628
628
|
"span",
|
|
629
629
|
{
|
|
@@ -4143,7 +4143,7 @@ function Indicator({
|
|
|
4143
4143
|
}
|
|
4144
4144
|
),
|
|
4145
4145
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(import_icons_react12.IconX, { className: "cursor-pointer text-red-600", onClick: handleCancelEditIndicator })
|
|
4146
|
-
] }) : void 0 :
|
|
4146
|
+
] }) : void 0 : false }),
|
|
4147
4147
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "body-1 mt-2 cursor-pointer", children: /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
4148
4148
|
import_icons_react12.IconTrash,
|
|
4149
4149
|
{
|
|
@@ -4798,6 +4798,8 @@ var PieChart = ({
|
|
|
4798
4798
|
var import_react24 = require("react");
|
|
4799
4799
|
var d33 = __toESM(require("d3"));
|
|
4800
4800
|
var import_date_fns3 = require("date-fns");
|
|
4801
|
+
var import_locale3 = require("date-fns/locale");
|
|
4802
|
+
var import_icons_react15 = require("@tabler/icons-react");
|
|
4801
4803
|
var import_jsx_runtime48 = require("react/jsx-runtime");
|
|
4802
4804
|
var LAYOUT = {
|
|
4803
4805
|
barHeight: 40,
|
|
@@ -4815,31 +4817,33 @@ var VIEW_MODE_SCALE = {
|
|
|
4815
4817
|
week: 10
|
|
4816
4818
|
};
|
|
4817
4819
|
var STATUS_META = {
|
|
4818
|
-
|
|
4819
|
-
|
|
4820
|
-
|
|
4821
|
-
}
|
|
4822
|
-
|
|
4823
|
-
|
|
4824
|
-
|
|
4825
|
-
|
|
4826
|
-
|
|
4827
|
-
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4832
|
-
|
|
4833
|
-
|
|
4834
|
-
|
|
4820
|
+
IN_PROGRESS: {
|
|
4821
|
+
color: "#FFC654",
|
|
4822
|
+
label: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23",
|
|
4823
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_icons_react15.IconHourglassEmpty, { className: "text-[#FFC654]" })
|
|
4824
|
+
},
|
|
4825
|
+
CANCEL: {
|
|
4826
|
+
color: "#D2D5DB",
|
|
4827
|
+
label: "\u0E22\u0E01\u0E40\u0E25\u0E34\u0E01",
|
|
4828
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_icons_react15.IconCircleX, { className: "text-[#D2D5DB]" })
|
|
4829
|
+
},
|
|
4830
|
+
SUCCESS: {
|
|
4831
|
+
color: "#81CF92",
|
|
4832
|
+
label: "\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27\u0E40\u0E2A\u0E23\u0E47\u0E08",
|
|
4833
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_icons_react15.IconRosetteDiscountCheck, { className: "text-[#81CF92]" })
|
|
4834
|
+
},
|
|
4835
|
+
COMPLETE: {
|
|
4836
|
+
color: "#81CF92",
|
|
4837
|
+
label: "\u0E40\u0E2A\u0E23\u0E47\u0E08\u0E2A\u0E34\u0E49\u0E19",
|
|
4838
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_icons_react15.IconRosetteDiscountCheck, { className: "text-[#81CF92]" })
|
|
4839
|
+
},
|
|
4840
|
+
DELAY: {
|
|
4841
|
+
color: "#F4827E",
|
|
4842
|
+
label: "\u0E25\u0E48\u0E32\u0E0A\u0E49\u0E32",
|
|
4843
|
+
icon: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(import_icons_react15.IconClockExclamation, { className: "text-[#F4827E]" })
|
|
4844
|
+
}
|
|
4835
4845
|
};
|
|
4836
|
-
var THAI_DAYS = ["\u0E2D\u0E32.", "\u0E08.", "\u0E2D.", "\u0E1E.", "\u0E1E\u0E24.", "\u0E28.", "\u0E2A."];
|
|
4837
4846
|
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}`;
|
|
4838
|
-
var formatThaiMonth = (date) => {
|
|
4839
|
-
const monthName = (0, import_date_fns3.format)(date, "MMMM");
|
|
4840
|
-
return THAI_MONTHS[monthName] || monthName;
|
|
4841
|
-
};
|
|
4842
|
-
var formatThaiDate = (date) => date ? date.toLocaleDateString("th-TH", { day: "numeric", month: "short" }) : "-";
|
|
4843
4847
|
var isDateOnlyValue = (dt) => {
|
|
4844
4848
|
const localZero = dt.getHours() === 0 && dt.getMinutes() === 0 && dt.getSeconds() === 0 && dt.getMilliseconds() === 0;
|
|
4845
4849
|
const utcZero = dt.getUTCHours() === 0 && dt.getUTCMinutes() === 0 && dt.getUTCSeconds() === 0 && dt.getUTCMilliseconds() === 0;
|
|
@@ -4869,60 +4873,46 @@ var getAdjustedEnd = (d) => {
|
|
|
4869
4873
|
}
|
|
4870
4874
|
return (0, import_date_fns3.startOfDay)(/* @__PURE__ */ new Date());
|
|
4871
4875
|
};
|
|
4872
|
-
var getStatusColor = (status2) => STATUS_META[status2]?.color ?? STATUS_META.
|
|
4873
|
-
var getStatusLabel = (status2) => STATUS_META[status2]?.label ?? STATUS_META.
|
|
4874
|
-
var ProjectRow = ({ element, barHeight, barSpacing }) => {
|
|
4876
|
+
var getStatusColor = (status2) => STATUS_META[status2]?.color ?? STATUS_META.IN_PROGRESS.color;
|
|
4877
|
+
var getStatusLabel = (status2) => STATUS_META[status2]?.label ?? STATUS_META.IN_PROGRESS.label;
|
|
4878
|
+
var ProjectRow = ({ element, barHeight, barSpacing, mode }) => {
|
|
4875
4879
|
const safeStartDate = element.startDate instanceof Date ? element.startDate : null;
|
|
4876
4880
|
const safeEndDate = element.endDate instanceof Date ? element.endDate : null;
|
|
4877
4881
|
const safeStatus = element.status || "pending";
|
|
4878
4882
|
const statusColor = getStatusColor(safeStatus);
|
|
4879
4883
|
const statusLabel = getStatusLabel(safeStatus);
|
|
4884
|
+
const statusIcon = STATUS_META[safeStatus]?.icon;
|
|
4885
|
+
const toBuddhistDate = (d) => new Date(d.getFullYear() + 543, d.getMonth(), d.getDate());
|
|
4880
4886
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
4881
4887
|
"div",
|
|
4882
4888
|
{
|
|
4883
4889
|
style: {
|
|
4884
|
-
display: "grid",
|
|
4885
|
-
gridTemplateColumns: "200px 100px 100px 100px",
|
|
4886
4890
|
alignItems: "center",
|
|
4887
4891
|
height: `${barHeight}px`,
|
|
4888
|
-
|
|
4889
|
-
|
|
4892
|
+
marginBottom: `${barSpacing}px`,
|
|
4893
|
+
fontSize: "12px"
|
|
4890
4894
|
},
|
|
4895
|
+
className: "body-1 grid grid-cols-[1fr_100px_130px] px-8 gap-2",
|
|
4891
4896
|
children: [
|
|
4892
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", {
|
|
4893
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
4894
|
-
"
|
|
4897
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: `grid ${mode === "project" ? "grid-cols-[10px_1fr]" : "grid-cols-[1fr]"} items-center gap-2`, children: [
|
|
4898
|
+
mode === "project" && /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
4899
|
+
"div",
|
|
4895
4900
|
{
|
|
4896
4901
|
style: {
|
|
4897
|
-
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
borderRadius: "50%",
|
|
4901
|
-
backgroundColor: element.color || "#999"
|
|
4902
|
-
}
|
|
4902
|
+
backgroundColor: element.color || "#E9E9E9"
|
|
4903
|
+
},
|
|
4904
|
+
className: "w-[10px] h-[10px] rounded-full"
|
|
4903
4905
|
}
|
|
4904
4906
|
),
|
|
4905
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("
|
|
4907
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "line-clamp-1 break-words text-[#333]", title: element.label, children: element.label })
|
|
4906
4908
|
] }),
|
|
4907
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", {
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
|
|
4912
|
-
|
|
4913
|
-
|
|
4914
|
-
minWidth: "100%",
|
|
4915
|
-
padding: "4px 8px",
|
|
4916
|
-
borderRadius: "4px",
|
|
4917
|
-
fontSize: "11px",
|
|
4918
|
-
backgroundColor: statusColor,
|
|
4919
|
-
color: "#000",
|
|
4920
|
-
border: "none",
|
|
4921
|
-
cursor: "pointer"
|
|
4922
|
-
},
|
|
4923
|
-
children: statusLabel
|
|
4924
|
-
}
|
|
4925
|
-
)
|
|
4909
|
+
mode === "project" ? /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { children: safeEndDate ? (0, import_date_fns3.format)(toBuddhistDate(safeEndDate), "dd MMM yyyy", { locale: import_locale3.th }) : "-" }) : /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { children: `Q${(0, import_date_fns3.getQuarter)(
|
|
4910
|
+
safeEndDate ?? /* @__PURE__ */ new Date()
|
|
4911
|
+
)}/${(safeEndDate?.getFullYear() ?? 0) + 543}` }),
|
|
4912
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("button", { className: "rounded-md subtitile-1 flex gap-2 align-start", children: [
|
|
4913
|
+
statusIcon,
|
|
4914
|
+
statusLabel
|
|
4915
|
+
] })
|
|
4926
4916
|
]
|
|
4927
4917
|
},
|
|
4928
4918
|
element.id
|
|
@@ -4937,42 +4927,52 @@ var RowOverlay = ({ data, barHeight, barSpacing, totalHeaderHeight }) => /* @__P
|
|
|
4937
4927
|
left: 0,
|
|
4938
4928
|
right: 0,
|
|
4939
4929
|
height: `${data.length * (barHeight + barSpacing)}px`,
|
|
4940
|
-
pointerEvents: "none"
|
|
4941
|
-
zIndex: 5
|
|
4930
|
+
pointerEvents: "none"
|
|
4942
4931
|
},
|
|
4943
|
-
children: data.map((
|
|
4932
|
+
children: data.map((_, i) => {
|
|
4944
4933
|
if (i === 0) return null;
|
|
4934
|
+
console.log("rendering row line", i);
|
|
4945
4935
|
const yPos = i * (barHeight + barSpacing) - barSpacing / 2;
|
|
4946
4936
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
4947
4937
|
"div",
|
|
4948
4938
|
{
|
|
4939
|
+
className: "",
|
|
4949
4940
|
style: {
|
|
4950
4941
|
position: "absolute",
|
|
4951
4942
|
top: `${yPos}px`,
|
|
4952
4943
|
left: 0,
|
|
4953
4944
|
right: 0,
|
|
4954
4945
|
height: "1px",
|
|
4955
|
-
backgroundColor: "#
|
|
4946
|
+
backgroundColor: "#E9E9E9"
|
|
4956
4947
|
}
|
|
4957
4948
|
},
|
|
4958
|
-
`row-line-${
|
|
4949
|
+
`row-line-${i}`
|
|
4959
4950
|
);
|
|
4960
4951
|
})
|
|
4961
4952
|
}
|
|
4962
4953
|
);
|
|
4963
|
-
var GanttChart = ({
|
|
4954
|
+
var GanttChart = ({
|
|
4955
|
+
data,
|
|
4956
|
+
width,
|
|
4957
|
+
mode
|
|
4958
|
+
}) => {
|
|
4964
4959
|
const svgRef = (0, import_react24.useRef)(null);
|
|
4965
4960
|
const leftPanelRef = (0, import_react24.useRef)(null);
|
|
4966
4961
|
const dataContainerRef = (0, import_react24.useRef)(null);
|
|
4967
4962
|
const [viewMode] = (0, import_react24.useState)("year");
|
|
4968
|
-
const {
|
|
4963
|
+
const {
|
|
4964
|
+
barHeight,
|
|
4965
|
+
barSpacing,
|
|
4966
|
+
headersGroupLayer1Height,
|
|
4967
|
+
headersGroupLayer2Height
|
|
4968
|
+
} = LAYOUT;
|
|
4969
4969
|
const totalHeaderHeight = headersGroupLayer1Height + headersGroupLayer2Height;
|
|
4970
4970
|
(0, import_react24.useEffect)(() => {
|
|
4971
4971
|
if (!data || !svgRef.current) return;
|
|
4972
4972
|
const margin = { top: 0, right: 20, bottom: 20, left: 20 };
|
|
4973
4973
|
const chartHeight = data.length * (barHeight + barSpacing) + margin.top + margin.bottom;
|
|
4974
4974
|
const containerWidth = width * 2;
|
|
4975
|
-
const containerHeight = totalHeaderHeight + chartHeight;
|
|
4975
|
+
const containerHeight = totalHeaderHeight + chartHeight > 585 ? totalHeaderHeight + chartHeight : 585;
|
|
4976
4976
|
const borderRadius = 5;
|
|
4977
4977
|
if (leftPanelRef.current) {
|
|
4978
4978
|
leftPanelRef.current.style.height = `${containerHeight}px`;
|
|
@@ -4985,23 +4985,31 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
4985
4985
|
const chartGroup = svg.append("g").attr("transform", `translate(${margin.left}, ${totalHeaderHeight})`);
|
|
4986
4986
|
const currentYear = (/* @__PURE__ */ new Date()).getFullYear();
|
|
4987
4987
|
const domainStart = (0, import_date_fns3.startOfDay)((0, import_date_fns3.startOfYear)(new Date(currentYear, 0, 1)));
|
|
4988
|
-
const domainEnd = (0, import_date_fns3.startOfDay)(
|
|
4988
|
+
const domainEnd = (0, import_date_fns3.startOfDay)(
|
|
4989
|
+
(0, import_date_fns3.addDays)((0, import_date_fns3.endOfYear)(new Date(currentYear, 0, 1)), 1)
|
|
4990
|
+
);
|
|
4989
4991
|
const xScale = d33.scaleTime().domain([domainStart, domainEnd]).range([0, containerWidth - margin.left - margin.right]);
|
|
4990
4992
|
const buildTimeBuckets = (domain) => ({
|
|
4991
4993
|
uniqueYears: d33.timeYear.every(1)?.range(domain[0], domain[1]) || [],
|
|
4992
4994
|
uniqueMonths: d33.timeMonth.every(1)?.range(domain[0], domain[1]) || [],
|
|
4993
|
-
uniqueWeeks: (0, import_date_fns3.eachWeekOfInterval)(
|
|
4994
|
-
|
|
4995
|
+
uniqueWeeks: (0, import_date_fns3.eachWeekOfInterval)(
|
|
4996
|
+
{ start: domain[0], end: domain[1] },
|
|
4997
|
+
{ weekStartsOn: 1 }
|
|
4998
|
+
),
|
|
4999
|
+
uniqueDays: d33.timeDay.range(
|
|
5000
|
+
(0, import_date_fns3.startOfDay)(domain[0]),
|
|
5001
|
+
(0, import_date_fns3.startOfDay)((0, import_date_fns3.addDays)(domain[1], 1))
|
|
5002
|
+
) || []
|
|
4995
5003
|
});
|
|
4996
5004
|
const renderYearHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
4997
5005
|
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) => {
|
|
4998
5006
|
const nextYearStart = (0, import_date_fns3.startOfDay)(new Date(d.getFullYear() + 1, 0, 1));
|
|
4999
5007
|
return newXScale(nextYearStart) - newXScale(d);
|
|
5000
|
-
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#
|
|
5008
|
+
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#E9E9E9").style("stroke-width", 1);
|
|
5001
5009
|
layer1.selectAll(".year-label").data(buckets.uniqueYears).enter().append("text").attr("class", "year-label").attr("x", (d) => {
|
|
5002
5010
|
const nextYear = new Date(d.getFullYear() + 1, 0, 1);
|
|
5003
5011
|
return newXScale(d) + (newXScale(nextYear) - newXScale(d)) / 2;
|
|
5004
|
-
}).attr("y", -totalHeaderHeight + headersGroupLayer1Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer1}px`).style("font-weight", "
|
|
5012
|
+
}).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}`);
|
|
5005
5013
|
const quarters2 = [];
|
|
5006
5014
|
buckets.uniqueYears.forEach((year) => {
|
|
5007
5015
|
for (let q = 0; q < 4; q++) {
|
|
@@ -5009,75 +5017,36 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5009
5017
|
}
|
|
5010
5018
|
});
|
|
5011
5019
|
layer2.selectAll(".quarter-bg").data(quarters2).enter().append("rect").attr("class", "quarter-bg").attr("x", (d) => newXScale(d)).attr("y", -headersGroupLayer2Height).attr("width", (d) => {
|
|
5012
|
-
const nextQuarter = (0, import_date_fns3.startOfDay)(
|
|
5020
|
+
const nextQuarter = (0, import_date_fns3.startOfDay)(
|
|
5021
|
+
new Date(d.getFullYear(), d.getMonth() + 3, 1)
|
|
5022
|
+
);
|
|
5013
5023
|
return newXScale(nextQuarter) - newXScale(d);
|
|
5014
|
-
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#
|
|
5024
|
+
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#E9E9E9").style("stroke-width", 1);
|
|
5015
5025
|
layer2.selectAll(".quarter-label").data(quarters2).enter().append("text").attr("class", "quarter-label").attr("x", (d) => {
|
|
5016
|
-
const nextQuarter = (0, import_date_fns3.startOfDay)(
|
|
5026
|
+
const nextQuarter = (0, import_date_fns3.startOfDay)(
|
|
5027
|
+
new Date(d.getFullYear(), d.getMonth() + 3, 1)
|
|
5028
|
+
);
|
|
5017
5029
|
return newXScale(d) + (newXScale(nextQuarter) - newXScale(d)) / 2;
|
|
5018
|
-
}).attr("y", -headersGroupLayer2Height / 2).attr("dy", "0.35em").attr("text-anchor", "middle").style("font-size", `${HEADER_FONTS.layer2}px`).style("font-weight", "
|
|
5019
|
-
};
|
|
5020
|
-
const renderMonthHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
5021
|
-
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) => {
|
|
5022
|
-
const nextMonth = (0, import_date_fns3.startOfDay)(new Date(d.getFullYear(), d.getMonth() + 1, 1));
|
|
5023
|
-
return newXScale(nextMonth) - newXScale(d) + 11;
|
|
5024
|
-
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
5025
|
-
layer1.selectAll(".month-label").data(buckets.uniqueMonths).enter().append("text").attr("class", "month-label").attr("x", (d) => {
|
|
5026
|
-
const nextMonth = (0, import_date_fns3.startOfDay)(new Date(d.getFullYear(), d.getMonth() + 1, 1));
|
|
5027
|
-
return newXScale(d) + (newXScale(nextMonth) - newXScale(d)) / 2;
|
|
5028
|
-
}).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}`);
|
|
5029
|
-
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) => {
|
|
5030
|
-
const weekEnd = (0, import_date_fns3.startOfDay)((0, import_date_fns3.addDays)(d, 7));
|
|
5031
|
-
return newXScale(weekEnd) - newXScale(d) + 1;
|
|
5032
|
-
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
5033
|
-
layer2.selectAll(".week-label").data(buckets.uniqueWeeks).enter().append("text").attr("class", "week-label").attr("x", (d) => {
|
|
5034
|
-
const weekEnd = (0, import_date_fns3.startOfDay)((0, import_date_fns3.addDays)(d, 7));
|
|
5035
|
-
return newXScale(d) + (newXScale(weekEnd) - newXScale(d)) / 2;
|
|
5036
|
-
}).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 ${(0, import_date_fns3.getWeek)(d, { weekStartsOn: 1 })}`);
|
|
5037
|
-
};
|
|
5038
|
-
const renderWeekHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
5039
|
-
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) => {
|
|
5040
|
-
const weekEnd = (0, import_date_fns3.startOfDay)((0, import_date_fns3.addDays)(d, 7));
|
|
5041
|
-
return newXScale(weekEnd) - newXScale(d);
|
|
5042
|
-
}).attr("height", headersGroupLayer1Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
5043
|
-
layer1.selectAll(".week-label").data(buckets.uniqueWeeks).enter().append("text").attr("class", "week-label").attr("x", (d) => {
|
|
5044
|
-
const weekEnd = (0, import_date_fns3.startOfDay)((0, import_date_fns3.addDays)(d, 7));
|
|
5045
|
-
return newXScale(d) + (newXScale(weekEnd) - newXScale(d)) / 2;
|
|
5046
|
-
}).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 ${(0, import_date_fns3.getWeek)(d, { weekStartsOn: 1 })}`);
|
|
5047
|
-
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) => {
|
|
5048
|
-
const nextDay = (0, import_date_fns3.startOfDay)((0, import_date_fns3.addDays)(d, 1));
|
|
5049
|
-
return newXScale(nextDay) - newXScale(d);
|
|
5050
|
-
}).attr("height", headersGroupLayer2Height).style("fill", "#fff").style("stroke", "#999").style("stroke-width", 1);
|
|
5051
|
-
layer2.selectAll(".day-of-week").data(buckets.uniqueDays).enter().append("text").attr("class", "day-of-week").attr("x", (d) => {
|
|
5052
|
-
const nextDay = (0, import_date_fns3.startOfDay)((0, import_date_fns3.addDays)(d, 1));
|
|
5053
|
-
return newXScale(d) + (newXScale(nextDay) - newXScale(d)) / 2;
|
|
5054
|
-
}).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) {
|
|
5055
|
-
const textElement = d33.select(this);
|
|
5056
|
-
textElement.text("");
|
|
5057
|
-
textElement.append("tspan").text(THAI_DAYS[d.getDay()]).attr("x", textElement.attr("x")).attr("dy", "-0.3em");
|
|
5058
|
-
textElement.append("tspan").text((0, import_date_fns3.format)(d, "d")).attr("x", textElement.attr("x")).attr("dy", "1.2em");
|
|
5059
|
-
});
|
|
5030
|
+
}).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}`);
|
|
5060
5031
|
};
|
|
5061
5032
|
const drawHeaders = (layer1, layer2, newXScale, buckets) => {
|
|
5062
|
-
|
|
5063
|
-
if (viewMode === "month") return renderMonthHeaders(layer1, layer2, newXScale, buckets);
|
|
5064
|
-
return renderWeekHeaders(layer1, layer2, newXScale, buckets);
|
|
5033
|
+
return renderYearHeaders(layer1, layer2, newXScale, buckets);
|
|
5065
5034
|
};
|
|
5066
|
-
const getGridlineData = (
|
|
5067
|
-
if (
|
|
5068
|
-
if (
|
|
5069
|
-
if (
|
|
5035
|
+
const getGridlineData = (mode2, buckets, domain) => {
|
|
5036
|
+
if (mode2 === "year") return buckets.uniqueMonths;
|
|
5037
|
+
if (mode2 === "month") return buckets.uniqueWeeks;
|
|
5038
|
+
if (mode2 === "week") return buckets.uniqueDays;
|
|
5070
5039
|
return (0, import_date_fns3.eachHourOfInterval)({ start: domain[0], end: domain[1] });
|
|
5071
5040
|
};
|
|
5072
5041
|
const drawGridlines = (group, gridlineData, newXScale) => {
|
|
5073
|
-
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",
|
|
5042
|
+
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);
|
|
5074
5043
|
};
|
|
5075
5044
|
const drawRowSeparators = (group, getYPosition) => {
|
|
5076
5045
|
const rowSeparatorGroup = group.append("g").attr("class", "row-separators");
|
|
5077
5046
|
data.forEach((_d, i) => {
|
|
5078
5047
|
if (i === 0) return;
|
|
5079
5048
|
const y = getYPosition(i) - barSpacing / 2;
|
|
5080
|
-
rowSeparatorGroup.append("line").attr("x1", 0).attr("x2", containerWidth - margin.left - margin.right).attr("y1", y).attr("y2", y).attr("stroke", "#
|
|
5049
|
+
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");
|
|
5081
5050
|
});
|
|
5082
5051
|
rowSeparatorGroup.lower();
|
|
5083
5052
|
};
|
|
@@ -5085,16 +5054,27 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5085
5054
|
const barsGroup = group.append("g").attr("class", "bars-group");
|
|
5086
5055
|
const renderBarHeight = barHeight;
|
|
5087
5056
|
const labelPadding = 10;
|
|
5088
|
-
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(
|
|
5089
|
-
|
|
5090
|
-
|
|
5091
|
-
|
|
5092
|
-
|
|
5093
|
-
|
|
5094
|
-
|
|
5095
|
-
|
|
5057
|
+
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(
|
|
5058
|
+
"width",
|
|
5059
|
+
(d) => newXScale(getAdjustedEnd(d)) - newXScale(getAdjustedStart(d))
|
|
5060
|
+
).attr("fill", (d) => getStatusColor(d.status)).attr("rx", borderRadius).attr("ry", borderRadius);
|
|
5061
|
+
{
|
|
5062
|
+
mode === "project" && barsGroup.selectAll(".bar-head").data(data).enter().append("path").attr("class", "bar-head").attr("fill", (d) => d.color).attr("d", (d, i) => {
|
|
5063
|
+
const x = newXScale(getAdjustedStart(d));
|
|
5064
|
+
const y = getYPosition(i);
|
|
5065
|
+
const barWidth = newXScale(getAdjustedEnd(d)) - newXScale(getAdjustedStart(d));
|
|
5066
|
+
const headWidth = Math.min(barWidth * 0.5, 20);
|
|
5067
|
+
return roundedRectPath(
|
|
5068
|
+
x,
|
|
5069
|
+
y,
|
|
5070
|
+
headWidth,
|
|
5071
|
+
renderBarHeight,
|
|
5072
|
+
borderRadius
|
|
5073
|
+
);
|
|
5074
|
+
});
|
|
5075
|
+
}
|
|
5096
5076
|
const labels = group.append("g").attr("class", "labels");
|
|
5097
|
-
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-
|
|
5077
|
+
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");
|
|
5098
5078
|
labelSelection.each(function(d) {
|
|
5099
5079
|
const barWidth = newXScale(getAdjustedEnd(d)) - newXScale(getAdjustedStart(d));
|
|
5100
5080
|
const headWidth = Math.min(barWidth * 0.5, 20);
|
|
@@ -5117,8 +5097,17 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5117
5097
|
const timeBuckets = buildTimeBuckets(newXScale.domain());
|
|
5118
5098
|
const headersGroupLayer1 = chartGroup.append("g");
|
|
5119
5099
|
const headersGroupLayer2 = chartGroup.append("g");
|
|
5120
|
-
drawHeaders(
|
|
5121
|
-
|
|
5100
|
+
drawHeaders(
|
|
5101
|
+
headersGroupLayer1,
|
|
5102
|
+
headersGroupLayer2,
|
|
5103
|
+
newXScale,
|
|
5104
|
+
timeBuckets
|
|
5105
|
+
);
|
|
5106
|
+
const gridlineData = getGridlineData(
|
|
5107
|
+
viewMode,
|
|
5108
|
+
timeBuckets,
|
|
5109
|
+
newXScale.domain()
|
|
5110
|
+
);
|
|
5122
5111
|
drawGridlines(headersGroupLayer2, gridlineData, newXScale);
|
|
5123
5112
|
drawRowSeparators(chartGroup, getYPosition);
|
|
5124
5113
|
drawBarsAndLabels(chartGroup, newXScale, getYPosition);
|
|
@@ -5136,7 +5125,6 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5136
5125
|
}, [
|
|
5137
5126
|
data,
|
|
5138
5127
|
width,
|
|
5139
|
-
height,
|
|
5140
5128
|
viewMode,
|
|
5141
5129
|
barHeight,
|
|
5142
5130
|
barSpacing,
|
|
@@ -5147,13 +5135,13 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5147
5135
|
return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5148
5136
|
"div",
|
|
5149
5137
|
{
|
|
5138
|
+
className: "body-1",
|
|
5150
5139
|
style: {
|
|
5151
5140
|
display: "flex",
|
|
5152
5141
|
flexDirection: "column",
|
|
5153
|
-
padding: "20px",
|
|
5154
5142
|
width: `${width}px`,
|
|
5155
|
-
height:
|
|
5156
|
-
border: "1px solid #
|
|
5143
|
+
height: `587px`,
|
|
5144
|
+
border: "1px solid #E9E9E9",
|
|
5157
5145
|
borderRadius: "10px",
|
|
5158
5146
|
backgroundColor: "#fff",
|
|
5159
5147
|
overflow: "hidden"
|
|
@@ -5169,49 +5157,69 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5169
5157
|
position: "relative"
|
|
5170
5158
|
},
|
|
5171
5159
|
children: [
|
|
5172
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5160
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "z-2", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5161
|
+
RowOverlay,
|
|
5162
|
+
{
|
|
5163
|
+
data: data.length > 10 ? data : ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"],
|
|
5164
|
+
barHeight,
|
|
5165
|
+
barSpacing,
|
|
5166
|
+
totalHeaderHeight
|
|
5167
|
+
}
|
|
5168
|
+
) }),
|
|
5173
5169
|
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
5174
5170
|
"div",
|
|
5175
5171
|
{
|
|
5176
5172
|
ref: leftPanelRef,
|
|
5173
|
+
className: "border-r",
|
|
5177
5174
|
style: {
|
|
5178
5175
|
width: "520px",
|
|
5179
5176
|
minWidth: "500px",
|
|
5180
5177
|
display: "flex",
|
|
5181
5178
|
flexDirection: "column",
|
|
5182
5179
|
backgroundColor: "#fff",
|
|
5183
|
-
borderRight: "1px solid #ddd",
|
|
5184
5180
|
zIndex: 2
|
|
5185
5181
|
},
|
|
5186
5182
|
children: [
|
|
5187
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
5197
|
-
|
|
5198
|
-
|
|
5199
|
-
|
|
5200
|
-
|
|
5201
|
-
|
|
5202
|
-
|
|
5203
|
-
|
|
5204
|
-
|
|
5183
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { ref: dataContainerRef, children: [
|
|
5184
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
|
|
5185
|
+
"div",
|
|
5186
|
+
{
|
|
5187
|
+
className: "grid body-2 grid-cols-[1fr_100px_130px] gap-2 px-8 border-b bg-white",
|
|
5188
|
+
style: {
|
|
5189
|
+
height: `${totalHeaderHeight}px`,
|
|
5190
|
+
marginBottom: "10px",
|
|
5191
|
+
position: "sticky",
|
|
5192
|
+
top: 0,
|
|
5193
|
+
alignItems: "center",
|
|
5194
|
+
zIndex: 5
|
|
5195
|
+
},
|
|
5196
|
+
children: [
|
|
5197
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { children: "\u0E42\u0E04\u0E23\u0E07\u0E01\u0E32\u0E23" }),
|
|
5198
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { children: "\u0E01\u0E33\u0E2B\u0E19\u0E14\u0E2A\u0E48\u0E07" }),
|
|
5199
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { children: "\u0E2A\u0E16\u0E32\u0E19\u0E30" })
|
|
5200
|
+
]
|
|
5201
|
+
}
|
|
5202
|
+
),
|
|
5203
|
+
data.map((element) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5204
|
+
ProjectRow,
|
|
5205
|
+
{
|
|
5206
|
+
mode,
|
|
5207
|
+
element,
|
|
5208
|
+
barHeight,
|
|
5209
|
+
barSpacing
|
|
5205
5210
|
},
|
|
5206
|
-
|
|
5207
|
-
|
|
5208
|
-
|
|
5209
|
-
|
|
5210
|
-
|
|
5211
|
-
|
|
5211
|
+
element.id
|
|
5212
|
+
))
|
|
5213
|
+
] }),
|
|
5214
|
+
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { className: "z-3", children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
|
|
5215
|
+
RowOverlay,
|
|
5216
|
+
{
|
|
5217
|
+
data,
|
|
5218
|
+
barHeight,
|
|
5219
|
+
barSpacing,
|
|
5220
|
+
totalHeaderHeight
|
|
5212
5221
|
}
|
|
5213
|
-
)
|
|
5214
|
-
/* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { ref: dataContainerRef, children: data.map((element) => /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(ProjectRow, { element, barHeight, barSpacing }, element.id)) })
|
|
5222
|
+
) })
|
|
5215
5223
|
]
|
|
5216
5224
|
}
|
|
5217
5225
|
),
|
|
@@ -5246,7 +5254,7 @@ var GanttChart = ({ data, width, height }) => {
|
|
|
5246
5254
|
};
|
|
5247
5255
|
|
|
5248
5256
|
// src/CardKPI/CardKPI/CardKPI.tsx
|
|
5249
|
-
var
|
|
5257
|
+
var import_icons_react16 = require("@tabler/icons-react");
|
|
5250
5258
|
var import_react25 = require("react");
|
|
5251
5259
|
var import_jsx_runtime49 = require("react/jsx-runtime");
|
|
5252
5260
|
function KPIRow({ item }) {
|
|
@@ -5257,7 +5265,7 @@ function KPIRow({ item }) {
|
|
|
5257
5265
|
children: [
|
|
5258
5266
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { className: "line-clamp-2", children: item.textValue }),
|
|
5259
5267
|
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)(
|
|
5268
|
+
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_react16.IconCheckbox, { className: "text-green-500 flex justify-center w-full", size: 30 }) : /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(import_icons_react16.IconSquare, { className: "text-gray-200 flex justify-center w-full", size: 30 }) })
|
|
5261
5269
|
]
|
|
5262
5270
|
}
|
|
5263
5271
|
);
|
|
@@ -5293,7 +5301,7 @@ function CardKPI({
|
|
|
5293
5301
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)(ProgressBar, { percent: overallPercent, type: "line", checkpoints: [0] })
|
|
5294
5302
|
] }),
|
|
5295
5303
|
/* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("div", { className: "border-b", children: [
|
|
5296
|
-
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "body-2 ", children: "\
|
|
5304
|
+
/* @__PURE__ */ (0, import_jsx_runtime49.jsx)("span", { className: "body-2 ", children: "\u0E01\u0E25\u0E38\u0E48\u0E21\u0E40\u0E1B\u0E49\u0E32\u0E2B\u0E21\u0E32\u0E22" }),
|
|
5297
5305
|
indicator.filter((ind) => ind.indicatorType === "TARGET").map((item, index) => {
|
|
5298
5306
|
if (index === 2) return;
|
|
5299
5307
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(KPIRow, { item });
|
|
@@ -5306,9 +5314,8 @@ function CardKPI({
|
|
|
5306
5314
|
return /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(KPIRow, { item });
|
|
5307
5315
|
})
|
|
5308
5316
|
] }),
|
|
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
5317
|
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
|
-
|
|
5318
|
+
import_icons_react16.IconDots,
|
|
5312
5319
|
{
|
|
5313
5320
|
className: "cursor-pointer",
|
|
5314
5321
|
onClick: () => setIsOpen(true)
|