pixelize-design-library 2.2.121 → 2.2.122

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.
@@ -176,6 +176,7 @@ var getFormatForPickerType = function (pickerType, dateFormat) {
176
176
  if (pickerType === "time") {
177
177
  var hasDate = /[dDmMyY]/.test(dateFormat);
178
178
  if (hasDate) {
179
+ // eslint-disable-next-line no-useless-escape
179
180
  var timeMatch = dateFormat.match(/[dDmMyY\/\-\s\.]+\s*([hHmsSaA\/\-\s:]+)$/);
180
181
  if (timeMatch && timeMatch[1]) {
181
182
  return timeMatch[1].trim();
@@ -185,27 +186,24 @@ var getFormatForPickerType = function (pickerType, dateFormat) {
185
186
  }
186
187
  return dateFormat;
187
188
  };
188
- var usesAmPm = function (format) { return /(^|[^a-zA-Z])a([^a-zA-Z]|$)/i.test(format); };
189
- var sanitizeTimeInput = function (raw, format) {
190
- var _a;
191
- var ampm = usesAmPm(format);
192
- var only = raw.replace(/[^0-9aApPmM:\s]/g, "");
193
- if (/H{1,2}:m{1,2}/.test(format) || /h{1,2}:m{1,2}/i.test(format)) {
194
- var digits = only.replace(/[^0-9]/g, "");
195
- var hh = digits.slice(0, 2);
196
- var mm = digits.slice(2, 4);
197
- var out = hh;
198
- if (mm.length)
199
- out += ":" + mm;
200
- if (ampm) {
201
- var suffix = (((_a = only.match(/(am|pm)/i)) === null || _a === void 0 ? void 0 : _a[0]) || "").toUpperCase();
202
- if (suffix)
203
- out += " " + suffix;
204
- }
205
- return out;
206
- }
207
- return only;
208
- };
189
+ // const usesAmPm = (format: string): boolean => /(^|[^a-zA-Z])a([^a-zA-Z]|$)/i.test(format);
190
+ // const sanitizeTimeInput = (raw: string, format: string): string => {
191
+ // const ampm = usesAmPm(format);
192
+ // const only = raw.replace(/[^0-9aApPmM:\s]/g, "");
193
+ // if (/H{1,2}:m{1,2}/.test(format) || /h{1,2}:m{1,2}/i.test(format)) {
194
+ // const digits = only.replace(/[^0-9]/g, "");
195
+ // const hh = digits.slice(0, 2);
196
+ // const mm = digits.slice(2, 4);
197
+ // let out = hh;
198
+ // if (mm.length) out += ":" + mm;
199
+ // if (ampm) {
200
+ // const suffix = (only.match(/(am|pm)/i)?.[0] || "").toUpperCase();
201
+ // if (suffix) out += " " + suffix;
202
+ // }
203
+ // return out;
204
+ // }
205
+ // return only;
206
+ // };
209
207
  var normalizeTimeBuffer = function (tokenChar, rawBuffer, segmentLength, is12Hour) {
210
208
  if (!tokenChar)
211
209
  return { value: rawBuffer, completed: rawBuffer.length >= segmentLength };
@@ -215,7 +213,7 @@ var normalizeTimeBuffer = function (tokenChar, rawBuffer, segmentLength, is12Hou
215
213
  return { value: buf, completed: buf.length >= segmentLength };
216
214
  }
217
215
  if (t === "h") {
218
- var maxHour = is12Hour ? 12 : 24;
216
+ // const maxHour = is12Hour ? 12 : 24;
219
217
  if (buf.length === 1) {
220
218
  var d = parseInt(buf[0], 10);
221
219
  var firstMax = is12Hour ? 1 : 2;
@@ -338,7 +336,7 @@ var SingleDatePicker = function (props) {
338
336
  var _t = (0, react_1.useState)(""), inputValue = _t[0], setInputValue = _t[1];
339
337
  var _u = (0, react_1.useState)(false), isTyping = _u[0], setIsTyping = _u[1];
340
338
  var _v = (0, react_1.useState)(false), isMaskActive = _v[0], setIsMaskActive = _v[1];
341
- var _w = (0, react_1.useState)(0), currentSegmentIndex = _w[0], setCurrentSegmentIndex = _w[1];
339
+ var _w = (0, react_1.useState)(0), setCurrentSegmentIndex = _w[1];
342
340
  var lastSegmentIndexRef = (0, react_1.useRef)(0);
343
341
  var resetCommitGuardAndOpen = function () {
344
342
  didCommitRef.current = false;
@@ -542,7 +540,7 @@ var SingleDatePicker = function (props) {
542
540
  document.removeEventListener("mousedown", handleClickOutside, true);
543
541
  document.removeEventListener("click", handleClickOutside, true);
544
542
  };
545
- }, [isOpen, tempDate, activeFormat]);
543
+ }, [isOpen, tempDate, activeFormat]); // eslint-disable-line react-hooks/exhaustive-deps
546
544
  var ensureMaskValue = (0, react_1.useCallback)(function () {
547
545
  var _a, _b, _c, _d;
548
546
  if (!enableMask) {
@@ -30,7 +30,6 @@ exports.TimeOnlyPicker = void 0;
30
30
  var react_1 = __importStar(require("react"));
31
31
  var react_2 = require("@chakra-ui/react");
32
32
  var date_fns_1 = require("date-fns");
33
- var useCustomTheme_1 = require("../../Theme/useCustomTheme");
34
33
  var FormLabel_1 = require("../Common/FormLabel");
35
34
  var HelperText_1 = __importDefault(require("../Common/HelperText"));
36
35
  var ErrorMessage_1 = __importDefault(require("../Common/ErrorMessage"));
@@ -41,16 +40,15 @@ var formatToPlaceholder = function (formatStr) {
41
40
  };
42
41
  var TimeOnlyPicker = function (props) {
43
42
  var _a;
44
- var id = props.id, name = props.name, label = props.label, isRequired = props.isRequired, isInformation = props.isInformation, informationMessage = props.informationMessage, error = props.error, errorMessage = props.errorMessage, helperText = props.helperText, placeholderText = props.placeholderText, _b = props.dateFormat, dateFormat = _b === void 0 ? "HH:mm" : _b, _c = props.autoComplete, autoComplete = _c === void 0 ? "off" : _c, disabled = props.disabled, _d = props.width, width = _d === void 0 ? "100%" : _d, _e = props.disableToday, disableToday = _e === void 0 ? false : _e;
45
- var theme = (0, useCustomTheme_1.useCustomTheme)();
46
- var _f = (0, react_2.useDisclosure)(), isOpen = _f.isOpen, onOpen = _f.onOpen, onClose = _f.onClose;
43
+ var id = props.id, label = props.label, isRequired = props.isRequired, isInformation = props.isInformation, informationMessage = props.informationMessage, error = props.error, errorMessage = props.errorMessage, helperText = props.helperText, placeholderText = props.placeholderText, _b = props.dateFormat, dateFormat = _b === void 0 ? "HH:mm" : _b, disabled = props.disabled, _c = props.width, width = _c === void 0 ? "100%" : _c, _d = props.disableToday, disableToday = _d === void 0 ? false : _d;
44
+ var _e = (0, react_2.useDisclosure)(), isOpen = _e.isOpen, onOpen = _e.onOpen, onClose = _e.onClose;
47
45
  var popoverRef = (0, react_1.useRef)(null);
48
46
  var triggerRef = (0, react_1.useRef)(null);
49
47
  var inputWrapperRef = (0, react_1.useRef)(null);
50
48
  var today = new Date();
51
49
  var tomorrow = (0, date_fns_1.addDays)(today, 1);
52
50
  var selectedDate = ((_a = props.value) !== null && _a !== void 0 ? _a : props.selectedDate);
53
- var _g = (0, react_1.useState)(selectedDate ? new Date(selectedDate) : null), tempDate = _g[0], setTempDate = _g[1];
51
+ var _f = (0, react_1.useState)(selectedDate ? new Date(selectedDate) : null), tempDate = _f[0], setTempDate = _f[1];
54
52
  (0, react_1.useEffect)(function () {
55
53
  setTempDate(selectedDate ? new Date(selectedDate) : null);
56
54
  }, [selectedDate]);
@@ -45,7 +45,7 @@ var TimePicker = function (_a) {
45
45
  if (is12HourFormat) {
46
46
  setAmpm(rawHour >= 12 ? "PM" : "AM");
47
47
  }
48
- }, [date, is12HourFormat]);
48
+ }, [date, is12HourFormat]); // eslint-disable-line react-hooks/exhaustive-deps
49
49
  var convertTo24Hour = function (hr, meridiem) {
50
50
  if (meridiem === "AM")
51
51
  return hr === 12 ? 0 : hr;
@@ -120,9 +120,9 @@ var TimePickerInput = function (_a) {
120
120
  var inputRef = (0, react_1.useRef)(null);
121
121
  var _c = (0, react_1.useState)(""), digits = _c[0], setDigits = _c[1];
122
122
  var digitsRef = (0, react_1.useRef)("");
123
- var _d = (0, react_1.useState)(false), isFocused = _d[0], setIsFocused = _d[1];
123
+ var _d = (0, react_1.useState)(false), setIsFocused = _d[1];
124
124
  var isFocusedRef = (0, react_1.useRef)(false);
125
- var _e = (0, react_1.useState)("hour"), activeSegment = _e[0], setActiveSegment = _e[1];
125
+ var _e = (0, react_1.useState)("hour"), setActiveSegment = _e[1];
126
126
  var is12Hour = (0, react_1.useMemo)(function () { return /h{1,2}/i.test(dateFormat) && !/H{1,2}/.test(dateFormat); }, [dateFormat]);
127
127
  var placeholderText = (0, react_1.useMemo)(function () { return placeholder || formatToPlaceholder(dateFormat); }, [placeholder, dateFormat]);
128
128
  var ampmRef = (0, react_1.useRef)("AM");
@@ -61,6 +61,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
61
61
  Object.defineProperty(exports, "__esModule", { value: true });
62
62
  var react_1 = __importStar(require("react"));
63
63
  var react_2 = require("@chakra-ui/react");
64
+ // eslint-disable-next-line no-control-regex, no-useless-escape
64
65
  var emailRegex = /^(?:[a-zA-Z0-9_'^&\/+{}=?`|~!-]+(?:\.[a-zA-Z0-9_'^&\/+{}=?`|~!-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-zA-Z-]*[a-zA-Z]:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]+)\])$/;
65
66
  function FeedbackForm(props) {
66
67
  var _this = this;
@@ -1,11 +1,12 @@
1
1
  import React from "react";
2
2
  import { Account, KanbanBoardProps } from "./KanbanBoardProps";
3
- declare const AccountCard: ({ account, index, onDelete, onOpen, isExpanded, onToggleExpand, }: {
3
+ declare const AccountCard: ({ account, index, onDelete, onOpen, isExpanded, onToggleExpand, isDeletable, }: {
4
4
  account: Account;
5
5
  index: number;
6
6
  onDelete: KanbanBoardProps["onDelete"];
7
7
  onOpen: KanbanBoardProps["onOpen"];
8
8
  isExpanded?: boolean | undefined;
9
9
  onToggleExpand?: (() => void) | undefined;
10
+ isDeletable?: boolean | undefined;
10
11
  }) => React.JSX.Element;
11
12
  export default AccountCard;
@@ -34,9 +34,9 @@ var AccountRow_1 = __importDefault(require("./AccountRow"));
34
34
  var excludeKeys = ["id", "details"];
35
35
  var AccountCard = function (_a) {
36
36
  var _b, _c, _d, _e, _f, _g;
37
- var account = _a.account, index = _a.index, onDelete = _a.onDelete, onOpen = _a.onOpen, _h = _a.isExpanded, isExpanded = _h === void 0 ? false : _h, onToggleExpand = _a.onToggleExpand;
37
+ var account = _a.account, index = _a.index, onDelete = _a.onDelete, onOpen = _a.onOpen, _h = _a.isExpanded, isExpanded = _h === void 0 ? false : _h, onToggleExpand = _a.onToggleExpand, _j = _a.isDeletable, isDeletable = _j === void 0 ? true : _j;
38
38
  var colors = (0, useCustomTheme_1.useCustomTheme)().colors;
39
- var _j = (0, react_1.useState)(false), showMore = _j[0], setShowMore = _j[1];
39
+ var _k = (0, react_1.useState)(false), showMore = _k[0], setShowMore = _k[1];
40
40
  var keys = Object.keys(account).filter(function (key) { return typeof account[key] === "string" && !excludeKeys.includes(key); });
41
41
  var visibleKeys = isExpanded ? keys : keys.slice(0, 4);
42
42
  // Handle the show more/less toggle
@@ -57,9 +57,9 @@ var AccountCard = function (_a) {
57
57
  isExpanded ? react_1.default.createElement(lucide_react_1.ChevronUp, { size: 14 }) : react_1.default.createElement(lucide_react_1.ChevronDown, { size: 14 }))),
58
58
  react_1.default.createElement(react_2.Spacer, null),
59
59
  react_1.default.createElement(react_2.HStack, { spacing: 2 },
60
- react_1.default.createElement(react_2.Tooltip, { label: "Delete" },
61
- react_1.default.createElement(lucide_react_1.Trash2, { size: 16, color: (_f = colors === null || colors === void 0 ? void 0 : colors.red) === null || _f === void 0 ? void 0 : _f[600], onClick: function () { return onDelete === null || onDelete === void 0 ? void 0 : onDelete(account); }, cursor: "pointer" })),
60
+ isDeletable && (react_1.default.createElement(react_2.Tooltip, { label: "Delete" },
61
+ react_1.default.createElement(lucide_react_1.Trash2, { size: 16, color: (_f = colors === null || colors === void 0 ? void 0 : colors.red) === null || _f === void 0 ? void 0 : _f[600], onClick: function () { return onDelete === null || onDelete === void 0 ? void 0 : onDelete(account); }, cursor: "pointer", "aria-label": "Delete" }))),
62
62
  react_1.default.createElement(react_2.Tooltip, { label: "Open" },
63
- react_1.default.createElement(lucide_react_1.ExternalLink, { size: 16, color: (_g = colors === null || colors === void 0 ? void 0 : colors.blue) === null || _g === void 0 ? void 0 : _g[600], onClick: function () { return onOpen === null || onOpen === void 0 ? void 0 : onOpen(account); }, cursor: "pointer" })))))));
63
+ react_1.default.createElement(lucide_react_1.ExternalLink, { size: 16, color: (_g = colors === null || colors === void 0 ? void 0 : colors.blue) === null || _g === void 0 ? void 0 : _g[600], onClick: function () { return onOpen === null || onOpen === void 0 ? void 0 : onOpen(account); }, cursor: "pointer", "aria-label": "Open" })))))));
64
64
  };
65
65
  exports.default = AccountCard;
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ var react_1 = __importDefault(require("react"));
18
+ var react_2 = require("@testing-library/react");
19
+ require("@testing-library/jest-dom");
20
+ var AccountCard_1 = __importDefault(require("./AccountCard"));
21
+ jest.mock("../../Theme/useCustomTheme", function () { return ({
22
+ useCustomTheme: function () { return ({
23
+ colors: {
24
+ background: { 500: "#fff" },
25
+ gray: { 200: "#eee", 700: "#333" },
26
+ primary: { 500: "#3182ce" },
27
+ red: { 600: "#e53e3e" },
28
+ blue: { 600: "#3182ce" },
29
+ text: {},
30
+ },
31
+ }); },
32
+ }); });
33
+ var mockAccount = {
34
+ id: "1",
35
+ name: "Test Account",
36
+ email: "test@example.com",
37
+ };
38
+ var defaultProps = {
39
+ account: mockAccount,
40
+ index: 0,
41
+ onDelete: jest.fn(),
42
+ onOpen: jest.fn(),
43
+ };
44
+ describe("AccountCard – permissions", function () {
45
+ it("renders the delete icon when isDeletable is true (default)", function () {
46
+ (0, react_2.render)(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps)));
47
+ expect(react_2.screen.getByLabelText("Delete")).toBeInTheDocument();
48
+ });
49
+ it("hides the delete icon when isDeletable is false", function () {
50
+ (0, react_2.render)(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps, { isDeletable: false })));
51
+ expect(react_2.screen.queryByLabelText("Delete")).not.toBeInTheDocument();
52
+ });
53
+ it("renders the open (ExternalLink) icon regardless of isDeletable", function () {
54
+ (0, react_2.render)(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps, { isDeletable: false })));
55
+ expect(react_2.screen.getByLabelText("Open")).toBeInTheDocument();
56
+ });
57
+ it("calls onDelete when delete icon is clicked and isDeletable is true", function () {
58
+ var onDelete = jest.fn();
59
+ (0, react_2.render)(react_1.default.createElement(AccountCard_1.default, __assign({}, defaultProps, { onDelete: onDelete, isDeletable: true })));
60
+ react_2.screen.getByLabelText("Delete").click();
61
+ expect(onDelete).toHaveBeenCalledWith(mockAccount);
62
+ });
63
+ });
@@ -1,4 +1,4 @@
1
1
  import React from "react";
2
2
  import { KanbanBoardProps } from "./KanbanBoardProps";
3
- declare const KanbanBoard: ({ data, onDrag, onDelete, onOpen, onColumnDelete, isLoading, kanbanSelect, kanbanEdit, kanbanCreate, virtualization, }: KanbanBoardProps) => React.JSX.Element;
3
+ declare const KanbanBoard: ({ data, onDrag, onDelete, onOpen, onColumnDelete, isLoading, kanbanSelect, kanbanEdit, kanbanCreate, virtualization, permissions, }: KanbanBoardProps) => React.JSX.Element | null;
4
4
  export default KanbanBoard;
@@ -57,8 +57,12 @@ var HeaderActions_1 = __importDefault(require("../Header/HeaderActions"));
57
57
  var MeasuredItem_1 = __importDefault(require("./MeasuredItem"));
58
58
  var KanbanBoard = function (_a) {
59
59
  var _b, _c, _d, _e, _f, _g, _h;
60
- var data = _a.data, onDrag = _a.onDrag, onDelete = _a.onDelete, onOpen = _a.onOpen, onColumnDelete = _a.onColumnDelete, _j = _a.isLoading, isLoading = _j === void 0 ? false : _j, kanbanSelect = _a.kanbanSelect, kanbanEdit = _a.kanbanEdit, kanbanCreate = _a.kanbanCreate, virtualization = _a.virtualization;
60
+ var data = _a.data, onDrag = _a.onDrag, onDelete = _a.onDelete, onOpen = _a.onOpen, onColumnDelete = _a.onColumnDelete, _j = _a.isLoading, isLoading = _j === void 0 ? false : _j, kanbanSelect = _a.kanbanSelect, kanbanEdit = _a.kanbanEdit, kanbanCreate = _a.kanbanCreate, virtualization = _a.virtualization, permissions = _a.permissions;
61
61
  var colors = (0, useCustomTheme_1.useCustomTheme)().colors;
62
+ var canDrag = (permissions === null || permissions === void 0 ? void 0 : permissions.isEditable) !== false;
63
+ var canDelete = (permissions === null || permissions === void 0 ? void 0 : permissions.isDeletable) !== false;
64
+ var canCreate = (permissions === null || permissions === void 0 ? void 0 : permissions.isCreatable) !== false;
65
+ var canView = (permissions === null || permissions === void 0 ? void 0 : permissions.isViewable) !== false;
62
66
  var _k = (0, react_1.useState)(data), columns = _k[0], setColumns = _k[1];
63
67
  var _l = (0, react_1.useState)(600), containerHeight = _l[0], setContainerHeight = _l[1];
64
68
  var _m = (0, react_1.useState)(null), hoveredColumn = _m[0], setHoveredColumn = _m[1];
@@ -160,12 +164,14 @@ var KanbanBoard = function (_a) {
160
164
  return (react_1.default.createElement("div", { style: style },
161
165
  react_1.default.createElement(MeasuredItem_1.default, { index: index, setSize: function (i, h) { return setSize(i, h, colId); } },
162
166
  react_1.default.createElement("div", { style: { marginBottom: 12 } },
163
- react_1.default.createElement(dnd_1.Draggable, { draggableId: account.id.toString(), index: index, key: account.id }, function (provided) { return (react_1.default.createElement("div", __assign({ ref: provided.innerRef }, provided.draggableProps, provided.dragHandleProps, { style: provided.draggableProps.style }),
164
- react_1.default.createElement(AccountCard_1.default, { key: account.id, account: account, index: index, onDelete: onDelete, onOpen: onOpen, isExpanded: expanded[account.id], onToggleExpand: function () { return toggleExpand(account.id, colId, index); } }))); }))),
167
+ react_1.default.createElement(dnd_1.Draggable, { draggableId: account.id.toString(), index: index, key: account.id, isDragDisabled: !canDrag }, function (provided) { return (react_1.default.createElement("div", __assign({ ref: provided.innerRef }, provided.draggableProps, provided.dragHandleProps, { style: provided.draggableProps.style }),
168
+ react_1.default.createElement(AccountCard_1.default, { key: account.id, account: account, index: index, onDelete: onDelete, onOpen: onOpen, isExpanded: expanded[account.id], onToggleExpand: function () { return toggleExpand(account.id, colId, index); }, isDeletable: canDelete }))); }))),
165
169
  index === items.length - 1 && placeholder));
166
170
  };
171
+ if (!canView)
172
+ return null;
167
173
  return (react_1.default.createElement(react_1.default.Fragment, null,
168
- react_1.default.createElement(HeaderActions_1.default, { select: kanbanSelect, edit: kanbanEdit, create: kanbanCreate }),
174
+ react_1.default.createElement(HeaderActions_1.default, { select: kanbanSelect, edit: canDrag ? kanbanEdit : undefined, create: canCreate ? kanbanCreate : undefined }),
169
175
  react_1.default.createElement(dnd_1.DragDropContext, { onDragEnd: onDragEnd },
170
176
  react_1.default.createElement(react_2.Box, { ref: containerRef, bg: (_b = colors === null || colors === void 0 ? void 0 : colors.gray) === null || _b === void 0 ? void 0 : _b[200], minH: "".concat(containerHeight, "px"), position: "relative", overflow: "hidden", mt: 2 },
171
177
  react_1.default.createElement(react_2.Flex, { gap: 4, p: 4, pb: 6, overflowX: "auto", overflowY: "hidden", height: "100%",
@@ -214,13 +220,9 @@ var KanbanBoard = function (_a) {
214
220
  : "0.125rem solid " + ((_d = colors.gray) === null || _d === void 0 ? void 0 : _d[200])), display: "flex", flexDirection: "column", flexShrink: 0, overflow: "hidden", height: "".concat(containerHeight - 60, "px"), onMouseEnter: function () { return setHoveredColumn(colId); }, onMouseLeave: function () { return setHoveredColumn(null); } }),
215
221
  react_1.default.createElement(react_2.Flex, { width: "95%", height: "2.75rem", borderRadius: "0.25rem", borderLeft: "0.188rem solid", borderLeftColor: (_e = column.color) !== null && _e !== void 0 ? _e : (_f = colors === null || colors === void 0 ? void 0 : colors.primary) === null || _f === void 0 ? void 0 : _f[500], background: (_g = colors === null || colors === void 0 ? void 0 : colors.gray) === null || _g === void 0 ? void 0 : _g[100], align: "center", px: 2, m: 2, flexShrink: 0, justifyContent: "space-between", position: "relative" },
216
222
  react_1.default.createElement(react_2.Text, { fontWeight: "600", fontSize: "1rem", color: (_h = colors === null || colors === void 0 ? void 0 : colors.text) === null || _h === void 0 ? void 0 : _h[700] }, column.title),
217
- hoveredColumn === colId && column.items.length > 0 && (react_1.default.createElement(react_2.Box, { as: lucide_react_1.Trash2, size: 16, cursor: "pointer", color: (_j = colors === null || colors === void 0 ? void 0 : colors.text) === null || _j === void 0 ? void 0 : _j[600], _hover: { color: (_k = colors === null || colors === void 0 ? void 0 : colors.red) === null || _k === void 0 ? void 0 : _k[600] }, onClick: function () { return handleColumnDelete(colId); }, transition: "color 0.2s ease" })),
218
- !(hoveredColumn === colId && column.items.length > 0) && (react_1.default.createElement(react_2.Box, { width: "16px", height: "16px" }))),
219
- react_1.default.createElement(react_2.Box
220
- // px={2}
221
- // pb={2}
222
- , {
223
- // px={2}
223
+ canDelete && hoveredColumn === colId && column.items.length > 0 && (react_1.default.createElement(react_2.Box, { as: lucide_react_1.Trash2, size: 16, cursor: "pointer", color: (_j = colors === null || colors === void 0 ? void 0 : colors.text) === null || _j === void 0 ? void 0 : _j[600], _hover: { color: (_k = colors === null || colors === void 0 ? void 0 : colors.red) === null || _k === void 0 ? void 0 : _k[600] }, onClick: function () { return handleColumnDelete(colId); }, transition: "color 0.2s ease" })),
224
+ !(canDelete && hoveredColumn === colId && column.items.length > 0) && (react_1.default.createElement(react_2.Box, { width: "16px", height: "16px" }))),
225
+ react_1.default.createElement(react_2.Box, { px: 2,
224
226
  // pb={2}
225
227
  flex: "1", overflowY: "auto", width: "100%",
226
228
  // mr={1} // Add right margin to create gap for scrollbar
@@ -255,6 +257,7 @@ var KanbanBoard = function (_a) {
255
257
  "&": {
256
258
  scrollbarGutter: "stable both-edges",
257
259
  },
260
+ cursor: canDrag ? "grab" : "not-allowed",
258
261
  } }, virtualization ? (react_1.default.createElement(react_window_1.VariableSizeList, { ref: function (el) {
259
262
  if (el)
260
263
  listRefs.current[colId] = el;
@@ -264,10 +267,10 @@ var KanbanBoard = function (_a) {
264
267
  placeholder: provided.placeholder,
265
268
  } }, Row)) : (react_1.default.createElement(react_2.Box, null,
266
269
  column.items.map(function (account, index) { return (react_1.default.createElement("div", { key: account.id, style: { marginBottom: 12 } },
267
- react_1.default.createElement(dnd_1.Draggable, { draggableId: account.id.toString(), index: index, key: account.id }, function (provided) { return (react_1.default.createElement("div", __assign({ ref: provided.innerRef }, provided.draggableProps, provided.dragHandleProps, { style: provided.draggableProps.style }),
270
+ react_1.default.createElement(dnd_1.Draggable, { draggableId: account.id.toString(), index: index, key: account.id, isDragDisabled: !canDrag }, function (provided) { return (react_1.default.createElement("div", __assign({ ref: provided.innerRef }, provided.draggableProps, provided.dragHandleProps, { style: provided.draggableProps.style }),
268
271
  react_1.default.createElement(AccountCard_1.default, { account: account, index: index, onDelete: onDelete, onOpen: onOpen, isExpanded: expanded[account.id], onToggleExpand: function () {
269
272
  return toggleExpand(account.id, colId, index);
270
- } }))); }))); }),
273
+ }, isDeletable: canDelete }))); }))); }),
271
274
  provided.placeholder)))));
272
275
  }));
273
276
  }))))));
@@ -0,0 +1 @@
1
+ import "@testing-library/jest-dom";
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ var react_1 = __importDefault(require("react"));
7
+ var react_2 = require("@testing-library/react");
8
+ require("@testing-library/jest-dom");
9
+ var KanbanBoard_1 = __importDefault(require("./KanbanBoard"));
10
+ jest.mock("../../Theme/useCustomTheme", function () { return ({
11
+ useCustomTheme: function () { return ({
12
+ colors: {
13
+ background: { 100: "#f9f9f9", 500: "#fff" },
14
+ gray: { 100: "#f0f0f0", 200: "#eee", 300: "#ddd", 400: "#ccc", 500: "#bbb", 700: "#333" },
15
+ primary: { 500: "#3182ce" },
16
+ blue: { 50: "#ebf8ff", 500: "#3182ce", 600: "#3182ce" },
17
+ red: { 600: "#e53e3e" },
18
+ text: { 500: "#555", 600: "#444", 700: "#333" },
19
+ secondary: { 500: "#805ad5" },
20
+ },
21
+ }); },
22
+ }); });
23
+ jest.mock("@hello-pangea/dnd", function () { return ({
24
+ DragDropContext: function (_a) {
25
+ var children = _a.children;
26
+ return react_1.default.createElement("div", null, children);
27
+ },
28
+ Droppable: function (_a) {
29
+ var children = _a.children;
30
+ return children({ innerRef: function () { }, droppableProps: {}, placeholder: null }, { isDraggingOver: false });
31
+ },
32
+ Draggable: function (_a) {
33
+ var children = _a.children, isDragDisabled = _a.isDragDisabled;
34
+ var provided = {
35
+ innerRef: function () { },
36
+ draggableProps: { "data-drag-disabled": isDragDisabled },
37
+ dragHandleProps: {},
38
+ };
39
+ return children(provided, { isDragging: false });
40
+ },
41
+ }); });
42
+ jest.mock("react-window", function () { return ({
43
+ VariableSizeList: function () { return null; },
44
+ }); });
45
+ var sampleData = {
46
+ col1: {
47
+ id: "col1",
48
+ title: "To Do",
49
+ color: "#3182ce",
50
+ items: [
51
+ { id: "1", name: "Account A", email: "a@example.com" },
52
+ { id: "2", name: "Account B", email: "b@example.com" },
53
+ ],
54
+ },
55
+ };
56
+ describe("KanbanBoard – permissions", function () {
57
+ describe("isDeletable", function () {
58
+ it("shows card delete icons when permissions.isDeletable is true", function () {
59
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, permissions: { isDeletable: true } }));
60
+ expect(react_2.screen.getAllByLabelText("Delete").length).toBeGreaterThan(0);
61
+ });
62
+ it("hides card delete icons when permissions.isDeletable is false", function () {
63
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, permissions: { isDeletable: false } }));
64
+ expect(react_2.screen.queryByLabelText("Delete")).not.toBeInTheDocument();
65
+ });
66
+ it("shows card delete icons when permissions prop is omitted (default allow)", function () {
67
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData }));
68
+ expect(react_2.screen.getAllByLabelText("Delete").length).toBeGreaterThan(0);
69
+ });
70
+ });
71
+ describe("isCreatable", function () {
72
+ var kanbanCreate = { isCreatable: true, label: "Create New" };
73
+ it("shows the create button when permissions.isCreatable is true", function () {
74
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanCreate: kanbanCreate, permissions: { isCreatable: true } }));
75
+ expect(react_2.screen.getByText("Create New")).toBeInTheDocument();
76
+ });
77
+ it("hides the create button when permissions.isCreatable is false", function () {
78
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanCreate: kanbanCreate, permissions: { isCreatable: false } }));
79
+ expect(react_2.screen.queryByText("Create New")).not.toBeInTheDocument();
80
+ });
81
+ });
82
+ describe("isEditable", function () {
83
+ var kanbanEdit = { isEditable: true, label: "Edit Layout" };
84
+ it("shows the edit button when permissions.isEditable is true", function () {
85
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanEdit: kanbanEdit, permissions: { isEditable: true } }));
86
+ expect(react_2.screen.getByText("Edit Layout")).toBeInTheDocument();
87
+ });
88
+ it("hides the edit button when permissions.isEditable is false", function () {
89
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, kanbanEdit: kanbanEdit, permissions: { isEditable: false } }));
90
+ expect(react_2.screen.queryByText("Edit Layout")).not.toBeInTheDocument();
91
+ });
92
+ it("sets isDragDisabled on cards when permissions.isEditable is false", function () {
93
+ (0, react_2.render)(react_1.default.createElement(KanbanBoard_1.default, { data: sampleData, permissions: { isEditable: false } }));
94
+ var disabledDraggables = react_2.screen
95
+ .getAllByRole("generic")
96
+ .filter(function (el) { return el.getAttribute("data-drag-disabled") === "true"; });
97
+ expect(disabledDraggables.length).toBeGreaterThan(0);
98
+ });
99
+ });
100
+ });
@@ -39,4 +39,10 @@ export type KanbanBoardProps = {
39
39
  label?: string;
40
40
  };
41
41
  virtualization?: boolean;
42
+ permissions?: {
43
+ isEditable?: boolean;
44
+ isCreatable?: boolean;
45
+ isDeletable?: boolean;
46
+ isViewable?: boolean;
47
+ };
42
48
  };
@@ -37,9 +37,9 @@ var Notification = function (_a) {
37
37
  var warningColor = (colors === null || colors === void 0 ? void 0 : colors.warningColor) || theme.colors.semantic.warning;
38
38
  var errorColor = (colors === null || colors === void 0 ? void 0 : colors.errorColor) || theme.colors.semantic.error;
39
39
  var successColor = (colors === null || colors === void 0 ? void 0 : colors.successColor) || theme.colors.semantic.success;
40
- var startDate = notification.startDate
40
+ var startDate = (0, react_1.useMemo)(function () { return notification.startDate
41
41
  ? new Date(notification.startDate)
42
- : null;
42
+ : null; }, [notification.startDate]);
43
43
  var _c = (0, react_1.useMemo)(function () {
44
44
  var targetDate = notification.dueDate
45
45
  ? new Date(notification.dueDate)
@@ -9,7 +9,6 @@ var ProductImageSlider_1 = __importDefault(require("./ProductImageSlider"));
9
9
  var ProductLabel_1 = __importDefault(require("../ProductCard/ProductLabel"));
10
10
  var ProductTags_1 = __importDefault(require("../ProductCard/ProductTags"));
11
11
  var ProductDtlPrice_1 = __importDefault(require("./ProductDtlPrice"));
12
- var useCustomTheme_1 = require("../../Theme/useCustomTheme");
13
12
  var Button_1 = __importDefault(require("../Button/Button"));
14
13
  var lucide_react_1 = require("lucide-react");
15
14
  var ProductReview_1 = __importDefault(require("../ProductCard/ProductReview"));
@@ -17,7 +16,6 @@ var FormattedDescription_1 = __importDefault(require("../Common/FormattedDescrip
17
16
  var ProductDetails = function (_a) {
18
17
  var _b, _c, _d, _e, _f;
19
18
  var id = _a.id, price = _a.price, label = _a.label, shortdesc = _a.shortdesc, tags = _a.tags, images = _a.images, batch = _a.batch, category = _a.category, onAddToCart = _a.onAddToCart, onNotifyMe = _a.onNotifyMe, onOptionChange = _a.onOptionChange, addToCart = _a.addToCart, goToCart = _a.goToCart, OnGoToCart = _a.OnGoToCart, rating = _a.rating, reviews = _a.reviews, notifyMe = _a.notifyMe, _g = _a.isQtyEditable, isQtyEditable = _g === void 0 ? false : _g, _h = _a.displayRating, displayRating = _h === void 0 ? true : _h;
20
- var theme = (0, useCustomTheme_1.useCustomTheme)();
21
19
  var isMobile = (0, react_2.useBreakpointValue)({ base: true, md: false });
22
20
  var _j = react_1.default.useState(price === null || price === void 0 ? void 0 : price[0]), selectedOption = _j[0], setSelectedOption = _j[1];
23
21
  var _k = react_1.default.useState(1), qty = _k[0], setQty = _k[1];
@@ -39,7 +39,6 @@ var SecondaryBar = function (_a) {
39
39
  var _l = (0, react_1.useState)(defaultCollapsed), collapsed = _l[0], setCollapsed = _l[1];
40
40
  var width = collapsed ? collapsedWidth : expandedWidth;
41
41
  var showText = !collapsed;
42
- var textMaxWidth = expandedWidth !== null && expandedWidth !== void 0 ? expandedWidth : "10rem";
43
42
  return (react_1.default.createElement(react_2.Box, { transition: "all 0.3s", pos: "sticky", top: 0, h: "100vh", w: width, bg: (_d = (_c = (_b = theme.colors.sidebar) === null || _b === void 0 ? void 0 : _b.background) === null || _c === void 0 ? void 0 : _c[400]) !== null && _d !== void 0 ? _d : theme.colors.gray[800], boxShadow: theme.shadows.md, zIndex: 1 },
44
43
  react_1.default.createElement(react_2.VStack, { align: "stretch", spacing: 0 },
45
44
  react_1.default.createElement(react_2.Flex, { align: "center", justify: showText ? "space-between" : "center", px: showText ? "0.75rem" : 0, h: "3.91rem", overflow: "hidden" },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pixelize-design-library",
3
- "version": "2.2.121",
3
+ "version": "2.2.122",
4
4
  "private": false,
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",