@loj-lang/rdsl-runtime 0.5.0 → 0.6.1

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 (125) hide show
  1. package/dist/components/Badge.d.ts +2 -1
  2. package/dist/components/Badge.d.ts.map +1 -1
  3. package/dist/components/Badge.js +2 -2
  4. package/dist/components/ConfirmDialog.d.ts +6 -1
  5. package/dist/components/ConfirmDialog.d.ts.map +1 -1
  6. package/dist/components/ConfirmDialog.js +35 -6
  7. package/dist/components/DataTable.d.ts +35 -2
  8. package/dist/components/DataTable.d.ts.map +1 -1
  9. package/dist/components/DataTable.js +64 -38
  10. package/dist/components/DropdownButton.d.ts +11 -0
  11. package/dist/components/DropdownButton.d.ts.map +1 -0
  12. package/dist/components/DropdownButton.js +9 -0
  13. package/dist/components/ErrorBoundary.d.ts +18 -0
  14. package/dist/components/ErrorBoundary.d.ts.map +1 -0
  15. package/dist/components/ErrorBoundary.js +19 -0
  16. package/dist/components/ErrorState.d.ts +6 -0
  17. package/dist/components/ErrorState.d.ts.map +1 -0
  18. package/dist/components/ErrorState.js +25 -0
  19. package/dist/components/FilterBar.d.ts +2 -0
  20. package/dist/components/FilterBar.d.ts.map +1 -1
  21. package/dist/components/FilterBar.js +3 -2
  22. package/dist/components/FormField.d.ts +7 -2
  23. package/dist/components/FormField.d.ts.map +1 -1
  24. package/dist/components/FormField.js +16 -5
  25. package/dist/components/GroupedDataTable.d.ts.map +1 -1
  26. package/dist/components/GroupedDataTable.js +40 -59
  27. package/dist/components/Pagination.js +1 -1
  28. package/dist/components/PivotDataTable.d.ts.map +1 -1
  29. package/dist/components/PivotDataTable.js +42 -65
  30. package/dist/components/Tag.d.ts +2 -1
  31. package/dist/components/Tag.d.ts.map +1 -1
  32. package/dist/components/Tag.js +2 -2
  33. package/dist/components/WorkflowSummary.js +6 -6
  34. package/dist/components/readFormatting.d.ts +2 -0
  35. package/dist/components/readFormatting.d.ts.map +1 -0
  36. package/dist/components/readFormatting.js +1 -0
  37. package/dist/derivations.d.ts +3 -0
  38. package/dist/derivations.d.ts.map +1 -0
  39. package/dist/derivations.js +1 -0
  40. package/dist/hooks/browserStorage.d.ts +3 -0
  41. package/dist/hooks/browserStorage.d.ts.map +1 -0
  42. package/dist/hooks/browserStorage.js +1 -0
  43. package/dist/hooks/deleteConfirmation.d.ts +20 -0
  44. package/dist/hooks/deleteConfirmation.d.ts.map +1 -0
  45. package/dist/hooks/deleteConfirmation.js +21 -0
  46. package/dist/hooks/exportDownload.d.ts +16 -0
  47. package/dist/hooks/exportDownload.d.ts.map +1 -0
  48. package/dist/hooks/exportDownload.js +55 -0
  49. package/dist/hooks/formDerivations.d.ts +7 -0
  50. package/dist/hooks/formDerivations.d.ts.map +1 -0
  51. package/dist/hooks/formDerivations.js +23 -0
  52. package/dist/hooks/formSeeds.d.ts +12 -0
  53. package/dist/hooks/formSeeds.d.ts.map +1 -0
  54. package/dist/hooks/formSeeds.js +26 -0
  55. package/dist/hooks/navigation.d.ts +37 -0
  56. package/dist/hooks/navigation.d.ts.map +1 -1
  57. package/dist/hooks/navigation.js +107 -70
  58. package/dist/hooks/readModelStore.d.ts +29 -0
  59. package/dist/hooks/readModelStore.d.ts.map +1 -0
  60. package/dist/hooks/readModelStore.js +135 -0
  61. package/dist/hooks/recordScopedWorkflow.d.ts +13 -0
  62. package/dist/hooks/recordScopedWorkflow.d.ts.map +1 -0
  63. package/dist/hooks/recordScopedWorkflow.js +40 -0
  64. package/dist/hooks/resourceClient.d.ts +39 -0
  65. package/dist/hooks/resourceClient.d.ts.map +1 -1
  66. package/dist/hooks/resourceClient.js +205 -71
  67. package/dist/hooks/resourceErrors.d.ts +13 -0
  68. package/dist/hooks/resourceErrors.d.ts.map +1 -0
  69. package/dist/hooks/resourceErrors.js +140 -0
  70. package/dist/hooks/resourceRowActions.d.ts +17 -0
  71. package/dist/hooks/resourceRowActions.d.ts.map +1 -0
  72. package/dist/hooks/resourceRowActions.js +48 -0
  73. package/dist/hooks/resourceStore.d.ts +2 -24
  74. package/dist/hooks/resourceStore.d.ts.map +1 -1
  75. package/dist/hooks/resourceStore.js +1 -164
  76. package/dist/hooks/resourceTarget.d.ts +1 -1
  77. package/dist/hooks/resourceTarget.d.ts.map +1 -1
  78. package/dist/hooks/resourceTarget.js +1 -22
  79. package/dist/hooks/serverListStore.d.ts +3 -0
  80. package/dist/hooks/serverListStore.d.ts.map +1 -0
  81. package/dist/hooks/serverListStore.js +1 -0
  82. package/dist/hooks/sessionCaches.d.ts +6 -0
  83. package/dist/hooks/sessionCaches.d.ts.map +1 -0
  84. package/dist/hooks/sessionCaches.js +14 -0
  85. package/dist/hooks/transitionedSetter.d.ts +2 -0
  86. package/dist/hooks/transitionedSetter.d.ts.map +1 -0
  87. package/dist/hooks/transitionedSetter.js +9 -0
  88. package/dist/hooks/useAuth.d.ts +18 -0
  89. package/dist/hooks/useAuth.d.ts.map +1 -1
  90. package/dist/hooks/useAuth.js +30 -0
  91. package/dist/hooks/useCollectionView.d.ts +2 -8
  92. package/dist/hooks/useCollectionView.d.ts.map +1 -1
  93. package/dist/hooks/useCollectionView.js +8 -36
  94. package/dist/hooks/useDocumentMetadata.d.ts.map +1 -1
  95. package/dist/hooks/useDocumentMetadata.js +57 -0
  96. package/dist/hooks/useGroupedCollectionView.d.ts +2 -7
  97. package/dist/hooks/useGroupedCollectionView.d.ts.map +1 -1
  98. package/dist/hooks/useGroupedCollectionView.js +8 -52
  99. package/dist/hooks/useI18n.d.ts +21 -0
  100. package/dist/hooks/useI18n.d.ts.map +1 -0
  101. package/dist/hooks/useI18n.js +86 -0
  102. package/dist/hooks/useReadModel.d.ts +15 -0
  103. package/dist/hooks/useReadModel.d.ts.map +1 -1
  104. package/dist/hooks/useReadModel.js +127 -40
  105. package/dist/hooks/useResource.d.ts +7 -0
  106. package/dist/hooks/useResource.d.ts.map +1 -1
  107. package/dist/hooks/useResource.js +159 -3
  108. package/dist/hooks/useStoredState.d.ts +15 -0
  109. package/dist/hooks/useStoredState.d.ts.map +1 -0
  110. package/dist/hooks/useStoredState.js +28 -0
  111. package/dist/hooks/useToast.d.ts.map +1 -1
  112. package/dist/hooks/useToast.js +1 -1
  113. package/dist/hooks/workflowTransition.d.ts +21 -0
  114. package/dist/hooks/workflowTransition.d.ts.map +1 -0
  115. package/dist/hooks/workflowTransition.js +54 -0
  116. package/dist/index.d.ts +35 -9
  117. package/dist/index.d.ts.map +1 -1
  118. package/dist/index.js +21 -5
  119. package/dist/policies/can.d.ts +2 -14
  120. package/dist/policies/can.d.ts.map +1 -1
  121. package/dist/policies/can.js +1 -160
  122. package/dist/workflow.d.ts +3 -0
  123. package/dist/workflow.d.ts.map +1 -0
  124. package/dist/workflow.js +1 -0
  125. package/package.json +142 -26
