Skip to content

Commit

Permalink
Merge pull request #656 from folio-org/release_8.3.2
Browse files Browse the repository at this point in the history
Release 8.3.2
  • Loading branch information
EthanFreestone authored Jan 24, 2023
2 parents 26dd5ed + 6a42303 commit 5e612d5
Show file tree
Hide file tree
Showing 6 changed files with 79 additions and 542 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Change history for ui-licenses

## 8.3.2 2023-01-24
* ERM-2547 On agreement and license user details do not display when more than one user linked to agreement/license as Internal contact
* ERM-2538 On agreement and license view not all linked Org interfaces displaying

## 8.3.1 2022-11-18
* ERM-2434 "customProperties.ctx.title": "" in en.json
* ERM-2420 Amendment doesn't show licensor value of parent license
Expand Down
8 changes: 4 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@folio/licenses",
"version": "8.3.1",
"version": "8.3.2",
"description": "ERM License functionality for Stripes",
"main": "src/index.js",
"repository": "",
Expand Down Expand Up @@ -31,7 +31,7 @@
"@folio/eslint-config-stripes": "^6.3.0",
"@folio/stripes": "^7.3.1",
"@folio/stripes-cli": "^2.6.1",
"@folio/stripes-erm-components": "^7.0.1",
"@folio/stripes-erm-components": "^7.0.5",
"@folio/stripes-testing": "^4.2.0",
"@formatjs/cli": "^4.2.29",
"@testing-library/dom": "^8.16.0",
Expand Down Expand Up @@ -67,7 +67,7 @@
"typescript": "^2.8.0"
},
"dependencies": {
"@k-int/stripes-kint-components": "^3.0.2",
"@k-int/stripes-kint-components": "^3.2.2",
"@rehooks/local-storage": "2.4.4",
"compose-function": "^3.0.3",
"final-form": "^4.18.4",
Expand All @@ -82,7 +82,7 @@
},
"peerDependencies": {
"@folio/stripes": "^7.3.1",
"@folio/stripes-erm-components": "^7.0.1",
"@folio/stripes-erm-components": "^7.0.5",
"moment": "^2.29.3",
"react": "^17.0.2",
"react-dom": "^17.0.2",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,15 @@
import React from 'react';
import PropTypes from 'prop-types';
import { get } from 'lodash';
import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
import { ViewOrganizationCard } from '@folio/stripes-erm-components';
import { Accordion, Badge, Icon, Layout } from '@folio/stripes/components';
import { AppIcon } from '@folio/stripes/core';

export default class LicenseOrganizations extends React.Component {
static propTypes = {
handlers: PropTypes.shape({
onFetchCredentials: PropTypes.func,
}),
id: PropTypes.string.isRequired,
license: PropTypes.shape({
orgs: PropTypes.arrayOf(
PropTypes.shape({
note: PropTypes.string,
org: PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string.isRequired,
vendorsUuid: PropTypes.string,
}).isRequired,
roles: PropTypes.arrayOf(
PropTypes.shape({
role: PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}).isRequired,
})
),
}),
),
}).isRequired,
};

