diff --git a/package-lock.json b/package-lock.json index b76eb83c..394d64de 100644 --- a/package-lock.json +++ b/package-lock.json @@ -33,6 +33,7 @@ "redux-thunk": "^2.4.1" }, "devDependencies": { + "@types/json-schema": "^7.0.15", "@types/react-dom": "^18.3.1", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", diff --git a/package.json b/package.json index 5f4b2b63..22def57c 100755 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "redux-thunk": "^2.4.1" }, "devDependencies": { + "@types/json-schema": "^7.0.15", "@types/react-dom": "^18.3.1", "@typescript-eslint/eslint-plugin": "^7.16.1", "@typescript-eslint/parser": "^7.16.1", diff --git a/src/js/components/BentoAppRouter.tsx b/src/js/components/BentoAppRouter.tsx index 38644cbb..c68f8278 100644 --- a/src/js/components/BentoAppRouter.tsx +++ b/src/js/components/BentoAppRouter.tsx @@ -106,10 +106,8 @@ const BentoAppRouter = () => { dispatch(makeGetAboutRequest()); dispatch(fetchGohanData()); dispatch(makeGetServiceInfoRequest()); - if (isAuthenticated) { - dispatch(makeGetDataTypes()); - } - }, [dispatch, isAuthenticated]); + dispatch(makeGetDataTypes()); + }, [dispatch]); if (isAutoAuthenticating || projectsStatus === RequestStatus.Pending) { return ; diff --git a/src/js/features/config/config.store.ts b/src/js/features/config/config.store.ts index 4be6d1ac..13f89502 100644 --- a/src/js/features/config/config.store.ts +++ b/src/js/features/config/config.store.ts @@ -52,7 +52,11 @@ export const makeGetServiceInfoRequest = createAsyncThunk< condition(_, { getState }) { const { serviceInfoStatus } = getState().config; const cond = serviceInfoStatus === RequestStatus.Idle; - if (!cond) console.debug(`makeGetServiceInfoRequest(), but a prior attempt gave status: ${serviceInfoStatus}`); + if (!cond) { + console.debug( + `makeGetServiceInfoRequest() was attempted, but a prior attempt gave status: ${serviceInfoStatus}` + ); + } return cond; }, } diff --git a/src/js/features/dataTypes/dataTypes.store.ts b/src/js/features/dataTypes/dataTypes.store.ts index a57f59ba..e148af8e 100644 --- a/src/js/features/dataTypes/dataTypes.store.ts +++ b/src/js/features/dataTypes/dataTypes.store.ts @@ -1,34 +1,45 @@ import axios from 'axios'; -import type { PayloadAction } from '@reduxjs/toolkit'; import { createAsyncThunk, createSlice } from '@reduxjs/toolkit'; import type { RootState } from '@/store'; +import type { BentoServiceDataType } from '@/types/dataTypes'; +import { RequestStatus } from '@/types/requests'; import { authorizedRequestConfig } from '@/utils/requests'; -// TODO: find a way to allow this without an auth token export const makeGetDataTypes = createAsyncThunk< - object, + BentoServiceDataType[], void, { rejectValue: string; state: RootState; } ->('dataTypes/makeGetDataTypes', async (_, { getState }) => { - // Not scoped currently - this is a way to get all data types in an instance from service registry, but it may make - // sense in the future to forward query params to nested calls depending on scope value especially in the case of - // count handling. TBD - TODO: figure this out - const res = await axios.get('/api/service-registry/data-types', authorizedRequestConfig(getState())); - return res.data; -}); +>( + 'dataTypes/makeGetDataTypes', + async (_, { getState }) => { + // Not scoped currently - this is a way to get all data types in an instance from service registry, but it may make + // sense in the future to forward query params to nested calls depending on scope value especially in the case of + // count handling. TBD - TODO: figure this out + const res = await axios.get('/api/service-registry/data-types', authorizedRequestConfig(getState())); + return res.data; + }, + { + condition(_, { getState }) { + const { status } = getState().dataTypes; + const cond = status === RequestStatus.Idle; + if (!cond) console.debug(`makeGetDataTypes() was attempted, but a prior attempt gave status: ${status}`); + return cond; + }, + } +); export type DataTypesState = { - isFetching: boolean; - dataTypes: object; + status: RequestStatus; + dataTypesById: Record; }; const initialState: DataTypesState = { - isFetching: false, - dataTypes: {}, + status: RequestStatus.Idle, + dataTypesById: {}, }; const dataTypes = createSlice({ @@ -37,14 +48,14 @@ const dataTypes = createSlice({ reducers: {}, extraReducers(builder) { builder.addCase(makeGetDataTypes.pending, (state) => { - state.isFetching = true; + state.status = RequestStatus.Pending; }); - builder.addCase(makeGetDataTypes.fulfilled, (state, { payload }: PayloadAction) => { - state.isFetching = false; - state.dataTypes = { ...payload }; + builder.addCase(makeGetDataTypes.fulfilled, (state, { payload }) => { + state.status = RequestStatus.Fulfilled; + state.dataTypesById = Object.fromEntries(payload.map((dt) => [dt.id, dt])); }); builder.addCase(makeGetDataTypes.rejected, (state) => { - state.isFetching = false; + state.status = RequestStatus.Rejected; }); }, }); diff --git a/src/js/store.ts b/src/js/store.ts index b6f954b3..d7bd59cb 100644 --- a/src/js/store.ts +++ b/src/js/store.ts @@ -7,6 +7,7 @@ import { LS_OPENID_CONFIG_KEY, AuthReducer as auth, OIDCReducer as openIdConfigu import configReducer from '@/features/config/config.store'; import contentReducer from '@/features/content/content.store'; import dataReducer from '@/features/data/data.store'; +import dataTypesReducer from '@/features/dataTypes/dataTypes.store'; import queryReducer from '@/features/search/query.store'; import lastIngestionDataReducer from '@/features/ingestion/lastIngestion.store'; import beaconReducer from './features/beacon/beacon.store'; @@ -32,6 +33,7 @@ export const store = configureStore({ config: configReducer, content: contentReducer, data: dataReducer, + dataTypes: dataTypesReducer, query: queryReducer, lastIngestionData: lastIngestionDataReducer, beacon: beaconReducer, diff --git a/src/js/types/dataTypes.ts b/src/js/types/dataTypes.ts index e69de29b..36ef5493 100644 --- a/src/js/types/dataTypes.ts +++ b/src/js/types/dataTypes.ts @@ -0,0 +1,12 @@ +import type { JSONSchema7 } from 'json-schema'; + +export type BentoDataType = { + id: string; + label: string; + queryable: boolean; + schema: JSONSchema7; + metadata_schema: JSONSchema7; + count?: number; +}; + +export type BentoServiceDataType = BentoDataType & { service_base_url: string };