@@ -0,0 +1,86 @@
1
+ import React from 'react';
2
+ import { humanizeEnumValue as humanizeEnumValueCore, resolveEnumValueText as resolveEnumValueTextCore, resolveMessageTextWithBundle as resolveMessageTextWithBundleCore, } from '../../../runtime-core/dist/i18n.js';
3
+ const I18nContext = React.createContext(undefined);
4
+ let activeI18nState = null;
5
+ const activeI18nProviders = [];
6
+ export function resolveMessageText(message, fallback = '') {
7
+ return resolveMessageTextWithBundle(message, activeI18nState?.messages, fallback);
8
+ }
9
+ export function resolveMessageTextWithBundle(message, messages, fallback = '') {
10
+ return resolveMessageTextWithBundleCore(message, messages, fallback);
11
+ }
12
+ export function humanizeEnumValue(value) {
13
+ return humanizeEnumValueCore(value);
14
+ }
15
+ export function resolveEnumValueText(value, keyPrefix, labels) {
16
+ return resolveEnumValueTextCore(value, keyPrefix, labels, activeI18nState?.messages);
17
+ }
18
+ export function resolveUnknownEnumValue(value, keyPrefix, labels) {
19
+ return typeof value === 'string' ? resolveEnumValueText(value, keyPrefix, labels) : String(value);
20
+ }
21
+ export function buildEnumValueRenderer(keyPrefix, labels) {
22
+ return (value) => resolveUnknownEnumValue(value, keyPrefix, labels);
23
+ }
24
+ function resolveWorkflowStepName(step) {
25
+ if (typeof step === 'object' && step !== null && 'name' in step) {
26
+ return step.name;
27
+ }
28
+ return step;
29
+ }
30
+ export function resolveWorkflowStepMessage(message, step, fallback = '') {
31
+ const stepName = resolveWorkflowStepName(step);
32
+ if (stepName === null || stepName === undefined) {
33
+ return fallback;
34
+ }
35
+ if (typeof message === 'string') {
36
+ return resolveMessageText({
37
+ defaultMessage: message,
38
+ values: {
39
+ step: stepName,
40
+ },
41
+ }, fallback ?? '');
42
+ }
43
+ if (typeof message === 'object' && message !== null && !Array.isArray(message)) {
44
+ const descriptor = message;
45
+ return resolveMessageText({
46
+ ...descriptor,
47
+ values: {
48
+ ...(descriptor.values ?? {}),
49
+ step: stepName,
50
+ },
51
+ }, fallback ?? '');
52
+ }
53
+ return resolveMessageText(message, fallback ?? '');
54
+ }
55
+ export function I18nProvider({ value, children }) {
56
+ const providerTokenRef = React.useRef(null);
57
+ if (!providerTokenRef.current) {
58
+ providerTokenRef.current = Symbol('rdsl-i18n-provider');
59
+ }
60
+ activeI18nState = value;
61
+ React.useEffect(() => {
62
+ const token = providerTokenRef.current;
63
+ const existingIndex = activeI18nProviders.findIndex((entry) => entry.token === token);
64
+ if (existingIndex >= 0) {
65
+ activeI18nProviders[existingIndex] = { token, value };
66
+ }
67
+ else {
68
+ activeI18nProviders.push({ token, value });
69
+ }
70
+ activeI18nState = value;
71
+ return () => {
72
+ const index = activeI18nProviders.findIndex((entry) => entry.token === token);
73
+ if (index >= 0) {
74
+ activeI18nProviders.splice(index, 1);
75
+ }
76
+ activeI18nState = activeI18nProviders[activeI18nProviders.length - 1]?.value ?? null;
77
+ };
78
+ }, [value]);
79
+ return React.createElement(I18nContext.Provider, { value }, children);
80
+ }
81
+ export function useI18n() {
82
+ return React.useContext(I18nContext) ?? {
83
+ locale: 'en',
84
+ messages: {},
85
+ };
86
+ }
@@ -1,5 +1,16 @@
1
1
  export interface UseReadModelOptions {
2
2
  enabled?: boolean;
3
+ pageSize?: number;
4
+ serverListView?: boolean;
5
+ }
6
+ export interface ReadModelSortState {
7
+ field: string;
8
+ direction: 'asc' | 'desc';
9
+ }
10
+ export interface ReadModelPaginationState {
11
+ page: number;
12
+ totalPages: number;
13
+ totalItems: number;
3
14
  }
