@hartl-services/medusa-base 2.7.0 → 2.9.0
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/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginSettingsForm.js +12 -9
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +5 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +20 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +5 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +20 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.d.ts +0 -5
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.js +0 -5
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.d.ts +4 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.js +4 -0
- package/.medusa/server/src/admin/admin-components/i18n/texts.d.ts +1 -2
- package/.medusa/server/src/admin/admin-components/i18n/texts.js +1 -2
- package/.medusa/server/src/admin/index.js +142 -87
- package/.medusa/server/src/admin/index.mjs +144 -89
- package/.medusa/server/src/api/admin/email/templates/[kind]/send-test/route.js +7 -1
- package/.medusa/server/src/customer-auth/plugin-features.js +10 -10
- package/.medusa/server/src/email/application/warn-credential-expiry.js +77 -0
- package/.medusa/server/src/email/config/index.js +8 -2
- package/.medusa/server/src/email/config/notification-module.js +28 -2
- package/.medusa/server/src/email/domain/business-keys.js +5 -2
- package/.medusa/server/src/email/domain/failure-classification.js +9 -1
- package/.medusa/server/src/email/plugin-features.js +123 -1
- package/.medusa/server/src/email/rendering/default-templates.js +16 -1
- package/.medusa/server/src/email/rendering/render-email.js +2 -1
- package/.medusa/server/src/email/types/email-kinds.js +2 -1
- package/.medusa/server/src/email/types/template-data.js +8 -1
- package/.medusa/server/src/jobs/email-credential-expiry.js +27 -0
- package/.medusa/server/src/modules/email/domain/message-state.js +3 -1
- package/.medusa/server/src/modules/email/migrations/Migration20261011120000.js +20 -0
- package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +27 -6
- package/.medusa/server/src/modules/plugin-features/service.js +4 -3
- package/.medusa/server/src/providers/smtp/delivery-settings.js +75 -0
- package/.medusa/server/src/providers/smtp/graph-transport.js +150 -0
- package/.medusa/server/src/providers/smtp/service.js +105 -37
- package/.medusa/server/src/providers/smtp/types.js +7 -1
- package/.medusa/server/src/public/descriptor.js +24 -3
- package/.medusa/server/src/shared/lib/dates.js +8 -2
- package/.medusa/server/src/shop-config/build-food-shop-config.js +3 -5
- package/README.md +100 -65
- package/dist/customer-auth/plugin-features.js +9 -9
- package/dist/email/config/index.d.ts +6 -1
- package/dist/email/config/index.js +7 -1
- package/dist/email/config/notification-module.d.ts +25 -0
- package/dist/email/config/notification-module.js +27 -1
- package/dist/email/types/email-kinds.d.ts +2 -1
- package/dist/email/types/email-kinds.js +1 -0
- package/dist/email/types/template-data.d.ts +10 -0
- package/dist/email/types/template-data.js +7 -0
- package/dist/public/descriptor.js +23 -2
- package/dist/public/types.d.ts +14 -4
- package/dist/shared/lib/dates.d.ts +2 -0
- package/dist/shared/lib/dates.js +7 -1
- package/dist/shop-config/build-food-shop-config.d.ts +1 -1
- package/dist/shop-config/build-food-shop-config.js +2 -4
- package/package.json +2 -2
|
@@ -28,7 +28,8 @@ const texts = {
|
|
|
28
28
|
},
|
|
29
29
|
breadcrumbs: {
|
|
30
30
|
hub: "Plugins",
|
|
31
|
-
emailAttachments: "Anhänge"
|
|
31
|
+
emailAttachments: "Anhänge",
|
|
32
|
+
emailDelivery: "Versand"
|
|
32
33
|
},
|
|
33
34
|
page: {
|
|
34
35
|
title: "Hartl Services Plugins",
|
|
@@ -94,8 +95,6 @@ const texts = {
|
|
|
94
95
|
secretClearUndoLabel: (label) => `${label} nicht löschen`,
|
|
95
96
|
/** Shown on a secret: the settings whose change deletes it ("A", "A oder B"). */
|
|
96
97
|
invalidatedBy: (labels) => `Wird gelöscht, wenn ${labels.length > 1 ? `${labels.slice(0, -1).join(", ")} oder ${labels[labels.length - 1]}` : labels.join("")} sich ändert.`,
|
|
97
|
-
/** Shown on the changing setting: the secrets its change deletes. */
|
|
98
|
-
invalidates: (labels) => `Beim Ändern muss ${labels} neu eingegeben werden.`,
|
|
99
98
|
invalidNumber: "Bitte eine gültige Zahl eingeben.",
|
|
100
99
|
invalidColor: "Bitte eine Hex-Farbe wie #1a2b3c eingeben.",
|
|
101
100
|
colorPlaceholder: "Standard",
|
|
@@ -396,9 +395,6 @@ const disabledParent = (features, feature) => {
|
|
|
396
395
|
};
|
|
397
396
|
const invalidatedByLabels = (settings, secretKey) => settings.filter((setting) => setting.invalidates.includes(secretKey)).map((setting) => setting.label);
|
|
398
397
|
const isGroupDimmed = (features, requiresFeature) => requiresFeature !== null && features.find((feature) => feature.key === requiresFeature)?.effective_enabled === false;
|
|
399
|
-
const invalidatesLabels = (settings, setting) => setting.invalidates.map(
|
|
400
|
-
(key) => settings.find((candidate) => candidate.key === key)?.label ?? key
|
|
401
|
-
);
|
|
402
398
|
const settingInfoText = (setting) => setting.hint !== null && setting.description !== null && setting.description !== setting.hint ? setting.description : null;
|
|
403
399
|
const headerInfoText = (plugin2) => plugin2.summary !== null && plugin2.description !== null && plugin2.description !== plugin2.summary ? plugin2.description : null;
|
|
404
400
|
const showsSourceHint = (source) => source !== "default";
|
|
@@ -963,6 +959,35 @@ const changedSettingValues = (settings, draft, unparsable = []) => {
|
|
|
963
959
|
}
|
|
964
960
|
return values;
|
|
965
961
|
};
|
|
962
|
+
const DATE_PATTERN = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
963
|
+
const DATE_TIME_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/;
|
|
964
|
+
const pad = (value, length = 2) => String(value).padStart(length, "0");
|
|
965
|
+
const build = ([year, month, day, hour = 0, minute = 0]) => {
|
|
966
|
+
const date = new Date(year, month - 1, day, hour, minute);
|
|
967
|
+
const matches = date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day && date.getHours() === hour && date.getMinutes() === minute;
|
|
968
|
+
return matches ? date : null;
|
|
969
|
+
};
|
|
970
|
+
const dateFromInputValue = (value) => {
|
|
971
|
+
const match = value ? DATE_PATTERN.exec(value) : null;
|
|
972
|
+
return match ? build(match.slice(1).map(Number)) : null;
|
|
973
|
+
};
|
|
974
|
+
const inputValueFromDate = (date) => {
|
|
975
|
+
if (!date || Number.isNaN(date.getTime())) {
|
|
976
|
+
return "";
|
|
977
|
+
}
|
|
978
|
+
return `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
979
|
+
};
|
|
980
|
+
const dateTimeFromInputValue = (value) => {
|
|
981
|
+
const match = value ? DATE_TIME_PATTERN.exec(value) : null;
|
|
982
|
+
return match ? build(match.slice(1).map(Number)) : null;
|
|
983
|
+
};
|
|
984
|
+
const inputValueFromDateTime = (date) => {
|
|
985
|
+
if (!date || Number.isNaN(date.getTime())) {
|
|
986
|
+
return "";
|
|
987
|
+
}
|
|
988
|
+
return `${inputValueFromDate(date)}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
989
|
+
};
|
|
990
|
+
const AdminDatePicker = (props) => /* @__PURE__ */ jsxRuntime.jsx(ui.I18nProvider, { locale: ADMIN_LOCALE, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DatePicker, { ...props }) });
|
|
966
991
|
const buildSettingBlocks = (settings) => {
|
|
967
992
|
const blocks = [];
|
|
968
993
|
let previousSection = null;
|
|
@@ -1014,11 +1039,13 @@ const buildSettingGroups = (settings, groups, ungroupedTitle) => {
|
|
|
1014
1039
|
description: meta?.description ?? null,
|
|
1015
1040
|
note: meta?.note ?? null,
|
|
1016
1041
|
requiresFeature: meta?.requires_feature ?? null,
|
|
1042
|
+
visibleWhen: meta?.visible_when ?? null,
|
|
1017
1043
|
settings: groupSettings,
|
|
1018
1044
|
blocks: buildSettingBlocks(groupSettings)
|
|
1019
1045
|
};
|
|
1020
1046
|
});
|
|
1021
1047
|
};
|
|
1048
|
+
const isGroupVisible = (group, draft) => group.visibleWhen === null || draft[group.visibleWhen.setting] === group.visibleWhen.equals;
|
|
1022
1049
|
function usePluginSettingsForm(plugin2) {
|
|
1023
1050
|
const mutation = useUpdatePluginSettings(plugin2.plugin_key);
|
|
1024
1051
|
const [draft, setDraft] = react.useState(
|
|
@@ -1312,13 +1339,13 @@ const SettingField = ({
|
|
|
1312
1339
|
pluginKey,
|
|
1313
1340
|
setting,
|
|
1314
1341
|
invalidatedBy,
|
|
1315
|
-
invalidates,
|
|
1316
1342
|
value,
|
|
1317
1343
|
invalid,
|
|
1318
1344
|
disabled,
|
|
1319
1345
|
onChange
|
|
1320
1346
|
}) => {
|
|
1321
1347
|
const id = fieldId(pluginKey, setting.key);
|
|
1348
|
+
const labelId = `${id}-label`;
|
|
1322
1349
|
const hintId = `${id}-hint`;
|
|
1323
1350
|
const clearPending = setting.type === "secret" && value === null;
|
|
1324
1351
|
const bounds = setting.type === "number" ? boundsText(setting) : void 0;
|
|
@@ -1326,13 +1353,13 @@ const SettingField = ({
|
|
|
1326
1353
|
const info = settingInfoText(setting);
|
|
1327
1354
|
const showBounds = Boolean(bounds) && showsBoundsLine(setting);
|
|
1328
1355
|
const required = setting.required;
|
|
1329
|
-
const hasHints = Boolean(hint) || clearPending || invalidatedBy.length > 0 ||
|
|
1356
|
+
const hasHints = Boolean(hint) || clearPending || invalidatedBy.length > 0 || showBounds || invalid;
|
|
1330
1357
|
const describedBy = hasHints ? hintId : void 0;
|
|
1331
1358
|
const placeholder = setting.placeholder ?? void 0;
|
|
1332
1359
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-2", children: [
|
|
1333
1360
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1334
1361
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-x-1", children: [
|
|
1335
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { htmlFor: id, size: "small", weight: "plus", children: labelText(setting) }),
|
|
1362
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Label, { id: labelId, htmlFor: id, size: "small", weight: "plus", children: labelText(setting) }),
|
|
1336
1363
|
info && /* @__PURE__ */ jsxRuntime.jsx(InfoTooltip, { label: texts.info.label(setting.label), children: info })
|
|
1337
1364
|
] }),
|
|
1338
1365
|
showsSourceHint(setting.source) && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "xsmall", className: "text-ui-fg-muted shrink-0", children: texts.settings.source[setting.source] })
|
|
@@ -1406,6 +1433,16 @@ const SettingField = ({
|
|
|
1406
1433
|
disabled,
|
|
1407
1434
|
onChange: (next) => onChange(next)
|
|
1408
1435
|
}
|
|
1436
|
+
) : setting.type === "date" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1437
|
+
AdminDatePicker,
|
|
1438
|
+
{
|
|
1439
|
+
id,
|
|
1440
|
+
"aria-labelledby": labelId,
|
|
1441
|
+
"aria-describedby": describedBy,
|
|
1442
|
+
isDisabled: disabled,
|
|
1443
|
+
value: dateFromInputValue(typeof value === "string" ? value : ""),
|
|
1444
|
+
onChange: (date) => onChange(inputValueFromDate(date))
|
|
1445
|
+
}
|
|
1409
1446
|
) : setting.type === "number" ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
1410
1447
|
ui.Input,
|
|
1411
1448
|
{
|
|
@@ -1440,7 +1477,6 @@ const SettingField = ({
|
|
|
1440
1477
|
hint && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: hint }),
|
|
1441
1478
|
clearPending && /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { variant: "info", children: texts.settings.secretClearPending }),
|
|
1442
1479
|
invalidatedBy.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: texts.settings.invalidatedBy(invalidatedBy) }),
|
|
1443
|
-
invalidates.length > 0 && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-subtle", children: texts.settings.invalidates(invalidates.join(", ")) }),
|
|
1444
1480
|
showBounds && !invalid && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", className: "text-ui-fg-muted", children: bounds }),
|
|
1445
1481
|
invalid && /* @__PURE__ */ jsxRuntime.jsx(ui.Hint, { variant: "error", children: setting.type === "color" ? texts.settings.invalidColor : bounds ?? texts.settings.invalidNumber })
|
|
1446
1482
|
] })
|
|
@@ -1453,9 +1489,9 @@ const PluginSettingsForm = ({ plugin: plugin2 }) => {
|
|
|
1453
1489
|
plugin2.settings,
|
|
1454
1490
|
plugin2.setting_groups,
|
|
1455
1491
|
texts.sections.settings
|
|
1456
|
-
);
|
|
1492
|
+
).filter((group) => isGroupVisible(group, form.draft));
|
|
1457
1493
|
const hasTextFields = plugin2.settings.some(
|
|
1458
|
-
(setting) => setting.type === "string" || setting.type === "url" || setting.type === "number" || setting.type === "color"
|
|
1494
|
+
(setting) => setting.type === "string" || setting.type === "url" || setting.type === "number" || setting.type === "color" || setting.type === "date"
|
|
1459
1495
|
);
|
|
1460
1496
|
const renderField = (setting) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
1461
1497
|
SettingField,
|
|
@@ -1463,7 +1499,6 @@ const PluginSettingsForm = ({ plugin: plugin2 }) => {
|
|
|
1463
1499
|
pluginKey: plugin2.plugin_key,
|
|
1464
1500
|
setting,
|
|
1465
1501
|
invalidatedBy: setting.type === "secret" ? invalidatedByLabels(plugin2.settings, setting.key) : [],
|
|
1466
|
-
invalidates: invalidatesLabels(plugin2.settings, setting),
|
|
1467
1502
|
value: form.draft[setting.key],
|
|
1468
1503
|
invalid: form.invalid.includes(setting.key),
|
|
1469
1504
|
disabled: pending,
|
|
@@ -1641,29 +1676,6 @@ const PluginFeatureDisabledNotice = ({
|
|
|
1641
1676
|
]
|
|
1642
1677
|
}
|
|
1643
1678
|
);
|
|
1644
|
-
const DATE_TIME_PATTERN = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/;
|
|
1645
|
-
const pad = (value, length = 2) => String(value).padStart(length, "0");
|
|
1646
|
-
const build = ([year, month, day, hour = 0, minute = 0]) => {
|
|
1647
|
-
const date = new Date(year, month - 1, day, hour, minute);
|
|
1648
|
-
const matches = date.getFullYear() === year && date.getMonth() === month - 1 && date.getDate() === day && date.getHours() === hour && date.getMinutes() === minute;
|
|
1649
|
-
return matches ? date : null;
|
|
1650
|
-
};
|
|
1651
|
-
const inputValueFromDate = (date) => {
|
|
1652
|
-
if (!date || Number.isNaN(date.getTime())) {
|
|
1653
|
-
return "";
|
|
1654
|
-
}
|
|
1655
|
-
return `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
1656
|
-
};
|
|
1657
|
-
const dateTimeFromInputValue = (value) => {
|
|
1658
|
-
const match = value ? DATE_TIME_PATTERN.exec(value) : null;
|
|
1659
|
-
return match ? build(match.slice(1).map(Number)) : null;
|
|
1660
|
-
};
|
|
1661
|
-
const inputValueFromDateTime = (date) => {
|
|
1662
|
-
if (!date || Number.isNaN(date.getTime())) {
|
|
1663
|
-
return "";
|
|
1664
|
-
}
|
|
1665
|
-
return `${inputValueFromDate(date)}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
1666
|
-
};
|
|
1667
1679
|
const fetchPdfObjectUrl = async (path) => {
|
|
1668
1680
|
const response = await sdk.client.fetch(path, {
|
|
1669
1681
|
headers: { accept: "application/pdf" }
|
|
@@ -1751,7 +1763,6 @@ const useDebouncedValue = (value, delayMs) => {
|
|
|
1751
1763
|
}, [value, delayMs]);
|
|
1752
1764
|
return debounced;
|
|
1753
1765
|
};
|
|
1754
|
-
const AdminDatePicker = (props) => /* @__PURE__ */ jsxRuntime.jsx(ui.I18nProvider, { locale: ADMIN_LOCALE, children: /* @__PURE__ */ jsxRuntime.jsx(ui.DatePicker, { ...props }) });
|
|
1755
1766
|
const FocusModalShell = ({
|
|
1756
1767
|
open,
|
|
1757
1768
|
onOpenChange,
|
|
@@ -3510,7 +3521,7 @@ const PluginFeaturesSettingsPage = () => {
|
|
|
3510
3521
|
const config = adminSdk.defineRouteConfig({
|
|
3511
3522
|
label: texts.menu.label
|
|
3512
3523
|
});
|
|
3513
|
-
const handle$
|
|
3524
|
+
const handle$b = {
|
|
3514
3525
|
breadcrumb: () => texts.breadcrumbs.hub
|
|
3515
3526
|
};
|
|
3516
3527
|
const KINDS = [
|
|
@@ -3526,7 +3537,8 @@ const KINDS = [
|
|
|
3526
3537
|
"auth.login_code",
|
|
3527
3538
|
"affiliate.consignment_report_due",
|
|
3528
3539
|
"affiliate.application_submitted.admin",
|
|
3529
|
-
"user.invite"
|
|
3540
|
+
"user.invite",
|
|
3541
|
+
"system.credential_expiry.admin"
|
|
3530
3542
|
];
|
|
3531
3543
|
const KIND_LABELS = {
|
|
3532
3544
|
"order.received": "Bestellbestätigung (Kunde)",
|
|
@@ -3541,10 +3553,12 @@ const KIND_LABELS = {
|
|
|
3541
3553
|
"auth.login_code": "Anmeldecode",
|
|
3542
3554
|
"affiliate.consignment_report_due": "Affiliate-Meldung",
|
|
3543
3555
|
"affiliate.application_submitted.admin": "Neue Partner-Bewerbung (Shop)",
|
|
3544
|
-
"user.invite": "Admin-Einladung"
|
|
3556
|
+
"user.invite": "Admin-Einladung",
|
|
3557
|
+
"system.credential_expiry.admin": "Secret läuft ab (Shop)"
|
|
3545
3558
|
};
|
|
3546
3559
|
const EMAIL_PAGE_PATH = `${PLUGIN_HUB_PATH}/email`;
|
|
3547
3560
|
const EMAIL_ATTACHMENTS_PAGE_PATH = `${EMAIL_PAGE_PATH}/attachments`;
|
|
3561
|
+
const EMAIL_DELIVERY_PAGE_PATH = `${EMAIL_PAGE_PATH}/delivery`;
|
|
3548
3562
|
const emailAttachmentPagePath = (attachmentId) => `${EMAIL_ATTACHMENTS_PAGE_PATH}/${encodeURIComponent(attachmentId)}`;
|
|
3549
3563
|
const NO_MAIL_ASSIGNED_LABEL = "keiner Mail zugeordnet";
|
|
3550
3564
|
const MAIL_KIND_OPTIONS = email$1.EMAIL_ATTACHABLE_KINDS.map((kind) => ({
|
|
@@ -3802,52 +3816,61 @@ const LinkRow = ({
|
|
|
3802
3816
|
description,
|
|
3803
3817
|
to,
|
|
3804
3818
|
disabled
|
|
3805
|
-
}) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3806
|
-
|
|
3807
|
-
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-y-0.5", children: [
|
|
3808
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", weight: "plus", children: title }),
|
|
3809
|
-
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: description })
|
|
3810
|
-
] }),
|
|
3811
|
-
disabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3812
|
-
ui.Button,
|
|
3813
|
-
{
|
|
3814
|
-
"aria-label": texts.plugin.openLabel(title),
|
|
3815
|
-
disabled: true,
|
|
3816
|
-
size: "small",
|
|
3817
|
-
variant: "secondary",
|
|
3818
|
-
children: texts.plugin.open
|
|
3819
|
-
}
|
|
3820
|
-
) : /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { asChild: true, size: "small", variant: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { "aria-label": texts.plugin.openLabel(title), to, children: texts.plugin.open }) })
|
|
3821
|
-
] });
|
|
3822
|
-
const EmailManagementSection = ({ disabled }) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3823
|
-
AdminSection,
|
|
3819
|
+
}) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
3820
|
+
"div",
|
|
3824
3821
|
{
|
|
3825
|
-
className: `transition-opacity ${disabled ? "opacity-50" : ""}`,
|
|
3826
|
-
title: "Verwaltung",
|
|
3822
|
+
className: `flex items-center gap-4 px-6 py-3 transition-opacity ${disabled ? "opacity-50" : ""}`,
|
|
3827
3823
|
children: [
|
|
3828
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3829
|
-
|
|
3830
|
-
{
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
to: EMAIL_ATTACHMENTS_PAGE_PATH
|
|
3836
|
-
}
|
|
3837
|
-
),
|
|
3838
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3839
|
-
LinkRow,
|
|
3824
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.IconBadge, { children: icon }),
|
|
3825
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex min-w-0 flex-1 flex-col gap-y-0.5", children: [
|
|
3826
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", weight: "plus", children: title }),
|
|
3827
|
+
/* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: "small", leading: "compact", className: "text-ui-fg-subtle", children: description })
|
|
3828
|
+
] }),
|
|
3829
|
+
disabled ? /* @__PURE__ */ jsxRuntime.jsx(
|
|
3830
|
+
ui.Button,
|
|
3840
3831
|
{
|
|
3841
|
-
|
|
3842
|
-
disabled,
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3832
|
+
"aria-label": texts.plugin.openLabel(title),
|
|
3833
|
+
disabled: true,
|
|
3834
|
+
size: "small",
|
|
3835
|
+
variant: "secondary",
|
|
3836
|
+
children: texts.plugin.open
|
|
3846
3837
|
}
|
|
3847
|
-
)
|
|
3838
|
+
) : /* @__PURE__ */ jsxRuntime.jsx(ui.Button, { asChild: true, size: "small", variant: "secondary", children: /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Link, { "aria-label": texts.plugin.openLabel(title), to, children: texts.plugin.open }) })
|
|
3848
3839
|
]
|
|
3849
3840
|
}
|
|
3850
3841
|
);
|
|
3842
|
+
const EmailManagementSection = ({ disabled }) => /* @__PURE__ */ jsxRuntime.jsxs(AdminSection, { title: "Verwaltung", children: [
|
|
3843
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3844
|
+
LinkRow,
|
|
3845
|
+
{
|
|
3846
|
+
description: "SMTP oder Microsoft 365.",
|
|
3847
|
+
disabled: false,
|
|
3848
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
|
|
3849
|
+
title: texts.breadcrumbs.emailDelivery,
|
|
3850
|
+
to: EMAIL_DELIVERY_PAGE_PATH
|
|
3851
|
+
}
|
|
3852
|
+
),
|
|
3853
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3854
|
+
LinkRow,
|
|
3855
|
+
{
|
|
3856
|
+
description: "PDFs an Kunden-Mails, z. B. AGB.",
|
|
3857
|
+
disabled,
|
|
3858
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperClip, {}),
|
|
3859
|
+
title: "Anhänge",
|
|
3860
|
+
to: EMAIL_ATTACHMENTS_PAGE_PATH
|
|
3861
|
+
}
|
|
3862
|
+
),
|
|
3863
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
3864
|
+
LinkRow,
|
|
3865
|
+
{
|
|
3866
|
+
description: "Status und Zustellversuche.",
|
|
3867
|
+
disabled,
|
|
3868
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.ClockSolid, {}),
|
|
3869
|
+
title: "E-Mail-Protokoll",
|
|
3870
|
+
to: EMAIL_LOG_PAGE_PATH
|
|
3871
|
+
}
|
|
3872
|
+
)
|
|
3873
|
+
] });
|
|
3851
3874
|
const EmailOverviewSections = () => {
|
|
3852
3875
|
const plugin2 = usePluginFeature("email").data?.plugin;
|
|
3853
3876
|
if (!plugin2) {
|
|
@@ -3859,7 +3882,7 @@ const EmailOverviewSections = () => {
|
|
|
3859
3882
|
] });
|
|
3860
3883
|
};
|
|
3861
3884
|
const EmailOverviewPage = () => /* @__PURE__ */ jsxRuntime.jsx(PluginPageShell, { pluginKey: "email", variant: "header", children: /* @__PURE__ */ jsxRuntime.jsx(EmailOverviewSections, {}) });
|
|
3862
|
-
const handle$
|
|
3885
|
+
const handle$a = {
|
|
3863
3886
|
breadcrumb: (_match) => /* @__PURE__ */ jsxRuntime.jsx(PluginLabelCrumb, { pluginKey: "email" })
|
|
3864
3887
|
};
|
|
3865
3888
|
const EMAIL_TEMPLATES_PATH = `${EMAIL_PAGE_PATH}/templates`;
|
|
@@ -3979,11 +4002,11 @@ const EmailTemplateGroupPage = ({
|
|
|
3979
4002
|
) })
|
|
3980
4003
|
] });
|
|
3981
4004
|
};
|
|
3982
|
-
const handle$
|
|
4005
|
+
const handle$9 = {
|
|
3983
4006
|
breadcrumb: () => EMAIL_TEMPLATE_GROUPS.account.label
|
|
3984
4007
|
};
|
|
3985
4008
|
const EmailAccountMailsRoute = () => /* @__PURE__ */ jsxRuntime.jsx(PluginFeatureRoute, { pluginKey: "email", children: /* @__PURE__ */ jsxRuntime.jsx(EmailTemplateGroupPage, { group: "account" }) });
|
|
3986
|
-
const handle$
|
|
4009
|
+
const handle$8 = {
|
|
3987
4010
|
breadcrumb: () => EMAIL_TEMPLATE_GROUPS.affiliate.label
|
|
3988
4011
|
};
|
|
3989
4012
|
const EmailAffiliateMailsRoute = () => /* @__PURE__ */ jsxRuntime.jsx(PluginFeatureRoute, { pluginKey: "email", children: /* @__PURE__ */ jsxRuntime.jsx(EmailTemplateGroupPage, { group: "affiliate" }) });
|
|
@@ -4384,10 +4407,37 @@ const EmailAttachmentsPage = () => {
|
|
|
4384
4407
|
/* @__PURE__ */ jsxRuntime.jsx(NewAttachmentModal, { onOpenChange: setNewOpen, open: newOpen })
|
|
4385
4408
|
] });
|
|
4386
4409
|
};
|
|
4387
|
-
const handle$
|
|
4410
|
+
const handle$7 = {
|
|
4388
4411
|
breadcrumb: () => texts.breadcrumbs.emailAttachments
|
|
4389
4412
|
};
|
|
4390
4413
|
const EmailAttachmentsRoute = () => /* @__PURE__ */ jsxRuntime.jsx(PluginFeatureRoute, { pluginKey: "email", children: /* @__PURE__ */ jsxRuntime.jsx(EmailAttachmentsPage, {}) });
|
|
4414
|
+
const EmailDeliveryPage = () => {
|
|
4415
|
+
const query = usePluginFeature("email");
|
|
4416
|
+
const plugin2 = query.data?.plugin;
|
|
4417
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-col gap-y-3", children: [
|
|
4418
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
4419
|
+
AdminPageHeader,
|
|
4420
|
+
{
|
|
4421
|
+
badges: plugin2 && /* @__PURE__ */ jsxRuntime.jsx(ui.StatusBadge, { color: plugin2.configured ? "green" : "orange", children: plugin2.configured ? texts.chips.configured : texts.chips.notConfigured }),
|
|
4422
|
+
description: "SMTP oder Microsoft 365.",
|
|
4423
|
+
icon: /* @__PURE__ */ jsxRuntime.jsx(icons.PaperPlane, {}),
|
|
4424
|
+
title: texts.breadcrumbs.emailDelivery
|
|
4425
|
+
}
|
|
4426
|
+
),
|
|
4427
|
+
plugin2 ? /* @__PURE__ */ jsxRuntime.jsx(PluginSettingsForm, { plugin: plugin2 }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { className: "p-0", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
4428
|
+
QueryState,
|
|
4429
|
+
{
|
|
4430
|
+
error: query.error,
|
|
4431
|
+
errorText: texts.states.error,
|
|
4432
|
+
isLoading: query.isPending,
|
|
4433
|
+
loadingText: texts.states.loading
|
|
4434
|
+
}
|
|
4435
|
+
) })
|
|
4436
|
+
] });
|
|
4437
|
+
};
|
|
4438
|
+
const handle$6 = {
|
|
4439
|
+
breadcrumb: () => texts.breadcrumbs.emailDelivery
|
|
4440
|
+
};
|
|
4391
4441
|
const LOG_PAGE_SIZE = 20;
|
|
4392
4442
|
const LOG_MAX_OFFSET = 1e4;
|
|
4393
4443
|
const LOG_MAX_RESOURCE_ID_LENGTH = 255;
|
|
@@ -6687,26 +6737,31 @@ const routeModule = {
|
|
|
6687
6737
|
{
|
|
6688
6738
|
Component: PluginFeaturesSettingsPage,
|
|
6689
6739
|
path: "/settings/hartl-services",
|
|
6690
|
-
handle: { label: config.label, translationNs: config.translationNs, ...handle$
|
|
6740
|
+
handle: { label: config.label, translationNs: config.translationNs, ...handle$b }
|
|
6691
6741
|
},
|
|
6692
6742
|
{
|
|
6693
6743
|
Component: EmailOverviewPage,
|
|
6694
6744
|
path: "/settings/hartl-services/email",
|
|
6695
|
-
handle: handle$
|
|
6745
|
+
handle: handle$a
|
|
6696
6746
|
},
|
|
6697
6747
|
{
|
|
6698
6748
|
Component: EmailAccountMailsRoute,
|
|
6699
6749
|
path: "/settings/hartl-services/email/account",
|
|
6700
|
-
handle: handle$
|
|
6750
|
+
handle: handle$9
|
|
6701
6751
|
},
|
|
6702
6752
|
{
|
|
6703
6753
|
Component: EmailAffiliateMailsRoute,
|
|
6704
6754
|
path: "/settings/hartl-services/email/affiliate",
|
|
6705
|
-
handle: handle$
|
|
6755
|
+
handle: handle$8
|
|
6706
6756
|
},
|
|
6707
6757
|
{
|
|
6708
6758
|
Component: EmailAttachmentsRoute,
|
|
6709
6759
|
path: "/settings/hartl-services/email/attachments",
|
|
6760
|
+
handle: handle$7
|
|
6761
|
+
},
|
|
6762
|
+
{
|
|
6763
|
+
Component: EmailDeliveryPage,
|
|
6764
|
+
path: "/settings/hartl-services/email/delivery",
|
|
6710
6765
|
handle: handle$6
|
|
6711
6766
|
},
|
|
6712
6767
|
{
|