@journeyapps-labs/reactor-mod-data-browser 3.2.0 → 3.3.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 +12 -0
- package/dist/@types/core/AbstractConnection.d.ts +12 -0
- package/dist/@types/core/query/widgets/SmartColumnWidget.d.ts +1 -1
- package/dist/@types/core/types/ManualConnection.d.ts +1 -0
- package/dist/@types/entities/ConnectionEntityDefinition.d.ts +2 -1
- package/dist/@types/forms/types/shared/ui.d.ts +12 -0
- package/dist/@types/panels/query/QueryPanelFactory.d.ts +2 -2
- package/dist/core/AbstractConnection.js +58 -5
- package/dist/core/AbstractConnection.js.map +1 -1
- package/dist/core/query/query-simple/SimpleQueryColumns.js +1 -1
- package/dist/core/query/widgets/SmartColumnWidget.js +4 -1
- package/dist/core/query/widgets/SmartColumnWidget.js.map +1 -1
- package/dist/core/types/ManualConnection.js +3 -0
- package/dist/core/types/ManualConnection.js.map +1 -1
- package/dist/entities/ConnectionEntityDefinition.js +29 -6
- package/dist/entities/ConnectionEntityDefinition.js.map +1 -1
- package/dist/panels/model-json/ModelJsonPanelWidget.js +4 -3
- package/dist/panels/model-json/ModelJsonPanelWidget.js.map +1 -1
- package/dist/panels/query/QueryPanelFactory.js.map +1 -1
- package/dist/stores/ConnectionStore.js +15 -3
- package/dist/stores/ConnectionStore.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist-module/bundle.js +34 -34
- package/dist-module/bundle.js.map +1 -1
- package/package.json +4 -4
- package/src/core/AbstractConnection.ts +45 -2
- package/src/core/query/query-simple/SimpleQueryColumns.tsx +1 -1
- package/src/core/query/widgets/SmartColumnWidget.tsx +6 -5
- package/src/core/types/ManualConnection.ts +4 -0
- package/src/entities/ConnectionEntityDefinition.tsx +32 -4
- package/src/panels/model-json/ModelJsonPanelWidget.tsx +8 -6
- package/src/panels/query/QueryPanelFactory.tsx +2 -2
- package/src/stores/ConnectionStore.ts +17 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@journeyapps-labs/reactor-mod-data-browser",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.0",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"typings": "./dist/@types/index",
|
|
6
6
|
"publishConfig": {
|
|
@@ -21,8 +21,8 @@
|
|
|
21
21
|
"@journeyapps-labs/common-sdk": "^1.0.3",
|
|
22
22
|
"@journeyapps-labs/common-utils": "^1.0.1",
|
|
23
23
|
"@journeyapps-labs/lib-reactor-data-layer": "1.0.10",
|
|
24
|
-
"@journeyapps-labs/reactor-mod": "5.1
|
|
25
|
-
"@journeyapps-labs/reactor-mod-editor": "2.1
|
|
24
|
+
"@journeyapps-labs/reactor-mod": "5.3.1",
|
|
25
|
+
"@journeyapps-labs/reactor-mod-editor": "2.2.1",
|
|
26
26
|
"@journeyapps/db": "^8.1.1",
|
|
27
27
|
"@journeyapps/parser-schema": "^8.2.5",
|
|
28
28
|
"@projectstorm/react-workspaces-core": "4.2.3",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"uuid": "^13.0.0"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
|
-
"@journeyapps-labs/lib-reactor-builder": "
|
|
37
|
+
"@journeyapps-labs/lib-reactor-builder": "3.0.1",
|
|
38
38
|
"@types/async": "^3.2.25",
|
|
39
39
|
"@types/lodash": "^4.17.24",
|
|
40
40
|
"@types/react": "^19.2.14",
|
|
@@ -7,7 +7,7 @@ import { v4 } from 'uuid';
|
|
|
7
7
|
import { BaseObserver } from '@journeyapps-labs/common-utils';
|
|
8
8
|
import { Collection, LifecycleCollection } from '@journeyapps-labs/lib-reactor-data-layer';
|
|
9
9
|
import { when } from 'mobx';
|
|
10
|
-
import { observable } from 'mobx';
|
|
10
|
+
import { computed, observable } from 'mobx';
|
|
11
11
|
import { EntityDescription } from '@journeyapps-labs/reactor-mod';
|
|
12
12
|
import { V4BackendClient, V4Index, V4Indexes } from '@journeyapps-labs/client-backend-v4';
|
|
13
13
|
import { SchemaModelObject } from './SchemaModelObject';
|
|
@@ -24,18 +24,27 @@ export interface AbstractConnectionListener {
|
|
|
24
24
|
removed: () => any;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
+
export enum ConnectionOnlineState {
|
|
28
|
+
OFFLINE = 'offline',
|
|
29
|
+
LOADING = 'loading',
|
|
30
|
+
ONLINE = 'online'
|
|
31
|
+
}
|
|
32
|
+
|
|
27
33
|
export abstract class AbstractConnection extends BaseObserver<AbstractConnectionListener> {
|
|
28
34
|
id: string;
|
|
29
35
|
@observable accessor color: string;
|
|
36
|
+
@observable accessor onlineState: ConnectionOnlineState;
|
|
30
37
|
|
|
31
38
|
schema_models_collection: Collection<ObjectType>;
|
|
32
39
|
schema_models: LifecycleCollection<ObjectType, SchemaModelDefinition>;
|
|
33
40
|
private fetch_indexes_promise: Promise<V4Indexes['models']>;
|
|
41
|
+
private initialize_online_promise: Promise<void>;
|
|
34
42
|
|
|
35
43
|
constructor(public factory: AbstractConnectionFactory) {
|
|
36
44
|
super();
|
|
37
45
|
this.id = v4();
|
|
38
46
|
this.color = getDefaultConnectionColor(this.id);
|
|
47
|
+
this.onlineState = ConnectionOnlineState.OFFLINE;
|
|
39
48
|
this.schema_models_collection = new Collection();
|
|
40
49
|
this.schema_models = new LifecycleCollection({
|
|
41
50
|
collection: this.schema_models_collection,
|
|
@@ -88,7 +97,16 @@ export abstract class AbstractConnection extends BaseObserver<AbstractConnection
|
|
|
88
97
|
return this.schema_models.items.find((i) => i.definition.name === name);
|
|
89
98
|
}
|
|
90
99
|
|
|
100
|
+
@computed get isOnline() {
|
|
101
|
+
return this.onlineState === ConnectionOnlineState.ONLINE;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
@computed get isLoadingOnline() {
|
|
105
|
+
return this.onlineState === ConnectionOnlineState.LOADING;
|
|
106
|
+
}
|
|
107
|
+
|
|
91
108
|
async waitForSchemaModelDefinitionByName(name: string) {
|
|
109
|
+
await this.ensureOnline();
|
|
92
110
|
await when(() => !!this.getSchemaModelDefinitionByName(name));
|
|
93
111
|
return this.getSchemaModelDefinitionByName(name);
|
|
94
112
|
}
|
|
@@ -107,10 +125,35 @@ export abstract class AbstractConnection extends BaseObserver<AbstractConnection
|
|
|
107
125
|
});
|
|
108
126
|
}
|
|
109
127
|
|
|
110
|
-
async init() {
|
|
128
|
+
async init() {}
|
|
129
|
+
|
|
130
|
+
protected async connectOnline() {
|
|
111
131
|
await this.reload();
|
|
112
132
|
}
|
|
113
133
|
|
|
134
|
+
async ensureOnline() {
|
|
135
|
+
if (this.isOnline) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (!this.initialize_online_promise) {
|
|
139
|
+
this.initialize_online_promise = this.initializeOnline();
|
|
140
|
+
}
|
|
141
|
+
await this.initialize_online_promise;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private async initializeOnline() {
|
|
145
|
+
this.onlineState = ConnectionOnlineState.LOADING;
|
|
146
|
+
try {
|
|
147
|
+
await this.connectOnline();
|
|
148
|
+
this.onlineState = ConnectionOnlineState.ONLINE;
|
|
149
|
+
} finally {
|
|
150
|
+
if (this.onlineState === ConnectionOnlineState.LOADING) {
|
|
151
|
+
this.onlineState = ConnectionOnlineState.OFFLINE;
|
|
152
|
+
}
|
|
153
|
+
this.initialize_online_promise = null;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
114
157
|
protected async getSchemaModelDefinitions() {
|
|
115
158
|
const schema = await this.getSchema();
|
|
116
159
|
return _.map(schema.objects, (o) => {
|
|
@@ -27,7 +27,7 @@ export const buildSimpleQueryColumns = (options: BuildSimpleQueryColumnsOptions)
|
|
|
27
27
|
if (!direction) {
|
|
28
28
|
return label;
|
|
29
29
|
}
|
|
30
|
-
return `${label} ${direction === SortDirection.ASC ? '
|
|
30
|
+
return `${label} ${direction === SortDirection.ASC ? '↓' : '↑'}`;
|
|
31
31
|
};
|
|
32
32
|
|
|
33
33
|
return [
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import styled from '@emotion/styled';
|
|
3
|
-
import { ObjectType,
|
|
3
|
+
import { ObjectType, Variable } from '@journeyapps/db';
|
|
4
4
|
import { ColumnDisplayWidget } from './ColumnDisplayWidget';
|
|
5
|
-
import {
|
|
5
|
+
import { SmartFilterWidget } from './SmartFilterWidget';
|
|
6
6
|
import { SimpleFilter } from '../filters';
|
|
7
|
-
import {
|
|
8
|
-
import type { SortDirection } from '../query-simple/SimpleQuery';
|
|
7
|
+
import { SortDirection } from '../query-simple/SimpleQuery';
|
|
9
8
|
|
|
10
9
|
export interface SmartColumnWidgetProps {
|
|
11
10
|
variable: Variable;
|
|
@@ -18,7 +17,9 @@ export interface SmartColumnWidgetProps {
|
|
|
18
17
|
|
|
19
18
|
export const SmartColumnWidget: React.FC<SmartColumnWidgetProps> = (props) => {
|
|
20
19
|
const baseLabel = props.variable.label || props.variable.name;
|
|
21
|
-
const displayLabel = props.sortDirection
|
|
20
|
+
const displayLabel = props.sortDirection
|
|
21
|
+
? `${baseLabel} ${props.sortDirection === SortDirection.ASC ? '↓' : '↑'}`
|
|
22
|
+
: baseLabel;
|
|
22
23
|
let display = <ColumnDisplayWidget label={displayLabel} onClick={props.onToggleSort} />;
|
|
23
24
|
if (props.type) {
|
|
24
25
|
display = (
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
DescendantEntityProviderComponent,
|
|
3
|
+
DescendantLoadingEntityProviderComponent,
|
|
3
4
|
EntityCardsPresenterComponent,
|
|
4
5
|
EntityDefinition,
|
|
5
6
|
EntityDescriberComponent,
|
|
@@ -7,13 +8,17 @@ import {
|
|
|
7
8
|
inject,
|
|
8
9
|
InlineTreePresenterComponent,
|
|
9
10
|
SearchableTreeSearchScope,
|
|
10
|
-
SimpleEntitySearchEngineComponent
|
|
11
|
+
SimpleEntitySearchEngineComponent,
|
|
12
|
+
TreeBadgeWidget,
|
|
13
|
+
ThemeStore
|
|
11
14
|
} from '@journeyapps-labs/reactor-mod';
|
|
15
|
+
import * as React from 'react';
|
|
12
16
|
import { DataBrowserEntities } from '../entities';
|
|
13
17
|
import { ConnectionStore } from '../stores/ConnectionStore';
|
|
14
18
|
import { AbstractConnection } from '../core/AbstractConnection';
|
|
15
19
|
import { AddConnectionAction } from '../actions/connections/AddConnectionAction';
|
|
16
20
|
import { SavedQueryEntity, SavedQueryStore } from '../stores/SavedQueryStore';
|
|
21
|
+
import { SchemaModelDefinition } from '../core/SchemaModelDefinition';
|
|
17
22
|
|
|
18
23
|
export class ConnectionEntityDefinition extends EntityDefinition<AbstractConnection> {
|
|
19
24
|
@inject(ConnectionStore)
|
|
@@ -22,6 +27,9 @@ export class ConnectionEntityDefinition extends EntityDefinition<AbstractConnect
|
|
|
22
27
|
@inject(SavedQueryStore)
|
|
23
28
|
accessor savedQueryStore: SavedQueryStore;
|
|
24
29
|
|
|
30
|
+
@inject(ThemeStore)
|
|
31
|
+
accessor themeStore: ThemeStore;
|
|
32
|
+
|
|
25
33
|
constructor() {
|
|
26
34
|
super({
|
|
27
35
|
type: DataBrowserEntities.CONNECTION,
|
|
@@ -56,14 +64,30 @@ export class ConnectionEntityDefinition extends EntityDefinition<AbstractConnect
|
|
|
56
64
|
new InlineTreePresenterComponent<AbstractConnection>({
|
|
57
65
|
loadChildrenAsNodesAreOpened: true,
|
|
58
66
|
cacheTreeEntities: true,
|
|
59
|
-
searchScope: SearchableTreeSearchScope.VISIBLE_ONLY
|
|
67
|
+
searchScope: SearchableTreeSearchScope.VISIBLE_ONLY,
|
|
68
|
+
augmentTreeNodeProps: (entity) => {
|
|
69
|
+
if (!entity.isOnline) {
|
|
70
|
+
return {};
|
|
71
|
+
}
|
|
72
|
+
const theme = this.themeStore.getCurrentTheme();
|
|
73
|
+
return {
|
|
74
|
+
rightChildren: (
|
|
75
|
+
<TreeBadgeWidget
|
|
76
|
+
icon="bolt"
|
|
77
|
+
background={'transparent'}
|
|
78
|
+
iconColor={theme.status.success}
|
|
79
|
+
tooltip="Connection online"
|
|
80
|
+
/>
|
|
81
|
+
)
|
|
82
|
+
};
|
|
83
|
+
}
|
|
60
84
|
})
|
|
61
85
|
);
|
|
62
86
|
|
|
63
87
|
this.registerComponent(new EntityCardsPresenterComponent<AbstractConnection>());
|
|
64
88
|
|
|
65
89
|
this.registerComponent(
|
|
66
|
-
new
|
|
90
|
+
new DescendantLoadingEntityProviderComponent<AbstractConnection, SchemaModelDefinition>({
|
|
67
91
|
descendantType: DataBrowserEntities.SCHEMA_MODEL_DEFINITION,
|
|
68
92
|
generateOptions: (parent) => {
|
|
69
93
|
return {
|
|
@@ -71,7 +95,11 @@ export class ConnectionEntityDefinition extends EntityDefinition<AbstractConnect
|
|
|
71
95
|
label: 'Models',
|
|
72
96
|
icon: 'cube'
|
|
73
97
|
},
|
|
74
|
-
descendants: parent.schema_models.items
|
|
98
|
+
descendants: parent.schema_models.items,
|
|
99
|
+
loading: () => parent.isLoadingOnline,
|
|
100
|
+
refreshDescendants: async () => {
|
|
101
|
+
await parent.ensureOnline();
|
|
102
|
+
}
|
|
75
103
|
};
|
|
76
104
|
}
|
|
77
105
|
})
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
-
import { useEffect, useState } from 'react';
|
|
2
|
+
import { JSX, useEffect, useState } from 'react';
|
|
3
3
|
import { observer } from 'mobx-react';
|
|
4
4
|
import styled from '@emotion/styled';
|
|
5
5
|
import { BorderLayoutWidget, LoadingPanelWidget, PanelToolbarWidget } from '@journeyapps-labs/reactor-mod';
|
|
6
|
-
import {
|
|
6
|
+
import { copyTextToClipboard, saveFile } from '@journeyapps-labs/lib-reactor-utils';
|
|
7
7
|
import { ModelJsonPanelModel } from './ModelJsonPanelFactory';
|
|
8
8
|
import { SimpleEditorWidget } from '@journeyapps-labs/reactor-mod-editor';
|
|
9
9
|
|
|
@@ -25,7 +25,7 @@ namespace S {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
export const ModelJsonPanelWidget: React.FC<QueryPanelWidgetProps> = observer((props) => {
|
|
28
|
-
const [json, setJson] = useState(null);
|
|
28
|
+
const [json, setJson] = useState<string | null>(null);
|
|
29
29
|
|
|
30
30
|
useEffect(() => {
|
|
31
31
|
if (!props.model?.model?.data) {
|
|
@@ -39,8 +39,8 @@ export const ModelJsonPanelWidget: React.FC<QueryPanelWidgetProps> = observer((p
|
|
|
39
39
|
}
|
|
40
40
|
}, [props.model.model?.data]);
|
|
41
41
|
|
|
42
|
-
let top
|
|
43
|
-
if (props.model.model) {
|
|
42
|
+
let top: JSX.Element;
|
|
43
|
+
if (props.model.model && json) {
|
|
44
44
|
top = (
|
|
45
45
|
<PanelToolbarWidget
|
|
46
46
|
btns={[
|
|
@@ -67,6 +67,8 @@ export const ModelJsonPanelWidget: React.FC<QueryPanelWidgetProps> = observer((p
|
|
|
67
67
|
label: 'ID',
|
|
68
68
|
value: props.model?.id
|
|
69
69
|
},
|
|
70
|
+
|
|
71
|
+
// @ts-ignore FIXME, this can take null
|
|
70
72
|
props.model?.field
|
|
71
73
|
? {
|
|
72
74
|
label: 'Field',
|
|
@@ -83,7 +85,7 @@ export const ModelJsonPanelWidget: React.FC<QueryPanelWidgetProps> = observer((p
|
|
|
83
85
|
{() => {
|
|
84
86
|
return (
|
|
85
87
|
<BorderLayoutWidget top={top}>
|
|
86
|
-
<S.SimpleEditor lang="application/json" path={`${props.model.model.id}`} text={json} />
|
|
88
|
+
<S.SimpleEditor lang="application/json" path={`${props.model.model.id}`} text={json!} />
|
|
87
89
|
</BorderLayoutWidget>
|
|
88
90
|
);
|
|
89
91
|
}}
|
|
@@ -4,7 +4,7 @@ import { QueryPanelWidget } from './QueryPanelWidget';
|
|
|
4
4
|
import { AbstractQuery } from '../../core/query/AbstractQuery';
|
|
5
5
|
import { ConnectionStore } from '../../stores/ConnectionStore';
|
|
6
6
|
import { observable } from 'mobx';
|
|
7
|
-
import { WorkspaceModelFactoryEvent } from '@projectstorm/react-workspaces-core';
|
|
7
|
+
import { WorkspaceEngine, WorkspaceModelFactoryEvent } from '@projectstorm/react-workspaces-core';
|
|
8
8
|
import { AbstractSerializableQuery } from '../../core/query/AbstractSerializableQuery';
|
|
9
9
|
import { SavedQueryStore } from '../../stores/SavedQueryStore';
|
|
10
10
|
import { AbstractConnection } from '../../core/AbstractConnection';
|
|
@@ -48,7 +48,7 @@ export class QueryPanelModel extends ReactorPanelModel {
|
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
50
|
|
|
51
|
-
fromArray(data: ReturnType<this['toArray']>, engine) {
|
|
51
|
+
fromArray(data: ReturnType<this['toArray']>, engine: WorkspaceEngine) {
|
|
52
52
|
super.fromArray(data, engine);
|
|
53
53
|
this.current_page = data.current_page || 0;
|
|
54
54
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AbstractStore, LocalStorageSerializer } from '@journeyapps-labs/reactor-mod';
|
|
2
2
|
import { AbstractConnection, AbstractConnectionSerialized } from '../core/AbstractConnection';
|
|
3
|
-
import {
|
|
3
|
+
import { computed, observable, runInAction, when } from 'mobx';
|
|
4
4
|
import { AbstractConnectionFactory } from '../core/AbstractConnectionFactory';
|
|
5
5
|
import { getDefaultConnectionColor } from '../core/connection-colors';
|
|
6
6
|
|
|
@@ -51,9 +51,18 @@ export class ConnectionStore extends AbstractStore<ConnectionStoreSerialized> {
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
async deserializeConnection(data: AbstractConnectionSerialized) {
|
|
54
|
-
let conn = this._connectionFactories.get(data.factory)
|
|
54
|
+
let conn = this._connectionFactories.get(data.factory)?.generateConnection();
|
|
55
|
+
if (!conn) {
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
55
59
|
conn.id = data.id;
|
|
56
|
-
|
|
60
|
+
try {
|
|
61
|
+
await conn._deSerialize(data.payload);
|
|
62
|
+
} catch (ex) {
|
|
63
|
+
this.logger.error(`Failed to deserialize connection: [${conn.id}]`, ex);
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
57
66
|
conn.color = data.color || getDefaultConnectionColor(conn.id);
|
|
58
67
|
return conn;
|
|
59
68
|
}
|
|
@@ -66,9 +75,11 @@ export class ConnectionStore extends AbstractStore<ConnectionStoreSerialized> {
|
|
|
66
75
|
return this.deserializeConnection(connSer);
|
|
67
76
|
})
|
|
68
77
|
);
|
|
69
|
-
connections
|
|
70
|
-
|
|
71
|
-
|
|
78
|
+
connections
|
|
79
|
+
.filter((c) => !!c)
|
|
80
|
+
.forEach((c) => {
|
|
81
|
+
this.addConnection(c);
|
|
82
|
+
});
|
|
72
83
|
});
|
|
73
84
|
}
|
|
74
85
|
|