Skip to content

Commit

Permalink
implement locations list components
Browse files Browse the repository at this point in the history
  • Loading branch information
usavkov-epam committed Dec 11, 2023
1 parent a1a569b commit 361af67
Show file tree
Hide file tree
Showing 6 changed files with 173 additions and 22 deletions.
7 changes: 7 additions & 0 deletions src/Funds/FundForm/FundLocations/FundLocations.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.actions {
display: flex;

& .unassignAll {
margin-left: var(--gutter);
}
}
76 changes: 62 additions & 14 deletions src/Funds/FundForm/FundLocations/FundLocations.js
Original file line number Diff line number Diff line change
@@ -1,38 +1,86 @@
import PropTypes from 'prop-types';
import { useCallback } from 'react';
import { useCallback, useState } from 'react';
import { FormattedMessage } from 'react-intl';
import { useForm } from 'react-final-form';
import { FieldArray } from 'react-final-form-arrays';

import { FindLocation } from '@folio/stripes-acq-components';
import {
Button,
ConfirmationModal,
Loading,
} from '@folio/stripes/components';
import {
FindLocation,
useLocations,
} from '@folio/stripes-acq-components';

import { FundLocationsList } from './FundLocationsList';

import css from './FundLocations.css';

const INITIAL_FILTERS = { isAssigned: [true] };
const SCOPE_TRANSLATION_ID = 'ui-finance.fund.information.locations';

