@journeyapps-labs/reactor-mod-data-browser 3.0.1 → 3.1.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 +45 -0
- package/dist/@types/actions/connections/SetConnectionColorAction.d.ts +11 -0
- package/dist/@types/actions/saved-queries/OpenSavedQueryAction.d.ts +10 -0
- package/dist/@types/actions/saved-queries/RemoveSavedQueryAction.d.ts +9 -0
- package/dist/@types/core/AbstractConnection.d.ts +2 -0
- package/dist/@types/core/SchemaModelDefinition.d.ts +5 -0
- package/dist/@types/core/connection-colors.d.ts +10 -0
- package/dist/@types/core/query/StandardModelFields.d.ts +5 -0
- package/dist/@types/core/query/filters.d.ts +46 -5
- package/dist/@types/core/query/query-simple/SimplePage.d.ts +2 -0
- package/dist/@types/core/query/query-simple/SimpleQuery.d.ts +12 -3
- package/dist/@types/core/query/query-simple/SimpleQueryColumns.d.ts +12 -0
- package/dist/@types/core/query/query-simple/SimpleQueryFilterState.d.ts +37 -0
- package/dist/@types/core/query/query-simple/SimpleQueryPlanner.d.ts +4 -0
- package/dist/@types/core/query/query-simple/SimpleQuerySortState.d.ts +23 -0
- package/dist/@types/core/query/query-simple/SimpleQueryTypes.d.ts +24 -0
- package/dist/@types/core/query/widgets/ColumnDisplayWidget.d.ts +1 -0
- package/dist/@types/core/query/widgets/PeekRelationshipButton.d.ts +7 -0
- package/dist/@types/core/query/widgets/SmartColumnWidget.d.ts +3 -0
- package/dist/@types/core/query/widgets/SmartFilterWidget.d.ts +6 -0
- package/dist/@types/entities/ConnectionEntityDefinition.d.ts +2 -0
- package/dist/@types/entities/SavedQueryEntityDefinition.d.ts +8 -0
- package/dist/@types/entities.d.ts +2 -1
- package/dist/@types/forms/APIConnectionForm.d.ts +1 -0
- package/dist/@types/forms/TypeEngine.d.ts +3 -21
- package/dist/@types/forms/types/attachment-handler.d.ts +2 -0
- package/dist/@types/forms/types/boolean-handler.d.ts +2 -0
- package/dist/@types/forms/types/date-handler.d.ts +2 -0
- package/dist/@types/forms/types/filters/ClearableFilterFormDialogDirective.d.ts +10 -0
- package/dist/@types/forms/types/filters/ConditionalFilterForm.d.ts +23 -0
- package/dist/@types/forms/types/image-handler.d.ts +2 -0
- package/dist/@types/forms/types/location-handler.d.ts +2 -0
- package/dist/@types/forms/types/multiple-choice-handler.d.ts +2 -0
- package/dist/@types/forms/types/multiple-choice-integer-handler.d.ts +2 -0
- package/dist/@types/forms/types/number-handler.d.ts +2 -0
- package/dist/@types/forms/types/shared/type-handler.d.ts +37 -0
- package/dist/@types/forms/types/shared/ui.d.ts +768 -0
- package/dist/@types/forms/types/single-choice-handler.d.ts +2 -0
- package/dist/@types/forms/types/single-choice-integer-handler.d.ts +2 -0
- package/dist/@types/forms/types/text-handler.d.ts +3 -0
- package/dist/@types/index.d.ts +1 -0
- package/dist/@types/panels/_shared/SharedConnectionPanelFactory.d.ts +19 -0
- package/dist/@types/panels/_shared/SharedModelPanelFactory.d.ts +5 -2
- package/dist/@types/panels/query/QueryPanelFactory.d.ts +6 -2
- package/dist/@types/panels/query/TableControlsWidget.d.ts +2 -0
- package/dist/@types/panels/query/table-controls/ChangesControlsWidget.d.ts +8 -0
- package/dist/@types/panels/query/table-controls/FilterControlsWidget.d.ts +7 -0
- package/dist/@types/panels/query/table-controls/PageControlsWidget.d.ts +9 -0
- package/dist/@types/panels/query/table-controls/QueryControlsWidget.d.ts +11 -0
- package/dist/@types/panels/query/table-controls/SortChipWidget.d.ts +10 -0
- package/dist/@types/panels/query/table-controls/SortControlsWidget.d.ts +7 -0
- package/dist/@types/preferences/QueryControlPreferences.d.ts +7 -0
- package/dist/@types/stores/SavedQueryStore.d.ts +34 -0
- package/dist/@types/widgets/EmptyValueWidget.d.ts +7 -0
- package/dist/DataBrowserModule.js +21 -7
- package/dist/DataBrowserModule.js.map +1 -1
- package/dist/actions/connections/AddConnectionAction.js +2 -2
- package/dist/actions/connections/AddConnectionAction.js.map +1 -1
- package/dist/actions/connections/RemoveConnectionAction.js +2 -2
- package/dist/actions/connections/RemoveConnectionAction.js.map +1 -1
- package/dist/actions/connections/SetConnectionColorAction.js +63 -0
- package/dist/actions/connections/SetConnectionColorAction.js.map +1 -0
- package/dist/actions/saved-queries/OpenSavedQueryAction.js +58 -0
- package/dist/actions/saved-queries/OpenSavedQueryAction.js.map +1 -0
- package/dist/actions/saved-queries/RemoveSavedQueryAction.js +43 -0
- package/dist/actions/saved-queries/RemoveSavedQueryAction.js.map +1 -0
- package/dist/actions/schema-definitions/CreateModelAction.js +2 -2
- package/dist/actions/schema-definitions/CreateModelAction.js.map +1 -1
- package/dist/actions/schema-definitions/QuerySchemaModelAction.js +2 -2
- package/dist/actions/schema-definitions/QuerySchemaModelAction.js.map +1 -1
- package/dist/actions/schema-model/EditSchemaModelAction.js +2 -2
- package/dist/actions/schema-model/EditSchemaModelAction.js.map +1 -1
- package/dist/actions/schema-model/ViewSchemaModelAsJsonAction.js +2 -2
- package/dist/actions/schema-model/ViewSchemaModelAsJsonAction.js.map +1 -1
- package/dist/core/AbstractConnection.js +116 -90
- package/dist/core/AbstractConnection.js.map +1 -1
- package/dist/core/SchemaModelDefinition.js +14 -0
- package/dist/core/SchemaModelDefinition.js.map +1 -1
- package/dist/core/connection-colors.js +36 -0
- package/dist/core/connection-colors.js.map +1 -0
- package/dist/core/query/StandardModelFields.js +10 -0
- package/dist/core/query/StandardModelFields.js.map +1 -0
- package/dist/core/query/filters.js +86 -4
- package/dist/core/query/filters.js.map +1 -1
- package/dist/core/query/query-simple/SimplePage.js +2 -4
- package/dist/core/query/query-simple/SimplePage.js.map +1 -1
- package/dist/core/query/query-simple/SimpleQuery.js +64 -68
- package/dist/core/query/query-simple/SimpleQuery.js.map +1 -1
- package/dist/core/query/query-simple/SimpleQueryColumns.js +88 -0
- package/dist/core/query/query-simple/SimpleQueryColumns.js.map +1 -0
- package/dist/core/query/query-simple/SimpleQueryFilterState.js +136 -0
- package/dist/core/query/query-simple/SimpleQueryFilterState.js.map +1 -0
- package/dist/core/query/query-simple/SimpleQueryPlanner.js +14 -0
- package/dist/core/query/query-simple/SimpleQueryPlanner.js.map +1 -0
- package/dist/core/query/query-simple/SimpleQuerySortState.js +140 -0
- package/dist/core/query/query-simple/SimpleQuerySortState.js.map +1 -0
- package/dist/core/query/query-simple/SimpleQueryTypes.js +44 -0
- package/dist/core/query/query-simple/SimpleQueryTypes.js.map +1 -0
- package/dist/core/query/widgets/BelongsToDisplayWidget.js +14 -7
- package/dist/core/query/widgets/BelongsToDisplayWidget.js.map +1 -1
- package/dist/core/query/widgets/CellDisplayWidget.js +5 -9
- package/dist/core/query/widgets/CellDisplayWidget.js.map +1 -1
- package/dist/core/query/widgets/ColumnDisplayWidget.js +13 -12
- package/dist/core/query/widgets/ColumnDisplayWidget.js.map +1 -1
- package/dist/core/query/widgets/PeekRelationshipButton.js +128 -0
- package/dist/core/query/widgets/PeekRelationshipButton.js.map +1 -0
- package/dist/core/query/widgets/SmartColumnWidget.js +18 -3
- package/dist/core/query/widgets/SmartColumnWidget.js.map +1 -1
- package/dist/core/query/widgets/SmartFilterWidget.js +88 -51
- package/dist/core/query/widgets/SmartFilterWidget.js.map +1 -1
- package/dist/entities/ConnectionEntityDefinition.js +32 -7
- package/dist/entities/ConnectionEntityDefinition.js.map +1 -1
- package/dist/entities/SavedQueryEntityDefinition.js +68 -0
- package/dist/entities/SavedQueryEntityDefinition.js.map +1 -0
- package/dist/entities/SchemaModelDefinitionEntityDefinition.js +3 -1
- package/dist/entities/SchemaModelDefinitionEntityDefinition.js.map +1 -1
- package/dist/entities.js +1 -0
- package/dist/entities.js.map +1 -1
- package/dist/forms/APIConnectionForm.js +11 -2
- package/dist/forms/APIConnectionForm.js.map +1 -1
- package/dist/forms/TypeEngine.js +30 -306
- package/dist/forms/TypeEngine.js.map +1 -1
- package/dist/forms/types/attachment-handler.js +29 -0
- package/dist/forms/types/attachment-handler.js.map +1 -0
- package/dist/forms/types/boolean-handler.js +22 -0
- package/dist/forms/types/boolean-handler.js.map +1 -0
- package/dist/forms/types/date-handler.js +97 -0
- package/dist/forms/types/date-handler.js.map +1 -0
- package/dist/forms/types/filters/ClearableFilterFormDialogDirective.js +25 -0
- package/dist/forms/types/filters/ClearableFilterFormDialogDirective.js.map +1 -0
- package/dist/forms/types/filters/ConditionalFilterForm.js +87 -0
- package/dist/forms/types/filters/ConditionalFilterForm.js.map +1 -0
- package/dist/forms/types/image-handler.js +82 -0
- package/dist/forms/types/image-handler.js.map +1 -0
- package/dist/forms/types/location-handler.js +49 -0
- package/dist/forms/types/location-handler.js.map +1 -0
- package/dist/forms/types/multiple-choice-handler.js +37 -0
- package/dist/forms/types/multiple-choice-handler.js.map +1 -0
- package/dist/forms/types/multiple-choice-integer-handler.js +37 -0
- package/dist/forms/types/multiple-choice-integer-handler.js.map +1 -0
- package/dist/forms/types/number-handler.js +79 -0
- package/dist/forms/types/number-handler.js.map +1 -0
- package/dist/forms/types/shared/type-handler.js +2 -0
- package/dist/forms/types/shared/type-handler.js.map +1 -0
- package/dist/forms/types/shared/ui.js +33 -0
- package/dist/forms/types/shared/ui.js.map +1 -0
- package/dist/forms/types/single-choice-handler.js +41 -0
- package/dist/forms/types/single-choice-handler.js.map +1 -0
- package/dist/forms/types/single-choice-integer-handler.js +41 -0
- package/dist/forms/types/single-choice-integer-handler.js.map +1 -0
- package/dist/forms/types/text-handler.js +170 -0
- package/dist/forms/types/text-handler.js.map +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/panels/_shared/SharedConnectionPanelFactory.js +48 -0
- package/dist/panels/_shared/SharedConnectionPanelFactory.js.map +1 -0
- package/dist/panels/_shared/SharedModelPanelFactory.js +7 -2
- package/dist/panels/_shared/SharedModelPanelFactory.js.map +1 -1
- package/dist/panels/query/PageResultsWidget.js +28 -11
- package/dist/panels/query/PageResultsWidget.js.map +1 -1
- package/dist/panels/query/QueryPanelFactory.js +17 -2
- package/dist/panels/query/QueryPanelFactory.js.map +1 -1
- package/dist/panels/query/QueryPanelWidget.js +55 -9
- package/dist/panels/query/QueryPanelWidget.js.map +1 -1
- package/dist/panels/query/TableControlsWidget.js +29 -67
- package/dist/panels/query/TableControlsWidget.js.map +1 -1
- package/dist/panels/query/table-controls/ChangesControlsWidget.js +36 -0
- package/dist/panels/query/table-controls/ChangesControlsWidget.js.map +1 -0
- package/dist/panels/query/table-controls/FilterControlsWidget.js +106 -0
- package/dist/panels/query/table-controls/FilterControlsWidget.js.map +1 -0
- package/dist/panels/query/table-controls/PageControlsWidget.js +65 -0
- package/dist/panels/query/table-controls/PageControlsWidget.js.map +1 -0
- package/dist/panels/query/table-controls/QueryControlsWidget.js +85 -0
- package/dist/panels/query/table-controls/QueryControlsWidget.js.map +1 -0
- package/dist/panels/query/table-controls/SortChipWidget.js +75 -0
- package/dist/panels/query/table-controls/SortChipWidget.js.map +1 -0
- package/dist/panels/query/table-controls/SortControlsWidget.js +65 -0
- package/dist/panels/query/table-controls/SortControlsWidget.js.map +1 -0
- package/dist/preferences/QueryControlPreferences.js +28 -0
- package/dist/preferences/QueryControlPreferences.js.map +1 -0
- package/dist/stores/ConnectionStore.js +2 -0
- package/dist/stores/ConnectionStore.js.map +1 -1
- package/dist/stores/SavedQueryStore.js +131 -0
- package/dist/stores/SavedQueryStore.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/widgets/EmptyValueWidget.js +15 -0
- package/dist/widgets/EmptyValueWidget.js.map +1 -0
- package/dist-module/bundle.js +181 -51
- package/dist-module/bundle.js.map +1 -1
- package/package.json +13 -13
- package/src/DataBrowserModule.ts +21 -7
- package/src/actions/connections/AddConnectionAction.tsx +2 -2
- package/src/actions/connections/RemoveConnectionAction.tsx +2 -2
- package/src/actions/connections/SetConnectionColorAction.ts +52 -0
- package/src/actions/saved-queries/OpenSavedQueryAction.ts +43 -0
- package/src/actions/saved-queries/RemoveSavedQueryAction.ts +27 -0
- package/src/actions/schema-definitions/CreateModelAction.ts +9 -2
- package/src/actions/schema-definitions/QuerySchemaModelAction.ts +9 -2
- package/src/actions/schema-model/EditSchemaModelAction.ts +9 -2
- package/src/actions/schema-model/ViewSchemaModelAsJsonAction.ts +9 -2
- package/src/core/AbstractConnection.ts +7 -1
- package/src/core/SchemaModelDefinition.ts +16 -0
- package/src/core/connection-colors.ts +49 -0
- package/src/core/query/StandardModelFields.ts +9 -0
- package/src/core/query/filters.ts +121 -6
- package/src/core/query/query-simple/SimplePage.ts +4 -5
- package/src/core/query/query-simple/SimpleQuery.tsx +83 -86
- package/src/core/query/query-simple/SimpleQueryColumns.tsx +126 -0
- package/src/core/query/query-simple/SimpleQueryFilterState.ts +160 -0
- package/src/core/query/query-simple/SimpleQueryPlanner.ts +18 -0
- package/src/core/query/query-simple/SimpleQuerySortState.ts +133 -0
- package/src/core/query/query-simple/SimpleQueryTypes.ts +61 -0
- package/src/core/query/widgets/BelongsToDisplayWidget.tsx +19 -11
- package/src/core/query/widgets/CellDisplayWidget.tsx +5 -10
- package/src/core/query/widgets/ColumnDisplayWidget.tsx +24 -20
- package/src/core/query/widgets/PeekRelationshipButton.tsx +161 -0
- package/src/core/query/widgets/SmartColumnWidget.tsx +26 -4
- package/src/core/query/widgets/SmartFilterWidget.tsx +119 -69
- package/src/entities/ConnectionEntityDefinition.tsx +33 -4
- package/src/entities/SavedQueryEntityDefinition.ts +72 -0
- package/src/entities/SchemaModelDefinitionEntityDefinition.ts +5 -2
- package/src/entities.ts +2 -1
- package/src/forms/APIConnectionForm.tsx +15 -2
- package/src/forms/TypeEngine.tsx +35 -421
- package/src/forms/types/attachment-handler.tsx +35 -0
- package/src/forms/types/boolean-handler.tsx +28 -0
- package/src/forms/types/date-handler.tsx +125 -0
- package/src/forms/types/filters/ClearableFilterFormDialogDirective.ts +32 -0
- package/src/forms/types/filters/ConditionalFilterForm.tsx +109 -0
- package/src/forms/types/image-handler.tsx +90 -0
- package/src/forms/types/location-handler.tsx +53 -0
- package/src/forms/types/multiple-choice-handler.tsx +37 -0
- package/src/forms/types/multiple-choice-integer-handler.tsx +37 -0
- package/src/forms/types/number-handler.tsx +100 -0
- package/src/forms/types/shared/type-handler.ts +36 -0
- package/src/forms/types/shared/ui.tsx +40 -0
- package/src/forms/types/single-choice-handler.tsx +47 -0
- package/src/forms/types/single-choice-integer-handler.tsx +47 -0
- package/src/forms/types/text-handler.tsx +247 -0
- package/src/index.ts +1 -0
- package/src/panels/_shared/SharedConnectionPanelFactory.tsx +55 -0
- package/src/panels/_shared/SharedModelPanelFactory.tsx +8 -2
- package/src/panels/query/PageResultsWidget.tsx +40 -28
- package/src/panels/query/QueryPanelFactory.tsx +19 -2
- package/src/panels/query/QueryPanelWidget.tsx +64 -9
- package/src/panels/query/TableControlsWidget.tsx +42 -120
- package/src/panels/query/table-controls/ChangesControlsWidget.tsx +72 -0
- package/src/panels/query/table-controls/FilterControlsWidget.tsx +145 -0
- package/src/panels/query/table-controls/PageControlsWidget.tsx +97 -0
- package/src/panels/query/table-controls/QueryControlsWidget.tsx +127 -0
- package/src/panels/query/table-controls/SortChipWidget.tsx +119 -0
- package/src/panels/query/table-controls/SortControlsWidget.tsx +95 -0
- package/src/preferences/QueryControlPreferences.ts +34 -0
- package/src/stores/ConnectionStore.ts +2 -0
- package/src/stores/SavedQueryStore.ts +121 -0
- package/src/widgets/EmptyValueWidget.tsx +20 -0
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ComboBoxItem,
|
|
4
|
+
ComboBoxStore2,
|
|
5
|
+
DialogStore,
|
|
6
|
+
InputContainerWidget,
|
|
7
|
+
ioc,
|
|
8
|
+
PanelButtonWidget,
|
|
9
|
+
SimpleComboBoxDirective,
|
|
10
|
+
styled
|
|
11
|
+
} from '@journeyapps-labs/reactor-mod';
|
|
12
|
+
import { SavedQueryStore } from '../../../stores/SavedQueryStore';
|
|
13
|
+
import { SimpleQuery } from '../../../core/query/query-simple/SimpleQuery';
|
|
14
|
+
import { observer } from 'mobx-react';
|
|
15
|
+
|
|
16
|
+
export interface QueryControlsWidgetProps {
|
|
17
|
+
query: { load: () => Promise<any> | any };
|
|
18
|
+
simpleQuery: SimpleQuery | null;
|
|
19
|
+
activeSavedQueryName?: string | null;
|
|
20
|
+
onLoadSavedQuery?: (id: string) => Promise<any> | any;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const QueryControlsWidget: React.FC<QueryControlsWidgetProps> = observer((props) => {
|
|
24
|
+
const savedQueryStore = ioc.get(SavedQueryStore);
|
|
25
|
+
const savedQueries = props.simpleQuery ? savedQueryStore.getSavedForQuery(props.simpleQuery) : [];
|
|
26
|
+
|
|
27
|
+
const showSavedQueryMenu = async (event: React.MouseEvent<any>) => {
|
|
28
|
+
if (!props.simpleQuery) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const queryChildren: ComboBoxItem[] =
|
|
33
|
+
savedQueries.length > 0
|
|
34
|
+
? savedQueries.map((saved) => {
|
|
35
|
+
return {
|
|
36
|
+
title: saved.name,
|
|
37
|
+
key: `query-${saved.id}`,
|
|
38
|
+
icon: 'search',
|
|
39
|
+
action: async () => {
|
|
40
|
+
await props.onLoadSavedQuery?.(saved.id);
|
|
41
|
+
}
|
|
42
|
+
} as ComboBoxItem;
|
|
43
|
+
})
|
|
44
|
+
: ([{ title: 'No saved queries', key: 'no-queries', disabled: true }] as ComboBoxItem[]);
|
|
45
|
+
|
|
46
|
+
const deleteChildren: ComboBoxItem[] =
|
|
47
|
+
savedQueries.length > 0
|
|
48
|
+
? savedQueries.map((saved) => {
|
|
49
|
+
return {
|
|
50
|
+
title: saved.name,
|
|
51
|
+
key: `delete-${saved.id}`,
|
|
52
|
+
icon: 'trash',
|
|
53
|
+
action: async () => {
|
|
54
|
+
await savedQueryStore.removeSavedQuery(saved.id);
|
|
55
|
+
}
|
|
56
|
+
} as ComboBoxItem;
|
|
57
|
+
})
|
|
58
|
+
: ([{ title: 'No saved queries', key: 'no-delete-queries', disabled: true }] as ComboBoxItem[]);
|
|
59
|
+
|
|
60
|
+
const directive = await ioc.get(ComboBoxStore2).show(
|
|
61
|
+
new SimpleComboBoxDirective({
|
|
62
|
+
title: 'Saved queries',
|
|
63
|
+
event: event as any,
|
|
64
|
+
items: [
|
|
65
|
+
{
|
|
66
|
+
title: 'Save query',
|
|
67
|
+
key: 'save-query',
|
|
68
|
+
icon: 'bookmark',
|
|
69
|
+
action: async () => {
|
|
70
|
+
const suggestedName = `${props.simpleQuery.options.definition.definition.label} query`;
|
|
71
|
+
const name = await ioc.get(DialogStore).showInputDialog({
|
|
72
|
+
title: 'Save query',
|
|
73
|
+
initialValue: suggestedName
|
|
74
|
+
});
|
|
75
|
+
if (!name) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
await savedQueryStore.saveQuery(name, props.simpleQuery);
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
{ title: 'Queries', key: 'queries', icon: 'list', children: queryChildren },
|
|
82
|
+
{ title: 'Delete query', key: 'delete-query', icon: 'trash', children: deleteChildren }
|
|
83
|
+
]
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
directive.getSelectedItem();
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
return (
|
|
90
|
+
<InputContainerWidget label="Query">
|
|
91
|
+
<S.Group>
|
|
92
|
+
<PanelButtonWidget
|
|
93
|
+
tooltip="Reload query"
|
|
94
|
+
icon="refresh"
|
|
95
|
+
action={async () => {
|
|
96
|
+
await props.query.load();
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
99
|
+
{props.simpleQuery ? (
|
|
100
|
+
<PanelButtonWidget
|
|
101
|
+
tooltip={
|
|
102
|
+
props.activeSavedQueryName
|
|
103
|
+
? `Saved query active: ${props.activeSavedQueryName}`
|
|
104
|
+
: 'Unsaved or modified query'
|
|
105
|
+
}
|
|
106
|
+
icon="bookmark"
|
|
107
|
+
highlight={!!props.activeSavedQueryName}
|
|
108
|
+
action={async (event) => {
|
|
109
|
+
await showSavedQueryMenu(event as any);
|
|
110
|
+
}}
|
|
111
|
+
/>
|
|
112
|
+
) : null}
|
|
113
|
+
</S.Group>
|
|
114
|
+
</InputContainerWidget>
|
|
115
|
+
);
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
namespace S {
|
|
119
|
+
export const Group = styled.div`
|
|
120
|
+
display: flex;
|
|
121
|
+
flex-direction: row;
|
|
122
|
+
align-items: center;
|
|
123
|
+
column-gap: 5px;
|
|
124
|
+
row-gap: 5px;
|
|
125
|
+
flex-wrap: wrap;
|
|
126
|
+
`;
|
|
127
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ComboBoxStore2,
|
|
4
|
+
MetadataWidget,
|
|
5
|
+
PanelButtonMode,
|
|
6
|
+
PanelButtonWidget,
|
|
7
|
+
SimpleComboBoxDirective,
|
|
8
|
+
ioc,
|
|
9
|
+
styled,
|
|
10
|
+
useDraggableRaw,
|
|
11
|
+
useDroppableRaw
|
|
12
|
+
} from '@journeyapps-labs/reactor-mod';
|
|
13
|
+
import { getTransparentColor } from '@journeyapps-labs/lib-reactor-utils';
|
|
14
|
+
import { SimpleQuerySort, SortDirection } from '../../../core/query/query-simple/SimpleQuery';
|
|
15
|
+
|
|
16
|
+
const SORT_DRAG_MIME = 'application/reactor-sort-field';
|
|
17
|
+
|
|
18
|
+
export interface SortChipWidgetProps {
|
|
19
|
+
sort: SimpleQuerySort;
|
|
20
|
+
label: string;
|
|
21
|
+
onToggle: () => Promise<any> | any;
|
|
22
|
+
onRemove: () => Promise<any> | any;
|
|
23
|
+
onDropBefore: (field: string) => Promise<any> | any;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const SortChipWidget: React.FC<SortChipWidgetProps> = (props) => {
|
|
27
|
+
const ref = React.useRef<HTMLDivElement>(null);
|
|
28
|
+
const [hover, setHover] = React.useState(false);
|
|
29
|
+
|
|
30
|
+
useDraggableRaw({
|
|
31
|
+
forwardRef: ref,
|
|
32
|
+
encode: () => {
|
|
33
|
+
return {
|
|
34
|
+
data: {
|
|
35
|
+
[SORT_DRAG_MIME]: props.sort.field
|
|
36
|
+
},
|
|
37
|
+
icon: null
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
useDroppableRaw<{ [key: string]: string }>(
|
|
43
|
+
{
|
|
44
|
+
forwardRef: ref,
|
|
45
|
+
accepts: (mimes) => mimes.includes(SORT_DRAG_MIME),
|
|
46
|
+
dragover: () => {
|
|
47
|
+
setHover(true);
|
|
48
|
+
},
|
|
49
|
+
dragexit: () => {
|
|
50
|
+
setHover(false);
|
|
51
|
+
},
|
|
52
|
+
dropped: async ({ entities }) => {
|
|
53
|
+
setHover(false);
|
|
54
|
+
const sourceField = entities[SORT_DRAG_MIME];
|
|
55
|
+
if (!sourceField || sourceField === props.sort.field) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
await props.onDropBefore(sourceField);
|
|
59
|
+
}
|
|
60
|
+
},
|
|
61
|
+
[props.sort.field]
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
return (
|
|
65
|
+
<S.SortItem
|
|
66
|
+
ref={ref}
|
|
67
|
+
hover={hover}
|
|
68
|
+
onContextMenu={async (event) => {
|
|
69
|
+
event.preventDefault();
|
|
70
|
+
const directive = await ioc.get(ComboBoxStore2).show(
|
|
71
|
+
new SimpleComboBoxDirective({
|
|
72
|
+
title: props.label,
|
|
73
|
+
event: event as any,
|
|
74
|
+
items: [
|
|
75
|
+
{
|
|
76
|
+
key: 'delete',
|
|
77
|
+
title: 'Delete sort',
|
|
78
|
+
icon: 'trash',
|
|
79
|
+
action: async () => {
|
|
80
|
+
await props.onRemove();
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
]
|
|
84
|
+
})
|
|
85
|
+
);
|
|
86
|
+
directive.getSelectedItem();
|
|
87
|
+
}}
|
|
88
|
+
>
|
|
89
|
+
<MetadataWidget
|
|
90
|
+
onClick={props.onToggle}
|
|
91
|
+
label={props.label}
|
|
92
|
+
value={props.sort.direction === SortDirection.ASC ? 'ASC' : 'DESC'}
|
|
93
|
+
/>
|
|
94
|
+
<S.CloseButton
|
|
95
|
+
mode={PanelButtonMode.LINK}
|
|
96
|
+
icon="close"
|
|
97
|
+
tooltip={`Remove ${props.label} sort`}
|
|
98
|
+
action={async () => {
|
|
99
|
+
await props.onRemove();
|
|
100
|
+
}}
|
|
101
|
+
/>
|
|
102
|
+
</S.SortItem>
|
|
103
|
+
);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
namespace S {
|
|
107
|
+
export const CloseButton = styled(PanelButtonWidget)`
|
|
108
|
+
padding: 2px;
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
export const SortItem = styled.div<{ hover: boolean }>`
|
|
112
|
+
display: flex;
|
|
113
|
+
flex-direction: row;
|
|
114
|
+
align-items: center;
|
|
115
|
+
border-radius: 4px;
|
|
116
|
+
padding: 2px;
|
|
117
|
+
background: ${(p) => (p.hover ? getTransparentColor(p.theme.dnd.hoverColor, 0.35) : 'transparent')};
|
|
118
|
+
`;
|
|
119
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import {
|
|
3
|
+
ComboBoxItem,
|
|
4
|
+
ComboBoxStore2,
|
|
5
|
+
InputContainerWidget,
|
|
6
|
+
ioc,
|
|
7
|
+
PanelButtonWidget,
|
|
8
|
+
SimpleComboBoxDirective,
|
|
9
|
+
styled
|
|
10
|
+
} from '@journeyapps-labs/reactor-mod';
|
|
11
|
+
import { SimpleQuery, SimpleQuerySort } from '../../../core/query/query-simple/SimpleQuery';
|
|
12
|
+
import { SortChipWidget } from './SortChipWidget';
|
|
13
|
+
|
|
14
|
+
export interface SortControlsWidgetProps {
|
|
15
|
+
simpleQuery: SimpleQuery;
|
|
16
|
+
goToPage?: (index: number) => any;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export const SortControlsWidget: React.FC<SortControlsWidgetProps> = (props) => {
|
|
20
|
+
const showAddSortMenu = async (event: React.MouseEvent<any>) => {
|
|
21
|
+
const used = new Set(props.simpleQuery.sortState.sorts.map((sort) => sort.field));
|
|
22
|
+
const fields = props.simpleQuery.sortState.getSortableFields().filter((field) => !used.has(field.key));
|
|
23
|
+
if (fields.length === 0) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const directive = await ioc.get(ComboBoxStore2).show(
|
|
27
|
+
new SimpleComboBoxDirective({
|
|
28
|
+
title: 'Add sort',
|
|
29
|
+
event: event as any,
|
|
30
|
+
items: fields.map((field) => {
|
|
31
|
+
return {
|
|
32
|
+
key: field.key,
|
|
33
|
+
title: field.label,
|
|
34
|
+
action: async () => {
|
|
35
|
+
props.simpleQuery.sortState.addSort(SimpleQuerySort.create(field.key));
|
|
36
|
+
props.goToPage?.(0);
|
|
37
|
+
}
|
|
38
|
+
} as ComboBoxItem;
|
|
39
|
+
})
|
|
40
|
+
})
|
|
41
|
+
);
|
|
42
|
+
directive.getSelectedItem();
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const getSortLabel = (field: string) => {
|
|
46
|
+
const resolved = props.simpleQuery.sortState.getSortableFields().find((entry) => entry.key === field);
|
|
47
|
+
return resolved?.label || field;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<InputContainerWidget label="Sort">
|
|
52
|
+
<S.Group>
|
|
53
|
+
<PanelButtonWidget
|
|
54
|
+
icon="plus"
|
|
55
|
+
tooltip="Add sort"
|
|
56
|
+
action={async (event) => {
|
|
57
|
+
await showAddSortMenu(event as any);
|
|
58
|
+
}}
|
|
59
|
+
/>
|
|
60
|
+
{props.simpleQuery.sortState.sorts.map((sort) => {
|
|
61
|
+
return (
|
|
62
|
+
<SortChipWidget
|
|
63
|
+
key={sort.field}
|
|
64
|
+
sort={sort}
|
|
65
|
+
label={getSortLabel(sort.field)}
|
|
66
|
+
onToggle={async () => {
|
|
67
|
+
sort.toggle();
|
|
68
|
+
props.goToPage?.(0);
|
|
69
|
+
}}
|
|
70
|
+
onRemove={async () => {
|
|
71
|
+
sort.remove();
|
|
72
|
+
props.goToPage?.(0);
|
|
73
|
+
}}
|
|
74
|
+
onDropBefore={async (sourceField) => {
|
|
75
|
+
props.simpleQuery.sortState.moveSortBefore(sourceField, sort.field);
|
|
76
|
+
props.goToPage?.(0);
|
|
77
|
+
}}
|
|
78
|
+
/>
|
|
79
|
+
);
|
|
80
|
+
})}
|
|
81
|
+
</S.Group>
|
|
82
|
+
</InputContainerWidget>
|
|
83
|
+
);
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
namespace S {
|
|
87
|
+
export const Group = styled.div`
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: row;
|
|
90
|
+
align-items: center;
|
|
91
|
+
column-gap: 5px;
|
|
92
|
+
row-gap: 5px;
|
|
93
|
+
flex-wrap: wrap;
|
|
94
|
+
`;
|
|
95
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BooleanSetting, PrefsStore } from '@journeyapps-labs/reactor-mod';
|
|
2
|
+
|
|
3
|
+
export enum QueryControlPreferences {
|
|
4
|
+
SHOW_SORT_CONTROLS = 'databrowser/query-controls/show-sort-controls',
|
|
5
|
+
SHOW_FILTER_CONTROLS = 'databrowser/query-controls/show-filter-controls',
|
|
6
|
+
FILTER_NULL_FIELDS_IN_RELATIONSHIP_PEEK = 'databrowser/query-controls/filter-null-fields-in-relationship-peek'
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export const registerQueryControlPreferences = (prefsStore: PrefsStore) => {
|
|
10
|
+
prefsStore.registerPreference(
|
|
11
|
+
new BooleanSetting({
|
|
12
|
+
key: QueryControlPreferences.SHOW_SORT_CONTROLS,
|
|
13
|
+
checked: true,
|
|
14
|
+
name: 'Show sort controls',
|
|
15
|
+
category: 'Query Controls'
|
|
16
|
+
})
|
|
17
|
+
);
|
|
18
|
+
prefsStore.registerPreference(
|
|
19
|
+
new BooleanSetting({
|
|
20
|
+
key: QueryControlPreferences.SHOW_FILTER_CONTROLS,
|
|
21
|
+
checked: true,
|
|
22
|
+
name: 'Show filter controls',
|
|
23
|
+
category: 'Query Controls'
|
|
24
|
+
})
|
|
25
|
+
);
|
|
26
|
+
prefsStore.registerPreference(
|
|
27
|
+
new BooleanSetting({
|
|
28
|
+
key: QueryControlPreferences.FILTER_NULL_FIELDS_IN_RELATIONSHIP_PEEK,
|
|
29
|
+
checked: true,
|
|
30
|
+
name: 'Hide null fields in relationship peek',
|
|
31
|
+
category: 'Query Controls'
|
|
32
|
+
})
|
|
33
|
+
);
|
|
34
|
+
};
|
|
@@ -2,6 +2,7 @@ import { AbstractStore, LocalStorageSerializer } from '@journeyapps-labs/reactor
|
|
|
2
2
|
import { AbstractConnection, AbstractConnectionSerialized } from '../core/AbstractConnection';
|
|
3
3
|
import { action, computed, observable, runInAction, when } from 'mobx';
|
|
4
4
|
import { AbstractConnectionFactory } from '../core/AbstractConnectionFactory';
|
|
5
|
+
import { getDefaultConnectionColor } from '../core/connection-colors';
|
|
5
6
|
|
|
6
7
|
export interface ConnectionStoreSerialized {
|
|
7
8
|
connections: AbstractConnectionSerialized[];
|
|
@@ -53,6 +54,7 @@ export class ConnectionStore extends AbstractStore<ConnectionStoreSerialized> {
|
|
|
53
54
|
let conn = this._connectionFactories.get(data.factory).generateConnection();
|
|
54
55
|
conn.id = data.id;
|
|
55
56
|
await conn._deSerialize(data.payload);
|
|
57
|
+
conn.color = data.color || getDefaultConnectionColor(conn.id);
|
|
56
58
|
return conn;
|
|
57
59
|
}
|
|
58
60
|
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { AbstractStore, inject, LocalStorageSerializer } from '@journeyapps-labs/reactor-mod';
|
|
2
|
+
import { action, computed, observable } from 'mobx';
|
|
3
|
+
import { v4 } from 'uuid';
|
|
4
|
+
import { SimpleQuery, SimpleQueryEncoded } from '../core/query/query-simple/SimpleQuery';
|
|
5
|
+
import { ConnectionStore } from './ConnectionStore';
|
|
6
|
+
|
|
7
|
+
export interface SavedQuery {
|
|
8
|
+
id: string;
|
|
9
|
+
name: string;
|
|
10
|
+
created_at: string;
|
|
11
|
+
updated_at: string;
|
|
12
|
+
query: SimpleQueryEncoded;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface SavedQueryStoreSerialized {
|
|
16
|
+
queries: SavedQuery[];
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export class SavedQueryEntity {
|
|
20
|
+
constructor(public saved: SavedQuery) {}
|
|
21
|
+
|
|
22
|
+
get id(): string {
|
|
23
|
+
return this.saved.id;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
get name(): string {
|
|
27
|
+
return this.saved.name;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export class SavedQueryStore extends AbstractStore<SavedQueryStoreSerialized> {
|
|
32
|
+
@inject(ConnectionStore)
|
|
33
|
+
accessor connectionStore: ConnectionStore;
|
|
34
|
+
|
|
35
|
+
@observable
|
|
36
|
+
protected accessor _queries: SavedQuery[];
|
|
37
|
+
|
|
38
|
+
constructor() {
|
|
39
|
+
super({
|
|
40
|
+
name: 'SAVED_QUERY_STORE',
|
|
41
|
+
serializer: new LocalStorageSerializer({
|
|
42
|
+
key: 'SAVED_QUERY_STORE'
|
|
43
|
+
})
|
|
44
|
+
});
|
|
45
|
+
this._queries = [];
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
@computed
|
|
49
|
+
get queries(): SavedQuery[] {
|
|
50
|
+
return [...this._queries].sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
protected serialize(): SavedQueryStoreSerialized {
|
|
54
|
+
return {
|
|
55
|
+
queries: this._queries
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
protected async deserialize(data: SavedQueryStoreSerialized): Promise<void> {
|
|
60
|
+
this._queries = data?.queries || [];
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
getSavedForQuery(query: SimpleQuery): SavedQuery[] {
|
|
64
|
+
const definition = query.options.definition?.definition?.name;
|
|
65
|
+
const connectionID = query.connection?.id;
|
|
66
|
+
return this.queries.filter((saved) => {
|
|
67
|
+
return saved.query.definition === definition && saved.query.connection_id === connectionID;
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
getSavedEntitiesForConnection(connectionID: string): SavedQueryEntity[] {
|
|
72
|
+
return this.queries
|
|
73
|
+
.filter((saved) => saved.query.connection_id === connectionID)
|
|
74
|
+
.map((saved) => new SavedQueryEntity(saved));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@action
|
|
78
|
+
async saveQuery(name: string, query: SimpleQuery): Promise<SavedQuery> {
|
|
79
|
+
const now = new Date().toISOString();
|
|
80
|
+
const saved: SavedQuery = {
|
|
81
|
+
id: v4(),
|
|
82
|
+
name,
|
|
83
|
+
created_at: now,
|
|
84
|
+
updated_at: now,
|
|
85
|
+
query: query.serialize()
|
|
86
|
+
};
|
|
87
|
+
this._queries.push(saved);
|
|
88
|
+
await this.save();
|
|
89
|
+
return saved;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
getByID(id: string): SavedQuery | null {
|
|
93
|
+
return this._queries.find((query) => query.id === id) || null;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getSavedEntityByID(id: string): SavedQueryEntity | null {
|
|
97
|
+
const saved = this.getByID(id);
|
|
98
|
+
if (!saved) {
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
return new SavedQueryEntity(saved);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async loadSavedQuery(id: string): Promise<SimpleQuery | null> {
|
|
105
|
+
const saved = this.getByID(id);
|
|
106
|
+
if (!saved) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
const query = new SimpleQuery({
|
|
110
|
+
limit: saved.query.limit
|
|
111
|
+
});
|
|
112
|
+
await query.deserialize(this.connectionStore, saved.query);
|
|
113
|
+
return query;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
@action
|
|
117
|
+
async removeSavedQuery(id: string): Promise<void> {
|
|
118
|
+
this._queries = this._queries.filter((query) => query.id !== id);
|
|
119
|
+
await this.save();
|
|
120
|
+
}
|
|
121
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { themed } from '@journeyapps-labs/reactor-mod';
|
|
3
|
+
|
|
4
|
+
export interface EmptyValueWidgetProps {
|
|
5
|
+
label?: string;
|
|
6
|
+
className?: any;
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const EmptyValueWidget: React.FC<EmptyValueWidgetProps> = (props) => {
|
|
11
|
+
const value = props.children ?? props.label ?? 'null';
|
|
12
|
+
return <S.Label className={props.className}>{value}</S.Label>;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
namespace S {
|
|
16
|
+
export const Label = themed.span`
|
|
17
|
+
color: ${(p) => p.theme.text.secondary};
|
|
18
|
+
opacity: 0.6;
|
|
19
|
+
`;
|
|
20
|
+
}
|