@truedat/dd 4.28.3 → 4.28.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/package.json +6 -6
- package/src/api.js +8 -0
- package/src/components/DictionaryRoutes.js +27 -0
- package/src/components/EditDomainForm.js +1 -0
- package/src/components/GrantDateFilter.js +30 -0
- package/src/components/GrantFilters.js +28 -0
- package/src/components/GrantFiltersLoader.js +29 -0
- package/src/components/GrantSelectedFilters.js +63 -0
- package/src/components/Grants.js +54 -0
- package/src/components/GrantsLabelResults.js +32 -0
- package/src/components/GrantsLoader.js +47 -0
- package/src/components/GrantsPagination.js +14 -0
- package/src/components/GrantsSearch.js +51 -0
- package/src/components/GrantsTable.js +112 -0
- package/src/components/StructureGrantCart.js +16 -14
- package/src/components/StructureGrantCartCheckout.js +9 -9
- package/src/components/StructureSummary.js +5 -5
- package/src/components/StructureTabPane.js +3 -3
- package/src/components/StructureView.js +14 -6
- package/src/components/__tests__/GrantDateFilter.spec.js +11 -0
- package/src/components/__tests__/GrantsLabelResults.js +17 -0
- package/src/components/__tests__/GrantsLoader.spec.js +41 -0
- package/src/components/__tests__/GrantsTable.spec.js +185 -0
- package/src/components/__tests__/StructureGrantRequestButton.spec.js +20 -9
- package/src/components/__tests__/StructureSummary.spec.js +1 -1
- package/src/components/__tests__/__snapshots__/DictionaryRoutes.spec.js.snap +8 -0
- package/src/components/__tests__/__snapshots__/GrantDateFilter.spec.js.snap +16 -0
- package/src/components/__tests__/__snapshots__/GrantsLabelResults.js.snap +16 -0
- package/src/components/__tests__/__snapshots__/GrantsLoader.spec.js.snap +27 -0
- package/src/components/__tests__/__snapshots__/GrantsTable.spec.js.snap +231 -0
- package/src/components/index.js +4 -0
- package/src/messages/en.js +12 -2
- package/src/messages/es.js +12 -2
- package/src/reducers/__tests__/grantDateFilter.spec.js +54 -0
- package/src/reducers/__tests__/grantFilters.spec.js +37 -0
- package/src/reducers/__tests__/grantQuery.spec.js +113 -0
- package/src/reducers/__tests__/grants.spec.js +102 -0
- package/src/reducers/grantActiveFilters.js +48 -0
- package/src/reducers/grantCount.js +20 -0
- package/src/reducers/grantDateFilter.js +31 -0
- package/src/reducers/grantFilters.js +19 -0
- package/src/reducers/grantLoading.js +16 -0
- package/src/reducers/grantQuery.js +62 -0
- package/src/reducers/grantSelectedFilter.js +34 -0
- package/src/reducers/grants.js +24 -0
- package/src/reducers/grantsFilters.js +19 -0
- package/src/reducers/grantsPageSize.js +15 -0
- package/src/reducers/index.js +18 -0
- package/src/reducers/structureDateFilter.js +2 -2
- package/src/reducers/structureQuery.js +2 -2
- package/src/routines.js +20 -0
- package/src/sagas/__tests__/fetchGrantFilters.spec.js +97 -0
- package/src/sagas/__tests__/fetchGrants.spec.js +86 -0
- package/src/sagas/fetchGrantFilters.js +31 -0
- package/src/sagas/fetchGrants.js +26 -0
- package/src/sagas/index.js +6 -0
- package/src/selectors/__tests__/__snapshots__/getGrantsColumns.spec.js.snap +10 -0
- package/src/selectors/__tests__/getGrantAvailableFilters.spec.js +15 -0
- package/src/selectors/__tests__/getGrantSelectedFilterActiveValues.spec.js +16 -0
- package/src/selectors/__tests__/getGrantSelectedFilterValues.spec.js +15 -0
- package/src/selectors/__tests__/getGrantSelectedFilters.spec.js +15 -0
- package/src/selectors/__tests__/getGrantsColumns.spec.js +40 -0
- package/src/selectors/__tests__/getTabVisibility.spec.js +30 -30
- package/src/selectors/getGrantAvailableFilters.js +17 -0
- package/src/selectors/getGrantSelectedFilterActiveValues.js +8 -0
- package/src/selectors/getGrantSelectedFilterValues.js +13 -0
- package/src/selectors/getGrantSelectedFilters.js +7 -0
- package/src/selectors/getGrantsColumns.js +84 -8
- package/src/selectors/getStructureSelectedFilterValues.js +5 -3
- package/src/selectors/getTabVisibility.js +7 -7
- package/src/selectors/index.js +4 -0
package/CHANGELOG.md
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@truedat/dd",
|
|
3
|
-
"version": "4.28.
|
|
3
|
+
"version": "4.28.7",
|
|
4
4
|
"description": "Truedat Web Data Dictionary",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"jsnext:main": "src/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"@testing-library/jest-dom": "^5.14.1",
|
|
35
35
|
"@testing-library/react": "^12.0.0",
|
|
36
36
|
"@testing-library/user-event": "^13.2.1",
|
|
37
|
-
"@truedat/test": "4.28.
|
|
37
|
+
"@truedat/test": "4.28.7",
|
|
38
38
|
"babel-jest": "^27.0.6",
|
|
39
39
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
40
40
|
"babel-plugin-lodash": "^3.3.4",
|
|
@@ -84,9 +84,9 @@
|
|
|
84
84
|
]
|
|
85
85
|
},
|
|
86
86
|
"dependencies": {
|
|
87
|
-
"@truedat/auth": "4.28.
|
|
88
|
-
"@truedat/core": "4.28.
|
|
89
|
-
"@truedat/df": "4.28.
|
|
87
|
+
"@truedat/auth": "4.28.7",
|
|
88
|
+
"@truedat/core": "4.28.7",
|
|
89
|
+
"@truedat/df": "4.28.7",
|
|
90
90
|
"lodash": "^4.17.21",
|
|
91
91
|
"path-to-regexp": "^1.7.0",
|
|
92
92
|
"prop-types": "^15.7.2",
|
|
@@ -107,5 +107,5 @@
|
|
|
107
107
|
"react-dom": ">= 16.8.6 < 17",
|
|
108
108
|
"semantic-ui-react": ">= 0.88.2 < 2.1"
|
|
109
109
|
},
|
|
110
|
-
"gitHead": "
|
|
110
|
+
"gitHead": "d5cfc6f850ec38066139c97836b75d2f21d61d54"
|
|
111
111
|
}
|
package/src/api.js
CHANGED
|
@@ -4,11 +4,15 @@ const API_DATA_STRUCTURES_CSV = "/api/data_structures/csv";
|
|
|
4
4
|
const API_DATA_STRUCTURES_SEARCH = "/api/data_structures/search";
|
|
5
5
|
const API_DATA_STRUCTURE_FILTERS_SEARCH = "/api/data_structure_filters/search";
|
|
6
6
|
const API_DATA_STRUCTURE_VERSION = "/api/data_structures/:id/versions/:version";
|
|
7
|
+
const API_GRANT_FILTERS_SEARCH = "/api/grant_filters/search";
|
|
7
8
|
const API_PROFILE_EXECUTION = "/api/profile_executions/:id";
|
|
8
9
|
const API_GRANT_REQUEST = "/api/grant_request_groups";
|
|
10
|
+
const API_GRANTS_SEARCH = "/api/grants/search";
|
|
9
11
|
const API_GRAPH = "/api/graphs/:id";
|
|
10
12
|
const API_GRAPHS = "/api/graphs";
|
|
11
13
|
const API_GRAPH_CSV = "/api/graphs/csv";
|
|
14
|
+
const API_MY_GRANT_FILTERS_SEARCH = "/api/grant_filters/search/mine";
|
|
15
|
+
const API_MY_GRANTS_SEARCH = "/api/grants/search/mine";
|
|
12
16
|
const API_NODE = "/api/nodes/:id";
|
|
13
17
|
const API_NODES = "/api/nodes";
|
|
14
18
|
const API_PROFILE_GROUP = "/api/profile_execution_groups/:id";
|
|
@@ -40,10 +44,14 @@ export {
|
|
|
40
44
|
API_DATA_STRUCTURE_FILTERS_SEARCH,
|
|
41
45
|
API_DATA_STRUCTURE_VERSION,
|
|
42
46
|
API_PROFILE_EXECUTION,
|
|
47
|
+
API_GRANT_FILTERS_SEARCH,
|
|
43
48
|
API_GRANT_REQUEST,
|
|
49
|
+
API_GRANTS_SEARCH,
|
|
44
50
|
API_GRAPH,
|
|
45
51
|
API_GRAPHS,
|
|
46
52
|
API_GRAPH_CSV,
|
|
53
|
+
API_MY_GRANTS_SEARCH,
|
|
54
|
+
API_MY_GRANT_FILTERS_SEARCH,
|
|
47
55
|
API_NODE,
|
|
48
56
|
API_NODES,
|
|
49
57
|
API_PROFILE_GROUP,
|
|
@@ -9,6 +9,8 @@ import {
|
|
|
9
9
|
STRUCTURE_TYPES,
|
|
10
10
|
SYSTEMS,
|
|
11
11
|
GRANTS_REQUESTS_CHECKOUT,
|
|
12
|
+
GRANTS,
|
|
13
|
+
MY_GRANTS,
|
|
12
14
|
} from "@truedat/core/routes";
|
|
13
15
|
import ProfileExecution from "./ProfileExecution";
|
|
14
16
|
import ProfileExecutionBreadcrumbs from "./ProfileExecutionBreadcrumbs";
|
|
@@ -24,6 +26,9 @@ import StructureTypesRoutes from "./StructureTypesRoutes";
|
|
|
24
26
|
import SystemsRoutes from "./SystemsRoutes";
|
|
25
27
|
import SystemsLoader from "./SystemsLoader";
|
|
26
28
|
import StructureGrantCartCheckout from "./StructureGrantCartCheckout";
|
|
29
|
+
import GrantFiltersLoader from "./GrantFiltersLoader";
|
|
30
|
+
import GrantsLoader from "./GrantsLoader";
|
|
31
|
+
import Grants from "./Grants";
|
|
27
32
|
|
|
28
33
|
const TemplatesLoader = React.lazy(() =>
|
|
29
34
|
import("@truedat/df/templates/components/TemplatesLoader")
|
|
@@ -69,6 +74,28 @@ export const DictionaryRoutes = () => {
|
|
|
69
74
|
path={GRANTS_REQUESTS_CHECKOUT}
|
|
70
75
|
render={() => <StructureGrantCartCheckout />}
|
|
71
76
|
/>
|
|
77
|
+
<Route
|
|
78
|
+
path={GRANTS}
|
|
79
|
+
render={() => (
|
|
80
|
+
<>
|
|
81
|
+
<GrantsLoader />
|
|
82
|
+
<GrantFiltersLoader />
|
|
83
|
+
<Grants />
|
|
84
|
+
</>
|
|
85
|
+
)}
|
|
86
|
+
/>
|
|
87
|
+
<Route
|
|
88
|
+
path={MY_GRANTS}
|
|
89
|
+
render={() => {
|
|
90
|
+
return (
|
|
91
|
+
<>
|
|
92
|
+
<GrantsLoader onlyMyGrants />
|
|
93
|
+
<GrantFiltersLoader onlyMyGrants />
|
|
94
|
+
<Grants onlyMyGrants />
|
|
95
|
+
</>
|
|
96
|
+
);
|
|
97
|
+
}}
|
|
98
|
+
/>
|
|
72
99
|
<Route path={STRUCTURE_TAGS} render={() => <StructureTagsRoutes />} />
|
|
73
100
|
<Route path={STRUCTURE_TYPES} render={() => <StructureTypesRoutes />} />
|
|
74
101
|
<Route
|
|
@@ -27,6 +27,7 @@ export const EditDomainForm = ({ title, updateStructure, structure }) => {
|
|
|
27
27
|
<Container style={{ width: "400px" }}>
|
|
28
28
|
<Header as="h2" content={title} />
|
|
29
29
|
<DomainDropdownSelector
|
|
30
|
+
clearable={false}
|
|
30
31
|
onChange={handleDomainSelected}
|
|
31
32
|
name="domain"
|
|
32
33
|
value={domainId || structure?.domain_id}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { propOr } from "lodash/fp";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
5
|
+
import { connect } from "react-redux";
|
|
6
|
+
import DateRangeFilter from "@truedat/core/components/DateRangeFilter";
|
|
7
|
+
import { applyGrantDateFilter } from "../routines";
|
|
8
|
+
|
|
9
|
+
export const GrantDateFilter = ({ active, applyGrantDateFilter, ...props }) =>
|
|
10
|
+
active ? (
|
|
11
|
+
<>
|
|
12
|
+
<DateRangeFilter
|
|
13
|
+
label={<FormattedMessage id="grant.start_date" />}
|
|
14
|
+
name="start_date,end_date"
|
|
15
|
+
onChange={applyGrantDateFilter}
|
|
16
|
+
defaultValues={props}
|
|
17
|
+
/>
|
|
18
|
+
</>
|
|
19
|
+
) : null;
|
|
20
|
+
|
|
21
|
+
GrantDateFilter.propTypes = {
|
|
22
|
+
active: PropTypes.bool,
|
|
23
|
+
applyGrantDateFilter: PropTypes.func,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export const mapStateToProps = propOr({}, "grantDateFilter");
|
|
27
|
+
|
|
28
|
+
export default connect(mapStateToProps, { applyGrantDateFilter })(
|
|
29
|
+
GrantDateFilter
|
|
30
|
+
);
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { connect } from "react-redux";
|
|
3
|
+
import { bindActionCreators } from "redux";
|
|
4
|
+
import { addGrantFilter, resetGrantFilters } from "../routines";
|
|
5
|
+
import { getGrantAvailableFilters } from "../selectors";
|
|
6
|
+
|
|
7
|
+
const AvailableFilters = React.lazy(() =>
|
|
8
|
+
import("@truedat/core/components/AvailableFilters")
|
|
9
|
+
);
|
|
10
|
+
|
|
11
|
+
const mapStateToProps = (state) => {
|
|
12
|
+
return {
|
|
13
|
+
filters: getGrantAvailableFilters(state),
|
|
14
|
+
disabled: state.grantFiltersLoading,
|
|
15
|
+
loading: state.grantFiltersLoading,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const mapDispatchToProps = (dispatch) =>
|
|
20
|
+
bindActionCreators(
|
|
21
|
+
{
|
|
22
|
+
addFilter: addGrantFilter,
|
|
23
|
+
resetFilters: resetGrantFilters,
|
|
24
|
+
},
|
|
25
|
+
dispatch
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
export default connect(mapStateToProps, mapDispatchToProps)(AvailableFilters);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { connect } from "react-redux";
|
|
2
|
+
import { bindActionCreators } from "redux";
|
|
3
|
+
import { FiltersLoader } from "@truedat/core/components";
|
|
4
|
+
import { makeActiveFiltersSelector } from "@truedat/core/selectors";
|
|
5
|
+
import { clearGrantFilters, fetchGrantFilters } from "../routines";
|
|
6
|
+
|
|
7
|
+
const mapDispatchToProps = (dispatch, props) => {
|
|
8
|
+
const { onlyMyGrants } = props;
|
|
9
|
+
const fetchMyGrantsFilters = (payload) => {
|
|
10
|
+
return fetchGrantFilters({ payload, onlyMyGrants });
|
|
11
|
+
};
|
|
12
|
+
return bindActionCreators(
|
|
13
|
+
{ clearFilters: clearGrantFilters, fetchFilters: fetchMyGrantsFilters },
|
|
14
|
+
dispatch
|
|
15
|
+
);
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const makeMapStateToProps = ({}) => {
|
|
19
|
+
const activeFiltersSelector = makeActiveFiltersSelector("grantActiveFilters");
|
|
20
|
+
const mapStateToProps = (state, props) => {
|
|
21
|
+
return {
|
|
22
|
+
selectedFilter: state.grantSelectedFilter,
|
|
23
|
+
filters: activeFiltersSelector(state, props),
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
return mapStateToProps;
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export default connect(makeMapStateToProps, mapDispatchToProps)(FiltersLoader);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import { bindActionCreators } from "redux";
|
|
3
|
+
import { connect } from "react-redux";
|
|
4
|
+
import { makeOption } from "@truedat/core/services/i18n";
|
|
5
|
+
import { SelectedFilters } from "@truedat/core/components";
|
|
6
|
+
import {
|
|
7
|
+
closeGrantFilter,
|
|
8
|
+
openGrantFilter,
|
|
9
|
+
removeGrantFilter,
|
|
10
|
+
resetGrantFilters,
|
|
11
|
+
toggleGrantFilterValue,
|
|
12
|
+
} from "../routines";
|
|
13
|
+
import {
|
|
14
|
+
getGrantSelectedFilterActiveValues,
|
|
15
|
+
getGrantSelectedFilters,
|
|
16
|
+
getGrantSelectedFilterValues,
|
|
17
|
+
} from "../selectors";
|
|
18
|
+
|
|
19
|
+
const translations = (formatMessage) => ({
|
|
20
|
+
"active.raw": (v) =>
|
|
21
|
+
formatMessage({ id: `filters.active.raw.${v}`, defaultMessage: v }),
|
|
22
|
+
"execution_result_info.result_text": (v) => formatMessage({ id: v }),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const mapStateToProps = (state, ownProps) => {
|
|
26
|
+
const formatMessage = _.pathOr(_.prop("id"), "intl.formatMessage")(ownProps);
|
|
27
|
+
const { grantSelectedFilter: selectedFilter } = state;
|
|
28
|
+
|
|
29
|
+
const i18nValues = _.flow(
|
|
30
|
+
getGrantSelectedFilterValues,
|
|
31
|
+
_.map(makeOption(translations(formatMessage), selectedFilter))
|
|
32
|
+
)(state);
|
|
33
|
+
|
|
34
|
+
// const values = _.flow(
|
|
35
|
+
// getGrantSelectedFilterValues,
|
|
36
|
+
// _.map((v) => ({ text: v, value: v }))
|
|
37
|
+
// )(state);
|
|
38
|
+
|
|
39
|
+
// _.map(
|
|
40
|
+
// makeOption(translations(formatMessage, structureTypes), selectedFilter)
|
|
41
|
+
// )(selectedFilterValues),
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
selectedFilter,
|
|
45
|
+
selectedFilters: getGrantSelectedFilters(state),
|
|
46
|
+
selectedFilterActiveValues: getGrantSelectedFilterActiveValues(state),
|
|
47
|
+
selectedFilterValues: i18nValues,
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const mapDispatchToProps = (dispatch) =>
|
|
52
|
+
bindActionCreators(
|
|
53
|
+
{
|
|
54
|
+
closeFilter: closeGrantFilter,
|
|
55
|
+
openFilter: openGrantFilter,
|
|
56
|
+
removeFilter: removeGrantFilter,
|
|
57
|
+
resetFilters: resetGrantFilters,
|
|
58
|
+
toggleFilterValue: toggleGrantFilterValue,
|
|
59
|
+
},
|
|
60
|
+
dispatch
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
export default connect(mapStateToProps, mapDispatchToProps)(SelectedFilters);
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { connect } from "react-redux";
|
|
4
|
+
import { Header, Icon, Segment, Dimmer, Loader } from "semantic-ui-react";
|
|
5
|
+
import { FormattedMessage } from "react-intl";
|
|
6
|
+
|
|
7
|
+
import GrantDateFilter from "./GrantDateFilter";
|
|
8
|
+
import GrantsSearch from "./GrantsSearch";
|
|
9
|
+
import GrantsTable from "./GrantsTable";
|
|
10
|
+
//import JobsLabelResults from "./JobsLabelResults";
|
|
11
|
+
import GrantsLabelResults from "./GrantsLabelResults";
|
|
12
|
+
|
|
13
|
+
import GrantSelectedFilters from "./GrantSelectedFilters";
|
|
14
|
+
import GrantsPagination from "./GrantsPagination";
|
|
15
|
+
|
|
16
|
+
export const Grants = ({ grantsLoading, onlyMyGrants }) => (
|
|
17
|
+
<Segment>
|
|
18
|
+
<Header as="h2">
|
|
19
|
+
<Icon circular name="cogs" />
|
|
20
|
+
<Header.Content>
|
|
21
|
+
<FormattedMessage
|
|
22
|
+
id={onlyMyGrants ? "grants.mine.header" : "grants.header"}
|
|
23
|
+
/>
|
|
24
|
+
<Header.Subheader>
|
|
25
|
+
<FormattedMessage
|
|
26
|
+
id={onlyMyGrants ? "grants.mine.subheader" : "grants.subheader"}
|
|
27
|
+
/>
|
|
28
|
+
</Header.Subheader>
|
|
29
|
+
</Header.Content>
|
|
30
|
+
</Header>
|
|
31
|
+
<Segment attached="bottom">
|
|
32
|
+
<GrantsSearch />
|
|
33
|
+
<GrantSelectedFilters />
|
|
34
|
+
<GrantDateFilter />
|
|
35
|
+
<Dimmer.Dimmable dimmed={grantsLoading}>
|
|
36
|
+
<Dimmer active={grantsLoading} inverted>
|
|
37
|
+
<Loader />
|
|
38
|
+
</Dimmer>
|
|
39
|
+
</Dimmer.Dimmable>
|
|
40
|
+
<GrantsLabelResults />
|
|
41
|
+
<GrantsTable onlyMyGrants={onlyMyGrants} />
|
|
42
|
+
<GrantsPagination />
|
|
43
|
+
</Segment>
|
|
44
|
+
</Segment>
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
Grants.propTypes = {
|
|
48
|
+
grantsLoading: PropTypes.bool,
|
|
49
|
+
onlyMyGrants: PropTypes.bool,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
const mapStateToProps = ({ grantsLoading }) => ({ grantsLoading });
|
|
53
|
+
|
|
54
|
+
export default connect(mapStateToProps)(Grants);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { connect } from "react-redux";
|
|
4
|
+
import { FormattedMessage } from "react-intl";
|
|
5
|
+
import { Label } from "semantic-ui-react";
|
|
6
|
+
|
|
7
|
+
export const GrantsLabelResults = ({ grantCount, grantsLoading }) => {
|
|
8
|
+
return (
|
|
9
|
+
<Label className="grants-label-results">
|
|
10
|
+
{grantsLoading ? (
|
|
11
|
+
<FormattedMessage id="grants.searching" />
|
|
12
|
+
) : (
|
|
13
|
+
<FormattedMessage
|
|
14
|
+
id="grants.retrieved.results"
|
|
15
|
+
values={{ count: grantCount }}
|
|
16
|
+
/>
|
|
17
|
+
)}
|
|
18
|
+
</Label>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
GrantsLabelResults.propTypes = {
|
|
23
|
+
grantCount: PropTypes.number,
|
|
24
|
+
grantsLoading: PropTypes.bool,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const mapStateToProps = ({ grantCount, grantsLoading }) => ({
|
|
28
|
+
grantCount,
|
|
29
|
+
grantsLoading,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
export default connect(mapStateToProps)(GrantsLabelResults);
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { useEffect } from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { connect } from "react-redux";
|
|
4
|
+
import { makeSearchQuerySelector } from "@truedat/core/selectors";
|
|
5
|
+
import { clearGrants, fetchGrants } from "../routines";
|
|
6
|
+
|
|
7
|
+
export const GrantsLoader = ({
|
|
8
|
+
clearGrants,
|
|
9
|
+
fetchGrants,
|
|
10
|
+
payload,
|
|
11
|
+
onlyMyGrants = false,
|
|
12
|
+
}) => {
|
|
13
|
+
useEffect(() => {
|
|
14
|
+
return () => {
|
|
15
|
+
clearGrants();
|
|
16
|
+
};
|
|
17
|
+
}, [clearGrants]);
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
fetchGrants({ payload, onlyMyGrants });
|
|
20
|
+
}, [payload, fetchGrants, onlyMyGrants]);
|
|
21
|
+
return null;
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
GrantsLoader.propTypes = {
|
|
25
|
+
clearGrants: PropTypes.func,
|
|
26
|
+
fetchGrants: PropTypes.func,
|
|
27
|
+
payload: PropTypes.object,
|
|
28
|
+
onlyMyGrants: PropTypes.bool,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
const makeMapStateToProps = () => {
|
|
32
|
+
const searchQuerySelector = makeSearchQuerySelector(
|
|
33
|
+
"grantQuery",
|
|
34
|
+
"grantActiveFilters",
|
|
35
|
+
"grantDateFilter"
|
|
36
|
+
);
|
|
37
|
+
const mapStateToProps = (state, props) => {
|
|
38
|
+
return {
|
|
39
|
+
payload: searchQuerySelector(state, props),
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
return mapStateToProps;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export default connect(makeMapStateToProps, { clearGrants, fetchGrants })(
|
|
46
|
+
GrantsLoader
|
|
47
|
+
);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { connect } from "react-redux";
|
|
2
|
+
import { bindActionCreators } from "redux";
|
|
3
|
+
import { Pagination } from "@truedat/core/components";
|
|
4
|
+
import { selectGrantPage } from "../routines";
|
|
5
|
+
|
|
6
|
+
const mapDispatchToProps = (dispatch) =>
|
|
7
|
+
bindActionCreators({ selectPage: selectGrantPage }, dispatch);
|
|
8
|
+
|
|
9
|
+
const mapStateToProps = ({ grantQuery, grantCount, grantsPageSize }) => ({
|
|
10
|
+
activePage: grantQuery?.page,
|
|
11
|
+
totalPages: Math.ceil(grantCount / grantsPageSize),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export default connect(mapStateToProps, mapDispatchToProps)(Pagination);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import PropTypes from "prop-types";
|
|
3
|
+
import { connect } from "react-redux";
|
|
4
|
+
import { Button, Icon, Input } from "semantic-ui-react";
|
|
5
|
+
import { useIntl } from "react-intl";
|
|
6
|
+
import { searchGrants, toggleGrantDateFilter } from "../routines";
|
|
7
|
+
import GrantFilters from "./GrantFilters";
|
|
8
|
+
|
|
9
|
+
export const GrantsSearch = ({
|
|
10
|
+
query,
|
|
11
|
+
searchGrants,
|
|
12
|
+
grantDateFilter,
|
|
13
|
+
toggleGrantDateFilter,
|
|
14
|
+
}) => {
|
|
15
|
+
const { formatMessage } = useIntl();
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<Input
|
|
19
|
+
value={query}
|
|
20
|
+
onChange={(_e, data) => searchGrants({ query: data.value })}
|
|
21
|
+
iconPosition="left"
|
|
22
|
+
action
|
|
23
|
+
placeholder={formatMessage({ id: "structures.search.placeholder" })}
|
|
24
|
+
>
|
|
25
|
+
<Icon name="search" link />
|
|
26
|
+
<input />
|
|
27
|
+
<Button
|
|
28
|
+
icon="calendar alternate outline"
|
|
29
|
+
active={grantDateFilter?.active}
|
|
30
|
+
onClick={() => toggleGrantDateFilter()}
|
|
31
|
+
/>
|
|
32
|
+
<GrantFilters />
|
|
33
|
+
</Input>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
GrantsSearch.propTypes = {
|
|
38
|
+
query: PropTypes.string,
|
|
39
|
+
searchGrants: PropTypes.func,
|
|
40
|
+
grantDateFilter: PropTypes.object,
|
|
41
|
+
toggleGrantDateFilter: PropTypes.func,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
const mapStateToProps = ({ grantQuery }) => ({
|
|
45
|
+
query: grantQuery?.query,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
export default connect(mapStateToProps, {
|
|
49
|
+
searchGrants,
|
|
50
|
+
toggleGrantDateFilter,
|
|
51
|
+
})(GrantsSearch);
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import _ from "lodash/fp";
|
|
2
|
+
import React, { useRef, useState } from "react";
|
|
3
|
+
import PropTypes from "prop-types";
|
|
4
|
+
import { useIntl } from "react-intl";
|
|
5
|
+
import { Table, Header, Icon } from "semantic-ui-react";
|
|
6
|
+
import { connect } from "react-redux";
|
|
7
|
+
import { columnDecoratorComponent } from "@truedat/core/services";
|
|
8
|
+
import { getSortInfo, sortColumn } from "@truedat/core/services/sort";
|
|
9
|
+
import { getGrantsColumns, getGrantsTableColumns } from "../selectors";
|
|
10
|
+
import { sortGrants } from "../routines";
|
|
11
|
+
|
|
12
|
+
export const GrantsTable = ({
|
|
13
|
+
columns,
|
|
14
|
+
grants,
|
|
15
|
+
grantsLoading,
|
|
16
|
+
sortGrants,
|
|
17
|
+
grantsSorting,
|
|
18
|
+
}) => {
|
|
19
|
+
const { formatMessage } = useIntl();
|
|
20
|
+
const filteredColumns = _.filter((c) => _.any(_.prop(c.name))(grants))(
|
|
21
|
+
columns
|
|
22
|
+
);
|
|
23
|
+
|
|
24
|
+
const [sortedColumn, setColumn] = useState(
|
|
25
|
+
_.prop("column")(getSortInfo(grantsSorting))
|
|
26
|
+
);
|
|
27
|
+
const [direction, setDirection] = useState(
|
|
28
|
+
_.prop("direction")(getSortInfo(grantsSorting))
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<>
|
|
33
|
+
{!_.isEmpty(grants) && (
|
|
34
|
+
<Table sortable selectable>
|
|
35
|
+
<Table.Header>
|
|
36
|
+
<Table.Row>
|
|
37
|
+
{columns.map((column, i) => {
|
|
38
|
+
return (
|
|
39
|
+
<Table.HeaderCell
|
|
40
|
+
key={i}
|
|
41
|
+
width={column.width}
|
|
42
|
+
content={formatMessage({
|
|
43
|
+
id: `grant.header.${column.name}`,
|
|
44
|
+
defaultMessage: column.name,
|
|
45
|
+
})}
|
|
46
|
+
sorted={
|
|
47
|
+
_.path("sort.name")(column) === sortedColumn
|
|
48
|
+
? direction
|
|
49
|
+
: null
|
|
50
|
+
}
|
|
51
|
+
className={_.path("sort.name")(column) ? "" : "disabled"}
|
|
52
|
+
onClick={() => {
|
|
53
|
+
filteredColumns.includes(column)
|
|
54
|
+
? sortColumn(
|
|
55
|
+
column,
|
|
56
|
+
sortGrants,
|
|
57
|
+
setDirection,
|
|
58
|
+
setColumn,
|
|
59
|
+
direction,
|
|
60
|
+
sortedColumn
|
|
61
|
+
)
|
|
62
|
+
: null;
|
|
63
|
+
}}
|
|
64
|
+
/>
|
|
65
|
+
);
|
|
66
|
+
})}
|
|
67
|
+
</Table.Row>
|
|
68
|
+
</Table.Header>
|
|
69
|
+
<Table.Body>
|
|
70
|
+
{grants.map((grant, i) => (
|
|
71
|
+
<Table.Row key={i}>
|
|
72
|
+
{columns &&
|
|
73
|
+
columns.map((column, key) => (
|
|
74
|
+
<Table.Cell
|
|
75
|
+
key={key}
|
|
76
|
+
textAlign={column.textAlign}
|
|
77
|
+
content={columnDecoratorComponent(column)(grant)}
|
|
78
|
+
/>
|
|
79
|
+
))}
|
|
80
|
+
</Table.Row>
|
|
81
|
+
))}
|
|
82
|
+
</Table.Body>
|
|
83
|
+
</Table>
|
|
84
|
+
)}
|
|
85
|
+
{_.isEmpty(grants) && !grantsLoading && (
|
|
86
|
+
<Header as="h4">
|
|
87
|
+
<Icon name="search" />
|
|
88
|
+
<Header.Content>
|
|
89
|
+
{formatMessage({ id: "grants.search.results.empty" })}
|
|
90
|
+
</Header.Content>
|
|
91
|
+
</Header>
|
|
92
|
+
)}
|
|
93
|
+
</>
|
|
94
|
+
);
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
GrantsTable.propTypes = {
|
|
98
|
+
columns: PropTypes.array,
|
|
99
|
+
grants: PropTypes.array,
|
|
100
|
+
grantsLoading: PropTypes.bool,
|
|
101
|
+
sortGrants: PropTypes.func,
|
|
102
|
+
grantsSorting: PropTypes.array,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const mapStateToProps = (state, { onlyMyGrants }) => ({
|
|
106
|
+
columns: getGrantsTableColumns({ ...state, onlyMyGrants }),
|
|
107
|
+
grants: state.grants,
|
|
108
|
+
grantsLoading: state.grantsLoading,
|
|
109
|
+
grantsSorting: _.path("grantQuery.sort")(state),
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
export default connect(mapStateToProps, { sortGrants })(GrantsTable);
|