diff --git a/src/components/forms/event-material-form.js b/src/components/forms/event-material-form.js index c90dcbbe5..6332e6af1 100644 --- a/src/components/forms/event-material-form.js +++ b/src/components/forms/event-material-form.js @@ -1,5 +1,5 @@ /** - * Copyright 2017 OpenStack Foundation + * 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 @@ -11,19 +11,14 @@ * limitations under the License. * */ -import React from "react"; +import React, { useState, useEffect } from "react"; import T from "i18n-react/dist/i18n-react"; import "awesome-bootstrap-checkbox/awesome-bootstrap-checkbox.css"; import Dropdown from "openstack-uicore-foundation/lib/components/inputs/dropdown"; import Input from "openstack-uicore-foundation/lib/components/inputs/text-input"; import UploadInputV3 from "openstack-uicore-foundation/lib/components/inputs/upload-input-v3"; import TextEditorV3 from "openstack-uicore-foundation/lib/components/inputs/editor-input-v3"; -import { - isEmpty, - scrollToError, - shallowEqual, - hasErrors -} from "../../utils/methods"; +import { scrollToError, hasErrors } from "../../utils/methods"; import { ALLOWED_SLIDES_FORMATS, KB, @@ -38,52 +33,53 @@ const MATERIAL_TYPE = { PRESENTATION_VIDEO: "PresentationVideo" }; -class EventMaterialForm extends React.Component { - constructor(props) { - super(props); - - this.state = { - entity: { ...props.entity }, - file: null, - errors: props.errors - }; - - this.handleChange = this.handleChange.bind(this); - this.handleChangeMUType = this.handleChangeMUType.bind(this); - this.handleSubmit = this.handleSubmit.bind(this); - this.handleUploadFile = this.handleUploadFile.bind(this); - this.handleRemoveFile = this.handleRemoveFile.bind(this); - this.onMediaUploadComplete = this.onMediaUploadComplete.bind(this); - } - - componentDidUpdate(prevProps) { - const state = {}; - const name = this.props.entity.id - ? this.props.entity.name - : this.props.event.title; - const description = this.props.entity.id - ? this.props.entity.description - : this.props.event.description; - - scrollToError(this.props.errors); - - if (!shallowEqual(prevProps.entity, this.props.entity)) { - state.entity = { ...this.props.entity, name, description }; - state.errors = {}; +const EventMaterialForm = ({ entity, errors, event, onSubmit }) => { + const [entityState, setEntityState] = useState(entity); + const [errorsState, setErrorsState] = useState(errors); + + // on admin we upload one per time + const mediaType = { + ...entityState.media_upload_type, + max_size: + (entityState.media_upload_type?.max_size || MAX_MEDIA_UPLOAD_SIZE) * KB, + max_uploads_qty: 1 + }; + const mediaInputValue = entityState.filename ? [entityState] : []; + + const eventMaterialsOpts = [ + { label: "Link", value: MATERIAL_TYPE.PRESENTATION_LINK }, + { label: "Slide", value: MATERIAL_TYPE.PRESENTATION_SLIDE }, + { label: "Video", value: MATERIAL_TYPE.PRESENTATION_VIDEO }, + { label: "Media Upload", value: MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD } + ]; + + const mediaUploadsOpts = event.type.allowed_media_upload_types.map((mu) => ({ + label: mu.name, + value: mu.id + })); + + const disableInputs = + entityState.class_name === MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD; + + const slideMediaType = { + id: "slide", + max_size: MAX_SLIDE_UPLOAD_SIZE * KB, + type: { + allowed_extensions: ALLOWED_SLIDES_FORMATS } + }; - if (!shallowEqual(prevProps.errors, this.props.errors)) { - state.errors = { ...this.props.errors }; - } + useEffect(() => { + setEntityState(entity); + setErrorsState({}); + }, [entity]); - if (!isEmpty(state)) { - this.setState({ ...this.state, ...state }); - } - } + useEffect(() => { + scrollToError(errors); + setErrorsState(errors); + }, [errors]); - handleChange(ev) { - const entity = { ...this.state.entity }; - const errors = { ...this.state.errors }; + const handleChange = (ev) => { let { value, id } = ev.target; if (ev.target.type === "checkbox") { @@ -94,290 +90,246 @@ class EventMaterialForm extends React.Component { value = parseInt(ev.target.value); } - errors[id] = ""; - entity[id] = value; - - this.setState({ entity, errors }); - } + setEntityState({ ...entityState, [id]: value }); + setErrorsState({ ...errorsState, [id]: "" }); + }; - handleChangeMUType(ev) { - const entity = { ...this.state.entity }; - const errors = { ...this.state.errors }; + const handleChangeMUType = (ev) => { const { value } = ev.target; - const type = this.props.event.type.allowed_media_upload_types.find( + const type = event.type.allowed_media_upload_types.find( (mu) => mu.id === value ); - errors.media_upload_type_id = ""; - entity.media_upload_type_id = value; - entity.media_upload_type = type; - entity.name = type.name; - - this.setState({ entity, errors }); - } - - handleUploadFile(file) { - this.setState({ file }); - } - - handleRemoveFile() { - const entity = { ...this.state.entity }; - entity.file_link = ""; - entity.filename = ""; - entity.filepath = ""; - this.setState({ entity, file: null }); - } - onMediaUploadComplete(response) { - const { entity } = this.state; + setEntityState({ + ...entityState, + media_upload_type_id: value, + media_upload_type: type, + name: type.name + }); + setErrorsState({ ...errorsState, media_upload_type_id: "" }); + }; + + const handleRemoveFile = () => { + setEntityState({ + ...entityState, + file_link: "", + filename: "", + filepath: "" + }); + }; + + const onMediaUploadComplete = (response) => { if (response) { - entity.filepath = `${response.path}${response.name}`; - entity.filename = response.name; - this.setState({ entity }); + setEntityState({ + ...entityState, + filepath: `${response.path}${response.name}`, + filename: response.name + }); } - } + }; - handleSubmit(ev) { - const { entity } = this.state; + const handleSubmit = (ev) => { ev.preventDefault(); - this.props.onSubmit(entity); - } - - render() { - const { entity, errors } = this.state; - - // on admin we upload one per time - const media_type = { - ...entity.media_upload_type, - max_size: - (entity.media_upload_type?.max_size || MAX_MEDIA_UPLOAD_SIZE) * KB, - max_uploads_qty: 1 - }; - const mediaInputValue = entity.filename ? [entity] : []; - - const event_materials_ddl = [ - { label: "Link", value: MATERIAL_TYPE.PRESENTATION_LINK }, - { label: "Slide", value: MATERIAL_TYPE.PRESENTATION_SLIDE }, - { label: "Video", value: MATERIAL_TYPE.PRESENTATION_VIDEO }, - { label: "Media Upload", value: MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD } - ]; - - const media_uploads_ddl = - this.props.event.type.allowed_media_upload_types.map((mu) => ({ - label: mu.name, - value: mu.id - })); - - const disableInputs = - entity.class_name === MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD; - - const slideMediaType = { - id: "slide", - max_size: MAX_SLIDE_UPLOAD_SIZE * KB, - type: { - allowed_extensions: ALLOWED_SLIDES_FORMATS - } - }; - - return ( -
- -
+ onSubmit(entityState); + }; + + return ( + + +
+
+ + +
+ {entityState.class_name === MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD && (
- + +
+ )} +
+
+
+ + +
+
+
+ + +
+
+
+ + {!disableInputs && ( +
+
+ +
- {entity.class_name === MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD && ( -
- - -
- )}
+ )} + {entityState.class_name === MATERIAL_TYPE.PRESENTATION_LINK && (
- +
-
-
- - -
+
+ )} + + {entityState.class_name === MATERIAL_TYPE.PRESENTATION_SLIDE && ( +
+
+ + +
+
+
+ +
+
+ +
+ )} - {!disableInputs && ( -
-
- - -
+ {entityState.class_name === MATERIAL_TYPE.PRESENTATION_VIDEO && ( +
+
+ +
- )} - {entity.class_name === MATERIAL_TYPE.PRESENTATION_LINK && ( -
-
- - -
+
+ )} + {entityState.class_name === MATERIAL_TYPE.PRESENTATION_VIDEO && ( +
+
+ +
- )} +
+ )} - {entity.class_name === MATERIAL_TYPE.PRESENTATION_SLIDE && ( + {entityState.class_name === MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD && + mediaType?.type && (
-
-
- -
-
- - -
)} - {entity.class_name === MATERIAL_TYPE.PRESENTATION_VIDEO && ( -
-
- - -
-
- )} - {entity.class_name === MATERIAL_TYPE.PRESENTATION_VIDEO && ( -
-
- - -
-
- )} - - {entity.class_name === MATERIAL_TYPE.PRESENTATION_MEDIA_UPLOAD && - media_type && - media_type.type && ( -
-
- - -
-
- )} - -
-
- -
+
+
+
- - ); - } -} +
+ + ); +}; export default EventMaterialForm;