@rippling/rippling-sdk 0.2.0-alpha.68 → 0.2.0-alpha.70
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/examples/manifest/dental-practice-management/dental-practice-management.ts +125 -1
- package/examples/manifest/dental-practice-management/functions/chair-schedule.ts +4 -4
- package/examples/manifest/dental-practice-management/functions/complete-visit.ts +121 -0
- package/examples/manifest/dental-practice-management/functions/operatory-list.ts +4 -4
- package/examples/manifest/dental-practice-management/functions/patient-list.ts +4 -4
- package/examples/manifest/dental-practice-management/functions/treatment-plan-list.ts +4 -4
- package/examples/manifest/gym-membership-management/functions/check-in-desk.ts +4 -4
- package/examples/manifest/gym-membership-management/functions/member-list.ts +4 -4
- package/examples/manifest/gym-membership-management/functions/today-schedule.ts +4 -4
- package/examples/manifest/gym-membership-management/functions/trainer-list.ts +4 -4
- package/examples/manifest/simple-todo-app/functions/todo-list.ts +4 -4
- package/examples/manifest/todo-app-without-object-list-view/functions/todo-page.ts +17 -7
- package/functions.d.mts +44 -1
- package/functions.d.mts.map +1 -1
- package/functions.d.ts +44 -1
- package/functions.d.ts.map +1 -1
- package/functions.js.map +1 -1
- package/functions.mjs.map +1 -1
- package/lib/manifest/custom-object-page-layout.d.mts +3 -3
- package/lib/manifest/custom-object-page-layout.d.mts.map +1 -1
- package/lib/manifest/custom-object-page-layout.d.ts +3 -3
- package/lib/manifest/custom-object-page-layout.d.ts.map +1 -1
- package/lib/manifest/custom-object-page-layout.js +7 -3
- package/lib/manifest/custom-object-page-layout.js.map +1 -1
- package/lib/manifest/custom-object-page-layout.mjs +7 -3
- package/lib/manifest/custom-object-page-layout.mjs.map +1 -1
- package/lib/manifest/index.d.mts +1 -1
- package/lib/manifest/index.d.mts.map +1 -1
- package/lib/manifest/index.d.ts +1 -1
- package/lib/manifest/index.d.ts.map +1 -1
- package/lib/manifest/index.js.map +1 -1
- package/lib/manifest/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/functions.md +26 -0
- package/src/functions.ts +66 -1
- package/src/lib/manifest/custom-object-page-layout.ts +13 -7
- package/src/lib/manifest/index.ts +0 -1
- package/src/version.ts +1 -1
- package/version.d.mts +1 -1
- package/version.d.ts +1 -1
- package/version.js +1 -1
- package/version.mjs +1 -1
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
* with status, treatment plans, rollups, and an SDUI ObjectListView tab for appointments.
|
|
4
4
|
*
|
|
5
5
|
* dental_patient__c ← chart: demographics, allergies, notes
|
|
6
|
+
* dental_provider__c ← providers selectable for appointments
|
|
6
7
|
* dental_operatory__c ← chair / room (parent for same-day board rollups)
|
|
7
8
|
* dental_appointment__c ← child of operatory; patient lookup, time, status, visit type
|
|
8
9
|
* dental_treatment_plan__c ← child of patient; plan status, procedures, estimates
|
|
@@ -146,6 +147,50 @@ const patientLabelField = new FormulaField(patientObj, {
|
|
|
146
147
|
section: patientIdentitySection,
|
|
147
148
|
});
|
|
148
149
|
|
|
150
|
+
// ── Provider ────────────────────────────────────────────────────────────────
|
|
151
|
+
const providerObj = new CustomObject(manifest, {
|
|
152
|
+
apiName: 'dental_provider__c',
|
|
153
|
+
name: 'Provider',
|
|
154
|
+
pluralLabel: 'Providers',
|
|
155
|
+
category: dentalCategory,
|
|
156
|
+
description: 'Clinicians who can be assigned to appointment blocks',
|
|
157
|
+
icon: { emoji: '🧑⚕️' },
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
const providerSection = new CustomObjectFieldSection(providerObj, {
|
|
161
|
+
name: 'Provider',
|
|
162
|
+
sectionId: 'sec_provider_info',
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
const providerNameField = providerObj.standardFields.name;
|
|
166
|
+
|
|
167
|
+
const providerStatusField = new SelectField(providerObj, {
|
|
168
|
+
apiName: 'provider_status__c',
|
|
169
|
+
displayName: 'Status',
|
|
170
|
+
description: 'Whether this provider is active in the practice',
|
|
171
|
+
options: ['Active', 'On leave', 'Inactive'],
|
|
172
|
+
required: true,
|
|
173
|
+
section: providerSection,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
const providerBookingStatusField = new SelectField(providerObj, {
|
|
177
|
+
apiName: 'booking_status__c',
|
|
178
|
+
displayName: 'Booking status',
|
|
179
|
+
description: 'Whether scheduling should offer this provider for new appointments',
|
|
180
|
+
options: ['Open', 'Limited', 'Closed'],
|
|
181
|
+
required: true,
|
|
182
|
+
section: providerSection,
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
const providerNextAvailableDaysField = new NumberField(providerObj, {
|
|
186
|
+
apiName: 'next_available_days__c',
|
|
187
|
+
displayName: 'Next available (days)',
|
|
188
|
+
description: 'Estimated days until this provider has an open appointment slot',
|
|
189
|
+
decimalPlaces: 0,
|
|
190
|
+
required: true,
|
|
191
|
+
section: providerSection,
|
|
192
|
+
});
|
|
193
|
+
|
|
149
194
|
// ── Operatory (chair) ─────────────────────────────────────────────────────────
|
|
150
195
|
const operatoryObj = new CustomObject(manifest, {
|
|
151
196
|
apiName: 'dental_operatory__c',
|
|
@@ -230,6 +275,18 @@ const apptPatientRef = new LookupField(apptObj, {
|
|
|
230
275
|
section: apptPatientSection,
|
|
231
276
|
});
|
|
232
277
|
|
|
278
|
+
const apptProviderRef = new LookupField(apptObj, {
|
|
279
|
+
apiName: 'provider_ref__c',
|
|
280
|
+
displayName: 'Provider',
|
|
281
|
+
target: providerObj,
|
|
282
|
+
relatedDataLabel: 'Appointments',
|
|
283
|
+
required: true,
|
|
284
|
+
lookup_filter_rql_condition:
|
|
285
|
+
"((provider_status__c == 'Active') AND (next_available_days__c <= 14) AND (booking_status__c != 'Closed'))",
|
|
286
|
+
description: 'Provider assigned to this visit (active and bookable within two weeks)',
|
|
287
|
+
section: apptPatientSection,
|
|
288
|
+
});
|
|
289
|
+
|
|
233
290
|
const apptVisitTypeField = new SelectField(apptObj, {
|
|
234
291
|
apiName: 'visit_type__c',
|
|
235
292
|
displayName: 'Visit type',
|
|
@@ -402,6 +459,22 @@ new ListViewDef(patientObj, {
|
|
|
402
459
|
objectScope: 'all',
|
|
403
460
|
});
|
|
404
461
|
|
|
462
|
+
new ListViewDef(providerObj, {
|
|
463
|
+
viewId: 'view_dental_providers',
|
|
464
|
+
name: 'All providers',
|
|
465
|
+
description: 'Provider directory with appointment booking fields',
|
|
466
|
+
fields: [
|
|
467
|
+
providerNameField,
|
|
468
|
+
providerStatusField,
|
|
469
|
+
providerBookingStatusField,
|
|
470
|
+
providerNextAvailableDaysField,
|
|
471
|
+
],
|
|
472
|
+
orderBy: 'name',
|
|
473
|
+
sortOrder: 'ASC',
|
|
474
|
+
isPublic: true,
|
|
475
|
+
objectScope: 'all',
|
|
476
|
+
});
|
|
477
|
+
|
|
405
478
|
new ListViewDef(operatoryObj, {
|
|
406
479
|
viewId: 'view_dental_all_operatories',
|
|
407
480
|
name: 'All operatories',
|
|
@@ -423,6 +496,7 @@ new ListViewDef(apptObj, {
|
|
|
423
496
|
apptStartField,
|
|
424
497
|
apptDurationMins,
|
|
425
498
|
apptPatientRef,
|
|
499
|
+
apptProviderRef,
|
|
426
500
|
apptVisitTypeField,
|
|
427
501
|
apptStatusField,
|
|
428
502
|
apptBoardLabel,
|
|
@@ -490,6 +564,37 @@ new CustomObjectPageLayout(patientObj, {
|
|
|
490
564
|
visibilityConditions: {},
|
|
491
565
|
});
|
|
492
566
|
|
|
567
|
+
new CustomObjectPageLayout(providerObj, {
|
|
568
|
+
apiName: 'default',
|
|
569
|
+
name: 'Provider',
|
|
570
|
+
layoutId: 'layout_dental_provider',
|
|
571
|
+
tabEdits: {
|
|
572
|
+
newTabs: [
|
|
573
|
+
{
|
|
574
|
+
key: 'provider',
|
|
575
|
+
name: 'Provider',
|
|
576
|
+
type: 'tab_with_sections',
|
|
577
|
+
sections: [
|
|
578
|
+
{
|
|
579
|
+
name: 'Booking',
|
|
580
|
+
type: 'fields_section',
|
|
581
|
+
section: providerSection,
|
|
582
|
+
fields: [
|
|
583
|
+
{ field: providerNameField, editable: true },
|
|
584
|
+
providerStatusField,
|
|
585
|
+
providerBookingStatusField,
|
|
586
|
+
providerNextAvailableDaysField,
|
|
587
|
+
],
|
|
588
|
+
},
|
|
589
|
+
],
|
|
590
|
+
},
|
|
591
|
+
],
|
|
592
|
+
systemTabEdits: {},
|
|
593
|
+
tabsOrder: ['provider'],
|
|
594
|
+
},
|
|
595
|
+
visibilityConditions: {},
|
|
596
|
+
});
|
|
597
|
+
|
|
493
598
|
new CustomObjectPageLayout(operatoryObj, {
|
|
494
599
|
apiName: 'default',
|
|
495
600
|
name: 'Operatory',
|
|
@@ -516,6 +621,15 @@ new CustomObjectPageLayout(operatoryObj, {
|
|
|
516
621
|
visibilityConditions: {},
|
|
517
622
|
});
|
|
518
623
|
|
|
624
|
+
const completeVisitFn = new ManifestFunction(manifest, {
|
|
625
|
+
apiName: 'dental_complete_visit_fn',
|
|
626
|
+
name: 'completeVisit',
|
|
627
|
+
description: 'Detail-view action that completes an appointment and drafts follow-up treatment',
|
|
628
|
+
code: fs.readFileSync(path.join(__dirname, 'functions', 'complete-visit.ts'), 'utf-8'),
|
|
629
|
+
dependencies: { '@rippling/rippling-sdk': '^0.2.0-alpha.65' },
|
|
630
|
+
isAsync: false,
|
|
631
|
+
});
|
|
632
|
+
|
|
519
633
|
new CustomObjectPageLayout(apptObj, {
|
|
520
634
|
apiName: 'default',
|
|
521
635
|
name: 'Appointment',
|
|
@@ -537,7 +651,14 @@ new CustomObjectPageLayout(apptObj, {
|
|
|
537
651
|
name: 'Patient & status',
|
|
538
652
|
type: 'fields_section',
|
|
539
653
|
section: apptPatientSection,
|
|
540
|
-
fields: [
|
|
654
|
+
fields: [
|
|
655
|
+
apptPatientRef,
|
|
656
|
+
apptProviderRef,
|
|
657
|
+
apptVisitTypeField,
|
|
658
|
+
apptStatusField,
|
|
659
|
+
apptBoardLabel,
|
|
660
|
+
apptClinicalNotes,
|
|
661
|
+
],
|
|
541
662
|
},
|
|
542
663
|
],
|
|
543
664
|
},
|
|
@@ -545,6 +666,9 @@ new CustomObjectPageLayout(apptObj, {
|
|
|
545
666
|
systemTabEdits: {},
|
|
546
667
|
tabsOrder: ['visit'],
|
|
547
668
|
},
|
|
669
|
+
headerEdits: {
|
|
670
|
+
buttons: [completeVisitFn],
|
|
671
|
+
},
|
|
548
672
|
visibilityConditions: {},
|
|
549
673
|
});
|
|
550
674
|
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'dental_appointment__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import RipplingSDK, {
|
|
2
|
+
DetailViewActionFunctionEvent,
|
|
3
|
+
FunctionContext,
|
|
4
|
+
FunctionResponse,
|
|
5
|
+
} from '@rippling/rippling-sdk';
|
|
6
|
+
import type { CustomObjectDataRow } from '@rippling/rippling-sdk/resources/custom-objects/records';
|
|
7
|
+
|
|
8
|
+
const APPOINTMENT_OBJECT_API_NAME = 'dental_appointment__c';
|
|
9
|
+
const TREATMENT_PLAN_OBJECT_API_NAME = 'dental_treatment_plan__c';
|
|
10
|
+
|
|
11
|
+
type CompleteVisitParameters = {
|
|
12
|
+
nextStepSummary?: string;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
type CompleteVisitEvent = DetailViewActionFunctionEvent<
|
|
16
|
+
CompleteVisitParameters,
|
|
17
|
+
typeof APPOINTMENT_OBJECT_API_NAME,
|
|
18
|
+
'dental_complete_visit_fn',
|
|
19
|
+
'layout_dental_appointment'
|
|
20
|
+
>;
|
|
21
|
+
|
|
22
|
+
type CompleteVisitResponse = {
|
|
23
|
+
appointmentId: string;
|
|
24
|
+
treatmentPlanId?: string;
|
|
25
|
+
message: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
function createClient(context: FunctionContext): RipplingSDK {
|
|
29
|
+
return new RipplingSDK({
|
|
30
|
+
bearerToken: context.env.rippling_user_bearer_token,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function stringValue(record: CustomObjectDataRow, key: string): string {
|
|
35
|
+
const value = record[key];
|
|
36
|
+
return typeof value === 'string' ? value : '';
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function lookupId(record: CustomObjectDataRow, key: string): string | undefined {
|
|
40
|
+
const value = record[key];
|
|
41
|
+
if (typeof value === 'string') return value;
|
|
42
|
+
if (value == null || typeof value !== 'object') return undefined;
|
|
43
|
+
|
|
44
|
+
const nested = value as Record<string, unknown>;
|
|
45
|
+
return typeof nested['id'] === 'string' ? nested['id'] : undefined;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function ok(body: CompleteVisitResponse): FunctionResponse<CompleteVisitResponse> {
|
|
49
|
+
return new FunctionResponse({
|
|
50
|
+
body,
|
|
51
|
+
statusCode: 200,
|
|
52
|
+
headers: {},
|
|
53
|
+
message: body.message,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function badRequest(message: string): FunctionResponse<{ error: string }> {
|
|
58
|
+
return new FunctionResponse({
|
|
59
|
+
body: { error: message },
|
|
60
|
+
statusCode: 400,
|
|
61
|
+
headers: {},
|
|
62
|
+
message,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export async function onRipplingEvent(
|
|
67
|
+
event: CompleteVisitEvent,
|
|
68
|
+
context: FunctionContext,
|
|
69
|
+
): Promise<FunctionResponse<CompleteVisitResponse | { error: string }>> {
|
|
70
|
+
if (event.object_api_name !== APPOINTMENT_OBJECT_API_NAME || event.button !== 'dental_complete_visit_fn') {
|
|
71
|
+
return badRequest('Unsupported detail view action.');
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const client = createClient(context);
|
|
75
|
+
const appointment = await client.customObjects.records.retrieve(
|
|
76
|
+
APPOINTMENT_OBJECT_API_NAME,
|
|
77
|
+
event.record_id,
|
|
78
|
+
);
|
|
79
|
+
|
|
80
|
+
if (stringValue(appointment, 'appointment_status__c') === 'Completed') {
|
|
81
|
+
return ok({
|
|
82
|
+
appointmentId: event.record_id,
|
|
83
|
+
message: `${appointment.name} is already completed.`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
await client.customObjects.records.update(APPOINTMENT_OBJECT_API_NAME, event.record_id, {
|
|
88
|
+
appointment_status__c: 'Completed',
|
|
89
|
+
visit_notes__c: stringValue(appointment, 'visit_notes__c'),
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const nextStepSummary = event.parameters.nextStepSummary?.trim();
|
|
93
|
+
if (!nextStepSummary) {
|
|
94
|
+
return ok({
|
|
95
|
+
appointmentId: event.record_id,
|
|
96
|
+
message: `${appointment.name} marked completed.`,
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const patientId = lookupId(appointment, 'patient_ref__c');
|
|
101
|
+
if (!patientId) {
|
|
102
|
+
return ok({
|
|
103
|
+
appointmentId: event.record_id,
|
|
104
|
+
message: `${appointment.name} marked completed. No treatment plan was created because the appointment has no patient.`,
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const treatmentPlan = await client.customObjects.records.create(TREATMENT_PLAN_OBJECT_API_NAME, {
|
|
109
|
+
name: `Follow-up: ${appointment.name}`,
|
|
110
|
+
plan_patient_ref__c: patientId,
|
|
111
|
+
plan_status__c: 'Draft',
|
|
112
|
+
procedures_summary__c: nextStepSummary,
|
|
113
|
+
});
|
|
114
|
+
const response: CompleteVisitResponse = {
|
|
115
|
+
appointmentId: event.record_id,
|
|
116
|
+
message: `${appointment.name} marked completed and follow-up treatment plan drafted.`,
|
|
117
|
+
};
|
|
118
|
+
if (treatmentPlan.data?.id != null) response.treatmentPlanId = treatmentPlan.data.id;
|
|
119
|
+
|
|
120
|
+
return ok(response);
|
|
121
|
+
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'dental_operatory__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'dental_patient__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'dental_treatment_plan__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'gym_class_enrollment__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'gym_member__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'gym_class_session__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'gym_trainer__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { FunctionContext,
|
|
1
|
+
import { FunctionContext, FunctionResponse, SduiPageFunctionEvent } from '@rippling/rippling-sdk';
|
|
2
2
|
import { ObjectListView, render } from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
3
3
|
|
|
4
4
|
const OBJECT = 'simple_todo__c';
|
|
5
5
|
|
|
6
6
|
export async function onRipplingEvent(
|
|
7
|
-
event:
|
|
7
|
+
event: SduiPageFunctionEvent,
|
|
8
8
|
context: FunctionContext,
|
|
9
9
|
): Promise<FunctionResponse> {
|
|
10
|
-
const action = event
|
|
10
|
+
const action = event.parameters.action;
|
|
11
11
|
|
|
12
|
-
if (
|
|
12
|
+
if (action === 'init') {
|
|
13
13
|
const spec = render({
|
|
14
14
|
root: ObjectListView({
|
|
15
15
|
props: { objectApiName: OBJECT },
|
|
@@ -32,10 +32,20 @@ import {
|
|
|
32
32
|
setState,
|
|
33
33
|
triggerFunction,
|
|
34
34
|
} from '@rippling/pebble-sdui-web/catalogs/custom-apps';
|
|
35
|
-
import RipplingSDK, {
|
|
35
|
+
import RipplingSDK, {
|
|
36
|
+
FunctionContext,
|
|
37
|
+
FunctionResponse,
|
|
38
|
+
SduiPageFunctionEvent,
|
|
39
|
+
} from '@rippling/rippling-sdk';
|
|
36
40
|
import type { CustomObjectDataRow } from '@rippling/rippling-sdk/resources/custom-objects/records';
|
|
37
41
|
|
|
38
42
|
const OBJECT_API_NAME = 'todo__c';
|
|
43
|
+
type TodoPageAction = 'init' | 'addTodo' | 'toggleTodo' | 'clearCompleted';
|
|
44
|
+
type TodoPageFunctionParameters = {
|
|
45
|
+
action: TodoPageAction;
|
|
46
|
+
text?: string;
|
|
47
|
+
todoId?: string;
|
|
48
|
+
};
|
|
39
49
|
|
|
40
50
|
type Todo = {
|
|
41
51
|
id: string;
|
|
@@ -125,7 +135,7 @@ function serverError(error: unknown): FunctionResponse {
|
|
|
125
135
|
});
|
|
126
136
|
}
|
|
127
137
|
|
|
128
|
-
function stringParam(params:
|
|
138
|
+
function stringParam(params: TodoPageFunctionParameters, key: 'text' | 'todoId'): string {
|
|
129
139
|
const value = params[key];
|
|
130
140
|
return typeof value === 'string' ? value.trim() : '';
|
|
131
141
|
}
|
|
@@ -396,7 +406,7 @@ function renderSpec(state: TodoAppState, functionId: string) {
|
|
|
396
406
|
|
|
397
407
|
async function addTodo(
|
|
398
408
|
client: RipplingSDK,
|
|
399
|
-
params:
|
|
409
|
+
params: TodoPageFunctionParameters,
|
|
400
410
|
roleId: string,
|
|
401
411
|
): Promise<TodoListState> {
|
|
402
412
|
const text = stringParam(params, 'text');
|
|
@@ -415,7 +425,7 @@ async function addTodo(
|
|
|
415
425
|
|
|
416
426
|
async function toggleTodo(
|
|
417
427
|
client: RipplingSDK,
|
|
418
|
-
params:
|
|
428
|
+
params: TodoPageFunctionParameters,
|
|
419
429
|
roleId: string,
|
|
420
430
|
): Promise<TodoListState> {
|
|
421
431
|
const todoId = stringParam(params, 'todoId');
|
|
@@ -449,11 +459,11 @@ async function clearCompleted(client: RipplingSDK, roleId: string): Promise<Todo
|
|
|
449
459
|
}
|
|
450
460
|
|
|
451
461
|
export async function onRipplingEvent(
|
|
452
|
-
event:
|
|
462
|
+
event: SduiPageFunctionEvent<TodoPageFunctionParameters>,
|
|
453
463
|
context: FunctionContext,
|
|
454
464
|
): Promise<FunctionResponse> {
|
|
455
|
-
const params =
|
|
456
|
-
const action =
|
|
465
|
+
const params = event.parameters;
|
|
466
|
+
const action = params.action;
|
|
457
467
|
const roleId = context.function.role_id;
|
|
458
468
|
if (!roleId) {
|
|
459
469
|
return badRequest('Role ID is required');
|
package/functions.d.mts
CHANGED
|
@@ -11,7 +11,49 @@ export declare class FunctionResponse<T = Record<string, any>> {
|
|
|
11
11
|
message: string;
|
|
12
12
|
constructor({ body, statusCode, headers, message, }?: FunctionResponseOptions<T>);
|
|
13
13
|
}
|
|
14
|
-
export type
|
|
14
|
+
export type FunctionEventPrimitive = string | number | boolean | null;
|
|
15
|
+
export type FunctionEventValue = FunctionEventPrimitive | FunctionEventValue[] | {
|
|
16
|
+
[key: string]: FunctionEventValue | undefined;
|
|
17
|
+
};
|
|
18
|
+
export type FunctionEventParameters = Record<string, FunctionEventValue | undefined>;
|
|
19
|
+
export type FunctionEventQueryParams = Record<string, string | string[] | undefined>;
|
|
20
|
+
type FunctionEventParameterShape<T> = {
|
|
21
|
+
[K in keyof T]: FunctionEventValue | undefined;
|
|
22
|
+
};
|
|
23
|
+
type FunctionEventQueryParamShape<T> = {
|
|
24
|
+
[K in keyof T]: string | string[] | undefined;
|
|
25
|
+
};
|
|
26
|
+
export interface FunctionEventUrl<TQueryParams extends FunctionEventQueryParamShape<TQueryParams> = FunctionEventQueryParams> {
|
|
27
|
+
path: string;
|
|
28
|
+
queryParams: TQueryParams;
|
|
29
|
+
hash: string;
|
|
30
|
+
}
|
|
31
|
+
export interface SduiPageFunctionParameters extends FunctionEventParameters {
|
|
32
|
+
action: string;
|
|
33
|
+
}
|
|
34
|
+
export interface SduiPageFunctionEvent<TParameters extends {
|
|
35
|
+
action: string;
|
|
36
|
+
} & FunctionEventParameterShape<TParameters> = SduiPageFunctionParameters, TQueryParams extends FunctionEventQueryParamShape<TQueryParams> = FunctionEventQueryParams> {
|
|
37
|
+
url: FunctionEventUrl<TQueryParams>;
|
|
38
|
+
parameters: TParameters;
|
|
39
|
+
}
|
|
40
|
+
export interface DetailViewActionFunctionEvent<TParameters extends FunctionEventParameterShape<TParameters> = FunctionEventParameters, TObjectApiName extends string = string, TButton extends string = string, TLayoutId extends string = string> {
|
|
41
|
+
app_id: string | null;
|
|
42
|
+
button: TButton;
|
|
43
|
+
current_user: string;
|
|
44
|
+
layout_id: TLayoutId;
|
|
45
|
+
object_api_name: TObjectApiName;
|
|
46
|
+
parameters: TParameters;
|
|
47
|
+
record_id: string;
|
|
48
|
+
trigger_type: 'record view';
|
|
49
|
+
url: string;
|
|
50
|
+
}
|
|
51
|
+
export type FunctionEvent = FunctionEventParameters;
|
|
52
|
+
export type FunctionHandler<TEvent = FunctionEvent, TContext extends FunctionContext = FunctionContext> = (event: TEvent, context: TContext) => FunctionResponse | Promise<FunctionResponse>;
|
|
53
|
+
export type SduiPageFunctionHandler<TParameters extends {
|
|
54
|
+
action: string;
|
|
55
|
+
} & FunctionEventParameterShape<TParameters> = SduiPageFunctionParameters, TQueryParams extends FunctionEventQueryParamShape<TQueryParams> = FunctionEventQueryParams> = FunctionHandler<SduiPageFunctionEvent<TParameters, TQueryParams>>;
|
|
56
|
+
export type DetailViewActionFunctionHandler<TParameters extends FunctionEventParameterShape<TParameters> = FunctionEventParameters, TObjectApiName extends string = string, TButton extends string = string, TLayoutId extends string = string> = FunctionHandler<DetailViewActionFunctionEvent<TParameters, TObjectApiName, TButton, TLayoutId>>;
|
|
15
57
|
export type DurableDuration = number | string;
|
|
16
58
|
export type DurableTimestamp = number | Date | string;
|
|
17
59
|
export interface DurableWaitForEventOptions {
|
|
@@ -107,4 +149,5 @@ export declare class DataBridgeRateLimitError extends Error {
|
|
|
107
149
|
waitTimeInSeconds: number;
|
|
108
150
|
constructor(message: string, waitTimeInSeconds: number);
|
|
109
151
|
}
|
|
152
|
+
export {};
|
|
110
153
|
//# sourceMappingURL=functions.d.mts.map
|
package/functions.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"functions.d.mts","sourceRoot":"","sources":["src/functions.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,uBAAuB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IAC9D,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,qBAAa,gBAAgB,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC;IACnD,IAAI,EAAE,CAAC,CAAC;IACR,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;gBAEJ,EACV,IAAc,EACd,UAAgB,EAChB,OAAY,EACZ,OAAY,GACb,GAAE,uBAAuB,CAAC,CAAC,CAAM;CAMnC;AAED,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"functions.d.mts","sourceRoot":"","sources":["src/functions.ts"],"names":[],"mappings":"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"}
|