@contember/bindx-react 0.1.28 → 0.1.30
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/dist/hooks/BackendAdapterContext.d.ts +8 -0
- package/dist/hooks/BackendAdapterContext.d.ts.map +1 -1
- package/dist/hooks/ContemberBindxProvider.d.ts.map +1 -1
- package/dist/hooks/index.d.ts +3 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/useNotifications.d.ts +15 -0
- package/dist/hooks/useNotifications.d.ts.map +1 -0
- package/dist/hooks/usePersistWithFeedback.d.ts +32 -0
- package/dist/hooks/usePersistWithFeedback.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/package.json +3 -3
- package/src/hooks/BackendAdapterContext.tsx +16 -0
- package/src/hooks/ContemberBindxProvider.tsx +2 -1
- package/src/hooks/index.ts +12 -0
- package/src/hooks/useNotifications.ts +40 -0
- package/src/hooks/usePersistWithFeedback.ts +106 -0
- package/src/index.ts +8 -0
- package/src/jsx/collectorProxy.ts +1 -0
|
@@ -5,6 +5,7 @@ import { ActionDispatcher } from '@contember/bindx';
|
|
|
5
5
|
import { BatchPersister } from '@contember/bindx';
|
|
6
6
|
import { SchemaRegistry } from '@contember/bindx';
|
|
7
7
|
import { UndoManager } from '@contember/bindx';
|
|
8
|
+
import { NotificationStore } from '@contember/bindx';
|
|
8
9
|
import { QueryBatcher } from '../batching/QueryBatcher.js';
|
|
9
10
|
/**
|
|
10
11
|
* Minimal GraphQL client interface exposed through bindx context.
|
|
@@ -35,6 +36,8 @@ export interface BindxContextValue {
|
|
|
35
36
|
undoManager: UndoManager | null;
|
|
36
37
|
/** GraphQL client (available when using ContemberBindxProvider) */
|
|
37
38
|
graphQlClient: BindxGraphQlClient | null;
|
|
39
|
+
/** Notification store for user-facing feedback (toasts) */
|
|
40
|
+
notificationStore: NotificationStore;
|
|
38
41
|
/** Whether debug logging is enabled */
|
|
39
42
|
debug: boolean;
|
|
40
43
|
}
|
|
@@ -118,4 +121,9 @@ export declare function useBindxContext(): BindxContextValue;
|
|
|
118
121
|
* Must be used within a BindxProvider.
|
|
119
122
|
*/
|
|
120
123
|
export declare function useQueryBatcher(): QueryBatcher;
|
|
124
|
+
/**
|
|
125
|
+
* Hook to access the notification store.
|
|
126
|
+
* Must be used within a BindxProvider.
|
|
127
|
+
*/
|
|
128
|
+
export declare function useNotificationStore(): NotificationStore;
|
|
121
129
|
//# sourceMappingURL=BackendAdapterContext.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"BackendAdapterContext.d.ts","sourceRoot":"","sources":["../../src/hooks/BackendAdapterContext.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AAC1E,OAAO,KAAK,EAAE,cAAc,EAAE,qBAAqB,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC9H,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AACjD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAA;AAE1D;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IAClC,OAAO,CAAC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAA;CAClG;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IACjC,oDAAoD;IACpD,OAAO,EAAE,cAAc,CAAA;IACvB,wEAAwE;IACxE,OAAO,EAAE,YAAY,CAAA;IACrB,+BAA+B;IAC/B,KAAK,EAAE,aAAa,CAAA;IACpB,sCAAsC;IACtC,UAAU,EAAE,gBAAgB,CAAA;IAC5B,mDAAmD;IACnD,cAAc,EAAE,cAAc,CAAA;IAC9B,0CAA0C;IAC1C,MAAM,EAAE,cAAc,CAAA;IACtB,gCAAgC;IAChC,WAAW,EAAE,WAAW,GAAG,IAAI,CAAA;IAC/B,mEAAmE;IACnE,aAAa,EAAE,kBAAkB,GAAG,IAAI,CAAA;IACxC,uCAAuC;IACvC,KAAK,EAAE,OAAO,CAAA;CACd;AAED,eAAO,MAAM,YAAY,mDAAgD,CAAA;AAEzE;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAClC,+DAA+D;IAC/D,OAAO,EAAE,cAAc,CAAA;IACvB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,oEAAoE;IACpE,MAAM,EAAE,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IAChD,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,qBAAqB,CAAA;IACzC,qCAAqC;IACrC,UAAU,CAAC,EAAE,OAAO,CAAA;IACpB,qCAAqC;IACrC,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,UAAU,CAAA;IAC9B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,QAAQ,EAAE,SAAS,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,EAC7B,OAAO,EACP,KAAK,EAAE,WAAW,EAClB,MAAM,EAAE,gBAAgB,EACxB,iBAAiB,EAAE,uBAAuB,EAC1C,UAAkB,EAClB,UAAU,EACV,iBAAiB,EACjB,KAAa,EACb,QAAQ,GACR,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"BackendAdapterContext.d.ts","sourceRoot":"","sources":["../../src/hooks/BackendAdapterContext.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ContemberBindxProvider.d.ts","sourceRoot":"","sources":["../../src/hooks/ContemberBindxProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEzD,OAAO,EAAoB,aAAa,EAAuF,WAAW,
|
|
1
|
+
{"version":3,"file":"ContemberBindxProvider.d.ts","sourceRoot":"","sources":["../../src/hooks/ContemberBindxProvider.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAiB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAA;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAA;AAEzD,OAAO,EAAoB,aAAa,EAAuF,WAAW,EAAqC,KAAK,gBAAgB,EAAE,KAAK,WAAW,EAAiB,KAAK,iBAAiB,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAIxS;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,WAAW,GAAG,gBAAgB,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAwBnG;AAED;;GAEG;AACH,MAAM,WAAW,2BAA2B;IAC3C,gDAAgD;IAChD,MAAM,EAAE,WAAW,CAAA;IACnB,0DAA0D;IAC1D,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,eAAe;IACf,QAAQ,EAAE,SAAS,CAAA;IAEnB,MAAM,EAAE,aAAa,CAAA;IAErB,gHAAgH;IAChH,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAA;IACnC,sFAAsF;IACtF,UAAU,CAAC,EAAE,iBAAiB,CAAA;IAC9B;;;;OAIG;IACH,iBAAiB,CAAC,EAAE,UAAU,CAAA;IAC9B,+DAA+D;IAC/D,KAAK,CAAC,EAAE,OAAO,CAAA;CACf;AAED;;GAEG;AACH,eAAO,MAAM,sBAAsB,mEAkEjC,CAAA"}
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { BindxProvider, useBackendAdapter, useSnapshotStore, useDispatcher, useBatchPersister, useBindxContext, useSchemaRegistry, type BindxProviderProps, type BindxContextValue, type BindxGraphQlClient, } from './BackendAdapterContext.js';
|
|
1
|
+
export { BindxProvider, useBackendAdapter, useSnapshotStore, useDispatcher, useBatchPersister, useBindxContext, useSchemaRegistry, useNotificationStore, type BindxProviderProps, type BindxContextValue, type BindxGraphQlClient, } from './BackendAdapterContext.js';
|
|
2
2
|
export { usePersist, usePersistEntity, type PersistApi, type EntityPersistApi, type AnyRefWithMeta, } from './usePersist.js';
|
|
3
3
|
export { useEntity, type UseEntityOptions, type LoadingEntityResult, type ErrorEntityResult, type NotFoundEntityResult, type ReadyEntityResult, type UseEntityResult, } from './useEntity.js';
|
|
4
4
|
export { useEntityList, type UseEntityListOptions, type LoadingEntityListResult, type ErrorEntityListResult, type ReadyEntityListResult, type UseEntityListResult, } from './useEntityList.js';
|
|
@@ -11,4 +11,6 @@ export { useField } from './useField.js';
|
|
|
11
11
|
export { useHasMany } from './useHasMany.js';
|
|
12
12
|
export { useHasOne } from './useHasOne.js';
|
|
13
13
|
export { useEntityErrors, type EntityErrorsState, } from './useErrors.js';
|
|
14
|
+
export { useNotifications, useShowNotification, useDismissNotification, } from './useNotifications.js';
|
|
15
|
+
export { usePersistWithFeedback, type PersistWithFeedbackApi, } from './usePersistWithFeedback.js';
|
|
14
16
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACvB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACnB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACN,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACpB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACxB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACN,sBAAsB,EACtB,gBAAgB,GAChB,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAE3D,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,GACjB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,EACN,eAAe,EACf,KAAK,iBAAiB,GACtB,MAAM,gBAAgB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,oBAAoB,EACpB,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,GACvB,MAAM,4BAA4B,CAAA;AAEnC,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,gBAAgB,EACrB,KAAK,cAAc,GACnB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACN,SAAS,EACT,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,eAAe,GACpB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,aAAa,EACb,KAAK,oBAAoB,EACzB,KAAK,uBAAuB,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,GACxB,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EACN,sBAAsB,EACtB,gBAAgB,GAChB,MAAM,6BAA6B,CAAA;AAEpC,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,cAAc,CAAA;AAE3D,OAAO,EACN,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,kBAAkB,EAClB,iBAAiB,GACjB,MAAM,qBAAqB,CAAA;AAE5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAA;AAEpE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE1C,OAAO,EACN,eAAe,EACf,KAAK,iBAAiB,GACtB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EACN,gBAAgB,EAChB,mBAAmB,EACnB,sBAAsB,GACtB,MAAM,uBAAuB,CAAA;AAE9B,OAAO,EACN,sBAAsB,EACtB,KAAK,sBAAsB,GAC3B,MAAM,6BAA6B,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Notification, NotificationInput } from '@contember/bindx';
|
|
2
|
+
/**
|
|
3
|
+
* Returns all active notifications, re-rendering on changes.
|
|
4
|
+
* Uses useSyncExternalStore for efficient subscriptions.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useNotifications(): readonly Notification[];
|
|
7
|
+
/**
|
|
8
|
+
* Returns a stable callback for adding a notification.
|
|
9
|
+
*/
|
|
10
|
+
export declare function useShowNotification(): (input: NotificationInput) => string;
|
|
11
|
+
/**
|
|
12
|
+
* Returns a stable callback for dismissing a notification.
|
|
13
|
+
*/
|
|
14
|
+
export declare function useDismissNotification(): (id: string) => void;
|
|
15
|
+
//# sourceMappingURL=useNotifications.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useNotifications.d.ts","sourceRoot":"","sources":["../../src/hooks/useNotifications.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAA;AAKvE;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,SAAS,YAAY,EAAE,CAO1D;AAED;;GAEG;AACH,wBAAgB,mBAAmB,IAAI,CAAC,KAAK,EAAE,iBAAiB,KAAK,MAAM,CAM1E;AAED;;GAEG;AACH,wBAAgB,sBAAsB,IAAI,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAM7D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { BatchPersistOptions, PersistenceResult } from '@contember/bindx';
|
|
2
|
+
import { type PersistApi } from './usePersist.js';
|
|
3
|
+
/**
|
|
4
|
+
* Extended persist API that automatically shows notifications on success/failure.
|
|
5
|
+
*/
|
|
6
|
+
export interface PersistWithFeedbackApi extends PersistApi {
|
|
7
|
+
/** Persist all dirty entities with automatic toast feedback */
|
|
8
|
+
persistAllWithFeedback(options?: BatchPersistOptions): Promise<PersistenceResult>;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Wraps `usePersist()` with automatic notification feedback.
|
|
12
|
+
*
|
|
13
|
+
* - On success: shows a success notification
|
|
14
|
+
* - On failure with server errors: shows an error notification with details
|
|
15
|
+
* - On failure with client validation errors: shows a warning notification
|
|
16
|
+
*
|
|
17
|
+
* The raw `usePersist()` methods are still available for manual control.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```tsx
|
|
21
|
+
* function SaveButton() {
|
|
22
|
+
* const { persistAllWithFeedback, isPersisting, isDirty } = usePersistWithFeedback()
|
|
23
|
+
* return (
|
|
24
|
+
* <button onClick={() => persistAllWithFeedback()} disabled={isPersisting || !isDirty}>
|
|
25
|
+
* Save
|
|
26
|
+
* </button>
|
|
27
|
+
* )
|
|
28
|
+
* }
|
|
29
|
+
* ```
|
|
30
|
+
*/
|
|
31
|
+
export declare function usePersistWithFeedback(): PersistWithFeedbackApi;
|
|
32
|
+
//# sourceMappingURL=usePersistWithFeedback.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usePersistWithFeedback.d.ts","sourceRoot":"","sources":["../../src/hooks/usePersistWithFeedback.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,iBAAiB,EAAsB,MAAM,kBAAkB,CAAA;AAClG,OAAO,EAAc,KAAK,UAAU,EAAE,MAAM,iBAAiB,CAAA;AAG7D;;GAEG;AACH,MAAM,WAAW,sBAAuB,SAAQ,UAAU;IACzD,+DAA+D;IAC/D,sBAAsB,CAAC,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAA;CACjF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,IAAI,sBAAsB,CAuE/D"}
|
package/dist/index.d.ts
CHANGED
|
@@ -5,10 +5,10 @@
|
|
|
5
5
|
*/
|
|
6
6
|
export type { RelationType, ScalarFieldDef, HasOneRelationDef, HasManyRelationDef, FieldDef, EntitySchemaDef, SchemaDefinition, InferModel, InferEntityNames, EntityDef, InferEntityDef, UnionToIntersection, RoleNames, CommonEntity, EntityForRoles, ResolveEntity, SingleRoleMap, DefaultRole, SelectionBuilder, SelectionMeta, SelectionFieldMeta, FluentFragment, FluentDefiner, HasManyOptions, InferSelection, QuerySpec, QueryFieldSpec, EntityWhere, EntityOrderBy, ScalarCondition, OrderDirection, TypedHasManyOptions, AliasOptions, HasOneRelationState, InputProps, EntityFields, EntityFieldsAccessor, EntityFieldsRef, ScalarKeys, HasManyKeys, HasOneKeys, FieldRefMeta, FieldRef, HasManyRef, HasOneRef, EntityRef, FieldAccessor, HasManyAccessor, HasOneAccessor, EntityAccessor, ExtractHasOneEntityName, ExtractHasManyEntityName, ExtractRoleMap, BackendAdapter, QueryOptions, Query, GetQuery, ListQuery, QueryResult, GetQueryResult, ListQueryResult, MockDataStore, MockAdapterOptions, ContemberAdapterOptions, EntityLoadResult, EntityListLoadResult, LoadEntityOptions, LoadEntityListOptions, SelectionInput, CoreFluentDefiner, EntitySnapshot, FieldSnapshot, HasOneRelationSnapshot, HasManySnapshot, EntityState, LoadStatus, UndoManagerConfig, UndoState, UndoEntry, BindxEvent, FieldScopedEvent, FieldChangingEvent, FieldChangedEvent, RelationConnectingEvent, RelationConnectedEvent, RelationDisconnectingEvent, RelationDisconnectedEvent, RelationDeletingEvent, RelationDeletedEvent, HasManyConnectingEvent, HasManyConnectedEvent, HasManyDisconnectingEvent, HasManyDisconnectedEvent, EntityPersistingEvent, EntityPersistedEvent, EntityPersistFailedEvent, EntityResettingEvent, EntityResetEvent, EntityDeletingEvent, EntityDeletedEvent, ErrorAddedEvent, ErrorsClearedEvent, LoadStateChangedEvent, BeforeEvent, AfterEvent, AnyBindxEvent, EventTypeMap, InterceptorResult, Interceptor, EventListener, Unsubscribe, BeforeEventTypes, AfterEventTypes, } from '@contember/bindx';
|
|
7
7
|
export { scalar, hasOne, hasMany, defineSchema, entityDef, roleEntityDef, DEFAULT_ROLE, SchemaRegistry, createFragment, buildQueryFromSelection, EntityHandle, HasOneHandle, HasManyListHandle, FieldHandle, FIELD_REF_META, MockAdapter, ContemberAdapter, createEntityLoader, resolveSelectionMeta, buildQuery, SnapshotStore, ActionDispatcher, isTempId, isPlaceholderId, isPersistedId, generatePlaceholderId, BatchPersister, ChangeRegistry, UndoManager, EventEmitter, __internal, } from '@contember/bindx';
|
|
8
|
-
export type { BindxProviderProps, BindxContextValue, BindxGraphQlClient, UseEntityOptions, UseEntityListOptions, LoadingEntityResult, ErrorEntityResult, NotFoundEntityResult, ReadyEntityResult, UseEntityResult, LoadingEntityListResult, ErrorEntityListResult, ReadyEntityListResult, UseEntityListResult, PersistApi, EntityPersistApi, AnyRefWithMeta, } from './hooks/index.js';
|
|
8
|
+
export type { BindxProviderProps, BindxContextValue, BindxGraphQlClient, UseEntityOptions, UseEntityListOptions, LoadingEntityResult, ErrorEntityResult, NotFoundEntityResult, ReadyEntityResult, UseEntityResult, LoadingEntityListResult, ErrorEntityListResult, ReadyEntityListResult, UseEntityListResult, PersistApi, EntityPersistApi, AnyRefWithMeta, PersistWithFeedbackApi, } from './hooks/index.js';
|
|
9
9
|
export type { DirtyEntity, PersistScope, AllScope, EntityScope as EntityPersistScope, FieldsScope, RelationScope, CustomScope, EntityPersistResult, PersistenceResult, BatchPersistOptions, } from '@contember/bindx';
|
|
10
10
|
export type { FieldProps, HasManyProps, HasOneProps, IfProps, EntityComponentProps, HasManyComponentOptions, ShowProps, SelectionPropMeta, SelectionProvider, EntityPropKeys, EntityFromProp, SelectionFromProp, ImplicitFragmentProperties, BindxComponentBase, BindxComponent, ComponentBuilder, ComponentBuilderState, CreateComponentOptions, InterfaceEntityPropConfig, ImplicitInterfaceEntityConfig, ExplicitInterfaceEntityConfig, AddInterfaces, InterfaceSelectorsMap, AnyEntityPropConfig, EntityPropConfig, ImplicitEntityConfig, ExplicitEntityConfig, AddImplicitEntity, AddExplicitEntity, AddImplicitInterfaceEntity, AddExplicitInterfaceEntity, SetScalarProps, BuildEntityProps, BuildProps, BuildFragmentProps, InitialBuilderState, } from './jsx/index.js';
|
|
11
|
-
export { BindxProvider, useBackendAdapter, useSnapshotStore, useDispatcher, useBatchPersister, useBindxContext, useSchemaRegistry, useEntity, useEntityList, usePersist, usePersistEntity, useUndo, useOnEvent, useOnEntityEvent, useOnFieldEvent, useIntercept, useInterceptEntity, useInterceptField, useAccessor, useField, useHasMany, useHasOne, ContemberBindxProvider, schemaNamesToDef, } from './hooks/index.js';
|
|
11
|
+
export { BindxProvider, useBackendAdapter, useSnapshotStore, useDispatcher, useBatchPersister, useBindxContext, useSchemaRegistry, useEntity, useEntityList, usePersist, usePersistEntity, useUndo, useOnEvent, useOnEntityEvent, useOnFieldEvent, useIntercept, useInterceptEntity, useInterceptField, useAccessor, useField, useHasMany, useHasOne, useNotificationStore, useNotifications, useShowNotification, useDismissNotification, usePersistWithFeedback, ContemberBindxProvider, schemaNamesToDef, } from './hooks/index.js';
|
|
12
12
|
export { RoleProvider, useHasRole, type RoleProviderProps } from './roles/index.js';
|
|
13
13
|
export type { UndoHookResult } from './hooks/useUndo.js';
|
|
14
14
|
export { Attribute, type AttributeProps, Field, HasMany, HasOne, If, Show, Entity, type EntityProps, EntityList, type EntityListProps, HasRole, type HasRoleProps, BINDX_COMPONENT, SCOPE_REF, cond, type Condition, createComponent, withCollector, isBindxComponent, mergeFragments, COMPONENT_MARKER, COMPONENT_BRAND, COMPONENT_SELECTIONS, createComponentBuilder, getComponentBrand, setBrandValidation, validateBrand, } from './jsx/index.js';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,YAAY,EAEX,YAAY,EACZ,cAAc,EACd,iBAAiB,EACjB,kBAAkB,EAClB,QAAQ,EACR,eAAe,EACf,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,SAAS,EACT,cAAc,EAEd,mBAAmB,EACnB,SAAS,EACT,YAAY,EACZ,cAAc,EACd,aAAa,EACb,aAAa,EACb,WAAW,EAEX,gBAAgB,EAChB,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,cAAc,EACd,cAAc,EACd,SAAS,EACT,cAAc,EAEd,WAAW,EACX,aAAa,EACb,eAAe,EACf,cAAc,EACd,mBAAmB,EACnB,YAAY,EAEZ,mBAAmB,EACnB,UAAU,EACV,YAAY,EACZ,oBAAoB,EACpB,eAAe,EACf,UAAU,EACV,WAAW,EACX,UAAU,EACV,YAAY,EAEZ,QAAQ,EACR,UAAU,EACV,SAAS,EACT,SAAS,EAET,aAAa,EACb,eAAe,EACf,cAAc,EACd,cAAc,EAEd,uBAAuB,EACvB,wBAAwB,EACxB,cAAc,EAEd,cAAc,EACd,YAAY,EACZ,KAAK,EACL,QAAQ,EACR,SAAS,EACT,WAAW,EACX,cAAc,EACd,eAAe,EACf,aAAa,EACb,kBAAkB,EAClB,uBAAuB,EAEvB,gBAAgB,EAChB,oBAAoB,EACpB,iBAAiB,EACjB,qBAAqB,EACrB,cAAc,EACd,iBAAiB,EAEjB,cAAc,EACd,aAAa,EACb,sBAAsB,EACtB,eAAe,EACf,WAAW,EACX,UAAU,EAEV,iBAAiB,EACjB,SAAS,EACT,SAAS,EAET,UAAU,EACV,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,uBAAuB,EACvB,sBAAsB,EACtB,0BAA0B,EAC1B,yBAAyB,EACzB,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,qBAAqB,EACrB,yBAAyB,EACzB,wBAAwB,EACxB,qBAAqB,EACrB,oBAAoB,EACpB,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,eAAe,EACf,kBAAkB,EAClB,qBAAqB,EACrB,WAAW,EACX,UAAU,EACV,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,WAAW,EACX,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,eAAe,GACf,MAAM,kBAAkB,CAAA;AAEzB,OAAO,EAEN,MAAM,EACN,MAAM,EACN,OAAO,EACP,YAAY,EACZ,SAAS,EACT,aAAa,EACb,YAAY,EACZ,cAAc,EAEd,cAAc,EACd,uBAAuB,EAEvB,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,WAAW,EAEX,cAAc,EAEd,WAAW,EACX,gBAAgB,EAEhB,kBAAkB,EAClB,oBAAoB,EACpB,UAAU,EAEV,aAAa,EACb,gBAAgB,EAEhB,QAAQ,EACR,eAAe,EACf,aAAa,EACb,qBAAqB,EAErB,cAAc,EACd,cAAc,EAEd,WAAW,EAEX,YAAY,EAEZ,UAAU,GACV,MAAM,kBAAkB,CAAA;AAOzB,YAAY,EACX,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,EACpB,mBAAmB,EACnB,iBAAiB,EACjB,oBAAoB,EACpB,iBAAiB,EACjB,eAAe,EACf,uBAAuB,EACvB,qBAAqB,EACrB,qBAAqB,EACrB,mBAAmB,EAEnB,UAAU,EACV,gBAAgB,EAChB,cAAc,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contember/bindx-react",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.30",
|
|
4
4
|
"description": "Type-safe React data binding framework",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.ts",
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
"react": ">=18.0.0"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@contember/bindx": "0.1.
|
|
19
|
-
"@contember/bindx-client": "0.1.
|
|
18
|
+
"@contember/bindx": "0.1.30",
|
|
19
|
+
"@contember/bindx-client": "0.1.30",
|
|
20
20
|
"@contember/graphql-client": "^2.1.0-beta.1",
|
|
21
21
|
"@radix-ui/primitive": "^1.1.3",
|
|
22
22
|
"@radix-ui/react-slot": "^1.2.4"
|
|
@@ -6,6 +6,7 @@ import { BatchPersister } from '@contember/bindx'
|
|
|
6
6
|
import { MutationCollector } from '@contember/bindx'
|
|
7
7
|
import { SchemaRegistry } from '@contember/bindx'
|
|
8
8
|
import { UndoManager } from '@contember/bindx'
|
|
9
|
+
import { NotificationStore } from '@contember/bindx'
|
|
9
10
|
import { QueryBatcher } from '../batching/QueryBatcher.js'
|
|
10
11
|
|
|
11
12
|
/**
|
|
@@ -36,6 +37,8 @@ export interface BindxContextValue {
|
|
|
36
37
|
undoManager: UndoManager | null
|
|
37
38
|
/** GraphQL client (available when using ContemberBindxProvider) */
|
|
38
39
|
graphQlClient: BindxGraphQlClient | null
|
|
40
|
+
/** Notification store for user-facing feedback (toasts) */
|
|
41
|
+
notificationStore: NotificationStore
|
|
39
42
|
/** Whether debug logging is enabled */
|
|
40
43
|
debug: boolean
|
|
41
44
|
}
|
|
@@ -133,6 +136,7 @@ export function BindxProvider({
|
|
|
133
136
|
schema: schemaRegistry,
|
|
134
137
|
undoManager,
|
|
135
138
|
graphQlClient: null,
|
|
139
|
+
notificationStore: new NotificationStore(),
|
|
136
140
|
debug,
|
|
137
141
|
}
|
|
138
142
|
}, [adapter, customStore, schemaDefinition, customMutationCollector, enableUndo, undoConfig, defaultUpdateMode, debug])
|
|
@@ -223,3 +227,15 @@ export function useQueryBatcher(): QueryBatcher {
|
|
|
223
227
|
}
|
|
224
228
|
return context.batcher
|
|
225
229
|
}
|
|
230
|
+
|
|
231
|
+
/**
|
|
232
|
+
* Hook to access the notification store.
|
|
233
|
+
* Must be used within a BindxProvider.
|
|
234
|
+
*/
|
|
235
|
+
export function useNotificationStore(): NotificationStore {
|
|
236
|
+
const context = useContext(BindxContext)
|
|
237
|
+
if (!context) {
|
|
238
|
+
throw new Error('useNotificationStore must be used within a BindxProvider')
|
|
239
|
+
}
|
|
240
|
+
return context.notificationStore
|
|
241
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { memo, useMemo, type ReactNode } from 'react'
|
|
2
2
|
import { GraphQlClient } from '@contember/graphql-client'
|
|
3
3
|
import { ContentClient } from '@contember/bindx-client'
|
|
4
|
-
import { ContemberAdapter, SnapshotStore, ActionDispatcher, BatchPersister, MutationCollector, ContemberSchemaMutationAdapter, UndoManager, SchemaRegistry, type SchemaDefinition, type SchemaNames, type FieldDef, type UndoManagerConfig, type UpdateMode } from '@contember/bindx'
|
|
4
|
+
import { ContemberAdapter, SnapshotStore, ActionDispatcher, BatchPersister, MutationCollector, ContemberSchemaMutationAdapter, UndoManager, SchemaRegistry, NotificationStore, type SchemaDefinition, type SchemaNames, type FieldDef, type UndoManagerConfig, type UpdateMode } from '@contember/bindx'
|
|
5
5
|
import { BindxContext, type BindxContextValue } from './BackendAdapterContext.js'
|
|
6
6
|
import { QueryBatcher } from '../batching/QueryBatcher.js'
|
|
7
7
|
|
|
@@ -121,6 +121,7 @@ export const ContemberBindxProvider = memo(function ContemberBindxProvider({
|
|
|
121
121
|
schema: schemaRegistry,
|
|
122
122
|
undoManager,
|
|
123
123
|
graphQlClient,
|
|
124
|
+
notificationStore: new NotificationStore(),
|
|
124
125
|
debug,
|
|
125
126
|
}
|
|
126
127
|
}, [schema, customStore, undoManagerProp, undoConfig, defaultUpdateMode, debug])
|
package/src/hooks/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ export {
|
|
|
6
6
|
useBatchPersister,
|
|
7
7
|
useBindxContext,
|
|
8
8
|
useSchemaRegistry,
|
|
9
|
+
useNotificationStore,
|
|
9
10
|
type BindxProviderProps,
|
|
10
11
|
type BindxContextValue,
|
|
11
12
|
type BindxGraphQlClient,
|
|
@@ -65,3 +66,14 @@ export {
|
|
|
65
66
|
useEntityErrors,
|
|
66
67
|
type EntityErrorsState,
|
|
67
68
|
} from './useErrors.js'
|
|
69
|
+
|
|
70
|
+
export {
|
|
71
|
+
useNotifications,
|
|
72
|
+
useShowNotification,
|
|
73
|
+
useDismissNotification,
|
|
74
|
+
} from './useNotifications.js'
|
|
75
|
+
|
|
76
|
+
export {
|
|
77
|
+
usePersistWithFeedback,
|
|
78
|
+
type PersistWithFeedbackApi,
|
|
79
|
+
} from './usePersistWithFeedback.js'
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useCallback, useSyncExternalStore } from 'react'
|
|
2
|
+
import type { Notification, NotificationInput } from '@contember/bindx'
|
|
3
|
+
import { useNotificationStore } from './BackendAdapterContext.js'
|
|
4
|
+
|
|
5
|
+
const EMPTY: readonly Notification[] = []
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Returns all active notifications, re-rendering on changes.
|
|
9
|
+
* Uses useSyncExternalStore for efficient subscriptions.
|
|
10
|
+
*/
|
|
11
|
+
export function useNotifications(): readonly Notification[] {
|
|
12
|
+
const store = useNotificationStore()
|
|
13
|
+
return useSyncExternalStore(
|
|
14
|
+
store.subscribe.bind(store),
|
|
15
|
+
() => store.getAll(),
|
|
16
|
+
() => EMPTY,
|
|
17
|
+
)
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Returns a stable callback for adding a notification.
|
|
22
|
+
*/
|
|
23
|
+
export function useShowNotification(): (input: NotificationInput) => string {
|
|
24
|
+
const store = useNotificationStore()
|
|
25
|
+
return useCallback(
|
|
26
|
+
(input: NotificationInput) => store.add(input),
|
|
27
|
+
[store],
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Returns a stable callback for dismissing a notification.
|
|
33
|
+
*/
|
|
34
|
+
export function useDismissNotification(): (id: string) => void {
|
|
35
|
+
const store = useNotificationStore()
|
|
36
|
+
return useCallback(
|
|
37
|
+
(id: string) => store.dismiss(id),
|
|
38
|
+
[store],
|
|
39
|
+
)
|
|
40
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { useCallback } from 'react'
|
|
2
|
+
import type { BatchPersistOptions, PersistenceResult, NotificationDetail } from '@contember/bindx'
|
|
3
|
+
import { usePersist, type PersistApi } from './usePersist.js'
|
|
4
|
+
import { useNotificationStore } from './BackendAdapterContext.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Extended persist API that automatically shows notifications on success/failure.
|
|
8
|
+
*/
|
|
9
|
+
export interface PersistWithFeedbackApi extends PersistApi {
|
|
10
|
+
/** Persist all dirty entities with automatic toast feedback */
|
|
11
|
+
persistAllWithFeedback(options?: BatchPersistOptions): Promise<PersistenceResult>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Wraps `usePersist()` with automatic notification feedback.
|
|
16
|
+
*
|
|
17
|
+
* - On success: shows a success notification
|
|
18
|
+
* - On failure with server errors: shows an error notification with details
|
|
19
|
+
* - On failure with client validation errors: shows a warning notification
|
|
20
|
+
*
|
|
21
|
+
* The raw `usePersist()` methods are still available for manual control.
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* ```tsx
|
|
25
|
+
* function SaveButton() {
|
|
26
|
+
* const { persistAllWithFeedback, isPersisting, isDirty } = usePersistWithFeedback()
|
|
27
|
+
* return (
|
|
28
|
+
* <button onClick={() => persistAllWithFeedback()} disabled={isPersisting || !isDirty}>
|
|
29
|
+
* Save
|
|
30
|
+
* </button>
|
|
31
|
+
* )
|
|
32
|
+
* }
|
|
33
|
+
* ```
|
|
34
|
+
*/
|
|
35
|
+
export function usePersistWithFeedback(): PersistWithFeedbackApi {
|
|
36
|
+
const persistApi = usePersist()
|
|
37
|
+
const notificationStore = useNotificationStore()
|
|
38
|
+
|
|
39
|
+
const persistAllWithFeedback = useCallback(
|
|
40
|
+
async (options?: BatchPersistOptions): Promise<PersistenceResult> => {
|
|
41
|
+
const result = await persistApi.persistAll(options)
|
|
42
|
+
|
|
43
|
+
if (result.success) {
|
|
44
|
+
notificationStore.add({
|
|
45
|
+
type: 'success',
|
|
46
|
+
message: 'Changes saved successfully',
|
|
47
|
+
source: 'persist',
|
|
48
|
+
dismissAfter: 6_000,
|
|
49
|
+
})
|
|
50
|
+
} else {
|
|
51
|
+
const details: NotificationDetail[] = []
|
|
52
|
+
let hasClientErrors = false
|
|
53
|
+
|
|
54
|
+
for (const entityResult of result.results) {
|
|
55
|
+
if (entityResult.success) continue
|
|
56
|
+
|
|
57
|
+
if (entityResult.error) {
|
|
58
|
+
// Server error
|
|
59
|
+
details.push({
|
|
60
|
+
entityType: entityResult.entityType,
|
|
61
|
+
message: entityResult.error.message,
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
// Add field-level details from mutation result
|
|
65
|
+
if (entityResult.error.mutationResult) {
|
|
66
|
+
for (const err of entityResult.error.mutationResult.errors) {
|
|
67
|
+
details.push({ message: err.message })
|
|
68
|
+
}
|
|
69
|
+
for (const err of entityResult.error.mutationResult.validation.errors) {
|
|
70
|
+
details.push({ message: err.message.text })
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} else {
|
|
74
|
+
// No server error means blocked by client validation
|
|
75
|
+
hasClientErrors = true
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (hasClientErrors && details.length === 0) {
|
|
80
|
+
notificationStore.add({
|
|
81
|
+
type: 'warning',
|
|
82
|
+
message: 'Please fix validation errors before saving',
|
|
83
|
+
source: 'persist',
|
|
84
|
+
dismissAfter: 15_000,
|
|
85
|
+
})
|
|
86
|
+
} else {
|
|
87
|
+
notificationStore.add({
|
|
88
|
+
type: 'error',
|
|
89
|
+
message: 'Failed to save changes',
|
|
90
|
+
details: details.length > 0 ? details : undefined,
|
|
91
|
+
source: 'persist',
|
|
92
|
+
dismissAfter: 60_000,
|
|
93
|
+
})
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
return result
|
|
98
|
+
},
|
|
99
|
+
[persistApi, notificationStore],
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
return {
|
|
103
|
+
...persistApi,
|
|
104
|
+
persistAllWithFeedback,
|
|
105
|
+
}
|
|
106
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -207,6 +207,8 @@ export type {
|
|
|
207
207
|
PersistApi,
|
|
208
208
|
EntityPersistApi,
|
|
209
209
|
AnyRefWithMeta,
|
|
210
|
+
// Notification hook types
|
|
211
|
+
PersistWithFeedbackApi,
|
|
210
212
|
} from './hooks/index.js'
|
|
211
213
|
|
|
212
214
|
// Persistence types from @contember/bindx
|
|
@@ -301,6 +303,12 @@ export {
|
|
|
301
303
|
useField,
|
|
302
304
|
useHasMany,
|
|
303
305
|
useHasOne,
|
|
306
|
+
// Notifications
|
|
307
|
+
useNotificationStore,
|
|
308
|
+
useNotifications,
|
|
309
|
+
useShowNotification,
|
|
310
|
+
useDismissNotification,
|
|
311
|
+
usePersistWithFeedback,
|
|
304
312
|
// Contember
|
|
305
313
|
ContemberBindxProvider,
|
|
306
314
|
schemaNamesToDef,
|