@churchapps/helpers 1.2.7 → 1.2.8

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.
Files changed (58) hide show
  1. package/dist/ApiHelper.js +3 -6
  2. package/dist/ApiHelper.js.map +1 -1
  3. package/dist/AppearanceHelper.js +1 -5
  4. package/dist/AppearanceHelper.js.map +1 -1
  5. package/dist/ArrayHelper.js +3 -7
  6. package/dist/ArrayHelper.js.map +1 -1
  7. package/dist/CommonEnvironmentHelper.js +1 -5
  8. package/dist/CommonEnvironmentHelper.js.map +1 -1
  9. package/dist/CurrencyHelper.js +1 -5
  10. package/dist/CurrencyHelper.js.map +1 -1
  11. package/dist/DateHelper.js +9 -49
  12. package/dist/DateHelper.js.map +1 -1
  13. package/dist/DonationHelper.js +1 -5
  14. package/dist/DonationHelper.js.map +1 -1
  15. package/dist/ErrorHelper.js +1 -5
  16. package/dist/ErrorHelper.js.map +1 -1
  17. package/dist/EventHelper.js +4 -8
  18. package/dist/EventHelper.js.map +1 -1
  19. package/dist/FileHelper.js +1 -5
  20. package/dist/FileHelper.js.map +1 -1
  21. package/dist/PersonHelper.js +3 -7
  22. package/dist/PersonHelper.js.map +1 -1
  23. package/dist/PlanHelper.js +3 -7
  24. package/dist/PlanHelper.js.map +1 -1
  25. package/dist/UniqueIdHelper.js +1 -5
  26. package/dist/UniqueIdHelper.js.map +1 -1
  27. package/dist/UserHelper.js +7 -11
  28. package/dist/UserHelper.js.map +1 -1
  29. package/dist/contentProviders/ContentProvider.js +1 -2
  30. package/dist/contentProviders/LessonsContentProvider.d.ts +52 -3
  31. package/dist/contentProviders/LessonsContentProvider.d.ts.map +1 -1
  32. package/dist/contentProviders/LessonsContentProvider.js +162 -26
  33. package/dist/contentProviders/LessonsContentProvider.js.map +1 -1
  34. package/dist/contentProviders/index.js +1 -5
  35. package/dist/contentProviders/index.js.map +1 -1
  36. package/dist/index.js +16 -47
  37. package/dist/index.js.map +1 -1
  38. package/dist/interfaces/Access.js +1 -2
  39. package/dist/interfaces/Attendance.js +1 -2
  40. package/dist/interfaces/Content.js +1 -2
  41. package/dist/interfaces/Doing.js +1 -2
  42. package/dist/interfaces/Donation.js +1 -5
  43. package/dist/interfaces/Donation.js.map +1 -1
  44. package/dist/interfaces/Error.js +1 -2
  45. package/dist/interfaces/Lessons.js +1 -2
  46. package/dist/interfaces/Lessons.js.map +1 -1
  47. package/dist/interfaces/Membership.js +1 -2
  48. package/dist/interfaces/Messaging.js +1 -2
  49. package/dist/interfaces/Permissions.js +1 -5
  50. package/dist/interfaces/Permissions.js.map +1 -1
  51. package/dist/interfaces/Reporting.js +1 -2
  52. package/dist/interfaces/UserContextInterface.js +1 -2
  53. package/dist/interfaces/index.js +12 -28
  54. package/dist/interfaces/index.js.map +1 -1
  55. package/package.json +9 -1
  56. package/src/contentProviders/LessonsContentProvider.ts +176 -26
  57. package/src/index.ts +0 -1
  58. package/tsconfig.json +2 -2
@@ -1,11 +1,6 @@
1
1
  import { ApiHelper } from "../ApiHelper";
2
- import type {
3
- PlanInterface,
4
- PlanItemInterface,
5
- PlanItemContentInterface,
6
- ExternalVenueRefInterface
7
- } from "../interfaces";
8
- import type { VenuePlanItemsResponseInterface, VenueActionResponseInterface } from "../interfaces/Lessons";
2
+ import type { PlanInterface, PlanItemInterface, PlanItemContentInterface, ExternalVenueRefInterface } from "../interfaces";
3
+ import type { VenuePlanItemsResponseInterface, VenueActionResponseInterface, LessonTreeInterface, LessonActionTreeInterface } from "../interfaces/Lessons";
9
4
  import type { ContentProviderInterface } from "./ContentProvider";
10
5
 
