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

[UICAL-269] Migrate from self-contained typings to stripes-types (again) #508

Merged
merged 6 commits into from
Dec 28, 2023
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

* Use non-empty close times for closed calendars. Refs UICAL-278
* Fix rendering monthly calendar view issue. Refs UICAL-277
* Add page titles. Refs UICAL-272
* Remove self-contained typings. Refs UICAL-269

## [10.0.0] (https://github.com/folio-org/ui-calendar/tree/v10.0.0) (2023-10-11)

Expand Down
10 changes: 5 additions & 5 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,14 @@ module.exports = {

preset: 'ts-jest',
transform: {
'^.+\\.(t|j)sx?$': ['ts-jest', { tsconfig: 'src/tsconfig.json' }]
'^.+\\.(t|j)sx?$': ['ts-jest', { tsconfig: 'src/tsconfig.json' }],
},
transformIgnorePatterns: ['node_modules/(?!@folio|ky)'],

moduleFileExtensions: ['js', 'jsx', 'ts', 'tsx', 'json'],

testMatch: ['**/src/**/?(*.)test.{js,jsx,ts,tsx}'],
testPathIgnorePatterns: ['/node_modules/', 'src/typings/'],
testPathIgnorePatterns: ['/node_modules/'],

reporters: ['default', 'jest-junit'],

Expand All @@ -24,7 +24,7 @@ module.exports = {
'!src/**/*.d.ts',
'!src/**/*.test.{ts,tsx}',
'!src/test/**',
'!**/node_modules/**'
'!**/node_modules/**',
],

setupFiles: [join(__dirname, './src/test/setupTests.ts')],
Expand All @@ -34,8 +34,8 @@ module.exports = {
'^.+\\.(css|svg)$': 'identity-obj-proxy',

// Force module uuid to resolve with the CJS entry point, because Jest does not support package.json.exports. See https://github.com/uuidjs/uuid/issues/451
uuid: require.resolve('uuid')
uuid: require.resolve('uuid'),
},

slowTestThreshold: 10
slowTestThreshold: 10,
};
91 changes: 43 additions & 48 deletions src/components/fields/ServicePointAssignmentField.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
MultiSelection,
MultiSelectionFieldRenderProps,
OptionSegment
} from '@folio/stripes/components';
import { MultiSelection, OptionSegment } from '@folio/stripes/components';
import fuzzysort from 'fuzzysort';
import React, { FunctionComponent, ReactNode } from 'react';
import { Field } from 'react-final-form';
Expand All @@ -11,15 +7,15 @@ import { ServicePoint } from '../../types/types';

interface ServicePointAssignmentFieldProps {
servicePoints: ServicePoint[];
error: ReactNode | undefined;
error?: ReactNode;
}