4
15
  export interface UseReadModelResult<T extends {
5
16
  id: string;
@@ -8,6 +19,10 @@ export interface UseReadModelResult<T extends {
8
19
  allData: T[];
9
20
  loading: boolean;
10
21
  error: unknown;
22
+ sort: ReadModelSortState | null;
23
+ setSort: (next: ReadModelSortState | null) => void;
24
+ pagination: ReadModelPaginationState;
25
+ setPagination: (page: number) => void;
11
26
  refresh: () => Promise<void>;
12
27
  }
13
28
  export declare function useReadModel<T extends {
@@ -1 +1 @@
1
- {"version":3,"file":"useReadModel.d.ts","sourceRoot":"","sources":["../../src/hooks/useReadModel.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC1D,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAmDD,wBAAgB,YAAY,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACnD,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,OAAO,GAAE,mBAAwB,GAChC,kBAAkB,CAAC,CAAC,CAAC,CA2DvB"}
1
+ {"version":3,"file":"useReadModel.d.ts","sourceRoot":"","sources":["../../src/hooks/useReadModel.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,mBAAmB;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,KAAK,GAAG,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IAC1D,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,IAAI,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAC;IACnD,UAAU,EAAE,wBAAwB,CAAC;IACrC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAgHD,wBAAgB,YAAY,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EACnD,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC7B,OAAO,GAAE,mBAAwB,GAChC,kBAAkB,CAAC,CAAC,CAAC,CAoHvB"}
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { useResourceClient } from './resourceClient.js';
3
+ import { getReadModelStore } from './readModelStore.js';
3
4
  import { matchesResourceTarget } from './resourceTarget.js';
4
5
  function isRecord(value) {
5
6
  return typeof value === 'object' && value !== null && !Array.isArray(value);
@@ -30,58 +31,127 @@ function normalizeReadModelItems(api, payload) {
30
31
  };
31
32
  });
32
33
  }
33
- function buildReadModelUrl(api, query) {
34
- const params = new URLSearchParams();
34
+ function normalizeReadModelPagePayload(api, payload, fallbackPage, fallbackSize) {
35
+ const items = normalizeReadModelItems(api, payload);
36
+ const payloadRecord = isRecord(payload) ? payload : null;
37
+ const paginationRecord = payloadRecord && isRecord(payloadRecord.pagination) ? payloadRecord.pagination : null;
38
+ const page = Number((paginationRecord && paginationRecord.page)
39
+ ?? payloadRecord?.page
40
+ ?? fallbackPage);
41
+ const size = Number((paginationRecord && paginationRecord.size)
42
+ ?? payloadRecord?.size
43
+ ?? fallbackSize);
44
+ const totalItems = Number((paginationRecord && paginationRecord.totalItems)
45
+ ?? payloadRecord?.totalItems
46
+ ?? items.length);
47
+ const totalPages = Number((paginationRecord && paginationRecord.totalPages)
48
+ ?? payloadRecord?.totalPages
49
+ ?? Math.max(1, Math.ceil((Number.isFinite(totalItems) ? totalItems : items.length) / Math.max(1, Number.isFinite(size) ? size : fallbackSize))));
50
+ return {
51
+ items,
52
+ page: Number.isFinite(page) && page > 0 ? page : fallbackPage,
53
+ size: Number.isFinite(size) && size > 0 ? size : fallbackSize,
54
+ totalItems: Number.isFinite(totalItems) && totalItems >= 0 ? totalItems : items.length,
55
+ totalPages: Number.isFinite(totalPages) && totalPages > 0 ? totalPages : 1,
56
+ };
57
+ }
58
+ function buildReadModelUrl(api, query, list) {
59
+ const parts = api.split('?');
60
+ const path = parts[0] ?? api;
61
+ const params = new URLSearchParams(parts[1] ?? '');
35
62
  for (const [key, value] of Object.entries(query)) {
36
63
  const trimmed = String(value ?? '').trim();
37
64
  if (trimmed !== '') {
38
65
  params.set(key, trimmed);
39
66
  }
40
67
  }
41
- const queryString = params.toString();
42
- if (queryString === '') {
43
- return api;
68
+ if (list?.page !== undefined) {
69
+ params.set('page', String(list.page));
70
+ }
71
+ if (list?.size !== undefined) {
72
+ params.set('size', String(list.size));
73
+ }
74
+ if (list?.sort?.field) {
75
+ params.set('sort', `${list.sort.field},${list.sort.direction}`);
76
+ }
77
+ else {
78
+ params.delete('sort');
44
79
  }
45
- return api.includes('?') ? `${api}&${queryString}` : `${api}?${queryString}`;
80
+ const queryString = params.toString();
81
+ return queryString === '' ? path : `${path}?${queryString}`;
46
82
  }
47
83
  export function useReadModel(api, query, options = {}) {
48
84
  const client = useResourceClient();
49
85
  const enabled = options.enabled ?? true;
50
- const [allData, setAllData] = React.useState([]);
51
- const [loading, setLoading] = React.useState(false);
52
- const [error, setError] = React.useState(null);
53
- const requestUrl = React.useMemo(() => buildReadModelUrl(api, query), [api, query]);
54
- const load = React.useCallback(async () => {
55
- if (!enabled) {
56
- setAllData([]);
57
- setLoading(false);
58
- setError(null);
59
- return;
60
- }
61
- setLoading(true);
62
- try {
63
- const payload = await client.get(requestUrl);
64
- setAllData(normalizeReadModelItems(api, payload));
65
- setError(null);
86
+ const pageSize = options.pageSize ?? 20;
87
+ const serverListView = options.serverListView ?? false;
88
+ const [sort, setSortState] = React.useState(null);
89
+ const [page, setPageState] = React.useState(1);
90
+ const querySignature = JSON.stringify(query);
91
+ const queryState = React.useMemo(() => query, [querySignature]);
92
+ const requestUrl = React.useMemo(() => buildReadModelUrl(api, queryState, serverListView ? { page, size: pageSize, sort } : undefined), [api, page, pageSize, queryState, serverListView, sort]);
93
+ const readModelStore = React.useMemo(() => getReadModelStore(client, requestUrl, async () => {
94
+ const payload = await client.get(requestUrl);
95
+ if (serverListView) {
96
+ const listPage = normalizeReadModelPagePayload(api, payload, page, pageSize);
97
+ return {
98
+ items: listPage.items,
99
+ page: listPage.page,
100
+ totalItems: listPage.totalItems,
101
+ totalPages: listPage.totalPages,
102
+ };
66
103
  }
67
- catch (nextError) {
68
- setAllData([]);
69
- setError(nextError);
70
- }
71
- finally {
72
- setLoading(false);
73
- }
74
- }, [api, client, enabled, requestUrl]);
104
+ const items = normalizeReadModelItems(api, payload);
105
+ return {
106
+ items,
107
+ page: 1,
108
+ totalItems: items.length,
109
+ totalPages: 1,
110
+ };
111
+ }), [api, client, page, pageSize, requestUrl, serverListView]);
112
+ const [, setRevision] = React.useState(0);
113
+ React.useEffect(() => {
114
+ if (!serverListView)
115
+ return;
116
+ setPageState(1);
117
+ }, [querySignature, serverListView]);
118
+ React.useEffect(() => {
119
+ if (!enabled)
120
+ return undefined;
121
+ return readModelStore.subscribe(() => {
122
+ setRevision((value) => value + 1);
123
+ });
124
+ }, [enabled, readModelStore]);
125
+ React.useEffect(() => {
126
+ if (!enabled)
127
+ return;
128
+ void readModelStore.load(false).catch(() => undefined);
129
+ }, [enabled, readModelStore]);
130
+ const snapshot = enabled
131
+ ? readModelStore.getSnapshot()
132
+ : {
133
+ result: null,
134
+ error: null,
135
+ pendingCount: 0,
136
+ resolvedOnce: true,
137
+ };
75
138
  React.useEffect(() => {
76
- void load();
77
- }, [load]);
139
+ if (!enabled || !serverListView)
140
+ return;
141
+ const resolvedPage = snapshot.result?.page;
142
+ if (!resolvedPage || resolvedPage === page)
143
+ return;
144
+ setPageState(resolvedPage);
145
+ }, [enabled, page, serverListView, snapshot.result?.page]);
78
146
  React.useEffect(() => {
147
+ if (!enabled || typeof window === 'undefined')
148
+ return undefined;
79
149
  if (typeof window === 'undefined')
80
150
  return undefined;
81
151
  const handleRefresh = (event) => {
82
152
  const target = event.detail?.target;
83
153
  if (matchesResourceTarget(api, target)) {
84
- void load();
154
+ void readModelStore.load(true).catch(() => undefined);
85
155
  }
86
156
  };
87
157
  window.addEventListener('rdsl:refresh', handleRefresh);
@@ -90,15 +160,32 @@ export function useReadModel(api, query, options = {}) {
90
160
  window.removeEventListener('rdsl:refresh', handleRefresh);
91
161
  window.removeEventListener('rdsl:invalidate', handleRefresh);
92
162
  };
93
- }, [api, load]);
163
+ }, [api, enabled, readModelStore]);
94
164
  const refresh = React.useCallback(async () => {
95
- await load();
96
- }, [load]);
165
+ if (!enabled)
166
+ return;
167
+ await readModelStore.load(true);
168
+ }, [enabled, readModelStore]);
169
+ const setSort = React.useCallback((next) => {
170
+ setSortState(next);
171
+ setPageState(1);
172
+ }, []);
173
+ const setPagination = React.useCallback((nextPage) => {
174
+ setPageState(Math.max(1, nextPage));
175
+ }, []);
97
176
  return {
98
- data: allData,
99
- allData,
100
- loading,
101
- error,
177
+ data: snapshot.result?.items ?? [],
178
+ allData: snapshot.result?.items ?? [],
179
+ loading: enabled && (snapshot.pendingCount > 0 || !snapshot.resolvedOnce),
180
+ error: snapshot.error,
181
+ sort,
182
+ setSort,
183
+ pagination: {
184
+ page: snapshot.result?.page ?? page,
185
+ totalPages: snapshot.result?.totalPages ?? 1,
186
+ totalItems: snapshot.result?.totalItems ?? 0,
187
+ },
188
+ setPagination,
102
189
  refresh,
103
190
  };