11
6
  export class LessonsContentProvider implements ContentProviderInterface {
@@ -74,10 +69,46 @@ export class LessonsContentProvider implements ContentProviderInterface {
74
69
  return result;
75
70
  }
76
71
 
77
- // Fetch venue plan items (for preview mode)
72
+ // ============================================
73
+ // Plan/Lesson Association Methods
74
+ // ============================================
75
+
76
+ hasAssociatedLesson(plan: PlanInterface): boolean {
77
+ return (plan?.contentType === "venue" || plan?.contentType === "externalVenue") && !!plan?.contentId;
78
+ }
79
+
80
+ isExternalVenue(plan: PlanInterface): boolean {
81
+ return plan?.contentType === "externalVenue";
82
+ }
83
+
84
+ getExternalRef(plan: PlanInterface): ExternalVenueRefInterface | null {
85
+ if (!this.isExternalVenue(plan) || !plan?.contentId) return null;
86
+ try {
87
+ return JSON.parse(plan.contentId);
88
+ } catch {
89
+ return null;
90
+ }
91
+ }
92
+
93
+ getVenueId(plan: PlanInterface): string | null {
94
+ if (!this.hasAssociatedLesson(plan)) return null;
95
+ if (this.isExternalVenue(plan)) {
96
+ return this.getExternalRef(plan)?.venueId || null;
97
+ }
98
+ return plan.contentId || null;
99
+ }
100
+
101
+ // ============================================
102
+ // API Fetch Methods
103
+ // ============================================
104
+
105
+ /**
106
+ * Fetch venue plan items - the basic hierarchical structure
107
+ * Returns: headers with children (sections), but sections don't have their actions
108
+ * Use this for preview mode display
109
+ */
78
110
  async fetchVenuePlanItems(plan: PlanInterface): Promise<VenuePlanItemsResponseInterface> {
79
111
  if (!this.hasAssociatedLesson(plan)) return { items: [] };
80
-
81
112
  const externalRef = this.getExternalRef(plan);
82
113
  if (externalRef) {
83
114
  return await ApiHelper.getAnonymous(
@@ -88,10 +119,12 @@ export class LessonsContentProvider implements ContentProviderInterface {
88
119
  return await ApiHelper.getAnonymous(`/venues/public/planItems/${plan.contentId}`, "LessonsApi");
89
120
  }
90
121
 
91
- // Fetch venue actions (for expanding sections)
122
+ /**
123
+ * Fetch venue actions - sections with their full action lists
124
+ * Use this for action selection dialogs and full expansion
125
+ */
92
126
  async fetchVenueActions(plan: PlanInterface): Promise<VenueActionResponseInterface> {
93
127
  if (!this.hasAssociatedLesson(plan)) return { sections: [] };
94
-
95
128
  const externalRef = this.getExternalRef(plan);
96
129
  if (externalRef) {
97
130
  return await ApiHelper.getAnonymous(
@@ -102,28 +135,145 @@ export class LessonsContentProvider implements ContentProviderInterface {
102
135
  return await ApiHelper.getAnonymous(`/venues/public/actions/${plan.contentId}`, "LessonsApi");
103
136
  }
104
137
 
105
- hasAssociatedLesson(plan: PlanInterface): boolean {
106
- return (plan?.contentType === "venue" || plan?.contentType === "externalVenue") && !!plan?.contentId;
138
+ /**
139
+ * Fetch the full lesson tree for browsing (programs -> studies -> lessons -> venues)
140
+ */
141
+ async fetchLessonTree(): Promise<LessonTreeInterface> {
142
+ return await ApiHelper.getAnonymous("/lessons/public/tree", "LessonsApi");
107
143
  }
108
144
 
109
- isExternalVenue(plan: PlanInterface): boolean {
110
- return plan?.contentType === "externalVenue";
145
+ /**
146
+ * Fetch the action tree for action selection (includes actions in each venue section)
147
+ */
148
+ async fetchActionTree(): Promise<LessonActionTreeInterface> {
149
+ return await ApiHelper.getAnonymous("/lessons/public/actionTree", "LessonsApi");
111
150
  }
112
151
 
113
- getExternalRef(plan: PlanInterface): ExternalVenueRefInterface | null {
114
- if (!this.isExternalVenue(plan) || !plan?.contentId) return null;
115
- try {
116
- return JSON.parse(plan.contentId);
117
- } catch {
118
- return null;
152
+ // ============================================
153
+ // Display List Methods (for preview/display without full actions)
154
+ // ============================================
155
+
156
+ /**
157
+ * Get the display list - hierarchical items suitable for preview
158
+ * Structure: headers -> sections (no actions expanded)
159
+ * This is the lightweight version for showing what a lesson contains
160
+ */
161
+ async getDisplayList(plan: PlanInterface): Promise<PlanItemInterface[]> {
162
+ const response = await this.fetchVenuePlanItems(plan);
163
+ return response?.items || [];
164
+ }
165
+
166
+ /**
167
+ * Get display list with sections only (strip actions from children)
168
+ * Use this when importing a lesson as editable plan items
169
+ */
170
+ async getSectionsOnlyList(plan: PlanInterface): Promise<PlanItemInterface[]> {
171
+ const response = await this.fetchVenuePlanItems(plan);
172
+ if (!response?.items) return [];
173
+
174
+ return response.items.map(item => ({
175
+ ...item,
176
+ children: item.children?.map(section => ({
177
+ ...section,
178
+ children: undefined // Remove actions from sections
179
+ }))
180
+ }));
181
+ }
182
+
183
+ // ============================================
184
+ // Expanded List Methods (with full actions)
185
+ // ============================================
186
+
187
+ /**
188
+ * Get the fully expanded list - items with all actions populated in sections
189
+ * Merges fetchVenuePlanItems with fetchVenueActions to get complete data
190
+ */
191
+ async getExpandedList(plan: PlanInterface): Promise<PlanItemInterface[]> {
192
+ const [planItemsResponse, actionsResponse] = await Promise.all([
193
+ this.fetchVenuePlanItems(plan),
194
+ this.fetchVenueActions(plan)
195
+ ]);
196
+
197
+ if (!planItemsResponse?.items) return [];
198
+
199
+ // Create a map of section ID -> actions
200
+ const sectionActionsMap = new Map<string, PlanItemInterface[]>();
201
+ if (actionsResponse?.sections) {
202
+ for (const section of actionsResponse.sections) {
203
+ if (section.id && section.actions) {
204
+ sectionActionsMap.set(section.id, section.actions.map(action => ({
205
+ itemType: "action",
206
+ relatedId: action.id,
207
+ label: action.name,
208
+ description: action.actionType,
209
+ seconds: action.seconds
210
+ })));
211
+ }
212
+ }
119
213
  }
214
+
215
+ // Recursively expand sections with their actions
216
+ const expandItem = (item: PlanItemInterface): PlanItemInterface => {
217
+ if (!item.children) return item;
218
+
219
+ return {
220
+ ...item,
221
+ children: item.children.map(child => {
222
+ // If this is a section (has relatedId), try to get its actions
223
+ if (child.relatedId && sectionActionsMap.has(child.relatedId)) {
224
+ return {
225
+ ...child,
226
+ children: sectionActionsMap.get(child.relatedId)
227
+ };
228
+ }
229
+ // Otherwise recursively process
230
+ return expandItem(child);
231
+ })
232
+ };
233
+ };
234
+
235
+ return planItemsResponse.items.map(expandItem);
120
236
  }
121
237
 
122
- getVenueId(plan: PlanInterface): string | null {
123
- if (!this.hasAssociatedLesson(plan)) return null;
124
- if (this.isExternalVenue(plan)) {
125
- return this.getExternalRef(plan)?.venueId || null;
238
+ // ============================================
239
+ // Embed URL Helpers
240
+ // ============================================
241
+
242
+ /**
243
+ * Get embed URL for an action
244
+ */
245
+ getActionEmbedUrl(actionId: string, externalProviderId?: string): string {
246
+ if (externalProviderId) {
247
+ return `${this.lessonsUrl}/embed/external/${externalProviderId}/action/${actionId}`;
126
248
  }
127
- return plan.contentId || null;
249
+ return `${this.lessonsUrl}/embed/action/${actionId}`;
250
+ }
251
+
252
+ /**
253
+ * Get embed URL for an add-on
254
+ */
255
+ getAddOnEmbedUrl(addOnId: string, externalProviderId?: string): string {
256
+ if (externalProviderId) {
257
+ return `${this.lessonsUrl}/embed/external/${externalProviderId}/addon/${addOnId}`;
258
+ }
259
+ return `${this.lessonsUrl}/embed/addon/${addOnId}`;
260
+ }
261
+
262
+ /**
263
+ * Get embed URL for a section
264
+ */
265
+ getSectionEmbedUrl(sectionId: string, externalProviderId?: string): string {
266
+ if (externalProviderId) {
267
+ return `${this.lessonsUrl}/embed/external/${externalProviderId}/section/${sectionId}`;
268
+ }
269
+ return `${this.lessonsUrl}/embed/section/${sectionId}`;
270
+ }
271
+
272
+ /**
273
+ * Get the external provider ID from a plan (if external)
274
+ */
275
+ getExternalProviderId(plan: PlanInterface): string | null {
276
+ const externalRef = this.getExternalRef(plan);
277
+ return externalRef?.externalProviderId || null;
128
278
  }
129
279
  }
package/src/index.ts CHANGED
@@ -14,4 +14,3 @@ export { UserHelper } from "./UserHelper";
14
14
  export { UniqueIdHelper } from "./UniqueIdHelper";
15
15
  export { PlanHelper } from "./PlanHelper";
16
16
  export * from "./contentProviders";
17
-
package/tsconfig.json CHANGED
@@ -16,8 +16,8 @@
16
16
  "allowSyntheticDefaultImports": true,
17
17
  "strict": false,
18
18
  "forceConsistentCasingInFileNames": true,
19
- "module": "commonjs",
20
- "moduleResolution": "node",
19
+ "module": "ESNext",
20
+ "moduleResolution": "bundler",
21
21
  "resolveJsonModule": true,
22
22
  "isolatedModules": true,
23
23
  "jsx": "react-jsx",