diff --git a/DSL/Resql/services/get-common-services-list.sql b/DSL/Resql/services/get-common-services-list.sql new file mode 100644 index 00000000..c331aeb9 --- /dev/null +++ b/DSL/Resql/services/get-common-services-list.sql @@ -0,0 +1,41 @@ +WITH MaxServices AS ( + SELECT MAX(id) AS maxId + FROM services + GROUP BY service_id +) +SELECT + id, + name, + description, + current_state AS state, + ruuter_type AS type, + is_common AS isCommon, + structure::json, + subquery.endpoints::json AS endpoints, + service_id, + CEIL(COUNT(*) OVER() / :page_size::DECIMAL) AS total_pages +FROM services +JOIN MaxServices ON id = maxId +JOIN ( + SELECT jsonb_agg(endpoint) AS endpoints + FROM ( + SELECT DISTINCT endpoint + FROM ( + SELECT endpoint::jsonb + FROM services, json_array_elements(endpoints) AS endpoint + WHERE (endpoint->>'isCommon')::boolean = true + UNION + SELECT endpoint::jsonb + FROM services, json_array_elements(endpoints) AS endpoint, MaxServices + WHERE id = maxId + ) AS combined_endpoints + ) subquery +) subquery ON true +WHERE NOT deleted AND is_common +ORDER BY + CASE WHEN :sorting = 'id asc' THEN id END ASC, + CASE WHEN :sorting = 'name asc' THEN name END ASC, + CASE WHEN :sorting = 'name desc' THEN name END DESC, + CASE WHEN :sorting = 'state asc' THEN current_state END ASC, + CASE WHEN :sorting = 'state desc' THEN current_state END DESC +OFFSET ((GREATEST(:page, 1) - 1) * :page_size) LIMIT :page_size; diff --git a/DSL/Resql/services/get-services-list.sql b/DSL/Resql/services/get-services-list.sql index c44ed0f2..51ca1eec 100644 --- a/DSL/Resql/services/get-services-list.sql +++ b/DSL/Resql/services/get-services-list.sql @@ -12,7 +12,8 @@ SELECT is_common AS isCommon, structure::json, subquery.endpoints::json AS endpoints, - service_id + service_id, + CEIL(COUNT(*) OVER() / :page_size::DECIMAL) AS total_pages FROM services JOIN MaxServices ON id = maxId JOIN ( @@ -30,5 +31,11 @@ JOIN ( ) AS combined_endpoints ) subquery ) subquery ON true -WHERE NOT deleted -ORDER BY id ASC; +WHERE NOT deleted AND NOT is_common +ORDER BY + CASE WHEN :sorting = 'id asc' THEN id END ASC, + CASE WHEN :sorting = 'name asc' THEN name END ASC, + CASE WHEN :sorting = 'name desc' THEN name END DESC, + CASE WHEN :sorting = 'state asc' THEN current_state END ASC, + CASE WHEN :sorting = 'state desc' THEN current_state END DESC +OFFSET ((GREATEST(:page, 1) - 1) * :page_size) LIMIT :page_size; diff --git a/DSL/Resql/training/get-available-intents.sql b/DSL/Resql/training/get-available-intents.sql index 0ca35ba8..691498ca 100644 --- a/DSL/Resql/training/get-available-intents.sql +++ b/DSL/Resql/training/get-available-intents.sql @@ -19,9 +19,12 @@ WITH connected_intents AS service_name) AND status in ('pending', 'approved')) -SELECT intent +SELECT intent, CEIL(COUNT(*) OVER() / :page_size::DECIMAL) AS total_pages FROM intent WHERE intent NOT IN (SELECT intent FROM connected_intents) -ORDER BY intent ASC +ORDER BY + CASE WHEN :sorting = 'intent asc' THEN intent END ASC, + CASE WHEN :sorting = 'intent desc' THEN intent END DESC +OFFSET ((GREATEST(:page, 1) - 1) * :page_size) LIMIT :page_size; diff --git a/DSL/Resql/training/get-requested-service-triggers.sql b/DSL/Resql/training/get-requested-service-triggers.sql index 974ffde7..3510b0bf 100644 --- a/DSL/Resql/training/get-requested-service-triggers.sql +++ b/DSL/Resql/training/get-requested-service-triggers.sql @@ -2,9 +2,18 @@ SELECT intent, service, MAX(service_name) AS service_name, MAX(created) AS requested_at, - MAX(author_role) as author_role + MAX(author_role) as author_role, + CEIL(COUNT(*) OVER() / :page_size::DECIMAL) AS total_pages FROM service_trigger GROUP BY intent, - service + service HAVING MAX(status) = 'pending' -AND MAX("author_role") != 'service_manager'; +AND MAX("author_role") != 'service_manager' +ORDER BY + CASE WHEN :sorting = 'intent asc' THEN intent END ASC, + CASE WHEN :sorting = 'intent desc' THEN intent END DESC, + CASE WHEN :sorting = 'serviceName asc' THEN MAX(service_name) END ASC, + CASE WHEN :sorting = 'serviceName desc' THEN MAX(service_name) END DESC, + CASE WHEN :sorting = 'requestedAt asc' THEN MAX(created) END ASC, + CASE WHEN :sorting = 'requestedAt desc' THEN MAX(created) END DESC +OFFSET ((GREATEST(:page, 1) - 1) * :page_size) LIMIT :page_size; diff --git a/DSL/Ruuter/GET/services/available-intents.yml b/DSL/Ruuter/GET/services/available-intents.yml deleted file mode 100644 index 5e768c82..00000000 --- a/DSL/Ruuter/GET/services/available-intents.yml +++ /dev/null @@ -1,17 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'AVAILABLE-INTENTS'" - method: get - accepts: json - returns: json - namespace: service - -get_available_intents: - call: http.post - args: - url: "[#SERVICE_TRAINING_RESQL]/get-available-intents" - result: res - -return_result: - return: ${res.response.body} diff --git a/DSL/Ruuter/GET/services/connection-requests.yml b/DSL/Ruuter/GET/services/connection-requests.yml deleted file mode 100644 index fc0e7a04..00000000 --- a/DSL/Ruuter/GET/services/connection-requests.yml +++ /dev/null @@ -1,17 +0,0 @@ -declaration: - call: declare - version: 0.1 - description: "Decription placeholder for 'CONNECTION-REQUESTS'" - method: get - accepts: json - returns: json - namespace: service - -get_connection_requests: - call: http.post - args: - url: "[#SERVICE_TRAINING_RESQL]/get-requested-service-triggers" - result: res - -return_result: - return: ${res.response.body} diff --git a/DSL/Ruuter/GET/services/services-detailed/nok.yml b/DSL/Ruuter/GET/services/services-detailed/nok.yml index adbe95f5..9c903abc 100644 --- a/DSL/Ruuter/GET/services/services-detailed/nok.yml +++ b/DSL/Ruuter/GET/services/services-detailed/nok.yml @@ -6,19 +6,32 @@ declaration: accepts: json returns: json namespace: service + allowlist: + params: + - field: page + type: number + description: "Parameter 'page'" + - field: page_size + type: number + description: "Parameter 'page_size'" + - field: sorting + type: string + description: "Parameter 'sorting'" getFaults: call: http.post args: url: "[#SERVICE_OPENSEARCH]/ruuterlog/_search" query: - size: 20 + from: ${(incoming.params.page - 1) * incoming.params.page_size} + size: ${incoming.params.page_size} _source_excludes: "stackTrace,statusCode" body: + sort: [{ "timestamp": { "order": "${incoming.params.order}" } }] query: match_phrase_prefix: dslName: - query: "services/active" + query: "services/active" result: getFaultsResult mapFaultsData: @@ -26,13 +39,11 @@ mapFaultsData: args: url: "[#SERVICE_DMAPPER]/hbs/services/get-faults" headers: - type: 'json' + type: "json" body: - data: { - "hits": "${getFaultsResult.response.body.hits.hits}" - } + data: { "hits": "${getFaultsResult.response.body.hits.hits}" } result: faultsData returnSuccess: wrapper: false - return: ${faultsData.response.body} + return: ${[faultsData.response.body, getFaultsResult.response.body.hits.total.value]} diff --git a/DSL/Ruuter/POST/common-services.yml b/DSL/Ruuter/POST/common-services.yml new file mode 100644 index 00000000..b9c5feb9 --- /dev/null +++ b/DSL/Ruuter/POST/common-services.yml @@ -0,0 +1,48 @@ +declaration: + call: declare + version: 0.1 + description: "Decription placeholder for 'COMMON SERVICES'" + method: post + accepts: json + returns: json + namespace: service + allowlist: + body: + - field: page + type: number + description: "Body field 'page'" + - field: page_size + type: number + description: "Body field 'page_size'" + - field: sorting + type: string + description: "Body field 'sorting'" + +get_services_list: + call: http.post + args: + url: "[#SERVICE_RESQL]/get-common-services-list" + body: + page: ${incoming.body.page} + page_size: ${incoming.body.page_size} + sorting: ${incoming.body.sorting} + result: services_res + +assign_services_result: + assign: + services: ${services_res.response.body} + +get_approved_triggers: + call: http.post + args: + url: "[#SERVICE_TRAINING_RESQL]/get-approved-tiggers" + result: triggers_res + +assign_training_result: + assign: + triggers: ${triggers_res.response.body} + +return_ok: + status: 200 + return: ${[services, triggers]} + next: end diff --git a/DSL/Ruuter/GET/services.yml b/DSL/Ruuter/POST/services.yml similarity index 57% rename from DSL/Ruuter/GET/services.yml rename to DSL/Ruuter/POST/services.yml index 50222e44..2cb1e653 100644 --- a/DSL/Ruuter/GET/services.yml +++ b/DSL/Ruuter/POST/services.yml @@ -2,19 +2,34 @@ declaration: call: declare version: 0.1 description: "Decription placeholder for 'SERVICES'" - method: get + method: post accepts: json returns: json namespace: service + allowlist: + body: + - field: page + type: number + description: "Body field 'page'" + - field: page_size + type: number + description: "Body field 'page_size'" + - field: sorting + type: string + description: "Body field 'sorting'" get_services_list: call: http.post args: url: "[#SERVICE_RESQL]/get-services-list" + body: + page: ${incoming.body.page} + page_size: ${incoming.body.page_size} + sorting: ${incoming.body.sorting} result: services_res assign_services_result: - assign: + assign: services: ${services_res.response.body} get_approved_triggers: @@ -24,7 +39,7 @@ get_approved_triggers: result: triggers_res assign_training_result: - assign: + assign: triggers: ${triggers_res.response.body} return_ok: diff --git a/DSL/Ruuter/POST/services/available-intents.yml b/DSL/Ruuter/POST/services/available-intents.yml new file mode 100644 index 00000000..32ca0a70 --- /dev/null +++ b/DSL/Ruuter/POST/services/available-intents.yml @@ -0,0 +1,32 @@ +declaration: + call: declare + version: 0.1 + description: "Decription placeholder for 'AVAILABLE-INTENTS'" + method: post + accepts: json + returns: json + namespace: service + allowlist: + body: + - field: page + type: number + description: "Body field 'page'" + - field: page_size + type: number + description: "Body field 'page_size'" + - field: sorting + type: string + description: "Body field 'sorting'" + +get_available_intents: + call: http.post + args: + url: "[#SERVICE_TRAINING_RESQL]/get-available-intents" + body: + page: ${incoming.body.page} + page_size: ${incoming.body.page_size} + sorting: ${incoming.body.sorting} + result: res + +return_result: + return: ${res.response.body} diff --git a/DSL/Ruuter/POST/services/connection-requests.yml b/DSL/Ruuter/POST/services/connection-requests.yml new file mode 100644 index 00000000..117c028a --- /dev/null +++ b/DSL/Ruuter/POST/services/connection-requests.yml @@ -0,0 +1,32 @@ +declaration: + call: declare + version: 0.1 + description: "Decription placeholder for 'CONNECTION-REQUESTS'" + method: post + accepts: json + returns: json + namespace: service + allowlist: + body: + - field: page + type: number + description: "Body field 'page'" + - field: page_size + type: number + description: "Body field 'page_size'" + - field: sorting + type: string + description: "Body field 'sorting'" + +get_connection_requests: + call: http.post + args: + url: "[#SERVICE_TRAINING_RESQL]/get-requested-service-triggers" + body: + page: ${incoming.body.page} + page_size: ${incoming.body.page_size} + sorting: ${incoming.body.sorting} + result: res + +return_result: + return: ${res.response.body} diff --git a/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/index.tsx b/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/index.tsx index 8461c440..1c5548b5 100644 --- a/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/index.tsx +++ b/GUI/src/components/ApiEndpointCard/Endpoints/RequestVariables/index.tsx @@ -18,6 +18,7 @@ import { } from "../../../../types/request-variables"; import useServiceStore from "store/new-services.store"; import { getColumns } from "./columns"; +import { PaginationState, SortingState } from "@tanstack/react-table"; type RequestVariablesProps = { disableRawData?: boolean; @@ -45,6 +46,12 @@ const RequestVariables: React.FC = ({ const [jsonError, setJsonError] = useState(); const [key, setKey] = useState(0); const { setEndpoints, updateEndpointRawData, updateEndpointData } = useServiceStore(); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + + const [sorting, setSorting] = useState([]); const constructRow = (id: number, data: EndpointVariableData, nestedLevel: number): RequestVariablesRowData => { const value = isLive ? data.value : data.testValue; @@ -178,21 +185,21 @@ const RequestVariables: React.FC = ({ const deleteVariable = (rowData: RequestVariablesRowData) => { setEndpoints((prevEndpoints: EndpointData[]) => { - const newEndpoints : EndpointData[] = []; + const newEndpoints: EndpointData[] = []; for (const prevEndpoint of prevEndpoints) { - const defEndpoint = prevEndpoint.definedEndpoints.find(x => x.id === endpointData.id); + const defEndpoint = prevEndpoint.definedEndpoints.find((x) => x.id === endpointData.id); const endpoint = defEndpoint?.[requestTab.tab]; - if(defEndpoint && endpoint) { + if (defEndpoint && endpoint) { if (rowData.endpointVariableId && endpoint.variables.map((v) => v.id).includes(rowData.endpointVariableId)) { endpoint.variables = endpoint.variables.filter((v) => v.id !== rowData.endpointVariableId); } else { endpoint.variables - .filter(variable => ["schema", "array"].includes(variable.type)) - .forEach(variable => checkNestedVariables(rowData.endpointVariableId!, variable)); + .filter((variable) => ["schema", "array"].includes(variable.type)) + .forEach((variable) => checkNestedVariables(rowData.endpointVariableId!, variable)); } } - + newEndpoints.push(prevEndpoint); } return newEndpoints; @@ -228,19 +235,23 @@ const RequestVariables: React.FC = ({ onParametersChange(parameters); } }; - - const columns = useMemo(() => getColumns({ - rowsData, - updateParams, - requestTab, - deleteVariable, - setRowsData, - updateRowVariable, - requestValues, - isLive, - updateRowValue, - getTabsRowsData, - }), []); + + const columns = useMemo( + () => + getColumns({ + rowsData, + updateParams, + requestTab, + deleteVariable, + setRowsData, + updateRowVariable, + requestValues, + isLive, + updateRowValue, + getTabsRowsData, + }), + [] + ); const buildRawDataView = (): JSX.Element => { return ( @@ -328,7 +339,15 @@ const RequestVariables: React.FC = ({ buildRawDataView() ) : ( <> - +
)} diff --git a/GUI/src/components/DataTable/DataTable.scss b/GUI/src/components/DataTable/DataTable.scss index bc027a2c..1e02fa28 100644 --- a/GUI/src/components/DataTable/DataTable.scss +++ b/GUI/src/components/DataTable/DataTable.scss @@ -1,11 +1,25 @@ -@import 'src/styles/tools/spacing'; -@import 'src/styles/tools/color'; -@import 'src/styles/settings/variables/typography'; +@import "src/styles/tools/spacing"; +@import "src/styles/tools/color"; +@import "src/styles/settings/variables/typography"; .data-table { width: 100%; color: get-color(black-coral-20); text-align: left; + margin-bottom: 0; + display: table; + + &__scrollWrapper { + height: 100%; + overflow-x: auto; + white-space: nowrap; + display: block; + } + + thead, + tbody { + width: 100%; + } th { padding: 12px 14.5px; @@ -20,6 +34,11 @@ padding: 12px 24px 12px 16px; border-bottom: 1px solid get-color(black-coral-2); vertical-align: middle; + max-width: fit-content; + + p { + white-space: break-spaces; + } .entity { display: inline-flex; @@ -121,7 +140,8 @@ li { display: block; - a, span { + a, + span { display: flex; align-items: center; justify-content: center; @@ -135,7 +155,8 @@ } &.active { - a, span { + a, + span { color: get-color(white); background-color: get-color(sapphire-blue-10); } @@ -160,10 +181,10 @@ height: 30px; min-width: 50px; padding: 6px 10px; - border: 1px solid #8F91A8; + border: 1px solid #8f91a8; border-radius: 2px; background-color: get-color(white); - background-image: url('data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iNiIgdmlld0JveD0iMCAwIDEwIDYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNS4zMTMwNiA1LjgwODIyQzUuMTU2ODUgNS45NjQ0MyA0LjkwMzU4IDUuOTY0NDMgNC43NDczNyA1LjgwODIyTDAuMjgyNzMgMS4zNDM1OEMwLjEyNjUyIDEuMTg3MzcgMC4xMjY1MiAwLjkzNDEwMiAwLjI4MjczIDAuNzc3ODkzTDAuNzc3NzA0IDAuMjgyOTE4QzAuOTMzOTE0IDAuMTI2NzA4IDEuMTg3MTggMC4xMjY3MDggMS4zNDMzOSAwLjI4MjkxN0w1LjAzMDIyIDMuOTY5NzRMOC43MTcwNCAwLjI4MjkxN0M4Ljg3MzI1IDAuMTI2NzA4IDkuMTI2NTIgMC4xMjY3MDggOS4yODI3MyAwLjI4MjkxN0w5Ljc3NzcgMC43Nzc4OTJDOS45MzM5MSAwLjkzNDEwMiA5LjkzMzkxIDEuMTg3MzcgOS43Nzc3IDEuMzQzNThMNS4zMTMwNiA1LjgwODIyWiIgZmlsbD0iIzU1NTg2NyIvPgo8L3N2Zz4K'); + background-image: url("data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMTAiIGhlaWdodD0iNiIgdmlld0JveD0iMCAwIDEwIDYiIGZpbGw9Im5vbmUiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyI+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNS4zMTMwNiA1LjgwODIyQzUuMTU2ODUgNS45NjQ0MyA0LjkwMzU4IDUuOTY0NDMgNC43NDczNyA1LjgwODIyTDAuMjgyNzMgMS4zNDM1OEMwLjEyNjUyIDEuMTg3MzcgMC4xMjY1MiAwLjkzNDEwMiAwLjI4MjczIDAuNzc3ODkzTDAuNzc3NzA0IDAuMjgyOTE4QzAuOTMzOTE0IDAuMTI2NzA4IDEuMTg3MTggMC4xMjY3MDggMS4zNDMzOSAwLjI4MjkxN0w1LjAzMDIyIDMuOTY5NzRMOC43MTcwNCAwLjI4MjkxN0M4Ljg3MzI1IDAuMTI2NzA4IDkuMTI2NTIgMC4xMjY3MDggOS4yODI3MyAwLjI4MjkxN0w5Ljc3NzcgMC43Nzc4OTJDOS45MzM5MSAwLjkzNDEwMiA5LjkzMzkxIDEuMTg3MzcgOS43Nzc3IDEuMzQzNThMNS4zMTMwNiA1LjgwODIyWiIgZmlsbD0iIzU1NTg2NyIvPgo8L3N2Zz4K"); background-repeat: no-repeat; background-position: top 11px right 10px; } diff --git a/GUI/src/components/DataTable/index.tsx b/GUI/src/components/DataTable/index.tsx index 11cfede5..171bf629 100644 --- a/GUI/src/components/DataTable/index.tsx +++ b/GUI/src/components/DataTable/index.tsx @@ -1,4 +1,4 @@ -import React, { CSSProperties, FC, ReactNode, useId, useState } from "react"; +import React, { CSSProperties, FC, ReactNode, useId } from "react"; import { ColumnDef, useReactTable, @@ -30,15 +30,19 @@ type DataTableProps = { data: any; columns: ColumnDef[]; tableBodyPrefix?: ReactNode; + isClientSide?: boolean; sortable?: boolean; filterable?: boolean; pagination?: PaginationState; - setPagination?: React.Dispatch>; + sorting?: SortingState; + setPagination?: (state: PaginationState) => void; + setSorting?: (state: SortingState) => void; globalFilter?: string; setGlobalFilter?: React.Dispatch>; columnVisibility?: VisibilityState; setColumnVisibility?: React.Dispatch>; disableHead?: boolean; + pagesCount?: number; meta?: TableMeta; }; @@ -80,18 +84,21 @@ const DataTable: FC = ({ tableBodyPrefix, sortable, filterable, + isClientSide = true, pagination, + sorting, setPagination, + setSorting, globalFilter, setGlobalFilter, columnVisibility, setColumnVisibility, disableHead, + pagesCount, meta, }) => { const id = useId(); const { t } = useTranslation(); - const [sorting, setSorting] = useState([]); const [columnFilters, setColumnFilters] = React.useState([]); const tablePagination = pagination ?? { pageIndex: 0, @@ -116,16 +123,25 @@ const DataTable: FC = ({ onGlobalFilterChange: setGlobalFilter, onColumnVisibilityChange: setColumnVisibility, globalFilterFn: fuzzyFilter, - onSortingChange: setSorting, - onPaginationChange: setPagination, + onSortingChange: (updater) => { + if (typeof updater !== "function") return; + setSorting?.(updater(table.getState().sorting)); + }, + onPaginationChange: (updater) => { + if (typeof updater !== "function") return; + setPagination?.(updater(table.getState().pagination)); + }, getCoreRowModel: getCoreRowModel(), getFilteredRowModel: getFilteredRowModel(), ...(pagination && { getPaginationRowModel: getPaginationRowModel() }), ...(sortable && { getSortedRowModel: getSortedRowModel() }), + manualPagination: isClientSide ? undefined : true, + manualSorting: isClientSide ? undefined : true, + pageCount: isClientSide ? undefined : pagesCount, }); return ( -
+
{!disableHead && ( @@ -146,9 +162,7 @@ const DataTable: FC = ({ )} {flexRender(header.column.columnDef.header, header.getContext())} - {filterable && header.column.getCanFilter() && ( - - )} + {filterable && header.column.getCanFilter() && } )} diff --git a/GUI/src/components/ServicesTable/index.tsx b/GUI/src/components/ServicesTable/index.tsx index a28e61b1..8fe2bc6f 100644 --- a/GUI/src/components/ServicesTable/index.tsx +++ b/GUI/src/components/ServicesTable/index.tsx @@ -1,4 +1,4 @@ -import { FC, useMemo, useState } from "react"; +import { FC, useEffect, useMemo, useState } from "react"; import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; import { Button, Card, Modal, Track } from ".."; @@ -11,6 +11,7 @@ import { Trigger } from "types/Trigger"; import { getColumns } from "./columns"; import "../../styles/main.scss"; import "./ServicesTable.scss"; +import { PaginationState, SortingState } from "@tanstack/react-table"; type ServicesTableProps = { isCommon?: boolean; @@ -25,9 +26,22 @@ const ServicesTable: FC = ({ isCommon = false }) => { const [popupText, setPopupText] = useState(""); const [readyPopupText, setReadyPopupText] = useState(""); const [isReadyStatusChecking, setIsReadyStatusChecking] = useState(false); - const services = useServiceListStore((state) => state.services.filter((x) => x.isCommon === isCommon)); + const services = useServiceListStore((state) => (isCommon ? state.commonServices : state.notCommonServices)); const navigate = useNavigate(); const [selectedConnectionTrigger, setSelectedConnectionTrigger] = useState(); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + const [sorting, setSorting] = useState([]); + + useEffect(() => { + if (!isCommon) { + useServiceListStore.getState().loadServicesList(pagination, sorting); + } else { + useServiceListStore.getState().loadCommonServicesList(pagination, sorting); + } + }, []); const checkIntentConnection = () => { useServiceListStore.getState().checkServiceIntentConnection( @@ -46,21 +60,25 @@ const ServicesTable: FC = ({ isCommon = false }) => { } ); }; - - const columns = useMemo(() => getColumns({ - isCommon, - navigate, - checkIntentConnection, - hideDeletePopup: () => setIsDeletePopupVisible(true), - showStatePopup: (text: string) => { - setPopupText(text); - setIsStatePopupVisible(true); - }, - showReadyPopup: () => { - setIsReadyStatusChecking(true); - setIsReadyPopupVisible(true); - } - }), []); + + const columns = useMemo( + () => + getColumns({ + isCommon, + navigate, + checkIntentConnection, + hideDeletePopup: () => setIsDeletePopupVisible(true), + showStatePopup: (text: string) => { + setPopupText(text); + setIsStatePopupVisible(true); + }, + showReadyPopup: () => { + setIsReadyStatusChecking(true); + setIsReadyPopupVisible(true); + }, + }), + [] + ); const changeServiceState = (activate: boolean = false, draft: boolean = false) => { useServiceListStore.getState().changeServiceState( @@ -71,7 +89,9 @@ const ServicesTable: FC = ({ isCommon = false }) => { t("overview.service.toast.updated"), t("overview.service.toast.failed.state"), activate, - draft + draft, + pagination, + sorting ); }; @@ -92,7 +112,9 @@ const ServicesTable: FC = ({ isCommon = false }) => { () => setIsIntentConnectionPopupVisible(false), t("overview.service.toast.connectedToIntentSuccessfully"), t("overview.service.toast.failed.failedToConnectToIntent"), - intent + intent, + pagination, + sorting ); }; @@ -110,19 +132,17 @@ const ServicesTable: FC = ({ isCommon = false }) => { }; const getChangeServiceStateButtonTitle = () => { - if(popupText === t("overview.popup.setInactive")) - return t("overview.popup.deactivate"); - if(popupText === t("overview.popup.setReady")) - return t("overview.popup.setState"); + if (popupText === t("overview.popup.setInactive")) return t("overview.popup.deactivate"); + if (popupText === t("overview.popup.setReady")) return t("overview.popup.setState"); return t("overview.popup.activate"); - } + }; const getActiveAndConnectionButton = () => { - if(readyPopupText === t("overview.popup.setActive")) { - return + if (readyPopupText === t("overview.popup.setActive")) { + return ; } - if(readyPopupText === t("overview.popup.connectionPending")) { - return + if (readyPopupText === t("overview.popup.connectionPending")) { + return ; } return ( - ) - } + ); + }; return ( @@ -159,9 +179,7 @@ const ServicesTable: FC = ({ isCommon = false }) => { {popupText === t("overview.popup.setInactive") && ( )} - + )} @@ -191,7 +209,32 @@ const ServicesTable: FC = ({ isCommon = false }) => { onConnect={(intent: Intent) => requestServiceIntentConnection(intent.intent)} /> )} - + { + if (state.pageIndex === pagination.pageIndex && state.pageSize === pagination.pageSize) return; + setPagination(state); + if (!isCommon) { + useServiceListStore.getState().loadServicesList(state, sorting); + } else { + useServiceListStore.getState().loadCommonServicesList(state, sorting); + } + }} + setSorting={(state: SortingState) => { + setSorting(state); + if (!isCommon) { + useServiceListStore.getState().loadServicesList(pagination, state); + } else { + useServiceListStore.getState().loadCommonServicesList(pagination, state); + } + }} + isClientSide={false} + pagesCount={services[services.length - 1]?.totalPages ?? 1} + /> ); }; diff --git a/GUI/src/pages/ConnectionRequestsPage.tsx b/GUI/src/pages/ConnectionRequestsPage.tsx index 920502be..57ffbce8 100644 --- a/GUI/src/pages/ConnectionRequestsPage.tsx +++ b/GUI/src/pages/ConnectionRequestsPage.tsx @@ -1,6 +1,6 @@ import React, { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; -import { createColumnHelper } from "@tanstack/react-table"; +import { PaginationState, SortingState, createColumnHelper } from "@tanstack/react-table"; import { format } from "date-fns"; import { AiFillCheckCircle, AiFillCloseCircle } from "react-icons/ai"; import { Card, DataTable, Icon } from "components"; @@ -11,22 +11,32 @@ import withAuthorization, { ROLES } from "hoc/with-authorization"; const ConnectionRequestsPage: React.FC = () => { const { t } = useTranslation(); const [triggers, setTriggers] = useState(undefined); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + const [sorting, setSorting] = useState([]); - const loadConnectionRequests = () => { + const loadConnectionRequests = (pagination: PaginationState, sorting: SortingState) => { useServiceStore .getState() - .loadRequestsList((requests: Trigger[]) => setTriggers(requests), t("connectionRequests.toast.failed.requests")); + .loadRequestsList( + (requests: Trigger[]) => setTriggers(requests), + t("connectionRequests.toast.failed.requests"), + pagination, + sorting + ); }; useEffect(() => { - loadConnectionRequests(); + loadConnectionRequests(pagination, sorting); }, []); const respondToConnectionRequest = (status: boolean, request: Trigger) => { useServiceStore .getState() .respondToConnectionRequest( - () => loadConnectionRequests(), + () => loadConnectionRequests(pagination, sorting), t("connectionRequests.approvedConnection"), t("connectionRequests.declinedConnection"), status, @@ -42,7 +52,24 @@ const ConnectionRequestsPage: React.FC = () => { <>

{t("connectionRequests.title")}

- + { + if (state.pageIndex === pagination.pageIndex && state.pageSize === pagination.pageSize) return; + setPagination(state); + loadConnectionRequests(state, sorting); + }} + setSorting={(state: SortingState) => { + setSorting(state); + loadConnectionRequests(pagination, state); + }} + isClientSide={false} + pagesCount={triggers[triggers.length - 1]?.totalPages ?? 1} + /> ); @@ -109,10 +136,7 @@ const getColumns = (respondToConnectionRequest: (result: boolean, tigger: Trigge size: "1%", }, }), - ] -} + ]; +}; -export default withAuthorization(ConnectionRequestsPage, [ - ROLES.ROLE_ADMINISTRATOR, - ROLES.ROLE_SERVICE_MANAGER, -]); +export default withAuthorization(ConnectionRequestsPage, [ROLES.ROLE_ADMINISTRATOR, ROLES.ROLE_SERVICE_MANAGER]); diff --git a/GUI/src/pages/FaultyServicesPage.tsx b/GUI/src/pages/FaultyServicesPage.tsx index f1ad1f37..93584356 100644 --- a/GUI/src/pages/FaultyServicesPage.tsx +++ b/GUI/src/pages/FaultyServicesPage.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import { Button, Card, DataTable, Icon, Track } from "../components"; -import { Row, createColumnHelper } from "@tanstack/react-table"; +import { PaginationState, Row, SortingState, createColumnHelper } from "@tanstack/react-table"; import { MdOutlineRemoveRedEye } from "react-icons/md"; import Popup from "../components/Popup"; import axios from "axios"; @@ -27,11 +27,46 @@ const FaultyServicesPage: React.FC = () => { const { t } = useTranslation(); const [viewFaultyServiceLog, setViewFaultyServiceLog] = useState(null); const [data, setData] = useState([]); - + const [pageCount, setPageCount] = useState(0); const columns = useMemo(() => getColumns(setViewFaultyServiceLog), []); + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 10, + }); + const [sorting, setSorting] = useState([]); + + const loadFaultyServices = (pagination: PaginationState, sorting: SortingState) => { + let sort = "dslName.keyword"; + let order = "desc"; + + if (sorting.length > 0) { + switch (sorting[0].id) { + case "serviceMethod": + sort = "dslMethod.keyword"; + break; + case "errorCode": + sort = "errorCode"; + break; + case "stepName": + sort = "stepName.keyword"; + break; + case "timestamp": + sort = "timestamp"; + break; + } + order = sorting[0].desc ? "desc" : "asc"; + } + axios + .get(getFaultyServices(pagination.pageIndex + 1, pagination.pageSize, sort, order)) + .then((res) => { + setData(res.data[0]); + setPageCount(Math.ceil(res.data[1] / pagination.pageSize)); + }) + .catch((err) => console.log(err)); + }; useEffect(() => { - axios.get(getFaultyServices()).then((res) => setData(res.data)); + loadFaultyServices(pagination, sorting); }, []); return ( @@ -124,6 +159,19 @@ const FaultyServicesPage: React.FC = () => { filterable data={data} columns={columns} + sorting={sorting} + pagination={pagination} + setPagination={(state: PaginationState) => { + if (state.pageIndex === pagination.pageIndex && state.pageSize === pagination.pageSize) return; + setPagination(state); + loadFaultyServices(state, sorting); + }} + setSorting={(state: SortingState) => { + setSorting(state); + loadFaultyServices(pagination, state); + }} + isClientSide={false} + pagesCount={pageCount} /> @@ -134,47 +182,44 @@ const FaultyServicesPage: React.FC = () => { const getColumns = (setViewFaultyServiceLog: (data: FaultyService) => void) => { const columnHelper = createColumnHelper(); - return [ - columnHelper.accessor("service", { - header: i18n.t("logs.service") ?? "", - cell: (props) => {props.getValue().split("/").pop()}, - }), - columnHelper.accessor("serviceMethod", { - header: i18n.t("logs.method") ?? "", - }), - columnHelper.accessor("errorCode", { - header: i18n.t("logs.errorCode") ?? "", - }), - columnHelper.accessor("stepName", { - header: i18n.t("logs.failedStep") ?? "", - }), - columnHelper.accessor("timestamp", { - header: i18n.t("logs.failedTime") ?? "", - cell: (props) => {format(new Date(parseInt(props.getValue() ?? "0")), "dd-MM-yyyy HH:mm:ss")}, - filterFn: (row: Row, _, filterValue) => { - return format(new Date(parseInt(row.original.timestamp ?? "0")), "dd-MM-yyyy HH:mm:ss") - .toLowerCase() - .includes(filterValue.toLowerCase()); - }, - }), - columnHelper.display({ - id: "view", - meta: { - size: 90, - }, - cell: (props) => ( - - - - ), - }), - ]; -} + return [ + columnHelper.accessor("service", { + header: i18n.t("logs.service") ?? "", + cell: (props) => {props.getValue().split("/").pop()}, + }), + columnHelper.accessor("serviceMethod", { + header: i18n.t("logs.method") ?? "", + }), + columnHelper.accessor("errorCode", { + header: i18n.t("logs.errorCode") ?? "", + }), + columnHelper.accessor("stepName", { + header: i18n.t("logs.failedStep") ?? "", + }), + columnHelper.accessor("timestamp", { + header: i18n.t("logs.failedTime") ?? "", + cell: (props) => {format(new Date(parseInt(props.getValue() ?? "0")), "dd-MM-yyyy HH:mm:ss")}, + filterFn: (row: Row, _, filterValue) => { + return format(new Date(parseInt(row.original.timestamp ?? "0")), "dd-MM-yyyy HH:mm:ss") + .toLowerCase() + .includes(filterValue.toLowerCase()); + }, + }), + columnHelper.display({ + id: "view", + meta: { + size: 90, + }, + cell: (props) => ( + + + + ), + }), + ]; +}; -export default withAuthorization(FaultyServicesPage, [ - ROLES.ROLE_ADMINISTRATOR, - ROLES.ROLE_SERVICE_MANAGER, -]); +export default withAuthorization(FaultyServicesPage, [ROLES.ROLE_ADMINISTRATOR, ROLES.ROLE_SERVICE_MANAGER]); diff --git a/GUI/src/pages/Integration/ConnectServiceToIntentModel.tsx b/GUI/src/pages/Integration/ConnectServiceToIntentModel.tsx index 09981634..8c54f7c9 100644 --- a/GUI/src/pages/Integration/ConnectServiceToIntentModel.tsx +++ b/GUI/src/pages/Integration/ConnectServiceToIntentModel.tsx @@ -1,5 +1,5 @@ import { FC, useEffect, useMemo, useState } from "react"; -import { createColumnHelper, PaginationState } from "@tanstack/react-table"; +import { createColumnHelper, PaginationState, SortingState } from "@tanstack/react-table"; import { useTranslation } from "react-i18next"; import { MdOutlineArrowForward } from "react-icons/md"; import useServiceStore from "store/services.store"; @@ -19,28 +19,32 @@ const ConnectServiceToIntentModel: FC = ({ onM pageIndex: 0, pageSize: 8, }); + const [sorting, setSorting] = useState([]); const [intents, setIntents] = useState(undefined); const [selectedIntent, setSelectedIntent] = useState(); const [showConfirmationModal, setShowConfirmationModal] = useState(false); - const loadAvailableIntents = () => { + const loadAvailableIntents = (pagination: PaginationState, sorting: SortingState) => { useServiceStore .getState() .loadAvailableIntentsList( (requests: Intent[]) => setIntents(requests), - t("overview.toast.failed.availableIntents") + t("overview.toast.failed.availableIntents"), + pagination, + sorting ); }; useEffect(() => { - loadAvailableIntents(); + loadAvailableIntents(pagination, sorting); }, []); const intentColumns = useMemo( - () => getColumns((intent) => { - setSelectedIntent(intent); - setShowConfirmationModal(true); - }), + () => + getColumns((intent) => { + setSelectedIntent(intent); + setShowConfirmationModal(true); + }), [] ); @@ -80,8 +84,19 @@ const ConnectServiceToIntentModel: FC = ({ onM globalFilter={filter} setGlobalFilter={setFilter} sortable + sorting={sorting} pagination={pagination} - setPagination={setPagination} + setPagination={(state: PaginationState) => { + if (state.pageIndex === pagination.pageIndex && state.pageSize === pagination.pageSize) return; + setPagination(state); + loadAvailableIntents(state, sorting); + }} + setSorting={(state: SortingState) => { + setSorting(state); + loadAvailableIntents(pagination, state); + }} + isClientSide={false} + pagesCount={intents[intents.length - 1]?.totalPages ?? 1} /> )} {showConfirmationModal && ( @@ -114,10 +129,7 @@ const getColumns = (onClick: (intent: Intent) => void) => { columnHelper.display({ id: "connect", cell: (props) => ( - @@ -126,7 +138,7 @@ const getColumns = (onClick: (intent: Intent) => void) => { size: "1%", }, }), - ] -} + ]; +}; export default ConnectServiceToIntentModel; diff --git a/GUI/src/pages/OverviewPage.tsx b/GUI/src/pages/OverviewPage.tsx index bdc34e80..cc0729e4 100644 --- a/GUI/src/pages/OverviewPage.tsx +++ b/GUI/src/pages/OverviewPage.tsx @@ -1,21 +1,16 @@ -import React, { useEffect } from "react"; +import React from "react"; import { useTranslation } from "react-i18next"; import { Button, Track } from "../components"; import { trainingModuleTraining } from "../resources/api-constants"; import ServicesTable from "../components/ServicesTable"; import { useNavigate } from "react-router-dom"; import { ROUTES } from "../resources/routes-constants"; -import useServiceListStore from "store/services.store"; import withAuthorization, { ROLES } from "hoc/with-authorization"; const OverviewPage: React.FC = () => { const { t } = useTranslation(); const navigate = useNavigate(); - useEffect(() => { - useServiceListStore.getState().loadServicesList(); - }, []); - return ( <> @@ -35,7 +30,4 @@ const OverviewPage: React.FC = () => { ); }; -export default withAuthorization(OverviewPage, [ - ROLES.ROLE_ADMINISTRATOR, - ROLES.ROLE_SERVICE_MANAGER, -]); +export default withAuthorization(OverviewPage, [ROLES.ROLE_ADMINISTRATOR, ROLES.ROLE_SERVICE_MANAGER]); diff --git a/GUI/src/resources/api-constants.ts b/GUI/src/resources/api-constants.ts index 949e78bc..7aa6398b 100644 --- a/GUI/src/resources/api-constants.ts +++ b/GUI/src/resources/api-constants.ts @@ -22,10 +22,12 @@ export const testService = (state: ServiceState, serviceName: string): string => `${baseUrl}/services/${state.toLowerCase()}/${serviceName}`; export const editService = (id: string): string => `${baseUrl}/services/edit?id=${id}`; export const getServicesList = (): string => `${baseUrl}/services`; +export const getCommonServicesList = (): string => `${baseUrl}/common-services`; export const getConnectionRequests = (): string => `${baseUrl}/services/connection-requests`; export const getAvailableIntents = (): string => `${baseUrl}/services/available-intents`; export const jsonToYml = (): string => `${baseUrl}/saveJsonToYml`; -export const getFaultyServices = (): string => `${baseUrl}/services/services-detailed/nok`; +export const getFaultyServices = (page: number, pageSize: number, sort: string, order: string): string => + `${baseUrl}/services/services-detailed/nok?page=${page}&page_size=${pageSize}&sort=${sort}&order=${order}`; export const trainingModuleTraining = (): string => `${trainingModuleBaseUrl}/treening/treeni-uus-mudel`; export const getServiceById = (id: string): string => `${baseUrl}/service-by-id?id=${id}`; export const updateServiceEndpoints = (id: string): string => `${baseUrl}/services/update-service-endpoints?id=${id}`; diff --git a/GUI/src/store/services.store.ts b/GUI/src/store/services.store.ts index 0fae2d63..548fed45 100644 --- a/GUI/src/store/services.store.ts +++ b/GUI/src/store/services.store.ts @@ -5,6 +5,7 @@ import { changeServiceStatus, deleteService as deleteServiceApi, getAvailableIntents, + getCommonServicesList, getConnectionRequests, getServicesList, requestServiceIntentConnection, @@ -14,12 +15,14 @@ import { Service, ServiceState } from "types"; import useToastStore from "./toasts.store"; import { Trigger } from "types/Trigger"; import { Intent } from "types/Intent"; +import { PaginationState, SortingState } from "@tanstack/react-table"; interface ServiceStoreState { services: Service[]; commonServices: Service[]; notCommonServices: Service[]; - loadServicesList: () => Promise; + loadServicesList: (pagination: PaginationState, sorting: SortingState) => Promise; + loadCommonServicesList: (pagination: PaginationState, sorting: SortingState) => Promise; deleteService: (id: string) => Promise; selectedService: Service | undefined; setSelectedService: (service: Service) => void; @@ -28,7 +31,9 @@ interface ServiceStoreState { successMessage: string, errorMessage: string, activate: boolean, - draft: boolean + draft: boolean, + pagination: PaginationState, + sorting: SortingState ) => Promise; checkServiceIntentConnection: (onConnected: (response: Trigger) => void, onNotConnected: () => void) => Promise; deleteSelectedService: (onEnd: () => void, successMessage: string, errorMessage: string) => Promise; @@ -36,10 +41,22 @@ interface ServiceStoreState { onEnd: () => void, successMessage: string, errorMessage: string, - intent: string + intent: string, + pagination: PaginationState, + sorting: SortingState + ) => Promise; + loadRequestsList: ( + onEnd: (requests: Trigger[]) => void, + errorMessage: string, + pagination: PaginationState, + sorting: SortingState + ) => Promise; + loadAvailableIntentsList: ( + onEnd: (requests: Intent[]) => void, + errorMessage: string, + pagination: PaginationState, + sorting: SortingState ) => Promise; - loadRequestsList: (onEnd: (requests: Trigger[]) => void, errorMessage: string) => Promise; - loadAvailableIntentsList: (onEnd: (requests: Intent[]) => void, errorMessage: string) => Promise; respondToConnectionRequest: ( onEnd: () => void, successMessage: string, @@ -59,8 +76,14 @@ const useServiceListStore = create((set, get, store) => ({ services: [], commonServices: [], notCommonServices: [], - loadServicesList: async () => { - const result = await axios.get(getServicesList()); + loadServicesList: async (pagination, sorting) => { + const order = sorting[0].desc ? "desc" : "asc"; + const sort = sorting.length === 0 ? "id asc" : sorting[0].id + " " + order; + const result = await axios.post(getServicesList(), { + page: pagination.pageIndex + 1, + page_size: pagination.pageSize, + sorting: sort, + }); const triggers = result.data.response[1]; const services = result.data.response[0].map?.( @@ -74,20 +97,48 @@ const useServiceListStore = create((set, get, store) => ({ isCommon: item.iscommon, serviceId: item.serviceId, usedCount: 0, + totalPages: item.totalPages, linkedIntent: triggers.find((e: Trigger) => e.service === item.serviceId)?.intent || "", } as Service) ) || []; set({ - services, - commonServices: services.filter((e: Service) => e.isCommon === true), - notCommonServices: services.filter((e: Service) => e.isCommon === false), + notCommonServices: services, + }); + }, + loadCommonServicesList: async (pagination, sorting) => { + const order = sorting[0].desc ? "desc" : "asc"; + const sort = sorting.length === 0 ? "id asc" : sorting[0].id + " " + order; + const result = await axios.post(getCommonServicesList(), { + page: pagination.pageIndex + 1, + page_size: pagination.pageSize, + sorting: sort, + }); + const triggers = result.data.response[1]; + const services = + result.data.response[0].map?.( + (item: any) => + ({ + id: item.id, + name: item.name, + description: item.description, + state: item.state, + type: item.type, + isCommon: item.iscommon, + serviceId: item.serviceId, + totalPages: item.totalPages, + usedCount: 0, + linkedIntent: triggers.find((e: Trigger) => e.service === item.serviceId)?.intent || "", + } as Service) + ) || []; + + set({ + commonServices: services, }); }, deleteService: async (id) => { const services = get().services.filter((e: Service) => e.serviceId !== id); set({ - services, commonServices: services.filter((e: Service) => e.isCommon === true), notCommonServices: services.filter((e: Service) => e.isCommon === false), }); @@ -98,9 +149,8 @@ const useServiceListStore = create((set, get, store) => ({ selectedService: service, }); }, - changeServiceState: async (onEnd, successMessage, errorMessage, activate, draft) => { + changeServiceState: async (onEnd, successMessage, errorMessage, activate, draft, pagination, sorting) => { const selectedService = get().selectedService; - console.log(selectedService); if (!selectedService) return; try { @@ -121,7 +171,8 @@ const useServiceListStore = create((set, get, store) => ({ type: selectedService.type, }); useToastStore.getState().success({ title: successMessage }); - await useServiceListStore.getState().loadServicesList(); + await useServiceListStore.getState().loadServicesList(pagination, sorting); + await useServiceListStore.getState().loadCommonServicesList(pagination, sorting); } catch (_) { useToastStore.getState().error({ title: errorMessage }); } @@ -166,7 +217,7 @@ const useServiceListStore = create((set, get, store) => ({ }); onEnd(); }, - requestServiceIntentConnection: async (onEnd, successMessage, errorMessage, intent) => { + requestServiceIntentConnection: async (onEnd, successMessage, errorMessage, intent, pagination, sorting) => { const selectedService = get().selectedService; if (!selectedService) return; @@ -177,24 +228,37 @@ const useServiceListStore = create((set, get, store) => ({ intent: intent, }); useToastStore.getState().success({ title: successMessage }); - await useServiceListStore.getState().loadServicesList(); + await useServiceListStore.getState().loadServicesList(pagination, sorting); + await useServiceListStore.getState().loadCommonServicesList(pagination, sorting); } catch (_) { useToastStore.getState().error({ title: errorMessage }); } onEnd(); }, - loadRequestsList: async (onEnd, errorMessage) => { + loadRequestsList: async (onEnd, errorMessage, pagination, sorting) => { try { - const requests = await axios.get(getConnectionRequests()); + const order = sorting[0].desc ? "desc" : "asc"; + const sort = sorting.length === 0 ? "requestedAt desc" : sorting[0].id + " " + order; + const requests = await axios.post(getConnectionRequests(), { + page: pagination.pageIndex + 1, + page_size: pagination.pageSize, + sorting: sort, + }); onEnd(requests.data.response); } catch (_) { onEnd([]); useToastStore.getState().error({ title: errorMessage }); } }, - loadAvailableIntentsList: async (onEnd, errorMessage) => { + loadAvailableIntentsList: async (onEnd, errorMessage, pagination, sorting) => { try { - const requests = await axios.get(getAvailableIntents()); + const order = sorting[0].desc ? "desc" : "asc"; + const sort = sorting.length === 0 ? "intent asc" : sorting[0].id + " " + order; + const requests = await axios.post(getAvailableIntents(), { + page: pagination.pageIndex + 1, + page_size: pagination.pageSize, + sorting: sort, + }); onEnd(requests.data.response); } catch (_) { onEnd([]); diff --git a/GUI/src/types/Intent.ts b/GUI/src/types/Intent.ts index db9fd7b4..dde5e2c6 100644 --- a/GUI/src/types/Intent.ts +++ b/GUI/src/types/Intent.ts @@ -1,4 +1,5 @@ export interface Intent { readonly id: number; intent: string; + readonly totalPages: number; } diff --git a/GUI/src/types/Trigger.ts b/GUI/src/types/Trigger.ts index 1865be94..d6b81173 100644 --- a/GUI/src/types/Trigger.ts +++ b/GUI/src/types/Trigger.ts @@ -6,4 +6,5 @@ export interface Trigger { authorRole: string; requestedAt: string; status: string; + readonly totalPages: number; } diff --git a/GUI/src/types/service.ts b/GUI/src/types/service.ts index 76e954ec..e5e8f72a 100644 --- a/GUI/src/types/service.ts +++ b/GUI/src/types/service.ts @@ -12,4 +12,5 @@ export interface Service { readonly endpoints: any; readonly serviceId: string; readonly linkedIntent: string; + readonly totalPages: number; }