const ServicePointAssignmentField: FunctionComponent<
ServicePointAssignmentFieldProps
> = (props: ServicePointAssignmentFieldProps) => {
const formatter = ({
option,
searchTerm
searchTerm,
}: {
option: ServicePoint;
searchTerm: string | undefined;
Expand All @@ -45,50 +41,49 @@ const ServicePointAssignmentField: FunctionComponent<
return (
<Field
name="service-points"
component={
MultiSelection<
ServicePoint,
MultiSelectionFieldRenderProps<ServicePoint>
>
}
label={
<FormattedMessage id="ui-calendar.calendarForm.field.servicePoints" />
}
formatter={formatter}
filter={(filterText: string | undefined, list: ServicePoint[]) => {
if (typeof filterText !== 'string' || filterText === '') {
return { renderedItems: list, exactMatch: false };
}
error={props.error}
render={(fieldProps) => (
<MultiSelection<ServicePoint>
{...fieldProps}
label={
<FormattedMessage id="ui-calendar.calendarForm.field.servicePoints" />
}
formatter={formatter}
filter={(filterText: string | undefined, list: ServicePoint[]) => {
if (typeof filterText !== 'string' || filterText === '') {
return { renderedItems: list, exactMatch: false };
}

// must spread and re-collect into a new array, as the returned array is immutable
const results = [
...fuzzysort.go(filterText, props.servicePoints, { key: 'name' })
];
// must spread and re-collect into a new array, as the returned array is immutable
const results = [
...fuzzysort.go(filterText, props.servicePoints, { key: 'name' }),
];

// score descending, then name ascending
// fixes "service point 1".."service point 4" etc having undefined order
results.sort((a, b) => {
if (a.score === b.score) {
return a.target.localeCompare(b.target);
}
return -(a.score - b.score);
});
// score descending, then name ascending
// fixes "service point 1".."service point 4" etc having undefined order
results.sort((a, b) => {
if (a.score === b.score) {
return a.target.localeCompare(b.target);
}
return -(a.score - b.score);
});

return {
// retrieve the original service point
renderedItems: results.map((result) => result.obj),
exactMatch: !!list.filter((sp) => sp.name === filterText).length
};
}}
itemToString={(servicePoint: ServicePoint | undefined) => {
if (typeof servicePoint === 'object' && servicePoint !== null) {
return servicePoint.name;
} else {
return '';
}
}}
dataOptions={props.servicePoints}
error={props.error}
return {
// retrieve the original service point
renderedItems: results.map((result) => result.obj),
exactMatch: !!list.filter((sp) => sp.name === filterText).length,
};
}}
itemToString={(servicePoint: ServicePoint | undefined) => {
if (servicePoint) {
return servicePoint.name;
} else {
return '';
}
}}
dataOptions={props.servicePoints}
/>
)}
/>
);
};
Expand Down
111 changes: 42 additions & 69 deletions src/forms/CalendarForm/CalendarForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,17 @@ import {
AccordionSet,
Col,
Datepicker as DateField,
DatepickerFieldRenderProps as DateFieldRenderProps,
ExpandAllButton,
getLocaleDateFormat,
getLocalizedTimeFormatInfo,
Headline,
Icon,
Row,
TextField,
TextFieldRenderProps,
} from '@folio/stripes/components';
import { CalloutContext } from '@folio/stripes/core';
import { FormApi, FORM_ERROR } from 'final-form';
import React, {
FunctionComponent,
useCallback,
useContext,
useMemo,
useRef,
} from 'react';
import React, { FunctionComponent, useCallback, useContext, useMemo, useRef } from 'react';
import { Field, Form } from 'react-final-form';
import { FormattedMessage, useIntl } from 'react-intl';
import ExceptionField from '../../components/fields/ExceptionField';
Expand All @@ -35,9 +27,6 @@ import onSubmit from './onSubmit';
import { FormValues, InnerFieldRefs } from './types';
import validate from './validation/validate';

const TextFieldComponent = TextField<string, TextFieldRenderProps<string>>;
const DateFieldComponent = DateField<DateFieldRenderProps>;

export const FORM_ID = 'ui-calendar-create-calendar-form';

export interface CreateCalendarFormProps {
Expand All @@ -50,7 +39,7 @@ export interface CreateCalendarFormProps {
}

export const CreateCalendarForm: FunctionComponent<CreateCalendarFormProps> = (
props: CreateCalendarFormProps
props: CreateCalendarFormProps,
) => {
const calloutContext = useContext(CalloutContext);
const intl = useIntl();
Expand All @@ -67,10 +56,10 @@ export const CreateCalendarForm: FunctionComponent<CreateCalendarFormProps> = (
calloutContext,
intl,
values,
form
form,
);
},
[props, calloutContext, intl]
[props, calloutContext, intl],
);

const localeDateFormat = getLocaleDateFormat({ intl });
Expand All @@ -89,7 +78,7 @@ export const CreateCalendarForm: FunctionComponent<CreateCalendarFormProps> = (
localeDateFormat,
localeTimeFormat,
{ startDateRef, endDateRef },
innerFieldRefs.current
innerFieldRefs.current,
);
}, [localeDateFormat, localeTimeFormat, startDateRef, endDateRef]);

