@orchestrator-ui/orchestrator-ui-components 8.9.3 → 9.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.
- package/.turbo/turbo-build.log +8 -8
- package/.turbo/turbo-lint.log +1 -1
- package/.turbo/turbo-test.log +17 -50
- package/CHANGELOG.md +19 -0
- package/dist/index.d.ts +2081 -2517
- package/dist/index.js +1247 -1579
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/components/WfoError/WfoError.tsx +2 -2
- package/src/components/WfoInlineNoteEdit/WfoSubscriptionDetailNoteEdit.tsx +4 -8
- package/src/components/WfoInlineNoteEdit/WfoSubscriptionNoteEdit.tsx +6 -7
- package/src/components/WfoPageTemplate/paths.ts +0 -1
- package/src/components/WfoSubscriptionsList/index.ts +1 -2
- package/src/components/WfoSubscriptionsList/subscriptionListItem.ts +14 -0
- package/src/components/WfoSubscriptionsList/subscriptionListTabs.ts +1 -20
- package/src/components/WfoSummary/WfoLatestActiveSubscriptionsSummaryCard.tsx +17 -13
- package/src/components/WfoSummary/WfoLatestOutOfSyncSubscriptionSummaryCard.tsx +28 -15
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoFieldSelector.spec.tsx +0 -16
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoFieldSelector.tsx +4 -10
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoFilterBuilder.tsx +9 -6
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoRestoreLoop.spec.tsx +2 -2
- package/src/components/WfoTable/WfoStructuredSearchTable/WfoStructuredSearchTable.tsx +3 -5
- package/src/components/WfoTable/WfoStructuredSearchTable/useSearchWithDebouncedCallback.spec.tsx +56 -3
- package/src/components/WfoTable/WfoStructuredSearchTable/utils.spec.ts +60 -1
- package/src/components/WfoTable/WfoStructuredSearchTable/utils.ts +27 -3
- package/src/configuration/version.ts +1 -1
- package/src/messages/en-GB.json +1 -1
- package/src/messages/nl-NL.json +1 -1
- package/src/pages/index.ts +0 -1
- package/src/pages/startPage/index.ts +1 -0
- package/src/pages/startPage/mappers.ts +15 -8
- package/src/pages/startPage/queryVariables.ts +0 -29
- package/src/pages/startPage/searchPayloads.ts +22 -0
- package/src/pages/subscriptions/WfoSubscriptionsListPage.tsx +511 -39
- package/src/rtk/endpoints/index.ts +0 -1
- package/src/rtk/endpoints/search.ts +3 -0
- package/src/rtk/endpoints/subscriptionListMutation.spec.ts +80 -0
- package/src/rtk/endpoints/subscriptionListMutation.ts +71 -52
- package/src/rtk/utils.spec.ts +30 -1
- package/src/rtk/utils.ts +2 -1
- package/src/types/search.ts +0 -1
- package/src/types/types.ts +0 -2
- package/src/utils/getDefaultTableConfig.ts +1 -6
- package/src/utils/getQueryParams.ts +1 -0
- package/src/components/WfoSubscriptionsList/WfoSubscriptionsList.tsx +0 -243
- package/src/components/WfoSubscriptionsList/subscriptionResultMappers.ts +0 -49
- package/src/pages/WfoSearchPocPage.tsx +0 -575
- package/src/rtk/endpoints/subscriptionListSummary.ts +0 -66
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type KeyboardEventHandler, useEffect, useRef } from 'react';
|
|
2
|
-
import { FullOperator, RuleGroupType, generateID } from 'react-querybuilder';
|
|
2
|
+
import { FullOperator, RuleGroupType, RuleType, generateID } from 'react-querybuilder';
|
|
3
3
|
import { prepareRuleGroup } from 'react-querybuilder';
|
|
4
4
|
import { parseCEL } from 'react-querybuilder/parseCEL';
|
|
5
5
|
|
|
@@ -11,12 +11,14 @@ export const FILTER_CHANGE_DEBOUNCE_DELAY = 1000;
|
|
|
11
11
|
interface SearchWithDebouncedCallbackProps {
|
|
12
12
|
filterString?: string;
|
|
13
13
|
isValidFilterString: boolean;
|
|
14
|
+
hasEmptyRuleValue?: boolean;
|
|
14
15
|
searchCallback: () => void;
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
export const useSearchWithDebouncedCallback = ({
|
|
18
19
|
filterString,
|
|
19
20
|
isValidFilterString,
|
|
21
|
+
hasEmptyRuleValue = false,
|
|
20
22
|
searchCallback,
|
|
21
23
|
}: SearchWithDebouncedCallbackProps) => {
|
|
22
24
|
const {
|
|
@@ -38,12 +40,12 @@ export const useSearchWithDebouncedCallback = ({
|
|
|
38
40
|
|
|
39
41
|
if (!hasFilterStringChanged) return;
|
|
40
42
|
|
|
41
|
-
if (isValidFilterString) {
|
|
43
|
+
if (isValidFilterString && !hasEmptyRuleValue) {
|
|
42
44
|
triggerSearch(FILTER_CHANGE_DEBOUNCE_DELAY);
|
|
43
45
|
} else {
|
|
44
46
|
cancelSearch();
|
|
45
47
|
}
|
|
46
|
-
}, [filterString, isValidFilterString, triggerSearch, cancelSearch]);
|
|
48
|
+
}, [filterString, isValidFilterString, hasEmptyRuleValue, triggerSearch, cancelSearch]);
|
|
47
49
|
|
|
48
50
|
// Enter applies the filter exactly like that button; Shift+Enter is left alone so it can
|
|
49
51
|
// insert a newline in a textarea.
|
|
@@ -159,6 +161,28 @@ const SEARCH_OPERATOR_TO_RQB_OPERATOR_MAP: Record<string, string> = {
|
|
|
159
161
|
// Operators without a value; marking them unary makes react-querybuilder's Rule hide the value editor.
|
|
160
162
|
const RQB_UNARY_OPERATORS = ['null', 'notNull'];
|
|
161
163
|
|
|
164
|
+
const isEmptyValue = (rule: RuleType): boolean => {
|
|
165
|
+
const { value } = rule;
|
|
166
|
+
if (RQB_UNARY_OPERATORS.includes(rule.operator)) {
|
|
167
|
+
return false;
|
|
168
|
+
} else if (typeof value !== 'string') {
|
|
169
|
+
return value === undefined || value === null;
|
|
170
|
+
} else if (rule.operator === 'between') {
|
|
171
|
+
const rangeParts = value.split(',');
|
|
172
|
+
return rangeParts.length < 2 || rangeParts.some((rangePart) => rangePart.trim() === '');
|
|
173
|
+
}
|
|
174
|
+
return value.trim() === '';
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
/** True when any rule of the group, nested groups included, has an empty value editor. */
|
|
178
|
+
export const hasNestedRuleWithEmptyValue = (ruleGroup?: RuleGroupType): boolean =>
|
|
179
|
+
!!ruleGroup?.rules.some((rule) => {
|
|
180
|
+
if (typeof rule === 'string') {
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
return 'rules' in rule ? hasNestedRuleWithEmptyValue(rule) : isEmptyValue(rule);
|
|
184
|
+
});
|
|
185
|
+
|
|
162
186
|
const OPERATOR_MAP: Record<string, OperatorDisplay> = {
|
|
163
187
|
eq: { symbol: '=', description: 'equals' },
|
|
164
188
|
neq: { symbol: '≠', description: 'not equals' },
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '
|
|
1
|
+
export const ORCHESTRATOR_UI_LIBRARY_VERSION = '9.0.0';
|
package/src/messages/en-GB.json
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"retrieverHybrid": "Hybrid",
|
|
24
24
|
"retrieverSemantic": "Semantic",
|
|
25
25
|
"search": "Search",
|
|
26
|
+
"searchError": "Search failed",
|
|
26
27
|
"searchModalText": "<p>Different options are available from free text search covering all data columns, or column specific filtering. Note that: <p></p><ul><li>Hidden columns are included</li> <li>Searching is case-insensitive</li> <li>Ordering of words does not matter (unless it is a Phrase)</li> <li>TSV (text search vector) search only available for subscriptions table</li></ul></p> <p>For example:</p> <li><b>\"l2vpn\"</b> – free text search</li> <li><b>tag:l2vpn</b> – search in a specific column</li><li><b>tag:lp description:test</b> – search in multiple columns</li><li><b>tag:(lp|lr)</b> – multiselect within 1 column</li><li><b>-tag:lp</b> – negated filter</li><li><b>test*</b> – prefix filter</li> <p></p><p><b>Note:</b> Search words containing characters `|-*():\"` may not be valid, as they are part of the search query grammar</p><p>Invalid search strings are for example:</p><ul><li>2a10:e300:fff0::/48</li> <li>\"node123(planned)\"</li> <li>\"node123|planned\"</li></ul>",
|
|
27
28
|
"searchModalTitle": "Search string options",
|
|
28
29
|
"showAllColumnsInDetailView": "Show all columns in detail view",
|
|
@@ -550,7 +551,6 @@
|
|
|
550
551
|
},
|
|
551
552
|
"index": {
|
|
552
553
|
"customerFullname": "Customer",
|
|
553
|
-
"customerId": "Customer ID",
|
|
554
554
|
"customerShortcode": "Customer abbr",
|
|
555
555
|
"description": "Description",
|
|
556
556
|
"endDate": "End date",
|
package/src/messages/nl-NL.json
CHANGED
|
@@ -23,6 +23,7 @@
|
|
|
23
23
|
"retrieverHybrid": "Hybride",
|
|
24
24
|
"retrieverSemantic": "Semantic",
|
|
25
25
|
"search": "Zoeken",
|
|
26
|
+
"searchError": "Zoeken mislukt",
|
|
26
27
|
"searchModalText": "<p>Er zijn verschillende opties beschikbaar: zoeken in vrije tekst voor alle datakolommen en specifiek per kolom te filteren. Houd er rekening mee dat: </p><p></p><ul><li>Verborgen kolommen zijn inbegrepen</li> <li>Zoeken is niet hoofdlettergevoelig</li> <li>De volgorde van woorden doet er niet toe (tenzij het een quote)</li> <li>TSV (text search vector) zoekactie alleen beschikbaar voor subscription tabel</li></ul><p>Bijvoorbeeld:</p> <li><b>\"l2vpn\"</b> – vrije tekst search</li> <li><b>tag:l2vpn</b> – zoeken in een specifieke kolom</li> <li><b>tag:lp beschrijving: test</b> – zoeken in meerdere kolommen</li><li><b>tag:(lp|lr)</b> – multi select binnen 1 kolom</li> <li><b>-tag:lp</b> – omgekeerd filteren</li> <li><b>test*</b> – prefix filter</li> <p></p><p><b>Opmerking:</b> Zoeken op woorden die tekens `|-*():\"` bevatten, zijn mogelijk niet geldig, omdat ze deel uitmaken van de grammatica van de zoekfunctie</p><p>Ongeldige zoekwoorden zijn bijvoorbeeld:</p><ul><li>2a10:e300:fff0::/48</li> <li>\"node123(gepland)\"</li> <li>\"node123|gepland\"</li></ul>",
|
|
27
28
|
"searchModalTitle": "Zoekwoorden opties",
|
|
28
29
|
"showAllColumnsInDetailView": "Toon alle kolommen in detailweergave",
|
|
@@ -550,7 +551,6 @@
|
|
|
550
551
|
},
|
|
551
552
|
"index": {
|
|
552
553
|
"customerFullname": "Klant",
|
|
553
|
-
"customerId": "Klant ID",
|
|
554
554
|
"customerShortcode": "Klantafkorting",
|
|
555
555
|
"description": "Beschrijving",
|
|
556
556
|
"endDate": "Einddatum",
|
package/src/pages/index.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
import { PATH_SUBSCRIPTIONS, PATH_WORKFLOWS } from '@/components';
|
|
2
2
|
import { SummaryCardListItem } from '@/components/WfoSummary';
|
|
3
3
|
import { ProcessSummary } from '@/rtk';
|
|
4
|
-
import {
|
|
4
|
+
import { SearchResult } from '@/types';
|
|
5
5
|
import { formatDate } from '@/utils';
|
|
6
6
|
|
|
7
|
+
import {
|
|
8
|
+
SUBSCRIPTION_DESCRIPTION_COLUMN,
|
|
9
|
+
SUBSCRIPTION_ID_COLUMN,
|
|
10
|
+
SUBSCRIPTION_START_DATE_COLUMN,
|
|
11
|
+
} from './searchPayloads';
|
|
12
|
+
|
|
7
13
|
export const mapProcessSummaryToSummaryCardListItem = (processSummary: ProcessSummary): SummaryCardListItem => ({
|
|
8
14
|
title: processSummary.workflowName,
|
|
9
15
|
value: formatDate(processSummary?.startedAt),
|
|
10
16
|
url: `${PATH_WORKFLOWS}/${processSummary.processId}`,
|
|
11
17
|
});
|
|
12
18
|
|
|
13
|
-
export const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
19
|
+
export const mapSubscriptionSearchResultToSummaryCardListItem = (result: SearchResult): SummaryCardListItem => {
|
|
20
|
+
const { response_columns } = result;
|
|
21
|
+
return {
|
|
22
|
+
title: String(response_columns[SUBSCRIPTION_DESCRIPTION_COLUMN] ?? ''),
|
|
23
|
+
value: formatDate(response_columns[SUBSCRIPTION_START_DATE_COLUMN] as string | null),
|
|
24
|
+
url: `${PATH_SUBSCRIPTIONS}/${response_columns[SUBSCRIPTION_ID_COLUMN]}`,
|
|
25
|
+
};
|
|
26
|
+
};
|
|
@@ -13,14 +13,6 @@ const baseQueryVariables: Partial<GraphqlQueryVariables<unknown>> = {
|
|
|
13
13
|
first: 5,
|
|
14
14
|
after: 0,
|
|
15
15
|
};
|
|
16
|
-
const baseQueryVariablesForSubscription: Partial<GraphqlQueryVariables<Subscription>> = {
|
|
17
|
-
...baseQueryVariables,
|
|
18
|
-
sortBy: {
|
|
19
|
-
field: 'startDate',
|
|
20
|
-
order: SortOrder.DESC,
|
|
21
|
-
},
|
|
22
|
-
};
|
|
23
|
-
|
|
24
16
|
const baseQueryVariablesForProcess: Partial<GraphqlQueryVariables<Process>> = {
|
|
25
17
|
...baseQueryVariables,
|
|
26
18
|
sortBy: {
|
|
@@ -41,27 +33,6 @@ const getTaskFilter = (isTask: boolean): GraphqlFilter<Process> => {
|
|
|
41
33
|
};
|
|
42
34
|
};
|
|
43
35
|
|
|
44
|
-
export const subscriptionsListSummaryQueryVariables: GraphqlQueryVariables<Subscription> = {
|
|
45
|
-
...baseQueryVariablesForSubscription,
|
|
46
|
-
filterBy: [
|
|
47
|
-
{
|
|
48
|
-
field: 'status',
|
|
49
|
-
value: 'Active',
|
|
50
|
-
},
|
|
51
|
-
],
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const outOfSyncSubscriptionsListSummaryQueryVariables: GraphqlQueryVariables<Subscription> = {
|
|
55
|
-
...baseQueryVariablesForSubscription,
|
|
56
|
-
query: 'insync:false',
|
|
57
|
-
filterBy: [
|
|
58
|
-
{
|
|
59
|
-
field: 'status',
|
|
60
|
-
value: 'Active-Provisioning',
|
|
61
|
-
},
|
|
62
|
-
],
|
|
63
|
-
};
|
|
64
|
-
|
|
65
36
|
export const getMyWorkflowListSummaryQueryVariables = (username: string): GraphqlQueryVariables<Process> => ({
|
|
66
37
|
...baseQueryVariablesForProcess,
|
|
67
38
|
filterBy: [
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { SearchPayload } from '@/rtk';
|
|
2
|
+
import { EntityKind, Filter } from '@/types';
|
|
3
|
+
|
|
4
|
+
export const SUBSCRIPTION_ID_COLUMN = 'subscription.subscription_id';
|
|
5
|
+
export const SUBSCRIPTION_DESCRIPTION_COLUMN = 'subscription.description';
|
|
6
|
+
export const SUBSCRIPTION_START_DATE_COLUMN = 'subscription.start_date';
|
|
7
|
+
|
|
8
|
+
const SUMMARY_CARD_ITEM_COUNT = 5;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Builds the search payload shared by the subscription summary cards on the start page: the five
|
|
12
|
+
* most recently started subscriptions matching `filters`, with just the columns the card renders.
|
|
13
|
+
* `filters` is an Elasticsearch bool query, the same shape the subscriptions list page sends.
|
|
14
|
+
*/
|
|
15
|
+
export const getSubscriptionSummarySearchPayload = (filters: Filter): SearchPayload => ({
|
|
16
|
+
entity_type: EntityKind.SUBSCRIPTION,
|
|
17
|
+
query: '',
|
|
18
|
+
filters,
|
|
19
|
+
limit: SUMMARY_CARD_ITEM_COUNT,
|
|
20
|
+
order_by: { element: SUBSCRIPTION_START_DATE_COLUMN, direction: 'desc' },
|
|
21
|
+
response_columns: [SUBSCRIPTION_ID_COLUMN, SUBSCRIPTION_DESCRIPTION_COLUMN, SUBSCRIPTION_START_DATE_COLUMN],
|
|
22
|
+
});
|