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

Local units delete modal #1587

Merged
merged 4 commits into from
Dec 17, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"namespace": "localUnitDeleteModal",
"strings": {
"localUnitsDeleteSubmitLabel": "Submit",
"deleteSuccessMessage": "{localUnitName} was deleted.",
"deleteFailureMessage": "Failed to validate {localUnitName}",
"deleteLocalUnitChooseMessage": "Choose the reason to delete local unit.",
"deleteLocalUnitReason": "Explain the reason why the local unit is being deleted.",
"deleteLocalUnitHeading": "Are you sure you want to delete \"{localUnitName}\"?"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,198 @@
import {
useCallback,
useMemo,
} from 'react';
import {
Button,
Modal,
RadioInput,
TextArea,
} from '@ifrc-go/ui';
import { useTranslation } from '@ifrc-go/ui/hooks';
import { resolveToString } from '@ifrc-go/ui/utils';
import {
createSubmitHandler,
getErrorObject,
ObjectSchema,
PartialForm,
requiredStringCondition,
useForm,
} from '@togglecorp/toggle-form';

import type { GlobalEnums } from '#contexts/domain';
import useAuth from '#hooks/domain/useAuth';
import useGlobalEnums from '#hooks/domain/useGlobalEnums';
import useAlert from '#hooks/useAlert';
import {
GoApiBody,
useLazyRequest,
} from '#utils/restRequest';

import i18n from './i18n.json';
import styles from './styles.module.css';

type DeprecateReason = NonNullable<GlobalEnums['local_units_deprecate_reason']>[number];

type LocalUnitDeprecateBody = GoApiBody<'/api/v2/local-units/{id}/deprecate/', 'POST'>;

type DeprecateFormType = PartialForm<LocalUnitDeprecateBody>;
type FormSchema = ObjectSchema<DeprecateFormType>;
type FormSchemaFields = ReturnType<FormSchema['fields']>;

const deprecateReasonKeySelector = (
item: DeprecateReason,
) => item.key;

const deprecateReasonLabelSelector = (
item: DeprecateReason,
) => item.value;

const defaultFormValue: DeprecateFormType = {
};

const schema: FormSchema = {
fields: (): FormSchemaFields => ({
deprecated_reason: {
required: true,
},
deprecated_reason_overview: {
required: true,
requiredValidation: requiredStringCondition,
},
}),
};

interface Props {
localUnitId: number;
onDeleteActionSuccess?: () => void;
onClose: () => void;
localUnitName: string;
disabled?: boolean;
}

function LocalUnitDeleteModal(props: Props) {
const strings = useTranslation(i18n);
const {
localUnitId,
localUnitName,
onDeleteActionSuccess,
onClose,
disabled,
} = props;

const {
local_units_deprecate_reason: deprecateReasonOptions,
} = useGlobalEnums();

const {
value,
error: formError,
setFieldValue,
setError,
validate,
} = useForm(schema, { value: defaultFormValue });

const error = useMemo(
() => getErrorObject(formError),
[formError],
);

const { isAuthenticated } = useAuth();

const hasDeletePermission = isAuthenticated;
samshara marked this conversation as resolved.
Show resolved Hide resolved

const alert = useAlert();

const {
pending: deleteLocalUnitPending,
trigger: deleteLocalUnit,
} = useLazyRequest({
method: 'POST',
url: '/api/v2/local-units/{id}/deprecate/',
body: (body: LocalUnitDeprecateBody) => body,
pathVariables: { id: localUnitId },
onSuccess: () => {
const validationMessage = resolveToString(
strings.deleteSuccessMessage,
{ localUnitName },
);
alert.show(
validationMessage,
{ variant: 'success' },
);
if (onDeleteActionSuccess) {
onDeleteActionSuccess();
}
},
onFailure: (response) => {
const {
value: { messageForNotification },
debugMessage,
} = response;

alert.show(
resolveToString(
strings.deleteFailureMessage,
{ localUnitName },
),
{
variant: 'danger',
description: messageForNotification,
debugMessage,
},
);
},
});

const handleFormSubmit = useCallback(
(formValues: DeprecateFormType) => {
deleteLocalUnit(formValues as LocalUnitDeprecateBody);
},
[deleteLocalUnit],
);

return (
<Modal
heading={resolveToString(
strings.deleteLocalUnitHeading,
{ localUnitName: localUnitName ?? '' },
samshara marked this conversation as resolved.
Show resolved Hide resolved
)}
withHeaderBorder
childrenContainerClassName={styles.modalChildren}
onClose={onClose}
footerActions={(
<Button
name={undefined}
onClick={createSubmitHandler(validate, setError, handleFormSubmit)}
disabled={deleteLocalUnitPending || !hasDeletePermission}
>
{strings.localUnitsDeleteSubmitLabel}
</Button>
)}
>
<RadioInput
required
name="deprecated_reason"
listContainerClassName={styles.radioList}
value={value.deprecated_reason}
label={strings.deleteLocalUnitChooseMessage}
onChange={setFieldValue}
options={deprecateReasonOptions}
keySelector={deprecateReasonKeySelector}
labelSelector={deprecateReasonLabelSelector}
error={error?.deprecated_reason}
/>
<TextArea
required
label={strings.deleteLocalUnitReason}
name="deprecated_reason_overview"
disabled={disabled}
value={value.deprecated_reason_overview}
onChange={setFieldValue}
error={error?.deprecated_reason_overview}
/>
</Modal>
);
}

export default LocalUnitDeleteModal;
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
.modal-children {
display: flex;
flex-direction: column;
gap: var(--go-ui-spacing-md);
}

.radio-list {
flex-direction: column;
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
"otherProfiles": "Other profiles",
"commentsNS": "Comments by the NS",
"submitButtonLabel": "Submit",
"editButtonLabel": "Edit"
"editButtonLabel": "Edit",
"localUnitDeleteButtonLabel": "Delete"
}
}
Loading
Loading