Skip to content

Commit

Permalink
UIBULKED-316: Bulk edit actions for holdings notes - add and remove M…
Browse files Browse the repository at this point in the history
…ark as staff only (#401)
  • Loading branch information
UladzislauKutarkin authored Oct 31, 2023
1 parent 60c1271 commit 7f54e65
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 10 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
* [UIBULKED-315](https://issues.folio.org/browse/UIBULKED-315) Group holdings record properties using optgroup component
* [UIBULKED-354](https://issues.folio.org/browse/UIBULKED-354) Two identical files with the preview of proposed changes are downloaded from Logs
* [UIBULKED-373](https://issues.folio.org/browse/UIBULKED-373) "User" dropdown doesn't include Users recently run bulk edit jobs
* [UIBULKED-316](https://issues.folio.org/browse/UIBULKED-316) Bulk edit actions for holdings notes - add and remove Mark as staff only.
* [UIBULKED-331](https://issues.folio.org/browse/UIBULKED-331) Bulk edit actions for holdings notes - add and remove notes.
* [UIBULKED-332](https://issues.folio.org/browse/UIBULKED-332) Bulk edit actions for holdings notes - find and replace or remove.
* [UIBULKED-333](https://issues.folio.org/browse/UIBULKED-333) Bulk edit actions for holdings notes - change note type.

## [4.0.0](https://github.com/folio-org/ui-bulk-edit/tree/v4.0.0) (2023-10-12)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,15 @@ import {
BASE_DATE_FORMAT,
CAPABILITIES,
CONTROL_TYPES,
getDuplicateNoteOptions,
getDuplicateNoteOptions, getHoldingsNotes,
getItemStatusOptions,
getNotesOptions,
} from '../../../../../constants';
import { FIELD_VALUE_KEY, TEMPORARY_LOCATIONS } from './helpers';
import { useLoanTypes, usePatronGroup } from '../../../../../hooks/api';
import { useItemNotes } from '../../../../../hooks/api/useItemNotes';
import { usePreselectedValue } from '../../../../../hooks/usePreselectedValue';
import { useHoldingsNotes } from '../../../../../hooks/api/useHoldingsNotes';

export const ValuesColumn = ({ action, actionIndex, onChange, option }) => {
const { formatMessage } = useIntl();
Expand All @@ -32,22 +33,30 @@ export const ValuesColumn = ({ action, actionIndex, onChange, option }) => {

const isUserCapability = capability === CAPABILITIES.USER;
const isItemCapability = capability === CAPABILITIES.ITEM;
const isHoldingsCapability = capability === CAPABILITIES.HOLDING;

const { userGroups } = usePatronGroup({ enabled: isUserCapability });
const { loanTypes, isLoanTypesLoading } = useLoanTypes({ enabled: isItemCapability });
const { itemNotes, usItemNotesLoading } = useItemNotes({ enabled: isItemCapability });
const { holdingsNotes, isHoldingsNotesLoading } = useHoldingsNotes({ enabled: isHoldingsCapability });
const duplicateNoteOptions = getDuplicateNoteOptions(formatMessage).filter(el => el.value !== option);

const filteredAndMappedNotes = getNotesOptions(formatMessage, itemNotes)
.filter(obj => obj.value !== option)
.map(({ label, value }) => ({ label, value }));

const filteredAndMappedHoldingsNotes = getHoldingsNotes(formatMessage, holdingsNotes)
.filter(obj => obj.value !== option)
.map(({ label, value, disabled }) => ({ label, value, disabled }));

const sortWithoutPlaceholder = (array) => {
const [placeholder, ...rest] = array;

return [placeholder, ...rest.sort((a, b) => a.label.localeCompare(b.label))];
};

const sortedNotes = sortWithoutPlaceholder(filteredAndMappedNotes);
const sortedHoldingsNotes = sortWithoutPlaceholder(filteredAndMappedHoldingsNotes);

const statuses = getItemStatusOptions(formatMessage);
const actionValue = action.value;
Expand Down Expand Up @@ -160,14 +169,28 @@ export const ValuesColumn = ({ action, actionIndex, onChange, option }) => {
);

const renderNoteTypeSelect = () => controlType === CONTROL_TYPES.NOTE_SELECT && (
<Select
id="noteType"
value={action.value}
loading={usItemNotesLoading}
onChange={e => onChange({ actionIndex, value: e.target.value, fieldName: FIELD_VALUE_KEY })}
dataOptions={sortedNotes}
aria-label={formatMessage({ id: 'ui-bulk-edit.ariaLabel.loanTypeSelect' })}
/>
isHoldingsCapability ? (
<Select
id="noteHoldingsType"
value={action.value}
loading={isHoldingsNotesLoading}
onChange={e => onChange({ actionIndex, value: e.target.value, fieldName: FIELD_VALUE_KEY })}
dataOptions={sortedHoldingsNotes}
aria-label={formatMessage({ id: 'ui-bulk-edit.ariaLabel.loanTypeSelect' })}
/>)
:
(<Select
id="noteType"
value={action.value}
loading={usItemNotesLoading}
onChange={e => onChange({
actionIndex,
value: e.target.value,
fieldName: FIELD_VALUE_KEY
})}
dataOptions={sortedNotes}
aria-label={formatMessage({ id: 'ui-bulk-edit.ariaLabel.loanTypeSelect' })}
/>)
);

const renderNoteDuplicateTypeSelect = () => controlType === CONTROL_TYPES.NOTE_DUPLICATE_SELECT && (
Expand All @@ -181,6 +204,17 @@ export const ValuesColumn = ({ action, actionIndex, onChange, option }) => {
/>
);

const renderNoteHoldingsTypeSelect = () => controlType === CONTROL_TYPES.HOLDINGS_NOTE && (
<Select
id="noteHoldingsType"
value={action.value}
loading={isHoldingsNotesLoading}
onChange={e => onChange({ actionIndex, value: e.target.value, fieldName: FIELD_VALUE_KEY })}
dataOptions={sortedHoldingsNotes}
aria-label={formatMessage({ id: 'ui-bulk-edit.ariaLabel.loanTypeSelect' })}
/>
);

return (
<Col xs={2} sm={2}>
{renderTextField()}
Expand All @@ -192,6 +226,7 @@ export const ValuesColumn = ({ action, actionIndex, onChange, option }) => {
{renderLoanTypeSelect()}
{renderNoteTypeSelect()}
{renderNoteDuplicateTypeSelect()}
{renderNoteHoldingsTypeSelect()}
</Col>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ export const getDefaultActions = (option, options, formatMessage) => {
},
],
};
case OPTIONS.HOLDINGS_NOTE:
case OPTIONS.ITEM_NOTE:
return {
type: '',
Expand All @@ -281,7 +282,7 @@ export const getDefaultActions = (option, options, formatMessage) => {
actionsList: noteWithMarkDefaultActions,
controlType: (action) => {
return action === ACTIONS.CHANGE_TYPE
? CONTROL_TYPES.NOTE_SELECT
? CONTROL_TYPES.HOLDINGS_NOTE
: CONTROL_TYPES.TEXTAREA;
},
[ACTION_VALUE_KEY]: noteWithMarkDefaultActions[0].value,
Expand Down Expand Up @@ -359,6 +360,7 @@ export const getExtraActions = (option, action, formattedMessage) => {
case `${OPTIONS.ADMINISTRATIVE_NOTE}-${ACTIONS.FIND}`:
case `${OPTIONS.CHECK_IN_NOTE}-${ACTIONS.FIND}`:
case `${OPTIONS.CHECK_OUT_NOTE}-${ACTIONS.FIND}`:
case `${OPTIONS.HOLDINGS_NOTE}-${ACTIONS.FIND}`:
return [{
actionsList: noteAdditionalActions(formattedMessage),
controlType: () => CONTROL_TYPES.TEXTAREA,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -491,6 +491,52 @@ describe('ContentUpdatesForm helpers', () => {
});
});

it('returns the correct object for the HOLDINGS_NOTE option', () => {
expect(JSON.stringify(getDefaultActions(OPTIONS.HOLDINGS_NOTE, [], formatMessage))).toEqual(
JSON.stringify({
type: '',
actions: [
null,
{
actionsList: [{
value: '',
disabled: true,
label: undefined,
},
{ value: 'MARK_AS_STAFF_ONLY',
disabled: false,
label: undefined },
{ value: 'REMOVE_MARK_AS_STAFF_ONLY',
disabled: false,
label: undefined },
{ value: 'ADD_TO_EXISTING',
disabled: false,
label: undefined },
{ value: 'REMOVE_ALL',
disabled: false,
label: undefined },
{ value: 'FIND',
disabled: false,
label: undefined },
{
value: 'CHANGE_TYPE',
disabled: false,
label: undefined,
},
],
controlType: (action) => {
return action === ACTIONS.CHANGE_TYPE
? CONTROL_TYPES.NOTE_SELECT
: CONTROL_TYPES.TEXTAREA;
},
[ACTION_VALUE_KEY]: '',
[FIELD_VALUE_KEY]: '',
},
],
}),
);
});

it('returns the correct object for the default case', () => {
expect(getDefaultActions('unknown', [], formatMessage)).toEqual({
type: null,
Expand Down
1 change: 1 addition & 0 deletions src/constants/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export const CONTROL_TYPES = {
TEXTAREA: 'TEXTAREA',
NOTE_SELECT: 'NOTE_SELECT',
NOTE_DUPLICATE_SELECT: 'NOTE_DUPLICATE_SELECT',
HOLDINGS_NOTE: 'HOLDINGS_NOTE'
};

export const TRANSLATION_SUFFIX = {
Expand Down
14 changes: 14 additions & 0 deletions src/constants/selectOptions.js
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,20 @@ export const getHoldingsOptions = (formatMessage, holdingsNotes = []) => [
},
];

export const getHoldingsNotes = (formatMessage, holdingsNotes) => [
{
value: '',
label: formatMessage({ id: 'ui-bulk-edit.options.placeholder' }),
disabled: true,
},
{
value: OPTIONS.ADMINISTRATIVE_NOTE,
label: formatMessage({ id: 'ui-bulk-edit.layer.options.administrativeNote' }),
disabled: false,
},
...holdingsNotes,
];

export const getNotesOptions = (formatMessage, itemNotes) => [
{
value: '',
Expand Down

0 comments on commit 7f54e65

Please sign in to comment.