Skip to content

Commit

Permalink
assets: add UI contrib components
Browse files Browse the repository at this point in the history
  • Loading branch information
kpsherva committed Apr 20, 2023
1 parent 9ae7f7d commit 7fc3848
Show file tree
Hide file tree
Showing 27 changed files with 1,378 additions and 1 deletion.
20 changes: 20 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ jobs:
requirements-level: [pypi]
db-service: [postgresql10, postgresql13]
search-service: [opensearch2,elasticsearch7]
node-version: [16.x]
exclude:
- python-version: 3.7
db-service: postgresql13
Expand All @@ -55,6 +56,13 @@ jobs:
- name: Checkout
uses: actions/checkout@v2

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v1
with:
node-version: ${{ matrix.node-version }}
- name: Run eslint test
run: ./run-js-linter.sh -i

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v2
with:
Expand Down Expand Up @@ -82,3 +90,15 @@ jobs:
- name: Run tests
run: |
./run-tests.sh
- name: Install deps for frontend tests
working-directory: ./invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies
run: npm install

- name: Install deps for frontend tests - translations
working-directory: ./invenio_vocabularies/assets/semantic-ui/translations/invenio_vocabularies
run: npm install

- name: Run frontend tests
working-directory: ./invenio_vocabularies/assets/semantic-ui/js/invenio_vocabularies
run: npm test
2 changes: 2 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ recursive-include invenio_vocabularies *.html
recursive-include invenio_vocabularies *.json
recursive-include invenio_vocabularies *.py
recursive-include invenio_vocabularies/translations *.po *.pot *.mo
recursive-include invenio_vocabularies *.js *.prettierrc *.yml
recursive-include invenio_vocabularies *.png
recursive-include tests *.json
recursive-include tests *.py
recursive-include tests *.yaml
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-
#
# This file is part of Invenio.
# Copyright (C) 2023 CERN.
#
# Invenio is free software; you can redistribute it and/or modify
# it under the terms of the MIT License; see LICENSE file for more details.

extends:
- '@inveniosoftware/eslint-config-invenio'
- '@inveniosoftware/eslint-config-invenio/prettier'
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"@inveniosoftware/eslint-config-invenio/prettier-config.js"
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// This file is part of InvenioVocabularies
// Copyright (C) 2023 CERN.
//
// Invenio is free software; you can redistribute it and/or modify it
// under the terms of the MIT License; see LICENSE file for more details.

