diff --git a/package.json b/package.json index 0e869b5fc..4aedaa4ed 100644 --- a/package.json +++ b/package.json @@ -92,7 +92,7 @@ "moment": "^2.29.1", "moment-duration-format": "^2.3.2", "moment-timezone": "^0.5.33", - "openstack-uicore-foundation": "5.0.36-beta.1", + "openstack-uicore-foundation": "5.0.36-beta.2", "p-limit": "^6.1.0", "path-browserify": "^1.0.1", "postcss-loader": "^6.2.1", diff --git a/src/actions/event-actions.js b/src/actions/event-actions.js index 60a669f89..330e5e809 100644 --- a/src/actions/event-actions.js +++ b/src/actions/event-actions.js @@ -51,7 +51,6 @@ import { FIVE_PER_PAGE, HOUR_AND_HALF } from "../utils/constants"; -import { getIdValue } from "../utils/summitUtils"; URI.escapeQuerySpace = false; @@ -195,12 +194,12 @@ export const normalizeBulkEvents = (entity) => { const normalizedEvent = { id: e.id, title: e.title, - selection_plan_id: getIdValue(e.selection_plan) || e.selection_plan_id, + selection_plan_id: e.selection_plan?.id || e.selection_plan_id, location_id: e.location?.id || e.location_id, start_date: e.start_date, end_date: e.end_date, - type_id: getIdValue(e.type) || e.type_id, - track_id: getIdValue(e.track) || e.track_id, + type_id: e.type?.id || e.type_id, + track_id: e.track?.id || e.track_id, duration: e.duration, streaming_url: e.streaming_url, streaming_type: e.streaming_type, @@ -299,66 +298,65 @@ export const getEvents = }); }; -export const bulkUpdateEvents = - (summitId, events) => async (dispatch, getState) => { - const { currentSummitState } = getState(); - const accessToken = await getAccessTokenSafely(); - const { currentSummit } = currentSummitState; - dispatch(startLoading()); +export const bulkUpdateEvents = (events) => async (dispatch, getState) => { + const { currentSummitState } = getState(); + const accessToken = await getAccessTokenSafely(); + const { currentSummit } = currentSummitState; + dispatch(startLoading()); - const normalizedEvents = normalizeBulkEvents( - events.map((event) => - normalizeEvent( - event, - currentSummit.event_types.find((et) => et.id === event.type_id) - ) + const normalizedEvents = normalizeBulkEvents( + events.map((event) => + normalizeEvent( + event, + currentSummit.event_types.find((et) => et.id === event.type_id) ) - ); + ) + ); - return putRequest( - null, - createAction(UPDATED_REMOTE_EVENTS)({}), - `${window.API_BASE_URL}/api/v1/summits/${summitId}/events/?access_token=${accessToken}`, - { - events: normalizedEvents - }, - authErrorHandler - )({})(dispatch) - .then(() => { - dispatch(stopLoading()); - dispatch( - showSuccessMessage( - T.translate("bulk_actions_page.messages.update_success"), - () => history.push(`/app/summits/${currentSummit.id}/events/`) - ) - ); - const { - currentEventListState: { - term, - currentPage, - perPage, - order, - orderDir, - filters, - extraColumns - } - } = getState(); - dispatch( - getEvents( - term, - currentPage, - perPage, - order, - orderDir, - filters, - extraColumns - ) - ); - }) - .catch(() => { - console.log("ERROR"); - }); - }; + return putRequest( + null, + createAction(UPDATED_REMOTE_EVENTS)({}), + `${window.API_BASE_URL}/api/v1/summits/${currentSummit.id}/events/?access_token=${accessToken}`, + { + events: normalizedEvents + }, + authErrorHandler + )({})(dispatch) + .then(() => { + dispatch(stopLoading()); + dispatch( + showSuccessMessage( + T.translate("bulk_actions_page.messages.update_success"), + () => history.push(`/app/summits/${currentSummit.id}/events/`) + ) + ); + const { + currentEventListState: { + term, + currentPage, + perPage, + order, + orderDir, + filters, + extraColumns + } + } = getState(); + dispatch( + getEvents( + term, + currentPage, + perPage, + order, + orderDir, + filters, + extraColumns + ) + ); + }) + .catch(() => { + console.log("ERROR"); + }); +}; export const getActionTypes = (selectionPlanId) => async (dispatch, getState) => { diff --git a/src/components/tables/editable-table/EditableTable.js b/src/components/tables/editable-table/EditableTable.js deleted file mode 100644 index a8f959d07..000000000 --- a/src/components/tables/editable-table/EditableTable.js +++ /dev/null @@ -1,269 +0,0 @@ -import React, { useState, useEffect } from "react"; -import { Tooltip } from "react-tooltip"; -import T from "i18n-react/dist/i18n-react"; -import EditableTableHeading from "./EditableTableHeading"; -import EditableTableRow from "./EditableTableRow"; -import { - INDEX_NOT_FOUND, - SORT_ASCENDING, - SORT_DESCENDING -} from "../../../utils/constants"; - -import styles from "./index.module.less"; - -const defaults = { - sortFunc: (a, b) => { - if (a < b) { - return SORT_DESCENDING; - } - if (a > b) { - return SORT_ASCENDING; - } - return 0; - }, - sortable: false, - sortCol: 0, - sortDir: 1, - colWidth: "" -}; - -function EditableTable(props) { - const { - options, - columns, - currentSummit, - page, - data, - handleSort, - updateData, - handleDeleteRow, - formattingFunction, - afterUpdate = [] - } = props; - let tableClass = options.hasOwnProperty("className") ? options.className : ""; - const [editButton, setEditButton] = useState(false); - const [editEnabled, setEditEnabled] = useState(false); - const [selected, setSelected] = useState([]); - const [selectAll, setSelectAll] = useState(false); - tableClass += options.actions?.edit ? " table-hover" : ""; - - const getSortDir = (columnKey, columnIndex, sortCol, sortDir) => { - if (columnKey && columnKey === sortCol) { - return sortDir; - } - if (sortCol === columnIndex) { - return sortDir; - } - return null; - }; - - const resetState = () => { - setSelectAll(false); - setEditButton(false); - setEditEnabled(false); - setSelected([]); - }; - - // reseting states on data changes/pagination - useEffect(() => { - resetState(); - }, [page]); - - useEffect(() => { - if (selected.length > 0) { - setEditButton(true); - } else { - setEditButton(false); - setEditEnabled(false); - } - }, [selected]); - - useEffect(() => { - if (selectAll) { - setSelected(data); - setSelectAll(true); - } else { - setSelectAll(false); - setSelected([]); - } - }, [selectAll]); - - const updateSelected = (row, checked) => { - const selectedRow = row; - const rowIndex = selected.findIndex((s) => s.id === selectedRow.id); - const exists = rowIndex !== INDEX_NOT_FOUND; - - if (checked) { - if (exists) { - // if already on selected list, replace with new data - const updatedSelected = { ...selectedRow }; - const newSelected = selected.slice(); - newSelected[rowIndex] = updatedSelected; - setSelected(newSelected); - } else { - // append to list - setSelected((currSelected) => [...currSelected, selectedRow]); - } - } else { - setSelected(selected.filter((se) => se.id !== selectedRow.id)); - } - }; - - const handledAfterUpdateData = () => { - const actionsAfterUpdate = []; - if (afterUpdate.length > 0) { - afterUpdate.forEach(({ action, propertyName }) => { - selected.forEach((row) => { - if (Array.isArray(row[propertyName])) { - row[propertyName].forEach((e) => { - actionsAfterUpdate.push(action(e)); - }); - } else { - actionsAfterUpdate.push(action(row[propertyName])); - } - }); - }); - } - return Promise.all(actionsAfterUpdate); - }; - - const onUpdateEvents = (evt) => { - evt.stopPropagation(); - evt.preventDefault(); - updateData(currentSummit.id, selected) - .then(() => handledAfterUpdateData()) - .then(() => resetState()) - .catch((error) => { - console.error("Error updating events:", error); - }); - }; - - return ( -
-
-
-
- {editEnabled ? ( - <> - - - - ) : ( - - )} -
-
-
- - - - - {columns.map((col, i) => { - const sortCol = - typeof options.sortCol !== "undefined" - ? options.sortCol - : defaults.sortCol; - const sortDir = - typeof options.sortDir !== "undefined" - ? options.sortDir - : defaults.sortDir; - const sortFunc = - typeof options.sortFunc !== "undefined" - ? options.sortFunc - : defaults.sortFunc; - const sortable = - typeof col.sortable !== "undefined" - ? col.sortable - : defaults.sortable; - const colWidth = - typeof col.width !== "undefined" - ? col.width - : defaults.colWidth; - - return ( - - {col.value} - - ); - })} - {options.actions && ( - - {options.actionsHeader || " "} - - )} - - - - {columns.length > 0 && - data.map((row, i) => { - if (Array.isArray(row) && row.length !== columns.length) { - console.warn( - `Data at row ${i} is ${row.length}. It should be ${columns.length}.` - ); - return ; - } - - return ( - - - - ); - })} - -
- setSelectAll(!selectAll)} - checked={selectAll} - /> -
-
- -
- ); -} - -export default EditableTable; diff --git a/src/components/tables/editable-table/EditableTableHeading.js b/src/components/tables/editable-table/EditableTableHeading.js deleted file mode 100644 index 17578effb..000000000 --- a/src/components/tables/editable-table/EditableTableHeading.js +++ /dev/null @@ -1,60 +0,0 @@ -import React from "react"; -import PropTypes from "prop-types"; -import { SORT_ASCENDING, SORT_DESCENDING } from "../../../utils/constants"; - -function EditableTableHeading(props) { - const { - editEnabled, - sortable, - sortDir, - onSort, - columnIndex, - columnKey, - sortFunc, - width, - children - } = props; - const getSortClass = () => { - // disable sorting if on edit mode - if (!sortable || editEnabled) return null; - - switch (sortDir) { - case SORT_ASCENDING: - return "sorting_asc"; - case SORT_DESCENDING: - return "sorting_desc"; - default: - return sortable ? "sorting" : null; - } - }; - - const handleSort = (e) => { - e.preventDefault(); - - if (!onSort || !sortable) return; - - onSort( - columnIndex, - columnKey, - sortDir ? sortDir * SORT_DESCENDING : SORT_ASCENDING, - sortFunc - ); - }; - - return ( - - {children} - - ); -} - -EditableTableHeading.propTypes = { - onSort: PropTypes.func, - sortDir: PropTypes.number, - columnIndex: PropTypes.number, - columnKey: PropTypes.any, - sortable: PropTypes.bool, - sortFunc: PropTypes.func -}; - -export default EditableTableHeading; diff --git a/src/components/tables/editable-table/EditableTableRow.js b/src/components/tables/editable-table/EditableTableRow.js deleted file mode 100644 index bcd49f6f7..000000000 --- a/src/components/tables/editable-table/EditableTableRow.js +++ /dev/null @@ -1,190 +0,0 @@ -import React, { useEffect, useState } from "react"; -import TextArea from "openstack-uicore-foundation/lib/components/inputs/textarea-input"; -import T from "i18n-react/dist/i18n-react"; -import history from "../../../history"; - -import styles from "./index.module.less"; - -function EditableTableRow(props) { - const { - row, - columns, - editEnabled, - selected, - updateSelected, - deleteRow, - selectAll, - currentSummit, - actions, - formattingFunction - } = props; - const [checked, setChecked] = useState(false); - const [editData, setEditData] = useState(row); - - const formattedData = formattingFunction(row, currentSummit); - - useEffect(() => { - setEditData(row); - }, [row]); - useEffect(() => { - updateSelected(editData, checked); - }, [checked, row]); - useEffect(() => { - setChecked(selectAll); - }, [selectAll]); - useEffect(() => { - if (selected.length === 0) { - setChecked(false); - } - }, [selected]); - useEffect(() => { - updateSelected(editData, checked); - }, [editData]); - useEffect(() => { - if (!editEnabled) { - setEditData(row); - } - }, [editEnabled]); - - const onRowChange = (ev) => { - const { value, id } = ev.target; - if (id.includes("___")) { - const parts = id.split("___"); // ['array property', '', 'element property'] - const arrayProp = parts[0]; - const elementId = parseInt(parts[1], 10); - const prop = parts[2]; - - const arrayToChange = editData[arrayProp].map((elem) => { - if (elem.id === elementId) { - return { ...elem, [prop]: value }; - } - return elem; - }); - - const newEventData = { ...editData, [arrayProp]: arrayToChange }; - setEditData(newEventData); - } else { - const newEventData = { ...editData, [id]: value }; - setEditData(newEventData); - } - }; - - const onRemoveOption = (rowId, id) => { - const currentRow = selected.find((r) => r.id === row.id); - const newOptions = currentRow[id].filter((s) => s.id !== rowId); - const newEventData = { ...editData, [id]: newOptions }; - setEditData(newEventData); - }; - - return ( - <> - - setChecked(!checked)} - checked={checked} - /> - - {row.id} - {selected.find((s) => s.id === row.id) && editEnabled && checked ? ( - <> - {columns.map((col) => { - if (col.columnKey === "id") { - return null; - } - if (col.editableField === true) { - // Default field as text - return ( - -