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
19 changes: 13 additions & 6 deletions app/components/CategoryModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import useFilterState from '#hooks/useFilterState';
import {
errorMessage,
idSelector,
transformToFormError,
} from '#utils/common';

type ThematicArea = NonNullable<NonNullable<ThematicAreasQuery['thematicAreas']>['results'][number]>;
Expand Down Expand Up @@ -146,11 +147,17 @@ function CategoryModal(props: Props) {
const actionPending = createPending || updatePending || deletePending;

const handleResult = useCallback((
ok: boolean | undefined,
result: { ok?: boolean | null; errors?: unknown } | null | undefined,
successMessage: string,
) => {
if (!ok) {
alert.show(errorMessage, { variant: 'danger' });
if (!result?.ok) {
const serverErrors = isDefined(result?.errors)
? transformToFormError(result?.errors as Parameters<typeof transformToFormError>[0])
: undefined;
const messages = serverErrors
? Object.values(serverErrors).filter(isDefined).join(' ')
: undefined;
alert.show(messages || errorMessage, { variant: 'danger' });
return;
}
setCategoryName(undefined);
Expand All @@ -166,7 +173,7 @@ function CategoryModal(props: Props) {
return;
}
createThematicArea({ data: { name } }).then((resp) => {
handleResult(resp.data?.createThematicArea?.ok, 'Category added successfully');
handleResult(resp.data?.createThematicArea, 'Category added successfully');
}).catch(() => {
alert.show(errorMessage, { variant: 'danger' });
});
Expand All @@ -178,7 +185,7 @@ function CategoryModal(props: Props) {
return;
}
updateThematicArea({ id: editingId, data: { name } }).then((resp) => {
handleResult(resp.data?.updateThematicArea?.ok, 'Category updated successfully');
handleResult(resp.data?.updateThematicArea, 'Category updated successfully');
}).catch(() => {
alert.show(errorMessage, { variant: 'danger' });
});
Expand All @@ -196,7 +203,7 @@ function CategoryModal(props: Props) {

const handleDelete = useCallback((id: string) => {
deleteThematicArea({ id }).then((resp) => {
handleResult(resp.data?.deleteThematicArea?.ok, 'Category deleted successfully');
handleResult(resp.data?.deleteThematicArea, 'Category deleted successfully');
}).catch(() => {
alert.show(errorMessage, { variant: 'danger' });
});
Expand Down
59 changes: 0 additions & 59 deletions app/components/ConfirmModal/index.tsx

This file was deleted.

52 changes: 24 additions & 28 deletions app/components/EditDeleteActions/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,13 @@ import {
DeleteBinLineIcon,
EditTwoLineIcon,
} from '@ifrc-go/icons';
import { TableActions } from '@ifrc-go/ui';
import {
Button,
ConfirmButton,
TableActions,
} from '@ifrc-go/ui';
import { isDefined } from '@togglecorp/fujs';

import DropdownMenuItem from '#components/DropdownMenuItem';
import useRouting, { type RoutesMap } from '#hooks/useRouting';

export interface Props {
Expand Down Expand Up @@ -41,32 +44,25 @@ function EditDeleteActions(props: Props) {
}, [navigate, to, id, member, dashboard]);

return (
<TableActions
persistent
extraActions={(
<>
<DropdownMenuItem
name={undefined}
type="button"
before={<EditTwoLineIcon />}
onClick={handleEditClick}
persist
>
Edit
</DropdownMenuItem>
<DropdownMenuItem
name={id}
onConfirm={onDelete}
type="confirm-button"
before={<DeleteBinLineIcon />}
confirmMessage={`Are you sure you want to delete ${`"${itemTitle}"` || 'this item'}? This action cannot be undone.`}
persist
>
Delete
</DropdownMenuItem>
</>
)}
/>
<TableActions>
<Button
name={undefined}
onClick={handleEditClick}
title="Edit"
styleVariant="action"
>
<EditTwoLineIcon />
</Button>
<ConfirmButton
name={id}
onConfirm={onDelete}
confirmMessage={`Are you sure you want to delete ${`"${itemTitle}"` || 'this item'}? This action cannot be undone.`}
title="Delete"
styleVariant="action"
>
<DeleteBinLineIcon />
</ConfirmButton>
</TableActions>
);
}

Expand Down
78 changes: 78 additions & 0 deletions app/components/FileInput/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import { useCallback } from 'react';
import {
Description,
InlineLayout,
RawFileInput,
} from '@ifrc-go/ui';
import { isDefined } from '@togglecorp/fujs';
import { type Error } from '@togglecorp/toggle-form';

import NonFieldError from '#components/NonFieldError';
import useAlert from '#hooks/useAlert';

interface Props<N, T> {
name: N;
fileName?: string;
onChange: (file: File | undefined, name: N) => void;
error?: Error<T>;
maxSize?: number;
accept?: string;
disabled?: boolean;
placeholder?: string;
}

function FileInput<N, T>(props: Props<N, T>) {
const {
name,
fileName,
onChange,
error,
maxSize,
accept,
disabled,
placeholder = 'Please upload a file',
} = props;

const alert = useAlert();

const handleChange = useCallback(
(file: File | undefined, inputName: N) => {
if (isDefined(file) && isDefined(maxSize) && file.size > maxSize) {
alert.show(
`File must be ${Math.round(maxSize / (1024 * 1024))}MB or smaller`,
{ variant: 'danger' },
);
return;
}
onChange(file, inputName);
},
[alert, maxSize, onChange],
);

return (
<>
<InlineLayout
spacing="sm"
contentAlignment="center"
before={(
<RawFileInput
name={name}
onChange={handleChange}
accept={accept}
disabled={disabled}
styleVariant="outline"
>
{isDefined(fileName) ? 'Change file' : 'Upload file'}
</RawFileInput>
)}
>
<Description>
{isDefined(fileName) ? fileName : placeholder}
</Description>
</InlineLayout>
<NonFieldError error={error} />
</>
);
}

export default FileInput;
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import { useState } from 'react';
import {
SelectInput,
TextInput,
} from '@ifrc-go/ui';
import { type EntriesAsList } from '@togglecorp/toggle-form';

import RegionSearchMultiSelectInput, { type AdminAreaItem } from '#components/RegionSearchMultiSelectInput';
import { AdminAreaLevel } from '#generated/types/graphql';
import {
labelSelector,
statusFilterOptions,
Expand All @@ -21,20 +18,8 @@ export interface Props {
}

function CapacityAndResourcesFilter({ value, onChange }: Props) {
const [regionOptions, setRegionOptions] = useState<
AdminAreaItem[] | undefined | null
>([]);
return (
<>
<RegionSearchMultiSelectInput
name="regions"
placeholder="Region"
level={AdminAreaLevel.Region}
value={value.regions}
onOptionsChange={setRegionOptions}
options={regionOptions}
onChange={onChange}
/>
<SelectInput
name="isActive"
placeholder="Status"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@ import {
} from '@togglecorp/toggle-form';

import NonFieldError from '#components/NonFieldError';
import RegionSelectInput from '#components/RegionSelectInput';
import {
AdminAreaLevel,
type CapacityAndResourceCreateInput,
type CapacityAndResourceUpdateInput,
useCapacityAndResourceDetailQuery,
Expand Down Expand Up @@ -58,7 +56,6 @@ const capacityAndResourceSchema: FormSchema = {
requiredValidation: requiredStringCondition,
},
description: {},
region: {},
isActive: {},
order: {
required: true,
Expand Down Expand Up @@ -154,11 +151,7 @@ function CapacityAndResourcesForm() {
if (isNotDefined(data?.capacityAndResource)) {
return;
}
const { regionId, ...otherValues } = removeNull(data.capacityAndResource);
setValue({
...otherValues,
region: regionId ?? undefined,
});
setValue(removeNull(data.capacityAndResource));
}, [data, setValue]);

if (detailFetching) {
Expand Down Expand Up @@ -227,19 +220,6 @@ function CapacityAndResourcesForm() {
disabled={pending}
/>
</InputSection>
<InputSection
title="Region"
description="Select the region"
>
<RegionSelectInput
name="region"
level={AdminAreaLevel.Region}
value={value.region}
onChange={setFieldValue}
error={error?.region}
disabled={pending}
/>
</InputSection>
<InputSection
title="Status"
description="Choose if the capacity and resource is to be active or inactive"
Expand Down
Loading
Loading