@journeyapps-labs/reactor-mod-data-browser 1.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.
Files changed (133) hide show
  1. package/CHANGELOG.md +7 -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 +33 -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 +12 -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 +36 -0
  16. package/dist/@types/core/types/ManualConnection.d.ts +14 -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/index.d.ts +3 -0
  27. package/dist/@types/panels/model/ModelPanelFactory.d.ts +28 -0
  28. package/dist/@types/panels/model/ModelPanelWidget.d.ts +6 -0
  29. package/dist/@types/panels/query/PageResultsWidget.d.ts +8 -0
  30. package/dist/@types/panels/query/QueryPanelFactory.d.ts +33 -0
  31. package/dist/@types/panels/query/QueryPanelWidget.d.ts +6 -0
  32. package/dist/@types/panels/query/TableControlsWidget.d.ts +10 -0
  33. package/dist/@types/stores/ConnectionStore.d.ts +20 -0
  34. package/dist/DataBrowserModule.js +45 -0
  35. package/dist/DataBrowserModule.js.map +1 -0
  36. package/dist/actions/connections/AddConnectionAction.js +48 -0
  37. package/dist/actions/connections/AddConnectionAction.js.map +1 -0
  38. package/dist/actions/connections/RemoveConnectionAction.js +43 -0
  39. package/dist/actions/connections/RemoveConnectionAction.js.map +1 -0
  40. package/dist/actions/schema-definitions/CreateModelAction.js +45 -0
  41. package/dist/actions/schema-definitions/CreateModelAction.js.map +1 -0
  42. package/dist/actions/schema-definitions/QuerySchemaModelAction.js +47 -0
  43. package/dist/actions/schema-definitions/QuerySchemaModelAction.js.map +1 -0
  44. package/dist/actions/schema-model/EditSchemaModelAction.js +46 -0
  45. package/dist/actions/schema-model/EditSchemaModelAction.js.map +1 -0
  46. package/dist/core/AbstractConnection.js +69 -0
  47. package/dist/core/AbstractConnection.js.map +1 -0
  48. package/dist/core/AbstractConnectionFactory.js +6 -0
  49. package/dist/core/AbstractConnectionFactory.js.map +1 -0
  50. package/dist/core/SchemaModelDefinition.js +31 -0
  51. package/dist/core/SchemaModelDefinition.js.map +1 -0
  52. package/dist/core/SchemaModelObject.js +12 -0
  53. package/dist/core/SchemaModelObject.js.map +1 -0
  54. package/dist/core/query/AbstractQuery.js +18 -0
  55. package/dist/core/query/AbstractQuery.js.map +1 -0
  56. package/dist/core/query/Page.js +65 -0
  57. package/dist/core/query/Page.js.map +1 -0
  58. package/dist/core/query/SimpleQuery.js +160 -0
  59. package/dist/core/query/SimpleQuery.js.map +1 -0
  60. package/dist/core/types/ManualConnection.js +21 -0
  61. package/dist/core/types/ManualConnection.js.map +1 -0
  62. package/dist/core/types/ManualConnectionFactory.js +50 -0
  63. package/dist/core/types/ManualConnectionFactory.js.map +1 -0
  64. package/dist/entities/ConnectionEntityDefinition.js +77 -0
  65. package/dist/entities/ConnectionEntityDefinition.js.map +1 -0
  66. package/dist/entities/ConnectionFactoryEntityDefinition.js +60 -0
  67. package/dist/entities/ConnectionFactoryEntityDefinition.js.map +1 -0
  68. package/dist/entities/QueryEntityDefinition.js +60 -0
  69. package/dist/entities/QueryEntityDefinition.js.map +1 -0
  70. package/dist/entities/SchemaModelDefinitionEntityDefinition.js +76 -0
  71. package/dist/entities/SchemaModelDefinitionEntityDefinition.js.map +1 -0
  72. package/dist/entities/SchemaModelObjectEntityDefinition.js +76 -0
  73. package/dist/entities/SchemaModelObjectEntityDefinition.js.map +1 -0
  74. package/dist/entities.js +9 -0
  75. package/dist/entities.js.map +1 -0
  76. package/dist/forms/APIConnectionForm.js +31 -0
  77. package/dist/forms/APIConnectionForm.js.map +1 -0
  78. package/dist/forms/SchemaModelForm.js +72 -0
  79. package/dist/forms/SchemaModelForm.js.map +1 -0
  80. package/dist/index.js +4 -0
  81. package/dist/index.js.map +1 -0
  82. package/dist/panels/model/ModelPanelFactory.js +94 -0
  83. package/dist/panels/model/ModelPanelFactory.js.map +1 -0
  84. package/dist/panels/model/ModelPanelWidget.js +28 -0
  85. package/dist/panels/model/ModelPanelWidget.js.map +1 -0
  86. package/dist/panels/query/PageResultsWidget.js +24 -0
  87. package/dist/panels/query/PageResultsWidget.js.map +1 -0
  88. package/dist/panels/query/QueryPanelFactory.js +94 -0
  89. package/dist/panels/query/QueryPanelFactory.js.map +1 -0
  90. package/dist/panels/query/QueryPanelWidget.js +41 -0
  91. package/dist/panels/query/QueryPanelWidget.js.map +1 -0
  92. package/dist/panels/query/TableControlsWidget.js +52 -0
  93. package/dist/panels/query/TableControlsWidget.js.map +1 -0
  94. package/dist/stores/ConnectionStore.js +93 -0
  95. package/dist/stores/ConnectionStore.js.map +1 -0
  96. package/dist/tsconfig.tsbuildinfo +1 -0
  97. package/dist-module/bundle.js +31 -0
  98. package/dist-module/bundle.js.LICENSE.txt +16 -0
  99. package/dist-module/bundle.js.map +1 -0
  100. package/package.json +40 -0
  101. package/reactor.config.json +4 -0
  102. package/src/DataBrowserModule.ts +54 -0
  103. package/src/actions/connections/AddConnectionAction.tsx +33 -0
  104. package/src/actions/connections/RemoveConnectionAction.tsx +28 -0
  105. package/src/actions/schema-definitions/CreateModelAction.ts +32 -0
  106. package/src/actions/schema-definitions/QuerySchemaModelAction.ts +36 -0
  107. package/src/actions/schema-model/EditSchemaModelAction.ts +33 -0
  108. package/src/core/AbstractConnection.ts +101 -0
  109. package/src/core/AbstractConnectionFactory.ts +14 -0
  110. package/src/core/SchemaModelDefinition.ts +44 -0
  111. package/src/core/SchemaModelObject.ts +19 -0
  112. package/src/core/query/AbstractQuery.ts +43 -0
  113. package/src/core/query/Page.ts +59 -0
  114. package/src/core/query/SimpleQuery.tsx +165 -0
  115. package/src/core/types/ManualConnection.ts +32 -0
  116. package/src/core/types/ManualConnectionFactory.tsx +36 -0
  117. package/src/entities/ConnectionEntityDefinition.tsx +81 -0
  118. package/src/entities/ConnectionFactoryEntityDefinition.tsx +54 -0
  119. package/src/entities/QueryEntityDefinition.ts +46 -0
  120. package/src/entities/SchemaModelDefinitionEntityDefinition.ts +82 -0
  121. package/src/entities/SchemaModelObjectEntityDefinition.ts +78 -0
  122. package/src/entities.ts +7 -0
  123. package/src/forms/APIConnectionForm.tsx +48 -0
  124. package/src/forms/SchemaModelForm.tsx +97 -0
  125. package/src/index.ts +5 -0
  126. package/src/panels/model/ModelPanelFactory.tsx +78 -0
  127. package/src/panels/model/ModelPanelWidget.tsx +42 -0
  128. package/src/panels/query/PageResultsWidget.tsx +52 -0
  129. package/src/panels/query/QueryPanelFactory.tsx +76 -0
  130. package/src/panels/query/QueryPanelWidget.tsx +72 -0
  131. package/src/panels/query/TableControlsWidget.tsx +83 -0
  132. package/src/stores/ConnectionStore.ts +87 -0
  133. package/tsconfig.json +14 -0