104
191
  }
@@ -1,9 +1,14 @@
1
+ import type { ResourceExportPayload, ResourceListQuery } from './resourceClient.js';
1
2
  export interface ResourcePaginationState {
2
3
  page: number;
3
4
  totalPages: number;
5
+ totalItems: number;
4
6
  }
5
7
  export interface UseResourceOptions {
6
8
  pageSize?: number;
9
+ serverListView?: boolean;
10
+ projectionFields?: string[];
11
+ baseFilters?: Record<string, string>;
7
12
  }
8
13
  export interface UseResourceResult<T extends {
9
14
  id: string;
@@ -28,6 +33,8 @@ export interface UseResourceResult<T extends {
28
33
  createItem: (input: Partial<T>) => Promise<T>;
29
34
  updateItem: (id: string, input: Partial<T>) => Promise<T>;
30
35
  deleteItem: (id: string) => Promise<void>;
36
+ batchDelete: (ids: string[]) => Promise<void>;
37
+ exportList: (format: string, query?: ResourceListQuery) => Promise<ResourceExportPayload>;
31
38
  refresh: () => void | Promise<void>;
32
39
  }
33
40
  export declare function useResource<T extends {
@@ -1 +1 @@
1
- {"version":3,"file":"useResource.d.ts","sourceRoot":"","sources":["../../src/hooks/useResource.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IACzD,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACnD,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7E,UAAU,EAAE,uBAAuB,CAAC;IACpC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;IACvC,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9C,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1D,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAYD,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAClD,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAAC,CAAC,CAAC,CAwEtB"}
1
+ {"version":3,"file":"useResource.d.ts","sourceRoot":"","sources":["../../src/hooks/useResource.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAMpF,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC5B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACtC;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE;IACzD,IAAI,EAAE,CAAC,EAAE,CAAC;IACV,OAAO,EAAE,CAAC,EAAE,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IACnD,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC1D,OAAO,EAAE,CAAC,IAAI,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,KAAK,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,KAAK,IAAI,CAAC;IAC7E,UAAU,EAAE,uBAAuB,CAAC;IACpC,aAAa,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,OAAO,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,CAAC,GAAG,SAAS,CAAC;IACvC,UAAU,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC9C,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC;IAC1D,UAAU,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,WAAW,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9C,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,iBAAiB,KAAK,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC1F,OAAO,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACrC;AAaD,wBAAgB,WAAW,CAAC,CAAC,SAAS;IAAE,EAAE,EAAE,MAAM,CAAA;CAAE,EAClD,GAAG,EAAE,MAAM,EACX,OAAO,GAAE,kBAAuB,GAC/B,iBAAiB,CAAC,CAAC,CAAC,CA0PtB"}
@@ -1,22 +1,141 @@
1
1
  import React from 'react';
2
2
  import { useResourceClient } from './resourceClient.js';
3
3
  import { getResourceStore } from './resourceStore.js';
4
+ import { getServerListStore } from './serverListStore.js';
4
5
  import { matchesResourceTarget } from './resourceTarget.js';
5
6
  import { useCollectionView } from './useCollectionView.js';
6
7
  export function useResource(api, options = {}) {
7
8
  const pageSize = options.pageSize ?? 20;
9
+ const serverListView = options.serverListView ?? false;
10
+ const projectionSignature = JSON.stringify(options.projectionFields ?? []);
11
+ const projectionFields = React.useMemo(() => (options.projectionFields ?? []).map((field) => String(field ?? '').trim()).filter((field) => field !== ''), [projectionSignature]);
12
+ const baseFilterSignature = JSON.stringify(options.baseFilters ?? {});
13
+ const baseFilters = React.useMemo(() => Object.fromEntries(Object.entries(options.baseFilters ?? {})
14
+ .map(([key, value]) => [String(key ?? '').trim(), String(value ?? '').trim()])
15
+ .filter(([key, value]) => key !== '' && value !== '')), [baseFilterSignature]);
8
16
  const client = useResourceClient();
17
+ const [serverFilters, setServerFiltersState] = React.useState({});
18
+ const [serverSort, setServerSortState] = React.useState(null);
19
+ const [serverPage, setServerPage] = React.useState(1);
9
20
  const store = React.useMemo(() => getResourceStore(client, api), [api, client]);
10
21
  const [, setRevision] = React.useState(0);
22
+ const requestFilters = React.useMemo(() => ({ ...baseFilters, ...serverFilters }), [baseFilters, serverFilters]);
23
+ const serverProjectionSignature = JSON.stringify(projectionFields);
24
+ const serverFilterSignature = JSON.stringify(requestFilters);
25
+ const serverSortSignature = JSON.stringify(serverSort);
26
+ const serverStore = React.useMemo(() => getServerListStore(client, api, {
27
+ page: serverPage,
28
+ size: pageSize,
29
+ sort: serverSort,
30
+ filters: requestFilters,
31
+ projections: projectionFields,
32
+ }), [api, client, pageSize, serverFilterSignature, serverPage, serverProjectionSignature, serverSortSignature]);
11
33
  React.useEffect(() => {
34
+ if (!serverListView)
35
+ return undefined;
36
+ return serverStore.subscribe(() => {
37
+ setRevision((value) => value + 1);
38
+ });
39
+ }, [serverListView, serverStore]);
40
+ React.useEffect(() => {
41
+ if (!serverListView)
42
+ return undefined;
43
+ void serverStore.load(false).catch(() => undefined);
44
+ }, [serverListView, serverStore]);
45
+ const serverSnapshot = serverStore.getSnapshot();
46
+ React.useEffect(() => {
47
+ if (!serverListView)
48
+ return;
49
+ const resolvedPage = serverSnapshot.page?.page;
50
+ if (!resolvedPage || resolvedPage === serverPage)
51
+ return;
52
+ setServerPage(resolvedPage);
53
+ }, [serverListView, serverPage, serverSnapshot.page?.page]);
54
+ React.useEffect(() => {
55
+ if (!serverListView || typeof window === 'undefined')
56
+ return undefined;
57
+ const handleRefresh = (event) => {
58
+ const target = event?.detail?.target;
59
+ if (matchesResourceTarget(api, target)) {
60
+ void serverStore.load(true).catch(() => undefined);
61
+ }
62
+ };
63
+ window.addEventListener('rdsl:refresh', handleRefresh);
64
+ window.addEventListener('rdsl:invalidate', handleRefresh);
65
+ return () => {
66
+ window.removeEventListener('rdsl:refresh', handleRefresh);
67
+ window.removeEventListener('rdsl:invalidate', handleRefresh);
68
+ };
69
+ }, [api, serverListView, serverStore]);
70
+ const invalidateServerLists = React.useCallback(() => {
71
+ if (typeof window === 'undefined') {
72
+ void serverStore.load(true).catch(() => undefined);
73
+ return;
74
+ }
75
+ window.dispatchEvent(new CustomEvent('rdsl:invalidate', { detail: { target: api } }));
76
+ }, [api, serverStore]);
77
+ const serverCreateItem = React.useCallback(async (input) => {
78
+ const created = await client.create(api, input);
79
+ invalidateServerLists();
80
+ return created;
81
+ }, [api, client, invalidateServerLists]);
82
+ const serverUpdateItem = React.useCallback(async (id, input) => {
83
+ const updated = await client.update(api, id, input);
84
+ invalidateServerLists();
85
+ return updated;
86
+ }, [api, client, invalidateServerLists]);
87
+ const serverDeleteItem = React.useCallback(async (id) => {
88
+ await client.delete(api, id);
89
+ invalidateServerLists();
90
+ }, [api, client, invalidateServerLists]);
91
+ const serverBatchDelete = React.useCallback(async (ids) => {
92
+ const normalizedIds = ids.map((id) => String(id)).filter((id) => id !== '');
93
+ if (normalizedIds.length === 0)
94
+ return;
95
+ await client.batch(api, 'delete', normalizedIds);
96
+ invalidateServerLists();
97
+ }, [api, client, invalidateServerLists]);
98
+ const serverRefresh = React.useCallback(() => {
99
+ return serverStore.load(true).then(() => undefined);
100
+ }, [serverStore]);
101
+ const exportList = React.useCallback((format, query = {}) => {
102
+ const mergedFilters = { ...baseFilters, ...(query.filters ?? {}) };
103
+ const mergedProjections = query.projections ?? projectionFields;
104
+ return client.export(api, format, {
105
+ ...query,
106
+ filters: mergedFilters,
107
+ projections: mergedProjections,
108
+ });
109
+ }, [api, baseFilters, client, projectionFields]);
110
+ const serverGetById = React.useCallback((id) => {
111
+ return serverSnapshot.page?.items.find((item) => item.id === id);
112
+ }, [serverSnapshot.page?.items]);
113
+ const setServerFilters = React.useCallback((next) => {
114
+ setServerFiltersState(next);
115
+ setServerPage(1);
116
+ }, []);
117
+ const setServerSort = React.useCallback((next) => {
118
+ setServerSortState(next);
119
+ setServerPage(1);
120
+ }, []);
121
+ const setServerPagination = React.useCallback((nextPage) => {
122
+ setServerPage(Math.max(1, nextPage));
123
+ }, []);
124
+ React.useEffect(() => {
125
+ if (serverListView)
126
+ return undefined;
12
127
  return store.subscribe(() => {
13
128
  setRevision((value) => value + 1);
14
129
  });
15
- }, [store]);
130
+ }, [serverListView, store]);
16
131
  React.useEffect(() => {
132
+ if (serverListView)
133
+ return undefined;
17
134
  void store.load(false).catch(() => undefined);
18
- }, [store]);
135
+ }, [serverListView, store]);
19
136
  React.useEffect(() => {
137
+ if (serverListView || typeof window === 'undefined')
138
+ return undefined;
20
139
  if (typeof window === 'undefined')
21
140
  return undefined;
22
141
  const handleRefresh = (event) => {
@@ -31,7 +150,7 @@ export function useResource(api, options = {}) {
31
150
  window.removeEventListener('rdsl:refresh', handleRefresh);
32
151
  window.removeEventListener('rdsl:invalidate', handleRefresh);
33
152
  };
34
- }, [api, store]);
153
+ }, [api, serverListView, store]);
35
154
  const snapshot = store.getSnapshot();
