@wealthx/shadcn 1.5.1 → 1.5.3

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.
Files changed (36) hide show
  1. package/.turbo/turbo-build.log +115 -115
  2. package/CHANGELOG.md +12 -0
  3. package/dist/chunk-G2EWIP2N.mjs +960 -0
  4. package/dist/{chunk-MHHA7QGO.mjs → chunk-ODO6BUOF.mjs} +1 -1
  5. package/dist/chunk-PX4M67XQ.mjs +301 -0
  6. package/dist/{chunk-FYUSF5KO.mjs → chunk-QRVEI6J3.mjs} +1 -1
  7. package/dist/{chunk-42NEC57Y.mjs → chunk-RAKBWNQH.mjs} +272 -3
  8. package/dist/components/ui/{contact-alert-dialog.js → contact-alert-dialog/index.js} +1029 -593
  9. package/dist/components/ui/contact-alert-dialog/index.mjs +31 -0
  10. package/dist/components/ui/file-preview-dialog.js +407 -100
  11. package/dist/components/ui/file-preview-dialog.mjs +3 -1
  12. package/dist/components/ui/kanban-column.js +408 -113
  13. package/dist/components/ui/kanban-column.mjs +3 -2
  14. package/dist/components/ui/opportunity-card.js +383 -88
  15. package/dist/components/ui/opportunity-card.mjs +2 -1
  16. package/dist/components/ui/pipeline-board.js +424 -129
  17. package/dist/components/ui/pipeline-board.mjs +4 -3
  18. package/dist/index.js +3081 -2282
  19. package/dist/index.mjs +39 -35
  20. package/dist/styles.css +1 -1
  21. package/package.json +5 -4
  22. package/src/components/index.tsx +3 -2
  23. package/src/components/ui/contact-alert-dialog/builder-ui.tsx +556 -0
  24. package/src/components/ui/contact-alert-dialog/config.ts +262 -0
  25. package/src/components/ui/contact-alert-dialog/contact-alert-dialog.tsx +214 -0
  26. package/src/components/ui/contact-alert-dialog/index.tsx +15 -0
  27. package/src/components/ui/contact-alert-dialog/types.ts +61 -0
  28. package/src/components/ui/contact-alert-dialog/utils.ts +93 -0
  29. package/src/components/ui/file-preview-dialog.tsx +299 -99
  30. package/src/components/ui/opportunity-card.tsx +328 -1
  31. package/src/styles/styles-css.ts +1 -1
  32. package/tsup.config.ts +1 -1
  33. package/dist/chunk-5WMFKQZ6.mjs +0 -180
  34. package/dist/chunk-Y24TXIFJ.mjs +0 -518
  35. package/dist/components/ui/contact-alert-dialog.mjs +0 -27
  36. package/src/components/ui/contact-alert-dialog.tsx +0 -710
