Skip to content

Commit

Permalink
Adjust http error handling and notifications
Browse files Browse the repository at this point in the history
503 errors mean that Tobira either isn't configured, or not
configured correcty in Opencast. Unfortunately, it doesn't
distinguish between the two.
Since it might very well be the former, I think we shouldn't
show the error as a notification in the UI.
Instead there will be an info in console saying "Tobira isn't
configured (correctly)" and the Tobira tab will be hidden.
This solution isn't optimal but I think it's the best we
can do for now.

The other errors (404, 500) will trigger notifications that
are shown in the respective Tobira tab.
  • Loading branch information
owi92 committed Sep 30, 2024
1 parent 9cba7a6 commit 3ca089a
Show file tree
Hide file tree
Showing 15 changed files with 147 additions and 133 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { useTranslation } from "react-i18next";
import Notifications from "../../../shared/Notifications";
import { useAppDispatch, useAppSelector } from "../../../../store";
import { getSeriesDetailsTobiraData, getSeriesDetailsTobiraDataError, getTobiraTabHierarchy } from "../../../../selectors/seriesDetailsSelectors";
import { addNotification, removeNotificationWizardForm } from "../../../../slices/notificationSlice";
import { addNotification } from "../../../../slices/notificationSlice";
import { NOTIFICATION_CONTEXT } from "../../../../configs/modalConfig";
import { getEventDetailsTobiraData, getEventDetailsTobiraDataError } from "../../../../selectors/eventDetailsSelectors";
import { Formik } from "formik";
Expand Down Expand Up @@ -112,7 +112,7 @@ const DetailsTobiraTab: React.FC<DetailsTobiraTabProps> = ({ kind, id }) => {
/>}
{tabHierarchy === "main" && <div className="modal-body">
{/* Notifications */}
<Notifications context="not_corner" />
<Notifications context="tobira" />
{!error && <>
<div className="tab-description">
<a href={directTobiraLink}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { OurNotification, addNotification, removeNotificationByKey, removeNotifi
import { useAppDispatch, useAppSelector } from "../../../../store";
import { TobiraPage, fetchSeriesDetailsTobiraNew, setErrorTobiraPage, setTobiraPage } from "../../../../slices/seriesSlice";
import { getSeriesTobiraPage, getSeriesTobiraPageError } from "../../../../selectors/seriesSeletctor";
import { NOTIFICATION_CONTEXT } from "../../../../configs/modalConfig";
import { NOTIFICATION_CONTEXT_TOBIRA } from "../../../../configs/modalConfig";
import { SaveEditFooter } from "../../../shared/SaveEditFooter";
import { Tooltip } from "../../../shared/Tooltip";

Expand Down Expand Up @@ -71,7 +71,7 @@ const NewTobiraPage = <T extends TobiraFormProps>({

let valid = true;

valid = valid && check('info', 'TOBIRA_OVERRIDE_NAME', NOTIFICATION_CONTEXT, () => {
valid = valid && check('info', 'TOBIRA_OVERRIDE_NAME', NOTIFICATION_CONTEXT_TOBIRA, () => {
return !!formik.values.selectedPage && !!formik.values.selectedPage.title;
});

Expand All @@ -87,9 +87,9 @@ const NewTobiraPage = <T extends TobiraFormProps>({
}
const newPage = currentPage.children[currentPage.children.length - 1];

valid = valid && check('warning', 'TOBIRA_NO_PATH_SEGMENT', NOTIFICATION_CONTEXT, () => !newPage.segment);
valid = valid && check('warning', 'TOBIRA_NO_PATH_SEGMENT', NOTIFICATION_CONTEXT_TOBIRA, () => !newPage.segment);

valid = valid && check('warning', 'TOBIRA_PATH_SEGMENT_INVALID', NOTIFICATION_CONTEXT, () => (
valid = valid && check('warning', 'TOBIRA_PATH_SEGMENT_INVALID', NOTIFICATION_CONTEXT_TOBIRA, () => (
newPage.segment.length <= 1 || [
// eslint-disable-next-line no-control-regex
/[\u0000-\u001F\u007F-\u009F]/u,
Expand All @@ -99,7 +99,7 @@ const NewTobiraPage = <T extends TobiraFormProps>({
].some(regex => regex.test(newPage.segment))
));

valid = valid && check('warning', 'TOBIRA_PATH_SEGMENT_UNIQUE', NOTIFICATION_CONTEXT, () => (
valid = valid && check('warning', 'TOBIRA_PATH_SEGMENT_UNIQUE', NOTIFICATION_CONTEXT_TOBIRA, () => (
currentPage.children.some(child => child !== newPage && child.segment === newPage.segment)
));

Expand Down Expand Up @@ -211,7 +211,7 @@ const NewTobiraPage = <T extends TobiraFormProps>({
<div className="modal-content">
<div className="modal-body">
{/* Notifications */}
<Notifications context="not_corner" />
<Notifications context="tobira" />
{!editMode && <p className="tab-description">{t("EVENTS.SERIES.NEW.TOBIRA.DESCRIPTION")}</p>}
{!error && <>
<div className="obj-container padded">
Expand Down Expand Up @@ -271,8 +271,8 @@ const NewTobiraPage = <T extends TobiraFormProps>({
{!!page.new
? <input
placeholder={t('EVENTS.SERIES.NEW.TOBIRA.PAGE_TITLE')}
value={page.title}
onChange={(e) => setPage(key, e, "title")}
value={page.title ?? ""}
onChange={e => setPage(key, e, "title")}
/>
: <button
className={"button-like-anchor "
Expand All @@ -291,7 +291,7 @@ const NewTobiraPage = <T extends TobiraFormProps>({
{!!page.new
? <input
placeholder={t('EVENTS.SERIES.NEW.TOBIRA.PATH_SEGMENT')}
value={page.segment}
value={page.segment ?? ""}
onChange={e => setPage(key, e, "segment")}
/>
: <span style={{ fontWeight: "inherit" }}>
Expand Down
8 changes: 6 additions & 2 deletions src/components/events/partials/modals/EventDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
isFetchingStatistics,
getModalWorkflowTabHierarchy,
getModalPage,
getEventDetailsTobiraDataError,
} from "../../../../selectors/eventDetailsSelectors";
import { getUserInformation } from "../../../../selectors/userInfoSelectors";
import EventDetailsStatisticsTab from "../ModalTabsAndPages/EventDetailsStatisticsTab";
Expand Down Expand Up @@ -83,7 +84,6 @@ const EventDetails = ({
dispatch(fetchSchedulingInfo(eventId)).then();
dispatch(fetchEventStatistics(eventId)).then();
dispatch(fetchAssetUploadOptions()).then();
dispatch(fetchEventDetailsTobira(eventId));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

Expand All @@ -98,6 +98,7 @@ const EventDetails = ({
const hasStatistics = useAppSelector(state => getHasStatistics(state));
const isLoadingStatistics = useAppSelector(state => isFetchingStatistics(state));
const captureAgents = useAppSelector(state => getRecordings(state));
const tobiraError = useAppSelector(state => getEventDetailsTobiraDataError(state));

const tabs = [
{
Expand Down Expand Up @@ -163,7 +164,7 @@ const EventDetails = ({
accessRole: "ROLE_UI_EVENTS_DETAILS_COMMENTS_VIEW",
name: "tobira",
page: EventDetailsPage.Tobira,
hidden: false, // TODO: Set to true if there no tobira data
hidden: tobiraError?.message?.includes("503"),
},
{
tabNameTranslation: "EVENTS.EVENTS.DETAILS.TABS.STATISTICS",
Expand All @@ -177,6 +178,9 @@ const EventDetails = ({

const openTab = (tabNr: EventDetailsPage) => {
dispatch(removeNotificationWizardForm());
if (tabNr === EventDetailsPage.Tobira) {
dispatch(fetchEventDetailsTobira(eventId));
}
dispatch(openModalTab(tabNr, "entry", "entry"))
};

Expand Down
4 changes: 3 additions & 1 deletion src/components/events/partials/modals/SeriesDetails.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
getSeriesDetailsMetadata,
getSeriesDetailsTheme,
getSeriesDetailsThemeNames,
getSeriesDetailsTobiraDataError,
hasStatistics as seriesHasStatistics,
} from "../../../../selectors/seriesDetailsSelectors";
import { getOrgProperties, getUserInformation } from "../../../../selectors/userInfoSelectors";
Expand Down Expand Up @@ -47,6 +48,7 @@ const SeriesDetails = ({
const theme = useAppSelector(state => getSeriesDetailsTheme(state));
const themeNames = useAppSelector(state => getSeriesDetailsThemeNames(state));
const hasStatistics = useAppSelector(state => seriesHasStatistics(state));
const tobiraError = useAppSelector(state => getSeriesDetailsTobiraDataError(state));

useEffect(() => {
dispatch(fetchSeriesStatistics(seriesId));
Expand Down Expand Up @@ -88,7 +90,7 @@ const SeriesDetails = ({
tabNameTranslation: "EVENTS.SERIES.DETAILS.TABS.TOBIRA",
accessRole: "ROLE_UI_SERIES_DETAILS_TOBIRA_VIEW",
name: "tobira",
hidden: false, // TODO: Set to true if there no tobira data
hidden: tobiraError?.message?.includes("503"),
},
{
tabNameTranslation: "EVENTS.SERIES.DETAILS.TABS.STATISTICS",
Expand Down
6 changes: 3 additions & 3 deletions src/components/events/partials/wizards/NewSeriesWizard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { Formik } from "formik";
import NewThemePage from "../ModalTabsAndPages/NewThemePage";
import NewSeriesSummary from "./NewSeriesSummary";
import {
getSeriesTobiraPageStatus,
getSeriesExtendedMetadata,
getSeriesMetadata,
getSeriesTobiraPageError,
} from "../../../../selectors/seriesSeletctor";
import NewMetadataPage from "../ModalTabsAndPages/NewMetadataPage";
import NewMetadataExtendedPage from "../ModalTabsAndPages/NewMetadataExtendedPage";
Expand Down Expand Up @@ -34,7 +34,7 @@ const NewSeriesWizard: React.FC<{

const metadataFields = useAppSelector(state => getSeriesMetadata(state));
const extendedMetadata = useAppSelector(state => getSeriesExtendedMetadata(state));
const statusTobiraPage = useAppSelector(state => getSeriesTobiraPageStatus(state));
const tobiraError = useAppSelector(state => getSeriesTobiraPageError(state));
const user = useAppSelector(state => getUserInformation(state));
const orgProperties = useAppSelector(state => getOrgProperties(state));

Expand Down Expand Up @@ -71,7 +71,7 @@ const NewSeriesWizard: React.FC<{
{
translation: "EVENTS.SERIES.NEW.TOBIRA.CAPTION",
name: "tobira",
hidden: statusTobiraPage !== "succeeded", // TODO: Figure out condition for this to be true
hidden: !!tobiraError?.message?.includes("503"),
},
{
translation: "EVENTS.SERIES.NEW.SUMMARY.CAPTION",
Expand Down
31 changes: 16 additions & 15 deletions src/components/shared/Notifications.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,26 +8,23 @@ import cn from "classnames";
import {
NOTIFICATION_CONTEXT,
NOTIFICATION_CONTEXT_ACCESS,
NOTIFICATION_CONTEXT_TOBIRA,
} from "../../configs/modalConfig";
import { useAppDispatch, useAppSelector } from "../../store";
import { OurNotification, setHidden } from "../../slices/notificationSlice";

/**
* This component renders notifications about occurred errors, warnings and info
*/
const Notifications : React.FC<{
context?: string,
}> = ({
context,
}) => {
const Notifications : React.FC<{ context?: string }> = ({ context }) => {
const { t } = useTranslation();
const dispatch = useAppDispatch();

const notifications = useAppSelector(state => getNotifications(state))
const globalPosition = useAppSelector(state => getGlobalPositions(state))
const notifications = useAppSelector(state => getNotifications(state));
const globalPosition = useAppSelector(state => getGlobalPositions(state));

const closeNotification = (id: number) => {
dispatch(setHidden({id: id, isHidden: true}));
dispatch(setHidden({ id: id, isHidden: true}));
};

const renderNotification = (notification: OurNotification, key: number) => (
Expand All @@ -46,13 +43,17 @@ const globalPosition = useAppSelector(state => getGlobalPositions(state))
// if context is not_corner then render notification without consider global notification position
context === "not_corner" ? (
<ul>
{notifications.map(
(notification, key) =>
!notification.hidden &&
(notification.context === NOTIFICATION_CONTEXT ||
notification.context === NOTIFICATION_CONTEXT_ACCESS) &&
renderNotification(notification, key)
)}
{notifications.map((notification, key) => !notification.hidden && (
notification.context === NOTIFICATION_CONTEXT
|| notification.context === NOTIFICATION_CONTEXT_ACCESS
|| notification.context === NOTIFICATION_CONTEXT_TOBIRA
) && renderNotification(notification, key))}
</ul>
) : context === "tobira" ? (
<ul>
{notifications.map((notification, key) => !notification.hidden && (
notification.context === NOTIFICATION_CONTEXT_TOBIRA
) && renderNotification(notification, key))}
</ul>
) : context === "above_table" ? (
<ul>
Expand Down
3 changes: 3 additions & 0 deletions src/configs/modalConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export const NOTIFICATION_CONTEXT = "modal-form";
// Context for notifications shown in wizard access page
export const NOTIFICATION_CONTEXT_ACCESS = "wizard-access";

// Context for notifications shown in tobira tabs.
export const NOTIFICATION_CONTEXT_TOBIRA = "tobira";

export const initialFormValuesNewEvents: {
sourceMode: string,
scheduleStartDate: string,
Expand Down
13 changes: 12 additions & 1 deletion src/i18n/org/opencastproject/adminui/languages/lang-en_US.json
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,18 @@
"NO_EVENTS_UPDATED": "All updates failed.",
"SOME_EVENTS_NOT_UPDATED": "Some events could not be updated."
},
"PROBLEM_ON_START": "A error occurred on start up. Please contact your Opencast admin"
"PROBLEM_ON_START": "An error occurred on start up. Please contact your Opencast admin",
"TOBIRA_OVERRIDE_NAME": "The title of the selected page will be overridden with the title of the series.",
"TOBIRA_NO_PATH_SEGMENT": "Page needs a path segment.",
"TOBIRA_NOT_MOUNTED": "Series could not be mounted in Tobira.",
"TOBIRA_PATH_SEGMENT_INVALID": "Path segment is invalid. A valid path segment is at least 2 characters long, does not contain any whitespace or control characters, none of the characters '<>\"[\\]^`{|}#%\/?]', and doesn't start with any of the characters '-+~@_!$&;:.,=*'()'.",
"TOBIRA_PATH_SEGMENT_UNIQUE": "The path segment of a page must be unique among all its sibling pages.",
"TOBIRA_PAGE_NOT_FOUND": "The page you tried to navigate to does not or no longer exist. Maybe try starting from the beginning.",
"TOBIRA_SERVER_ERROR":" Error talking to Tobira. Contact your system administrator and/or try again later.",
"TOBIRA_COPIED_DIRECT_LINK": "Copied link to clipboard.",
"TOBIRA_FAILED_COPYING_DIRECT_LINK": "Couldn't copy link to clipboard.",
"TOBIRA_NOT_FOUND": "Tobira doesn't know about this series or event (yet). Try again in a few minutes or contact your system administrator.",
"TOBIRA_NOT_CONFIGURED": "Tobira is not configured (correctly)."
},
"BULK_ACTIONS": {
"CAPTION": "Actions",
Expand Down
6 changes: 4 additions & 2 deletions src/selectors/eventDetailsSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,9 +115,11 @@ export const isFetchingWorkflowErrorDetails = (state: RootState) =>
state.eventDetails.statusWorkflowErrorDetails === 'loading';

export const getEventDetailsTobiraData = (state: RootState) =>
state.eventDetails.tobiraData
state.eventDetails.tobiraData;
export const getEventDetailsTobiraDataError = (state: RootState) =>
state.eventDetails.errorTobiraData
state.eventDetails.errorTobiraData;
export const getEventDetailsTobiraStatus = (state: RootState) =>
state.eventDetails.statusTobiraData;

/* selectors for publications */
export const getPublications = (state: RootState) => state.eventDetails.publications;
Expand Down
4 changes: 2 additions & 2 deletions src/selectors/seriesDetailsSelectors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ export const getSeriesDetailsThemeNames = (state: RootState) =>
state.seriesDetails.themeNames;

export const getSeriesDetailsTobiraData = (state: RootState) =>
state.seriesDetails.tobiraData
state.seriesDetails.tobiraData;
export const getSeriesDetailsTobiraDataError = (state: RootState) =>
state.seriesDetails.errorTobiraData
state.seriesDetails.errorTobiraData;
export const getTobiraTabHierarchy = (state: RootState) =>
state.seriesDetails.tobiraTab;

Expand Down
31 changes: 3 additions & 28 deletions src/slices/eventDetailsSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
import { AppDispatch } from "../store";
import { Ace } from './aclSlice';
import { setTobiraTabHierarchy, TobiraData } from './seriesDetailsSlice';
import { handleTobiraError } from './shared/tobiraErrors';

// Contains the navigation logic for the modal
type EventDetailsModal = {
Expand Down Expand Up @@ -980,33 +981,7 @@ export const fetchEventDetailsTobira = createAppAsyncThunk('eventDetails/fetchEv
{ dispatch },
) => {
const res = await axios.get(`/admin-ng/event/${id}/tobira/pages`)
.catch(response => {
console.error(response);
const data = response.response;

if (data.status === 500) {
dispatch(addNotification({
type: "error",
key: "TOBIRA_SERVER_ERROR",
duration: -1,
parameter: null,
context: NOTIFICATION_CONTEXT
}));

throw Error(response);
} else if (data.status === 404) {
dispatch(addNotification({
type: "warning",
key: "TOBIRA_NOT_FOUND",
duration: -1,
parameter: null,
context: NOTIFICATION_CONTEXT
}));

throw Error(response);
}
return undefined;
});
.catch(response => handleTobiraError(response, dispatch));

if (!res) {
throw Error;
Expand Down Expand Up @@ -1520,7 +1495,6 @@ export const openModal = (
) => (dispatch: AppDispatch) => {
dispatch(setModalEvent(event));
dispatch(setModalWorkflowId(workflowId));
dispatch(setTobiraTabHierarchy("main"));
dispatch(openModalTab(page, workflowTab, assetsTab))
dispatch(setShowModal(true));
};
Expand All @@ -1531,6 +1505,7 @@ export const openModalTab = (
assetsTab: AssetTabHierarchy
) => (dispatch: AppDispatch) => {
dispatch(setModalPage(page));
dispatch(setTobiraTabHierarchy("main"));
dispatch(setModalWorkflowTabHierarchy(workflowTab));
dispatch(setModalAssetsTabHierarchy(assetsTab));
};
Expand Down
2 changes: 1 addition & 1 deletion src/slices/notificationSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@ const notificationSlice = createSlice({
},
removeNotificationWizardForm(state) {
state.notifications = state.notifications.filter(
(notification) => notification.context !== NOTIFICATION_CONTEXT
(notification) => notification.context === NOTIFICATION_CONTEXT
)
},
removeNotificationWizardAccess(state) {
Expand Down
Loading

0 comments on commit 3ca089a

Please sign in to comment.