diff --git a/.kubernetes/deployment.yml b/.kubernetes/deployment.yml index a75c0a464..3bab7d340 100644 --- a/.kubernetes/deployment.yml +++ b/.kubernetes/deployment.yml @@ -14,7 +14,7 @@ spec: spec: containers: - name: bauhaus - image: nicolaslaval/bauhaus:3.0.7 + image: nicolaslaval/bauhaus:3.0.8 env: - name: API_BASE_HOST value: 'https://bauhaus-api.toto.fr/api' diff --git a/app/package.json b/app/package.json index 44aa21332..470d81cbf 100755 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "Bauhaus", - "version": "3.0.7", + "version": "3.0.8", "description": "Web application for the management of concepts, classifications and other statistical objects", "repository": { "type": "git", diff --git a/app/src/index.js b/app/src/index.js index 5b5f22820..4e56dc217 100755 --- a/app/src/index.js +++ b/app/src/index.js @@ -13,6 +13,7 @@ import '@inseefr/iam/dist/index.css'; import 'bauhaus-operations/dist/index.css'; import 'bauhaus-structures/dist/index.css'; import 'bauhaus-utilities/dist/index.css'; +import 'bauhaus-codelists/dist/index.css'; import 'main.scss'; diff --git a/app/src/js/applications/auth/open-id-connect-auth/login-container.js b/app/src/js/applications/auth/open-id-connect-auth/login-container.js index ca08b45ab..27d146512 100644 --- a/app/src/js/applications/auth/open-id-connect-auth/login-container.js +++ b/app/src/js/applications/auth/open-id-connect-auth/login-container.js @@ -1,4 +1,4 @@ -import React, { useEffect, useCallback } from 'react'; +import React, { useEffect, useCallback, useState } from 'react'; import { connect } from 'react-redux'; import { useHistory } from 'react-router-dom'; import Keycloak from 'keycloak'; @@ -10,6 +10,7 @@ const kcConfig = `${window.location.origin}/keycloak.json`; const kc = Keycloak(kcConfig); const LoginOpenIDConnect = ({ saveUserProps, authenticated, WrappedComponent }) => { + const [token, setToken] = useState(Auth.getToken()) const history = useHistory() const refreshToken = useCallback(() => { kc @@ -42,7 +43,10 @@ const LoginOpenIDConnect = ({ saveUserProps, authenticated, WrappedComponent }) saveUserProps( Auth.getAuthPropsFromToken(kc.tokenParsed) ); - kc.token && Auth.setToken(kc.token); + if(kc.token) { + Auth.setToken(kc.token); + setToken(kc.token) + } setInterval(() => refreshToken(), 20000); history.push({ pathname: history.location.pathname, state: 'init' }); }) @@ -53,7 +57,6 @@ const LoginOpenIDConnect = ({ saveUserProps, authenticated, WrappedComponent }) initLogin(); }, [initLogin]) - const token = Auth.getToken(); if (authenticated && token && Auth.isTokenValid(token)) return ; return ; diff --git a/app/src/js/applications/classifications/correspondences/home.js b/app/src/js/applications/classifications/correspondences/home.js index 4e90b3664..7091f2acd 100644 --- a/app/src/js/applications/classifications/correspondences/home.js +++ b/app/src/js/applications/classifications/correspondences/home.js @@ -2,8 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { PageTitle, SearchableList } from '@inseefr/wilco'; import D from 'js/i18n'; +import { useTitle } from 'bauhaus-utilities'; const CorrespondencesHome = ({ correspondences }) => { + useTitle(D.classificationsTitle, D.correspondencesTitle); return (
diff --git a/app/src/js/applications/classifications/correspondences/visualization/home-general.js b/app/src/js/applications/classifications/correspondences/visualization/home-general.js index dd474009d..c69d65289 100644 --- a/app/src/js/applications/classifications/correspondences/visualization/home-general.js +++ b/app/src/js/applications/classifications/correspondences/visualization/home-general.js @@ -1,46 +1,44 @@ -import React, { Component } from 'react'; +import React from 'react'; import { PageTitle, Note } from '@inseefr/wilco'; import CorrespondenceControls from './controls'; import { generalFields } from './general-fields'; import { ExplanatoryNote } from 'js/applications/shared/explanatory-note'; import { D1, D2 } from 'js/i18n'; -import { propTypes as correspondencePropTypes } from 'js/applications/classifications/utils/correspondence/general'; -import { CheckSecondLang } from 'bauhaus-utilities'; +import { CheckSecondLang, useTitle } from 'bauhaus-utilities'; +import D from '../../../../i18n/build-dictionary'; -class HomeGeneral extends Component { - static propTypes = { - correspondence: correspondencePropTypes.isRequired, - }; - render() { - const { - correspondence, - secondLang, - langs: { lg1, lg2 }, - } = this.props; - const { - labelLg1, - labelLg2, - firstClassLabelLg2, - secondClassLabelLg2, - } = correspondence; - const title = secondLang ? labelLg2 : labelLg1; - return ( -
- {title && } - - -
- {(!secondLang || - (secondLang && (firstClassLabelLg2 || secondClassLabelLg2))) && ( - - )} -
- +const HomeGeneral = ({ + correspondence, + secondLang, + langs: { lg1, lg2 }, + }) => { + const { + labelLg1, + labelLg2, + firstClassLabelLg2, + secondClassLabelLg2, + } = correspondence; + const title = secondLang ? labelLg2 : labelLg1; + + useTitle(D.classificationsTitle, labelLg1); + + return ( +
+ {title && } + + +
+ {(!secondLang || + (secondLang && (firstClassLabelLg2 || secondClassLabelLg2))) && ( + + )} +
+ {correspondence.descriptionLg1 && (
)} -
- ); - } +
+ ); } export default HomeGeneral; diff --git a/app/src/js/applications/classifications/families/home.js b/app/src/js/applications/classifications/families/home.js index f0edd0757..96f005b37 100644 --- a/app/src/js/applications/classifications/families/home.js +++ b/app/src/js/applications/classifications/families/home.js @@ -2,8 +2,10 @@ import React from 'react'; import PropTypes from 'prop-types'; import { PageTitle, SearchableList } from '@inseefr/wilco'; import D from 'js/i18n'; +import { useTitle } from 'bauhaus-utilities'; const FamiliesHome = ({ families }) => { + useTitle(D.classificationsTitle, D.familiesTitle); return (
diff --git a/app/src/js/applications/classifications/families/visualization/home.js b/app/src/js/applications/classifications/families/visualization/home.js index 5c31713b2..46999fd3e 100644 --- a/app/src/js/applications/classifications/families/visualization/home.js +++ b/app/src/js/applications/classifications/families/visualization/home.js @@ -2,7 +2,8 @@ import React from 'react'; import { PageTitle } from '@inseefr/wilco'; import Controls from './controls'; import Members from './members'; -import { CheckSecondLang } from 'bauhaus-utilities'; +import { CheckSecondLang, useTitle } from 'bauhaus-utilities'; +import D from '../../../../i18n/build-dictionary'; const FamilyVisualization = ({ family: { @@ -11,6 +12,8 @@ const FamilyVisualization = ({ }, secondLang, }) => { + useTitle(D.classificationsTitle, prefLabelLg1); + return (
diff --git a/app/src/js/applications/classifications/home.js b/app/src/js/applications/classifications/home.js index ba6f679c0..adb5ff7f8 100644 --- a/app/src/js/applications/classifications/home.js +++ b/app/src/js/applications/classifications/home.js @@ -2,8 +2,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { PageTitle, SearchableList } from '@inseefr/wilco'; import D from 'js/i18n'; +import { useTitle } from 'bauhaus-utilities'; const ClassificationsHome = ({ classifications }) => { + useTitle(D.classificationsTitle, D.classificationsTitle); + return (
diff --git a/app/src/js/applications/classifications/series/home.js b/app/src/js/applications/classifications/series/home.js index 34f026cc7..7a53f5e86 100644 --- a/app/src/js/applications/classifications/series/home.js +++ b/app/src/js/applications/classifications/series/home.js @@ -2,8 +2,11 @@ import React from 'react'; import PropTypes from 'prop-types'; import { PageTitle, SearchableList } from '@inseefr/wilco'; import D from 'js/i18n'; +import { useTitle } from 'bauhaus-utilities'; const SeriesHome = ({ series }) => { + useTitle(D.classificationsTitle, D.seriesTitle); + return (
diff --git a/app/src/js/applications/classifications/series/visualization/home.js b/app/src/js/applications/classifications/series/visualization/home.js index db111647f..56181c025 100644 --- a/app/src/js/applications/classifications/series/visualization/home.js +++ b/app/src/js/applications/classifications/series/visualization/home.js @@ -1,19 +1,20 @@ -import React, { Component } from 'react'; +import React from 'react'; import { PageSubtitle, PageTitle } from '@inseefr/wilco'; import Controls from './controls'; import General from './general'; import Notes from './notes'; import Members from './members'; -import { CheckSecondLang } from 'bauhaus-utilities'; +import { CheckSecondLang, useTitle } from 'bauhaus-utilities'; +import D from '../../../../i18n/build-dictionary'; -class SeriesVisualization extends Component { - render() { - const { - series: { general, members }, - secondLang, - langs, - } = this.props; - const notes = { +const SeriesVisualization = ({ + series: { general, members }, + secondLang, + langs, + }) => { + useTitle(D.classificationsTitle, general?.prefLabelLg1); + + const notes = { scopeNoteLg1: general.scopeNoteLg1, scopeNoteLg2: general.scopeNoteLg2, }; @@ -34,7 +35,6 @@ class SeriesVisualization extends Component { )}
); - } } export default SeriesVisualization; diff --git a/app/src/js/applications/classifications/visualization/home.js b/app/src/js/applications/classifications/visualization/home.js index 0f749db9a..a79ba0e5a 100644 --- a/app/src/js/applications/classifications/visualization/home.js +++ b/app/src/js/applications/classifications/visualization/home.js @@ -6,7 +6,7 @@ import General from './general'; import Notes from './notes'; import Levels from './levels'; import D from 'js/i18n'; -import { CheckSecondLang } from 'bauhaus-utilities'; +import { CheckSecondLang, useTitle } from 'bauhaus-utilities'; const ClassificationVisualization = props => { const { @@ -15,6 +15,8 @@ const ClassificationVisualization = props => { secondLang, langs, } = props; + useTitle(D.classificationsTitle, general?.prefLabelLg1); + const notes = { scopeNoteLg1: general.scopeNoteLg1, scopeNoteLg2: general.scopeNoteLg2, diff --git a/app/src/js/applications/classifications/visualization/tree/home.js b/app/src/js/applications/classifications/visualization/tree/home.js index 33cb71035..3cd5e984b 100644 --- a/app/src/js/applications/classifications/visualization/tree/home.js +++ b/app/src/js/applications/classifications/visualization/tree/home.js @@ -4,9 +4,11 @@ import { PageTitle } from '@inseefr/wilco'; import Controls from './controls'; import DnDTree from 'js/applications/shared/tree/dnd'; import D from 'js/i18n'; -import { CheckSecondLang } from 'bauhaus-utilities'; +import { CheckSecondLang, useTitle } from 'bauhaus-utilities'; const ClassificationTree = ({ data, prefLabel }) => { + useTitle(D.classificationsTitle, D.classificationTreeTitle + ': ' + prefLabel); + return (
diff --git a/app/src/js/applications/codelists/routes/index.js b/app/src/js/applications/codelists/routes/index.js index e9751dea6..01a37e403 100644 --- a/app/src/js/applications/codelists/routes/index.js +++ b/app/src/js/applications/codelists/routes/index.js @@ -6,12 +6,10 @@ import { Home, CodelistComponentView, CodelistEdit, - D, SearchFormList, } from 'bauhaus-codelists'; const CodesListComponent = () => { - document.title = 'Bauhaus - ' + D.codelistsTitle; document.getElementById('root-app').classList = ['codelists']; return ( <> diff --git a/app/src/js/applications/collections/edition-creation/home.js b/app/src/js/applications/collections/edition-creation/home.js index 69be06392..60796d9b5 100644 --- a/app/src/js/applications/collections/edition-creation/home.js +++ b/app/src/js/applications/collections/edition-creation/home.js @@ -5,6 +5,8 @@ import CollectionEditionCreationControls from './controls'; import GeneralEdition from './general'; import MembersEdition from './members'; import { propTypes as generalPropTypes } from 'js/utils/collections/general'; +import { withTitle } from 'bauhaus-utilities'; +import D from '../../../i18n/build-dictionary'; class CollectionEditionCreation extends Component { constructor(props) { @@ -140,4 +142,4 @@ CollectionEditionCreation.propTypes = { langs: PropTypes.object.isRequired, }; -export default CollectionEditionCreation; +export default withTitle(CollectionEditionCreation, D.collectionsTitle, props => props.general.prefLabelLg1 || D.createCollectionTitle); diff --git a/app/src/js/applications/collections/export/home-container.js b/app/src/js/applications/collections/export/home-container.js index 45adf69df..40343d8aa 100644 --- a/app/src/js/applications/collections/export/home-container.js +++ b/app/src/js/applications/collections/export/home-container.js @@ -8,6 +8,8 @@ import { Loading } from '@inseefr/wilco'; import exportCollectionList from 'js/actions/collections/export-multi'; import loadCollectionList from 'js/actions/collections/list'; import { OK } from 'js/constants'; +import { useTitle } from 'bauhaus-utilities'; +import D from '../../../i18n/build-dictionary'; const CollectionsToExportContainer = ({ collections, @@ -15,6 +17,8 @@ const CollectionsToExportContainer = ({ loadCollectionList, exportCollectionList, }) => { + useTitle(D.collectionsTitle, D.exportTitle) + const [exportRequested, setExportRequested] = useState(false); const handleExportCollectionList = useCallback( diff --git a/app/src/js/applications/collections/home.js b/app/src/js/applications/collections/home.js index dd936ab7d..72922726f 100644 --- a/app/src/js/applications/collections/home.js +++ b/app/src/js/applications/collections/home.js @@ -1,6 +1,5 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import { withRouter } from 'react-router-dom'; import { PageTitle, Button, @@ -13,87 +12,67 @@ import { propTypes as collectionOverviewPropTypes } from 'js/utils/collections/c import { propTypes as permissionOverviewPropTypes } from 'js/utils/auth/permission-overview'; import D from 'js/i18n'; -class CollectionsHome extends Component { - static propTypes = { - collections: PropTypes.arrayOf(collectionOverviewPropTypes.isRequired), - permission: permissionOverviewPropTypes.isRequired, - }; +const CollectionsHome = ({ + collections, + permission: { authType, roles }, + }) => { - constructor() { - super(); - - this.handleClick = e => { - e.preventDefault(); - this.props.history.push('/collection/create'); - }; - this.handleClickExport = e => { - e.preventDefault(); - this.props.history.push('/collections/export'); - }; - this.handleClickValidate = e => { - e.preventDefault(); - this.props.history.push('/collections/validation'); - }; - } - - render() { - const { - collections, - permission: { authType, roles }, - } = this.props; - const authImpl = check(authType); - const adminOrCreator = authImpl.isAdminOrCollectionCreator(roles); - const adminOrContributor = authImpl.isAdminOrContributor(roles); - return ( -
-
- - {adminOrContributor && ( -
- ); - } +
+ ); } +CollectionsHome.propTypes = { + collections: PropTypes.arrayOf(collectionOverviewPropTypes.isRequired), + permission: permissionOverviewPropTypes.isRequired, +}; -export default withRouter(CollectionsHome); +export default CollectionsHome; diff --git a/app/src/js/applications/collections/validation/home-container.js b/app/src/js/applications/collections/validation/home-container.js index 7587dc0c6..9decd5618 100644 --- a/app/src/js/applications/collections/validation/home-container.js +++ b/app/src/js/applications/collections/validation/home-container.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import { Redirect } from 'react-router'; import CollectionsToValidate from './home'; @@ -8,43 +8,37 @@ import validateCollectionList from 'js/actions/collections/validate'; import loadCollectionValidateList from 'js/actions/collections/validate-list'; import { VALIDATE_COLLECTION_LIST } from 'js/actions/constants'; import { OK } from 'js/constants'; -import { Auth } from 'bauhaus-utilities'; +import { Auth, useTitle } from 'bauhaus-utilities'; +import D from 'js/i18n'; -class CollectionsToValidateContainer extends Component { - constructor(props) { - super(props); - this.state = { - validationRequested: false, - }; +const CollectionsToValidateContainer = + ({ validateCollectionList, collections, loadCollectionValidateList, permission, validationStatus }) => { + useTitle(D.collectionsTitle, D.btnValid); - this.handleValidateCollectionList = ids => { - this.props.validateCollectionList(ids); - this.setState({ - validationRequested: true, - }); - }; - } - componentWillMount() { - if (!this.props.collections) this.props.loadCollectionValidateList(); - } + const [validationRequested, setValidationRequested] = useState(false); + + const handleValidateCollectionList = ids => { + validateCollectionList(ids); + setValidationRequested(true) + }; + + useEffect(() => { + if (!collections) loadCollectionValidateList(); + }, [collections, loadCollectionValidateList]); - render() { - const { validationRequested } = this.state; - const { collections, permission, validationStatus } = this.props; - if (validationRequested) { - if (validationStatus === OK) { - return ; - } else return ; - } - if (!collections) return ; - return ( - - ); + if (validationRequested) { + if (validationStatus === OK) { + return ; + } else return ; } + if (!collections) return ; + return ( + + ); } const mapStateToProps = state => ({ diff --git a/app/src/js/applications/collections/visualization/home.js b/app/src/js/applications/collections/visualization/home.js index 801dc5a03..9ec5c8d0a 100644 --- a/app/src/js/applications/collections/visualization/home.js +++ b/app/src/js/applications/collections/visualization/home.js @@ -7,7 +7,8 @@ import CollectionMembers from './members'; import { propTypes as generalPropTypes } from 'js/utils/collections/general'; import { propTypes as membersPropTypes } from 'js/utils/collections/members'; import { propTypes as permissionOverviewPropTypes } from 'js/utils/auth/permission-overview'; -import { CheckSecondLang } from 'bauhaus-utilities'; +import { CheckSecondLang, withTitle } from 'bauhaus-utilities'; +import D from 'js/i18n'; class CollectionVisualization extends Component { constructor(props) { @@ -63,4 +64,4 @@ CollectionVisualization.propTypes = { langs: PropTypes.object.isRequired, }; -export default CollectionVisualization; +export default withTitle(CollectionVisualization, D.collectionsTitle, props => props.general.prefLabelLg1); diff --git a/app/src/js/applications/concepts/advanced-search/home.js b/app/src/js/applications/concepts/advanced-search/home.js index e78a419a6..5a1dd185e 100644 --- a/app/src/js/applications/concepts/advanced-search/home.js +++ b/app/src/js/applications/concepts/advanced-search/home.js @@ -6,7 +6,7 @@ import Controls from './controls'; import DatePickerRmes from 'js/applications/shared/date-picker-rmes'; import D from 'js/i18n'; import { filterKeyDate } from 'js/utils/array-utils'; -import { ArrayUtils } from 'bauhaus-utilities'; +import { ArrayUtils, withTitle } from 'bauhaus-utilities'; const filterLabel = ArrayUtils.filterKeyDeburr(['label']); const filterAltLabel = ArrayUtils.filterKeyDeburr(['altLabel']); @@ -293,4 +293,4 @@ ConceptSearchList.propTypes = { disseminationStatusList: PropTypes.array.isRequired, }; -export default ConceptSearchList; +export default withTitle(ConceptSearchList, D.conceptsTitle, () => D.advancedSearch); diff --git a/app/src/js/applications/concepts/edition-creation/home.js b/app/src/js/applications/concepts/edition-creation/home.js index 7cd3b7b9b..0c91870a9 100644 --- a/app/src/js/applications/concepts/edition-creation/home.js +++ b/app/src/js/applications/concepts/edition-creation/home.js @@ -17,6 +17,7 @@ import D from 'js/i18n'; import isVersioningPossible from 'js/utils/concepts/is-versioning-possible'; import { VERSIONING, NO_VERSIONING } from 'js/constants'; import { withRouter } from 'react-router'; +import { withTitle } from 'bauhaus-utilities'; class ConceptEditionCreation extends Component { constructor(props) { @@ -275,4 +276,4 @@ ConceptEditionCreation.propTypes = { langs: PropTypes.object.isRequired, }; -export default withRouter(ConceptEditionCreation); +export default withRouter(withTitle(ConceptEditionCreation, D.conceptsTitle, props => props?.general?.prefLabelLg1 || D.createConceptTitle)); diff --git a/app/src/js/applications/concepts/export/home-container.js b/app/src/js/applications/concepts/export/home-container.js index b1e401b71..9a4e927ad 100644 --- a/app/src/js/applications/concepts/export/home-container.js +++ b/app/src/js/applications/concepts/export/home-container.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import { Redirect } from 'react-router-dom'; import * as select from 'js/reducers'; @@ -8,47 +8,46 @@ import { Loading } from '@inseefr/wilco'; import exportConceptList from 'js/actions/concepts/export-multi'; import loadConceptList from 'js/actions/concepts/list'; import { OK } from 'js/constants'; +import { useTitle } from 'bauhaus-utilities'; +import D from 'js/i18n'; -class ConceptsToExportContainer extends Component { - constructor() { - super(); - this.state = { - exportRequested: false, - }; - this.handleExportConceptList = (ids, MimeType) => { - this.props.exportConceptList(ids, MimeType); - this.setState({ - exportRequested: true, - }); - }; - } +const ConceptsToExportContainer = ({ + concepts, + exportStatus, + loadConceptList, + exportConceptList + }) => { + useTitle(D.conceptsTitle, D.exportTitle) + const [exportRequested, setExportRequested] = useState(false) + + useEffect(() => { + if(!concepts){ + loadConceptList() + } + }, [concepts, loadConceptList]); - componentWillMount() { - if (!this.props.concepts) this.props.loadConceptList(); + const handleExportConceptList = (ids, MimeType) => { + exportConceptList(ids, MimeType); + setExportRequested(true); } - render() { - const { concepts, exportStatus } = this.props; - const { exportRequested } = this.state; - if (exportRequested) { - if (exportStatus === OK) { - return ; - } - return ; + if (exportRequested) { + if (exportStatus === OK) { + return ; } + return ; + } - if (!concepts) { - return ; - } - return ( - - ); + if (!concepts) { + return ; } + return ( + + ); } - const mapStateToProps = state => ({ concepts: select.getConceptList(state), exportStatus: select.getStatus(state, EXPORT_CONCEPT_LIST), diff --git a/app/src/js/applications/concepts/home.js b/app/src/js/applications/concepts/home.js index 6cdc0db9d..d34282fa2 100755 --- a/app/src/js/applications/concepts/home.js +++ b/app/src/js/applications/concepts/home.js @@ -1,6 +1,5 @@ -import React, { Component } from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; -import { withRouter } from 'react-router-dom'; import { PageTitle, SearchableList, @@ -14,68 +13,47 @@ import { propTypes as conceptOverviewPropTypes } from 'js/utils/concepts/concept import { propTypes as permissionOverviewPropTypes } from 'js/utils/auth/permission-overview'; import D from 'js/i18n'; -class ConceptsHome extends Component { - constructor() { - super(); - - this.handleClick = e => { - e.preventDefault(); - this.props.history.push('/concept/create'); - }; - this.handleClickExport = e => { - e.preventDefault(); - this.props.history.push('/concepts/export'); - }; - this.handleClickValidate = e => { - e.preventDefault(); - this.props.history.push('/concepts/validation'); - }; - } - - render() { - const { - concepts, - permission: { authType, roles }, - } = this.props; - const authImpl = check(authType); - const adminOrContributor = authImpl.isAdminOrContributor(roles); - const adminOrCreator = authImpl.isAdminOrConceptCreator(roles); - return ( -
-
- - {adminOrContributor && ( - - )} - - {adminOrCreator && ( - - )} - -
- - { + const authImpl = check(authType); + const adminOrContributor = authImpl.isAdminOrContributor(roles); + const adminOrCreator = authImpl.isAdminOrConceptCreator(roles); + return ( +
+
+ + {adminOrContributor && ( + + )} + + {adminOrCreator && ( + -
+ )} + +
+ +
- ); - } +
+ ); } - ConceptsHome.propTypes = { concepts: PropTypes.arrayOf(conceptOverviewPropTypes.isRequired), permission: permissionOverviewPropTypes.isRequired, }; -export default withRouter(ConceptsHome); +export default ConceptsHome; diff --git a/app/src/js/applications/concepts/validation/home-container.js b/app/src/js/applications/concepts/validation/home-container.js index ddd0d2c67..17c5e136c 100644 --- a/app/src/js/applications/concepts/validation/home-container.js +++ b/app/src/js/applications/concepts/validation/home-container.js @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { useEffect, useState } from 'react'; import { connect } from 'react-redux'; import { Redirect } from 'react-router'; import ConceptsToValidate from './home'; @@ -8,43 +8,40 @@ import * as select from 'js/reducers'; import validateConceptList from 'js/actions/concepts/validate'; import loadConceptValidateList from 'js/actions/concepts/validate-list'; import { OK } from 'js/constants'; -import { Auth } from 'bauhaus-utilities'; +import { Auth, useTitle } from 'bauhaus-utilities'; +import D from 'js/i18n'; -class ConceptsToValidateContainer extends Component { - constructor(props) { - super(props); - this.state = { - validationRequested: false, - }; - this.handleValidateConceptList = ids => { - this.props.validateConceptList(ids); - this.setState({ - validationRequested: true, - }); - }; - } - componentWillMount() { - if (!this.props.concepts) this.props.loadConceptValidateList(); - } - render() { - const { validationRequested } = this.state; - const { concepts, permission, validationStatus } = this.props; - if (validationRequested) { - if (validationStatus === OK) { - return ; - } else { - return ; - } +const ConceptsToValidateContainer = ({ + concepts, validateConceptList, loadConceptValidateList, permission, validationStatus + }) => { + + useTitle(D.conceptsTitle, D.btnValid); + const [validationRequested, setValidationRequested] = useState(false); + + const handleValidateConceptList = ids => { + validateConceptList(ids); + setValidationRequested(true) + }; + + useEffect(() => { + if (!concepts) loadConceptValidateList(); + }, [concepts, loadConceptValidateList]); + + if (validationRequested) { + if (validationStatus === OK) { + return ; + } else { + return ; } - if (!concepts) return ; - return ( - - ); } + if (!concepts) return ; + return ( + + ); } const mapStateToProps = state => ({ diff --git a/app/src/js/applications/concepts/visualization/home.js b/app/src/js/applications/concepts/visualization/home.js index fc18e0c62..d5196a6b8 100644 --- a/app/src/js/applications/concepts/visualization/home.js +++ b/app/src/js/applications/concepts/visualization/home.js @@ -12,7 +12,7 @@ import { propTypes as notePropTypes } from 'js/utils/concepts/notes'; import { propTypesBilingual as linksPropTypes } from 'js/utils/concepts/links'; import { propTypes as permissionOverviewPropTypes } from 'js/utils/auth/permission-overview'; import { getModalMessage } from 'js/utils/concepts/build-validation-message'; -import { CheckSecondLang, DateUtils, PageTitleBlock } from 'bauhaus-utilities'; +import { CheckSecondLang, DateUtils, PageTitleBlock, useTitle } from 'bauhaus-utilities'; const ConceptVisualization = ({ id, @@ -26,6 +26,7 @@ const ConceptVisualization = ({ validateConcept, deleteConcept, }) => { + useTitle( D.conceptsTitle, general?.prefLabelLg1); const [modalValid, setModalValid] = useState(false); const handleClickValidation = useCallback(() => { diff --git a/app/src/js/applications/operations/document/edition/edition.js b/app/src/js/applications/operations/document/edition/edition.js index f5c49d593..857a11b69 100644 --- a/app/src/js/applications/operations/document/edition/edition.js +++ b/app/src/js/applications/operations/document/edition/edition.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import D, { D1, D2 } from 'js/i18n'; import PropTypes from 'prop-types'; -import { EditorMarkdown, PageTitleBlock } from 'bauhaus-utilities'; +import { EditorMarkdown, PageTitleBlock, withTitle } from 'bauhaus-utilities'; import { validate } from 'js/applications/operations/document/edition/validation'; import { LINK, DOCUMENT } from '../utils'; import Dropzone from 'react-dropzone'; @@ -281,4 +281,6 @@ class OperationsDocumentationEdition extends Component { } } -export default OperationsDocumentationEdition; +export default withTitle(OperationsDocumentationEdition, D.operationsTitle, props => { + return props.document.labelLg1 || (props.type === LINK ? D.linksCreateTitle : D.documentsCreateTitle) +}); diff --git a/app/src/js/applications/operations/document/home.js b/app/src/js/applications/operations/document/home.js index a80c5e4ce..0bea14e42 100644 --- a/app/src/js/applications/operations/document/home.js +++ b/app/src/js/applications/operations/document/home.js @@ -10,7 +10,7 @@ import { } from '@inseefr/wilco'; import D from 'js/i18n'; import { BOTH, DOCUMENT, LINK, isLink, isDocument } from './utils'; -import { Auth, FilterToggleButtons } from 'bauhaus-utilities'; +import { Auth, FilterToggleButtons, useTitle } from 'bauhaus-utilities'; import { Link, useHistory } from 'react-router-dom'; const sessionStorageKey = 'documents-displayMode'; @@ -23,6 +23,7 @@ const SearchableList = ({ searchValue = '', itemFormatter = (content) => content, }) => { + const [search, handleSearch] = useState(searchValue); const filter = filterKeyDeburr( @@ -30,10 +31,22 @@ const SearchableList = ({ ); const hits = items.filter(filter(search)); + const formatter = content => { + const extraInformations = [] + if(content.lang){ + extraInformations.push(content.lang); + } + if(content.updatedDate){ + + const [year, month, day] = content.updatedDate.split('-'); + extraInformations.push(`${day}/${month}/${year}`); + } + return `${content[label]} ${extraInformations.length > 0 ? `(${extraInformations.join(' - ')})` : ''}`; + } const hitEls = hits.map((item) => (
  • - {itemFormatter(item[label], item)} + {formatter(item)}
  • )); @@ -63,6 +76,8 @@ const SearchableList = ({ }; function DocumentHome({ documents }) { + useTitle(D.operationsTitle, D.documentsTitle) + const history = useHistory(); const queryMode = sessionStorage.getItem(sessionStorageKey); diff --git a/app/src/js/applications/operations/document/index.js b/app/src/js/applications/operations/document/index.js index fb165ccef..11a7721c1 100644 --- a/app/src/js/applications/operations/document/index.js +++ b/app/src/js/applications/operations/document/index.js @@ -33,6 +33,8 @@ export const mapStateToProps = state => { id: document.id, label: document.labelLg1 || document.labelLg2, uri: document.uri, + lang: document.lang, + updatedDate: document.updatedDate }; }) ), diff --git a/app/src/js/applications/operations/document/visualization/home.js b/app/src/js/applications/operations/document/visualization/home.js index 994b06faa..c17b42301 100644 --- a/app/src/js/applications/operations/document/visualization/home.js +++ b/app/src/js/applications/operations/document/visualization/home.js @@ -1,9 +1,9 @@ import { Note } from '@inseefr/wilco'; -import { D1, D2 } from 'js/i18n'; +import D, { D1, D2 } from 'js/i18n'; import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; import { isDocument, isLink } from '../utils'; -import { API } from 'bauhaus-utilities'; +import { API, useTitle } from 'bauhaus-utilities'; import RelationsView from '../../shared/relations'; function formatSims(sims){ @@ -50,6 +50,7 @@ function OperationsDocumentationVisualization({ langs: { lg1, lg2 }, langOptions }) { + useTitle(D.operationsTitle, attr.labelLg1) const sims = formatSims(attr.sims); const [baseURI, setBaseURI] = useState(''); useEffect(() => { diff --git a/app/src/js/applications/operations/families/edition/edition.js b/app/src/js/applications/operations/families/edition/edition.js index c3183526e..7836da8f6 100644 --- a/app/src/js/applications/operations/families/edition/edition.js +++ b/app/src/js/applications/operations/families/edition/edition.js @@ -1,7 +1,7 @@ import React, { Component } from 'react'; import { D1, D2 } from 'js/i18n'; import PropTypes from 'prop-types'; -import { EditorMarkdown, PageTitleBlock } from 'bauhaus-utilities'; +import { EditorMarkdown, PageTitleBlock, withTitle } from 'bauhaus-utilities'; import { CancelButton, SaveButton, @@ -13,6 +13,7 @@ import { LabelRequired, } from '@inseefr/wilco'; import { validate } from './validation'; +import D from '../../../../i18n/build-dictionary'; const defaultFamily = { prefLabelLg1: '', @@ -175,4 +176,6 @@ class OperationsFamilyEdition extends Component { } } -export default OperationsFamilyEdition; +export default withTitle(OperationsFamilyEdition, D.operationsTitle, props => { + return props.family.prefLabelLg1 || D.familiesCreateTitle +}); diff --git a/app/src/js/applications/operations/families/home.js b/app/src/js/applications/operations/families/home.js index 595454d2b..0007b1dd6 100644 --- a/app/src/js/applications/operations/families/home.js +++ b/app/src/js/applications/operations/families/home.js @@ -1,10 +1,11 @@ -import React from 'react'; +import React from 'react'; import PropTypes from 'prop-types'; import D from 'js/i18n'; -import { Auth } from 'bauhaus-utilities'; +import { Auth, useTitle } from 'bauhaus-utilities'; import OperationsObjectHome from 'js/applications/operations/shared/list'; function FamiliesHome({ families }) { + useTitle(D.operationsTitle, D.familiesTitle) return ( { + useEffect(() => { + if(status !== LOADED){ + loadFamiliesList() } - } - render() { - const { families, status } = this.props; - if (status !== LOADED) return ; - return ; - } + }, [status, loadFamiliesList]) + + if (status !== LOADED) return ; + return ; } export const mapStateToProps = state => { diff --git a/app/src/js/applications/operations/families/search.js b/app/src/js/applications/operations/families/search.js index f5949bc64..de6a237c0 100644 --- a/app/src/js/applications/operations/families/search.js +++ b/app/src/js/applications/operations/families/search.js @@ -1,6 +1,6 @@ import D from 'js/i18n'; import { Link, Redirect } from 'react-router-dom'; -import React, { Component } from 'react'; +import React, { useEffect, useState } from 'react'; import { Loading } from '@inseefr/wilco'; import api from 'js/remote-api/operations-api'; @@ -8,6 +8,7 @@ import { ArrayUtils, AbstractAdvancedSearchComponent, AdvancedSearchList, + useTitle } from 'bauhaus-utilities'; const filterLabel = ArrayUtils.filterKeyDeburr(['prefLabelLg1']); @@ -59,22 +60,20 @@ class SearchFormList extends AbstractAdvancedSearchComponent { ); } } -class SearchListContainer extends Component { - constructor(props) { - super(props); - this.state = {}; - } - componentWillMount() { +const SearchListContainer = () => { + useTitle(D.operationsTitle, D.familiesTitle + ' - ' + D.advancedSearch) + const [data, setData] = useState(); + + useEffect(() => { api.getFamiliesSearchList().then(data => { - this.setState({ data: sortByLabel(data) }); + setData(sortByLabel(data)); }); - } + }, []); - render() { - const { data } = this.state; - if (!data) return ; - return ; + if(!data){ + return } + return } export default SearchListContainer; diff --git a/app/src/js/applications/operations/families/visualization/visualization.js b/app/src/js/applications/operations/families/visualization/visualization.js index 1211b16a1..0c1324b53 100644 --- a/app/src/js/applications/operations/families/visualization/visualization.js +++ b/app/src/js/applications/operations/families/visualization/visualization.js @@ -3,7 +3,8 @@ import React from 'react'; import { Note } from '@inseefr/wilco'; import { D1, D2 } from 'js/i18n'; import RelationsView from 'js/applications/operations/shared/relations'; -import { HTMLUtils, PublicationFemale } from 'bauhaus-utilities'; +import { HTMLUtils, PublicationFemale, withTitle } from 'bauhaus-utilities'; +import D from '../../../../i18n/build-dictionary'; function OperationsFamilyVisualization({ attr, @@ -73,4 +74,6 @@ function OperationsFamilyVisualization({ ); } -export default OperationsFamilyVisualization; +export default withTitle(OperationsFamilyVisualization, D.operationsTitle, props => { + return props.attr?.prefLabelLg1; +}); diff --git a/app/src/js/applications/operations/indicators/edition/edition.js b/app/src/js/applications/operations/indicators/edition/edition.js index a8c03964b..14ceeb53e 100644 --- a/app/src/js/applications/operations/indicators/edition/edition.js +++ b/app/src/js/applications/operations/indicators/edition/edition.js @@ -4,7 +4,7 @@ import PropTypes from 'prop-types'; import { EditorMarkdown, ItemToSelectModel, - PageTitleBlock, + PageTitleBlock, withTitle, } from 'bauhaus-utilities'; import { PublishersInput, CreatorsInput } from 'bauhaus-operations'; import { CL_FREQ } from 'js/actions/constants/codeList'; @@ -370,4 +370,6 @@ class OperationsIndicatorEdition extends Component { } } -export default OperationsIndicatorEdition; +export default withTitle(OperationsIndicatorEdition, D.operationsTitle, props => { + return props.indicator?.prefLabelLg1 || D.indicatorsCreateTitle; +}); diff --git a/app/src/js/applications/operations/indicators/home.js b/app/src/js/applications/operations/indicators/home.js deleted file mode 100644 index 7d732e7c8..000000000 --- a/app/src/js/applications/operations/indicators/home.js +++ /dev/null @@ -1,46 +0,0 @@ -import React from 'react'; -import PropTypes from 'prop-types'; -import { - PageTitle, - SearchableList, - NewButton, - VerticalMenu, -} from '@inseefr/wilco'; -import D from 'js/i18n'; -import { Auth } from 'bauhaus-utilities'; - -function IndicatorsHome({ indicators }) { - return ( -
    -
    - - - - - -
    - - -
    -
    -
    - ); -} - -IndicatorsHome.propTypes = { - indicators: PropTypes.arrayOf( - PropTypes.shape({ - id: PropTypes.string.isRequired, - label: PropTypes.string.isRequired, - }).isRequired - ), -}; - -export default IndicatorsHome; diff --git a/app/src/js/applications/operations/indicators/home.spec.js b/app/src/js/applications/operations/indicators/home.spec.js deleted file mode 100644 index 97913c1d9..000000000 --- a/app/src/js/applications/operations/indicators/home.spec.js +++ /dev/null @@ -1,31 +0,0 @@ -import React from 'react'; -import { render } from '@testing-library/react'; -import IndicatorsHome from './home'; -import { MemoryRouter } from 'react-router-dom'; - -import { Provider } from 'react-redux'; -import configureStore from 'redux-mock-store'; - -const mockStore = configureStore([]); -const store = mockStore({ users: { results: {stamp: 'stamp'}}, app: { auth: { user: { roles: [] } } } }); - -describe('IndicatorsHome', () => { - it('should display the PageTitle component', () => { - const { container } = render( - - - , - { wrapper: MemoryRouter } - ); - expect(container.querySelectorAll('h1').length).toBe(1); - }); - it('should display the SearchableList component', () => { - const { container } = render( - - - , - { wrapper: MemoryRouter } - ); - expect(container.querySelectorAll('.list-group').length).toBe(1); - }); -}); diff --git a/app/src/js/applications/operations/indicators/index.js b/app/src/js/applications/operations/indicators/index.js index c28a8e65e..63fa3bf92 100644 --- a/app/src/js/applications/operations/indicators/index.js +++ b/app/src/js/applications/operations/indicators/index.js @@ -1,38 +1,53 @@ import React from 'react'; -import { Loading } from '@inseefr/wilco'; -import IndicatorsHome from './home'; -import loadIndicatorsList from 'js/actions/operations/indicators/list'; -import { connect } from 'react-redux'; -import { NOT_LOADED, LOADED } from 'js/constants'; -import { Auth } from 'bauhaus-utilities'; +import PropTypes from 'prop-types'; +import { + PageTitle, + SearchableList, + NewButton, + VerticalMenu, Loading, +} from '@inseefr/wilco'; +import D from 'js/i18n'; +import { Auth, useTitle } from 'bauhaus-utilities'; +import { LOADED, NOT_LOADED } from '../../../constants'; +import { useSelector } from 'react-redux'; -function IndicatorsHomeContainer({ indicators, status, permission }) { +function IndicatorsHome() { + useTitle(D.operationsTitle, D.indicatorsTitle) + + const { results: indicators = [], status = NOT_LOADED } = useSelector(state => state.operationsIndicatorsList) if (status !== LOADED) return ; - return ; -} -export const mapStateToProps = state => { - if (!state.operationsIndicatorsList) { - return { - status: NOT_LOADED, - indicators: [], - }; - } - const { results: indicators, status, err } = state.operationsIndicatorsList; - const permission = Auth.getPermission(state); - return { - indicators, - status, - permission, - err, - }; -}; + return ( +
    +
    + + + + + +
    + + +
    +
    +
    + ); +} -const mapDispatchToProps = { - loadIndicatorsList, +IndicatorsHome.propTypes = { + indicators: PropTypes.arrayOf( + PropTypes.shape({ + id: PropTypes.string.isRequired, + label: PropTypes.string.isRequired, + }).isRequired + ), }; -export default connect( - mapStateToProps, - mapDispatchToProps -)(IndicatorsHomeContainer); +export default IndicatorsHome; diff --git a/app/src/js/applications/operations/indicators/index.spec.js b/app/src/js/applications/operations/indicators/index.spec.js deleted file mode 100644 index db6a51efe..000000000 --- a/app/src/js/applications/operations/indicators/index.spec.js +++ /dev/null @@ -1,32 +0,0 @@ -import { mapStateToProps } from './index'; - -describe('IndicatorsHomeContainer', () => { - it('should return indicators if available', () => { - const result = mapStateToProps({}); - expect(result).toEqual({ indicators: [], status: 'NOT_LOADED' }); - }); - it('if the id of the indicators is not defined should return an empty object', () => { - const result = mapStateToProps({ - operationsIndicatorsList: { - results: 'results', - status: 'LOADED', - err: 'err', - }, - app: { - auth: { - type: 'authType', - user: { - roles: 'roles', - stamp: 'stamp', - }, - }, - }, - }); - expect(result).toEqual({ - err: 'err', - indicators: 'results', - permission: { authType: 'authType', roles: 'roles', stamp: 'stamp' }, - status: 'LOADED', - }); - }); -}); diff --git a/app/src/js/applications/operations/indicators/visualization/general.js b/app/src/js/applications/operations/indicators/visualization/general.js index 3984e97d0..8d969ccf3 100644 --- a/app/src/js/applications/operations/indicators/visualization/general.js +++ b/app/src/js/applications/operations/indicators/visualization/general.js @@ -5,8 +5,9 @@ import { D1, D2 } from 'js/i18n'; import { getSeeAlsoByType } from 'js/applications/operations/shared/links/utils'; import DisplayLinks from 'js/applications/operations/shared/links/'; import SeeAlso from 'js/applications/operations/shared/seeAlso'; -import { HTMLUtils, PublicationMale } from 'bauhaus-utilities'; +import { HTMLUtils, PublicationMale, withTitle } from 'bauhaus-utilities'; import { PublishersView, CreatorsView } from 'bauhaus-operations'; +import D from '../../../../i18n/build-dictionary'; function DisplayMultiLangNote({ value1, @@ -136,4 +137,6 @@ function OperationsIndicatorVisualization(props) { ); } -export default OperationsIndicatorVisualization; +export default withTitle(OperationsIndicatorVisualization, D.operationsTitle, props => { + return props.attr?.prefLabelLg1; +}); diff --git a/app/src/js/applications/operations/operations/edition/edition.js b/app/src/js/applications/operations/operations/edition/edition.js index 64864baf0..3400a82f0 100644 --- a/app/src/js/applications/operations/operations/edition/edition.js +++ b/app/src/js/applications/operations/operations/edition/edition.js @@ -13,7 +13,7 @@ import { Select, } from '@inseefr/wilco'; import { validate } from './validation'; -import { PageTitleBlock } from 'bauhaus-utilities'; +import { PageTitleBlock, withTitle } from 'bauhaus-utilities'; const defaultOperation = { prefLabelLg1: '', @@ -191,4 +191,7 @@ class OperationsOperationEdition extends Component { } } -export default OperationsOperationEdition; +export default withTitle(OperationsOperationEdition, D.operationsTitle, props => { + return props.operation?.prefLabelLg1 || D.operationsCreateTitle; +}); + diff --git a/app/src/js/applications/operations/operations/home.js b/app/src/js/applications/operations/operations/home.js index 4d794371b..47ca138e6 100644 --- a/app/src/js/applications/operations/operations/home.js +++ b/app/src/js/applications/operations/operations/home.js @@ -1,10 +1,12 @@ import React from 'react'; import PropTypes from 'prop-types'; import D from 'js/i18n'; -import { Auth } from 'bauhaus-utilities'; +import { Auth, useTitle } from 'bauhaus-utilities'; import OperationsObjectHome from 'js/applications/operations/shared/list'; function OperationsHome({ operations }) { + useTitle(D.operationsTitle, D.operationsTitle) + return ( { + return props.attr?.prefLabelLg1; +}); diff --git a/app/src/js/applications/operations/series/edition/edition.js b/app/src/js/applications/operations/series/edition/edition.js index 9027e8a2f..6656ae23a 100644 --- a/app/src/js/applications/operations/series/edition/edition.js +++ b/app/src/js/applications/operations/series/edition/edition.js @@ -16,7 +16,7 @@ import { CL_SOURCE_CATEGORY, CL_FREQ } from 'js/actions/constants/codeList'; import { EditorMarkdown, ItemToSelectModel, - PageTitleBlock, + PageTitleBlock, withTitle, } from 'bauhaus-utilities'; import { PublishersInput, CreatorsInput } from 'bauhaus-operations'; @@ -491,4 +491,6 @@ class OperationsSerieEdition extends Component { } } -export default OperationsSerieEdition; +export default withTitle(OperationsSerieEdition, D.operationsTitle, props => { + return props.serie?.prefLabelLg1 || D.seriesCreateTitle; +}); diff --git a/app/src/js/applications/operations/series/home.js b/app/src/js/applications/operations/series/home.js index d0dcb5c5a..170142a46 100644 --- a/app/src/js/applications/operations/series/home.js +++ b/app/src/js/applications/operations/series/home.js @@ -1,11 +1,13 @@ import React from 'react'; import PropTypes from 'prop-types'; import D from 'js/i18n'; -import { Auth } from 'bauhaus-utilities'; +import { Auth, useTitle } from 'bauhaus-utilities'; import OperationsObjectHome from 'js/applications/operations/shared/list'; function SeriesHome({ series }) { + useTitle(D.operationsTitle, D.seriesTitle) + return ( { - this.setState({ data: sortByLabel(data) }); - }); - } - render() { - const { data } = this.state; - const { categories, organisations, stamps } = this.props; +const SearchListContainer = () => { + useTitle(D.operationsTitle, D.seriesTitle + ' - ' + D.advancedSearch) - if (!data) return ; - return ( - - ); - } -} + const [data, setData] = useState(); + const categories = useSelector(state => state.operationsCodesList.results[CL_SOURCE_CATEGORY] || {}); + const organisations = useSelector(state => state.operationsOrganisations.results); + const stamps = useSelector(state => Stores.Stamps.getStampList(state) || []); -const mapStateToProps = (state) => { - const categories = - state.operationsCodesList.results[CL_SOURCE_CATEGORY] || {}; - return { - categories, - organisations: state.operationsOrganisations.results, - stamps: Stores.Stamps.getStampList(state) || [], - }; -}; + useEffect(() => { + api.getSeriesSearchList().then((data) => { + setData(sortByLabel(data)); + }); + }, []); + + if (!data) return ; + return ( + + ); +} -export default connect(mapStateToProps)(SearchListContainer); +export default SearchListContainer; diff --git a/app/src/js/applications/operations/series/visualization/home.js b/app/src/js/applications/operations/series/visualization/home.js index 4269c174c..c0b5cfc7d 100644 --- a/app/src/js/applications/operations/series/visualization/home.js +++ b/app/src/js/applications/operations/series/visualization/home.js @@ -6,8 +6,9 @@ import RelationsView from 'js/applications/operations/shared/relations'; import DisplayLinks from 'js/applications/operations/shared/links/'; import SeeAlso from 'js/applications/operations/shared/seeAlso'; import { getSeeAlsoByType } from 'js/applications/operations/shared/links/utils'; -import { HTMLUtils, PublicationFemale } from 'bauhaus-utilities'; +import { HTMLUtils, PublicationFemale, withTitle } from 'bauhaus-utilities'; import { PublishersView, CreatorsView } from 'bauhaus-operations'; +import D from '../../../../i18n/build-dictionary'; function OperationsSerieVisualization({ attr, @@ -198,4 +199,6 @@ function OperationsSerieVisualization({ ); } -export default OperationsSerieVisualization; +export default withTitle(OperationsSerieVisualization, D.operationsTitle, props => { + return props.attr?.prefLabelLg1; +}); diff --git a/app/src/js/applications/operations/tree/index.js b/app/src/js/applications/operations/tree/index.js index e2be61fcb..f8420a207 100644 --- a/app/src/js/applications/operations/tree/index.js +++ b/app/src/js/applications/operations/tree/index.js @@ -7,6 +7,7 @@ import D from 'js/i18n'; import { goBack, PageTitle, ReturnButton, ActionToolbar } from '@inseefr/wilco'; import './tree.scss'; +import { useTitle } from 'bauhaus-utilities'; export const formatLeaf = ( leaf, @@ -63,6 +64,8 @@ export const updateTree = (treeData, leaf, familyIndex, seriesIndex) => { }; const TreeComponent = props => { + useTitle(D.operationsTitle, D.operationsTreeTitle) + const [treeData, setTreeData] = useState([]); const [selectedLeaf, setSelectedLeaf] = useState({}); diff --git a/app/src/js/applications/structures/edition/create/component.js b/app/src/js/applications/structures/edition/create/component.js deleted file mode 100644 index bf2b01ad9..000000000 --- a/app/src/js/applications/structures/edition/create/component.js +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react'; -import Edition from '../component'; - -const Create = () => { - return ; -}; - -export default Create; diff --git a/app/src/js/applications/structures/edition/create/index.js b/app/src/js/applications/structures/edition/create/index.js index b404d7fd4..e75f2619a 100644 --- a/app/src/js/applications/structures/edition/create/index.js +++ b/app/src/js/applications/structures/edition/create/index.js @@ -1 +1,11 @@ -export { default } from './component'; +import React from 'react'; +import Edition from '../component'; +import { useTitle } from 'bauhaus-utilities'; +import D from 'js/i18n'; + +const Create = () => { + useTitle(D.structuresTitle, D.structuresCreateTitle) + return ; +}; + +export default Create; diff --git a/app/src/js/applications/structures/edition/update/component.js b/app/src/js/applications/structures/edition/update/component.js deleted file mode 100644 index e7c1c36f4..000000000 --- a/app/src/js/applications/structures/edition/update/component.js +++ /dev/null @@ -1,57 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import Edition from '../component'; -import { Loading } from '@inseefr/wilco'; -import { StructureAPI } from 'bauhaus-structures'; -import { useLocation, useParams } from 'react-router-dom'; - -const Update = () => { - const location = useLocation(); - const [loading, setLoading] = useState(true); - const { dsdId } = useParams(); - - const [structure, setStructure] = useState({}); - useEffect(() => { - StructureAPI.getStructure(dsdId) - .then(res => setStructure(res)) - .finally(() => { - setLoading(false); - }); - }, [dsdId]); - const duplicate = location.pathname.indexOf('/duplicate') >= 0; - - if (loading) return ; - - if(duplicate){ - return ( - { - return { - component: cd.component, - order: cd.order, - required: cd.required, - attachment: cd.attachment - } - }) - }} - /> - ); - } - - return ( - - ); -}; - -export default Update; diff --git a/app/src/js/applications/structures/edition/update/index.js b/app/src/js/applications/structures/edition/update/index.js index b404d7fd4..c27193d67 100644 --- a/app/src/js/applications/structures/edition/update/index.js +++ b/app/src/js/applications/structures/edition/update/index.js @@ -1 +1,61 @@ -export { default } from './component'; +import React, { useState, useEffect } from 'react'; +import Edition from '../component'; +import { Loading } from '@inseefr/wilco'; +import { StructureAPI } from 'bauhaus-structures'; +import { useLocation, useParams } from 'react-router-dom'; +import { useTitle } from 'bauhaus-utilities'; +import D from '../../../../i18n/build-dictionary'; + +const Update = () => { + const location = useLocation(); + const [loading, setLoading] = useState(true); + const { dsdId } = useParams(); + + const [structure, setStructure] = useState({}); + useTitle(D.structuresTitle, structure?.labelLg1); + + useEffect(() => { + StructureAPI.getStructure(dsdId) + .then(res => setStructure(res)) + .finally(() => { + setLoading(false); + }); + }, [dsdId]); + const duplicate = location.pathname.indexOf('/duplicate') >= 0; + + if (loading) return ; + + if(duplicate){ + return ( + { + return { + component: cd.component, + order: cd.order, + required: cd.required, + attachment: cd.attachment + } + }) + }} + /> + ); + } + + return ( + + ); +}; + +export default Update; diff --git a/app/src/js/applications/structures/home.js b/app/src/js/applications/structures/home.js index b8b7270ff..b2e12be52 100644 --- a/app/src/js/applications/structures/home.js +++ b/app/src/js/applications/structures/home.js @@ -10,8 +10,10 @@ import { import { StructureAPI } from 'bauhaus-structures'; import D from 'js/i18n'; import { getEnvVar } from 'js/utils/env'; +import { useTitle } from 'bauhaus-utilities'; const Home = () => { + useTitle(D.structuresTitle, D.structuresTitle); const [DSDs, setDSDs] = useState([]); useEffect(() => { diff --git a/app/src/js/applications/structures/visualization/components/components.js b/app/src/js/applications/structures/visualization/components/components.js deleted file mode 100644 index ca31a762b..000000000 --- a/app/src/js/applications/structures/visualization/components/components.js +++ /dev/null @@ -1,60 +0,0 @@ -import React, { useState, useEffect, useCallback } from 'react'; -import { - StructureComponentsSelector, - getFormattedCodeList, - ComponentSpecificationModal, - CodesListPanel -} from 'bauhaus-structures'; -import { ConceptsAPI } from 'bauhaus-utilities'; - -const Components = ({ componentDefinitions = []}) => { - const [concepts, setConcepts] = useState([]); - const [codesLists, setCodesLists] = useState([]); - const [modalOpened, setModalOpened] = useState(false); - const [selectedComponent, setSelectedComponent] = useState({}); - - const [codesListNotation, setCodesListNotation] = useState(undefined); - const handleCodesListDetail = useCallback(notation => { - setCodesListNotation(notation); - }, []) - - useEffect(() => { - ConceptsAPI.getConceptList().then(res => setConcepts(res)); - }, []); - - useEffect(() => { - getFormattedCodeList().then(res => setCodesLists(res)); - }, []); - - const handleSpecificationClick = useCallback(component => { - setSelectedComponent(component); - setModalOpened(true); - }, []); - return ( -
    - {modalOpened && ( - setModalOpened(false)} - structureComponents={componentDefinitions} - disabled={true} - specification={{ - attachment: selectedComponent.attachment, - required: selectedComponent.required, - }} - /> - )} - - setCodesListNotation(undefined)}/> - -
    - ); -}; - -export default Components; diff --git a/app/src/js/applications/structures/visualization/components/index.js b/app/src/js/applications/structures/visualization/components/index.js index 8188d191b..ca31a762b 100644 --- a/app/src/js/applications/structures/visualization/components/index.js +++ b/app/src/js/applications/structures/visualization/components/index.js @@ -1 +1,60 @@ -export { default } from './components'; +import React, { useState, useEffect, useCallback } from 'react'; +import { + StructureComponentsSelector, + getFormattedCodeList, + ComponentSpecificationModal, + CodesListPanel +} from 'bauhaus-structures'; +import { ConceptsAPI } from 'bauhaus-utilities'; + +const Components = ({ componentDefinitions = []}) => { + const [concepts, setConcepts] = useState([]); + const [codesLists, setCodesLists] = useState([]); + const [modalOpened, setModalOpened] = useState(false); + const [selectedComponent, setSelectedComponent] = useState({}); + + const [codesListNotation, setCodesListNotation] = useState(undefined); + const handleCodesListDetail = useCallback(notation => { + setCodesListNotation(notation); + }, []) + + useEffect(() => { + ConceptsAPI.getConceptList().then(res => setConcepts(res)); + }, []); + + useEffect(() => { + getFormattedCodeList().then(res => setCodesLists(res)); + }, []); + + const handleSpecificationClick = useCallback(component => { + setSelectedComponent(component); + setModalOpened(true); + }, []); + return ( +
    + {modalOpened && ( + setModalOpened(false)} + structureComponents={componentDefinitions} + disabled={true} + specification={{ + attachment: selectedComponent.attachment, + required: selectedComponent.required, + }} + /> + )} + + setCodesListNotation(undefined)}/> + +
    + ); +}; + +export default Components; diff --git a/app/src/js/applications/structures/visualization/dsd.js b/app/src/js/applications/structures/visualization/dsd.js deleted file mode 100644 index a37ba9820..000000000 --- a/app/src/js/applications/structures/visualization/dsd.js +++ /dev/null @@ -1,130 +0,0 @@ -import React, { useState, useEffect } from 'react'; -import { useParams } from 'react-router-dom'; -import { Note, Loading, ErrorBloc } from '@inseefr/wilco'; -import { useSelector } from 'react-redux'; -import { - CheckSecondLang, - Stores, - PageTitleBlock, - DateUtils, - PublicationFemale -} from 'bauhaus-utilities'; -import Components from './components'; -import { D1, D2 } from 'js/i18n'; -import { - StructureAPI, - StructureVisualizationControl, - StructuresUtils -} from 'bauhaus-structures'; -import D from 'bauhaus-structures/src/i18n/build-dictionary'; -import api from 'bauhaus-structures/src/apis/structure-api'; - -export const StructureView = ({secondLang, structure, publish, serverSideError}) => { - const { - labelLg1, - labelLg2, - descriptionLg1, - descriptionLg2, - componentDefinitions = [], - } = structure; - - return ( - <> - - - - -
    - -
  • - {D1.idTitle} : {structure.identifiant} -
  • -
  • - {D1.createdDateTitle} : {DateUtils.stringToDate(structure.created)} -
  • -
  • - {D1.modifiedDateTitle} : {DateUtils.stringToDate(structure.modified)} -
  • -
  • - {D.componentValididationStatusTitle} :{' '} - -
  • -
  • - {D.creator} :{' '} - {structure.creator} -
  • -
  • - {D.contributor} :{' '} - {structure.contributor} -
  • -
  • - {D.disseminationStatusTitle} :{' '} - {StructuresUtils.getDisseminationStatus(structure.disseminationStatus)} -
  • - - } - title={D1.globalInformationsTitle} - alone={true} - /> -
    -
    - - {secondLang && ( - - )} -
    - - - ); -} -const Structure = () => { - const { dsdId } = useParams(); - const [structure, setStructure] = useState({}); - const [loading, setLoading] = useState(true); - const [serverSideError, setServerSideError] = useState(); - const secondLang = useSelector((state) => - Stores.SecondLang.getSecondLang(state) - ); - - useEffect(() => { - StructureAPI.getStructure(dsdId) - .then((res) => setStructure(res)) - .finally(() => setLoading(false)); - }, [dsdId]); - - const publish = () => { - setLoading(true); - setServerSideError(); - return api.publishStructure(structure) - .then(() => api.getStructure(structure.id)) - .then(component => setStructure(component)) - .finally(() => setLoading(false)) - .catch(error => { - setServerSideError(D['errors_' + JSON.parse(error).code]) - }) - } - - if (loading) { - return ; - } - - return -}; - -export default Structure; diff --git a/app/src/js/applications/structures/visualization/index.js b/app/src/js/applications/structures/visualization/index.js index db3b198dc..365cc0fd8 100644 --- a/app/src/js/applications/structures/visualization/index.js +++ b/app/src/js/applications/structures/visualization/index.js @@ -1 +1,132 @@ -export { default } from './dsd'; +import React, { useState, useEffect } from 'react'; +import { useParams } from 'react-router-dom'; +import { Note, Loading, ErrorBloc } from '@inseefr/wilco'; +import { useSelector } from 'react-redux'; +import { + CheckSecondLang, + Stores, + PageTitleBlock, + DateUtils, + PublicationFemale, + useTitle +} from 'bauhaus-utilities'; +import Components from './components'; +import { D1, D2 } from 'js/i18n'; +import { + StructureAPI, + StructureVisualizationControl, + StructuresUtils +} from 'bauhaus-structures'; +import D from 'bauhaus-structures/src/i18n/build-dictionary'; +import api from 'bauhaus-structures/src/apis/structure-api'; + +export const StructureView = ({secondLang, structure, publish, serverSideError}) => { + useTitle(D.structuresTitle, structure?.labelLg1) + const { + labelLg1, + labelLg2, + descriptionLg1, + descriptionLg2, + componentDefinitions = [], + } = structure; + + return ( + <> + + + + +
    + +
  • + {D1.idTitle} : {structure.identifiant} +
  • +
  • + {D1.createdDateTitle} : {DateUtils.stringToDate(structure.created)} +
  • +
  • + {D1.modifiedDateTitle} : {DateUtils.stringToDate(structure.modified)} +
  • +
  • + {D.componentValididationStatusTitle} :{' '} + +
  • +
  • + {D.creator} :{' '} + {structure.creator} +
  • +
  • + {D.contributor} :{' '} + {structure.contributor} +
  • +
  • + {D.disseminationStatusTitle} :{' '} + {StructuresUtils.getDisseminationStatus(structure.disseminationStatus)} +
  • + + } + title={D1.globalInformationsTitle} + alone={true} + /> +
    +
    + + {secondLang && ( + + )} +
    + + + ); +} +const Structure = () => { + const { dsdId } = useParams(); + const [structure, setStructure] = useState({}); + const [loading, setLoading] = useState(true); + const [serverSideError, setServerSideError] = useState(); + const secondLang = useSelector((state) => + Stores.SecondLang.getSecondLang(state) + ); + + useEffect(() => { + StructureAPI.getStructure(dsdId) + .then((res) => setStructure(res)) + .finally(() => setLoading(false)); + }, [dsdId]); + + const publish = () => { + setLoading(true); + setServerSideError(); + return api.publishStructure(structure) + .then(() => api.getStructure(structure.id)) + .then(component => setStructure(component)) + .finally(() => setLoading(false)) + .catch(error => { + setServerSideError(D['errors_' + JSON.parse(error).code]) + }) + } + + if (loading) { + return ; + } + + return +}; + +export default Structure; diff --git a/app/src/js/applications/structures/visualization/dsd.spec.js b/app/src/js/applications/structures/visualization/index.spec.js similarity index 98% rename from app/src/js/applications/structures/visualization/dsd.spec.js rename to app/src/js/applications/structures/visualization/index.spec.js index 7b7ea2fae..19b656c6c 100644 --- a/app/src/js/applications/structures/visualization/dsd.spec.js +++ b/app/src/js/applications/structures/visualization/index.spec.js @@ -1,5 +1,5 @@ import React from 'react'; -import {StructureView} from './dsd'; +import {StructureView} from './index'; import { render } from '@testing-library/react'; import {MemoryRouter} from 'react-router'; import { Provider } from 'react-redux'; diff --git a/app/src/js/i18n/dictionary/app.js b/app/src/js/i18n/dictionary/app.js index 0ed08ac37..f78ae3bdd 100644 --- a/app/src/js/i18n/dictionary/app.js +++ b/app/src/js/i18n/dictionary/app.js @@ -425,6 +425,8 @@ const dictionary = { }, btnExport: { fr: "Options d'export", en: 'Export options' }, btnExportValidate: { fr: 'Exporter en odt', en: 'Export to odt' }, + advancedSearch: { fr: 'Recherche Avancée', en: 'Advanced Search' }, + }; export default dictionary; diff --git a/app/src/js/i18n/dictionary/dsds.js b/app/src/js/i18n/dictionary/dsds.js index 99fa97732..e4a8fa98c 100644 --- a/app/src/js/i18n/dictionary/dsds.js +++ b/app/src/js/i18n/dictionary/dsds.js @@ -1,5 +1,9 @@ export default { structuresTitle: { fr: 'Structures', en: 'Structures' }, + structuresCreateTitle: { + fr: 'Créer une nouvelle structure', + en: 'Create a new structure', + }, dsdsSearchTitle: { fr: 'Data structure definition - Recherche', en: 'Data structure definition - Search', diff --git a/app/src/js/i18n/dictionary/operations/documents.js b/app/src/js/i18n/dictionary/operations/documents.js index adec2e3c0..edecd35fd 100644 --- a/app/src/js/i18n/dictionary/operations/documents.js +++ b/app/src/js/i18n/dictionary/operations/documents.js @@ -20,4 +20,8 @@ export default { fr: 'Document/Lien - Recherche', en: 'Document/Link - Search', }, + documentsTitle: { + fr: 'Document/Lien', + en: 'Document/Link', + }, }; diff --git a/app/src/js/i18n/dictionary/operations/index.js b/app/src/js/i18n/dictionary/operations/index.js index ca0eff3b0..fe1570642 100644 --- a/app/src/js/i18n/dictionary/operations/index.js +++ b/app/src/js/i18n/dictionary/operations/index.js @@ -21,6 +21,30 @@ const dictionary = { fr: 'Indicateurs', en: 'Indicators', }, + operationsCreateTitle: { + fr: 'Créer une nouvelle opération', + en: 'Create a new operation', + }, + familiesCreateTitle: { + fr: 'Créer une nouvelle famille', + en: 'Create a new family', + }, + documentsCreateTitle: { + fr: 'Créer un nouveau document', + en: 'Create a new document', + }, + linksCreateTitle: { + fr: 'Créer un nouveau lien', + en: 'Create a new link', + }, + seriesCreateTitle: { + fr: 'Créer une nouvelle série', + en: 'Create a new series', + }, + indicatorsCreateTitle: { + fr: 'Créer un nouvel indicateur', + en: 'Create a new indicator', + }, operationsSearchTitle: { fr: 'Opérations - Recherche', en: 'Operations - Search', diff --git a/package.json b/package.json index 6604f2412..797d4e5f4 100644 --- a/package.json +++ b/package.json @@ -49,8 +49,8 @@ "jest": "26.6.0", "jest-localstorage-mock": "2.4.3", "lcov-result-merger": "3.1.0", - "prettier": "2.0.5", - "webpack": "5.39.1" + "prettier": "2.3.2", + "webpack": "5.49.0" }, "dependencies": { "dompurify": "2.2.9", diff --git a/packages/codelists/package.json b/packages/codelists/package.json index 5c3e4e8dd..b346a2f7e 100644 --- a/packages/codelists/package.json +++ b/packages/codelists/package.json @@ -28,6 +28,7 @@ "dependencies": { "bauhaus-utilities": "^0.0.0", "react-is": "^16.13.1", - "react-sliding-side-panel": "^1.0.14" + "react-sliding-side-panel": "^1.0.14", + "react-sortable-tree": "2.1.0" } } diff --git a/packages/codelists/src/components/code-detail/code-columns.js b/packages/codelists/src/components/code-detail/code-columns.js new file mode 100644 index 000000000..2b5d079d8 --- /dev/null +++ b/packages/codelists/src/components/code-detail/code-columns.js @@ -0,0 +1,14 @@ +import { D1, D2 } from '../../i18n/build-dictionary'; + +export const rowParams = [ + { + dataField: 'code', + text: D1.codeTitle, + width: '8%', + isKey: true, + }, + { dataField: 'labelLg1', text: D1.codeLabel, width: '16%' }, + { dataField: 'labelLg2', text: D2.codeLabel, width: '16%' }, + { dataField: 'descriptionLg1', text: D1.codeDescription, width: '30%' }, + { dataField: 'descriptionLg2', text: D2.codeDescription, width: '30%' }, +]; diff --git a/packages/codelists/src/components/code-detail/edit.js b/packages/codelists/src/components/code-detail/edit.js new file mode 100644 index 000000000..143af4e5a --- /dev/null +++ b/packages/codelists/src/components/code-detail/edit.js @@ -0,0 +1,171 @@ +import React, { useState, useCallback, useEffect } from 'react'; +import { + CancelButton, + SaveButton, + ActionToolbar, + ErrorBloc, + LabelRequired, + Select, +} from '@inseefr/wilco'; +import PropTypes from 'prop-types'; +import { Stores } from 'bauhaus-utilities'; +import { validateCode } from '../../utils'; +import D, { D1, D2 } from '../../i18n/build-dictionary'; +import './edit.scss'; + +/** + * TODO: + * - Afficher le TreeView à gauche + * - Ajouter le formulaire vide à droite + * - Ajouter les boutons (qui ne font rien pour le moment) + * - Gérer le click sur un code -> initaliser le formulaire avec les bonnes données + * - Gérer l'ajout d'un nouveau code + * - Gérer la sauvegarde d'un code existant + * - Gérer la transformation TreeView -> Structure de données pour l'API + * - Gérer la suppression d'un code et remontée des enfants + * - gérer la suppression d'un code et suppression des enfants + * - Gérer le DragnDrop + */ +const DumbCodeDetailEdit = ({ + code: initialCode, + codes, + handleSave, + handleBack, + serverSideError, +}) => { + const [code, setCode] = useState({}); + useEffect(() => { + setCode({ ...initialCode }); + }, [initialCode]); + const [parents, setParents] = useState(code.parents); + + const handleChange = useCallback( + (e) => { + const { name, value } = e.target; + setCode({ + ...code, + [name]: value, + }); + }, + [code] + ); + + const codesOptions = codes + .map((code) => { + return { + label: code.code + ' - ' + code.labelLg1, + value: code.code, + }; + }) + .concat({ label: '', value: '' }); + + const handleSaveClick = useCallback(() => { + handleSave(code); + }, [code, handleSave]); + + const { field, message } = validateCode(code); + return ( + + + + + + {message && } + {serverSideError && } +
    +
    + {D.parentCodeTitle} + +
    +
    +
    +
    + {D1.codeLabel} + +
    +
    + {D2.codeLabel} + +
    +
    + +
    +
    + + +
    +
    + + +
    +
    + + + ); +}; + +DumbCodeDetailEdit.propTypes = { + code: PropTypes.object, + handleSave: PropTypes.func, + handleBack: PropTypes.func, + secondLang: PropTypes.bool, +}; + +export const CodeDetailEdit = Stores.DisseminationStatus.withDisseminationStatusListOptions( + DumbCodeDetailEdit +); diff --git a/packages/codelists/src/components/code-detail/edit.scss b/packages/codelists/src/components/code-detail/edit.scss new file mode 100644 index 000000000..a57d955c4 --- /dev/null +++ b/packages/codelists/src/components/code-detail/edit.scss @@ -0,0 +1,13 @@ +.code-list-zone { + display: flex; + div:nth-child(1){ + flex: 1; + margin-bottom: 0; + } + + button { + padding: .5em 2em; + margin: 0 0 0 1em; + align-self: flex-end; + } +} diff --git a/packages/codelists/src/components/code-detail/index.js b/packages/codelists/src/components/code-detail/index.js new file mode 100644 index 000000000..4932288ba --- /dev/null +++ b/packages/codelists/src/components/code-detail/index.js @@ -0,0 +1,52 @@ +import React, { useCallback, useState } from 'react'; +import { CodeDetailEdit } from './edit'; +import { CodeDetailView } from './view'; +import CodeTitle from './title'; +import { useSelector } from 'react-redux'; +import { Stores } from 'bauhaus-utilities'; + +export const CodeDetail = (props) => { + const secondLang = useSelector(Stores.SecondLang.getSecondLang); + + const [mode, setMode] = useState( + !props.readOnly && !props.code?.labelLg1 ? 'EDIT' : 'VIEW' + ); + + const handleViewUpdate = useCallback(() => setMode('EDIT'), []); + const handleEditUpdate = useCallback( + (code) => { + props.handleSave(code); + setMode('VIEW'); + }, + [props] + ); + const handleEditBack = useCallback( + () => (!props.code.labelLg1 ? props.handleBack() : setMode('VIEW')), + [props] + ); + return ( +
    + {mode === 'VIEW' && ( + + + + + + )} + {mode === 'EDIT' && ( + + )} +
    + ); +}; diff --git a/packages/codelists/src/components/code-detail/title.js b/packages/codelists/src/components/code-detail/title.js new file mode 100644 index 000000000..413e19c48 --- /dev/null +++ b/packages/codelists/src/components/code-detail/title.js @@ -0,0 +1,17 @@ +import React from 'react'; +import { CheckSecondLang, PageTitleBlock } from 'bauhaus-utilities'; + +const CodeTitle = ({ code, secondLang }) => { + return ( + + + + + ); +}; + +export default CodeTitle; diff --git a/packages/codelists/src/components/code-detail/view.js b/packages/codelists/src/components/code-detail/view.js new file mode 100644 index 000000000..cb9c08cb5 --- /dev/null +++ b/packages/codelists/src/components/code-detail/view.js @@ -0,0 +1,104 @@ +import React from 'react'; +import { + Note, + UpdateButton, + ActionToolbar, + ReturnButton, + ErrorBloc, +} from '@inseefr/wilco'; +import D, { D1, D2 } from '../../i18n/build-dictionary'; +import { HTMLUtils, ValidationButton } from 'bauhaus-utilities'; +import PropTypes from 'prop-types'; +import './view.scss'; + +export const CodeDetailView = ({ + code, + codes, + handleUpdate, + handleBack, + updatable, + secondLang, + col = 3, + publishComponent, + serverSideError, +}) => { + const descriptionLg1 = HTMLUtils.renderMarkdownElement(code.descriptionLg1); + const descriptionLg2 = HTMLUtils.renderMarkdownElement(code.descriptionLg2); + + const publish = () => { + publishComponent(); + }; + + const codesOptions = codes.map((code) => { + return { + label: code.code + ' - ' + code.labelLg1, + value: code.code, + }; + }); + + return ( + + + + + {updatable && } + + + +
    + + {codesOptions + .filter( + ({ value }) => + code.parents && + code.parents.some((parent) => parent === value) + ) + .map((code) => ( +
  • {code.label}
  • + ))} + + } + title={D1.parentCodeTitle} + alone={true} + /> +
    +
    + +
    +
    + + {secondLang && ( + + )} +
    +
    + + {secondLang && ( + + )} +
    +
    + ); +}; + +CodeDetailView.propTypes = { + code: PropTypes.object, + codes: PropTypes.array, + handleUpdate: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), + handleBack: PropTypes.func, + updatable: PropTypes.bool, + secondLang: PropTypes.bool, + publishComponent: PropTypes.func, +}; diff --git a/packages/codelists/src/components/code-detail/view.scss b/packages/codelists/src/components/code-detail/view.scss new file mode 100644 index 000000000..7b6124f7a --- /dev/null +++ b/packages/codelists/src/components/code-detail/view.scss @@ -0,0 +1,11 @@ +.code-list-zone-view { + display: flex; + justify-content: space-between; + align-items: center; + + button { + padding: .5em 2em; + margin: 0 0 0 1em; + align-self: flex-end; + } +} diff --git a/packages/codelists/src/components/codelist-detail/edit.js b/packages/codelists/src/components/codelist-detail/edit.js index c53907004..01336ec64 100644 --- a/packages/codelists/src/components/codelist-detail/edit.js +++ b/packages/codelists/src/components/codelist-detail/edit.js @@ -7,9 +7,9 @@ import { LabelRequired, Select, } from '@inseefr/wilco'; -import { Stores } from 'bauhaus-utilities'; +import { Stores, useTitle } from 'bauhaus-utilities'; import { validateCodelist } from '../../utils'; -import { D1, D2 } from '../../i18n/build-dictionary'; +import D, { D1, D2 } from '../../i18n/build-dictionary'; import PropTypes from 'prop-types'; import { default as ReactSelect } from 'react-select'; import dayjs from 'dayjs'; @@ -27,7 +27,10 @@ const DumbCodelistDetailEdit = ({ stampListOptions, serverSideError, }) => { + const [codelist, setCodelist] = useState(defaultCodelist); + useTitle(D.codelistsTitle, codelist?.labelLg1 || D.codelistsCreateTitle) + useEffect(() => { setCodelist({ ...initialCodelist, ...defaultCodelist }); }, [initialCodelist]); @@ -129,7 +132,7 @@ const DumbCodelistDetailEdit = ({
    - + {D1.creator} { + useTitle(D.codelistsTitle, codelist?.labelLg1) + const descriptionLg1 = HTMLUtils.renderMarkdownElement( codelist.descriptionLg1 ); @@ -38,6 +44,9 @@ export const CodeListDetailView = ({ publishComponent(); }; + const unsortedCodes = Object.values(codelist.codes); + const sortedCodes = unsortedCodes.sort((a, b) => (a.code > b.code ? 1 : -1)); + const codes = Object.values(codelist.codes); return ( @@ -99,17 +108,22 @@ export const CodeListDetailView = ({ {codelist.codes && (
    - } + text={} title={D.listElements} alone={true} /> )} + {codelist.codes && codes.filter((code) => code.parents).length > 0 && ( +
    + +
    + )} ); }; diff --git a/packages/codelists/src/components/codes-tree/index.js b/packages/codelists/src/components/codes-tree/index.js new file mode 100644 index 000000000..b35061989 --- /dev/null +++ b/packages/codelists/src/components/codes-tree/index.js @@ -0,0 +1,72 @@ +import React, { useCallback, useState } from 'react'; +import PropTypes from 'prop-types'; +import SlidingPanel from 'react-sliding-side-panel'; +import D from '../../i18n/build-dictionary'; +import { CollapsiblePanel } from '../collapsible-panel'; +import { CodeDetail } from '../code-detail'; +import RmesTree from '../tree'; + +const CodesTree = ({ hidden = false, codes, tree, handleAdd, readOnly }) => { + const [openPanel, setOpenPanel] = useState(false); + const [selectedCode, setSelectedCode] = useState(null); + + const seeClickHandler = useCallback( + (e) => { + const chosenCode = codes.find( + (c) => c.code === e.target.parentElement.dataset.componentId + ); + setSelectedCode(chosenCode); + setOpenPanel(true); + }, + [codes] + ); + + /* const addClickHandler = useCallback( + (e) => { + handleAdd(e.id); + }, + [handleAdd] + ); */ + + return ( +