@journeyapps-labs/reactor-mod-data-browser 0.0.0-dev-20250825225306

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.
Files changed (138) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/README.md +3 -0
  3. package/dist/@types/DataBrowserModule.d.ts +7 -0
  4. package/dist/@types/actions/connections/AddConnectionAction.d.ts +10 -0
  5. package/dist/@types/actions/connections/RemoveConnectionAction.d.ts +10 -0
  6. package/dist/@types/actions/schema-definitions/CreateModelAction.d.ts +9 -0
  7. package/dist/@types/actions/schema-definitions/QuerySchemaModelAction.d.ts +9 -0
  8. package/dist/@types/actions/schema-model/EditSchemaModelAction.d.ts +9 -0
  9. package/dist/@types/core/AbstractConnection.d.ts +34 -0
  10. package/dist/@types/core/AbstractConnectionFactory.d.ts +11 -0
  11. package/dist/@types/core/SchemaModelDefinition.d.ts +20 -0
  12. package/dist/@types/core/SchemaModelObject.d.ts +16 -0
  13. package/dist/@types/core/query/AbstractQuery.d.ts +22 -0
  14. package/dist/@types/core/query/Page.d.ts +24 -0
  15. package/dist/@types/core/query/SimpleQuery.d.ts +37 -0
  16. package/dist/@types/core/types/ManualConnection.d.ts +15 -0
  17. package/dist/@types/core/types/ManualConnectionFactory.d.ts +9 -0
  18. package/dist/@types/entities/ConnectionEntityDefinition.d.ts +9 -0
  19. package/dist/@types/entities/ConnectionFactoryEntityDefinition.d.ts +9 -0
  20. package/dist/@types/entities/QueryEntityDefinition.d.ts +9 -0
  21. package/dist/@types/entities/SchemaModelDefinitionEntityDefinition.d.ts +13 -0
  22. package/dist/@types/entities/SchemaModelObjectEntityDefinition.d.ts +14 -0
  23. package/dist/@types/entities.d.ts +7 -0
  24. package/dist/@types/forms/APIConnectionForm.d.ts +12 -0
  25. package/dist/@types/forms/SchemaModelForm.d.ts +11 -0
  26. package/dist/@types/forms/inputs/LocationInput.d.ts +13 -0
  27. package/dist/@types/index.d.ts +25 -0
  28. package/dist/@types/panels/model/ModelPanelFactory.d.ts +28 -0
  29. package/dist/@types/panels/model/ModelPanelWidget.d.ts +6 -0
  30. package/dist/@types/panels/query/PageResultsWidget.d.ts +8 -0
  31. package/dist/@types/panels/query/QueryPanelFactory.d.ts +33 -0
  32. package/dist/@types/panels/query/QueryPanelWidget.d.ts +6 -0
  33. package/dist/@types/panels/query/TableControlsWidget.d.ts +10 -0
  34. package/dist/@types/stores/ConnectionStore.d.ts +20 -0
  35. package/dist/DataBrowserModule.js +45 -0
  36. package/dist/DataBrowserModule.js.map +1 -0
  37. package/dist/actions/connections/AddConnectionAction.js +48 -0
  38. package/dist/actions/connections/AddConnectionAction.js.map +1 -0
  39. package/dist/actions/connections/RemoveConnectionAction.js +43 -0
  40. package/dist/actions/connections/RemoveConnectionAction.js.map +1 -0
  41. package/dist/actions/schema-definitions/CreateModelAction.js +45 -0
  42. package/dist/actions/schema-definitions/CreateModelAction.js.map +1 -0
  43. package/dist/actions/schema-definitions/QuerySchemaModelAction.js +47 -0
  44. package/dist/actions/schema-definitions/QuerySchemaModelAction.js.map +1 -0
  45. package/dist/actions/schema-model/EditSchemaModelAction.js +46 -0
  46. package/dist/actions/schema-model/EditSchemaModelAction.js.map +1 -0
  47. package/dist/core/AbstractConnection.js +71 -0
  48. package/dist/core/AbstractConnection.js.map +1 -0
  49. package/dist/core/AbstractConnectionFactory.js +6 -0
  50. package/dist/core/AbstractConnectionFactory.js.map +1 -0
  51. package/dist/core/SchemaModelDefinition.js +31 -0
  52. package/dist/core/SchemaModelDefinition.js.map +1 -0
  53. package/dist/core/SchemaModelObject.js +51 -0
  54. package/dist/core/SchemaModelObject.js.map +1 -0
  55. package/dist/core/query/AbstractQuery.js +18 -0
  56. package/dist/core/query/AbstractQuery.js.map +1 -0
  57. package/dist/core/query/Page.js +65 -0
  58. package/dist/core/query/Page.js.map +1 -0
  59. package/dist/core/query/SimpleQuery.js +197 -0
  60. package/dist/core/query/SimpleQuery.js.map +1 -0
  61. package/dist/core/types/ManualConnection.js +23 -0
  62. package/dist/core/types/ManualConnection.js.map +1 -0
  63. package/dist/core/types/ManualConnectionFactory.js +50 -0
  64. package/dist/core/types/ManualConnectionFactory.js.map +1 -0
  65. package/dist/entities/ConnectionEntityDefinition.js +75 -0
  66. package/dist/entities/ConnectionEntityDefinition.js.map +1 -0
  67. package/dist/entities/ConnectionFactoryEntityDefinition.js +60 -0
  68. package/dist/entities/ConnectionFactoryEntityDefinition.js.map +1 -0
  69. package/dist/entities/QueryEntityDefinition.js +60 -0
  70. package/dist/entities/QueryEntityDefinition.js.map +1 -0
  71. package/dist/entities/SchemaModelDefinitionEntityDefinition.js +76 -0
  72. package/dist/entities/SchemaModelDefinitionEntityDefinition.js.map +1 -0
  73. package/dist/entities/SchemaModelObjectEntityDefinition.js +76 -0
  74. package/dist/entities/SchemaModelObjectEntityDefinition.js.map +1 -0
  75. package/dist/entities.js +9 -0
  76. package/dist/entities.js.map +1 -0
  77. package/dist/forms/APIConnectionForm.js +31 -0
  78. package/dist/forms/APIConnectionForm.js.map +1 -0
  79. package/dist/forms/SchemaModelForm.js +87 -0
  80. package/dist/forms/SchemaModelForm.js.map +1 -0
  81. package/dist/forms/inputs/LocationInput.js +74 -0
  82. package/dist/forms/inputs/LocationInput.js.map +1 -0
  83. package/dist/index.js +26 -0
  84. package/dist/index.js.map +1 -0
  85. package/dist/panels/model/ModelPanelFactory.js +94 -0
  86. package/dist/panels/model/ModelPanelFactory.js.map +1 -0
  87. package/dist/panels/model/ModelPanelWidget.js +46 -0
  88. package/dist/panels/model/ModelPanelWidget.js.map +1 -0
  89. package/dist/panels/query/PageResultsWidget.js +24 -0
  90. package/dist/panels/query/PageResultsWidget.js.map +1 -0
  91. package/dist/panels/query/QueryPanelFactory.js +94 -0
  92. package/dist/panels/query/QueryPanelFactory.js.map +1 -0
  93. package/dist/panels/query/QueryPanelWidget.js +41 -0
  94. package/dist/panels/query/QueryPanelWidget.js.map +1 -0
  95. package/dist/panels/query/TableControlsWidget.js +52 -0
  96. package/dist/panels/query/TableControlsWidget.js.map +1 -0
  97. package/dist/stores/ConnectionStore.js +93 -0
  98. package/dist/stores/ConnectionStore.js.map +1 -0
  99. package/dist/tsconfig.tsbuildinfo +1 -0
  100. package/dist-module/bundle.js +49 -0
  101. package/dist-module/bundle.js.LICENSE.txt +16 -0
  102. package/dist-module/bundle.js.map +1 -0
  103. package/package.json +41 -0
  104. package/reactor.config.json +4 -0
  105. package/src/DataBrowserModule.ts +54 -0
  106. package/src/actions/connections/AddConnectionAction.tsx +33 -0
  107. package/src/actions/connections/RemoveConnectionAction.tsx +28 -0
  108. package/src/actions/schema-definitions/CreateModelAction.ts +32 -0
  109. package/src/actions/schema-definitions/QuerySchemaModelAction.ts +36 -0
  110. package/src/actions/schema-model/EditSchemaModelAction.ts +33 -0
  111. package/src/core/AbstractConnection.ts +104 -0
  112. package/src/core/AbstractConnectionFactory.ts +14 -0
  113. package/src/core/SchemaModelDefinition.ts +44 -0
  114. package/src/core/SchemaModelObject.ts +46 -0
  115. package/src/core/query/AbstractQuery.ts +43 -0
  116. package/src/core/query/Page.ts +59 -0
  117. package/src/core/query/SimpleQuery.tsx +218 -0
  118. package/src/core/types/ManualConnection.ts +35 -0
  119. package/src/core/types/ManualConnectionFactory.tsx +36 -0
  120. package/src/entities/ConnectionEntityDefinition.tsx +79 -0
  121. package/src/entities/ConnectionFactoryEntityDefinition.tsx +54 -0
  122. package/src/entities/QueryEntityDefinition.ts +46 -0
  123. package/src/entities/SchemaModelDefinitionEntityDefinition.ts +82 -0
  124. package/src/entities/SchemaModelObjectEntityDefinition.ts +78 -0
  125. package/src/entities.ts +7 -0
  126. package/src/forms/APIConnectionForm.tsx +48 -0
  127. package/src/forms/SchemaModelForm.tsx +116 -0
  128. package/src/forms/inputs/LocationInput.tsx +104 -0
  129. package/src/index.ts +27 -0
  130. package/src/panels/model/ModelPanelFactory.tsx +78 -0
  131. package/src/panels/model/ModelPanelWidget.tsx +76 -0
  132. package/src/panels/query/PageResultsWidget.tsx +52 -0
  133. package/src/panels/query/QueryPanelFactory.tsx +76 -0
  134. package/src/panels/query/QueryPanelWidget.tsx +72 -0
  135. package/src/panels/query/TableControlsWidget.tsx +85 -0
  136. package/src/stores/ConnectionStore.ts +87 -0
  137. package/tsconfig.json +14 -0
  138. package/webpack.config.js +9 -0
