Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const FeedbackBarComponentPlain = ({ feedback, onClose }: Props) => {
return null;
}

const { message, displayType, variant } = feedback;
const { id, message, displayType, variant } = feedback;
const isAlertBarOpen = typeof message === 'string' && !displayType;
const isDialogOpen = typeof message === 'object' && displayType === 'dialog';
const alertVariant = getAlertVariant(variant);
Expand All @@ -33,7 +33,7 @@ const FeedbackBarComponentPlain = ({ feedback, onClose }: Props) => {
<>
<AlertStack>
{isAlertBarOpen && (
<AlertBar {...alertVariant} duration={5000}>
<AlertBar key={id} {...alertVariant} duration={5000} onHidden={onClose}>
{message}
</AlertBar>
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { ReactNode } from 'react';

export type Feedback = {
id: string;
message: string | { title: string; content: string };
action?: ReactNode;
displayType?: 'alert' | 'dialog';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import log from 'loglevel';
import i18n from '@dhis2/d2-i18n';
import isString from 'd2-utilizr/lib/isString';
import isObject from 'd2-utilizr/lib/isObject';
import uuid from 'd2-utilizr/lib/uuid';
import { errorCreator } from 'capture-core-utils';
import { createReducerDescription } from '../../trackerRedux/trackerReducer';
import { actionTypes as feedbackActionTypes } from '../../components/FeedbackBar/actions/feedback.actions';
Expand Down Expand Up @@ -41,31 +42,19 @@ type ErrorFeedbackInput = {
action?: ReactNode,
};

function addErrorFeedback(
state: any,
{ message, variant = alertVariants.critical as keyof typeof alertVariants, action }: ErrorFeedbackInput,
) {
return [
...state,
{
message,
action,
feedbackType: 'ERROR',
variant,
},
];
}
const getErrorFeedback = ({
message,
variant = 'critical',
action,
}: ErrorFeedbackInput) => ({
id: uuid(),
message,
action,
feedbackType: 'ERROR' as const,
variant,
});

function getErrorFeedback(
{ message, variant = alertVariants.critical as keyof typeof alertVariants, action }: ErrorFeedbackInput,
) {
return {
message,
action,
feedbackType: 'ERROR',
variant,
};
}
const addErrorFeedback = (input: ErrorFeedbackInput) => [getErrorFeedback(input)];

export const getFeedbackDesc = (appUpdaters: Updaters) => createReducerDescription({
...appUpdaters,
Expand All @@ -74,80 +63,61 @@ export const getFeedbackDesc = (appUpdaters: Updaters) => createReducerDescripti
newState.shift();
return newState;
},
[dataEntryActionTypes.COMPLETE_EVENT_ERROR]: (state, action) =>
addErrorFeedback(state, {
[dataEntryActionTypes.COMPLETE_EVENT_ERROR]: (_state, action) =>
addErrorFeedback({
message: action.payload.error,
action: action.payload.action,
}),
[enrollmentActionTypes.ENROLLMENT_LOAD_FAILED]: (state, action) =>
addErrorFeedback(state, action.payload),
[workingListsCommonActionTypes.LIST_VIEW_INIT_ERROR]: (state, action) =>
addErrorFeedback(state, action.payload.errorMessage),
[newEventDataEntryActionTypes.SAVE_FAILED_FOR_NEW_EVENT_AFTER_RETURNED_TO_MAIN_PAGE]: (state, action) => {
[enrollmentActionTypes.ENROLLMENT_LOAD_FAILED]: (_state, action) =>
addErrorFeedback(action.payload),
[workingListsCommonActionTypes.LIST_VIEW_INIT_ERROR]: (_state, action) =>
addErrorFeedback({ message: action.payload.errorMessage }),
[newEventDataEntryActionTypes.SAVE_FAILED_FOR_NEW_EVENT_AFTER_RETURNED_TO_MAIN_PAGE]: (_state, action) => {
const error = action.payload;
const errorMessage = isString(error) ? error : error.message;
const errorObject = isObject(error) ? error : null;
log.error(errorCreator(errorMessage || 'Error saving event')(errorObject));
const newState = [
...state,
getErrorFeedback({ message: i18n.t('Could not save event') }),
];
return newState;
return addErrorFeedback({ message: i18n.t('Could not save event') });
},
[workingListsCommonActionTypes.LIST_UPDATE_ERROR]: (state, action) => [
...state,
getErrorFeedback({ message: action.payload.errorMessage }),
],
[eventWorkingListsActionTypes.EVENT_DELETE_ERROR]: state => [
...state,
getErrorFeedback({ message: i18n.t('Could not delete event') }),
],

[workingListsCommonActionTypes.TEMPLATE_UPDATE_ERROR]: state => [
...state,
getErrorFeedback({ message: i18n.t('Could not save working list') }),
],
[workingListsCommonActionTypes.TEMPLATE_ADD_ERROR]: state => [
...state,
getErrorFeedback({ message: i18n.t('Could not add working list') }),
],
[workingListsCommonActionTypes.TEMPLATE_DELETE_ERROR]: state => [
...state,
getErrorFeedback({ message: i18n.t('Could not delete working list') }),
],
[asyncHandlerActionTypes.ASYNC_UPDATE_FIELD_FAILED]: (state, { payload }) =>
addErrorFeedback(state, { message: payload.message }),
[newEventDataEntryActionTypes.SAVE_FAILED_FOR_NEW_EVENT_ADD_ANOTHER]: (state, action) => {
[workingListsCommonActionTypes.LIST_UPDATE_ERROR]: (_state, action) =>
addErrorFeedback({ message: action.payload.errorMessage }),
[eventWorkingListsActionTypes.EVENT_DELETE_ERROR]: () =>
addErrorFeedback({ message: i18n.t('Could not delete event') }),
[workingListsCommonActionTypes.TEMPLATE_UPDATE_ERROR]: () =>
addErrorFeedback({ message: i18n.t('Could not save working list') }),
[workingListsCommonActionTypes.TEMPLATE_ADD_ERROR]: () =>
addErrorFeedback({ message: i18n.t('Could not add working list') }),
[workingListsCommonActionTypes.TEMPLATE_DELETE_ERROR]: () =>
addErrorFeedback({ message: i18n.t('Could not delete working list') }),
[asyncHandlerActionTypes.ASYNC_UPDATE_FIELD_FAILED]: (_state, { payload }) =>
addErrorFeedback({ message: payload.message }),
[newEventDataEntryActionTypes.SAVE_FAILED_FOR_NEW_EVENT_ADD_ANOTHER]: (_state, action) => {
const error = action.payload;
const errorMessage = isString(error) ? error : error.message;
const errorObject = isObject(error) ? error : null;
log.error(errorCreator(errorMessage || 'Error saving event')(errorObject));
const newState = [
...state,
getErrorFeedback({ message: i18n.t('Could not save event') }),
];
return newState;
return addErrorFeedback({ message: i18n.t('Could not save event') });
},
[dataEntryActionTypes.DATA_ENTRY_RELATIONSHIP_ALREADY_EXISTS]: (state, action) =>
addErrorFeedback(state, { message: action.payload.message }),
[viewEventNewRelationshipActionTypes.EVENT_RELATIONSHIP_ALREADY_EXISTS]: (state, action) =>
addErrorFeedback(state, { message: action.payload.message }),
[registrationSectionActionTypes.ORG_UNIT_SEARCH_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Organisation unit search failed.') }),
[registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_SAVE_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Error saving tracked entity instance') }),
[registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Error saving enrollment') }),
[enrollmentSiteActionTypes.SAVE_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Error saving the enrollment event') }),
[editEventActionTypes.DELETE_EVENT_DATA_ENTRY_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Error deleting the enrollment event') }),
[editEventDataEntryAction.SAVE_EDIT_EVENT_DATA_ENTRY_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Error editing the event, the changes made were not saved') }),
[enrollmentSiteActionTypes.ERROR_ENROLLMENT]: (state, action) =>
addErrorFeedback(state, { message: i18n.t(action.payload.message) }),
[viewEventActionTypes.ASSIGNEE_SAVE_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Error updating the Assignee') }),
[enrollmentEditEventActionTypes.ASSIGNEE_SAVE_FAILED]: state =>
addErrorFeedback(state, { message: i18n.t('Error updating the Assignee') }),
[dataEntryActionTypes.DATA_ENTRY_RELATIONSHIP_ALREADY_EXISTS]: (_state, action) =>
addErrorFeedback({ message: action.payload.message }),
[viewEventNewRelationshipActionTypes.EVENT_RELATIONSHIP_ALREADY_EXISTS]: (_state, action) =>
addErrorFeedback({ message: action.payload.message }),
[registrationSectionActionTypes.ORG_UNIT_SEARCH_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Organisation unit search failed.') }),
[registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_SAVE_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Error saving tracked entity instance') }),
[registrationFormActionTypes.NEW_TRACKED_ENTITY_INSTANCE_WITH_ENROLLMENT_SAVE_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Error saving enrollment') }),
[enrollmentSiteActionTypes.SAVE_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Error saving the enrollment event') }),
[editEventActionTypes.DELETE_EVENT_DATA_ENTRY_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Error deleting the enrollment event') }),
[editEventDataEntryAction.SAVE_EDIT_EVENT_DATA_ENTRY_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Error editing the event, the changes made were not saved') }),
[enrollmentSiteActionTypes.ERROR_ENROLLMENT]: (_state, action) =>
addErrorFeedback({ message: i18n.t(action.payload.message) }),
[viewEventActionTypes.ASSIGNEE_SAVE_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Error updating the Assignee') }),
[enrollmentEditEventActionTypes.ASSIGNEE_SAVE_FAILED]: () =>
addErrorFeedback({ message: i18n.t('Error updating the Assignee') }),
}, 'feedbacks', []);
20 changes: 10 additions & 10 deletions src/reducers/descriptions/feedback.reducerDescription.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import i18n from '@dhis2/d2-i18n';
import uuid from 'd2-utilizr/lib/uuid';
import { getFeedbackDesc } from 'capture-core/reducers/descriptions/feedback.reducerDescriptionGetter';
import { getMainStorageController } from 'capture-core/storageControllers';
import { appStartActionTypes } from '../../components/AppStart';
Expand All @@ -7,17 +8,16 @@ export const feedbackDesc = getFeedbackDesc({
[appStartActionTypes.APP_LOAD_SUCESS]: (state) => {
const storageController = getMainStorageController();
if (storageController.Adapters[0] !== storageController.adapterType) {
return [
...state, {
message: {
title: i18n.t('Compatibility mode'),
// eslint-disable-next-line max-len
content: i18n.t('This app is currently running in compatibility mode due to browser restrictions. For better performance, use another browser or exit private mode if this is currently in use.'),
},
feedbackType: 'ERROR',
displayType: 'dialog',
return [{
id: uuid(),
message: {
title: i18n.t('Compatibility mode'),
// eslint-disable-next-line max-len
content: i18n.t('This app is currently running in compatibility mode due to browser restrictions. For better performance, use another browser or exit private mode if this is currently in use.'),
},
];
feedbackType: 'ERROR',
displayType: 'dialog',
}];
}
return state;
},
Expand Down
Loading