@reopt-ai/opt-ui 1.11.0 → 1.12.1
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/COMPONENT_CATALOG.md +495 -230
- package/README.md +43 -5
- package/dist/core/index.cjs +2 -2
- package/dist/core/index.d.cts +2 -2
- package/dist/core/index.d.ts +2 -2
- package/dist/core/index.js +2 -2
- package/dist/docs/02-components/01-core.md +154 -85
- package/dist/docs/02-components/02-visuals.md +1 -1
- package/dist/docs/02-components/03-shells.md +349 -149
- package/dist/docs/02-components/04-surfaces.md +1 -1
- package/dist/docs/02-components/index.md +5 -5
- package/dist/docs/03-recipes/02-dashboards.md +126 -10
- package/dist/{field-sidebar-B5SQC35J.d.cts → field-sidebar-CrYlRZew.d.ts} +164 -154
- package/dist/{field-sidebar-DAuN4jPV.cjs → field-sidebar-oa6zOmcd.cjs} +1540 -1537
- package/dist/{field-sidebar-CBeWE8xX.d.ts → field-sidebar-uXmoyvd7.d.cts} +164 -154
- package/dist/{field-sidebar-BXl5RJ3q.js → field-sidebar-zkkqC7__.js} +1541 -1540
- package/dist/id-registry.cjs +78 -6
- package/dist/id-registry.d.cts +1 -2
- package/dist/id-registry.d.ts +1 -2
- package/dist/id-registry.js +78 -8
- package/dist/id-registry.json +168 -19
- package/dist/index.cjs +1127 -224
- package/dist/index.d.cts +567 -58
- package/dist/index.d.ts +567 -58
- package/dist/index.js +1118 -227
- package/dist/{key-pad-menu-BxTy_u0Q.d.cts → key-pad-menu-CwcY_Vps.d.cts} +2 -3
- package/dist/{key-pad-menu-wXkWn1I1.js → key-pad-menu-Di2aRGbM.js} +4 -6
- package/dist/{key-pad-menu-Cg6rZBie.cjs → key-pad-menu-SItoHPLu.cjs} +1 -1
- package/dist/{key-pad-menu-u5GTJl9B.d.ts → key-pad-menu-WBJShCJn.d.ts} +3 -4
- package/dist/meta.cjs +894 -28
- package/dist/meta.d.cts +12 -36
- package/dist/meta.d.ts +12 -36
- package/dist/meta.js +894 -30
- package/dist/query.d.cts +1 -2
- package/dist/query.d.ts +1 -2
- package/dist/query.js +0 -2
- package/dist/shells/index.cjs +1 -1
- package/dist/shells/index.d.cts +1 -1
- package/dist/shells/index.d.ts +1 -1
- package/dist/shells/index.js +1 -1
- package/dist/tailwind.css +7 -0
- package/dist/{text-truncate-DW78lg4S.d.cts → text-truncate-CQyfUZvq.d.cts} +31 -3
- package/dist/{text-truncate-DW78lg4S.d.ts → text-truncate-CQyfUZvq.d.ts} +31 -3
- package/dist/{text-truncate-C17HHCR-.js → text-truncate-DSuZECy0.js} +43 -10
- package/dist/{text-truncate-BZdL1k5Z.cjs → text-truncate-I1XLWmRa.cjs} +48 -7
- package/dist/theme/server.d.cts +1 -2
- package/dist/theme/server.d.ts +1 -2
- package/dist/theme/server.js +0 -2
- package/dist/visuals/index.js +0 -1
- package/package.json +4 -3
- package/dist/field-sidebar-B5SQC35J.d.cts.map +0 -1
- package/dist/field-sidebar-BXl5RJ3q.js.map +0 -1
- package/dist/field-sidebar-CBeWE8xX.d.ts.map +0 -1
- package/dist/id-registry.d.cts.map +0 -1
- package/dist/id-registry.d.ts.map +0 -1
- package/dist/id-registry.js.map +0 -1
- package/dist/index.d.cts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/key-pad-menu-BxTy_u0Q.d.cts.map +0 -1
- package/dist/key-pad-menu-u5GTJl9B.d.ts.map +0 -1
- package/dist/key-pad-menu-wXkWn1I1.js.map +0 -1
- package/dist/meta.d.cts.map +0 -1
- package/dist/meta.d.ts.map +0 -1
- package/dist/meta.js.map +0 -1
- package/dist/query.d.cts.map +0 -1
- package/dist/query.d.ts.map +0 -1
- package/dist/query.js.map +0 -1
- package/dist/text-truncate-C17HHCR-.js.map +0 -1
- package/dist/text-truncate-DW78lg4S.d.cts.map +0 -1
- package/dist/text-truncate-DW78lg4S.d.ts.map +0 -1
- package/dist/theme/server.d.cts.map +0 -1
- package/dist/theme/server.d.ts.map +0 -1
- package/dist/theme/server.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1,17 +1,355 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
-
const require_text_truncate = require("./text-truncate-
|
|
4
|
-
const require_key_pad_menu = require("./key-pad-menu-
|
|
5
|
-
const require_field_sidebar = require("./field-sidebar-
|
|
3
|
+
const require_text_truncate = require("./text-truncate-I1XLWmRa.cjs");
|
|
4
|
+
const require_key_pad_menu = require("./key-pad-menu-SItoHPLu.cjs");
|
|
5
|
+
const require_field_sidebar = require("./field-sidebar-oa6zOmcd.cjs");
|
|
6
6
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
7
|
let react = require("react");
|
|
8
8
|
react = require_text_truncate.__toESM(react, 1);
|
|
9
|
+
let _reopt_ai_opt_ui_primitives = require("@reopt-ai/opt-ui-primitives");
|
|
9
10
|
let lucide_react = require("lucide-react");
|
|
10
11
|
let _reopt_ai_opt_palette = require("@reopt-ai/opt-palette");
|
|
11
12
|
let _reopt_ai_opt_charts = require("@reopt-ai/opt-charts");
|
|
12
13
|
let match_sorter = require("match-sorter");
|
|
13
14
|
let next_navigation = require("next/navigation");
|
|
14
|
-
|
|
15
|
+
//#region src/core/callout.tsx
|
|
16
|
+
const _excluded$2 = [
|
|
17
|
+
"tone",
|
|
18
|
+
"title",
|
|
19
|
+
"icon",
|
|
20
|
+
"action",
|
|
21
|
+
"size",
|
|
22
|
+
"className",
|
|
23
|
+
"children"
|
|
24
|
+
];
|
|
25
|
+
const toneStyles = {
|
|
26
|
+
info: "border-info/40 bg-info-subtle",
|
|
27
|
+
success: "border-success/40 bg-success-subtle",
|
|
28
|
+
warning: "border-warning/40 bg-warning-subtle",
|
|
29
|
+
danger: "border-danger/40 bg-danger-subtle",
|
|
30
|
+
neutral: "border-border bg-bg-subtle"
|
|
31
|
+
};
|
|
32
|
+
const iconTone = {
|
|
33
|
+
info: "text-info-fg",
|
|
34
|
+
success: "text-success-fg",
|
|
35
|
+
warning: "text-warning-fg",
|
|
36
|
+
danger: "text-danger-fg",
|
|
37
|
+
neutral: "text-text-tertiary"
|
|
38
|
+
};
|
|
39
|
+
const titleTone = {
|
|
40
|
+
info: "text-info-fg",
|
|
41
|
+
success: "text-success-fg",
|
|
42
|
+
warning: "text-warning-fg",
|
|
43
|
+
danger: "text-danger-fg",
|
|
44
|
+
neutral: "text-text-primary"
|
|
45
|
+
};
|
|
46
|
+
const defaultIcons = {
|
|
47
|
+
info: lucide_react.Info,
|
|
48
|
+
success: lucide_react.CircleCheck,
|
|
49
|
+
warning: lucide_react.TriangleAlert,
|
|
50
|
+
danger: lucide_react.CircleAlert,
|
|
51
|
+
neutral: null
|
|
52
|
+
};
|
|
53
|
+
const sizeStyles$3 = {
|
|
54
|
+
sm: "gap-2 p-2.5 text-xs [&_svg]:size-3.5",
|
|
55
|
+
md: "gap-3 p-3 text-sm [&_svg]:size-4"
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Callout — a notice that belongs to the page, not to the moment.
|
|
59
|
+
*
|
|
60
|
+
* `Alert` reports something that just happened and can be dismissed once read.
|
|
61
|
+
* A callout is the opposite: it is part of the layout, it is true for as long
|
|
62
|
+
* as the condition holds, and dismissing it would only hide a fact that is
|
|
63
|
+
* still true. "12 new events to triage" above a list, or "these numbers come
|
|
64
|
+
* from a 10,000-row sample" above a chart — both are read many times and
|
|
65
|
+
* dismissed never.
|
|
66
|
+
*
|
|
67
|
+
* That is why there is no `onDismiss` here, and why `action` takes one control:
|
|
68
|
+
* a notice earns its space by naming the single thing to do about it.
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```tsx
|
|
72
|
+
* <Callout tone="info" title="정리할 신규 이벤트 12개"
|
|
73
|
+
* action={<Button size="sm" onClick={showNew}>보기</Button>}>
|
|
74
|
+
* 7일 안에 처음 관측된 이벤트입니다.
|
|
75
|
+
* </Callout>
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
function Callout(_ref) {
|
|
79
|
+
let { tone = "info", title, icon, action, size = "md", className, children } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$2);
|
|
80
|
+
const DefaultIcon = defaultIcons[tone];
|
|
81
|
+
const glyph = icon === void 0 ? DefaultIcon ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(DefaultIcon, { "aria-hidden": "true" }) : null : icon;
|
|
82
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({ className: require_text_truncate.cn("flex items-start rounded-lg border", toneStyles[tone], sizeStyles$3[size], className) }, props), {}, {
|
|
83
|
+
"data-opt-id": "AT7TX",
|
|
84
|
+
"data-opt-slug": "callout.Callout",
|
|
85
|
+
"data-tone": tone,
|
|
86
|
+
children: [
|
|
87
|
+
glyph && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
88
|
+
className: require_text_truncate.cn("mt-0.5 shrink-0", iconTone[tone]),
|
|
89
|
+
children: glyph
|
|
90
|
+
}),
|
|
91
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
92
|
+
className: "min-w-0 flex-1",
|
|
93
|
+
children: [title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
94
|
+
className: require_text_truncate.cn("font-medium", titleTone[tone]),
|
|
95
|
+
children: title
|
|
96
|
+
}), children && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
97
|
+
className: require_text_truncate.cn("text-text-secondary", title && "mt-1"),
|
|
98
|
+
children
|
|
99
|
+
})]
|
|
100
|
+
}),
|
|
101
|
+
action && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
102
|
+
className: "shrink-0 self-center",
|
|
103
|
+
children: action
|
|
104
|
+
})
|
|
105
|
+
]
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/core/status-dot.tsx
|
|
110
|
+
const _excluded$1 = [
|
|
111
|
+
"tone",
|
|
112
|
+
"size",
|
|
113
|
+
"hint",
|
|
114
|
+
"className",
|
|
115
|
+
"children"
|
|
116
|
+
];
|
|
117
|
+
const dotTone = {
|
|
118
|
+
neutral: "bg-text-tertiary",
|
|
119
|
+
muted: "bg-border-hover",
|
|
120
|
+
info: "bg-info",
|
|
121
|
+
success: "bg-success",
|
|
122
|
+
warning: "bg-warning",
|
|
123
|
+
danger: "bg-danger"
|
|
124
|
+
};
|
|
125
|
+
const textTone = {
|
|
126
|
+
neutral: "text-text-secondary",
|
|
127
|
+
muted: "text-text-tertiary",
|
|
128
|
+
info: "text-text-secondary",
|
|
129
|
+
success: "text-text-secondary",
|
|
130
|
+
warning: "text-text-secondary",
|
|
131
|
+
danger: "text-text-secondary"
|
|
132
|
+
};
|
|
133
|
+
const sizeStyles$2 = {
|
|
134
|
+
sm: "gap-1.5 text-[11px]",
|
|
135
|
+
md: "gap-2 text-xs"
|
|
136
|
+
};
|
|
137
|
+
const dotSize = {
|
|
138
|
+
sm: "size-1.5",
|
|
139
|
+
md: "size-2"
|
|
140
|
+
};
|
|
141
|
+
/**
|
|
142
|
+
* StatusDot — a state, said in a dot and a word.
|
|
143
|
+
*
|
|
144
|
+
* `Badge` is a chip: a filled pill that reads as a label somebody attached.
|
|
145
|
+
* A status is not attached, it is observed, and a column of seven filled pills
|
|
146
|
+
* is a column nobody scans. This is the other shape — a dot, the word, no
|
|
147
|
+
* chrome — which is what a dense table can afford to repeat on every row.
|
|
148
|
+
*
|
|
149
|
+
* The dot is decorative on purpose. It never carries meaning the text does not
|
|
150
|
+
* also carry, so the component cannot be used to say something in colour alone.
|
|
151
|
+
*
|
|
152
|
+
* @example
|
|
153
|
+
* ```tsx
|
|
154
|
+
* <StatusDot tone="warning" hint="7일 이상 수신되지 않음">비활성</StatusDot>
|
|
155
|
+
* ```
|
|
156
|
+
*/
|
|
157
|
+
function StatusDot(_ref) {
|
|
158
|
+
let { tone = "neutral", size = "md", hint, className, children } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded$1);
|
|
159
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
|
|
160
|
+
className: require_text_truncate.cn("inline-flex items-center whitespace-nowrap", sizeStyles$2[size], textTone[tone], className),
|
|
161
|
+
title: hint
|
|
162
|
+
}, props), {}, {
|
|
163
|
+
"data-opt-id": "N51AT",
|
|
164
|
+
"data-opt-slug": "status-dot.StatusDot",
|
|
165
|
+
"data-tone": tone,
|
|
166
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
167
|
+
className: require_text_truncate.cn("shrink-0 rounded-full", dotSize[size], dotTone[tone]),
|
|
168
|
+
"aria-hidden": "true"
|
|
169
|
+
}), children]
|
|
170
|
+
}));
|
|
171
|
+
}
|
|
172
|
+
//#endregion
|
|
173
|
+
//#region src/core/copy-button.tsx
|
|
174
|
+
const _excluded = [
|
|
175
|
+
"value",
|
|
176
|
+
"variant",
|
|
177
|
+
"size",
|
|
178
|
+
"feedbackDuration",
|
|
179
|
+
"onCopy",
|
|
180
|
+
"labels",
|
|
181
|
+
"className",
|
|
182
|
+
"disabled",
|
|
183
|
+
"onClick"
|
|
184
|
+
];
|
|
185
|
+
const defaultLabels$35 = {
|
|
186
|
+
copy: "복사",
|
|
187
|
+
copied: "복사됨",
|
|
188
|
+
failed: "복사할 수 없습니다"
|
|
189
|
+
};
|
|
190
|
+
const sizeStyles$1 = {
|
|
191
|
+
sm: "h-6 gap-1 text-[11px] [&>svg]:size-3",
|
|
192
|
+
md: "h-7 gap-1.5 text-xs [&>svg]:size-3.5"
|
|
193
|
+
};
|
|
194
|
+
const paddingStyles = {
|
|
195
|
+
icon: {
|
|
196
|
+
sm: "w-6 justify-center",
|
|
197
|
+
md: "w-7 justify-center"
|
|
198
|
+
},
|
|
199
|
+
text: {
|
|
200
|
+
sm: "px-1.5",
|
|
201
|
+
md: "px-2"
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const stateIcon = {
|
|
205
|
+
idle: lucide_react.Copy,
|
|
206
|
+
copied: lucide_react.Check,
|
|
207
|
+
failed: lucide_react.X
|
|
208
|
+
};
|
|
209
|
+
const stateTone = {
|
|
210
|
+
idle: "text-text-tertiary hover:text-text-primary",
|
|
211
|
+
copied: "text-success-fg",
|
|
212
|
+
failed: "text-danger-fg"
|
|
213
|
+
};
|
|
214
|
+
/**
|
|
215
|
+
* CopyButton — put a value on the clipboard, and say whether it went.
|
|
216
|
+
*
|
|
217
|
+
* Copying an identifier is the most common thing a reader does with one: an
|
|
218
|
+
* event key, a property name, a request id. Every surface that shows one was
|
|
219
|
+
* writing this button again, and each copy re-decided what happens when the
|
|
220
|
+
* clipboard refuses — mostly by pretending it did not.
|
|
221
|
+
*
|
|
222
|
+
* The confirmed state is announced, not just drawn, so the answer reaches a
|
|
223
|
+
* reader who is not looking at the glyph.
|
|
224
|
+
*
|
|
225
|
+
* @example
|
|
226
|
+
* ```tsx
|
|
227
|
+
* <CopyButton value={event.name} labels={{ copy: "이벤트 키 복사" }} />
|
|
228
|
+
* ```
|
|
229
|
+
*/
|
|
230
|
+
function CopyButton(_ref) {
|
|
231
|
+
let { value, variant = "icon", size = "md", feedbackDuration = 1500, onCopy, labels: customLabels, className, disabled, onClick } = _ref, props = require_text_truncate._objectWithoutProperties(_ref, _excluded);
|
|
232
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$35), customLabels);
|
|
233
|
+
const [state, setState] = (0, react.useState)("idle");
|
|
234
|
+
const timer = (0, react.useRef)(null);
|
|
235
|
+
(0, react.useEffect)(() => () => {
|
|
236
|
+
if (timer.current) clearTimeout(timer.current);
|
|
237
|
+
}, []);
|
|
238
|
+
const handleClick = (0, react.useCallback)(async (event) => {
|
|
239
|
+
onClick === null || onClick === void 0 || onClick(event);
|
|
240
|
+
if (event.defaultPrevented) return;
|
|
241
|
+
let ok = false;
|
|
242
|
+
try {
|
|
243
|
+
await navigator.clipboard.writeText(value);
|
|
244
|
+
ok = true;
|
|
245
|
+
} catch (_unused) {
|
|
246
|
+
ok = false;
|
|
247
|
+
}
|
|
248
|
+
setState(ok ? "copied" : "failed");
|
|
249
|
+
onCopy === null || onCopy === void 0 || onCopy(ok);
|
|
250
|
+
if (timer.current) clearTimeout(timer.current);
|
|
251
|
+
timer.current = setTimeout(() => setState("idle"), feedbackDuration);
|
|
252
|
+
}, [
|
|
253
|
+
feedbackDuration,
|
|
254
|
+
onClick,
|
|
255
|
+
onCopy,
|
|
256
|
+
value
|
|
257
|
+
]);
|
|
258
|
+
const Icon = stateIcon[state];
|
|
259
|
+
const label = state === "copied" ? labels.copied : state === "failed" ? labels.failed : labels.copy;
|
|
260
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({
|
|
261
|
+
type: "button",
|
|
262
|
+
onClick: handleClick,
|
|
263
|
+
disabled,
|
|
264
|
+
"aria-label": variant === "icon" ? label : void 0,
|
|
265
|
+
className: require_text_truncate.cn("inline-flex shrink-0 items-center rounded transition-colors", "disabled:pointer-events-none disabled:opacity-50", require_text_truncate.OPT_FOCUS_VISIBLE, sizeStyles$1[size], paddingStyles[variant][size], stateTone[state], className)
|
|
266
|
+
}, props), {}, {
|
|
267
|
+
"data-opt-id": "E0C8T",
|
|
268
|
+
"data-opt-slug": "copy-button.CopyButton",
|
|
269
|
+
"data-copy-state": state,
|
|
270
|
+
children: [
|
|
271
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { "aria-hidden": "true" }),
|
|
272
|
+
variant === "text" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: label }),
|
|
273
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
274
|
+
role: "status",
|
|
275
|
+
"aria-live": "polite",
|
|
276
|
+
className: "sr-only",
|
|
277
|
+
children: state === "idle" ? "" : label
|
|
278
|
+
})
|
|
279
|
+
]
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/core/segmented-control.tsx
|
|
284
|
+
const sizeStyles = {
|
|
285
|
+
sm: "h-7 text-[11px] [&_svg]:size-3",
|
|
286
|
+
md: "h-8 text-xs [&_svg]:size-3.5"
|
|
287
|
+
};
|
|
288
|
+
const segmentPadding = {
|
|
289
|
+
sm: "gap-1 px-2",
|
|
290
|
+
md: "gap-1.5 px-2.5"
|
|
291
|
+
};
|
|
292
|
+
/**
|
|
293
|
+
* SegmentedControl — one of a few views, all of them visible.
|
|
294
|
+
*
|
|
295
|
+
* A `Select` hides the alternatives behind a click; a `ToggleGroup` presses
|
|
296
|
+
* buttons that may be on together. Neither is what "이벤트 | 속성" is: exactly
|
|
297
|
+
* one is true, the set is small enough to show, and the reader is choosing a
|
|
298
|
+
* view rather than filtering anything.
|
|
299
|
+
*
|
|
300
|
+
* Built on the radio-group primitive rather than on buttons, so the arrow keys,
|
|
301
|
+
* the group name and the checked state come from the platform. A control that
|
|
302
|
+
* merely looks like a radiogroup is one a keyboard cannot drive.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```tsx
|
|
306
|
+
* <SegmentedControl
|
|
307
|
+
* aria-label="카탈로그 탭"
|
|
308
|
+
* options={[
|
|
309
|
+
* { value: "events", label: "이벤트", badge: 128 },
|
|
310
|
+
* { value: "properties", label: "속성", badge: 341 },
|
|
311
|
+
* ]}
|
|
312
|
+
* value={tab}
|
|
313
|
+
* onChange={setTab}
|
|
314
|
+
* />
|
|
315
|
+
* ```
|
|
316
|
+
*/
|
|
317
|
+
function SegmentedControl({ options, value, onChange, size = "md", fullWidth = false, disabled = false, "aria-label": ariaLabel, className }) {
|
|
318
|
+
const name = (0, react.useId)();
|
|
319
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.RadioGroupRoot, {
|
|
320
|
+
value,
|
|
321
|
+
onValueChange: (next) => onChange(next),
|
|
322
|
+
disabled,
|
|
323
|
+
orientation: "horizontal",
|
|
324
|
+
name,
|
|
325
|
+
"aria-label": ariaLabel,
|
|
326
|
+
className: require_text_truncate.cn("inline-flex items-center rounded-lg border border-border bg-bg-subtle p-0.5", fullWidth && "flex w-full", sizeStyles[size], className),
|
|
327
|
+
"data-opt-id": "YKENE",
|
|
328
|
+
"data-opt-slug": "segmented-control.SegmentedControl",
|
|
329
|
+
children: options.map((option) => {
|
|
330
|
+
const selected = option.value === value;
|
|
331
|
+
const itemDisabled = disabled || option.disabled;
|
|
332
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("label", {
|
|
333
|
+
className: require_text_truncate.cn("relative inline-flex h-full cursor-pointer items-center justify-center", "rounded-md font-medium whitespace-nowrap transition-colors", "has-[:focus-visible]:ring-2 has-[:focus-visible]:ring-ring has-[:focus-visible]:ring-offset-1 has-[:focus-visible]:ring-offset-ring-offset", segmentPadding[size], fullWidth && "flex-1", selected ? "bg-surface text-text-primary shadow-sm" : "text-text-tertiary hover:text-text-secondary", itemDisabled && "pointer-events-none opacity-50"),
|
|
334
|
+
"data-selected": selected || void 0,
|
|
335
|
+
children: [
|
|
336
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_reopt_ai_opt_ui_primitives.Radio, {
|
|
337
|
+
value: option.value,
|
|
338
|
+
disabled: itemDisabled,
|
|
339
|
+
className: "sr-only"
|
|
340
|
+
}),
|
|
341
|
+
option.icon,
|
|
342
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: option.label }),
|
|
343
|
+
option.badge != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
344
|
+
className: require_text_truncate.cn("tabular-nums", selected ? "text-text-tertiary" : "text-text-tertiary/70"),
|
|
345
|
+
children: option.badge
|
|
346
|
+
})
|
|
347
|
+
]
|
|
348
|
+
}, option.value);
|
|
349
|
+
})
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
//#endregion
|
|
15
353
|
//#region src/lib/schema-validator.ts
|
|
16
354
|
/** Handles schema validator. */
|
|
17
355
|
function schemaValidator(schema) {
|
|
@@ -86,7 +424,7 @@ function PageAside({ header, children, footer, widthClassName = "w-60", label, h
|
|
|
86
424
|
PageAside.displayName = "PageAside";
|
|
87
425
|
//#endregion
|
|
88
426
|
//#region src/shells/task-list.tsx
|
|
89
|
-
const defaultLabels$
|
|
427
|
+
const defaultLabels$34 = {
|
|
90
428
|
title: "작업 목록",
|
|
91
429
|
emptyMessage: "작업이 없습니다",
|
|
92
430
|
completedOf: "{completed}/{total} 완료",
|
|
@@ -106,9 +444,9 @@ const defaultLabels$31 = {
|
|
|
106
444
|
};
|
|
107
445
|
/** Renders the task list component. */
|
|
108
446
|
function TaskList({ tasks, title, onTaskClick, onTaskStatusChange, emptyMessage, showSubtasks = false, maxItems, labels: customLabels, className }) {
|
|
109
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
110
|
-
priority: require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
111
|
-
status: require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
447
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$34), customLabels), {}, {
|
|
448
|
+
priority: require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$34.priority), customLabels === null || customLabels === void 0 ? void 0 : customLabels.priority),
|
|
449
|
+
status: require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$34.status), customLabels === null || customLabels === void 0 ? void 0 : customLabels.status)
|
|
112
450
|
});
|
|
113
451
|
const displayTitle = title !== null && title !== void 0 ? title : labels.title;
|
|
114
452
|
const displayEmptyMessage = emptyMessage !== null && emptyMessage !== void 0 ? emptyMessage : labels.emptyMessage;
|
|
@@ -266,7 +604,7 @@ function TaskList({ tasks, title, onTaskClick, onTaskStatusChange, emptyMessage,
|
|
|
266
604
|
}
|
|
267
605
|
//#endregion
|
|
268
606
|
//#region src/shells/activity-feed.tsx
|
|
269
|
-
const defaultLabels$
|
|
607
|
+
const defaultLabels$33 = {
|
|
270
608
|
title: "활동 피드",
|
|
271
609
|
emptyMessage: "활동이 없습니다",
|
|
272
610
|
moreItems: "{count}개 더 보기",
|
|
@@ -316,24 +654,24 @@ const variantBorder = {
|
|
|
316
654
|
function ActivityFeed({ activities, title, maxItems, onActivityClick, onShowMore, emptyMessage, labels: customLabels, locale = "ko-KR", loading = false, layout = "list", renderActions, className }) {
|
|
317
655
|
var _customLabels$timeAgo, _customLabels$timeAgo2, _customLabels$timeAgo3, _customLabels$timeAgo4, _customLabels$timeAgo5, _customLabels$timeAgo6, _customLabels$timeAgo7, _customLabels$timeAgo8, _customLabels$activit, _customLabels$activit2, _customLabels$activit3, _customLabels$activit4, _customLabels$activit5, _customLabels$activit6, _customLabels$activit7, _customLabels$activit8, _customLabels$activit9, _customLabels$activit10, _customLabels$activit11, _customLabels$activit12, _customLabels$activit13, _customLabels$activit14, _customLabels$title, _customLabels$emptyMe, _customLabels$moreIte;
|
|
318
656
|
const mergedTimeAgo = {
|
|
319
|
-
justNow: (_customLabels$timeAgo = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo2 = customLabels.timeAgo) === null || _customLabels$timeAgo2 === void 0 ? void 0 : _customLabels$timeAgo2.justNow) !== null && _customLabels$timeAgo !== void 0 ? _customLabels$timeAgo : defaultLabels$
|
|
320
|
-
minutesAgo: (_customLabels$timeAgo3 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo4 = customLabels.timeAgo) === null || _customLabels$timeAgo4 === void 0 ? void 0 : _customLabels$timeAgo4.minutesAgo) !== null && _customLabels$timeAgo3 !== void 0 ? _customLabels$timeAgo3 : defaultLabels$
|
|
321
|
-
hoursAgo: (_customLabels$timeAgo5 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo6 = customLabels.timeAgo) === null || _customLabels$timeAgo6 === void 0 ? void 0 : _customLabels$timeAgo6.hoursAgo) !== null && _customLabels$timeAgo5 !== void 0 ? _customLabels$timeAgo5 : defaultLabels$
|
|
322
|
-
daysAgo: (_customLabels$timeAgo7 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo8 = customLabels.timeAgo) === null || _customLabels$timeAgo8 === void 0 ? void 0 : _customLabels$timeAgo8.daysAgo) !== null && _customLabels$timeAgo7 !== void 0 ? _customLabels$timeAgo7 : defaultLabels$
|
|
657
|
+
justNow: (_customLabels$timeAgo = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo2 = customLabels.timeAgo) === null || _customLabels$timeAgo2 === void 0 ? void 0 : _customLabels$timeAgo2.justNow) !== null && _customLabels$timeAgo !== void 0 ? _customLabels$timeAgo : defaultLabels$33.timeAgo.justNow,
|
|
658
|
+
minutesAgo: (_customLabels$timeAgo3 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo4 = customLabels.timeAgo) === null || _customLabels$timeAgo4 === void 0 ? void 0 : _customLabels$timeAgo4.minutesAgo) !== null && _customLabels$timeAgo3 !== void 0 ? _customLabels$timeAgo3 : defaultLabels$33.timeAgo.minutesAgo,
|
|
659
|
+
hoursAgo: (_customLabels$timeAgo5 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo6 = customLabels.timeAgo) === null || _customLabels$timeAgo6 === void 0 ? void 0 : _customLabels$timeAgo6.hoursAgo) !== null && _customLabels$timeAgo5 !== void 0 ? _customLabels$timeAgo5 : defaultLabels$33.timeAgo.hoursAgo,
|
|
660
|
+
daysAgo: (_customLabels$timeAgo7 = customLabels === null || customLabels === void 0 || (_customLabels$timeAgo8 = customLabels.timeAgo) === null || _customLabels$timeAgo8 === void 0 ? void 0 : _customLabels$timeAgo8.daysAgo) !== null && _customLabels$timeAgo7 !== void 0 ? _customLabels$timeAgo7 : defaultLabels$33.timeAgo.daysAgo
|
|
323
661
|
};
|
|
324
662
|
const mergedActivityVerbs = {
|
|
325
|
-
created: (_customLabels$activit = customLabels === null || customLabels === void 0 || (_customLabels$activit2 = customLabels.activityVerbs) === null || _customLabels$activit2 === void 0 ? void 0 : _customLabels$activit2.created) !== null && _customLabels$activit !== void 0 ? _customLabels$activit : defaultLabels$
|
|
326
|
-
updated: (_customLabels$activit3 = customLabels === null || customLabels === void 0 || (_customLabels$activit4 = customLabels.activityVerbs) === null || _customLabels$activit4 === void 0 ? void 0 : _customLabels$activit4.updated) !== null && _customLabels$activit3 !== void 0 ? _customLabels$activit3 : defaultLabels$
|
|
327
|
-
completed: (_customLabels$activit5 = customLabels === null || customLabels === void 0 || (_customLabels$activit6 = customLabels.activityVerbs) === null || _customLabels$activit6 === void 0 ? void 0 : _customLabels$activit6.completed) !== null && _customLabels$activit5 !== void 0 ? _customLabels$activit5 : defaultLabels$
|
|
328
|
-
commented: (_customLabels$activit7 = customLabels === null || customLabels === void 0 || (_customLabels$activit8 = customLabels.activityVerbs) === null || _customLabels$activit8 === void 0 ? void 0 : _customLabels$activit8.commented) !== null && _customLabels$activit7 !== void 0 ? _customLabels$activit7 : defaultLabels$
|
|
329
|
-
assigned: (_customLabels$activit9 = customLabels === null || customLabels === void 0 || (_customLabels$activit10 = customLabels.activityVerbs) === null || _customLabels$activit10 === void 0 ? void 0 : _customLabels$activit10.assigned) !== null && _customLabels$activit9 !== void 0 ? _customLabels$activit9 : defaultLabels$
|
|
330
|
-
deployed: (_customLabels$activit11 = customLabels === null || customLabels === void 0 || (_customLabels$activit12 = customLabels.activityVerbs) === null || _customLabels$activit12 === void 0 ? void 0 : _customLabels$activit12.deployed) !== null && _customLabels$activit11 !== void 0 ? _customLabels$activit11 : defaultLabels$
|
|
331
|
-
merged: (_customLabels$activit13 = customLabels === null || customLabels === void 0 || (_customLabels$activit14 = customLabels.activityVerbs) === null || _customLabels$activit14 === void 0 ? void 0 : _customLabels$activit14.merged) !== null && _customLabels$activit13 !== void 0 ? _customLabels$activit13 : defaultLabels$
|
|
663
|
+
created: (_customLabels$activit = customLabels === null || customLabels === void 0 || (_customLabels$activit2 = customLabels.activityVerbs) === null || _customLabels$activit2 === void 0 ? void 0 : _customLabels$activit2.created) !== null && _customLabels$activit !== void 0 ? _customLabels$activit : defaultLabels$33.activityVerbs.created,
|
|
664
|
+
updated: (_customLabels$activit3 = customLabels === null || customLabels === void 0 || (_customLabels$activit4 = customLabels.activityVerbs) === null || _customLabels$activit4 === void 0 ? void 0 : _customLabels$activit4.updated) !== null && _customLabels$activit3 !== void 0 ? _customLabels$activit3 : defaultLabels$33.activityVerbs.updated,
|
|
665
|
+
completed: (_customLabels$activit5 = customLabels === null || customLabels === void 0 || (_customLabels$activit6 = customLabels.activityVerbs) === null || _customLabels$activit6 === void 0 ? void 0 : _customLabels$activit6.completed) !== null && _customLabels$activit5 !== void 0 ? _customLabels$activit5 : defaultLabels$33.activityVerbs.completed,
|
|
666
|
+
commented: (_customLabels$activit7 = customLabels === null || customLabels === void 0 || (_customLabels$activit8 = customLabels.activityVerbs) === null || _customLabels$activit8 === void 0 ? void 0 : _customLabels$activit8.commented) !== null && _customLabels$activit7 !== void 0 ? _customLabels$activit7 : defaultLabels$33.activityVerbs.commented,
|
|
667
|
+
assigned: (_customLabels$activit9 = customLabels === null || customLabels === void 0 || (_customLabels$activit10 = customLabels.activityVerbs) === null || _customLabels$activit10 === void 0 ? void 0 : _customLabels$activit10.assigned) !== null && _customLabels$activit9 !== void 0 ? _customLabels$activit9 : defaultLabels$33.activityVerbs.assigned,
|
|
668
|
+
deployed: (_customLabels$activit11 = customLabels === null || customLabels === void 0 || (_customLabels$activit12 = customLabels.activityVerbs) === null || _customLabels$activit12 === void 0 ? void 0 : _customLabels$activit12.deployed) !== null && _customLabels$activit11 !== void 0 ? _customLabels$activit11 : defaultLabels$33.activityVerbs.deployed,
|
|
669
|
+
merged: (_customLabels$activit13 = customLabels === null || customLabels === void 0 || (_customLabels$activit14 = customLabels.activityVerbs) === null || _customLabels$activit14 === void 0 ? void 0 : _customLabels$activit14.merged) !== null && _customLabels$activit13 !== void 0 ? _customLabels$activit13 : defaultLabels$33.activityVerbs.merged
|
|
332
670
|
};
|
|
333
671
|
const labels = {
|
|
334
|
-
title: (_customLabels$title = customLabels === null || customLabels === void 0 ? void 0 : customLabels.title) !== null && _customLabels$title !== void 0 ? _customLabels$title : defaultLabels$
|
|
335
|
-
emptyMessage: (_customLabels$emptyMe = customLabels === null || customLabels === void 0 ? void 0 : customLabels.emptyMessage) !== null && _customLabels$emptyMe !== void 0 ? _customLabels$emptyMe : defaultLabels$
|
|
336
|
-
moreItems: (_customLabels$moreIte = customLabels === null || customLabels === void 0 ? void 0 : customLabels.moreItems) !== null && _customLabels$moreIte !== void 0 ? _customLabels$moreIte : defaultLabels$
|
|
672
|
+
title: (_customLabels$title = customLabels === null || customLabels === void 0 ? void 0 : customLabels.title) !== null && _customLabels$title !== void 0 ? _customLabels$title : defaultLabels$33.title,
|
|
673
|
+
emptyMessage: (_customLabels$emptyMe = customLabels === null || customLabels === void 0 ? void 0 : customLabels.emptyMessage) !== null && _customLabels$emptyMe !== void 0 ? _customLabels$emptyMe : defaultLabels$33.emptyMessage,
|
|
674
|
+
moreItems: (_customLabels$moreIte = customLabels === null || customLabels === void 0 ? void 0 : customLabels.moreItems) !== null && _customLabels$moreIte !== void 0 ? _customLabels$moreIte : defaultLabels$33.moreItems,
|
|
337
675
|
timeAgo: mergedTimeAgo,
|
|
338
676
|
activityVerbs: mergedActivityVerbs
|
|
339
677
|
};
|
|
@@ -461,13 +799,13 @@ function ActivityFeed({ activities, title, maxItems, onActivityClick, onShowMore
|
|
|
461
799
|
ActivityFeed.displayName = "ActivityFeed";
|
|
462
800
|
//#endregion
|
|
463
801
|
//#region src/shells/filter-bar.tsx
|
|
464
|
-
const defaultLabels$
|
|
802
|
+
const defaultLabels$32 = {
|
|
465
803
|
clearAll: "필터 초기화",
|
|
466
804
|
searchPlaceholder: "검색..."
|
|
467
805
|
};
|
|
468
806
|
/** Renders the filter bar component. */
|
|
469
807
|
function FilterBar({ filters, onFilterChange, onDateRangeChange, onClearAll, labels: customLabels, presetActions, className }) {
|
|
470
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
808
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$32), customLabels);
|
|
471
809
|
const [searchValues, setSearchValues] = (0, react.useState)({});
|
|
472
810
|
const [tagInputValues, setTagInputValues] = (0, react.useState)({});
|
|
473
811
|
const [multiSelectOpen, setMultiSelectOpen] = (0, react.useState)({});
|
|
@@ -693,10 +1031,10 @@ function matchesShortcut(event, shortcut) {
|
|
|
693
1031
|
if (requiresMeta && !event.metaKey) return false;
|
|
694
1032
|
return event.key.toLowerCase() === key;
|
|
695
1033
|
}
|
|
696
|
-
const defaultLabels$
|
|
1034
|
+
const defaultLabels$31 = { title: "빠른 작업" };
|
|
697
1035
|
/** Renders the quick actions component. */
|
|
698
1036
|
function QuickActions({ actions, title, layout = "grid", columns = 3, showDescriptionInGrid = false, bindShortcuts = false, labels: customLabels, className }) {
|
|
699
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
1037
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$31), customLabels);
|
|
700
1038
|
const displayTitle = title !== null && title !== void 0 ? title : labels.title;
|
|
701
1039
|
const titleId = (0, react.useId)();
|
|
702
1040
|
(0, react.useEffect)(() => {
|
|
@@ -774,7 +1112,7 @@ function QuickActions({ actions, title, layout = "grid", columns = 3, showDescri
|
|
|
774
1112
|
QuickActions.displayName = "QuickActions";
|
|
775
1113
|
//#endregion
|
|
776
1114
|
//#region src/shells/team-member-list.tsx
|
|
777
|
-
const defaultLabels$
|
|
1115
|
+
const defaultLabels$30 = {
|
|
778
1116
|
title: "팀원",
|
|
779
1117
|
emptyMessage: "팀원이 없습니다",
|
|
780
1118
|
onlineCount: "{online}/{total} 온라인",
|
|
@@ -795,7 +1133,7 @@ const statusDot = {
|
|
|
795
1133
|
};
|
|
796
1134
|
/** Renders the team member list component. */
|
|
797
1135
|
function TeamMemberList({ members, title, layout = "list", maxDisplay, onMemberClick, onShowMore, emptyMessage, labels: customLabels, className }) {
|
|
798
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
1136
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$30), customLabels), {}, { status: require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$30.status), customLabels === null || customLabels === void 0 ? void 0 : customLabels.status) });
|
|
799
1137
|
const displayTitle = title !== null && title !== void 0 ? title : labels.title;
|
|
800
1138
|
const displayEmptyMessage = emptyMessage !== null && emptyMessage !== void 0 ? emptyMessage : labels.emptyMessage;
|
|
801
1139
|
const titleId = (0, react.useId)();
|
|
@@ -1695,7 +2033,7 @@ const COLOR_PRESETS = [
|
|
|
1695
2033
|
"#f97316",
|
|
1696
2034
|
"#14b8a6"
|
|
1697
2035
|
];
|
|
1698
|
-
const defaultLabels$
|
|
2036
|
+
const defaultLabels$29 = {
|
|
1699
2037
|
eventLabelPrefix: "Event",
|
|
1700
2038
|
defaultAriaLabel: "Event icon"
|
|
1701
2039
|
};
|
|
@@ -1726,7 +2064,7 @@ function getEventIconStyle(color) {
|
|
|
1726
2064
|
/** Renders the event icon component. */
|
|
1727
2065
|
function EventIcon({ icon, color, size = "md", className, labels: customLabels }) {
|
|
1728
2066
|
var _iconEntry$label;
|
|
1729
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2067
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$29), customLabels);
|
|
1730
2068
|
const sizes = SIZE_MAP[size];
|
|
1731
2069
|
const resolvedColor = (color === null || color === void 0 ? void 0 : color.trim()) ? color : void 0;
|
|
1732
2070
|
const iconEntry = typeof icon === "string" ? require_text_truncate.getIconRegistryEntry(icon) : void 0;
|
|
@@ -1818,14 +2156,14 @@ function ConnectionIndicator({ status, tone, label, showLabel = true, pulse, cla
|
|
|
1818
2156
|
ConnectionIndicator.displayName = "ConnectionIndicator";
|
|
1819
2157
|
//#endregion
|
|
1820
2158
|
//#region src/shells/floating-action-bar.tsx
|
|
1821
|
-
const defaultLabels$
|
|
2159
|
+
const defaultLabels$28 = {
|
|
1822
2160
|
toolbarAriaLabel: "Actions",
|
|
1823
2161
|
selectedLabel: (count) => `${count} selected`,
|
|
1824
2162
|
dismissAriaLabel: "Dismiss"
|
|
1825
2163
|
};
|
|
1826
2164
|
/** Renders the floating action bar component. */
|
|
1827
2165
|
function FloatingActionBar({ actions, selectedCount, onAction, onDismiss, className, labels: customLabels }) {
|
|
1828
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2166
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$28), customLabels);
|
|
1829
2167
|
if (actions.length === 0) return null;
|
|
1830
2168
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1831
2169
|
role: "toolbar",
|
|
@@ -1862,7 +2200,7 @@ function FloatingActionBar({ actions, selectedCount, onAction, onDismiss, classN
|
|
|
1862
2200
|
FloatingActionBar.displayName = "FloatingActionBar";
|
|
1863
2201
|
//#endregion
|
|
1864
2202
|
//#region src/shells/template-picker.tsx
|
|
1865
|
-
const defaultLabels$
|
|
2203
|
+
const defaultLabels$27 = {
|
|
1866
2204
|
ariaLabel: "Templates",
|
|
1867
2205
|
defaultCategory: "General",
|
|
1868
2206
|
searchPlaceholder: "Search templates...",
|
|
@@ -1870,7 +2208,7 @@ const defaultLabels$24 = {
|
|
|
1870
2208
|
};
|
|
1871
2209
|
/** Renders the template picker component. */
|
|
1872
2210
|
function TemplatePicker({ templates, selected, onSelect, labels: customLabels, showSearch = false, className }) {
|
|
1873
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2211
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$27), customLabels);
|
|
1874
2212
|
const [search, setSearch] = react.useState("");
|
|
1875
2213
|
const filtered = react.useMemo(() => {
|
|
1876
2214
|
if (!showSearch || !search) return templates;
|
|
@@ -1956,7 +2294,7 @@ function TemplatePicker({ templates, selected, onSelect, labels: customLabels, s
|
|
|
1956
2294
|
TemplatePicker.displayName = "TemplatePicker";
|
|
1957
2295
|
//#endregion
|
|
1958
2296
|
//#region src/shells/code-snippet-viewer.tsx
|
|
1959
|
-
const defaultLabels$
|
|
2297
|
+
const defaultLabels$26 = {
|
|
1960
2298
|
copy: "Copy",
|
|
1961
2299
|
copied: "Copied!",
|
|
1962
2300
|
codeRegion: "Code snippet"
|
|
@@ -1994,7 +2332,7 @@ const syntaxThemeClasses = {
|
|
|
1994
2332
|
/** Renders the code snippet viewer component. */
|
|
1995
2333
|
function CodeSnippetViewer({ code, language = "text", title, showLineNumbers = true, showCopyButton = true, maxHeight = 400, syntaxTheme = "default", className, labels: customLabels }) {
|
|
1996
2334
|
var _syntaxThemeClasses$s;
|
|
1997
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2335
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$26), customLabels);
|
|
1998
2336
|
const [copied, setCopied] = react.useState(false);
|
|
1999
2337
|
const lines = code.split("\n");
|
|
2000
2338
|
const theme = (_syntaxThemeClasses$s = syntaxThemeClasses[syntaxTheme]) !== null && _syntaxThemeClasses$s !== void 0 ? _syntaxThemeClasses$s : syntaxThemeClasses.default;
|
|
@@ -2046,13 +2384,15 @@ function CodeSnippetViewer({ code, language = "text", title, showLineNumbers = t
|
|
|
2046
2384
|
CodeSnippetViewer.displayName = "CodeSnippetViewer";
|
|
2047
2385
|
//#endregion
|
|
2048
2386
|
//#region src/shells/property-explorer.tsx
|
|
2049
|
-
const defaultLabels$
|
|
2387
|
+
const defaultLabels$25 = {
|
|
2050
2388
|
searchPlaceholder: "Search properties...",
|
|
2051
|
-
noPropertiesFound: "No properties found"
|
|
2389
|
+
noPropertiesFound: "No properties found",
|
|
2390
|
+
edit: (property) => `${property} 편집`,
|
|
2391
|
+
hidden: "숨김"
|
|
2052
2392
|
};
|
|
2053
2393
|
/** Renders the property explorer component. */
|
|
2054
|
-
function PropertyExplorer({ groups, onSelect, className, labels: customLabels }) {
|
|
2055
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2394
|
+
function PropertyExplorer({ groups, onSelect, onEdit, className, labels: customLabels }) {
|
|
2395
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$25), customLabels);
|
|
2056
2396
|
const [search, setSearch] = react.useState("");
|
|
2057
2397
|
const filtered = react.useMemo(() => {
|
|
2058
2398
|
if (!search) return groups;
|
|
@@ -2078,36 +2418,55 @@ function PropertyExplorer({ groups, onSelect, className, labels: customLabels })
|
|
|
2078
2418
|
children: group.name
|
|
2079
2419
|
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2080
2420
|
className: "gap-element flex flex-col",
|
|
2081
|
-
children: group.properties.map((prop) =>
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2090
|
-
|
|
2091
|
-
|
|
2092
|
-
|
|
2093
|
-
|
|
2094
|
-
|
|
2095
|
-
|
|
2096
|
-
|
|
2097
|
-
|
|
2098
|
-
|
|
2099
|
-
|
|
2100
|
-
|
|
2101
|
-
|
|
2102
|
-
|
|
2103
|
-
|
|
2421
|
+
children: group.properties.map((prop) => {
|
|
2422
|
+
var _prop$dataType;
|
|
2423
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2424
|
+
className: require_text_truncate.cn("hover:bg-bg-subtle flex items-center rounded-md transition-colors", prop.hidden && "opacity-60"),
|
|
2425
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
2426
|
+
onClick: () => onSelect === null || onSelect === void 0 ? void 0 : onSelect(prop),
|
|
2427
|
+
className: "flex min-w-0 flex-1 items-center justify-between px-2.5 py-1.5 text-left",
|
|
2428
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2429
|
+
className: "min-w-0",
|
|
2430
|
+
children: [
|
|
2431
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.FieldToken, {
|
|
2432
|
+
type: (_prop$dataType = prop.dataType) !== null && _prop$dataType !== void 0 ? _prop$dataType : require_text_truncate.resolveFieldType(prop.type),
|
|
2433
|
+
size: "xs",
|
|
2434
|
+
title: prop.type,
|
|
2435
|
+
className: "mr-2 align-[-2px]"
|
|
2436
|
+
}),
|
|
2437
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2438
|
+
className: "text-text-primary text-sm font-medium",
|
|
2439
|
+
children: prop.name
|
|
2440
|
+
}),
|
|
2441
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2442
|
+
className: "text-text-tertiary ml-2 font-mono text-xs",
|
|
2443
|
+
children: prop.type
|
|
2444
|
+
}),
|
|
2445
|
+
prop.hidden && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2446
|
+
className: "text-text-tertiary ml-2 text-xs",
|
|
2447
|
+
children: labels.hidden
|
|
2448
|
+
}),
|
|
2449
|
+
prop.description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2450
|
+
className: "text-text-tertiary truncate text-xs",
|
|
2451
|
+
children: prop.description
|
|
2452
|
+
})
|
|
2453
|
+
]
|
|
2454
|
+
}), prop.eventCount !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2455
|
+
className: "text-text-tertiary ml-2 shrink-0 text-xs",
|
|
2456
|
+
children: require_text_truncate.formatOptNumber(prop.eventCount)
|
|
2457
|
+
})]
|
|
2458
|
+
}), onEdit && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2459
|
+
type: "button",
|
|
2460
|
+
onClick: () => onEdit(prop),
|
|
2461
|
+
"aria-label": labels.edit(prop.name),
|
|
2462
|
+
className: "text-text-tertiary hover:text-text-primary mr-1.5 shrink-0 rounded p-1",
|
|
2463
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Pencil, {
|
|
2464
|
+
"aria-hidden": "true",
|
|
2465
|
+
className: "size-3.5"
|
|
2104
2466
|
})
|
|
2105
|
-
]
|
|
2106
|
-
}
|
|
2107
|
-
|
|
2108
|
-
children: require_text_truncate.formatOptNumber(prop.eventCount)
|
|
2109
|
-
})]
|
|
2110
|
-
}, prop.name))
|
|
2467
|
+
})]
|
|
2468
|
+
}, prop.name);
|
|
2469
|
+
})
|
|
2111
2470
|
})] }, group.name)), filtered.length === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
2112
2471
|
className: "text-text-tertiary py-4 text-center text-sm",
|
|
2113
2472
|
children: labels.noPropertiesFound
|
|
@@ -2118,14 +2477,14 @@ function PropertyExplorer({ groups, onSelect, className, labels: customLabels })
|
|
|
2118
2477
|
PropertyExplorer.displayName = "PropertyExplorer";
|
|
2119
2478
|
//#endregion
|
|
2120
2479
|
//#region src/shells/query-results-table.tsx
|
|
2121
|
-
const defaultLabels$
|
|
2480
|
+
const defaultLabels$24 = {
|
|
2122
2481
|
emptyMessage: "No results",
|
|
2123
2482
|
loadingMessage: "Running query...",
|
|
2124
2483
|
rowsSuffix: "row(s)"
|
|
2125
2484
|
};
|
|
2126
2485
|
/** Renders the query results table component. */
|
|
2127
2486
|
function QueryResultsTable({ columns, rows, maxHeight = 400, emptyMessage, loading = false, error, labels: customLabels, className }) {
|
|
2128
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2487
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$24), customLabels);
|
|
2129
2488
|
if (error) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2130
2489
|
className: require_text_truncate.cn("border-danger bg-danger-subtle rounded-lg border p-4", className),
|
|
2131
2490
|
role: "alert",
|
|
@@ -2209,7 +2568,7 @@ function QueryResultsTable({ columns, rows, maxHeight = 400, emptyMessage, loadi
|
|
|
2209
2568
|
QueryResultsTable.displayName = "QueryResultsTable";
|
|
2210
2569
|
//#endregion
|
|
2211
2570
|
//#region src/shells/alert-builder.tsx
|
|
2212
|
-
const defaultLabels$
|
|
2571
|
+
const defaultLabels$23 = {
|
|
2213
2572
|
alertNameLabel: "Alert name",
|
|
2214
2573
|
conditionsLabel: "Conditions",
|
|
2215
2574
|
metricLabel: "Metric",
|
|
@@ -2280,7 +2639,7 @@ function AlertBuilder({ value, onChange, metrics = [
|
|
|
2280
2639
|
], labels: customLabels, className }) {
|
|
2281
2640
|
const resolvedMetrics = eventOptions ? eventOptions.map((e) => e.id) : metrics;
|
|
2282
2641
|
const metricLabelMap = eventOptions ? Object.fromEntries(eventOptions.map((e) => [e.id, e.name])) : null;
|
|
2283
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2642
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$23), customLabels);
|
|
2284
2643
|
const alertNameId = react.useId();
|
|
2285
2644
|
const conditionsId = react.useId();
|
|
2286
2645
|
const checkFrequencyId = react.useId();
|
|
@@ -2435,7 +2794,7 @@ function AlertBuilder({ value, onChange, metrics = [
|
|
|
2435
2794
|
AlertBuilder.displayName = "AlertBuilder";
|
|
2436
2795
|
//#endregion
|
|
2437
2796
|
//#region src/shells/sql-editor.tsx
|
|
2438
|
-
const defaultLabels$
|
|
2797
|
+
const defaultLabels$22 = {
|
|
2439
2798
|
placeholder: "SELECT * FROM events LIMIT 100",
|
|
2440
2799
|
runHint: "Ctrl+Enter to run",
|
|
2441
2800
|
runButton: "Run Query",
|
|
@@ -2443,7 +2802,7 @@ const defaultLabels$19 = {
|
|
|
2443
2802
|
};
|
|
2444
2803
|
/** Renders the sql editor component. */
|
|
2445
2804
|
function SqlEditor({ value, onChange, onRun, onRunAndAdvance, placeholder, readOnly = false, height = 200, schema, completionSources, keymap: customKeymap, extensions: customExtensions, ariaLabel, autoFocus = false, showFooter, labels: customLabels, className }) {
|
|
2446
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2805
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$22), customLabels);
|
|
2447
2806
|
const fill = height === "fill";
|
|
2448
2807
|
const footerVisible = showFooter !== null && showFooter !== void 0 ? showFooter : Boolean(onRun);
|
|
2449
2808
|
const editorRef = react.useRef(null);
|
|
@@ -2615,7 +2974,7 @@ function SqlEditor({ value, onChange, onRun, onRunAndAdvance, placeholder, readO
|
|
|
2615
2974
|
SqlEditor.displayName = "SqlEditor";
|
|
2616
2975
|
//#endregion
|
|
2617
2976
|
//#region src/shells/event-meta-editor.tsx
|
|
2618
|
-
const defaultLabels$
|
|
2977
|
+
const defaultLabels$21 = {
|
|
2619
2978
|
icon: "Icon",
|
|
2620
2979
|
color: "Color",
|
|
2621
2980
|
name: "Event name",
|
|
@@ -2629,8 +2988,8 @@ const defaultLabels$18 = {
|
|
|
2629
2988
|
emptyTagsMessage: "No tags added yet."
|
|
2630
2989
|
};
|
|
2631
2990
|
/** Renders the event meta editor component. */
|
|
2632
|
-
function EventMetaEditor({ value, onChange, icons, className, labels: customLabels }) {
|
|
2633
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
2991
|
+
function EventMetaEditor({ value, onChange, icons, sections, footer, className, labels: customLabels }) {
|
|
2992
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$21), customLabels);
|
|
2634
2993
|
const hasTags = value.tags.length > 0;
|
|
2635
2994
|
const nameId = react.useId();
|
|
2636
2995
|
const displayNameId = react.useId();
|
|
@@ -2723,17 +3082,32 @@ function EventMetaEditor({ value, onChange, icons, className, labels: customLabe
|
|
|
2723
3082
|
className: "text-text-tertiary mt-1 block text-xs",
|
|
2724
3083
|
children: labels.emptyTagsMessage
|
|
2725
3084
|
})
|
|
2726
|
-
] })
|
|
3085
|
+
] }),
|
|
3086
|
+
sections === null || sections === void 0 ? void 0 : sections.map((section) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
|
|
3087
|
+
className: "gap-element flex flex-col",
|
|
3088
|
+
children: [
|
|
3089
|
+
section.title && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3090
|
+
className: "text-text-tertiary block text-xs font-medium",
|
|
3091
|
+
children: section.title
|
|
3092
|
+
}),
|
|
3093
|
+
section.children,
|
|
3094
|
+
section.description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
3095
|
+
className: "text-text-tertiary block text-xs",
|
|
3096
|
+
children: section.description
|
|
3097
|
+
})
|
|
3098
|
+
]
|
|
3099
|
+
}, section.id)),
|
|
3100
|
+
footer
|
|
2727
3101
|
]
|
|
2728
3102
|
});
|
|
2729
3103
|
}
|
|
2730
3104
|
EventMetaEditor.displayName = "EventMetaEditor";
|
|
2731
3105
|
//#endregion
|
|
2732
3106
|
//#region src/shells/widget-grid.tsx
|
|
2733
|
-
const defaultLabels$
|
|
3107
|
+
const defaultLabels$20 = { emptyMessage: "No widgets to display" };
|
|
2734
3108
|
/** Renders the widget grid component. */
|
|
2735
3109
|
function WidgetGrid({ widgets, cols = 12, rowHeight = 80, gap = 16, editable = false, onReorder, labels: customLabels, className }) {
|
|
2736
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
3110
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$20), customLabels);
|
|
2737
3111
|
const [dragIdx, setDragIdx] = react.useState(null);
|
|
2738
3112
|
const [overIdx, setOverIdx] = react.useState(null);
|
|
2739
3113
|
if (widgets.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
@@ -2778,7 +3152,7 @@ function WidgetGrid({ widgets, cols = 12, rowHeight = 80, gap = 16, editable = f
|
|
|
2778
3152
|
WidgetGrid.displayName = "WidgetGrid";
|
|
2779
3153
|
//#endregion
|
|
2780
3154
|
//#region src/shells/report-builder.tsx
|
|
2781
|
-
const defaultLabels$
|
|
3155
|
+
const defaultLabels$19 = {
|
|
2782
3156
|
stepsLabel: "Report steps",
|
|
2783
3157
|
stepType: "Chart Type",
|
|
2784
3158
|
stepConfig: "Data Config",
|
|
@@ -2854,7 +3228,7 @@ const STEPS = [
|
|
|
2854
3228
|
];
|
|
2855
3229
|
/** Renders the report builder component. */
|
|
2856
3230
|
function ReportBuilder({ chartTypes = DEFAULT_CHART_TYPES, dataSources = [], onSave, onCancel, configForm, styleForm, preview, onChartTypeChange, onDataSourceChange, onStepChange, selectedChartType: controlledChartType, selectedDataSource: controlledDataSource, labels: customLabels, className }) {
|
|
2857
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
3231
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$19), customLabels);
|
|
2858
3232
|
const [stepIndex, setStepIndex] = react.useState(0);
|
|
2859
3233
|
const [internalChartType, setInternalChartType] = react.useState(null);
|
|
2860
3234
|
const [internalDataSource, setInternalDataSource] = react.useState("");
|
|
@@ -3074,7 +3448,7 @@ function ReportBuilder({ chartTypes = DEFAULT_CHART_TYPES, dataSources = [], onS
|
|
|
3074
3448
|
ReportBuilder.displayName = "ReportBuilder";
|
|
3075
3449
|
//#endregion
|
|
3076
3450
|
//#region src/shells/audit-timeline.tsx
|
|
3077
|
-
const defaultLabels$
|
|
3451
|
+
const defaultLabels$18 = {
|
|
3078
3452
|
title: "변경 이력",
|
|
3079
3453
|
empty: "변경 이력이 없습니다",
|
|
3080
3454
|
expand: "상세 보기",
|
|
@@ -3153,7 +3527,7 @@ function DiffTable({ changes, labels }) {
|
|
|
3153
3527
|
}
|
|
3154
3528
|
/** Renders the audit timeline component. */
|
|
3155
3529
|
function AuditTimeline({ entries, labels: customLabels, className, onEntryClick }) {
|
|
3156
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
3530
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$18), customLabels);
|
|
3157
3531
|
const [expandedIds, setExpandedIds] = react.useState(/* @__PURE__ */ new Set());
|
|
3158
3532
|
const toggleExpanded = react.useCallback((id) => {
|
|
3159
3533
|
setExpandedIds((prev) => {
|
|
@@ -3276,7 +3650,7 @@ function AuditTimeline({ entries, labels: customLabels, className, onEntryClick
|
|
|
3276
3650
|
AuditTimeline.displayName = "AuditTimeline";
|
|
3277
3651
|
//#endregion
|
|
3278
3652
|
//#region src/shells/segment-builder.tsx
|
|
3279
|
-
const defaultLabels$
|
|
3653
|
+
const defaultLabels$17 = {
|
|
3280
3654
|
match: "Match",
|
|
3281
3655
|
ofTheFollowing: "of the following",
|
|
3282
3656
|
groupLabel: "Segment group",
|
|
@@ -3397,7 +3771,7 @@ function SegmentBuilder({ groups, onChange, eventOptions = [
|
|
|
3397
3771
|
"New Users",
|
|
3398
3772
|
"Power Users"
|
|
3399
3773
|
], className, labels: customLabels }) {
|
|
3400
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
3774
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$17), customLabels);
|
|
3401
3775
|
const builderId = react.useId().replace(/:/g, "");
|
|
3402
3776
|
const nextIdRef = react.useRef(1);
|
|
3403
3777
|
const createId = react.useCallback(() => {
|
|
@@ -3610,7 +3984,7 @@ function SegmentBuilder({ groups, onChange, eventOptions = [
|
|
|
3610
3984
|
SegmentBuilder.displayName = "SegmentBuilder";
|
|
3611
3985
|
//#endregion
|
|
3612
3986
|
//#region src/shells/insights-panel.tsx
|
|
3613
|
-
const defaultLabels$
|
|
3987
|
+
const defaultLabels$16 = {
|
|
3614
3988
|
title: "Insights",
|
|
3615
3989
|
dismiss: "Dismiss",
|
|
3616
3990
|
showDismissed: "Show dismissed",
|
|
@@ -3641,7 +4015,7 @@ const severityConfig = {
|
|
|
3641
4015
|
/** Renders the insights panel component. */
|
|
3642
4016
|
function InsightsPanel({ insights, stats, detectionTypes, onDetectionTypeToggle, detectionConfig, onDetectionConfigChange, onDismiss, onInsightClick, onStatClick, header, actions, labels: customLabels, className }) {
|
|
3643
4017
|
var _detectionConfig$days, _detectionConfig$zSco;
|
|
3644
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
4018
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$16), customLabels);
|
|
3645
4019
|
const [showDismissed, setShowDismissed] = react.useState(false);
|
|
3646
4020
|
const visibleInsights = showDismissed ? insights : insights.filter((i) => !i.dismissed);
|
|
3647
4021
|
const hasStats = stats && stats.length > 0;
|
|
@@ -4033,7 +4407,7 @@ function ExportButton({ data, columns, fileName = "export", formats = ["csv", "j
|
|
|
4033
4407
|
ExportButton.displayName = "ExportButton";
|
|
4034
4408
|
//#endregion
|
|
4035
4409
|
//#region src/shells/summary-row.tsx
|
|
4036
|
-
const defaultLabels$
|
|
4410
|
+
const defaultLabels$15 = {
|
|
4037
4411
|
emptyTitle: "No summary stats",
|
|
4038
4412
|
emptyDescription: "Provide at least one stat to render the summary row."
|
|
4039
4413
|
};
|
|
@@ -4057,7 +4431,7 @@ const colsClass = {
|
|
|
4057
4431
|
};
|
|
4058
4432
|
/** Renders the summary row component. */
|
|
4059
4433
|
function SummaryRow({ stats, columns = 4, onStatClick, selectedStatId, size = "md", formatValue, durationFractionDigits = 1, percentageFractionDigits = 1, loading = false, labels: customLabels, className }) {
|
|
4060
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
4434
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$15), customLabels);
|
|
4061
4435
|
if (loading) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4062
4436
|
className: require_text_truncate.cn("gap-group grid", colsClass[columns], className),
|
|
4063
4437
|
"data-opt-id": "FGFP3",
|
|
@@ -4097,6 +4471,505 @@ function SummaryRow({ stats, columns = 4, onStatClick, selectedStatId, size = "m
|
|
|
4097
4471
|
}
|
|
4098
4472
|
SummaryRow.displayName = "SummaryRow";
|
|
4099
4473
|
//#endregion
|
|
4474
|
+
//#region src/lib/query/query-match.ts
|
|
4475
|
+
function toText(value) {
|
|
4476
|
+
if (value === null || value === void 0) return "";
|
|
4477
|
+
if (typeof value === "string") return value;
|
|
4478
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
4479
|
+
return JSON.stringify(value);
|
|
4480
|
+
}
|
|
4481
|
+
function compare(left, right) {
|
|
4482
|
+
const leftNumber = typeof left === "number" ? left : Number(toText(left));
|
|
4483
|
+
const rightNumber = Number(right);
|
|
4484
|
+
if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) return leftNumber - rightNumber;
|
|
4485
|
+
return toText(left).localeCompare(right);
|
|
4486
|
+
}
|
|
4487
|
+
function matchesClause(clause, read, searchable) {
|
|
4488
|
+
if (clause.type === "term") return searchable().toLowerCase().includes(clause.value.toLowerCase());
|
|
4489
|
+
const value = read(clause.field);
|
|
4490
|
+
switch (clause.operator) {
|
|
4491
|
+
case "exists": return value !== void 0 && value !== null && value !== "";
|
|
4492
|
+
case "eq": return clause.values.some((candidate) => toText(value).toLowerCase() === candidate.toLowerCase());
|
|
4493
|
+
case "contains": return clause.values.some((candidate) => toText(value).toLowerCase().includes(candidate.toLowerCase()));
|
|
4494
|
+
case "gt":
|
|
4495
|
+
var _clause$values$;
|
|
4496
|
+
return compare(value, (_clause$values$ = clause.values[0]) !== null && _clause$values$ !== void 0 ? _clause$values$ : "") > 0;
|
|
4497
|
+
case "gte":
|
|
4498
|
+
var _clause$values$2;
|
|
4499
|
+
return compare(value, (_clause$values$2 = clause.values[0]) !== null && _clause$values$2 !== void 0 ? _clause$values$2 : "") >= 0;
|
|
4500
|
+
case "lt":
|
|
4501
|
+
var _clause$values$3;
|
|
4502
|
+
return compare(value, (_clause$values$3 = clause.values[0]) !== null && _clause$values$3 !== void 0 ? _clause$values$3 : "") < 0;
|
|
4503
|
+
case "lte":
|
|
4504
|
+
var _clause$values$4;
|
|
4505
|
+
return compare(value, (_clause$values$4 = clause.values[0]) !== null && _clause$values$4 !== void 0 ? _clause$values$4 : "") <= 0;
|
|
4506
|
+
default: return true;
|
|
4507
|
+
}
|
|
4508
|
+
}
|
|
4509
|
+
/**
|
|
4510
|
+
* Whether one row satisfies every clause.
|
|
4511
|
+
*
|
|
4512
|
+
* `searchable` is lazy because most queries are field constraints, and
|
|
4513
|
+
* flattening a row to text for a term match nobody asked for is the expensive
|
|
4514
|
+
* part of filtering a live tail.
|
|
4515
|
+
*/
|
|
4516
|
+
function matchesQuery(query, read, searchable) {
|
|
4517
|
+
return query.clauses.every((clause) => {
|
|
4518
|
+
const matched = matchesClause(clause, read, searchable);
|
|
4519
|
+
return clause.negated ? !matched : matched;
|
|
4520
|
+
});
|
|
4521
|
+
}
|
|
4522
|
+
/** Convenience for plain objects, including one level of nested properties. */
|
|
4523
|
+
function matchesQueryObject(query, row, options = {}) {
|
|
4524
|
+
const nested = options.nested ? row[options.nested] : void 0;
|
|
4525
|
+
const read = (field) => field in row ? row[field] : nested === null || nested === void 0 ? void 0 : nested[field];
|
|
4526
|
+
let cached = null;
|
|
4527
|
+
const searchable = () => {
|
|
4528
|
+
var _cached;
|
|
4529
|
+
(_cached = cached) !== null && _cached !== void 0 || (cached = [...Object.values(row).filter((value) => typeof value !== "object"), ...Object.values(nested !== null && nested !== void 0 ? nested : {})].map(toText).join(" "));
|
|
4530
|
+
return cached;
|
|
4531
|
+
};
|
|
4532
|
+
return matchesQuery(query, read, searchable);
|
|
4533
|
+
}
|
|
4534
|
+
//#endregion
|
|
4535
|
+
//#region src/lib/use-media-query.ts
|
|
4536
|
+
/**
|
|
4537
|
+
* Whether a media query matches, kept in sync with the browser.
|
|
4538
|
+
*
|
|
4539
|
+
* `useSyncExternalStore` rather than an effect: a layout that switches on width
|
|
4540
|
+
* must not render the wrong shape for a frame first. The server snapshot is the
|
|
4541
|
+
* caller's `serverFallback`, because the server does not know the viewport and
|
|
4542
|
+
* guessing "narrow" collapses a wide layout on every first paint.
|
|
4543
|
+
*
|
|
4544
|
+
* Internal. Exported from `lib` for the components in this package, not from
|
|
4545
|
+
* the package barrel — a hook that answers "is this viewport wide" invites
|
|
4546
|
+
* layout decisions that belong in CSS.
|
|
4547
|
+
*/
|
|
4548
|
+
function useMediaQuery(query, serverFallback = false) {
|
|
4549
|
+
return (0, react.useSyncExternalStore)((onChange) => {
|
|
4550
|
+
if (typeof window === "undefined") return () => {};
|
|
4551
|
+
const list = window.matchMedia(query);
|
|
4552
|
+
list.addEventListener("change", onChange);
|
|
4553
|
+
return () => list.removeEventListener("change", onChange);
|
|
4554
|
+
}, () => typeof window === "undefined" ? serverFallback : window.matchMedia(query).matches, () => serverFallback);
|
|
4555
|
+
}
|
|
4556
|
+
//#endregion
|
|
4557
|
+
//#region src/shells/inspector-layout.tsx
|
|
4558
|
+
/** Tailwind needs whole class names, so the queries and widths are literals. */
|
|
4559
|
+
const breakpointQuery = {
|
|
4560
|
+
lg: "(min-width: 64rem)",
|
|
4561
|
+
xl: "(min-width: 80rem)",
|
|
4562
|
+
"2xl": "(min-width: 96rem)"
|
|
4563
|
+
};
|
|
4564
|
+
const pushWidth = {
|
|
4565
|
+
sm: "w-[22rem]",
|
|
4566
|
+
md: "w-[30rem]",
|
|
4567
|
+
lg: "w-[42rem]"
|
|
4568
|
+
};
|
|
4569
|
+
const flyoutSize = {
|
|
4570
|
+
sm: "sm",
|
|
4571
|
+
md: "md",
|
|
4572
|
+
lg: "lg"
|
|
4573
|
+
};
|
|
4574
|
+
/**
|
|
4575
|
+
* InspectorLayout — a list and the record it is showing, side by side.
|
|
4576
|
+
*
|
|
4577
|
+
* Reading a catalogue is a loop: look at the list, open one, decide, come back.
|
|
4578
|
+
* A dialog breaks that loop — it takes the list away, and coming back costs the
|
|
4579
|
+
* reader their scroll position and their place in the scan. This keeps both on
|
|
4580
|
+
* screen where there is room, and falls back to an overlay where there is not.
|
|
4581
|
+
*
|
|
4582
|
+
* Every surface that wanted this was writing `w-80 border-l` by hand and
|
|
4583
|
+
* re-deciding the two things that are easy to get wrong: which width switches
|
|
4584
|
+
* the layout, and whether the list stays mounted.
|
|
4585
|
+
*
|
|
4586
|
+
* Focus is deliberately **not** one of them. `Flyout` already remembers who
|
|
4587
|
+
* opened it and hands focus back on close, and its effect runs before this
|
|
4588
|
+
* one — a parent that also tried to capture `document.activeElement` would
|
|
4589
|
+
* read the panel the child had just focused and "restore" to a node that is
|
|
4590
|
+
* about to be removed. One owner, and it is the one closest to the panel.
|
|
4591
|
+
*
|
|
4592
|
+
* @example
|
|
4593
|
+
* ```tsx
|
|
4594
|
+
* <InspectorLayout
|
|
4595
|
+
* open={selected !== null}
|
|
4596
|
+
* onClose={() => setSelected(null)}
|
|
4597
|
+
* title={selected?.name}
|
|
4598
|
+
* inspector={<EventInspector name={selected?.name} />}
|
|
4599
|
+
* >
|
|
4600
|
+
* <DataTable … />
|
|
4601
|
+
* </InspectorLayout>
|
|
4602
|
+
* ```
|
|
4603
|
+
*/
|
|
4604
|
+
function InspectorLayout({ children, inspector, open, onClose, title, description, actions, footer, breakpoint = "xl", width = "md", labels, className }) {
|
|
4605
|
+
const canPush = useMediaQuery(breakpointQuery[breakpoint], true);
|
|
4606
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4607
|
+
className: require_text_truncate.cn("flex min-w-0 items-stretch gap-group", className),
|
|
4608
|
+
"data-opt-id": "MN44T",
|
|
4609
|
+
"data-opt-slug": "inspector-layout.InspectorLayout",
|
|
4610
|
+
"data-inspector-mode": canPush ? "push" : "overlay",
|
|
4611
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4612
|
+
className: "min-w-0 flex-1",
|
|
4613
|
+
children
|
|
4614
|
+
}), canPush ? open && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("aside", {
|
|
4615
|
+
className: require_text_truncate.cn("shrink-0", pushWidth[width]),
|
|
4616
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.Flyout, {
|
|
4617
|
+
open,
|
|
4618
|
+
onClose,
|
|
4619
|
+
type: "inline",
|
|
4620
|
+
title,
|
|
4621
|
+
description,
|
|
4622
|
+
actions,
|
|
4623
|
+
footer,
|
|
4624
|
+
labels,
|
|
4625
|
+
className: "h-full",
|
|
4626
|
+
children: inspector
|
|
4627
|
+
})
|
|
4628
|
+
}) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.Flyout, {
|
|
4629
|
+
open,
|
|
4630
|
+
onClose,
|
|
4631
|
+
type: "overlay",
|
|
4632
|
+
scrim: true,
|
|
4633
|
+
size: flyoutSize[width],
|
|
4634
|
+
title,
|
|
4635
|
+
description,
|
|
4636
|
+
actions,
|
|
4637
|
+
footer,
|
|
4638
|
+
labels,
|
|
4639
|
+
children: inspector
|
|
4640
|
+
})]
|
|
4641
|
+
});
|
|
4642
|
+
}
|
|
4643
|
+
//#endregion
|
|
4644
|
+
//#region src/shells/query-filter-bar.tsx
|
|
4645
|
+
const defaultLabels$14 = {
|
|
4646
|
+
placeholder: "검색하거나 필터를 입력하세요",
|
|
4647
|
+
ariaLabel: "검색",
|
|
4648
|
+
filtersAriaLabel: "필터",
|
|
4649
|
+
clearAll: "필터 지우기",
|
|
4650
|
+
activeCount: (count) => `${count}개 적용됨`
|
|
4651
|
+
};
|
|
4652
|
+
function toggleValue(query, field, value, active, multiSelect) {
|
|
4653
|
+
if (active) {
|
|
4654
|
+
const remaining = require_field_sidebar.fieldValues(query, field).filter((it) => it !== value);
|
|
4655
|
+
const cleared = require_field_sidebar.withoutField(query, field);
|
|
4656
|
+
return remaining.reduce((next, keep) => require_field_sidebar.withFieldValue(next, field, keep), cleared);
|
|
4657
|
+
}
|
|
4658
|
+
return multiSelect ? require_field_sidebar.withFieldValue(query, field, value) : require_field_sidebar.withFieldValue(require_field_sidebar.withoutField(query, field), field, value);
|
|
4659
|
+
}
|
|
4660
|
+
/**
|
|
4661
|
+
* QueryFilterBar — filter buttons and a query string that are the same thing.
|
|
4662
|
+
*
|
|
4663
|
+
* The failure this exists to prevent is two sources of truth. A search box
|
|
4664
|
+
* beside a row of filter buttons will drift: the buttons keep their own state,
|
|
4665
|
+
* the box keeps the text, and a link to the page carries one of them. Readers
|
|
4666
|
+
* find the two disagreeing and stop trusting either.
|
|
4667
|
+
*
|
|
4668
|
+
* So the buttons hold no state at all. Each one reads the query to decide
|
|
4669
|
+
* whether it is active and writes the query when clicked, which makes the
|
|
4670
|
+
* behaviour fall out for free: typing `status:archived` lights up the status
|
|
4671
|
+
* filter, clicking the filter puts `status:archived` in the box, and the URL
|
|
4672
|
+
* that carries the query carries the whole filter state with it.
|
|
4673
|
+
*
|
|
4674
|
+
* @example
|
|
4675
|
+
* ```tsx
|
|
4676
|
+
* <QueryFilterBar
|
|
4677
|
+
* value={query}
|
|
4678
|
+
* onChange={setQuery}
|
|
4679
|
+
* filters={[
|
|
4680
|
+
* { id: "conversion", label: "전환", kind: "is", field: "is", value: "conversion" },
|
|
4681
|
+
* { id: "status", label: "상태", kind: "field_value_selection", field: "status",
|
|
4682
|
+
* options: [{ value: "archived", label: "보관", count: 12 }] },
|
|
4683
|
+
* ]}
|
|
4684
|
+
* />
|
|
4685
|
+
* ```
|
|
4686
|
+
*/
|
|
4687
|
+
function QueryFilterBar({ value, onChange, filters, fields, actions, showClauses = true, live = false, disabled = false, labels: customLabels, queryBarLabels, className }) {
|
|
4688
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$14), customLabels);
|
|
4689
|
+
const activeCount = (0, react.useMemo)(() => filters.reduce((count, filter) => {
|
|
4690
|
+
const values = require_field_sidebar.fieldValues(value, filter.field);
|
|
4691
|
+
if (filter.kind === "field_value_selection") return count + values.length;
|
|
4692
|
+
return count + (filter.value && values.includes(filter.value) ? 1 : 0);
|
|
4693
|
+
}, 0), [filters, value]);
|
|
4694
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4695
|
+
className: require_text_truncate.cn("flex flex-col gap-element", className),
|
|
4696
|
+
"data-opt-id": "SK31N",
|
|
4697
|
+
"data-opt-slug": "query-filter-bar.QueryFilterBar",
|
|
4698
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_field_sidebar.QueryBar, {
|
|
4699
|
+
value,
|
|
4700
|
+
onChange,
|
|
4701
|
+
fields,
|
|
4702
|
+
showClauses,
|
|
4703
|
+
live,
|
|
4704
|
+
disabled,
|
|
4705
|
+
labels: require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, queryBarLabels), {}, {
|
|
4706
|
+
placeholder: labels.placeholder,
|
|
4707
|
+
ariaLabel: labels.ariaLabel
|
|
4708
|
+
})
|
|
4709
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4710
|
+
className: "gap-element flex flex-wrap items-center",
|
|
4711
|
+
role: "group",
|
|
4712
|
+
"aria-label": labels.filtersAriaLabel,
|
|
4713
|
+
children: [
|
|
4714
|
+
filters.map((filter) => {
|
|
4715
|
+
var _filter$multiSelect, _filter$value;
|
|
4716
|
+
const values = require_field_sidebar.fieldValues(value, filter.field);
|
|
4717
|
+
const multiSelect = (_filter$multiSelect = filter.multiSelect) !== null && _filter$multiSelect !== void 0 ? _filter$multiSelect : true;
|
|
4718
|
+
if (filter.kind === "field_value_selection") {
|
|
4719
|
+
var _filter$options, _filter$options2;
|
|
4720
|
+
const selected = (_filter$options = filter.options) === null || _filter$options === void 0 ? void 0 : _filter$options.filter((option) => values.includes(option.value));
|
|
4721
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.PopoverRoot, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.PopoverTrigger, {
|
|
4722
|
+
disabled,
|
|
4723
|
+
className: require_text_truncate.cn("inline-flex h-7 items-center gap-1 rounded-md border px-2 text-xs transition-colors", require_text_truncate.OPT_FOCUS_VISIBLE, (selected === null || selected === void 0 ? void 0 : selected.length) ? "border-accent bg-accent-subtle text-text-primary" : "border-border text-text-secondary hover:text-text-primary", disabled && "pointer-events-none opacity-50"),
|
|
4724
|
+
children: [
|
|
4725
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { children: filter.label }),
|
|
4726
|
+
(selected === null || selected === void 0 ? void 0 : selected.length) ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Badge, {
|
|
4727
|
+
variant: "info",
|
|
4728
|
+
size: "sm",
|
|
4729
|
+
children: selected.length
|
|
4730
|
+
}) : null,
|
|
4731
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.ChevronDown, {
|
|
4732
|
+
"aria-hidden": "true",
|
|
4733
|
+
className: "size-3"
|
|
4734
|
+
})
|
|
4735
|
+
]
|
|
4736
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.PopoverContent, {
|
|
4737
|
+
className: "min-w-48 p-1",
|
|
4738
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4739
|
+
role: "group",
|
|
4740
|
+
"aria-label": filter.label,
|
|
4741
|
+
children: (_filter$options2 = filter.options) === null || _filter$options2 === void 0 ? void 0 : _filter$options2.map((option) => {
|
|
4742
|
+
const active = values.includes(option.value);
|
|
4743
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
|
|
4744
|
+
type: "button",
|
|
4745
|
+
disabled,
|
|
4746
|
+
"aria-pressed": active,
|
|
4747
|
+
onClick: () => onChange(toggleValue(value, filter.field, option.value, active, multiSelect)),
|
|
4748
|
+
className: require_text_truncate.cn("flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-xs", "hover:bg-bg-subtle", "disabled:pointer-events-none disabled:opacity-50", require_text_truncate.OPT_FOCUS_VISIBLE),
|
|
4749
|
+
children: [
|
|
4750
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.Check, {
|
|
4751
|
+
"aria-hidden": "true",
|
|
4752
|
+
className: require_text_truncate.cn("size-3 shrink-0", active ? "opacity-100" : "opacity-0")
|
|
4753
|
+
}),
|
|
4754
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4755
|
+
className: "flex-1 truncate",
|
|
4756
|
+
children: option.label
|
|
4757
|
+
}),
|
|
4758
|
+
option.count != null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4759
|
+
className: "text-text-tertiary tabular-nums",
|
|
4760
|
+
children: option.count
|
|
4761
|
+
})
|
|
4762
|
+
]
|
|
4763
|
+
}, option.value);
|
|
4764
|
+
})
|
|
4765
|
+
})
|
|
4766
|
+
})] }, filter.id);
|
|
4767
|
+
}
|
|
4768
|
+
const filterValue = (_filter$value = filter.value) !== null && _filter$value !== void 0 ? _filter$value : filter.id;
|
|
4769
|
+
const active = values.includes(filterValue);
|
|
4770
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4771
|
+
type: "button",
|
|
4772
|
+
disabled,
|
|
4773
|
+
"aria-pressed": active,
|
|
4774
|
+
onClick: () => onChange(toggleValue(value, filter.field, filterValue, active, multiSelect)),
|
|
4775
|
+
className: require_text_truncate.cn("inline-flex h-7 items-center rounded-md border px-2 text-xs transition-colors", require_text_truncate.OPT_FOCUS_VISIBLE, active ? "border-accent bg-accent-subtle text-text-primary" : "border-border text-text-secondary hover:text-text-primary", "disabled:pointer-events-none disabled:opacity-50"),
|
|
4776
|
+
children: filter.label
|
|
4777
|
+
}, filter.id);
|
|
4778
|
+
}),
|
|
4779
|
+
activeCount > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4780
|
+
className: "text-text-tertiary text-xs",
|
|
4781
|
+
children: labels.activeCount(activeCount)
|
|
4782
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.Button, {
|
|
4783
|
+
variant: "ghost",
|
|
4784
|
+
size: "sm",
|
|
4785
|
+
disabled,
|
|
4786
|
+
onClick: () => onChange({ clauses: [] }),
|
|
4787
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.X, {
|
|
4788
|
+
"aria-hidden": "true",
|
|
4789
|
+
className: "size-3"
|
|
4790
|
+
}), labels.clearAll]
|
|
4791
|
+
})] }),
|
|
4792
|
+
actions
|
|
4793
|
+
]
|
|
4794
|
+
})]
|
|
4795
|
+
});
|
|
4796
|
+
}
|
|
4797
|
+
/** Whether the bar is filtering anything — for an empty state's wording. */
|
|
4798
|
+
function hasActiveQuery(query) {
|
|
4799
|
+
return !require_field_sidebar.isEmptyQuery(query);
|
|
4800
|
+
}
|
|
4801
|
+
//#endregion
|
|
4802
|
+
//#region src/shells/catalog-frame.tsx
|
|
4803
|
+
/**
|
|
4804
|
+
* CatalogRowActions — a row's actions, two of them visible.
|
|
4805
|
+
*
|
|
4806
|
+
* Beyond two, a row's action column starts competing with the row's content
|
|
4807
|
+
* for the reader's eye, so the rest go behind one menu. The click never
|
|
4808
|
+
* reaches the row: acting on a row and selecting it are different intentions,
|
|
4809
|
+
* and a table that does both at once is one a reader stops trusting.
|
|
4810
|
+
*/
|
|
4811
|
+
function CatalogRowActions({ item, actions, visibleCount = 2, labels }) {
|
|
4812
|
+
var _labels$rowActions, _labels$moreActions;
|
|
4813
|
+
const applicable = actions.filter((action) => {
|
|
4814
|
+
var _action$available, _action$available2;
|
|
4815
|
+
return (_action$available = (_action$available2 = action.available) === null || _action$available2 === void 0 ? void 0 : _action$available2.call(action, item)) !== null && _action$available !== void 0 ? _action$available : true;
|
|
4816
|
+
});
|
|
4817
|
+
const visible = applicable.slice(0, visibleCount);
|
|
4818
|
+
const overflow = applicable.slice(visibleCount);
|
|
4819
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4820
|
+
className: "flex items-center justify-end gap-1",
|
|
4821
|
+
role: "group",
|
|
4822
|
+
"aria-label": (_labels$rowActions = labels === null || labels === void 0 ? void 0 : labels.rowActions) !== null && _labels$rowActions !== void 0 ? _labels$rowActions : "행 액션",
|
|
4823
|
+
onClick: (event) => event.stopPropagation(),
|
|
4824
|
+
children: [visible.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.Button, {
|
|
4825
|
+
variant: "ghost",
|
|
4826
|
+
size: "sm",
|
|
4827
|
+
onClick: () => action.onSelect(item),
|
|
4828
|
+
children: [action.icon, action.label]
|
|
4829
|
+
}, action.id)), overflow.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_key_pad_menu.DropdownMenu, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_key_pad_menu.DropdownTrigger, {
|
|
4830
|
+
"aria-label": (_labels$moreActions = labels === null || labels === void 0 ? void 0 : labels.moreActions) !== null && _labels$moreActions !== void 0 ? _labels$moreActions : "더 보기",
|
|
4831
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(lucide_react.MoreHorizontal, {
|
|
4832
|
+
"aria-hidden": "true",
|
|
4833
|
+
className: "size-4"
|
|
4834
|
+
})
|
|
4835
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_key_pad_menu.DropdownContent, { children: overflow.map((action) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_key_pad_menu.DropdownItem, {
|
|
4836
|
+
onClick: () => action.onSelect(item),
|
|
4837
|
+
children: action.label
|
|
4838
|
+
}, action.id)) })] })]
|
|
4839
|
+
});
|
|
4840
|
+
}
|
|
4841
|
+
/**
|
|
4842
|
+
* Keeps a cell's own controls from also selecting the row.
|
|
4843
|
+
*
|
|
4844
|
+
* A click on a switch or a copy button reaches the row handler on its way up,
|
|
4845
|
+
* so toggling a flag would open the inspector at the same time.
|
|
4846
|
+
*/
|
|
4847
|
+
function CatalogCellControls({ children }) {
|
|
4848
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
4849
|
+
className: "contents",
|
|
4850
|
+
onClick: (event) => event.stopPropagation(),
|
|
4851
|
+
children
|
|
4852
|
+
});
|
|
4853
|
+
}
|
|
4854
|
+
const defaultLabels$13 = {
|
|
4855
|
+
emptyTitle: "아직 아무것도 없습니다",
|
|
4856
|
+
emptyDescription: "데이터가 도착하면 여기에 나타납니다.",
|
|
4857
|
+
filteredEmptyTitle: "조건에 맞는 항목이 없습니다",
|
|
4858
|
+
filteredEmptyDescription: "필터를 지우면 전체 목록이 보입니다.",
|
|
4859
|
+
clearFilters: "필터 지우기",
|
|
4860
|
+
errorTitle: "목록을 불러오지 못했습니다",
|
|
4861
|
+
retry: "다시 시도"
|
|
4862
|
+
};
|
|
4863
|
+
/**
|
|
4864
|
+
* CatalogFrame — the shape every catalogue list has.
|
|
4865
|
+
*
|
|
4866
|
+
* Two catalogues (events, properties) differ only in their columns and their
|
|
4867
|
+
* words; everything around the table is the same, and writing it twice meant
|
|
4868
|
+
* two copies of the decisions that are easy to get wrong — that a failed read
|
|
4869
|
+
* must not look like an empty list, that an empty list reads differently when a
|
|
4870
|
+
* filter is on, and that a selection must not survive a filter change.
|
|
4871
|
+
*
|
|
4872
|
+
* The last one is enforced here rather than left to the caller. A bulk action
|
|
4873
|
+
* applied to rows the reader can no longer see is the kind of mistake that is
|
|
4874
|
+
* only noticed afterwards.
|
|
4875
|
+
*/
|
|
4876
|
+
function CatalogFrame({ children, isEmpty, query, onQueryChange, filters, stats, onStatClick, notice, emptyActions, header, actions, toolbar, inspector, inspectorOpen, onInspectorClose, inspectorTitle, inspectorDescription, inspectorActions, inspectorFooter, inspectorWidth, page = 1, pageSize = 50, totalCount, onPageChange, selectedKeys, onSelectionChange, bulkActions, onBulkAction, error, onRetry, labels: customLabels, className }) {
|
|
4877
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$13), customLabels);
|
|
4878
|
+
const lastScope = (0, react.useRef)({
|
|
4879
|
+
query,
|
|
4880
|
+
page
|
|
4881
|
+
});
|
|
4882
|
+
(0, react.useEffect)(() => {
|
|
4883
|
+
const changed = lastScope.current.query !== query || lastScope.current.page !== page;
|
|
4884
|
+
lastScope.current = {
|
|
4885
|
+
query,
|
|
4886
|
+
page
|
|
4887
|
+
};
|
|
4888
|
+
if (changed && selectedKeys && selectedKeys.length > 0) onSelectionChange === null || onSelectionChange === void 0 || onSelectionChange([]);
|
|
4889
|
+
}, [
|
|
4890
|
+
query,
|
|
4891
|
+
page,
|
|
4892
|
+
selectedKeys,
|
|
4893
|
+
onSelectionChange
|
|
4894
|
+
]);
|
|
4895
|
+
const filtering = !require_field_sidebar.isEmptyQuery(query);
|
|
4896
|
+
const body = error ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.EmptyState, {
|
|
4897
|
+
tone: "error",
|
|
4898
|
+
hasBorder: true,
|
|
4899
|
+
title: labels.errorTitle,
|
|
4900
|
+
body: error,
|
|
4901
|
+
actions: onRetry ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Button, {
|
|
4902
|
+
variant: "secondary",
|
|
4903
|
+
onClick: onRetry,
|
|
4904
|
+
children: labels.retry
|
|
4905
|
+
}) : void 0
|
|
4906
|
+
}) : isEmpty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.EmptyState, {
|
|
4907
|
+
tone: "subdued",
|
|
4908
|
+
hasBorder: true,
|
|
4909
|
+
title: filtering ? labels.filteredEmptyTitle : labels.emptyTitle,
|
|
4910
|
+
description: filtering ? labels.filteredEmptyDescription : labels.emptyDescription,
|
|
4911
|
+
actions: filtering ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Button, {
|
|
4912
|
+
variant: "secondary",
|
|
4913
|
+
onClick: () => onQueryChange({ clauses: [] }),
|
|
4914
|
+
children: labels.clearFilters
|
|
4915
|
+
}) : emptyActions
|
|
4916
|
+
}) : children;
|
|
4917
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4918
|
+
className: require_text_truncate.cn("flex flex-col gap-section", className),
|
|
4919
|
+
children: [
|
|
4920
|
+
(header || actions) && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4921
|
+
className: "gap-group flex min-w-0 flex-col lg:flex-row lg:items-start lg:justify-between",
|
|
4922
|
+
children: [header && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4923
|
+
className: "min-w-0 flex-1",
|
|
4924
|
+
children: header
|
|
4925
|
+
}), actions && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4926
|
+
className: "gap-element flex flex-wrap items-center",
|
|
4927
|
+
children: actions
|
|
4928
|
+
})]
|
|
4929
|
+
}),
|
|
4930
|
+
stats && stats.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SummaryRow, {
|
|
4931
|
+
stats,
|
|
4932
|
+
onStatClick
|
|
4933
|
+
}),
|
|
4934
|
+
notice,
|
|
4935
|
+
toolbar && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4936
|
+
className: "gap-group flex flex-wrap items-center",
|
|
4937
|
+
children: toolbar
|
|
4938
|
+
}),
|
|
4939
|
+
filters && filters.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(QueryFilterBar, {
|
|
4940
|
+
value: query,
|
|
4941
|
+
onChange: onQueryChange,
|
|
4942
|
+
filters,
|
|
4943
|
+
disabled: Boolean(error)
|
|
4944
|
+
}),
|
|
4945
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(InspectorLayout, {
|
|
4946
|
+
open: inspectorOpen && Boolean(inspector),
|
|
4947
|
+
onClose: onInspectorClose,
|
|
4948
|
+
inspector,
|
|
4949
|
+
title: inspectorTitle,
|
|
4950
|
+
description: inspectorDescription,
|
|
4951
|
+
actions: inspectorActions,
|
|
4952
|
+
footer: inspectorFooter,
|
|
4953
|
+
width: inspectorWidth,
|
|
4954
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4955
|
+
className: "gap-group flex flex-col",
|
|
4956
|
+
children: [body, onPageChange && totalCount != null && totalCount > pageSize && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.Pagination, {
|
|
4957
|
+
currentPage: page,
|
|
4958
|
+
totalPages: Math.ceil(totalCount / pageSize),
|
|
4959
|
+
onPageChange
|
|
4960
|
+
})]
|
|
4961
|
+
})
|
|
4962
|
+
}),
|
|
4963
|
+
bulkActions && bulkActions.length > 0 && onBulkAction && selectedKeys && selectedKeys.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(FloatingActionBar, {
|
|
4964
|
+
actions: bulkActions,
|
|
4965
|
+
selectedCount: selectedKeys.length,
|
|
4966
|
+
onAction: onBulkAction,
|
|
4967
|
+
onDismiss: () => onSelectionChange === null || onSelectionChange === void 0 ? void 0 : onSelectionChange([])
|
|
4968
|
+
})
|
|
4969
|
+
]
|
|
4970
|
+
});
|
|
4971
|
+
}
|
|
4972
|
+
//#endregion
|
|
4100
4973
|
//#region src/shells/comparison-selector.tsx
|
|
4101
4974
|
/** Renders the comparison selector component. */
|
|
4102
4975
|
function ComparisonSelector({ segments, valueA, valueB, onChangeA, onChangeB, values, onValuesChange, maxItems = 5, labels: customLabels, className }) {
|
|
@@ -5251,7 +6124,7 @@ function ThemeSwitcher({ className, labels: userLabels, variant = "default", cus
|
|
|
5251
6124
|
ThemeSwitcher.displayName = "ThemeSwitcher";
|
|
5252
6125
|
//#endregion
|
|
5253
6126
|
//#region src/shells/prompt-template.tsx
|
|
5254
|
-
const defaultLabels$
|
|
6127
|
+
const defaultLabels$12 = {
|
|
5255
6128
|
copy: "Copy",
|
|
5256
6129
|
copied: "Copied!",
|
|
5257
6130
|
copyFailed: "Copy failed"
|
|
@@ -5261,7 +6134,7 @@ function renderPrompt(template, values) {
|
|
|
5261
6134
|
}
|
|
5262
6135
|
/** Renders the prompt template component. */
|
|
5263
6136
|
function PromptTemplate({ title, description, template, variables = [], className, labels: customLabels }) {
|
|
5264
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
6137
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$12), customLabels);
|
|
5265
6138
|
const [values, setValues] = react.useState(() => {
|
|
5266
6139
|
const initial = {};
|
|
5267
6140
|
for (const v of variables) if (v.defaultValue) initial[v.name] = v.defaultValue;
|
|
@@ -5750,14 +6623,14 @@ function AsyncCombobox({ onSearch, debounceMs = 300, loadingText, minChars = 1,
|
|
|
5750
6623
|
}
|
|
5751
6624
|
//#endregion
|
|
5752
6625
|
//#region src/shells/vertical-tabs.tsx
|
|
5753
|
-
const defaultLabels$
|
|
6626
|
+
const defaultLabels$11 = {
|
|
5754
6627
|
ariaLabel: "Vertical tabs",
|
|
5755
6628
|
emptyMessage: "No tabs available"
|
|
5756
6629
|
};
|
|
5757
6630
|
/** Renders the vertical tabs component. */
|
|
5758
6631
|
function VerticalTabs({ tabs, defaultTabId, labels: customLabels, className }) {
|
|
5759
6632
|
var _tabs$;
|
|
5760
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
6633
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$11), customLabels);
|
|
5761
6634
|
if (tabs.length === 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
5762
6635
|
className: require_text_truncate.cn("text-text-secondary text-sm", className),
|
|
5763
6636
|
"data-opt-id": "J81G4",
|
|
@@ -5766,6 +6639,7 @@ function VerticalTabs({ tabs, defaultTabId, labels: customLabels, className }) {
|
|
|
5766
6639
|
});
|
|
5767
6640
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.TabsRoot, {
|
|
5768
6641
|
defaultSelectedId: defaultTabId !== null && defaultTabId !== void 0 ? defaultTabId : (_tabs$ = tabs[0]) === null || _tabs$ === void 0 ? void 0 : _tabs$.id,
|
|
6642
|
+
orientation: "vertical",
|
|
5769
6643
|
"data-opt-id": "J81G4",
|
|
5770
6644
|
"data-opt-slug": "vertical-tabs.VerticalTabs",
|
|
5771
6645
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -5790,13 +6664,13 @@ function VerticalTabs({ tabs, defaultTabId, labels: customLabels, className }) {
|
|
|
5790
6664
|
}
|
|
5791
6665
|
//#endregion
|
|
5792
6666
|
//#region src/shells/column-toggler.tsx
|
|
5793
|
-
const defaultLabels$
|
|
6667
|
+
const defaultLabels$10 = {
|
|
5794
6668
|
triggerLabel: (count) => `Columns (${count})`,
|
|
5795
6669
|
emptyMessage: "No columns available"
|
|
5796
6670
|
};
|
|
5797
6671
|
/** Renders the column toggler component. */
|
|
5798
6672
|
function ColumnToggler({ columns, visibleColumns, onChange, className, labels: customLabels }) {
|
|
5799
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
6673
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$10), customLabels);
|
|
5800
6674
|
const visibleCount = visibleColumns.length;
|
|
5801
6675
|
const hasColumns = columns.length > 0;
|
|
5802
6676
|
const toggle = (id) => {
|
|
@@ -5875,7 +6749,7 @@ function BulkActions({ selectedCount, actions, onAction, onClear, labels: custom
|
|
|
5875
6749
|
}
|
|
5876
6750
|
//#endregion
|
|
5877
6751
|
//#region src/shells/saved-filters.tsx
|
|
5878
|
-
const defaultLabels$
|
|
6752
|
+
const defaultLabels$9 = {
|
|
5879
6753
|
triggerLabel: (count) => `Saved Filters (${count})`,
|
|
5880
6754
|
emptyMessage: "No saved filters",
|
|
5881
6755
|
deleteLabel: (name) => `Delete ${name}`,
|
|
@@ -5886,7 +6760,7 @@ const defaultLabels$8 = {
|
|
|
5886
6760
|
};
|
|
5887
6761
|
/** Renders the saved filters component. */
|
|
5888
6762
|
function SavedFilters({ currentFilters, presets, onSavePreset, onLoadPreset, onDeletePreset, className, labels: customLabels }) {
|
|
5889
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
6763
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$9), customLabels);
|
|
5890
6764
|
const [newName, setNewName] = react.useState("");
|
|
5891
6765
|
const [pendingDeleteId, setPendingDeleteId] = react.useState(null);
|
|
5892
6766
|
const triggerId = react.useId();
|
|
@@ -6038,7 +6912,7 @@ function SavedFilters({ currentFilters, presets, onSavePreset, onLoadPreset, onD
|
|
|
6038
6912
|
}
|
|
6039
6913
|
//#endregion
|
|
6040
6914
|
//#region src/shells/notification-center.tsx
|
|
6041
|
-
const defaultLabels$
|
|
6915
|
+
const defaultLabels$8 = {
|
|
6042
6916
|
triggerLabel: "Notifications",
|
|
6043
6917
|
unreadSuffix: (count) => `(${count} unread)`,
|
|
6044
6918
|
title: "Notifications",
|
|
@@ -6047,7 +6921,7 @@ const defaultLabels$7 = {
|
|
|
6047
6921
|
};
|
|
6048
6922
|
/** Renders the notification center component. */
|
|
6049
6923
|
function NotificationCenter({ notifications, onMarkRead, onMarkAllRead, onAction, className, labels: customLabels }) {
|
|
6050
|
-
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$
|
|
6924
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$8), customLabels);
|
|
6051
6925
|
const unreadCount = notifications.filter((n) => !n.read).length;
|
|
6052
6926
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.PopoverRoot, {
|
|
6053
6927
|
"data-opt-id": "7A0XY",
|
|
@@ -6251,9 +7125,29 @@ function AuditLog({ entries, onLoadMore, loading, labels: customLabels, classNam
|
|
|
6251
7125
|
AuditLog.displayName = "AuditLog";
|
|
6252
7126
|
//#endregion
|
|
6253
7127
|
//#region src/shells/tree-table.tsx
|
|
7128
|
+
const defaultLabels$7 = {
|
|
7129
|
+
ariaLabel: "Tree table",
|
|
7130
|
+
expand: (rowLabel) => `Expand ${rowLabel}`,
|
|
7131
|
+
collapse: (rowLabel) => `Collapse ${rowLabel}`,
|
|
7132
|
+
level: (depth) => `Level ${depth}`
|
|
7133
|
+
};
|
|
7134
|
+
function flattenTree(nodes, expanded, depth = 0, ancestorsVisible = true) {
|
|
7135
|
+
return nodes.flatMap((node) => {
|
|
7136
|
+
var _node$children;
|
|
7137
|
+
const visible = ancestorsVisible;
|
|
7138
|
+
return [{
|
|
7139
|
+
node,
|
|
7140
|
+
depth,
|
|
7141
|
+
visible
|
|
7142
|
+
}, ...flattenTree((_node$children = node.children) !== null && _node$children !== void 0 ? _node$children : [], expanded, depth + 1, visible && expanded.has(node.id))];
|
|
7143
|
+
});
|
|
7144
|
+
}
|
|
6254
7145
|
/** Renders the tree table component. */
|
|
6255
|
-
function TreeTable({ data, columns, defaultExpanded = [], indentSize = 24, className }) {
|
|
7146
|
+
function TreeTable({ data, columns, defaultExpanded = [], indentSize = 24, getRowLabel, labels: customLabels, className, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy }) {
|
|
6256
7147
|
const [expanded, setExpanded] = react.useState(() => new Set(defaultExpanded));
|
|
7148
|
+
const baseId = react.useId();
|
|
7149
|
+
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$7), customLabels);
|
|
7150
|
+
const rows = flattenTree(data, expanded);
|
|
6257
7151
|
const toggle = (id) => {
|
|
6258
7152
|
setExpanded((prev) => {
|
|
6259
7153
|
const next = new Set(prev);
|
|
@@ -6267,46 +7161,82 @@ function TreeTable({ data, columns, defaultExpanded = [], indentSize = 24, class
|
|
|
6267
7161
|
if (typeof col.accessor === "function") return col.accessor(row);
|
|
6268
7162
|
return String((_row$col$accessor = row[col.accessor]) !== null && _row$col$accessor !== void 0 ? _row$col$accessor : "");
|
|
6269
7163
|
};
|
|
6270
|
-
const
|
|
6271
|
-
|
|
6272
|
-
|
|
6273
|
-
|
|
6274
|
-
|
|
6275
|
-
|
|
6276
|
-
|
|
6277
|
-
|
|
6278
|
-
|
|
6279
|
-
|
|
6280
|
-
children: [
|
|
6281
|
-
ci === 0 && hasChildren && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
6282
|
-
type: "button",
|
|
6283
|
-
onClick: () => toggle(node.id),
|
|
6284
|
-
className: require_text_truncate.cn("mr-1 flex h-5 w-5 items-center justify-center rounded text-xs", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
|
|
6285
|
-
"aria-expanded": isExpanded,
|
|
6286
|
-
"aria-label": isExpanded ? "Collapse" : "Expand",
|
|
6287
|
-
children: isExpanded ? "▼" : "▶"
|
|
6288
|
-
}),
|
|
6289
|
-
ci === 0 && !hasChildren && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "mr-1 inline-block w-5" }),
|
|
6290
|
-
getCellValue(node.data, col)
|
|
6291
|
-
]
|
|
6292
|
-
})
|
|
6293
|
-
}, col.id))
|
|
6294
|
-
}, node.id), ...isExpanded && hasChildren ? renderRows(node.children, depth + 1) : []];
|
|
6295
|
-
});
|
|
7164
|
+
const rowId = (id) => `${baseId}-row-${encodeURIComponent(id)}`;
|
|
7165
|
+
const resolveRowLabel = (node) => {
|
|
7166
|
+
if (getRowLabel) return getRowLabel(node);
|
|
7167
|
+
const firstColumn = columns[0];
|
|
7168
|
+
if (firstColumn) {
|
|
7169
|
+
const value = getCellValue(node.data, firstColumn);
|
|
7170
|
+
if (typeof value === "string" || typeof value === "number") return String(value);
|
|
7171
|
+
}
|
|
7172
|
+
return node.id;
|
|
7173
|
+
};
|
|
6296
7174
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
6297
7175
|
className: require_text_truncate.cn("overflow-auto", className),
|
|
6298
|
-
"data-opt-id": "
|
|
7176
|
+
"data-opt-id": "PP194",
|
|
6299
7177
|
"data-opt-slug": "tree-table.TreeTable",
|
|
6300
7178
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("table", {
|
|
6301
7179
|
className: require_text_truncate.cn("w-full border-collapse", require_text_truncate.OPT_BORDER),
|
|
7180
|
+
"aria-label": ariaLabelledBy == null ? ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : labels.ariaLabel : void 0,
|
|
7181
|
+
"aria-labelledby": ariaLabelledBy,
|
|
6302
7182
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("thead", { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", {
|
|
6303
7183
|
className: "border-border border-b",
|
|
6304
7184
|
children: columns.map((col) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
7185
|
+
scope: "col",
|
|
6305
7186
|
className: require_text_truncate.cn(require_text_truncate.OPT_TH),
|
|
6306
7187
|
style: { width: col.width },
|
|
6307
7188
|
children: col.header
|
|
6308
7189
|
}, col.id))
|
|
6309
|
-
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children:
|
|
7190
|
+
}) }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tbody", { children: rows.map(({ node, depth, visible }) => {
|
|
7191
|
+
var _node$children$length, _node$children2, _node$children3;
|
|
7192
|
+
const hasChildren = ((_node$children$length = (_node$children2 = node.children) === null || _node$children2 === void 0 ? void 0 : _node$children2.length) !== null && _node$children$length !== void 0 ? _node$children$length : 0) > 0;
|
|
7193
|
+
const isExpanded = expanded.has(node.id);
|
|
7194
|
+
const resolvedRowLabel = resolveRowLabel(node);
|
|
7195
|
+
const controlledRows = ((_node$children3 = node.children) !== null && _node$children3 !== void 0 ? _node$children3 : []).map((child) => rowId(child.id)).join(" ");
|
|
7196
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("tr", {
|
|
7197
|
+
id: rowId(node.id),
|
|
7198
|
+
hidden: !visible,
|
|
7199
|
+
className: "border-border border-b",
|
|
7200
|
+
children: columns.map((col, columnIndex) => {
|
|
7201
|
+
const content = /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
7202
|
+
className: "flex items-center",
|
|
7203
|
+
style: columnIndex === 0 ? { paddingLeft: depth * indentSize } : void 0,
|
|
7204
|
+
children: [
|
|
7205
|
+
columnIndex === 0 && hasChildren && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
7206
|
+
type: "button",
|
|
7207
|
+
onClick: () => toggle(node.id),
|
|
7208
|
+
className: require_text_truncate.cn("mr-1 flex h-5 w-5 items-center justify-center rounded text-xs", "outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 focus-visible:ring-offset-ring-offset"),
|
|
7209
|
+
"aria-expanded": isExpanded,
|
|
7210
|
+
"aria-controls": controlledRows || void 0,
|
|
7211
|
+
"aria-label": isExpanded ? labels.collapse(resolvedRowLabel) : labels.expand(resolvedRowLabel),
|
|
7212
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7213
|
+
"aria-hidden": "true",
|
|
7214
|
+
children: isExpanded ? "▼" : "▶"
|
|
7215
|
+
})
|
|
7216
|
+
}),
|
|
7217
|
+
columnIndex === 0 && !hasChildren && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "mr-1 inline-block w-5" }),
|
|
7218
|
+
columnIndex === 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7219
|
+
className: "sr-only",
|
|
7220
|
+
children: [
|
|
7221
|
+
labels.level(depth + 1),
|
|
7222
|
+
".",
|
|
7223
|
+
" "
|
|
7224
|
+
]
|
|
7225
|
+
}),
|
|
7226
|
+
getCellValue(node.data, col)
|
|
7227
|
+
]
|
|
7228
|
+
});
|
|
7229
|
+
return columnIndex === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("th", {
|
|
7230
|
+
scope: "row",
|
|
7231
|
+
className: require_text_truncate.cn(require_text_truncate.OPT_TD),
|
|
7232
|
+
children: content
|
|
7233
|
+
}, col.id) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("td", {
|
|
7234
|
+
className: require_text_truncate.cn(require_text_truncate.OPT_TD),
|
|
7235
|
+
children: content
|
|
7236
|
+
}, col.id);
|
|
7237
|
+
})
|
|
7238
|
+
}, node.id);
|
|
7239
|
+
}) })]
|
|
6310
7240
|
})
|
|
6311
7241
|
});
|
|
6312
7242
|
}
|
|
@@ -7048,17 +7978,37 @@ function DataImportWizard({ fields, onImport, acceptedFormats = ".csv", labels:
|
|
|
7048
7978
|
//#endregion
|
|
7049
7979
|
//#region src/shells/mega-menu.tsx
|
|
7050
7980
|
const defaultLabels$3 = { trigger: "Menu" };
|
|
7981
|
+
function MegaMenuItemContent({ item }) {
|
|
7982
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [item.icon && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7983
|
+
"aria-hidden": "true",
|
|
7984
|
+
className: "text-text-secondary mt-0.5 flex-shrink-0",
|
|
7985
|
+
children: item.icon
|
|
7986
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
|
|
7987
|
+
className: "flex flex-col text-left",
|
|
7988
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7989
|
+
className: "text-text-primary text-sm font-medium",
|
|
7990
|
+
children: item.label
|
|
7991
|
+
}), item.description && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
7992
|
+
className: "text-text-tertiary text-xs",
|
|
7993
|
+
children: item.description
|
|
7994
|
+
})]
|
|
7995
|
+
})] });
|
|
7996
|
+
}
|
|
7051
7997
|
/** Renders the mega menu component. */
|
|
7052
|
-
function MegaMenu({ menus, columns = 3, footer, triggerLabel, labels: customLabels, className }) {
|
|
7998
|
+
function MegaMenu({ menus, columns = 3, footer, triggerLabel, labels: customLabels, className, "aria-label": ariaLabel }) {
|
|
7999
|
+
var _ref;
|
|
7053
8000
|
const labels = require_text_truncate._objectSpread2(require_text_truncate._objectSpread2({}, defaultLabels$3), customLabels);
|
|
7054
8001
|
const resolvedTriggerLabel = triggerLabel !== null && triggerLabel !== void 0 ? triggerLabel : labels.trigger;
|
|
8002
|
+
const navigationLabel = (_ref = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : labels.navigation) !== null && _ref !== void 0 ? _ref : `${resolvedTriggerLabel} navigation`;
|
|
8003
|
+
const itemClassName = "hover:bg-bg-subtle gap-element flex w-full items-start rounded-md p-2 transition-colors";
|
|
7055
8004
|
if (menus.length === 0) return null;
|
|
7056
8005
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.PopoverRoot, {
|
|
7057
|
-
"data-opt-id": "
|
|
8006
|
+
"data-opt-id": "AHTK9",
|
|
7058
8007
|
"data-opt-slug": "mega-menu.MegaMenu",
|
|
7059
8008
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)(require_text_truncate.PopoverTrigger, {
|
|
7060
8009
|
className: require_text_truncate.cn("border-border bg-surface text-text-primary hover:bg-bg-subtle inline-flex h-9 items-center gap-1.5 rounded-lg border px-3 text-sm font-medium", className),
|
|
7061
8010
|
children: [resolvedTriggerLabel, /* @__PURE__ */ (0, react_jsx_runtime.jsx)("svg", {
|
|
8011
|
+
"aria-hidden": "true",
|
|
7062
8012
|
width: "12",
|
|
7063
8013
|
height: "12",
|
|
7064
8014
|
viewBox: "0 0 12 12",
|
|
@@ -7067,38 +8017,41 @@ function MegaMenu({ menus, columns = 3, footer, triggerLabel, labels: customLabe
|
|
|
7067
8017
|
strokeWidth: "1.5",
|
|
7068
8018
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("path", { d: "M3 5l3 3 3-3" })
|
|
7069
8019
|
})]
|
|
7070
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.
|
|
8020
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.PopoverContent, {
|
|
7071
8021
|
className: "w-auto max-w-2xl p-0",
|
|
7072
|
-
children:
|
|
7073
|
-
|
|
7074
|
-
|
|
7075
|
-
|
|
7076
|
-
|
|
7077
|
-
children:
|
|
7078
|
-
className: "
|
|
7079
|
-
children:
|
|
7080
|
-
|
|
7081
|
-
|
|
7082
|
-
|
|
7083
|
-
|
|
7084
|
-
|
|
7085
|
-
|
|
7086
|
-
|
|
7087
|
-
|
|
7088
|
-
|
|
7089
|
-
|
|
7090
|
-
|
|
7091
|
-
|
|
7092
|
-
|
|
7093
|
-
|
|
7094
|
-
|
|
8022
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
|
|
8023
|
+
"aria-label": navigationLabel,
|
|
8024
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8025
|
+
className: "gap-group grid p-4",
|
|
8026
|
+
style: { gridTemplateColumns: `repeat(${columns}, minmax(0, 1fr))` },
|
|
8027
|
+
children: menus.map((section) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
8028
|
+
className: "gap-element flex flex-col",
|
|
8029
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("h4", {
|
|
8030
|
+
className: "text-text-tertiary text-xs font-semibold tracking-wider uppercase",
|
|
8031
|
+
children: section.title
|
|
8032
|
+
}), section.items.map((item) => {
|
|
8033
|
+
if (item.href != null) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
|
|
8034
|
+
href: item.href,
|
|
8035
|
+
className: itemClassName,
|
|
8036
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MegaMenuItemContent, { item })
|
|
8037
|
+
}, item.label);
|
|
8038
|
+
if (item.onSelect) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(require_text_truncate.PopoverClose, {
|
|
8039
|
+
onClick: item.onSelect,
|
|
8040
|
+
className: itemClassName,
|
|
8041
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MegaMenuItemContent, { item })
|
|
8042
|
+
}, item.label);
|
|
8043
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
8044
|
+
"aria-disabled": "true",
|
|
8045
|
+
className: require_text_truncate.cn(itemClassName, "cursor-not-allowed opacity-60"),
|
|
8046
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(MegaMenuItemContent, { item })
|
|
8047
|
+
}, item.label);
|
|
7095
8048
|
})]
|
|
7096
|
-
},
|
|
7097
|
-
},
|
|
7098
|
-
|
|
7099
|
-
|
|
7100
|
-
|
|
7101
|
-
})
|
|
8049
|
+
}, section.title))
|
|
8050
|
+
}), footer && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
8051
|
+
className: "border-border bg-bg-subtle border-t px-4 py-3",
|
|
8052
|
+
children: footer
|
|
8053
|
+
})]
|
|
8054
|
+
})
|
|
7102
8055
|
})]
|
|
7103
8056
|
});
|
|
7104
8057
|
}
|
|
@@ -8296,67 +9249,6 @@ const enStarRatingLabels = {
|
|
|
8296
9249
|
};
|
|
8297
9250
|
const enBreadcrumbLabels = { navAriaLabel: "Go to {label}" };
|
|
8298
9251
|
//#endregion
|
|
8299
|
-
//#region src/lib/query/query-match.ts
|
|
8300
|
-
function toText(value) {
|
|
8301
|
-
if (value === null || value === void 0) return "";
|
|
8302
|
-
if (typeof value === "string") return value;
|
|
8303
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
8304
|
-
return JSON.stringify(value);
|
|
8305
|
-
}
|
|
8306
|
-
function compare(left, right) {
|
|
8307
|
-
const leftNumber = typeof left === "number" ? left : Number(toText(left));
|
|
8308
|
-
const rightNumber = Number(right);
|
|
8309
|
-
if (Number.isFinite(leftNumber) && Number.isFinite(rightNumber)) return leftNumber - rightNumber;
|
|
8310
|
-
return toText(left).localeCompare(right);
|
|
8311
|
-
}
|
|
8312
|
-
function matchesClause(clause, read, searchable) {
|
|
8313
|
-
if (clause.type === "term") return searchable().toLowerCase().includes(clause.value.toLowerCase());
|
|
8314
|
-
const value = read(clause.field);
|
|
8315
|
-
switch (clause.operator) {
|
|
8316
|
-
case "exists": return value !== void 0 && value !== null && value !== "";
|
|
8317
|
-
case "eq": return clause.values.some((candidate) => toText(value).toLowerCase() === candidate.toLowerCase());
|
|
8318
|
-
case "contains": return clause.values.some((candidate) => toText(value).toLowerCase().includes(candidate.toLowerCase()));
|
|
8319
|
-
case "gt":
|
|
8320
|
-
var _clause$values$;
|
|
8321
|
-
return compare(value, (_clause$values$ = clause.values[0]) !== null && _clause$values$ !== void 0 ? _clause$values$ : "") > 0;
|
|
8322
|
-
case "gte":
|
|
8323
|
-
var _clause$values$2;
|
|
8324
|
-
return compare(value, (_clause$values$2 = clause.values[0]) !== null && _clause$values$2 !== void 0 ? _clause$values$2 : "") >= 0;
|
|
8325
|
-
case "lt":
|
|
8326
|
-
var _clause$values$3;
|
|
8327
|
-
return compare(value, (_clause$values$3 = clause.values[0]) !== null && _clause$values$3 !== void 0 ? _clause$values$3 : "") < 0;
|
|
8328
|
-
case "lte":
|
|
8329
|
-
var _clause$values$4;
|
|
8330
|
-
return compare(value, (_clause$values$4 = clause.values[0]) !== null && _clause$values$4 !== void 0 ? _clause$values$4 : "") <= 0;
|
|
8331
|
-
default: return true;
|
|
8332
|
-
}
|
|
8333
|
-
}
|
|
8334
|
-
/**
|
|
8335
|
-
* Whether one row satisfies every clause.
|
|
8336
|
-
*
|
|
8337
|
-
* `searchable` is lazy because most queries are field constraints, and
|
|
8338
|
-
* flattening a row to text for a term match nobody asked for is the expensive
|
|
8339
|
-
* part of filtering a live tail.
|
|
8340
|
-
*/
|
|
8341
|
-
function matchesQuery(query, read, searchable) {
|
|
8342
|
-
return query.clauses.every((clause) => {
|
|
8343
|
-
const matched = matchesClause(clause, read, searchable);
|
|
8344
|
-
return clause.negated ? !matched : matched;
|
|
8345
|
-
});
|
|
8346
|
-
}
|
|
8347
|
-
/** Convenience for plain objects, including one level of nested properties. */
|
|
8348
|
-
function matchesQueryObject(query, row, options = {}) {
|
|
8349
|
-
const nested = options.nested ? row[options.nested] : void 0;
|
|
8350
|
-
const read = (field) => field in row ? row[field] : nested === null || nested === void 0 ? void 0 : nested[field];
|
|
8351
|
-
let cached = null;
|
|
8352
|
-
const searchable = () => {
|
|
8353
|
-
var _cached;
|
|
8354
|
-
(_cached = cached) !== null && _cached !== void 0 || (cached = [...Object.values(row).filter((value) => typeof value !== "object"), ...Object.values(nested !== null && nested !== void 0 ? nested : {})].map(toText).join(" "));
|
|
8355
|
-
return cached;
|
|
8356
|
-
};
|
|
8357
|
-
return matchesQuery(query, read, searchable);
|
|
8358
|
-
}
|
|
8359
|
-
//#endregion
|
|
8360
9252
|
exports.ALL_COMPOUND_THEMES = ALL_COMPOUND_THEMES;
|
|
8361
9253
|
exports.AccordionContent = require_key_pad_menu.AccordionContent;
|
|
8362
9254
|
exports.AccordionItem = require_key_pad_menu.AccordionItem;
|
|
@@ -8381,12 +9273,16 @@ exports.Breadcrumb = require_key_pad_menu.Breadcrumb;
|
|
|
8381
9273
|
exports.BulkActions = BulkActions;
|
|
8382
9274
|
exports.Button = require_text_truncate.Button;
|
|
8383
9275
|
exports.COLOR_PRESETS = COLOR_PRESETS;
|
|
9276
|
+
exports.Callout = Callout;
|
|
8384
9277
|
exports.Card = require_key_pad_menu.Card;
|
|
8385
9278
|
exports.CardContent = require_key_pad_menu.CardContent;
|
|
8386
9279
|
exports.CardDescription = require_key_pad_menu.CardDescription;
|
|
8387
9280
|
exports.CardFooter = require_key_pad_menu.CardFooter;
|
|
8388
9281
|
exports.CardHeader = require_key_pad_menu.CardHeader;
|
|
8389
9282
|
exports.CardTitle = require_key_pad_menu.CardTitle;
|
|
9283
|
+
exports.CatalogCellControls = CatalogCellControls;
|
|
9284
|
+
exports.CatalogFrame = CatalogFrame;
|
|
9285
|
+
exports.CatalogRowActions = CatalogRowActions;
|
|
8390
9286
|
exports.ChatInput = ChatInput;
|
|
8391
9287
|
exports.ChatMessageList = ChatMessageList;
|
|
8392
9288
|
exports.ChatSidebar = ChatSidebar;
|
|
@@ -8428,6 +9324,7 @@ exports.ConfirmDialog = ConfirmDialog;
|
|
|
8428
9324
|
exports.ConnectionIndicator = ConnectionIndicator;
|
|
8429
9325
|
exports.Container = require_key_pad_menu.Container;
|
|
8430
9326
|
exports.ContentTabs = require_field_sidebar.ContentTabs;
|
|
9327
|
+
exports.CopyButton = CopyButton;
|
|
8431
9328
|
exports.DEFAULT_PRESETS = require_text_truncate.DEFAULT_PRESETS;
|
|
8432
9329
|
exports.DEFAULT_TIME_PRESETS = require_field_sidebar.DEFAULT_TIME_PRESETS;
|
|
8433
9330
|
exports.DashboardGrid = require_field_sidebar.DashboardGrid;
|
|
@@ -8486,6 +9383,7 @@ exports.FaqAccordion = require_field_sidebar.FaqAccordion;
|
|
|
8486
9383
|
exports.FeatureFlagPanel = FeatureFlagPanel;
|
|
8487
9384
|
exports.FieldSidebar = require_field_sidebar.FieldSidebar;
|
|
8488
9385
|
exports.FieldToken = require_text_truncate.FieldToken;
|
|
9386
|
+
exports.FieldTokenLegend = require_text_truncate.FieldTokenLegend;
|
|
8489
9387
|
exports.FileUploadForm = FileUploadForm;
|
|
8490
9388
|
exports.FilterBar = FilterBar;
|
|
8491
9389
|
exports.FloatingActionBar = FloatingActionBar;
|
|
@@ -8529,6 +9427,7 @@ exports.InlineEdit = require_key_pad_menu.InlineEdit;
|
|
|
8529
9427
|
exports.InlineEditTable = InlineEditTable;
|
|
8530
9428
|
exports.Input = require_text_truncate.Input;
|
|
8531
9429
|
exports.InsightsPanel = InsightsPanel;
|
|
9430
|
+
exports.InspectorLayout = InspectorLayout;
|
|
8532
9431
|
exports.KanbanBoard = KanbanBoard;
|
|
8533
9432
|
exports.Kbd = require_text_truncate.Kbd;
|
|
8534
9433
|
exports.KeyPadMenu = require_key_pad_menu.KeyPadMenu;
|
|
@@ -8576,6 +9475,7 @@ exports.ProjectSwitcher = require_field_sidebar.ProjectSwitcher;
|
|
|
8576
9475
|
exports.PromptTemplate = PromptTemplate;
|
|
8577
9476
|
exports.PropertyExplorer = PropertyExplorer;
|
|
8578
9477
|
exports.QueryBar = require_field_sidebar.QueryBar;
|
|
9478
|
+
exports.QueryFilterBar = QueryFilterBar;
|
|
8579
9479
|
exports.QueryResultsTable = QueryResultsTable;
|
|
8580
9480
|
exports.QuickActions = QuickActions;
|
|
8581
9481
|
exports.Radio = require_key_pad_menu.Radio;
|
|
@@ -8603,6 +9503,7 @@ exports.ScrollArea = require_key_pad_menu.ScrollArea;
|
|
|
8603
9503
|
exports.SearchCombobox = require_field_sidebar.SearchCombobox;
|
|
8604
9504
|
exports.Section = require_key_pad_menu.Section;
|
|
8605
9505
|
exports.SegmentBuilder = SegmentBuilder;
|
|
9506
|
+
exports.SegmentedControl = SegmentedControl;
|
|
8606
9507
|
exports.SelectItem = require_text_truncate.SelectItem;
|
|
8607
9508
|
exports.SelectLabel = require_text_truncate.SelectLabel;
|
|
8608
9509
|
exports.SelectPopover = require_text_truncate.SelectPopover;
|
|
@@ -8624,6 +9525,7 @@ exports.Spinner = require_text_truncate.Spinner;
|
|
|
8624
9525
|
exports.SqlEditor = SqlEditor;
|
|
8625
9526
|
exports.StarRating = require_text_truncate.StarRating;
|
|
8626
9527
|
exports.StatCard = require_text_truncate.StatCard;
|
|
9528
|
+
exports.StatusDot = StatusDot;
|
|
8627
9529
|
exports.StatusSelect = require_field_sidebar.StatusSelect;
|
|
8628
9530
|
exports.StepBuilder = require_key_pad_menu.StepBuilder;
|
|
8629
9531
|
exports.SummaryRow = SummaryRow;
|
|
@@ -8701,6 +9603,7 @@ exports.getShaderFragment = require_key_pad_menu.getShaderFragment;
|
|
|
8701
9603
|
exports.getShaderPreset = require_key_pad_menu.getShaderPreset;
|
|
8702
9604
|
exports.getThemeDescriptor = getThemeDescriptor;
|
|
8703
9605
|
exports.getTrappedContextRole = getTrappedContextRole;
|
|
9606
|
+
exports.hasActiveQuery = hasActiveQuery;
|
|
8704
9607
|
exports.isDescriptorSpec = isDescriptorSpec;
|
|
8705
9608
|
exports.isEmptyQuery = require_field_sidebar.isEmptyQuery;
|
|
8706
9609
|
exports.isForceLightSpec = isForceLightSpec;
|