@journeyapps-labs/reactor-mod-data-browser 3.5.0 → 3.6.1

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 (78) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/dist/@types/actions/schema-model/DeleteSchemaModelAction.d.ts +12 -0
  3. package/dist/@types/core/AbstractConnection.d.ts +1 -0
  4. package/dist/@types/core/SchemaModelObject.d.ts +3 -0
  5. package/dist/@types/core/delete-schema-models.d.ts +8 -0
  6. package/dist/@types/core/query/AbstractQuery.d.ts +3 -1
  7. package/dist/@types/forms/types/shared/ui.d.ts +6 -0
  8. package/dist/@types/panels/query/PageResultsWidget.d.ts +5 -1
  9. package/dist/@types/panels/query/QueryPanelFactory.d.ts +8 -0
  10. package/dist/@types/panels/query/TableControlsWidget.d.ts +2 -0
  11. package/dist/@types/panels/query/table-controls/SelectionControlsWidget.d.ts +6 -0
  12. package/dist/DataBrowserModule.js +2 -0
  13. package/dist/DataBrowserModule.js.map +1 -1
  14. package/dist/actions/schema-definitions/CreateModelAction.js +1 -1
  15. package/dist/actions/schema-definitions/CreateModelAction.js.map +1 -1
  16. package/dist/actions/schema-model/DeleteSchemaModelAction.js +27 -0
  17. package/dist/actions/schema-model/DeleteSchemaModelAction.js.map +1 -0
  18. package/dist/core/AbstractConnection.js +23 -1
  19. package/dist/core/AbstractConnection.js.map +1 -1
  20. package/dist/core/SchemaModelDefinition.js +2 -2
  21. package/dist/core/SchemaModelDefinition.js.map +1 -1
  22. package/dist/core/SchemaModelObject.js +52 -9
  23. package/dist/core/SchemaModelObject.js.map +1 -1
  24. package/dist/core/delete-schema-models.js +101 -0
  25. package/dist/core/delete-schema-models.js.map +1 -0
  26. package/dist/core/query/AbstractQuery.js +48 -10
  27. package/dist/core/query/AbstractQuery.js.map +1 -1
  28. package/dist/core/query/query-simple/SimpleQueryColumns.js +0 -2
  29. package/dist/core/query/query-simple/SimpleQueryColumns.js.map +1 -1
  30. package/dist/core/query/widgets/SmartFilterWidget.js +1 -1
  31. package/dist/core/query/widgets/SmartFilterWidget.js.map +1 -1
  32. package/dist/entities/SchemaModelObjectEntityDefinition.js +5 -0
  33. package/dist/entities/SchemaModelObjectEntityDefinition.js.map +1 -1
  34. package/dist/forms/SchemaModelForm.js +9 -3
  35. package/dist/forms/SchemaModelForm.js.map +1 -1
  36. package/dist/panels/_shared/SharedModelPanelFactory.js +4 -2
  37. package/dist/panels/_shared/SharedModelPanelFactory.js.map +1 -1
  38. package/dist/panels/model/ModelPanelWidget.js +15 -11
  39. package/dist/panels/model/ModelPanelWidget.js.map +1 -1
  40. package/dist/panels/query/PageResultsWidget.js +26 -6
  41. package/dist/panels/query/PageResultsWidget.js.map +1 -1
  42. package/dist/panels/query/QueryPanelFactory.js +39 -4
  43. package/dist/panels/query/QueryPanelFactory.js.map +1 -1
  44. package/dist/panels/query/QueryPanelWidget.js +12 -2
  45. package/dist/panels/query/QueryPanelWidget.js.map +1 -1
  46. package/dist/panels/query/TableControlsWidget.js +13 -2
  47. package/dist/panels/query/TableControlsWidget.js.map +1 -1
  48. package/dist/panels/query/table-controls/ChangesControlsWidget.js +1 -1
  49. package/dist/panels/query/table-controls/ChangesControlsWidget.js.map +1 -1
  50. package/dist/panels/query/table-controls/PageControlsWidget.js +8 -5
  51. package/dist/panels/query/table-controls/PageControlsWidget.js.map +1 -1
  52. package/dist/panels/query/table-controls/SelectionControlsWidget.js +11 -0
  53. package/dist/panels/query/table-controls/SelectionControlsWidget.js.map +1 -0
  54. package/dist/tsconfig.tsbuildinfo +1 -1
  55. package/dist-module/bundle.js +75 -75
  56. package/dist-module/bundle.js.map +1 -1
  57. package/package.json +8 -8
  58. package/src/DataBrowserModule.ts +2 -0
  59. package/src/actions/schema-definitions/CreateModelAction.ts +1 -1
  60. package/src/actions/schema-model/DeleteSchemaModelAction.ts +43 -0
  61. package/src/core/AbstractConnection.ts +23 -1
  62. package/src/core/SchemaModelDefinition.ts +3 -5
  63. package/src/core/SchemaModelObject.ts +30 -7
  64. package/src/core/delete-schema-models.ts +131 -0
  65. package/src/core/query/AbstractQuery.ts +16 -2
  66. package/src/core/query/query-simple/SimpleQueryColumns.tsx +0 -2
  67. package/src/core/query/widgets/SmartFilterWidget.tsx +1 -1
  68. package/src/entities/SchemaModelObjectEntityDefinition.ts +4 -0
  69. package/src/forms/SchemaModelForm.tsx +7 -2
  70. package/src/panels/_shared/SharedModelPanelFactory.tsx +4 -2
  71. package/src/panels/model/ModelPanelWidget.tsx +18 -11
  72. package/src/panels/query/PageResultsWidget.tsx +45 -8
  73. package/src/panels/query/QueryPanelFactory.tsx +23 -0
  74. package/src/panels/query/QueryPanelWidget.tsx +14 -0
  75. package/src/panels/query/TableControlsWidget.tsx +26 -2
  76. package/src/panels/query/table-controls/ChangesControlsWidget.tsx +1 -1
  77. package/src/panels/query/table-controls/PageControlsWidget.tsx +7 -5
  78. package/src/panels/query/table-controls/SelectionControlsWidget.tsx +34 -0
