@asteby/metacore-runtime-react 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +31 -0
- package/LICENSE +201 -0
- package/README.md +59 -0
- package/dist/action-modal-dispatcher.d.ts +4 -0
- package/dist/action-modal-dispatcher.d.ts.map +1 -0
- package/dist/action-modal-dispatcher.js +123 -0
- package/dist/addon-loader.d.ts +27 -0
- package/dist/addon-loader.d.ts.map +1 -0
- package/dist/addon-loader.js +73 -0
- package/dist/api-context.d.ts +40 -0
- package/dist/api-context.d.ts.map +1 -0
- package/dist/api-context.js +25 -0
- package/dist/capability-gate.d.ts +29 -0
- package/dist/capability-gate.d.ts.map +1 -0
- package/dist/capability-gate.js +43 -0
- package/dist/dialogs/_primitives.d.ts +29 -0
- package/dist/dialogs/_primitives.d.ts.map +1 -0
- package/dist/dialogs/_primitives.js +35 -0
- package/dist/dialogs/dynamic-record.d.ts +11 -0
- package/dist/dialogs/dynamic-record.d.ts.map +1 -0
- package/dist/dialogs/dynamic-record.js +377 -0
- package/dist/dialogs/export.d.ts +12 -0
- package/dist/dialogs/export.d.ts.map +1 -0
- package/dist/dialogs/export.js +146 -0
- package/dist/dialogs/import.d.ts +11 -0
- package/dist/dialogs/import.d.ts.map +1 -0
- package/dist/dialogs/import.js +128 -0
- package/dist/dynamic-columns-shim.d.ts +25 -0
- package/dist/dynamic-columns-shim.d.ts.map +1 -0
- package/dist/dynamic-columns-shim.js +1 -0
- package/dist/dynamic-form.d.ts +12 -0
- package/dist/dynamic-form.d.ts.map +1 -0
- package/dist/dynamic-form.js +51 -0
- package/dist/dynamic-icon.d.ts +6 -0
- package/dist/dynamic-icon.d.ts.map +1 -0
- package/dist/dynamic-icon.js +11 -0
- package/dist/dynamic-table.d.ts +22 -0
- package/dist/dynamic-table.d.ts.map +1 -0
- package/dist/dynamic-table.js +516 -0
- package/dist/i18n-provider.d.ts +16 -0
- package/dist/i18n-provider.d.ts.map +1 -0
- package/dist/i18n-provider.js +16 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +21 -0
- package/dist/metadata-cache.d.ts +42 -0
- package/dist/metadata-cache.d.ts.map +1 -0
- package/dist/metadata-cache.js +71 -0
- package/dist/navigation-builder.d.ts +34 -0
- package/dist/navigation-builder.d.ts.map +1 -0
- package/dist/navigation-builder.js +45 -0
- package/dist/options-context.d.ts +8 -0
- package/dist/options-context.d.ts.map +1 -0
- package/dist/options-context.js +5 -0
- package/dist/slot.d.ts +32 -0
- package/dist/slot.d.ts.map +1 -0
- package/dist/slot.js +45 -0
- package/dist/types.d.ts +114 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +1 -0
- package/package.json +67 -0
- package/src/action-modal-dispatcher.tsx +275 -0
- package/src/addon-loader.tsx +111 -0
- package/src/api-context.tsx +55 -0
- package/src/capability-gate.tsx +69 -0
- package/src/dialogs/_primitives.tsx +114 -0
- package/src/dialogs/dynamic-record.tsx +770 -0
- package/src/dialogs/export.tsx +339 -0
- package/src/dialogs/import.tsx +404 -0
- package/src/dynamic-columns-shim.ts +36 -0
- package/src/dynamic-form.tsx +108 -0
- package/src/dynamic-icon.tsx +15 -0
- package/src/dynamic-table.tsx +766 -0
- package/src/i18n-provider.tsx +33 -0
- package/src/index.ts +30 -0
- package/src/metadata-cache.ts +103 -0
- package/src/navigation-builder.tsx +77 -0
- package/src/options-context.tsx +11 -0
- package/src/slot.tsx +77 -0
- package/src/types.ts +112 -0
- package/tsconfig.json +16 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Metadata cache — a zustand store that memoizes table/modal metadata
|
|
2
|
+
// responses across dynamic-table mounts. Ported from the ops starter's
|
|
3
|
+
// `@/stores/metadata-cache` so the runtime-react package no longer depends
|
|
4
|
+
// on a host-specific alias.
|
|
5
|
+
//
|
|
6
|
+
// The prefetchAll() method needs an `api` client (axios-like); we keep that
|
|
7
|
+
// as an injectable parameter so the store stays host-agnostic. If a caller
|
|
8
|
+
// never invokes prefetchAll, the `api` dep is not required.
|
|
9
|
+
import { create } from 'zustand';
|
|
10
|
+
import { persist } from 'zustand/middleware';
|
|
11
|
+
export const useMetadataCache = create()(persist((set, get) => ({
|
|
12
|
+
cache: {},
|
|
13
|
+
modalCache: {},
|
|
14
|
+
metadataVersion: '',
|
|
15
|
+
prefetched: false,
|
|
16
|
+
getMetadata: (key) => get().cache[key],
|
|
17
|
+
getModalMetadata: (key) => get().modalCache[key],
|
|
18
|
+
setMetadata: (key, metadata) => {
|
|
19
|
+
set((state) => ({
|
|
20
|
+
cache: { ...state.cache, [key]: metadata },
|
|
21
|
+
}));
|
|
22
|
+
},
|
|
23
|
+
setModalMetadata: (key, metadata) => {
|
|
24
|
+
set((state) => ({
|
|
25
|
+
modalCache: { ...state.modalCache, [key]: metadata },
|
|
26
|
+
}));
|
|
27
|
+
},
|
|
28
|
+
hasMetadata: (key) => key in get().cache,
|
|
29
|
+
hasModalMetadata: (key) => key in get().modalCache,
|
|
30
|
+
prefetchAll: async (api) => {
|
|
31
|
+
if (get().prefetched)
|
|
32
|
+
return;
|
|
33
|
+
try {
|
|
34
|
+
const res = await api.get('/metadata/all');
|
|
35
|
+
const { tables, modals, version } = res.data.data;
|
|
36
|
+
const serverVersion = version || '';
|
|
37
|
+
const localVersion = get().metadataVersion;
|
|
38
|
+
const versionChanged = serverVersion !== localVersion && localVersion !== '';
|
|
39
|
+
const newCache = versionChanged ? {} : { ...get().cache };
|
|
40
|
+
const newModalCache = versionChanged ? {} : { ...get().modalCache };
|
|
41
|
+
if (tables) {
|
|
42
|
+
for (const [key, meta] of Object.entries(tables)) {
|
|
43
|
+
newCache[key] = meta;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (modals) {
|
|
47
|
+
for (const [key, meta] of Object.entries(modals)) {
|
|
48
|
+
newModalCache[key] = meta;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
set({
|
|
52
|
+
cache: newCache,
|
|
53
|
+
modalCache: newModalCache,
|
|
54
|
+
metadataVersion: serverVersion,
|
|
55
|
+
prefetched: true,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Offline or error — keep using cached data.
|
|
60
|
+
set({ prefetched: true });
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
}), {
|
|
64
|
+
name: 'metacore-metadata-cache',
|
|
65
|
+
version: 3,
|
|
66
|
+
partialize: (state) => ({
|
|
67
|
+
cache: state.cache,
|
|
68
|
+
modalCache: state.modalCache,
|
|
69
|
+
metadataVersion: state.metadataVersion,
|
|
70
|
+
}),
|
|
71
|
+
}));
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export interface NavItem {
|
|
2
|
+
key: string;
|
|
3
|
+
label: string;
|
|
4
|
+
icon?: string;
|
|
5
|
+
to?: string;
|
|
6
|
+
/** Sort weight; higher = earlier. Default 0. */
|
|
7
|
+
priority?: number;
|
|
8
|
+
/** Capability required to see this item. */
|
|
9
|
+
requires?: string;
|
|
10
|
+
/** Nested children (rendered as a collapsible section). */
|
|
11
|
+
children?: NavItem[];
|
|
12
|
+
/** Group this item belongs to — items with the same group are clustered. */
|
|
13
|
+
group?: string;
|
|
14
|
+
/** Source addon key (for debugging / telemetry). */
|
|
15
|
+
source?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface AddonNavigationContribution {
|
|
18
|
+
source: string;
|
|
19
|
+
items: NavItem[];
|
|
20
|
+
}
|
|
21
|
+
/** Deep-merge nav trees by `key`. Children are merged recursively; on
|
|
22
|
+
* conflict the higher-priority wins, then the later contribution.
|
|
23
|
+
*/
|
|
24
|
+
export declare function mergeNavigation(base: NavItem[], contributions: AddonNavigationContribution[]): NavItem[];
|
|
25
|
+
export declare function useNavigation(base: NavItem[], contributions: AddonNavigationContribution[]): NavItem[];
|
|
26
|
+
export interface NavigationBuilderProps {
|
|
27
|
+
base: NavItem[];
|
|
28
|
+
contributions: AddonNavigationContribution[];
|
|
29
|
+
render: (items: NavItem[]) => React.ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/** Render-prop component for hosts that want the merge logic but render
|
|
32
|
+
* the sidebar with their own primitives. */
|
|
33
|
+
export declare function NavigationBuilder({ base, contributions, render }: NavigationBuilderProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
//# sourceMappingURL=navigation-builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation-builder.d.ts","sourceRoot":"","sources":["../src/navigation-builder.tsx"],"names":[],"mappings":"AAIA,MAAM,WAAW,OAAO;IACpB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,gDAAgD;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,2DAA2D;IAC3D,QAAQ,CAAC,EAAE,OAAO,EAAE,CAAA;IACpB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,oDAAoD;IACpD,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,MAAM,WAAW,2BAA2B;IACxC,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,OAAO,EAAE,CAAA;CACnB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,2BAA2B,EAAE,GAAG,OAAO,EAAE,CA8BxG;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,aAAa,EAAE,2BAA2B,EAAE,GAAG,OAAO,EAAE,CAEtG;AAED,MAAM,WAAW,sBAAsB;IACnC,IAAI,EAAE,OAAO,EAAE,CAAA;IACf,aAAa,EAAE,2BAA2B,EAAE,CAAA;IAC5C,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,KAAK,CAAC,SAAS,CAAA;CAChD;AAED;6CAC6C;AAC7C,wBAAgB,iBAAiB,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,EAAE,EAAE,sBAAsB,2CAGxF"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// NavigationBuilder — merges a host's base sidebar with `manifest.navigation`
|
|
3
|
+
// contributions from every loaded addon. Pure function + a React hook.
|
|
4
|
+
import { useMemo } from 'react';
|
|
5
|
+
/** Deep-merge nav trees by `key`. Children are merged recursively; on
|
|
6
|
+
* conflict the higher-priority wins, then the later contribution.
|
|
7
|
+
*/
|
|
8
|
+
export function mergeNavigation(base, contributions) {
|
|
9
|
+
const byKey = new Map();
|
|
10
|
+
const order = [];
|
|
11
|
+
const absorb = (items, source) => {
|
|
12
|
+
for (const raw of items) {
|
|
13
|
+
const item = { ...raw, source: raw.source ?? source };
|
|
14
|
+
const existing = byKey.get(item.key);
|
|
15
|
+
if (!existing) {
|
|
16
|
+
byKey.set(item.key, item);
|
|
17
|
+
order.push(item.key);
|
|
18
|
+
continue;
|
|
19
|
+
}
|
|
20
|
+
const a = existing.priority ?? 0;
|
|
21
|
+
const b = item.priority ?? 0;
|
|
22
|
+
const winner = b >= a ? item : existing;
|
|
23
|
+
const loser = b >= a ? existing : item;
|
|
24
|
+
const mergedChildren = (winner.children || loser.children)
|
|
25
|
+
? mergeNavigation(winner.children ?? [], [{ source: winner.source ?? '', items: loser.children ?? [] }])
|
|
26
|
+
: undefined;
|
|
27
|
+
byKey.set(item.key, { ...winner, children: mergedChildren });
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
absorb(base, 'host');
|
|
31
|
+
for (const c of contributions)
|
|
32
|
+
absorb(c.items, c.source);
|
|
33
|
+
return order
|
|
34
|
+
.map(k => byKey.get(k))
|
|
35
|
+
.sort((a, b) => (b.priority ?? 0) - (a.priority ?? 0));
|
|
36
|
+
}
|
|
37
|
+
export function useNavigation(base, contributions) {
|
|
38
|
+
return useMemo(() => mergeNavigation(base, contributions), [base, contributions]);
|
|
39
|
+
}
|
|
40
|
+
/** Render-prop component for hosts that want the merge logic but render
|
|
41
|
+
* the sidebar with their own primitives. */
|
|
42
|
+
export function NavigationBuilder({ base, contributions, render }) {
|
|
43
|
+
const items = useNavigation(base, contributions);
|
|
44
|
+
return _jsx(_Fragment, { children: render(items) });
|
|
45
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
interface OptionsContextValue {
|
|
3
|
+
optionsMap: Map<string, any[]>;
|
|
4
|
+
}
|
|
5
|
+
export declare const OptionsContext: React.Context<OptionsContextValue>;
|
|
6
|
+
export declare const useOptions: () => OptionsContextValue;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=options-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"options-context.d.ts","sourceRoot":"","sources":["../src/options-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,UAAU,mBAAmB;IACzB,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,CAAA;CACjC;AAED,eAAO,MAAM,cAAc,oCAEzB,CAAA;AAEF,eAAO,MAAM,UAAU,2BAAyC,CAAA"}
|
package/dist/slot.d.ts
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
export type SlotComponent<P = any> = React.ComponentType<P>;
|
|
3
|
+
interface SlotEntry {
|
|
4
|
+
id: string;
|
|
5
|
+
component: SlotComponent;
|
|
6
|
+
priority: number;
|
|
7
|
+
source?: string;
|
|
8
|
+
}
|
|
9
|
+
type Listener = () => void;
|
|
10
|
+
declare class SlotRegistryImpl {
|
|
11
|
+
private slots;
|
|
12
|
+
private listeners;
|
|
13
|
+
register(slotId: string, component: SlotComponent, opts?: {
|
|
14
|
+
priority?: number;
|
|
15
|
+
source?: string;
|
|
16
|
+
}): () => void;
|
|
17
|
+
get(slotId: string): SlotEntry[];
|
|
18
|
+
subscribe(listener: Listener): () => void;
|
|
19
|
+
private emit;
|
|
20
|
+
}
|
|
21
|
+
export declare const slotRegistry: SlotRegistryImpl;
|
|
22
|
+
export interface SlotProps {
|
|
23
|
+
/** Slot id. */
|
|
24
|
+
name: string;
|
|
25
|
+
/** Props forwarded to each contribution component. */
|
|
26
|
+
props?: Record<string, any>;
|
|
27
|
+
/** Fallback element shown when no contribution is registered. */
|
|
28
|
+
fallback?: React.ReactNode;
|
|
29
|
+
}
|
|
30
|
+
export declare function Slot({ name, props, fallback }: SlotProps): import("react/jsx-runtime").JSX.Element;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=slot.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slot.d.ts","sourceRoot":"","sources":["../src/slot.tsx"],"names":[],"mappings":"AAGA,OAAO,KAA+B,MAAM,OAAO,CAAA;AAEnD,MAAM,MAAM,aAAa,CAAC,CAAC,GAAG,GAAG,IAAI,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,CAAA;AAE3D,UAAU,SAAS;IACf,EAAE,EAAE,MAAM,CAAA;IACV,SAAS,EAAE,aAAa,CAAA;IACxB,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,KAAK,QAAQ,GAAG,MAAM,IAAI,CAAA;AAE1B,cAAM,gBAAgB;IAClB,OAAO,CAAC,KAAK,CAAiC;IAC9C,OAAO,CAAC,SAAS,CAAsB;IAEvC,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,aAAa,EAAE,IAAI,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,MAAM,IAAI;IAkB7G,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,EAAE;IAIhC,SAAS,CAAC,QAAQ,EAAE,QAAQ,GAAG,MAAM,IAAI;IAKzC,OAAO,CAAC,IAAI;CACf;AAED,eAAO,MAAM,YAAY,kBAAyB,CAAA;AAElD,MAAM,WAAW,SAAS;IACtB,eAAe;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAC3B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;CAC7B;AAED,wBAAgB,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,QAAe,EAAE,EAAE,SAAS,2CAe/D"}
|
package/dist/slot.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
// Slot / SlotRegistry — named extension points the host renders and addons
|
|
3
|
+
// contribute to at register() time. Keyed by a slot id (e.g. "dashboard.widgets",
|
|
4
|
+
// "invoice.footer"). Each contribution is an arbitrary React element factory.
|
|
5
|
+
import { useSyncExternalStore } from 'react';
|
|
6
|
+
class SlotRegistryImpl {
|
|
7
|
+
slots = new Map();
|
|
8
|
+
listeners = new Set();
|
|
9
|
+
register(slotId, component, opts) {
|
|
10
|
+
const entry = { id: slotId, component, priority: opts?.priority ?? 0, source: opts?.source };
|
|
11
|
+
const list = this.slots.get(slotId) ?? [];
|
|
12
|
+
list.push(entry);
|
|
13
|
+
list.sort((a, b) => b.priority - a.priority);
|
|
14
|
+
this.slots.set(slotId, list);
|
|
15
|
+
this.emit();
|
|
16
|
+
return () => {
|
|
17
|
+
const arr = this.slots.get(slotId);
|
|
18
|
+
if (!arr)
|
|
19
|
+
return;
|
|
20
|
+
const idx = arr.indexOf(entry);
|
|
21
|
+
if (idx >= 0) {
|
|
22
|
+
arr.splice(idx, 1);
|
|
23
|
+
this.emit();
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
get(slotId) {
|
|
28
|
+
return this.slots.get(slotId) ?? [];
|
|
29
|
+
}
|
|
30
|
+
subscribe(listener) {
|
|
31
|
+
this.listeners.add(listener);
|
|
32
|
+
return () => { this.listeners.delete(listener); };
|
|
33
|
+
}
|
|
34
|
+
emit() { this.listeners.forEach(l => l()); }
|
|
35
|
+
}
|
|
36
|
+
export const slotRegistry = new SlotRegistryImpl();
|
|
37
|
+
export function Slot({ name, props, fallback = null }) {
|
|
38
|
+
const entries = useSyncExternalStore((cb) => slotRegistry.subscribe(cb), () => slotRegistry.get(name), () => slotRegistry.get(name));
|
|
39
|
+
if (entries.length === 0)
|
|
40
|
+
return _jsx(_Fragment, { children: fallback });
|
|
41
|
+
return (_jsx(_Fragment, { children: entries.map((entry, i) => {
|
|
42
|
+
const C = entry.component;
|
|
43
|
+
return _jsx(C, { ...(props ?? {}) }, `${entry.source ?? 'anon'}-${i}`);
|
|
44
|
+
}) }));
|
|
45
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
export interface TableMetadata {
|
|
2
|
+
title: string;
|
|
3
|
+
endpoint: string;
|
|
4
|
+
columns: ColumnDefinition[];
|
|
5
|
+
actions: ActionDefinition[];
|
|
6
|
+
filters?: FilterDefinition[];
|
|
7
|
+
perPageOptions: number[];
|
|
8
|
+
defaultPerPage: number;
|
|
9
|
+
searchPlaceholder: string;
|
|
10
|
+
enableCRUDActions: boolean;
|
|
11
|
+
hasActions: boolean;
|
|
12
|
+
canExport?: boolean;
|
|
13
|
+
canImport?: boolean;
|
|
14
|
+
canCreate?: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface FilterDefinition {
|
|
17
|
+
key: string;
|
|
18
|
+
label: string;
|
|
19
|
+
type: 'select' | 'boolean' | 'date_range' | 'number_range' | 'text';
|
|
20
|
+
column: string;
|
|
21
|
+
options?: {
|
|
22
|
+
value: string | boolean;
|
|
23
|
+
label: string;
|
|
24
|
+
icon?: string;
|
|
25
|
+
color?: string;
|
|
26
|
+
}[];
|
|
27
|
+
searchEndpoint?: string;
|
|
28
|
+
}
|
|
29
|
+
export interface ColumnDefinition {
|
|
30
|
+
key: string;
|
|
31
|
+
label: string;
|
|
32
|
+
type: 'text' | 'number' | 'date' | 'select' | 'search' | 'relation-badge-list' | 'avatar' | 'boolean' | 'phone' | 'media-gallery' | 'image';
|
|
33
|
+
sortable: boolean;
|
|
34
|
+
filterable: boolean;
|
|
35
|
+
hidden?: boolean;
|
|
36
|
+
styleConfig?: Record<string, any>;
|
|
37
|
+
tooltip?: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
cellStyle?: string;
|
|
40
|
+
searchEndpoint?: string;
|
|
41
|
+
filterField?: string;
|
|
42
|
+
basePath?: string;
|
|
43
|
+
displayField?: string;
|
|
44
|
+
iconField?: string;
|
|
45
|
+
relationPath?: string;
|
|
46
|
+
useOptions?: boolean;
|
|
47
|
+
options?: {
|
|
48
|
+
value: string;
|
|
49
|
+
label: string;
|
|
50
|
+
icon?: string;
|
|
51
|
+
color?: string;
|
|
52
|
+
}[];
|
|
53
|
+
}
|
|
54
|
+
export interface ActionCondition {
|
|
55
|
+
field: string;
|
|
56
|
+
operator: 'eq' | 'neq' | 'in' | 'not_in';
|
|
57
|
+
value: string | string[];
|
|
58
|
+
}
|
|
59
|
+
export interface ActionFieldDef {
|
|
60
|
+
key: string;
|
|
61
|
+
label: string;
|
|
62
|
+
type: string;
|
|
63
|
+
required?: boolean;
|
|
64
|
+
options?: {
|
|
65
|
+
value: string;
|
|
66
|
+
label: string;
|
|
67
|
+
}[];
|
|
68
|
+
defaultValue?: any;
|
|
69
|
+
placeholder?: string;
|
|
70
|
+
searchEndpoint?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface ActionDefinition {
|
|
73
|
+
key: string;
|
|
74
|
+
name: string;
|
|
75
|
+
label: string;
|
|
76
|
+
icon: string;
|
|
77
|
+
class: string;
|
|
78
|
+
color?: string;
|
|
79
|
+
type: 'view' | 'edit' | 'delete' | 'custom' | 'link';
|
|
80
|
+
linkUrl?: string;
|
|
81
|
+
condition?: ActionCondition;
|
|
82
|
+
confirm?: boolean;
|
|
83
|
+
confirmMessage?: string;
|
|
84
|
+
fields?: ActionFieldDef[];
|
|
85
|
+
requiresState?: string[];
|
|
86
|
+
executable?: boolean;
|
|
87
|
+
}
|
|
88
|
+
export interface ApiResponse<T> {
|
|
89
|
+
success: boolean;
|
|
90
|
+
data: T;
|
|
91
|
+
meta?: PaginationMeta;
|
|
92
|
+
filters?: Record<string, any>;
|
|
93
|
+
message?: string;
|
|
94
|
+
}
|
|
95
|
+
export interface PaginationMeta {
|
|
96
|
+
current_page: number;
|
|
97
|
+
from: number;
|
|
98
|
+
last_page: number;
|
|
99
|
+
per_page: number;
|
|
100
|
+
to: number;
|
|
101
|
+
total: number;
|
|
102
|
+
}
|
|
103
|
+
export interface ActionMetadata {
|
|
104
|
+
key: string;
|
|
105
|
+
label: string;
|
|
106
|
+
icon: string;
|
|
107
|
+
color?: string;
|
|
108
|
+
confirm?: boolean;
|
|
109
|
+
confirmMessage?: string;
|
|
110
|
+
fields?: ActionFieldDef[];
|
|
111
|
+
requiresState?: string[];
|
|
112
|
+
executable?: boolean;
|
|
113
|
+
}
|
|
114
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@asteby/metacore-runtime-react",
|
|
3
|
+
"version": "4.0.0",
|
|
4
|
+
"description": "React runtime for metacore hosts — renders addon contributions dynamically",
|
|
5
|
+
"repository": {
|
|
6
|
+
"type": "git",
|
|
7
|
+
"url": "https://github.com/asteby/metacore-sdk",
|
|
8
|
+
"directory": "packages/runtime-react"
|
|
9
|
+
},
|
|
10
|
+
"type": "module",
|
|
11
|
+
"main": "./dist/index.js",
|
|
12
|
+
"types": "./dist/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"import": "./dist/index.js"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"react": ">=18",
|
|
21
|
+
"react-dom": ">=18",
|
|
22
|
+
"@tanstack/react-query": ">=5",
|
|
23
|
+
"@tanstack/react-table": ">=8",
|
|
24
|
+
"@tanstack/react-router": ">=1.100",
|
|
25
|
+
"i18next": ">=23",
|
|
26
|
+
"react-i18next": ">=13",
|
|
27
|
+
"sonner": ">=1.7",
|
|
28
|
+
"zustand": ">=5",
|
|
29
|
+
"lucide-react": ">=0.460",
|
|
30
|
+
"date-fns": ">=3",
|
|
31
|
+
"react-day-picker": ">=8",
|
|
32
|
+
"@asteby/metacore-sdk": "^2.2.0",
|
|
33
|
+
"@asteby/metacore-ui": "^0.3.0"
|
|
34
|
+
},
|
|
35
|
+
"peerDependenciesMeta": {
|
|
36
|
+
"@tanstack/react-router": {
|
|
37
|
+
"optional": true
|
|
38
|
+
},
|
|
39
|
+
"react-day-picker": {
|
|
40
|
+
"optional": true
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"devDependencies": {
|
|
44
|
+
"@tanstack/react-query": "^5.95.0",
|
|
45
|
+
"@tanstack/react-router": "^1.168.0",
|
|
46
|
+
"@tanstack/react-table": "^8.20.0",
|
|
47
|
+
"@types/react": "^19.0.0",
|
|
48
|
+
"date-fns": "^4.1.0",
|
|
49
|
+
"i18next": "^23.16.0",
|
|
50
|
+
"lucide-react": "^0.460.0",
|
|
51
|
+
"react": "^19.2.4",
|
|
52
|
+
"react-day-picker": "^8.10.1",
|
|
53
|
+
"react-dom": "^19.2.4",
|
|
54
|
+
"react-i18next": "^15.1.0",
|
|
55
|
+
"sonner": "^1.7.0",
|
|
56
|
+
"typescript": "^5.6.0",
|
|
57
|
+
"zustand": "^5.0.0",
|
|
58
|
+
"@asteby/metacore-sdk": "2.2.0",
|
|
59
|
+
"@asteby/metacore-ui": "0.3.0"
|
|
60
|
+
},
|
|
61
|
+
"scripts": {
|
|
62
|
+
"build": "tsc -p tsconfig.json",
|
|
63
|
+
"dev": "tsc -w -p tsconfig.json",
|
|
64
|
+
"typecheck": "tsc -p tsconfig.json --noEmit",
|
|
65
|
+
"clean": "rm -rf dist"
|
|
66
|
+
}
|
|
67
|
+
}
|