Skip to content

Commit

Permalink
refactor(ui): status on get all model (#103)
Browse files Browse the repository at this point in the history
* refactor(ui): manage status on model list (WIP)

* refactor(ui): add polling on getModels api

* refactor(ui): invalidate cache of getAllModel when user import new current or new reference file
  • Loading branch information
dvalleri authored Jul 15, 2024
1 parent 1ff9332 commit 1522c89
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 42 deletions.
11 changes: 1 addition & 10 deletions ui/src/components/JobStatus/job-status-pin.jsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,7 @@
import { JOB_STATUS } from '@Src/constants';
import { useGetCurrentDataQualityQueryWithPolling, useGetReferenceDataQualityQueryWithPolling } from '@Src/store/state/models/polling-hook';
import { Pin, Spinner } from '@radicalbit/radicalbit-design-system';

function JobStatusPin({ modelUUID }) {
const { data: referenceData } = useGetReferenceDataQualityQueryWithPolling(modelUUID);
const referenceJobStatus = referenceData?.jobStatus;

const { data: currentData } = useGetCurrentDataQualityQueryWithPolling(modelUUID);
const currentJobStatus = currentData?.jobStatus;

const jobStatus = (referenceJobStatus === JOB_STATUS.SUCCEEDED) ? currentJobStatus : referenceJobStatus;

function JobStatusPin({ jobStatus }) {
switch (jobStatus) {
case JOB_STATUS.IMPORTING: {
return (
Expand Down
34 changes: 15 additions & 19 deletions ui/src/container/models/Details/secondary-column/content.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { modelsApiSlice } from '@Src/store/state/models/api';
import JobStatusPin from '@Components/JobStatus/job-status-pin';
import { MODEL_TABS_ENUM } from '@Container/models/Details/constants';
import { JOB_STATUS } from '@Src/constants';
import { useGetModelQueryWithPolling } from '@Src/store/state/models/polling-hook';
import { selectors as layoutSelectors } from '@State/layout';
import { Menu, Truncate } from '@radicalbit/radicalbit-design-system';
import { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import {
useNavigate, useParams, useSearchParams,
} from 'react-router-dom';
import { selectors as layoutSelectors } from '@State/layout';
import { useSelector } from 'react-redux';
import JobStatusPin from '@Components/JobStatus/job-status-pin';
import { selectors as contextConfigurationSelectors } from '@State/context-configuration';
import { NamespaceEnum } from '@Src/constants';
import { MODEL_TABS_ENUM } from '@Container/models/Details/constants';

const { useGetModelsQuery } = modelsApiSlice;

const { selectQueryParamsSelector } = contextConfigurationSelectors;

const commonChildrenMenu = [
{ label: 'Overview', key: MODEL_TABS_ENUM.OVERVIEW },
Expand All @@ -30,23 +25,24 @@ export default function SecondaryColumnModelsContent() {

const isSecondaryColumnCollapsed = useSelector(selectHasSecondaryColumnCollapsed);

const queryParams = useSelector((state) => selectQueryParamsSelector(state, NamespaceEnum.MODELS));

const { data } = useGetModelsQuery({ queryParams });
const { data } = useGetModelQueryWithPolling();
const modelList = data?.items ?? [];
const modelListMenuItem = modelList.map(({ uuid: modelUUID, name }) => (
{
const modelListMenuItem = modelList.map(({
uuid: modelUUID, name, latestReferenceJobStatus, latestCurrentJobStatus,
}) => {
const jobStatus = latestReferenceJobStatus === JOB_STATUS.SUCCEEDED ? latestCurrentJobStatus : latestReferenceJobStatus;
return {
label: (
<div className="flex gap-2 items-center">
<Truncate className="w-10/12">{name}</Truncate>

<JobStatusPin modelUUID={modelUUID} />
<JobStatusPin jobStatus={jobStatus} />
</div>),
key: modelUUID,
children: commonChildrenMenu,
className: uuid === modelUUID ? Menu.HIDE_EXPAND_ICON : '',
}
));
};
});

const [openKeys, setOpenKeys] = useState([uuid]);
const rootSubmenuKeys = modelListMenuItem.map(({ key }) => (key));
Expand Down
17 changes: 15 additions & 2 deletions ui/src/container/models/List/columns.jsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,32 @@
import JobStatusPin from '@Components/JobStatus/job-status-pin';
import { columnFactory } from '@Src/components/smart-table/utils';
import { JOB_STATUS } from '@Src/constants';
import { DataTypeEnumLabel, ModelTypeEnumLabel } from '@Src/store/state/models/constants';
import { RelativeDateTime } from '@radicalbit/radicalbit-design-system';

export const getColumns = (
activeFilters,
activeSorter,
) => [
columnFactory({
title: 'S',
key: 'name',
width: '3rem',
align: 'center',
render: ({ latestCurrentJobStatus, latestReferenceJobStatus }) => {
const jobStatus = latestReferenceJobStatus === JOB_STATUS.SUCCEEDED ? latestCurrentJobStatus : latestReferenceJobStatus;
return (
<JobStatusPin jobStatus={jobStatus} />
);
},
}),
columnFactory({
title: 'Name',
dataIndex: 'name',
key: 'name',
activeFilters,
activeSorter,
width: 250,
render: (name) => (<div className="font-[var(--coo-font-weight-bold)]">{name}</div>),
render: ({ name }) => (<div className="font-[var(--coo-font-weight-bold)]">{name}</div>),
}),

columnFactory({
Expand Down
14 changes: 3 additions & 11 deletions ui/src/container/models/List/index.jsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
import SomethingWentWrong from '@Components/ErrorPage/something-went-wrong';
import SmartTable from '@Components/smart-table';
import LogoSquared from '@Img/logo-collapsed.svg';
import { ModalsEnum, NamespaceEnum } from '@Src/constants';
import useModals from '@Src/hooks/use-modals';
import { modelsApiSlice } from '@Src/store/state/models/api';
import { useGetModelQueryWithPolling } from '@Src/store/state/models/polling-hook';
import { Button, Spinner, Void } from '@radicalbit/radicalbit-design-system';
import { useLocation, useNavigate } from 'react-router-dom';
import SomethingWentWrong from '@Components/ErrorPage/something-went-wrong';
import { useSelector } from 'react-redux';
import { selectors as contextConfigurationSelectors } from '@State/context-configuration';
import { getColumns } from './columns';

const { useGetModelsQuery } = modelsApiSlice;

const { selectQueryParamsSelector } = contextConfigurationSelectors;

export function ModelsList() {
const navigate = useNavigate();
const { search } = useLocation();

const queryParams = useSelector((state) => selectQueryParamsSelector(state, NamespaceEnum.MODELS));

const { data, isLoading, isError } = useGetModelsQuery({ queryParams });
const { data, isLoading, isError } = useGetModelQueryWithPolling();

const models = data?.items || [];
const count = data?.total || 0;
Expand Down
3 changes: 3 additions & 0 deletions ui/src/store/state/models/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ export const modelsApiSlice = apiService.injectEndpoints({
if (result) {
return [
{ type: API_TAGS.REFERENCE_IMPORT, id: modelUUID },
{ type: API_TAGS.MODEL, id: modelUUID },
{ type: API_TAGS.MODELS },
];
}
return [];
Expand Down Expand Up @@ -178,6 +180,7 @@ export const modelsApiSlice = apiService.injectEndpoints({
return [
{ type: API_TAGS.CURRENT_IMPORT, id: modelUUID },
{ type: API_TAGS.MODEL, id: modelUUID },
{ type: API_TAGS.MODELS },
];
}
return [];
Expand Down
17 changes: 17 additions & 0 deletions ui/src/store/state/models/polling-hook.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useParams } from 'react-router';
import useModals from '@Hooks/use-modals';
import { modelsApiSlice } from './api';

const { selectQueryParamsSelector } = contextConfigurationSelectors;

const {
useGetReferenceImportsQuery,
useGetReferenceDataQualityQuery,
Expand All @@ -16,6 +18,7 @@ const {
useGetCurrentStatisticsByUUIDQuery,
useGetCurrentDriftQuery,
useGetModelByUUIDQuery,
useGetModelsQuery,
} = modelsApiSlice;

const useGetReferenceImportsQueryWithPolling = () => {
Expand Down Expand Up @@ -153,6 +156,19 @@ const useGetCurrentDriftQueryWithPolling = () => {
return result;
};

const useGetModelQueryWithPolling = () => {
const queryParams = useSelector((state) => selectQueryParamsSelector(state, NamespaceEnum.MODELS));
const result = useGetModelsQuery({ queryParams });

const isReferencePending = result.data?.items.every((d) => d.latestReferenceJobStatus === JOB_STATUS.SUCCEEDED);
const isCurrentPending = result.data?.items.every((d) => d.latestCurrentJobStatus === JOB_STATUS.SUCCEEDED);
const isOperationCompleted = isReferencePending && isCurrentPending;

useGetModelsQuery({ queryParams }, { pollingInterval: DEFAULT_POLLING_INTERVAL, skip: isOperationCompleted });

return result;
};

export {
useGetCurrentDataQualityQueryWithPolling,
useGetCurrentDriftQueryWithPolling,
Expand All @@ -163,4 +179,5 @@ export {
useGetReferenceImportsQueryWithPolling,
useGetReferenceModelQualityQueryWithPolling,
useGetReferenceStatisticsQueryWithPolling,
useGetModelQueryWithPolling,
};

0 comments on commit 1522c89

Please sign in to comment.