@rebasepro/app 0.17.3 → 0.18.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 (185) hide show
  1. package/README.md +4 -1
  2. package/dist/components/index.d.ts +0 -3
  3. package/dist/contexts/AuthControllerContext.d.ts +2 -1
  4. package/dist/contexts/CustomizationControllerContext.d.ts +2 -1
  5. package/dist/contexts/DialogsProvider.d.ts +2 -1
  6. package/dist/contexts/RebaseDataContext.d.ts +10 -1
  7. package/dist/contexts/StorageSourceContext.d.ts +11 -1
  8. package/dist/core/RebaseProps.d.ts +2 -12
  9. package/dist/debug/index.d.ts +19 -0
  10. package/dist/debug.js +3631 -0
  11. package/dist/hooks/data/delete.d.ts +16 -7
  12. package/dist/hooks/data/save.d.ts +18 -4
  13. package/dist/hooks/index.d.ts +1 -0
  14. package/dist/hooks/useAdminModeController.d.ts +5 -4
  15. package/dist/hooks/useNavigationGroupLabel.d.ts +17 -0
  16. package/dist/hooks/useStudioBridge.d.ts +33 -0
  17. package/dist/index.es.js +2599 -6980
  18. package/dist/index.es.js.map +1 -1
  19. package/dist/vitePlugin.d.ts +22 -0
  20. package/dist/vitePlugin.js +40 -1
  21. package/package.json +42 -31
  22. package/src/auth/api.ts +0 -134
  23. package/src/auth/index.ts +0 -26
  24. package/src/auth/types.ts +0 -115
  25. package/src/auth/useRebaseAuthController.ts +0 -345
  26. package/src/collections/collection_view_config.ts +0 -76
  27. package/src/collections/entity-display-cache.ts +0 -195
  28. package/src/collections/entity-display.ts +0 -77
  29. package/src/collections/entity_image_preview.ts +0 -61
  30. package/src/collections/filter-operator-resolution.ts +0 -119
  31. package/src/collections/form-layout.ts +0 -394
  32. package/src/collections/index.ts +0 -13
  33. package/src/collections/navigation_from_path.ts +0 -123
  34. package/src/collections/navigation_utils.ts +0 -171
  35. package/src/collections/parent_references_from_path.ts +0 -59
  36. package/src/collections/property-path.ts +0 -30
  37. package/src/collections/property_presentation.ts +0 -264
  38. package/src/collections/summary-property.ts +0 -114
  39. package/src/collections/title-property.ts +0 -312
  40. package/src/components/AIIcon.tsx +0 -47
  41. package/src/components/AuthSimulationMenu.tsx +0 -0
  42. package/src/components/ConfirmationDialog.tsx +0 -48
  43. package/src/components/Debug/UIReferenceView.tsx +0 -1053
  44. package/src/components/Debug/UIStyleGuide.tsx +0 -159
  45. package/src/components/Debug/collection-views/CardViewDemo.tsx +0 -87
  46. package/src/components/Debug/collection-views/CollectionTableDemo.tsx +0 -107
  47. package/src/components/Debug/collection-views/KanbanBoardDemo.tsx +0 -89
  48. package/src/components/Debug/collection-views/index.ts +0 -3
  49. package/src/components/Debug/collection-views/sample_data.ts +0 -44
  50. package/src/components/Debug/crm-dashboard/CalendarWidget.tsx +0 -387
  51. package/src/components/Debug/crm-dashboard/CrmDashboardDemo.tsx +0 -1100
  52. package/src/components/Debug/crm-dashboard/DashboardMetrics.tsx +0 -131
  53. package/src/components/Debug/crm-dashboard/PipelineOverview.tsx +0 -288
  54. package/src/components/Debug/crm-dashboard/RecentActivity.tsx +0 -213
  55. package/src/components/Debug/crm-dashboard/TaskFilters.tsx +0 -182
  56. package/src/components/Debug/crm-dashboard/TaskTable.tsx +0 -425
  57. package/src/components/Debug/crm-dashboard/TasksView.tsx +0 -234
  58. package/src/components/ErrorTooltip.tsx +0 -12
  59. package/src/components/ErrorView.tsx +0 -94
  60. package/src/components/LanguageToggle.tsx +0 -59
  61. package/src/components/LoginView/LoginView.tsx +0 -1235
  62. package/src/components/LoginView/index.ts +0 -2
  63. package/src/components/LoginView/oauth-redirect-flow.ts +0 -184
  64. package/src/components/NotFoundPage.tsx +0 -27
  65. package/src/components/RebaseAuth.tsx +0 -27
  66. package/src/components/RebaseLogo.tsx +0 -88
  67. package/src/components/SchemaDriftBanner.tsx +0 -102
  68. package/src/components/UnsavedChangesDialog.tsx +0 -46
  69. package/src/components/UserDisplay.tsx +0 -54
  70. package/src/components/UserSelectPopover.tsx +0 -399
  71. package/src/components/UserSettingsView.tsx +0 -318
  72. package/src/components/common/index.ts +0 -6
  73. package/src/components/common/table_height.tsx +0 -21
  74. package/src/components/common/types.tsx +0 -66
  75. package/src/components/common/useColumnsIds.tsx +0 -261
  76. package/src/components/common/useDataTableController.tsx +0 -571
  77. package/src/components/common/useDebouncedData.ts +0 -49
  78. package/src/components/common/useScrollRestoration.tsx +0 -68
  79. package/src/components/index.tsx +0 -26
  80. package/src/contexts/AdminModeController.tsx +0 -11
  81. package/src/contexts/AnalyticsContext.tsx +0 -4
  82. package/src/contexts/AuthControllerContext.tsx +0 -4
  83. package/src/contexts/CollectionResolverContext.tsx +0 -24
  84. package/src/contexts/CollectionScopeContext.tsx +0 -68
  85. package/src/contexts/ComponentOverrideContext.tsx +0 -81
  86. package/src/contexts/CustomizationControllerContext.tsx +0 -4
  87. package/src/contexts/DataDriverContext.tsx +0 -4
  88. package/src/contexts/DataSourcesContext.tsx +0 -36
  89. package/src/contexts/DatabaseAdminContext.tsx +0 -4
  90. package/src/contexts/DialogsProvider.tsx +0 -56
  91. package/src/contexts/EffectiveRoleController.tsx +0 -12
  92. package/src/contexts/ModeController.tsx +0 -11
  93. package/src/contexts/RebaseClientInstanceContext.tsx +0 -7
  94. package/src/contexts/RebaseDataContext.tsx +0 -4
  95. package/src/contexts/SnackbarProvider.tsx +0 -15
  96. package/src/contexts/StorageSourceContext.tsx +0 -4
  97. package/src/contexts/StorageSourcesContext.tsx +0 -30
  98. package/src/contexts/UserConfigurationPersistenceContext.tsx +0 -4
  99. package/src/contexts/index.ts +0 -18
  100. package/src/core/PluginLifecycleManager.tsx +0 -96
  101. package/src/core/PluginProviderStack.tsx +0 -40
  102. package/src/core/Rebase.tsx +0 -488
  103. package/src/core/RebaseProps.tsx +0 -333
  104. package/src/core/RebaseRouter.tsx +0 -18
  105. package/src/core/RebaseRoutes.tsx +0 -24
  106. package/src/core/index.tsx +0 -5
  107. package/src/hooks/ApiConfigContext.tsx +0 -83
  108. package/src/hooks/data/collectionQuery.ts +0 -55
  109. package/src/hooks/data/delete.ts +0 -56
  110. package/src/hooks/data/save.ts +0 -78
  111. package/src/hooks/data/useCollection.tsx +0 -183
  112. package/src/hooks/data/useData.tsx +0 -18
  113. package/src/hooks/data/useDataOrder.ts +0 -26
  114. package/src/hooks/data/useFetch.tsx +0 -156
  115. package/src/hooks/data/useRelationSelector.tsx +0 -280
  116. package/src/hooks/index.tsx +0 -45
  117. package/src/hooks/useAdminModeController.tsx +0 -23
  118. package/src/hooks/useAnalyticsController.tsx +0 -8
  119. package/src/hooks/useAuthController.tsx +0 -15
  120. package/src/hooks/useAuthSubscription.ts +0 -130
  121. package/src/hooks/useBackendStorageSource.ts +0 -295
  122. package/src/hooks/useBridgeRegistration.tsx +0 -32
  123. package/src/hooks/useBrowserTitleAndIcon.tsx +0 -23
  124. package/src/hooks/useBuildAdminModeController.tsx +0 -29
  125. package/src/hooks/useBuildEffectiveRoleController.tsx +0 -30
  126. package/src/hooks/useBuildLocalConfigurationPersistence.tsx +0 -83
  127. package/src/hooks/useBuildModeController.tsx +0 -73
  128. package/src/hooks/useClipboard.tsx +0 -158
  129. package/src/hooks/useCollapsedGroups.ts +0 -116
  130. package/src/hooks/useComponentOverride.tsx +0 -59
  131. package/src/hooks/useCustomizationController.tsx +0 -14
  132. package/src/hooks/useDialogsController.tsx +0 -15
  133. package/src/hooks/useEffectiveRoleController.tsx +0 -10
  134. package/src/hooks/useLargeLayout.tsx +0 -65
  135. package/src/hooks/useModeController.tsx +0 -23
  136. package/src/hooks/useNavigationBlocker.tsx +0 -108
  137. package/src/hooks/usePermissions.ts +0 -45
  138. package/src/hooks/useRebaseClient.tsx +0 -10
  139. package/src/hooks/useRebaseContext.tsx +0 -84
  140. package/src/hooks/useRebaseRegistry.tsx +0 -91
  141. package/src/hooks/useResolvedComponent.tsx +0 -195
  142. package/src/hooks/useSlot.tsx +0 -64
  143. package/src/hooks/useSnackbarController.tsx +0 -80
  144. package/src/hooks/useStorageSource.tsx +0 -11
  145. package/src/hooks/useStudioBridge.tsx +0 -258
  146. package/src/hooks/useTranslation.ts +0 -38
  147. package/src/hooks/useUnsavedChangesDialog.tsx +0 -67
  148. package/src/hooks/useUserConfigurationPersistence.tsx +0 -11
  149. package/src/i18n/RebaseI18nProvider.tsx +0 -159
  150. package/src/index.ts +0 -32
  151. package/src/internal/common.tsx +0 -28
  152. package/src/internal/useRestoreScroll.tsx +0 -69
  153. package/src/locales/de.ts +0 -941
  154. package/src/locales/en.ts +0 -1021
  155. package/src/locales/es.ts +0 -962
  156. package/src/locales/fr.ts +0 -941
  157. package/src/locales/hi.ts +0 -941
  158. package/src/locales/it.ts +0 -941
  159. package/src/locales/pt.ts +0 -949
  160. package/src/util/constants.ts +0 -7
  161. package/src/util/createFormexStub.tsx +0 -66
  162. package/src/util/entity_cache.ts +0 -242
  163. package/src/util/enums.ts +0 -34
  164. package/src/util/icon_list.ts +0 -22
  165. package/src/util/icons.tsx +0 -129
  166. package/src/util/index.ts +0 -13
  167. package/src/util/local_storage.ts +0 -66
  168. package/src/util/previews.ts +0 -127
  169. package/src/util/useStorageUploadController.tsx +0 -354
  170. package/src/vitePlugin.ts +0 -215
  171. /package/dist/{components/Debug → debug}/UIReferenceView.d.ts +0 -0
  172. /package/dist/{components/Debug → debug}/UIStyleGuide.d.ts +0 -0
  173. /package/dist/{components/Debug → debug}/collection-views/CardViewDemo.d.ts +0 -0
  174. /package/dist/{components/Debug → debug}/collection-views/CollectionTableDemo.d.ts +0 -0
  175. /package/dist/{components/Debug → debug}/collection-views/KanbanBoardDemo.d.ts +0 -0
  176. /package/dist/{components/Debug → debug}/collection-views/index.d.ts +0 -0
  177. /package/dist/{components/Debug → debug}/collection-views/sample_data.d.ts +0 -0
  178. /package/dist/{components/Debug → debug}/crm-dashboard/CalendarWidget.d.ts +0 -0
  179. /package/dist/{components/Debug → debug}/crm-dashboard/CrmDashboardDemo.d.ts +0 -0
  180. /package/dist/{components/Debug → debug}/crm-dashboard/DashboardMetrics.d.ts +0 -0
  181. /package/dist/{components/Debug → debug}/crm-dashboard/PipelineOverview.d.ts +0 -0
  182. /package/dist/{components/Debug → debug}/crm-dashboard/RecentActivity.d.ts +0 -0
  183. /package/dist/{components/Debug → debug}/crm-dashboard/TaskFilters.d.ts +0 -0
  184. /package/dist/{components/Debug → debug}/crm-dashboard/TaskTable.d.ts +0 -0
  185. /package/dist/{components/Debug → debug}/crm-dashboard/TasksView.d.ts +0 -0