@@ -10,6 +10,9 @@ import { SavedQueryStore } from '../../stores/SavedQueryStore';
10
10
  import { AbstractConnection } from '../../core/AbstractConnection';
11
11
  import { SharedConnectionPanelFactory } from '../_shared/SharedConnectionPanelFactory';
12
12
  import { Page } from '../../core/query/Page';
13
+ import { SchemaModelObject } from '../../core/SchemaModelObject';
14
+ import { action } from 'mobx';
15
+ import * as _ from 'lodash';
13
16
 
14
17
  export class QueryPanelModel extends ReactorPanelModel {
15
18
  @inject(ConnectionStore)
@@ -24,6 +27,9 @@ export class QueryPanelModel extends ReactorPanelModel {
24
27
  @observable.ref
25
28
  accessor current_page_data: Page | null;
26
29
 
30
+ @observable.ref
31
+ accessor selected_models: SchemaModelObject[];
32
+
27
33
  accessor table_scroll_top: number;
28
34
  accessor table_scroll_left: number;
29
35
 
@@ -33,10 +39,26 @@ export class QueryPanelModel extends ReactorPanelModel {
33
39
  this.query = query;
34
40
  this.current_page = 0;
35
41
  this.current_page_data = null;
42
+ this.selected_models = [];
36
43
  this.table_scroll_top = 0;
37
44
  this.table_scroll_left = 0;
38
45
  }
39
46
 
47
+ @action clearSelection() {
48
+ this.selected_models = [];
49
+ }
50
+
51
+ @action mergeSelectionForPage(event: { page: Page; models: SchemaModelObject[] }) {
52
+ const pageRowKeys = new Set(event.page.asRows().map((row) => row.key));
53
+ const nextSelectedModels = this.selected_models.filter((model) => !pageRowKeys.has(model.id));
54
+ this.selected_models = _.uniqBy([...nextSelectedModels, ...event.models], (model) => model.id);
55
+ }
56
+
57
+ @action async reloadQuery() {
58
+ this.clearSelection();
59
+ await this.query.load();
60
+ }
61
+
40
62
  isSerializable() {
41
63
  return this.query instanceof AbstractSerializableQuery;
42
64
  }
@@ -71,6 +93,7 @@ export class QueryPanelModel extends ReactorPanelModel {
71
93
  }
72
94
  this.current_page = 0;
73
95
  this.current_page_data = null;
96
+ this.clearSelection();
74
97
  this.query = query;
75
98
  await query.load();
76
99
  }
@@ -9,6 +9,7 @@ import { PageResultsWidget } from './PageResultsWidget';
9
9
  import { TableControlsWidget } from './TableControlsWidget';
10
10
  import { autorun } from 'mobx';
11
11
  import { TableControlsPositionPreference, TableControlsPositionValue } from '../../preferences/QueryControlPreferences';
12
+ import { deleteSchemaModels } from '../../core/delete-schema-models';
12
13
 
13
14
  export interface QueryPanelWidgetProps {
14
15
  model: QueryPanelModel;
@@ -101,6 +102,12 @@ export const QueryPanelWidget: React.FC<QueryPanelWidgetProps> = observer((props
101
102
  query={props.model.query}
102
103
  current_page={activePage}
103
104
  loading={loading}
105
+ selectedCount={props.model.selected_models.length}
106
+ onDeleteSelected={async () => {
107
+ await deleteSchemaModels({
108
+ models: props.model.selected_models
109
+ });
110
+ }}
104
111
  onLoadSavedQuery={async (id) => {
105
112
  await props.model.loadSavedQuery(id);
106
113
  }}
@@ -132,6 +139,13 @@ export const QueryPanelWidget: React.FC<QueryPanelWidgetProps> = observer((props
132
139
  <PageResultsWidget
133
140
  query={props.model.query}
134
141
  page={activePage}
142
+ selectedModels={props.model.selected_models}
143
+ onSelectionChange={(event) => {
144
+ props.model.mergeSelectionForPage({
145
+ page: activePage,
146
+ models: event.rows.map((row) => row.model)
147
+ });
148
+ }}
135
149
  scrollTop={props.model.table_scroll_top}
136
150
  scrollLeft={props.model.table_scroll_left}
137
151
  onScroll={({ top, left }) => {
@@ -1,5 +1,13 @@
1
1
  import * as React from 'react';
2
- import { BooleanSetting, IconWidget, ioc, PrefsStore, styled } from '@journeyapps-labs/reactor-mod';
2
+ import {
3
+ BooleanSetting,
4
+ IconWidget,
5
+ ioc,
6
+ PanelButtonMode,
7
+ PanelButtonWidget,
8
+ PrefsStore,
9
+ styled
10
+ } from '@journeyapps-labs/reactor-mod';
3
11
  import { AbstractQuery } from '../../core/query/AbstractQuery';
4
12
  import { observer } from 'mobx-react';
5
13
  import * as _ from 'lodash';
@@ -12,6 +20,8 @@ import { SortControlsWidget } from './table-controls/SortControlsWidget';
12
20
  import { ChangesControlsWidget } from './table-controls/ChangesControlsWidget';
13
21
  import { FilterControlsWidget } from './table-controls/FilterControlsWidget';
14
22
  import { QueryControlPreferences } from '../../preferences/QueryControlPreferences';
23
+ import { SelectionControlsWidget } from './table-controls/SelectionControlsWidget';
24
+ import { CreateModelAction } from '../../actions/schema-definitions/CreateModelAction';
15
25
 
16
26
  export interface TableControlsWidgetProps {
17
27
  current_page: Page;
@@ -20,6 +30,8 @@ export interface TableControlsWidgetProps {
20
30
  query: AbstractQuery;
21
31
  onLoadSavedQuery?: (id: string) => Promise<any> | any;
22
32
  loading?: boolean;
33
+ selectedCount: number;
34
+ onDeleteSelected: () => Promise<void>;
23
35
  }
24
36
 
25
37
  export const TableControlsWidget: React.FC<TableControlsWidgetProps> = observer((props) => {
@@ -36,9 +48,20 @@ export const TableControlsWidget: React.FC<TableControlsWidgetProps> = observer(
36
48
  const showFilterControls = prefsStore.getPreference<BooleanSetting>(
37
49
  QueryControlPreferences.SHOW_FILTER_CONTROLS
38
50
  ).checked;
51
+ const createModelButton = simpleQuery?.options.definition
52
+ ? CreateModelAction.get().renderAsButton(
53
+ (btn) => {
54
+ return <PanelButtonWidget {...btn} label="Create model" mode={PanelButtonMode.PRIMARY} />;
55
+ },
56
+ {
57
+ targetEntity: simpleQuery.options.definition
58
+ }
59
+ )
60
+ : null;
39
61
 
40
62
  return (
41
63
  <S.Container className={props.className}>
64
+ {createModelButton}
42
65
  <PageControlsWidget query={props.query} currentPage={props.current_page} goToPage={props.goToPage} />
43
66
  <QueryControlsWidget
44
67
  query={props.query}
@@ -52,6 +75,7 @@ export const TableControlsWidget: React.FC<TableControlsWidgetProps> = observer(
52
75
  {simpleQuery && showSortControls ? (
53
76
  <SortControlsWidget simpleQuery={simpleQuery} goToPage={props.goToPage} />
54
77
  ) : null}
78
+ <SelectionControlsWidget selectedCount={props.selectedCount} onDeleteSelected={props.onDeleteSelected} />
55
79
  <ChangesControlsWidget query={props.query} currentPage={props.current_page} />
56
80
  {props.loading ? <S.Loading icon="spinner" spin={true} /> : null}
57
81
  </S.Container>
@@ -65,7 +89,7 @@ namespace S {
65
89
  column-gap: 20px;
66
90
  row-gap: 20px;
67
91
  padding: 5px 5px;
68
- align-items: center;
92
+ align-items: flex-end;
69
93
  flex-wrap: wrap;
70
94
  `;
71
95
 
@@ -36,7 +36,7 @@ export const ChangesControlsWidget: React.FC<ChangesControlsWidgetProps> = obser
36
36
  icon="save"
37
37
  iconColor={_theme.status.success}
38
38
  action={async () => {
39
- props.query.batchSave();
39
+ await props.query.batchSave();
40
40
  }}
41
41
  />
42
42
  <PanelButtonWidget
@@ -21,6 +21,9 @@ export interface PageControlsWidgetProps {
21
21
  export const PageControlsWidget: React.FC<PageControlsWidgetProps> = observer((props) => {
22
22
  const hasCurrentPage = !!props.currentPage;
23
23
  const currentPageIndex = props.currentPage?.index ?? 0;
24
+ const totalPages = props.query.totalPages;
25
+ const totalPagesLoading = totalPages === 0 && !!props.currentPage?.loading;
26
+ const canGoNext = hasCurrentPage && totalPages > currentPageIndex + 1;
24
27
 
25
28
  return (
26
29
  <InputContainerWidget label="Page">
@@ -36,7 +39,7 @@ export const PageControlsWidget: React.FC<PageControlsWidgetProps> = observer((p
36
39
  }}
37
40
  />
38
41
  <PanelButtonWidget
39
- disabled={!hasCurrentPage || props.query.totalPages === currentPageIndex + 1}
42
+ disabled={!canGoNext}
40
43
  label="Next"
41
44
  action={() => {
42
45
  if (!hasCurrentPage) {
@@ -47,20 +50,19 @@ export const PageControlsWidget: React.FC<PageControlsWidgetProps> = observer((p
47
50
  />
48
51
  <S.PageSelector>
49
52
  <PanelDropdownWidget
53
+ disabled={totalPages === 0}
50
54
  onChange={({ key }) => {
51
55
  props.goToPage?.(parseInt(key));
52
56
  }}
53
57
  selected={`${currentPageIndex}`}
54
- items={_.range(0, props.query.totalPages).map((r) => {
58
+ items={_.range(0, totalPages).map((r) => {
55
59
  return {
56
60
  title: `${r + 1}`,
57
61
  key: `${r}`
58
62
  } as ComboBoxItem;
59
63
  })}
60
64
  />
61
- <S.TotalPages>
62
- / {props.query.totalPages === 0 ? <S.Spinner icon="spinner" spin={true} /> : props.query.totalPages}
63
- </S.TotalPages>
65
+ <S.TotalPages>/ {totalPagesLoading ? <S.Spinner icon="spinner" spin={true} /> : totalPages}</S.TotalPages>
64
66
  </S.PageSelector>
65
67
  </S.Group>
66
68
  </InputContainerWidget>
@@ -0,0 +1,34 @@
1
+ import * as React from 'react';
2
+ import {
3
+ InputContainerWidget,
4
+ ioc,
5
+ PanelButtonMode,
6
+ PanelButtonWidget,
7
+ theme,
8
+ ThemeStore
9
+ } from '@journeyapps-labs/reactor-mod';
10
+
11
+ export interface SelectionControlsWidgetProps {
12
+ selectedCount: number;
13
+ onDeleteSelected: () => Promise<void>;
14
+ }
15
+
16
+ export const SelectionControlsWidget: React.FC<SelectionControlsWidgetProps> = (props) => {
17
+ const _theme = ioc.get(ThemeStore).getCurrentTheme(theme);
18
+
19
+ if (props.selectedCount === 0) {
20
+ return null;
21
+ }
22
+
23
+ return (
24
+ <InputContainerWidget label="Selection">
25
+ <PanelButtonWidget
26
+ mode={PanelButtonMode.PRIMARY}
27
+ label={`Delete selected [${props.selectedCount}]`}
28
+ icon="trash"
29
+ iconColor={_theme.status.failed}
30
+ action={props.onDeleteSelected}
31
+ />
32
+ </InputContainerWidget>
33
+ );
34
+ };