renderOrgList = (orgs) => {
const LicenseOrganizations = ({
id,
license
}) => {
const renderOrgList = (orgs) => {
return orgs.map(o => {
const { interfaces, note, org, primaryOrg, roles } = o;
if (!org || !roles.length) return null;
Expand All @@ -44,7 +18,6 @@ export default class LicenseOrganizations extends React.Component {
<ViewOrganizationCard
key={`${org.orgsUuid}`}
data-test-license-org
fetchCredentials={this.props.handlers.onFetchCredentials}
headerStart={
<span>
<AppIcon
Expand All @@ -61,39 +34,61 @@ export default class LicenseOrganizations extends React.Component {
}
interfaces={interfaces}
note={note}
org={org}
roles={roles}
/>
);
});
}

renderOrganizations = () => {
const { orgs } = this.props.license;
};

const renderOrganizations = () => {
const orgs = license?.orgs;
if (!orgs || !orgs.length) return <FormattedMessage id="ui-licenses.emptyAccordion.organizations" />;

return this.renderOrgList(orgs);
}
return renderOrgList(orgs);
};

renderBadge = () => {
const count = get(this.props.license, ['orgs', 'length']);
const renderBadge = () => {
const count = license?.orgs?.length;
return count !== undefined ? <Badge>{count}</Badge> : <Icon icon="spinner-ellipsis" width="10px" />;
}
};

return (
<Accordion
displayWhenClosed={renderBadge()}
displayWhenOpen={renderBadge()}
id={id}
label={<FormattedMessage id="ui-licenses.section.organizations" />}
>
<Layout className="padding-bottom-gutter">
{renderOrganizations()}
</Layout>
</Accordion>
);
};

render() {
const { id } = this.props;
LicenseOrganizations.propTypes = {
id: PropTypes.string.isRequired,
license: PropTypes.shape({
orgs: PropTypes.arrayOf(
PropTypes.shape({
note: PropTypes.string,
org: PropTypes.shape({
id: PropTypes.string,
name: PropTypes.string.isRequired,
vendorsUuid: PropTypes.string,
}).isRequired,
roles: PropTypes.arrayOf(
PropTypes.shape({
role: PropTypes.shape({
label: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
}).isRequired,
})
),
}),
),
}).isRequired,
};

return (
<Accordion
displayWhenClosed={this.renderBadge()}
displayWhenOpen={this.renderBadge()}
id={id}
label={<FormattedMessage id="ui-licenses.section.organizations" />}
>
<Layout className="padding-bottom-gutter">
{this.renderOrganizations()}
</Layout>
</Accordion>
);
}
}
export default LicenseOrganizations;
90 changes: 13 additions & 77 deletions src/routes/ViewLicenseRoute/ViewLicenseRoute.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import React, { useContext } from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';

import { useMutation, useQuery, useQueryClient } from 'react-query';

import { get, flatten, uniqBy } from 'lodash';
import { flatten } from 'lodash';

import { CalloutContext, stripesConnect, useOkapiKy } from '@folio/stripes/core';
import { useBatchedFetch, useUsers } from '@folio/stripes-erm-components';
import { useCallout, useOkapiKy, useStripes } from '@folio/stripes/core';
import { useBatchedFetch, useInterfaces, useUsers } from '@folio/stripes-erm-components';

import View from '../../components/License';
import { urls as appUrls } from '../../components/utils';
Expand All @@ -17,20 +16,17 @@ import { LICENSE_ENDPOINT, LINKED_AGREEMENTS_ENDPOINT } from '../../constants/en
import { useLicensesHelperApp } from '../../hooks';

const RECORDS_PER_REQUEST = 100;
const credentialsArray = [];

