@blocklet/labels 1.6.195 → 1.6.197

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.es.js CHANGED
@@ -1,72 +1,1370 @@
1
- import { G, j, b, a, L, d, k, h, i, f, u, e } from "./index-aAHAaJv_.mjs";
2
- import "react/jsx-runtime";
3
- import "react";
4
- import "@mui/icons-material";
5
- import "@mui/material/Box";
6
- import "@mui/material/styles";
7
- import "react-arborist";
8
- import "@iconify/react";
9
- import "lodash/omit";
10
- import "react-select";
11
- import "@mui/material";
12
- import "@arcblock/ux/lib/Locale/context";
13
- import "ahooks";
14
- import "unstated-next";
15
- import "performant-array-to-tree";
16
- import "@mui/icons-material/Close";
17
- import "@mui/icons-material/Done";
18
- import "chroma-js";
19
- import "lodash/pick";
20
- import "lodash/cloneDeep";
21
- import "lodash/isFunction";
22
- import "lodash/isUndefined";
23
- import "lodash/defaultsDeep";
24
- import "@arcblock/ux/lib/Util";
25
- import "@arcblock/ux/lib/Toast";
26
- import "@arcblock/ux/lib/Center";
27
- import "@arcblock/ux/lib/Colors";
28
- import "@arcblock/ux/lib/Dialog/use-confirm";
29
- import "@arcblock/ux/lib/DID";
30
- import "@arcblock/ux/lib/Avatar";
31
- import "@arcblock/ux/lib/SessionUser/libs/utils";
32
- import "@arcblock/ux/lib/Locale/util";
33
- import "node:crypto";
34
- import "@arcblock/ux/lib/Util/wallet";
35
- import "@arcblock/ux/lib/Dialog";
36
- import "@arcblock/ux/lib/Button";
37
- import "@arcblock/ux/lib/Empty";
38
- import "lodash/noop";
39
- import "@arcblock/ux/lib/CardSelector";
40
- import "node:buffer";
41
- import "@arcblock/ux/lib/Util/federated";
42
- import "react-dom";
43
- import "@arcblock/ux/lib/WebWalletSWKeeper";
44
- import "@arcblock/ux/lib/BlockletContext";
45
- import "lodash";
46
- import "@arcblock/ux/lib/RelativeTime";
47
- import "@arcblock/ux/lib/WalletOSIcon";
48
- import "@arcblock/ux/lib/LoadingMask";
49
- import "@arcblock/ux/lib/Success";
50
- import "lodash/intersection";
51
- import "@arcblock/ux/lib/QRCode";
52
- import "lodash/get";
53
- import "lodash/omitBy";
54
- import "lodash/isNil";
55
- import "lodash/unionBy";
56
- import "lodash/sortBy";
57
- import "@arcblock/ux/lib/Address";
58
- import "@arcblock/ux/lib/Img";
1
+ var __defProp = Object.defineProperty;
2
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
+ var __publicField = (obj, key, value) => {
4
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
5
+ return value;
6
+ };
7
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
8
+ import { createContext, useRef, useState, useCallback, useEffect, useMemo, useContext, createElement } from "react";
9
+ import { ExpandMore, Edit, LabelOutlined } from "@mui/icons-material";
10
+ import Box from "@mui/material/Box";
11
+ import { styled } from "@mui/material/styles";
12
+ import { Tree } from "react-arborist";
13
+ import { Icon } from "@iconify/react";
14
+ import omit from "lodash/omit";
15
+ import Select, { components } from "react-select";
16
+ import { ClickAwayListener, Box as Box$1, Chip, IconButton, Button, getContrastRatio, alpha, useTheme, ButtonBase, Popper, Autocomplete, InputBase, autocompleteClasses, TextField } from "@mui/material";
17
+ import { useLocaleContext } from "@arcblock/ux/lib/Locale/context";
18
+ import { useReactive, useRequest, useSize, useDeepCompareLayoutEffect } from "ahooks";
19
+ import { createContainer } from "unstated-next";
20
+ import { arrayToTree } from "performant-array-to-tree";
21
+ import CloseOutlineIcon from "@mui/icons-material/Close";
22
+ import DoneIcon from "@mui/icons-material/Done";
23
+ import chroma from "chroma-js";
24
+ import { SessionContext } from "@arcblock/did-connect/lib/Session";
25
+ const materialSymbolsLabelRounded = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "currentColor", d: "M5 19q-.825 0-1.413-.587Q3 17.825 3 17V7q0-.825.587-1.412Q4.175 5 5 5h10q.5 0 .938.225q.437.225.712.625l3.525 5q.375.525.375 1.15q0 .625-.375 1.15l-3.525 5q-.275.4-.712.625Q15.5 19 15 19Z" }) });
26
+ const materialSymbolsCheckSmall = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "currentColor", d: "m10 16.4l-4-4L7.4 11l2.6 2.6L16.6 7L18 8.4Z" }) });
27
+ const LabelTreeContext = createContext({});
28
+ function LabelTreeProvider({
29
+ selectable = false,
30
+ selected = [],
31
+ onSelect,
32
+ renderItem,
33
+ children
34
+ }) {
35
+ const isSelected = (id) => selected.indexOf(id) !== -1;
36
+ const select = (id) => {
37
+ Array.from(new Set(selected).add(id));
38
+ onSelect == null ? void 0 : onSelect(id);
39
+ };
40
+ const value = useMemo(
41
+ () => ({
42
+ selectable,
43
+ selected,
44
+ isSelected,
45
+ select,
46
+ renderItem
47
+ }),
48
+ // eslint-disable-next-line react-hooks/exhaustive-deps
49
+ [selected]
50
+ );
51
+ return /* @__PURE__ */ jsx(LabelTreeContext.Provider, { value, children });
52
+ }
53
+ const isLeaf = (node) => {
54
+ var _a;
55
+ return node.isLeaf || !((_a = node.data.children) == null ? void 0 : _a.length);
56
+ };
57
+ function FolderArrow({ node }) {
58
+ if (isLeaf(node))
59
+ return /* @__PURE__ */ jsx("span", {});
60
+ return node.isOpen ? /* @__PURE__ */ jsx(ExpandMore, { style: { fontSize: 20 } }) : /* @__PURE__ */ jsx(ExpandMore, { style: { fontSize: 20, transform: "rotate(-90deg)" } });
61
+ }
62
+ function Node({ node, style, dragHandle }) {
63
+ const { selectable, select, isSelected, renderItem } = useContext(LabelTreeContext);
64
+ const { data } = node;
65
+ const icon = data.icon ? /* @__PURE__ */ jsx(Icon, { icon: data.icon, style: { fontSize: 18 } }) : /* @__PURE__ */ jsx(materialSymbolsLabelRounded, { style: { fontSize: 18, color: data.color || "#ddd" } });
66
+ const handleToggle = (e) => {
67
+ e.stopPropagation();
68
+ if (node.isInternal) {
69
+ node.toggle();
70
+ }
71
+ };
72
+ const handleClick = (e) => {
73
+ e.stopPropagation();
74
+ if (selectable) {
75
+ select(node.id);
76
+ }
77
+ };
78
+ const children = /* @__PURE__ */ jsxs(Fragment, { children: [
79
+ /* @__PURE__ */ jsxs(Box, { sx: { display: "flex", alignItems: "center", flex: 1 }, children: [
80
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", cursor: "pointer" }, onClick: handleToggle, children: /* @__PURE__ */ jsx(FolderArrow, { node }) }),
81
+ /* @__PURE__ */ jsx(Box, { sx: { display: "flex", alignItems: "center", width: 22, height: 22 }, children: icon }),
82
+ /* @__PURE__ */ jsx(Box, { component: "span", sx: { color: "grey.700" }, children: node.data.name })
83
+ ] }),
84
+ selectable && isSelected(node.id) && /* @__PURE__ */ jsx(materialSymbolsCheckSmall, {})
85
+ ] });
86
+ return /* @__PURE__ */ jsxs(
87
+ Box,
88
+ {
89
+ className: "label-tree-item",
90
+ style,
91
+ sx: {
92
+ display: "flex",
93
+ alignItems: "center",
94
+ justifyContent: "space-between",
95
+ color: (theme) => theme.palette.mode === "dark" ? "grey.800" : "text.primary"
96
+ },
97
+ ref: dragHandle,
98
+ onClick: handleClick,
99
+ children: [
100
+ !renderItem && children,
101
+ !!renderItem && renderItem(children, node.data)
102
+ ]
103
+ }
104
+ );
105
+ }
106
+ const Root = styled(Box)`
107
+ > div,
108
+ > div > div,
109
+ > div > div > div {
110
+ width: auto !important;
111
+ }
112
+ [role='treeitem'] {
113
+ display: flex;
114
+ align-items: stretch;
115
+ }
116
+ .label-tree-item {
117
+ width: 100%;
118
+ }
119
+ `;
120
+ function LabelTree({
121
+ data,
122
+ selectable,
123
+ selected = [],
124
+ onSelect,
125
+ rowHeight = 28,
126
+ renderItem,
127
+ sx,
128
+ ...rest
129
+ }) {
130
+ const tree = useRef();
131
+ const mergedSx = [...Array.isArray(sx) ? sx : [sx]];
132
+ const [height, setHeight] = useState(0);
133
+ const updateHeight = useCallback(() => {
134
+ var _a, _b;
135
+ setHeight((((_b = (_a = tree.current) == null ? void 0 : _a.visibleNodes) == null ? void 0 : _b.length) || 0) * rowHeight);
136
+ }, [rowHeight]);
137
+ useEffect(() => {
138
+ updateHeight();
139
+ }, [data, updateHeight]);
140
+ const handleToggle = () => {
141
+ setTimeout(updateHeight);
142
+ };
143
+ return /* @__PURE__ */ jsx(LabelTreeProvider, { selectable, selected, onSelect, renderItem, children: /* @__PURE__ */ jsx(Root, { ...rest, sx: mergedSx, children: /* @__PURE__ */ jsx(Tree, { data, rowHeight, height, indent: 32, ref: tree, onToggle: handleToggle, children: Node }) }) });
144
+ }
145
+ const flatten = (data) => {
146
+ return data.reduce((acc, cur) => {
147
+ var _a;
148
+ acc.push(cur);
149
+ if ((_a = cur.children) == null ? void 0 : _a.length) {
150
+ acc.push(...flatten(cur.children));
151
+ }
152
+ return acc;
153
+ }, []);
154
+ };
155
+ const safeParseJSON = (json, defaultValue = null) => {
156
+ try {
157
+ return JSON.parse(json);
158
+ } catch {
159
+ return defaultValue;
160
+ }
161
+ };
162
+ const transformLabels = (labelDtos) => {
163
+ const relations = labelDtos.reduce((acc, cur) => {
164
+ acc[cur.id] = acc[cur.id] || {};
165
+ if (cur.parentId) {
166
+ acc[cur.id].parent = cur.parentId;
167
+ acc[cur.parentId] = acc[cur.parentId] || {};
168
+ acc[cur.parentId].children = acc[cur.parentId].children || [];
169
+ acc[cur.parentId].children.push(cur.id);
170
+ }
171
+ return acc;
172
+ }, {});
173
+ const labels = labelDtos.map(({ parentId, translation, ...rest }) => ({
174
+ ...rest,
175
+ translation: safeParseJSON(translation),
176
+ children: []
177
+ }));
178
+ const labelsKeyById = labels.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
179
+ labels.forEach((item) => {
180
+ const relation = relations[item.id];
181
+ if (relation.parent && labelsKeyById[relation.parent]) {
182
+ item.parent = labelsKeyById[relation.parent];
183
+ }
184
+ if (relation.children) {
185
+ item.children = relation.children.map((childId) => labelsKeyById[childId]);
186
+ }
187
+ });
188
+ return labels.filter((item) => !item.parent);
189
+ };
190
+ const LabelMenuList = (props) => {
191
+ const { options, getValue, selectProps, selectOption } = props;
192
+ const value = getValue();
193
+ const handleSelect = (id) => {
194
+ const option = options.find((item) => item.data.id === id);
195
+ if (option) {
196
+ selectOption(option);
197
+ }
198
+ };
199
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
200
+ /* @__PURE__ */ jsx(components.MenuList, { ...omit(props, ["addon"]), children: /* @__PURE__ */ jsx(Box, { sx: { px: 2, py: 1 }, children: /* @__PURE__ */ jsx(
201
+ LabelTree,
202
+ {
203
+ data: selectProps.data,
204
+ selectable: true,
205
+ onSelect: handleSelect,
206
+ selected: value.map((item) => item.data.id)
207
+ }
208
+ ) }) }),
209
+ props.addon
210
+ ] });
211
+ };
212
+ const ValueContainer = ({ children, ...props }) => {
213
+ const [values, input] = children;
214
+ const count = Array.isArray(values) ? values.length : 0;
215
+ return /* @__PURE__ */ jsxs(components.ValueContainer, { ...props, children: [
216
+ /* @__PURE__ */ jsx(
217
+ Box,
218
+ {
219
+ component: "span",
220
+ sx: {
221
+ fontSize: 13,
222
+ fontWeight: "bold",
223
+ color: (theme) => theme.palette.mode === "dark" ? "grey.800" : "text.primary"
224
+ },
225
+ children: count ? "Labels" : "Filter by labels"
226
+ }
227
+ ),
228
+ !!count && /* @__PURE__ */ jsx(
229
+ Box,
230
+ {
231
+ sx: {
232
+ display: "inline-flex",
233
+ justifyContent: "center",
234
+ alignItems: "center",
235
+ width: 22,
236
+ height: 22,
237
+ ml: 1,
238
+ borderRadius: "100%",
239
+ fontSize: 12,
240
+ color: (theme) => theme.palette.mode === "dark" ? "grey.800" : "text.primary",
241
+ bgcolor: "grey.200"
242
+ },
243
+ children: count
244
+ }
245
+ ),
246
+ input
247
+ ] });
248
+ };
249
+ const compactSelectStyles = {
250
+ control: (provided) => ({
251
+ ...provided,
252
+ minHeight: 31
253
+ }),
254
+ valueContainer: (provided) => ({
255
+ ...provided,
256
+ display: "flex"
257
+ }),
258
+ dropdownIndicator: (provided) => ({
259
+ ...provided,
260
+ padding: "0 4px"
261
+ }),
262
+ clearIndicator: (provided) => ({
263
+ ...provided,
264
+ padding: "4px"
265
+ })
266
+ };
267
+ function LabelPicker({
268
+ data,
269
+ value = [],
270
+ editable = false,
271
+ addon,
272
+ onChange,
273
+ compact,
274
+ isMulti = true,
275
+ maxHeight = 264,
276
+ ...rest
277
+ }) {
278
+ const selectRef = useRef(null);
279
+ const options = useMemo(
280
+ () => flatten(data).map((item) => ({ data: item, label: item.name, value: item.id })),
281
+ [data]
282
+ );
283
+ const optionsKeyById = options.reduce(
284
+ (acc, cur) => ({ ...acc, [cur.data.id]: cur }),
285
+ {}
286
+ );
287
+ const valueArr = Array.isArray(value) ? value : [value];
288
+ const selectedOptions = valueArr.map((item) => optionsKeyById[item]);
289
+ const changes = useRef({
290
+ prev: valueArr.map((item) => {
291
+ var _a;
292
+ return ((_a = optionsKeyById[item]) == null ? void 0 : _a.data) || "";
293
+ })
294
+ });
295
+ const handleChange = (v, actionMeta) => {
296
+ if (!isMulti || !Array.isArray(v)) {
297
+ onChange(v ? [v.data] : []);
298
+ } else {
299
+ changes.current.current = v.map((item) => item.data);
300
+ }
301
+ if (["clear", "remove-value"].includes(actionMeta.action) && selectRef.current) {
302
+ setTimeout(() => {
303
+ var _a;
304
+ return (_a = selectRef == null ? void 0 : selectRef.current) == null ? void 0 : _a.blur();
305
+ }, 1);
306
+ }
307
+ };
308
+ const handleMenuClose = () => {
309
+ if (changes.current.current) {
310
+ const changed = JSON.stringify(changes.current.prev.map((item) => item.id)) !== JSON.stringify(changes.current.current.map((item) => item.id));
311
+ if (changed) {
312
+ onChange(changes.current.current);
313
+ changes.current.prev = changes.current.current;
314
+ }
315
+ }
316
+ };
317
+ return /* @__PURE__ */ jsx(Box, { ...rest, children: /* @__PURE__ */ jsx(
318
+ Select,
319
+ {
320
+ ref: selectRef,
321
+ defaultValue: selectedOptions,
322
+ options,
323
+ onChange: handleChange,
324
+ components: {
325
+ // @ts-ignore
326
+ MenuList: (props) => /* @__PURE__ */ jsx(LabelMenuList, { ...props, addon }),
327
+ // eslint-disable-line react/no-unstable-nested-components
328
+ ...compact && { ValueContainer }
329
+ },
330
+ placeholder: "Select labels",
331
+ styles: {
332
+ ...compact && compactSelectStyles,
333
+ menu: (css) => ({
334
+ ...css,
335
+ ...editable && { paddingBottom: "36px" },
336
+ zIndex: 99
337
+ }),
338
+ menuList: (css) => ({
339
+ ...css,
340
+ overflowY: "auto",
341
+ maxHeight: `${maxHeight}px`
342
+ })
343
+ },
344
+ theme: (_theme) => ({
345
+ ..._theme,
346
+ colors: {
347
+ ..._theme.colors,
348
+ primary25: "#ddd",
349
+ primary50: "#ddd",
350
+ primary: "#ddd"
351
+ }
352
+ }),
353
+ isSearchable: false,
354
+ isMulti,
355
+ closeMenuOnSelect: !isMulti,
356
+ onMenuClose: handleMenuClose,
357
+ isClearable: true,
358
+ data
359
+ }
360
+ ) });
361
+ }
362
+ class TreeNode {
363
+ constructor({ data, parent, children }) {
364
+ __publicField(this, "data");
365
+ __publicField(this, "parent");
366
+ __publicField(this, "children");
367
+ this.data = data;
368
+ this.parent = parent;
369
+ this.children = children || [];
370
+ }
371
+ setParent(node) {
372
+ this.parent = node;
373
+ }
374
+ add(...nodes) {
375
+ this.children.push(...nodes);
376
+ nodes.forEach((node) => node.setParent(this));
377
+ }
378
+ removeChild(node) {
379
+ this.children = this.children.filter((x) => x !== node);
380
+ node.setParent(void 0);
381
+ }
382
+ isLeaf(node) {
383
+ var _a;
384
+ return !((_a = node.children) == null ? void 0 : _a.length);
385
+ }
386
+ getAllParents(includeSelf = true) {
387
+ const parents = [];
388
+ if (includeSelf) {
389
+ parents.unshift(this);
390
+ }
391
+ let { parent } = this;
392
+ while (parent) {
393
+ parents.unshift(parent);
394
+ parent = parent.parent;
395
+ }
396
+ return parents;
397
+ }
398
+ getAllSiblings() {
399
+ var _a;
400
+ const siblings = ((_a = this.parent) == null ? void 0 : _a.children.filter((node) => node !== this)) || [];
401
+ return siblings;
402
+ }
403
+ flatten(includeRoot) {
404
+ const nodes = [];
405
+ const traverse = (node) => {
406
+ nodes.push(node);
407
+ node.children.forEach(traverse);
408
+ };
409
+ traverse(this);
410
+ if (!includeRoot) {
411
+ nodes.shift();
412
+ }
413
+ return nodes;
414
+ }
415
+ clone() {
416
+ const cloned = new TreeNode({ data: this.data });
417
+ cloned.add(...this.children);
418
+ return cloned;
419
+ }
420
+ }
421
+ class Label {
422
+ constructor(data) {
423
+ __publicField(this, "id");
424
+ __publicField(this, "name");
425
+ __publicField(this, "icon");
426
+ __publicField(this, "type");
427
+ __publicField(this, "color");
428
+ __publicField(this, "passports");
429
+ __publicField(this, "translation");
430
+ this.id = data.id;
431
+ this.name = data.name;
432
+ this.icon = data.icon;
433
+ this.type = data.type;
434
+ this.color = data.color || "#ddd";
435
+ this.passports = data.passports || [];
436
+ this.translation = this._normalizeTranslation(data.translation);
437
+ }
438
+ _normalizeTranslation(translation) {
439
+ if (typeof translation === "object") {
440
+ return translation;
441
+ }
442
+ try {
443
+ return JSON.parse(translation);
444
+ } catch {
445
+ return {};
446
+ }
447
+ }
448
+ getName(locale) {
449
+ var _a;
450
+ if (!locale) {
451
+ return this.name;
452
+ }
453
+ return ((_a = this == null ? void 0 : this.translation) == null ? void 0 : _a[locale]) || (this == null ? void 0 : this.name);
454
+ }
455
+ }
456
+ class LabelTreeNode extends TreeNode {
457
+ getName(locale) {
458
+ return this.data.getName(locale);
459
+ }
460
+ isSystemLabel() {
461
+ return this.data.type === "system";
462
+ }
463
+ getFullName(locale) {
464
+ const parents = this.getAllParents();
465
+ parents.shift();
466
+ if (locale) {
467
+ return parents.map((item) => item.getName(locale)).join(" / ");
468
+ }
469
+ return parents.map((item) => item.data.name).join(" / ");
470
+ }
471
+ }
472
+ __publicField(LabelTreeNode, "Label", Label);
473
+ const mapToTree = (items, parent) => {
474
+ return items.map((item) => {
475
+ const node = new LabelTreeNode({ data: new Label(item.data), parent });
476
+ const children = mapToTree(item.children || [], node);
477
+ node.add(...children);
478
+ return node;
479
+ });
480
+ };
481
+ const initLabelTree = (data) => {
482
+ const treeData = arrayToTree(data);
483
+ const root = new LabelTreeNode({ data: {} });
484
+ root.add(...mapToTree(treeData));
485
+ return root;
486
+ };
487
+ const createEmptyLabelTree = () => {
488
+ return new LabelTreeNode({ data: {}, children: [] });
489
+ };
490
+ const useLabels = ({ loading, data, createLabel: createLabelAPI }) => {
491
+ const { locale } = useLocaleContext();
492
+ const state = useReactive({
493
+ loading: true,
494
+ tree: createEmptyLabelTree(),
495
+ stats: []
496
+ });
497
+ useEffect(() => {
498
+ try {
499
+ if (data && !loading) {
500
+ const { labels, stats } = data;
501
+ const tree = initLabelTree(labels || []);
502
+ state.loading = false;
503
+ state.tree = tree;
504
+ state.stats = stats.sort((a, b) => b.count - a.count);
505
+ }
506
+ } catch (e) {
507
+ console.error(e);
508
+ state.loading = false;
509
+ }
510
+ }, [data, loading]);
511
+ const flattened = useMemo(() => state.tree.flatten(), [state.tree]);
512
+ const counts = useMemo(
513
+ () => state.stats.reduce((acc, cur) => ({ ...acc, [cur.id]: cur.count }), {}),
514
+ [state.stats]
515
+ );
516
+ const nodesKeyById = useMemo(() => {
517
+ return flattened.reduce((acc, cur) => ({ ...acc, [cur.data.id]: cur }), {});
518
+ }, [flattened]);
519
+ const popularLabels = useMemo(
520
+ () => state.stats.slice(0, 12).map((x) => nodesKeyById[x.id]),
521
+ [nodesKeyById, state.stats]
522
+ );
523
+ const getLabelsByIds = useCallback(
524
+ (ids) => {
525
+ return ids.map((id) => nodesKeyById[id]).filter(Boolean);
526
+ },
527
+ [nodesKeyById]
528
+ );
529
+ const labelExists = useCallback((id) => !!nodesKeyById[id], [nodesKeyById]);
530
+ const getLabelName = (id) => {
531
+ var _a;
532
+ return (_a = nodesKeyById[id]) == null ? void 0 : _a.data.getName(locale);
533
+ };
534
+ const getRelatedLabels = (id) => {
535
+ const node = nodesKeyById[id];
536
+ if (!node || node.parent === state.tree) {
537
+ return [];
538
+ }
539
+ const siblings = node.getAllSiblings();
540
+ return siblings;
541
+ };
542
+ const getRecommended = (id) => {
543
+ const related = id ? getRelatedLabels(id) : [];
544
+ const set = new Set([...related.map((x) => x.data.id), id].filter(Boolean));
545
+ return [...related, ...popularLabels.filter((x) => !set.has(x.data.id))].filter((x) => !!counts[x.data.id]);
546
+ };
547
+ const createLabel = async (name) => {
548
+ const saved = await createLabelAPI({ name });
549
+ const node = new LabelTreeNode({ data: new LabelTreeNode.Label(saved) });
550
+ state.tree.add(node);
551
+ state.tree = state.tree.clone();
552
+ return node.data;
553
+ };
554
+ const addLabelNode = (payload) => {
555
+ const parent = payload.parentId ? nodesKeyById[payload.parentId] : state.tree;
556
+ const node = new LabelTreeNode({ data: new LabelTreeNode.Label(payload) });
557
+ parent.add(node);
558
+ state.tree = state.tree.clone();
559
+ };
560
+ const updateLabelNode = (id, payload) => {
561
+ const existing = nodesKeyById[id];
562
+ if (existing && existing.parent) {
563
+ const node = new LabelTreeNode({ data: new LabelTreeNode.Label(payload) });
564
+ node.add(...existing.children);
565
+ if (existing.parent.data.id == payload.parentId) {
566
+ existing.parent.children = existing.parent.children.map((x) => {
567
+ if (x.data.id === id) {
568
+ node.setParent(existing.parent);
569
+ return node;
570
+ }
571
+ return x;
572
+ });
573
+ } else {
574
+ const parent = nodesKeyById[payload.parentId];
575
+ if (parent) {
576
+ existing.parent.children = existing.parent.children.filter((x) => x.data.id !== id);
577
+ parent.add(node);
578
+ }
579
+ }
580
+ state.tree = state.tree.clone();
581
+ }
582
+ };
583
+ const removeLabelNode = (id) => {
584
+ const node = nodesKeyById[id];
585
+ if (node == null ? void 0 : node.parent) {
586
+ node.parent.removeChild(node);
587
+ state.tree = state.tree.clone();
588
+ }
589
+ };
590
+ const getFullLabelName = (id) => {
591
+ var _a;
592
+ return ((_a = nodesKeyById[id]) == null ? void 0 : _a.getFullName(locale)) ?? id;
593
+ };
594
+ const parseLabelsStr = useCallback((labelIdsStr) => {
595
+ return (labelIdsStr == null ? void 0 : labelIdsStr.split(",").filter(Boolean)) || [];
596
+ }, []);
597
+ return {
598
+ ...state,
599
+ flattenedLabels: flattened,
600
+ popularLabels,
601
+ counts,
602
+ getLabelsByIds,
603
+ labelExists,
604
+ getLabelName,
605
+ getRelatedLabels,
606
+ getRecommended,
607
+ createLabel,
608
+ addLabelNode,
609
+ updateLabelNode,
610
+ removeLabelNode,
611
+ getFullLabelName,
612
+ parseLabelsStr
613
+ };
614
+ };
615
+ const LabelsContainer = createContainer(useLabels);
616
+ const LabelsContext = createContext({});
617
+ const useLabelsContext = () => useContext(LabelsContext);
618
+ const useLabelsUpdateOnDestroy = () => {
619
+ const { updateLabels } = useLabelsContext();
620
+ useEffect(() => {
621
+ return () => {
622
+ updateLabels();
623
+ };
624
+ }, []);
625
+ };
626
+ function LabelsProvider({ fetchLabels, createLabel, children }) {
627
+ const { locale } = useLocaleContext();
628
+ const [updateCounter, setUpdateCounter] = useState(1);
629
+ const { loading, data } = useRequest(fetchLabels, {
630
+ refreshDeps: [updateCounter]
631
+ });
632
+ const labels = useMemo(() => transformLabels((data == null ? void 0 : data.labels) || []), [data]);
633
+ const labelsKeyById = useMemo(() => {
634
+ if (!(labels == null ? void 0 : labels.length)) {
635
+ return {};
636
+ }
637
+ const flattened = flatten(labels);
638
+ return flattened.reduce((acc, cur) => ({ ...acc, [cur.id]: cur }), {});
639
+ }, [labels]);
640
+ const localeTransformer = useCallback(
641
+ (label) => {
642
+ var _a;
643
+ return {
644
+ ...label,
645
+ name: ((_a = label.translation) == null ? void 0 : _a[locale]) || label.name
646
+ };
647
+ },
648
+ [locale]
649
+ );
650
+ const getLabelsById = useCallback(
651
+ (ids) => ids.filter(Boolean).map((item) => labelsKeyById[item]).map(localeTransformer),
652
+ [labelsKeyById, localeTransformer]
653
+ );
654
+ const getParents = useCallback((label) => {
655
+ let { parent } = label;
656
+ const parents = [];
657
+ while (parent) {
658
+ parents.unshift(parent);
659
+ parent = parent.parent;
660
+ }
661
+ return parents;
662
+ }, []);
663
+ const getFullLabelName = useCallback(
664
+ (label) => {
665
+ const parents = [...getParents(label), label].map(localeTransformer);
666
+ return parents.map((item) => item.name).join(" / ");
667
+ },
668
+ [localeTransformer, getParents]
669
+ );
670
+ const parseLabelIds = useCallback((labelIdsStr) => {
671
+ return (labelIdsStr == null ? void 0 : labelIdsStr.split(",").filter(Boolean)) || [];
672
+ }, []);
673
+ const stringifyLabelIds = useCallback((labelIds = []) => {
674
+ if (!(labelIds == null ? void 0 : labelIds.length)) {
675
+ return void 0;
676
+ }
677
+ return labelIds.join(",");
678
+ }, []);
679
+ const localizedLabels = useMemo(() => labels.map(localeTransformer), [labels, localeTransformer]);
680
+ const value = useMemo(() => {
681
+ return {
682
+ loading,
683
+ labels: labels || [],
684
+ updateLabels: () => setUpdateCounter((prev) => prev + 1),
685
+ getLabelsById,
686
+ parseLabelIds,
687
+ stringifyLabelIds,
688
+ localizedLabels,
689
+ flattenedLabels: flatten(localizedLabels || []),
690
+ getFullLabelName
691
+ };
692
+ }, [loading, labels, getLabelsById, parseLabelIds, stringifyLabelIds, localizedLabels, getFullLabelName]);
693
+ return /* @__PURE__ */ jsx(LabelsContext.Provider, { value, children: /* @__PURE__ */ jsx(LabelsContainer.Provider, { initialState: { loading, data, createLabel }, children }) });
694
+ }
695
+ const getContrastTextColor = (bgcolor) => {
696
+ try {
697
+ const ratio = getContrastRatio(bgcolor, "#fff");
698
+ return ratio > 2.7 ? "#fff" : "#111";
699
+ } catch {
700
+ return "#111";
701
+ }
702
+ };
703
+ const getAlphaColor = (color, alpha$1) => {
704
+ try {
705
+ if (color) {
706
+ return alpha(color, alpha$1);
707
+ }
708
+ } catch {
709
+ return color;
710
+ }
711
+ return color;
712
+ };
713
+ function Labels({ labels, editable, onChange, sx, renderLabel }) {
714
+ const isEmpty = !(labels == null ? void 0 : labels.length);
715
+ const { labels: allLabels, loading, getLabelsById, getFullLabelName } = useLabelsContext();
716
+ const [editing, setEditing] = useState(false);
717
+ if (loading || !editable && isEmpty) {
718
+ return null;
719
+ }
720
+ const handleOnChange = (v) => {
721
+ onChange == null ? void 0 : onChange(v);
722
+ setTimeout(() => {
723
+ setEditing(false);
724
+ }, 300);
725
+ };
726
+ if (editing) {
727
+ return /* @__PURE__ */ jsx(ClickAwayListener, { onClickAway: () => editing && setEditing(false), children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(LabelPicker, { data: allLabels, value: labels || [], onChange: handleOnChange }) }) });
728
+ }
729
+ const labelObjects = getLabelsById(labels || []).filter((x) => x.type !== "system");
730
+ const mergedSx = [
731
+ { display: "flex", gap: 1, alignItems: "center", flexWrap: "wrap" },
732
+ ...Array.isArray(sx) ? sx : [sx]
733
+ ];
734
+ return /* @__PURE__ */ jsxs(Box$1, { sx: mergedSx, children: [
735
+ labelObjects.map((item) => {
736
+ if (!item) {
737
+ return null;
738
+ }
739
+ if (renderLabel) {
740
+ return renderLabel(item);
741
+ }
742
+ return /* @__PURE__ */ jsx(
743
+ Chip,
744
+ {
745
+ label: getFullLabelName(item),
746
+ variant: "filled",
747
+ size: "small",
748
+ sx: {
749
+ height: 20,
750
+ borderRadius: 1,
751
+ fontSize: 12,
752
+ bgcolor: getAlphaColor(item.color || "#ddd", 0.8),
753
+ color: getContrastTextColor(item.color || "#ddd")
754
+ }
755
+ },
756
+ item.id
757
+ );
758
+ }),
759
+ editable && !isEmpty && /* @__PURE__ */ jsx(IconButton, { color: "inherit", size: "small", onClick: () => setEditing(true), sx: { color: "grey.400" }, children: /* @__PURE__ */ jsx(Edit, { sx: { fontSize: 20 } }) }),
760
+ editable && isEmpty && /* @__PURE__ */ jsx(Button, { color: "inherit", variant: "outlined", startIcon: /* @__PURE__ */ jsx(LabelOutlined, {}), onClick: () => setEditing(true), children: "Edit labels" })
761
+ ] });
762
+ }
763
+ const mdiTagPlusOutline = (props) => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", width: "1.2em", height: "1.2em", ...props, children: /* @__PURE__ */ jsx("path", { fill: "currentColor", d: "M6.5 5A1.5 1.5 0 1 0 8 6.5A1.5 1.5 0 0 0 6.5 5m0 0A1.5 1.5 0 1 0 8 6.5A1.5 1.5 0 0 0 6.5 5m14.91 6.58l-9-9A2 2 0 0 0 11 2H4a2 2 0 0 0-2 2v7a2 2 0 0 0 .59 1.42l.41.4a5.62 5.62 0 0 1 2.08-.74L4 11V4h7l9 9l-7 7l-1.08-1.08a5.57 5.57 0 0 1-.74 2.08l.41.41A2 2 0 0 0 13 22a2 2 0 0 0 1.41-.59l7-7A2 2 0 0 0 22 13a2 2 0 0 0-.59-1.42M6.5 5A1.5 1.5 0 1 0 8 6.5A1.5 1.5 0 0 0 6.5 5M10 19H7v3H5v-3H2v-2h3v-3h2v3h3Z" }) });
764
+ const getTextColor = (color) => {
765
+ return chroma(color).hex();
766
+ };
767
+ const getBorderColor = (color) => {
768
+ if (chroma(color).luminance() > 0.5) {
769
+ return chroma(color).darken(3).hex();
770
+ }
771
+ return chroma(color).brighten(0.5).alpha(0.25).hex();
772
+ };
773
+ const getBackgroundColor = (color) => {
774
+ if (chroma(color).luminance() > 0.5) {
775
+ return chroma(color).darken(2.5).hex();
776
+ }
777
+ return chroma(color).brighten(2.5).alpha(0.25).hex();
778
+ };
779
+ const getFilterStyle = (color) => {
780
+ if (chroma(color).luminance() > 0.5) {
781
+ return "brightness(0.85) contrast(1.2)";
782
+ }
783
+ return "brightness(0.85) contrast(1.2)";
784
+ };
785
+ function LabelChip({
786
+ label,
787
+ onDelete,
788
+ sx,
789
+ fullName = true,
790
+ onClick,
791
+ disabled = false,
792
+ renderName = (name) => name
793
+ }) {
794
+ const { getFullLabelName, getLabelName } = LabelsContainer.useContainer();
795
+ const mergedSx = [
796
+ {
797
+ height: 20,
798
+ borderRadius: 0.5,
799
+ fontSize: 12,
800
+ fontWeight: 500,
801
+ color: `${getTextColor(label.data.color)} !important`,
802
+ bgcolor: `${getBackgroundColor(label.data.color)} !important`,
803
+ transition: "filter 0.2s",
804
+ borderColor: `${getBorderColor(label.data.color)} !important`,
805
+ // -webkit-text-fill-color
806
+ WebkitTextFillColor: `${getTextColor(label.data.color)} !important`,
807
+ ".MuiChip-deleteIcon": {
808
+ color: `${getTextColor(label.data.color)} !important`,
809
+ cursor: "pointer",
810
+ transition: "transform 0.3s",
811
+ "&:hover": {
812
+ transform: "rotate(90deg)"
813
+ }
814
+ },
815
+ ".MuiChip-label": {
816
+ px: 0.5,
817
+ maxHeight: 20
818
+ },
819
+ ...onClick && {
820
+ cursor: "pointer",
821
+ "&:hover": {
822
+ filter: getFilterStyle(label.data.color)
823
+ }
824
+ }
825
+ },
826
+ ...Array.isArray(sx) ? sx : [sx]
827
+ ];
828
+ const hasDelete = !disabled && !!onDelete;
829
+ const hasOnClick = !disabled && !!onClick;
830
+ return (
831
+ // @ts-ignore
832
+ /* @__PURE__ */ jsx(
833
+ Chip,
834
+ {
835
+ label: renderName(fullName ? getFullLabelName(label.data.id) : getLabelName(label.data.id)),
836
+ variant: "outlined",
837
+ size: "small",
838
+ ...hasDelete && {
839
+ onDelete: (e) => {
840
+ e.stopPropagation();
841
+ e.preventDefault();
842
+ onDelete(label);
843
+ },
844
+ deleteIcon: /* @__PURE__ */ jsx(CloseOutlineIcon, {})
845
+ },
846
+ ...hasOnClick && {
847
+ onClick: (e) => {
848
+ e.stopPropagation();
849
+ e.preventDefault();
850
+ onClick(label);
851
+ }
852
+ },
853
+ sx: mergedSx
854
+ },
855
+ label.data.id
856
+ )
857
+ );
858
+ }
859
+ function Labels2({
860
+ compact = true,
861
+ labels,
862
+ sx,
863
+ renderLabel,
864
+ prepend,
865
+ displaySystemLabels = true,
866
+ onItemClick
867
+ }) {
868
+ const { getLabelsByIds, loading } = LabelsContainer.useContainer();
869
+ const labelsWrapperRef = useRef(null);
870
+ const [overflowIndex, setOverflowIndex] = useState(99999);
871
+ let labelNodes = getLabelsByIds(labels || []);
872
+ const size = useSize(labelsWrapperRef);
873
+ useDeepCompareLayoutEffect(() => {
874
+ if (compact) {
875
+ if (labelsWrapperRef.current) {
876
+ const { right } = labelsWrapperRef.current.getBoundingClientRect();
877
+ const labelElements = labelsWrapperRef.current.querySelectorAll(".MuiChip-root");
878
+ if ((labelElements == null ? void 0 : labelElements.length) > 0) {
879
+ Array.from(labelElements).some((x, i) => {
880
+ const rect = x.getBoundingClientRect();
881
+ if (rect.right > right - 36) {
882
+ setOverflowIndex(i);
883
+ return true;
884
+ }
885
+ return false;
886
+ });
887
+ }
888
+ }
889
+ } else {
890
+ setOverflowIndex(99999);
891
+ }
892
+ }, [size, compact]);
893
+ if (loading) {
894
+ return null;
895
+ }
896
+ if (!displaySystemLabels) {
897
+ labelNodes = labelNodes.filter((x) => x.data.type !== "system");
898
+ }
899
+ const mergedSx = [
900
+ {
901
+ display: "flex",
902
+ gap: 1,
903
+ width: "100%",
904
+ alignItems: "center",
905
+ overflow: "hidden",
906
+ flexWrap: compact ? "no-wrap" : "wrap"
907
+ },
908
+ ...Array.isArray(sx) ? sx : [sx]
909
+ ];
910
+ return /* @__PURE__ */ jsxs(Box$1, { sx: mergedSx, ref: labelsWrapperRef, children: [
911
+ prepend,
912
+ labelNodes.map((item, index) => {
913
+ if (!item) {
914
+ return null;
915
+ }
916
+ const visible = index < overflowIndex;
917
+ let extra = null;
918
+ if (index === overflowIndex) {
919
+ extra = /* @__PURE__ */ jsx(
920
+ Box$1,
921
+ {
922
+ sx: {
923
+ display: "inline-flex",
924
+ ...compact && { height: 20, lineHeight: "20px" },
925
+ color: "text.secondary",
926
+ fontWeight: "bold",
927
+ fontSize: 14
928
+ },
929
+ children: `+${labelNodes.length - overflowIndex}`
930
+ },
931
+ "overflow-label"
932
+ );
933
+ }
934
+ let labelChip = /* @__PURE__ */ jsx(
935
+ LabelChip,
936
+ {
937
+ label: item,
938
+ onClick: onItemClick,
939
+ sx: {
940
+ visibility: visible ? "visible" : "hidden",
941
+ pointerEvents: visible ? "auto" : "none"
942
+ }
943
+ },
944
+ item.data.id
945
+ );
946
+ if (renderLabel) {
947
+ labelChip = renderLabel(item, labelChip);
948
+ }
949
+ if (extra) {
950
+ return [extra, labelChip];
951
+ }
952
+ return labelChip;
953
+ })
954
+ ] });
955
+ }
956
+ const useSessionContext = () => {
957
+ var _a, _b;
958
+ const ctx = useContext(SessionContext) || {};
959
+ const loginRole = (_b = (_a = ctx == null ? void 0 : ctx.session) == null ? void 0 : _a.user) == null ? void 0 : _b.role;
960
+ return {
961
+ ...ctx,
962
+ isAdmin: ["admin", "owner"].includes(loginRole),
963
+ hasAnyPassport: (passports) => {
964
+ if (!passports || passports.length === 0) {
965
+ return true;
966
+ }
967
+ const passportsArr = Array.isArray(passports) ? passports : [passports];
968
+ return passportsArr.includes(loginRole);
969
+ }
970
+ };
971
+ };
972
+ function PopperComponent({
973
+ disablePortal,
974
+ anchorEl,
975
+ open,
976
+ ...other
977
+ }) {
978
+ return /* @__PURE__ */ jsx(
979
+ Box$1,
980
+ {
981
+ ...other,
982
+ sx: (theme) => ({
983
+ [`& .${autocompleteClasses.paper}`]: {
984
+ boxShadow: "none",
985
+ margin: 0,
986
+ color: "inherit",
987
+ fontSize: 13
988
+ },
989
+ [`& .${autocompleteClasses.listbox}`]: {
990
+ backgroundColor: theme.palette.mode === "light" ? "#fff" : "#1c2128",
991
+ padding: 0,
992
+ [`& .${autocompleteClasses.option}`]: {
993
+ minHeight: "auto",
994
+ alignItems: "flex-start",
995
+ padding: 1,
996
+ borderBottom: `1px solid ${theme.palette.mode === "light" ? " #eaecef" : "#30363d"}`,
997
+ '&[aria-selected="true"]': {
998
+ backgroundColor: "transparent"
999
+ },
1000
+ [`&.${autocompleteClasses.focused}, &.${autocompleteClasses.focused}[aria-selected="true"]`]: {
1001
+ backgroundColor: theme.palette.action.hover
1002
+ }
1003
+ }
1004
+ },
1005
+ [`&.${autocompleteClasses.popperDisablePortal}`]: {
1006
+ position: "relative"
1007
+ }
1008
+ })
1009
+ }
1010
+ );
1011
+ }
1012
+ function GithubLabelPicker({
1013
+ value = [],
1014
+ onChange,
1015
+ title,
1016
+ noLabelsText,
1017
+ buttonSx,
1018
+ actions,
1019
+ trigger,
1020
+ multiple = true,
1021
+ updateImmediately = true,
1022
+ excludes = [],
1023
+ disabled = false,
1024
+ enableAccessControl = true
1025
+ }) {
1026
+ const { locale } = useLocaleContext();
1027
+ const { isAdmin, hasAnyPassport } = useSessionContext();
1028
+ const { flattenedLabels: labels, getLabelsByIds, loading, createLabel } = LabelsContainer.useContainer();
1029
+ const [anchorEl, setAnchorEl] = useState(null);
1030
+ const [pendingValue, setPendingValue] = useState([]);
1031
+ const pendingOptions = useMemo(() => getLabelsByIds(pendingValue), [getLabelsByIds, pendingValue]);
1032
+ const [inputValue, setInputValue] = useState("");
1033
+ const exists = useMemo(
1034
+ () => labels.some((x) => x.data.getName(locale).toLowerCase() === inputValue.toLowerCase()),
1035
+ [inputValue, labels, locale]
1036
+ );
1037
+ const filteredLabels = useMemo(() => {
1038
+ const excludesSet = new Set(excludes);
1039
+ return labels.filter((x) => !excludesSet.has(x.data.id));
1040
+ }, [labels]);
1041
+ const theme = useTheme();
1042
+ const handleClick = (event) => {
1043
+ if (disabled) {
1044
+ return;
1045
+ }
1046
+ event.preventDefault();
1047
+ setPendingValue(value);
1048
+ setAnchorEl(event.currentTarget);
1049
+ };
1050
+ const handleClose = () => {
1051
+ if (!updateImmediately) {
1052
+ onChange == null ? void 0 : onChange(pendingValue);
1053
+ }
1054
+ setInputValue("");
1055
+ if (anchorEl) {
1056
+ anchorEl.focus();
1057
+ }
1058
+ setAnchorEl(null);
1059
+ };
1060
+ const handleCreate = async () => {
1061
+ const { id: id2 } = await createLabel(inputValue);
1062
+ setPendingValue([...pendingValue, id2]);
1063
+ };
1064
+ const open = Boolean(anchorEl);
1065
+ const id = open ? "github-label-picker" : void 0;
1066
+ if (loading) {
1067
+ return null;
1068
+ }
1069
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
1070
+ /* @__PURE__ */ jsx(
1071
+ Box$1,
1072
+ {
1073
+ onClick: handleClick,
1074
+ sx: {
1075
+ display: "flex",
1076
+ alignItems: "center"
1077
+ },
1078
+ children: trigger || /* @__PURE__ */ jsx(
1079
+ Box$1,
1080
+ {
1081
+ component: ButtonBase,
1082
+ disableRipple: true,
1083
+ "aria-describedby": id,
1084
+ className: "label-picker-trigger",
1085
+ sx: [
1086
+ (t) => ({
1087
+ width: "100%",
1088
+ fontSize: 13,
1089
+ color: t.palette.mode === "light" ? "#586069" : "#8b949e",
1090
+ fontWeight: 600,
1091
+ "&:hover": {
1092
+ color: t.palette.mode === "light" ? "primary.main" : "#58a6ff"
1093
+ },
1094
+ "& svg": {
1095
+ width: 22,
1096
+ height: 22
1097
+ }
1098
+ }),
1099
+ ...Array.isArray(buttonSx) ? buttonSx : [buttonSx]
1100
+ ],
1101
+ children: /* @__PURE__ */ jsx(mdiTagPlusOutline, {})
1102
+ }
1103
+ )
1104
+ }
1105
+ ),
1106
+ /* @__PURE__ */ jsx(
1107
+ Box$1,
1108
+ {
1109
+ component: Popper,
1110
+ id,
1111
+ open,
1112
+ anchorEl,
1113
+ placement: "bottom-start",
1114
+ disablePortal: true,
1115
+ sx: (t) => ({
1116
+ border: `1px solid ${t.palette.mode === "light" ? "#e1e4e8" : "#30363d"}`,
1117
+ boxShadow: `0 8px 24px ${t.palette.mode === "light" ? "rgba(149, 157, 165, 0.2)" : "rgb(1, 4, 9)"}`,
1118
+ borderRadius: "4px",
1119
+ width: 300,
1120
+ zIndex: t.zIndex.modal,
1121
+ fontSize: 13,
1122
+ color: t.palette.mode === "light" ? "#24292e" : "#c9d1d9",
1123
+ backgroundColor: t.palette.mode === "light" ? "#fff" : "#1c2128"
1124
+ }),
1125
+ children: /* @__PURE__ */ jsx(ClickAwayListener, { onClickAway: handleClose, children: /* @__PURE__ */ jsxs(Box$1, { onClick: (e) => e.preventDefault(), children: [
1126
+ title && /* @__PURE__ */ jsx(
1127
+ Box$1,
1128
+ {
1129
+ sx: {
1130
+ borderBottom: `1px solid ${theme.palette.mode === "light" ? "#eaecef" : "#30363d"}`,
1131
+ padding: "8px 10px",
1132
+ fontWeight: 600
1133
+ },
1134
+ children: title
1135
+ }
1136
+ ),
1137
+ /* @__PURE__ */ jsx(
1138
+ Autocomplete,
1139
+ {
1140
+ open: true,
1141
+ multiple: true,
1142
+ inputValue,
1143
+ onInputChange: (event, newInputValue, reason) => {
1144
+ if (reason === "reset") {
1145
+ return;
1146
+ }
1147
+ setInputValue(newInputValue);
1148
+ },
1149
+ onClose: (event, reason) => {
1150
+ if (reason === "escape") {
1151
+ handleClose();
1152
+ }
1153
+ },
1154
+ value: pendingOptions,
1155
+ onChange: (event, newValue, reason) => {
1156
+ event.preventDefault();
1157
+ if (event.type === "keydown" && event.key === "Backspace" && reason === "removeOption") {
1158
+ return;
1159
+ }
1160
+ setPendingValue(newValue.map((x) => x.data.id));
1161
+ if (!multiple) {
1162
+ onChange == null ? void 0 : onChange(newValue.length ? [newValue[newValue.length - 1].data.id] : []);
1163
+ setAnchorEl(null);
1164
+ } else if (updateImmediately) {
1165
+ onChange(newValue.map((x) => x.data.id));
1166
+ }
1167
+ },
1168
+ disableCloseOnSelect: true,
1169
+ PopperComponent,
1170
+ renderTags: () => null,
1171
+ noOptionsText: noLabelsText || "No labels",
1172
+ renderOption: (props, option, { selected }) => {
1173
+ const label = option.data;
1174
+ const passportsToCheck = [
1175
+ ...label.passports || [],
1176
+ ...label.type === "system" ? ["admin", "owner"] : []
1177
+ ];
1178
+ const isPermitted = !enableAccessControl || isAdmin || hasAnyPassport(passportsToCheck);
1179
+ if (!isPermitted) {
1180
+ props.onClick = () => {
1181
+ };
1182
+ if (!(value == null ? void 0 : value.includes(label.id))) {
1183
+ return null;
1184
+ }
1185
+ }
1186
+ return /* @__PURE__ */ createElement(
1187
+ Box$1,
1188
+ {
1189
+ component: "li",
1190
+ ...props,
1191
+ key: option.data.id,
1192
+ sx: {
1193
+ ...!isPermitted && { bgcolor: "grey.100", cursor: "not-allowed!important" }
1194
+ }
1195
+ },
1196
+ /* @__PURE__ */ jsxs(
1197
+ Box$1,
1198
+ {
1199
+ sx: {
1200
+ display: "flex",
1201
+ alignItems: "center",
1202
+ width: 1
1203
+ },
1204
+ children: [
1205
+ /* @__PURE__ */ jsx(
1206
+ Box$1,
1207
+ {
1208
+ component: DoneIcon,
1209
+ sx: { width: 17, height: 17, mr: "5px", ml: "-2px" },
1210
+ style: {
1211
+ visibility: selected ? "visible" : "hidden"
1212
+ }
1213
+ }
1214
+ ),
1215
+ /* @__PURE__ */ jsx(
1216
+ Box$1,
1217
+ {
1218
+ sx: {
1219
+ flexGrow: 1,
1220
+ alignItems: "center",
1221
+ display: "flex"
1222
+ },
1223
+ children: /* @__PURE__ */ jsx(LabelChip, { label: option, disabled: disabled || !isPermitted })
1224
+ }
1225
+ ),
1226
+ /* @__PURE__ */ jsx(
1227
+ Box$1,
1228
+ {
1229
+ component: CloseOutlineIcon,
1230
+ sx: { opacity: 0.6, width: 18, height: 18 },
1231
+ style: {
1232
+ visibility: selected ? "visible" : "hidden"
1233
+ }
1234
+ }
1235
+ )
1236
+ ]
1237
+ }
1238
+ )
1239
+ );
1240
+ },
1241
+ options: [...filteredLabels].sort((a, b) => {
1242
+ let ai = value.indexOf(a.data.id);
1243
+ ai = ai === -1 ? value.length + filteredLabels.indexOf(a) : ai;
1244
+ let bi = value.indexOf(b.data.id);
1245
+ bi = bi === -1 ? value.length + filteredLabels.indexOf(b) : bi;
1246
+ return ai - bi;
1247
+ }),
1248
+ getOptionLabel: (option) => option.data.getName(locale),
1249
+ renderInput: (params) => /* @__PURE__ */ jsx(
1250
+ Box$1,
1251
+ {
1252
+ component: InputBase,
1253
+ ref: params.InputProps.ref,
1254
+ inputProps: params.inputProps,
1255
+ autoFocus: true,
1256
+ placeholder: "Filter labels",
1257
+ sx: (t) => ({
1258
+ padding: 1,
1259
+ width: "100%",
1260
+ borderBottom: `1px solid ${t.palette.mode === "light" ? "#eaecef" : "#30363d"}`,
1261
+ "& input": {
1262
+ borderRadius: "4px",
1263
+ backgroundColor: t.palette.mode === "light" ? "#fff" : "#0d1117",
1264
+ padding: 1,
1265
+ transition: t.transitions.create(["border-color", "box-shadow"]),
1266
+ border: `1px solid ${t.palette.mode === "light" ? "#eaecef" : "#30363d"}`,
1267
+ fontSize: 14,
1268
+ "&:focus": {
1269
+ boxShadow: `0px 0px 0px 3px ${t.palette.mode === "light" ? alpha(t.palette.primary.light, 0.4) : "rgb(12, 45, 107)"}`,
1270
+ borderColor: t.palette.mode === "light" ? t.palette.primary.light : "#388bfd"
1271
+ }
1272
+ }
1273
+ })
1274
+ }
1275
+ )
1276
+ }
1277
+ ),
1278
+ /* @__PURE__ */ jsxs(Box$1, { children: [
1279
+ inputValue && !exists && /* @__PURE__ */ jsx(
1280
+ Box$1,
1281
+ {
1282
+ sx: {
1283
+ display: "flex",
1284
+ alignItems: "center",
1285
+ gap: 1,
1286
+ width: "100%",
1287
+ height: 36,
1288
+ px: 2,
1289
+ borderTop: "1px solid #eee",
1290
+ fontSize: 14,
1291
+ color: "grey.600",
1292
+ cursor: "pointer",
1293
+ textDecoration: "none"
1294
+ },
1295
+ onClick: handleCreate,
1296
+ children: /* @__PURE__ */ jsxs("span", { children: [
1297
+ 'Create new label "',
1298
+ inputValue,
1299
+ '"'
1300
+ ] })
1301
+ }
1302
+ ),
1303
+ actions
1304
+ ] })
1305
+ ] }) })
1306
+ }
1307
+ )
1308
+ ] });
1309
+ }
1310
+ function LabelsInput({
1311
+ value = [],
1312
+ onChange,
1313
+ LabelPickerProps,
1314
+ sx,
1315
+ ...rest
1316
+ }) {
1317
+ var _a;
1318
+ const { getLabelsByIds, loading } = LabelsContainer.useContainer();
1319
+ const valueOptions = useMemo(() => getLabelsByIds(value), [getLabelsByIds, value]);
1320
+ const mergedSx = [
1321
+ {
1322
+ "& .MuiInputBase-root": { flexWrap: "wrap", gap: 0.5, py: 0.75 },
1323
+ "& .MuiInputBase-input": { width: !(value == null ? void 0 : value.length) ? "initial" : "20px", p: 0 }
1324
+ },
1325
+ ...Array.isArray(sx) ? sx : [sx]
1326
+ ];
1327
+ const placeholder = !(value == null ? void 0 : value.length) ? rest.placeholder || "Select labels" : "";
1328
+ if (loading) {
1329
+ return null;
1330
+ }
1331
+ return /* @__PURE__ */ jsx(
1332
+ GithubLabelPicker,
1333
+ {
1334
+ value,
1335
+ onChange,
1336
+ trigger: /* @__PURE__ */ jsx(
1337
+ TextField,
1338
+ {
1339
+ ...rest,
1340
+ placeholder,
1341
+ fullWidth: true,
1342
+ InputProps: {
1343
+ autoComplete: "off",
1344
+ ...rest.InputProps,
1345
+ startAdornment: [
1346
+ (_a = rest.InputProps) == null ? void 0 : _a.startAdornment,
1347
+ ...valueOptions.map((x, index) => /* @__PURE__ */ jsx(LabelChip, { label: x }, index))
1348
+ ].filter(Boolean)
1349
+ },
1350
+ sx: mergedSx
1351
+ }
1352
+ ),
1353
+ ...LabelPickerProps
1354
+ }
1355
+ );
1356
+ }
59
1357
  export {
60
- G as GithubLabelPicker,
61
- j as LabelChip,
62
- b as LabelPicker,
63
- a as LabelTree,
64
- L as LabelTreeNode,
65
- d as Labels,
66
- k as Labels2,
67
- h as LabelsContainer,
68
- i as LabelsInput,
69
- f as LabelsProvider,
70
- u as useLabelsContext,
71
- e as useLabelsUpdateOnDestroy
1358
+ GithubLabelPicker,
1359
+ LabelChip,
1360
+ LabelPicker,
1361
+ LabelTree,
1362
+ LabelTreeNode,
1363
+ Labels,
1364
+ Labels2,
1365
+ LabelsContainer,
1366
+ LabelsInput,
1367
+ LabelsProvider,
1368
+ useLabelsContext,
1369
+ useLabelsUpdateOnDestroy
72
1370
  };