From dc0e517fd5918b8b1ef0186ab617d4f847cdcc0f Mon Sep 17 00:00:00 2001
From: Reinder Kraaij <kraaij@astron.nl>
Date: Mon, 20 Nov 2023 21:41:16 +0100
Subject: [PATCH] Let there be a Project change dialog

---
 .../tmss_webapp/src/routes/Project/create.js  |  4 +-
 .../tmss_webapp/src/routes/Project/list.js    | 89 +++++++------------
 .../src/routes/Project/projectStatusDialog.js | 61 +++++++++++++
 .../src/services/project.service.js           |  7 +-
 4 files changed, 102 insertions(+), 59 deletions(-)
 create mode 100644 SAS/TMSS/frontend/tmss_webapp/src/routes/Project/projectStatusDialog.js

diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js
index ba9a85fcf8d..21d84310dba 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/create.js
@@ -468,8 +468,8 @@ export class ProjectCreate extends Component {
         return (
             <React.Fragment>
                 <Toast ref={(el) => this.growl = el} />
-                 <PageHeader location={this.props.location} title={'Project - Add'} actions={[{icon:'fa-window-close', title:'Click to Close Project',
-                   type: 'button',  actOn: 'click', props:{ callback: this.checkIsDirty }}]}/>
+                 <PageHeader className="defaultpageHeader" location={this.props.location} title={'Project - Add'} actions={[{icon:'pi pi-times', title:'Click to Close Project', 
+                   type: 'buttonv2',  actOn: 'click', props:{ callback: this.checkIsDirty }}]}/>
                 { this.state.isLoading ? <AppLoader /> :
                 <>
                 <div style={{marginBottom: '2em'}}>
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
index cbf021d9f8e..7ad7b80b0bd 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/list.js
@@ -7,15 +7,13 @@ import CycleService from '../../services/cycle.service';
 import UtilService from '../../services/util.service';
 import AuthUtil from '../../utils/auth.util';
 import _ from 'lodash';
-import { Dialog } from 'primereact/dialog';
-import { RadioButton } from 'primereact/radiobutton';
-import { Button } from 'primereact/button';
+
 import { CustomDialog } from '../../layout/components/CustomDialog';
 import { Column } from 'primereact/column';
 import { DataTable } from 'primereact/datatable';
 import { appGrowl } from '../../layout/components/AppGrowl';
 import TopProgressBar from '../../layout/components/TopProgressBar';
-
+import ProjectStatusDialog from './projectStatusDialog'
 export class ProjectList extends Component {
     lsTableName = 'project_list';
     lsKeySortColumn = "projectSortData";
@@ -263,7 +261,7 @@ export class ProjectList extends Component {
         let changedData = [];
         for (const row of this.selectedRows) {
             let changedRow = {}
-            changedRow.project_state_value = this.state.changedStatus.value;
+            changedRow.project_state_value = this.state.changedStatus;
             changedRow.name = row.name;
             changedData.push(changedRow);
         }
@@ -360,7 +358,7 @@ export class ProjectList extends Component {
         let statusChangeResponse = []
         for (const row of this.selectedRows) {
             row.project_state = this.state.changedStatus.url
-            row.project_state_value = this.state.changedStatus.value;
+            row.project_state_value = this.state.changedStatus;
             let response = await ProjectService.updateProject(row.name, row)
             if(response.isUpdated) {
                 statusChangeResponse.push({
@@ -414,36 +412,34 @@ export class ProjectList extends Component {
 
    
 
+    prepareSaveProjectStatus  = (projectStatus) => {
+        this.setState({ changedStatus: projectStatus },() =>this.confirmStatusChange());
+    }
+
+    gotoAdd = () =>{
+        
+       this.props. history.push("/project/create") ;
+
+    }
     render() {
-        const footer = (
-            <div >
-                <Button label="Save" className="p-button-primary p-mr-2" icon="pi pi-check" disabled={!this.state.changedStatus} onClick={this.confirmStatusChange } data-testid="save-btn" />
-                <Button label="Cancel" className="act-btn-cancel mr-0" icon="pi pi-times" onClick={() => this.setState({showStatusUpdateDialog: false})} />
-            </div>
-        );
+
         return (
             <>
-                {/*<div className="p-grid">
-                    <div className="p-col-10 p-lg-10 p-md-10">
-                        <h2>Project - List </h2>
-                    </div>
-                    <div className="p-col-2 p-lg-2 p-md-2">
-                        <Link to={{ pathname: '/project/create'}} title="Add New Project" style={{float: "right"}}>
-                            <i className="fa fa-plus-square" style={{marginTop: "10px"}}></i>
-                        </Link>
-                    </div>
-                </div> */}
                 { (this.props.cycle) ?
                     <>
                     </>
                     :
-                    <PageHeader location={this.props.location} title={'Project - List'}
-                        actions={[{icon: 'fa fa-tag',title: this.state.userrole && this.state.userrole.userRolePermission.project && this.state.userrole.userRolePermission.project.edit?'Update Project(s) Status':"Don't have permission to Update Status", 
+                    <PageHeader location={this.props.location} title={'Project - List'} className="defaultpageHeader"
+                        actions={[{icon: 'pi pi-briefcase',title: this.state.userrole && this.state.userrole.userRolePermission.project && this.state.userrole.userRolePermission.project.edit?'Update Project(s) Status':"Don't have permission to Update Status", 
                         disabled: this.state.userrole && this.state.userrole.userRolePermission.project?!this.state.userrole.userRolePermission.project.edit:true,
-                        type: 'button', actOn: 'click', props: { callback: this.showStatusChangeDialog }},
-                        { icon: 'fa-plus-square', title: this.state.userrole && this.state.userrole.userRolePermission.project && this.state.userrole.userRolePermission.project.create?'Click to Add Project':"Don't have permission to add new Project", 
-                        disabled: this.state.userrole && this.state.userrole.userRolePermission.project?!this.state.userrole.userRolePermission.project.create:true, props: { pathname: '/project/create' }}]}
-                    />
+                        type: 'buttonv2', actOn: 'click', props: { callback: this.showStatusChangeDialog }},
+                        { 
+                             icon: 'pi-plus',
+                             type: 'buttonv2',
+                             title: this.state.userrole && this.state.userrole.userRolePermission.project && this.state.userrole.userRolePermission.project.create?'Click to Add Project':"Don't have permission to add new Project", 
+                             disabled: this.state.userrole && this.state.userrole.userRolePermission.project?!this.state.userrole.userRolePermission.project.create:true,
+                             actOn: 'click', props:{ callback:this.gotoAdd }}]}/> 
+                    
                 }
                 {this.state.isLoading ? <AppLoader /> : (this.state.isprocessed && this.state.projectlist.length > 0) ?
                     <div>
@@ -473,38 +469,19 @@ export class ProjectList extends Component {
                 }
                 {this.state.showStatusUpdateDialog &&
                 <div>
-                    <Dialog header={`Update Project(s) Status`}
-                        footer={footer} maximizable= {false}
-                        visible={this.state.showStatusUpdateDialog} maximized={false} position="center" style={{ width: '20vw' }}
-                        onHide={() => { this.setState({ showStatusUpdateDialog: false }) }}
-                        className="content_dlg">
-                            <div style={{ width: '100%' }}>
-                                <div className="p-fluid">
-                                    <div className="p-grid p-field" style={{ paddingLeft: '15px' }}>Select the status and click &apos;Save&apos; to update.</div>
-                                    {this.statusOptions.map((option) => {
-                                        return (
-                                            <div className="p-col-12" style={{width: "100%"}} key={option.value} >
-                                                <RadioButton
-                                                    inputId={option.value}
-                                                    name={option.value}
-                                                    value={option.value}
-                                                    onChange={() => this.setState({ changedStatus: option })}
-                                                    checked={this.state.changedStatus && this.state.changedStatus.value === option.value}
-                                                />
-                                                <label htmlFor={option.value} className='p-radiobutton-label' style={{textTransform: 'capitalize'}}>
-                                                    {option.value}
-                                                </label>
-                                            </div>
-                                        )
-                                    })}
-                                </div>
-                            </div>
-                    </Dialog>
+                    <ProjectStatusDialog 
+                        statusOptions= {this.statusOptions}
+                        visible={this.state.showStatusUpdateDialog}
+                        onHide={ () => { this.setState({ showStatusUpdateDialog: false }) }}
+                        onCancel={ () => { this.setState({ showStatusUpdateDialog: false }) }}
+                        onSave={ (projectStatus) => {this.prepareSaveProjectStatus(projectStatus)}} 
+                        /> 
+
                     <CustomDialog type="confirmation" visible={this.state.dialog && this.state.dialog.dialogVisible}
                         header={this.state.dialog && this.state.dialog.header} message={this.state.dialog && this.state.dialog.detail} actions={this.state.dialog && this.state.dialog.actions}
                         content={this.state.dialog && this.state.dialog.content} width={this.state.dialog && this.state.dialog.width} showIcon={this.state.dialog && this.state.dialog.showIcon}
                         onClose={this.closeDialog} onCancel={this.closeDialog}/>
-                    </div>
+                </div>
                 }
             </>
         )
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/projectStatusDialog.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/projectStatusDialog.js
new file mode 100644
index 00000000000..463d145060e
--- /dev/null
+++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Project/projectStatusDialog.js
@@ -0,0 +1,61 @@
+
+import { useState } from "react";
+import { RadioButton } from "primereact/radiobutton";
+import { Dialog } from 'primereact/dialog';
+import { Button  } from 'primereact/button';
+
+export default function ProjectStatusDialog(props) {
+    const {
+        visible,
+        onSave,
+        onHide,
+        onCancel,
+        statusOptions
+    } = props
+
+    const [projectStatus, setProjectStatus] = useState('');
+
+
+    const Save = () => {
+        if (!onSave) return;
+        onSave(projectStatus);
+
+    }
+
+    const footer = (
+        <div >
+            <Button label="Save" className="p-button-primary p-mr-2" icon="pi pi-check" disabled={projectStatus==''} onClick={Save} data-testid="save-btn" />
+            <Button label="Cancel" className="act-btn-cancel mr-0" icon="pi pi-times" onClick={onCancel} />
+        </div>
+    );
+    return (
+        <Dialog header={`Update Project(s) Status`}
+        footer={footer} maximizable= {false}
+        visible={visible} maximized={false} position="center" style={{ width: '20vw' }}
+        onHide={onHide}
+        className="content_dlg">
+            <div style={{ width: '100%' }}>
+                <div className="p-fluid">
+                    <div className="p-grid p-field" style={{ paddingLeft: '15px' }}>Select the status and click &apos;Save&apos; to update.</div>
+                    {statusOptions?.map((option) => {
+                        return (
+                            <div className="p-col-12 p-2 " style={{width: "100%"}} key={option.value} >
+                                <RadioButton
+                                    inputId={option.value}
+                                    name={option.value}
+                                    value={option.value}
+                                    onChange={(e) => setProjectStatus(e.value)} 
+                                    checked= {projectStatus === option.value}
+                                />
+                                <label htmlFor={option.value} className='p-radiobutton-label' style={{textTransform: 'capitalize'}}>
+                                    {option.value}
+                                </label>
+                            </div>
+                        )
+                    })}
+                </div>
+            </div>
+    </Dialog>
+    );
+}
+        
\ No newline at end of file
diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/project.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/project.service.js
index d4ce5c47a48..9b8f9e37fad 100644
--- a/SAS/TMSS/frontend/tmss_webapp/src/services/project.service.js
+++ b/SAS/TMSS/frontend/tmss_webapp/src/services/project.service.js
@@ -338,7 +338,12 @@ const ProjectService = {
         const response = await axios.get(`/api/project/${projectName}/friend`);
         return response.data;
       } catch (error) {
-        console.error('[project.services.getFriendsforProject]',error);
+        if (error?.response?.data?.indexOf("Keycloak admin API token could not be obtained")>0) {
+          console.info('The Friend list does not work. This is expected behavoir on Dev.',error);
+        } else
+        {
+          console.error('[project.services.getFriendsforProject]',error);
+        }
         return [];
       }
     },
-- 
GitLab