@scryme/chat 2.91.119 → 2.91.121
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/custom-message-schema.d.ts +35 -48
- package/dist/custom-message-schema.js +155 -237
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/package.json +1 -1
- package/src/__tests__/custom-message.test.ts +20 -69
- package/src/custom-message-schema.ts +30 -141
- package/src/index.ts +0 -3
|
@@ -45,7 +45,7 @@ export declare const ValidationSchema: z.ZodObject<{
|
|
|
45
45
|
}>;
|
|
46
46
|
export type ValidationSchemaType = z.infer<typeof ValidationSchema>;
|
|
47
47
|
/**
|
|
48
|
-
* Data Source Schema for dynamic content (e.g., Select
|
|
48
|
+
* Data Source Schema for dynamic content (e.g., Select or Radio options).
|
|
49
49
|
*/
|
|
50
50
|
export declare const DataSourceSchema: z.ZodObject<{
|
|
51
51
|
/** Source type: 'STATIC' for inline items, 'API' for external fetching, 'VARIABLE' for message data interpolation */
|
|
@@ -141,6 +141,10 @@ export declare const CustomMessageThemeSchema: z.ZodObject<{
|
|
|
141
141
|
textColor: z.ZodOptional<z.ZodString>;
|
|
142
142
|
/** Accent / Brand highlight color */
|
|
143
143
|
accentColor: z.ZodOptional<z.ZodString>;
|
|
144
|
+
/** Inner card background override */
|
|
145
|
+
cardBackgroundColor: z.ZodOptional<z.ZodString>;
|
|
146
|
+
/** Primary button background override */
|
|
147
|
+
primaryButtonColor: z.ZodOptional<z.ZodString>;
|
|
144
148
|
/** Custom CSS class names applied to the container */
|
|
145
149
|
className: z.ZodOptional<z.ZodString>;
|
|
146
150
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -148,12 +152,16 @@ export declare const CustomMessageThemeSchema: z.ZodObject<{
|
|
|
148
152
|
borderColor?: string | undefined;
|
|
149
153
|
textColor?: string | undefined;
|
|
150
154
|
accentColor?: string | undefined;
|
|
155
|
+
cardBackgroundColor?: string | undefined;
|
|
156
|
+
primaryButtonColor?: string | undefined;
|
|
151
157
|
className?: string | undefined;
|
|
152
158
|
}, {
|
|
153
159
|
backgroundColor?: string | undefined;
|
|
154
160
|
borderColor?: string | undefined;
|
|
155
161
|
textColor?: string | undefined;
|
|
156
162
|
accentColor?: string | undefined;
|
|
163
|
+
cardBackgroundColor?: string | undefined;
|
|
164
|
+
primaryButtonColor?: string | undefined;
|
|
157
165
|
className?: string | undefined;
|
|
158
166
|
}>;
|
|
159
167
|
export type CustomMessageTheme = z.infer<typeof CustomMessageThemeSchema>;
|
|
@@ -161,7 +169,7 @@ export type CustomMessageTheme = z.infer<typeof CustomMessageThemeSchema>;
|
|
|
161
169
|
* A Node is the recursive structural building block of custom message UI components.
|
|
162
170
|
*/
|
|
163
171
|
export type MessageNode = {
|
|
164
|
-
/** The type identifier of the component (e.g., 'Layout.Card', 'Display.Field', 'Input.Text', '
|
|
172
|
+
/** The type identifier of the component (e.g., 'Layout.Card', 'Display.Field', 'Input.Text', 'Input.RadioGroup', 'Input.Switch', 'Display.Progress') */
|
|
165
173
|
type: string;
|
|
166
174
|
/** Unique identifier for the node (required for form inputs to track state & validation) */
|
|
167
175
|
id?: string;
|
|
@@ -169,6 +177,9 @@ export type MessageNode = {
|
|
|
169
177
|
properties?: Record<string, any>;
|
|
170
178
|
/** Nested child nodes rendered inside this node */
|
|
171
179
|
children?: MessageNode[];
|
|
180
|
+
/** Allow multiple responses toggle */
|
|
181
|
+
allowMultipleResponses?: boolean;
|
|
182
|
+
allowMultiple?: boolean;
|
|
172
183
|
/** Optional conditional display logic evaluating visibility based on form state or message data */
|
|
173
184
|
condition?: ConditionSchemaType;
|
|
174
185
|
/** Optional validation rules for user inputs */
|
|
@@ -180,7 +191,7 @@ export declare const MessageNodeSchema: z.ZodType<MessageNode>;
|
|
|
180
191
|
/**
|
|
181
192
|
* Predefined Custom Message Types supported out of the box.
|
|
182
193
|
*/
|
|
183
|
-
export declare const PredefinedCustomMessageTypeSchema: z.ZodEnum<["APPROVAL", "REPORT", "FORM", "FEEDBACK", "TASK_CARD", "SURVEY", "GENERIC"]>;
|
|
194
|
+
export declare const PredefinedCustomMessageTypeSchema: z.ZodEnum<["APPROVAL", "REPORT", "FORM", "FEEDBACK", "TASK_CARD", "SURVEY", "LOW_STOCK_ALERT", "GENERIC"]>;
|
|
184
195
|
export type PredefinedCustomMessageType = z.infer<typeof PredefinedCustomMessageTypeSchema>;
|
|
185
196
|
/**
|
|
186
197
|
* Action item schema for interactive buttons rendered on custom messages.
|
|
@@ -219,9 +230,10 @@ export declare const MessageActionSchema: z.ZodObject<{
|
|
|
219
230
|
payload?: Record<string, any> | undefined;
|
|
220
231
|
includeFormState?: boolean | undefined;
|
|
221
232
|
}>;
|
|
222
|
-
/**
|
|
233
|
+
/** Flag to allow users to trigger this action multiple times */
|
|
223
234
|
allowMultipleResponses: z.ZodOptional<z.ZodBoolean>;
|
|
224
235
|
allowMultiple: z.ZodOptional<z.ZodBoolean>;
|
|
236
|
+
/** Optional visibility condition for displaying this action button */
|
|
225
237
|
condition: z.ZodOptional<z.ZodObject<{
|
|
226
238
|
/** The field ID or path inside data/formState to evaluate */
|
|
227
239
|
field: z.ZodString;
|
|
@@ -286,7 +298,7 @@ export declare const CustomMessageSchema: z.ZodObject<{
|
|
|
286
298
|
version: z.ZodDefault<z.ZodString>;
|
|
287
299
|
/** Optional template identifier reference */
|
|
288
300
|
templateId: z.ZodOptional<z.ZodString>;
|
|
289
|
-
/** The logical message category type (e.g. 'APPROVAL', 'REPORT', 'FORM', 'FEEDBACK', 'TASK_CARD', 'SURVEY', or custom string) */
|
|
301
|
+
/** The logical message category type (e.g. 'APPROVAL', 'REPORT', 'FORM', 'FEEDBACK', 'TASK_CARD', 'SURVEY', 'LOW_STOCK_ALERT', or custom string) */
|
|
290
302
|
type: z.ZodString;
|
|
291
303
|
/** Top-level configuration, branding, and header context */
|
|
292
304
|
context: z.ZodObject<{
|
|
@@ -323,6 +335,10 @@ export declare const CustomMessageSchema: z.ZodObject<{
|
|
|
323
335
|
textColor: z.ZodOptional<z.ZodString>;
|
|
324
336
|
/** Accent / Brand highlight color */
|
|
325
337
|
accentColor: z.ZodOptional<z.ZodString>;
|
|
338
|
+
/** Inner card background override */
|
|
339
|
+
cardBackgroundColor: z.ZodOptional<z.ZodString>;
|
|
340
|
+
/** Primary button background override */
|
|
341
|
+
primaryButtonColor: z.ZodOptional<z.ZodString>;
|
|
326
342
|
/** Custom CSS class names applied to the container */
|
|
327
343
|
className: z.ZodOptional<z.ZodString>;
|
|
328
344
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -330,12 +346,16 @@ export declare const CustomMessageSchema: z.ZodObject<{
|
|
|
330
346
|
borderColor?: string | undefined;
|
|
331
347
|
textColor?: string | undefined;
|
|
332
348
|
accentColor?: string | undefined;
|
|
349
|
+
cardBackgroundColor?: string | undefined;
|
|
350
|
+
primaryButtonColor?: string | undefined;
|
|
333
351
|
className?: string | undefined;
|
|
334
352
|
}, {
|
|
335
353
|
backgroundColor?: string | undefined;
|
|
336
354
|
borderColor?: string | undefined;
|
|
337
355
|
textColor?: string | undefined;
|
|
338
356
|
accentColor?: string | undefined;
|
|
357
|
+
cardBackgroundColor?: string | undefined;
|
|
358
|
+
primaryButtonColor?: string | undefined;
|
|
339
359
|
className?: string | undefined;
|
|
340
360
|
}>>;
|
|
341
361
|
/** Hierarchical node tree defining the layout and components */
|
|
@@ -375,9 +395,10 @@ export declare const CustomMessageSchema: z.ZodObject<{
|
|
|
375
395
|
payload?: Record<string, any> | undefined;
|
|
376
396
|
includeFormState?: boolean | undefined;
|
|
377
397
|
}>;
|
|
378
|
-
/**
|
|
398
|
+
/** Flag to allow users to trigger this action multiple times */
|
|
379
399
|
allowMultipleResponses: z.ZodOptional<z.ZodBoolean>;
|
|
380
400
|
allowMultiple: z.ZodOptional<z.ZodBoolean>;
|
|
401
|
+
/** Optional visibility condition for displaying this action button */
|
|
381
402
|
condition: z.ZodOptional<z.ZodObject<{
|
|
382
403
|
/** The field ID or path inside data/formState to evaluate */
|
|
383
404
|
field: z.ZodString;
|
|
@@ -470,6 +491,8 @@ export declare const CustomMessageSchema: z.ZodObject<{
|
|
|
470
491
|
borderColor?: string | undefined;
|
|
471
492
|
textColor?: string | undefined;
|
|
472
493
|
accentColor?: string | undefined;
|
|
494
|
+
cardBackgroundColor?: string | undefined;
|
|
495
|
+
primaryButtonColor?: string | undefined;
|
|
473
496
|
className?: string | undefined;
|
|
474
497
|
} | undefined;
|
|
475
498
|
actions?: {
|
|
@@ -515,6 +538,8 @@ export declare const CustomMessageSchema: z.ZodObject<{
|
|
|
515
538
|
borderColor?: string | undefined;
|
|
516
539
|
textColor?: string | undefined;
|
|
517
540
|
accentColor?: string | undefined;
|
|
541
|
+
cardBackgroundColor?: string | undefined;
|
|
542
|
+
primaryButtonColor?: string | undefined;
|
|
518
543
|
className?: string | undefined;
|
|
519
544
|
} | undefined;
|
|
520
545
|
actions?: {
|
|
@@ -558,24 +583,12 @@ export interface CreateApprovalMessageOptions {
|
|
|
558
583
|
priority?: 'low' | 'normal' | 'high' | 'urgent';
|
|
559
584
|
approveLabel?: string;
|
|
560
585
|
rejectLabel?: string;
|
|
586
|
+
allowMultipleResponses?: boolean;
|
|
561
587
|
data?: Record<string, any>;
|
|
562
588
|
theme?: CustomMessageTheme;
|
|
563
589
|
}
|
|
564
590
|
/**
|
|
565
591
|
* Creates a standard Approval Custom Message schema structure.
|
|
566
|
-
*
|
|
567
|
-
* @example
|
|
568
|
-
* ```ts
|
|
569
|
-
* const approvalSchema = createApprovalMessage({
|
|
570
|
-
* title: 'Expense Reimbursement Request',
|
|
571
|
-
* description: 'Requested by Jane Doe for $450.00',
|
|
572
|
-
* fields: [
|
|
573
|
-
* { label: 'Category', value: 'Travel' },
|
|
574
|
-
* { label: 'Amount', value: '$450.00' }
|
|
575
|
-
* ],
|
|
576
|
-
* callbackId: 'expense-approval-101'
|
|
577
|
-
* });
|
|
578
|
-
* ```
|
|
579
592
|
*/
|
|
580
593
|
export declare const createApprovalMessage: (options: CreateApprovalMessageOptions) => CustomMessage;
|
|
581
594
|
/**
|
|
@@ -603,7 +616,7 @@ export declare const createReportMessage: (options: CreateReportMessageOptions)
|
|
|
603
616
|
export interface FormFieldConfig {
|
|
604
617
|
id: string;
|
|
605
618
|
label: string;
|
|
606
|
-
type?: 'text' | 'textarea' | 'select' | 'checkbox';
|
|
619
|
+
type?: 'text' | 'textarea' | 'select' | 'checkbox' | 'radio' | 'switch';
|
|
607
620
|
placeholder?: string;
|
|
608
621
|
options?: Array<{
|
|
609
622
|
label: string;
|
|
@@ -621,6 +634,7 @@ export interface CreateFormMessageOptions {
|
|
|
621
634
|
submitCallbackId: string;
|
|
622
635
|
submitLabel?: string;
|
|
623
636
|
type?: 'FORM' | 'FEEDBACK' | 'SURVEY';
|
|
637
|
+
allowMultipleResponses?: boolean;
|
|
624
638
|
data?: Record<string, any>;
|
|
625
639
|
theme?: CustomMessageTheme;
|
|
626
640
|
}
|
|
@@ -638,6 +652,7 @@ export interface CreateTaskCardMessageOptions {
|
|
|
638
652
|
assignee?: string;
|
|
639
653
|
dueDate?: string;
|
|
640
654
|
callbackId: string;
|
|
655
|
+
allowMultipleResponses?: boolean;
|
|
641
656
|
data?: Record<string, any>;
|
|
642
657
|
theme?: CustomMessageTheme;
|
|
643
658
|
}
|
|
@@ -645,31 +660,3 @@ export interface CreateTaskCardMessageOptions {
|
|
|
645
660
|
* Creates a Task Card Custom Message schema structure.
|
|
646
661
|
*/
|
|
647
662
|
export declare const createTaskCardMessage: (options: CreateTaskCardMessageOptions) => CustomMessage;
|
|
648
|
-
/**
|
|
649
|
-
* Helper to format product item name combining productName and variantName.
|
|
650
|
-
* If variantName is missing, empty, or 'default' (case-insensitive), returns productName.
|
|
651
|
-
*/
|
|
652
|
-
export declare const formatLowStockItemName: (options: {
|
|
653
|
-
productName: string;
|
|
654
|
-
variantName?: string | null;
|
|
655
|
-
}) => string;
|
|
656
|
-
/**
|
|
657
|
-
* Builder options for creating a Low Stock Alert custom message schema.
|
|
658
|
-
*/
|
|
659
|
-
export interface CreateLowStockAlertMessageOptions {
|
|
660
|
-
productName: string;
|
|
661
|
-
variantName?: string | null;
|
|
662
|
-
currentQuantity: number;
|
|
663
|
-
thresholdQuantity: number;
|
|
664
|
-
sku?: string;
|
|
665
|
-
location?: string;
|
|
666
|
-
reorderUrl?: string;
|
|
667
|
-
callbackId?: string;
|
|
668
|
-
priority?: 'low' | 'normal' | 'high' | 'urgent';
|
|
669
|
-
data?: Record<string, any>;
|
|
670
|
-
theme?: CustomMessageTheme;
|
|
671
|
-
}
|
|
672
|
-
/**
|
|
673
|
-
* Creates a standard Low Stock Alert Custom Message schema structure.
|
|
674
|
-
*/
|
|
675
|
-
export declare const createLowStockAlertMessage: (options: CreateLowStockAlertMessageOptions) => CustomMessage;
|
|
@@ -35,7 +35,7 @@ export var ValidationSchema = z.object({
|
|
|
35
35
|
errorMessage: z.string().optional(),
|
|
36
36
|
});
|
|
37
37
|
/**
|
|
38
|
-
* Data Source Schema for dynamic content (e.g., Select
|
|
38
|
+
* Data Source Schema for dynamic content (e.g., Select or Radio options).
|
|
39
39
|
*/
|
|
40
40
|
export var DataSourceSchema = z.object({
|
|
41
41
|
/** Source type: 'STATIC' for inline items, 'API' for external fetching, 'VARIABLE' for message data interpolation */
|
|
@@ -82,6 +82,10 @@ export var CustomMessageThemeSchema = z.object({
|
|
|
82
82
|
textColor: z.string().optional(),
|
|
83
83
|
/** Accent / Brand highlight color */
|
|
84
84
|
accentColor: z.string().optional(),
|
|
85
|
+
/** Inner card background override */
|
|
86
|
+
cardBackgroundColor: z.string().optional(),
|
|
87
|
+
/** Primary button background override */
|
|
88
|
+
primaryButtonColor: z.string().optional(),
|
|
85
89
|
/** Custom CSS class names applied to the container */
|
|
86
90
|
className: z.string().optional(),
|
|
87
91
|
});
|
|
@@ -109,6 +113,7 @@ export var PredefinedCustomMessageTypeSchema = z.enum([
|
|
|
109
113
|
'FEEDBACK',
|
|
110
114
|
'TASK_CARD',
|
|
111
115
|
'SURVEY',
|
|
116
|
+
'LOW_STOCK_ALERT',
|
|
112
117
|
'GENERIC',
|
|
113
118
|
]);
|
|
114
119
|
/**
|
|
@@ -136,9 +141,10 @@ export var MessageActionSchema = z.object({
|
|
|
136
141
|
/** Whether to automatically gather and send all current form input state in the callback payload */
|
|
137
142
|
includeFormState: z.boolean().default(true).optional(),
|
|
138
143
|
}),
|
|
139
|
-
/**
|
|
144
|
+
/** Flag to allow users to trigger this action multiple times */
|
|
140
145
|
allowMultipleResponses: z.boolean().optional(),
|
|
141
146
|
allowMultiple: z.boolean().optional(),
|
|
147
|
+
/** Optional visibility condition for displaying this action button */
|
|
142
148
|
condition: ConditionSchema.optional(),
|
|
143
149
|
});
|
|
144
150
|
/**
|
|
@@ -149,7 +155,7 @@ export var CustomMessageSchema = z.object({
|
|
|
149
155
|
version: z.string().default('v1'),
|
|
150
156
|
/** Optional template identifier reference */
|
|
151
157
|
templateId: z.string().optional(),
|
|
152
|
-
/** The logical message category type (e.g. 'APPROVAL', 'REPORT', 'FORM', 'FEEDBACK', 'TASK_CARD', 'SURVEY', or custom string) */
|
|
158
|
+
/** The logical message category type (e.g. 'APPROVAL', 'REPORT', 'FORM', 'FEEDBACK', 'TASK_CARD', 'SURVEY', 'LOW_STOCK_ALERT', or custom string) */
|
|
153
159
|
type: z.string(),
|
|
154
160
|
/** Top-level configuration, branding, and header context */
|
|
155
161
|
context: z.object({
|
|
@@ -186,71 +192,63 @@ export var CustomMessageSchema = z.object({
|
|
|
186
192
|
});
|
|
187
193
|
/**
|
|
188
194
|
* Creates a standard Approval Custom Message schema structure.
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```ts
|
|
192
|
-
* const approvalSchema = createApprovalMessage({
|
|
193
|
-
* title: 'Expense Reimbursement Request',
|
|
194
|
-
* description: 'Requested by Jane Doe for $450.00',
|
|
195
|
-
* fields: [
|
|
196
|
-
* { label: 'Category', value: 'Travel' },
|
|
197
|
-
* { label: 'Amount', value: '$450.00' }
|
|
198
|
-
* ],
|
|
199
|
-
* callbackId: 'expense-approval-101'
|
|
200
|
-
* });
|
|
201
|
-
* ```
|
|
202
195
|
*/
|
|
203
|
-
export var createApprovalMessage = function (options) {
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
196
|
+
export var createApprovalMessage = function (options) {
|
|
197
|
+
var _a, _b;
|
|
198
|
+
return ({
|
|
199
|
+
version: 'v1',
|
|
200
|
+
type: 'APPROVAL',
|
|
201
|
+
context: {
|
|
202
|
+
title: options.title,
|
|
203
|
+
description: options.description,
|
|
204
|
+
icon: 'CheckSquare',
|
|
205
|
+
priority: options.priority || 'normal',
|
|
206
|
+
},
|
|
207
|
+
theme: options.theme,
|
|
208
|
+
root: {
|
|
209
|
+
type: 'Layout.Card',
|
|
210
|
+
children: [
|
|
211
|
+
{
|
|
212
|
+
type: 'Layout.Grid',
|
|
213
|
+
properties: { columns: 2 },
|
|
214
|
+
children: options.fields.map(function (f) { return ({
|
|
215
|
+
type: 'Display.Field',
|
|
216
|
+
properties: { label: f.label, value: f.value },
|
|
217
|
+
}); }),
|
|
218
|
+
},
|
|
219
|
+
],
|
|
220
|
+
},
|
|
221
|
+
actions: [
|
|
216
222
|
{
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
id: 'approve',
|
|
229
|
-
label: options.approveLabel || 'Approve',
|
|
230
|
-
type: 'PRIMARY',
|
|
231
|
-
icon: 'Check',
|
|
232
|
-
handler: {
|
|
233
|
-
type: 'CALLBACK',
|
|
234
|
-
callbackId: options.callbackId,
|
|
235
|
-
payload: { action: 'approve' },
|
|
236
|
-
includeFormState: true,
|
|
223
|
+
id: 'approve',
|
|
224
|
+
label: options.approveLabel || 'Approve',
|
|
225
|
+
type: 'PRIMARY',
|
|
226
|
+
icon: 'Check',
|
|
227
|
+
allowMultipleResponses: (_a = options.allowMultipleResponses) !== null && _a !== void 0 ? _a : false,
|
|
228
|
+
handler: {
|
|
229
|
+
type: 'CALLBACK',
|
|
230
|
+
callbackId: options.callbackId,
|
|
231
|
+
payload: { action: 'approve' },
|
|
232
|
+
includeFormState: true,
|
|
233
|
+
},
|
|
237
234
|
},
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
235
|
+
{
|
|
236
|
+
id: 'reject',
|
|
237
|
+
label: options.rejectLabel || 'Reject',
|
|
238
|
+
type: 'DESTRUCTIVE',
|
|
239
|
+
icon: 'X',
|
|
240
|
+
allowMultipleResponses: (_b = options.allowMultipleResponses) !== null && _b !== void 0 ? _b : false,
|
|
241
|
+
handler: {
|
|
242
|
+
type: 'CALLBACK',
|
|
243
|
+
callbackId: options.callbackId,
|
|
244
|
+
payload: { action: 'reject' },
|
|
245
|
+
includeFormState: true,
|
|
246
|
+
},
|
|
249
247
|
},
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
}
|
|
248
|
+
],
|
|
249
|
+
data: options.data,
|
|
250
|
+
});
|
|
251
|
+
};
|
|
254
252
|
/**
|
|
255
253
|
* Creates a standard Report Custom Message schema structure.
|
|
256
254
|
*/
|
|
@@ -296,197 +294,117 @@ export var createReportMessage = function (options) { return ({
|
|
|
296
294
|
/**
|
|
297
295
|
* Creates an interactive Form / Survey / Feedback Custom Message schema structure.
|
|
298
296
|
*/
|
|
299
|
-
export var createFormMessage = function (options) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
? 'Input.
|
|
316
|
-
:
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
type: 'STATIC',
|
|
330
|
-
items: field.options,
|
|
297
|
+
export var createFormMessage = function (options) {
|
|
298
|
+
var _a;
|
|
299
|
+
return ({
|
|
300
|
+
version: 'v1',
|
|
301
|
+
type: options.type || 'FORM',
|
|
302
|
+
context: {
|
|
303
|
+
title: options.title,
|
|
304
|
+
description: options.description,
|
|
305
|
+
icon: options.type === 'FEEDBACK' ? 'HelpCircle' : 'FileText',
|
|
306
|
+
priority: 'normal',
|
|
307
|
+
},
|
|
308
|
+
theme: options.theme,
|
|
309
|
+
root: {
|
|
310
|
+
type: 'Layout.Stack',
|
|
311
|
+
children: options.fields.map(function (field) {
|
|
312
|
+
var nodeType = field.type === 'select'
|
|
313
|
+
? 'Input.Select'
|
|
314
|
+
: field.type === 'checkbox'
|
|
315
|
+
? 'Input.Checkbox'
|
|
316
|
+
: field.type === 'radio'
|
|
317
|
+
? 'Input.RadioGroup'
|
|
318
|
+
: field.type === 'switch'
|
|
319
|
+
? 'Input.Switch'
|
|
320
|
+
: 'Input.Text';
|
|
321
|
+
var validation = field.required
|
|
322
|
+
? { required: true, errorMessage: "".concat(field.label, " is required") }
|
|
323
|
+
: undefined;
|
|
324
|
+
var properties = {
|
|
325
|
+
label: field.label,
|
|
326
|
+
placeholder: field.placeholder,
|
|
331
327
|
};
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
callbackId: options.submitCallbackId,
|
|
350
|
-
payload: { action: 'submit' },
|
|
351
|
-
includeFormState: true,
|
|
352
|
-
},
|
|
328
|
+
if (field.type === 'textarea') {
|
|
329
|
+
properties.multiline = true;
|
|
330
|
+
}
|
|
331
|
+
if ((field.type === 'select' || field.type === 'radio') && field.options) {
|
|
332
|
+
properties.dataSource = {
|
|
333
|
+
type: 'STATIC',
|
|
334
|
+
items: field.options,
|
|
335
|
+
};
|
|
336
|
+
properties.options = field.options;
|
|
337
|
+
}
|
|
338
|
+
return {
|
|
339
|
+
type: nodeType,
|
|
340
|
+
id: field.id,
|
|
341
|
+
properties: properties,
|
|
342
|
+
validation: validation,
|
|
343
|
+
};
|
|
344
|
+
}),
|
|
353
345
|
},
|
|
354
|
-
|
|
355
|
-
data: options.data,
|
|
356
|
-
}); };
|
|
357
|
-
/**
|
|
358
|
-
* Creates a Task Card Custom Message schema structure.
|
|
359
|
-
*/
|
|
360
|
-
export var createTaskCardMessage = function (options) { return ({
|
|
361
|
-
version: 'v1',
|
|
362
|
-
type: 'TASK_CARD',
|
|
363
|
-
context: {
|
|
364
|
-
title: options.title,
|
|
365
|
-
description: options.description,
|
|
366
|
-
icon: 'CheckSquare',
|
|
367
|
-
priority: 'normal',
|
|
368
|
-
},
|
|
369
|
-
theme: options.theme,
|
|
370
|
-
root: {
|
|
371
|
-
type: 'Layout.Stack',
|
|
372
|
-
children: [
|
|
346
|
+
actions: [
|
|
373
347
|
{
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
348
|
+
id: 'submit',
|
|
349
|
+
label: options.submitLabel || 'Submit',
|
|
350
|
+
type: 'PRIMARY',
|
|
351
|
+
icon: 'Send',
|
|
352
|
+
allowMultipleResponses: (_a = options.allowMultipleResponses) !== null && _a !== void 0 ? _a : false,
|
|
353
|
+
handler: {
|
|
354
|
+
type: 'CALLBACK',
|
|
355
|
+
callbackId: options.submitCallbackId,
|
|
356
|
+
payload: { action: 'submit' },
|
|
357
|
+
includeFormState: true,
|
|
358
|
+
},
|
|
381
359
|
},
|
|
382
360
|
],
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
{
|
|
386
|
-
id: 'complete_task',
|
|
387
|
-
label: 'Mark Completed',
|
|
388
|
-
type: 'PRIMARY',
|
|
389
|
-
icon: 'Check',
|
|
390
|
-
handler: {
|
|
391
|
-
type: 'CALLBACK',
|
|
392
|
-
callbackId: options.callbackId,
|
|
393
|
-
payload: { action: 'complete' },
|
|
394
|
-
includeFormState: false,
|
|
395
|
-
},
|
|
396
|
-
},
|
|
397
|
-
],
|
|
398
|
-
data: options.data,
|
|
399
|
-
}); };
|
|
400
|
-
/**
|
|
401
|
-
* Helper to format product item name combining productName and variantName.
|
|
402
|
-
* If variantName is missing, empty, or 'default' (case-insensitive), returns productName.
|
|
403
|
-
*/
|
|
404
|
-
export var formatLowStockItemName = function (options) {
|
|
405
|
-
var trimmedProduct = options.productName.trim();
|
|
406
|
-
var trimmedVariant = options.variantName ? options.variantName.trim() : '';
|
|
407
|
-
if (!trimmedVariant || trimmedVariant.toLowerCase() === 'default') {
|
|
408
|
-
return trimmedProduct;
|
|
409
|
-
}
|
|
410
|
-
return "".concat(trimmedProduct, " - ").concat(trimmedVariant);
|
|
361
|
+
data: options.data,
|
|
362
|
+
});
|
|
411
363
|
};
|
|
412
364
|
/**
|
|
413
|
-
* Creates a
|
|
365
|
+
* Creates a Task Card Custom Message schema structure.
|
|
414
366
|
*/
|
|
415
|
-
export var
|
|
416
|
-
var
|
|
417
|
-
|
|
418
|
-
variantName: options.variantName,
|
|
419
|
-
});
|
|
420
|
-
var fields = [
|
|
421
|
-
{ label: 'Item Name', value: itemName },
|
|
422
|
-
{ label: 'Current Stock', value: "".concat(options.currentQuantity, " units") },
|
|
423
|
-
{ label: 'Reorder Threshold', value: "".concat(options.thresholdQuantity, " units") },
|
|
424
|
-
];
|
|
425
|
-
if (options.sku) {
|
|
426
|
-
fields.push({ label: 'SKU', value: options.sku });
|
|
427
|
-
}
|
|
428
|
-
if (options.location) {
|
|
429
|
-
fields.push({ label: 'Location', value: options.location });
|
|
430
|
-
}
|
|
431
|
-
var actions = [];
|
|
432
|
-
if (options.reorderUrl) {
|
|
433
|
-
actions.push({
|
|
434
|
-
id: 'reorder',
|
|
435
|
-
label: 'Reorder Stock',
|
|
436
|
-
type: 'PRIMARY',
|
|
437
|
-
icon: 'ExternalLink',
|
|
438
|
-
handler: {
|
|
439
|
-
type: 'LINK',
|
|
440
|
-
url: options.reorderUrl,
|
|
441
|
-
},
|
|
442
|
-
});
|
|
443
|
-
}
|
|
444
|
-
else if (options.callbackId) {
|
|
445
|
-
actions.push({
|
|
446
|
-
id: 'reorder',
|
|
447
|
-
label: 'Reorder Stock',
|
|
448
|
-
type: 'PRIMARY',
|
|
449
|
-
icon: 'Send',
|
|
450
|
-
handler: {
|
|
451
|
-
type: 'CALLBACK',
|
|
452
|
-
callbackId: options.callbackId,
|
|
453
|
-
payload: {
|
|
454
|
-
action: 'reorder',
|
|
455
|
-
productName: options.productName,
|
|
456
|
-
variantName: options.variantName || undefined,
|
|
457
|
-
itemName: itemName,
|
|
458
|
-
currentQuantity: options.currentQuantity,
|
|
459
|
-
thresholdQuantity: options.thresholdQuantity,
|
|
460
|
-
sku: options.sku,
|
|
461
|
-
},
|
|
462
|
-
includeFormState: false,
|
|
463
|
-
},
|
|
464
|
-
});
|
|
465
|
-
}
|
|
466
|
-
return {
|
|
367
|
+
export var createTaskCardMessage = function (options) {
|
|
368
|
+
var _a;
|
|
369
|
+
return ({
|
|
467
370
|
version: 'v1',
|
|
468
|
-
type: '
|
|
371
|
+
type: 'TASK_CARD',
|
|
469
372
|
context: {
|
|
470
|
-
title:
|
|
471
|
-
description:
|
|
472
|
-
icon: '
|
|
473
|
-
priority:
|
|
373
|
+
title: options.title,
|
|
374
|
+
description: options.description,
|
|
375
|
+
icon: 'CheckSquare',
|
|
376
|
+
priority: 'normal',
|
|
474
377
|
},
|
|
475
378
|
theme: options.theme,
|
|
476
379
|
root: {
|
|
477
|
-
type: 'Layout.
|
|
380
|
+
type: 'Layout.Stack',
|
|
478
381
|
children: [
|
|
479
382
|
{
|
|
480
383
|
type: 'Layout.Grid',
|
|
481
|
-
properties: { columns:
|
|
482
|
-
children:
|
|
483
|
-
type: 'Display.Field',
|
|
484
|
-
properties: { label:
|
|
485
|
-
|
|
384
|
+
properties: { columns: 3 },
|
|
385
|
+
children: [
|
|
386
|
+
{ type: 'Display.Field', properties: { label: 'Status', value: options.status } },
|
|
387
|
+
{ type: 'Display.Field', properties: { label: 'Assignee', value: options.assignee || 'Unassigned' } },
|
|
388
|
+
{ type: 'Display.Field', properties: { label: 'Due Date', value: options.dueDate || 'None' } },
|
|
389
|
+
],
|
|
486
390
|
},
|
|
487
391
|
],
|
|
488
392
|
},
|
|
489
|
-
actions:
|
|
393
|
+
actions: [
|
|
394
|
+
{
|
|
395
|
+
id: 'complete_task',
|
|
396
|
+
label: 'Mark Completed',
|
|
397
|
+
type: 'PRIMARY',
|
|
398
|
+
icon: 'Check',
|
|
399
|
+
allowMultipleResponses: (_a = options.allowMultipleResponses) !== null && _a !== void 0 ? _a : false,
|
|
400
|
+
handler: {
|
|
401
|
+
type: 'CALLBACK',
|
|
402
|
+
callbackId: options.callbackId,
|
|
403
|
+
payload: { action: 'complete' },
|
|
404
|
+
includeFormState: false,
|
|
405
|
+
},
|
|
406
|
+
},
|
|
407
|
+
],
|
|
490
408
|
data: options.data,
|
|
491
|
-
};
|
|
409
|
+
});
|
|
492
410
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from './custom-instance';
|
|
2
2
|
export * from './generated/v3-client';
|
|
3
3
|
export * from './sdk';
|
|
4
|
-
export { CustomMessageSchema, MessageNodeSchema, ConditionSchema, ValidationSchema, DataSourceSchema, CustomMessageThemeSchema, PredefinedCustomMessageTypeSchema, MessageActionSchema, createApprovalMessage, createReportMessage, createFormMessage, createTaskCardMessage,
|
|
4
|
+
export { CustomMessageSchema, MessageNodeSchema, ConditionSchema, ValidationSchema, DataSourceSchema, CustomMessageThemeSchema, PredefinedCustomMessageTypeSchema, MessageActionSchema, createApprovalMessage, createReportMessage, createFormMessage, createTaskCardMessage, type CustomMessage, type MessageNode, type ConditionSchemaType, type ValidationSchemaType, type CustomMessageTheme, type PredefinedCustomMessageType, type MessageAction, type CreateApprovalMessageOptions, type CreateReportMessageOptions, type CreateFormMessageOptions, type CreateTaskCardMessageOptions, type FormFieldConfig, } from './custom-message-schema';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from './custom-instance';
|
|
2
2
|
export * from './generated/v3-client';
|
|
3
3
|
export * from './sdk';
|
|
4
|
-
export { CustomMessageSchema, MessageNodeSchema, ConditionSchema, ValidationSchema, DataSourceSchema, CustomMessageThemeSchema, PredefinedCustomMessageTypeSchema, MessageActionSchema, createApprovalMessage, createReportMessage, createFormMessage, createTaskCardMessage,
|
|
4
|
+
export { CustomMessageSchema, MessageNodeSchema, ConditionSchema, ValidationSchema, DataSourceSchema, CustomMessageThemeSchema, PredefinedCustomMessageTypeSchema, MessageActionSchema, createApprovalMessage, createReportMessage, createFormMessage, createTaskCardMessage, } from './custom-message-schema';
|
package/package.json
CHANGED
|
@@ -5,8 +5,6 @@ import {
|
|
|
5
5
|
createReportMessage,
|
|
6
6
|
createFormMessage,
|
|
7
7
|
createTaskCardMessage,
|
|
8
|
-
createLowStockAlertMessage,
|
|
9
|
-
formatLowStockItemName,
|
|
10
8
|
} from '../index';
|
|
11
9
|
|
|
12
10
|
describe('Custom Message Schema & Helper Builders', () => {
|
|
@@ -21,6 +19,7 @@ describe('Custom Message Schema & Helper Builders', () => {
|
|
|
21
19
|
],
|
|
22
20
|
callbackId: 'reimbursement_123',
|
|
23
21
|
priority: 'urgent',
|
|
22
|
+
allowMultipleResponses: true,
|
|
24
23
|
});
|
|
25
24
|
|
|
26
25
|
expect(approval.type).toBe('APPROVAL');
|
|
@@ -28,6 +27,7 @@ describe('Custom Message Schema & Helper Builders', () => {
|
|
|
28
27
|
expect(approval.context.priority).toBe('urgent');
|
|
29
28
|
expect(approval.actions).toHaveLength(2);
|
|
30
29
|
expect(approval.actions?.[0].id).toBe('approve');
|
|
30
|
+
expect(approval.actions?.[0].allowMultipleResponses).toBe(true);
|
|
31
31
|
expect(approval.actions?.[1].id).toBe('reject');
|
|
32
32
|
|
|
33
33
|
const validationResult = CustomMessageSchema.safeParse(approval);
|
|
@@ -56,7 +56,7 @@ describe('Custom Message Schema & Helper Builders', () => {
|
|
|
56
56
|
});
|
|
57
57
|
|
|
58
58
|
describe('createFormMessage', () => {
|
|
59
|
-
it('should generate a valid CustomMessage for forms and surveys', () => {
|
|
59
|
+
it('should generate a valid CustomMessage for forms and surveys with Radio and Switch inputs', () => {
|
|
60
60
|
const form = createFormMessage({
|
|
61
61
|
title: 'User Feedback Survey',
|
|
62
62
|
description: 'Please rate your experience',
|
|
@@ -73,6 +73,20 @@ describe('Custom Message Schema & Helper Builders', () => {
|
|
|
73
73
|
{ label: 'Low', value: 'low' },
|
|
74
74
|
],
|
|
75
75
|
},
|
|
76
|
+
{
|
|
77
|
+
id: 'frequency',
|
|
78
|
+
label: 'Usage Frequency',
|
|
79
|
+
type: 'radio',
|
|
80
|
+
options: [
|
|
81
|
+
{ label: 'Daily', value: 'daily' },
|
|
82
|
+
{ label: 'Weekly', value: 'weekly' },
|
|
83
|
+
],
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
id: 'newsletter',
|
|
87
|
+
label: 'Subscribe to product newsletter',
|
|
88
|
+
type: 'switch',
|
|
89
|
+
},
|
|
76
90
|
{
|
|
77
91
|
id: 'comments',
|
|
78
92
|
label: 'Additional Comments',
|
|
@@ -82,9 +96,10 @@ describe('Custom Message Schema & Helper Builders', () => {
|
|
|
82
96
|
});
|
|
83
97
|
|
|
84
98
|
expect(form.type).toBe('FORM');
|
|
85
|
-
expect(form.root.children).toHaveLength(
|
|
99
|
+
expect(form.root.children).toHaveLength(4);
|
|
86
100
|
expect(form.root.children?.[0].type).toBe('Input.Select');
|
|
87
|
-
expect(form.root.children?.[
|
|
101
|
+
expect(form.root.children?.[1].type).toBe('Input.RadioGroup');
|
|
102
|
+
expect(form.root.children?.[2].type).toBe('Input.Switch');
|
|
88
103
|
|
|
89
104
|
const validationResult = CustomMessageSchema.safeParse(form);
|
|
90
105
|
expect(validationResult.success).toBe(true);
|
|
@@ -110,70 +125,6 @@ describe('Custom Message Schema & Helper Builders', () => {
|
|
|
110
125
|
});
|
|
111
126
|
});
|
|
112
127
|
|
|
113
|
-
describe('createLowStockAlertMessage & formatLowStockItemName', () => {
|
|
114
|
-
it('should omit variant name if variant is missing, empty, or default (case-insensitive)', () => {
|
|
115
|
-
expect(formatLowStockItemName({ productName: 'Wireless Mouse' })).toBe('Wireless Mouse');
|
|
116
|
-
expect(formatLowStockItemName({ productName: 'Wireless Mouse', variantName: 'default' })).toBe('Wireless Mouse');
|
|
117
|
-
expect(formatLowStockItemName({ productName: 'Wireless Mouse', variantName: 'DEFAULT' })).toBe('Wireless Mouse');
|
|
118
|
-
expect(formatLowStockItemName({ productName: 'Wireless Mouse', variantName: ' Default ' })).toBe('Wireless Mouse');
|
|
119
|
-
|
|
120
|
-
expect(createLowStockAlertMessage({
|
|
121
|
-
productName: 'Wireless Mouse',
|
|
122
|
-
currentQuantity: 2,
|
|
123
|
-
thresholdQuantity: 5,
|
|
124
|
-
}).context.description).toContain('Wireless Mouse');
|
|
125
|
-
|
|
126
|
-
const msg1 = createLowStockAlertMessage({
|
|
127
|
-
productName: 'Wireless Mouse',
|
|
128
|
-
variantName: 'default',
|
|
129
|
-
currentQuantity: 2,
|
|
130
|
-
thresholdQuantity: 5,
|
|
131
|
-
});
|
|
132
|
-
|
|
133
|
-
const gridChildren1 = msg1.root.children?.[0]?.children || [];
|
|
134
|
-
const itemNameField1 = gridChildren1.find((c: any) => c.properties?.label === 'Item Name');
|
|
135
|
-
expect(itemNameField1?.properties?.value).toBe('Wireless Mouse');
|
|
136
|
-
|
|
137
|
-
const msg2 = createLowStockAlertMessage({
|
|
138
|
-
productName: 'Mechanical Keyboard',
|
|
139
|
-
variantName: 'DEFAULT',
|
|
140
|
-
currentQuantity: 1,
|
|
141
|
-
thresholdQuantity: 10,
|
|
142
|
-
});
|
|
143
|
-
const gridChildren2 = msg2.root.children?.[0]?.children || [];
|
|
144
|
-
const itemNameField2 = gridChildren2.find((c: any) => c.properties?.label === 'Item Name');
|
|
145
|
-
expect(itemNameField2?.properties?.value).toBe('Mechanical Keyboard');
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
it('should include variant name when variant is not default', () => {
|
|
149
|
-
expect(formatLowStockItemName({ productName: 'Ergonomic Chair', variantName: 'Mesh Black' })).toBe('Ergonomic Chair - Mesh Black');
|
|
150
|
-
|
|
151
|
-
const msg = createLowStockAlertMessage({
|
|
152
|
-
productName: 'Ergonomic Chair',
|
|
153
|
-
variantName: 'Mesh Black',
|
|
154
|
-
currentQuantity: 3,
|
|
155
|
-
thresholdQuantity: 8,
|
|
156
|
-
sku: 'CHAIR-BLK-01',
|
|
157
|
-
location: 'Warehouse A',
|
|
158
|
-
reorderUrl: 'https://inventory.example.com/reorder/CHAIR-BLK-01',
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
expect(msg.type).toBe('LOW_STOCK_ALERT');
|
|
162
|
-
expect(msg.context.title).toBe('Low Stock Alert');
|
|
163
|
-
expect(msg.context.priority).toBe('high');
|
|
164
|
-
|
|
165
|
-
const gridChildren = msg.root.children?.[0]?.children || [];
|
|
166
|
-
const itemNameField = gridChildren.find((c: any) => c.properties?.label === 'Item Name');
|
|
167
|
-
expect(itemNameField?.properties?.value).toBe('Ergonomic Chair - Mesh Black');
|
|
168
|
-
|
|
169
|
-
expect(msg.actions?.[0].handler.type).toBe('LINK');
|
|
170
|
-
expect(msg.actions?.[0].handler.url).toBe('https://inventory.example.com/reorder/CHAIR-BLK-01');
|
|
171
|
-
|
|
172
|
-
const validationResult = CustomMessageSchema.safeParse(msg);
|
|
173
|
-
expect(validationResult.success).toBe(true);
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
|
|
177
128
|
describe('Customization and Theming', () => {
|
|
178
129
|
it('should validate custom message theme overrides', () => {
|
|
179
130
|
const customMessage = createApprovalMessage({
|
|
@@ -41,7 +41,7 @@ export const ValidationSchema = z.object({
|
|
|
41
41
|
export type ValidationSchemaType = z.infer<typeof ValidationSchema>;
|
|
42
42
|
|
|
43
43
|
/**
|
|
44
|
-
* Data Source Schema for dynamic content (e.g., Select
|
|
44
|
+
* Data Source Schema for dynamic content (e.g., Select or Radio options).
|
|
45
45
|
*/
|
|
46
46
|
export const DataSourceSchema = z.object({
|
|
47
47
|
/** Source type: 'STATIC' for inline items, 'API' for external fetching, 'VARIABLE' for message data interpolation */
|
|
@@ -92,6 +92,10 @@ export const CustomMessageThemeSchema = z.object({
|
|
|
92
92
|
textColor: z.string().optional(),
|
|
93
93
|
/** Accent / Brand highlight color */
|
|
94
94
|
accentColor: z.string().optional(),
|
|
95
|
+
/** Inner card background override */
|
|
96
|
+
cardBackgroundColor: z.string().optional(),
|
|
97
|
+
/** Primary button background override */
|
|
98
|
+
primaryButtonColor: z.string().optional(),
|
|
95
99
|
/** Custom CSS class names applied to the container */
|
|
96
100
|
className: z.string().optional(),
|
|
97
101
|
});
|
|
@@ -102,7 +106,7 @@ export type CustomMessageTheme = z.infer<typeof CustomMessageThemeSchema>;
|
|
|
102
106
|
* A Node is the recursive structural building block of custom message UI components.
|
|
103
107
|
*/
|
|
104
108
|
export type MessageNode = {
|
|
105
|
-
/** The type identifier of the component (e.g., 'Layout.Card', 'Display.Field', 'Input.Text', '
|
|
109
|
+
/** The type identifier of the component (e.g., 'Layout.Card', 'Display.Field', 'Input.Text', 'Input.RadioGroup', 'Input.Switch', 'Display.Progress') */
|
|
106
110
|
type: string;
|
|
107
111
|
/** Unique identifier for the node (required for form inputs to track state & validation) */
|
|
108
112
|
id?: string;
|
|
@@ -110,6 +114,9 @@ export type MessageNode = {
|
|
|
110
114
|
properties?: Record<string, any>;
|
|
111
115
|
/** Nested child nodes rendered inside this node */
|
|
112
116
|
children?: MessageNode[];
|
|
117
|
+
/** Allow multiple responses toggle */
|
|
118
|
+
allowMultipleResponses?: boolean;
|
|
119
|
+
allowMultiple?: boolean;
|
|
113
120
|
/** Optional conditional display logic evaluating visibility based on form state or message data */
|
|
114
121
|
condition?: ConditionSchemaType;
|
|
115
122
|
/** Optional validation rules for user inputs */
|
|
@@ -126,8 +133,8 @@ export const MessageNodeSchema: z.ZodType<MessageNode> = z.lazy(() =>
|
|
|
126
133
|
properties: z.record(z.string(), z.any()).optional(),
|
|
127
134
|
children: z.array(MessageNodeSchema).optional(),
|
|
128
135
|
allowMultipleResponses: z.boolean().optional(),
|
|
129
|
-
|
|
130
|
-
|
|
136
|
+
allowMultiple: z.boolean().optional(),
|
|
137
|
+
condition: ConditionSchema.optional(),
|
|
131
138
|
validation: ValidationSchema.optional(),
|
|
132
139
|
metadata: z.record(z.string(), z.any()).optional(),
|
|
133
140
|
})
|
|
@@ -143,6 +150,7 @@ export const PredefinedCustomMessageTypeSchema = z.enum([
|
|
|
143
150
|
'FEEDBACK',
|
|
144
151
|
'TASK_CARD',
|
|
145
152
|
'SURVEY',
|
|
153
|
+
'LOW_STOCK_ALERT',
|
|
146
154
|
'GENERIC',
|
|
147
155
|
]);
|
|
148
156
|
|
|
@@ -173,9 +181,10 @@ export const MessageActionSchema = z.object({
|
|
|
173
181
|
/** Whether to automatically gather and send all current form input state in the callback payload */
|
|
174
182
|
includeFormState: z.boolean().default(true).optional(),
|
|
175
183
|
}),
|
|
176
|
-
/**
|
|
184
|
+
/** Flag to allow users to trigger this action multiple times */
|
|
177
185
|
allowMultipleResponses: z.boolean().optional(),
|
|
178
186
|
allowMultiple: z.boolean().optional(),
|
|
187
|
+
/** Optional visibility condition for displaying this action button */
|
|
179
188
|
condition: ConditionSchema.optional(),
|
|
180
189
|
});
|
|
181
190
|
|
|
@@ -189,7 +198,7 @@ export const CustomMessageSchema = z.object({
|
|
|
189
198
|
version: z.string().default('v1'),
|
|
190
199
|
/** Optional template identifier reference */
|
|
191
200
|
templateId: z.string().optional(),
|
|
192
|
-
/** The logical message category type (e.g. 'APPROVAL', 'REPORT', 'FORM', 'FEEDBACK', 'TASK_CARD', 'SURVEY', or custom string) */
|
|
201
|
+
/** The logical message category type (e.g. 'APPROVAL', 'REPORT', 'FORM', 'FEEDBACK', 'TASK_CARD', 'SURVEY', 'LOW_STOCK_ALERT', or custom string) */
|
|
193
202
|
type: z.string(),
|
|
194
203
|
/** Top-level configuration, branding, and header context */
|
|
195
204
|
context: z.object({
|
|
@@ -240,25 +249,13 @@ export interface CreateApprovalMessageOptions {
|
|
|
240
249
|
priority?: 'low' | 'normal' | 'high' | 'urgent';
|
|
241
250
|
approveLabel?: string;
|
|
242
251
|
rejectLabel?: string;
|
|
252
|
+
allowMultipleResponses?: boolean;
|
|
243
253
|
data?: Record<string, any>;
|
|
244
254
|
theme?: CustomMessageTheme;
|
|
245
255
|
}
|
|
246
256
|
|
|
247
257
|
/**
|
|
248
258
|
* Creates a standard Approval Custom Message schema structure.
|
|
249
|
-
*
|
|
250
|
-
* @example
|
|
251
|
-
* ```ts
|
|
252
|
-
* const approvalSchema = createApprovalMessage({
|
|
253
|
-
* title: 'Expense Reimbursement Request',
|
|
254
|
-
* description: 'Requested by Jane Doe for $450.00',
|
|
255
|
-
* fields: [
|
|
256
|
-
* { label: 'Category', value: 'Travel' },
|
|
257
|
-
* { label: 'Amount', value: '$450.00' }
|
|
258
|
-
* ],
|
|
259
|
-
* callbackId: 'expense-approval-101'
|
|
260
|
-
* });
|
|
261
|
-
* ```
|
|
262
259
|
*/
|
|
263
260
|
export const createApprovalMessage = (options: CreateApprovalMessageOptions): CustomMessage => ({
|
|
264
261
|
version: 'v1',
|
|
@@ -289,6 +286,7 @@ export const createApprovalMessage = (options: CreateApprovalMessageOptions): Cu
|
|
|
289
286
|
label: options.approveLabel || 'Approve',
|
|
290
287
|
type: 'PRIMARY',
|
|
291
288
|
icon: 'Check',
|
|
289
|
+
allowMultipleResponses: options.allowMultipleResponses ?? false,
|
|
292
290
|
handler: {
|
|
293
291
|
type: 'CALLBACK',
|
|
294
292
|
callbackId: options.callbackId,
|
|
@@ -301,6 +299,7 @@ export const createApprovalMessage = (options: CreateApprovalMessageOptions): Cu
|
|
|
301
299
|
label: options.rejectLabel || 'Reject',
|
|
302
300
|
type: 'DESTRUCTIVE',
|
|
303
301
|
icon: 'X',
|
|
302
|
+
allowMultipleResponses: options.allowMultipleResponses ?? false,
|
|
304
303
|
handler: {
|
|
305
304
|
type: 'CALLBACK',
|
|
306
305
|
callbackId: options.callbackId,
|
|
@@ -374,7 +373,7 @@ export const createReportMessage = (options: CreateReportMessageOptions): Custom
|
|
|
374
373
|
export interface FormFieldConfig {
|
|
375
374
|
id: string;
|
|
376
375
|
label: string;
|
|
377
|
-
type?: 'text' | 'textarea' | 'select' | 'checkbox';
|
|
376
|
+
type?: 'text' | 'textarea' | 'select' | 'checkbox' | 'radio' | 'switch';
|
|
378
377
|
placeholder?: string;
|
|
379
378
|
options?: Array<{ label: string; value: string }>;
|
|
380
379
|
required?: boolean;
|
|
@@ -390,6 +389,7 @@ export interface CreateFormMessageOptions {
|
|
|
390
389
|
submitCallbackId: string;
|
|
391
390
|
submitLabel?: string;
|
|
392
391
|
type?: 'FORM' | 'FEEDBACK' | 'SURVEY';
|
|
392
|
+
allowMultipleResponses?: boolean;
|
|
393
393
|
data?: Record<string, any>;
|
|
394
394
|
theme?: CustomMessageTheme;
|
|
395
395
|
}
|
|
@@ -415,7 +415,11 @@ export const createFormMessage = (options: CreateFormMessageOptions): CustomMess
|
|
|
415
415
|
? 'Input.Select'
|
|
416
416
|
: field.type === 'checkbox'
|
|
417
417
|
? 'Input.Checkbox'
|
|
418
|
-
:
|
|
418
|
+
: field.type === 'radio'
|
|
419
|
+
? 'Input.RadioGroup'
|
|
420
|
+
: field.type === 'switch'
|
|
421
|
+
? 'Input.Switch'
|
|
422
|
+
: 'Input.Text';
|
|
419
423
|
|
|
420
424
|
const validation: ValidationSchemaType | undefined = field.required
|
|
421
425
|
? { required: true, errorMessage: `${field.label} is required` }
|
|
@@ -430,11 +434,12 @@ export const createFormMessage = (options: CreateFormMessageOptions): CustomMess
|
|
|
430
434
|
properties.multiline = true;
|
|
431
435
|
}
|
|
432
436
|
|
|
433
|
-
if (field.type === 'select' && field.options) {
|
|
437
|
+
if ((field.type === 'select' || field.type === 'radio') && field.options) {
|
|
434
438
|
properties.dataSource = {
|
|
435
439
|
type: 'STATIC',
|
|
436
440
|
items: field.options,
|
|
437
441
|
};
|
|
442
|
+
properties.options = field.options;
|
|
438
443
|
}
|
|
439
444
|
|
|
440
445
|
return {
|
|
@@ -451,6 +456,7 @@ export const createFormMessage = (options: CreateFormMessageOptions): CustomMess
|
|
|
451
456
|
label: options.submitLabel || 'Submit',
|
|
452
457
|
type: 'PRIMARY',
|
|
453
458
|
icon: 'Send',
|
|
459
|
+
allowMultipleResponses: options.allowMultipleResponses ?? false,
|
|
454
460
|
handler: {
|
|
455
461
|
type: 'CALLBACK',
|
|
456
462
|
callbackId: options.submitCallbackId,
|
|
@@ -472,6 +478,7 @@ export interface CreateTaskCardMessageOptions {
|
|
|
472
478
|
assignee?: string;
|
|
473
479
|
dueDate?: string;
|
|
474
480
|
callbackId: string;
|
|
481
|
+
allowMultipleResponses?: boolean;
|
|
475
482
|
data?: Record<string, any>;
|
|
476
483
|
theme?: CustomMessageTheme;
|
|
477
484
|
}
|
|
@@ -509,6 +516,7 @@ export const createTaskCardMessage = (options: CreateTaskCardMessageOptions): Cu
|
|
|
509
516
|
label: 'Mark Completed',
|
|
510
517
|
type: 'PRIMARY',
|
|
511
518
|
icon: 'Check',
|
|
519
|
+
allowMultipleResponses: options.allowMultipleResponses ?? false,
|
|
512
520
|
handler: {
|
|
513
521
|
type: 'CALLBACK',
|
|
514
522
|
callbackId: options.callbackId,
|
|
@@ -519,122 +527,3 @@ export const createTaskCardMessage = (options: CreateTaskCardMessageOptions): Cu
|
|
|
519
527
|
],
|
|
520
528
|
data: options.data,
|
|
521
529
|
});
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* Helper to format product item name combining productName and variantName.
|
|
525
|
-
* If variantName is missing, empty, or 'default' (case-insensitive), returns productName.
|
|
526
|
-
*/
|
|
527
|
-
export const formatLowStockItemName = (options: { productName: string; variantName?: string | null }): string => {
|
|
528
|
-
const trimmedProduct = options.productName.trim();
|
|
529
|
-
const trimmedVariant = options.variantName ? options.variantName.trim() : '';
|
|
530
|
-
|
|
531
|
-
if (!trimmedVariant || trimmedVariant.toLowerCase() === 'default') {
|
|
532
|
-
return trimmedProduct;
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
return `${trimmedProduct} - ${trimmedVariant}`;
|
|
536
|
-
};
|
|
537
|
-
|
|
538
|
-
/**
|
|
539
|
-
* Builder options for creating a Low Stock Alert custom message schema.
|
|
540
|
-
*/
|
|
541
|
-
export interface CreateLowStockAlertMessageOptions {
|
|
542
|
-
productName: string;
|
|
543
|
-
variantName?: string | null;
|
|
544
|
-
currentQuantity: number;
|
|
545
|
-
thresholdQuantity: number;
|
|
546
|
-
sku?: string;
|
|
547
|
-
location?: string;
|
|
548
|
-
reorderUrl?: string;
|
|
549
|
-
callbackId?: string;
|
|
550
|
-
priority?: 'low' | 'normal' | 'high' | 'urgent';
|
|
551
|
-
data?: Record<string, any>;
|
|
552
|
-
theme?: CustomMessageTheme;
|
|
553
|
-
}
|
|
554
|
-
|
|
555
|
-
/**
|
|
556
|
-
* Creates a standard Low Stock Alert Custom Message schema structure.
|
|
557
|
-
*/
|
|
558
|
-
export const createLowStockAlertMessage = (options: CreateLowStockAlertMessageOptions): CustomMessage => {
|
|
559
|
-
const itemName = formatLowStockItemName({
|
|
560
|
-
productName: options.productName,
|
|
561
|
-
variantName: options.variantName,
|
|
562
|
-
});
|
|
563
|
-
|
|
564
|
-
const fields: Array<{ label: string; value: string }> = [
|
|
565
|
-
{ label: 'Item Name', value: itemName },
|
|
566
|
-
{ label: 'Current Stock', value: `${options.currentQuantity} units` },
|
|
567
|
-
{ label: 'Reorder Threshold', value: `${options.thresholdQuantity} units` },
|
|
568
|
-
];
|
|
569
|
-
|
|
570
|
-
if (options.sku) {
|
|
571
|
-
fields.push({ label: 'SKU', value: options.sku });
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
if (options.location) {
|
|
575
|
-
fields.push({ label: 'Location', value: options.location });
|
|
576
|
-
}
|
|
577
|
-
|
|
578
|
-
const actions: MessageAction[] = [];
|
|
579
|
-
|
|
580
|
-
if (options.reorderUrl) {
|
|
581
|
-
actions.push({
|
|
582
|
-
id: 'reorder',
|
|
583
|
-
label: 'Reorder Stock',
|
|
584
|
-
type: 'PRIMARY',
|
|
585
|
-
icon: 'ExternalLink',
|
|
586
|
-
handler: {
|
|
587
|
-
type: 'LINK',
|
|
588
|
-
url: options.reorderUrl,
|
|
589
|
-
},
|
|
590
|
-
});
|
|
591
|
-
} else if (options.callbackId) {
|
|
592
|
-
actions.push({
|
|
593
|
-
id: 'reorder',
|
|
594
|
-
label: 'Reorder Stock',
|
|
595
|
-
type: 'PRIMARY',
|
|
596
|
-
icon: 'Send',
|
|
597
|
-
handler: {
|
|
598
|
-
type: 'CALLBACK',
|
|
599
|
-
callbackId: options.callbackId,
|
|
600
|
-
payload: {
|
|
601
|
-
action: 'reorder',
|
|
602
|
-
productName: options.productName,
|
|
603
|
-
variantName: options.variantName || undefined,
|
|
604
|
-
itemName,
|
|
605
|
-
currentQuantity: options.currentQuantity,
|
|
606
|
-
thresholdQuantity: options.thresholdQuantity,
|
|
607
|
-
sku: options.sku,
|
|
608
|
-
},
|
|
609
|
-
includeFormState: false,
|
|
610
|
-
},
|
|
611
|
-
});
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
return {
|
|
615
|
-
version: 'v1',
|
|
616
|
-
type: 'LOW_STOCK_ALERT',
|
|
617
|
-
context: {
|
|
618
|
-
title: 'Low Stock Alert',
|
|
619
|
-
description: `Stock level for ${itemName} has dropped below threshold.`,
|
|
620
|
-
icon: 'AlertCircle',
|
|
621
|
-
priority: options.priority || 'high',
|
|
622
|
-
},
|
|
623
|
-
theme: options.theme,
|
|
624
|
-
root: {
|
|
625
|
-
type: 'Layout.Card',
|
|
626
|
-
children: [
|
|
627
|
-
{
|
|
628
|
-
type: 'Layout.Grid',
|
|
629
|
-
properties: { columns: 2 },
|
|
630
|
-
children: fields.map(f => ({
|
|
631
|
-
type: 'Display.Field',
|
|
632
|
-
properties: { label: f.label, value: f.value },
|
|
633
|
-
})),
|
|
634
|
-
},
|
|
635
|
-
],
|
|
636
|
-
},
|
|
637
|
-
actions: actions.length > 0 ? actions : undefined,
|
|
638
|
-
data: options.data,
|
|
639
|
-
};
|
|
640
|
-
};
|
package/src/index.ts
CHANGED
|
@@ -14,8 +14,6 @@ export {
|
|
|
14
14
|
createReportMessage,
|
|
15
15
|
createFormMessage,
|
|
16
16
|
createTaskCardMessage,
|
|
17
|
-
createLowStockAlertMessage,
|
|
18
|
-
formatLowStockItemName,
|
|
19
17
|
type CustomMessage,
|
|
20
18
|
type MessageNode,
|
|
21
19
|
type ConditionSchemaType,
|
|
@@ -27,6 +25,5 @@ export {
|
|
|
27
25
|
type CreateReportMessageOptions,
|
|
28
26
|
type CreateFormMessageOptions,
|
|
29
27
|
type CreateTaskCardMessageOptions,
|
|
30
|
-
type CreateLowStockAlertMessageOptions,
|
|
31
28
|
type FormFieldConfig,
|
|
32
29
|
} from './custom-message-schema';
|