@elqnt/entity 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs ADDED
@@ -0,0 +1,1108 @@
1
+ // context/entity-definition-context.tsx
2
+ import { createContext, useContext, useMemo } from "react";
3
+
4
+ // hooks/use-entity-definition.ts
5
+ import { useCallback, useEffect } from "react";
6
+ import { useDispatch, useSelector } from "react-redux";
7
+ import { useNatsContext } from "@elqnt/nats";
8
+
9
+ // models/entity.ts
10
+ var OperatorEq = "eq";
11
+ var OperatorNe = "ne";
12
+ var OperatorGt = "gt";
13
+ var OperatorGte = "gte";
14
+ var OperatorLt = "lt";
15
+ var OperatorLte = "lte";
16
+ var OperatorIn = "in";
17
+ var OperatorNin = "nin";
18
+ var OperatorContains = "contains";
19
+ var OperatorStartsWith = "startsWith";
20
+ var OperatorEndsWith = "endsWith";
21
+ var OperatorExists = "exists";
22
+ var OperatorEmpty = "empty";
23
+ var OperatorBetween = "between";
24
+ var EntityFilterOperators = {
25
+ eq: { value: "eq", label: "Equal to" },
26
+ ne: { value: "ne", label: "Not equal to" },
27
+ gt: { value: "gt", label: "Greater than" },
28
+ gte: { value: "gte", label: "Greater than or equal to" },
29
+ lt: { value: "lt", label: "Less than" },
30
+ lte: { value: "lte", label: "Less than or equal to" },
31
+ in: { value: "in", label: "In" },
32
+ nin: { value: "nin", label: "Not in" },
33
+ contains: { value: "contains", label: "Contains" },
34
+ startsWith: { value: "startsWith", label: "Starts with" },
35
+ endsWith: { value: "endsWith", label: "Ends with" },
36
+ exists: { value: "exists", label: "Exists" },
37
+ empty: { value: "empty", label: "Empty" },
38
+ between: { value: "between", label: "Between" }
39
+ };
40
+ var EntityFieldTypeString = "string";
41
+ var EntityFieldTypeStringMultiline = "stringMultiline";
42
+ var EntityFieldTypeText = "text";
43
+ var EntityFieldTypeInt = "int";
44
+ var EntityFieldTypeFloat = "float";
45
+ var EntityFieldTypeBool = "bool";
46
+ var EntityFieldTypeDate = "date";
47
+ var EntityFieldTypeDateTime = "datetime";
48
+ var EntityFieldTypeEmail = "email";
49
+ var EntityFieldTypePhone = "phone";
50
+ var EntityFieldTypeURL = "url";
51
+ var EntityFieldTypeDropdown = "dropdown";
52
+ var EntityFieldTypeMultiSelect = "multiselect";
53
+ var EntityFieldTypeLookup = "lookup";
54
+ var EntityFieldTypeMultiLookup = "multilookup";
55
+ var EntityFieldTypeCurrency = "currency";
56
+ var EntityFieldTypeFile = "file";
57
+ var EntityFieldTypeImage = "image";
58
+ var EntityFieldTypeJSON = "json";
59
+ var EntityFieldTypes = {
60
+ string: { value: "string", label: "Short Text" },
61
+ stringMultiline: { value: "stringMultiline", label: "Long Text" },
62
+ text: { value: "text", label: "Rich Text Editor" },
63
+ int: { value: "int", label: "Integer" },
64
+ float: { value: "float", label: "Decimal" },
65
+ bool: { value: "bool", label: "Boolean" },
66
+ date: { value: "date", label: "Date" },
67
+ datetime: { value: "datetime", label: "Date & Time" },
68
+ email: { value: "email", label: "Email" },
69
+ phone: { value: "phone", label: "Phone" },
70
+ url: { value: "url", label: "URL" },
71
+ dropdown: { value: "dropdown", label: "Dropdown" },
72
+ multiselect: { value: "multiselect", label: "Multi Select" },
73
+ lookup: { value: "lookup", label: "Lookup" },
74
+ multilookup: { value: "multilookup", label: "Multi Lookup" },
75
+ currency: { value: "currency", label: "Currency" },
76
+ file: { value: "file", label: "File" },
77
+ image: { value: "image", label: "Image" },
78
+ json: { value: "json", label: "JSON" }
79
+ };
80
+ var RecordChangeActionCreated = "created";
81
+ var RecordChangeActionUpdated = "updated";
82
+ var RecordChangeActionDeleted = "deleted";
83
+ var EntityOrgSchemaCreate = "entity.org.schema.create";
84
+ var EntityOrgSchemaDrop = "entity.org.schema.drop";
85
+ var EntityDefinitionCreate = "entity.definition.create";
86
+ var EntityDefinitionCreated = "entity.definition.created";
87
+ var EntityDefinitionUpdate = "entity.definition.update";
88
+ var EntityDefinitionGet = "entity.definition.get";
89
+ var EntityDefinitionGetServer = "entity.definition.get.server";
90
+ var EntityDefinitionList = "entity.definition.list";
91
+ var EntityDefinitionUpdated = "entity.definition.updated";
92
+ var EntityDefinitionDelete = "entity.definition.delete";
93
+ var EntityDefinitionDeleted = "entity.definition.deleted";
94
+ var EntityRecordCreate = "entity.record.create";
95
+ var EntityRecordCreated = "entity.record.created";
96
+ var EntityRecordGet = "entity.record.get";
97
+ var EntityRecordQuery = "entity.record.query";
98
+ var EntityRecordCount = "entity.record.count";
99
+ var EntityRecordUpdate = "entity.record.update";
100
+ var EntityRecordUpdated = "entity.record.updated";
101
+ var EntityRecordDelete = "entity.record.delete";
102
+ var EntityRecordDeleted = "entity.record.deleted";
103
+ var EntityRecordsBulkCreate = "entity.records.bulk.create";
104
+ var EntityRecordsBulkCreated = "entity.records.bulk.created";
105
+ var EntityRecordsBulkUpdate = "entity.records.bulk.update";
106
+ var EntityRecordsBulkUpdated = "entity.records.bulk.updated";
107
+ var EntityRecordsBulkDelete = "entity.records.bulk.delete";
108
+ var EntityRecordsBulkDeleted = "entity.records.bulk.deleted";
109
+ var EntityViewCreate = "entity.view.create";
110
+ var EntityViewCreated = "entity.view.created";
111
+ var EntityViewUpdate = "entity.view.update";
112
+ var EntityViewUpdated = "entity.view.updated";
113
+ var EntityViewDelete = "entity.view.delete";
114
+ var EntityViewDeleted = "entity.view.deleted";
115
+ var EntityViewList = "entity.view.list";
116
+
117
+ // store/entity-definition-slice.ts
118
+ import { createSlice } from "@reduxjs/toolkit";
119
+ var initialState = {
120
+ definitions: {},
121
+ views: {},
122
+ isLoading: false,
123
+ loadingStates: {}
124
+ };
125
+ var entityDefinitionSlice = createSlice({
126
+ name: "entityDefinition",
127
+ initialState,
128
+ reducers: {
129
+ setLoading: (state, action) => {
130
+ state.isLoading = action.payload;
131
+ },
132
+ setOperationLoading: (state, action) => {
133
+ state.loadingStates[action.payload.operation] = action.payload.loading;
134
+ },
135
+ setError: (state, action) => {
136
+ state.error = action.payload;
137
+ },
138
+ setDefinitions: (state, action) => {
139
+ state.definitions = action.payload.reduce(
140
+ (acc, def) => {
141
+ acc[def.name] = def;
142
+ return acc;
143
+ },
144
+ {}
145
+ );
146
+ },
147
+ addDefinition: (state, action) => {
148
+ const definition = action.payload;
149
+ state.definitions[definition.name] = definition;
150
+ },
151
+ updateDefinition: (state, action) => {
152
+ const definition = action.payload;
153
+ state.definitions[definition.name] = definition;
154
+ if (state.selectedDefinition?.name === definition.name) {
155
+ state.selectedDefinition = definition;
156
+ }
157
+ },
158
+ removeDefinition: (state, action) => {
159
+ delete state.definitions[action.payload];
160
+ if (state.selectedDefinition?.name === action.payload) {
161
+ state.selectedDefinition = void 0;
162
+ }
163
+ },
164
+ setSelectedDefinition: (state, action) => {
165
+ state.selectedDefinition = action.payload;
166
+ },
167
+ setViews: (state, action) => {
168
+ const { entityName, views } = action.payload;
169
+ state.views[entityName] = views;
170
+ },
171
+ addView: (state, action) => {
172
+ const { entityName, view } = action.payload;
173
+ if (!state.views[entityName]) {
174
+ state.views[entityName] = [];
175
+ }
176
+ state.views[entityName].push(view);
177
+ },
178
+ updateView: (state, action) => {
179
+ const { entityName, view } = action.payload;
180
+ const views = state.views[entityName];
181
+ if (views) {
182
+ const index = views.findIndex((v) => v.id === view.id);
183
+ if (index !== -1) {
184
+ views[index] = view;
185
+ if (state.selectedView?.id === view.id) {
186
+ state.selectedView = view;
187
+ }
188
+ }
189
+ }
190
+ },
191
+ removeView: (state, action) => {
192
+ const { entityName, viewId } = action.payload;
193
+ const views = state.views[entityName];
194
+ if (views) {
195
+ state.views[entityName] = views.filter((v) => v.id !== viewId);
196
+ if (state.selectedView?.id === viewId) {
197
+ state.selectedView = void 0;
198
+ }
199
+ }
200
+ },
201
+ setSelectedView: (state, action) => {
202
+ state.selectedView = action.payload;
203
+ }
204
+ }
205
+ });
206
+ var {
207
+ setLoading,
208
+ setOperationLoading,
209
+ setError,
210
+ setDefinitions,
211
+ addDefinition,
212
+ updateDefinition,
213
+ removeDefinition,
214
+ setSelectedDefinition,
215
+ setViews,
216
+ addView,
217
+ updateView,
218
+ removeView,
219
+ setSelectedView
220
+ } = entityDefinitionSlice.actions;
221
+ var entityDefinitionReducer = entityDefinitionSlice.reducer;
222
+
223
+ // hooks/use-entity-definition.ts
224
+ function useEntityDefinition(orgId, entityName, options = {}) {
225
+ const { autoLoad, module } = options;
226
+ const { natsConnected, request } = useNatsContext();
227
+ const dispatch = useDispatch();
228
+ const definitions = useSelector(
229
+ (state) => state.entityDefinition.definitions
230
+ );
231
+ const selectedDefinition = useSelector(
232
+ (state) => state.entityDefinition.selectedDefinition
233
+ );
234
+ const views = useSelector(
235
+ (state) => state.entityDefinition.views
236
+ );
237
+ const selectedView = useSelector(
238
+ (state) => state.entityDefinition.selectedView
239
+ );
240
+ const isLoading = useSelector(
241
+ (state) => state.entityDefinition.isLoading
242
+ );
243
+ const loadingStates = useSelector(
244
+ (state) => state.entityDefinition.loadingStates
245
+ );
246
+ const error = useSelector(
247
+ (state) => state.entityDefinition.error
248
+ );
249
+ const createOrgSchema = useCallback(
250
+ async (targetOrgId) => {
251
+ if (!natsConnected) {
252
+ throw new Error("Not connected to NATS");
253
+ }
254
+ dispatch(setOperationLoading({ operation: "createOrgSchema", loading: true }));
255
+ try {
256
+ const response = await request(EntityOrgSchemaCreate, { orgId: targetOrgId });
257
+ if (response instanceof Error) {
258
+ throw response;
259
+ }
260
+ return response;
261
+ } finally {
262
+ dispatch(setOperationLoading({ operation: "createOrgSchema", loading: false }));
263
+ }
264
+ },
265
+ [natsConnected, dispatch, request]
266
+ );
267
+ const dropOrgSchema = useCallback(
268
+ async (targetOrgId) => {
269
+ if (!natsConnected) {
270
+ throw new Error("Not connected to NATS");
271
+ }
272
+ dispatch(setOperationLoading({ operation: "dropOrgSchema", loading: true }));
273
+ try {
274
+ const response = await request(EntityOrgSchemaDrop, { orgId: targetOrgId });
275
+ if (response instanceof Error) {
276
+ throw response;
277
+ }
278
+ return response;
279
+ } finally {
280
+ dispatch(setOperationLoading({ operation: "dropOrgSchema", loading: false }));
281
+ }
282
+ },
283
+ [natsConnected, dispatch, request]
284
+ );
285
+ const loadDefinitions = useCallback(async () => {
286
+ if (!natsConnected || !orgId) return;
287
+ const loadingKey = "loadDefinitions";
288
+ if (loadingStates[loadingKey]) return;
289
+ dispatch(setOperationLoading({ operation: loadingKey, loading: true }));
290
+ try {
291
+ const response = await request(EntityDefinitionList, { orgId, module });
292
+ if (response instanceof Error) {
293
+ dispatch(setError(response.message));
294
+ } else {
295
+ dispatch(setDefinitions(response?.definitions ?? []));
296
+ }
297
+ } catch (err) {
298
+ dispatch(setError(err instanceof Error ? err.message : "Unknown error"));
299
+ } finally {
300
+ dispatch(setOperationLoading({ operation: loadingKey, loading: false }));
301
+ }
302
+ }, [natsConnected, orgId, options.module, dispatch, request]);
303
+ useEffect(() => {
304
+ let mounted = true;
305
+ if (autoLoad && natsConnected && orgId && mounted) {
306
+ loadDefinitions();
307
+ }
308
+ return () => {
309
+ mounted = false;
310
+ };
311
+ }, [autoLoad, natsConnected, orgId]);
312
+ const loadDefinition = useCallback(
313
+ async (name) => {
314
+ if (!natsConnected || !orgId) return;
315
+ dispatch(
316
+ setOperationLoading({ operation: `load_${name}`, loading: true })
317
+ );
318
+ try {
319
+ const response = await request(EntityDefinitionGet, { entityName: name, orgId }, {});
320
+ if (response instanceof Error) {
321
+ dispatch(setError(response.message));
322
+ return;
323
+ }
324
+ dispatch(setSelectedDefinition(response.definition));
325
+ } finally {
326
+ dispatch(
327
+ setOperationLoading({ operation: `load_${name}`, loading: false })
328
+ );
329
+ }
330
+ },
331
+ [natsConnected, orgId, dispatch, request]
332
+ );
333
+ useEffect(() => {
334
+ if (natsConnected && orgId && entityName) {
335
+ loadDefinition(entityName);
336
+ }
337
+ }, [natsConnected, orgId, entityName, loadDefinition]);
338
+ const createDefinition = async (definition) => {
339
+ if (!natsConnected || !orgId) {
340
+ throw new Error("Not connected or missing orgId");
341
+ }
342
+ dispatch(setOperationLoading({ operation: "create", loading: true }));
343
+ try {
344
+ const response = await request(EntityDefinitionCreate, { definition, orgId }, {});
345
+ if (response instanceof Error) {
346
+ console.error("createDefinition error", response);
347
+ throw response;
348
+ }
349
+ if (response.metadata.success) {
350
+ dispatch(addDefinition(response.definition));
351
+ }
352
+ return response;
353
+ } finally {
354
+ dispatch(setOperationLoading({ operation: "create", loading: false }));
355
+ }
356
+ };
357
+ const updateDefinitionById = async (name, definition) => {
358
+ if (!natsConnected || !orgId) {
359
+ throw new Error("Not connected or missing orgId");
360
+ }
361
+ dispatch(
362
+ setOperationLoading({ operation: `update_${name}`, loading: true })
363
+ );
364
+ try {
365
+ const response = await request(
366
+ EntityDefinitionUpdate,
367
+ {
368
+ entityName: name,
369
+ definition,
370
+ orgId
371
+ },
372
+ {}
373
+ );
374
+ if (response instanceof Error) {
375
+ throw response;
376
+ }
377
+ if (response.metadata.success) {
378
+ dispatch(updateDefinition(response.definition));
379
+ }
380
+ return response;
381
+ } finally {
382
+ dispatch(
383
+ setOperationLoading({ operation: `update_${name}`, loading: false })
384
+ );
385
+ }
386
+ };
387
+ const deleteDefinition = async (name) => {
388
+ if (!natsConnected || !orgId) {
389
+ throw new Error("Not connected or missing orgId");
390
+ }
391
+ dispatch(
392
+ setOperationLoading({ operation: `delete_${name}`, loading: true })
393
+ );
394
+ try {
395
+ const response = await request(EntityDefinitionDelete, { entityName: name, orgId }, {});
396
+ if (response instanceof Error) {
397
+ throw response;
398
+ }
399
+ dispatch(removeDefinition(name));
400
+ return response;
401
+ } finally {
402
+ dispatch(
403
+ setOperationLoading({ operation: `delete_${name}`, loading: false })
404
+ );
405
+ }
406
+ };
407
+ const loadViews = useCallback(
408
+ async (entityName2) => {
409
+ if (!natsConnected || !orgId) return;
410
+ const loadingKey = `loadViews_${entityName2}`;
411
+ if (loadingStates[loadingKey]) return;
412
+ dispatch(setOperationLoading({ operation: loadingKey, loading: true }));
413
+ try {
414
+ const response = await request(
415
+ EntityViewList,
416
+ { entityName: entityName2, orgId },
417
+ {}
418
+ );
419
+ console.log("loadViews response", response);
420
+ if (response instanceof Error) {
421
+ dispatch(setError(response.message));
422
+ return;
423
+ }
424
+ dispatch(setViews({ entityName: entityName2, views: response.views }));
425
+ } catch (err) {
426
+ dispatch(
427
+ setError(err instanceof Error ? err.message : "Unknown error")
428
+ );
429
+ } finally {
430
+ dispatch(
431
+ setOperationLoading({ operation: loadingKey, loading: false })
432
+ );
433
+ }
434
+ },
435
+ [natsConnected, orgId, loadingStates, dispatch, request]
436
+ );
437
+ const createView = async (entityName2, view) => {
438
+ if (!natsConnected || !orgId) {
439
+ throw new Error("Not connected or missing orgId");
440
+ }
441
+ dispatch(setOperationLoading({ operation: "create_view", loading: true }));
442
+ try {
443
+ const response = await request(
444
+ EntityViewCreate,
445
+ { entityName: entityName2, view, orgId },
446
+ {}
447
+ );
448
+ if (response instanceof Error) {
449
+ throw response;
450
+ }
451
+ dispatch(addView({ entityName: entityName2, view: response.view }));
452
+ return response.view;
453
+ } finally {
454
+ dispatch(
455
+ setOperationLoading({ operation: "create_view", loading: false })
456
+ );
457
+ }
458
+ };
459
+ const updateViewById = async (entityName2, view) => {
460
+ if (!natsConnected || !orgId || !view.id) {
461
+ throw new Error("Not connected, missing orgId, or invalid view");
462
+ }
463
+ dispatch(
464
+ setOperationLoading({
465
+ operation: `update_view_${view.id}`,
466
+ loading: true
467
+ })
468
+ );
469
+ try {
470
+ const response = await request(
471
+ EntityViewUpdate,
472
+ { view, orgId },
473
+ {}
474
+ );
475
+ if (response instanceof Error) {
476
+ throw response;
477
+ }
478
+ dispatch(updateView({ entityName: entityName2, view: response.view }));
479
+ return response.view;
480
+ } finally {
481
+ dispatch(
482
+ setOperationLoading({
483
+ operation: `update_view_${view.id}`,
484
+ loading: false
485
+ })
486
+ );
487
+ }
488
+ };
489
+ const deleteView = async (entityName2, viewId) => {
490
+ if (!natsConnected || !orgId) {
491
+ throw new Error("Not connected or missing orgId");
492
+ }
493
+ dispatch(
494
+ setOperationLoading({ operation: `delete_view_${viewId}`, loading: true })
495
+ );
496
+ try {
497
+ const response = await request(
498
+ EntityViewDelete,
499
+ { viewId, orgId },
500
+ {}
501
+ );
502
+ if (response instanceof Error) {
503
+ throw response;
504
+ }
505
+ dispatch(removeView({ entityName: entityName2, viewId }));
506
+ return response;
507
+ } finally {
508
+ dispatch(
509
+ setOperationLoading({
510
+ operation: `delete_view_${viewId}`,
511
+ loading: false
512
+ })
513
+ );
514
+ }
515
+ };
516
+ const refresh = useCallback(() => {
517
+ if (!natsConnected || !orgId) return;
518
+ if (entityName) {
519
+ loadDefinition(entityName);
520
+ } else {
521
+ dispatch(setLoading(true));
522
+ loadDefinitions().finally(() => dispatch(setLoading(false)));
523
+ }
524
+ }, [natsConnected, orgId, entityName, loadDefinition, dispatch]);
525
+ return {
526
+ // State
527
+ definitions,
528
+ selectedDefinition,
529
+ views,
530
+ selectedView,
531
+ isLoading,
532
+ loadingStates,
533
+ error,
534
+ // Organization operations
535
+ createOrgSchema,
536
+ dropOrgSchema,
537
+ // Definition operations
538
+ loadDefinitions,
539
+ loadDefinition,
540
+ createDefinition,
541
+ updateDefinition: updateDefinitionById,
542
+ deleteDefinition,
543
+ // View operations
544
+ loadViews,
545
+ createView,
546
+ updateView: updateViewById,
547
+ deleteView,
548
+ // Utilities
549
+ refresh
550
+ };
551
+ }
552
+
553
+ // hooks/use-entity-definition-details.ts
554
+ import { useCallback as useCallback2, useEffect as useEffect2 } from "react";
555
+ function useEntityDefinitionDetails(entityName) {
556
+ const context = useEntityDefinitionContext();
557
+ const definition = context.definitions[entityName];
558
+ const loadDefinitionDetails = useCallback2(async () => {
559
+ return context.loadDefinition(entityName);
560
+ }, [context, entityName]);
561
+ useEffect2(() => {
562
+ if (entityName && !definition) {
563
+ loadDefinitionDetails();
564
+ }
565
+ }, [definition, entityName, loadDefinitionDetails]);
566
+ return {
567
+ definition,
568
+ isLoading: context.loadingStates[`load_${entityName}`],
569
+ error: context.error,
570
+ updateDefinition: (updatedDef) => context.updateDefinition(entityName, updatedDef),
571
+ deleteDefinition: () => context.deleteDefinition(entityName),
572
+ refresh: loadDefinitionDetails
573
+ };
574
+ }
575
+
576
+ // hooks/use-entity-record.ts
577
+ import { useCallback as useCallback3, useEffect as useEffect3 } from "react";
578
+ import { useDispatch as useDispatch2, useSelector as useSelector2 } from "react-redux";
579
+ import { useNatsContext as useNatsContext2 } from "@elqnt/nats";
580
+
581
+ // store/entity-record-slice.ts
582
+ import { createSlice as createSlice2 } from "@reduxjs/toolkit";
583
+ var initialState2 = {
584
+ records: {},
585
+ isLoading: false,
586
+ loadingStates: {}
587
+ };
588
+ var entityRecordSlice = createSlice2({
589
+ name: "entityRecord",
590
+ initialState: initialState2,
591
+ reducers: {
592
+ setLoading: (state, action) => {
593
+ state.isLoading = action.payload;
594
+ },
595
+ setOperationLoading: (state, action) => {
596
+ state.loadingStates[action.payload.operation] = action.payload.loading;
597
+ },
598
+ setError: (state, action) => {
599
+ state.error = action.payload;
600
+ },
601
+ setRecords: (state, action) => {
602
+ const { entityName, records, params } = action.payload;
603
+ state.records[entityName] = {
604
+ items: records.items.reduce(
605
+ (acc, record) => {
606
+ acc[record.id] = record;
607
+ return acc;
608
+ },
609
+ {}
610
+ ),
611
+ params,
612
+ meta: records,
613
+ selected: []
614
+ };
615
+ },
616
+ addRecord: (state, action) => {
617
+ const { entityName, record } = action.payload;
618
+ if (state.records[entityName]) {
619
+ state.records[entityName].items[record.id] = record;
620
+ }
621
+ },
622
+ updateRecord: (state, action) => {
623
+ const { entityName, record } = action.payload;
624
+ if (state.records[entityName]) {
625
+ state.records[entityName].items[record.id] = record;
626
+ }
627
+ },
628
+ removeRecord: (state, action) => {
629
+ const { entityName, recordId } = action.payload;
630
+ if (state.records[entityName]) {
631
+ delete state.records[entityName].items[recordId];
632
+ state.records[entityName].selected = state.records[entityName].selected.filter((id) => id !== recordId);
633
+ }
634
+ },
635
+ setSelected: (state, action) => {
636
+ const { entityName, ids } = action.payload;
637
+ if (state.records[entityName]) {
638
+ state.records[entityName].selected = ids;
639
+ }
640
+ },
641
+ setActiveView: (state, action) => {
642
+ state.activeView = action.payload;
643
+ },
644
+ updateQueryParams: (state, action) => {
645
+ const { entityName, params } = action.payload;
646
+ if (state.records[entityName]) {
647
+ state.records[entityName].params = {
648
+ ...state.records[entityName].params,
649
+ ...params
650
+ };
651
+ }
652
+ },
653
+ setSelectedRecord: (state, action) => {
654
+ const { record } = action.payload;
655
+ state.selectedRecord = record;
656
+ }
657
+ }
658
+ });
659
+ var {
660
+ setLoading: setLoading2,
661
+ setOperationLoading: setOperationLoading2,
662
+ setError: setError2,
663
+ setRecords,
664
+ addRecord,
665
+ updateRecord,
666
+ removeRecord,
667
+ setSelected,
668
+ setSelectedRecord,
669
+ setActiveView,
670
+ updateQueryParams
671
+ } = entityRecordSlice.actions;
672
+ var entityRecordReducer = entityRecordSlice.reducer;
673
+
674
+ // hooks/use-entity-record.ts
675
+ var defaultQuery = {
676
+ filters: {},
677
+ page: 1,
678
+ pageSize: 25,
679
+ sortBy: "metadata.createdAt",
680
+ sortOrder: -1
681
+ };
682
+ function useEntityRecord(orgId, entityName, options = {}) {
683
+ const { autoLoad = true } = options;
684
+ const { natsConnected, request } = useNatsContext2();
685
+ const dispatch = useDispatch2();
686
+ const recordState = useSelector2(
687
+ (state) => state.entityRecord.records[entityName] || {
688
+ items: {},
689
+ params: defaultQuery,
690
+ meta: {
691
+ items: [],
692
+ totalCount: 0,
693
+ currentPage: 1,
694
+ pageSize: 25,
695
+ totalPages: 0
696
+ },
697
+ selected: []
698
+ }
699
+ );
700
+ const selectedRecord = useSelector2(
701
+ (state) => state.entityRecord.selectedRecord
702
+ );
703
+ const isLoading = useSelector2(
704
+ (state) => state.entityRecord.isLoading
705
+ );
706
+ const loadingStates = useSelector2(
707
+ (state) => state.entityRecord.loadingStates
708
+ );
709
+ const error = useSelector2(
710
+ (state) => state.entityRecord.error
711
+ );
712
+ const loadRecords = useCallback3(
713
+ async (params) => {
714
+ if (!natsConnected || !orgId) return;
715
+ const loadingKey = `load_${entityName}`;
716
+ if (loadingStates[loadingKey]) return;
717
+ dispatch(setOperationLoading2({ operation: loadingKey, loading: true }));
718
+ try {
719
+ const queryParams = { ...recordState.params, ...params };
720
+ const response = await request(
721
+ EntityRecordQuery,
722
+ {
723
+ orgId,
724
+ entityName,
725
+ query: queryParams
726
+ }
727
+ );
728
+ if (response instanceof Error) {
729
+ dispatch(setError2(response.message));
730
+ } else if (response.records) {
731
+ dispatch(
732
+ setRecords({
733
+ entityName,
734
+ records: response.records,
735
+ params: queryParams
736
+ })
737
+ );
738
+ }
739
+ } catch (err) {
740
+ dispatch(
741
+ setError2(err instanceof Error ? err.message : "Unknown error")
742
+ );
743
+ } finally {
744
+ dispatch(
745
+ setOperationLoading2({ operation: loadingKey, loading: false })
746
+ );
747
+ }
748
+ },
749
+ [natsConnected, orgId, entityName, recordState.params, dispatch, request]
750
+ );
751
+ const loadRecord = useCallback3(
752
+ async (recordId) => {
753
+ if (!natsConnected || !orgId) return;
754
+ const loadingKey = `load_${recordId}`;
755
+ if (loadingStates[loadingKey]) return;
756
+ dispatch(setOperationLoading2({ operation: loadingKey, loading: true }));
757
+ try {
758
+ const response = await request(EntityRecordGet, { entityName, recordId, orgId }, {});
759
+ if (response instanceof Error) {
760
+ dispatch(setError2(response.message));
761
+ return;
762
+ }
763
+ dispatch(setSelectedRecord({ record: response.record }));
764
+ } finally {
765
+ dispatch(
766
+ setOperationLoading2({ operation: loadingKey, loading: false })
767
+ );
768
+ }
769
+ },
770
+ [natsConnected, orgId, entityName, recordState.params, dispatch, request]
771
+ );
772
+ const createRecord = async (record) => {
773
+ if (!natsConnected || !orgId) {
774
+ throw new Error("Not connected or missing orgId");
775
+ }
776
+ dispatch(
777
+ setOperationLoading2({ operation: "create_record", loading: true })
778
+ );
779
+ try {
780
+ const response = await request(
781
+ EntityRecordCreate,
782
+ {
783
+ orgId,
784
+ entityName,
785
+ record
786
+ }
787
+ );
788
+ if (response instanceof Error) {
789
+ throw response;
790
+ }
791
+ if (response.metadata.success) {
792
+ dispatch(addRecord({ entityName, record: response.record }));
793
+ }
794
+ loadRecords();
795
+ return response;
796
+ } finally {
797
+ dispatch(
798
+ setOperationLoading2({ operation: "create_record", loading: false })
799
+ );
800
+ }
801
+ };
802
+ const updateRecordById = async (record) => {
803
+ if (!natsConnected || !orgId) {
804
+ throw new Error("Not connected or missing orgId");
805
+ }
806
+ dispatch(
807
+ setOperationLoading2({ operation: `update_${record.id}`, loading: true })
808
+ );
809
+ try {
810
+ const response = await request(
811
+ EntityRecordUpdate,
812
+ {
813
+ orgId,
814
+ entityName,
815
+ record,
816
+ recordId: record.id
817
+ }
818
+ );
819
+ if (response instanceof Error) {
820
+ throw response;
821
+ }
822
+ dispatch(updateRecord({ entityName, record: response.record }));
823
+ return response;
824
+ } finally {
825
+ dispatch(
826
+ setOperationLoading2({
827
+ operation: `update_${record.id}`,
828
+ loading: false
829
+ })
830
+ );
831
+ }
832
+ };
833
+ const deleteRecordById = async (recordId) => {
834
+ if (!natsConnected || !orgId) {
835
+ throw new Error("Not connected or missing orgId");
836
+ }
837
+ dispatch(
838
+ setOperationLoading2({ operation: `delete_${recordId}`, loading: true })
839
+ );
840
+ try {
841
+ const response = await request(
842
+ EntityRecordDelete,
843
+ {
844
+ orgId,
845
+ entityName,
846
+ recordId
847
+ }
848
+ );
849
+ if (response instanceof Error) {
850
+ throw response;
851
+ }
852
+ dispatch(removeRecord({ entityName, recordId }));
853
+ return response;
854
+ } finally {
855
+ dispatch(
856
+ setOperationLoading2({ operation: `delete_${recordId}`, loading: false })
857
+ );
858
+ }
859
+ };
860
+ const countRecords = async (filters) => {
861
+ if (!natsConnected || !orgId) {
862
+ throw new Error("Not connected or missing orgId");
863
+ }
864
+ try {
865
+ const response = await request(
866
+ EntityRecordCount,
867
+ {
868
+ orgId,
869
+ entityName,
870
+ filters: filters || {}
871
+ }
872
+ );
873
+ if (response instanceof Error) {
874
+ throw response;
875
+ }
876
+ if (!response.metadata?.success) {
877
+ throw new Error(response.metadata?.error || "Failed to count records");
878
+ }
879
+ return response.count || 0;
880
+ } catch (err) {
881
+ console.error("Error counting records:", err);
882
+ return 0;
883
+ }
884
+ };
885
+ const getEntityRecordById = async (recordId) => {
886
+ if (!natsConnected || !orgId) {
887
+ throw new Error("Not connected or missing orgId");
888
+ }
889
+ try {
890
+ const response = await request(EntityRecordGet, { entityName, recordId, orgId }, {});
891
+ if (response instanceof Error) {
892
+ console.error("Error fetching record:", response.message);
893
+ return null;
894
+ }
895
+ return response.record || null;
896
+ } catch (error2) {
897
+ console.error("Error in getEntityRecordById:", error2);
898
+ return null;
899
+ }
900
+ };
901
+ const selectRecords = (ids) => {
902
+ dispatch(setSelected({ entityName, ids }));
903
+ };
904
+ const clearSelection = () => {
905
+ dispatch(setSelected({ entityName, ids: [] }));
906
+ };
907
+ const updateParams = (params) => {
908
+ console.log("updating query params", params);
909
+ dispatch(updateQueryParams({ entityName, params }));
910
+ loadRecords(params);
911
+ };
912
+ const refresh = useCallback3(() => {
913
+ loadRecords();
914
+ }, [loadRecords]);
915
+ useEffect3(() => {
916
+ let mounted = true;
917
+ if (autoLoad && natsConnected && orgId && mounted) {
918
+ loadRecords();
919
+ }
920
+ return () => {
921
+ mounted = false;
922
+ };
923
+ }, [autoLoad, natsConnected, orgId]);
924
+ return {
925
+ // State
926
+ records: recordState.items,
927
+ params: recordState.params,
928
+ selected: recordState.selected,
929
+ selectedRecord,
930
+ isLoading,
931
+ loadingStates,
932
+ error,
933
+ // Operations
934
+ loadRecords,
935
+ createRecord,
936
+ updateRecord: updateRecordById,
937
+ deleteRecord: deleteRecordById,
938
+ loadRecord,
939
+ countRecords,
940
+ getEntityRecordById,
941
+ // Selection
942
+ selectRecords,
943
+ clearSelection,
944
+ // Query
945
+ updateParams,
946
+ refresh
947
+ };
948
+ }
949
+
950
+ // hooks/use-debounce.ts
951
+ import { useCallback as useCallback4, useRef } from "react";
952
+ function useDebounce(callback, delay) {
953
+ const timerRef = useRef(null);
954
+ return useCallback4((...args) => {
955
+ if (timerRef.current) {
956
+ clearTimeout(timerRef.current);
957
+ }
958
+ timerRef.current = setTimeout(() => {
959
+ callback(...args);
960
+ }, delay);
961
+ }, [callback, delay]);
962
+ }
963
+
964
+ // context/entity-definition-context.tsx
965
+ import { jsx } from "react/jsx-runtime";
966
+ var EntityDefinitionContext = createContext(void 0);
967
+ function EntityDefinitionProvider({
968
+ children,
969
+ orgId,
970
+ entityName,
971
+ options = {}
972
+ }) {
973
+ const hookValue = useEntityDefinition(orgId, entityName, options);
974
+ const value = useMemo(() => hookValue, [hookValue]);
975
+ return /* @__PURE__ */ jsx(EntityDefinitionContext.Provider, { value, children });
976
+ }
977
+ function useEntityDefinitionContext() {
978
+ const context = useContext(EntityDefinitionContext);
979
+ if (!context) {
980
+ throw new Error(
981
+ "useEntityDefinitionContext must be used within an EntityDefinitionProvider"
982
+ );
983
+ }
984
+ return context;
985
+ }
986
+
987
+ // context/entity-record-context.tsx
988
+ import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2 } from "react";
989
+ import { jsx as jsx2 } from "react/jsx-runtime";
990
+ var EntityRecordContext = createContext2(void 0);
991
+ function EntityRecordProvider({
992
+ children,
993
+ orgId,
994
+ entityName,
995
+ options = {}
996
+ }) {
997
+ const hookValue = useEntityRecord(orgId, entityName, options);
998
+ const value = useMemo2(() => hookValue, [hookValue]);
999
+ return /* @__PURE__ */ jsx2(EntityRecordContext.Provider, { value, children });
1000
+ }
1001
+ function useEntityRecordContext() {
1002
+ const context = useContext2(EntityRecordContext);
1003
+ if (!context) {
1004
+ throw new Error(
1005
+ "useEntityRecordContext must be used within an EntityRecordProvider"
1006
+ );
1007
+ }
1008
+ return context;
1009
+ }
1010
+
1011
+ // consts/colors.ts
1012
+ var PREDEFINED_COLORS = [
1013
+ { value: "#EF4444", name: "Red" },
1014
+ { value: "#F97316", name: "Orange" },
1015
+ { value: "#EAB308", name: "Yellow" },
1016
+ { value: "#22C55E", name: "Green" },
1017
+ { value: "#06B6D4", name: "Cyan" },
1018
+ { value: "#3B82F6", name: "Blue" },
1019
+ { value: "#6366F1", name: "Indigo" },
1020
+ { value: "#A855F7", name: "Purple" }
1021
+ ];
1022
+ export {
1023
+ EntityDefinitionContext,
1024
+ EntityDefinitionCreate,
1025
+ EntityDefinitionCreated,
1026
+ EntityDefinitionDelete,
1027
+ EntityDefinitionDeleted,
1028
+ EntityDefinitionGet,
1029
+ EntityDefinitionGetServer,
1030
+ EntityDefinitionList,
1031
+ EntityDefinitionProvider,
1032
+ EntityDefinitionUpdate,
1033
+ EntityDefinitionUpdated,
1034
+ EntityFieldTypeBool,
1035
+ EntityFieldTypeCurrency,
1036
+ EntityFieldTypeDate,
1037
+ EntityFieldTypeDateTime,
1038
+ EntityFieldTypeDropdown,
1039
+ EntityFieldTypeEmail,
1040
+ EntityFieldTypeFile,
1041
+ EntityFieldTypeFloat,
1042
+ EntityFieldTypeImage,
1043
+ EntityFieldTypeInt,
1044
+ EntityFieldTypeJSON,
1045
+ EntityFieldTypeLookup,
1046
+ EntityFieldTypeMultiLookup,
1047
+ EntityFieldTypeMultiSelect,
1048
+ EntityFieldTypePhone,
1049
+ EntityFieldTypeString,
1050
+ EntityFieldTypeStringMultiline,
1051
+ EntityFieldTypeText,
1052
+ EntityFieldTypeURL,
1053
+ EntityFieldTypes,
1054
+ EntityFilterOperators,
1055
+ EntityOrgSchemaCreate,
1056
+ EntityOrgSchemaDrop,
1057
+ EntityRecordContext,
1058
+ EntityRecordCount,
1059
+ EntityRecordCreate,
1060
+ EntityRecordCreated,
1061
+ EntityRecordDelete,
1062
+ EntityRecordDeleted,
1063
+ EntityRecordGet,
1064
+ EntityRecordProvider,
1065
+ EntityRecordQuery,
1066
+ EntityRecordUpdate,
1067
+ EntityRecordUpdated,
1068
+ EntityRecordsBulkCreate,
1069
+ EntityRecordsBulkCreated,
1070
+ EntityRecordsBulkDelete,
1071
+ EntityRecordsBulkDeleted,
1072
+ EntityRecordsBulkUpdate,
1073
+ EntityRecordsBulkUpdated,
1074
+ EntityViewCreate,
1075
+ EntityViewCreated,
1076
+ EntityViewDelete,
1077
+ EntityViewDeleted,
1078
+ EntityViewList,
1079
+ EntityViewUpdate,
1080
+ EntityViewUpdated,
1081
+ OperatorBetween,
1082
+ OperatorContains,
1083
+ OperatorEmpty,
1084
+ OperatorEndsWith,
1085
+ OperatorEq,
1086
+ OperatorExists,
1087
+ OperatorGt,
1088
+ OperatorGte,
1089
+ OperatorIn,
1090
+ OperatorLt,
1091
+ OperatorLte,
1092
+ OperatorNe,
1093
+ OperatorNin,
1094
+ OperatorStartsWith,
1095
+ PREDEFINED_COLORS,
1096
+ RecordChangeActionCreated,
1097
+ RecordChangeActionDeleted,
1098
+ RecordChangeActionUpdated,
1099
+ entityDefinitionReducer,
1100
+ entityRecordReducer,
1101
+ useDebounce,
1102
+ useEntityDefinition,
1103
+ useEntityDefinitionContext,
1104
+ useEntityDefinitionDetails,
1105
+ useEntityRecord,
1106
+ useEntityRecordContext
1107
+ };
1108
+ //# sourceMappingURL=index.mjs.map