@nivaro/react 0.3.41 → 0.3.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/LayoutForm.js +100 -98
- package/dist/full.css +1 -1
- package/dist/hooks/useSessionRecorder.js +1 -1
- package/dist/index.d.ts +644 -15
- package/dist/index.js +814 -775
- package/dist/shared/components/ActivityEntry.js +154 -0
- package/dist/shared/components/AudienceConfirmPanel.js +98 -0
- package/dist/shared/components/BackgroundRunOffer.js +43 -31
- package/dist/shared/components/BroadcastView.js +225 -204
- package/dist/shared/components/CollectionBrowserView.js +3924 -3584
- package/dist/shared/components/ConfigHistory.js +153 -0
- package/dist/shared/components/ConfigReadBack.js +65 -0
- package/dist/shared/components/DataTable.js +379 -346
- package/dist/shared/components/ForceReloadBanner.js +47 -40
- package/dist/shared/components/IdleReloadWatcher.js +69 -0
- package/dist/shared/components/ItemEditForm.js +4041 -3853
- package/dist/shared/components/MyWorkView.js +278 -213
- package/dist/shared/components/NotificationBell.js +130 -121
- package/dist/shared/components/ProfileView.js +776 -1003
- package/dist/shared/components/RecentRecordsRail.js +34 -16
- package/dist/shared/components/RecordReadView.js +500 -477
- package/dist/shared/components/Skeletons.js +199 -0
- package/dist/shared/components/SlowNotice.js +63 -0
- package/dist/shared/components/Term.js +23 -0
- package/dist/shared/components/WidgetSlot.js +350 -353
- package/dist/shared/components/access/PermissionSummary.js +106 -0
- package/dist/shared/components/bulk/BulkActionButtons.js +76 -73
- package/dist/shared/components/chat/ChatPanel.js +902 -886
- package/dist/shared/components/chat/MemberPaging.js +70 -0
- package/dist/shared/components/chat/RoomParts.js +147 -117
- package/dist/shared/components/chat/ScreenClip.js +73 -69
- package/dist/shared/components/chat/chat-core.js +449 -396
- package/dist/shared/components/chat/huddle/huddle-store.js +48 -43
- package/dist/shared/components/help-videos/api.js +2 -5
- package/dist/shared/components/help-videos/viewer/HelpVideoMatchChip.js +79 -0
- package/dist/shared/components/help-videos/viewer/matchChip.js +50 -0
- package/dist/shared/components/imports/CollectionImportPanel.js +139 -133
- package/dist/shared/components/imports/RunDetailSheet.js +222 -227
- package/dist/shared/components/integrations/console/ErrorExplanation.js +121 -0
- package/dist/shared/components/integrations/console/PartnerDetail.js +175 -174
- package/dist/shared/components/integrations/console/SubmissionRow.js +36 -34
- package/dist/shared/components/integrations/console/drill/SubmissionDrill.js +50 -48
- package/dist/shared/components/item-edit/FieldComments.js +212 -0
- package/dist/shared/components/item-edit/FieldRow.js +340 -336
- package/dist/shared/components/item-edit/RecordHeaderActions.js +23 -22
- package/dist/shared/components/item-edit/RelationCombobox.js +231 -222
- package/dist/shared/components/item-edit/RuleHiddenNotes.js +55 -0
- package/dist/shared/components/item-edit/field-comments-context.js +6 -0
- package/dist/shared/components/item-edit/field-sources.js +33 -0
- package/dist/shared/components/item-edit/rule-hidden.js +30 -0
- package/dist/shared/components/layout-editor/HistoryPanel.js +113 -96
- package/dist/shared/components/layout-editor/editors/cascade-filters.js +170 -145
- package/dist/shared/components/layout-editor/inspector/Breadcrumb.js +22 -18
- package/dist/shared/components/layout-editor/inspector/GroupInspector.js +177 -159
- package/dist/shared/components/layout-editor/inspector/PickerTab.js +35 -34
- package/dist/shared/components/layout-editor/inspector/RulesTab.js +124 -111
- package/dist/shared/components/layout-editor/inspector/kit.js +292 -277
- package/dist/shared/components/layout-editor/parity-keys.json.js +1 -1
- package/dist/shared/components/list/CopyListLinkButton.js +41 -0
- package/dist/shared/components/list/InlineEdit.js +363 -0
- package/dist/shared/components/notifications/NotificationCenterView.js +213 -181
- package/dist/shared/components/notifications/NotificationDetailBits.js +205 -82
- package/dist/shared/components/notifications/NotificationRulesEditor.js +515 -0
- package/dist/shared/components/notifications/TestMyRules.js +137 -0
- package/dist/shared/components/notifications/changes-lines.js +24 -0
- package/dist/shared/components/notifications/why-lines.js +64 -0
- package/dist/shared/components/panels/CommentPanel.js +316 -281
- package/dist/shared/components/panels/LegalHoldBanner.js +38 -0
- package/dist/shared/components/panels/PipelinePanel.js +201 -196
- package/dist/shared/components/panels/RevisionsPanel.js +496 -479
- package/dist/shared/components/pipeline/PipelineEditorView.js +1587 -1560
- package/dist/shared/components/pipeline/PipelineStateOwners.js +116 -103
- package/dist/shared/components/profile/PersonDidPanel.js +188 -0
- package/dist/shared/components/profile/PersonProfile.js +57 -52
- package/dist/shared/components/queue/QueueWorklist.js +1526 -1365
- package/dist/shared/hooks/useSlowReason.js +39 -0
- package/dist/shared/lib/activity-sentence.js +670 -0
- package/dist/shared/lib/config-sentences.js +418 -0
- package/dist/shared/lib/core-glossary.js +229 -0
- package/dist/shared/lib/error-hints.js +159 -0
- package/dist/shared/lib/error-message.js +105 -0
- package/dist/shared/lib/error-toast.js +22 -0
- package/dist/shared/lib/field-comments.js +25 -0
- package/dist/shared/lib/filter-sentence.js +261 -0
- package/dist/shared/lib/glossary.js +55 -48
- package/dist/shared/lib/idle-reload.js +138 -0
- package/dist/shared/lib/layout-resolve.js +42 -29
- package/dist/shared/lib/list-inline-edit.js +190 -0
- package/dist/shared/lib/list-link.js +147 -0
- package/dist/shared/lib/prefetch.js +259 -106
- package/dist/shared/lib/record-ref.js +72 -0
- package/dist/shared/lib/reload-holds.js +25 -0
- package/dist/shared/lib/safe-error.js +52 -24
- package/dist/shared/lib/skeleton-shapes.js +72 -0
- package/dist/shared/lib/slow-reason.js +63 -0
- package/package.json +1 -1
|
@@ -1,129 +1,139 @@
|
|
|
1
|
-
import { jsxs as a, jsx as t, Fragment as
|
|
2
|
-
import { useQueryClient as
|
|
3
|
-
import { useState as
|
|
4
|
-
import { createPortal as
|
|
5
|
-
import { useNivaroClient as
|
|
6
|
-
import { get as v, post as j, patch as
|
|
7
|
-
import { useLiveOps as
|
|
1
|
+
import { jsxs as a, jsx as t, Fragment as ce } from "react/jsx-runtime";
|
|
2
|
+
import { useQueryClient as me, useQuery as k, useMutation as $ } from "@tanstack/react-query";
|
|
3
|
+
import { useState as u, useMemo as Y, useEffect as Ae } from "react";
|
|
4
|
+
import { createPortal as Te } from "react-dom";
|
|
5
|
+
import { useNivaroClient as I } from "../context.js";
|
|
6
|
+
import { get as v, post as j, patch as Le, del as je } from "../lib/commands.js";
|
|
7
|
+
import { useLiveOps as Fe } from "../lib/live-ops.js";
|
|
8
8
|
import { useLiveRefetchInterval as Ke } from "../lib/live-queries.js";
|
|
9
9
|
import { cn as y } from "../lib/utils.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
|
|
10
|
+
import { audienceConfirmFromError as Pe, AudienceConfirmPanel as Ee } from "./AudienceConfirmPanel.js";
|
|
11
|
+
import { BroadcastDraftPanel as De } from "./BroadcastDraft.js";
|
|
12
|
+
import { useHelpVideoLibrary as Oe } from "./help-videos/api.js";
|
|
13
|
+
import { formatDuration as Ie } from "./help-videos/viewer/format.js";
|
|
14
|
+
import { PickList as Qe } from "./imports/ServiceConfigBuilder.js";
|
|
15
|
+
const ue = {
|
|
15
16
|
info: "bg-sky-500",
|
|
16
17
|
warn: "bg-amber-500",
|
|
17
18
|
critical: "bg-red-500"
|
|
18
19
|
};
|
|
19
|
-
function
|
|
20
|
-
var
|
|
21
|
-
const
|
|
20
|
+
function st({ className: r }) {
|
|
21
|
+
var ie;
|
|
22
|
+
const i = I(), c = me(), [b, h] = u(""), [s, p] = u(""), [o, n] = u("info"), [m, x] = u(!1), [d, N] = u(!1), [g, xe] = u(!0), [Q, he] = u(!1), [_, be] = u("banner"), [R, ge] = u(!1), [Z, fe] = u(""), [M, H] = u(""), [J, ye] = u(""), [F, V] = u([]), [A, ke] = u([]), [W, q] = u(null), [T, X] = u(""), [ee, te] = u(""), L = Oe({ status: "published" }), ae = () => {
|
|
22
23
|
if (!T) return {};
|
|
23
|
-
const e = Number(
|
|
24
|
+
const e = Number(ee);
|
|
24
25
|
return {
|
|
25
26
|
help_video_id: T,
|
|
26
27
|
help_video_t_ms: Number.isFinite(e) && e > 0 ? Math.round(e * 1e3) : null
|
|
27
28
|
};
|
|
28
|
-
}, { data:
|
|
29
|
+
}, { data: U } = k({
|
|
29
30
|
queryKey: ["broadcast-config"],
|
|
30
|
-
queryFn: () =>
|
|
31
|
+
queryFn: () => i.request(v("/announcements/config")).then((e) => e.data).catch(() => ({ sms_enabled: !1 })),
|
|
31
32
|
staleTime: 5 * 6e4
|
|
32
|
-
}), { data:
|
|
33
|
+
}), { data: ve = [] } = k({
|
|
33
34
|
queryKey: ["broadcast-dimensions"],
|
|
34
|
-
queryFn: () =>
|
|
35
|
+
queryFn: () => i.request(v("/scope-dimensions")).then((e) => e.data ?? []).catch(() => []),
|
|
35
36
|
staleTime: 5 * 6e4
|
|
36
|
-
}), { data:
|
|
37
|
+
}), { data: Ne = [] } = k({
|
|
37
38
|
queryKey: ["broadcast-roles"],
|
|
38
|
-
queryFn: () =>
|
|
39
|
+
queryFn: () => i.request(v("/chat/roles")).then((e) => e.data ?? []).catch(() => []),
|
|
39
40
|
staleTime: 5 * 6e4
|
|
40
|
-
}), { data:
|
|
41
|
+
}), { data: re = [] } = k({
|
|
41
42
|
queryKey: ["broadcasts"],
|
|
42
|
-
queryFn: () =>
|
|
43
|
+
queryFn: () => i.request(v("/announcements")).then((e) => e.data ?? [])
|
|
43
44
|
});
|
|
44
|
-
|
|
45
|
+
Fe("broadcasts", () => {
|
|
45
46
|
c.invalidateQueries({ queryKey: ["broadcasts"] }), c.invalidateQueries({ queryKey: ["broadcast-receipt-summary"] }), c.invalidateQueries({ queryKey: ["broadcast-receipts"] });
|
|
46
47
|
});
|
|
47
|
-
const w =
|
|
48
|
+
const w = Y(() => {
|
|
48
49
|
const e = [];
|
|
49
|
-
return g && e.push(_), m && e.push("email"), d && e.push("sms"),
|
|
50
|
-
}, [g, _, m, d,
|
|
51
|
-
() =>
|
|
52
|
-
const
|
|
53
|
-
for (const [f, S] of Object.entries(e)) f && S.length > 0 && (
|
|
54
|
-
return
|
|
50
|
+
return g && e.push(_), m && e.push("email"), d && e.push("sms"), Q && e.push("login"), e;
|
|
51
|
+
}, [g, _, m, d, Q]), K = Y(
|
|
52
|
+
() => F.map((e) => {
|
|
53
|
+
const l = {};
|
|
54
|
+
for (const [f, S] of Object.entries(e)) f && S.length > 0 && (l[f] = S);
|
|
55
|
+
return l;
|
|
55
56
|
}).filter((e) => Object.keys(e).length > 0),
|
|
56
|
-
[
|
|
57
|
-
),
|
|
57
|
+
[F]
|
|
58
|
+
), P = Y(
|
|
58
59
|
() => ({
|
|
59
|
-
...
|
|
60
|
-
|
|
60
|
+
...K.length > 0 ? { groups: K } : {},
|
|
61
|
+
...A.length > 0 ? { roles: A } : {}
|
|
61
62
|
}),
|
|
62
|
-
[
|
|
63
|
-
),
|
|
64
|
-
mutationFn: () =>
|
|
63
|
+
[K, A]
|
|
64
|
+
), [ne, E] = u(null), C = $({
|
|
65
|
+
mutationFn: (e) => i.request(
|
|
65
66
|
j("/announcements", {
|
|
67
|
+
...e != null && e.confirm ? { confirm_audience: !0 } : {},
|
|
66
68
|
subject: b.trim() || void 0,
|
|
67
69
|
message: s.trim(),
|
|
68
|
-
severity:
|
|
70
|
+
severity: o,
|
|
69
71
|
channels: w,
|
|
70
|
-
starts_at:
|
|
71
|
-
scheduled_send_at:
|
|
72
|
-
ends_at:
|
|
73
|
-
require_ack: g && _ === "banner" ?
|
|
74
|
-
audience:
|
|
75
|
-
...
|
|
72
|
+
starts_at: Z || void 0,
|
|
73
|
+
scheduled_send_at: M || void 0,
|
|
74
|
+
ends_at: J || void 0,
|
|
75
|
+
require_ack: g && _ === "banner" ? R : !1,
|
|
76
|
+
audience: P,
|
|
77
|
+
...ae()
|
|
76
78
|
})
|
|
77
79
|
),
|
|
78
80
|
onSuccess: (e) => {
|
|
79
|
-
|
|
81
|
+
E(null);
|
|
82
|
+
const l = e.data.scheduled_for;
|
|
80
83
|
q(
|
|
81
|
-
|
|
82
|
-
),
|
|
84
|
+
l ? `Scheduled — delivers ${new Date(l).toLocaleString()}. Cancel from the history below.` : w.some((f) => f !== "banner") ? `Sent — reached ${e.data.delivered} recipient(s).` : "Banner published."
|
|
85
|
+
), p(""), h(""), H(""), X(""), te(""), c.invalidateQueries({ queryKey: ["broadcasts"] }), c.invalidateQueries({ queryKey: ["announcements-active"] });
|
|
83
86
|
},
|
|
84
|
-
onError: (e) =>
|
|
85
|
-
|
|
87
|
+
onError: (e) => {
|
|
88
|
+
const l = Pe(e);
|
|
89
|
+
if (l) {
|
|
90
|
+
E(l);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
q(e.message);
|
|
94
|
+
}
|
|
95
|
+
}), D = s.trim().length > 0 && w.length > 0 && !C.isPending, { data: se = [] } = k({
|
|
86
96
|
queryKey: ["broadcast-templates"],
|
|
87
|
-
queryFn: () =>
|
|
97
|
+
queryFn: () => i.request(v("/announcements/templates")).then((e) => e.data ?? []).catch(() => []),
|
|
88
98
|
staleTime: 6e4
|
|
89
|
-
}),
|
|
90
|
-
mutationFn: (e) =>
|
|
99
|
+
}), de = $({
|
|
100
|
+
mutationFn: (e) => i.request(
|
|
91
101
|
j("/announcements/templates", {
|
|
92
102
|
name: e,
|
|
93
103
|
snapshot: {
|
|
94
104
|
subject: b,
|
|
95
105
|
message: s,
|
|
96
|
-
severity:
|
|
106
|
+
severity: o,
|
|
97
107
|
channels: w,
|
|
98
|
-
require_ack:
|
|
99
|
-
audience:
|
|
108
|
+
require_ack: R,
|
|
109
|
+
audience: P
|
|
100
110
|
}
|
|
101
111
|
})
|
|
102
112
|
),
|
|
103
113
|
onSuccess: () => void c.invalidateQueries({ queryKey: ["broadcast-templates"] })
|
|
104
|
-
}),
|
|
105
|
-
const
|
|
106
|
-
typeof
|
|
107
|
-
}, [
|
|
108
|
-
mutationFn: () =>
|
|
114
|
+
}), we = (e) => {
|
|
115
|
+
const l = e.snapshot ?? {};
|
|
116
|
+
typeof l.subject == "string" && h(l.subject), typeof l.message == "string" && p(l.message);
|
|
117
|
+
}, [B, le] = u(""), [Se, oe] = u(!1), G = $({
|
|
118
|
+
mutationFn: () => i.request(
|
|
109
119
|
j("/announcements/test-send", {
|
|
110
120
|
subject: b.trim() || void 0,
|
|
111
121
|
message: s.trim(),
|
|
112
122
|
channels: w.filter((e) => e !== "banner"),
|
|
113
|
-
...
|
|
123
|
+
...ae()
|
|
114
124
|
})
|
|
115
125
|
),
|
|
116
126
|
onSuccess: (e) => q(
|
|
117
|
-
`Test sent to you — ${Object.entries(e.data ?? {}).map(([
|
|
127
|
+
`Test sent to you — ${Object.entries(e.data ?? {}).map(([l, f]) => `${l}: ${f}`).join(", ")}`
|
|
118
128
|
),
|
|
119
129
|
onError: (e) => q(e.message)
|
|
120
|
-
}),
|
|
121
|
-
mutationFn: ({ id: e, body:
|
|
130
|
+
}), O = (/* @__PURE__ */ new Date()).getHours(), _e = !M && (O >= 21 || O < 7), qe = $({
|
|
131
|
+
mutationFn: ({ id: e, body: l }) => i.request(Le(`/announcements/${e}`, l)),
|
|
122
132
|
onSuccess: () => {
|
|
123
133
|
c.invalidateQueries({ queryKey: ["broadcasts"] }), c.invalidateQueries({ queryKey: ["announcements-active"] });
|
|
124
134
|
}
|
|
125
|
-
}),
|
|
126
|
-
mutationFn: (e) =>
|
|
135
|
+
}), Ce = $({
|
|
136
|
+
mutationFn: (e) => i.request(je(`/announcements/${e}`)),
|
|
127
137
|
onSuccess: () => {
|
|
128
138
|
c.invalidateQueries({ queryKey: ["broadcasts"] }), c.invalidateQueries({ queryKey: ["announcements-active"] });
|
|
129
139
|
}
|
|
@@ -133,43 +143,43 @@ function et({ className: r }) {
|
|
|
133
143
|
/* @__PURE__ */ t("p", { className: "text-[13px] font-semibold text-slate-800 dark:text-foreground", children: "Audience" }),
|
|
134
144
|
/* @__PURE__ */ t("p", { className: "mt-0.5 text-[11.5px] text-slate-400", children: "No selection = everyone. Zone/role targeting narrows both send channels and who sees a banner." }),
|
|
135
145
|
/* @__PURE__ */ a("div", { className: "mt-3 space-y-2", children: [
|
|
136
|
-
|
|
137
|
-
|
|
146
|
+
F.map((e, l) => /* @__PURE__ */ t(
|
|
147
|
+
Me,
|
|
138
148
|
{
|
|
139
|
-
index:
|
|
149
|
+
index: l,
|
|
140
150
|
group: e,
|
|
141
|
-
dimensions:
|
|
142
|
-
onChange: (f) =>
|
|
143
|
-
onRemove: () =>
|
|
151
|
+
dimensions: ve,
|
|
152
|
+
onChange: (f) => V((S) => S.map((z, $e) => $e === l ? f : z)),
|
|
153
|
+
onRemove: () => V((f) => f.filter((S, z) => z !== l))
|
|
144
154
|
},
|
|
145
|
-
|
|
155
|
+
l
|
|
146
156
|
)),
|
|
147
157
|
/* @__PURE__ */ a(
|
|
148
158
|
"button",
|
|
149
159
|
{
|
|
150
160
|
type: "button",
|
|
151
|
-
onClick: () =>
|
|
161
|
+
onClick: () => V((e) => [...e, {}]),
|
|
152
162
|
className: "rounded-md border border-dashed border-slate-300 px-3 py-1.5 text-[11.5px] text-slate-500 hover:border-slate-400 hover:text-slate-700 dark:border-border dark:text-muted-foreground",
|
|
153
163
|
children: [
|
|
154
164
|
"+",
|
|
155
165
|
" ",
|
|
156
|
-
|
|
166
|
+
F.length === 0 ? "Target by scope (e.g. Zone 2 + Node Splits)" : "Add another group (OR)"
|
|
157
167
|
]
|
|
158
168
|
}
|
|
159
169
|
)
|
|
160
170
|
] }),
|
|
161
171
|
/* @__PURE__ */ a("div", { className: "mt-3", children: [
|
|
162
172
|
/* @__PURE__ */ t("p", { className: "mb-1 text-[11.5px] font-medium text-slate-700 dark:text-foreground", children: "Limit to roles" }),
|
|
163
|
-
/* @__PURE__ */ t("div", { className: "flex flex-wrap gap-1.5", children:
|
|
164
|
-
const
|
|
173
|
+
/* @__PURE__ */ t("div", { className: "flex flex-wrap gap-1.5", children: Ne.map((e) => {
|
|
174
|
+
const l = A.includes(e.id);
|
|
165
175
|
return /* @__PURE__ */ t(
|
|
166
176
|
"button",
|
|
167
177
|
{
|
|
168
178
|
type: "button",
|
|
169
|
-
onClick: () =>
|
|
179
|
+
onClick: () => ke((f) => l ? f.filter((S) => S !== e.id) : [...f, e.id]),
|
|
170
180
|
className: y(
|
|
171
181
|
"rounded-full border px-2.5 py-0.5 text-[11.5px] transition-colors",
|
|
172
|
-
|
|
182
|
+
l ? "border-nvr-cyan/50 bg-nvr-cyan/10 text-slate-800 dark:text-foreground" : "border-slate-200 text-slate-500 hover:text-slate-700 dark:border-border dark:text-muted-foreground"
|
|
173
183
|
),
|
|
174
184
|
children: e.name
|
|
175
185
|
},
|
|
@@ -178,10 +188,10 @@ function et({ className: r }) {
|
|
|
178
188
|
}) })
|
|
179
189
|
] }),
|
|
180
190
|
/* @__PURE__ */ t("div", { className: "mt-3 border-t border-slate-100 pt-2.5 dark:border-border", children: /* @__PURE__ */ t(
|
|
181
|
-
|
|
191
|
+
pe,
|
|
182
192
|
{
|
|
183
|
-
audience:
|
|
184
|
-
everyone:
|
|
193
|
+
audience: P,
|
|
194
|
+
everyone: K.length === 0 && A.length === 0,
|
|
185
195
|
label: "Sending to"
|
|
186
196
|
}
|
|
187
197
|
) })
|
|
@@ -189,13 +199,13 @@ function et({ className: r }) {
|
|
|
189
199
|
/* @__PURE__ */ a("div", { className: "max-w-[760px] rounded-lg border border-slate-200 bg-white p-4 dark:border-border dark:bg-card", children: [
|
|
190
200
|
/* @__PURE__ */ t("p", { className: "text-[13px] font-semibold text-slate-800 dark:text-foreground", children: "Message" }),
|
|
191
201
|
/* @__PURE__ */ t(
|
|
192
|
-
|
|
202
|
+
De,
|
|
193
203
|
{
|
|
194
|
-
audience:
|
|
204
|
+
audience: P,
|
|
195
205
|
channels: w,
|
|
196
|
-
severity:
|
|
206
|
+
severity: o,
|
|
197
207
|
onUse: (e) => {
|
|
198
|
-
e.subject !== void 0 && h(e.subject),
|
|
208
|
+
e.subject !== void 0 && h(e.subject), p(e.message);
|
|
199
209
|
}
|
|
200
210
|
}
|
|
201
211
|
),
|
|
@@ -212,7 +222,7 @@ function et({ className: r }) {
|
|
|
212
222
|
"textarea",
|
|
213
223
|
{
|
|
214
224
|
value: s,
|
|
215
|
-
onChange: (e) =>
|
|
225
|
+
onChange: (e) => p(e.target.value),
|
|
216
226
|
rows: 5,
|
|
217
227
|
placeholder: "Compose your message… (plain text; line breaks are kept)",
|
|
218
228
|
className: "mt-2 w-full rounded-md border border-slate-200 bg-background px-2.5 py-2 text-[12.5px] text-slate-800 dark:border-border dark:text-foreground"
|
|
@@ -224,7 +234,7 @@ function et({ className: r }) {
|
|
|
224
234
|
"button",
|
|
225
235
|
{
|
|
226
236
|
type: "button",
|
|
227
|
-
onClick: () =>
|
|
237
|
+
onClick: () => p((l) => l ? `${l} ${e}` : e),
|
|
228
238
|
className: "rounded bg-slate-100 px-1.5 py-0.5 font-mono text-[10.5px] text-slate-600 hover:bg-slate-200 dark:bg-muted dark:text-slate-300 dark:hover:bg-accent",
|
|
229
239
|
title: `Insert ${e} — replaced with each recipient's ${e === "{{name}}" ? "full name" : "first name"} at send time`,
|
|
230
240
|
children: e
|
|
@@ -245,15 +255,15 @@ function et({ className: r }) {
|
|
|
245
255
|
"select",
|
|
246
256
|
{
|
|
247
257
|
value: T,
|
|
248
|
-
onChange: (e) =>
|
|
258
|
+
onChange: (e) => X(e.target.value),
|
|
249
259
|
className: "h-7 max-w-[320px] rounded-md border border-slate-200 bg-background px-1.5 text-[12px] text-slate-800 dark:border-border dark:text-foreground",
|
|
250
260
|
"aria-label": "Attach a video",
|
|
251
261
|
"data-broadcast-video-id": !0,
|
|
252
262
|
children: [
|
|
253
263
|
/* @__PURE__ */ t("option", { value: "", children: "None" }),
|
|
254
|
-
(((
|
|
264
|
+
(((ie = L.data) == null ? void 0 : ie.data) ?? []).map((e) => /* @__PURE__ */ a("option", { value: e.id, children: [
|
|
255
265
|
e.title || "Untitled video",
|
|
256
|
-
e.duration_ms != null ? ` (${
|
|
266
|
+
e.duration_ms != null ? ` (${Ie(e.duration_ms)})` : ""
|
|
257
267
|
] }, e.id))
|
|
258
268
|
]
|
|
259
269
|
}
|
|
@@ -267,8 +277,8 @@ function et({ className: r }) {
|
|
|
267
277
|
type: "number",
|
|
268
278
|
min: 0,
|
|
269
279
|
step: 1,
|
|
270
|
-
value:
|
|
271
|
-
onChange: (e) =>
|
|
280
|
+
value: ee,
|
|
281
|
+
onChange: (e) => te(e.target.value),
|
|
272
282
|
placeholder: "0",
|
|
273
283
|
className: "h-7 w-20 rounded-md border border-slate-200 bg-background px-1.5 text-[12px] dark:border-border",
|
|
274
284
|
"aria-label": "Start at (seconds)",
|
|
@@ -277,14 +287,14 @@ function et({ className: r }) {
|
|
|
277
287
|
),
|
|
278
288
|
"seconds"
|
|
279
289
|
] }),
|
|
280
|
-
|
|
290
|
+
L.hasNextPage && /* @__PURE__ */ t(
|
|
281
291
|
"button",
|
|
282
292
|
{
|
|
283
293
|
type: "button",
|
|
284
|
-
onClick: () => void
|
|
285
|
-
disabled:
|
|
294
|
+
onClick: () => void L.fetchNextPage(),
|
|
295
|
+
disabled: L.isFetchingNextPage,
|
|
286
296
|
className: "rounded border border-slate-200 px-1.5 py-0.5 text-[11px] hover:bg-slate-50 dark:border-border dark:hover:bg-muted",
|
|
287
|
-
children:
|
|
297
|
+
children: L.isFetchingNextPage ? "Loading…" : "More videos"
|
|
288
298
|
}
|
|
289
299
|
),
|
|
290
300
|
T && /* @__PURE__ */ t("span", { className: "text-slate-400 dark:text-slate-500", children: "Shown as a card with a link to that moment — only to people who can watch the video." })
|
|
@@ -298,7 +308,7 @@ function et({ className: r }) {
|
|
|
298
308
|
{
|
|
299
309
|
type: "checkbox",
|
|
300
310
|
checked: g,
|
|
301
|
-
onChange: (e) =>
|
|
311
|
+
onChange: (e) => xe(e.target.checked),
|
|
302
312
|
className: "h-3.5 w-3.5"
|
|
303
313
|
}
|
|
304
314
|
),
|
|
@@ -311,7 +321,7 @@ function et({ className: r }) {
|
|
|
311
321
|
"button",
|
|
312
322
|
{
|
|
313
323
|
type: "button",
|
|
314
|
-
onClick: () =>
|
|
324
|
+
onClick: () => be(e.value),
|
|
315
325
|
className: y(
|
|
316
326
|
"rounded px-2 py-0.5 text-[11px] font-medium transition-colors",
|
|
317
327
|
_ === e.value ? "bg-nvr-cyan/10 text-slate-800 dark:text-foreground" : "text-slate-400 hover:text-slate-600"
|
|
@@ -342,8 +352,8 @@ function et({ className: r }) {
|
|
|
342
352
|
"input",
|
|
343
353
|
{
|
|
344
354
|
type: "checkbox",
|
|
345
|
-
checked:
|
|
346
|
-
onChange: (e) =>
|
|
355
|
+
checked: Q,
|
|
356
|
+
onChange: (e) => he(e.target.checked),
|
|
347
357
|
className: "h-3.5 w-3.5"
|
|
348
358
|
}
|
|
349
359
|
),
|
|
@@ -351,7 +361,7 @@ function et({ className: r }) {
|
|
|
351
361
|
]
|
|
352
362
|
}
|
|
353
363
|
),
|
|
354
|
-
(
|
|
364
|
+
(U == null ? void 0 : U.sms_enabled) && /* @__PURE__ */ a("label", { className: "flex cursor-pointer items-center gap-1.5 text-[12px] text-slate-600 dark:text-muted-foreground", children: [
|
|
355
365
|
/* @__PURE__ */ t(
|
|
356
366
|
"input",
|
|
357
367
|
{
|
|
@@ -363,14 +373,14 @@ function et({ className: r }) {
|
|
|
363
373
|
),
|
|
364
374
|
"Text (SMS)"
|
|
365
375
|
] }),
|
|
366
|
-
g && _ === "banner" && /* @__PURE__ */ a(
|
|
376
|
+
g && _ === "banner" && /* @__PURE__ */ a(ce, { children: [
|
|
367
377
|
/* @__PURE__ */ a("label", { className: "flex cursor-pointer items-center gap-1.5 text-[12px] text-slate-600 dark:text-slate-300", children: [
|
|
368
378
|
/* @__PURE__ */ t(
|
|
369
379
|
"input",
|
|
370
380
|
{
|
|
371
381
|
type: "checkbox",
|
|
372
|
-
checked:
|
|
373
|
-
onChange: (e) =>
|
|
382
|
+
checked: R,
|
|
383
|
+
onChange: (e) => ge(e.target.checked),
|
|
374
384
|
className: "h-3.5 w-3.5"
|
|
375
385
|
}
|
|
376
386
|
),
|
|
@@ -383,10 +393,10 @@ function et({ className: r }) {
|
|
|
383
393
|
onClick: () => n(e),
|
|
384
394
|
className: y(
|
|
385
395
|
"flex items-center gap-1.5 rounded px-2 py-0.5 text-[11px] font-medium capitalize transition-colors",
|
|
386
|
-
|
|
396
|
+
o === e ? "bg-nvr-cyan/10 text-slate-800 dark:text-foreground" : "text-slate-400 hover:text-slate-600"
|
|
387
397
|
),
|
|
388
398
|
children: [
|
|
389
|
-
/* @__PURE__ */ t("span", { className: y("h-1.5 w-1.5 rounded-full",
|
|
399
|
+
/* @__PURE__ */ t("span", { className: y("h-1.5 w-1.5 rounded-full", ue[e]) }),
|
|
390
400
|
e
|
|
391
401
|
]
|
|
392
402
|
},
|
|
@@ -398,8 +408,8 @@ function et({ className: r }) {
|
|
|
398
408
|
"input",
|
|
399
409
|
{
|
|
400
410
|
type: "datetime-local",
|
|
401
|
-
value:
|
|
402
|
-
onChange: (e) =>
|
|
411
|
+
value: Z,
|
|
412
|
+
onChange: (e) => fe(e.target.value),
|
|
403
413
|
className: "h-7 rounded-md border border-slate-200 bg-background px-1.5 text-[12px] dark:border-border"
|
|
404
414
|
}
|
|
405
415
|
)
|
|
@@ -410,8 +420,8 @@ function et({ className: r }) {
|
|
|
410
420
|
"input",
|
|
411
421
|
{
|
|
412
422
|
type: "datetime-local",
|
|
413
|
-
value:
|
|
414
|
-
onChange: (e) =>
|
|
423
|
+
value: J,
|
|
424
|
+
onChange: (e) => ye(e.target.value),
|
|
415
425
|
className: "h-7 rounded-md border border-slate-200 bg-background px-1.5 text-[12px] dark:border-border"
|
|
416
426
|
}
|
|
417
427
|
)
|
|
@@ -426,8 +436,8 @@ function et({ className: r }) {
|
|
|
426
436
|
"input",
|
|
427
437
|
{
|
|
428
438
|
type: "datetime-local",
|
|
429
|
-
value:
|
|
430
|
-
onChange: (e) =>
|
|
439
|
+
value: M,
|
|
440
|
+
onChange: (e) => H(e.target.value),
|
|
431
441
|
title: "Leave empty to send immediately. With a time set, every channel (banner included) waits until then.",
|
|
432
442
|
className: "h-7 rounded-md border border-slate-200 bg-background px-1.5 text-[12px] dark:border-border"
|
|
433
443
|
}
|
|
@@ -437,13 +447,13 @@ function et({ className: r }) {
|
|
|
437
447
|
"button",
|
|
438
448
|
{
|
|
439
449
|
type: "button",
|
|
440
|
-
disabled: !D ||
|
|
450
|
+
disabled: !D || G.isPending,
|
|
441
451
|
onClick: () => {
|
|
442
|
-
q(null),
|
|
452
|
+
q(null), G.mutate();
|
|
443
453
|
},
|
|
444
454
|
"data-tip": "Send this compose to YOURSELF over the picked channels first (#429)",
|
|
445
455
|
className: "h-8 rounded-md border border-slate-200 px-3 text-[12.5px] font-medium text-slate-600 hover:bg-muted disabled:opacity-50 dark:border-border dark:text-slate-300",
|
|
446
|
-
children:
|
|
456
|
+
children: G.isPending ? "Testing…" : "Test on me"
|
|
447
457
|
}
|
|
448
458
|
),
|
|
449
459
|
/* @__PURE__ */ t(
|
|
@@ -452,18 +462,18 @@ function et({ className: r }) {
|
|
|
452
462
|
type: "button",
|
|
453
463
|
disabled: !D,
|
|
454
464
|
onClick: () => {
|
|
455
|
-
q(null),
|
|
465
|
+
q(null), E(null), C.mutate(void 0);
|
|
456
466
|
},
|
|
457
467
|
className: "h-8 rounded-md bg-nvr-cyan px-4 text-[12.5px] font-medium text-white disabled:opacity-50",
|
|
458
|
-
children:
|
|
468
|
+
children: C.isPending ? "Sending…" : "Send"
|
|
459
469
|
}
|
|
460
470
|
),
|
|
461
|
-
|
|
471
|
+
Se ? /* @__PURE__ */ a("span", { className: "flex items-center gap-1", children: [
|
|
462
472
|
/* @__PURE__ */ t(
|
|
463
473
|
"input",
|
|
464
474
|
{
|
|
465
|
-
value:
|
|
466
|
-
onChange: (e) =>
|
|
475
|
+
value: B,
|
|
476
|
+
onChange: (e) => le(e.target.value),
|
|
467
477
|
placeholder: "Template name…",
|
|
468
478
|
className: "h-7 w-40 rounded-md border border-slate-200 bg-background px-1.5 text-[12px] dark:border-border"
|
|
469
479
|
}
|
|
@@ -472,9 +482,9 @@ function et({ className: r }) {
|
|
|
472
482
|
"button",
|
|
473
483
|
{
|
|
474
484
|
type: "button",
|
|
475
|
-
disabled: !
|
|
485
|
+
disabled: !B.trim() || de.isPending,
|
|
476
486
|
onClick: () => {
|
|
477
|
-
|
|
487
|
+
de.mutate(B.trim()), oe(!1), le("");
|
|
478
488
|
},
|
|
479
489
|
className: "h-7 rounded-md border border-slate-200 px-2 text-[11.5px] hover:bg-muted dark:border-border",
|
|
480
490
|
children: "Save"
|
|
@@ -485,18 +495,29 @@ function et({ className: r }) {
|
|
|
485
495
|
{
|
|
486
496
|
type: "button",
|
|
487
497
|
disabled: !s.trim(),
|
|
488
|
-
onClick: () =>
|
|
498
|
+
onClick: () => oe(!0),
|
|
489
499
|
"data-tip": "Save this compose (audience + channels + text) as a reusable template (#104)",
|
|
490
500
|
className: "h-8 rounded-md border border-dashed border-slate-300 px-2.5 text-[11.5px] text-slate-500 hover:text-slate-700 disabled:opacity-40 dark:border-border",
|
|
491
501
|
children: "☆ Save template"
|
|
492
502
|
}
|
|
493
503
|
),
|
|
494
|
-
!D && !
|
|
495
|
-
|
|
504
|
+
!D && !C.isPending && /* @__PURE__ */ t("span", { className: "text-[11.5px] text-slate-400", children: "A message and at least one channel are required." }),
|
|
505
|
+
W && /* @__PURE__ */ t("span", { className: "text-[12px] font-medium text-emerald-600 dark:text-emerald-400", children: W })
|
|
496
506
|
] }),
|
|
497
|
-
|
|
507
|
+
ne && /* @__PURE__ */ t(
|
|
508
|
+
Ee,
|
|
509
|
+
{
|
|
510
|
+
className: "mt-3",
|
|
511
|
+
preview: ne,
|
|
512
|
+
busy: C.isPending,
|
|
513
|
+
confirmLabel: "Confirm and send",
|
|
514
|
+
onConfirm: () => C.mutate({ confirm: !0 }),
|
|
515
|
+
onCancel: () => E(null)
|
|
516
|
+
}
|
|
517
|
+
),
|
|
518
|
+
_e && D && /* @__PURE__ */ a("p", { className: "mt-2 rounded-md bg-amber-50 px-3 py-1.5 text-[12px] text-amber-700 dark:bg-amber-400/10 dark:text-amber-400", children: [
|
|
498
519
|
"It's ",
|
|
499
|
-
|
|
520
|
+
O >= 21 ? "late" : "early",
|
|
500
521
|
" for most recipients — consider the schedule field so this lands in the morning instead of overnight.",
|
|
501
522
|
" ",
|
|
502
523
|
/* @__PURE__ */ t(
|
|
@@ -506,19 +527,19 @@ function et({ className: r }) {
|
|
|
506
527
|
className: "font-medium underline underline-offset-2",
|
|
507
528
|
onClick: () => {
|
|
508
529
|
const e = /* @__PURE__ */ new Date();
|
|
509
|
-
|
|
510
|
-
const
|
|
511
|
-
|
|
512
|
-
`${e.getFullYear()}-${
|
|
530
|
+
O >= 21 && e.setDate(e.getDate() + 1), e.setHours(8, 0, 0, 0);
|
|
531
|
+
const l = (f) => String(f).padStart(2, "0");
|
|
532
|
+
H(
|
|
533
|
+
`${e.getFullYear()}-${l(e.getMonth() + 1)}-${l(e.getDate())}T${l(e.getHours())}:${l(e.getMinutes())}`
|
|
513
534
|
);
|
|
514
535
|
},
|
|
515
536
|
children: "Schedule for 8:00 AM"
|
|
516
537
|
}
|
|
517
538
|
)
|
|
518
539
|
] }),
|
|
519
|
-
|
|
540
|
+
se.length > 0 && /* @__PURE__ */ a("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: [
|
|
520
541
|
/* @__PURE__ */ t("span", { className: "text-[11px] text-slate-400", children: "Templates:" }),
|
|
521
|
-
|
|
542
|
+
se.map((e) => /* @__PURE__ */ t(
|
|
522
543
|
"span",
|
|
523
544
|
{
|
|
524
545
|
className: "inline-flex items-center overflow-hidden rounded-full border border-slate-200 dark:border-border",
|
|
@@ -526,7 +547,7 @@ function et({ className: r }) {
|
|
|
526
547
|
"button",
|
|
527
548
|
{
|
|
528
549
|
type: "button",
|
|
529
|
-
onClick: () =>
|
|
550
|
+
onClick: () => we(e),
|
|
530
551
|
className: "px-2 py-0.5 text-[11.5px] text-slate-600 hover:bg-muted dark:text-slate-300",
|
|
531
552
|
children: e.name
|
|
532
553
|
}
|
|
@@ -538,30 +559,30 @@ function et({ className: r }) {
|
|
|
538
559
|
] }),
|
|
539
560
|
/* @__PURE__ */ a("div", { className: "max-w-[760px] space-y-2", children: [
|
|
540
561
|
/* @__PURE__ */ t("p", { className: "text-[11px] font-semibold uppercase tracking-wide text-slate-500 dark:text-muted-foreground", children: "History" }),
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
562
|
+
re.length === 0 && /* @__PURE__ */ t("p", { className: "text-[12px] text-slate-400", children: "Nothing sent yet." }),
|
|
563
|
+
re.map((e) => /* @__PURE__ */ t(
|
|
564
|
+
Re,
|
|
544
565
|
{
|
|
545
566
|
broadcast: e,
|
|
546
|
-
onPatch:
|
|
547
|
-
onRemove:
|
|
567
|
+
onPatch: qe.mutate,
|
|
568
|
+
onRemove: Ce.mutate
|
|
548
569
|
},
|
|
549
570
|
e.id
|
|
550
571
|
))
|
|
551
572
|
] })
|
|
552
573
|
] });
|
|
553
574
|
}
|
|
554
|
-
function
|
|
575
|
+
function Re({
|
|
555
576
|
broadcast: r,
|
|
556
|
-
onPatch:
|
|
577
|
+
onPatch: i,
|
|
557
578
|
onRemove: c
|
|
558
579
|
}) {
|
|
559
|
-
const b =
|
|
580
|
+
const b = I(), h = me(), [s, p] = u(!1), { data: o } = k({
|
|
560
581
|
queryKey: ["broadcast-receipt-summary", r.id],
|
|
561
582
|
queryFn: () => b.request(v(`/announcements/${r.id}/receipts/summary`)).then((d) => d.data),
|
|
562
583
|
enabled: s,
|
|
563
584
|
staleTime: 5e3
|
|
564
|
-
}), n =
|
|
585
|
+
}), n = $({
|
|
565
586
|
mutationFn: () => b.request(
|
|
566
587
|
j(`/announcements/${r.id}/nudge`, {})
|
|
567
588
|
),
|
|
@@ -579,7 +600,7 @@ function Ee({
|
|
|
579
600
|
});
|
|
580
601
|
return /* @__PURE__ */ a("div", { className: "rounded-lg border border-slate-200 bg-white dark:border-border dark:bg-card", children: [
|
|
581
602
|
/* @__PURE__ */ a("div", { className: "flex items-start gap-3 px-4 py-3", children: [
|
|
582
|
-
/* @__PURE__ */ t("span", { className: y("mt-1.5 h-2 w-2 shrink-0 rounded-full",
|
|
603
|
+
/* @__PURE__ */ t("span", { className: y("mt-1.5 h-2 w-2 shrink-0 rounded-full", ue[r.severity]) }),
|
|
583
604
|
/* @__PURE__ */ a("div", { className: "min-w-0 flex-1", children: [
|
|
584
605
|
r.subject && /* @__PURE__ */ t("p", { className: "text-[12.5px] font-medium text-slate-800 dark:text-foreground", children: r.subject }),
|
|
585
606
|
/* @__PURE__ */ t("p", { className: "text-[12.5px] text-slate-600 dark:text-muted-foreground", children: r.message }),
|
|
@@ -612,7 +633,7 @@ function Ee({
|
|
|
612
633
|
"button",
|
|
613
634
|
{
|
|
614
635
|
type: "button",
|
|
615
|
-
onClick: () =>
|
|
636
|
+
onClick: () => p((d) => !d),
|
|
616
637
|
className: "underline decoration-dotted underline-offset-2 hover:text-slate-600 dark:hover:text-muted-foreground",
|
|
617
638
|
children: [
|
|
618
639
|
s ? "hide receipts" : "who saw this?",
|
|
@@ -630,7 +651,7 @@ function Ee({
|
|
|
630
651
|
"button",
|
|
631
652
|
{
|
|
632
653
|
type: "button",
|
|
633
|
-
onClick: () =>
|
|
654
|
+
onClick: () => i({ id: r.id, body: { is_active: !r.is_active } }),
|
|
634
655
|
className: y(
|
|
635
656
|
"shrink-0 rounded-full border px-2 py-0.5 text-[11px] font-medium",
|
|
636
657
|
r.is_active ? "border-emerald-300 text-emerald-700 dark:border-emerald-500/40 dark:text-emerald-400" : "border-slate-200 text-slate-400 dark:border-border"
|
|
@@ -648,7 +669,7 @@ function Ee({
|
|
|
648
669
|
}
|
|
649
670
|
)
|
|
650
671
|
] }),
|
|
651
|
-
s &&
|
|
672
|
+
s && o && (o.totals.delivered > 0 || o.totals.acked > 0) && /* @__PURE__ */ a(
|
|
652
673
|
"div",
|
|
653
674
|
{
|
|
654
675
|
className: "border-t border-slate-100 px-4 py-3 dark:border-border",
|
|
@@ -658,17 +679,17 @@ function Ee({
|
|
|
658
679
|
/* @__PURE__ */ t("p", { className: "text-[10.5px] font-semibold uppercase tracking-wide text-slate-400", children: "By audience" }),
|
|
659
680
|
/* @__PURE__ */ a("span", { className: "text-[11.5px] text-slate-500 dark:text-muted-foreground", children: [
|
|
660
681
|
"delivered ",
|
|
661
|
-
/* @__PURE__ */ t("b", { children:
|
|
682
|
+
/* @__PURE__ */ t("b", { children: o.totals.delivered }),
|
|
662
683
|
" · opened ",
|
|
663
|
-
/* @__PURE__ */ t("b", { children:
|
|
684
|
+
/* @__PURE__ */ t("b", { children: o.totals.opened }),
|
|
664
685
|
" · acknowledged ",
|
|
665
|
-
/* @__PURE__ */ t("b", { children:
|
|
686
|
+
/* @__PURE__ */ t("b", { children: o.totals.acked }),
|
|
666
687
|
" · still unread",
|
|
667
688
|
" ",
|
|
668
|
-
/* @__PURE__ */ t("b", { children:
|
|
689
|
+
/* @__PURE__ */ t("b", { children: o.totals.unread })
|
|
669
690
|
] }),
|
|
670
691
|
/* @__PURE__ */ t("span", { className: "flex-1" }),
|
|
671
|
-
|
|
692
|
+
o.totals.unread > 0 && /* @__PURE__ */ t(
|
|
672
693
|
"button",
|
|
673
694
|
{
|
|
674
695
|
type: "button",
|
|
@@ -676,11 +697,11 @@ function Ee({
|
|
|
676
697
|
onClick: () => n.mutate(),
|
|
677
698
|
className: "rounded-md border border-amber-300 bg-amber-50 px-2.5 py-1 text-[11.5px] font-medium text-amber-800 hover:bg-amber-100 disabled:opacity-50 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-300",
|
|
678
699
|
"data-nvr-nudge": !0,
|
|
679
|
-
children: n.isPending ? "Nudging…" : n.data ? `Nudged ${n.data.data.nudged}` : `Nudge ${
|
|
700
|
+
children: n.isPending ? "Nudging…" : n.data ? `Nudged ${n.data.data.nudged}` : `Nudge ${o.totals.unread} unread`
|
|
680
701
|
}
|
|
681
702
|
)
|
|
682
703
|
] }),
|
|
683
|
-
/* @__PURE__ */ t("div", { className: "mt-2 grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3", children: [["Role",
|
|
704
|
+
/* @__PURE__ */ t("div", { className: "mt-2 grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3", children: [["Role", o.by_role], ...Object.entries(o.by_dimension)].map(
|
|
684
705
|
([d, N]) => /* @__PURE__ */ a("table", { className: "w-full text-[11.5px] tabular-nums", children: [
|
|
685
706
|
/* @__PURE__ */ t("thead", { children: /* @__PURE__ */ a("tr", { className: "text-left text-[10px] uppercase tracking-wide text-slate-400", children: [
|
|
686
707
|
/* @__PURE__ */ t("th", { className: "py-0.5 font-semibold", children: d }),
|
|
@@ -707,11 +728,11 @@ function Ee({
|
|
|
707
728
|
] }, g.label)) })
|
|
708
729
|
] }, d)
|
|
709
730
|
) }),
|
|
710
|
-
|
|
731
|
+
o.unread_users.length > 0 && /* @__PURE__ */ a("p", { className: "mt-2 text-[11px] text-slate-400", children: [
|
|
711
732
|
"Unread:",
|
|
712
733
|
" ",
|
|
713
|
-
|
|
714
|
-
|
|
734
|
+
o.unread_users.slice(0, 12).map((d) => d.name).join(", "),
|
|
735
|
+
o.unread_users.length > 12 ? ` +${o.unread_users.length - 12} more` : ""
|
|
715
736
|
] })
|
|
716
737
|
]
|
|
717
738
|
}
|
|
@@ -752,14 +773,14 @@ function Ee({
|
|
|
752
773
|
] })
|
|
753
774
|
] });
|
|
754
775
|
}
|
|
755
|
-
function
|
|
776
|
+
function Me({
|
|
756
777
|
index: r,
|
|
757
|
-
group:
|
|
778
|
+
group: i,
|
|
758
779
|
dimensions: c,
|
|
759
780
|
onChange: b,
|
|
760
781
|
onRemove: h
|
|
761
782
|
}) {
|
|
762
|
-
const s = Object.keys(
|
|
783
|
+
const s = Object.keys(i), p = c.filter((n) => !s.includes(n.name)), o = s.length > 0 && s.every((n) => (i[n] ?? []).length > 0);
|
|
763
784
|
return /* @__PURE__ */ a("div", { className: "rounded-lg border border-slate-200 bg-slate-50/60 p-3 dark:border-border dark:bg-muted/30", children: [
|
|
764
785
|
/* @__PURE__ */ a("div", { className: "flex items-center justify-between", children: [
|
|
765
786
|
/* @__PURE__ */ a("p", { className: "text-[10.5px] font-semibold uppercase tracking-wide text-slate-400", children: [
|
|
@@ -768,10 +789,10 @@ function Oe({
|
|
|
768
789
|
s.length > 1 && " · all conditions must match"
|
|
769
790
|
] }),
|
|
770
791
|
/* @__PURE__ */ a("div", { className: "flex items-center gap-2.5", children: [
|
|
771
|
-
|
|
772
|
-
|
|
792
|
+
o && /* @__PURE__ */ t(
|
|
793
|
+
pe,
|
|
773
794
|
{
|
|
774
|
-
audience: { groups: [
|
|
795
|
+
audience: { groups: [i] },
|
|
775
796
|
everyone: !1,
|
|
776
797
|
label: "Matches",
|
|
777
798
|
compact: !0
|
|
@@ -794,45 +815,45 @@ function Oe({
|
|
|
794
815
|
return /* @__PURE__ */ a("div", { className: "flex flex-wrap items-start gap-2", children: [
|
|
795
816
|
/* @__PURE__ */ t("span", { className: "mt-0.5 w-[110px] shrink-0 text-[11.5px] font-medium text-slate-600 dark:text-muted-foreground", children: (m == null ? void 0 : m.label) ?? n }),
|
|
796
817
|
/* @__PURE__ */ t("div", { className: "min-w-0 flex-1", children: m ? /* @__PURE__ */ t(
|
|
797
|
-
|
|
818
|
+
He,
|
|
798
819
|
{
|
|
799
820
|
dim: m,
|
|
800
|
-
selected:
|
|
821
|
+
selected: i[n] ?? [],
|
|
801
822
|
onChange: (x) => {
|
|
802
|
-
const d = { ...
|
|
823
|
+
const d = { ...i };
|
|
803
824
|
x.length === 0 ? delete d[n] : d[n] = x, b(d);
|
|
804
825
|
}
|
|
805
826
|
}
|
|
806
827
|
) : /* @__PURE__ */ t("span", { className: "text-[11.5px] text-slate-400", children: "Unknown scope" }) })
|
|
807
828
|
] }, n);
|
|
808
829
|
}),
|
|
809
|
-
|
|
810
|
-
|
|
830
|
+
p.length > 0 && /* @__PURE__ */ t("div", { className: "w-[200px]", children: /* @__PURE__ */ t(
|
|
831
|
+
Qe,
|
|
811
832
|
{
|
|
812
833
|
value: "",
|
|
813
834
|
onChange: (n) => {
|
|
814
|
-
n && b({ ...
|
|
835
|
+
n && b({ ...i, [n]: [] });
|
|
815
836
|
},
|
|
816
|
-
options:
|
|
837
|
+
options: p.map((n) => ({ value: n.name, label: n.label })),
|
|
817
838
|
placeholder: s.length === 0 ? "Pick a scope…" : "+ And also…"
|
|
818
839
|
}
|
|
819
840
|
) })
|
|
820
841
|
] })
|
|
821
842
|
] });
|
|
822
843
|
}
|
|
823
|
-
function
|
|
844
|
+
function He({
|
|
824
845
|
dim: r,
|
|
825
|
-
selected:
|
|
846
|
+
selected: i,
|
|
826
847
|
onChange: c
|
|
827
848
|
}) {
|
|
828
|
-
const b =
|
|
849
|
+
const b = I(), { data: h = [] } = k({
|
|
829
850
|
queryKey: ["broadcast-dim-options", r.target_collection],
|
|
830
851
|
queryFn: () => b.request(
|
|
831
852
|
v(`/items/${r.target_collection}`, { limit: 200 })
|
|
832
853
|
).then(
|
|
833
|
-
(s) => (s.data ?? []).map((
|
|
834
|
-
id:
|
|
835
|
-
label: String(
|
|
854
|
+
(s) => (s.data ?? []).map((p) => ({
|
|
855
|
+
id: p.id,
|
|
856
|
+
label: String(p[r.display_field || "name"] ?? p.id)
|
|
836
857
|
}))
|
|
837
858
|
),
|
|
838
859
|
staleTime: 5 * 6e4
|
|
@@ -840,17 +861,17 @@ function Ie({
|
|
|
840
861
|
return /* @__PURE__ */ a("div", { className: "flex flex-wrap gap-1.5", children: [
|
|
841
862
|
h.length === 0 && /* @__PURE__ */ t("span", { className: "text-[11.5px] text-slate-400", children: "Loading…" }),
|
|
842
863
|
h.map((s) => {
|
|
843
|
-
const
|
|
864
|
+
const p = i.some((o) => String(o) === String(s.id));
|
|
844
865
|
return /* @__PURE__ */ t(
|
|
845
866
|
"button",
|
|
846
867
|
{
|
|
847
868
|
type: "button",
|
|
848
869
|
onClick: () => c(
|
|
849
|
-
|
|
870
|
+
p ? i.filter((o) => String(o) !== String(s.id)) : [...i, s.id]
|
|
850
871
|
),
|
|
851
872
|
className: y(
|
|
852
873
|
"rounded-full border px-2.5 py-0.5 text-[11.5px] transition-colors",
|
|
853
|
-
|
|
874
|
+
p ? "border-nvr-cyan/50 bg-nvr-cyan/10 text-slate-800 dark:text-foreground" : "border-slate-200 bg-white text-slate-500 hover:text-slate-700 dark:border-border dark:bg-card dark:text-muted-foreground"
|
|
854
875
|
),
|
|
855
876
|
children: s.label
|
|
856
877
|
},
|
|
@@ -859,28 +880,28 @@ function Ie({
|
|
|
859
880
|
})
|
|
860
881
|
] });
|
|
861
882
|
}
|
|
862
|
-
function
|
|
883
|
+
function pe({
|
|
863
884
|
audience: r,
|
|
864
|
-
everyone:
|
|
885
|
+
everyone: i,
|
|
865
886
|
label: c,
|
|
866
887
|
compact: b
|
|
867
888
|
}) {
|
|
868
|
-
const h =
|
|
869
|
-
queryKey: ["broadcast-audience-preview",
|
|
889
|
+
const h = I(), [s, p] = u(!1), o = JSON.stringify(r), { data: n } = k({
|
|
890
|
+
queryKey: ["broadcast-audience-preview", o],
|
|
870
891
|
queryFn: () => h.request(j("/announcements/preview-audience", { audience: r })).then((m) => m.data),
|
|
871
|
-
enabled: !
|
|
892
|
+
enabled: !i,
|
|
872
893
|
staleTime: 3e4
|
|
873
894
|
});
|
|
874
|
-
return
|
|
895
|
+
return i ? /* @__PURE__ */ a("p", { className: "text-[11.5px] text-slate-500 dark:text-muted-foreground", children: [
|
|
875
896
|
c,
|
|
876
897
|
": ",
|
|
877
898
|
/* @__PURE__ */ t("span", { className: "font-medium", children: "Everyone" })
|
|
878
|
-
] }) : /* @__PURE__ */ a(
|
|
899
|
+
] }) : /* @__PURE__ */ a(ce, { children: [
|
|
879
900
|
/* @__PURE__ */ a(
|
|
880
901
|
"button",
|
|
881
902
|
{
|
|
882
903
|
type: "button",
|
|
883
|
-
onClick: () =>
|
|
904
|
+
onClick: () => p(!0),
|
|
884
905
|
className: "text-[11.5px] text-slate-500 underline decoration-dotted underline-offset-2 hover:text-slate-700 dark:text-muted-foreground",
|
|
885
906
|
title: "Click to see who",
|
|
886
907
|
children: [
|
|
@@ -893,35 +914,35 @@ function me({
|
|
|
893
914
|
}
|
|
894
915
|
),
|
|
895
916
|
s && n && /* @__PURE__ */ t(
|
|
896
|
-
|
|
917
|
+
Ve,
|
|
897
918
|
{
|
|
898
919
|
title: c === "Matches" ? "This group matches" : "Sending to",
|
|
899
920
|
count: n.count,
|
|
900
921
|
users: n.users,
|
|
901
922
|
truncated: n.truncated,
|
|
902
|
-
onClose: () =>
|
|
923
|
+
onClose: () => p(!1)
|
|
903
924
|
}
|
|
904
925
|
)
|
|
905
926
|
] });
|
|
906
927
|
}
|
|
907
|
-
function
|
|
928
|
+
function Ve({
|
|
908
929
|
title: r,
|
|
909
|
-
count:
|
|
930
|
+
count: i,
|
|
910
931
|
users: c,
|
|
911
932
|
truncated: b,
|
|
912
933
|
onClose: h
|
|
913
934
|
}) {
|
|
914
|
-
const [s,
|
|
915
|
-
|
|
935
|
+
const [s, p] = u("");
|
|
936
|
+
Ae(() => {
|
|
916
937
|
const m = (x) => {
|
|
917
938
|
x.key === "Escape" && h();
|
|
918
939
|
};
|
|
919
940
|
return window.addEventListener("keydown", m), () => window.removeEventListener("keydown", m);
|
|
920
941
|
}, [h]);
|
|
921
|
-
const
|
|
922
|
-
(m) => m.name.toLowerCase().includes(
|
|
942
|
+
const o = s.trim().toLowerCase(), n = o ? c.filter(
|
|
943
|
+
(m) => m.name.toLowerCase().includes(o) || (m.email ?? "").toLowerCase().includes(o)
|
|
923
944
|
) : c;
|
|
924
|
-
return
|
|
945
|
+
return Te(
|
|
925
946
|
/* @__PURE__ */ a("div", { className: "fixed inset-0 z-[100]", children: [
|
|
926
947
|
/* @__PURE__ */ t("div", { className: "absolute inset-0 bg-black/30", onClick: h }),
|
|
927
948
|
/* @__PURE__ */ a("div", { className: "absolute right-0 top-0 flex h-full w-[380px] max-w-[92vw] flex-col border-l border-slate-200 bg-white shadow-xl dark:border-border dark:bg-card", children: [
|
|
@@ -930,9 +951,9 @@ function Qe({
|
|
|
930
951
|
/* @__PURE__ */ a("p", { className: "text-[13px] font-semibold text-slate-800 dark:text-foreground", children: [
|
|
931
952
|
r,
|
|
932
953
|
/* @__PURE__ */ a("span", { className: "ml-1.5 font-normal text-slate-400", children: [
|
|
933
|
-
|
|
954
|
+
i,
|
|
934
955
|
" user",
|
|
935
|
-
|
|
956
|
+
i === 1 ? "" : "s"
|
|
936
957
|
] })
|
|
937
958
|
] }),
|
|
938
959
|
/* @__PURE__ */ t(
|
|
@@ -950,7 +971,7 @@ function Qe({
|
|
|
950
971
|
{
|
|
951
972
|
autoFocus: !0,
|
|
952
973
|
value: s,
|
|
953
|
-
onChange: (m) =>
|
|
974
|
+
onChange: (m) => p(m.target.value),
|
|
954
975
|
placeholder: "Search name or email…",
|
|
955
976
|
className: "mt-2 h-8 w-full rounded-md border border-slate-200 bg-background px-2.5 text-[12.5px] text-slate-800 dark:border-border dark:text-foreground"
|
|
956
977
|
}
|
|
@@ -973,7 +994,7 @@ function Qe({
|
|
|
973
994
|
"Showing the first ",
|
|
974
995
|
c.length,
|
|
975
996
|
" of ",
|
|
976
|
-
|
|
997
|
+
i,
|
|
977
998
|
"."
|
|
978
999
|
] })
|
|
979
1000
|
] })
|
|
@@ -983,5 +1004,5 @@ function Qe({
|
|
|
983
1004
|
);
|
|
984
1005
|
}
|
|
985
1006
|
export {
|
|
986
|
-
|
|
1007
|
+
st as BroadcastView
|
|
987
1008
|
};
|