@hartl-services/medusa-base 2.6.0 → 2.7.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/ImageSettingInput.d.ts +3 -2
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ImageSettingInput.js +4 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginActionsSection.js +4 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginBreadcrumb.d.ts +16 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginBreadcrumb.js +25 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginDetailPage.js +1 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeatureSections.d.ts +5 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeatureSections.js +8 -5
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesCard.d.ts +4 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesCard.js +24 -27
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.d.ts +2 -2
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginFeaturesSettingsPage.js +9 -9
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginHubCard.d.ts +5 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginHubCard.js +11 -15
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginPageShell.d.ts +10 -4
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginPageShell.js +10 -5
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginSettingsForm.d.ts +0 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginSettingsForm.js +73 -26
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginStatusChips.d.ts +5 -1
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/PluginStatusChips.js +8 -6
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ShopMasterDataBanner.d.ts +11 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/components/ShopMasterDataBanner.js +15 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatureEnabled.d.ts +36 -5
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginFeatures.d.ts +144 -20
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSettingsForm.d.ts +36 -5
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSwitch.d.ts +15 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/hooks/usePluginSwitch.js +66 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-features-admin-client.d.ts +144 -20
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.d.ts +49 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.js +72 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-draft.d.ts +1 -12
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-draft.js +4 -20
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.d.ts +43 -0
- package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.js +66 -0
- package/.medusa/server/src/admin/admin-components/i18n/texts.d.ts +22 -2
- package/.medusa/server/src/admin/admin-components/i18n/texts.js +29 -7
- package/.medusa/server/src/admin/admin-components/index.d.ts +12 -0
- package/.medusa/server/src/admin/admin-components/index.js +11 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/AdminPageHeader.d.ts +22 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/AdminPageHeader.js +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/AdminSection.d.ts +26 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/AdminSection.js +12 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/BreadcrumbTrail.d.ts +23 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/BreadcrumbTrail.js +20 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/FileDropField.d.ts +21 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/FileDropField.js +33 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/FocusModalShell.d.ts +27 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/FocusModalShell.js +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/InfoTooltip.d.ts +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/InfoTooltip.js +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/MultiSelectDropdown.d.ts +22 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/MultiSelectDropdown.js +14 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/PdfPreviewModal.js +1 -1
- package/.medusa/server/src/admin/admin-components/shared/ui/PluginIcon.d.ts +10 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/PluginIcon.js +10 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/SwitchRow.d.ts +27 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/SwitchRow.js +15 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/WidgetHeader.d.ts +15 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/WidgetHeader.js +8 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/file-drop.d.ts +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/file-drop.js +16 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/multi-select.d.ts +13 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/multi-select.js +11 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/plugin-icon.d.ts +12 -0
- package/.medusa/server/src/admin/admin-components/shared/ui/plugin-icon.js +29 -0
- package/.medusa/server/src/admin/index.js +3123 -2019
- package/.medusa/server/src/admin/index.mjs +3126 -2022
- package/.medusa/server/src/api/admin-first-login-password-policy.js +56 -0
- package/.medusa/server/src/api/answer-actor-type-casing-not-found.js +26 -0
- package/.medusa/server/src/api/answer-code-provider-route-not-found.js +34 -0
- package/.medusa/server/src/api/code-account-password-routes.js +92 -0
- package/.medusa/server/src/api/middlewares.js +82 -17
- package/.medusa/server/src/api/password-policy.js +55 -10
- package/.medusa/server/src/api/require-login-code-customer-email.js +40 -0
- package/.medusa/server/src/api/store/customer-auth/login-code/route.js +17 -0
- package/.medusa/server/src/api/store/customer-auth/password-policy/route.js +19 -0
- package/.medusa/server/src/customer-auth/application/prepare-code-account-password-reset.js +111 -0
- package/.medusa/server/src/customer-auth/application/request-login-code.js +145 -0
- package/.medusa/server/src/customer-auth/customer-auth-methods-snapshot.js +55 -0
- package/.medusa/server/src/customer-auth/customer-password-policy.js +40 -0
- package/.medusa/server/src/customer-auth/domain/account-linking.js +53 -0
- package/.medusa/server/src/customer-auth/domain/auth-methods.js +32 -0
- package/.medusa/server/src/customer-auth/domain/login-code.js +39 -0
- package/.medusa/server/src/customer-auth/login-code-accounts.js +146 -0
- package/.medusa/server/src/customer-auth/login-code-state.js +139 -0
- package/.medusa/server/src/customer-auth/plugin-features.js +80 -0
- package/.medusa/server/src/customer-auth/remove-provider-identity.js +18 -0
- package/.medusa/server/src/customer-auth/start-customer-auth-methods.js +20 -0
- package/.medusa/server/src/documents/plugin-features.js +8 -2
- package/.medusa/server/src/email/application/deliver-ephemeral-auth-mail.js +186 -0
- package/.medusa/server/src/email/application/deliver-login-code.js +89 -0
- package/.medusa/server/src/email/application/handle-customer-verification-event.js +29 -168
- package/.medusa/server/src/email/application/handle-password-reset-event.js +27 -166
- package/.medusa/server/src/email/customer-verification-snapshot.js +20 -108
- package/.medusa/server/src/email/domain/business-keys.js +15 -2
- package/.medusa/server/src/email/plugin-features.js +8 -3
- package/.medusa/server/src/email/rendering/default-templates.js +2 -1
- package/.medusa/server/src/email/templates/blocks/dynamic-blocks.js +19 -1
- package/.medusa/server/src/email/templates/defaults/documents.js +7 -1
- package/.medusa/server/src/email/templates/defaults/subjects.js +3 -1
- package/.medusa/server/src/email/templates/defaults/texts.js +5 -2
- package/.medusa/server/src/email/templates/render.js +2 -1
- package/.medusa/server/src/email/templates/sample-data.js +2 -1
- package/.medusa/server/src/email/templates/validate.js +8 -3
- package/.medusa/server/src/email/types/email-kinds.js +4 -2
- package/.medusa/server/src/email/types/template-data.js +9 -1
- package/.medusa/server/src/modules/customer-auth/index.js +14 -0
- package/.medusa/server/src/modules/customer-auth/service.js +35 -0
- package/.medusa/server/src/modules/email/migrations/Migration20261010090000.js +20 -0
- package/.medusa/server/src/modules/plugin-features/domain/plugin-settings.js +4 -1
- package/.medusa/server/src/modules/plugin-features/service.js +26 -1
- package/.medusa/server/src/providers/email-otp/index.js +8 -0
- package/.medusa/server/src/providers/email-otp/service.js +96 -0
- package/.medusa/server/src/public/descriptor.js +117 -5
- package/.medusa/server/src/public/effective-features.js +22 -1
- package/.medusa/server/src/public/index.js +4 -2
- package/.medusa/server/src/public/plugin-icons.js +28 -0
- package/.medusa/server/src/public/shop-master-data.js +33 -14
- package/.medusa/server/src/shared/lib/index.js +2 -1
- package/.medusa/server/src/shared/lib/refreshing-snapshot.js +122 -0
- package/.medusa/server/src/shop-config/build-food-shop-config.js +38 -1
- package/README.md +436 -87
- package/dist/customer-auth/customer-auth-methods-snapshot.d.ts +25 -0
- package/dist/customer-auth/customer-auth-methods-snapshot.js +54 -0
- package/dist/customer-auth/domain/auth-methods.d.ts +16 -0
- package/dist/customer-auth/domain/auth-methods.js +31 -0
- package/dist/customer-auth/plugin-features.d.ts +2 -0
- package/dist/customer-auth/plugin-features.js +79 -0
- package/dist/email/customer-verification-snapshot.d.ts +3 -15
- package/dist/email/customer-verification-snapshot.js +19 -107
- package/dist/email/types/email-kinds.d.ts +4 -3
- package/dist/email/types/email-kinds.js +3 -1
- package/dist/email/types/template-data.d.ts +8 -0
- package/dist/email/types/template-data.js +8 -0
- package/dist/public/descriptor.js +116 -4
- package/dist/public/effective-features.d.ts +10 -0
- package/dist/public/effective-features.js +21 -0
- package/dist/public/index.d.ts +2 -1
- package/dist/public/index.js +3 -1
- package/dist/public/plugin-icons.d.ts +7 -0
- package/dist/public/plugin-icons.js +27 -0
- package/dist/public/shop-master-data.js +32 -13
- package/dist/public/types.d.ts +63 -1
- package/dist/shared/lib/index.d.ts +1 -0
- package/dist/shared/lib/index.js +1 -0
- package/dist/shared/lib/refreshing-snapshot.d.ts +52 -0
- package/dist/shared/lib/refreshing-snapshot.js +121 -0
- package/dist/shop-config/build-food-shop-config.js +37 -0
- package/package.json +8 -3
|
@@ -25,8 +25,12 @@ export declare const listPluginFeatures: () => Promise<{
|
|
|
25
25
|
group: string | null;
|
|
26
26
|
required: boolean;
|
|
27
27
|
is_set: boolean;
|
|
28
|
-
source: "
|
|
28
|
+
source: "none" | "default" | "stored" | "config";
|
|
29
29
|
invalidates: string[];
|
|
30
|
+
hint: string | null;
|
|
31
|
+
placeholder: string | null;
|
|
32
|
+
width: "full" | "half";
|
|
33
|
+
section: string | null;
|
|
30
34
|
} | {
|
|
31
35
|
type: "select";
|
|
32
36
|
options: {
|
|
@@ -41,12 +45,17 @@ export declare const listPluginFeatures: () => Promise<{
|
|
|
41
45
|
group: string | null;
|
|
42
46
|
required: boolean;
|
|
43
47
|
is_set: boolean;
|
|
44
|
-
source: "
|
|
48
|
+
source: "none" | "default" | "stored" | "config";
|
|
45
49
|
invalidates: string[];
|
|
50
|
+
hint: string | null;
|
|
51
|
+
placeholder: string | null;
|
|
52
|
+
width: "full" | "half";
|
|
53
|
+
section: string | null;
|
|
46
54
|
} | {
|
|
47
55
|
type: "number";
|
|
48
56
|
min: number | null;
|
|
49
57
|
max: number | null;
|
|
58
|
+
integer: boolean;
|
|
50
59
|
default: number | null;
|
|
51
60
|
value: number | null;
|
|
52
61
|
key: string;
|
|
@@ -55,10 +64,14 @@ export declare const listPluginFeatures: () => Promise<{
|
|
|
55
64
|
group: string | null;
|
|
56
65
|
required: boolean;
|
|
57
66
|
is_set: boolean;
|
|
58
|
-
source: "
|
|
67
|
+
source: "none" | "default" | "stored" | "config";
|
|
59
68
|
invalidates: string[];
|
|
69
|
+
hint: string | null;
|
|
70
|
+
placeholder: string | null;
|
|
71
|
+
width: "full" | "half";
|
|
72
|
+
section: string | null;
|
|
60
73
|
} | {
|
|
61
|
-
type: "string" | "boolean" | "color" | "
|
|
74
|
+
type: "string" | "boolean" | "color" | "image" | "url";
|
|
62
75
|
default: string | number | boolean | null;
|
|
63
76
|
value: string | number | boolean | null;
|
|
64
77
|
key: string;
|
|
@@ -67,8 +80,12 @@ export declare const listPluginFeatures: () => Promise<{
|
|
|
67
80
|
group: string | null;
|
|
68
81
|
required: boolean;
|
|
69
82
|
is_set: boolean;
|
|
70
|
-
source: "
|
|
83
|
+
source: "none" | "default" | "stored" | "config";
|
|
71
84
|
invalidates: string[];
|
|
85
|
+
hint: string | null;
|
|
86
|
+
placeholder: string | null;
|
|
87
|
+
width: "full" | "half";
|
|
88
|
+
section: string | null;
|
|
72
89
|
})[];
|
|
73
90
|
configured: boolean;
|
|
74
91
|
missing: string[];
|
|
@@ -81,6 +98,20 @@ export declare const listPluginFeatures: () => Promise<{
|
|
|
81
98
|
confirm: string | null;
|
|
82
99
|
}[];
|
|
83
100
|
admin_page: string | null;
|
|
101
|
+
icon: string | null;
|
|
102
|
+
summary: string | null;
|
|
103
|
+
disable_hint: string | null;
|
|
104
|
+
disable_confirm: string | null;
|
|
105
|
+
features_heading: string | null;
|
|
106
|
+
features_note: string | null;
|
|
107
|
+
all_off_warning: string | null;
|
|
108
|
+
require_enabled_feature: boolean;
|
|
109
|
+
setting_groups: {
|
|
110
|
+
name: string;
|
|
111
|
+
description: string | null;
|
|
112
|
+
note: string | null;
|
|
113
|
+
requires_feature: string | null;
|
|
114
|
+
}[];
|
|
84
115
|
}[];
|
|
85
116
|
}>;
|
|
86
117
|
export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
@@ -109,8 +140,12 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
|
109
140
|
group: string | null;
|
|
110
141
|
required: boolean;
|
|
111
142
|
is_set: boolean;
|
|
112
|
-
source: "
|
|
143
|
+
source: "none" | "default" | "stored" | "config";
|
|
113
144
|
invalidates: string[];
|
|
145
|
+
hint: string | null;
|
|
146
|
+
placeholder: string | null;
|
|
147
|
+
width: "full" | "half";
|
|
148
|
+
section: string | null;
|
|
114
149
|
} | {
|
|
115
150
|
type: "select";
|
|
116
151
|
options: {
|
|
@@ -125,12 +160,17 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
|
125
160
|
group: string | null;
|
|
126
161
|
required: boolean;
|
|
127
162
|
is_set: boolean;
|
|
128
|
-
source: "
|
|
163
|
+
source: "none" | "default" | "stored" | "config";
|
|
129
164
|
invalidates: string[];
|
|
165
|
+
hint: string | null;
|
|
166
|
+
placeholder: string | null;
|
|
167
|
+
width: "full" | "half";
|
|
168
|
+
section: string | null;
|
|
130
169
|
} | {
|
|
131
170
|
type: "number";
|
|
132
171
|
min: number | null;
|
|
133
172
|
max: number | null;
|
|
173
|
+
integer: boolean;
|
|
134
174
|
default: number | null;
|
|
135
175
|
value: number | null;
|
|
136
176
|
key: string;
|
|
@@ -139,10 +179,14 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
|
139
179
|
group: string | null;
|
|
140
180
|
required: boolean;
|
|
141
181
|
is_set: boolean;
|
|
142
|
-
source: "
|
|
182
|
+
source: "none" | "default" | "stored" | "config";
|
|
143
183
|
invalidates: string[];
|
|
184
|
+
hint: string | null;
|
|
185
|
+
placeholder: string | null;
|
|
186
|
+
width: "full" | "half";
|
|
187
|
+
section: string | null;
|
|
144
188
|
} | {
|
|
145
|
-
type: "string" | "boolean" | "color" | "
|
|
189
|
+
type: "string" | "boolean" | "color" | "image" | "url";
|
|
146
190
|
default: string | number | boolean | null;
|
|
147
191
|
value: string | number | boolean | null;
|
|
148
192
|
key: string;
|
|
@@ -151,8 +195,12 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
|
151
195
|
group: string | null;
|
|
152
196
|
required: boolean;
|
|
153
197
|
is_set: boolean;
|
|
154
|
-
source: "
|
|
198
|
+
source: "none" | "default" | "stored" | "config";
|
|
155
199
|
invalidates: string[];
|
|
200
|
+
hint: string | null;
|
|
201
|
+
placeholder: string | null;
|
|
202
|
+
width: "full" | "half";
|
|
203
|
+
section: string | null;
|
|
156
204
|
})[];
|
|
157
205
|
configured: boolean;
|
|
158
206
|
missing: string[];
|
|
@@ -165,6 +213,20 @@ export declare const retrievePluginFeatures: (pluginKey: string) => Promise<{
|
|
|
165
213
|
confirm: string | null;
|
|
166
214
|
}[];
|
|
167
215
|
admin_page: string | null;
|
|
216
|
+
icon: string | null;
|
|
217
|
+
summary: string | null;
|
|
218
|
+
disable_hint: string | null;
|
|
219
|
+
disable_confirm: string | null;
|
|
220
|
+
features_heading: string | null;
|
|
221
|
+
features_note: string | null;
|
|
222
|
+
all_off_warning: string | null;
|
|
223
|
+
require_enabled_feature: boolean;
|
|
224
|
+
setting_groups: {
|
|
225
|
+
name: string;
|
|
226
|
+
description: string | null;
|
|
227
|
+
note: string | null;
|
|
228
|
+
requires_feature: string | null;
|
|
229
|
+
}[];
|
|
168
230
|
};
|
|
169
231
|
}>;
|
|
170
232
|
export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload) => Promise<{
|
|
@@ -193,8 +255,12 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
|
|
|
193
255
|
group: string | null;
|
|
194
256
|
required: boolean;
|
|
195
257
|
is_set: boolean;
|
|
196
|
-
source: "
|
|
258
|
+
source: "none" | "default" | "stored" | "config";
|
|
197
259
|
invalidates: string[];
|
|
260
|
+
hint: string | null;
|
|
261
|
+
placeholder: string | null;
|
|
262
|
+
width: "full" | "half";
|
|
263
|
+
section: string | null;
|
|
198
264
|
} | {
|
|
199
265
|
type: "select";
|
|
200
266
|
options: {
|
|
@@ -209,12 +275,17 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
|
|
|
209
275
|
group: string | null;
|
|
210
276
|
required: boolean;
|
|
211
277
|
is_set: boolean;
|
|
212
|
-
source: "
|
|
278
|
+
source: "none" | "default" | "stored" | "config";
|
|
213
279
|
invalidates: string[];
|
|
280
|
+
hint: string | null;
|
|
281
|
+
placeholder: string | null;
|
|
282
|
+
width: "full" | "half";
|
|
283
|
+
section: string | null;
|
|
214
284
|
} | {
|
|
215
285
|
type: "number";
|
|
216
286
|
min: number | null;
|
|
217
287
|
max: number | null;
|
|
288
|
+
integer: boolean;
|
|
218
289
|
default: number | null;
|
|
219
290
|
value: number | null;
|
|
220
291
|
key: string;
|
|
@@ -223,10 +294,14 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
|
|
|
223
294
|
group: string | null;
|
|
224
295
|
required: boolean;
|
|
225
296
|
is_set: boolean;
|
|
226
|
-
source: "
|
|
297
|
+
source: "none" | "default" | "stored" | "config";
|
|
227
298
|
invalidates: string[];
|
|
299
|
+
hint: string | null;
|
|
300
|
+
placeholder: string | null;
|
|
301
|
+
width: "full" | "half";
|
|
302
|
+
section: string | null;
|
|
228
303
|
} | {
|
|
229
|
-
type: "string" | "boolean" | "color" | "
|
|
304
|
+
type: "string" | "boolean" | "color" | "image" | "url";
|
|
230
305
|
default: string | number | boolean | null;
|
|
231
306
|
value: string | number | boolean | null;
|
|
232
307
|
key: string;
|
|
@@ -235,8 +310,12 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
|
|
|
235
310
|
group: string | null;
|
|
236
311
|
required: boolean;
|
|
237
312
|
is_set: boolean;
|
|
238
|
-
source: "
|
|
313
|
+
source: "none" | "default" | "stored" | "config";
|
|
239
314
|
invalidates: string[];
|
|
315
|
+
hint: string | null;
|
|
316
|
+
placeholder: string | null;
|
|
317
|
+
width: "full" | "half";
|
|
318
|
+
section: string | null;
|
|
240
319
|
})[];
|
|
241
320
|
configured: boolean;
|
|
242
321
|
missing: string[];
|
|
@@ -249,6 +328,20 @@ export declare const updatePluginFeatures: (payload: UpdatePluginFeaturesPayload
|
|
|
249
328
|
confirm: string | null;
|
|
250
329
|
}[];
|
|
251
330
|
admin_page: string | null;
|
|
331
|
+
icon: string | null;
|
|
332
|
+
summary: string | null;
|
|
333
|
+
disable_hint: string | null;
|
|
334
|
+
disable_confirm: string | null;
|
|
335
|
+
features_heading: string | null;
|
|
336
|
+
features_note: string | null;
|
|
337
|
+
all_off_warning: string | null;
|
|
338
|
+
require_enabled_feature: boolean;
|
|
339
|
+
setting_groups: {
|
|
340
|
+
name: string;
|
|
341
|
+
description: string | null;
|
|
342
|
+
note: string | null;
|
|
343
|
+
requires_feature: string | null;
|
|
344
|
+
}[];
|
|
252
345
|
};
|
|
253
346
|
}>;
|
|
254
347
|
export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePluginSettingsPayload) => Promise<{
|
|
@@ -277,8 +370,12 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
|
|
|
277
370
|
group: string | null;
|
|
278
371
|
required: boolean;
|
|
279
372
|
is_set: boolean;
|
|
280
|
-
source: "
|
|
373
|
+
source: "none" | "default" | "stored" | "config";
|
|
281
374
|
invalidates: string[];
|
|
375
|
+
hint: string | null;
|
|
376
|
+
placeholder: string | null;
|
|
377
|
+
width: "full" | "half";
|
|
378
|
+
section: string | null;
|
|
282
379
|
} | {
|
|
283
380
|
type: "select";
|
|
284
381
|
options: {
|
|
@@ -293,12 +390,17 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
|
|
|
293
390
|
group: string | null;
|
|
294
391
|
required: boolean;
|
|
295
392
|
is_set: boolean;
|
|
296
|
-
source: "
|
|
393
|
+
source: "none" | "default" | "stored" | "config";
|
|
297
394
|
invalidates: string[];
|
|
395
|
+
hint: string | null;
|
|
396
|
+
placeholder: string | null;
|
|
397
|
+
width: "full" | "half";
|
|
398
|
+
section: string | null;
|
|
298
399
|
} | {
|
|
299
400
|
type: "number";
|
|
300
401
|
min: number | null;
|
|
301
402
|
max: number | null;
|
|
403
|
+
integer: boolean;
|
|
302
404
|
default: number | null;
|
|
303
405
|
value: number | null;
|
|
304
406
|
key: string;
|
|
@@ -307,10 +409,14 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
|
|
|
307
409
|
group: string | null;
|
|
308
410
|
required: boolean;
|
|
309
411
|
is_set: boolean;
|
|
310
|
-
source: "
|
|
412
|
+
source: "none" | "default" | "stored" | "config";
|
|
311
413
|
invalidates: string[];
|
|
414
|
+
hint: string | null;
|
|
415
|
+
placeholder: string | null;
|
|
416
|
+
width: "full" | "half";
|
|
417
|
+
section: string | null;
|
|
312
418
|
} | {
|
|
313
|
-
type: "string" | "boolean" | "color" | "
|
|
419
|
+
type: "string" | "boolean" | "color" | "image" | "url";
|
|
314
420
|
default: string | number | boolean | null;
|
|
315
421
|
value: string | number | boolean | null;
|
|
316
422
|
key: string;
|
|
@@ -319,8 +425,12 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
|
|
|
319
425
|
group: string | null;
|
|
320
426
|
required: boolean;
|
|
321
427
|
is_set: boolean;
|
|
322
|
-
source: "
|
|
428
|
+
source: "none" | "default" | "stored" | "config";
|
|
323
429
|
invalidates: string[];
|
|
430
|
+
hint: string | null;
|
|
431
|
+
placeholder: string | null;
|
|
432
|
+
width: "full" | "half";
|
|
433
|
+
section: string | null;
|
|
324
434
|
})[];
|
|
325
435
|
configured: boolean;
|
|
326
436
|
missing: string[];
|
|
@@ -333,6 +443,20 @@ export declare const updatePluginSettings: (pluginKey: string, payload: UpdatePl
|
|
|
333
443
|
confirm: string | null;
|
|
334
444
|
}[];
|
|
335
445
|
admin_page: string | null;
|
|
446
|
+
icon: string | null;
|
|
447
|
+
summary: string | null;
|
|
448
|
+
disable_hint: string | null;
|
|
449
|
+
disable_confirm: string | null;
|
|
450
|
+
features_heading: string | null;
|
|
451
|
+
features_note: string | null;
|
|
452
|
+
all_off_warning: string | null;
|
|
453
|
+
require_enabled_feature: boolean;
|
|
454
|
+
setting_groups: {
|
|
455
|
+
name: string;
|
|
456
|
+
description: string | null;
|
|
457
|
+
note: string | null;
|
|
458
|
+
requires_feature: string | null;
|
|
459
|
+
}[];
|
|
336
460
|
};
|
|
337
461
|
}>;
|
|
338
462
|
export declare const runPluginAction: (pluginKey: string, actionKey: string) => Promise<{
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/plugin-view.d.ts
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { AdminPluginFeature, AdminPluginFeatures, AdminPluginSetting, PluginSettingSource } from "@hartl-services/medusa-food-supplements-contracts/types/plugin-features-admin";
|
|
2
|
+
/** Configured feature values (what the base stores), keyed by feature key. */
|
|
3
|
+
export declare const configuredFeatures: (plugin: Pick<AdminPluginFeatures, "features">) => Record<string, boolean>;
|
|
4
|
+
/** Labels of the required settings that have no value, "A, B". */
|
|
5
|
+
export declare const missingLabels: (plugin: Pick<AdminPluginFeatures, "missing" | "settings">) => string;
|
|
6
|
+
/** The plugin has settings that must be filled for it to count as configured. */
|
|
7
|
+
export declare const hasRequiredSettings: (plugin: Pick<AdminPluginFeatures, "settings">) => boolean;
|
|
8
|
+
/** The plugin is not configured: something required is missing. */
|
|
9
|
+
export declare const isUnconfigured: (plugin: Pick<AdminPluginFeatures, "settings" | "configured">) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Every top-level feature is switched off (as configured, regardless of the
|
|
12
|
+
* plugin switch). `false` for a plugin without features.
|
|
13
|
+
*/
|
|
14
|
+
export declare const allTopLevelFeaturesOff: (plugin: Pick<AdminPluginFeatures, "features">) => boolean;
|
|
15
|
+
/**
|
|
16
|
+
* The feature is the only enabled top-level feature of a plugin that requires
|
|
17
|
+
* one (`require_enabled_feature`): switching it off would be rejected by the
|
|
18
|
+
* server, so the Admin locks it.
|
|
19
|
+
*/
|
|
20
|
+
export declare const isLastRequiredFeature: (plugin: Pick<AdminPluginFeatures, "features" | "require_enabled_feature">, feature: Pick<AdminPluginFeature, "key" | "parent_key" | "enabled">) => boolean;
|
|
21
|
+
/** The feature's parent when that parent is off, else `undefined`. */
|
|
22
|
+
export declare const disabledParent: (features: readonly AdminPluginFeature[], feature: AdminPluginFeature) => AdminPluginFeature | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* Labels of the settings whose change deletes the given secret (reverse of
|
|
25
|
+
* `invalidates`), in the order the settings are declared.
|
|
26
|
+
*/
|
|
27
|
+
export declare const invalidatedByLabels: (settings: readonly AdminPluginSetting[], secretKey: string) => string[];
|
|
28
|
+
/** Whether a settings group is dimmed: its required feature exists and is not effective. */
|
|
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
|
+
/**
|
|
36
|
+
* The description a setting shows in its info tooltip: only when a `hint`
|
|
37
|
+
* takes the place under the field and the description says something else.
|
|
38
|
+
*/
|
|
39
|
+
export declare const settingInfoText: (setting: Pick<AdminPluginSetting, "hint" | "description">) => string | null;
|
|
40
|
+
/** The description a page header shows in its info tooltip: when the summary is shown instead and differs. */
|
|
41
|
+
export declare const headerInfoText: (plugin: Pick<AdminPluginFeatures, "summary" | "description">) => string | null;
|
|
42
|
+
/** "default" is the normal case and not worth a line under every field. */
|
|
43
|
+
export declare const showsSourceHint: (source: PluginSettingSource) => boolean;
|
|
44
|
+
/** The plain-language range line ("Zwischen 8 und 128.") is only a separate line when no `hint` explains the field. */
|
|
45
|
+
export declare const showsBoundsLine: (setting: Pick<AdminPluginSetting, "hint">) => boolean;
|
|
46
|
+
/** The plugins in hub order: those that cannot be switched off first, then the server's order. */
|
|
47
|
+
export declare const hubOrder: <T extends {
|
|
48
|
+
switchable: boolean;
|
|
49
|
+
}>(plugins: readonly T[]) => T[];
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/** Configured feature values (what the base stores), keyed by feature key. */
|
|
2
|
+
export const configuredFeatures = (plugin) => Object.fromEntries(plugin.features.map((feature) => [feature.key, feature.enabled]));
|
|
3
|
+
/** Labels of the required settings that have no value, "A, B". */
|
|
4
|
+
export const missingLabels = (plugin) => plugin.missing
|
|
5
|
+
.map((key) => plugin.settings.find((setting) => setting.key === key)?.label ?? key)
|
|
6
|
+
.join(", ");
|
|
7
|
+
/** The plugin has settings that must be filled for it to count as configured. */
|
|
8
|
+
export const hasRequiredSettings = (plugin) => plugin.settings.some((setting) => setting.required);
|
|
9
|
+
/** The plugin is not configured: something required is missing. */
|
|
10
|
+
export const isUnconfigured = (plugin) => !plugin.configured && hasRequiredSettings(plugin);
|
|
11
|
+
/**
|
|
12
|
+
* Every top-level feature is switched off (as configured, regardless of the
|
|
13
|
+
* plugin switch). `false` for a plugin without features.
|
|
14
|
+
*/
|
|
15
|
+
export const allTopLevelFeaturesOff = (plugin) => {
|
|
16
|
+
const topLevel = plugin.features.filter((feature) => feature.parent_key === null);
|
|
17
|
+
return topLevel.length > 0 && topLevel.every((feature) => !feature.enabled);
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The feature is the only enabled top-level feature of a plugin that requires
|
|
21
|
+
* one (`require_enabled_feature`): switching it off would be rejected by the
|
|
22
|
+
* server, so the Admin locks it.
|
|
23
|
+
*/
|
|
24
|
+
export const isLastRequiredFeature = (plugin, feature) => plugin.require_enabled_feature &&
|
|
25
|
+
feature.parent_key === null &&
|
|
26
|
+
feature.enabled &&
|
|
27
|
+
plugin.features.every((other) => other.key === feature.key || other.parent_key !== null || !other.enabled);
|
|
28
|
+
/** The feature's parent when that parent is off, else `undefined`. */
|
|
29
|
+
export const disabledParent = (features, feature) => {
|
|
30
|
+
const parent = features.find((candidate) => candidate.key === feature.parent_key);
|
|
31
|
+
return parent && !parent.enabled ? parent : undefined;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Labels of the settings whose change deletes the given secret (reverse of
|
|
35
|
+
* `invalidates`), in the order the settings are declared.
|
|
36
|
+
*/
|
|
37
|
+
export const invalidatedByLabels = (settings, secretKey) => settings
|
|
38
|
+
.filter((setting) => setting.invalidates.includes(secretKey))
|
|
39
|
+
.map((setting) => setting.label);
|
|
40
|
+
/** Whether a settings group is dimmed: its required feature exists and is not effective. */
|
|
41
|
+
export const isGroupDimmed = (features, requiresFeature) => requiresFeature !== null &&
|
|
42
|
+
features.find((feature) => feature.key === requiresFeature)
|
|
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
|
+
/**
|
|
50
|
+
* The description a setting shows in its info tooltip: only when a `hint`
|
|
51
|
+
* takes the place under the field and the description says something else.
|
|
52
|
+
*/
|
|
53
|
+
export const settingInfoText = (setting) => setting.hint !== null &&
|
|
54
|
+
setting.description !== null &&
|
|
55
|
+
setting.description !== setting.hint
|
|
56
|
+
? setting.description
|
|
57
|
+
: null;
|
|
58
|
+
/** The description a page header shows in its info tooltip: when the summary is shown instead and differs. */
|
|
59
|
+
export const headerInfoText = (plugin) => plugin.summary !== null &&
|
|
60
|
+
plugin.description !== null &&
|
|
61
|
+
plugin.description !== plugin.summary
|
|
62
|
+
? plugin.description
|
|
63
|
+
: null;
|
|
64
|
+
/** "default" is the normal case and not worth a line under every field. */
|
|
65
|
+
export const showsSourceHint = (source) => source !== "default";
|
|
66
|
+
/** The plain-language range line ("Zwischen 8 und 128.") is only a separate line when no `hint` explains the field. */
|
|
67
|
+
export const showsBoundsLine = (setting) => setting.hint === null;
|
|
68
|
+
/** The plugins in hub order: those that cannot be switched off first, then the server's order. */
|
|
69
|
+
export const hubOrder = (plugins) => [
|
|
70
|
+
...plugins.filter((plugin) => !plugin.switchable),
|
|
71
|
+
...plugins.filter((plugin) => plugin.switchable),
|
|
72
|
+
];
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-draft.d.ts
CHANGED
|
@@ -12,17 +12,6 @@ export declare const initialSettingsDraft: (settings: readonly AdminPluginSettin
|
|
|
12
12
|
export declare const isHexColor: (value: string) => boolean;
|
|
13
13
|
/** Colors are typed and sent lowercase; surrounding spaces are dropped. */
|
|
14
14
|
export declare const normalizeColorInput: (value: string) => string;
|
|
15
|
-
export type SettingSection = {
|
|
16
|
-
/** Section heading; `null` = no heading. */
|
|
17
|
-
group: string | null;
|
|
18
|
-
settings: AdminPluginSetting[];
|
|
19
|
-
};
|
|
20
|
-
/**
|
|
21
|
-
* Splits the settings (in their given order) into consecutive runs of the
|
|
22
|
-
* same `group`; a new section starts whenever the group differs from the
|
|
23
|
-
* previous setting's group.
|
|
24
|
-
*/
|
|
25
|
-
export declare const groupSettings: (settings: readonly AdminPluginSetting[]) => SettingSection[];
|
|
26
15
|
/**
|
|
27
16
|
* Keys of number fields whose input the browser could not parse (e.g. "1e"):
|
|
28
17
|
* the input then reports `""`, which must not be read as "cleared".
|
|
@@ -30,7 +19,7 @@ export declare const groupSettings: (settings: readonly AdminPluginSetting[]) =>
|
|
|
30
19
|
export type UnparsableKeys = readonly string[];
|
|
31
20
|
/**
|
|
32
21
|
* Keys whose draft value cannot be sent: unparsable, not a number or
|
|
33
|
-
* outside min/max, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
|
|
22
|
+
* outside min/max, a fraction for an integer setting, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
|
|
34
23
|
*/
|
|
35
24
|
export declare const invalidDraftKeys: (settings: readonly AdminPluginSetting[], draft: SettingsDraft, unparsable?: UnparsableKeys) => string[];
|
|
36
25
|
/**
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-draft.js
CHANGED
|
@@ -13,24 +13,6 @@ const HEX_COLOR = /^#[0-9a-fA-F]{6}$/;
|
|
|
13
13
|
export const isHexColor = (value) => HEX_COLOR.test(value);
|
|
14
14
|
/** Colors are typed and sent lowercase; surrounding spaces are dropped. */
|
|
15
15
|
export const normalizeColorInput = (value) => value.trim().toLowerCase();
|
|
16
|
-
/**
|
|
17
|
-
* Splits the settings (in their given order) into consecutive runs of the
|
|
18
|
-
* same `group`; a new section starts whenever the group differs from the
|
|
19
|
-
* previous setting's group.
|
|
20
|
-
*/
|
|
21
|
-
export const groupSettings = (settings) => {
|
|
22
|
-
const sections = [];
|
|
23
|
-
for (const setting of settings) {
|
|
24
|
-
const last = sections[sections.length - 1];
|
|
25
|
-
if (last && last.group === setting.group) {
|
|
26
|
-
last.settings.push(setting);
|
|
27
|
-
}
|
|
28
|
-
else {
|
|
29
|
-
sections.push({ group: setting.group, settings: [setting] });
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
return sections;
|
|
33
|
-
};
|
|
34
16
|
const outsideBounds = (setting, value) => (setting.min !== null && value < setting.min) ||
|
|
35
17
|
(setting.max !== null && value > setting.max);
|
|
36
18
|
const numberEntryValue = (entry) => {
|
|
@@ -39,7 +21,7 @@ const numberEntryValue = (entry) => {
|
|
|
39
21
|
};
|
|
40
22
|
/**
|
|
41
23
|
* Keys whose draft value cannot be sent: unparsable, not a number or
|
|
42
|
-
* outside min/max, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
|
|
24
|
+
* outside min/max, a fraction for an integer setting, or a color that is not `#rrggbb`. Saving is disabled while any key is listed.
|
|
43
25
|
*/
|
|
44
26
|
export const invalidDraftKeys = (settings, draft, unparsable = []) => settings
|
|
45
27
|
.filter((setting) => {
|
|
@@ -60,7 +42,9 @@ export const invalidDraftKeys = (settings, draft, unparsable = []) => settings
|
|
|
60
42
|
return false;
|
|
61
43
|
}
|
|
62
44
|
const value = numberEntryValue(entry);
|
|
63
|
-
return value === null ||
|
|
45
|
+
return (value === null ||
|
|
46
|
+
outsideBounds(setting, value) ||
|
|
47
|
+
(setting.integer && !Number.isInteger(value)));
|
|
64
48
|
})
|
|
65
49
|
.map((setting) => setting.key);
|
|
66
50
|
/**
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.d.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { AdminPluginSetting, AdminPluginSettingGroup } from "@hartl-services/medusa-food-supplements-contracts/types/plugin-features-admin";
|
|
2
|
+
/** One row of fields: a full-width setting, or consecutive `half` settings sharing a row. */
|
|
3
|
+
export type SettingFieldRow = {
|
|
4
|
+
kind: "full";
|
|
5
|
+
setting: AdminPluginSetting;
|
|
6
|
+
} | {
|
|
7
|
+
kind: "half";
|
|
8
|
+
settings: AdminPluginSetting[];
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* A run of rows in a group. Boolean settings are switch rows of their own;
|
|
12
|
+
* all other settings between two switches (or two sub-headings) share one
|
|
13
|
+
* `fields` block. `heading` is the sub-heading that starts the block.
|
|
14
|
+
*/
|
|
15
|
+
export type SettingBlock = {
|
|
16
|
+
kind: "fields";
|
|
17
|
+
heading: string | null;
|
|
18
|
+
rows: SettingFieldRow[];
|
|
19
|
+
} | {
|
|
20
|
+
kind: "switch";
|
|
21
|
+
heading: string | null;
|
|
22
|
+
setting: AdminPluginSetting;
|
|
23
|
+
};
|
|
24
|
+
/** One card of the settings form: a group with its metadata and blocks. */
|
|
25
|
+
export type SettingGroupView = {
|
|
26
|
+
/** Group name as in `setting.group`; `null` = the ungrouped settings. */
|
|
27
|
+
name: string | null;
|
|
28
|
+
/** Card heading (the group name, or the fallback title for ungrouped). */
|
|
29
|
+
title: string;
|
|
30
|
+
description: string | null;
|
|
31
|
+
note: string | null;
|
|
32
|
+
requiresFeature: string | null;
|
|
33
|
+
settings: AdminPluginSetting[];
|
|
34
|
+
blocks: SettingBlock[];
|
|
35
|
+
};
|
|
36
|
+
/** Blocks of one group's settings (in their given order). */
|
|
37
|
+
export declare const buildSettingBlocks: (settings: readonly AdminPluginSetting[]) => SettingBlock[];
|
|
38
|
+
/**
|
|
39
|
+
* Groups the settings into cards, in order of the first appearance of each
|
|
40
|
+
* group; settings without a group form one card titled `ungroupedTitle`.
|
|
41
|
+
* `groups` supplies the description, note and required feature per group.
|
|
42
|
+
*/
|
|
43
|
+
export declare const buildSettingGroups: (settings: readonly AdminPluginSetting[], groups: readonly AdminPluginSettingGroup[], ungroupedTitle: string) => SettingGroupView[];
|
package/.medusa/server/src/admin/admin-components/features/plugin-features/lib/settings-layout.js
ADDED
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/** Blocks of one group's settings (in their given order). */
|
|
2
|
+
export const buildSettingBlocks = (settings) => {
|
|
3
|
+
const blocks = [];
|
|
4
|
+
let previousSection = null;
|
|
5
|
+
for (const [index, setting] of settings.entries()) {
|
|
6
|
+
const startsSection = setting.section !== null && (index === 0 || setting.section !== previousSection);
|
|
7
|
+
const sectionChanged = index > 0 && setting.section !== previousSection;
|
|
8
|
+
previousSection = setting.section;
|
|
9
|
+
const heading = startsSection ? setting.section : null;
|
|
10
|
+
if (setting.type === "boolean") {
|
|
11
|
+
blocks.push({ kind: "switch", heading, setting });
|
|
12
|
+
continue;
|
|
13
|
+
}
|
|
14
|
+
const last = blocks[blocks.length - 1];
|
|
15
|
+
let block;
|
|
16
|
+
if (last?.kind === "fields" && !startsSection && !sectionChanged) {
|
|
17
|
+
block = last;
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
block = { kind: "fields", heading, rows: [] };
|
|
21
|
+
blocks.push(block);
|
|
22
|
+
}
|
|
23
|
+
const lastRow = block.rows[block.rows.length - 1];
|
|
24
|
+
if (setting.width === "half") {
|
|
25
|
+
if (lastRow?.kind === "half") {
|
|
26
|
+
lastRow.settings.push(setting);
|
|
27
|
+
}
|
|
28
|
+
else {
|
|
29
|
+
block.rows.push({ kind: "half", settings: [setting] });
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
block.rows.push({ kind: "full", setting });
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return blocks;
|
|
37
|
+
};
|
|
38
|
+
/**
|
|
39
|
+
* Groups the settings into cards, in order of the first appearance of each
|
|
40
|
+
* group; settings without a group form one card titled `ungroupedTitle`.
|
|
41
|
+
* `groups` supplies the description, note and required feature per group.
|
|
42
|
+
*/
|
|
43
|
+
export const buildSettingGroups = (settings, groups, ungroupedTitle) => {
|
|
44
|
+
const byName = new Map();
|
|
45
|
+
for (const setting of settings) {
|
|
46
|
+
const entry = byName.get(setting.group);
|
|
47
|
+
if (entry) {
|
|
48
|
+
entry.push(setting);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
byName.set(setting.group, [setting]);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return [...byName.entries()].map(([name, groupSettings]) => {
|
|
55
|
+
const meta = name === null ? undefined : groups.find((group) => group.name === name);
|
|
56
|
+
return {
|
|
57
|
+
name,
|
|
58
|
+
title: name ?? ungroupedTitle,
|
|
59
|
+
description: meta?.description ?? null,
|
|
60
|
+
note: meta?.note ?? null,
|
|
61
|
+
requiresFeature: meta?.requires_feature ?? null,
|
|
62
|
+
settings: groupSettings,
|
|
63
|
+
blocks: buildSettingBlocks(groupSettings),
|
|
64
|
+
};
|
|
65
|
+
});
|
|
66
|
+
};
|