@@ -1,7 +0,0 @@
1
- export const STUDIO_NAVIGATION_GROUPS = [
2
- "Database",
3
- "Compute",
4
- "API",
5
- "Storage",
6
- "Access Control"
7
- ];
@@ -1,66 +0,0 @@
1
- import { FormexController } from "@rebasepro/forms";
2
-
3
- export function createFormexStub<T extends object>(values: T): FormexController<T> {
4
- const errorMessage = "You are in a read-only context. You cannot modify the formex controller.";
5
-
6
- return {
7
- debugId: "",
8
- values,
9
- initialValues: values,
10
- touched: {} as Record<string, boolean>,
11
- dirty: false,
12
- errors: {} as Record<string, string>,
13
- submitCount: 0,
14
- isSubmitting: false,
15
- isValidating: false,
16
- version: 0,
17
- canUndo: false,
18
- canRedo: false,
19
-
20
- setValues: () => {
21
- throw new Error(errorMessage);
22
- },
23
- setTouched(touched: Record<string, boolean>): void {
24
- throw new Error(errorMessage);
25
- },
26
- setFieldValue: () => {
27
- throw new Error(errorMessage);
28
- },
29
- setFieldTouched: () => {
30
- throw new Error(errorMessage);
31
- },
32
- setDirty: () => {
33
- throw new Error(errorMessage);
34
- },
35
- setSubmitCount: () => {
36
- throw new Error(errorMessage);
37
- },
38
- setFieldError: () => {
39
- throw new Error(errorMessage);
40
- },
41
- handleChange: () => {
42
- throw new Error(errorMessage);
43
- },
44
- handleBlur: () => {
45
- throw new Error(errorMessage);
46
- },
47
- handleSubmit: () => {
48
- throw new Error(errorMessage);
49
- },
50
- validate: () => {
51
- throw new Error(errorMessage);
52
- },
53
- resetForm: () => {
54
- throw new Error(errorMessage);
55
- },
56
- setSubmitting: () => {
57
- throw new Error(errorMessage);
58
- },
59
- undo: () => {
60
- throw new Error(errorMessage);
61
- },
62
- redo: () => {
63
- throw new Error(errorMessage);
64
- }
65
- };
66
- }
@@ -1,242 +0,0 @@
1
- import { EntityReference, EntityRelation, GeoPoint, Vector } from "@rebasepro/types";
2
- import { isObject, isPlainObject } from "@rebasepro/utils";
3
-
4
- // Define a unique prefix for entity keys in sessionStorage to avoid key collisions
5
- const LOCAL_STORAGE_PREFIX = "entity_cache::";
6
-
7
- /**
8
- * The in-session handoff channel: an edit in flight, parked here by the layout
9
- * that is being replaced and picked up by the one taking over — the split's
10
- * "hide list", full screen's "show list", the side panel's "open full screen".
11
- * A record loaded from it opens *dirty*, because that is what it is for.
12
- *
13
- * Deliberately **not** hydrated from `sessionStorage`, and it is the one thing
14
- * here that isn't. The persisted half of this file is the local-changes backup:
15
- * a draft that outlives a reload, offered back through the banner or applied on
16
- * open, according to the collection's `localChangesBackup`. Loading those
17
- * drafts into this map on startup made every one of them look like a handoff —
18
- * the first visit to the record after a reload silently opened dirty carrying a
19
- * draft the user had walked away from, and the banner that exists to ask about
20
- * it never appeared.
21
- */
22
- const entityCache: Map<string, object> = new Map();
23
-
24
- // Check `sessionStorage` availability once during initialization
25
- const isSessionStorageAvailable = typeof sessionStorage !== "undefined";
26
-
27
- // Define custom replacer for JSON.stringify
28
- function customReplacer(this: Record<string, unknown>, key: string): unknown {
29
-
30
- const value = this[key];
31
-
32
- // Handle Date objects
33
- if (value instanceof Date) {
34
- return {
35
- __type: "Date",
36
- value: value.toISOString()
37
- };
38
- }
39
-
40
- // Handle EntityReference
41
- if (value instanceof EntityReference) {
42
- return {
43
- __type: "EntityReference",
44
- id: value.id,
45
- path: value.path,
46
- driver: value.driver,
47
- databaseId: value.databaseId
48
- };
49
- }
50
-
51
- if (value instanceof EntityRelation) {
52
- return {
53
- __type: "EntityRelation",
54
- id: value.id,
55
- path: value.path,
56
- data: value.data
57
- };
58
- }
59
-
60
- // Handle GeoPoint
61
- if (value instanceof GeoPoint) {
62
- return {
63
- __type: "GeoPoint",
64
- latitude: value.latitude,
65
- longitude: value.longitude
66
- };
67
- }
68
-
69
- // Handle Vector
70
- if (value instanceof Vector) {
71
- return {
72
- __type: "Vector",
73
- value: value.value
74
- };
75
- }
76
-
77
- return value;
78
- }
79
-
80
- // Define custom reviver for JSON.parse
81
- function customReviver(_key: string, value: unknown): unknown {
82
- if (value && typeof value === "object" && "__type" in value) {
83
- const record = value as Record<string, unknown>;
84
- switch (record.__type) {
85
- case "date":
86
- case "Date":
87
- return new Date(record.value as string);
88
- case "reference":
89
- case "EntityReference":
90
- return new EntityReference({
91
- id: record.id as string,
92
- path: record.path as string,
93
- driver: record.driver as string | undefined,
94
- databaseId: record.databaseId as string | undefined
95
- });
96
- case "relation":
97
- case "EntityRelation":
98
- return new EntityRelation(record.id as string, record.path as string, record.data as Record<string, unknown> | undefined);
99
- case "GeoPoint":
100
- return new GeoPoint(record.latitude as number, record.longitude as number);
101
- case "Vector":
102
- return new Vector(record.value as number[]);
103
- default:
104
- return value;
105
- }
106
- }
107
- return value;
108
- }
109
-
110
- /**
111
- * Saves data to the local-changes backup in `sessionStorage`.
112
- *
113
- * The backup only — a draft that survives a reload is not an edit in flight.
114
- * {@link saveEntityToMemoryCache} is the other channel; see {@link entityCache}
115
- * for what separates them.
116
- * @param path - The unique path/key for the data.
117
- * @param data - The data to cache and persist.
118
- */
119
- export function saveEntityToCache(path: string, data: object): void {
120
- // Persist the data individually in sessionStorage
121
- if (isSessionStorageAvailable) {
122
- try {
123
- const key = LOCAL_STORAGE_PREFIX + path;
124
-
125
- const entityString = JSON.stringify(data, customReplacer);
126
- sessionStorage.setItem(key, entityString);
127
- } catch (error) {
128
- console.error(
129
- `Failed to save entity for path "${path}" to sessionStorage:`,
130
- error
131
- );
132
- }
133
- }
134
- }
135
-
136
- /**
137
- * Consumes a handoff. The channel is one-shot: whoever picks an edit up owns it
138
- * from then on, and an edit left behind here is one that reopens a record dirty
139
- * long after the user stopped looking at it.
140
- */
141
- export function removeEntityFromMemoryCache(path: string): void {
142
- entityCache.delete(path);
143
- }
144
-
145
- /**
146
- * Parks an edit in flight for the layout about to take over. See
147
- * {@link entityCache}: this is the handoff, not the backup.
148
- */
149
- export function saveEntityToMemoryCache(path: string, data: object): void {
150
- entityCache.set(path, data);
151
- }
152
-
153
- export function getEntityFromMemoryCache(path: string): object | undefined {
154
- return entityCache.get(path);
155
- }
156
-
157
-
158
- /**
159
- * Retrieves a entity from the local-changes backup in `sessionStorage`.
160
- *
161
- * The backup only — the handoff channel is read through
162
- * {@link getEntityFromMemoryCache}, and the two mean different things to the
163
- * form that receives them.
164
- * @param path - The unique path/key for the entity.
165
- * @returns The cached entity or `undefined` if not found.
166
- */
167
- export function getEntityFromCache(path: string): object | undefined {
168
-
169
- // If not in the cache, attempt to load it from sessionStorage
170
- if (isSessionStorageAvailable) {
171
- try {
172
- const key = LOCAL_STORAGE_PREFIX + path;
173
- const entityString = sessionStorage.getItem(key);
174
- if (entityString) {
175
- const entity: object = JSON.parse(entityString, customReviver);
176
- return entity;
177
- }
178
- } catch (error) {
179
- console.error(
180
- `Failed to load entity for path "${path}" from sessionStorage:`,
181
- error
182
- );
183
- }
184
- }
185
-
186
- // Entity not found
187
- return undefined;
188
- }
189
-
190
- /**
191
- * Removes a entity from both the in-memory cache and `sessionStorage`.
192
- * @param path - The unique path/key for the entity to remove.
193
- */
194
- export function removeEntityFromCache(path: string): void {
195
-
196
- console.debug("Removing entity from cache", path);
197
-
198
- // Remove from the in-memory cache
199
- entityCache.delete(path);
200
-
201
- // Remove from sessionStorage
202
- if (isSessionStorageAvailable) {
203
- try {
204
- const key = LOCAL_STORAGE_PREFIX + path;
205
- sessionStorage.removeItem(key);
206
- } catch (error) {
207
- console.error(
208
- `Failed to remove entity for path "${path}" from sessionStorage:`,
209
- error
210
- );
211
- }
212
- }
213
- }
214
-
215
-
216
- export function flattenKeys(obj: Record<string, unknown> | unknown[], prefix = "", result: string[] = []): string[] {
217
-
218
- if (isObject(obj) || Array.isArray(obj)) {
219
- const plainObject = isPlainObject(obj);
220
- if (!plainObject && prefix) {
221
- result.push(prefix);
222
- } else {
223
- const record = obj as Record<string, unknown>;
224
- for (const key in record) {
225
- if (Object.prototype.hasOwnProperty.call(record, key)) {
226
- const newKey = prefix
227
- ? Array.isArray(obj)
228
- ? `${prefix}[${key}]`
229
- : `${prefix}.${key}`
230
- : key;
231
- const val = record[key];
232
- if (isObject(val) || Array.isArray(val)) {
233
- flattenKeys(val as Record<string, unknown> | unknown[], newKey, result);
234
- } else {
235
- result.push(newKey);
236
- }
237
- }
238
- }
239
- }
240
- }
241
- return result;
242
- }
package/src/util/enums.ts DELETED
@@ -1,34 +0,0 @@
1
- import { EnumValueConfig } from "@rebasepro/types";
2
- import { ChipColorScheme, getColorSchemeForKey, getColorSchemeForSeed } from "@rebasepro/ui";
3
- import { getLabelOrConfigFrom } from "@rebasepro/common";
4
-
5
- export function getColorScheme(enumValues: EnumValueConfig[], key: string | number): ChipColorScheme | undefined {
6
- const labelOrConfig = getLabelOrConfigFrom(enumValues, key);
7
- if (!labelOrConfig?.color)
8
- return getColorSchemeForSeed(key.toString());
9
- if (typeof labelOrConfig === "object" && "color" in labelOrConfig) {
10
- if (typeof labelOrConfig.color === "string")
11
- // Not a raw table lookup: a config naming a colour this build does
12
- // not have still deserves a colour rather than `undefined`.
13
- return getColorSchemeForKey(labelOrConfig.color);
14
- if (typeof labelOrConfig.color === "object")
15
- return labelOrConfig.color;
16
- }
17
- return undefined;
18
- }
19
-
20
- export function isEnumValueDisabled(labelOrConfig?: string | EnumValueConfig) {
21
- return typeof labelOrConfig === "object" && (labelOrConfig as EnumValueConfig).disabled;
22
- }
23
-
24
- export function buildEnumLabel(
25
- labelOrConfig?: string | EnumValueConfig
26
- ): string | undefined {
27
- if (labelOrConfig === undefined)
28
- return undefined;
29
- if (typeof labelOrConfig === "object") {
30
- return labelOrConfig.label;
31
- } else {
32
- return labelOrConfig;
33
- }
34
- }
@@ -1,22 +0,0 @@
1
- const iconSynonyms: Record<string, string> = {};
2
- import { iconKeys } from "@rebasepro/ui";
3
- import Fuse from "fuse.js";
4
-
5
-
6
- const map = iconKeys
7
- .map((importName) => {
8
- const iconSynonym = importName in iconSynonyms ? iconSynonyms[importName] : "";
9
- return {
10
- key: importName,
11
- synonyms: iconSynonym
12
- }
13
- });
14
- export const iconsSearch = new Fuse(map, {
15
- isCaseSensitive: false,
16
- shouldSort: true,
17
- ignoreLocation: true,
18
- distance: 0,
19
- keys: ["key", "synonyms"]
20
- })
21
-
22
-
@@ -1,129 +0,0 @@
1
- import React from "react";
2
- import {
3
- cls,
4
- colorClassesMapping,
5
- coolIconKeys,
6
- IconColor,
7
- iconKeys,
8
- iconSize,
9
- LucideIconByName
10
- } from "@rebasepro/ui";
11
- import { deepEqual as equal } from "fast-equals"
12
- import { hashString, slugify } from "@rebasepro/utils";
13
-
14
- // iconKeys are now PascalCase strings (e.g. "ShoppingCart", "Users")
15
- const iconKeysMap: Record<string, string> = iconKeys.reduce((acc: Record<string, string>, key) => {
16
- // Also add lowercase versions and snake_case versions to support legacy lookups
17
- const lower = key.toLowerCase();
18
- const snake = key.replace(/([A-Z])/g, "_$1").toLowerCase().replace(/^_/, "");
19
- acc[lower] = key;
20
- acc[snake] = key;
21
- acc[key] = key;
22
- return acc;
23
- }, {});
24
-
25
- /**
26
- * Render an icon element from a string key or existing React element.
27
- *
28
- * Whether a key names an icon is decided here, against `iconKeys` — an array
29
- * of strings. The component behind the key is fetched by `LucideIconByName` on
30
- * first use: this used to index lucide's full `icons` map, which is the whole
31
- * library and cannot be tree-shaken.
32
- */
33
- export function getIcon(iconKey?: string | React.ReactNode,
34
- className?: string,
35
- color?: IconColor,
36
- size?: "smallest" | "small" | "medium" | "large" | number): React.ReactElement | undefined {
37
-
38
- if (React.isValidElement(iconKey)) {
39
- return iconKey;
40
- }
41
-
42
- if (!iconKey) return undefined;
43
- if (typeof iconKey === "string") {
44
- const lowerKey = iconKey.toLowerCase();
45
- const slugifiedKey = slugify(iconKey).replace(/-/g, "_");
46
-
47
- const mappedKey = iconKeysMap[iconKey] || iconKeysMap[lowerKey] || iconKeysMap[slugifiedKey];
48
-
49
- if (!mappedKey) {
50
- return undefined;
51
- }
52
-
53
- const sizeInPx = typeof size === "number" ? size : iconSize[size ?? "medium"];
54
- return <LucideIconByName
55
- name={mappedKey}
56
- size={sizeInPx}
57
- className={cls(
58
- color ? colorClassesMapping[color] : "",
59
- "select-none shrink-0",
60
- className
61
- )}
62
- />;
63
- }
64
-
65
- console.warn("Invalid icon key provided:", iconKey);
66
- return undefined;
67
- }
68
-
69
- export type IconViewProps = {
70
- slug: string;
71
- name: string;
72
- singularName?: string;
73
- group?: string;
74
- icon?: string | React.ReactNode;
75
- }
76
-
77
- export const IconForView = React.memo(
78
- function IconForView({
79
- collectionOrView,
80
- className,
81
- color,
82
- size = "medium"
83
- }: {
84
- collectionOrView?: IconViewProps,
85
- color?: IconColor,
86
- className?: string,
87
- size?: "smallest" | "small" | "medium" | "large" | number,
88
- }): React.ReactElement {
89
- if (!collectionOrView) return <></>;
90
- const icon = getIcon(collectionOrView.icon, className, color, size);
91
- if (collectionOrView?.icon && icon)
92
- return icon;
93
-
94
- let pathname = slugify(("singularName" in collectionOrView ? collectionOrView.singularName : undefined) ?? collectionOrView.name).replace(/-/g, "_");
95
-
96
- let key: string | undefined;
97
- if (pathname in iconKeysMap)
98
- key = iconKeysMap[pathname];
99
-
100
- if (!key) {
101
- pathname = slugify(collectionOrView.slug).replace(/-/g, "_");
102
- if (pathname in iconKeysMap)
103
- key = iconKeysMap[pathname];
104
- }
105
-
106
- const iconsCount = coolIconKeys.length;
107
-
108
- if (!key)
109
- key = coolIconKeys[hashString(collectionOrView.slug) % iconsCount];
110
-
111
- const sizeInPx = typeof size === "number" ? size : iconSize[size];
112
- return <LucideIconByName
113
- name={key}
114
- size={sizeInPx}
115
- className={cls(
116
- color ? colorClassesMapping[color] : "",
117
- "select-none shrink-0",
118
- className
119
- )}
120
- />;
121
- }, (prevProps, nextProps) => {
122
- return equal(prevProps.collectionOrView?.icon, nextProps.collectionOrView?.icon) &&
123
- prevProps.collectionOrView?.name === nextProps.collectionOrView?.name &&
124
- prevProps.collectionOrView?.slug === nextProps.collectionOrView?.slug &&
125
- prevProps.collectionOrView?.singularName === nextProps.collectionOrView?.singularName &&
126
- equal(prevProps.color, nextProps.color) &&
127
- prevProps.className === nextProps.className &&
128
- prevProps.size === nextProps.size;
129
- });
package/src/util/index.ts DELETED
@@ -1,13 +0,0 @@
1
-
2
- export * from "./icon_list";
3
-
4
- export * from "./icons";
5
- export * from "./createFormexStub";
6
- export * from "./entity_cache";
7
-
8
- export * from "./useStorageUploadController";
9
-
10
- export * from "./previews";
11
- export * from "./enums";
12
- export * from "./constants";
13
- export * from "./local_storage";
@@ -1,66 +0,0 @@
1
- /**
2
- * localStorage that tolerates not being there.
3
- *
4
- * `typeof window !== "undefined"` was the guard these call sites used, and it
5
- * answers the wrong question: it says "am I in a browser", not "can I read
6
- * storage". Three things make that distinction real rather than theoretical:
7
- *
8
- * - A browser can have storage **disabled**. Safari in private mode, a blocked
9
- * third-party cookie policy, and a sandboxed iframe all give you a `window`
10
- * whose `localStorage` property *throws on access* — a SecurityError raised
11
- * before any method is called, which no amount of null-checking the result
12
- * catches.
13
- * - A test environment can be **half torn down**. jsdom is disposed at the end
14
- * of a file while React is still finishing a concurrent render, so `window`
15
- * survives as a husk and `localStorage.getItem` is no longer a function.
16
- * That is how this was found: `TypeError: localStorage.getItem is not a
17
- * function`, thrown out of a render, failing a suite in which every one of
18
- * 709 tests passed.
19
- * - Server rendering has no `window` at all, which is the only case the old
20
- * guard actually covered.
21
- *
22
- * Reading a UI preference is never worth a crash. Every function here fails to
23
- * `null` / no-op, so a user with storage switched off gets the default
24
- * appearance instead of a blank page.
25
- */
26
-
27
- /** The Storage object, or null when it is absent, blocked, or not usable. */
28
- function usableStorage(): Storage | null {
29
- try {
30
- if (typeof window === "undefined") return null;
31
- const candidate = window.localStorage;
32
- // Not `!= null`: a torn-down jsdom leaves an object behind whose
33
- // methods are gone, which is exactly the shape that threw.
34
- return typeof candidate?.getItem === "function" ? candidate : null;
35
- } catch {
36
- // Access itself throws when storage is blocked by policy.
37
- return null;
38
- }
39
- }
40
-
41
- /** The stored string for `key`, or null if it is unset or unreadable. */
42
- export function readStoredString(key: string): string | null {
43
- try {
44
- return usableStorage()?.getItem(key) ?? null;
45
- } catch {
46
- return null;
47
- }
48
- }
49
-
50
- /** Persist `value` under `key`. A no-op when storage is unavailable. */
51
- export function writeStoredString(key: string, value: string): void {
52
- try {
53
- usableStorage()?.setItem(key, value);
54
- } catch {
55
- // Also the quota path: a full store throws on write but reads fine.
56
- }
57
- }
58
-
59
- /** Remove `key`. A no-op when storage is unavailable. */
60
- export function removeStoredString(key: string): void {
61
- try {
62
- usableStorage()?.removeItem(key);
63
- } catch {
64
- /* nothing to undo */
65
- }
66
- }