diff --git a/src/actions/event-type-actions.js b/src/actions/event-type-actions.js
index 502194260..2d72c551a 100644
--- a/src/actions/event-type-actions.js
+++ b/src/actions/event-type-actions.js
@@ -24,7 +24,6 @@ import {
authErrorHandler,
escapeFilterValue
} from "openstack-uicore-foundation/lib/utils/actions";
-import history from "../history";
import { getAccessTokenSafely } from "../utils/methods";
import { DEFAULT_PER_PAGE, DEFAULT_CURRENT_PAGE } from "../utils/constants";
@@ -124,7 +123,7 @@ export const saveEventType = (entity) => async (dispatch, getState) => {
const params = { access_token: accessToken };
if (entity.id) {
- putRequest(
+ return putRequest(
createAction(UPDATE_EVENT_TYPE),
createAction(EVENT_TYPE_UPDATED),
`${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/event-types/${entity.id}`,
@@ -135,31 +134,27 @@ export const saveEventType = (entity) => async (dispatch, getState) => {
dispatch(
showSuccessMessage(T.translate("edit_event_type.event_type_saved"))
);
+ return dispatch(getEventTypes());
});
- } else {
+ }
const success_message = {
title: T.translate("general.done"),
html: T.translate("edit_event_type.event_type_created"),
type: "success"
};
- postRequest(
+ return postRequest(
createAction(UPDATE_EVENT_TYPE),
createAction(EVENT_TYPE_ADDED),
`${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/event-types`,
normalizedEntity,
authErrorHandler,
entity
- )(params)(dispatch).then((payload) => {
- dispatch(
- showMessage(success_message, () => {
- history.push(
- `/app/summits/${currentSummit.id}/event-types/${payload.response.id}`
- );
- })
- );
+ )(params)(dispatch).then(() => {
+ dispatch(showMessage(success_message, () => {}));
+ return dispatch(getEventTypes());
});
- }
+
};
export const deleteEventType = (eventTypeId) => async (dispatch, getState) => {
diff --git a/src/components/forms/event-type-form.js b/src/components/forms/event-type-form.js
index dea75dc08..dca560548 100644
--- a/src/components/forms/event-type-form.js
+++ b/src/components/forms/event-type-form.js
@@ -120,7 +120,7 @@ class EventTypeForm extends React.Component {
render() {
const { entity, errors, showSection } = this.state;
- const { getMediaUploads, currentSummit } = this.props;
+ const { getMediaUploads, currentSummit, isSaving } = this.props;
const event_types_ddl = [
{ label: "Presentation", value: "PRESENTATION_TYPE" },
{ label: "Event", value: "EVENT_TYPE" }
@@ -618,6 +618,7 @@ class EventTypeForm extends React.Component {
onClick={this.handleSubmit}
className="btn btn-primary pull-right"
value={T.translate("general.save")}
+ disabled={isSaving}
/>
diff --git a/src/layouts/event-type-layout.js b/src/layouts/event-type-layout.js
index 579798981..b4ec1d484 100644
--- a/src/layouts/event-type-layout.js
+++ b/src/layouts/event-type-layout.js
@@ -9,49 +9,36 @@
* 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 PropTypes from "prop-types";
import { Switch, Route, withRouter } from "react-router-dom";
import T from "i18n-react/dist/i18n-react";
import { Breadcrumb } from "react-breadcrumbs";
import Restrict from "../routes/restrict";
-import EditEventTypePage from "../pages/events/edit-event-type-page";
import EventTypeListPage from "../pages/events/event-type-list-page";
import NoMatchPage from "../pages/no-match-page";
-class EventTypeLayout extends React.Component {
- render() {
- const { match } = this.props;
- return (
-
-
+const EventTypeLayout = ({ match }) => (
+
+
-
-
-
-
-
-
-
- );
- }
-}
+
+
+
+
+
+);
+
+EventTypeLayout.propTypes = {
+ match: PropTypes.shape({ url: PropTypes.string }).isRequired
+};
export default Restrict(withRouter(EventTypeLayout), "events");
diff --git a/src/pages/events/components/event-type-dialog.js b/src/pages/events/components/event-type-dialog.js
new file mode 100644
index 000000000..31f9e2b3f
--- /dev/null
+++ b/src/pages/events/components/event-type-dialog.js
@@ -0,0 +1,135 @@
+/**
+ * Copyright 2026 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 PropTypes from "prop-types";
+import T from "i18n-react/dist/i18n-react";
+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 IconButton from "@mui/material/IconButton";
+import CloseIcon from "@mui/icons-material/Close";
+import EventTypeForm from "../../../components/forms/event-type-form";
+import { saveEventType as saveEventTypeAction } from "../../../actions/event-type-actions";
+import {
+ linkToPresentationType as linkToPresentationTypeAction,
+ unlinkFromPresentationType as unlinkFromPresentationTypeAction,
+ queryMediaUploads
+} from "../../../actions/media-upload-actions";
+
+const EventTypeDialog = ({
+ currentSummit,
+ entity,
+ errors,
+ loading,
+ onClose,
+ saveEventType,
+ linkToPresentationType,
+ unlinkFromPresentationType
+}) => {
+ const isSaving = Boolean(loading);
+
+ const handleClose = () => {
+ if (isSaving) return;
+ onClose();
+ };
+
+ const handleOnSave = (eventTypeEntity) => {
+ if (isSaving) return;
+ saveEventType(eventTypeEntity)
+ .then(() => onClose())
+ .catch(() => {
+ // keep dialog open on save error to preserve user input
+ });
+ };
+
+ const getMediaUploads = (input, callback) => {
+ if (!input) return Promise.resolve({ options: [] });
+ return queryMediaUploads(currentSummit.id, input, callback);
+ };
+
+ const isEdit = Boolean(entity.id);
+ const title = `${T.translate(
+ isEdit ? "general.edit" : "general.add"
+ )} ${T.translate("edit_event_type.event_type")}`;
+
+ return (
+
+ );
+};
+
+EventTypeDialog.propTypes = {
+ currentSummit: PropTypes.shape({ id: PropTypes.number }).isRequired,
+ entity: PropTypes.shape({ id: PropTypes.number }).isRequired,
+ errors: PropTypes.shape({}),
+ loading: PropTypes.number,
+ onClose: PropTypes.func.isRequired,
+ saveEventType: PropTypes.func.isRequired,
+ linkToPresentationType: PropTypes.func.isRequired,
+ unlinkFromPresentationType: PropTypes.func.isRequired
+};
+
+EventTypeDialog.defaultProps = {
+ errors: {},
+ loading: 0
+};
+
+const mapStateToProps = ({
+ baseState,
+ currentSummitState,
+ currentEventTypeState
+}) => ({
+ currentSummit: currentSummitState.currentSummit,
+ loading: baseState.loading,
+ ...currentEventTypeState
+});
+
+export default connect(mapStateToProps, {
+ saveEventType: saveEventTypeAction,
+ linkToPresentationType: linkToPresentationTypeAction,
+ unlinkFromPresentationType: unlinkFromPresentationTypeAction
+})(EventTypeDialog);
diff --git a/src/pages/events/edit-event-type-page.js b/src/pages/events/edit-event-type-page.js
deleted file mode 100644
index 7fe3782c4..000000000
--- a/src/pages/events/edit-event-type-page.js
+++ /dev/null
@@ -1,113 +0,0 @@
-/**
- * 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.
- * 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 EventTypeForm from "../../components/forms/event-type-form";
-import { getSummitById } from "../../actions/summit-actions";
-import {
- getEventType,
- resetEventTypeForm,
- saveEventType
-} from "../../actions/event-type-actions";
-import "../../styles/edit-event-type-page.less";
-import {
- queryMediaUploads,
- linkToPresentationType,
- unlinkFromPresentationType
-} from "../../actions/media-upload-actions";
-import AddNewButton from "../../components/buttons/add-new-button";
-
-class EditEventTypePage extends React.Component {
- constructor(props) {
- const eventTypeId = props.match.params.event_type_id;
- super(props);
-
- if (!eventTypeId) {
- props.resetEventTypeForm();
- } else {
- props.getEventType(eventTypeId);
- }
-
- this.getMediaUploads = this.getMediaUploads.bind(this);
- }
-
- componentDidUpdate(prevProps, prevState, snapshot) {
- const oldId = prevProps.match.params.event_type_id;
- const newId = this.props.match.params.event_type_id;
-
- if (oldId !== newId) {
- if (!newId) {
- this.props.resetEventTypeForm();
- } else {
- this.props.getEventType(newId);
- }
- }
- }
-
- getMediaUploads(input, callback) {
- const { currentSummit } = this.props;
-
- if (!input) {
- return Promise.resolve({ options: [] });
- }
-
- return queryMediaUploads(currentSummit.id, input, callback);
- }
-
- render() {
- const { currentSummit, entity, 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");
-
- return (
-
-
-
- {title} {T.translate("edit_event_type.event_type")}
-
-
-
- {currentSummit && (
-
- )}
-
- );
- }
-}
-
-const mapStateToProps = ({ currentSummitState, currentEventTypeState }) => ({
- currentSummit: currentSummitState.currentSummit,
- ...currentEventTypeState
-});
-
-export default connect(mapStateToProps, {
- getSummitById,
- getEventType,
- resetEventTypeForm,
- saveEventType,
- linkToPresentationType,
- unlinkFromPresentationType
-})(EditEventTypePage);
diff --git a/src/pages/events/event-type-list-page.js b/src/pages/events/event-type-list-page.js
index 72d2e2259..6157e9e9d 100644
--- a/src/pages/events/event-type-list-page.js
+++ b/src/pages/events/event-type-list-page.js
@@ -11,7 +11,7 @@
* limitations under the License.
* */
-import React, { useEffect } from "react";
+import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import PropTypes from "prop-types";
import T from "i18n-react/dist/i18n-react";
@@ -23,10 +23,13 @@ import MuiTable from "openstack-uicore-foundation/lib/components/mui/table";
import SearchInput from "openstack-uicore-foundation/lib/components/mui/search-input";
import {
getEventTypes as getEventTypesAction,
+ getEventType as getEventTypeAction,
deleteEventType as deleteEventTypeAction,
- seedEventTypes as seedEventTypesAction
+ seedEventTypes as seedEventTypesAction,
+ resetEventTypeForm as resetEventTypeFormAction
} from "../../actions/event-type-actions";
import { DEFAULT_CURRENT_PAGE } from "../../utils/constants";
+import EventTypeDialog from "./components/event-type-dialog";
const EventTypeListPage = ({
currentSummit,
@@ -38,20 +41,24 @@ const EventTypeListPage = ({
orderDir,
totalEventTypes,
getEventTypes,
+ getEventType,
deleteEventType,
seedEventTypes,
- history
+ resetEventTypeForm
}) => {
+ const [openPopup, setOpenPopup] = useState(null);
+
useEffect(() => {
getEventTypes();
}, []);
const handleEdit = (row) => {
- history.push(`/app/summits/${currentSummit.id}/event-types/${row.id}`);
+ getEventType(row.id).then(() => setOpenPopup("eventTypeForm"));
};
const handleNew = () => {
- history.push(`/app/summits/${currentSummit.id}/event-types/new`);
+ resetEventTypeForm();
+ setOpenPopup("eventTypeForm");
};
const handleDelete = (eventTypeId) => {
@@ -175,6 +182,10 @@ const EventTypeListPage = ({
{eventTypes.length === 0 && (
{T.translate("event_type_list.no_items")}
)}
+
+ {openPopup === "eventTypeForm" && (
+ setOpenPopup(null)} />
+ )}
);
};
@@ -196,9 +207,10 @@ EventTypeListPage.propTypes = {
orderDir: PropTypes.number,
totalEventTypes: PropTypes.number,
getEventTypes: PropTypes.func.isRequired,
+ getEventType: PropTypes.func.isRequired,
deleteEventType: PropTypes.func.isRequired,
seedEventTypes: PropTypes.func.isRequired,
- history: PropTypes.shape({ push: PropTypes.func }).isRequired
+ resetEventTypeForm: PropTypes.func.isRequired
};
EventTypeListPage.defaultProps = {
@@ -220,6 +232,8 @@ const mapStateToProps = ({
export default connect(mapStateToProps, {
getEventTypes: getEventTypesAction,
+ getEventType: getEventTypeAction,
deleteEventType: deleteEventTypeAction,
- seedEventTypes: seedEventTypesAction
+ seedEventTypes: seedEventTypesAction,
+ resetEventTypeForm: resetEventTypeFormAction
})(EventTypeListPage);