@esic-lab/data-core-ui 0.0.44 → 0.0.46

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.mjs CHANGED
@@ -2424,7 +2424,7 @@ function SelectField({
2424
2424
  Select,
2425
2425
  {
2426
2426
  showSearch: true,
2427
- value,
2427
+ value: value ? value : void 0,
2428
2428
  defaultValue,
2429
2429
  onChange,
2430
2430
  className: `body-1 flex justify-center w-full ${className ?? ""}`,
@@ -2495,7 +2495,7 @@ function SelectFieldGroup({
2495
2495
  Select2,
2496
2496
  {
2497
2497
  showSearch: true,
2498
- value,
2498
+ value: value ? value : void 0,
2499
2499
  defaultValue,
2500
2500
  onChange,
2501
2501
  className: `body-1 flex justify-center w-full ${className ?? ""}`,
@@ -2582,7 +2582,7 @@ function SelectFieldStatus({
2582
2582
  {
2583
2583
  disabled,
2584
2584
  suffixIcon: /* @__PURE__ */ jsx29(DownOutlined, { style: { color: value ? "#fff" : "#D9D9D9" } }),
2585
- value,
2585
+ value: value ? value : void 0,
2586
2586
  onChange,
2587
2587
  className: `body-3 custom-select flex justify-center w-full ${className ?? ""}`,
2588
2588
  placeholder,
@@ -2649,7 +2649,7 @@ function SelectFieldStatusReport({
2649
2649
  {
2650
2650
  disabled,
2651
2651
  suffixIcon: /* @__PURE__ */ jsx30(DownOutlined2, { style: { color: value ? "#fff" : "#D9D9D9" } }),
2652
- value,
2652
+ value: value ? value : void 0,
2653
2653
  onChange,
2654
2654
  className: `body-3 custom-select flex justify-center w-full ${className ?? ""}`,
2655
2655
  placeholder,
@@ -2721,7 +2721,7 @@ function SelectFieldTag({
2721
2721
  mode: "tags",
2722
2722
  className: `body-1 flex justify-center w-full ${className ?? ""}`,
2723
2723
  placeholder,
2724
- value,
2724
+ value: value ? value : void 0,
2725
2725
  onChange: handleChange,
2726
2726
  onSearch: handleSearch,
2727
2727
  filterOption: (input, option) => {
@@ -2791,7 +2791,7 @@ function SelectCustom({
2791
2791
  /* @__PURE__ */ jsx32(
2792
2792
  Select6,
2793
2793
  {
2794
- value,
2794
+ value: value ? value : void 0,
2795
2795
  onChange: handleChange,
2796
2796
  placeholder,
2797
2797
  options: filteredOptions,
@@ -2800,16 +2800,29 @@ function SelectCustom({
2800
2800
  }
2801
2801
  ),
2802
2802
  error && /* @__PURE__ */ jsx32("p", { className: "text-red-500 caption-1", children: error }),
2803
- /* @__PURE__ */ jsx32("div", { className: "w-full p-[2px] overflow-y-auto", children: valueList.map((v, index) => /* @__PURE__ */ jsxs28("div", { className: "flex justify-between items-center py-[2px] body-1", children: [
2804
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-row gap-[8px]", children: [
2805
- /* @__PURE__ */ jsxs28("p", { children: [
2806
- index + 1,
2807
- "."
2808
- ] }),
2809
- /* @__PURE__ */ jsx32("p", { children: v })
2810
- ] }),
2811
- /* @__PURE__ */ jsx32(IconTrash, { className: "cursor-pointer", onClick: () => handleDelete(v) })
2812
- ] }, index)) })
2803
+ /* @__PURE__ */ jsx32("div", { className: "w-full p-[2px] overflow-y-auto", children: valueList.map((v, index) => /* @__PURE__ */ jsxs28(
2804
+ "div",
2805
+ {
2806
+ className: "flex justify-between items-center py-[2px] body-1",
2807
+ children: [
2808
+ /* @__PURE__ */ jsxs28("div", { className: "flex flex-row gap-[8px]", children: [
2809
+ /* @__PURE__ */ jsxs28("p", { children: [
2810
+ index + 1,
2811
+ "."
2812
+ ] }),
2813
+ /* @__PURE__ */ jsx32("p", { children: v })
2814
+ ] }),
2815
+ /* @__PURE__ */ jsx32(
2816
+ IconTrash,
2817
+ {
2818
+ className: "cursor-pointer",
2819
+ onClick: () => handleDelete(v)
2820
+ }
2821
+ )
2822
+ ]
2823
+ },
2824
+ index
2825
+ )) })
2813
2826
  ] })
2814
2827
  }
2815
2828
  );
@@ -3891,6 +3904,406 @@ var FilterPopUp = (filter) => {
3891
3904
  ] }) : void 0
3892
3905
  ] });
3893
3906
  };
3907
+
3908
+ // src/ProfileSelect/ProfileSelect/ProfileSelect.tsx
3909
+ import { useEffect as useEffect7, useRef as useRef6, useState as useState17 } from "react";
3910
+ import { IconSearch, IconUsers, IconX as IconX4 } from "@tabler/icons-react";
3911
+ import { Input as Input5 } from "antd";
3912
+ import { Fragment as Fragment8, jsx as jsx42, jsxs as jsxs36 } from "react/jsx-runtime";
3913
+ function ProfileSelect({
3914
+ allUser,
3915
+ assignUser,
3916
+ mode,
3917
+ onUpdateAssignUser
3918
+ }) {
3919
+ const [maxVisible, setMaxVisible] = useState17(4);
3920
+ const [userNotAssign, setUserNotAssign] = useState17([]);
3921
+ const [search, setSearch] = useState17("");
3922
+ const [isShowSelect, setIsShowSelect] = useState17(false);
3923
+ const containerRef = useRef6(null);
3924
+ const selectRef = useRef6(null);
3925
+ const avatarSize = 30;
3926
+ const spacing = 8;
3927
+ useEffect7(() => {
3928
+ const handler = (e) => {
3929
+ if (!selectRef?.current?.contains(e.target) && !containerRef?.current?.contains(e.target)) {
3930
+ setIsShowSelect(false);
3931
+ }
3932
+ };
3933
+ document.addEventListener("mousedown", handler);
3934
+ return () => {
3935
+ document.removeEventListener("mousedown", handler);
3936
+ };
3937
+ }, []);
3938
+ useEffect7(() => {
3939
+ if (!containerRef.current) return;
3940
+ const updateWidth = () => {
3941
+ if (containerRef.current) {
3942
+ const rect = containerRef.current.getBoundingClientRect();
3943
+ const count = Math.floor(rect.width / (avatarSize + spacing));
3944
+ setMaxVisible(Math.max(1, count));
3945
+ }
3946
+ };
3947
+ const resizeObserver = new ResizeObserver(updateWidth);
3948
+ resizeObserver.observe(containerRef.current);
3949
+ updateWidth();
3950
+ return () => {
3951
+ resizeObserver.disconnect();
3952
+ };
3953
+ }, [allUser]);
3954
+ useEffect7(() => {
3955
+ setUserNotAssign(
3956
+ allUser.filter((u) => !assignUser.some((au) => au.id === u.id))
3957
+ );
3958
+ }, [allUser, assignUser]);
3959
+ const showPlus = assignUser.length > maxVisible;
3960
+ const visibleUsers = showPlus ? assignUser.slice(0, maxVisible - 1) : assignUser;
3961
+ const extraCount = assignUser.length - (maxVisible - 1);
3962
+ const normalizedSearch = search.trim().toLowerCase();
3963
+ const filteredAssigned = normalizedSearch ? assignUser.filter(
3964
+ (u) => u.name.toLowerCase().includes(normalizedSearch)
3965
+ ) : assignUser;
3966
+ const filteredUnassigned = normalizedSearch ? userNotAssign.filter(
3967
+ (u) => u.name.toLowerCase().includes(normalizedSearch)
3968
+ ) : userNotAssign;
3969
+ return /* @__PURE__ */ jsxs36("div", { ref: containerRef, className: "relative body-1", children: [
3970
+ mode === "icon" ? /* @__PURE__ */ jsx42("button", { children: /* @__PURE__ */ jsx42(
3971
+ IconUsers,
3972
+ {
3973
+ size: 40,
3974
+ className: "p-2 border rounded cursor-pointer",
3975
+ onClick: () => setIsShowSelect(!isShowSelect)
3976
+ }
3977
+ ) }) : mode === "showAssign" ? /* @__PURE__ */ jsxs36(
3978
+ "button",
3979
+ {
3980
+ className: "w-full h-[40px] flex -space-x-2 p-2 border-1 rounded-sm",
3981
+ onClick: () => setIsShowSelect(!isShowSelect),
3982
+ children: [
3983
+ visibleUsers.map((user) => /* @__PURE__ */ jsx42("div", { className: "flex items-center cursor-point", children: /* @__PURE__ */ jsxs36("label", { className: "relative group cursor-pointer", children: [
3984
+ /* @__PURE__ */ jsx42(
3985
+ "img",
3986
+ {
3987
+ src: user.profile,
3988
+ alt: user.name,
3989
+ style: {
3990
+ width: avatarSize,
3991
+ height: avatarSize,
3992
+ borderRadius: "50%"
3993
+ },
3994
+ className: "border border-white group-hover:border-2 group-hover:border-red-500 transition"
3995
+ }
3996
+ ),
3997
+ /* @__PURE__ */ jsx42(
3998
+ "span",
3999
+ {
4000
+ className: "absolute top-0 right-0 -translate-y-2 translate-x-2 \r\n rounded-full bg-white opacity-0 group-hover:opacity-100 \r\n border-2 border-red-500 flex items-center justify-center transition",
4001
+ onClick: () => onUpdateAssignUser(user, "remove"),
4002
+ children: /* @__PURE__ */ jsx42(IconX4, { className: "w-4 h-4 text-red-500" })
4003
+ }
4004
+ )
4005
+ ] }) }, user.id)),
4006
+ showPlus && /* @__PURE__ */ jsxs36(
4007
+ "div",
4008
+ {
4009
+ className: "border border-white flex items-center justify-center bg-gray-300 text-black text-sm",
4010
+ style: {
4011
+ width: avatarSize,
4012
+ height: avatarSize,
4013
+ borderRadius: "50%"
4014
+ },
4015
+ children: [
4016
+ "+",
4017
+ extraCount
4018
+ ]
4019
+ }
4020
+ )
4021
+ ]
4022
+ }
4023
+ ) : /* @__PURE__ */ jsxs36("div", { className: "w-full h-[40px] flex -space-x-2 p-2 border-1 rounded-sm", children: [
4024
+ visibleUsers.map((user) => /* @__PURE__ */ jsx42("div", { className: "flex items-center ", children: /* @__PURE__ */ jsx42("label", { className: "relative group ", children: /* @__PURE__ */ jsx42(
4025
+ "img",
4026
+ {
4027
+ src: user.profile,
4028
+ alt: user.name,
4029
+ style: {
4030
+ width: avatarSize,
4031
+ height: avatarSize,
4032
+ borderRadius: "50%"
4033
+ },
4034
+ className: "border border-white transition"
4035
+ }
4036
+ ) }) }, user.id)),
4037
+ showPlus && /* @__PURE__ */ jsxs36(
4038
+ "div",
4039
+ {
4040
+ className: "border border-white flex items-center justify-center bg-gray-300 text-black text-sm",
4041
+ style: {
4042
+ width: avatarSize,
4043
+ height: avatarSize,
4044
+ borderRadius: "50%"
4045
+ },
4046
+ children: [
4047
+ "+",
4048
+ extraCount
4049
+ ]
4050
+ }
4051
+ )
4052
+ ] }),
4053
+ isShowSelect ? /* @__PURE__ */ jsxs36(
4054
+ "div",
4055
+ {
4056
+ className: "absolute top-12 min-w-[261px] max-w-[400px] w-full h-[314px] p-2 text-xs border-1 rounded-sm ",
4057
+ ref: selectRef,
4058
+ children: [
4059
+ /* @__PURE__ */ jsxs36("div", { className: "flex border-1 rounded-md p-2 gap-2 items-center", children: [
4060
+ /* @__PURE__ */ jsx42(IconSearch, {}),
4061
+ /* @__PURE__ */ jsx42(
4062
+ Input5,
4063
+ {
4064
+ variant: "borderless",
4065
+ placeholder: "\u0E04\u0E49\u0E19\u0E2B\u0E32\u0E0A\u0E37\u0E48\u0E2D",
4066
+ className: "body-3",
4067
+ value: search,
4068
+ onChange: (e) => setSearch(e.target.value)
4069
+ }
4070
+ )
4071
+ ] }),
4072
+ /* @__PURE__ */ jsxs36("div", { className: "overflow-y-auto h-[250px] pt-2 px-4 body-3", children: [
4073
+ filteredAssigned.length > 0 && /* @__PURE__ */ jsxs36(Fragment8, { children: [
4074
+ /* @__PURE__ */ jsx42("div", { children: "\u0E2A\u0E21\u0E32\u0E0A\u0E34\u0E01\u0E17\u0E35\u0E48\u0E40\u0E25\u0E37\u0E2D\u0E01" }),
4075
+ filteredAssigned.map((user) => /* @__PURE__ */ jsxs36(
4076
+ "button",
4077
+ {
4078
+ className: "flex items-center group my-1 w-full p-1 rounded hover:bg-gray-100",
4079
+ onClick: () => onUpdateAssignUser(user, "remove"),
4080
+ children: [
4081
+ /* @__PURE__ */ jsxs36("label", { className: "relative cursor-pointer", children: [
4082
+ /* @__PURE__ */ jsx42(
4083
+ "img",
4084
+ {
4085
+ src: user.profile,
4086
+ alt: user.name,
4087
+ style: {
4088
+ width: avatarSize,
4089
+ height: avatarSize,
4090
+ borderRadius: "50%"
4091
+ },
4092
+ className: "border-2 border-red-500"
4093
+ }
4094
+ ),
4095
+ /* @__PURE__ */ jsx42(
4096
+ "span",
4097
+ {
4098
+ className: "absolute top-0 right-0 -translate-y-2 translate-x-2 \r\n rounded-full bg-white opacity-0 group-hover:opacity-100 \r\n border-2 border-red-500 flex items-center justify-center transition",
4099
+ onClick: () => onUpdateAssignUser(user, "remove"),
4100
+ children: /* @__PURE__ */ jsx42(IconX4, { className: "text-red-500", size: 15 })
4101
+ }
4102
+ )
4103
+ ] }),
4104
+ /* @__PURE__ */ jsx42("span", { className: "ml-2", children: user.name })
4105
+ ]
4106
+ },
4107
+ user.id
4108
+ ))
4109
+ ] }),
4110
+ /* @__PURE__ */ jsx42("div", { children: "\u0E1C\u0E39\u0E49\u0E04\u0E19 " }),
4111
+ filteredUnassigned.map((user) => /* @__PURE__ */ jsxs36(
4112
+ "button",
4113
+ {
4114
+ className: "flex items-center my-1 hover:bg-gray-100 w-full p-1 rounded",
4115
+ onClick: () => onUpdateAssignUser(user),
4116
+ children: [
4117
+ /* @__PURE__ */ jsx42(
4118
+ "img",
4119
+ {
4120
+ src: user.profile,
4121
+ alt: user.name,
4122
+ style: {
4123
+ width: avatarSize,
4124
+ height: avatarSize,
4125
+ borderRadius: "50%"
4126
+ },
4127
+ className: "border "
4128
+ }
4129
+ ),
4130
+ /* @__PURE__ */ jsx42("span", { className: "ml-2", children: user.name })
4131
+ ]
4132
+ },
4133
+ user.id
4134
+ ))
4135
+ ] })
4136
+ ]
4137
+ }
4138
+ ) : null
4139
+ ] });
4140
+ }
4141
+
4142
+ // src/Button/QRCode/QRCode.tsx
4143
+ import { useEffect as useEffect8, useRef as useRef7, useState as useState18 } from "react";
4144
+ import QRCode from "qrcode";
4145
+ import { jsx as jsx43, jsxs as jsxs37 } from "react/jsx-runtime";
4146
+ var QRCodeGenerator = ({
4147
+ url,
4148
+ previewSize = 200,
4149
+ defaultExportSize = 512,
4150
+ fileBaseName = "qr-code"
4151
+ }) => {
4152
+ const canvasRef = useRef7(null);
4153
+ const [format3, setFormat] = useState18("png");
4154
+ const [exportSize, setExportSize] = useState18(defaultExportSize);
4155
+ const sizeOption = [
4156
+ {
4157
+ label: "64 x 64",
4158
+ value: "64"
4159
+ },
4160
+ {
4161
+ label: "128 x 128",
4162
+ value: "128"
4163
+ },
4164
+ {
4165
+ label: "256 x 256",
4166
+ value: "256"
4167
+ },
4168
+ {
4169
+ label: "512 x 512",
4170
+ value: "512"
4171
+ },
4172
+ {
4173
+ label: "1024 x 1024",
4174
+ value: "1024"
4175
+ },
4176
+ {
4177
+ label: "2048 x 2048",
4178
+ value: "2048"
4179
+ },
4180
+ {
4181
+ label: "4096 x 4096",
4182
+ value: "4096"
4183
+ }
4184
+ ];
4185
+ const typeOption = [
4186
+ {
4187
+ label: "PNG",
4188
+ value: "png"
4189
+ },
4190
+ {
4191
+ label: "SVG",
4192
+ value: "svg"
4193
+ },
4194
+ {
4195
+ label: "JPEG",
4196
+ value: "jpeg"
4197
+ }
4198
+ ];
4199
+ useEffect8(() => {
4200
+ if (!canvasRef.current) return;
4201
+ QRCode.toCanvas(canvasRef.current, url, { width: previewSize, margin: 1 }, (error) => {
4202
+ if (error) console.error(error);
4203
+ });
4204
+ }, [url, previewSize]);
4205
+ const download = async () => {
4206
+ try {
4207
+ if (format3 === "svg") {
4208
+ const svgString = await QRCode.toString(url, {
4209
+ type: "svg",
4210
+ width: exportSize,
4211
+ margin: 1
4212
+ });
4213
+ const blob = new Blob([svgString], { type: "image/svg+xml" });
4214
+ const objUrl = URL.createObjectURL(blob);
4215
+ triggerDownload(objUrl, `${fileBaseName}.svg`);
4216
+ URL.revokeObjectURL(objUrl);
4217
+ } else {
4218
+ const offscreen = document.createElement("canvas");
4219
+ await QRCode.toCanvas(offscreen, url, {
4220
+ width: exportSize,
4221
+ margin: 1
4222
+ });
4223
+ const mime = format3 === "png" ? "image/png" : "image/jpeg";
4224
+ const dataURL = format3 === "jpeg" ? offscreen.toDataURL(mime, 0.92) : offscreen.toDataURL(mime);
4225
+ triggerDownload(dataURL, `${fileBaseName}.${format3}`);
4226
+ }
4227
+ } catch (err) {
4228
+ console.error("Failed to generate QR export:", err);
4229
+ alert("Sorry, something went wrong creating the download.");
4230
+ }
4231
+ };
4232
+ const triggerDownload = (href, filename) => {
4233
+ const a = document.createElement("a");
4234
+ a.href = href;
4235
+ a.download = filename;
4236
+ document.body.appendChild(a);
4237
+ a.click();
4238
+ a.remove();
4239
+ };
4240
+ return /* @__PURE__ */ jsxs37("div", { style: { display: "inline-flex", flexDirection: "column", gap: 8 }, className: "justify-center items-center", children: [
4241
+ url === "" ? /* @__PURE__ */ jsx43("div", { className: "border-1 p-2 mb-2", style: { width: `${previewSize}px`, height: `${previewSize}px` } }) : /* @__PURE__ */ jsx43("canvas", { ref: canvasRef, className: "border-1 p-2 mb-2" }),
4242
+ /* @__PURE__ */ jsxs37(
4243
+ "div",
4244
+ {
4245
+ style: {
4246
+ display: "flex",
4247
+ gap: 8,
4248
+ alignItems: "center",
4249
+ flexWrap: "wrap"
4250
+ },
4251
+ className: "flex-col",
4252
+ children: [
4253
+ /* @__PURE__ */ jsxs37("div", { className: "flex gap-2 mx-2", children: [
4254
+ /* @__PURE__ */ jsx43("label", { className: "border-1 p-2 rounded-md flex flex-col w-1/2 text-sm text-gray-400", children: /* @__PURE__ */ jsx43(
4255
+ SelectField,
4256
+ {
4257
+ label: "\u0E23\u0E39\u0E1B\u0E41\u0E1A\u0E1A",
4258
+ value: format3,
4259
+ onChange: (e) => setFormat(e.target.value),
4260
+ options: typeOption
4261
+ }
4262
+ ) }),
4263
+ /* @__PURE__ */ jsx43("label", { className: "border-1 p-2 rounded-md flex flex-col w-1/2 text-sm text-gray-400", children: /* @__PURE__ */ jsx43(
4264
+ SelectField,
4265
+ {
4266
+ label: "\u0E02\u0E19\u0E32\u0E14 (px)",
4267
+ value: exportSize,
4268
+ onChange: (e) => setExportSize(Number(e.target.value)),
4269
+ options: sizeOption
4270
+ }
4271
+ ) })
4272
+ ] }),
4273
+ /* @__PURE__ */ jsx43(PrimaryButton, { onClick: download, disabled: url === "", textColor: "white", title: "\u0E14\u0E32\u0E27\u0E42\u0E2B\u0E25\u0E14\u0E23\u0E2B\u0E31\u0E2A QR" })
4274
+ ]
4275
+ }
4276
+ )
4277
+ ] });
4278
+ };
4279
+
4280
+ // src/TabPropject/Tabproject/TabProject.tsx
4281
+ import { Tabs } from "antd";
4282
+ import { jsx as jsx44, jsxs as jsxs38 } from "react/jsx-runtime";
4283
+ function TabProject({ tabOption, now, onChange }) {
4284
+ return /* @__PURE__ */ jsx44(
4285
+ Tabs,
4286
+ {
4287
+ activeKey: now,
4288
+ items: tabOption.map((item, i) => {
4289
+ return {
4290
+ key: item.key,
4291
+ label: /* @__PURE__ */ jsxs38(
4292
+ "button",
4293
+ {
4294
+ className: "tab-label flex gap-2 items-center body-1",
4295
+ onClick: () => onChange(item.key),
4296
+ children: [
4297
+ item.icon,
4298
+ /* @__PURE__ */ jsx44("span", { children: item.label })
4299
+ ]
4300
+ }
4301
+ )
4302
+ };
4303
+ })
4304
+ }
4305
+ );
4306
+ }
3894
4307
  export {
3895
4308
  AntDModal,
3896
4309
  AntDataTable,
@@ -3914,7 +4327,9 @@ export {
3914
4327
  Loader,
3915
4328
  MenuNavBar,
3916
4329
  PrimaryButton,
4330
+ ProfileSelect,
3917
4331
  ProgressBar,
4332
+ QRCodeGenerator,
3918
4333
  Radio,
3919
4334
  RadioGroup,
3920
4335
  SecondaryButton,
@@ -3928,6 +4343,7 @@ export {
3928
4343
  SortFilter,
3929
4344
  Switch,
3930
4345
  SwitchSelect,
4346
+ TabProject,
3931
4347
  TabSelectionButton,
3932
4348
  TextAreaInput,
3933
4349
  TextInput,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@esic-lab/data-core-ui",
3
- "version": "0.0.44",
3
+ "version": "0.0.46",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",