@everystack/admin 0.4.6 → 0.4.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/package.json +12 -5
- package/src/adapters/CannotSortError.ts +19 -0
- package/src/adapters/EverystackAdapter.ts +28 -16
- package/src/adapters/types.ts +21 -6
- package/src/components/DateConditionInput.tsx +148 -0
- package/src/components/DateFilterBar.tsx +85 -0
- package/src/components/DateTimeValue.tsx +37 -0
- package/src/components/DeletePreview.tsx +15 -6
- package/src/hooks/useAdminData.ts +44 -3
- package/src/hooks/useDateRangeFilters.ts +47 -0
- package/src/hooks/useViewState.ts +41 -8
- package/src/index.ts +12 -0
- package/src/providers/AdminConfigProvider.tsx +7 -2
- package/src/providers/DataAdapterProvider.tsx +5 -3
- package/src/rpc/list-filter.ts +210 -0
- package/src/rpc/resource-dashboard-rpc.ts +62 -13
- package/src/screens/AdminRouter.tsx +19 -6
- package/src/screens/ResourceCreate.tsx +34 -5
- package/src/screens/ResourceEdit.tsx +34 -5
- package/src/screens/ResourceList.tsx +118 -17
- package/src/screens/ResourceListView.tsx +7 -3
- package/src/screens/ResourceShow.tsx +8 -4
- package/src/types.ts +107 -18
- package/src/utils/date-filter-fields.ts +32 -0
- package/src/utils/date-range.ts +146 -0
- package/src/utils/datetime-submission.ts +25 -0
- package/src/utils/field-sortable.ts +19 -0
- package/src/utils/format-cell-value.ts +23 -10
- package/src/utils/list-query.ts +3 -3
- package/src/utils/resource-query.ts +318 -0
- package/src/utils/validate-config.ts +85 -0
- package/src/utils/view-filters.ts +9 -3
- package/src/utils/wall-clock.ts +2 -1
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* AnalyticsHeader's DashboardFilters and the CRUD table's PostgREST conditions.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
-
import type { ViewParams } from '../hooks/useViewState';
|
|
9
|
+
import type { ViewParams, ViewParamValues } from '../hooks/useViewState';
|
|
10
10
|
import type { DimensionConfig, ResourceDashboardConfig } from '../types';
|
|
11
11
|
import type { DashboardFilters } from '../rpc/resource-dashboard-rpc';
|
|
12
12
|
|
|
@@ -39,7 +39,9 @@ export function filtersToParams(filters: DashboardFilters, dimensions: Dimension
|
|
|
39
39
|
}
|
|
40
40
|
|
|
41
41
|
/** Query params reserved for view state (not column filters). */
|
|
42
|
-
export const RESERVED_PARAMS: ReadonlySet<string> = new Set([
|
|
42
|
+
export const RESERVED_PARAMS: ReadonlySet<string> = new Set([
|
|
43
|
+
'from', 'to', 'sort', 'dir', 'page', 'size', 'q', 'tab',
|
|
44
|
+
]);
|
|
43
45
|
|
|
44
46
|
/**
|
|
45
47
|
* Pass-through column filters: any query param that names a real resource field
|
|
@@ -51,11 +53,15 @@ export function paramsToColumnFilters(
|
|
|
51
53
|
params: ViewParams,
|
|
52
54
|
fieldNames: Set<string>,
|
|
53
55
|
exclude: Set<string> = new Set(),
|
|
56
|
+
paramValues?: ViewParamValues,
|
|
54
57
|
): Record<string, unknown> {
|
|
55
58
|
const f: Record<string, unknown> = {};
|
|
56
59
|
for (const [k, v] of Object.entries(params)) {
|
|
57
60
|
if (RESERVED_PARAMS.has(k) || exclude.has(k)) continue;
|
|
58
|
-
if (fieldNames.has(k)
|
|
61
|
+
if (!fieldNames.has(k)) continue;
|
|
62
|
+
const values = paramValues?.[k] ?? [v];
|
|
63
|
+
if (values.length > 1) f[k] = values;
|
|
64
|
+
else if (values.length === 1 && values[0]) f[k] = values[0];
|
|
59
65
|
}
|
|
60
66
|
return f;
|
|
61
67
|
}
|
package/src/utils/wall-clock.ts
CHANGED
|
@@ -49,7 +49,7 @@ export function wallClockError(field: FieldDefinition, value: unknown): string |
|
|
|
49
49
|
* on a `datetime` field and must be a time zone this engine knows. Config can arrive untyped,
|
|
50
50
|
* so the TypeScript union is not enough on its own.
|
|
51
51
|
*/
|
|
52
|
-
export function
|
|
52
|
+
export function validateWallClockFields(config: AdminConfig): void {
|
|
53
53
|
for (const resource of config.resources ?? []) {
|
|
54
54
|
for (const field of resource.fields ?? []) {
|
|
55
55
|
const raw = field as { name: string; type: unknown; timezone?: unknown; storage?: unknown };
|
|
@@ -58,6 +58,7 @@ export function validateAdminConfig(config: AdminConfig): void {
|
|
|
58
58
|
if (raw.type !== 'datetime') {
|
|
59
59
|
throw new TypeError(`${where}: timezone and storage are only for a datetime field, not type ${JSON.stringify(raw.type)}`);
|
|
60
60
|
}
|
|
61
|
+
if (raw.storage === 'utc' && raw.timezone === undefined) continue;
|
|
61
62
|
if (raw.storage !== 'wall') {
|
|
62
63
|
throw new TypeError(`${where}: a timezone needs storage: 'wall' (a naive timestamp column), got storage ${JSON.stringify(raw.storage)}`);
|
|
63
64
|
}
|