@@ -1,518 +0,0 @@
1
- import {
2
- InputGroup,
3
- InputGroupAddon,
4
- InputGroupInput,
5
- InputGroupText
6
- } from "./chunk-7YI3HEBH.mjs";
7
- import {
8
- Field,
9
- FieldLabel
10
- } from "./chunk-MUV4EGDW.mjs";
11
- import {
12
- Checkbox
13
- } from "./chunk-IKXYTCSB.mjs";
14
- import {
15
- Select,
16
- SelectContent,
17
- SelectItem,
18
- SelectTrigger,
19
- SelectValue
20
- } from "./chunk-TAX3KL66.mjs";
21
- import {
22
- Dialog,
23
- DialogContent,
24
- DialogFooter,
25
- DialogHeader,
26
- DialogTitle
27
- } from "./chunk-NCUH54IZ.mjs";
28
- import {
29
- Label
30
- } from "./chunk-P7CEBZM6.mjs";
31
- import {
32
- ToggleGroup,
33
- ToggleGroupItem
34
- } from "./chunk-OWFQSXVD.mjs";
35
- import {
36
- Input
37
- } from "./chunk-LBTHZSBT.mjs";
38
- import {
39
- Button
40
- } from "./chunk-NOOEKOWY.mjs";
41
- import {
42
- cn
43
- } from "./chunk-AFML43VJ.mjs";
44
- import {
45
- __spreadProps,
46
- __spreadValues
47
- } from "./chunk-WNQUEZJF.mjs";
48
-
49
- // src/components/ui/contact-alert-dialog.tsx
50
- import * as React from "react";
51
- import { PlusIcon, Trash2Icon } from "lucide-react";
52
- import { Fragment as Fragment2, jsx, jsxs } from "react/jsx-runtime";
53
- var ALERT_QUERY_FIELDS = [
54
- {
55
- key: "userMetric.max_loan_amount",
56
- label: "Borrowing Capacity",
57
- type: "number",
58
- unit: "dollar",
59
- operators: [
60
- "equal",
61
- "less",
62
- "less_or_equal",
63
- "greater",
64
- "greater_or_equal",
65
- "between"
66
- ]
67
- },
68
- {
69
- key: "userMetric.debt_outstanding",
70
- label: "Outstanding Debt",
71
- type: "number",
72
- unit: "dollar",
73
- operators: [
74
- "equal",
75
- "less",
76
- "less_or_equal",
77
- "greater",
78
- "greater_or_equal"
79
- ]
80
- },
81
- {
82
- key: "userMetric.lvr",
83
- label: "Current LVR",
84
- type: "number",
85
- unit: "percent",
86
- operators: [
87
- "equal",
88
- "less",
89
- "less_or_equal",
90
- "greater",
91
- "greater_or_equal"
92
- ]
93
- },
94
- {
95
- key: "userMetric.has_met_buying_goal",
96
- label: "Has Met Buying Goal",
97
- type: "boolean"
98
- },
99
- {
100
- key: "userMetric.excess_monthly_surplus",
101
- label: "Excess Monthly Surplus",
102
- type: "number",
103
- unit: "dollar",
104
- operators: [
105
- "equal",
106
- "less",
107
- "less_or_equal",
108
- "greater",
109
- "greater_or_equal"
110
- ]
111
- },
112
- {
113
- key: "userMetric.equity",
114
- label: "Equity Amount",
115
- type: "number",
116
- unit: "dollar",
117
- operators: [
118
- "equal",
119
- "less",
120
- "less_or_equal",
121
- "greater",
122
- "greater_or_equal"
123
- ]
124
- },
125
- {
126
- key: "userMetric.max_debt_interest_rate",
127
- label: "Max Debt Interest Rate",
128
- type: "number",
129
- unit: "percent",
130
- operators: [
131
- "equal",
132
- "less",
133
- "less_or_equal",
134
- "greater",
135
- "greater_or_equal"
136
- ]
137
- },
138
- {
139
- key: "userMetric.min_debt_interest_rate",
140
- label: "Min Debt Interest Rate",
141
- type: "number",
142
- unit: "percent",
143
- operators: [
144
- "equal",
145
- "less",
146
- "less_or_equal",
147
- "greater",
148
- "greater_or_equal"
149
- ]
150
- }
151
- ];
152
- var ALL_NUMERIC_OPERATORS = [
153
- "equal",
154
- "not_equal",
155
- "less",
156
- "less_or_equal",
157
- "greater",
158
- "greater_or_equal",
159
- "between"
160
- ];
161
- var BOOLEAN_OPERATORS = ["equal"];
162
- var OPERATOR_LABELS = {
163
- equal: "=",
164
- not_equal: "\u2260",
165
- less: "<",
166
- less_or_equal: "\u2264",
167
- greater: ">",
168
- greater_or_equal: "\u2265",
169
- between: "between"
170
- };
171
- var SEVERITY_LABELS = {
172
- INSIGHT: "Insight",
173
- WATCH: "Watch",
174
- NEED_ACTION: "Need Action"
175
- };
176
- var EMPTY_RULE = () => ({
177
- id: Math.random().toString(36).slice(2),
178
- field: ALERT_QUERY_FIELDS[0].key,
179
- operator: "greater_or_equal",
180
- value: "",
181
- value2: ""
182
- });
183
- function longestOf(labels) {
184
- return labels.reduce((a, b) => a.length >= b.length ? a : b, "");
185
- }
186
- function allOperatorLabels(fields) {
187
- var _a;
188
- const ops = /* @__PURE__ */ new Set();
189
- for (const f of fields) {
190
- const fieldOps = f.type === "boolean" ? BOOLEAN_OPERATORS : (_a = f.operators) != null ? _a : ALL_NUMERIC_OPERATORS;
191
- fieldOps.forEach((op) => ops.add(op));
192
- }
193
- return [...ops].map((op) => OPERATOR_LABELS[op]);
194
- }
195
- function formatWithCommas(raw) {
196
- if (!raw) return "";
197
- const [int, dec] = raw.split(".");
198
- const formatted = int.replace(/\B(?=(\d{3})+(?!\d))/g, ",");
199
- return dec !== void 0 ? `${formatted}.${dec}` : formatted;
200
- }
201
- function parseCommas(display) {
202
- return display.replace(/[^\d.]/g, "").replace(/(\..*)\./g, "$1");
203
- }
204
- function SelectAutoWidth({
205
- longestLabel,
206
- children
207
- }) {
208
- return /* @__PURE__ */ jsxs("div", { className: "relative inline-block shrink-0", children: [
209
- /* @__PURE__ */ jsx(
210
- "span",
211
- {
212
- "aria-hidden": true,
213
- className: "invisible block h-8 whitespace-nowrap pl-3 pr-10 text-body-medium",
214
- children: longestLabel
215
- }
216
- ),
217
- /* @__PURE__ */ jsx("div", { className: "absolute inset-0", children })
218
- ] });
219
- }
220
- function ValueInput({
221
- value,
222
- onChange,
223
- unit,
224
- placeholder = "0"
225
- }) {
226
- return /* @__PURE__ */ jsxs(InputGroup, { className: "w-36", children: [
227
- unit === "dollar" && /* @__PURE__ */ jsx(InputGroupAddon, { align: "inline-start", children: /* @__PURE__ */ jsx(InputGroupText, { children: "$" }) }),
228
- /* @__PURE__ */ jsx(
229
- InputGroupInput,
230
- {
231
- type: "text",
232
- inputMode: "numeric",
233
- value: formatWithCommas(value),
234
- onChange: (e) => onChange(parseCommas(e.target.value)),
235
- placeholder
236
- }
237
- ),
238
- unit === "percent" && /* @__PURE__ */ jsx(InputGroupAddon, { align: "inline-end", children: /* @__PURE__ */ jsx(InputGroupText, { children: "%" }) })
239
- ] });
240
- }
241
- function QueryRuleRow({
242
- rule,
243
- fields,
244
- longestFieldLabel,
245
- longestOperatorLabel,
246
- onUpdate,
247
- onRemove,
248
- removable
249
- }) {
250
- var _a, _b, _c, _d, _e;
251
- const fieldDef = (_a = fields.find((f) => f.key === rule.field)) != null ? _a : fields[0];
252
- const isBooleanField = fieldDef.type === "boolean";
253
- const availableOperators = isBooleanField ? BOOLEAN_OPERATORS : (_b = fieldDef.operators) != null ? _b : ALL_NUMERIC_OPERATORS;
254
- const update = (patch) => onUpdate(__spreadValues(__spreadValues({}, rule), patch));
255
- function handleFieldChange(key) {
256
- var _a2;
257
- const newField = fields.find((f) => f.key === key);
258
- const newOps = (newField == null ? void 0 : newField.type) === "boolean" ? BOOLEAN_OPERATORS : (_a2 = newField == null ? void 0 : newField.operators) != null ? _a2 : ALL_NUMERIC_OPERATORS;
259
- const validOp = newOps.includes(rule.operator) ? rule.operator : newOps[0];
260
- update({ field: key, operator: validOp, value: "", value2: "" });
261
- }
262
- return /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-1.5 border border-border bg-muted/20 p-2", children: [
263
- /* @__PURE__ */ jsx(SelectAutoWidth, { longestLabel: longestFieldLabel, children: /* @__PURE__ */ jsxs(Select, { value: rule.field, onValueChange: handleFieldChange, children: [
264
- /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-full", children: /* @__PURE__ */ jsx(SelectValue, { children: (_d = (_c = fields.find((f) => f.key === rule.field)) == null ? void 0 : _c.label) != null ? _d : rule.field }) }),
265
- /* @__PURE__ */ jsx(SelectContent, { children: fields.map((f) => /* @__PURE__ */ jsx(SelectItem, { value: f.key, children: f.label }, f.key)) })
266
- ] }) }),
267
- /* @__PURE__ */ jsx(SelectAutoWidth, { longestLabel: longestOperatorLabel, children: /* @__PURE__ */ jsxs(
268
- Select,
269
- {
270
- value: rule.operator,
271
- onValueChange: (v) => update({ operator: v }),
272
- children: [
273
- /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-full", children: /* @__PURE__ */ jsx(SelectValue, { children: OPERATOR_LABELS[rule.operator] }) }),
274
- /* @__PURE__ */ jsx(SelectContent, { children: availableOperators.map((op) => /* @__PURE__ */ jsx(SelectItem, { value: op, children: OPERATOR_LABELS[op] }, op)) })
275
- ]
276
- }
277
- ) }),
278
- isBooleanField ? /* @__PURE__ */ jsxs(
279
- Select,
280
- {
281
- value: rule.value || "true",
282
- onValueChange: (v) => update({ value: v }),
283
- children: [
284
- /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", className: "w-36", children: /* @__PURE__ */ jsx(SelectValue, { children: (rule.value || "true") === "false" ? "No" : "Yes" }) }),
285
- /* @__PURE__ */ jsxs(SelectContent, { children: [
286
- /* @__PURE__ */ jsx(SelectItem, { value: "true", children: "Yes" }),
287
- /* @__PURE__ */ jsx(SelectItem, { value: "false", children: "No" })
288
- ] })
289
- ]
290
- }
291
- ) : /* @__PURE__ */ jsxs(Fragment2, { children: [
292
- /* @__PURE__ */ jsx(
293
- ValueInput,
294
- {
295
- value: rule.value,
296
- onChange: (v) => update({ value: v }),
297
- unit: fieldDef.unit
298
- }
299
- ),
300
- rule.operator === "between" && /* @__PURE__ */ jsxs(Fragment2, { children: [
301
- /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: "and" }),
302
- /* @__PURE__ */ jsx(
303
- ValueInput,
304
- {
305
- value: (_e = rule.value2) != null ? _e : "",
306
- onChange: (v) => update({ value2: v }),
307
- unit: fieldDef.unit
308
- }
309
- )
310
- ] })
311
- ] }),
312
- /* @__PURE__ */ jsx(
313
- Button,
314
- {
315
- type: "button",
316
- variant: "ghost",
317
- size: "sm",
318
- onClick: onRemove,
319
- disabled: !removable,
320
- "aria-label": "Remove rule",
321
- className: "ml-auto",
322
- children: /* @__PURE__ */ jsx(Trash2Icon, {})
323
- }
324
- )
325
- ] });
326
- }
327
- function ContactAlertQueryBuilder({
328
- value,
329
- onChange,
330
- fields,
331
- className
332
- }) {
333
- const longestFieldLabel = React.useMemo(
334
- () => longestOf(fields.map((f) => f.label)),
335
- [fields]
336
- );
337
- const longestOperatorLabel = React.useMemo(
338
- () => longestOf(allOperatorLabels(fields)),
339
- [fields]
340
- );
341
- function updateRule(index, updated) {
342
- onChange(__spreadProps(__spreadValues({}, value), {
343
- rules: value.rules.map((r, i) => i === index ? updated : r)
344
- }));
345
- }
346
- function removeRule(index) {
347
- if (value.rules.length <= 1) return;
348
- const rules = value.rules.filter((_, i) => i !== index);
349
- const opIdx = Math.min(index, value.logicalOps.length - 1);
350
- const logicalOps = value.logicalOps.filter((_, i) => i !== opIdx);
351
- onChange({ rules, logicalOps });
352
- }
353
- function addRule() {
354
- onChange({
355
- rules: [...value.rules, EMPTY_RULE()],
356
- logicalOps: [...value.logicalOps, "AND"]
357
- });
358
- }
359
- function setLogicalOp(index, op) {
360
- onChange(__spreadProps(__spreadValues({}, value), {
361
- logicalOps: value.logicalOps.map((o, i) => i === index ? op : o)
362
- }));
363
- }
364
- return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-1.5", className), children: [
365
- value.rules.map((rule, idx) => {
366
- var _a;
367
- return /* @__PURE__ */ jsxs(React.Fragment, { children: [
368
- /* @__PURE__ */ jsx(
369
- QueryRuleRow,
370
- {
371
- rule,
372
- fields,
373
- longestFieldLabel,
374
- longestOperatorLabel,
375
- onUpdate: (updated) => updateRule(idx, updated),
376
- onRemove: () => removeRule(idx),
377
- removable: value.rules.length > 1
378
- }
379
- ),
380
- idx < value.rules.length - 1 && /* @__PURE__ */ jsx("div", { className: "flex items-center gap-2 pl-1", children: /* @__PURE__ */ jsxs(
381
- ToggleGroup,
382
- {
383
- type: "single",
384
- variant: "outline",
385
- size: "sm",
386
- value: (_a = value.logicalOps[idx]) != null ? _a : "AND",
387
- onValueChange: (v) => v && setLogicalOp(idx, v),
388
- children: [
389
- /* @__PURE__ */ jsx(ToggleGroupItem, { value: "AND", children: "AND" }),
390
- /* @__PURE__ */ jsx(ToggleGroupItem, { value: "OR", children: "OR" })
391
- ]
392
- }
393
- ) })
394
- ] }, rule.id);
395
- }),
396
- /* @__PURE__ */ jsxs(
397
- Button,
398
- {
399
- type: "button",
400
- variant: "ghost",
401
- size: "sm",
402
- onClick: addRule,
403
- className: "w-fit",
404
- children: [
405
- /* @__PURE__ */ jsx(PlusIcon, {}),
406
- "Add rule"
407
- ]
408
- }
409
- )
410
- ] });
411
- }
412
- function ContactAlertDialog({
413
- open,
414
- onOpenChange,
415
- mode = "create",
416
- initialName = "",
417
- initialSeverity = "NEED_ACTION",
418
- initialQuery,
419
- isCompanyAdmin = false,
420
- initialShareAcrossCompany = false,
421
- onSave,
422
- isLoading = false,
423
- className
424
- }) {
425
- const [name, setName] = React.useState(initialName);
426
- const [severity, setSeverity] = React.useState(initialSeverity);
427
- const [query, setQuery] = React.useState(
428
- initialQuery != null ? initialQuery : { rules: [EMPTY_RULE()], logicalOps: [] }
429
- );
430
- const [shareAcrossCompany, setShareAcrossCompany] = React.useState(
431
- initialShareAcrossCompany
432
- );
433
- React.useEffect(() => {
434
- if (open) {
435
- setName(initialName);
436
- setSeverity(initialSeverity);
437
- setQuery(initialQuery != null ? initialQuery : { rules: [EMPTY_RULE()], logicalOps: [] });
438
- setShareAcrossCompany(initialShareAcrossCompany);
439
- }
440
- }, [open]);
441
- const hasValidRule = query.rules.some((r) => {
442
- const fieldDef = ALERT_QUERY_FIELDS.find((f) => f.key === r.field);
443
- return (fieldDef == null ? void 0 : fieldDef.type) === "boolean" || r.value !== "";
444
- });
445
- const canSave = name.trim().length > 0 && hasValidRule && !isLoading;
446
- function handleSave() {
447
- if (!canSave) return;
448
- onSave({ name: name.trim(), severity, query, shareAcrossCompany });
449
- }
450
- return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: isLoading ? void 0 : onOpenChange, children: /* @__PURE__ */ jsxs(DialogContent, { size: "lg", className, children: [
451
- /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: mode === "edit" ? "Update Alert" : "Create Alert" }) }),
452
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
453
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Alert trigger severity" }),
454
- /* @__PURE__ */ jsx(
455
- ToggleGroup,
456
- {
457
- type: "single",
458
- variant: "outline",
459
- size: "sm",
460
- value: severity,
461
- onValueChange: (v) => v && setSeverity(v),
462
- children: ["NEED_ACTION", "WATCH", "INSIGHT"].map((s) => /* @__PURE__ */ jsx(ToggleGroupItem, { value: s, children: SEVERITY_LABELS[s] }, s))
463
- }
464
- )
465
- ] }),
466
- /* @__PURE__ */ jsxs(Field, { children: [
467
- /* @__PURE__ */ jsx(FieldLabel, { children: "Alert name" }),
468
- /* @__PURE__ */ jsx(
469
- Input,
470
- {
471
- value: name,
472
- onChange: (e) => setName(e.target.value),
473
- placeholder: "e.g. High equity opportunity"
474
- }
475
- )
476
- ] }),
477
- isCompanyAdmin && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
478
- /* @__PURE__ */ jsx(
479
- Checkbox,
480
- {
481
- id: "alert-share",
482
- checked: shareAcrossCompany,
483
- onCheckedChange: (v) => setShareAcrossCompany(!!v)
484
- }
485
- ),
486
- /* @__PURE__ */ jsx(Label, { htmlFor: "alert-share", className: "cursor-pointer font-normal", children: "Share across company" })
487
- ] }),
488
- /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1.5", children: [
489
- /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-foreground", children: "Filter conditions" }),
490
- /* @__PURE__ */ jsx(
491
- ContactAlertQueryBuilder,
492
- {
493
- value: query,
494
- onChange: setQuery,
495
- fields: ALERT_QUERY_FIELDS
496
- }
497
- )
498
- ] }),
499
- /* @__PURE__ */ jsxs(DialogFooter, { children: [
500
- /* @__PURE__ */ jsx(
501
- Button,
502
- {
503
- variant: "outline",
504
- onClick: () => onOpenChange(false),
505
- disabled: isLoading,
506
- children: "Cancel"
507
- }
508
- ),
509
- /* @__PURE__ */ jsx(Button, { disabled: !canSave, onClick: handleSave, children: mode === "edit" ? "Update Alert" : "Create Alert" })
510
- ] })
511
- ] }) });
512
- }
513
-
514
- export {
515
- ALERT_QUERY_FIELDS,
516
- ContactAlertQueryBuilder,
517
- ContactAlertDialog
518
- };
@@ -1,27 +0,0 @@
1
- import {
2
- ALERT_QUERY_FIELDS,
3
- ContactAlertDialog,
4
- ContactAlertQueryBuilder
5
- } from "../../chunk-Y24TXIFJ.mjs";
6
- import "../../chunk-7YI3HEBH.mjs";
7
- import "../../chunk-MUV4EGDW.mjs";
8
- import "../../chunk-IKXYTCSB.mjs";
9
- import "../../chunk-TAX3KL66.mjs";
10
- import "../../chunk-2GIYVERS.mjs";
11
- import "../../chunk-BS75ICOO.mjs";
12
- import "../../chunk-NCUH54IZ.mjs";
13
- import "../../chunk-P7CEBZM6.mjs";
14
- import "../../chunk-OWFQSXVD.mjs";
15
- import "../../chunk-6QAFGZC2.mjs";
16
- import "../../chunk-LBTHZSBT.mjs";
17
- import "../../chunk-WDTXHLYM.mjs";
18
- import "../../chunk-S4CTM3UE.mjs";
19
- import "../../chunk-NOOEKOWY.mjs";
20
- import "../../chunk-R4HCRDU5.mjs";
21
- import "../../chunk-AFML43VJ.mjs";
22
- import "../../chunk-WNQUEZJF.mjs";
23
- export {
24
- ALERT_QUERY_FIELDS,
25
- ContactAlertDialog,
26
- ContactAlertQueryBuilder
27
- };