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
4 changes: 4 additions & 0 deletions app/src/components/domain/ImageWithCaptionInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ interface Props<N> {
name: N;
url: SupportedPaths;
value: Value | null | undefined;
readOnly: boolean;
onChange: (value: SetValueArg<Value> | undefined, name: N) => void;
error: ObjectError<Value> | undefined;
fileIdToUrlMap: Record<number, string>;
Expand All @@ -44,6 +45,7 @@ interface Props<N> {
function ImageWithCaptionInput<const N extends string | number>(props: Props<N>) {
const {
className,
readOnly,
name,
value,
url,
Expand Down Expand Up @@ -92,6 +94,7 @@ function ImageWithCaptionInput<const N extends string | number>(props: Props<N>)
name="id"
accept="image/*"
value={value?.id}
readOnly={readOnly}
onChange={handleFileInputChange}
url={url}
fileIdToUrlMap={fileIdToUrlMap}
Expand All @@ -116,6 +119,7 @@ function ImageWithCaptionInput<const N extends string | number>(props: Props<N>)
className={styles.captionInput}
name="caption"
value={value?.caption}
readOnly={readOnly}
onChange={setFieldValue}
error={error?.caption}
placeholder={strings.imageWithCaptionEnterCaption}
Expand Down
6 changes: 3 additions & 3 deletions app/src/components/domain/LanguageMismatchMessage/i18n.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{
"namespace": "languageMismatchMessage",
"strings": {
"languageMismatchErrorTitle": "Edit not available in selected language!",
"languageMismatchErrorMessage": "This form was originally created in {originalLanguage} and cannot be edited in a different language!",
"languageMismatchHelpMessage": "Please change the language to {originalLanguage} to edit it!"
"languageMismatchErrorTitle": "Edit not available in {selectedLanguage} language!",
"languageMismatchErrorMessage": "This is because form was originally created in {originalLanguage} language and edits cannot be edited in the {selectedLanguage} language.",
"languageMismatchHelpMessage": "To make changes, please switch to the original language of the form."
}
}
17 changes: 8 additions & 9 deletions app/src/components/domain/LanguageMismatchMessage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,16 @@ interface Props {
// FIXME: typings should be fixed in the server
// this should be of type Language
originalLanguage: string | undefined;
selectedLanguage: Language;
}

function LanguageMismatchMessage(props: Props) {
const strings = useTranslation(i18n);

const {
title = strings.languageMismatchErrorTitle,
originalLanguage = 'en',
originalLanguage,
selectedLanguage,
} = props;

return (
Expand All @@ -32,16 +34,13 @@ function LanguageMismatchMessage(props: Props) {
resolveToString(
strings.languageMismatchErrorMessage,
// FIXME: this should not require cast
{ originalLanguage: languageNameMapEn[originalLanguage as Language] ?? '--' },
)
}
actions={
resolveToString(
strings.languageMismatchHelpMessage,
// FIXME: this should not require cast
{ originalLanguage: languageNameMapEn[originalLanguage as Language] ?? '--' },
{
originalLanguage: languageNameMapEn[originalLanguage as Language] ?? '--',
selectedLanguage: languageNameMapEn[selectedLanguage] ?? '--',
},
)
}
actions={strings.languageMismatchHelpMessage}
/>
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface Props<N> {
label: React.ReactNode;
icons?: React.ReactNode;
actions?: React.ReactNode;
readOnly?: boolean;
disabled?: boolean;
}

Expand All @@ -62,6 +63,7 @@ function MultiImageWithCaptionInput<const N extends string | number>(props: Prop
label,
icons,
actions,
readOnly,
disabled,
} = props;

Expand Down Expand Up @@ -139,6 +141,7 @@ function MultiImageWithCaptionInput<const N extends string | number>(props: Prop
icons={icons}
actions={actions}
withoutPreview
readOnly={readOnly}
disabled={disabled}
>
{label}
Expand Down Expand Up @@ -168,7 +171,7 @@ function MultiImageWithCaptionInput<const N extends string | number>(props: Prop
ariaLabel={strings.removeImagesButtonTitle}
variant="secondary"
spacing="none"
disabled={disabled}
disabled={disabled || readOnly}
>
<DeleteBinLineIcon />
</IconButton>
Expand All @@ -187,6 +190,7 @@ function MultiImageWithCaptionInput<const N extends string | number>(props: Prop
onChange={handleCaptionChange}
error={imageError?.caption}
placeholder={strings.enterCaptionPlaceholder}
readOnly={readOnly}
disabled={disabled}
/>
</div>
Expand Down
6 changes: 5 additions & 1 deletion app/src/components/domain/SourceInformationInput/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ interface Props {
onRemove: (index: number) => void;
index: number;
disabled?: boolean;
readOnly: boolean;
}

function SourceInformationInput(props: Props) {
Expand All @@ -41,6 +42,7 @@ function SourceInformationInput(props: Props) {
index,
onRemove,
disabled,
readOnly,
} = props;

const strings = useTranslation(i18n);
Expand Down Expand Up @@ -92,6 +94,7 @@ function SourceInformationInput(props: Props) {
value={value.source_name}
error={error?.source_name}
onChange={onFieldChange}
readOnly={readOnly}
disabled={disabled}
/>
<TextInput
Expand All @@ -101,14 +104,15 @@ function SourceInformationInput(props: Props) {
value={value.source_link}
error={error?.source_link}
onChange={handleSourceFieldChange}
readOnly={readOnly}
disabled={disabled}
/>
<Button
className={styles.removeButton}
name={index}
onClick={onRemove}
variant="tertiary"
disabled={disabled}
disabled={disabled || readOnly}
title={strings.sourceInformationDeleteButton}
>
<DeleteBinTwoLineIcon />
Expand Down
2 changes: 1 addition & 1 deletion app/src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ export const FONT_FAMILY_HEADER = 'Montserrat';
// FIXME: fix typing in server (medium priority)
// This should not be the same as OperationType.
export type DrefStatus = components<'read'>['schemas']['DrefDrefStatusEnumKey'];
// const DREF_STATUS_COMPLETED = 1 satisfies DrefStatus;
export const DREF_STATUS_DRAFT = 1 satisfies DrefStatus;
export const DREF_STATUS_FINALIZED = 3 satisfies DrefStatus;
export const DREF_STATUS_APPROVED = 4 satisfies DrefStatus;

export type TypeOfDrefEnum = components<'read'>['schemas']['DrefDrefDrefTypeEnumKey'];
Expand Down
4 changes: 4 additions & 0 deletions app/src/views/AccountMyFormsDref/DrefTableActions/i18n.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"namespace": "accountMyFormsDref",
"strings": {
"dropdownActionApproveLabel": "Approved",
"dropdownActionFinalizeLabel": "Finalize",
"dropdownActionAllocationFormLabel": "Allocation Form",
"dropdownActionAddOpsUpdateLabel": "Add Operational Update",
"dropdownActionCreateFinalReportLabel": "Create Final Report",
Expand All @@ -10,10 +11,13 @@
"dropdownActionEditLabel": "Edit",
"drefApprovalSuccessTitle": "Successfully approved the DREF!",
"drefApprovalFailureTitle": "Failed to approve the DREF!",
"drefFinalizeSuccessTitle": "Successfully finalized the DREF!",
"drefFinalizeFailureTitle": "Failed to finalize the DREF!",
"drefApprovalInProgressTitle": "Approval in progress...",
"drefAccountCouldNotCreate": "Could not create new operational update",
"drefAccountCouldNotCreateFinalReport": "Could not create final report",
"drefAccountConfirmMessage": "You're about to Approve this DREF. Once approved, it can no longer be edited. Are you sure you want to Approve?",
"drefAccountFinalizeConfirmMessage": "You're about to Finalize this DREF. Once finalize, it can no longer be edited. Are you sure you want to Finalize?",
"dropdownActionImminentNewOpsUpdateConfirmationHeading": "Confirm addition of Operational Update",
"dropdownActionImminentNewOpsUpdateConfirmationMessage": "The DREF type will be changed to Response (from Imminent) for the Operational Update. Once created, you'll be able to change it to other types except Imminent. Are you sure you want to add an Operational Update?"
}
Expand Down
137 changes: 133 additions & 4 deletions app/src/views/AccountMyFormsDref/DrefTableActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import useAlert from '#hooks/useAlert';
import useRouting from '#hooks/useRouting';
import {
DREF_STATUS_DRAFT,
DREF_STATUS_FINALIZED,
DREF_TYPE_IMMINENT,
DREF_TYPE_LOAN,
type DrefStatus,
Expand Down Expand Up @@ -255,6 +256,96 @@ function DrefTableActions(props: Props) {
},
});

const {
trigger: finalizeDref,
pending: finalizeDrefPending,
} = useLazyRequest({
method: 'POST',
url: '/api/v2/dref/{id}/finalize/',
pathVariables: { id: String(id) },
body: () => ({} as never),
onSuccess: () => {
alert.show(
strings.drefFinalizeSuccessTitle,
{ variant: 'success' },
);
if (onPublishSuccess) {
onPublishSuccess();
}
},
onFailure: ({
value: { messageForNotification },
}) => {
alert.show(
strings.drefFinalizeFailureTitle,
{
description: messageForNotification,
variant: 'danger',
},
);
},
});

const {
trigger: finalizeOpsUpdate,
pending: finalizeOpsUpdatePending,
} = useLazyRequest({
method: 'POST',
url: '/api/v2/dref-op-update/{id}/finalize/',
pathVariables: { id: String(id) },
body: () => ({} as never),
onSuccess: () => {
alert.show(
strings.drefFinalizeSuccessTitle,
{ variant: 'success' },
);
if (onPublishSuccess) {
onPublishSuccess();
}
},
onFailure: ({
value: { messageForNotification },
}) => {
alert.show(
strings.drefFinalizeFailureTitle,
{
description: messageForNotification,
variant: 'danger',
},
);
},
});

const {
trigger: finalizeFinalReport,
pending: finalizeFinalReportPending,
} = useLazyRequest({
method: 'POST',
url: '/api/v2/dref-final-report/{id}/finalize/',
pathVariables: { id: String(id) },
body: () => ({} as never),
onSuccess: () => {
alert.show(
strings.drefFinalizeSuccessTitle,
{ variant: 'success' },
);
if (onPublishSuccess) {
onPublishSuccess();
}
},
onFailure: ({
value: { messageForNotification },
}) => {
alert.show(
strings.drefFinalizeFailureTitle,
{
description: messageForNotification,
variant: 'danger',
},
);
},
});

// FIXME: the type should be fixed on the server
type OpsUpdateRequestBody = GoApiBody<'/api/v2/dref-op-update/', 'POST'>;

Expand Down Expand Up @@ -368,6 +459,26 @@ function DrefTableActions(props: Props) {
],
);

const handleFinalizeClick = useCallback(
() => {
if (applicationType === 'DREF') {
finalizeDref(null);
} else if (applicationType === 'OPS_UPDATE') {
finalizeOpsUpdate(null);
} else if (applicationType === 'FINAL_REPORT') {
finalizeFinalReport(null);
} else {
applicationType satisfies never;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need this?
Also, lets add a alert saying failed to finalize if none of the types match.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it is handled in useRequest

}
},
[
applicationType,
finalizeDref,
finalizeOpsUpdate,
finalizeFinalReport,
],
);

const handleDrefAllocationExport = useCallback(
() => {
if (applicationType === 'DREF') {
Expand All @@ -385,13 +496,18 @@ function DrefTableActions(props: Props) {

const canDownloadAllocation = (applicationType === 'DREF' || applicationType === 'OPS_UPDATE');

const canApprove = status === DREF_STATUS_DRAFT && hasPermissionToApprove;
const canApprove = status === DREF_STATUS_FINALIZED && hasPermissionToApprove;

const canFinalize = status === DREF_STATUS_DRAFT && hasPermissionToApprove;

const shouldConfirmImminentAddOpsUpdate = drefType === DREF_TYPE_IMMINENT && isDrefImminentV2;

const disabled = fetchingDref
|| fetchingOpsUpdate
|| publishDrefPending
|| finalizeDrefPending
|| finalizeOpsUpdatePending
|| finalizeFinalReportPending
|| publishOpsUpdatePending
|| publishFinalReportPending
|| createOpsUpdatePending
Expand All @@ -402,6 +518,19 @@ function DrefTableActions(props: Props) {
persistent
extraActions={(
<>
{canFinalize && (
<DropdownMenuItem
name={undefined}
type="confirm-button"
icons={<CheckLineIcon className={styles.icon} />}
confirmMessage={strings.drefAccountFinalizeConfirmMessage}
onConfirm={handleFinalizeClick}
disabled={disabled}
persist
>
{strings.dropdownActionFinalizeLabel}
</DropdownMenuItem>
)}
{canApprove && (
<DropdownMenuItem
name={undefined}
Expand Down Expand Up @@ -494,7 +623,7 @@ function DrefTableActions(props: Props) {
</>
)}
>
{status === DREF_STATUS_DRAFT && applicationType === 'DREF' && (
{(status === DREF_STATUS_DRAFT || status === DREF_STATUS_FINALIZED) && applicationType === 'DREF' && (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can the person edit after its finalized?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes

<Link
to="drefApplicationForm"
urlParams={{ drefId: id }}
Expand All @@ -504,7 +633,7 @@ function DrefTableActions(props: Props) {
{strings.dropdownActionEditLabel}
</Link>
)}
{status === DREF_STATUS_DRAFT && applicationType === 'OPS_UPDATE' && (
{(status === DREF_STATUS_DRAFT || status === DREF_STATUS_FINALIZED) && applicationType === 'OPS_UPDATE' && (
<Link
to="drefOperationalUpdateForm"
urlParams={{ opsUpdateId: id }}
Expand All @@ -514,7 +643,7 @@ function DrefTableActions(props: Props) {
{strings.dropdownActionEditLabel}
</Link>
)}
{status === DREF_STATUS_DRAFT && applicationType === 'FINAL_REPORT' && (
{(status === DREF_STATUS_DRAFT || status === DREF_STATUS_FINALIZED) && applicationType === 'FINAL_REPORT' && (
<Link
to={isDrefImminentV2 ? 'drefFinalReportForm' : 'oldDrefFinalReportForm'}
urlParams={{ finalReportId: id }}
Expand Down
Loading