@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
|
@@ -4,9 +4,11 @@ import { texts } from "../../../i18n/texts";
|
|
|
4
4
|
import { AdminSection } from "../../../shared/ui/AdminSection";
|
|
5
5
|
import { InfoTooltip } from "../../../shared/ui/InfoTooltip";
|
|
6
6
|
import { SwitchRow } from "../../../shared/ui/SwitchRow";
|
|
7
|
-
import { invalidatedByLabels,
|
|
7
|
+
import { invalidatedByLabels, isGroupDimmed, settingInfoText, showsBoundsLine, showsSourceHint, } from "../lib/plugin-view";
|
|
8
8
|
import { isHexColor, normalizeColorInput } from "../lib/settings-draft";
|
|
9
|
-
import {
|
|
9
|
+
import { dateFromInputValue, inputValueFromDate } from "../../../shared/lib/date-input";
|
|
10
|
+
import { AdminDatePicker } from "../../../shared/ui/AdminDatePicker";
|
|
11
|
+
import { buildSettingGroups, isGroupVisible, } from "../lib/settings-layout";
|
|
10
12
|
import { usePluginSettingsForm } from "../hooks/usePluginSettingsForm";
|
|
11
13
|
import { ImageSettingInput } from "./ImageSettingInput";
|
|
12
14
|
const fieldId = (pluginKey, key) => `plugin-setting-${pluginKey}-${key}`;
|
|
@@ -34,8 +36,9 @@ const ColorSettingInput = ({ id, hintId, label, value, invalid, required, disabl
|
|
|
34
36
|
className: `h-8 w-10 shrink-0 cursor-pointer rounded-md border border-ui-border-base bg-ui-bg-field p-1 disabled:cursor-not-allowed ${hasColor ? "" : "opacity-30"}`, value: hasColor ? value.trim() : "#000000", disabled: disabled, onChange: (event) => onChange(normalizeColorInput(event.target.value)) })] }));
|
|
35
37
|
};
|
|
36
38
|
/** A non-boolean setting: label (with source hint), control and hints. */
|
|
37
|
-
const SettingField = ({ pluginKey, setting, invalidatedBy,
|
|
39
|
+
const SettingField = ({ pluginKey, setting, invalidatedBy, value, invalid, disabled, onChange, }) => {
|
|
38
40
|
const id = fieldId(pluginKey, setting.key);
|
|
41
|
+
const labelId = `${id}-label`;
|
|
39
42
|
const hintId = `${id}-hint`;
|
|
40
43
|
const clearPending = setting.type === "secret" && value === null;
|
|
41
44
|
const bounds = setting.type === "number" ? boundsText(setting) : undefined;
|
|
@@ -46,30 +49,30 @@ const SettingField = ({ pluginKey, setting, invalidatedBy, invalidates, value, i
|
|
|
46
49
|
const hasHints = Boolean(hint) ||
|
|
47
50
|
clearPending ||
|
|
48
51
|
invalidatedBy.length > 0 ||
|
|
49
|
-
invalidates.length > 0 ||
|
|
50
52
|
showBounds ||
|
|
51
53
|
invalid;
|
|
52
54
|
const describedBy = hasHints ? hintId : undefined;
|
|
53
55
|
const placeholder = setting.placeholder ?? undefined;
|
|
54
|
-
return (_jsxs("div", { className: "flex flex-col gap-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-x-1", children: [_jsx(Label, { htmlFor: id, size: "small", weight: "plus", children: labelText(setting) }), info && (_jsx(InfoTooltip, { label: texts.info.label(setting.label), children: info }))] }), showsSourceHint(setting.source) && (_jsx(Text, { size: "xsmall", className: "text-ui-fg-muted shrink-0", children: texts.settings.source[setting.source] }))] }), setting.type === "secret" ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { id: id, "aria-describedby": describedBy, "aria-required": required || undefined, className: "flex-1", type: "password", autoComplete: "new-password", placeholder: setting.is_set ? texts.settings.secretPlaceholder : placeholder, value: typeof value === "string" ? value : "", disabled: disabled || clearPending, onChange: (event) => onChange(event.target.value) }), setting.source === "stored" && (_jsx(Button, { type: "button", size: "small", variant: "secondary", disabled: disabled, "aria-label": clearPending
|
|
56
|
+
return (_jsxs("div", { className: "flex flex-col gap-y-2", children: [_jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsxs("div", { className: "flex items-center gap-x-1", children: [_jsx(Label, { id: labelId, htmlFor: id, size: "small", weight: "plus", children: labelText(setting) }), info && (_jsx(InfoTooltip, { label: texts.info.label(setting.label), children: info }))] }), showsSourceHint(setting.source) && (_jsx(Text, { size: "xsmall", className: "text-ui-fg-muted shrink-0", children: texts.settings.source[setting.source] }))] }), setting.type === "secret" ? (_jsxs("div", { className: "flex items-center gap-2", children: [_jsx(Input, { id: id, "aria-describedby": describedBy, "aria-required": required || undefined, className: "flex-1", type: "password", autoComplete: "new-password", placeholder: setting.is_set ? texts.settings.secretPlaceholder : placeholder, value: typeof value === "string" ? value : "", disabled: disabled || clearPending, onChange: (event) => onChange(event.target.value) }), setting.source === "stored" && (_jsx(Button, { type: "button", size: "small", variant: "secondary", disabled: disabled, "aria-label": clearPending
|
|
55
57
|
? texts.settings.secretClearUndoLabel(setting.label)
|
|
56
58
|
: texts.settings.secretClearLabel(setting.label), onClick: () => onChange(clearPending ? "" : null), children: clearPending
|
|
57
59
|
? texts.settings.secretClearUndo
|
|
58
|
-
: texts.settings.secretClear }))] })) : setting.type === "select" ? (_jsxs(Select, { value: typeof value === "string" ? value : "", disabled: disabled, onValueChange: (next) => onChange(next), children: [_jsx(Select.Trigger, { id: id, "aria-describedby": describedBy, "aria-required": required || undefined, children: _jsx(Select.Value, { placeholder: texts.settings.selectPlaceholder }) }), _jsx(Select.Content, { children: setting.options.map((option) => (_jsx(Select.Item, { value: option.value, children: option.label }, option.value))) })] })) : setting.type === "image" ? (_jsx(ImageSettingInput, { id: id, describedBy: describedBy, label: setting.label, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (url) => onChange(url) })) : setting.type === "color" ? (_jsx(ColorSettingInput, { id: id, hintId: describedBy, label: setting.label, value: typeof value === "string" ? value : "", invalid: invalid, required: required, disabled: disabled, onChange: (next) => onChange(next) })) : setting.type === "number" ? (_jsx(Input, { id: id, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-required": required || undefined, type: "number", step: setting.integer ? 1 : "any", min: setting.min ?? undefined, max: setting.max ?? undefined, placeholder: placeholder, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value, event.target.validity.badInput) })) : (_jsx(Input, { id: id, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-required": required || undefined, type: setting.type === "url" ? "url" : "text", placeholder: placeholder, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value) })), hasHints && (_jsxs("div", { id: hintId, className: "flex flex-col gap-y-1", children: [hint && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: hint })), clearPending && (_jsx(Hint, { variant: "info", children: texts.settings.secretClearPending })), invalidatedBy.length > 0 && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: texts.settings.invalidatedBy(invalidatedBy) })),
|
|
60
|
+
: texts.settings.secretClear }))] })) : setting.type === "select" ? (_jsxs(Select, { value: typeof value === "string" ? value : "", disabled: disabled, onValueChange: (next) => onChange(next), children: [_jsx(Select.Trigger, { id: id, "aria-describedby": describedBy, "aria-required": required || undefined, children: _jsx(Select.Value, { placeholder: texts.settings.selectPlaceholder }) }), _jsx(Select.Content, { children: setting.options.map((option) => (_jsx(Select.Item, { value: option.value, children: option.label }, option.value))) })] })) : setting.type === "image" ? (_jsx(ImageSettingInput, { id: id, describedBy: describedBy, label: setting.label, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (url) => onChange(url) })) : setting.type === "color" ? (_jsx(ColorSettingInput, { id: id, hintId: describedBy, label: setting.label, value: typeof value === "string" ? value : "", invalid: invalid, required: required, disabled: disabled, onChange: (next) => onChange(next) })) : setting.type === "date" ? (_jsx(AdminDatePicker, { id: id, "aria-labelledby": labelId, "aria-describedby": describedBy, isDisabled: disabled, value: dateFromInputValue(typeof value === "string" ? value : ""), onChange: (date) => onChange(inputValueFromDate(date)) })) : setting.type === "number" ? (_jsx(Input, { id: id, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-required": required || undefined, type: "number", step: setting.integer ? 1 : "any", min: setting.min ?? undefined, max: setting.max ?? undefined, placeholder: placeholder, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value, event.target.validity.badInput) })) : (_jsx(Input, { id: id, "aria-describedby": describedBy, "aria-invalid": invalid, "aria-required": required || undefined, type: setting.type === "url" ? "url" : "text", placeholder: placeholder, value: typeof value === "string" ? value : "", disabled: disabled, onChange: (event) => onChange(event.target.value) })), hasHints && (_jsxs("div", { id: hintId, className: "flex flex-col gap-y-1", children: [hint && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: hint })), clearPending && (_jsx(Hint, { variant: "info", children: texts.settings.secretClearPending })), invalidatedBy.length > 0 && (_jsx(Text, { size: "small", className: "text-ui-fg-subtle", children: texts.settings.invalidatedBy(invalidatedBy) })), showBounds && !invalid && (_jsx(Text, { size: "small", className: "text-ui-fg-muted", children: bounds })), invalid && (_jsx(Hint, { variant: "error", children: setting.type === "color"
|
|
59
61
|
? texts.settings.invalidColor
|
|
60
62
|
: (bounds ?? texts.settings.invalidNumber) }))] }))] }));
|
|
61
63
|
};
|
|
62
64
|
export const PluginSettingsForm = ({ plugin }) => {
|
|
63
65
|
const form = usePluginSettingsForm(plugin);
|
|
64
66
|
const pending = form.mutation.isPending;
|
|
65
|
-
const groups = buildSettingGroups(plugin.settings, plugin.setting_groups, texts.sections.settings);
|
|
67
|
+
const groups = buildSettingGroups(plugin.settings, plugin.setting_groups, texts.sections.settings).filter((group) => isGroupVisible(group, form.draft));
|
|
66
68
|
const hasTextFields = plugin.settings.some((setting) => setting.type === "string" ||
|
|
67
69
|
setting.type === "url" ||
|
|
68
70
|
setting.type === "number" ||
|
|
69
|
-
setting.type === "color"
|
|
71
|
+
setting.type === "color" ||
|
|
72
|
+
setting.type === "date");
|
|
70
73
|
const renderField = (setting) => (_jsx(SettingField, { pluginKey: plugin.plugin_key, setting: setting, invalidatedBy: setting.type === "secret"
|
|
71
74
|
? invalidatedByLabels(plugin.settings, setting.key)
|
|
72
|
-
: [],
|
|
75
|
+
: [], value: form.draft[setting.key], invalid: form.invalid.includes(setting.key), disabled: pending, onChange: (value, badInput) => form.setValue(setting.key, value, badInput) }, setting.key));
|
|
73
76
|
// `dimmed`: the group's required feature is off; the rows stay editable.
|
|
74
77
|
const renderBlock = (block, dimmed) => {
|
|
75
78
|
const dim = dimmed ? "opacity-50 transition-opacity" : "transition-opacity";
|
|
@@ -90,7 +90,7 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
|
|
|
90
90
|
width: "full" | "half";
|
|
91
91
|
section: string | null;
|
|
92
92
|
} | {
|
|
93
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
93
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
94
94
|
default: string | number | boolean | null;
|
|
95
95
|
value: string | number | boolean | null;
|
|
96
96
|
key: string;
|
|
@@ -130,6 +130,10 @@ export declare const pluginFeatureEnabledQueryOptions: (pluginKey: string, featu
|
|
|
130
130
|
description: string | null;
|
|
131
131
|
note: string | null;
|
|
132
132
|
requires_feature: string | null;
|
|
133
|
+
visible_when: {
|
|
134
|
+
setting: string;
|
|
135
|
+
equals: string | boolean;
|
|
136
|
+
} | null;
|
|
133
137
|
}[];
|
|
134
138
|
}[];
|
|
135
139
|
}>;
|
|
@@ -70,7 +70,7 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
|
|
|
70
70
|
width: "full" | "half";
|
|
71
71
|
section: string | null;
|
|
72
72
|
} | {
|
|
73
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
73
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
74
74
|
default: string | number | boolean | null;
|
|
75
75
|
value: string | number | boolean | null;
|
|
76
76
|
key: string;
|
|
@@ -110,6 +110,10 @@ export declare function usePluginFeatures(): import("@tanstack/react-query").Use
|
|
|
110
110
|
description: string | null;
|
|
111
111
|
note: string | null;
|
|
112
112
|
requires_feature: string | null;
|
|
113
|
+
visible_when: {
|
|
114
|
+
setting: string;
|
|
115
|
+
equals: string | boolean;
|
|
116
|
+
} | null;
|
|
113
117
|
}[];
|
|
114
118
|
}[];
|
|
115
119
|
}, Error>;
|
|
@@ -192,7 +196,7 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
|
|
|
192
196
|
width: "full" | "half";
|
|
193
197
|
section: string | null;
|
|
194
198
|
} | {
|
|
195
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
199
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
196
200
|
default: string | number | boolean | null;
|
|
197
201
|
value: string | number | boolean | null;
|
|
198
202
|
key: string;
|
|
@@ -232,6 +236,10 @@ export declare function usePluginFeature(pluginKey: string | undefined): import(
|
|
|
232
236
|
description: string | null;
|
|
233
237
|
note: string | null;
|
|
234
238
|
requires_feature: string | null;
|
|
239
|
+
visible_when: {
|
|
240
|
+
setting: string;
|
|
241
|
+
equals: string | boolean;
|
|
242
|
+
} | null;
|
|
235
243
|
}[];
|
|
236
244
|
};
|
|
237
245
|
}, Error>;
|
|
@@ -308,7 +316,7 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
|
|
|
308
316
|
width: "full" | "half";
|
|
309
317
|
section: string | null;
|
|
310
318
|
} | {
|
|
311
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
319
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
312
320
|
default: string | number | boolean | null;
|
|
313
321
|
value: string | number | boolean | null;
|
|
314
322
|
key: string;
|
|
@@ -348,6 +356,10 @@ export declare function useUpdatePluginFeatures(): import("@tanstack/react-query
|
|
|
348
356
|
description: string | null;
|
|
349
357
|
note: string | null;
|
|
350
358
|
requires_feature: string | null;
|
|
359
|
+
visible_when: {
|
|
360
|
+
setting: string;
|
|
361
|
+
equals: string | boolean;
|
|
362
|
+
} | null;
|
|
351
363
|
}[];
|
|
352
364
|
};
|
|
353
365
|
}, Error, {
|
|
@@ -428,7 +440,7 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
|
|
|
428
440
|
width: "full" | "half";
|
|
429
441
|
section: string | null;
|
|
430
442
|
} | {
|
|
431
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
443
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
432
444
|
default: string | number | boolean | null;
|
|
433
445
|
value: string | number | boolean | null;
|
|
434
446
|
key: string;
|
|
@@ -468,6 +480,10 @@ export declare function useUpdatePluginSettings(pluginKey: string): import("@tan
|
|
|
468
480
|
description: string | null;
|
|
469
481
|
note: string | null;
|
|
470
482
|
requires_feature: string | null;
|
|
483
|
+
visible_when: {
|
|
484
|
+
setting: string;
|
|
485
|
+
equals: string | boolean;
|
|
486
|
+
} | null;
|
|
471
487
|
}[];
|
|
472
488
|
};
|
|
473
489
|
}, Error, {
|
|
@@ -79,7 +79,7 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
|
|
|
79
79
|
width: "full" | "half";
|
|
80
80
|
section: string | null;
|
|
81
81
|
} | {
|
|
82
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
82
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
83
83
|
default: string | number | boolean | null;
|
|
84
84
|
value: string | number | boolean | null;
|
|
85
85
|
key: string;
|
|
@@ -119,6 +119,10 @@ export declare function usePluginSettingsForm(plugin: AdminPluginFeatures): {
|
|
|
119
119
|
description: string | null;
|
|
120
120
|
note: string | null;
|
|
121
121
|
requires_feature: string | null;
|
|
122
|
+
visible_when: {
|
|
123
|
+
setting: string;
|
|
124
|
+
equals: string | boolean;
|
|
125
|
+
} | null;
|
|
122
126
|
}[];
|
|
123
127
|
};
|
|
124
128
|
}, Error, {
|
|
@@ -71,7 +71,7 @@ export declare const listPluginFeatures: () => Promise<{
|
|
|
71
71
|
width: "full" | "half";
|
|
72
72
|
section: string | null;
|
|
73
73
|
} | {
|
|
74
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
74
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
75
75
|
default: string | number | boolean | null;
|
|
76
76
|
value: string | number | boolean | null;
|
|
77
77
|
key: string;
|
|
@@ -111,6 +111,10 @@ export declare const listPluginFeatures: () => Promise<{
|
|
|
111
111
|
description: string | null;
|
|
112
112
|
note: string | null;
|
|
113
113
|
requires_feature: string | null;
|
|
114
|
+
visible_when: {
|
|
115
|
+
setting: string;
|
|
116
|
+
equals: string | boolean;
|
|
117
|
+
} | null;
|
|
114
118
|
}[];
|
|
115
119
|
}[];
|
|
116
120
|
}>;
|
|
@@ -186,7 +190,7 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
|
186
190
|
width: "full" | "half";
|
|
187
191
|
section: string | null;
|
|
188
192
|
} | {
|
|
189
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
193
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
190
194
|
default: string | number | boolean | null;
|
|
191
195
|
value: string | number | boolean | null;
|
|
192
196
|
key: string;
|
|
@@ -226,6 +230,10 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
|
226
230
|
description: string | null;
|
|
227
231
|
note: string | null;
|
|
228
232
|
requires_feature: string | null;
|
|
233
|
+
visible_when: {
|
|
234
|
+
setting: string;
|
|
235
|
+
equals: string | boolean;
|
|
236
|
+
} | null;
|
|
229
237
|
}[];
|
|
230
238
|
};
|
|
231
239
|
}>;
|
|
@@ -301,7 +309,7 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
|
|
|
301
309
|
width: "full" | "half";
|
|
302
310
|
section: string | null;
|
|
303
311
|
} | {
|
|
304
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
312
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
305
313
|
default: string | number | boolean | null;
|
|
306
314
|
value: string | number | boolean | null;
|
|
307
315
|
key: string;
|
|
@@ -341,6 +349,10 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
|
|
|
341
349
|
description: string | null;
|
|
342
350
|
note: string | null;
|
|
343
351
|
requires_feature: string | null;
|
|
352
|
+
visible_when: {
|
|
353
|
+
setting: string;
|
|
354
|
+
equals: string | boolean;
|
|
355
|
+
} | null;
|
|
344
356
|
}[];
|
|
345
357
|
};
|
|
346
358
|
}>;
|
|
@@ -416,7 +428,7 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
|
|
|
416
428
|
width: "full" | "half";
|
|
417
429
|
section: string | null;
|
|
418
430
|
} | {
|
|
419
|
-
type: "string" | "boolean" | "color" | "image" | "url";
|
|
431
|
+
type: "string" | "boolean" | "color" | "image" | "url" | "date";
|
|
420
432
|
default: string | number | boolean | null;
|
|
421
433
|
value: string | number | boolean | null;
|
|
422
434
|
key: string;
|
|
@@ -456,6 +468,10 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
|
|
|
456
468
|
description: string | null;
|
|
457
469
|
note: string | null;
|
|
458
470
|
requires_feature: string | null;
|
|
471
|
+
visible_when: {
|
|
472
|
+
setting: string;
|
|
473
|
+
equals: string | boolean;
|
|
474
|
+
} | null;
|
|
459
475
|
}[];
|
|
460
476
|
};
|
|
461
477
|
}>;
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.d.ts
CHANGED
|
@@ -27,11 +27,6 @@ export declare const disabledParent: (features: readonly AdminPluginFeature[], f
|
|
|
27
27
|
export declare const invalidatedByLabels: (settings: readonly AdminPluginSetting[], secretKey: string) => string[];
|
|
28
28
|
/** Whether a settings group is dimmed: its required feature exists and is not effective. */
|
|
29
29
|
export declare const isGroupDimmed: (features: readonly AdminPluginFeature[], requiresFeature: string | null) => boolean;
|
|
30
|
-
/**
|
|
31
|
-
* Labels of the secrets that a change of `setting` deletes (forward
|
|
32
|
-
* `invalidates`), in the setting's order; unknown keys fall back to the key.
|
|
33
|
-
*/
|
|
34
|
-
export declare const invalidatesLabels: (settings: readonly AdminPluginSetting[], setting: Pick<AdminPluginSetting, "invalidates">) => string[];
|
|
35
30
|
/**
|
|
36
31
|
* The description a setting shows in its info tooltip: only when a `hint`
|
|
37
32
|
* takes the place under the field and the description says something else.
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.js
CHANGED
|
@@ -41,11 +41,6 @@ export const invalidatedByLabels = (settings, secretKey) => settings
|
|
|
41
41
|
export const isGroupDimmed = (features, requiresFeature) => requiresFeature !== null &&
|
|
42
42
|
features.find((feature) => feature.key === requiresFeature)
|
|
43
43
|
?.effective_enabled === false;
|
|
44
|
-
/**
|
|
45
|
-
* Labels of the secrets that a change of `setting` deletes (forward
|
|
46
|
-
* `invalidates`), in the setting's order; unknown keys fall back to the key.
|
|
47
|
-
*/
|
|
48
|
-
export const invalidatesLabels = (settings, setting) => setting.invalidates.map((key) => settings.find((candidate) => candidate.key === key)?.label ?? key);
|
|
49
44
|
/**
|
|
50
45
|
* The description a setting shows in its info tooltip: only when a `hint`
|
|
51
46
|
* takes the place under the field and the description says something else.
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.d.ts
CHANGED
|
@@ -30,6 +30,8 @@ export type SettingGroupView = {
|
|
|
30
30
|
description: string | null;
|
|
31
31
|
note: string | null;
|
|
32
32
|
requiresFeature: string | null;
|
|
33
|
+
/** The group applies only while this setting's draft value equals `equals`. */
|
|
34
|
+
visibleWhen: AdminPluginSettingGroup["visible_when"];
|
|
33
35
|
settings: AdminPluginSetting[];
|
|
34
36
|
blocks: SettingBlock[];
|
|
35
37
|
};
|
|
@@ -41,3 +43,5 @@ export declare const buildSettingBlocks: (settings: readonly AdminPluginSetting[
|
|
|
41
43
|
* `groups` supplies the description, note and required feature per group.
|
|
42
44
|
*/
|
|
43
45
|
export declare const buildSettingGroups: (settings: readonly AdminPluginSetting[], groups: readonly AdminPluginSettingGroup[], ungroupedTitle: string) => SettingGroupView[];
|
|
46
|
+
/** Whether a group's `visible_when` holds for the current form values. */
|
|
47
|
+
export declare const isGroupVisible: (group: Pick<SettingGroupView, "visibleWhen">, draft: Readonly<Record<string, string | boolean | null>>) => boolean;
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.js
CHANGED
|
@@ -59,8 +59,12 @@ export const buildSettingGroups = (settings, groups, ungroupedTitle) => {
|
|
|
59
59
|
description: meta?.description ?? null,
|
|
60
60
|
note: meta?.note ?? null,
|
|
61
61
|
requiresFeature: meta?.requires_feature ?? null,
|
|
62
|
+
visibleWhen: meta?.visible_when ?? null,
|
|
62
63
|
settings: groupSettings,
|
|
63
64
|
blocks: buildSettingBlocks(groupSettings),
|
|
64
65
|
};
|
|
65
66
|
});
|
|
66
67
|
};
|
|
68
|
+
/** Whether a group's `visible_when` holds for the current form values. */
|
|
69
|
+
export const isGroupVisible = (group, draft) => group.visibleWhen === null ||
|
|
70
|
+
draft[group.visibleWhen.setting] === group.visibleWhen.equals;
|
|
@@ -5,6 +5,7 @@ export declare const texts: {
|
|
|
5
5
|
breadcrumbs: {
|
|
6
6
|
hub: string;
|
|
7
7
|
emailAttachments: string;
|
|
8
|
+
emailDelivery: string;
|
|
8
9
|
};
|
|
9
10
|
page: {
|
|
10
11
|
title: string;
|
|
@@ -70,8 +71,6 @@ export declare const texts: {
|
|
|
70
71
|
secretClearUndoLabel: (label: string) => string;
|
|
71
72
|
/** Shown on a secret: the settings whose change deletes it ("A", "A oder B"). */
|
|
72
73
|
invalidatedBy: (labels: readonly string[]) => string;
|
|
73
|
-
/** Shown on the changing setting: the secrets its change deletes. */
|
|
74
|
-
invalidates: (labels: string) => string;
|
|
75
74
|
invalidNumber: string;
|
|
76
75
|
invalidColor: string;
|
|
77
76
|
colorPlaceholder: string;
|
|
@@ -5,6 +5,7 @@ export const texts = {
|
|
|
5
5
|
breadcrumbs: {
|
|
6
6
|
hub: "Plugins",
|
|
7
7
|
emailAttachments: "Anhänge",
|
|
8
|
+
emailDelivery: "Versand",
|
|
8
9
|
},
|
|
9
10
|
page: {
|
|
10
11
|
title: "Hartl Services Plugins",
|
|
@@ -72,8 +73,6 @@ export const texts = {
|
|
|
72
73
|
invalidatedBy: (labels) => `Wird gelöscht, wenn ${labels.length > 1
|
|
73
74
|
? `${labels.slice(0, -1).join(", ")} oder ${labels[labels.length - 1]}`
|
|
74
75
|
: labels.join("")} sich ändert.`,
|
|
75
|
-
/** Shown on the changing setting: the secrets its change deletes. */
|
|
76
|
-
invalidates: (labels) => `Beim Ändern muss ${labels} neu eingegeben werden.`,
|
|
77
76
|
invalidNumber: "Bitte eine gültige Zahl eingeben.",
|
|
78
77
|
invalidColor: "Bitte eine Hex-Farbe wie #1a2b3c eingeben.",
|
|
79
78
|
colorPlaceholder: "Standard",
|