From 561f2d154947df8b5849438d1b9c665533c7a975 Mon Sep 17 00:00:00 2001
From: Philippe Coicadan <philcoicadan@arolios.org>
Date: Mon, 30 Dec 2024 18:18:39 +0100
Subject: [PATCH] some improvements and bug fixing

---
 src/pages/dashboard/index.jsx     | 21 +++++----
 src/pages/export/index.jsx        |  2 +-
 src/resources/instances/index.jsx | 11 ++---
 src/resources/settings/index.jsx  | 75 ++++++++++++++++---------------
 src/resources/users/index.jsx     |  2 +-
 src/utils/authProvider/index.jsx  |  2 +-
 src/utils/dataProvider/index.jsx  | 19 +++++++-
 src/utils/fields/index.jsx        | 22 ++++++---
 src/utils/i18nProvider/en.js      | 17 +++----
 src/utils/i18nProvider/fr.js      | 19 ++++----
 10 files changed, 111 insertions(+), 79 deletions(-)

diff --git a/src/pages/dashboard/index.jsx b/src/pages/dashboard/index.jsx
index 901e4dd..fe3f93a 100644
--- a/src/pages/dashboard/index.jsx
+++ b/src/pages/dashboard/index.jsx
@@ -1,29 +1,32 @@
-import { useCreatePath} from 'react-admin';
+import { useCreatePath, useGetList} from 'react-admin';
 import {useNavigate } from 'react-router-dom';
-import { useContext , useEffect} from "react";
+import { useContext , useEffect, useState} from "react";
 import { ClassifierContext} from '../../utils/contexts'
 