@@ -0,0 +1,218 @@
1
+ import { AbstractQuery, AbstractQueryEncoded } from './AbstractQuery';
2
+ import {
3
+ CheckboxWidget,
4
+ ImageMedia,
5
+ inject,
6
+ MetadataWidget,
7
+ SmartDateDisplayWidget,
8
+ styled,
9
+ TableColumn
10
+ } from '@journeyapps-labs/reactor-mod';
11
+ import { ConnectionStore } from '../../stores/ConnectionStore';
12
+ import * as db from '@journeyapps/db';
13
+ import { Attachment, Day, Location, Promise, Variable } from '@journeyapps/db';
14
+ import { Page, PageRow } from './Page';
15
+ import { SchemaModelDefinition } from '../SchemaModelDefinition';
16
+ import * as _ from 'lodash';
17
+ import * as React from 'react';
18
+ import { observable } from 'mobx';
19
+
20
+ export interface SimpleQueryOptions {
21
+ definition?: SchemaModelDefinition;
22
+ limit?: number;
23
+ }
24
+
25
+ export interface SimpleQueryEncoded extends AbstractQueryEncoded {
26
+ limit: number;
27
+ definition: string;
28
+ }
29
+
30
+ export class SimpleQuery extends AbstractQuery<SimpleQueryEncoded> {
31
+ @inject(ConnectionStore)
32
+ accessor connStore: ConnectionStore;
33
+
34
+ @observable
35
+ accessor _totalPages: number;
36
+
37
+ @observable
38
+ accessor _pages: Page[];
39
+
40
+ constructor(public options: SimpleQueryOptions = {}) {
41
+ super('simple', options.definition?.connection);
42
+ this._totalPages = 0;
43
+ this._pages = [];
44
+ }
45
+
46
+ async getCollection() {
47
+ let connection = await this.connection.getConnection();
48
+ return connection[this.options.definition.definition.name] as db.Collection;
49
+ }
50
+
51
+ async load() {
52
+ let collection = await this.getCollection();
53
+ let results = await (collection.adapter as any).doApiQuery(collection.all());
54
+ this._totalPages = Math.ceil(results.total / this.options.limit);
55
+ }
56
+
57
+ getPage(number: number): Page {
58
+ if (!this._pages[number]) {
59
+ let page = new Page({
60
+ offset: number * this.options.limit,
61
+ limit: this.options.limit,
62
+ collection: () => this.getCollection(),
63
+ definition: this.options.definition,
64
+ index: number
65
+ });
66
+ page.load();
67
+ this._pages[number] = page;
68
+ }
69
+ return this._pages[number];
70
+ }
71
+
72
+ get totalPages(): number {
73
+ return this._totalPages;
74
+ }
75
+
76
+ serialize(): SimpleQueryEncoded {
77
+ return {
78
+ ...super.serialize(),
79
+ definition: this.options.definition.definition.name,
80
+ limit: this.options.limit
81
+ };
82
+ }
83
+
84
+ async deserialize(connectionStore: ConnectionStore, data: SimpleQueryEncoded): Promise<void> {
85
+ await super.deserialize(connectionStore, data);
86
+ this.options.limit = data.limit;
87
+ this.options.definition = await this.connection.waitForSchemaModelDefinitionByName(data.definition);
88
+ }
89
+
90
+ getColumns(): TableColumn[] {
91
+ return [
92
+ {
93
+ key: 'id',
94
+ display: 'ID',
95
+ noWrap: true,
96
+ shrink: true
97
+ },
98
+ ..._.map(this.options.definition.definition.attributes, (a) => {
99
+ return {
100
+ key: a.name,
101
+ display: a.label,
102
+ noWrap: true,
103
+ shrink: true,
104
+ accessor: (cell, row: PageRow) => {
105
+ return <CellDisplayWidget variable={a} cell={cell} row={row} />;
106
+ }
107
+ } as TableColumn;
108
+ })
109
+ ];
110
+ }
111
+
112
+ getSimpleName(): string {
113
+ return `Query: ${this.options.definition.definition.label}`;
114
+ }
115
+ }
116
+
117
+ namespace S {
118
+ export const Empty = styled.div`
119
+ opacity: 0.2;
120
+ `;
121
+
122
+ export const Preview = styled.img`
123
+ max-height: 40px;
124
+ max-width: 40px;
125
+ cursor: pointer;
126
+ `;
127
+
128
+ export const pill = styled.div`
129
+ padding: 2px 4px;
130
+ background: ${(p) => p.theme.table.pills};
131
+ border-radius: 3px;
132
+ font-size: 12px;
133
+ `;
134
+
135
+ export const Pills = styled.div`
136
+ display: flex;
137
+ column-gap: 2px;
138
+ row-gap: 2px;
139
+ `;
140
+ }
141
+
142
+ export interface CellDisplayWidgetProps {
143
+ row: PageRow;
144
+ cell: any;
145
+ variable: Variable;
146
+ }
147
+
148
+ const MAX_NUMBER_OF_ARR_ITEMS_TO_DISPLAY = 3;
149
+
150
+ export const CellDisplayWidget: React.FC<CellDisplayWidgetProps> = (props) => {
151
+ const { row, cell, variable } = props;
152
+ if (cell == null) {
153
+ return <S.Empty>null</S.Empty>;
154
+ }
155
+ if (_.isString(cell)) {
156
+ if (cell.trim() === '') {
157
+ return <S.Empty>empty</S.Empty>;
158
+ }
159
+ return cell;
160
+ }
161
+ if (_.isNumber(cell)) {
162
+ return cell;
163
+ }
164
+ if (_.isArray(cell)) {
165
+ if (cell.length === 0) {
166
+ return <S.Empty>empty array</S.Empty>;
167
+ }
168
+
169
+ let items = _.slice(cell, 0, MAX_NUMBER_OF_ARR_ITEMS_TO_DISPLAY);
170
+
171
+ return (
172
+ <S.Pills>
173
+ {items.map((c) => {
174
+ return <S.pill key={c}>{c}</S.pill>;
175
+ })}
176
+ {items.length !== cell.length ? '...' : null}
177
+ </S.Pills>
178
+ );
179
+ }
180
+ if (cell instanceof Date) {
181
+ return <SmartDateDisplayWidget date={cell} />;
182
+ }
183
+ if (cell instanceof Day) {
184
+ return <SmartDateDisplayWidget date={cell.toDate()} />;
185
+ }
186
+ if (_.isBoolean(cell)) {
187
+ return <CheckboxWidget checked={cell} onChange={() => {}} />;
188
+ }
189
+ if (cell instanceof Location) {
190
+ return (
191
+ <>
192
+ <MetadataWidget label={'Lat'} value={`${cell.latitude}`} />
193
+ <MetadataWidget label={'Long'} value={`${cell.longitude}`} />
194
+ </>
195
+ );
196
+ }
197
+ if (cell instanceof Attachment) {
198
+ if (cell.uploaded()) {
199
+ return (
200
+ <S.Preview
201
+ onClick={() => {
202
+ row.model.getMedia(variable.name).then((media) => {
203
+ if (media instanceof ImageMedia) {
204
+ media.open();
205
+ } else {
206
+ window.open(cell.url(), '_blank');
207
+ }
208
+ });
209
+ }}
210
+ src={cell.urls['thumbnail']}
211
+ />
212
+ );
213
+ }
214
+ return <S.Empty>Not uploaded</S.Empty>;
215
+ }
216
+ console.log('unknown type', cell);
217
+ return null;
218
+ };
@@ -0,0 +1,35 @@
1
+ import { ApiCredentialOptions, Database } from '@journeyapps/db';
2
+ import { AbstractConnection } from '../AbstractConnection';
3
+ import { ManualConnectionFactory } from './ManualConnectionFactory';
4
+ import { EntityDescription } from '@journeyapps-labs/reactor-mod';
5
+
6
+ export interface ManualConnectionDetails extends ApiCredentialOptions {
7
+ name: string;
8
+ }
9
+
10
+ export class ManualConnection extends AbstractConnection {
11
+ constructor(
12
+ factory: ManualConnectionFactory,
13
+ protected options?: ManualConnectionDetails
14
+ ) {
15
+ super(factory);
16
+ }
17
+
18
+ getConnection(): Promise<Database> {
19
+ return Database.instance(this.options);
20
+ }
21
+
22
+ _serialize(): ManualConnectionDetails {
23
+ return this.options;
24
+ }
25
+
26
+ async _deSerialize(data: ManualConnectionDetails): Promise<any> {
27
+ this.options = data;
28
+ }
29
+
30
+ get name(): EntityDescription {
31
+ return {
32
+ simpleName: this.options.name
33
+ };
34
+ }
35
+ }
@@ -0,0 +1,36 @@
1
+ import { AbstractConnectionFactory } from '../AbstractConnectionFactory';
2
+ import { ManualConnection } from './ManualConnection';
3
+ import { DialogStore2, FormDialogDirective, inject } from '@journeyapps-labs/reactor-mod';
4
+ import { APIConnectionForm } from '../../forms/APIConnectionForm';
5
+
6
+ export class ManualConnectionFactory extends AbstractConnectionFactory<ManualConnection> {
7
+ @inject(DialogStore2)
8
+ accessor dialogStore: DialogStore2;
9
+
10
+ constructor() {
11
+ super({
12
+ key: 'MANUAL_CONNECTION',
13
+ label: 'API Token Connection'
14
+ });
15
+ }
16
+
17
+ async generateConnectionFromUI(): Promise<ManualConnection | null> {
18
+ let result = await this.dialogStore.showDialog(
19
+ new FormDialogDirective({
20
+ form: new APIConnectionForm(),
21
+ title: 'Create connection',
22
+
23
+ // FIXME remove when the fix in Reactor is merged: https://github.com/journeyapps-labs/reactor/pull/32
24
+ handler: async () => {}
25
+ })
26
+ );
27
+ if (result) {
28
+ return result.form.generateConnection(this);
29
+ }
30
+ return null;
31
+ }
32
+
33
+ generateConnection(): ManualConnection {
34
+ return new ManualConnection(this);
35
+ }
36
+ }
@@ -0,0 +1,79 @@
1
+ import {
2
+ DescendantEntityProviderComponent,
3
+ EntityDefinition,
4
+ EntityDescriberComponent,
5
+ EntityPanelComponent,
6
+ inject,
7
+ InlineTreePresenterComponent,
8
+ SimpleEntitySearchEngineComponent
9
+ } from '@journeyapps-labs/reactor-mod';
10
+ import { DataBrowserEntities } from '../entities';
11
+ import { ConnectionStore } from '../stores/ConnectionStore';
12
+ import { AbstractConnection } from '../core/AbstractConnection';
13
+ import { AddConnectionAction } from '../actions/connections/AddConnectionAction';
14
+
15
+ export class ConnectionEntityDefinition extends EntityDefinition<AbstractConnection> {
16
+ @inject(ConnectionStore)
17
+ accessor connectionStore: ConnectionStore;
18
+
19
+ constructor() {
20
+ super({
21
+ type: DataBrowserEntities.CONNECTION,
22
+ category: 'DataBrowser',
23
+ label: 'Connection',
24
+ icon: 'database',
25
+ iconColor: 'cyan'
26
+ });
27
+
28
+ this.registerComponent(
29
+ new EntityDescriberComponent<AbstractConnection>({
30
+ label: 'Simple',
31
+ describe: (entity: AbstractConnection) => {
32
+ return entity.name;
33
+ }
34
+ })
35
+ );
36
+
37
+ this.registerComponent(
38
+ new SimpleEntitySearchEngineComponent<AbstractConnection>({
39
+ label: 'Simple',
40
+ getEntities: async () => {
41
+ return this.connectionStore.connections;
42
+ }
43
+ })
44
+ );
45
+
46
+ this.registerComponent(new InlineTreePresenterComponent<AbstractConnection>());
47
+
48
+ this.registerComponent(
49
+ new DescendantEntityProviderComponent<AbstractConnection>({
50
+ descendantType: DataBrowserEntities.SCHEMA_MODEL_DEFINITION,
51
+ generateOptions: (parent) => {
52
+ return {
53
+ descendants: parent.schema_models.items
54
+ };
55
+ }
56
+ })
57
+ );
58
+
59
+ this.registerComponent(
60
+ new EntityPanelComponent<AbstractConnection>({
61
+ label: 'Connections',
62
+ getEntities: () => {
63
+ return this.connectionStore.connections;
64
+ },
65
+ additionalActions: [AddConnectionAction.ID]
66
+ })
67
+ );
68
+ }
69
+
70
+ matchEntity(t: any): boolean {
71
+ if (t instanceof AbstractConnection) {
72
+ return true;
73
+ }
74
+ }
75
+
76
+ getEntityUID(t: AbstractConnection) {
77
+ return t.id;
78
+ }
79
+ }
@@ -0,0 +1,54 @@
1
+ import {
2
+ EntityDefinition,
3
+ EntityDescriberComponent,
4
+ inject,
5
+ SimpleEntitySearchEngineComponent
6
+ } from '@journeyapps-labs/reactor-mod';
7
+ import { DataBrowserEntities } from '../entities';
8
+ import { ConnectionStore } from '../stores/ConnectionStore';
9
+ import { AbstractConnectionFactory } from '../core/AbstractConnectionFactory';
10
+
11
+ export class ConnectionFactoryEntityDefinition extends EntityDefinition<AbstractConnectionFactory> {
12
+ @inject(ConnectionStore)
13
+ accessor connectionStore: ConnectionStore;
14
+
15
+ constructor() {
16
+ super({
17
+ type: DataBrowserEntities.CONNECTION_FACTORY,
18
+ category: 'DataBrowser',
19
+ label: 'Connection type',
20
+ icon: 'database',
21
+ iconColor: 'blue'
22
+ });
23
+
24
+ this.registerComponent(
25
+ new EntityDescriberComponent<AbstractConnectionFactory>({
26
+ label: 'Simple',
27
+ describe: (entity: AbstractConnectionFactory) => {
28
+ return {
29
+ simpleName: entity.options.label
30
+ };
31
+ }
32
+ })
33
+ );
34
+
35
+ this.registerComponent(
36
+ new SimpleEntitySearchEngineComponent<AbstractConnectionFactory>({
37
+ label: 'Simple',
38
+ getEntities: async () => {
39
+ return this.connectionStore.connectionFactories;
40
+ }
41
+ })
42
+ );
43
+ }
44
+
45
+ matchEntity(t: any): boolean {
46
+ if (t instanceof AbstractConnectionFactory) {
47
+ return true;
48
+ }
49
+ }
50
+
51
+ getEntityUID(t: AbstractConnectionFactory) {
52
+ return t.options.key;
53
+ }
54
+ }
@@ -0,0 +1,46 @@
1
+ import { EntityDefinition, inject, InlineEntityEncoderComponent } from '@journeyapps-labs/reactor-mod';
2
+ import { DataBrowserEntities } from '../entities';
3
+ import { ConnectionStore } from '../stores/ConnectionStore';
4
+ import { AbstractQuery, AbstractQueryEncoded } from '../core/query/AbstractQuery';
5
+ import { SimpleQuery } from '../core/query/SimpleQuery';
6
+
7
+ export class QueryEntityDefinition extends EntityDefinition<AbstractQuery> {
8
+ @inject(ConnectionStore)
9
+ accessor connectionStore: ConnectionStore;
10
+
11
+ constructor() {
12
+ super({
13
+ type: DataBrowserEntities.QUERY,
14
+ category: 'DataBrowser',
15
+ label: 'Query',
16
+ icon: 'search',
17
+ iconColor: 'red'
18
+ });
19
+
20
+ this.registerComponent(
21
+ new InlineEntityEncoderComponent<AbstractQuery, AbstractQueryEncoded>({
22
+ version: 1,
23
+ encode: (e) => {
24
+ return e.serialize();
25
+ },
26
+ decode: async (entity) => {
27
+ if (entity.type === 'simple') {
28
+ let query = new SimpleQuery();
29
+ await query.deserialize(this.connectionStore, entity as any);
30
+ return query;
31
+ }
32
+ }
33
+ })
34
+ );
35
+ }
36
+
37
+ matchEntity(t: any): boolean {
38
+ if (t instanceof AbstractQuery) {
39
+ return true;
40
+ }
41
+ }
42
+
43
+ getEntityUID(t: AbstractQuery) {
44
+ return t.id;
45
+ }
46
+ }
@@ -0,0 +1,82 @@
1
+ import {
2
+ EntityDefinition,
3
+ EntityDescriberComponent,
4
+ inject,
5
+ InlineEntityEncoderComponent,
6
+ InlineTreePresenterComponent,
7
+ SimpleParentEntitySearchEngine
8
+ } from '@journeyapps-labs/reactor-mod';
9
+ import { DataBrowserEntities } from '../entities';
10
+ import { ConnectionStore } from '../stores/ConnectionStore';
11
+ import { AbstractConnection } from '../core/AbstractConnection';
12
+ import { SchemaModelDefinition } from '../core/SchemaModelDefinition';
13
+
14
+ export interface SchemaModelDefinitionEntityDefinitionEncoded {
15
+ connection_id: string;
16
+ type: string;
17
+ }
18
+
19
+ export class SchemaModelDefinitionEntityDefinition extends EntityDefinition<SchemaModelDefinition> {
20
+ @inject(ConnectionStore)
21
+ accessor connectionStore: ConnectionStore;
22
+
23
+ constructor() {
24
+ super({
25
+ type: DataBrowserEntities.SCHEMA_MODEL_DEFINITION,
26
+ category: 'DataBrowser',
27
+ label: 'Schema model definition',
28
+ icon: 'cube',
29
+ iconColor: 'mediumpurple'
30
+ });
31
+
32
+ this.registerComponent(
33
+ new EntityDescriberComponent<SchemaModelDefinition>({
34
+ label: 'Simple',
35
+ describe: (entity: SchemaModelDefinition) => {
36
+ return {
37
+ simpleName: entity.definition.label,
38
+ complexName: entity.definition.name
39
+ };
40
+ }
41
+ })
42
+ );
43
+
44
+ this.registerComponent(
45
+ new InlineEntityEncoderComponent<SchemaModelDefinition, SchemaModelDefinitionEntityDefinitionEncoded>({
46
+ version: 1,
47
+ encode: (e) => {
48
+ return {
49
+ connection_id: e.connection.id,
50
+ type: e.definition.name
51
+ };
52
+ },
53
+ decode: async (entity) => {
54
+ let connection = await this.connectionStore.waitForReadyForConnection(entity.connection_id);
55
+ return connection.waitForSchemaModelDefinitionByName(entity.type);
56
+ }
57
+ })
58
+ );
59
+
60
+ this.registerComponent(new InlineTreePresenterComponent());
61
+
62
+ this.registerComponent(
63
+ new SimpleParentEntitySearchEngine<AbstractConnection, SchemaModelDefinition>({
64
+ label: 'Simple',
65
+ type: DataBrowserEntities.CONNECTION,
66
+ getEntities: async (event) => {
67
+ return event.parameters.parent.schema_models.items;
68
+ }
69
+ })
70
+ );
71
+ }
72
+
73
+ matchEntity(t: any): boolean {
74
+ if (t instanceof SchemaModelDefinition) {
75
+ return true;
76
+ }
77
+ }
78
+
79
+ getEntityUID(t: SchemaModelDefinition) {
80
+ return t.definition.name;
81
+ }
82
+ }
@@ -0,0 +1,78 @@
1
+ import {
2
+ EntityDefinition,
3
+ EntityDescriberComponent,
4
+ inject,
5
+ InlineEntityEncoderComponent,
6
+ InlineTreePresenterComponent
7
+ } from '@journeyapps-labs/reactor-mod';
8
+ import { DataBrowserEntities } from '../entities';
9
+ import { ConnectionStore } from '../stores/ConnectionStore';
10
+ import { SchemaModelObject } from '../core/SchemaModelObject';
11
+
12
+ export interface SchemaModelObjectEntityDefinitionEncoded {
13
+ connection_id: string;
14
+ type: string;
15
+ id: string;
16
+ }
17
+
18
+ export class SchemaModelObjectEntityDefinition extends EntityDefinition<SchemaModelObject> {
19
+ @inject(ConnectionStore)
20
+ accessor connectionStore: ConnectionStore;
21
+
22
+ constructor() {
23
+ super({
24
+ type: DataBrowserEntities.SCHEMA_MODEL_OBJECT,
25
+ category: 'DataBrowser',
26
+ label: 'Schema model',
27
+ icon: 'cube',
28
+ iconColor: 'mediumpurple'
29
+ });
30
+
31
+ this.registerComponent(
32
+ new EntityDescriberComponent<SchemaModelObject>({
33
+ label: 'Simple',
34
+ describe: (entity: SchemaModelObject) => {
35
+ return {
36
+ simpleName: entity.model.id,
37
+ complexName: entity.definition.definition.label
38
+ };
39
+ }
40
+ })
41
+ );
42
+
43
+ this.registerComponent(
44
+ new InlineEntityEncoderComponent<SchemaModelObject, SchemaModelObjectEntityDefinitionEncoded>({
45
+ version: 1,
46
+ encode: (e) => {
47
+ return {
48
+ connection_id: e.definition.connection.id,
49
+ type: e.definition.definition.name,
50
+ id: e.model.id
51
+ };
52
+ },
53
+ decode: async (entity) => {
54
+ let connection = await this.connectionStore.waitForReadyForConnection(entity.connection_id);
55
+ let definition = await connection.waitForSchemaModelDefinitionByName(entity.type);
56
+ let db = await definition.getCollection();
57
+ let model = await db.first(entity.id);
58
+ return new SchemaModelObject({
59
+ model,
60
+ definition
61
+ });
62
+ }
63
+ })
64
+ );
65
+
66
+ this.registerComponent(new InlineTreePresenterComponent<SchemaModelObject>());
67
+ }
68
+
69
+ matchEntity(t: any): boolean {
70
+ if (t instanceof SchemaModelObject) {
71
+ return true;
72
+ }
73
+ }
74
+
75
+ getEntityUID(t: SchemaModelObject) {
76
+ return t.model.id;
77
+ }
78
+ }
@@ -0,0 +1,7 @@
1
+ export enum DataBrowserEntities {
2
+ CONNECTION = 'databrowser/connection',
3
+ CONNECTION_FACTORY = 'databrowser/connection_factory',
4
+ SCHEMA_MODEL_DEFINITION = 'databrowser/schema_model_definition',
5
+ SCHEMA_MODEL_OBJECT = 'databrowser/schema_model_object',
6
+ QUERY = 'databrowser/query'
7
+ }
@@ -0,0 +1,48 @@
1
+ import { FormModel, TextInput, TextInputType } from '@journeyapps-labs/reactor-mod';
2
+ import { ManualConnection } from '../core/types/ManualConnection';
3
+ import { ManualConnectionFactory } from '../core/types/ManualConnectionFactory';
4
+
5
+ export interface APIConnectionFormValue {
6
+ name: string;
7
+ base_url: string;
8
+ api_token: string;
9
+ }
10
+
11
+ export class APIConnectionForm extends FormModel<APIConnectionFormValue> {
12
+ constructor(value?: APIConnectionFormValue) {
13
+ super();
14
+
15
+ this.addInput(
16
+ new TextInput({
17
+ name: 'name',
18
+ label: 'Connection name',
19
+ value: value?.name || 'Default'
20
+ })
21
+ );
22
+
23
+ this.addInput(
24
+ new TextInput({
25
+ name: 'base_url',
26
+ label: 'Base URL',
27
+ value: value?.base_url
28
+ })
29
+ );
30
+
31
+ this.addInput(
32
+ new TextInput({
33
+ name: 'api_token',
34
+ label: 'API Token',
35
+ inputType: TextInputType.PASSWORD,
36
+ value: value?.api_token
37
+ })
38
+ );
39
+ }
40
+
41
+ generateConnection(factory: ManualConnectionFactory) {
42
+ return new ManualConnection(factory, {
43
+ baseUrl: this.value().base_url,
44
+ token: this.value().api_token,
45
+ name: this.value().name
46
+ });
47
+ }
48
+ }