export const FundLocations = ({
assignedLocations,
name,
}) => {
export const FundLocations = ({ assignedLocations, name }) => {
const { change } = useForm();
const { isLoading, locations } = useLocations();

const [isUnassignModalOpen, setIsUnassignModalOpen] = useState();

const onRecordsSelect = useCallback((locations) => {

Check failure on line 30 in src/Funds/FundForm/FundLocations/FundLocations.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

'locations' is already declared in the upper scope on line 26 column 22
const locationIds = locations.map(({ id }) => id);

change(name, locationIds);
}, [name]);

Check warning on line 34 in src/Funds/FundForm/FundLocations/FundLocations.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

React Hook useCallback has a missing dependency: 'change'. Either include it or remove the dependency array

const openUnassignModal = (e) => {
e.preventDefault();
e.stopPropagation();
setIsUnassignModalOpen(true);
};

const closeIsUnassignModal = () => setIsUnassignModalOpen(false);

const unassignAll = () => {
change(name, []);
closeIsUnassignModal();
};

if (isLoading) return <Loading />;

return (
<>
<FundLocationsList
items={assignedLocations}
<FieldArray
component={FundLocationsList}
name={name}
locations={locations}
/>

<FindLocation
isMultiSelect
searchLabel={<FormattedMessage id="ui-finance.fund.information.locations.add" />}
initialFilters={assignedLocations.length ? INITIAL_FILTERS : undefined}
initialSelected={assignedLocations}
onRecordsSelect={onRecordsSelect}
<div className={css.actions}>
<FindLocation
isMultiSelect
searchLabel={<FormattedMessage id={`${SCOPE_TRANSLATION_ID}.action.add`} />}
initialFilters={assignedLocations.length ? INITIAL_FILTERS : undefined}
initialSelected={assignedLocations}
onRecordsSelect={onRecordsSelect}
/>

<Button
buttonClass={css.unassignAll}
disabled={!assignedLocations.length}
id="clickable-remove-all-locations"
onClick={openUnassignModal}
>
<FormattedMessage id={`${SCOPE_TRANSLATION_ID}.action.removeAll`} />
</Button>
</div>

<ConfirmationModal
open={isUnassignModalOpen}
heading={<FormattedMessage id={`${SCOPE_TRANSLATION_ID}.action.removeAll`} />}
message={<FormattedMessage id={`${SCOPE_TRANSLATION_ID}.action.removeAll.confirm.message`} />}
onConfirm={unassignAll}
onCancel={closeIsUnassignModal}
/>
</>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,39 @@
import { useMemo } from 'react';
import { useCallback, useMemo } from 'react';
import { FormattedMessage } from 'react-intl';

import { List } from '@folio/stripes/components';

export const FundLocationsList = ({ items }) => {
const sortedItems = useMemo(() => {
return items.sort((a, b) => a.localeCompare(b))
}, [items]);
import { FundLocationsListItem } from './FundLocationsListItem';

export const FundLocationsList = ({ fields, locations }) => {

Check failure on line 8 in src/Funds/FundForm/FundLocations/FundLocationsList/FundLocationsList.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

'fields' is missing in props validation

Check failure on line 8 in src/Funds/FundForm/FundLocations/FundLocationsList/FundLocationsList.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

'locations' is missing in props validation
const items = useMemo(() => {
return (fields.value || [])

Check failure on line 10 in src/Funds/FundForm/FundLocations/FundLocationsList/FundLocationsList.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

'fields.value' is missing in props validation
.map((locationId) => locations.find(location => locationId === location.id) || {})

Check failure on line 11 in src/Funds/FundForm/FundLocations/FundLocationsList/FundLocationsList.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

'locations.find' is missing in props validation
.sort((a, b) => a.name.localeCompare(b.name))

Check failure on line 12 in src/Funds/FundForm/FundLocations/FundLocationsList/FundLocationsList.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

Missing semicolon
}, [fields?.value, locations]);

Check failure on line 13 in src/Funds/FundForm/FundLocations/FundLocationsList/FundLocationsList.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

'fields.value' is missing in props validation

const onRemove = useCallback((location) => {
const indexToRemove = (fields.value || []).findIndex((locationId) => locationId === location.id);

if (indexToRemove > -1) {
fields.remove(indexToRemove);
}
}, [fields.value, fields.remove]);

Check warning on line 21 in src/Funds/FundForm/FundLocations/FundLocationsList/FundLocationsList.js

View workflow job for this annotation

GitHub Actions / github-actions-ci

React Hook useCallback has a missing dependency: 'fields'. Either include it or remove the dependency array

const itemFormatter = useCallback((location, index) => {
return (
<FundLocationsListItem
location={location}
index={index}
onRemove={onRemove}
/>
)
}, [onRemove]);

return (
<List
items={sortedItems}
// itemFormatter={itemFormatter}
items={items}
itemFormatter={itemFormatter}
isEmptyMessage={<FormattedMessage id="ui-finance.fund.information.locations.empty" />}
/>
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.itemValue,
.removeBtn {
margin: 0 9px;
}

.removeIconRoot {
padding: 0 4px;

& .removeIcon {
fill: #999;
transition: fill .2s ease;
}

&:hover {
& .removeIcon{
fill: #555;
}
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

import {
Button,
Icon,
} from '@folio/stripes/components';

import css from './FundLocationsListItem.css';

const formatLocationValue = ({ name, code }) => [name, code && `(${code})`].join(' ');

export const FundLocationsListItem = ({
location,
index,
onRemove,
}) => {
return (
<li className={css.listItem}>
<span className={css.itemValue}>{formatLocationValue(location)}</span>
<FormattedMessage id="ui-finance.fund.information.locations.action.remove">
{aria => (
<Button
buttonStyle="fieldControl"
buttonClass={css.removeBtn}
align="end"
type="button"
id={`clickable-remove-location-${index}`}
onClick={() => onRemove(location)}
aria-label={`${aria}: ${location.name}`}
>
<Icon
icon="times-circle"
iconClassName={css.removeIcon}
iconRootClass={css.removeIconRoot}
/>
</Button>
)}
</FormattedMessage>
</li>
);
};

FundLocationsListItem.propTypes = {
location: PropTypes.object,
index: PropTypes.number,
fields: PropTypes.object,
showPerms: PropTypes.bool,
permToDelete: PropTypes.string,
changePermissions: PropTypes.func.isRequired,
};
5 changes: 4 additions & 1 deletion translations/ui-finance/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -268,7 +268,10 @@
"fund.information.title": "Fund information",
"fund.information.donorInformation": "Donor information",
"fund.information.locations": "Locations",
"fund.information.locations.add": "Add location",
"fund.information.locations.action.add": "Add location",
"fund.information.locations.action.remove": "Remove location",
"fund.information.locations.action.removeAll": "Unassign all locations",
"fund.information.locations.action.removeAll.confirm.message": "Are you sure you want to unassign all locations from the fund?",
"fund.information.locations.empty": "No locations found",
"fund.information.restrictByLocations": "Restrict use by location",
"fund.information.transferFrom": "Transfer from",
Expand Down

0 comments on commit 361af67

Please sign in to comment.