Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions dashboard/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions dashboard/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
"@testing-library/jest-dom": "^4.2.4",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.1",
"deferred": "^0.7.11",
"enum": "^3.0.4",
"jest-canvas-mock": "^2.2.0",
"material-table": "^1.66.0",
"react": "^16.13.1",
Expand Down
22 changes: 11 additions & 11 deletions dashboard/src/components/app/__snapshots__/App.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -442,87 +442,87 @@ exports[`App hasn't changed 1`] = `
key="/sources"
path="/sources"
>
<ResourceList
<ResourceListView
title="Data Sources"
/>
</Route>
<Route
key="/views"
path="/views"
>
<ResourceList
<ResourceListView
title="Materialized Views"
/>
</Route>
<Route
key="/features"
path="/features"
>
<ResourceList
<ResourceListView
title="Features"
/>
</Route>
<Route
key="/feature-sets"
path="/feature-sets"
>
<ResourceList
<ResourceListView
title="Feature Sets"
/>
</Route>
<Route
key="/training-sets"
path="/training-sets"
>
<ResourceList
<ResourceListView
title="Training Sets"
/>
</Route>
<Route
key="/metrics"
path="/metrics"
>
<ResourceList
<ResourceListView
title="Metrics"
/>
</Route>
<Route
key="/deployment"
path="/deployment"
>
<ResourceList
<ResourceListView
title="Deployment"
/>
</Route>
<Route
key="/users"
path="/users"
>
<ResourceList
<ResourceListView
title="Users"
/>
</Route>
<Route
key="/settings"
path="/settings"
>
<ResourceList
<ResourceListView
title="Settings"
/>
</Route>
<Route
key="/billing"
path="/billing"
>
<ResourceList
<ResourceListView
title="Billing"
/>
</Route>
<Route
key="/help"
path="/help"
>
<ResourceList
<ResourceListView
title="Help"
/>
</Route>
Expand Down
5 changes: 5 additions & 0 deletions dashboard/src/components/redux/store/ReduxStore.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ const store = configureStore({
reducer: rootReducer,
});

export const newTestStore = () =>
configureStore({
reducer: rootReducer,
});

export default store;
2 changes: 1 addition & 1 deletion dashboard/src/components/redux/store/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default } from "./ReduxStore.js";
export { default, newTestStore } from "./ReduxStore.js";
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const useStyles = makeStyles((theme) => ({
},
}));

export const ResourceList = ({ title }) => {
export const ResourceListView = ({ title }) => {
const classes = useStyles();
return (
// MaterialTable doesn't support className, so we wrap it in a Box:
Expand All @@ -28,4 +28,4 @@ export const ResourceList = ({ title }) => {
);
};

export default ResourceList;
export default ResourceListView;
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import "jest-canvas-mock";
import { configure, shallow } from "enzyme";
import Adapter from "enzyme-adapter-react-16";

import { ResourceList } from "./ResourceList.js";
import { ResourceListView } from "./ResourceListView.js";

configure({ adapter: new Adapter() });

describe("ResourceList", () => {
const sources = shallow(<ResourceList title={"abc"} />);
describe("ResourceListView", () => {
const sources = shallow(<ResourceListView title={"abc"} />);

it("passes title to child prop", () => {
expect(sources.children().props().title).toEqual("abc");
Expand Down
73 changes: 73 additions & 0 deletions dashboard/src/components/resource-list/ResourceSlice.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit";
import Enum from "enum";

export const fetchResources = createAsyncThunk(
"resourceList/fetchByType",
async ({ api, type }, { signal }) => {
const response = await api.fetchResources(type, signal);
return response.data;
},
{
condition: ({ api, type }, { getState }) => {
const { resources, loading } = getState().resourceList[type];
if (loading || resources) {
return false;
}
},
}
);

export const resourceTypes = new Enum([
"DATA_SOURCE",
"MATERIALIZED_VIEW",
"FEATURE",
"FEATURE_SET",
"TRAINING_SET",
]);

const reduceFn = (map, type) => {
map[type] = {};
return map;
};
const reduceFnInitial = {};
export const initialState = resourceTypes.enums.reduce(
reduceFn,
reduceFnInitial
);

const resourceSlice = createSlice({
name: "resourceList",
// initialState is a map between each resource type to an empty object.
initialState: initialState,
extraReducers: {
[fetchResources.pending]: (state, action) => {
const type = action.meta.arg.type;
const requestId = action.meta.requestId;
state[type].resources = null;
state[type].requestId = requestId;
state[type].loading = true;
state[type].failed = false;
},
[fetchResources.fulfilled]: (state, action) => {
const type = action.meta.arg.type;
const requestId = action.meta.requestId;
if (requestId !== state[type].requestId) {
return;
}
state[type].resources = action.payload;
state[type].loading = false;
state[type].failed = false;
},
[fetchResources.rejected]: (state, action) => {
const type = action.meta.arg.type;
const requestId = action.meta.requestId;
if (requestId !== state[type].requestId) {
return;
}
state[type].loading = false;
state[type].failed = true;
},
},
});

export default resourceSlice.reducer;
Loading