const ViewLicenseRoute = ({
handlers = {},
history,
location,
match: { params: { id: licenseId } },
mutator,
resources,
stripes
}) => {
const callout = useContext(CalloutContext);
const callout = useCallout();
const ky = useOkapiKy();
const queryClient = useQueryClient();
const stripes = useStripes();

const licensePath = LICENSE_ENDPOINT(licenseId);

Expand All @@ -56,6 +52,10 @@ const ViewLicenseRoute = ({
}
);

const interfaces = useInterfaces({
interfaceIds: flatten((license?.orgs ?? []).map(o => o?.org?.orgsUuid_object?.interfaces ?? []))
}) ?? [];

// Users fetch
const { data: { users = [] } = {} } = useUsers(license?.contacts?.filter(c => c.user)?.map(c => c.user));

Expand All @@ -74,32 +74,19 @@ const ViewLicenseRoute = ({
path: LINKED_AGREEMENTS_ENDPOINT(licenseId),
});

const getRecord = (id, resourceType) => {
return get(resources, `${resourceType}.records`, [])
.find(i => i.id === id);
};

const getCompositeLicense = () => {
const contacts = license.contacts?.map(c => ({
...c,
user: users?.find(user => user?.id === c.user) || c.user,
}));

const interfacesCredentials = uniqBy(get(resources, 'interfacesCredentials.records', []), 'id');

if (interfacesCredentials[0]) {
const index = credentialsArray.findIndex(object => object.id === interfacesCredentials[0].id);
if (index === -1) {
credentialsArray.push(interfacesCredentials[0]);
}
}

const orgs = license.orgs?.map(o => ({
...o,
interfaces: get(o, 'org.orgsUuid_object.interfaces', [])
interfaces: (o?.org?.orgsUuid_object?.interfaces ?? [])
.map(id => ({
...getRecord(id, 'interfaces') || {},
credentials: credentialsArray.find(cred => cred.interfaceId === id)
...(interfaces?.find(int => int?.id === id) ?? {}),
/* Credentials are now handled by ViewOrganizationCard directly */
})),
}));

Expand Down Expand Up @@ -150,10 +137,6 @@ const ViewLicenseRoute = ({
});
};

const handleFetchCredentials = (id) => {
mutator.interfaceRecord.replace({ id });
};

const urls = {
edit: stripes.hasPerm('ui-licenses.licenses.edit') && (() => `${location.pathname}/edit${location.search}`),
addAmendment: stripes.hasPerm('ui-licenses.licenses.edit') && (() => `${location.pathname}/amendments/create${location.search}`),
Expand Down Expand Up @@ -184,7 +167,6 @@ const ViewLicenseRoute = ({
onClose: handleClose,
onDelete: handleDelete,
onEdit: editLicense,
onFetchCredentials: handleFetchCredentials,
onAmendmentClick: viewAmendment,
onToggleTags: handleToggleTags,
}}
Expand All @@ -208,52 +190,6 @@ ViewLicenseRoute.propTypes = {
id: PropTypes.string.isRequired,
}).isRequired
}).isRequired,
mutator: PropTypes.shape({
interfaceRecord: PropTypes.shape({
replace: PropTypes.func,
}),
}).isRequired,
resources: PropTypes.shape({
interfaces: PropTypes.object,
license: PropTypes.object,
query: PropTypes.shape({
helper: PropTypes.string,
}),
}).isRequired,
stripes: PropTypes.shape({
hasPerm: PropTypes.func.isRequired,
okapi: PropTypes.object.isRequired,
}).isRequired,
};

ViewLicenseRoute.manifest = Object.freeze({
interfaces: {
type: 'okapi',
path: 'organizations-storage/interfaces',
perRequest: RECORDS_PER_REQUEST,
params: (_q, _p, _r, _l, props) => {
const orgs = get(props.resources, 'license.records[0].orgs', []);
const interfaces = flatten(orgs.map(o => get(o, 'org.orgsUuid_object.interfaces', [])));
const query = [
...new Set(interfaces.map(i => `id==${i}`))
].join(' or ');

return query ? { query } : {};
},
fetch: props => !!props.stripes.hasInterface('organizations-storage.interfaces', '2.0'),
permissionsRequired: 'organizations-storage.interfaces.collection.get',
records: 'interfaces',
},
interfacesCredentials: {
clientGeneratePk: false,
throwErrors: false,
path: 'organizations-storage/interfaces/%{interfaceRecord.id}/credentials',
type: 'okapi',
pk: 'FAKE_PK', // it's done to fool stripes-connect not to add cred id to the path's end.
permissionsRequired: 'organizations-storage.interfaces.credentials.item.get',
fetch: props => !!props.stripes.hasInterface('organizations-storage.interfaces', '1.0 2.0'),
},
interfaceRecord: {},
});

export default stripesConnect(ViewLicenseRoute);
export default ViewLicenseRoute;
Loading

0 comments on commit 5e612d5

Please sign in to comment.