Skip to content

Commit

Permalink
UIIN-3175: Use AuditLogPane from streipes/components
Browse files Browse the repository at this point in the history
  • Loading branch information
OleksandrHladchenko1 committed Feb 28, 2025
1 parent cbf12a8 commit e315f71
Show file tree
Hide file tree
Showing 8 changed files with 198 additions and 9 deletions.
34 changes: 28 additions & 6 deletions src/Item/ItemVersionHistory/ItemVersionHistory.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import { useContext } from 'react';
import { useContext, useState } from 'react';
import { useIntl } from 'react-intl';
import PropTypes from 'prop-types';

import { AuditLogPane } from '@folio/stripes-acq-components';
import { AuditLogPane } from '@folio/stripes/components';

import { useItemAuditDataQuery } from '../../hooks';
import {
useItemAuditDataQuery,
useVersionHistory,
} from '../../hooks';
import { DataContext } from '../../contexts';
import { getDateWithTime } from '../../utils';

Expand Down Expand Up @@ -42,7 +45,19 @@ const ItemVersionHistory = ({
const { formatMessage } = useIntl();
const referenceData = useContext(DataContext);

const { data, isLoading } = useItemAuditDataQuery(itemId);
const [lastVersionEventTs, setLastVersionEventTs] = useState(null);

const {
data,
totalRecords,
isLoading,
} = useItemAuditDataQuery(itemId, lastVersionEventTs);

const {
actionsMap,
isLoadedMoreVisible,
versionsToDisplay,
} = useVersionHistory(data, totalRecords);

const fieldLabelsMap = {
discoverySuppress: formatMessage({ id: 'ui-inventory.discoverySuppress' }),
Expand Down Expand Up @@ -91,13 +106,20 @@ const ItemVersionHistory = ({

const fieldFormatter = createFieldFormatter(referenceData, circulationHistory);

const handleLoadMore = lastEventTs => {
setLastVersionEventTs(lastEventTs);
};

return (
<AuditLogPane
versions={data}
isLoading={isLoading}
versions={versionsToDisplay}
onClose={onClose}
isLoadedMoreVisible={isLoadedMoreVisible}
handleLoadMore={handleLoadMore}
isLoading={isLoading}
fieldLabelsMap={fieldLabelsMap}
fieldFormatter={fieldFormatter}
actionsMap={actionsMap}
/>
);
};
Expand Down
1 change: 1 addition & 0 deletions src/hooks/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export { default as useClassificationBrowseConfig } from './useClassificationBro
export { default as useUpdateOwnership } from './useUpdateOwnership';
export { default as useLocalStorageItems } from './useLocalStorageItems';
export { default as useItemAuditDataQuery } from './useItemAuditDataQuery';
export { default as useVersionHistory } from './useVersionHistory';
export * from './useQuickExport';
export * from '@folio/stripes-inventory-components/lib/queries/useInstanceDateTypes';
export * from './useCallNumberTypesQuery';
Expand Down
12 changes: 9 additions & 3 deletions src/hooks/useItemAuditDataQuery/useItemAuditDataQuery.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@ import {
useOkapiKy,
} from '@folio/stripes/core';

const useItemAuditDataQuery = (itemId) => {
const useItemAuditDataQuery = (itemId, eventTs) => {
const ky = useOkapiKy();
const [namespace] = useNamespace({ key: 'item-audit-data' });

// eventTs param is used to load more data
const { isLoading, data = {} } = useQuery({
queryKey: [namespace, itemId],
queryFn: () => ky.get(`audit-data/inventory/item/${itemId}`).json(),
queryKey: [namespace, itemId, eventTs],
queryFn: () => ky.get(`audit-data/inventory/item/${itemId}`, {
searchParams: {
...(eventTs && { eventTs })
}
}).json(),
enabled: Boolean(itemId),
});

return {
data: data?.inventoryAuditItems || [],
totalRecords: data?.totalRecords,
isLoading,
};
};
Expand Down
12 changes: 12 additions & 0 deletions src/hooks/useVersionHistory/getActionLabel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/**
* Gets translated change type label
* @param {function} formatMessage
* @returns {{ADDED, MODIFIED, REMOVED}}
*/
export const getActionLabel = formatMessage => {
return {
ADDED: formatMessage({ id: 'stripes-acq-components.audit-log.action.added' }),
MODIFIED: formatMessage({ id: 'stripes-acq-components.audit-log.action.edited' }),
REMOVED: formatMessage({ id: 'stripes-acq-components.audit-log.action.removed' }),
};
};
15 changes: 15 additions & 0 deletions src/hooks/useVersionHistory/getActionLabel.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { getActionLabel } from './getActionLabel';

const intl = { formatMessage: ({ id }) => id };

describe('getActionLabel', () => {
it('should return correct action labels', () => {
const labels = {
ADDED: 'stripes-acq-components.audit-log.action.added',
MODIFIED: 'stripes-acq-components.audit-log.action.edited',
REMOVED: 'stripes-acq-components.audit-log.action.removed',
};

expect(getActionLabel(intl.formatMessage)).toEqual(labels);
});
});
28 changes: 28 additions & 0 deletions src/hooks/useVersionHistory/getChangedFieldsList.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { sortBy } from 'lodash';

/**
* Merge fieldChanges and collectionChanges into a list of changed fields and sort by changeType
* @param {Object} diff
* @param {Array} diff.fieldChanges
* @param {Array} diff.collectionChanges
* @returns {Array.<{fieldName: String, changeType: String, newValue: any, oldValue: any}>}
*/
export const getChangedFieldsList = diff => {
const fieldChanges = diff.fieldChanges ? diff.fieldChanges.map(field => ({
fieldName: field.fieldName,
changeType: field.changeType,
newValue: field.newValue,
oldValue: field.oldValue,
})) : [];

const collectionChanges = diff.collectionChanges ? diff.collectionChanges.flatMap(collection => {
return collection.itemChanges.map(field => ({
fieldName: collection.collectionName,
changeType: field.changeType,
newValue: field.newValue,
oldValue: field.oldValue,
}));
}) : [];

return sortBy([...fieldChanges, ...collectionChanges], data => data.changeType);
};
1 change: 1 addition & 0 deletions src/hooks/useVersionHistory/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './useVersionHistory';
104 changes: 104 additions & 0 deletions src/hooks/useVersionHistory/useVersionHistory.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import {
useEffect,
useMemo,
useState,
} from 'react';
import { useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
import {
keyBy,
uniq,
} from 'lodash';

import {
formatDateTime,
useUsersBatch,
} from '@folio/stripes-acq-components';

import { getChangedFieldsList } from './getChangedFieldsList';
import { getActionLabel } from './getActionLabel';

const useVersionHistory = (data, totalRecords) => {
const intl = useIntl();
const anonymousUserLabel = intl.formatMessage({ id: 'stripes-components.versionHistory.anonymousUser' });

const [versions, setVersions] = useState([]);
const [usersId, setUsersId] = useState([]);
const [usersMap, setUsersMap] = useState({});
const [isLoadedMoreVisible, setIsLoadedMoreVisible] = useState(true);

const { users } = useUsersBatch(usersId);

// cleanup when component unmounts
useEffect(() => () => {
setVersions([]);
setUsersMap({});
}, []);

// update usersId when data changes
useEffect(() => {
if (!data?.length) return;

const newUsersId = uniq(data.map(version => version.userId));

setUsersId(newUsersId);
}, [data]);

// update usersMap when new users are fetched
useEffect(() => {
if (!users?.length) return;

setUsersMap(prevState => ({
...prevState,
...keyBy(users, 'id'),
}));
}, [users]);

useEffect(() => {
if (!data?.length) return;

setVersions(prevState => [...prevState, ...data]);
}, [data]);

useEffect(() => {
setIsLoadedMoreVisible(versions.length < totalRecords);
}, [versions]);

const versionsToDisplay = useMemo(
() => {
const getUserName = userId => {
const user = usersMap[userId];

return user ? `${user.personal.lastName}, ${user.personal.firstName}` : null;
};
const getSourceLink = userId => {
return userId ? <Link to={`/users/preview/${userId}`}>{getUserName(userId)}</Link> : anonymousUserLabel;
};

const transformDiffToVersions = diffArray => {
return diffArray
.filter(({ action }) => action !== 'CREATE')
.map(({ eventDate, eventTs, userId, eventId, diff }) => ({
eventDate: formatDateTime(eventDate, intl),
source: getSourceLink(userId),
userName: getUserName(userId) || anonymousUserLabel,
fieldChanges: diff ? getChangedFieldsList(diff) : [],
eventId,
eventTs,
}));
};

return transformDiffToVersions(versions);
}, [versions, usersMap],
);

const actionsMap = { ...getActionLabel(intl.formatMessage) };

return {
actionsMap,
isLoadedMoreVisible,
versionsToDisplay,
};
};

export default useVersionHistory;

0 comments on commit e315f71

Please sign in to comment.