diff --git a/src/actions/event-category-actions.js b/src/actions/event-category-actions.js index 95bfcaf46..41db09473 100644 --- a/src/actions/event-category-actions.js +++ b/src/actions/event-category-actions.js @@ -489,7 +489,7 @@ export const saveEventCategoryGroup = const params = { access_token: accessToken }; if (entity.id) { - putRequest( + return putRequest( createAction(UPDATE_EVENT_CATEGORY_GROUP), createAction(EVENT_CATEGORY_GROUP_UPDATED), `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/track-groups/${entity.id}`, @@ -503,30 +503,22 @@ export const saveEventCategoryGroup = ) ); }); - } else { - const successMessage = { - title: T.translate("general.done"), - html: T.translate("edit_event_category_group.group_created"), - type: "success" - }; - - postRequest( + } + return postRequest( createAction(UPDATE_EVENT_CATEGORY_GROUP), createAction(EVENT_CATEGORY_GROUP_ADDED), `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/track-groups`, normalizedEntity, authErrorHandler, entity - )(params)(dispatch).then((payload) => { + )(params)(dispatch).then(() => { dispatch( - showMessage(successMessage, () => { - history.replace( - `/app/summits/${currentSummit.id}/event-category-groups/${payload.response.id}` - ); - }) + showSuccessMessage( + T.translate("edit_event_category_group.group_created") + ) ); }); - } + }; export const deleteEventCategoryGroup = diff --git a/src/components/forms/event-category-group-form.js b/src/components/forms/event-category-group-form.js index 3c0f9abfd..01b369666 100644 --- a/src/components/forms/event-category-group-form.js +++ b/src/components/forms/event-category-group-form.js @@ -1,4 +1,4 @@ -/* * +/** * Copyright 2017 OpenStack Foundation * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -11,360 +11,520 @@ * limitations under the License. * */ -import React from "react"; +import React, { useState } from "react"; import T from "i18n-react/dist/i18n-react"; -import "awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css"; +import PropTypes from "prop-types"; +import { FormikProvider, useFormik } from "formik"; +import * as yup from "yup"; +import Button from "@mui/material/Button"; +import Box from "@mui/material/Box"; +import Divider from "@mui/material/Divider"; +import Grid2 from "@mui/material/Grid2"; +import Typography from "@mui/material/Typography"; +import { DateTimePicker } from "@mui/x-date-pickers/DateTimePicker"; +import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; +import { AdapterMoment } from "@mui/x-date-pickers/AdapterMoment"; import { epochToMomentTimeZone } from "openstack-uicore-foundation/lib/utils/methods"; import { queryTracks, queryGroups } from "openstack-uicore-foundation/lib/utils/query-actions"; -import { - Input, - SimpleLinkList, - Dropdown, - DateTimePicker -} from "openstack-uicore-foundation/lib/components"; +import MuiTable from "openstack-uicore-foundation/lib/components/mui/table"; +import MuiFormikTextField from "openstack-uicore-foundation/lib/components/mui/formik-inputs/textfield"; +import MuiFormikSelectV2 from "openstack-uicore-foundation/lib/components/mui/formik-inputs/select-v2"; import TextEditorV3 from "openstack-uicore-foundation/lib/components/inputs/editor-input-v3"; -import Swal from "sweetalert2"; -import { - isEmpty, - scrollToError, - shallowEqual, - hasErrors -} from "../../utils/methods"; - -class EventCategoryGroupForm extends React.Component { - constructor(props) { - super(props); +import MuiFormikAsyncAutocomplete from "openstack-uicore-foundation/lib/components/mui/formik-inputs/async-select"; +import MuiFormikColorField from "../mui/formik-inputs/mui-formik-color-field"; +import useScrollToError from "../../hooks/useScrollToError"; +import { requiredStringValidation } from "../../utils/yup"; - this.state = { - entity: { ...props.entity }, - errors: props.errors - }; +const DEFAULT_PER_PAGE = 10; - this.handleChange = this.handleChange.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - this.handleTrackLink = this.handleTrackLink.bind(this); - this.handleTrackUnLink = this.handleTrackUnLink.bind(this); - this.handleAllowedGroupLink = this.handleAllowedGroupLink.bind(this); - this.handleAllowedGroupUnLink = this.handleAllowedGroupUnLink.bind(this); - } +const EventCategoryGroupForm = ({ + entity: initialEntity, + allClasses, + currentSummit, + onSubmit, + onTrackLink, + onTrackUnLink, + onAllowedGroupLink, + onAllowedGroupUnLink +}) => { + const [isSaving, setIsSaving] = useState(false); + const [trackState, setTrackState] = useState({ + page: 1, + perPage: DEFAULT_PER_PAGE + }); + const [groupState, setGroupState] = useState({ + page: 1, + perPage: DEFAULT_PER_PAGE + }); - componentDidUpdate(prevProps) { - const state = {}; - scrollToError(this.props.errors); + const trackSearchFormik = useFormik({ + initialValues: { track: null }, + onSubmit: () => {} + }); + const groupSearchFormik = useFormik({ + initialValues: { group: null }, + onSubmit: () => {} + }); - if (!shallowEqual(prevProps.entity, this.props.entity)) { - state.entity = { ...this.props.entity }; - state.errors = {}; - } + const isNew = !initialEntity?.id; - if (!shallowEqual(prevProps.errors, this.props.errors)) { - state.errors = { ...this.props.errors }; - } + const excludedTrackIds = initialEntity?.tracks?.map((t) => t.id) ?? []; + const queryTrackOptions = (input, callback) => + queryTracks(currentSummit.id, input, callback, excludedTrackIds); - if (!isEmpty(state)) { - this.setState({ ...this.state, ...state }); - } - } + const toEpoch = (momentValue) => { + if (!momentValue || !momentValue.isValid()) return 0; + return momentValue.unix(); + }; - handleChange(ev) { - const entity = { ...this.state.entity }; - const errors = { ...this.state.errors }; - let { value, id } = ev.target; + const fromEpoch = (epoch) => { + if (!epoch) return null; + return epochToMomentTimeZone(epoch, currentSummit.time_zone_id); + }; - if (ev.target.type === "datetime") { - value = value.unix(); + const formik = useFormik({ + initialValues: { + id: initialEntity?.id ?? 0, + class_name: initialEntity?.class_name ?? null, + name: initialEntity?.name ?? "", + color: initialEntity?.color ?? "", + begin_attendee_voting_period_date: + initialEntity?.begin_attendee_voting_period_date ?? 0, + end_attendee_voting_period_date: + initialEntity?.end_attendee_voting_period_date ?? 0, + max_attendee_votes: initialEntity?.max_attendee_votes ?? 0, + submission_begin_date: initialEntity?.submission_begin_date ?? 0, + submission_end_date: initialEntity?.submission_end_date ?? 0, + max_submission_allowed_per_user: + initialEntity?.max_submission_allowed_per_user ?? 0, + description: initialEntity?.description ?? "" + }, + enableReinitialize: true, + validationSchema: yup.object().shape({ + name: requiredStringValidation(), + class_name: yup + .string() + .nullable() + .required(T.translate("validation.required")) + }), + onSubmit: (values) => { + if (isSaving) return; + setIsSaving(true); + Promise.resolve(onSubmit(values)).finally(() => { + setIsSaving(false); + }); } + }); - errors[id] = ""; - entity[id] = value; - this.setState({ entity, errors }); - } + useScrollToError(formik, true); - handleSubmit(ev) { - ev.preventDefault(); - this.props.onSubmit(this.state.entity); - } + const selectedClass = allClasses.find( + (c) => c.class_name === formik.values.class_name + ); + const showSubmissionFields = selectedClass?.submission_begin_date ?? false; + const showAllowedGroups = selectedClass?.allowed_groups ?? false; - handleTrackLink(value) { - const { entity } = this.state; - this.props.onTrackLink(entity.id, value); - } + const classNameDdl = allClasses.map((c) => ({ + label: c.class_name, + value: c.class_name + })); - handleTrackUnLink(valueId) { - const { entity } = this.state; - const { onTrackUnLink } = this.props; + const tracksColumns = [ + { columnKey: "name", header: T.translate("edit_event_category.name") }, + { columnKey: "code", header: T.translate("edit_event_category.code") } + ]; - Swal.fire({ - title: T.translate("general.are_you_sure"), - text: T.translate("edit_event_category_group.unlink_track_warning"), - type: "warning", - showCancelButton: true, - confirmButtonText: T.translate("general.yes") - }).then((result) => { - if (result.value) { - onTrackUnLink(entity.id, valueId); - } - }); - } - - handleAllowedGroupLink(value) { - const { entity } = this.state; - this.props.onAllowedGroupLink(entity.id, value); - } - - handleAllowedGroupUnLink(valueId) { - const { entity } = this.state; - this.props.onAllowedGroupUnLink(entity.id, valueId); - } - - shouldShowField(flag) { - const { entity } = this.state; - if (!entity.class_name) return false; - const class_name = this.props.allClasses.find( - (c) => c.class_name === entity.class_name - ); - - return class_name[flag]; - } + const allowedGroupsColumns = [ + { columnKey: "title", header: T.translate("edit_event_category.name") }, + { + columnKey: "description", + header: T.translate("edit_event_category.description") + } + ]; - render() { - const { entity, errors } = this.state; - const { currentSummit, allClasses } = this.props; - const selectedTrackIds = entity?.tracks?.map((t) => t.id) || []; + const handleAddTrack = () => { + const track = trackSearchFormik.values.track?.raw; + if (!track) return; + onTrackLink(initialEntity.id, track); + trackSearchFormik.setFieldValue("track", null); + }; - const tracksColumns = [ - { columnKey: "name", value: T.translate("edit_event_category.name") }, - { columnKey: "code", value: T.translate("edit_event_category.code") } - ]; + const handleTrackDelete = (trackId) => { + onTrackUnLink(initialEntity.id, trackId); + }; - const tracksOptions = { - title: T.translate("edit_event_category_group.tracks"), - valueKey: "name", - labelKey: "name", - actions: { - search: (input, callback) => { - queryTracks(currentSummit.id, input, callback, selectedTrackIds); - }, - delete: { onClick: this.handleTrackUnLink }, - add: { onClick: this.handleTrackLink } - } - }; + const handleAddGroup = () => { + const group = groupSearchFormik.values.group?.raw; + if (!group) return; + onAllowedGroupLink(initialEntity.id, group); + groupSearchFormik.setFieldValue("group", null); + }; - const allowedGroupsColumns = [ - { columnKey: "title", value: T.translate("edit_event_category.name") }, - { - columnKey: "description", - value: T.translate("edit_event_category.description") - } - ]; + const handleAllowedGroupDelete = (groupId) => { + onAllowedGroupUnLink(initialEntity.id, groupId); + }; - const allowedGroupsOptions = { - title: T.translate("edit_event_category_group.allowed_groups"), - valueKey: "id", - labelKey: "title", - actions: { - search: queryGroups, - delete: { onClick: this.handleAllowedGroupUnLink }, - add: { onClick: this.handleAllowedGroupLink } - } - }; + const tracks = initialEntity?.tracks ?? []; + const paginatedTracks = tracks.slice( + (trackState.page - 1) * trackState.perPage, + trackState.page * trackState.perPage + ); - const class_name_ddl = allClasses.map((i) => ({ - label: i.class_name, - value: i.class_name - })); + const allowedGroups = initialEntity?.allowed_groups ?? []; + const paginatedGroups = allowedGroups.slice( + (groupState.page - 1) * groupState.perPage, + groupState.page * groupState.perPage + ); - return ( -
- -
-
- - -
-
- - -
-
- - -
-
-
-
- - -
-
- - -
-
- - -
-
- {this.shouldShowField("submission_begin_date") && ( -
-
- - + + + + + + {T.translate("edit_event_category_group.class")} * + + -
-
- + + + + {T.translate("edit_event_category_group.name")} * + + + + + + {T.translate("edit_event_category_group.color")} * + + + + + + + {T.translate( + "edit_event_category_group.begin_attendee_voting_period_date" + )} + + formik.setFieldValue( + "begin_attendee_voting_period_date", + toEpoch(val) + ) + } + slotProps={{ + textField: { + fullWidth: true, + size: "small" + } + }} /> -
-
- - + + formik.setFieldValue( + "end_attendee_voting_period_date", + toEpoch(val) + ) + } + slotProps={{ + textField: { + fullWidth: true, + size: "small" + } + }} + /> + + + + {T.translate("edit_event_category_group.max_attendee_votes")} + + -
-
- )} -
-
- - -
-
+ + + {showSubmissionFields && ( + <> + + + {T.translate( + "edit_event_category_group.submission_begin_date" + )} + + + formik.setFieldValue( + "submission_begin_date", + toEpoch(val) + ) + } + slotProps={{ + textField: { + fullWidth: true, + size: "small" + } + }} + /> + + + + {T.translate( + "edit_event_category_group.submission_end_date" + )} + + + formik.setFieldValue("submission_end_date", toEpoch(val)) + } + slotProps={{ + textField: { + fullWidth: true, + size: "small" + } + }} + /> + + + + {T.translate( + "edit_event_category_group.max_submission_allowed_per_user" + )} + + + + + )} + + + + {T.translate("edit_event_category_group.description")} + + + + formik.setFieldValue("description", ev.target.value) + } + license={process.env.JODIT_LICENSE_KEY} + /> + + + + {!isNew && ( + <> + + + + {T.translate("edit_event_category_group.tracks")} + + + + + ({ + value: track.id, + label: track.name, + raw: track + })} + /> + + + + + + + + setTrackState((prev) => ({ ...prev, page })) + } + onPerPageChange={(n) => { + setTrackState((prev) => ({ + ...prev, + perPage: parseInt(n, 10), + page: 1 + })); + }} + onDelete={handleTrackDelete} + getName={(row) => row.name} + deleteDialogBody={T.translate( + "edit_event_category_group.unlink_track_warning" + )} + /> + + + {showAllowedGroups && ( + + + {T.translate("edit_event_category_group.allowed_groups")} + + + + + ({ + value: group.id, + label: group.title, + raw: group + })} + /> + + + + + + + + setGroupState((prev) => ({ ...prev, page })) + } + onPerPageChange={(n) => { + setGroupState((prev) => ({ + ...prev, + perPage: parseInt(n, 10), + page: 1 + })); + }} + onDelete={handleAllowedGroupDelete} + getName={(row) => row.title} + /> + + )} + + )} + + + + + + + + + ); +}; -
- {entity.id !== 0 && ( - - )} -
-
- {entity.id !== 0 && this.shouldShowField("allowed_groups") && ( - - )} +EventCategoryGroupForm.propTypes = { + entity: PropTypes.shape({}), + allClasses: PropTypes.arrayOf(PropTypes.shape({})).isRequired, + currentSummit: PropTypes.shape({}).isRequired, + onSubmit: PropTypes.func.isRequired, + onTrackLink: PropTypes.func, + onTrackUnLink: PropTypes.func, + onAllowedGroupLink: PropTypes.func, + onAllowedGroupUnLink: PropTypes.func +}; -
-
- -
-
- - ); - } -} +EventCategoryGroupForm.defaultProps = { + entity: null, + onTrackLink: () => {}, + onTrackUnLink: () => {}, + onAllowedGroupLink: () => {}, + onAllowedGroupUnLink: () => {} +}; export default EventCategoryGroupForm; diff --git a/src/i18n/en.json b/src/i18n/en.json index 0f46a5816..66acc075f 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -1410,7 +1410,9 @@ "group_created": "Activity Category Group created successfully.", "unlink_track_warning": "if you remove a category from the category group, any activities linked to that category will automatically be removed from the selection plan. Do you want to continue?", "placeholders": { - "select_class": "Select Class" + "select_class": "Select Class", + "search_categories": "Search and add categories", + "search_groups": "Search and add allowed groups" } }, "location_list": { diff --git a/src/layouts/event-category-group-layout.js b/src/layouts/event-category-group-layout.js index 496c0262b..8aa12a94a 100644 --- a/src/layouts/event-category-group-layout.js +++ b/src/layouts/event-category-group-layout.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 { Switch, Route, withRouter } from "react-router-dom"; @@ -21,44 +21,36 @@ import EditEventCategoryGroupPage from "../pages/events/edit-event-category-grou import EventCategoryGroupListPage from "../pages/events/event-category-group-list-page"; import NoMatchPage from "../pages/no-match-page"; -class EventCategoryGroupLayout extends React.Component { - render() { - const { match } = this.props; - return ( -
- - - - - - - - -
- ); - } -} +const EventCategoryGroupLayout = ({ match }) => ( +
+ + + + + + + +
+); export default Restrict(withRouter(EventCategoryGroupLayout), "events"); diff --git a/src/pages/events/edit-event-category-group-page.js b/src/pages/events/edit-event-category-group-page.js index 8da448c84..8e264c6cb 100644 --- a/src/pages/events/edit-event-category-group-page.js +++ b/src/pages/events/edit-event-category-group-page.js @@ -11,7 +11,7 @@ * limitations under the License. * */ -import React from "react"; +import React, { useEffect } from "react"; import { connect } from "react-redux"; import T from "i18n-react/dist/i18n-react"; import { Breadcrumb } from "react-breadcrumbs"; @@ -26,74 +26,70 @@ import { removeAllowedGroupFromGroup, getEventCategoryGroupMeta } from "../../actions/event-category-actions"; -import AddNewButton from "../../components/buttons/add-new-button"; -// import '../../styles/edit-summit-attendee-page.less'; - -class EditEventCategoryGroupPage extends React.Component { - componentDidMount() { - const { allClasses } = this.props; - const groupId = this.props.match.params.group_id; +const EditEventCategoryGroupPage = ({ + currentSummit, + entity, + allClasses, + match, + history, + getEventCategoryGroup, + resetEventCategoryGroupForm, + saveEventCategoryGroup, + addCategoryToGroup, + removeCategoryFromGroup, + addAllowedGroupToGroup, + removeAllowedGroupFromGroup, + getEventCategoryGroupMeta +}) => { + const groupId = match.params.group_id; + useEffect(() => { if (!groupId) { - this.props.resetEventCategoryGroupForm(); + resetEventCategoryGroupForm(); } else { - this.props.getEventCategoryGroup(groupId); + getEventCategoryGroup(groupId); } + }, [groupId]); + useEffect(() => { if (allClasses.length === 0) { - this.props.getEventCategoryGroupMeta(); + getEventCategoryGroupMeta(); } - } + }, [allClasses.length]); - componentDidUpdate(prevProps, prevState, snapshot) { - const oldId = prevProps.match.params.group_id; - const newId = this.props.match.params.group_id; - - if (oldId !== newId) { - if (!newId) { - this.props.resetEventCategoryGroupForm(); - } else { - this.props.getEventCategoryGroup(newId); - } - } - } + const handleSubmit = (values) => + saveEventCategoryGroup(values).then(() => { + history.push(`/app/summits/${currentSummit.id}/event-category-groups`); + }); - render() { - const { currentSummit, entity, allClasses, errors, match } = this.props; - const title = entity.id - ? T.translate("general.edit") - : T.translate("general.add"); - const breadcrumb = entity.id ? entity.name : T.translate("general.new"); + const title = entity.id + ? T.translate("general.edit") + : T.translate("general.add"); + const breadcrumb = entity.id ? entity.name : T.translate("general.new"); - if (!allClasses.length) return
; + if (!allClasses.length || !currentSummit) return
; - return ( -
- -

- {title}{" "} - {T.translate("edit_event_category_group.event_category_group")} - -

-
- {currentSummit && ( - - )} -
- ); - } -} + return ( +
+ +

+ {title} {T.translate("edit_event_category_group.event_category_group")} +

+
+ +
+ ); +}; const mapStateToProps = ({ currentSummitState, diff --git a/src/pages/events/event-category-group-list-page.js b/src/pages/events/event-category-group-list-page.js index 39b8d7cf1..ce1cdcad5 100644 --- a/src/pages/events/event-category-group-list-page.js +++ b/src/pages/events/event-category-group-list-page.js @@ -35,9 +35,9 @@ const EventCategoryGroupListPage = ({ order, orderDir, totalEventCategoryGroups, + history, getEventCategoryGroups, - deleteEventCategoryGroup, - history + deleteEventCategoryGroup }) => { useEffect(() => { if (currentSummit?.id) { @@ -45,16 +45,16 @@ const EventCategoryGroupListPage = ({ } }, [currentSummit?.id]); + const handleNew = () => { + history.push(`/app/summits/${currentSummit.id}/event-category-groups/new`); + }; + const handleEdit = (row) => { history.push( `/app/summits/${currentSummit.id}/event-category-groups/${row.id}` ); }; - const handleNew = () => { - history.push(`/app/summits/${currentSummit.id}/event-category-groups/new`); - }; - const handleDelete = (groupId) => { deleteEventCategoryGroup(groupId).then(() => getEventCategoryGroups( @@ -126,7 +126,7 @@ const EventCategoryGroupListPage = ({ sx={{ width: 24, height: 24, - backgroundColor: row.color, + backgroundColor: `#${row.color}`, borderRadius: 1 }} /> @@ -193,6 +193,7 @@ const EventCategoryGroupListPage = ({ onSort={handleSort} onEdit={handleEdit} onDelete={handleDelete} + getName={(row) => row.name} deleteDialogBody={(name) => `${T.translate("event_category_group_list.delete_warning")} ${name}` } diff --git a/src/reducers/events/event-category-group-reducer.js b/src/reducers/events/event-category-group-reducer.js index 3db8ccc90..b99e1840a 100644 --- a/src/reducers/events/event-category-group-reducer.js +++ b/src/reducers/events/event-category-group-reducer.js @@ -9,8 +9,11 @@ * 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 { VALIDATE } from "openstack-uicore-foundation/lib/utils/actions"; +import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; import { RECEIVE_EVENT_CATEGORY_GROUP, RESET_EVENT_CATEGORY_GROUP_FORM, @@ -22,9 +25,6 @@ import { GROUP_ADDED_TO_GROUP, GROUP_REMOVED_FROM_GROUP } from "../../actions/event-category-actions"; - -import { VALIDATE } from "openstack-uicore-foundation/lib/utils/actions"; -import { LOGOUT_USER } from "openstack-uicore-foundation/lib/security/actions"; import { SET_CURRENT_SUMMIT } from "../../actions/summit-actions"; export const DEFAULT_ENTITY = { @@ -49,99 +49,71 @@ const DEFAULT_STATE = { errors: {} }; +// eslint-disable-next-line default-param-last const eventCategoryGroupReducer = (state = DEFAULT_STATE, action) => { const { type, payload } = action; switch (type) { case LOGOUT_USER: - { - // we need this in case the token expired while editing the form - if (payload.hasOwnProperty("persistStore")) { - return state; - } else { - return { ...state, entity: { ...DEFAULT_ENTITY }, errors: {} }; - } + if (Object.hasOwn(payload, "persistStore")) { + return state; } - break; + return { ...state, entity: { ...DEFAULT_ENTITY }, errors: {} }; case SET_CURRENT_SUMMIT: case RESET_EVENT_CATEGORY_GROUP_FORM: - { - return { ...state, entity: { ...DEFAULT_ENTITY }, errors: {} }; - } - break; - case RECEIVE_EVENT_CATEGORY_GROUP_META: - { - let allClasses = [...payload.response]; - - return { ...state, allClasses: allClasses }; - } - break; + return { ...state, entity: { ...DEFAULT_ENTITY }, errors: {} }; + case RECEIVE_EVENT_CATEGORY_GROUP_META: { + const allClasses = [...payload.response]; + return { ...state, allClasses }; + } case UPDATE_EVENT_CATEGORY_GROUP: - { - return { ...state, entity: { ...payload }, errors: {} }; - } - break; + return { ...state, entity: { ...state.entity, ...payload }, errors: {} }; case EVENT_CATEGORY_GROUP_ADDED: - case RECEIVE_EVENT_CATEGORY_GROUP: - { - let entity = { ...payload.response }; + case RECEIVE_EVENT_CATEGORY_GROUP: { + const entity = { ...payload.response }; - for (var key in entity) { - if (entity.hasOwnProperty(key)) { - entity[key] = entity[key] == null ? "" : entity[key]; - } - } - - return { ...state, entity: { ...DEFAULT_ENTITY, ...entity } }; - } - break; - case CATEGORY_ADDED_TO_GROUP: - { - let category = { ...payload.category }; - return { - ...state, - entity: { - ...state.entity, - tracks: [...state.entity.tracks, category] - } - }; - } - break; - case CATEGORY_REMOVED_FROM_GROUP: - { - let { categoryId } = payload; - let tracks = state.entity.tracks.filter((t) => t.id !== categoryId); - return { ...state, entity: { ...state.entity, tracks: tracks } }; - } - break; - case GROUP_ADDED_TO_GROUP: - { - let allowedGroup = { ...payload.allowedGroup }; - return { - ...state, - entity: { - ...state.entity, - allowed_groups: [...state.entity.allowed_groups, allowedGroup] - } - }; + for (const [key, value] of Object.entries(entity)) { + entity[key] = value == null ? "" : value; } - break; - case GROUP_REMOVED_FROM_GROUP: - { - let { allowedGroupId } = payload; - let allowed_groups = state.entity.allowed_groups.filter( - (g) => g.id !== allowedGroupId - ); - return { - ...state, - entity: { ...state.entity, allowed_groups: allowed_groups } - }; - } - break; + + return { ...state, entity: { ...DEFAULT_ENTITY, ...entity } }; + } + case CATEGORY_ADDED_TO_GROUP: { + const category = { ...payload.category }; + return { + ...state, + entity: { + ...state.entity, + tracks: [...state.entity.tracks, category] + } + }; + } + case CATEGORY_REMOVED_FROM_GROUP: { + const { categoryId } = payload; + const tracks = state.entity.tracks.filter((t) => t.id !== categoryId); + return { ...state, entity: { ...state.entity, tracks } }; + } + case GROUP_ADDED_TO_GROUP: { + const allowedGroup = { ...payload.allowedGroup }; + return { + ...state, + entity: { + ...state.entity, + allowed_groups: [...state.entity.allowed_groups, allowedGroup] + } + }; + } + case GROUP_REMOVED_FROM_GROUP: { + const { allowedGroupId } = payload; + const allowedGroups = state.entity.allowed_groups.filter( + (g) => g.id !== allowedGroupId + ); + return { + ...state, + entity: { ...state.entity, allowed_groups: allowedGroups } + }; + } case VALIDATE: - { - return { ...state, errors: payload.errors }; - } - break; + return { ...state, errors: payload.errors }; default: return state; }