+
 const CustomDashboard = () => {
-    const createPath = useCreatePath();
+   
     const navigate = useNavigate();
-    const {mapDomainNameResource} = useContext(ClassifierContext);
-    const def_dom = sessionStorage.getItem('arolios_model_default_domain') ;
+    const createPath = useCreatePath();
 
-    useEffect(() => {
+    const { mapDomainNameResource } = useContext(ClassifierContext);
 
-        if (def_dom) {
+    
+
+    useEffect(() => {
+       
+        if (sessionStorage.getItem('arolios_model_default_domain')) {
             const { name, _tname } = JSON.parse(sessionStorage.getItem('arolios_model_default_domain'));
             const path = createPath({ resource: `${name}/classes`, type: 'list' });
             mapDomainNameResource(name, _tname);
 
             return navigate(path);
 
-
         } else {
             const path = createPath({ resource: 'domains', type: 'list' });
             return navigate(path);
         }
-    }, []);
+    }, []); 
 }
 
 export default CustomDashboard;
\ No newline at end of file
diff --git a/src/pages/export/index.jsx b/src/pages/export/index.jsx
index ed3556d..7671a03 100644
--- a/src/pages/export/index.jsx
+++ b/src/pages/export/index.jsx
@@ -50,7 +50,7 @@ const ExportData = () => {
         .then ( json => {
             notify ('arolios.export_success', {type: 'success', messageArgs: { title: `${data.query.title}`}});
             downloadJSON (JSON.stringify(json["elements"]), "export");
-            redirect (createPath( { resource: 'domains', type: 'list' }));
+            redirect ('/');
             return Promise.resolve();
         })
         .catch(() => {
diff --git a/src/resources/instances/index.jsx b/src/resources/instances/index.jsx
index 6aed809..6448ca3 100644
--- a/src/resources/instances/index.jsx
+++ b/src/resources/instances/index.jsx
@@ -1,6 +1,7 @@
 import { List, Datagrid,
     ShowButton, EditButton, Loading, Show, Edit, SimpleShowLayout, SimpleForm,
-     Create, TopToolbar, ExportButton, CreateButton, SaveButton, Toolbar, DeleteWithConfirmButton, SearchInput, useTranslate, EmptyClasses} from 'react-admin';
+     Create, TopToolbar, ExportButton, CreateButton, SaveButton, Toolbar, DeleteWithConfirmButton, SearchInput, useTranslate, EmptyClasses,
+     useRecordSelection} from 'react-admin';
 import { useContext} from "react";
 import { AssociationMemberEndContext, ClassifierContext } from "../../utils/contexts";
 import { useProperties } from "../../utils/properties";
@@ -219,7 +220,7 @@ const assocFunctions = {
 
 
 const classFilters = ( loading ) => {
-    if (loading) return [];
+   // if (loading) return [];
     const arr1 = [ <SearchInput source="_s" alwaysOn />]
 
     return arr1;
@@ -474,14 +475,14 @@ export const AssocInstanceShow = () => {
        )
 }
 
-const EditToolbar = () => {
+const EditToolbar = ( {type} ) => {
     const translate = useTranslate();
     return (
         <Toolbar>
             <SaveButton  />
             <DeleteWithConfirmButton
                 resource='instances'
-                confirmContent={translate('arolios.delete_confirm_msg')}
+                confirmTitle = {translate('arolios.delete_confirm_title', { name : type}) }
                 redirect='/'
             />
 
@@ -506,7 +507,7 @@ export const ClassInstanceEdit = () => {
                 <Loading />
             ) : (
                 <div>
-                    <SimpleForm toolbar={<EditToolbar />}>
+                    <SimpleForm toolbar={<EditToolbar type={csf_name} />}>
 
                         {
 
diff --git a/src/resources/settings/index.jsx b/src/resources/settings/index.jsx
index f749531..3cf8848 100644
--- a/src/resources/settings/index.jsx
+++ b/src/resources/settings/index.jsx
@@ -1,6 +1,6 @@
-import { Toolbar, SaveButton, PasswordInput, Create, Edit, SimpleForm, SelectInput, required , ReferenceInput, TopToolbar, useNotify, useRedirect} from "react-admin";
+import { Toolbar, SaveButton, PasswordInput, Create, Edit, SimpleForm, SelectInput, required, ReferenceInput, TopToolbar, useNotify, useRedirect} from "react-admin";
 import * as MUI from '@mui/material';
-import {  useCreatePath, useTranslate } from "react-admin";
+import { useCreatePath, useTranslate} from "react-admin";
 import { useNavigate } from 'react-router-dom';
 
 
@@ -20,20 +20,20 @@ export const PasswordCreate = () => {
 
     }
     return (
-    
-  
-    <Create   title="arolios.change_password" mutationOptions={{ onSuccess }} >
-    
-    <SimpleForm>
-    
-    <PasswordInput label="arolios.current_password" source="current_password" fullWidth validate={required()}/> 
-    <PasswordInput label="arolios.new_password" source="new_password" fullWidth validate={required()}/> 
-    <PasswordInput label="arolios.confirm_password" source="confirm_password" fullWidth validate={[required(), equalToNewPassword]}/> 
 
 
-    </SimpleForm>
+        <Create title="arolios.change_password" mutationOptions={{ onSuccess }} >
 
-    </Create>
+            <SimpleForm>
+
+                <PasswordInput label="arolios.current_password" source="current_password" fullWidth validate={required()} />
+                <PasswordInput label="arolios.new_password" source="new_password" fullWidth validate={required()} />
+                <PasswordInput label="arolios.confirm_password" source="confirm_password" fullWidth validate={[required(), equalToNewPassword]} />
+
+
+            </SimpleForm>
+
+        </Create>
     )
 }
 
@@ -46,47 +46,50 @@ const ChangePasswordButton = () => {
         const link = createPath({
             type: 'create',
             resource: 'password'
-         });
-         
+        });
+
         navigate(link);
     };
 
-    return (<MUI.Link  component="button"  variant="body2" onClick={handleClick} >{translate('arolios.change_password')}</MUI.Link>);
+    return (<MUI.Link component="button" variant="body2" onClick={handleClick} >{translate('arolios.change_password')}</MUI.Link>);
 }
 
 
- const SettingActions = () => (
+const SettingActions = () => (
     <TopToolbar>
         <ChangePasswordButton />
     </TopToolbar>
- )
+)
+
 
- const EditToolbar = () => {
+const EditToolbar = () => {
 
     return (
         <Toolbar>
-            <SaveButton />         
+            <SaveButton />
         </Toolbar>
     )
 
 }
+
 export const SettingsEdit = () => {
     const translate = useTranslate();
+ 
     return (
-    
-  
-    <Edit  title={translate('resources.settings.name',2)} actions={<SettingActions />} redirect={false} mutationOptions={{ meta:{ prefix: 'settings' }}} queryOptions={{ meta:{ prefix: 'settings', context: 'rfu'}}}>
-    
-    <SimpleForm toolbar= {<EditToolbar />}>
-
-    <ReferenceInput source="model_language" reference="languages" sort={{field: 'code', order: 'ASC'}} queryOptions={{ meta:{ getmany_context: 'languages'} }}>
-                <SelectInput label= "arolios.model_language" optionText="name" optionValue="code" validate={required()}/>
-    </ReferenceInput>
-
-    </SimpleForm>
-
-       
-    </Edit>)
-    
-    
+
+
+        <Edit title={translate('resources.settings.name', 2)} actions={<SettingActions />} redirect={false} mutationOptions={{ meta: { prefix: 'settings' }  }} mutationMode="pessimistic" queryOptions={{ meta: { prefix: 'settings', context: 'rfu' } } }>
+
+            <SimpleForm toolbar={<EditToolbar />}>
+
+                <ReferenceInput source="model_language" reference="languages" sort={{ field: 'code', order: 'ASC' }} queryOptions={{ meta: { getmany_context: 'languages' } }}>
+                    <SelectInput label="arolios.model_language" optionText="name" optionValue="code" validate={required()} />
+                </ReferenceInput>
+
+            </SimpleForm>
+
+
+        </Edit>)
+
+
 }
diff --git a/src/resources/users/index.jsx b/src/resources/users/index.jsx
index 5876e69..c640d70 100644
--- a/src/resources/users/index.jsx
+++ b/src/resources/users/index.jsx
@@ -75,7 +75,7 @@ export const UserCreate = () => {
      
     return (
         
-            <Create>
+            <Create redirect="list">
         
                 <SimpleForm>
                     <TextInput label="arolios.user_identifier" source="identifier" multiline fullWidth resettable validate={required()}/>
diff --git a/src/utils/authProvider/index.jsx b/src/utils/authProvider/index.jsx
index ff87c4d..d32d3ea 100644
--- a/src/utils/authProvider/index.jsx
+++ b/src/utils/authProvider/index.jsx
@@ -79,7 +79,7 @@ const authProvider = {
     },
 
     canEdit: (role) => {
-        return role === 'admin' || role === 'author' ;
+        return role === 'admin' || role === 'producer' ;
     }
 };
 
diff --git a/src/utils/dataProvider/index.jsx b/src/utils/dataProvider/index.jsx
index b691612..002e6db 100644
--- a/src/utils/dataProvider/index.jsx
+++ b/src/utils/dataProvider/index.jsx
@@ -43,7 +43,11 @@ const CustomDataProvider = {
             querySep = '&';    
         }
         if (field) {
-            query +=`${querySep}s=${field}`;
+            //eliminate field translation 
+            const field_arr1 = field.split('.');
+            const field_arr2 = field_arr1.map ( (item) => ( item.startsWith ('_t')) ? item.substring(2) :  item);
+            const true_field = field_arr2.join('.');
+            query +=`${querySep}s=${true_field}`;
             querySep = '&';
         }
         if (order) {
@@ -316,7 +320,18 @@ const CustomDataProvider = {
     
             const {prefix, suffix ,context } = params.meta || {};
             if (prefix === 'settings') {
-                localStorage.setItem("arolios_model_language",  params.data.model_language);
+                localStorage.setItem("arolios_model_language",  params.data.model_language);          
+                
+                const url = `${apiUrl}/domains?lang=${params.data.model_language}`
+                httpClient(url).then(({ headers, json }) => {
+                    if (json["total"] === 1) {
+                        sessionStorage.setItem('arolios_model_default_domain', JSON.stringify({ name: json["elements"][0]['name'], _tname: json["elements"][0]['_tname'] }));
+                    } else {
+                        sessionStorage.removeItem('arolios_model_default_domain');
+                    };
+                    
+                });
+                        
                 return Promise.resolve({data: params.data});
             }
             let url = `${apiUrl}/`;
diff --git a/src/utils/fields/index.jsx b/src/utils/fields/index.jsx
index e29edb0..d35e7dd 100644
--- a/src/utils/fields/index.jsx
+++ b/src/utils/fields/index.jsx
@@ -65,8 +65,9 @@ const MemberEndShowButton = ( {resource, resourceDisplay, prefix, field, sx }) =
 
 export const concatenateIdFieldValues = ( record ) => {
     let allIdFields = "" ;
+    let enumFields = [];
     for (const [key, value] of Object.entries(record.properties)) {
-        if (key[0] !== '_') {
+       // if (key[0] !== '_') {
             if (value instanceof Object) {
                 if (value.hasOwnProperty("properties")) { // linked prop
                     allIdFields= allIdFields.concat(" ", concatenateIdFieldValues(record['properties'][key]));
@@ -77,10 +78,13 @@ export const concatenateIdFieldValues = ( record ) => {
                         }
                     } 
                 }
-            } else {
+            } else if (key.startsWith ("_t") ){
+                allIdFields = allIdFields.concat(" ", String(value));
+                enumFields.push(key.substring(2));
+            } else if ( enumFields.indexOf( key ) === -1) {
                 allIdFields = allIdFields.concat(" ", String(value));
             }
-        }
+      // }
     }
     allIdFields = allIdFields.trim();
     return allIdFields;
@@ -207,8 +211,10 @@ export const InsertListField = ( property, prefix) => {
             };
             }
         case "_enumeration":
-            return (<TextField key={`${prefix}.${property.id_name}`} label={property._tpathname} source={source} />);
-
+            {
+                const source_enum = `${prefix}._t${property.id_name}`;
+            return (<TextField key={`${prefix}.${property.id_name}`} label={property._tpathname} source={source_enum} />);
+            }
         case "_composite_type":
             break;
         case "_class":
@@ -251,8 +257,10 @@ export const InsertShowField = (property, prefix) => {
             };
             }
         case "_enumeration":
-            return (<TextField key={`${prefix}.${property.id_name}`} label={property._tpathname} source={source} />);
-
+            {
+                const source_enum = `${prefix}._t${property.id_name}`;
+                return (<TextField key={`${prefix}.${property.id_name}`} label={property._tpathname} source={source_enum} />);
+            }
         case "_composite_type":
 
             break;
diff --git a/src/utils/i18nProvider/en.js b/src/utils/i18nProvider/en.js
index 90bbcb2..6f3286e 100644
--- a/src/utils/i18nProvider/en.js
+++ b/src/utils/i18nProvider/en.js
@@ -62,22 +62,22 @@ export const en = {
             model_loading: 'Data model loading',
             translation_loading: 'Translations loading',
             data_loading: 'Data loading',
-            delete_confirm_msg: 'Do you confirm the deletion?',
+            delete_confirm_title: 'Delete %{name}',
             classifier: 'Classifier',
-            list_of: '%{type}: List of data',
-            instance_of: 'Instance of %{type}',
+            list_of: '%{type}: List of items',
+            instance_of: 'Item of %{type}',
             trash_contents: "Trash contents",
             empty_trash: "Empty the trash",
             empty_trash_success: "Trash emptied successfully",
             empty_trash_error: "Error while emptying the trash : %{message}",
             recover: "Recover",
-            recover_success: "Data recovered successfully",
-            recover_error: "Error while recovering data: %{message}",
+            recover_success: "Item(s) recovered successfully",
+            recover_error: "Error while recovering item(s): %{message}",
             eliminate: "Delete",
             eliminate_title: "Delete definitively",
-            eliminate_confirm_msg: "You will not be able to recover these data. Are you sure ?",
-            empty_trash_title: "Delete definitively the data contained in the trash",
-            empty_trash_confirm_msg: "You will not be able to recover the data contained in the trash. Are you sure ?",
+            eliminate_confirm_msg: "You will not be able to recover this item. Are you sure ?",
+            empty_trash_title: "Delete definitively the items contained in the trash",
+            empty_trash_confirm_msg: "You will not be able to recover the items contained in the trash. Are you sure ?",
             code: "Code",
             model_language: "Model language",
             version: "Version",
@@ -108,6 +108,7 @@ export const en = {
             current_password: 'Current password',
             new_password: 'New password',
             password_updated: 'password updated',
+            settings_updated: 'settings updated',
             value: 'Value'
         },
     }
diff --git a/src/utils/i18nProvider/fr.js b/src/utils/i18nProvider/fr.js
index 6330f91..cd39d18 100644
--- a/src/utils/i18nProvider/fr.js
+++ b/src/utils/i18nProvider/fr.js
@@ -63,22 +63,22 @@ export const fr = {
             model_loading: 'Chargement du modèle de données',
             translation_loading: 'Chargement de traductions',
             data_loading: 'Chargement de données',
-            delete_confirm_msg: 'Confirmez-vous la suppression?',
+            delete_confirm_title: 'Supprimer %{name}',
             classifier: 'Classifieur',
-            list_of: '%{type}: Liste de données',
-            instance_of: 'Instance de %{type}',
+            list_of: "%{type}: Liste d'éléments",
+            instance_of: 'Element de %{type}',
             trash_contents: "Contenu de la corbeille",
             empty_trash: "Vider la corbeille",
             empty_trash_success: "Corbeille vidée",
             empty_trash_error: "Erreur en vidant la corbeille : %{message}",
-            recover: "Restaurer",
-            recover_success: "Donnée(s) restaurée(s)",
-            recover_error: "Erreur dans la restauration de donnée(s): %{message}",
+            recover: "Récuperer",
+            recover_success: "Donnée(s) récupérée(s)",
+            recover_error: "Erreur dans la récupération de donnée(s): %{message}",
             eliminate: "Supprimer",
             eliminate_title: "Supprimer definitivement",
-            eliminate_confirm_msg: "Vous ne pourrez pas récupérer ces données. Etes-vous sûr ?",
-            empty_trash_title: "Supprimer définitivement les données contenues dans la corbeille",
-            empty_trash_confirm_msg: "Vous ne pourrez pas récupérer les données contenues dans la corbeille. Etes-vous sûr ?",
+            eliminate_confirm_msg: "Vous ne pourrez pas récupérer cet élément. Etes-vous sûr ?",
+            empty_trash_title: "Supprimer définitivement les éléments contenus dans la corbeille",
+            empty_trash_confirm_msg: "Vous ne pourrez pas récupérer les éléments contenus dans la corbeille. Etes-vous sûr ?",
             code: "Code",
             model_language: "Langue du modèle",
             version: "Version",
@@ -109,6 +109,7 @@ export const fr = {
             current_password: 'mot de passe actuel',
             new_password: 'nouveau mot de passe',
             password_updated: 'mot de passe modifié',
+            settings_updated: 'réglages modifiés',
             value: 'Valeur'
         },
     }
-- 
GitLab