export * from "./src";
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"@comment": [
"This package.json is needed to run the JS tests, locally and CI."
],
"scripts": {
"test": "react-scripts test"
},
"devDependencies": {
"@testing-library/jest-dom": "^4.2.0",
"@testing-library/react": "^9.5.0",
"@testing-library/user-event": "^7.2.0",
"axios": "^0.21.0",
"coveralls": "^3.0.0",
"enzyme": "^3.10.0",
"enzyme-adapter-react-16": "^1.15.0",
"enzyme-to-json": "^3.4.0",
"expect": "^26.0.0",
"lodash": "^4.17.0",
"luxon": "^1.23.0",
"react": "^16.13.0",
"react-dom": "^16.13.0",
"react-scripts": "^5.0.1",
"semantic-ui-react": "^2.1.0",
"react-overridable": "^0.0.3"
},
"jest": {
"snapshotSerializers": [
"enzyme-to-json/serializer"
]
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
// This file is part of InvenioVocabularies
// Copyright (C) 2021-2023 CERN.
// Copyright (C) 2021 Northwestern University.
//
// Invenio is free software; you can redistribute it and/or modify it
// under the terms of the MIT License; see LICENSE file for more details.

import React from "react";
import PropTypes from "prop-types";
import _get from "lodash/get";
import { Item, Header, Radio, Label, Icon } from "semantic-ui-react";
import { withState } from "react-searchkit";
import { FastField } from "formik";

export const AwardResults = withState(
({
currentResultsState: results,
deserializeAward,
deserializeFunder,
computeFundingContents,
}) => {
return (
<FastField name="selectedFunding">
{({ form: { values, setFieldValue } }) => {
return (
<Item.Group>
{results.data.hits.map((award) => {
let funder = award?.funder;
const deserializedAward = deserializeAward(award);
const deserializedFunder = deserializeFunder(funder);
const funding = {
award: deserializedAward,
funder: deserializedFunder,
};
let { headerContent, descriptionContent, awardOrFunder } =
computeFundingContents(funding);

return (
<Item
key={deserializedAward.id}
onClick={() => setFieldValue("selectedFunding", funding)}
className="license-item"
>
<Radio
checked={
_get(values, "selectedFunding.award.id") === funding.award.id
}
onChange={() => setFieldValue("selectedFunding", funding)}
/>
<Item.Content className="license-item-content">
<Header size="small">
{headerContent}
{awardOrFunder === "award"
? award.number && (
<Label basic size="mini">
{award.number}
</Label>
)
: ""}
{awardOrFunder === "award"
? award.url && (
<a
href={`${award.url}`}
target="_blank"
rel="noopener noreferrer"
>
<Icon
link
name="external alternate"
className="spaced-left"
/>
</a>
)
: ""}
</Header>
<Item.Description className="license-item-description">
{descriptionContent}
</Item.Description>
</Item.Content>
</Item>
);
})}
</Item.Group>
);
}}
</FastField>
);
}
);

AwardResults.propTypes = {
deserializeAward: PropTypes.func.isRequired,
deserializeFunder: PropTypes.func.isRequired,
computeFundingContents: PropTypes.func.isRequired,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
// This file is part of InvenioVocabularies
// Copyright (C) 2021-2023 CERN.
// Copyright (C) 2021 Northwestern University.
//
// Invenio is free software; you can redistribute it and/or modify it
// under the terms of the MIT License; see LICENSE file for more details.

import PropTypes from "prop-types";
import React from "react";
import { Form, Header } from "semantic-ui-react";
import { TextField, RemoteSelectField } from "react-invenio-forms";
import { i18next } from "@translations/invenio_rdm_records/i18next";
import _isEmpty from "lodash/isEmpty";

function CustomAwardForm({ deserializeFunder, selectedFunding }) {
function deserializeFunderToDropdown(funderItem) {
let funderName = null;
let funderPID = null;

if (funderItem.name) {
funderName = funderItem.name;
}

if (funderItem.pid) {
funderPID = funderItem.pid;
}

if (!funderName && !funderPID) {
return {};
}

return {
text: funderName || funderPID,
value: funderItem.id,
key: funderItem.id,
...(funderName && { name: funderName }),
...(funderPID && { pid: funderPID }),
};
}

function serializeFunderFromDropdown(funderDropObject) {
return {
id: funderDropObject.key,
...(funderDropObject.name && { name: funderDropObject.name }),
...(funderDropObject.pid && { pid: funderDropObject.pid }),
};
}

return (
<Form>
<RemoteSelectField
fieldPath="selectedFunding.funder.id"
suggestionAPIUrl="/api/funders"
suggestionAPIHeaders={{
Accept: "application/vnd.inveniordm.v1+json",
}}
placeholder={i18next.t("Search for a funder by name")}
serializeSuggestions={(funders) => {
return funders.map((funder) =>
deserializeFunderToDropdown(deserializeFunder(funder))
);
}}
searchInput={{
autoFocus: _isEmpty(selectedFunding),
}}
label={i18next.t("Funder")}
noQueryMessage={i18next.t("Search for funder...")}
clearable
allowAdditions={false}
multiple={false}
selectOnBlur={false}
selectOnNavigation={false}
required
search={(options) => options}
onValueChange={({ formikProps }, selectedFundersArray) => {
if (selectedFundersArray.length === 1) {
const selectedFunder = selectedFundersArray[0];
if (selectedFunder) {
const deserializedFunder = serializeFunderFromDropdown(selectedFunder);
formikProps.form.setFieldValue(
"selectedFunding.funder",
deserializedFunder
);
}
}
}}
/>

<Header as="h3" size="small">
{i18next.t("Award information")} ({i18next.t("optional")})
</Header>
<Form.Group widths="equal">
<TextField
label={i18next.t("Number")}
placeholder={i18next.t("Award number")}
fieldPath="selectedFunding.award.number"
/>
<TextField
label={i18next.t("Title")}
placeholder={i18next.t("Award Title")}
fieldPath="selectedFunding.award.title"
/>
<TextField
label={i18next.t("URL")}
placeholder={i18next.t("Award URL")}
fieldPath="selectedFunding.award.url"
/>
</Form.Group>
</Form>
);
}

CustomAwardForm.propTypes = {
deserializeFunder: PropTypes.func.isRequired,
selectedFunding: PropTypes.object,
};

CustomAwardForm.defaultProps = {
selectedFunding: undefined,
};

export default CustomAwardForm;
Loading

0 comments on commit 7fc3848

Please sign in to comment.