@@ -0,0 +1,97 @@
1
+ import {
2
+ BooleanInput,
3
+ DateInput,
4
+ DateTimePickerType,
5
+ FormModel,
6
+ SelectInput,
7
+ TextInput
8
+ } from '@journeyapps-labs/reactor-mod';
9
+ import { SchemaModelDefinition } from '../core/SchemaModelDefinition';
10
+ import { SchemaModelObject } from '../core/SchemaModelObject';
11
+ import * as _ from 'lodash';
12
+ import {
13
+ AttachmentType,
14
+ BooleanType,
15
+ DatetimeType,
16
+ DateType,
17
+ LocationType,
18
+ MultipleChoiceType,
19
+ PhotoType,
20
+ SignatureType,
21
+ SingleChoiceIntegerType,
22
+ SingleChoiceType,
23
+ TextType
24
+ } from '@journeyapps/db';
25
+
26
+ export interface SchemaModelFormOptions {
27
+ definition: SchemaModelDefinition;
28
+ object?: SchemaModelObject;
29
+ }
30
+
31
+ export class SchemaModelForm extends FormModel {
32
+ constructor(protected options: SchemaModelFormOptions) {
33
+ super();
34
+
35
+ _.map(options.definition.definition.attributes, (attribute) => {
36
+ if (attribute.type instanceof DatetimeType) {
37
+ return new DateInput({
38
+ name: attribute.name,
39
+ label: attribute.label,
40
+ value: options.object?.model[attribute.name] || null,
41
+ type: DateTimePickerType.DATETIME
42
+ });
43
+ }
44
+ if (attribute.type instanceof DateType) {
45
+ return new DateInput({
46
+ name: attribute.name,
47
+ label: attribute.label,
48
+ value: options.object?.model[attribute.name] || null,
49
+ type: DateTimePickerType.DATE
50
+ });
51
+ }
52
+ if (attribute.type instanceof AttachmentType) {
53
+ }
54
+ if (attribute.type instanceof SignatureType) {
55
+ console.log(options.object?.model[attribute.name]);
56
+ }
57
+ if (attribute.type instanceof PhotoType) {
58
+ console.log(options.object?.model[attribute.name]);
59
+ }
60
+ if (attribute.type instanceof BooleanType) {
61
+ return new BooleanInput({
62
+ name: attribute.name,
63
+ label: attribute.label,
64
+ value: options.object?.model[attribute.name]
65
+ });
66
+ }
67
+ if (attribute.type instanceof LocationType) {
68
+ }
69
+ if (attribute.type instanceof SingleChoiceIntegerType) {
70
+ }
71
+ if (attribute.type instanceof SingleChoiceType) {
72
+ return new SelectInput({
73
+ name: attribute.name,
74
+ label: attribute.label,
75
+ value: options.object?.model[attribute.name],
76
+ options: _.mapValues(attribute.type.options, (option) => {
77
+ return `${option.value}`;
78
+ })
79
+ });
80
+ }
81
+ if (attribute.type instanceof MultipleChoiceType) {
82
+ }
83
+ if (attribute.type instanceof TextType) {
84
+ return new TextInput({
85
+ name: attribute.name,
86
+ label: attribute.label,
87
+ value: options.object?.model[attribute.name]
88
+ });
89
+ }
90
+ return null;
91
+ })
92
+ .filter((f) => !!f)
93
+ .forEach((a) => {
94
+ this.addInput(a);
95
+ });
96
+ }
97
+ }
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ import { DataBrowserModule } from './DataBrowserModule';
2
+
3
+ export * from './entities';
4
+
5
+ export default DataBrowserModule;
@@ -0,0 +1,78 @@
1
+ import * as React from 'react';
2
+ import { inject, ReactorPanelFactory, ReactorPanelModel } from '@journeyapps-labs/reactor-mod';
3
+ import { ModelPanelWidget } from './ModelPanelWidget';
4
+ import { ConnectionStore } from '../../stores/ConnectionStore';
5
+ import { computed, observable } from 'mobx';
6
+ import { WorkspaceModelFactoryEvent } from '@projectstorm/react-workspaces-core';
7
+ import { SchemaModelDefinition } from '../../core/SchemaModelDefinition';
8
+ import { SchemaModelObject } from '../../core/SchemaModelObject';
9
+
10
+ export interface ModelPanelModelOptions {
11
+ definition: SchemaModelDefinition;
12
+ model?: SchemaModelObject;
13
+ }
14
+
15
+ export class ModelPanelModel extends ReactorPanelModel {
16
+ @inject(ConnectionStore)
17
+ accessor connStore: ConnectionStore;
18
+
19
+ @observable
20
+ accessor definition: SchemaModelDefinition;
21
+
22
+ @observable
23
+ accessor model: SchemaModelObject;
24
+
25
+ constructor(options?: ModelPanelModelOptions) {
26
+ super(ModelPanelFactory.TYPE);
27
+ this.setExpand(true, true);
28
+ this.definition = options?.definition;
29
+ this.model = options?.model;
30
+ }
31
+
32
+ encodeEntities() {
33
+ return {
34
+ definition: this.definition,
35
+ model: this.model
36
+ };
37
+ }
38
+
39
+ decodeEntities(data: ReturnType<this['encodeEntities']>) {
40
+ this.definition = data.definition;
41
+ this.model = data.model;
42
+ }
43
+ }
44
+
45
+ export class ModelPanelFactory extends ReactorPanelFactory<ModelPanelModel> {
46
+ static TYPE = 'databrowser/model';
47
+
48
+ constructor() {
49
+ super({
50
+ icon: 'cube',
51
+ color: 'mediumpurple',
52
+ name: 'Model',
53
+ allowManualCreation: false,
54
+ isMultiple: true,
55
+ fullscreen: false,
56
+ type: ModelPanelFactory.TYPE,
57
+ category: 'Databrowser'
58
+ });
59
+ }
60
+
61
+ getSimpleName(model: ModelPanelModel) {
62
+ if (!model.definition) {
63
+ return super.getSimpleName(model);
64
+ }
65
+ if (model.model) {
66
+ return `${model.definition.definition.label}: ${model.model.model.toString()}`;
67
+ }
68
+ return `${model.definition.definition.label}`;
69
+ }
70
+
71
+ _generateModel(): ModelPanelModel {
72
+ return new ModelPanelModel(null);
73
+ }
74
+
75
+ generatePanelContent(event: WorkspaceModelFactoryEvent<ModelPanelModel>): React.JSX.Element {
76
+ return <ModelPanelWidget key={event.model.id} model={event.model} />;
77
+ }
78
+ }
@@ -0,0 +1,42 @@
1
+ import * as React from 'react';
2
+ import { useEffect, useState } from 'react';
3
+ import { observer } from 'mobx-react';
4
+ import styled from '@emotion/styled';
5
+ import { BorderLayoutWidget, LoadingPanelWidget } from '@journeyapps-labs/reactor-mod';
6
+
7
+ import { SchemaModelForm } from '../../forms/SchemaModelForm';
8
+ import { ModelPanelModel } from './ModelPanelFactory';
9
+
10
+ export interface QueryPanelWidgetProps {
11
+ model: ModelPanelModel;
12
+ }
13
+
14
+ namespace S {
15
+ export const Container = styled.div`
16
+ padding: 20px;
17
+ `;
18
+ }
19
+
20
+ export const ModelPanelWidget: React.FC<QueryPanelWidgetProps> = observer((props) => {
21
+ const [form, setForm] = useState<SchemaModelForm>(null);
22
+
23
+ useEffect(() => {
24
+ if (!props.model.definition) {
25
+ return;
26
+ }
27
+ setForm(
28
+ new SchemaModelForm({
29
+ object: props.model.model,
30
+ definition: props.model.definition
31
+ })
32
+ );
33
+ }, [props.model.model, props.model.definition]);
34
+
35
+ return (
36
+ <LoadingPanelWidget loading={!form}>
37
+ {() => {
38
+ return <S.Container>{form.render()}</S.Container>;
39
+ }}
40
+ </LoadingPanelWidget>
41
+ );
42
+ });
@@ -0,0 +1,52 @@
1
+ import * as React from 'react';
2
+ import { Page } from '../../core/query/Page';
3
+ import {
4
+ ActionSource,
5
+ ioc,
6
+ LoadingPanelWidget,
7
+ ScrollableDivCss,
8
+ System,
9
+ TableWidget
10
+ } from '@journeyapps-labs/reactor-mod';
11
+ import { AbstractQuery } from '../../core/query/AbstractQuery';
12
+ import { observer } from 'mobx-react';
13
+ import styled from '@emotion/styled';
14
+ import { DataBrowserEntities } from '../../entities';
15
+ import { SchemaModelObject } from '../../core/SchemaModelObject';
16
+
17
+ export interface PageResultsWidgetProps {
18
+ page: Page;
19
+ query: AbstractQuery;
20
+ }
21
+
22
+ export const PageResultsWidget: React.FC<PageResultsWidgetProps> = observer((props) => {
23
+ const system = ioc.get(System);
24
+
25
+ return (
26
+ <LoadingPanelWidget
27
+ loading={props.page.loading}
28
+ children={() => {
29
+ return (
30
+ <S.Container>
31
+ <TableWidget
32
+ onContextMenu={(event, row) => {
33
+ system
34
+ .getDefinition<SchemaModelObject>(DataBrowserEntities.SCHEMA_MODEL_OBJECT)
35
+ .showContextMenuForEntity(row.model, event);
36
+ }}
37
+ rows={props.page.asRows()}
38
+ columns={props.query.getColumns()}
39
+ />
40
+ </S.Container>
41
+ );
42
+ }}
43
+ />
44
+ );
45
+ });
46
+
47
+ namespace S {
48
+ export const Container = styled.div`
49
+ overflow: auto;
50
+ ${ScrollableDivCss};
51
+ `;
52
+ }
@@ -0,0 +1,76 @@
1
+ import * as React from 'react';
2
+ import { inject, ReactorPanelFactory, ReactorPanelModel } from '@journeyapps-labs/reactor-mod';
3
+ import { QueryPanelWidget } from './QueryPanelWidget';
4
+ import { AbstractQuery } from '../../core/query/AbstractQuery';
5
+ import { ConnectionStore } from '../../stores/ConnectionStore';
6
+ import { observable } from 'mobx';
7
+ import { WorkspaceModelFactoryEvent } from '@projectstorm/react-workspaces-core';
8
+
9
+ export class QueryPanelModel extends ReactorPanelModel {
10
+ @inject(ConnectionStore)
11
+ accessor connStore: ConnectionStore;
12
+
13
+ @observable
14
+ accessor query: AbstractQuery;
15
+
16
+ @observable
17
+ accessor current_page: number;
18
+
19
+ constructor(query: AbstractQuery) {
20
+ super(QueryPanelFactory.TYPE);
21
+ this.setExpand(true, true);
22
+ this.query = query;
23
+ this.current_page = 0;
24
+ }
25
+
26
+ toArray() {
27
+ return {
28
+ ...super.toArray(),
29
+ current_page: this.current_page
30
+ };
31
+ }
32
+
33
+ fromArray(data: ReturnType<this['toArray']>, engine) {
34
+ super.fromArray(data, engine);
35
+ this.current_page = data.current_page || 0;
36
+ }
37
+
38
+ encodeEntities() {
39
+ return {
40
+ query: this.query
41
+ };
42
+ }
43
+
44
+ decodeEntities(data: ReturnType<this['encodeEntities']>) {
45
+ this.query = data.query;
46
+ }
47
+ }
48
+
49
+ export class QueryPanelFactory extends ReactorPanelFactory<QueryPanelModel> {
50
+ static TYPE = 'query';
51
+
52
+ constructor() {
53
+ super({
54
+ icon: 'table',
55
+ color: 'rgb(0,192,255)',
56
+ name: 'Query',
57
+ allowManualCreation: false,
58
+ isMultiple: true,
59
+ fullscreen: false,
60
+ type: QueryPanelFactory.TYPE,
61
+ category: 'Databrowser'
62
+ });
63
+ }
64
+
65
+ getSimpleName(model: QueryPanelModel): string {
66
+ return model.query?.getSimpleName();
67
+ }
68
+
69
+ _generateModel(): QueryPanelModel {
70
+ return new QueryPanelModel(null);
71
+ }
72
+
73
+ generatePanelContent(event: WorkspaceModelFactoryEvent<QueryPanelModel>): React.JSX.Element {
74
+ return <QueryPanelWidget key={event.model.id} model={event.model} />;
75
+ }
76
+ }
@@ -0,0 +1,72 @@
1
+ import * as React from 'react';
2
+ import { useEffect, useState } from 'react';
3
+ import { QueryPanelModel } from './QueryPanelFactory';
4
+ import { observer } from 'mobx-react';
5
+ import styled from '@emotion/styled';
6
+ import { BorderLayoutWidget, LoadingPanelWidget } from '@journeyapps-labs/reactor-mod';
7
+ import { Page } from '../../core/query/Page';
8
+ import { PageResultsWidget } from './PageResultsWidget';
9
+ import { TableControlsWidget } from './TableControlsWidget';
10
+
11
+ export interface QueryPanelWidgetProps {
12
+ model: QueryPanelModel;
13
+ }
14
+
15
+ namespace S {
16
+ export const Container = styled.div`
17
+ position: absolute;
18
+ width: 100%;
19
+ height: 100%;
20
+ `;
21
+ }
22
+
23
+ export const QueryPanelWidget: React.FC<QueryPanelWidgetProps> = observer((props) => {
24
+ const [page, setPage] = useState<Page>(null);
25
+ useEffect(() => {
26
+ if (!props.model.query) {
27
+ return;
28
+ }
29
+ props.model.query.load();
30
+ }, [props.model.query]);
31
+
32
+ useEffect(() => {
33
+ if (props.model.query) {
34
+ setPage(props.model.query.getPage(props.model.current_page));
35
+ }
36
+ }, [props.model.query]);
37
+
38
+ return (
39
+ <LoadingPanelWidget loading={!props.model.query || !page}>
40
+ {() => {
41
+ return (
42
+ <S.Container>
43
+ <BorderLayoutWidget
44
+ top={
45
+ <TableControlsWidget
46
+ query={props.model.query}
47
+ current_page={page}
48
+ goToPage={(index) => {
49
+ setPage(props.model.query.getPage(index));
50
+ props.model.current_page = index;
51
+ }}
52
+ />
53
+ }
54
+ bottom={
55
+ <TableControlsWidget
56
+ query={props.model.query}
57
+ current_page={page}
58
+ goToPage={(index) => {
59
+ setPage(props.model.query.getPage(index));
60
+ props.model.current_page = index;
61
+ }}
62
+ />
63
+ }
64
+ >
65
+ <PageResultsWidget query={props.model.query} page={page} />
66
+ </BorderLayoutWidget>
67
+ </S.Container>
68
+ );
69
+ }}
70
+ </LoadingPanelWidget>
71
+ );
72
+ });
@@ -0,0 +1,83 @@
1
+ import * as React from 'react';
2
+ import { ComboBoxItem, PanelButtonWidget, PanelDropdownWidget, styled } from '@journeyapps-labs/reactor-mod';
3
+ import { AbstractQuery } from '../../core/query/AbstractQuery';
4
+ import { observer } from 'mobx-react';
5
+ import * as _ from 'lodash';
6
+ import { Page } from '../../core/query/Page';
7
+
8
+ export interface TableControlsWidgetProps {
9
+ current_page: Page;
10
+ goToPage?: (index: number) => any;
11
+ className?: any;
12
+ query: AbstractQuery;
13
+ }
14
+
15
+ export const TableControlsWidget: React.FC<TableControlsWidgetProps> = observer((props) => {
16
+ return (
17
+ <S.Container className={props.className}>
18
+ <PanelButtonWidget
19
+ disabled={props.current_page?.index === 0}
20
+ label="Prev"
21
+ action={() => {
22
+ props.goToPage(props.current_page.index - 1);
23
+ }}
24
+ />
25
+ <S.PageSelector>
26
+ <PanelDropdownWidget
27
+ onChange={({ key }) => {
28
+ props.goToPage(parseInt(key));
29
+ }}
30
+ selected={`${props.current_page.index}`}
31
+ items={_.range(0, props.query.totalPages).map((r) => {
32
+ return {
33
+ title: `${r + 1}`,
34
+ key: `${r}`
35
+ } as ComboBoxItem;
36
+ })}
37
+ />
38
+ <S.TotalPages>/ {props.query.totalPages}</S.TotalPages>
39
+ </S.PageSelector>
40
+ <PanelButtonWidget
41
+ disabled={props.query.totalPages == props.current_page.index + 1}
42
+ label="Next"
43
+ action={() => {
44
+ props.goToPage(props.current_page.index + 1);
45
+ }}
46
+ />
47
+ <PanelButtonWidget
48
+ label="Page"
49
+ icon="refresh"
50
+ action={() => {
51
+ props.current_page.load();
52
+ }}
53
+ />
54
+ <PanelButtonWidget
55
+ label="Query"
56
+ icon="refresh"
57
+ action={() => {
58
+ props.query.load();
59
+ }}
60
+ />
61
+ </S.Container>
62
+ );
63
+ });
64
+ namespace S {
65
+ export const Container = styled.div`
66
+ display: flex;
67
+ flex-direction: row;
68
+ column-gap: 5px;
69
+ padding: 5px 5px;
70
+ align-items: center;
71
+ `;
72
+
73
+ export const PageSelector = styled.div`
74
+ display: flex;
75
+ flex-direction: row;
76
+ align-items: center;
77
+ `;
78
+
79
+ export const TotalPages = styled.div`
80
+ color: ${(p) => p.theme.text.primary};
81
+ padding-left: 5px;
82
+ `;
83
+ }
@@ -0,0 +1,87 @@
1
+ import { AbstractStore, LocalStorageSerializer } from '@journeyapps-labs/reactor-mod';
2
+ import { AbstractConnection, AbstractConnectionSerialized } from '../core/AbstractConnection';
3
+ import { action, computed, observable, when } from 'mobx';
4
+ import { AbstractConnectionFactory } from '../core/AbstractConnectionFactory';
5
+
6
+ export interface ConnectionStoreSerialized {
7
+ connections: AbstractConnectionSerialized[];
8
+ }
9
+
10
+ export class ConnectionStore extends AbstractStore<ConnectionStoreSerialized> {
11
+ @observable
12
+ protected accessor _connections: Set<AbstractConnection>;
13
+
14
+ protected _connectionFactories: Map<string, AbstractConnectionFactory>;
15
+
16
+ constructor() {
17
+ super({
18
+ name: 'CONNECTION_STORE',
19
+ serializer: new LocalStorageSerializer({
20
+ key: 'CONNECTION_STORE'
21
+ })
22
+ });
23
+ this._connections = new Set<AbstractConnection>();
24
+ this._connectionFactories = new Map<string, AbstractConnectionFactory>();
25
+ }
26
+
27
+ @computed get connections() {
28
+ return Array.from(this._connections.values());
29
+ }
30
+
31
+ get connectionFactories() {
32
+ return Array.from(this._connectionFactories.values());
33
+ }
34
+
35
+ protected serialize(): ConnectionStoreSerialized {
36
+ return {
37
+ connections: this.connections.map((m) => m.serialize())
38
+ };
39
+ }
40
+
41
+ getConnectionByID(id: string) {
42
+ return this.connections.find((c) => c.id === id);
43
+ }
44
+
45
+ async waitForReadyForConnection(id: string) {
46
+ await when(() => {
47
+ return !!this.getConnectionByID(id);
48
+ });
49
+ return this.getConnectionByID(id);
50
+ }
51
+
52
+ async deserializeConnection(data: AbstractConnectionSerialized) {
53
+ let conn = this._connectionFactories.get(data.factory).generateConnection();
54
+ conn.id = data.id;
55
+ await conn._deSerialize(data.payload);
56
+ return conn;
57
+ }
58
+
59
+ @action
60
+ protected async deserialize(data: ConnectionStoreSerialized) {
61
+ let connections = await Promise.all(
62
+ data.connections.map((connSer) => {
63
+ return this.deserializeConnection(connSer);
64
+ })
65
+ );
66
+ connections.forEach((c) => {
67
+ this.addConnection(c);
68
+ });
69
+ }
70
+
71
+ registerConnectionFactory(factory: AbstractConnectionFactory) {
72
+ this._connectionFactories.set(factory.options.key, factory);
73
+ }
74
+
75
+ addConnection(connection: AbstractConnection) {
76
+ let l1 = connection.registerListener({
77
+ removed: () => {
78
+ this._connections.delete(connection);
79
+ this.save();
80
+ l1();
81
+ }
82
+ });
83
+ this._connections.add(connection);
84
+ this.save();
85
+ connection.init();
86
+ }
87
+ }
package/tsconfig.json ADDED
@@ -0,0 +1,14 @@
1
+ {
2
+ "extends": "../../tsconfig.base.json",
3
+ "compilerOptions": {
4
+ "declarationDir": "dist/@types",
5
+ "rootDir": "src",
6
+ "outDir": "dist",
7
+ "tsBuildInfoFile": "dist/tsconfig.tsbuildinfo"
8
+ },
9
+ "include": [
10
+ "src/**/*.ts",
11
+ "src/**/*.tsx",
12
+ "src/**/*.json"
13
+ ]
14
+ }