diff --git a/src/actions/admin-access-actions.js b/src/actions/admin-access-actions.js
index ec960e643..17ac4e785 100644
--- a/src/actions/admin-access-actions.js
+++ b/src/actions/admin-access-actions.js
@@ -95,7 +95,7 @@ export const getAdminAccesses =
createAction(RECEIVE_ADMIN_ACCESSES),
`${window.API_BASE_URL}/api/v1/summit-administrator-groups`,
authErrorHandler,
- { order, orderDir, term }
+ { order, orderDir, term, page, perPage }
)(params)(dispatch).then(() => {
dispatch(stopLoading());
});
@@ -129,7 +129,7 @@ export const resetAdminAccessForm = () => (dispatch) => {
};
export const saveAdminAccess =
- (entity, noAlert = false) =>
+ (entity, redirectOnCreate = true) =>
async (dispatch) => {
const accessToken = await getAccessTokenSafely();
@@ -139,7 +139,7 @@ export const saveAdminAccess =
const params = { access_token: accessToken };
if (entity.id) {
- putRequest(
+ return putRequest(
createAction(UPDATE_ADMIN_ACCESS),
createAction(ADMIN_ACCESS_UPDATED),
`${window.API_BASE_URL}/api/v1/summit-administrator-groups/${entity.id}`,
@@ -147,32 +147,34 @@ export const saveAdminAccess =
authErrorHandler,
entity
)(params)(dispatch).then(() => {
- if (!noAlert)
- dispatch(showSuccessMessage(T.translate("admin_access.saved")));
- else dispatch(stopLoading());
+ dispatch(showSuccessMessage(T.translate("admin_access.saved")));
});
- } else {
- const successMessage = {
- title: T.translate("general.done"),
- html: T.translate("admin_access.created"),
- type: "success"
- };
-
- postRequest(
- createAction(UPDATE_ADMIN_ACCESS),
- createAction(ADMIN_ACCESS_ADDED),
- `${window.API_BASE_URL}/api/v1/summit-administrator-groups`,
- normalizedEntity,
- authErrorHandler,
- entity
- )(params)(dispatch).then((payload) => {
+ }
+ return postRequest(
+ createAction(UPDATE_ADMIN_ACCESS),
+ createAction(ADMIN_ACCESS_ADDED),
+ `${window.API_BASE_URL}/api/v1/summit-administrator-groups`,
+ normalizedEntity,
+ authErrorHandler,
+ entity
+ )(params)(dispatch).then((payload) => {
+ if (redirectOnCreate) {
+ const successMessage = {
+ title: T.translate("general.done"),
+ html: T.translate("admin_access.created"),
+ type: "success"
+ };
+
dispatch(
showMessage(successMessage, () => {
history.push(`/app/admin-access/${payload.response.id}`);
})
);
- });
- }
+ return;
+ }
+
+ dispatch(showSuccessMessage(T.translate("admin_access.created")));
+ });
};
export const deleteAdminAccess = (adminAccessId) => async (dispatch) => {
diff --git a/src/components/forms/admin-access-form.js b/src/components/forms/admin-access-form.js
index 6207d00d1..c0c908ed8 100644
--- a/src/components/forms/admin-access-form.js
+++ b/src/components/forms/admin-access-form.js
@@ -9,7 +9,7 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- **/
+ * */
import React from "react";
import T from "i18n-react/dist/i18n-react";
@@ -17,6 +17,10 @@ import "awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css";
import Input from "openstack-uicore-foundation/lib/components/inputs/text-input"
import MemberInput from "openstack-uicore-foundation/lib/components/inputs/member-input"
import SummitInput from "openstack-uicore-foundation/lib/components/inputs/summit-input";
+import Box from "@mui/material/Box";
+import Button from "@mui/material/Button";
+import Grid2 from "@mui/material/Grid2";
+import Typography from "@mui/material/Typography";
import {
scrollToError,
hasErrors,
@@ -37,7 +41,7 @@ class AdminAccessForm extends React.Component {
this.handleSubmit = this.handleSubmit.bind(this);
}
- componentDidUpdate(prevProps, prevState, snapshot) {
+ componentDidUpdate(prevProps) {
const state = {};
scrollToError(this.props.errors);
@@ -63,7 +67,7 @@ class AdminAccessForm extends React.Component {
errors[id] = "";
entity[id] = value;
- this.setState({ entity: entity, errors: errors });
+ this.setState({ entity, errors });
}
handleSubmit(ev) {
@@ -77,11 +81,17 @@ class AdminAccessForm extends React.Component {
const { entity, errors } = this.state;
return (
-
+ >
+ {T.translate("general.save")}
+
+
+
+
);
}
}
diff --git a/src/layouts/admin-access-layout.js b/src/layouts/admin-access-layout.js
index 738e36794..8e61a069e 100644
--- a/src/layouts/admin-access-layout.js
+++ b/src/layouts/admin-access-layout.js
@@ -9,52 +9,41 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- **/
+ * */
import React from "react";
import { Switch, Route, Redirect } from "react-router-dom";
import T from "i18n-react/dist/i18n-react";
-import { connect } from "react-redux";
import { Breadcrumb } from "react-breadcrumbs";
import Restrict from "../routes/restrict";
import AdminAccessListPage from "../pages/admin_access/admin-access-list-page";
-import EditAdminAccessPage from "../pages/admin_access/edit-admin-access-page";
-class AdminAccessLayout extends React.Component {
- render() {
- const { match } = this.props;
+const AdminAccessLayout = ({ match }) => (
+
+
- return (
-
-
+
+
+
+
+
+
+
+);
-
-
-
-
-
-
-
- );
- }
-}
-
-export default Restrict(connect(null, {})(AdminAccessLayout), "admin-access");
+export default Restrict(AdminAccessLayout, "admin-access");
diff --git a/src/pages/admin_access/__tests__/admin-access-list-page.test.js b/src/pages/admin_access/__tests__/admin-access-list-page.test.js
new file mode 100644
index 000000000..ddabdf40b
--- /dev/null
+++ b/src/pages/admin_access/__tests__/admin-access-list-page.test.js
@@ -0,0 +1,145 @@
+import React from "react";
+import { Provider } from "react-redux";
+import { MemoryRouter, Route } from "react-router-dom";
+import { render, screen, fireEvent, waitFor } from "@testing-library/react";
+import configureStore from "redux-mock-store";
+import thunk from "redux-thunk";
+import AdminAccessListPage from "../admin-access-list-page";
+
+const mockGetAdminAccesses = jest.fn(() => () => Promise.resolve());
+const mockDeleteAdminAccess = jest.fn(() => () => Promise.resolve());
+const mockGetAdminAccess = jest.fn(() => () => Promise.resolve());
+const mockResetAdminAccessForm = jest.fn(() => () => Promise.resolve());
+const mockSaveAdminAccess = jest.fn(() => () => Promise.resolve());
+
+jest.mock("../../../actions/admin-access-actions", () => ({
+ getAdminAccesses: (...args) => mockGetAdminAccesses(...args),
+ deleteAdminAccess: (...args) => mockDeleteAdminAccess(...args),
+ getAdminAccess: (...args) => mockGetAdminAccess(...args),
+ resetAdminAccessForm: (...args) => mockResetAdminAccessForm(...args),
+ saveAdminAccess: (...args) => mockSaveAdminAccess(...args)
+}));
+
+jest.mock("openstack-uicore-foundation/lib/components/mui/table", () => {
+ const MockMuiTable = ({ data = [], onEdit, onDelete, onPerPageChange }) => (
+
+
onPerPageChange(25)}>
+ per-page-25
+
+ {data.map((row) => (
+
+ {row.title}
+ onEdit(row)}>
+ edit
+
+ onDelete(row)}>
+ delete
+
+
+ ))}
+
+ );
+
+ return MockMuiTable;
+});
+
+jest.mock("../../../components/forms/admin-access-form", () => {
+ const MockAdminAccessForm = ({ onSubmit }) => (
+
+ onSubmit({ title: "Group A", members: [], summits: [] })}
+ >
+ submit-form
+
+
+ );
+
+ return MockAdminAccessForm;
+});
+
+jest.mock("sweetalert2", () => ({
+ fire: jest.fn(() => Promise.resolve({ value: true }))
+}));
+
+const middlewares = [thunk];
+const mockStore = configureStore(middlewares);
+
+const baseListState = {
+ admin_accesses: [
+ { id: 1, title: "Group A", members: "John Doe", summits: "Summit One" }
+ ],
+ term: "",
+ order: "id",
+ orderDir: 1,
+ currentPage: 1,
+ lastPage: 1,
+ perPage: 10
+};
+
+const baseFormState = {
+ entity: { id: 0, title: "", members: [], summits: [] },
+ errors: {}
+};
+
+const renderPage = (path = "/app/admin-access", formState = baseFormState) => {
+ const store = mockStore({
+ adminAccessListState: baseListState,
+ adminAccessState: formState
+ });
+
+ render(
+
+
+
+
+
+ );
+
+ return store;
+};
+
+describe("AdminAccessListPage MUI migration", () => {
+ beforeEach(() => {
+ jest.clearAllMocks();
+ });
+
+ it("renders grid and opens popup for new item", async () => {
+ renderPage("/app/admin-access");
+
+ expect(screen.getByTestId("mui-table")).toBeInTheDocument();
+ expect(screen.queryByTestId("admin-access-form")).not.toBeInTheDocument();
+
+ fireEvent.click(screen.getByRole("button", { name: /create|add/i }));
+
+ await waitFor(() => {
+ expect(screen.getByTestId("admin-access-form")).toBeInTheDocument();
+ });
+ });
+
+ it("opens popup when route has an access id", async () => {
+ const formState = {
+ entity: { id: 1, title: "Group A", members: [], summits: [] },
+ errors: {}
+ };
+
+ renderPage("/app/admin-access/1", formState);
+
+ await waitFor(() => {
+ expect(screen.getByTestId("admin-access-form")).toBeInTheDocument();
+ });
+ });
+
+ it("requests data with selected rows per page", async () => {
+ renderPage("/app/admin-access");
+
+ fireEvent.click(screen.getByRole("button", { name: "per-page-25" }));
+
+ await waitFor(() => {
+ expect(mockGetAdminAccesses).toHaveBeenCalledWith("", 1, 25, "id", 1);
+ });
+ });
+});
diff --git a/src/pages/admin_access/admin-access-list-page.js b/src/pages/admin_access/admin-access-list-page.js
index d4c943e15..2b5b21739 100644
--- a/src/pages/admin_access/admin-access-list-page.js
+++ b/src/pages/admin_access/admin-access-list-page.js
@@ -11,167 +11,255 @@
* limitations under the License.
* */
-import React from "react";
+import React, { useEffect, useMemo, useState } from "react";
import { connect } from "react-redux";
import T from "i18n-react/dist/i18n-react";
-import Swal from "sweetalert2";
-import { Pagination } from "react-bootstrap";
-import FreeTextSearch from "openstack-uicore-foundation/lib/components/free-text-search"
-import Table from "openstack-uicore-foundation/lib/components/table";
+import Box from "@mui/material/Box";
+import Button from "@mui/material/Button";
+import Dialog from "@mui/material/Dialog";
+import DialogContent from "@mui/material/DialogContent";
+import DialogTitle from "@mui/material/DialogTitle";
+import Divider from "@mui/material/Divider";
+import Grid2 from "@mui/material/Grid2";
+import AddIcon from "@mui/icons-material/Add";
+import MuiTable from "openstack-uicore-foundation/lib/components/mui/table";
+import MuiSearchInput from "openstack-uicore-foundation/lib/components/mui/search-input";
import { getSummitById } from "../../actions/summit-actions";
+import AdminAccessForm from "../../components/forms/admin-access-form";
import {
getAdminAccesses,
- deleteAdminAccess
+ deleteAdminAccess,
+ getAdminAccess,
+ resetAdminAccessForm,
+ saveAdminAccess
} from "../../actions/admin-access-actions";
+import { DEFAULT_CURRENT_PAGE } from "../../utils/constants";
-class AdminAccessListPage extends React.Component {
- constructor(props) {
- super(props);
+const AdminAccessListPage = ({
+ admin_accesses,
+ totalAdminAccesses,
+ currentPage,
+ perPage,
+ term,
+ order,
+ orderDir,
+ entity,
+ errors,
+ match,
+ history,
+ getAdminAccesses,
+ deleteAdminAccess,
+ getAdminAccess,
+ resetAdminAccessForm,
+ saveAdminAccess
+}) => {
+ const [searchTerm, setSearchTerm] = useState(term || "");
+ const [open, setOpen] = useState(false);
+
+ useEffect(() => {
+ getAdminAccesses(term, DEFAULT_CURRENT_PAGE, perPage, order, orderDir);
+ }, [getAdminAccesses]);
- this.handleEdit = this.handleEdit.bind(this);
- this.handlePageChange = this.handlePageChange.bind(this);
- this.handleSort = this.handleSort.bind(this);
- this.handleSearch = this.handleSearch.bind(this);
- this.handleNewAdminAccess = this.handleNewAdminAccess.bind(this);
- this.handleDeleteAdminAccess = this.handleDeleteAdminAccess.bind(this);
+ useEffect(() => {
+ const { access_id: accessId } = match.params;
+ const isNew = /\/new$/.test(history.location.pathname);
- this.state = {};
- }
+ if (isNew) {
+ resetAdminAccessForm();
+ setOpen(true);
+ return;
+ }
- componentDidMount() {
- this.props.getAdminAccesses();
- }
+ if (accessId) {
+ getAdminAccess(accessId).then(() => setOpen(true));
+ return;
+ }
- handleEdit(admin_access_id) {
- const { history } = this.props;
- history.push(`/app/admin-access/${admin_access_id}`);
- }
+ setOpen(false);
+ }, [match.params.access_id, history.location.pathname]);
- handlePageChange(page) {
- const { term, order, orderDir, perPage } = this.props;
- this.props.getAdminAccesses(term, page, perPage, order, orderDir);
- }
+ const handlePageChange = (page) => {
+ getAdminAccesses(term, page, perPage, order, orderDir);
+ };
- handleSort(index, key, dir) {
- const { term, page, perPage } = this.props;
- this.props.getAdminAccesses(term, page, perPage, key, dir);
- }
+ const handlePerPageChange = (newPerPage) => {
+ getAdminAccesses(term, DEFAULT_CURRENT_PAGE, newPerPage, order, orderDir);
+ };
- handleSearch(term) {
- const { order, orderDir, page, perPage } = this.props;
- this.props.getAdminAccesses(term, page, perPage, order, orderDir);
- }
+ const handleSort = (key, dir) => {
+ getAdminAccesses(term, currentPage, perPage, key, dir);
+ };
- handleNewAdminAccess(ev) {
- const { history } = this.props;
- ev.preventDefault();
+ const handleSearch = (value) => {
+ setSearchTerm(value);
+ getAdminAccesses(value, DEFAULT_CURRENT_PAGE, perPage, order, orderDir);
+ };
+ const handleNewAdminAccess = () => {
history.push("/app/admin-access/new");
- }
-
- handleDeleteAdminAccess(accessId) {
- const { deleteAdminAccess, admin_accesses } = this.props;
- const admin_access = admin_accesses.find((t) => t.id === accessId);
-
- Swal.fire({
- title: T.translate("general.are_you_sure"),
- text: `${T.translate("admin_access.delete_warning")} ${
- admin_access.title
- }`,
- type: "warning",
- showCancelButton: true,
- confirmButtonColor: "#DD6B55",
- confirmButtonText: T.translate("general.yes_delete")
- }).then((result) => {
- if (result.value) {
- deleteAdminAccess(accessId);
- }
+ };
+
+ const handleEdit = (row) => {
+ history.push(`/app/admin-access/${row.id}`);
+ };
+
+ const handleDeleteAdminAccess = (rowOrId) => {
+ const accessId = typeof rowOrId === "object" ? rowOrId?.id : rowOrId;
+
+ if (!accessId) return;
+
+ const nextPage =
+ admin_accesses.length === 1 && currentPage > 1
+ ? currentPage - 1
+ : currentPage;
+
+ deleteAdminAccess(accessId).then(() => {
+ getAdminAccesses(term, nextPage, perPage, order, orderDir);
});
- }
+ };
- render() {
- const { admin_accesses, lastPage, currentPage, term, order, orderDir } =
- this.props;
+ const closeDialog = () => {
+ resetAdminAccessForm();
+ setOpen(false);
+ history.push("/app/admin-access");
+ };
+
+ const handleSave = (adminAccessEntity) => {
+ saveAdminAccess(adminAccessEntity, false).then(() => {
+ getAdminAccesses(term, currentPage, perPage, order, orderDir);
+ closeDialog();
+ });
+ };
- const columns = [
- { columnKey: "id", value: T.translate("general.id"), sortable: true },
+ const columns = useMemo(
+ () => [
+ { columnKey: "id", header: T.translate("general.id"), sortable: true },
{
columnKey: "title",
- value: T.translate("admin_access.title"),
+ header: T.translate("admin_access.title"),
sortable: true
},
- { columnKey: "summits", value: T.translate("admin_access.summits") },
- { columnKey: "members", value: T.translate("admin_access.members") }
- ];
-
- const table_options = {
- sortCol: order,
- sortDir: orderDir,
- actions: {
- edit: { onClick: this.handleEdit },
- delete: { onClick: this.handleDeleteAdminAccess }
- }
- };
-
- return (
-
-
{T.translate("admin_access.admin_access_list")}
-
-
-
-
-
-
- {T.translate("admin_access.add")}
-
-
-
-
- {admin_accesses.length === 0 && (
-
{T.translate("admin_access.no_results")}
- )}
-
- {admin_accesses.length > 0 && (
-
-
-
+ {T.translate("admin_access.admin_access_list")}
+
+
+
+ {totalItems} {T.translate("general.items")}
+
+
+
+
+ }
+ onClick={handleNewAdminAccess}
+ sx={{
+ height: "36px",
+ padding: "6px 16px",
+ fontSize: "1.4rem",
+ lineHeight: "2.4rem",
+ letterSpacing: "0.4px"
+ }}
+ >
+ {T.translate("admin_access.add")}
+
+
+
+
+ {admin_accesses.length === 0 && (
+ {T.translate("admin_access.no_results")}
+ )}
+
+ {admin_accesses.length > 0 && (
+ adminAccess?.title ?? adminAccess?.id}
+ deleteDialogBody={(groupName) =>
+ `${T.translate("admin_access.delete_warning")} "${groupName}" ?`
+ }
+ confirmButtonColor="error"
+ onPageChange={handlePageChange}
+ onPerPageChange={handlePerPageChange}
+ onSort={handleSort}
+ onEdit={handleEdit}
+ onDelete={handleDeleteAdminAccess}
+ />
+ )}
+
+ {open && (
+
+
+ {entity.id
+ ? T.translate("general.edit")
+ : T.translate("general.add")}{" "}
+ {T.translate("admin_access.admin_access")}
+
+
+
+
-
- )}
-
- );
- }
-}
-
-const mapStateToProps = ({ adminAccessListState }) => ({
- ...adminAccessListState
+
+
+ )}
+
+ );
+};
+
+const mapStateToProps = ({ adminAccessListState, adminAccessState }) => ({
+ ...adminAccessListState,
+ entity: adminAccessState.entity,
+ errors: adminAccessState.errors
});
export default connect(mapStateToProps, {
getSummitById,
getAdminAccesses,
- deleteAdminAccess
+ deleteAdminAccess,
+ getAdminAccess,
+ resetAdminAccessForm,
+ saveAdminAccess
})(AdminAccessListPage);
diff --git a/src/pages/admin_access/edit-admin-access-page.js b/src/pages/admin_access/edit-admin-access-page.js
deleted file mode 100644
index 12fe488b6..000000000
--- a/src/pages/admin_access/edit-admin-access-page.js
+++ /dev/null
@@ -1,89 +0,0 @@
-/**
- * Copyright 2020 OpenStack Foundation
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- * http://www.apache.org/licenses/LICENSE-2.0
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- **/
-
-import React from "react";
-import { connect } from "react-redux";
-import T from "i18n-react/dist/i18n-react";
-import { Breadcrumb } from "react-breadcrumbs";
-import AdminAccessForm from "../../components/forms/admin-access-form";
-import { getSummitById } from "../../actions/summit-actions";
-import {
- getAdminAccess,
- resetAdminAccessForm,
- saveAdminAccess
-} from "../../actions/admin-access-actions";
-
-//import '../../styles/edit-admin-access-page.less';
-
-class EditAdminAccessPage extends React.Component {
- constructor(props) {
- super(props);
-
- this.state = {};
-
- const accessId = props.match.params.access_id;
-
- if (!accessId) {
- props.resetAdminAccessForm();
- } else {
- props.getAdminAccess(accessId);
- }
- }
-
- componentDidUpdate(prevProps, prevState, snapshot) {
- const oldId = prevProps.match.params.access_id;
- const newId = this.props.match.params.access_id;
-
- if (oldId !== newId) {
- if (!newId) {
- this.props.resetTemplateForm();
- } else {
- this.props.getAdminAccess(newId);
- }
- }
- }
-
- render() {
- const { entity, errors, match } = this.props;
- const title = entity.id
- ? T.translate("general.edit")
- : T.translate("general.add");
- const breadcrumb = entity.id ? entity.title : T.translate("general.new");
-
- return (
-
-
-
- {title} {T.translate("admin_access.admin_access")}
-
-
-
-
- );
- }
-}
-
-const mapStateToProps = ({ adminAccessState }) => ({
- ...adminAccessState
-});
-
-export default connect(mapStateToProps, {
- getSummitById,
- getAdminAccess,
- resetAdminAccessForm,
- saveAdminAccess
-})(EditAdminAccessPage);
diff --git a/src/reducers/admin_access/__tests__/admin-access-list-reducer.test.js b/src/reducers/admin_access/__tests__/admin-access-list-reducer.test.js
new file mode 100644
index 000000000..76c65bae0
--- /dev/null
+++ b/src/reducers/admin_access/__tests__/admin-access-list-reducer.test.js
@@ -0,0 +1,49 @@
+import adminAccessListReducer from "../admin-access-list-reducer";
+import { ADMIN_ACCESS_DELETED } from "../../../actions/admin-access-actions";
+
+describe("adminAccessListReducer", () => {
+ test("decrements totalAdminAccesses when deleting an existing row", () => {
+ const initialState = {
+ admin_accesses: [
+ { id: 10, title: "Group A" },
+ { id: 11, title: "Group B" }
+ ],
+ totalAdminAccesses: 2,
+ term: "",
+ order: "id",
+ orderDir: 1,
+ currentPage: 1,
+ lastPage: 1,
+ perPage: 10
+ };
+
+ const result = adminAccessListReducer(initialState, {
+ type: ADMIN_ACCESS_DELETED,
+ payload: { adminAccessId: 10 }
+ });
+
+ expect(result.admin_accesses).toStrictEqual([{ id: 11, title: "Group B" }]);
+ expect(result.totalAdminAccesses).toBe(1);
+ });
+
+ test("keeps totalAdminAccesses when deleted id does not exist", () => {
+ const initialState = {
+ admin_accesses: [{ id: 10, title: "Group A" }],
+ totalAdminAccesses: 1,
+ term: "",
+ order: "id",
+ orderDir: 1,
+ currentPage: 1,
+ lastPage: 1,
+ perPage: 10
+ };
+
+ const result = adminAccessListReducer(initialState, {
+ type: ADMIN_ACCESS_DELETED,
+ payload: { adminAccessId: 999 }
+ });
+
+ expect(result.admin_accesses).toStrictEqual([{ id: 10, title: "Group A" }]);
+ expect(result.totalAdminAccesses).toBe(1);
+ });
+});
diff --git a/src/reducers/admin_access/admin-access-list-reducer.js b/src/reducers/admin_access/admin-access-list-reducer.js
index cbf46006f..decacd9d5 100644
--- a/src/reducers/admin_access/admin-access-list-reducer.js
+++ b/src/reducers/admin_access/admin-access-list-reducer.js
@@ -9,18 +9,19 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- **/
+ * */
+import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions";
import {
RECEIVE_ADMIN_ACCESSES,
REQUEST_ADMIN_ACCESSES,
ADMIN_ACCESS_DELETED
} from "../../actions/admin-access-actions";
-import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions";
const DEFAULT_STATE = {
admin_accesses: [],
+ totalAdminAccesses: 0,
term: null,
order: "id",
orderDir: 1,
@@ -36,37 +37,50 @@ const adminAccessListReducer = (state = DEFAULT_STATE, action) => {
return DEFAULT_STATE;
}
case REQUEST_ADMIN_ACCESSES: {
- let { order, orderDir, term } = payload;
+ const { order, orderDir, term, page, perPage } = payload;
- return { ...state, order, orderDir, term };
+ return {
+ ...state,
+ order,
+ orderDir,
+ term,
+ currentPage: page || state.currentPage,
+ perPage: perPage || state.perPage
+ };
}
case RECEIVE_ADMIN_ACCESSES: {
- let { total, last_page, current_page } = payload.response;
- let admin_accesses = payload.response.data.map((aa) => {
- return {
+ const { total, last_page, current_page, per_page } = payload.response;
+ const admin_accesses = payload.response.data.map((aa) => ({
id: aa.id,
title: aa.title,
members: aa.members
.map((m) => `${m.first_name} ${m.last_name}`)
.join(", "),
summits: aa.summits.map((s) => s.name).join(", ")
- };
- });
+ }));
return {
...state,
- admin_accesses: admin_accesses,
+ admin_accesses,
+ totalAdminAccesses: total || 0,
currentPage: current_page,
- lastPage: last_page
+ lastPage: last_page,
+ perPage: per_page || state.perPage
};
}
case ADMIN_ACCESS_DELETED: {
- let { adminAccessId } = payload;
+ const { adminAccessId } = payload;
+ const filteredAdminAccesses = state.admin_accesses.filter(
+ (aa) => aa.id !== adminAccessId
+ );
+
return {
...state,
- admin_accesses: state.admin_accesses.filter(
- (aa) => aa.id !== adminAccessId
- )
+ admin_accesses: filteredAdminAccesses,
+ totalAdminAccesses:
+ filteredAdminAccesses.length === state.admin_accesses.length
+ ? state.totalAdminAccesses
+ : Math.max(0, (state.totalAdminAccesses ?? 0) - 1)
};
}
default: