@burdenoff/microfe-channel 2026.510.112
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/README.md +147 -0
- package/dist/channel/ChannelRoot.d.ts +32 -0
- package/dist/channel/ChannelRoot.d.ts.map +1 -0
- package/dist/channel/ChannelRoot.js +81 -0
- package/dist/channel/ChannelRoot.js.map +1 -0
- package/dist/channel/ChannelRoutes.d.ts +10 -0
- package/dist/channel/ChannelRoutes.d.ts.map +1 -0
- package/dist/channel/ChannelRoutes.js +104 -0
- package/dist/channel/ChannelRoutes.js.map +1 -0
- package/dist/channel/components/AdapterCredentialsForm.d.ts +20 -0
- package/dist/channel/components/AdapterCredentialsForm.d.ts.map +1 -0
- package/dist/channel/components/AdapterCredentialsForm.js +230 -0
- package/dist/channel/components/AdapterCredentialsForm.js.map +1 -0
- package/dist/channel/components/FeatureNotEnabled.d.ts +10 -0
- package/dist/channel/components/FeatureNotEnabled.d.ts.map +1 -0
- package/dist/channel/components/FeatureNotEnabled.js +32 -0
- package/dist/channel/components/FeatureNotEnabled.js.map +1 -0
- package/dist/channel/components/PermissionGuard.d.ts +15 -0
- package/dist/channel/components/PermissionGuard.d.ts.map +1 -0
- package/dist/channel/components/PermissionGuard.js +23 -0
- package/dist/channel/components/PermissionGuard.js.map +1 -0
- package/dist/channel/config/adapterCredentials.d.ts +44 -0
- package/dist/channel/config/adapterCredentials.d.ts.map +1 -0
- package/dist/channel/config/adapterCredentials.js +946 -0
- package/dist/channel/config/adapterCredentials.js.map +1 -0
- package/dist/channel/constants/permissions.d.ts +32 -0
- package/dist/channel/constants/permissions.d.ts.map +1 -0
- package/dist/channel/constants/permissions.js +30 -0
- package/dist/channel/constants/permissions.js.map +1 -0
- package/dist/channel/graphql/global-client.d.ts +11 -0
- package/dist/channel/graphql/global-client.d.ts.map +1 -0
- package/dist/channel/graphql/global-client.js +56 -0
- package/dist/channel/graphql/global-client.js.map +1 -0
- package/dist/channel/hooks/useChannelOrgSettings.d.ts +22 -0
- package/dist/channel/hooks/useChannelOrgSettings.d.ts.map +1 -0
- package/dist/channel/hooks/useChannelOrgSettings.js +61 -0
- package/dist/channel/hooks/useChannelOrgSettings.js.map +1 -0
- package/dist/channel/hooks/useChannelSubscription.d.ts +36 -0
- package/dist/channel/hooks/useChannelSubscription.d.ts.map +1 -0
- package/dist/channel/hooks/useChannelSubscription.js +111 -0
- package/dist/channel/hooks/useChannelSubscription.js.map +1 -0
- package/dist/channel/hooks/useChannels.d.ts +214 -0
- package/dist/channel/hooks/useChannels.d.ts.map +1 -0
- package/dist/channel/hooks/useChannels.js +416 -0
- package/dist/channel/hooks/useChannels.js.map +1 -0
- package/dist/channel/index.d.ts +12 -0
- package/dist/channel/index.d.ts.map +1 -0
- package/dist/channel/index.js +2 -0
- package/dist/channel/modules/channels/hooks/useExport.d.ts +45 -0
- package/dist/channel/modules/channels/hooks/useExport.d.ts.map +1 -0
- package/dist/channel/modules/channels/hooks/useExport.js +195 -0
- package/dist/channel/modules/channels/hooks/useExport.js.map +1 -0
- package/dist/channel/modules/channels/i18n.d.ts +14 -0
- package/dist/channel/modules/channels/i18n.d.ts.map +1 -0
- package/dist/channel/modules/channels/i18n.js +110 -0
- package/dist/channel/modules/channels/i18n.js.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts +14 -0
- package/dist/channel/modules/channels/pages/ChannelDashboardPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelDashboardPage.js +680 -0
- package/dist/channel/modules/channels/pages/ChannelDashboardPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/ChannelDetailsPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelDetailsPage.js +949 -0
- package/dist/channel/modules/channels/pages/ChannelDetailsPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.js +404 -0
- package/dist/channel/modules/channels/pages/ChannelSettingsPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/ChannelUsersPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelUsersPage.js +315 -0
- package/dist/channel/modules/channels/pages/ChannelUsersPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/ChannelsListPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/ChannelsListPage.js +604 -0
- package/dist/channel/modules/channels/pages/ChannelsListPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js +323 -0
- package/dist/channel/modules/channels/pages/ConnectionDetailsPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/ConnectionsListPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/ConnectionsListPage.js +276 -0
- package/dist/channel/modules/channels/pages/ConnectionsListPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/CreateChannelPage.d.ts +12 -0
- package/dist/channel/modules/channels/pages/CreateChannelPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/CreateChannelPage.js +456 -0
- package/dist/channel/modules/channels/pages/CreateChannelPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/CreateConnectionPage.d.ts +11 -0
- package/dist/channel/modules/channels/pages/CreateConnectionPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/CreateConnectionPage.js +219 -0
- package/dist/channel/modules/channels/pages/CreateConnectionPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js +375 -0
- package/dist/channel/modules/channels/pages/DeliveryHistoryPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/EditChannelPage.d.ts +8 -0
- package/dist/channel/modules/channels/pages/EditChannelPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/EditChannelPage.js +459 -0
- package/dist/channel/modules/channels/pages/EditChannelPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/EditConnectionPage.d.ts +10 -0
- package/dist/channel/modules/channels/pages/EditConnectionPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/EditConnectionPage.js +199 -0
- package/dist/channel/modules/channels/pages/EditConnectionPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/SendMessagePage.d.ts +8 -0
- package/dist/channel/modules/channels/pages/SendMessagePage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/SendMessagePage.js +403 -0
- package/dist/channel/modules/channels/pages/SendMessagePage.js.map +1 -0
- package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts +7 -0
- package/dist/channel/modules/channels/pages/WebhookEventsPage.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/WebhookEventsPage.js +303 -0
- package/dist/channel/modules/channels/pages/WebhookEventsPage.js.map +1 -0
- package/dist/channel/modules/channels/pages/index.d.ts +18 -0
- package/dist/channel/modules/channels/pages/index.d.ts.map +1 -0
- package/dist/channel/modules/channels/pages/index.js +14 -0
- package/dist/channel/pages/ChannelLandingPage.d.ts +9 -0
- package/dist/channel/pages/ChannelLandingPage.d.ts.map +1 -0
- package/dist/channel/pages/ChannelLandingPage.js +72 -0
- package/dist/channel/pages/ChannelLandingPage.js.map +1 -0
- package/dist/channel/providers/ChannelProvider.d.ts +16 -0
- package/dist/channel/providers/ChannelProvider.d.ts.map +1 -0
- package/dist/channel/providers/ChannelProvider.js +35 -0
- package/dist/channel/providers/ChannelProvider.js.map +1 -0
- package/dist/channel/types/index.d.ts +89 -0
- package/dist/channel/types/index.d.ts.map +1 -0
- package/dist/channel/utils/shellBridge.d.ts +59 -0
- package/dist/channel/utils/shellBridge.d.ts.map +1 -0
- package/dist/channel/utils/shellBridge.js +36 -0
- package/dist/channel/utils/shellBridge.js.map +1 -0
- package/dist/dev/App.d.ts +6 -0
- package/dist/dev/App.d.ts.map +1 -0
- package/dist/dev/main.d.ts +2 -0
- package/dist/dev/main.d.ts.map +1 -0
- package/dist/generated/global-operations.d.ts +1547 -0
- package/dist/generated/global-operations.d.ts.map +1 -0
- package/dist/generated/global-operations.js +466 -0
- package/dist/generated/global-operations.js.map +1 -0
- package/dist/generated/global-types.d.ts +21289 -0
- package/dist/generated/global-types.d.ts.map +1 -0
- package/dist/generated/global-types.js +14 -0
- package/dist/generated/global-types.js.map +1 -0
- package/dist/generated/wspace-operations.d.ts +2 -0
- package/dist/generated/wspace-operations.d.ts.map +1 -0
- package/dist/generated/wspace-types.d.ts +55214 -0
- package/dist/generated/wspace-types.d.ts.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js +24 -0
- package/dist/node_modules/@apollo/client/errors/CombinedGraphQLErrors.js.map +1 -0
- package/dist/node_modules/@apollo/client/errors/utils.js +16 -0
- package/dist/node_modules/@apollo/client/errors/utils.js.map +1 -0
- package/dist/utils/nativeBridge.d.ts +3 -0
- package/dist/utils/nativeBridge.d.ts.map +1 -0
- package/dist/utils/nativeBridge.js +2 -0
- package/package.json +116 -0
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { useChannel as e } from "../../../providers/ChannelProvider.js";
|
|
2
|
+
import { emitShellEvent as t, reportShellError as n } from "../../../utils/shellBridge.js";
|
|
3
|
+
import { getGlobalChannelClient as r } from "../../../graphql/global-client.js";
|
|
4
|
+
import { GetConnectionDocument as i, UpdateConnectionDocument as a } from "../../../../generated/global-operations.js";
|
|
5
|
+
import { PermissionGuard as o } from "../../../components/PermissionGuard.js";
|
|
6
|
+
import { CHANNEL_PERMISSIONS as s } from "../../../constants/permissions.js";
|
|
7
|
+
import { useEffect as c, useState as l } from "react";
|
|
8
|
+
import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
9
|
+
import { AlertCircle as d, ArrowLeft as f, Loader2 as p, Save as m, Shield as h } from "lucide-react";
|
|
10
|
+
import { useNavigate as g, useParams as _ } from "react-router-dom";
|
|
11
|
+
import { jsx as v, jsxs as y } from "react/jsx-runtime";
|
|
12
|
+
//#region src/channel/modules/channels/pages/EditConnectionPage.tsx
|
|
13
|
+
function b() {
|
|
14
|
+
let b = g(), { connectionId: x } = _(), { authToken: S, apiGatewayUrl: C, organizationId: w } = e(), { t: T } = u(), E = (e, t) => {
|
|
15
|
+
let n = T(e);
|
|
16
|
+
return n === e ? t : n;
|
|
17
|
+
}, [D, O] = l(null), [k, A] = l(!0), [j, M] = l(null), [N, P] = l(!0), [F, I] = l(""), [L, R] = l(""), [z, B] = l(!1);
|
|
18
|
+
return c(() => {
|
|
19
|
+
if (!x) return;
|
|
20
|
+
let e = !1;
|
|
21
|
+
return (async () => {
|
|
22
|
+
A(!0), M(null);
|
|
23
|
+
try {
|
|
24
|
+
let t = await r(C, S, w).query({
|
|
25
|
+
query: i,
|
|
26
|
+
variables: { id: x },
|
|
27
|
+
fetchPolicy: "network-only"
|
|
28
|
+
});
|
|
29
|
+
if (e) return;
|
|
30
|
+
let n = t.data?.getConnection ?? null;
|
|
31
|
+
O(n), P(n?.isActive ?? !0);
|
|
32
|
+
} catch (t) {
|
|
33
|
+
if (e) return;
|
|
34
|
+
M(t instanceof Error ? t.message : E("connection.loadFailed", "Failed to load connection"));
|
|
35
|
+
} finally {
|
|
36
|
+
e || A(!1);
|
|
37
|
+
}
|
|
38
|
+
})(), () => {
|
|
39
|
+
e = !0;
|
|
40
|
+
};
|
|
41
|
+
}, [
|
|
42
|
+
x,
|
|
43
|
+
C,
|
|
44
|
+
S,
|
|
45
|
+
w,
|
|
46
|
+
E
|
|
47
|
+
]), k ? /* @__PURE__ */ v("div", {
|
|
48
|
+
className: "container mx-auto p-6 flex items-center justify-center min-h-64",
|
|
49
|
+
children: /* @__PURE__ */ v(p, { className: "w-6 h-6 animate-spin text-fg-muted" })
|
|
50
|
+
}) : D ? /* @__PURE__ */ v(o, {
|
|
51
|
+
permission: s.CHANNEL_CONNECTION_UPDATE,
|
|
52
|
+
children: /* @__PURE__ */ y("div", {
|
|
53
|
+
className: "container mx-auto p-6 max-w-2xl",
|
|
54
|
+
children: [
|
|
55
|
+
/* @__PURE__ */ y("button", {
|
|
56
|
+
onClick: () => b(-1),
|
|
57
|
+
className: "flex items-center gap-2 text-fg-muted hover:text-fg mb-6",
|
|
58
|
+
children: [/* @__PURE__ */ v(f, { className: "w-4 h-4" }), E("common.back", "Back")]
|
|
59
|
+
}),
|
|
60
|
+
/* @__PURE__ */ y("div", {
|
|
61
|
+
className: "flex items-center gap-3 mb-6",
|
|
62
|
+
children: [/* @__PURE__ */ v(h, { className: "w-7 h-7 text-accent-blue" }), /* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("h1", {
|
|
63
|
+
className: "text-2xl font-bold text-fg",
|
|
64
|
+
children: E("connection.edit.title", "Edit Connection")
|
|
65
|
+
}), /* @__PURE__ */ v("p", {
|
|
66
|
+
className: "text-sm text-fg-muted",
|
|
67
|
+
children: E("connection.edit.subtitle", "Update credentials, status, or platform metadata.")
|
|
68
|
+
})] })]
|
|
69
|
+
}),
|
|
70
|
+
j && /* @__PURE__ */ y("div", {
|
|
71
|
+
className: "bg-status-error-bg-subtle border border-status-error-bg-subtle rounded-lg p-4 mb-6 flex gap-3",
|
|
72
|
+
children: [/* @__PURE__ */ v(d, { className: "w-5 h-5 text-status-error-text shrink-0" }), /* @__PURE__ */ v("p", {
|
|
73
|
+
className: "text-sm text-status-error-text",
|
|
74
|
+
children: j
|
|
75
|
+
})]
|
|
76
|
+
}),
|
|
77
|
+
/* @__PURE__ */ y("form", {
|
|
78
|
+
onSubmit: async (e) => {
|
|
79
|
+
if (e.preventDefault(), !x) return;
|
|
80
|
+
M(null);
|
|
81
|
+
let i;
|
|
82
|
+
if (F.trim()) try {
|
|
83
|
+
i = JSON.parse(F);
|
|
84
|
+
} catch {
|
|
85
|
+
M(E("connection.validation.credentialsJson", "Credentials must be valid JSON"));
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
let o;
|
|
89
|
+
if (L.trim()) try {
|
|
90
|
+
o = JSON.parse(L);
|
|
91
|
+
} catch {
|
|
92
|
+
M(E("connection.validation.metadataJson", "Platform metadata must be valid JSON"));
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
B(!0);
|
|
96
|
+
try {
|
|
97
|
+
await r(C, S, w).mutate({
|
|
98
|
+
mutation: a,
|
|
99
|
+
variables: {
|
|
100
|
+
id: x,
|
|
101
|
+
input: {
|
|
102
|
+
isActive: N,
|
|
103
|
+
credentials: i,
|
|
104
|
+
platformMetadata: o
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}), t("connection.updated", { id: x }), b(`../${x}`);
|
|
108
|
+
} catch (e) {
|
|
109
|
+
n(e, {
|
|
110
|
+
module: "channel",
|
|
111
|
+
context: {
|
|
112
|
+
action: "EditConnectionPage.submit",
|
|
113
|
+
connectionId: x
|
|
114
|
+
}
|
|
115
|
+
}, "[channel] Failed to update connection"), M(e instanceof Error ? e.message : E("connection.updateFailed", "Failed to update connection"));
|
|
116
|
+
} finally {
|
|
117
|
+
B(!1);
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
className: "space-y-6 bg-bg-elevated rounded-lg p-6 border border-border",
|
|
121
|
+
children: [
|
|
122
|
+
/* @__PURE__ */ y("div", {
|
|
123
|
+
className: "text-sm text-fg-muted",
|
|
124
|
+
children: [
|
|
125
|
+
/* @__PURE__ */ v("span", {
|
|
126
|
+
className: "font-medium text-fg",
|
|
127
|
+
children: "ID:"
|
|
128
|
+
}),
|
|
129
|
+
" ",
|
|
130
|
+
D.id,
|
|
131
|
+
/* @__PURE__ */ v("br", {}),
|
|
132
|
+
/* @__PURE__ */ y("span", {
|
|
133
|
+
className: "font-medium text-fg",
|
|
134
|
+
children: [E("connection.field.authType", "Auth Type"), ":"]
|
|
135
|
+
}),
|
|
136
|
+
" ",
|
|
137
|
+
D.authType
|
|
138
|
+
]
|
|
139
|
+
}),
|
|
140
|
+
/* @__PURE__ */ v("div", { children: /* @__PURE__ */ y("label", {
|
|
141
|
+
className: "flex items-center gap-2 text-sm font-medium text-fg",
|
|
142
|
+
children: [/* @__PURE__ */ v("input", {
|
|
143
|
+
type: "checkbox",
|
|
144
|
+
checked: N,
|
|
145
|
+
onChange: (e) => P(e.target.checked)
|
|
146
|
+
}), E("connection.field.isActive", "Active")]
|
|
147
|
+
}) }),
|
|
148
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
149
|
+
className: "block text-sm font-medium text-fg mb-2",
|
|
150
|
+
children: E("connection.field.credentials", "Credentials (JSON)")
|
|
151
|
+
}), /* @__PURE__ */ v("textarea", {
|
|
152
|
+
value: F,
|
|
153
|
+
onChange: (e) => I(e.target.value),
|
|
154
|
+
rows: 6,
|
|
155
|
+
className: "w-full px-3 py-2 bg-bg border border-border rounded-md font-mono text-sm text-fg",
|
|
156
|
+
placeholder: E("connection.field.credentialsLeaveBlank", "Leave blank to keep existing credentials")
|
|
157
|
+
})] }),
|
|
158
|
+
/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("label", {
|
|
159
|
+
className: "block text-sm font-medium text-fg mb-2",
|
|
160
|
+
children: E("connection.field.platformMetadata", "Platform Metadata (JSON)")
|
|
161
|
+
}), /* @__PURE__ */ v("textarea", {
|
|
162
|
+
value: L,
|
|
163
|
+
onChange: (e) => R(e.target.value),
|
|
164
|
+
rows: 4,
|
|
165
|
+
className: "w-full px-3 py-2 bg-bg border border-border rounded-md font-mono text-sm text-fg"
|
|
166
|
+
})] }),
|
|
167
|
+
/* @__PURE__ */ y("div", {
|
|
168
|
+
className: "flex gap-3 pt-2",
|
|
169
|
+
children: [/* @__PURE__ */ y("button", {
|
|
170
|
+
type: "submit",
|
|
171
|
+
disabled: z,
|
|
172
|
+
className: "flex items-center gap-2 px-4 py-2 bg-accent-blue text-fg-on-accent rounded-md disabled:opacity-50",
|
|
173
|
+
children: [z ? /* @__PURE__ */ v(p, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ v(m, { className: "w-4 h-4" }), E("common.save", "Save")]
|
|
174
|
+
}), /* @__PURE__ */ v("button", {
|
|
175
|
+
type: "button",
|
|
176
|
+
onClick: () => b(-1),
|
|
177
|
+
className: "px-4 py-2 text-fg border border-border rounded-md",
|
|
178
|
+
children: E("common.cancel", "Cancel")
|
|
179
|
+
})]
|
|
180
|
+
})
|
|
181
|
+
]
|
|
182
|
+
})
|
|
183
|
+
]
|
|
184
|
+
})
|
|
185
|
+
}) : /* @__PURE__ */ v("div", {
|
|
186
|
+
className: "container mx-auto p-6 max-w-2xl",
|
|
187
|
+
children: /* @__PURE__ */ y("div", {
|
|
188
|
+
className: "bg-status-error-bg-subtle border border-status-error-bg-subtle rounded-lg p-4 flex gap-3",
|
|
189
|
+
children: [/* @__PURE__ */ v(d, { className: "w-5 h-5 text-status-error-text shrink-0" }), /* @__PURE__ */ v("p", {
|
|
190
|
+
className: "text-sm text-status-error-text",
|
|
191
|
+
children: j ?? E("connection.notFound", "Connection not found")
|
|
192
|
+
})]
|
|
193
|
+
})
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
//#endregion
|
|
197
|
+
export { b as EditConnectionPage };
|
|
198
|
+
|
|
199
|
+
//# sourceMappingURL=EditConnectionPage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EditConnectionPage.js","names":[],"sources":["../../../../../src/channel/modules/channels/pages/EditConnectionPage.tsx"],"sourcesContent":["/**\n * Edit Connection Page\n *\n * Standalone page mounted at /channels/connections/:connectionId/edit.\n * Fetches the connection directly via getConnection (no channelId required in URL).\n *\n * Form fields match UpdateConnectionInput exactly.\n */\n\nimport { useEffect, useState } from 'react';\nimport { useNavigate, useParams } from 'react-router-dom';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { ArrowLeft, Loader2, AlertCircle, Save, Shield } from 'lucide-react';\nimport { useChannel as useChannelContext } from '../../../providers/ChannelProvider';\nimport { getGlobalChannelClient } from '../../../graphql/global-client';\nimport {\n GetConnectionDocument,\n UpdateConnectionDocument,\n type GetConnectionQuery,\n type UpdateConnectionMutation,\n} from '../../../../generated/global-operations';\nimport { PermissionGuard } from '../../../components/PermissionGuard';\nimport { CHANNEL_PERMISSIONS } from '../../../constants/permissions';\nimport { emitShellEvent, reportShellError } from '../../../utils/shellBridge';\n\ntype Connection = NonNullable<GetConnectionQuery['getConnection']>;\n\nexport function EditConnectionPage() {\n const navigate = useNavigate();\n const { connectionId } = useParams<{ connectionId: string }>();\n const { authToken, apiGatewayUrl, organizationId } = useChannelContext();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const [connection, setConnection] = useState<Connection | null>(null);\n const [isLoading, setIsLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n const [isActive, setIsActive] = useState(true);\n const [credentials, setCredentials] = useState('');\n const [platformMetadata, setPlatformMetadata] = useState('');\n const [isSubmitting, setIsSubmitting] = useState(false);\n\n useEffect(() => {\n if (!connectionId) return;\n let cancelled = false;\n void (async () => {\n setIsLoading(true);\n setError(null);\n try {\n const client = getGlobalChannelClient(apiGatewayUrl, authToken, organizationId);\n const result = await client.query<GetConnectionQuery>({\n query: GetConnectionDocument,\n variables: { id: connectionId },\n fetchPolicy: 'network-only',\n });\n if (cancelled) return;\n const conn = result.data?.getConnection ?? null;\n setConnection(conn);\n setIsActive(conn?.isActive ?? true);\n } catch (err: unknown) {\n if (cancelled) return;\n setError(\n err instanceof Error\n ? err.message\n : tr('connection.loadFailed', 'Failed to load connection')\n );\n } finally {\n if (!cancelled) setIsLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n };\n }, [connectionId, apiGatewayUrl, authToken, organizationId, tr]);\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n if (!connectionId) return;\n setError(null);\n\n let parsedCredentials: Record<string, unknown> | undefined;\n if (credentials.trim()) {\n try {\n parsedCredentials = JSON.parse(credentials);\n } catch {\n setError(tr('connection.validation.credentialsJson', 'Credentials must be valid JSON'));\n return;\n }\n }\n\n let parsedMetadata: Record<string, unknown> | undefined;\n if (platformMetadata.trim()) {\n try {\n parsedMetadata = JSON.parse(platformMetadata);\n } catch {\n setError(tr('connection.validation.metadataJson', 'Platform metadata must be valid JSON'));\n return;\n }\n }\n\n setIsSubmitting(true);\n try {\n const client = getGlobalChannelClient(apiGatewayUrl, authToken, organizationId);\n await client.mutate<UpdateConnectionMutation>({\n mutation: UpdateConnectionDocument,\n variables: {\n id: connectionId,\n input: {\n isActive,\n credentials: parsedCredentials,\n platformMetadata: parsedMetadata,\n },\n },\n });\n emitShellEvent('connection.updated', { id: connectionId });\n navigate(`../${connectionId}`);\n } catch (err: unknown) {\n reportShellError(\n err,\n { module: 'channel', context: { action: 'EditConnectionPage.submit', connectionId } },\n '[channel] Failed to update connection'\n );\n setError(\n err instanceof Error\n ? err.message\n : tr('connection.updateFailed', 'Failed to update connection')\n );\n } finally {\n setIsSubmitting(false);\n }\n };\n\n if (isLoading) {\n return (\n <div className=\"container mx-auto p-6 flex items-center justify-center min-h-64\">\n <Loader2 className=\"w-6 h-6 animate-spin text-fg-muted\" />\n </div>\n );\n }\n\n if (!connection) {\n return (\n <div className=\"container mx-auto p-6 max-w-2xl\">\n <div className=\"bg-status-error-bg-subtle border border-status-error-bg-subtle rounded-lg p-4 flex gap-3\">\n <AlertCircle className=\"w-5 h-5 text-status-error-text shrink-0\" />\n <p className=\"text-sm text-status-error-text\">\n {error ?? tr('connection.notFound', 'Connection not found')}\n </p>\n </div>\n </div>\n );\n }\n\n return (\n <PermissionGuard permission={CHANNEL_PERMISSIONS.CHANNEL_CONNECTION_UPDATE}>\n <div className=\"container mx-auto p-6 max-w-2xl\">\n <button\n onClick={() => navigate(-1)}\n className=\"flex items-center gap-2 text-fg-muted hover:text-fg mb-6\"\n >\n <ArrowLeft className=\"w-4 h-4\" />\n {tr('common.back', 'Back')}\n </button>\n\n <div className=\"flex items-center gap-3 mb-6\">\n <Shield className=\"w-7 h-7 text-accent-blue\" />\n <div>\n <h1 className=\"text-2xl font-bold text-fg\">\n {tr('connection.edit.title', 'Edit Connection')}\n </h1>\n <p className=\"text-sm text-fg-muted\">\n {tr('connection.edit.subtitle', 'Update credentials, status, or platform metadata.')}\n </p>\n </div>\n </div>\n\n {error && (\n <div className=\"bg-status-error-bg-subtle border border-status-error-bg-subtle rounded-lg p-4 mb-6 flex gap-3\">\n <AlertCircle className=\"w-5 h-5 text-status-error-text shrink-0\" />\n <p className=\"text-sm text-status-error-text\">{error}</p>\n </div>\n )}\n\n <form\n onSubmit={handleSubmit}\n className=\"space-y-6 bg-bg-elevated rounded-lg p-6 border border-border\"\n >\n <div className=\"text-sm text-fg-muted\">\n <span className=\"font-medium text-fg\">ID:</span> {connection.id}\n <br />\n <span className=\"font-medium text-fg\">\n {tr('connection.field.authType', 'Auth Type')}:\n </span>{' '}\n {connection.authType}\n </div>\n\n <div>\n <label className=\"flex items-center gap-2 text-sm font-medium text-fg\">\n <input\n type=\"checkbox\"\n checked={isActive}\n onChange={(e) => setIsActive(e.target.checked)}\n />\n {tr('connection.field.isActive', 'Active')}\n </label>\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-fg mb-2\">\n {tr('connection.field.credentials', 'Credentials (JSON)')}\n </label>\n <textarea\n value={credentials}\n onChange={(e) => setCredentials(e.target.value)}\n rows={6}\n className=\"w-full px-3 py-2 bg-bg border border-border rounded-md font-mono text-sm text-fg\"\n placeholder={tr(\n 'connection.field.credentialsLeaveBlank',\n 'Leave blank to keep existing credentials'\n )}\n />\n </div>\n\n <div>\n <label className=\"block text-sm font-medium text-fg mb-2\">\n {tr('connection.field.platformMetadata', 'Platform Metadata (JSON)')}\n </label>\n <textarea\n value={platformMetadata}\n onChange={(e) => setPlatformMetadata(e.target.value)}\n rows={4}\n className=\"w-full px-3 py-2 bg-bg border border-border rounded-md font-mono text-sm text-fg\"\n />\n </div>\n\n <div className=\"flex gap-3 pt-2\">\n <button\n type=\"submit\"\n disabled={isSubmitting}\n className=\"flex items-center gap-2 px-4 py-2 bg-accent-blue text-fg-on-accent rounded-md disabled:opacity-50\"\n >\n {isSubmitting ? (\n <Loader2 className=\"w-4 h-4 animate-spin\" />\n ) : (\n <Save className=\"w-4 h-4\" />\n )}\n {tr('common.save', 'Save')}\n </button>\n <button\n type=\"button\"\n onClick={() => navigate(-1)}\n className=\"px-4 py-2 text-fg border border-border rounded-md\"\n >\n {tr('common.cancel', 'Cancel')}\n </button>\n </div>\n </form>\n </div>\n </PermissionGuard>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Send Message Page
|
|
3
|
+
*
|
|
4
|
+
* UI for sending notifications/messages through channels.
|
|
5
|
+
* Supports single and bulk delivery with recipient management.
|
|
6
|
+
*/
|
|
7
|
+
export declare function SendMessagePage(): import("react/jsx-runtime").JSX.Element;
|
|
8
|
+
//# sourceMappingURL=SendMessagePage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SendMessagePage.d.ts","sourceRoot":"","sources":["../../../../../src/channel/modules/channels/pages/SendMessagePage.tsx"],"names":[],"mappings":"AAAA;;;;;GAKG;AA0EH,wBAAgB,eAAe,4CA6e9B"}
|
|
@@ -0,0 +1,403 @@
|
|
|
1
|
+
import { useChannel as e } from "../../../providers/ChannelProvider.js";
|
|
2
|
+
import { getGlobalChannelClient as t } from "../../../graphql/global-client.js";
|
|
3
|
+
import { useSendNotificationMutation as n } from "../../../../generated/global-operations.js";
|
|
4
|
+
import { useChannels as r } from "../../../hooks/useChannels.js";
|
|
5
|
+
import { PermissionGuard as i } from "../../../components/PermissionGuard.js";
|
|
6
|
+
import { CHANNEL_PERMISSIONS as a } from "../../../constants/permissions.js";
|
|
7
|
+
import { NotificationChannel as o, NotificationPriority as s } from "../../../../generated/global-types.js";
|
|
8
|
+
import { useCallback as c, useState as l } from "react";
|
|
9
|
+
import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
|
|
10
|
+
import { AlertCircle as d, ArrowLeft as ee, Bell as f, CheckCircle2 as p, Hash as m, Loader2 as h, Mail as g, MessageCircle as _, MessageSquare as v, Plus as y, Send as b, Smartphone as x, Users as S, X as C, XCircle as te } from "lucide-react";
|
|
11
|
+
import { useNavigate as ne } from "react-router-dom";
|
|
12
|
+
import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
|
|
13
|
+
//#region src/channel/modules/channels/pages/SendMessagePage.tsx
|
|
14
|
+
var D = {
|
|
15
|
+
EMAIL: g,
|
|
16
|
+
SMS: x,
|
|
17
|
+
PUSH: f,
|
|
18
|
+
WHATSAPP: v,
|
|
19
|
+
SLACK: m,
|
|
20
|
+
TEAMS: S,
|
|
21
|
+
DISCORD: _,
|
|
22
|
+
INAPP: f,
|
|
23
|
+
WEBCHAT: v,
|
|
24
|
+
WEBHOOK: b
|
|
25
|
+
};
|
|
26
|
+
function O() {
|
|
27
|
+
let f = ne(), { channels: m } = r(), { organizationId: g, authToken: _, apiGatewayUrl: v } = e(), { t: x } = u(), S = (e, t) => {
|
|
28
|
+
let n = x(e);
|
|
29
|
+
return n === e ? t : n;
|
|
30
|
+
}, [O, { loading: k }] = n({ client: t(v, _, g) }), [A, j] = l(""), [M, N] = l("EMAIL"), [P, F] = l([]), [I, L] = l(""), [R, z] = l(""), [B, V] = l(""), [H, U] = l(""), [W, G] = l(s.Medium), [K, q] = l(null), [J, Y] = l(null), X = m.filter((e) => e.platform === M), Z = c(() => {
|
|
31
|
+
if (!I.trim()) return;
|
|
32
|
+
let e = {
|
|
33
|
+
id: `temp-${Date.now()}`,
|
|
34
|
+
address: I.trim(),
|
|
35
|
+
name: R.trim() || void 0
|
|
36
|
+
};
|
|
37
|
+
F((t) => [...t, e]), L(""), z("");
|
|
38
|
+
}, [I, R]), re = c((e) => {
|
|
39
|
+
F((t) => t.filter((t) => t.id !== e));
|
|
40
|
+
}, []), ie = c(() => {
|
|
41
|
+
q(null), Y(null), V(""), U(""), F([]);
|
|
42
|
+
}, []), ae = async () => {
|
|
43
|
+
if (!A) {
|
|
44
|
+
Y(S("channel.validation.selectChannel", "Please select a channel"));
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
if (P.length === 0) {
|
|
48
|
+
Y(S("channel.validation.addRecipient", "Please add at least one recipient"));
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
if (!H.trim()) {
|
|
52
|
+
Y(S("channel.validation.enterMessage", "Please enter a message"));
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
Y(null), q(null);
|
|
56
|
+
try {
|
|
57
|
+
let e = m.find((e) => e.id === A);
|
|
58
|
+
if (!e) {
|
|
59
|
+
Y(S("channel.error.channelNotFound", "Selected channel not found"));
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
let t = M === "INAPP" ? o.InApp : M;
|
|
63
|
+
q(await Promise.all(P.map(async (n) => {
|
|
64
|
+
let r = {};
|
|
65
|
+
switch (M) {
|
|
66
|
+
case "EMAIL":
|
|
67
|
+
r.email = n.address;
|
|
68
|
+
break;
|
|
69
|
+
case "SMS":
|
|
70
|
+
case "WHATSAPP":
|
|
71
|
+
r.phoneNumber = n.address;
|
|
72
|
+
break;
|
|
73
|
+
case "PUSH":
|
|
74
|
+
r.pushToken = n.address;
|
|
75
|
+
break;
|
|
76
|
+
case "SLACK":
|
|
77
|
+
r.slackUserId = n.address;
|
|
78
|
+
break;
|
|
79
|
+
case "TEAMS":
|
|
80
|
+
r.teamsUserId = n.address;
|
|
81
|
+
break;
|
|
82
|
+
case "WEBHOOK":
|
|
83
|
+
r.webhookUrl = n.address;
|
|
84
|
+
break;
|
|
85
|
+
default: r.email = n.address;
|
|
86
|
+
}
|
|
87
|
+
let i = {
|
|
88
|
+
channelId: e.id,
|
|
89
|
+
platform: t,
|
|
90
|
+
notification: {
|
|
91
|
+
body: H,
|
|
92
|
+
channel: t,
|
|
93
|
+
recipient: r,
|
|
94
|
+
subject: M === "EMAIL" ? B : void 0,
|
|
95
|
+
priority: W
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
try {
|
|
99
|
+
let e = await O({ variables: { input: i } });
|
|
100
|
+
if (e.data?.triggerNotification) {
|
|
101
|
+
let t = e.data.triggerNotification, r = t.status === "FAILED" || t.triggerStatus === "FAILED";
|
|
102
|
+
return {
|
|
103
|
+
recipientId: n.id,
|
|
104
|
+
success: !r,
|
|
105
|
+
messageId: t.id,
|
|
106
|
+
error: r ? "Delivery failed" : void 0
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
return {
|
|
110
|
+
recipientId: n.id,
|
|
111
|
+
success: !1,
|
|
112
|
+
error: e.error?.message || "Failed to send notification"
|
|
113
|
+
};
|
|
114
|
+
} catch (e) {
|
|
115
|
+
return {
|
|
116
|
+
recipientId: n.id,
|
|
117
|
+
success: !1,
|
|
118
|
+
error: e instanceof Error ? e.message : "Failed to send notification"
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
})));
|
|
122
|
+
} catch (e) {
|
|
123
|
+
Y(e instanceof Error ? e.message : "Failed to send message");
|
|
124
|
+
}
|
|
125
|
+
}, Q = K?.filter((e) => e.success).length ?? 0, $ = K?.filter((e) => !e.success).length ?? 0;
|
|
126
|
+
return /* @__PURE__ */ T(i, {
|
|
127
|
+
permission: a.CHANNEL_DELIVERY_SEND,
|
|
128
|
+
children: /* @__PURE__ */ E("div", {
|
|
129
|
+
className: "min-h-screen bg-background",
|
|
130
|
+
children: [/* @__PURE__ */ T("div", {
|
|
131
|
+
className: "border-b bg-card",
|
|
132
|
+
children: /* @__PURE__ */ T("div", {
|
|
133
|
+
className: "container mx-auto px-6 py-4",
|
|
134
|
+
children: /* @__PURE__ */ E("div", {
|
|
135
|
+
className: "flex items-center gap-4",
|
|
136
|
+
children: [/* @__PURE__ */ T("button", {
|
|
137
|
+
onClick: () => f("/channels/list"),
|
|
138
|
+
className: "p-2 hover:bg-muted rounded-lg transition-colors",
|
|
139
|
+
children: /* @__PURE__ */ T(ee, { className: "w-5 h-5" })
|
|
140
|
+
}), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("h1", {
|
|
141
|
+
className: "text-2xl font-bold",
|
|
142
|
+
children: S("channel.sendMessage", "Send Message")
|
|
143
|
+
}), /* @__PURE__ */ T("p", {
|
|
144
|
+
className: "text-sm text-muted-foreground",
|
|
145
|
+
children: S("channel.sendMessageSubtitle", "Send notifications through configured channels")
|
|
146
|
+
})] })]
|
|
147
|
+
})
|
|
148
|
+
})
|
|
149
|
+
}), /* @__PURE__ */ T("div", {
|
|
150
|
+
className: "container mx-auto px-6 py-8 max-w-3xl",
|
|
151
|
+
children: K === null ? /* @__PURE__ */ E("div", {
|
|
152
|
+
className: "space-y-6",
|
|
153
|
+
children: [
|
|
154
|
+
J && /* @__PURE__ */ E("div", {
|
|
155
|
+
className: "p-4 rounded-lg bg-destructive/10 border border-destructive/20 flex items-center gap-3",
|
|
156
|
+
children: [/* @__PURE__ */ T(d, { className: "w-5 h-5 text-destructive shrink-0" }), /* @__PURE__ */ T("p", {
|
|
157
|
+
className: "text-sm text-destructive",
|
|
158
|
+
children: J
|
|
159
|
+
})]
|
|
160
|
+
}),
|
|
161
|
+
/* @__PURE__ */ E("div", {
|
|
162
|
+
className: "space-y-3",
|
|
163
|
+
children: [/* @__PURE__ */ T("label", {
|
|
164
|
+
className: "text-sm font-medium",
|
|
165
|
+
children: S("channel.platform", "Platform")
|
|
166
|
+
}), /* @__PURE__ */ T("div", {
|
|
167
|
+
className: "flex flex-wrap gap-2",
|
|
168
|
+
children: [
|
|
169
|
+
"EMAIL",
|
|
170
|
+
"SMS",
|
|
171
|
+
"PUSH",
|
|
172
|
+
"WHATSAPP",
|
|
173
|
+
"SLACK",
|
|
174
|
+
"TEAMS",
|
|
175
|
+
"WEBHOOK"
|
|
176
|
+
].map((e) => {
|
|
177
|
+
let t = D[e] || b;
|
|
178
|
+
return /* @__PURE__ */ E("button", {
|
|
179
|
+
onClick: () => {
|
|
180
|
+
N(e), j("");
|
|
181
|
+
},
|
|
182
|
+
className: `px-4 py-2 rounded-lg border flex items-center gap-2 transition-all ${M === e ? "bg-primary text-primary-foreground border-primary" : "bg-card hover:bg-muted border-border"}`,
|
|
183
|
+
children: [/* @__PURE__ */ T(t, { className: "w-4 h-4" }), /* @__PURE__ */ T("span", {
|
|
184
|
+
className: "text-sm",
|
|
185
|
+
children: e
|
|
186
|
+
})]
|
|
187
|
+
}, e);
|
|
188
|
+
})
|
|
189
|
+
})]
|
|
190
|
+
}),
|
|
191
|
+
/* @__PURE__ */ E("div", {
|
|
192
|
+
className: "space-y-2",
|
|
193
|
+
children: [/* @__PURE__ */ E("label", {
|
|
194
|
+
className: "text-sm font-medium",
|
|
195
|
+
children: [S("channel.channel", "Channel"), " *"]
|
|
196
|
+
}), X.length === 0 ? /* @__PURE__ */ T("div", {
|
|
197
|
+
className: "p-4 rounded-lg border border-dashed text-center",
|
|
198
|
+
children: /* @__PURE__ */ E("p", {
|
|
199
|
+
className: "text-sm text-muted-foreground",
|
|
200
|
+
children: [
|
|
201
|
+
"No ",
|
|
202
|
+
M,
|
|
203
|
+
" channels configured.",
|
|
204
|
+
/* @__PURE__ */ T("button", {
|
|
205
|
+
onClick: () => f("./create"),
|
|
206
|
+
className: "text-primary hover:underline ml-1",
|
|
207
|
+
children: "Create one"
|
|
208
|
+
})
|
|
209
|
+
]
|
|
210
|
+
})
|
|
211
|
+
}) : /* @__PURE__ */ E("select", {
|
|
212
|
+
value: A,
|
|
213
|
+
onChange: (e) => j(e.target.value),
|
|
214
|
+
className: "w-full px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary",
|
|
215
|
+
children: [/* @__PURE__ */ T("option", {
|
|
216
|
+
value: "",
|
|
217
|
+
children: S("channel.selectChannel", "Select a channel...")
|
|
218
|
+
}), X.map((e) => /* @__PURE__ */ E("option", {
|
|
219
|
+
value: e.id,
|
|
220
|
+
children: [
|
|
221
|
+
e.name,
|
|
222
|
+
" (",
|
|
223
|
+
e.adapterType,
|
|
224
|
+
")"
|
|
225
|
+
]
|
|
226
|
+
}, e.id))]
|
|
227
|
+
})]
|
|
228
|
+
}),
|
|
229
|
+
/* @__PURE__ */ E("div", {
|
|
230
|
+
className: "space-y-3",
|
|
231
|
+
children: [
|
|
232
|
+
/* @__PURE__ */ T("label", {
|
|
233
|
+
className: "text-sm font-medium",
|
|
234
|
+
children: S("channel.recipients", "Recipients")
|
|
235
|
+
}),
|
|
236
|
+
/* @__PURE__ */ E("div", {
|
|
237
|
+
className: "flex gap-2",
|
|
238
|
+
children: [
|
|
239
|
+
/* @__PURE__ */ T("input", {
|
|
240
|
+
type: "text",
|
|
241
|
+
value: I,
|
|
242
|
+
onChange: (e) => L(e.target.value),
|
|
243
|
+
placeholder: M === "EMAIL" ? "email@example.com" : "+1234567890",
|
|
244
|
+
className: "flex-1 px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary"
|
|
245
|
+
}),
|
|
246
|
+
/* @__PURE__ */ T("input", {
|
|
247
|
+
type: "text",
|
|
248
|
+
value: R,
|
|
249
|
+
onChange: (e) => z(e.target.value),
|
|
250
|
+
placeholder: S("channel.nameOptional", "Name (optional)"),
|
|
251
|
+
className: "w-48 px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary"
|
|
252
|
+
}),
|
|
253
|
+
/* @__PURE__ */ E("button", {
|
|
254
|
+
onClick: Z,
|
|
255
|
+
disabled: !I.trim(),
|
|
256
|
+
className: "px-4 py-2 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50 flex items-center gap-2",
|
|
257
|
+
children: [/* @__PURE__ */ T(y, { className: "w-4 h-4" }), S("channel.add", "Add")]
|
|
258
|
+
})
|
|
259
|
+
]
|
|
260
|
+
}),
|
|
261
|
+
P.length > 0 ? /* @__PURE__ */ T("div", {
|
|
262
|
+
className: "border rounded-lg divide-y",
|
|
263
|
+
children: P.map((e) => /* @__PURE__ */ E("div", {
|
|
264
|
+
className: "p-3 flex items-center justify-between",
|
|
265
|
+
children: [/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("p", {
|
|
266
|
+
className: "text-sm font-medium",
|
|
267
|
+
children: e.address
|
|
268
|
+
}), e.name && /* @__PURE__ */ T("p", {
|
|
269
|
+
className: "text-xs text-muted-foreground",
|
|
270
|
+
children: e.name
|
|
271
|
+
})] }), /* @__PURE__ */ T("button", {
|
|
272
|
+
onClick: () => re(e.id),
|
|
273
|
+
className: "p-1 hover:bg-muted rounded transition-colors",
|
|
274
|
+
children: /* @__PURE__ */ T(C, { className: "w-4 h-4 text-muted-foreground" })
|
|
275
|
+
})]
|
|
276
|
+
}, e.id))
|
|
277
|
+
}) : /* @__PURE__ */ T("p", {
|
|
278
|
+
className: "text-sm text-muted-foreground text-center py-4",
|
|
279
|
+
children: S("channel.noRecipientsYet", "No recipients added yet")
|
|
280
|
+
})
|
|
281
|
+
]
|
|
282
|
+
}),
|
|
283
|
+
/* @__PURE__ */ E("div", {
|
|
284
|
+
className: "space-y-3",
|
|
285
|
+
children: [
|
|
286
|
+
/* @__PURE__ */ E("label", {
|
|
287
|
+
className: "text-sm font-medium",
|
|
288
|
+
children: [S("channel.messageContent", "Message Content"), " *"]
|
|
289
|
+
}),
|
|
290
|
+
M === "EMAIL" && /* @__PURE__ */ T("input", {
|
|
291
|
+
type: "text",
|
|
292
|
+
value: B,
|
|
293
|
+
onChange: (e) => V(e.target.value),
|
|
294
|
+
placeholder: "Subject",
|
|
295
|
+
className: "w-full px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary"
|
|
296
|
+
}),
|
|
297
|
+
/* @__PURE__ */ T("textarea", {
|
|
298
|
+
value: H,
|
|
299
|
+
onChange: (e) => U(e.target.value),
|
|
300
|
+
placeholder: "Enter your message...",
|
|
301
|
+
rows: 6,
|
|
302
|
+
className: "w-full px-4 py-2 rounded-lg border bg-background focus:outline-none focus:ring-2 focus:ring-primary resize-none"
|
|
303
|
+
})
|
|
304
|
+
]
|
|
305
|
+
}),
|
|
306
|
+
/* @__PURE__ */ E("div", {
|
|
307
|
+
className: "space-y-2",
|
|
308
|
+
children: [/* @__PURE__ */ T("label", {
|
|
309
|
+
className: "text-sm font-medium",
|
|
310
|
+
children: S("channel.priority", "Priority")
|
|
311
|
+
}), /* @__PURE__ */ T("div", {
|
|
312
|
+
className: "flex gap-2",
|
|
313
|
+
children: [
|
|
314
|
+
s.Low,
|
|
315
|
+
s.Medium,
|
|
316
|
+
s.High,
|
|
317
|
+
s.Urgent
|
|
318
|
+
].map((e) => /* @__PURE__ */ T("button", {
|
|
319
|
+
onClick: () => G(e),
|
|
320
|
+
className: `px-4 py-2 rounded-lg border text-sm transition-all ${W === e ? "bg-primary text-primary-foreground border-primary" : "bg-card hover:bg-muted border-border"}`,
|
|
321
|
+
children: e
|
|
322
|
+
}, e))
|
|
323
|
+
})]
|
|
324
|
+
}),
|
|
325
|
+
/* @__PURE__ */ T("div", {
|
|
326
|
+
className: "flex justify-end pt-4",
|
|
327
|
+
children: /* @__PURE__ */ T("button", {
|
|
328
|
+
onClick: ae,
|
|
329
|
+
disabled: k || !A || P.length === 0 || !H.trim(),
|
|
330
|
+
className: "px-6 py-3 rounded-lg bg-primary text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50 flex items-center gap-2",
|
|
331
|
+
children: k ? /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T(h, { className: "w-5 h-5 animate-spin" }), S("channel.sending", "Sending...")] }) : /* @__PURE__ */ E(w, { children: [
|
|
332
|
+
/* @__PURE__ */ T(b, { className: "w-5 h-5" }),
|
|
333
|
+
S("channel.sendTo", "Send to"),
|
|
334
|
+
" ",
|
|
335
|
+
P.length,
|
|
336
|
+
" ",
|
|
337
|
+
P.length === 1 ? S("channel.recipient", "recipient") : S("channel.recipients", "recipients")
|
|
338
|
+
] })
|
|
339
|
+
})
|
|
340
|
+
})
|
|
341
|
+
]
|
|
342
|
+
}) : /* @__PURE__ */ E("div", {
|
|
343
|
+
className: "space-y-6",
|
|
344
|
+
children: [/* @__PURE__ */ E("div", {
|
|
345
|
+
className: "p-4 rounded-lg border flex items-center justify-between",
|
|
346
|
+
children: [/* @__PURE__ */ E("div", {
|
|
347
|
+
className: "flex items-center gap-4",
|
|
348
|
+
children: [$ === 0 ? /* @__PURE__ */ T(p, { className: "w-8 h-8 text-green-500" }) : /* @__PURE__ */ T(d, { className: "w-8 h-8 text-yellow-500" }), /* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("h2", {
|
|
349
|
+
className: "text-lg font-semibold",
|
|
350
|
+
children: $ === 0 ? S("channel.allMessagesSent", "All messages sent!") : `${Q} of ${P.length} sent`
|
|
351
|
+
}), /* @__PURE__ */ E("p", {
|
|
352
|
+
className: "text-sm text-muted-foreground",
|
|
353
|
+
children: [
|
|
354
|
+
Q,
|
|
355
|
+
" ",
|
|
356
|
+
S("channel.successful", "successful"),
|
|
357
|
+
", ",
|
|
358
|
+
$,
|
|
359
|
+
" ",
|
|
360
|
+
S("channel.failed", "failed")
|
|
361
|
+
]
|
|
362
|
+
})] })]
|
|
363
|
+
}), /* @__PURE__ */ T("button", {
|
|
364
|
+
onClick: ie,
|
|
365
|
+
className: "px-4 py-2 rounded-lg border hover:bg-muted transition-colors",
|
|
366
|
+
children: S("channel.sendAnother", "Send Another")
|
|
367
|
+
})]
|
|
368
|
+
}), /* @__PURE__ */ T("div", {
|
|
369
|
+
className: "border rounded-lg divide-y",
|
|
370
|
+
children: K.map((e) => {
|
|
371
|
+
let t = P.find((t) => t.id === e.recipientId);
|
|
372
|
+
return /* @__PURE__ */ E("div", {
|
|
373
|
+
className: "p-4 flex items-center justify-between",
|
|
374
|
+
children: [/* @__PURE__ */ E("div", { children: [
|
|
375
|
+
/* @__PURE__ */ T("p", {
|
|
376
|
+
className: "text-sm font-medium",
|
|
377
|
+
children: t?.address
|
|
378
|
+
}),
|
|
379
|
+
t?.name && /* @__PURE__ */ T("p", {
|
|
380
|
+
className: "text-xs text-muted-foreground",
|
|
381
|
+
children: t.name
|
|
382
|
+
}),
|
|
383
|
+
e.messageId && /* @__PURE__ */ T("p", {
|
|
384
|
+
className: "text-xs text-muted-foreground font-mono",
|
|
385
|
+
children: e.messageId
|
|
386
|
+
}),
|
|
387
|
+
e.error && /* @__PURE__ */ T("p", {
|
|
388
|
+
className: "text-xs text-destructive",
|
|
389
|
+
children: e.error
|
|
390
|
+
})
|
|
391
|
+
] }), e.success ? /* @__PURE__ */ T(p, { className: "w-5 h-5 text-green-500" }) : /* @__PURE__ */ T(te, { className: "w-5 h-5 text-destructive" })]
|
|
392
|
+
}, e.recipientId);
|
|
393
|
+
})
|
|
394
|
+
})]
|
|
395
|
+
})
|
|
396
|
+
})]
|
|
397
|
+
})
|
|
398
|
+
});
|
|
399
|
+
}
|
|
400
|
+
//#endregion
|
|
401
|
+
export { O as SendMessagePage };
|
|
402
|
+
|
|
403
|
+
//# sourceMappingURL=SendMessagePage.js.map
|