Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add revert changes button in local unit form #1588

Merged
merged 3 commits into from
Dec 18, 2024
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 @@ -3,7 +3,9 @@
"strings": {
"lastUpdateLabel": "Last update: {modifiedAt} by {modifiedBy}",
"successMessage": "Local unit added successfully!",
"revertChangesSuccessMessage": "Local unit reverted successfully!",
"failedMessage": "Failed to add local unit",
"revertChangesFailedMessage": "Failed to revert changes in the local unit",
"updateMessage": "Local unit updated successfully!",
"updateFailedMessage": "Failed to update local unit",
"specialitiesAndCapacityTitle": "Specialities & Capacity",
Expand Down Expand Up @@ -76,6 +78,10 @@
"editButtonLabel": "Edit",
"localUnitDeleteButtonLabel": "Delete",
"doneButtonLabel": "Done",
"revertButtonLabel": "Revert",
"reasonLabel": "Reason",
"revertChangesModalHeading": "Revert the Changes",
"revertChangesContentQuestion": "Are you sure you want to have these changes revert in this project?",
"confirmChangesModalHeading": "Confirm the Changes",
"confirmChangesContentQuestion": "Are you sure you want to have these changes in this project?",
"latitude": "Latitude",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import {
isNotDefined,
} from '@togglecorp/fujs';
import {
createSubmitHandler,
getErrorObject,
getErrorString,
removeNull,
Expand Down Expand Up @@ -73,7 +74,10 @@ import LocalUnitDeleteModal from '../../LocalUnitDeleteModal';
import LocalUnitValidateButton from '../../LocalUnitValidateButton';
import schema, {
type LocalUnitsRequestPostBody,
LocalUnitsRevertRequestPostBody,
type PartialLocalUnits,
PartialLocalUnitsRevertForm,
revertSchema,
TYPE_HEALTH_CARE,
} from './schema';
import useLocalUnitFormFieldLabels from './useLocalUnitFormFieldLabels';
Expand Down Expand Up @@ -104,6 +108,7 @@ type ChangedFormField = {
const VisibilityOptions = (option: VisibilityOptions) => option.key;

const defaultHealthValue = {};
const defaultRevertChangesValue: PartialLocalUnitsRevertForm = {};

interface FormGridProps {
className?: string;
Expand Down Expand Up @@ -232,7 +237,7 @@ interface Props {

function LocalUnitsForm(props: Props) {
const {
readOnly = false,
readOnly: readOnlyFromProps = false,
onSuccess,
onEditButtonClick,
localUnitId,
Expand All @@ -247,6 +252,11 @@ function LocalUnitsForm(props: Props) {
setFalse: setShowChangesModalFalse,
}] = useBooleanState(false);

const [showRevertChangesModal, {
setTrue: setShowRevertChangesModalTrue,
setFalse: setShowRevertChangesModalFalse,
}] = useBooleanState(false);

const alert = useAlert();
const strings = useTranslation(i18n);
const formFieldsContainerRef = useRef<HTMLDivElement>(null);
Expand Down Expand Up @@ -295,6 +305,17 @@ function LocalUnitsForm(props: Props) {
},
);

const {
value: revertChangesValue,
error: revertChangesError,
setFieldValue: setRevertChangesFieldValue,
validate: revertChangesValidate,
setError: setRevertChangesError,
} = useForm(
revertSchema,
{ value: defaultRevertChangesValue },
);

const [
localUnitChangedFormFields,
setLocalUnitChangedFormFields,
Expand Down Expand Up @@ -404,6 +425,10 @@ function LocalUnitsForm(props: Props) {
},
});

const readOnly = readOnlyFromProps
|| isNotDefined(localUnitDetailsResponse)
|| localUnitDetailsResponse.is_locked;

const {
response: localUnitsOptions,
pending: localUnitsOptionsPending,
Expand Down Expand Up @@ -521,6 +546,45 @@ function LocalUnitsForm(props: Props) {
[validate, localUnitId, setError, updateLocalUnit, addLocalUnit],
);

const {
pending: revertChangesPending,
trigger: revertChanges,
} = useLazyRequest({
method: 'POST',
url: '/api/v2/local-units/{id}/revert/',
pathVariables: isDefined(localUnitId) ? { id: localUnitId } : undefined,
body: (formFields: LocalUnitsRevertRequestPostBody) => formFields,
onSuccess: () => {
alert.show(
strings.revertChangesSuccessMessage,
{ variant: 'success' },
);
},
onFailure: (error) => {
const {
value: {
formErrors,
},
} = error;

setError(transformObjectError(formErrors, () => undefined));

alert.show(
strings.revertChangesFailedMessage,
{
variant: 'danger',
},
);
},
});

const handleRevertChangesFormSubmit = useCallback(
(formValues: PartialLocalUnitsRevertForm) => {
revertChanges(formValues as LocalUnitsRevertRequestPostBody);
},
[revertChanges],
);

const onDoneButtonClick = useCallback(
() => {
if (isDefined(localUnitDetailsResponse) && isDefined(localUnitsOptions)) {
Expand All @@ -543,6 +607,7 @@ function LocalUnitsForm(props: Props) {

const error = getErrorObject(formError);
const healthFormError = getErrorObject(error?.health);
const revertChangesFormError = getErrorObject(revertChangesError);

const submitButton = readOnly ? null : (
<Button
Expand Down Expand Up @@ -575,7 +640,9 @@ function LocalUnitsForm(props: Props) {

return (
<div className={styles.localUnitsForm}>
{readOnly && isDefined(actionsContainerRef.current) && (
{isDefined(localUnitDetailsResponse)
&& !readOnly
&& isDefined(actionsContainerRef.current) && (
tnagorra marked this conversation as resolved.
Show resolved Hide resolved
<Portal container={actionsContainerRef.current}>
{(environment !== 'production') && (
<Button
Expand Down Expand Up @@ -680,6 +747,15 @@ function LocalUnitsForm(props: Props) {
readOnly={!pristine}
/>
)}
{localUnitDetailsResponse.is_locked && (
<Button
name={undefined}
onClick={setShowRevertChangesModalTrue}
variant="secondary"
>
{strings.revertButtonLabel}
</Button>
)}
</div>
)}
</FormGrid>
Expand Down Expand Up @@ -1336,6 +1412,35 @@ function LocalUnitsForm(props: Props) {
localUnitId={localUnitId}
/>
)}
{showRevertChangesModal && (
<Modal
heading={strings.revertChangesModalHeading}
headerDescription={strings.revertChangesContentQuestion}
onClose={setShowRevertChangesModalFalse}
footerActions={(
<Button
name={undefined}
onClick={createSubmitHandler(
revertChangesValidate,
setRevertChangesError,
handleRevertChangesFormSubmit,
)}
disabled={revertChangesPending}
>
{strings.submitButtonLabel}
</Button>
)}
>
<TextArea
name="reason"
required
label={strings.reasonLabel}
value={revertChangesValue.reason}
onChange={setRevertChangesFieldValue}
error={getErrorString(revertChangesFormError?.reason)}
/>
</Modal>
)}
{showChangesModal && (
<Modal
heading={strings.confirmChangesModalHeading}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
type ObjectSchema,
type PartialForm,
type PurgeNull,
requiredStringCondition,
urlCondition,
} from '@togglecorp/toggle-form';

Expand All @@ -28,6 +29,8 @@ export type LocalUnitsRequestPostBody = GoApiBody<'/api/v2/local-units/', 'POST'
lat: number;
}
};

export type LocalUnitsRevertRequestPostBody = GoApiBody<'/api/v2/local-units/{id}/revert/', 'POST'>;
type TypeOfLocalUnits = components<'read'>['schemas']['LocalUnitType']['code'];

export type PartialLocalUnits = PartialForm<
Expand All @@ -42,6 +45,19 @@ export const TYPE_HEALTH_CARE = 2 satisfies TypeOfLocalUnits;
// const TYPE_TRAINING_AND_EDUCATION = 5 satisfies TypeOfLocalUnits;
// const TYPE_OTHER = 6 satisfies TypeOfLocalUnits;

export type PartialLocalUnitsRevertForm = PartialForm<LocalUnitsRevertRequestPostBody>;
type LocalUnitsRevertFormSchema = ObjectSchema<PartialLocalUnitsRevertForm>;
type LocalUnitRevertSchemaFields = ReturnType<LocalUnitsRevertFormSchema['fields']>;

export const revertSchema: LocalUnitsRevertFormSchema = {
fields: (): LocalUnitRevertSchemaFields => ({
reason: {
required: true,
requiredValidation: requiredStringCondition,
},
}),
};

type LocalUnitsFormSchema = ObjectSchema<PartialLocalUnits>;
type LocalUnitsFormSchemaFields = ReturnType<LocalUnitsFormSchema['fields']>;
type LocalUnitsHealthFormSchema = ObjectSchema<NonNullable<PartialLocalUnits['health']>>;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ export interface Props {
isValidated: boolean;
onDeleteActionSuccess: () => void;
onValidationActionSuccess: () => void;
isLocked: boolean;
}

function LocalUnitsTableActions(props: Props) {
Expand All @@ -40,6 +41,7 @@ function LocalUnitsTableActions(props: Props) {
isValidated,
onValidationActionSuccess,
onDeleteActionSuccess,
isLocked,
} = props;

const strings = useTranslation(i18n);
Expand Down Expand Up @@ -120,14 +122,6 @@ function LocalUnitsTableActions(props: Props) {
>
{strings.localUnitsView}
</DropdownMenuItem>
<DropdownMenuItem
type="button"
name={localUnitId}
onClick={handleEditLocalUnitClick}
disabled={isGuestUser}
>
{strings.localUnitsEdit}
</DropdownMenuItem>
{hasDeletePermission && (
<DropdownMenuItem
type="button"
Expand All @@ -137,6 +131,16 @@ function LocalUnitsTableActions(props: Props) {
{strings.localUnitsDelete}
</DropdownMenuItem>
)}
{!isLocked && (
<DropdownMenuItem
type="button"
name={localUnitId}
onClick={handleEditLocalUnitClick}
disabled={isGuestUser}
>
{strings.localUnitsEdit}
</DropdownMenuItem>
)}
</>
)}
>
Expand All @@ -153,6 +157,7 @@ function LocalUnitsTableActions(props: Props) {
name={localUnitId}
variant="tertiary"
onClick={handleViewLocalUnitClick}
disabled={isGuestUser}
>
{strings.localUnitsView}
</Button>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ function LocalUnitsTable(props: Props) {
countryId: item.country,
localUnitId: item.id,
isValidated: item.validated,
isLocked: item.is_locked,
localUnitName: getFirstTruthyString(
item.local_branch_name,
item.english_branch_name,
Expand Down
Loading