Expand All @@ -98,29 +87,15 @@ export const CreateCalendarForm: FunctionComponent<CreateCalendarFormProps> = (
onSubmit={onSubmitCallback}
validate={validationFunction}
validateOnBlur
initialValues={calendarToInitialValues(
props.dataRepository,
props.initialValues
)}
initialValues={calendarToInitialValues(props.dataRepository, props.initialValues)}
render={(params) => {
const {
handleSubmit,
errors,
submitErrors,
touched,
dirtyFieldsSinceLastSubmit,
active,
} = params;
const { handleSubmit, errors, submitErrors, touched, dirtyFieldsSinceLastSubmit, active } =
params;

let topErrorMessage = <></>;
if (submitErrors?.[FORM_ERROR]) {
topErrorMessage = (
<Headline
margin="none"
className={css.conflictMessage}
weight="medium"
size="medium"
>
<Headline margin="none" className={css.conflictMessage} weight="medium" size="medium">
<Icon icon="exclamation-circle" status="error" />
{submitErrors[FORM_ERROR]}
</Headline>
Expand All @@ -137,67 +112,69 @@ export const CreateCalendarForm: FunctionComponent<CreateCalendarFormProps> = (
</Col>
</Row>
<Accordion
label={
<FormattedMessage id="ui-calendar.calendarForm.category.general" />
}
label={<FormattedMessage id="ui-calendar.calendarForm.category.general" />}
>
<Row>
<Col xs={12} md={6}>
<Field
component={TextFieldComponent}
autoFocus
required
name="name"
label={
<FormattedMessage id="ui-calendar.calendarForm.field.name" />
}
error={
(!dirtyFieldsSinceLastSubmit?.name &&
submitErrors?.name) ||
(!dirtyFieldsSinceLastSubmit?.name && submitErrors?.name) ||
((props.submitAttempted || touched?.name) &&
active !== 'name' &&
errors?.name)
}
render={(fieldProps) => (
<TextField
{...fieldProps}
label={<FormattedMessage id="ui-calendar.calendarForm.field.name" />}
autoFocus
required
/>
)}
/>
</Col>
<Col xs={12} md={3}>
<Field
component={DateFieldComponent}
inputRef={startDateRef}
backendDateStandard="YYYY-MM-DD"
required
usePortal
name="start-date"
label={
<FormattedMessage id="ui-calendar.calendarForm.field.startDate" />
}
error={
(!dirtyFieldsSinceLastSubmit?.['start-date'] &&
submitErrors?.['start-date']) ||
((props.submitAttempted || touched?.['start-date']) &&
active !== 'start-date' &&
errors?.['start-date'])
}
render={(fieldProps) => (
<DateField
{...fieldProps}
inputRef={startDateRef}
backendDateStandard="YYYY-MM-DD"
required
usePortal
label={<FormattedMessage id="ui-calendar.calendarForm.field.startDate" />}
/>
)}
/>
</Col>
<Col xs={12} md={3}>
<Field
component={DateFieldComponent}
inputRef={endDateRef}
backendDateStandard="YYYY-MM-DD"
required
usePortal
name="end-date"
label={
<FormattedMessage id="ui-calendar.calendarForm.field.endDate" />
}
error={
(!dirtyFieldsSinceLastSubmit?.['end-date'] &&
submitErrors?.['end-date']) ||
(!dirtyFieldsSinceLastSubmit?.['end-date'] && submitErrors?.['end-date']) ||
((props.submitAttempted || touched?.['end-date']) &&
active !== 'end-date' &&
errors?.['end-date'])
}
render={(fieldProps) => (
<DateField
{...fieldProps}
inputRef={endDateRef}
backendDateStandard="YYYY-MM-DD"
required
usePortal
label={<FormattedMessage id="ui-calendar.calendarForm.field.endDate" />}
/>
)}
/>
</Col>
</Row>
Expand All @@ -207,9 +184,7 @@ export const CreateCalendarForm: FunctionComponent<CreateCalendarFormProps> = (
/>
</Accordion>
<Accordion
label={
<FormattedMessage id="ui-calendar.calendarForm.category.hoursOfOperation" />
}
label={<FormattedMessage id="ui-calendar.calendarForm.category.hoursOfOperation" />}
>
<Field
name="hours-of-operation"
Expand All @@ -222,9 +197,7 @@ export const CreateCalendarForm: FunctionComponent<CreateCalendarFormProps> = (
/>
</Accordion>
<Accordion
label={
<FormattedMessage id="ui-calendar.calendarForm.category.exceptions" />
}
label={<FormattedMessage id="ui-calendar.calendarForm.category.exceptions" />}
>
<Field
name="exceptions"
Expand Down
Loading
Loading