Skip to content
Open
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
12 changes: 12 additions & 0 deletions app/Root/config/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,16 @@ const documents: RouteConfig = {
load: () => import('#views/Documents'),
visibility: 'is-authenticated',
};
const createDocument: RouteConfig = {
path: '/documents/new',
load: () => import('#views/Documents/DocumentsForm'),
visibility: 'is-authenticated',
};
const editDocument: RouteConfig = {
path: '/documents/:id/edit',
load: () => import('#views/Documents/DocumentsForm'),
visibility: 'is-authenticated',
};
const onlineInteractive: RouteConfig = {
index: true,
path: '/online-interactive',
Expand Down Expand Up @@ -250,6 +260,8 @@ const routes = {
createResourceDashboard,
editResourceDashboard,
documents,
createDocument,
editDocument,
onlineInteractive,
createOnlineInteractive,
editOnlineInteractive,
Expand Down
1 change: 1 addition & 0 deletions app/Root/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ function RootContent() {

const globalEnumsContext: GlobalEnumsContextInterface = useMemo(() => ({
linkType: globalEnumsData?.enums.LinkType,
reportType: globalEnumsData?.enums.ReportType,
userRole: globalEnumsData?.enums.UserRole,
teamMemberSex: globalEnumsData?.enums.TeamMemberSex,
dashboardPage: globalEnumsData?.enums.DashboardPage,
Expand Down
4 changes: 4 additions & 0 deletions app/Root/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ export const GLOBAL_ENUMS = gql`
key
label
}
ReportType {
key
label
}
UserRole {
key
label
Expand Down
24 changes: 13 additions & 11 deletions app/components/FileInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import { useCallback } from 'react';
import {
useCallback,
useState,
} from 'react';
import {
Description,
InlineLayout,
InputError,
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';
import { MAX_REPORT_FILE_SIZE } from '#utils/common';

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;
Expand All @@ -27,26 +30,24 @@ function FileInput<N, T>(props: Props<N, T>) {
fileName,
onChange,
error,
maxSize,
accept,
disabled,
placeholder = 'Please upload a file',
} = props;

const alert = useAlert();
const [sizeError, setSizeError] = useState<string>();

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' },
);
if (isDefined(file) && file.size > MAX_REPORT_FILE_SIZE) {
setSizeError(`File must be less than ${MAX_REPORT_FILE_SIZE / (1024 * 1024)}MB`);
onChange(undefined, inputName);
return;
}
setSizeError(undefined);
onChange(file, inputName);
},
[alert, maxSize, onChange],
[onChange],
);

return (
Expand All @@ -70,6 +71,7 @@ function FileInput<N, T>(props: Props<N, T>) {
{isDefined(fileName) ? fileName : placeholder}
</Description>
</InlineLayout>
{isDefined(sizeError) && <InputError>{sizeError}</InputError>}
<NonFieldError error={error} />
</>
);
Expand Down
3 changes: 3 additions & 0 deletions app/contexts/GlobalEnumsContext.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@ import type {
AppEnumCollectionDashboardPage,
AppEnumCollectionLinkType,
AppEnumCollectionReportContentType,
AppEnumCollectionReportType,
AppEnumCollectionTeamMemberSex,
AppEnumCollectionUserRole,
} from '#generated/types/graphql';

export interface GlobalEnumsContextInterface {
linkType: AppEnumCollectionLinkType[] | undefined;
reportType: AppEnumCollectionReportType[] | undefined;
userRole: AppEnumCollectionUserRole[] | undefined;
teamMemberSex: AppEnumCollectionTeamMemberSex[] | undefined;
dashboardPage: AppEnumCollectionDashboardPage[] | undefined;
Expand All @@ -18,6 +20,7 @@ export interface GlobalEnumsContextInterface {

const GlobalEnumsContext = createContext<GlobalEnumsContextInterface>({
linkType: undefined,
reportType: undefined,
userRole: undefined,
teamMemberSex: undefined,
dashboardPage: undefined,
Expand Down
3 changes: 3 additions & 0 deletions app/utils/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { nonFieldError } from '@togglecorp/toggle-form';

import type { AdminAreaLevel } from '#generated/types/graphql';

export const MAX_REPORT_FILE_SIZE = 5 * 1024 * 1024; // 5MB
export const MAX_IMAGE_FILE_SIZE = 2 * 1024 * 1024; // 2MB

export function labelSelector<T>(item: { label: T }) {
return item.label;
}
Expand Down
17 changes: 14 additions & 3 deletions app/views/DataAndReports/DataAndReportsForm/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { useParams } from 'react-router';
import {
Expand All @@ -10,6 +11,7 @@ import {
Container,
DateInput,
Image,
InputError,
InputSection,
ListView,
RadioInput,
Expand Down Expand Up @@ -55,6 +57,7 @@ import {
idSelector,
keySelector,
labelSelector,
MAX_IMAGE_FILE_SIZE,
nameSelector,
omitKeys,
safeUrlCondition,
Expand Down Expand Up @@ -123,8 +126,6 @@ const defaultFormValue: PartialFormType = {
visibility: ReportVisibility.Public,
};

const MAX_FILE_SIZE = 5 * 1024 * 1024; // 5MB

function getFileFields(
file: File | null | undefined,
coverImage: File | null | undefined,
Expand Down Expand Up @@ -194,8 +195,16 @@ function DataAndReportsForm() {
}
}, [coverImagePreview, value.coverImage]);

const [coverImageSizeError, setCoverImageSizeError] = useState<string>();

const handleCoverImageChange = useCallback(
(file: File | undefined, name: 'coverImage') => {
if (isDefined(file) && file.size > MAX_IMAGE_FILE_SIZE) {
setCoverImageSizeError(`Image must be less than ${MAX_IMAGE_FILE_SIZE / (1024 * 1024)}MB`);
setFieldValue(undefined, name);
return;
}
setCoverImageSizeError(undefined);
setFieldValue(file, name);
},
[setFieldValue],
Expand Down Expand Up @@ -390,6 +399,9 @@ function DataAndReportsForm() {
alt="Cover image preview"
/>
)}
{isDefined(coverImageSizeError) && (
<InputError>{coverImageSizeError}</InputError>
)}
<NonFieldError error={error?.coverImage} />
</InputSection>
<InputSection
Expand Down Expand Up @@ -433,7 +445,6 @@ function DataAndReportsForm() {
fileName={fileName}
onChange={handleFileChange}
error={error?.file}
maxSize={MAX_FILE_SIZE}
disabled={pending}
/>
</InputSection>
Expand Down
39 changes: 39 additions & 0 deletions app/views/Documents/DocumentsFilters/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import {
DateInput,
TextInput,
} from '@ifrc-go/ui';
import { type EntriesAsList } from '@togglecorp/toggle-form';

import type { DocumentFilterType } from '..';

export interface Props {
value: DocumentFilterType;
onChange: (...args: EntriesAsList<DocumentFilterType>) => void;
}

function DocumentsFilter({ value, onChange }: Props) {
return (
<>
<DateInput
name="createdAtGte"
label="Created at start date"
value={value.createdAtGte}
onChange={onChange}
/>
<DateInput
name="createdAtLte"
label="Created at end date"
value={value.createdAtLte}
onChange={onChange}
/>
<TextInput
name="search"
placeholder="Search by title"
value={value.search}
onChange={onChange}
/>
</>
);
}

export default DocumentsFilter;
Loading
Loading