@vuu-ui/vuu-data-test 4.0.0-alpha.20 → 4.0.0-alpha.21
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/package.json +7 -7
- package/src/TickingArrayDataSource.js +7 -2
- package/src/core/module/VuuModule.js +3 -1
- package/src/local-datasource-provider/LocalDatasourceProvider.js +15 -5
- package/src/module-admin/ModuleAdminModule.js +3 -3
- package/src/module-admin/module-admin-schemas.js +0 -12
- package/src/notifications/NotificationModule.js +39 -1
- package/src/notifications/simulated/SimulatedNotificationsModule.js +5 -1
- package/types/TickingArrayDataSource.d.ts +1 -1
- package/types/local-datasource-provider/LocalDatasourceProvider.d.ts +4 -2
- package/types/notifications/NotificationModule.d.ts +21 -0
- package/types/notifications/simulated/SimulatedNotificationsModule.d.ts +8 -1
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "4.0.0-alpha.
|
|
2
|
+
"version": "4.0.0-alpha.21",
|
|
3
3
|
"main": "./src/index.js",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"author": "heswell",
|
|
@@ -12,14 +12,14 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@heswell/module-admin": "1.1.0",
|
|
14
14
|
"@heswell/user-admin": "1.0.1",
|
|
15
|
-
"@vuu-ui/vuu-data-editing": "4.0.0-alpha.
|
|
16
|
-
"@vuu-ui/vuu-data-local": "4.0.0-alpha.
|
|
17
|
-
"@vuu-ui/vuu-utils": "4.0.0-alpha.
|
|
15
|
+
"@vuu-ui/vuu-data-editing": "4.0.0-alpha.21",
|
|
16
|
+
"@vuu-ui/vuu-data-local": "4.0.0-alpha.21",
|
|
17
|
+
"@vuu-ui/vuu-utils": "4.0.0-alpha.21"
|
|
18
18
|
},
|
|
19
19
|
"devDependencies": {
|
|
20
|
-
"@vuu-ui/vuu-data-types": "4.0.0-alpha.
|
|
21
|
-
"@vuu-ui/vuu-protocol-types": "4.0.0-alpha.
|
|
22
|
-
"@vuu-ui/vuu-table-types": "4.0.0-alpha.
|
|
20
|
+
"@vuu-ui/vuu-data-types": "4.0.0-alpha.21",
|
|
21
|
+
"@vuu-ui/vuu-protocol-types": "4.0.0-alpha.21",
|
|
22
|
+
"@vuu-ui/vuu-table-types": "4.0.0-alpha.21"
|
|
23
23
|
},
|
|
24
24
|
"sideEffects": false,
|
|
25
25
|
"files": [
|
|
@@ -181,14 +181,19 @@ class TickingArrayDataSource extends ArrayDataSource {
|
|
|
181
181
|
get columns() {
|
|
182
182
|
return super.columns;
|
|
183
183
|
}
|
|
184
|
-
async endEditSession(saveChanges = false) {
|
|
184
|
+
async endEditSession(saveChanges = false, force = false) {
|
|
185
|
+
if ("unsubscribed" === this.status || !this.viewport) {
|
|
186
|
+
if (!saveChanges) return;
|
|
187
|
+
throw Error("Cannot save changes: datasource is unsubscribed");
|
|
188
|
+
}
|
|
185
189
|
const type = "RPC_REQUEST";
|
|
186
190
|
const rpcName = "endEditSession";
|
|
187
191
|
const rpcResponse = await this.rpcRequest(saveChanges ? {
|
|
188
192
|
type,
|
|
189
193
|
rpcName,
|
|
190
194
|
params: {
|
|
191
|
-
save: true
|
|
195
|
+
save: true,
|
|
196
|
+
force
|
|
192
197
|
}
|
|
193
198
|
} : {
|
|
194
199
|
type,
|
|
@@ -2,16 +2,26 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { DataProvider } from "@vuu-ui/core";
|
|
3
3
|
import { DataProvider as vuu_utils_DataProvider } from "@vuu-ui/vuu-utils";
|
|
4
4
|
import ModuleContainer, { ensureVuuModule } from "../core/module/ModuleContainer.js";
|
|
5
|
-
|
|
6
|
-
const
|
|
5
|
+
const createLocalDataSourceProvider = (modules)=>{
|
|
6
|
+
const ownModules = modules ? new Map(modules.map((module)=>[
|
|
7
|
+
module.name,
|
|
8
|
+
module
|
|
9
|
+
])) : void 0;
|
|
7
10
|
const getModule = (moduleName)=>{
|
|
8
|
-
if (
|
|
11
|
+
if (ownModules) {
|
|
12
|
+
const module = ownModules.get(moduleName);
|
|
13
|
+
if (module) return module;
|
|
14
|
+
throw Error(`[LocalDataSourceProvider] module ${moduleName} is not available on this server`);
|
|
15
|
+
}
|
|
9
16
|
return ModuleContainer.get(moduleName);
|
|
10
17
|
};
|
|
11
18
|
const serverAPI = {
|
|
12
19
|
getTableList: async ()=>{
|
|
13
20
|
const tables = [];
|
|
14
|
-
for (const moduleName of
|
|
21
|
+
for (const moduleName of ownModules?.keys() ?? ModuleContainer.moduleNames){
|
|
22
|
+
const module = getModule(moduleName);
|
|
23
|
+
for (const tableName of module.getTableList())tables.push(module.getTableSchema(tableName).table);
|
|
24
|
+
}
|
|
15
25
|
return {
|
|
16
26
|
tables
|
|
17
27
|
};
|
|
@@ -54,7 +64,7 @@ const createLocalVuuServer = ({ connectionId, modules })=>{
|
|
|
54
64
|
modules.forEach(ensureVuuModule);
|
|
55
65
|
return {
|
|
56
66
|
connectionId,
|
|
57
|
-
DataSourceProvider: createLocalDataSourceProvider(
|
|
67
|
+
DataSourceProvider: createLocalDataSourceProvider(modules)
|
|
58
68
|
};
|
|
59
69
|
};
|
|
60
70
|
export { LocalDataSourceProvider, createLocalVuuServer };
|
|
@@ -46,9 +46,9 @@ const EXAMPLE_MODULES = [
|
|
|
46
46
|
mfScope: "orderBlotter",
|
|
47
47
|
mfUrl: "http://localhost:5009",
|
|
48
48
|
navIconUrl: MODULE_NAV_ICONS.tables,
|
|
49
|
-
vuuConnectionId: "
|
|
50
|
-
vuuWebsocketUrl: "
|
|
51
|
-
vuuRestUrl: "
|
|
49
|
+
vuuConnectionId: "",
|
|
50
|
+
vuuWebsocketUrl: "",
|
|
51
|
+
vuuRestUrl: "",
|
|
52
52
|
accessRole: "",
|
|
53
53
|
created: INITIAL_TIMESTAMP,
|
|
54
54
|
updated: INITIAL_TIMESTAMP
|
|
@@ -55,18 +55,6 @@ const MODULE_ADMIN_TABLE_SCHEMAS = {
|
|
|
55
55
|
name: "mfUrl",
|
|
56
56
|
serverDataType: "string"
|
|
57
57
|
},
|
|
58
|
-
{
|
|
59
|
-
name: "vuuConnectionId",
|
|
60
|
-
serverDataType: "string"
|
|
61
|
-
},
|
|
62
|
-
{
|
|
63
|
-
name: "vuuWebsocketUrl",
|
|
64
|
-
serverDataType: "string"
|
|
65
|
-
},
|
|
66
|
-
{
|
|
67
|
-
name: "vuuRestUrl",
|
|
68
|
-
serverDataType: "string"
|
|
69
|
-
},
|
|
70
58
|
{
|
|
71
59
|
name: "navIconUrl",
|
|
72
60
|
serverDataType: "string"
|
|
@@ -25,6 +25,8 @@ const VUU_DEFAULT_COLUMNS = [
|
|
|
25
25
|
class NotificationModule extends VuuModule {
|
|
26
26
|
static NAME = NAME;
|
|
27
27
|
static TABLE_NAME = TABLE_NAME;
|
|
28
|
+
#autoStarted = false;
|
|
29
|
+
#expiryTimers = new Map();
|
|
28
30
|
#provider;
|
|
29
31
|
#running = false;
|
|
30
32
|
#schemas;
|
|
@@ -60,7 +62,42 @@ class NotificationModule extends VuuModule {
|
|
|
60
62
|
};
|
|
61
63
|
}
|
|
62
64
|
beforeCreateDataSource() {
|
|
63
|
-
this
|
|
65
|
+
if (!this.#autoStarted) {
|
|
66
|
+
this.#autoStarted = true;
|
|
67
|
+
this.start();
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
publish(notification = {}) {
|
|
71
|
+
const table = this.#tables[TABLE_NAME];
|
|
72
|
+
const { map, schema } = table;
|
|
73
|
+
const id = notification.id ?? crypto.randomUUID();
|
|
74
|
+
const values = {
|
|
75
|
+
type: "toast",
|
|
76
|
+
title: "Notification",
|
|
77
|
+
message: "",
|
|
78
|
+
level: "INFO",
|
|
79
|
+
audience: "all",
|
|
80
|
+
...notification,
|
|
81
|
+
id
|
|
82
|
+
};
|
|
83
|
+
const row = schema.columns.map(({ serverDataType })=>"string" === serverDataType ? "" : "boolean" === serverDataType ? false : 0);
|
|
84
|
+
for (const [name, value] of Object.entries(values)){
|
|
85
|
+
const idx = map[name];
|
|
86
|
+
if (void 0 !== idx && void 0 !== value) row[idx] = value;
|
|
87
|
+
}
|
|
88
|
+
const existingRow = table.findByKey(id);
|
|
89
|
+
if (existingRow) {
|
|
90
|
+
row[map.vuuCreatedTimestamp] = existingRow[map.vuuCreatedTimestamp];
|
|
91
|
+
table.updateRow(row);
|
|
92
|
+
} else table.insert(row);
|
|
93
|
+
clearTimeout(this.#expiryTimers.get(id));
|
|
94
|
+
this.#expiryTimers.delete(id);
|
|
95
|
+
const { expiryTime } = values;
|
|
96
|
+
if ("number" == typeof expiryTime && expiryTime > 0) this.#expiryTimers.set(id, setTimeout(()=>{
|
|
97
|
+
this.#expiryTimers.delete(id);
|
|
98
|
+
if (table.findByKey(id)) table.delete(id);
|
|
99
|
+
}, Math.max(0, expiryTime - Date.now())));
|
|
100
|
+
return id;
|
|
64
101
|
}
|
|
65
102
|
get isRunning() {
|
|
66
103
|
return this.#running;
|
|
@@ -72,6 +109,7 @@ class NotificationModule extends VuuModule {
|
|
|
72
109
|
}
|
|
73
110
|
}
|
|
74
111
|
stop() {
|
|
112
|
+
this.#autoStarted = true;
|
|
75
113
|
if (this.#running) {
|
|
76
114
|
this.#running = false;
|
|
77
115
|
this.#provider.stop();
|
|
@@ -2,7 +2,11 @@ import { PermissionFilter } from "../../core/filter/PermissionFilter.js";
|
|
|
2
2
|
import { NotificationModule } from "../NotificationModule.js";
|
|
3
3
|
import { DismissNotificationRpcHandler } from "./DismissNotificationRpcHandler.js";
|
|
4
4
|
import { SimulatedNotificationsProvider } from "./SimulatedNotificationsProvider.js";
|
|
5
|
-
const
|
|
5
|
+
const noSimulation = {
|
|
6
|
+
start: ()=>void 0,
|
|
7
|
+
stop: ()=>void 0
|
|
8
|
+
};
|
|
9
|
+
const SimulatedNotificationsModule = ({ simulate = true } = {})=>new NotificationModule((table)=>simulate ? new SimulatedNotificationsProvider(table) : noSimulation, (viewport)=>{
|
|
6
10
|
const currentUser = viewport.user.name;
|
|
7
11
|
return PermissionFilter("audience", new Set([
|
|
8
12
|
"all",
|
|
@@ -33,7 +33,7 @@ export declare class TickingArrayDataSource extends ArrayDataSource {
|
|
|
33
33
|
undoRowChange: (key: string) => Promise<RpcResultSuccess | RpcResultError>;
|
|
34
34
|
set columns(columns: string[]);
|
|
35
35
|
get columns(): string[];
|
|
36
|
-
endEditSession(saveChanges?: boolean): Promise<void>;
|
|
36
|
+
endEditSession(saveChanges?: boolean, force?: boolean): Promise<void>;
|
|
37
37
|
rpcRequest(rpcRequest: Omit<VuuRpcServiceRequest, "context">): Promise<RpcResultSuccess | RpcResultError>;
|
|
38
38
|
menuRpcCall(rpcRequest: Omit<VuuRpcMenuRequest, "vpId">): Promise<VuuRpcMenuResponse>;
|
|
39
39
|
getTypeaheadSuggestions(column: string, pattern?: string): Promise<string[]>;
|
|
@@ -4,7 +4,7 @@ import type { VuuModule } from "../core/module/VuuModule";
|
|
|
4
4
|
/** Data context covering every VuuModule registered in the browser. */
|
|
5
5
|
export declare const LocalDataSourceProvider: ({ children }: {
|
|
6
6
|
children: ReactNode;
|
|
7
|
-
}) => import("react").JSX.Element;
|
|
7
|
+
}) => import("react/jsx-runtime").JSX.Element;
|
|
8
8
|
export interface LocalVuuServerOptions {
|
|
9
9
|
/** Matches the `vuu.connectionId` of the modules this server serves. */
|
|
10
10
|
connectionId: string;
|
|
@@ -12,7 +12,9 @@ export interface LocalVuuServerOptions {
|
|
|
12
12
|
}
|
|
13
13
|
/**
|
|
14
14
|
* Simulates a Vuu server in the browser, publishing the tables of the given
|
|
15
|
-
* modules.
|
|
15
|
+
* modules. Module instances are resolved from this server, not by name from
|
|
16
|
+
* the global registry, so servers can each have their own instance of a
|
|
17
|
+
* module (e.g. NOTIFICATIONS). Pass the result to a local-mode `AuthenticationProvider` as one of
|
|
16
18
|
* its `localServers`.
|
|
17
19
|
*/
|
|
18
20
|
export declare const createLocalVuuServer: ({ connectionId, modules, }: LocalVuuServerOptions) => LocalVuuServer;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { TableSchema } from "@vuu-ui/vuu-data-types";
|
|
2
|
+
import type { VuuRowDataItemType } from "@vuu-ui/vuu-protocol-types";
|
|
2
3
|
import { type RpcService, VuuModule } from "../core/module/VuuModule";
|
|
3
4
|
import type { PermissionFunction } from "../core/filter/PermissionFilter";
|
|
4
5
|
import { type Table } from "../Table";
|
|
@@ -13,6 +14,20 @@ export interface NotificationsProvider {
|
|
|
13
14
|
stop: () => void;
|
|
14
15
|
}
|
|
15
16
|
export type NotificationsProviderFactory = (table: Table) => NotificationsProvider;
|
|
17
|
+
/**
|
|
18
|
+
* A notification to publish. Values are keyed by column name; columns not
|
|
19
|
+
* supplied are defaulted. `expiryTime` (epoch ms) schedules deletion of the row.
|
|
20
|
+
*/
|
|
21
|
+
export interface NotificationInput {
|
|
22
|
+
id?: string;
|
|
23
|
+
type?: string;
|
|
24
|
+
expiryTime?: number;
|
|
25
|
+
title?: string;
|
|
26
|
+
message?: string;
|
|
27
|
+
level?: string;
|
|
28
|
+
audience?: string;
|
|
29
|
+
[columnName: string]: VuuRowDataItemType | undefined;
|
|
30
|
+
}
|
|
16
31
|
export type NotificationsServiceFactory = (table: Table, module: NotificationModule) => RpcService[];
|
|
17
32
|
/**
|
|
18
33
|
* A generic Notifications module, exposing a single 'notifications' table.
|
|
@@ -27,6 +42,12 @@ export declare class NotificationModule extends VuuModule<NotificationsTableName
|
|
|
27
42
|
static readonly TABLE_NAME: "notifications";
|
|
28
43
|
constructor(providerFactory: NotificationsProviderFactory, permissionFunction: PermissionFunction, serviceFactory: NotificationsServiceFactory, ...additionalColumns: ColumnDefinition[]);
|
|
29
44
|
protected beforeCreateDataSource(): void;
|
|
45
|
+
/**
|
|
46
|
+
* Inserts a notification row, as a server-side publisher would. Defaults:
|
|
47
|
+
* a random `id`, `type` "toast", `level` "INFO", `audience` "all" and
|
|
48
|
+
* empty strings for other string columns. Returns the row id.
|
|
49
|
+
*/
|
|
50
|
+
publish(notification?: NotificationInput): string;
|
|
30
51
|
get isRunning(): boolean;
|
|
31
52
|
start(): void;
|
|
32
53
|
stop(): void;
|
|
@@ -1,2 +1,9 @@
|
|
|
1
1
|
import { NotificationModule } from "../NotificationModule";
|
|
2
|
-
export
|
|
2
|
+
export interface SimulatedNotificationsModuleOptions {
|
|
3
|
+
/**
|
|
4
|
+
* Generate random notifications. When false, notifications are only
|
|
5
|
+
* created by calls to `publish`. Default true.
|
|
6
|
+
*/
|
|
7
|
+
simulate?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare const SimulatedNotificationsModule: ({ simulate, }?: SimulatedNotificationsModuleOptions) => NotificationModule;
|