@rebasepro/app 0.17.3 → 0.18.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/README.md +4 -1
- package/dist/components/index.d.ts +0 -3
- package/dist/contexts/AuthControllerContext.d.ts +2 -1
- package/dist/contexts/CustomizationControllerContext.d.ts +2 -1
- package/dist/contexts/DialogsProvider.d.ts +2 -1
- package/dist/contexts/RebaseDataContext.d.ts +10 -1
- package/dist/contexts/StorageSourceContext.d.ts +11 -1
- package/dist/core/RebaseProps.d.ts +2 -12
- package/dist/debug/index.d.ts +19 -0
- package/dist/debug.js +3631 -0
- package/dist/hooks/data/delete.d.ts +16 -7
- package/dist/hooks/data/save.d.ts +18 -4
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/useAdminModeController.d.ts +5 -4
- package/dist/hooks/useNavigationGroupLabel.d.ts +17 -0
- package/dist/hooks/useStudioBridge.d.ts +33 -0
- package/dist/index.es.js +2599 -6980
- package/dist/index.es.js.map +1 -1
- package/dist/vitePlugin.d.ts +22 -0
- package/dist/vitePlugin.js +40 -1
- package/package.json +42 -31
- package/src/auth/api.ts +0 -134
- package/src/auth/index.ts +0 -26
- package/src/auth/types.ts +0 -115
- package/src/auth/useRebaseAuthController.ts +0 -345
- package/src/collections/collection_view_config.ts +0 -76
- package/src/collections/entity-display-cache.ts +0 -195
- package/src/collections/entity-display.ts +0 -77
- package/src/collections/entity_image_preview.ts +0 -61
- package/src/collections/filter-operator-resolution.ts +0 -119
- package/src/collections/form-layout.ts +0 -394
- package/src/collections/index.ts +0 -13
- package/src/collections/navigation_from_path.ts +0 -123
- package/src/collections/navigation_utils.ts +0 -171
- package/src/collections/parent_references_from_path.ts +0 -59
- package/src/collections/property-path.ts +0 -30
- package/src/collections/property_presentation.ts +0 -264
- package/src/collections/summary-property.ts +0 -114
- package/src/collections/title-property.ts +0 -312
- package/src/components/AIIcon.tsx +0 -47
- package/src/components/AuthSimulationMenu.tsx +0 -0
- package/src/components/ConfirmationDialog.tsx +0 -48
- package/src/components/Debug/UIReferenceView.tsx +0 -1053
- package/src/components/Debug/UIStyleGuide.tsx +0 -159
- package/src/components/Debug/collection-views/CardViewDemo.tsx +0 -87
- package/src/components/Debug/collection-views/CollectionTableDemo.tsx +0 -107
- package/src/components/Debug/collection-views/KanbanBoardDemo.tsx +0 -89
- package/src/components/Debug/collection-views/index.ts +0 -3
- package/src/components/Debug/collection-views/sample_data.ts +0 -44
- package/src/components/Debug/crm-dashboard/CalendarWidget.tsx +0 -387
- package/src/components/Debug/crm-dashboard/CrmDashboardDemo.tsx +0 -1100
- package/src/components/Debug/crm-dashboard/DashboardMetrics.tsx +0 -131
- package/src/components/Debug/crm-dashboard/PipelineOverview.tsx +0 -288
- package/src/components/Debug/crm-dashboard/RecentActivity.tsx +0 -213
- package/src/components/Debug/crm-dashboard/TaskFilters.tsx +0 -182
- package/src/components/Debug/crm-dashboard/TaskTable.tsx +0 -425
- package/src/components/Debug/crm-dashboard/TasksView.tsx +0 -234
- package/src/components/ErrorTooltip.tsx +0 -12
- package/src/components/ErrorView.tsx +0 -94
- package/src/components/LanguageToggle.tsx +0 -59
- package/src/components/LoginView/LoginView.tsx +0 -1235
- package/src/components/LoginView/index.ts +0 -2
- package/src/components/LoginView/oauth-redirect-flow.ts +0 -184
- package/src/components/NotFoundPage.tsx +0 -27
- package/src/components/RebaseAuth.tsx +0 -27
- package/src/components/RebaseLogo.tsx +0 -88
- package/src/components/SchemaDriftBanner.tsx +0 -102
- package/src/components/UnsavedChangesDialog.tsx +0 -46
- package/src/components/UserDisplay.tsx +0 -54
- package/src/components/UserSelectPopover.tsx +0 -399
- package/src/components/UserSettingsView.tsx +0 -318
- package/src/components/common/index.ts +0 -6
- package/src/components/common/table_height.tsx +0 -21
- package/src/components/common/types.tsx +0 -66
- package/src/components/common/useColumnsIds.tsx +0 -261
- package/src/components/common/useDataTableController.tsx +0 -571
- package/src/components/common/useDebouncedData.ts +0 -49
- package/src/components/common/useScrollRestoration.tsx +0 -68
- package/src/components/index.tsx +0 -26
- package/src/contexts/AdminModeController.tsx +0 -11
- package/src/contexts/AnalyticsContext.tsx +0 -4
- package/src/contexts/AuthControllerContext.tsx +0 -4
- package/src/contexts/CollectionResolverContext.tsx +0 -24
- package/src/contexts/CollectionScopeContext.tsx +0 -68
- package/src/contexts/ComponentOverrideContext.tsx +0 -81
- package/src/contexts/CustomizationControllerContext.tsx +0 -4
- package/src/contexts/DataDriverContext.tsx +0 -4
- package/src/contexts/DataSourcesContext.tsx +0 -36
- package/src/contexts/DatabaseAdminContext.tsx +0 -4
- package/src/contexts/DialogsProvider.tsx +0 -56
- package/src/contexts/EffectiveRoleController.tsx +0 -12
- package/src/contexts/ModeController.tsx +0 -11
- package/src/contexts/RebaseClientInstanceContext.tsx +0 -7
- package/src/contexts/RebaseDataContext.tsx +0 -4
- package/src/contexts/SnackbarProvider.tsx +0 -15
- package/src/contexts/StorageSourceContext.tsx +0 -4
- package/src/contexts/StorageSourcesContext.tsx +0 -30
- package/src/contexts/UserConfigurationPersistenceContext.tsx +0 -4
- package/src/contexts/index.ts +0 -18
- package/src/core/PluginLifecycleManager.tsx +0 -96
- package/src/core/PluginProviderStack.tsx +0 -40
- package/src/core/Rebase.tsx +0 -488
- package/src/core/RebaseProps.tsx +0 -333
- package/src/core/RebaseRouter.tsx +0 -18
- package/src/core/RebaseRoutes.tsx +0 -24
- package/src/core/index.tsx +0 -5
- package/src/hooks/ApiConfigContext.tsx +0 -83
- package/src/hooks/data/collectionQuery.ts +0 -55
- package/src/hooks/data/delete.ts +0 -56
- package/src/hooks/data/save.ts +0 -78
- package/src/hooks/data/useCollection.tsx +0 -183
- package/src/hooks/data/useData.tsx +0 -18
- package/src/hooks/data/useDataOrder.ts +0 -26
- package/src/hooks/data/useFetch.tsx +0 -156
- package/src/hooks/data/useRelationSelector.tsx +0 -280
- package/src/hooks/index.tsx +0 -45
- package/src/hooks/useAdminModeController.tsx +0 -23
- package/src/hooks/useAnalyticsController.tsx +0 -8
- package/src/hooks/useAuthController.tsx +0 -15
- package/src/hooks/useAuthSubscription.ts +0 -130
- package/src/hooks/useBackendStorageSource.ts +0 -295
- package/src/hooks/useBridgeRegistration.tsx +0 -32
- package/src/hooks/useBrowserTitleAndIcon.tsx +0 -23
- package/src/hooks/useBuildAdminModeController.tsx +0 -29
- package/src/hooks/useBuildEffectiveRoleController.tsx +0 -30
- package/src/hooks/useBuildLocalConfigurationPersistence.tsx +0 -83
- package/src/hooks/useBuildModeController.tsx +0 -73
- package/src/hooks/useClipboard.tsx +0 -158
- package/src/hooks/useCollapsedGroups.ts +0 -116
- package/src/hooks/useComponentOverride.tsx +0 -59
- package/src/hooks/useCustomizationController.tsx +0 -14
- package/src/hooks/useDialogsController.tsx +0 -15
- package/src/hooks/useEffectiveRoleController.tsx +0 -10
- package/src/hooks/useLargeLayout.tsx +0 -65
- package/src/hooks/useModeController.tsx +0 -23
- package/src/hooks/useNavigationBlocker.tsx +0 -108
- package/src/hooks/usePermissions.ts +0 -45
- package/src/hooks/useRebaseClient.tsx +0 -10
- package/src/hooks/useRebaseContext.tsx +0 -84
- package/src/hooks/useRebaseRegistry.tsx +0 -91
- package/src/hooks/useResolvedComponent.tsx +0 -195
- package/src/hooks/useSlot.tsx +0 -64
- package/src/hooks/useSnackbarController.tsx +0 -80
- package/src/hooks/useStorageSource.tsx +0 -11
- package/src/hooks/useStudioBridge.tsx +0 -258
- package/src/hooks/useTranslation.ts +0 -38
- package/src/hooks/useUnsavedChangesDialog.tsx +0 -67
- package/src/hooks/useUserConfigurationPersistence.tsx +0 -11
- package/src/i18n/RebaseI18nProvider.tsx +0 -159
- package/src/index.ts +0 -32
- package/src/internal/common.tsx +0 -28
- package/src/internal/useRestoreScroll.tsx +0 -69
- package/src/locales/de.ts +0 -941
- package/src/locales/en.ts +0 -1021
- package/src/locales/es.ts +0 -962
- package/src/locales/fr.ts +0 -941
- package/src/locales/hi.ts +0 -941
- package/src/locales/it.ts +0 -941
- package/src/locales/pt.ts +0 -949
- package/src/util/constants.ts +0 -7
- package/src/util/createFormexStub.tsx +0 -66
- package/src/util/entity_cache.ts +0 -242
- package/src/util/enums.ts +0 -34
- package/src/util/icon_list.ts +0 -22
- package/src/util/icons.tsx +0 -129
- package/src/util/index.ts +0 -13
- package/src/util/local_storage.ts +0 -66
- package/src/util/previews.ts +0 -127
- package/src/util/useStorageUploadController.tsx +0 -354
- package/src/vitePlugin.ts +0 -215
- /package/dist/{components/Debug → debug}/UIReferenceView.d.ts +0 -0
- /package/dist/{components/Debug → debug}/UIStyleGuide.d.ts +0 -0
- /package/dist/{components/Debug → debug}/collection-views/CardViewDemo.d.ts +0 -0
- /package/dist/{components/Debug → debug}/collection-views/CollectionTableDemo.d.ts +0 -0
- /package/dist/{components/Debug → debug}/collection-views/KanbanBoardDemo.d.ts +0 -0
- /package/dist/{components/Debug → debug}/collection-views/index.d.ts +0 -0
- /package/dist/{components/Debug → debug}/collection-views/sample_data.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/CalendarWidget.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/CrmDashboardDemo.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/DashboardMetrics.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/PipelineOverview.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/RecentActivity.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/TaskFilters.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/TaskTable.d.ts +0 -0
- /package/dist/{components/Debug → debug}/crm-dashboard/TasksView.d.ts +0 -0
package/src/util/constants.ts
DELETED
|
@@ -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
|
-
}
|
package/src/util/entity_cache.ts
DELETED
|
@@ -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
|
-
}
|
package/src/util/icon_list.ts
DELETED
|
@@ -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
|
-
|
package/src/util/icons.tsx
DELETED
|
@@ -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
|
-
}
|