36
155
  const collection = useCollectionView(snapshot.items, { pageSize, paginate: true });
37
156
  const getById = React.useCallback((id) => {
@@ -46,9 +165,44 @@ export function useResource(api, options = {}) {
46
165
  const deleteItem = React.useCallback((id) => {
47
166
  return store.deleteItem(id);
48
167
  }, [store]);
168
+ const batchDelete = React.useCallback(async (ids) => {
169
+ const normalizedIds = ids.map((id) => String(id)).filter((id) => id !== '');
170
+ if (normalizedIds.length === 0)
171
+ return;
172
+ if (typeof store.batchDelete === 'function') {
173
+ await store.batchDelete(normalizedIds);
174
+ return;
175
+ }
176
+ await Promise.all(normalizedIds.map((id) => store.deleteItem(id)));
177
+ }, [store]);
49
178
  const refresh = React.useCallback(() => {
50
179
  return store.load(true).then(() => undefined);
51
180
  }, [store]);
181
+ if (serverListView) {
182
+ return {
183
+ data: serverSnapshot.page?.items ?? [],
184
+ allData: serverSnapshot.page?.items ?? [],
185
+ loading: serverSnapshot.pendingCount > 0 || !serverSnapshot.resolvedOnce,
186
+ error: serverSnapshot.error,
187
+ filters: serverFilters,
188
+ setFilters: setServerFilters,
189
+ sort: serverSort,
190
+ setSort: setServerSort,
191
+ pagination: {
192
+ page: serverSnapshot.page?.page ?? serverPage,
193
+ totalPages: serverSnapshot.page?.totalPages ?? 1,
194
+ totalItems: serverSnapshot.page?.totalItems ?? 0,
195
+ },
196
+ setPagination: setServerPagination,
197
+ getById: serverGetById,
198
+ createItem: serverCreateItem,
199
+ updateItem: serverUpdateItem,
200
+ deleteItem: serverDeleteItem,
201
+ batchDelete: serverBatchDelete,
202
+ exportList,
203
+ refresh: serverRefresh,
204
+ };
205
+ }
52
206
  return {
53
207
  data: collection.data,
54
208
  allData: snapshot.items,
@@ -64,6 +218,8 @@ export function useResource(api, options = {}) {
64
218
  createItem,
65
219
  updateItem,
66
220
  deleteItem,
221
+ batchDelete,
222
+ exportList,
67
223
  refresh,
68
224
  };
69
225
  }
@@ -0,0 +1,15 @@
1
+ import { type BrowserStorageKind } from './browserStorage.js';
2
+ export type StoredStateStorageKind = 'memory' | BrowserStorageKind;
3
+ export interface StoredStateOptions<T> {
4
+ key: string;
5
+ initialValue: T;
6
+ storage?: StoredStateStorageKind;
7
+ parse: (parsed: unknown) => T;
8
+ }
9
+ export interface StoredStateResult<T> {
10
+ value: T;
11
+ setValue: (value: T | ((current: T) => T)) => void;
12
+ clearValue: () => void;
13
+ }
14
+ export declare function useStoredState<T>({ key, initialValue, storage, parse, }: StoredStateOptions<T>): StoredStateResult<T>;
15
+ //# sourceMappingURL=useStoredState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useStoredState.d.ts","sourceRoot":"","sources":["../../src/hooks/useStoredState.ts"],"names":[],"mappings":"AACA,OAAO,EAA6C,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAEzG,MAAM,MAAM,sBAAsB,GAAG,QAAQ,GAAG,kBAAkB,CAAC;AAEnE,MAAM,WAAW,kBAAkB,CAAC,CAAC;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,YAAY,EAAE,CAAC,CAAC;IAChB,OAAO,CAAC,EAAE,sBAAsB,CAAC;IACjC,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,CAAC,CAAC;CAC/B;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,KAAK,EAAE,CAAC,CAAC;IACT,QAAQ,EAAE,CAAC,KAAK,EAAE,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,IAAI,CAAC;IACnD,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,EAChC,GAAG,EACH,YAAY,EACZ,OAAkB,EAClB,KAAK,GACN,EAAE,kBAAkB,CAAC,CAAC,CAAC,GAAG,iBAAiB,CAAC,CAAC,CAAC,CA6B9C"}
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { readStoredJsonValue, writeStoredJsonValue } from './browserStorage.js';
3
+ export function useStoredState({ key, initialValue, storage = 'memory', parse, }) {
4
+ const readValue = React.useCallback(() => {
5
+ if (storage === 'memory') {
6
+ return initialValue;
7
+ }
8
+ return readStoredJsonValue(key, parse, { storage }) ?? initialValue;
9
+ }, [initialValue, key, parse, storage]);
10
+ const [value, setValue] = React.useState(() => readValue());
11
+ React.useEffect(() => {
12
+ if (storage === 'memory') {
13
+ return;
14
+ }
15
+ writeStoredJsonValue(key, value, { storage });
16
+ }, [key, storage, value]);
17
+ const clearValue = React.useCallback(() => {
18
+ if (storage !== 'memory') {
19
+ writeStoredJsonValue(key, null, { storage });
20
+ }
21
+ setValue(initialValue);
22
+ }, [initialValue, key, storage]);
23
+ return {
24
+ value,
25
+ setValue,
26
+ clearValue,
27
+ };
28
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useToast.d.ts","sourceRoot":"","sources":["../../src/hooks/useToast.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAEzG,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AACvD,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAC1E,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;AAE1D,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACzC,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;CACvC;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAID,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAEjE;AAuBD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,kBAAkB,OAEpE;AAED,wBAAgB,QAAQ,IAAI,QAAQ,CAEnC"}
1
+ {"version":3,"file":"useToast.d.ts","sourceRoot":"","sources":["../../src/hooks/useToast.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,WAAW,EAAE,MAAM,4BAA4B,CAAC;AAGzG,MAAM,MAAM,iBAAiB,GAAG,sBAAsB,CAAC;AACvD,MAAM,MAAM,sBAAsB,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;AAC1E,MAAM,MAAM,YAAY,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;AAE1D,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACzC,KAAK,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;IACvC,IAAI,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;CACvC;AAED,UAAU,kBAAkB;IAC1B,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B;AAID,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAEjE;AAuBD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,kBAAkB,OAEpE;AAED,wBAAgB,QAAQ,IAAI,QAAQ,CAEnC"}
@@ -1,5 +1,5 @@
1
1
  import React from 'react';
2
- import { resolveMessageText } from '@loj-lang/shared-contracts';
2
+ import { resolveMessageText } from './useI18n.js';
3
3
  const ToastContext = React.createContext(undefined);
4
4
  export function resolveToastMessage(message) {
5
5
  return resolveMessageText(message);
@@ -0,0 +1,21 @@
1
+ interface WorkflowTransitionClient {
2
+ post<T>(path: string): Promise<T>;
3
+ }
4
+ interface WorkflowTransitionResource {
5
+ refresh(): Promise<unknown> | unknown;
6
+ }
7
+ export declare function useWorkflowTransitionHandler(options: {
8
+ resourceApi: string;
9
+ id: string;
10
+ resourceClient: WorkflowTransitionClient;
11
+ resourceView: WorkflowTransitionResource;
12
+ workflowTransitionTargets: Record<string, string | null | undefined>;
13
+ resolveNextWorkflowSurfaceHref: (stateName: string) => string | null;
14
+ setPreconditionError: (value: string | null) => void;
15
+ updatedMessage: string;
16
+ preconditionMessage: string;
17
+ invalidTransitionMessage: string;
18
+ updateFailedMessage: string;
19
+ }): (transitionName: string) => Promise<void>;
20
+ export {};
21
+ //# sourceMappingURL=workflowTransition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflowTransition.d.ts","sourceRoot":"","sources":["../../src/hooks/workflowTransition.ts"],"names":[],"mappings":"AAKA,UAAU,wBAAwB;IAChC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;CACnC;AAED,UAAU,0BAA0B;IAClC,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CACvC;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE;IACpD,WAAW,EAAE,MAAM,CAAC;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,cAAc,EAAE,wBAAwB,CAAC;IACzC,YAAY,EAAE,0BAA0B,CAAC;IACzC,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACrE,8BAA8B,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;IACrE,oBAAoB,EAAE,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IACrD,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,mBAAmB,EAAE,MAAM,CAAC;CAC7B,GAAG,CAAC,cAAc,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAgD5C"}