diff --git a/src/components/datasets/Dataset.js b/src/components/datasets/Dataset.js
index 75fe1ebc9..227f71a47 100644
--- a/src/components/datasets/Dataset.js
+++ b/src/components/datasets/Dataset.js
@@ -13,8 +13,8 @@ import {
} from "../../modules/metadata/actions";
import {
- fetchDatasetDataTypesSummaryIfPossible,
- fetchDatasetSummaryIfPossible,
+ fetchDatasetDataTypesSummariesIfPossible,
+ fetchDatasetSummariesIfPossible,
} from "../../modules/datasets/actions";
import {INITIAL_DATA_USE_VALUE} from "../../duo";
@@ -315,8 +315,8 @@ const mapDispatchToProps = (dispatch, ownProps) => ({
deleteProjectDataset: dataset => dispatch(deleteProjectDatasetIfPossible(ownProps.project, dataset)),
deleteLinkedFieldSet: (dataset, linkedFieldSet, linkedFieldSetIndex) =>
dispatch(deleteDatasetLinkedFieldSetIfPossible(dataset, linkedFieldSet, linkedFieldSetIndex)),
- fetchDatasetSummary: (datasetId) => dispatch(fetchDatasetSummaryIfPossible(datasetId)),
- fetchDatasetDataTypesSummary: (datasetId) => dispatch(fetchDatasetDataTypesSummaryIfPossible(datasetId)),
+ fetchDatasetSummary: (datasetId) => dispatch(fetchDatasetSummariesIfPossible(datasetId)),
+ fetchDatasetDataTypesSummary: (datasetId) => dispatch(fetchDatasetDataTypesSummariesIfPossible(datasetId)),
});
export default connect(mapStateToProps, mapDispatchToProps)(Dataset);
diff --git a/src/components/datasets/DatasetDataTypes.js b/src/components/datasets/DatasetDataTypes.js
index 4aecd931a..450604574 100644
--- a/src/components/datasets/DatasetDataTypes.js
+++ b/src/components/datasets/DatasetDataTypes.js
@@ -5,7 +5,7 @@ import { Button, Col, Row, Table, Typography } from "antd";
import PropTypes from "prop-types";
import { datasetPropTypesShape, projectPropTypesShape } from "../../propTypes";
import { clearDatasetDataType } from "../../modules/metadata/actions";
-import { fetchDatasetDataTypesSummaryIfPossible } from "../../modules/datasets/actions";
+import { fetchDatasetDataTypesSummariesIfPossible } from "../../modules/datasets/actions";
import genericConfirm from "../ConfirmationModal";
import DataTypeSummaryModal from "./datatype/DataTypeSummaryModal";
import { nop } from "../../utils/misc";
@@ -16,7 +16,7 @@ const DatasetDataTypes = React.memo(
({isPrivate, project, dataset, onDatasetIngest}) => {
const dispatch = useDispatch();
const datasetDataTypes = useSelector((state) => Object.values(
- state.datasetDataTypes.itemsById[dataset.identifier]?.itemsById));
+ state.datasetDataTypes.itemsById[dataset.identifier]?.itemsById ?? {}));
const datasetSummaries = useSelector((state) => state.datasetSummaries.itemsById[dataset.identifier]);
const isFetchingDataset = useSelector(
(state) => state.datasetDataTypes.itemsById[dataset.identifier]?.isFetching);
@@ -35,7 +35,7 @@ const DatasetDataTypes = React.memo(
"will be deleted permanently, and will no longer be available for exploration.",
onOk: async () => {
await dispatch(clearDatasetDataType(dataset.identifier, dataType.id));
- await dispatch(fetchDatasetDataTypesSummaryIfPossible(dataset.identifier));
+ await dispatch(fetchDatasetDataTypesSummariesIfPossible(dataset.identifier));
},
});
}, [dispatch, dataset]);
diff --git a/src/components/discovery/DiscoveryQueryBuilder.js b/src/components/discovery/DiscoveryQueryBuilder.js
index 38b7067b6..a0fb07c8b 100644
--- a/src/components/discovery/DiscoveryQueryBuilder.js
+++ b/src/components/discovery/DiscoveryQueryBuilder.js
@@ -254,14 +254,15 @@ DiscoveryQueryBuilder.propTypes = {
const mapStateToProps = state => ({
servicesInfo: state.services.items,
- dataTypes: state.serviceDataTypes.dataTypesByServiceID,
dataTypesByID: state.serviceDataTypes.itemsByID,
dataTypesByDataset: state.datasetDataTypes,
autoQuery: state.explorer.autoQuery,
isFetchingTextSearch: state.explorer.fetchingTextSearch || false,
- dataTypesLoading: state.services.isFetching || state.datasetDataTypes.isFetchingAll,
+ dataTypesLoading: state.services.isFetching
+ || state.serviceDataTypes.isFetching
+ || state.datasetDataTypes.isFetchingAll,
});
const mapDispatchToProps = (dispatch) => ({
diff --git a/src/components/manager/DataTypeSelect.js b/src/components/manager/DataTypeSelect.js
index 3962e34f1..531e3c06f 100644
--- a/src/components/manager/DataTypeSelect.js
+++ b/src/components/manager/DataTypeSelect.js
@@ -6,17 +6,15 @@ import { useSelector } from "react-redux";
const DataTypeSelect = ({value, workflows, onChange}) => {
const [selected, setSelected] = useState(value ?? undefined);
const servicesFetching = useSelector((state) => state.services.isFetchingAll);
- const workflowsFetching = useSelector((state) => state.serviceWorkflows.isFetchingAll);
+ const workflowsFetching = useSelector((state) => state.serviceWorkflows.isFetching);
const {
- itemsByID: dataTypes,
- isFetchingAll: isFetchingDataTypes,
+ items: dataTypes,
+ isFetching: isFetchingDataTypes,
} = useSelector((state) => state.serviceDataTypes);
const labels = useMemo(() => {
if (!dataTypes) return {};
- return Object.fromEntries(
- Object.values(dataTypes).map(dt => [dt.id, dt.label]),
- );
+ return Object.fromEntries(dataTypes.map(dt => [dt.id, dt.label]));
}, dataTypes);
useEffect(() => {
@@ -34,8 +32,8 @@ const DataTypeSelect = ({value, workflows, onChange}) => {
if (!Array.isArray(workflows)) {
return [];
}
- const dataTypes = new Set(workflows.map((w) => w.data_type));
- return Array.from(dataTypes)
+ const workflowDataTypes = new Set(workflows.map((w) => w.data_type));
+ return Array.from(workflowDataTypes)
// filter out workflow types for which we have no labels (mcode)
.filter(dt => dt in labels)
.map((dt) =>
@@ -43,7 +41,7 @@ const DataTypeSelect = ({value, workflows, onChange}) => {
{labels[dt]} ({{dt}})
,
);
- }, [workflows, dataTypes, labels]);
+ }, [workflows, labels]);
return (
diff --git a/src/components/manager/projects/RoutedProject.js b/src/components/manager/projects/RoutedProject.js
index 22a2536ab..73c686ca7 100644
--- a/src/components/manager/projects/RoutedProject.js
+++ b/src/components/manager/projects/RoutedProject.js
@@ -150,12 +150,6 @@ RoutedProject.propTypes = {
services: PropTypes.arrayOf(serviceInfoPropTypesShape),
servicesByID: PropTypes.objectOf(serviceInfoPropTypesShape),
- serviceDataTypesByServiceID: PropTypes.objectOf(PropTypes.shape({
- items: PropTypes.array, // TODO: Shape
- itemsByID: PropTypes.object, // TODO: Shape
- isFetching: PropTypes.bool,
- })),
-
projects: PropTypes.arrayOf(projectPropTypesShape),
projectsByID: PropTypes.objectOf(projectPropTypesShape),
@@ -178,8 +172,6 @@ const mapStateToProps = state => ({
services: state.services.items,
servicesByID: state.services.itemsByID,
- serviceDataTypesByServiceID: state.serviceDataTypes.dataTypesByServiceID,
-
projects: state.projects.items,
projectsByID: state.projects.itemsByID,
diff --git a/src/modules/datasets/actions.js b/src/modules/datasets/actions.js
index 265922b6c..b6dcfdb77 100644
--- a/src/modules/datasets/actions.js
+++ b/src/modules/datasets/actions.js
@@ -1,28 +1,30 @@
import {beginFlow, createFlowActionTypes, createNetworkActionTypes, endFlow, networkAction} from "../../utils/actions";
+import {getDataServices} from "../services/utils";
-export const FETCHING_DATASETS_DATATYPE = createFlowActionTypes("FETCHING_DATASETS_DATATYPE");
-export const FETCH_DATASET_DATATYPE = createNetworkActionTypes("FETCH_DATASET_DATATYPE");
+export const FETCHING_DATASETS_DATA_TYPES = createFlowActionTypes("FETCHING_DATASETS_DATA_TYPES");
+export const FETCH_DATASET_DATA_TYPES_SUMMARY = createNetworkActionTypes("FETCH_DATASET_DATA_TYPES_SUMMARY");
export const FETCH_DATASET_SUMMARY = createNetworkActionTypes("FETCH_DATASET_SUMMARY");
-const fetchDatasetDataTypeSummary = networkAction((serviceInfo, datasetID) => ({
- types: FETCH_DATASET_DATATYPE,
+const fetchDatasetDataTypesSummary = networkAction((serviceInfo, datasetID) => ({
+ types: FETCH_DATASET_DATA_TYPES_SUMMARY,
params: {serviceInfo, datasetID},
url: `${serviceInfo.url}/datasets/${datasetID}/data-types`,
}));
-export const fetchDatasetDataTypesSummaryIfPossible = (datasetID) => async (dispatch, getState) => {
- if (getState().datasetDataTypes.isFetching) return;
- await dispatch(fetchDatasetDataTypeSummary(getState().services.itemsByArtifact.metadata, datasetID));
- await dispatch(fetchDatasetDataTypeSummary(getState().services.itemsByArtifact.gohan, datasetID));
+export const fetchDatasetDataTypesSummariesIfPossible = (datasetID) => async (dispatch, getState) => {
+ if (getState().datasetDataTypes.isFetchingAll) return;
+ await Promise.all(
+ getDataServices(getState()).map(serviceInfo => dispatch(fetchDatasetDataTypesSummary(serviceInfo, datasetID))),
+ );
};
export const fetchDatasetsDataTypes = () => async (dispatch, getState) => {
- dispatch(beginFlow(FETCHING_DATASETS_DATATYPE));
+ dispatch(beginFlow(FETCHING_DATASETS_DATA_TYPES));
await Promise.all(
Object.keys(getState().projects.datasetsByID).map(datasetID =>
- dispatch(fetchDatasetDataTypesSummaryIfPossible(datasetID))),
+ dispatch(fetchDatasetDataTypesSummariesIfPossible(datasetID))),
);
- dispatch(endFlow(FETCHING_DATASETS_DATATYPE));
+ dispatch(endFlow(FETCHING_DATASETS_DATA_TYPES));
};
const fetchDatasetSummary = networkAction((serviceInfo, datasetID) => ({
@@ -31,8 +33,9 @@ const fetchDatasetSummary = networkAction((serviceInfo, datasetID) => ({
url: `${serviceInfo.url}/datasets/${datasetID}/summary`,
}));
-export const fetchDatasetSummaryIfPossible = (datasetID) => async (dispatch, getState) => {
+export const fetchDatasetSummariesIfPossible = (datasetID) => async (dispatch, getState) => {
if (getState().datasetSummaries.isFetching) return;
- await dispatch(fetchDatasetSummary(getState().services.itemsByArtifact.metadata, datasetID));
- await dispatch(fetchDatasetSummary(getState().services.itemsByArtifact.gohan, datasetID));
+ await Promise.all(
+ getDataServices(getState()).map(serviceInfo => fetchDatasetSummary(serviceInfo, datasetID)),
+ );
};
diff --git a/src/modules/datasets/reducers.js b/src/modules/datasets/reducers.js
index 614dd82cf..e2af914ed 100644
--- a/src/modules/datasets/reducers.js
+++ b/src/modules/datasets/reducers.js
@@ -1,4 +1,4 @@
-import {FETCHING_DATASETS_DATATYPE, FETCH_DATASET_DATATYPE, FETCH_DATASET_SUMMARY} from "./actions";
+import {FETCHING_DATASETS_DATA_TYPES, FETCH_DATASET_DATA_TYPES_SUMMARY, FETCH_DATASET_SUMMARY} from "./actions";
export const datasetDataTypes = (
state = {
@@ -8,24 +8,24 @@ export const datasetDataTypes = (
action,
) => {
switch (action.type) {
- case FETCHING_DATASETS_DATATYPE.BEGIN:
+ case FETCHING_DATASETS_DATA_TYPES.BEGIN:
return {...state, isFetchingAll: true};
- case FETCHING_DATASETS_DATATYPE.END:
+ case FETCHING_DATASETS_DATA_TYPES.END:
return {...state, isFetchingAll: false};
- case FETCH_DATASET_DATATYPE.REQUEST:{
+ case FETCH_DATASET_DATA_TYPES_SUMMARY.REQUEST:{
const {datasetID} = action;
return {
...state,
itemsById: {
...state.itemsById,
[datasetID]: {
- itemsById: {...(state.itemsById[datasetID]?.itemsById ?? {})},
+ itemsById: state.itemsById[datasetID]?.itemsById ?? {},
isFetching: true,
},
},
};
}
- case FETCH_DATASET_DATATYPE.RECEIVE:{
+ case FETCH_DATASET_DATA_TYPES_SUMMARY.RECEIVE:{
const {datasetID} = action;
const itemsByID = Object.fromEntries(action.data.map(d => [d.id, d]));
return {
@@ -41,8 +41,8 @@ export const datasetDataTypes = (
},
};
}
- case FETCH_DATASET_DATATYPE.FINISH:
- case FETCH_DATASET_DATATYPE.ERROR:{
+ case FETCH_DATASET_DATA_TYPES_SUMMARY.FINISH:
+ case FETCH_DATASET_DATA_TYPES_SUMMARY.ERROR:{
const {datasetID} = action;
return {
...state,
diff --git a/src/modules/metadata/actions.js b/src/modules/metadata/actions.js
index 76f545fb0..9e692b9a3 100644
--- a/src/modules/metadata/actions.js
+++ b/src/modules/metadata/actions.js
@@ -28,18 +28,18 @@ export const FETCH_OVERVIEW_SUMMARY = createNetworkActionTypes("FETCH_OVERVIEW_S
export const DELETE_DATASET_DATA_TYPE = createNetworkActionTypes("DELETE_DATASET_DATA_TYPE");
-export const clearDatasetDataType = networkAction((datasetId, dataType) => (dispatch, getState) => {
- // TODO: more robust mapping from dataType to url.
- const serviceUrl = dataType === "variant"
- ? getState().services.itemsByKind.gohan.url
- : getState().services.itemsByKind.metadata.url;
- console.log(serviceUrl);
+export const clearDatasetDataType = networkAction((datasetId, dataTypeID) => (dispatch, getState) => {
+ const {service_base_url: serviceBaseUrl} = getState().serviceDataTypes.itemsByID[dataTypeID];
return {
types: DELETE_DATASET_DATA_TYPE,
- url: `${serviceUrl}/datasets/${datasetId}/data-types/${dataType}`,
+ url: `${serviceBaseUrl}datasets/${datasetId}/data-types/${dataTypeID}`,
req: {
method: "DELETE",
},
+ onError: (error) => {
+ // Needs to re throw for project/dataset deletion error handling
+ throw error;
+ },
};
});
@@ -125,11 +125,25 @@ export const deleteProject = networkAction(project => (dispatch, getState) => ({
onSuccess: () => message.success(`Project '${project.title}' deleted!`),
}));
-export const deleteProjectIfPossible = project => (dispatch, getState) => {
+export const deleteProjectIfPossible = project => async (dispatch, getState) => {
if (getState().projects.isDeleting) return;
- return dispatch(deleteProject(project));
+
+ // Remove data without destroying project/datasets first
+ try {
+ await Promise.all(project.datasets.map(ds => dispatch(clearDatasetDataTypes(ds.identifier))));
+ await dispatch(deleteProject(project));
+ } catch (err) {
+ console.error(err);
+ message.error(`Error deleting project '${project.title}'`);
+ }
};
+export const clearDatasetDataTypes = datasetId => async (dispatch, getState) => {
+ // only clear data types which can yield counts - `queryable` is a proxy for this
+ const dataTypes = Object.values(getState().datasetDataTypes.itemsById[datasetId].itemsById)
+ .filter(dt => dt.queryable);
+ return await Promise.all(dataTypes.map(dt => dispatch(clearDatasetDataType(datasetId, dt.id))));
+};
const saveProject = networkAction(project => (dispatch, getState) => ({
types: SAVE_PROJECT,
@@ -181,11 +195,17 @@ export const deleteProjectDataset = networkAction((project, dataset) => (dispatc
err: `Error deleting dataset '${dataset.title}'`,
}));
-export const deleteProjectDatasetIfPossible = (project, dataset) => (dispatch, getState) => {
+export const deleteProjectDatasetIfPossible = (project, dataset) => async (dispatch, getState) => {
if (getState().projects.isAddingDataset
|| getState().projects.isSavingDataset
|| getState().projects.isDeletingDataset) return;
- return dispatch(deleteProjectDataset(project, dataset));
+ try {
+ await dispatch(clearDatasetDataTypes(dataset.identifier));
+ await dispatch(deleteProjectDataset(project, dataset));
+ } catch (err) {
+ console.error(err);
+ message.error(`Error deleting dataset '${dataset.title}'`);
+ }
};
diff --git a/src/modules/metadata/reducers.js b/src/modules/metadata/reducers.js
index 26e2653fb..0614fcdf7 100644
--- a/src/modules/metadata/reducers.js
+++ b/src/modules/metadata/reducers.js
@@ -146,6 +146,9 @@ export const projects = (
};
}
+ case ADD_PROJECT_DATASET.FINISH:
+ return {...state, isAddingDataset: false};
+
// DELETE_PROJECT_DATASET
case DELETE_PROJECT_DATASET.REQUEST:
diff --git a/src/modules/services/actions.js b/src/modules/services/actions.js
index 556a0e336..c7f265aeb 100644
--- a/src/modules/services/actions.js
+++ b/src/modules/services/actions.js
@@ -21,12 +21,8 @@ export const LOADING_ALL_SERVICE_DATA = createFlowActionTypes("LOADING_ALL_SERVI
export const FETCH_BENTO_SERVICES = createNetworkActionTypes("FETCH_BENTO_SERVICES");
export const FETCH_SERVICES = createNetworkActionTypes("FETCH_SERVICES");
-
-export const FETCH_SERVICE_DATA_TYPES = createNetworkActionTypes("FETCH_SERVICE_DATA_TYPES");
-export const LOADING_SERVICE_DATA_TYPES = createFlowActionTypes("LOADING_SERVICE_DATA_TYPES");
-
-export const FETCH_SERVICE_WORKFLOWS = createNetworkActionTypes("FETCH_SERVICE_WORKFLOWS");
-export const LOADING_SERVICE_WORKFLOWS = createFlowActionTypes("LOADING_SERVICE_WORKFLOWS");
+export const FETCH_DATA_TYPES = createNetworkActionTypes("FETCH_DATA_TYPES");
+export const FETCH_WORKFLOWS = createNetworkActionTypes("FETCH_WORKFLOWS");
export const fetchBentoServices = networkAction(() => ({
@@ -41,17 +37,16 @@ export const fetchServices = networkAction(() => ({
err: "Error fetching services",
}));
-export const fetchDataServiceDataTypes = networkAction((serviceInfo) => ({
- types: FETCH_SERVICE_DATA_TYPES,
- params: {serviceInfo},
- url: `${serviceInfo.url}/data-types`,
- err: `Error fetching data types from service '${serviceInfo.name}'`,
+export const fetchDataTypes = networkAction(() => ({
+ types: FETCH_DATA_TYPES,
+ url: `${BENTO_PUBLIC_URL}/api/service-registry/data-types`,
+ err: "Error fetching data types",
}));
-export const fetchDataServiceWorkflows = networkAction((serviceInfo) => ({
- types: FETCH_SERVICE_WORKFLOWS,
- params: {serviceInfo},
- url: `${serviceInfo.url}/workflows`,
+export const fetchWorkflows = networkAction(() => ({
+ types: FETCH_WORKFLOWS,
+ url: `${BENTO_PUBLIC_URL}/api/service-registry/workflows`,
+ err: "Error fetching workflows",
}));
@@ -59,46 +54,27 @@ export const fetchServicesWithMetadataAndDataTypes = (onServiceFetchFinish) => a
dispatch(beginFlow(LOADING_ALL_SERVICE_DATA));
// Fetch Services
- await Promise.all([dispatch(fetchBentoServices()), dispatch(fetchServices())]);
- if (!getState().services.items) {
- // Something went wrong, terminate early
- dispatch(terminateFlow(LOADING_ALL_SERVICE_DATA));
- return;
- }
-
- // Fetch other data (need metadata first):
-
- // - Skip services that don't provide data (i.e. no data types/workflows/etc.)
-
- const dataServicesInfo = getState().services.items.filter(s => s?.type).map(s => {
- // Backwards compatibility for:
- // - old type ("group:artifact:version")
- // - and new ({"group": "...", "artifact": "...", "version": "..."})
- const serviceKind = s.bento?.serviceKind ?? s.type.artifact;
- return {
- ...s,
- bentoService: getState().bentoServices.itemsByKind[serviceKind] ?? null,
- };
- }).filter(s => s.bento?.dataService ?? false);
-
- // - Custom stuff to start - explicitly don't wait for this promise to finish since it runs parallel to this flow.
- if (onServiceFetchFinish) onServiceFetchFinish();
-
- // - Fetch Data Service Data Types and Workflows
await Promise.all([
(async () => {
- dispatch(beginFlow(LOADING_SERVICE_DATA_TYPES));
- await Promise.all(dataServicesInfo.map(s => dispatch(fetchDataServiceDataTypes(s))));
- dispatch(endFlow(LOADING_SERVICE_DATA_TYPES));
+ await Promise.all([
+ dispatch(fetchBentoServices()),
+ dispatch(fetchServices()),
+ ]);
+ // - Custom stuff to start
+ // - explicitly don't wait for this promise to finish since it runs parallel to this flow.
+ if (onServiceFetchFinish) onServiceFetchFinish();
})(),
- (async () => {
- dispatch(beginFlow(LOADING_SERVICE_WORKFLOWS));
- await Promise.all(dataServicesInfo.map(s => dispatch(fetchDataServiceWorkflows(s))));
- dispatch(endFlow(LOADING_SERVICE_WORKFLOWS));
- })(),
+ dispatch(fetchDataTypes()),
+ dispatch(fetchWorkflows()),
]);
+ if (!getState().services.items) {
+ // Something went wrong, terminate early
+ dispatch(terminateFlow(LOADING_ALL_SERVICE_DATA));
+ return;
+ }
+
dispatch(endFlow(LOADING_ALL_SERVICE_DATA));
};
@@ -106,8 +82,7 @@ export const fetchServicesWithMetadataAndDataTypesIfNeeded = (onServiceFetchFini
(dispatch, getState) => {
const state = getState();
if ((Object.keys(state.bentoServices.itemsByArtifact).length === 0 || state.services.items.length === 0 ||
- Object.keys(state.serviceDataTypes.dataTypesByServiceID).length === 0) &&
- !state.services.isFetchingAll) {
+ state.serviceDataTypes.items.length === 0) && !state.services.isFetchingAll) {
return dispatch(fetchServicesWithMetadataAndDataTypes(onServiceFetchFinish));
}
};
diff --git a/src/modules/services/reducers.js b/src/modules/services/reducers.js
index ed1f7c810..06bb8c9f6 100644
--- a/src/modules/services/reducers.js
+++ b/src/modules/services/reducers.js
@@ -3,12 +3,8 @@ import {
FETCH_BENTO_SERVICES,
FETCH_SERVICES,
-
- FETCH_SERVICE_DATA_TYPES,
- LOADING_SERVICE_DATA_TYPES,
-
- FETCH_SERVICE_WORKFLOWS,
- LOADING_SERVICE_WORKFLOWS,
+ FETCH_DATA_TYPES,
+ FETCH_WORKFLOWS,
} from "./actions";
import {normalizeServiceInfo} from "../../utils/serviceInfo";
@@ -125,108 +121,23 @@ export const services = (
export const serviceDataTypes = (
state = {
- isFetchingAll: false,
+ isFetching: false,
itemsByID: {},
- dataTypesByServiceID: {},
- dataTypesByServiceArtifact: {},
- dataTypesByServiceKind: {},
+ items: [],
},
action,
) => {
switch (action.type) {
- case LOADING_SERVICE_DATA_TYPES.BEGIN:
- return {...state, isFetchingAll: true};
-
- case LOADING_SERVICE_DATA_TYPES.END:
- case LOADING_SERVICE_DATA_TYPES.TERMINATE:
- return {...state, isFetchingAll: false};
-
- case FETCH_SERVICE_DATA_TYPES.REQUEST: {
- const {serviceInfo} = action;
- const kind = serviceInfo.bento?.serviceKind ?? serviceInfo.type.artifact;
- return {
- ...state,
- dataTypesByServiceID: {
- ...state.dataTypesByServiceID,
- [serviceInfo.id]: {
- ...(state.dataTypesByServiceID[serviceInfo.id] ?? {items: null, itemsByID: null}),
- isFetching: true,
- },
- },
- dataTypesByServiceArtifact: {
- ...state.dataTypesByServiceArtifact,
- [serviceInfo.type.artifact]: {
- ...(state.dataTypesByServiceArtifact[serviceInfo.type.artifact] ??
- {items: null, itemsByID: null}),
- isFetching: true,
- },
- },
- dataTypesByServiceKind: {
- ...state.dataTypesByServiceKind,
- [kind]: {
- ...(state.dataTypesByServiceKind[kind] ?? {items: null, itemsByID: null}),
- isFetching: true,
- },
- },
- };
- }
-
- case FETCH_SERVICE_DATA_TYPES.RECEIVE: {
- const {serviceInfo} = action;
- const artifact = serviceInfo.type.artifact;
- const kind = serviceInfo.bento?.serviceKind ?? artifact;
- const itemsByID = Object.fromEntries(action.data.map(d => [d.id, d]));
- return {
- ...state,
- itemsByID: {
- ...state.itemsByID,
- ...itemsByID,
- },
- dataTypesByServiceID: {
- ...state.dataTypesByServiceID,
- [serviceInfo.id]: {items: action.data, itemsByID, isFetching: false},
- },
- dataTypesByServiceArtifact: {
- ...state.dataTypesByServiceArtifact,
- [artifact]: {items: action.data, itemsByID, isFetching: false},
- },
- dataTypesByServiceKind: {
- ...state.dataTypesByServiceKind,
- [kind]: {items: action.data, itemsByID, isFetching: false},
- },
- lastUpdated: action.receivedAt,
- };
- }
-
- case FETCH_SERVICE_DATA_TYPES.ERROR: {
- const {serviceInfo} = action;
- const artifact = serviceInfo.type.artifact;
- const kind = serviceInfo.bento?.serviceKind ?? artifact;
+ case FETCH_DATA_TYPES.REQUEST:
+ return {...state, isFetching: true};
+ case FETCH_DATA_TYPES.RECEIVE:
return {
...state,
- dataTypesByServiceID: {
- ...state.dataTypesByServiceID,
- [action.serviceID]: {
- ...(state.dataTypesByServiceID[serviceInfo.id] ?? {items: null, itemsByID: null}),
- isFetching: false,
- },
- },
- dataTypesByServiceArtifact: {
- ...state.dataTypesByServiceArtifact,
- [artifact]: {
- ...(state.dataTypesByServiceArtifact[artifact] ?? {items: null, itemsByID: null}),
- isFetching: false,
- },
- },
- dataTypesByServiceKind: {
- ...state.dataTypesByServiceArtifact,
- [kind]: {
- ...(state.dataTypesByServiceArtifact[kind] ?? {items: null, itemsByID: null}),
- isFetching: false,
- },
- },
+ items: action.data,
+ itemsByID: Object.fromEntries(action.data.map(dt => [dt.id, dt])),
};
- }
+ case FETCH_DATA_TYPES.FINISH:
+ return {...state, isFetching: false};
default:
return state;
@@ -235,47 +146,24 @@ export const serviceDataTypes = (
export const serviceWorkflows = (
state = {
- isFetchingAll: false,
- workflowsByServiceID: {},
+ isFetching: false,
+ items: {}, // by purpose and then by workflow ID
},
action,
) => {
switch (action.type) {
- case LOADING_SERVICE_WORKFLOWS.BEGIN:
- return {...state, isFetchingAll: true};
-
- case LOADING_SERVICE_WORKFLOWS.END:
- case LOADING_SERVICE_WORKFLOWS.TERMINATE:
- return {...state, isFetchingAll: false};
-
- case FETCH_SERVICE_WORKFLOWS.REQUEST: {
- const {serviceInfo: {id: serviceID}} = action;
+ case FETCH_WORKFLOWS.REQUEST:
+ return {...state, isFetching: true};
+ case FETCH_WORKFLOWS.RECEIVE:
return {
...state,
- workflowsByServiceID: {
- ...state.workflowsByServiceID,
- [serviceID]: {
- isFetching: true,
- ...(state.workflowsByServiceID[serviceID] ?? {workflows: null}),
- },
- },
+ items: action.data,
};
- }
-
- case FETCH_SERVICE_WORKFLOWS.RECEIVE: {
- const {serviceInfo: {id: serviceID}, data} = action;
+ case FETCH_WORKFLOWS.FINISH:
return {
...state,
isFetching: false,
- workflowsByServiceID: {
- ...state.workflowsByServiceID,
- [serviceID]: {isFetching: false, workflows: data},
- },
};
- }
-
- case FETCH_SERVICE_WORKFLOWS.ERROR:
- return {...state, isFetching: false};
default:
return state;
diff --git a/src/modules/services/utils.js b/src/modules/services/utils.js
new file mode 100644
index 000000000..5b8777661
--- /dev/null
+++ b/src/modules/services/utils.js
@@ -0,0 +1,2 @@
+export const getDataServices = (state) =>
+ state.services.items.filter(serviceInfo => serviceInfo.bento?.dataService ?? false);
diff --git a/src/propTypes.js b/src/propTypes.js
index 45f33c717..39c8a4a63 100644
--- a/src/propTypes.js
+++ b/src/propTypes.js
@@ -161,26 +161,21 @@ export const workflowsStateToPropsMixin = state => {
export: [],
};
- Object.entries(state.serviceWorkflows.workflowsByServiceID)
- .filter(([_, s]) => !s.isFetching)
- .forEach(([serviceID, s]) => {
- Object.entries(s.workflows).forEach(([workflowType, workflowTypeWorkflows]) => {
- if (!(workflowType in workflowsByType)) return;
-
- // noinspection JSCheckFunctionSignatures
- workflowsByType[workflowType].push(
- ...Object.entries(workflowTypeWorkflows).map(([k, v]) => ({
- ...v,
- id: k,
- serviceID,
- })),
- );
- });
- });
+ Object.entries(state.serviceWorkflows.items).forEach(([workflowType, workflowTypeWorkflows]) => {
+ if (!(workflowType in workflowsByType)) return;
+
+ // noinspection JSCheckFunctionSignatures
+ workflowsByType[workflowType].push(
+ ...Object.entries(workflowTypeWorkflows).map(([k, v]) => ({
+ ...v,
+ id: k,
+ })),
+ );
+ });
return {
workflows: workflowsByType,
- workflowsLoading: state.services.isFetchingAll || state.serviceWorkflows.isFetchingAll,
+ workflowsLoading: state.services.isFetchingAll || state.serviceWorkflows.isFetching,
};
};