diff --git a/src/actions/media-file-type-actions.js b/src/actions/media-file-type-actions.js index 7398a21de..d770436b3 100644 --- a/src/actions/media-file-type-actions.js +++ b/src/actions/media-file-type-actions.js @@ -21,15 +21,12 @@ import { createAction, stopLoading, startLoading, - showMessage, - showSuccessMessage, - authErrorHandler, fetchResponseHandler, fetchErrorHandler, escapeFilterValue } from "openstack-uicore-foundation/lib/utils/actions"; import URI from "urijs"; -import history from "../history"; +import { snackbarErrorHandler, snackbarSuccessHandler } from "./base-actions"; import { getAccessTokenSafely } from "../utils/methods"; import { DEBOUNCE_WAIT, @@ -87,9 +84,9 @@ export const getMediaFileTypes = createAction(REQUEST_MEDIA_FILE_TYPES), createAction(RECEIVE_MEDIA_FILE_TYPES), `${window.API_BASE_URL}/api/v1/summit-media-file-types`, - authErrorHandler, - { order, orderDir, term } - )(params)(dispatch).then(() => { + snackbarErrorHandler, + { order, orderDir, term, perPage } + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; @@ -109,9 +106,9 @@ export const getAllMediaFileTypes = () => async (dispatch) => { createAction(REQUEST_ALL_MEDIA_FILE_TYPES), createAction(RECEIVE_ALL_MEDIA_FILE_TYPES), `${window.API_BASE_URL}/api/v1/summit-media-file-types`, - authErrorHandler, + snackbarErrorHandler, {} - )(params)(dispatch).then(() => { + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; @@ -129,8 +126,8 @@ export const getMediaFileType = (mediaFileTypeId) => async (dispatch) => { null, createAction(RECEIVE_MEDIA_FILE_TYPE), `${window.API_BASE_URL}/api/v1/summit-media-file-types/${mediaFileTypeId}`, - authErrorHandler - )(params)(dispatch).then(() => { + snackbarErrorHandler + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; @@ -139,52 +136,52 @@ export const resetMediaFileTypeForm = () => (dispatch) => { dispatch(createAction(RESET_MEDIA_FILE_TYPE_FORM)({})); }; -export const saveMediaFileType = - (entity, noAlert = false) => - async (dispatch) => { - const accessToken = await getAccessTokenSafely(); +export const saveMediaFileType = (entity) => async (dispatch) => { + const accessToken = await getAccessTokenSafely(); - dispatch(startLoading()); + dispatch(startLoading()); - const normalizedEntity = normalizeEntity(entity); - const params = { access_token: accessToken }; - - if (entity.id) { - putRequest( - createAction(UPDATE_MEDIA_FILE_TYPE), - createAction(MEDIA_FILE_TYPE_UPDATED), - `${window.API_BASE_URL}/api/v1/summit-media-file-types/${entity.id}`, - normalizedEntity, - authErrorHandler, - entity - )(params)(dispatch).then(() => { - if (!noAlert) - dispatch(showSuccessMessage(T.translate("media_file_type.saved"))); - else dispatch(stopLoading()); - }); - } else { - const success_message = { - title: T.translate("general.done"), - html: T.translate("media_file_type.created"), - type: "success" - }; - - postRequest( - createAction(UPDATE_MEDIA_FILE_TYPE), - createAction(MEDIA_FILE_TYPE_ADDED), - `${window.API_BASE_URL}/api/v1/summit-media-file-types`, - normalizedEntity, - authErrorHandler, - entity - )(params)(dispatch).then((payload) => { + const normalizedEntity = normalizeEntity(entity); + const params = { access_token: accessToken }; + + if (entity.id) { + return putRequest( + createAction(UPDATE_MEDIA_FILE_TYPE), + createAction(MEDIA_FILE_TYPE_UPDATED), + `${window.API_BASE_URL}/api/v1/summit-media-file-types/${entity.id}`, + normalizedEntity, + snackbarErrorHandler, + entity + )(params)(dispatch) + .then(() => { dispatch( - showMessage(success_message, () => { - history.push(`/app/media-file-types/${payload.response.id}`); + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("media_file_type.saved") }) ); - }); - } - }; + }) + .finally(() => dispatch(stopLoading())); + } + + return postRequest( + createAction(UPDATE_MEDIA_FILE_TYPE), + createAction(MEDIA_FILE_TYPE_ADDED), + `${window.API_BASE_URL}/api/v1/summit-media-file-types`, + normalizedEntity, + snackbarErrorHandler, + entity + )(params)(dispatch) + .then(() => { + dispatch( + snackbarSuccessHandler({ + title: T.translate("general.success"), + html: T.translate("media_file_type.created") + }) + ); + }) + .finally(() => dispatch(stopLoading())); +}; export const deleteMediaFileType = (mediaFileTypeId) => async (dispatch) => { const accessToken = await getAccessTokenSafely(); @@ -198,8 +195,8 @@ export const deleteMediaFileType = (mediaFileTypeId) => async (dispatch) => { createAction(MEDIA_FILE_TYPE_DELETED)({ mediaFileTypeId }), `${window.API_BASE_URL}/api/v1/summit-media-file-types/${mediaFileTypeId}`, null, - authErrorHandler - )(params)(dispatch).then(() => { + snackbarErrorHandler + )(params)(dispatch).finally(() => { dispatch(stopLoading()); }); }; diff --git a/src/i18n/en.json b/src/i18n/en.json index 3fb5ca6c3..fd248415a 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -3354,7 +3354,7 @@ "description": "Description", "allowed_extensions_input": "Allowed Extensions (comma separated: PDF,DOC,etc)", "allowed_extensions": "Allowed Extensions", - "delete_warning": "Are you sure you want to delete media file type ", + "delete_warning": "Are you sure you want to delete media file type {name}?", "saved": "Media File Type saved successfully.", "created": "Media File Type created successfully.", "placeholders": { diff --git a/src/pages/media_file_types/__tests__/media-file-type-list-page.test.js b/src/pages/media_file_types/__tests__/media-file-type-list-page.test.js new file mode 100644 index 000000000..ed77e0ed2 --- /dev/null +++ b/src/pages/media_file_types/__tests__/media-file-type-list-page.test.js @@ -0,0 +1,222 @@ +import React from "react"; +import { screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import { renderWithRedux } from "../../../utils/test-utils"; +import MediaFileTypeListPage from "../media-file-type-list-page"; +import * as mediaFileTypeActions from "../../../actions/media-file-type-actions"; +import { + DEFAULT_CURRENT_PAGE, + DEFAULT_PER_PAGE +} from "../../../utils/constants"; + +jest.mock("i18n-react/dist/i18n-react", () => ({ + __esModule: true, + default: { translate: (key) => key } +})); + +jest.mock("openstack-uicore-foundation/lib/components/mui/table", () => ({ + __esModule: true, + default: ({ data, onEdit, onDelete }) => ( +
+ {data.map((row) => ( +
+ {row.name} + + +
+ ))} +
+ ) +})); + +jest.mock("openstack-uicore-foundation/lib/components/mui/search-input", () => { + const React = require("react"); + return { + __esModule: true, + default: ({ onSearch, term }) => { + const [value, setValue] = React.useState(term || ""); + return ( + setValue(e.target.value)} + onKeyDown={(e) => { + if (e.key === "Enter") onSearch(value); + }} + /> + ); + } + }; +}); + +jest.mock("../components/media-file-type-dialog", () => ({ + __esModule: true, + default: ({ onClose, onSave }) => ( +
+ + +
+ ) +})); + +jest.mock("../../../actions/media-file-type-actions", () => ({ + ...jest.requireActual("../../../actions/media-file-type-actions"), + getMediaFileTypes: jest.fn(() => () => Promise.resolve()), + getMediaFileType: jest.fn(() => () => Promise.resolve()), + saveMediaFileType: jest.fn(() => () => Promise.resolve()), + deleteMediaFileType: jest.fn(() => () => Promise.resolve()), + resetMediaFileTypeForm: jest.fn(() => () => {}) +})); + +const buildInitialState = (listOverrides = {}) => ({ + mediaFileTypeListState: { + media_file_types: [], + term: "", + order: "id", + orderDir: 1, + currentPage: 1, + lastPage: 1, + perPage: 10, + totalMediaFileTypes: 0, + ...listOverrides + }, + mediaFileTypeState: { + entity: { id: 0, name: "", description: "", allowed_extensions: "" }, + errors: {} + } +}); + +describe("MediaFileTypeListPage", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + test("should call getMediaFileTypes on mount", async () => { + renderWithRedux(, { + initialState: buildInitialState() + }); + + await waitFor(() => { + expect(mediaFileTypeActions.getMediaFileTypes).toHaveBeenCalledTimes(1); + }); + }); + + test("should show empty state message when list is empty", () => { + renderWithRedux(, { + initialState: buildInitialState() + }); + + expect(screen.getByText("media_file_type.no_results")).toBeInTheDocument(); + expect(screen.queryByTestId("mui-table")).not.toBeInTheDocument(); + }); + + test("should show table and total count when media file types are present", () => { + renderWithRedux(, { + initialState: buildInitialState({ + media_file_types: [ + { id: 1, name: "Image", description: "", allowed_extensions: [] }, + { id: 2, name: "Document", description: "", allowed_extensions: [] } + ], + totalMediaFileTypes: 2 + }) + }); + + expect(screen.getByTestId("mui-table")).toBeInTheDocument(); + expect( + screen.getByText(/2\smedia_file_type\.media_file_types/) + ).toBeInTheDocument(); + expect( + screen.queryByText("media_file_type.no_results") + ).not.toBeInTheDocument(); + }); + + test("opens dialog and resets form when Add button is clicked", async () => { + const user = userEvent.setup(); + renderWithRedux(, { + initialState: buildInitialState() + }); + + await user.click(screen.getByText("media_file_type.add")); + + expect(mediaFileTypeActions.resetMediaFileTypeForm).toHaveBeenCalled(); + expect(screen.getByTestId("media-file-type-dialog")).toBeInTheDocument(); + }); + + test("closes dialog when dialog close is triggered", async () => { + const user = userEvent.setup(); + renderWithRedux(, { + initialState: buildInitialState() + }); + + await user.click(screen.getByText("media_file_type.add")); + expect(screen.getByTestId("media-file-type-dialog")).toBeInTheDocument(); + + await user.click(screen.getByText("dialog-close")); + expect( + screen.queryByTestId("media-file-type-dialog") + ).not.toBeInTheDocument(); + }); + + test("should fetch entity and opens dialog on row edit", async () => { + const user = userEvent.setup(); + renderWithRedux(, { + initialState: buildInitialState({ + media_file_types: [ + { id: 7, name: "Video", description: "", allowed_extensions: ["MP4"] } + ], + totalMediaFileTypes: 1 + }) + }); + + await user.click(screen.getByText("edit-row")); + + await waitFor(() => { + expect(mediaFileTypeActions.getMediaFileType).toHaveBeenCalledWith(7); + }); + }); + + test("should call deleteMediaFileType and refreshes list on row delete", async () => { + const user = userEvent.setup(); + renderWithRedux(, { + initialState: buildInitialState({ + media_file_types: [ + { id: 3, name: "Audio", description: "", allowed_extensions: [] } + ], + totalMediaFileTypes: 1 + }) + }); + + await user.click(screen.getByText("delete-row")); + + await waitFor(() => { + expect(mediaFileTypeActions.deleteMediaFileType).toHaveBeenCalledWith(3); + }); + }); + + test("should call getMediaFileTypes with search term on search", async () => { + const user = userEvent.setup(); + renderWithRedux(, { + initialState: buildInitialState() + }); + + await user.type(screen.getByTestId("search-input"), "pdf{Enter}"); + + await waitFor(() => { + expect(mediaFileTypeActions.getMediaFileTypes).toHaveBeenCalledWith( + "pdf", + DEFAULT_CURRENT_PAGE, + DEFAULT_PER_PAGE, + "id", + 1 + ); + }); + }); +}); diff --git a/src/pages/media_file_types/components/__tests__/media-file-type-dialog.test.js b/src/pages/media_file_types/components/__tests__/media-file-type-dialog.test.js new file mode 100644 index 000000000..15e60080f --- /dev/null +++ b/src/pages/media_file_types/components/__tests__/media-file-type-dialog.test.js @@ -0,0 +1,173 @@ +import React from "react"; +import { render, screen, waitFor } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import MediaFileTypeDialog from "../media-file-type-dialog"; + +jest.mock("i18n-react/dist/i18n-react", () => ({ + __esModule: true, + default: { translate: (key) => key } +})); + +jest.mock( + "../../../../components/mui/formik-inputs/mui-formik-textfield", + () => { + const React = require("react"); + return { + __esModule: true, + default: ({ name, id, formik }) => ( + + ) + }; + } +); + +jest.mock("../../../../hooks/useScrollToError", () => ({ + __esModule: true, + default: jest.fn() +})); + +const NEW_ENTITY = { id: 0, name: "", description: "", allowed_extensions: [] }; + +describe("MediaFileTypeDialog", () => { + let onClose; + let onSave; + + beforeEach(() => { + onClose = jest.fn(); + onSave = jest.fn(); + }); + + test("should show Add title for a new entity", () => { + render( + + ); + + expect(screen.getByText(/general\.add/)).toBeInTheDocument(); + }); + + test("should show Edit title for an existing entity", () => { + render( + + ); + + expect(screen.getByText(/general\.edit/)).toBeInTheDocument(); + }); + + test("should call onClose when close icon is clicked", async () => { + const user = userEvent.setup(); + render( + + ); + + await user.click(screen.getByRole("button", { name: "close" })); + + expect(onClose).toHaveBeenCalledTimes(1); + }); + + test("should call onSave with form values on valid submit", async () => { + const user = userEvent.setup(); + render( + + ); + + await user.type(screen.getByTestId("field-name"), "PDF Type"); + await user.type(screen.getByTestId("field-description"), "All PDF files"); + await user.type(screen.getByTestId("field-allowed_extensions"), "PDF"); + await user.click(screen.getByRole("button", { name: "general.save" })); + + await waitFor(() => { + expect(onSave).toHaveBeenCalledWith( + expect.objectContaining({ + name: "PDF Type", + description: "All PDF files", + allowed_extensions: "PDF" + }) + ); + }); + }); + + test("should not call onSave when name is empty", async () => { + const user = userEvent.setup(); + render( + + ); + + await user.click(screen.getByRole("button", { name: "general.save" })); + + await waitFor(() => { + expect(onSave).not.toHaveBeenCalled(); + }); + }); + + test("should prefill fields with existing entity values", () => { + render( + + ); + + expect(screen.getByTestId("field-name")).toHaveValue("Video"); + expect(screen.getByTestId("field-description")).toHaveValue("Video files"); + expect(screen.getByTestId("field-allowed_extensions")).toHaveValue( + "MP4,AVI" + ); + }); + + test("should join array allowed_extensions to comma-separated string", () => { + render( + + ); + + expect(screen.getByTestId("field-allowed_extensions")).toHaveValue( + "PDF,DOC,DOCX" + ); + }); +}); diff --git a/src/pages/media_file_types/components/media-file-type-dialog.js b/src/pages/media_file_types/components/media-file-type-dialog.js new file mode 100644 index 000000000..c795e61e7 --- /dev/null +++ b/src/pages/media_file_types/components/media-file-type-dialog.js @@ -0,0 +1,146 @@ +import React from "react"; +import T from "i18n-react/dist/i18n-react"; +import PropTypes from "prop-types"; +import { FormikProvider, useFormik } from "formik"; +import * as yup from "yup"; +import { + Dialog, + DialogActions, + DialogContent, + DialogTitle, + Button, + InputLabel, + Box, + IconButton, + Divider, + Grid2 +} from "@mui/material"; +import CloseIcon from "@mui/icons-material/Close"; +import MuiFormikTextField from "../../../components/mui/formik-inputs/mui-formik-textfield"; +import useScrollToError from "../../../hooks/useScrollToError"; +import { requiredStringValidation } from "../../../utils/yup"; + +const MediaFileTypeDialog = ({ entity: initialEntity, onClose, onSave }) => { + const formik = useFormik({ + initialValues: { + id: initialEntity?.id ?? 0, + name: initialEntity?.name ?? "", + description: initialEntity?.description ?? "", + allowed_extensions: Array.isArray(initialEntity?.allowed_extensions) + ? initialEntity.allowed_extensions.join(",") + : initialEntity?.allowed_extensions ?? "" + }, + enableReinitialize: true, + validationSchema: yup.object().shape({ + name: requiredStringValidation() + }), + onSubmit: (values) => onSave(values) + }); + + useScrollToError(formik); + + const handleClose = () => { + formik.resetForm(); + onClose(); + }; + + const title = initialEntity?.id + ? `${T.translate("general.edit")} ${T.translate( + "media_file_type.media_file_type" + )}` + : `${T.translate("general.add")} ${T.translate( + "media_file_type.media_file_type" + )}`; + + return ( + + + {title} + + + + + + + + + + + + {T.translate("media_file_type.name")} * + + + + + + {T.translate("media_file_type.description")} + + + + + + {T.translate("media_file_type.allowed_extensions_input")} + + + + + + + + + + + + + ); +}; + +MediaFileTypeDialog.propTypes = { + entity: PropTypes.object, + onClose: PropTypes.func.isRequired, + onSave: PropTypes.func.isRequired +}; + +export default MediaFileTypeDialog; diff --git a/src/pages/media_file_types/media-file-type-list-page.js b/src/pages/media_file_types/media-file-type-list-page.js index 4e4afb5a1..7c410cc14 100644 --- a/src/pages/media_file_types/media-file-type-list-page.js +++ b/src/pages/media_file_types/media-file-type-list-page.js @@ -11,177 +11,207 @@ * limitations under the License. * */ -import React from "react"; +import React, { useEffect, 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, - Table -} from "openstack-uicore-foundation/lib/components"; -import { getSummitById } from "../../actions/summit-actions"; +import { Box, Button, Grid2 } from "@mui/material"; +import AddIcon from "@mui/icons-material/Add"; +import MuiTable from "openstack-uicore-foundation/lib/components/mui/table"; +import SearchInput from "openstack-uicore-foundation/lib/components/mui/search-input"; import { getMediaFileTypes, - deleteMediaFileType + getMediaFileType, + saveMediaFileType, + deleteMediaFileType, + resetMediaFileTypeForm } from "../../actions/media-file-type-actions"; - -class MediaFileTypeListPage extends React.Component { - constructor(props) { - super(props); - - 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.handleNewMediaFileType = this.handleNewMediaFileType.bind(this); - this.handleDelete = this.handleDelete.bind(this); - - this.state = {}; - } - - componentDidMount() { - this.props.getMediaFileTypes(); - } - - handleEdit(media_file_type_id) { - const { history } = this.props; - history.push(`/app/media-file-types/${media_file_type_id}`); - } - - handlePageChange(page) { - const { term, order, orderDir, perPage } = this.props; - this.props.getMediaFileTypes(term, page, perPage, order, orderDir); - } - - handleSort(index, key, dir) { - const { term, page, perPage } = this.props; - this.props.getMediaFileTypes(term, page, perPage, key, dir); - } - - handleSearch(term) { - const { order, orderDir, page, perPage } = this.props; - this.props.getMediaFileTypes(term, page, perPage, order, orderDir); - } - - handleNewMediaFileType(ev) { - const { history } = this.props; - ev.preventDefault(); - - history.push("/app/media-file-types/new"); - } - - handleDelete(typeId) { - const { deleteMediaFileType, media_file_types } = this.props; - const media_file_type = media_file_types.find((t) => t.id === typeId); - - Swal.fire({ - title: T.translate("general.are_you_sure"), - text: `${T.translate("media_file_type.delete_warning")} ${ - media_file_type.name - }`, - type: "warning", - showCancelButton: true, - confirmButtonColor: "#DD6B55", - confirmButtonText: T.translate("general.yes_delete") - }).then((result) => { - if (result.value) { - deleteMediaFileType(accessId); - } - }); - } - - canEdit = (item) => !item.is_system_defined; - - render() { - const { media_file_types, lastPage, currentPage, term, order, orderDir } = - this.props; - - const columns = [ - { columnKey: "id", value: T.translate("general.id"), sortable: true }, - { - columnKey: "name", - value: T.translate("media_file_type.name"), - sortable: true - }, - { - columnKey: "description", - value: T.translate("media_file_type.description") - }, - { - columnKey: "allowed_extensions", - value: T.translate("media_file_type.allowed_extensions") - } - ]; - - const table_options = { - sortCol: order, - sortDir: orderDir, - actions: { - edit: { onClick: this.handleEdit }, - delete: { onClick: this.handleDelete, display: this.canEdit } - } - }; - - return ( -
-

{T.translate("media_file_type.media_file_type_list")}

-
-
- -
-
- -
-
- - {media_file_types.length === 0 && ( -
{T.translate("media_file_type.no_results")}
- )} - - {media_file_types.length > 0 && ( -
- - - - )} - +import { DEFAULT_CURRENT_PAGE } from "../../utils/constants"; +import MediaFileTypeDialog from "./components/media-file-type-dialog"; + +const MediaFileTypeListPage = ({ + media_file_types, + currentMediaFileType, + term, + currentPage, + perPage, + order, + orderDir, + totalMediaFileTypes, + getMediaFileTypes, + getMediaFileType, + saveMediaFileType, + deleteMediaFileType, + resetMediaFileTypeForm +}) => { + const [open, setOpen] = useState(false); + + useEffect(() => { + getMediaFileTypes(); + }, []); + + const handlePageChange = (page) => { + getMediaFileTypes(term, page, perPage, order, orderDir); + }; + + const handlePerPageChange = (newPerPage) => { + getMediaFileTypes(term, DEFAULT_CURRENT_PAGE, newPerPage, order, orderDir); + }; + + const handleSort = (key, dir) => { + getMediaFileTypes(term, currentPage, perPage, key, dir); + }; + + const handleSearch = (searchTerm) => { + getMediaFileTypes( + searchTerm, + DEFAULT_CURRENT_PAGE, + perPage, + order, + orderDir ); - } -} - -const mapStateToProps = ({ mediaFileTypeListState }) => ({ - ...mediaFileTypeListState + }; + + const handleRowEdit = (row) => { + getMediaFileType(row.id).then(() => setOpen(true)); + }; + + const handleNew = () => { + resetMediaFileTypeForm(); + setOpen(true); + }; + + const handleClose = () => { + resetMediaFileTypeForm(); + setOpen(false); + }; + + const handleSave = (entity) => + saveMediaFileType(entity) + .then(() => + getMediaFileTypes(term, DEFAULT_CURRENT_PAGE, perPage, order, orderDir) + ) + .then(() => setOpen(false)); + + const handleDelete = (mediaFileTypeId) => { + deleteMediaFileType(mediaFileTypeId).then(() => + getMediaFileTypes(term, DEFAULT_CURRENT_PAGE, perPage, order, orderDir) + ); + }; + + const columns = [ + { + columnKey: "id", + header: T.translate("media_file_type.id"), + sortable: true + }, + { + columnKey: "name", + header: T.translate("media_file_type.name"), + sortable: true + }, + { + columnKey: "description", + header: T.translate("media_file_type.description") + }, + { + columnKey: "allowed_extensions", + header: T.translate("media_file_type.allowed_extensions"), + render: (row) => row.allowed_extensions.join(", ") + } + ]; + + const tableOptions = { sortCol: order, sortDir: orderDir }; + + return ( +
+

{T.translate("media_file_type.media_file_type_list")}

+ + + + {totalMediaFileTypes}{" "} + {T.translate("media_file_type.media_file_types")} + + + + + + + + + + + {media_file_types.length > 0 && ( + + T.translate("media_file_type.delete_warning", { name }) + } + /> + )} + + {media_file_types.length === 0 && ( +
{T.translate("media_file_type.no_results")}
+ )} + + {open && ( + + )} +
+ ); +}; + +const mapStateToProps = ({ mediaFileTypeListState, mediaFileTypeState }) => ({ + ...mediaFileTypeListState, + currentMediaFileType: mediaFileTypeState.entity }); export default connect(mapStateToProps, { - getSummitById, getMediaFileTypes, - deleteMediaFileType + getMediaFileType, + saveMediaFileType, + deleteMediaFileType, + resetMediaFileTypeForm })(MediaFileTypeListPage); diff --git a/src/reducers/media_file_types/media-file-type-list-reducer.js b/src/reducers/media_file_types/media-file-type-list-reducer.js index b72693552..01a73c5a8 100644 --- a/src/reducers/media_file_types/media-file-type-list-reducer.js +++ b/src/reducers/media_file_types/media-file-type-list-reducer.js @@ -9,7 +9,9 @@ * 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_MEDIA_FILE_TYPES, @@ -17,16 +19,15 @@ import { MEDIA_FILE_TYPE_DELETED } from "../../actions/media-file-type-actions"; -import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; - const DEFAULT_STATE = { media_file_types: [], - term: null, + term: "", order: "id", orderDir: 1, currentPage: 1, lastPage: 1, - perPage: 10 + perPage: 10, + totalMediaFileTypes: 0 }; const mediaFileTypeListReducer = (state = DEFAULT_STATE, action) => { @@ -36,30 +37,29 @@ const mediaFileTypeListReducer = (state = DEFAULT_STATE, action) => { return DEFAULT_STATE; } case REQUEST_MEDIA_FILE_TYPES: { - let { order, orderDir, term } = payload; + const { order, orderDir, term, perPage } = payload; - return { ...state, order, orderDir, term }; + return { ...state, order, orderDir, term, perPage }; } case RECEIVE_MEDIA_FILE_TYPES: { - let { total, last_page, current_page } = payload.response; - let media_file_types = payload.response.data.map((mft) => { - return { - id: mft.id, - name: mft.name, - description: mft.description, - allowed_extensions: mft.allowed_extensions - }; - }); + const { total, last_page, current_page } = payload.response; + const media_file_types = payload.response.data.map((mft) => ({ + id: mft.id, + name: mft.name, + description: mft.description, + allowed_extensions: mft.allowed_extensions + })); return { ...state, - media_file_types: media_file_types, + media_file_types, currentPage: current_page, - lastPage: last_page + lastPage: last_page, + totalMediaFileTypes: total }; } case MEDIA_FILE_TYPE_DELETED: { - let { mediaFileTypeId } = payload; + const { mediaFileTypeId } = payload; return { ...state, media_file_types: state.media_file_types.filter(