diff --git a/SAS/TMSS/frontend/tmss_webapp/src/App.js b/SAS/TMSS/frontend/tmss_webapp/src/App.js index 3abca18eb4682b9a8debe753161544e2b4d0c0ea..12ca8a5aa7118073ce961d010b690f1d54143a1a 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/App.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/App.js @@ -136,7 +136,7 @@ class App extends Component { 'layout-mobile-sidebar-active': this.state.mobileMenuActive }); const AppBreadCrumbWithRouter = withRouter(AppBreadcrumb); - console.log(this.props); + //console.log(this.props); return ( <React.Fragment> <div className="App"> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_viewtable.scss b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_viewtable.scss index 6f6a530c1bddbfe2a81a7115a73d7064dd4c37d8..c9d775b33c357d2acecddfd55b751bd1d62c9836 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_viewtable.scss +++ b/SAS/TMSS/frontend/tmss_webapp/src/layout/sass/_viewtable.scss @@ -187,5 +187,5 @@ body .p-paginator { text-align: right; position: relative; top: 2.5em; - margin-right: 1em; + margin-right: 0.05em; } \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js index 641ab1a84853bf87650bbc2637f096fff0cc1ea3..c18e28993f7923aaeb1d34d01042be6607f22a7f 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/SchedulingUnitList.js @@ -8,6 +8,10 @@ import _ from 'lodash'; import ScheduleService from '../../services/schedule.service'; import { Link } from 'react-router-dom'; import WorkflowService from '../../services/workflow.service'; +import { DataTable } from 'primereact/datatable'; +import { Column } from 'primereact/column'; +import { CustomDialog } from '../../layout/components/CustomDialog'; +import { Growl } from 'primereact/components/growl/Growl'; class SchedulingUnitList extends Component{ constructor(props){ @@ -115,8 +119,18 @@ class SchedulingUnitList extends Component{ "Number of SAPs in the target observation":"filter-input-50" }], defaultSortColumn: [{id: "Name", desc: false}], + dialog: {header: 'Confirm', detail: 'Do you want to create a Scheduling Unit Blueprint?'}, + //dialogVisible: false } - + this.selectedRows = []; + this.suDraftsList = []; // List of selected SU Drafts + this.suBlueprintList = []; // List of selected SU Blueprints + this.deleteableDraftWithBlueprint = []; // List of deleteable Scheduling Unit(s) + + this.checkAndDeleteSchedulingUnit = this.checkAndDeleteSchedulingUnit.bind(this); + this.deleteSchedulingUnit = this.deleteSchedulingUnit.bind(this); + this.getDialogContent = this.getDialogContent.bind(this); + this.closeDialog = this.closeDialog.bind(this); this.onRowSelection = this.onRowSelection.bind(this); this.reloadData = this.reloadData.bind(this); this.addTargetColumns = this.addTargetColumns.bind(this); @@ -265,7 +279,8 @@ class SchedulingUnitList extends Component{ blueP['template_description'] = suTemplate[blueP.requirements_template_id].description; blueP['station_group'] = this.getStationGroup(blueP).counts; blueP.project = project.name; - blueP.canSelect = false; + //TMSS-579 + blueP.canSelect = true; blueP.suSet = suSet.name; // blueP.links = ['Project']; // blueP.linksURL = { @@ -364,12 +379,130 @@ class SchedulingUnitList extends Component{ this.getSchedulingUnitList(); } + /** + * Check and delete the selected Scheduling Unit(s) + */ + checkAndDeleteSchedulingUnit() { + this.suDraftsList = []; + this.suBlueprintList = []; + this.deleteableDraftWithBlueprint = []; + let tmpTotalSUBList = []; + let hasInvalidSUD = false; + + if(this.selectedRows.length === 0) { + this.growl.show({severity: 'warn', summary: 'Warning', detail: 'Select Scheduling Unit Draft(s) to delete.'}); + } else { + //Filter SUB + this.suBlueprintList = _.filter(this.selectedRows, (schedulingUnit) => { return schedulingUnit.type.toLowerCase() === "blueprint" }); + //Filter SUD + if (this.suBlueprintList && this.suBlueprintList.length > 0) { + this.suDraftsList = _.difference(this.selectedRows, this.suBlueprintList); + } else { + this.suDraftsList = this.selectedRows; + } + //Find Deletable SU Drafts + if (this.suDraftsList && this.suDraftsList.length > 0) { + this.suDraftsList.map(sud => { + if (sud.scheduling_unit_blueprints_ids && sud.scheduling_unit_blueprints_ids.length === 0) { + this.deleteableDraftWithBlueprint.push(sud); + } else if (this.suBlueprintList && this.suBlueprintList.length > 0) { + let tmpSUBList = _.filter(this.suBlueprintList, (sub => { return sub.draft_id === sud.id})); + tmpTotalSUBList = (tmpSUBList && tmpSUBList.length > 0)?[...tmpTotalSUBList, ...tmpSUBList]: tmpSUBList; + if (sud.scheduling_unit_blueprints_ids && tmpSUBList && tmpSUBList.length === sud.scheduling_unit_blueprints_ids.length) { + this.deleteableDraftWithBlueprint.push(sud); + } else { + hasInvalidSUD = true; + this.deleteableDraftWithBlueprint = [...this.deleteableDraftWithBlueprint, ...tmpSUBList]; + } + } else { + hasInvalidSUD = true; + } + }); + } + // Find SUB which is not blongs to the selected SUD + if (this.suBlueprintList && this.suBlueprintList.length !== tmpTotalSUBList.length) { + this.deleteableDraftWithBlueprint = [...this.deleteableDraftWithBlueprint, ..._.difference(this.suBlueprintList, tmpTotalSUBList)]; + } + + if (this.deleteableDraftWithBlueprint && this.deleteableDraftWithBlueprint.length === 0 ) { + this.growl.show({severity: 'warn', summary: 'Warning', detail: 'Select valid Scheduling Unit Draft(s) to delete.'}); + } else { + let dialog = this.state.dialog; + dialog.type = "confirmation"; + dialog.header= "Delete Scheduling Unit(s)"; + if (hasInvalidSUD) { + dialog.detail = "Selected Scheduling Unit Draft(s) has Blueprint(s) and it can't be deleted until relevant Blueprint(s) are deleted, Do you want to delete the remaining selected Scheduling Unit(s)?"; + } else { + dialog.detail = "Do you want to delete the selected Scheduling Unit(s)?"; + } + + dialog.content = this.getDialogContent; + dialog.actions = [{id: 'yes', title: 'Yes', callback: this.deleteSchedulingUnit}, + {id: 'no', title: 'No', callback: this.closeDialog}]; + dialog.onSubmit = this.deleteSchedulingUnit; + dialog.width = '55vw'; + dialog.showIcon = true; + this.setState({dialog: dialog, dialogVisible: true}); + } + } + } + + /** + * Prepare Scheduling Unit(s) details to show on confirmation dialog + */ + getDialogContent() { + let selectedSchedulingUnits = []; + for(const su of this.deleteableDraftWithBlueprint) { + selectedSchedulingUnits.push({suId: su.id, suName: su.name, + suType: (su.type.toLowerCase() === 'draft' && su.scheduling_unit_blueprints_ids && su.scheduling_unit_blueprints_ids.length > 0) + ? su.type+' - ('+su.scheduling_unit_blueprints_ids.length+') Blueprint': su.type}); + } + return <> + <div > + <DataTable value={selectedSchedulingUnits} resizableColumns columnResizeMode="expand" className="card" style={{paddingLeft: '0em'}}> + <Column field="suId" header="Scheduling Id"></Column> + <Column field="suName" header="Scheduling Name"></Column> + <Column field="suType" header="Scheduling Type"></Column> + </DataTable> + </div> + </> + } + + /** + * Delete selected Scheduling Unit(s) + */ + deleteSchedulingUnit() { + this.suDraftsWithBlueprintList = []; + let hasError = false; + for(const schedulingUnit of this.deleteableDraftWithBlueprint) { + if( !ScheduleService.deleteSchedulingUnit(schedulingUnit.type, schedulingUnit.id)){ + hasError = true; + } + } + if(hasError){ + this.growl.show({severity: 'error', summary: 'error', detail: 'Error while deleting scheduling Unit(s)'}); + } else { + this.growl.show({severity: 'success', summary: 'Success', detail: 'Selected Scheduling Unit(s) deleted successfully'}); + } + this.selectedRows = []; + this.setState({dialogVisible: false}); + this.componentDidMount(); + } + + /** + * Callback function to close the dialog prompted. + */ + closeDialog() { + this.setState({dialogVisible: false}); + } + render(){ if (this.state.isLoading) { return <AppLoader/> } return( <> + <Growl ref={(el) => this.growl = el} /> { /* * Call View table to show table data, the parameters are, @@ -381,7 +514,18 @@ class SchedulingUnitList extends Component{ paths - specify the path for navigation - Table will set "id" value for each row in action button */} - + <div className="p-field p-grid delete-option"> + <div > + <span className="p-float-label"> + {this.state.scheduleunit && this.state.scheduleunit.length > 0 && + <a href="#" onClick={this.checkAndDeleteSchedulingUnit} title="Delete selected Scheduling Unit(s)"> + <i class="fa fa-trash" aria-hidden="true" ></i> + </a> + } + </span> + </div> + </div> + { (this.state.scheduleunit && this.state.scheduleunit.length>0)? <ViewTable data={this.state.scheduleunit} @@ -398,8 +542,12 @@ class SchedulingUnitList extends Component{ allowRowSelection={this.props.allowRowSelection} onRowSelection = {this.onRowSelection} /> - :<div>No scheduling unit found </div> + :<div>No scheduling unit found</div> } + <CustomDialog type="confirmation" visible={this.state.dialogVisible} + header={this.state.dialog.header} message={this.state.dialog.detail} actions={this.state.dialog.actions} + content={this.state.dialog.content} width={this.state.dialog.width} showIcon={this.state.dialog.showIcon} + onClose={this.closeDialog} onCancel={this.closeDialog} onSubmit={this.state.dialog.onSubmit}/> </> ) } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js index 15ef8f5477bf51e4456fa32ef3510107b27c320b..4b688388b25ec0ba240829926b6bf69ff81a5bf1 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js @@ -131,7 +131,8 @@ class ViewSchedulingUnit extends Component{ }], stationGroup: [], dialog: {header: 'Confirm', detail: 'Do you want to create a Scheduling Unit Blueprint?'}, - dialogVisible: false + dialogVisible: false, + actions: [] } this.actions = []; this.stations = []; @@ -141,12 +142,14 @@ class ViewSchedulingUnit extends Component{ this.confirmDeleteTasks = this.confirmDeleteTasks.bind(this); this.onRowSelection = this.onRowSelection.bind(this); this.deleteTasks = this.deleteTasks.bind(this); - this.getDialogContent = this.getDialogContent.bind(this); + this.deleteSchedulingUnit = this.deleteSchedulingUnit.bind(this); + this.getTaskDialogContent = this.getTaskDialogContent.bind(this); + this.getSUDialogContent = this.getSUDialogContent.bind(this); this.checkAndCreateBlueprint = this.checkAndCreateBlueprint.bind(this); this.createBlueprintTree = this.createBlueprintTree.bind(this); this.closeDialog = this.closeDialog.bind(this); this.showTaskRelationDialog = this.showTaskRelationDialog.bind(this); - + this.showDeleteSUConfirmation = this.showDeleteSUConfirmation.bind(this); } componentDidUpdate(prevProps, prevState) { @@ -180,8 +183,8 @@ class ViewSchedulingUnit extends Component{ ); }; - getSchedulingUnitDetails(schedule_type, schedule_id) { - ScheduleService.getSchedulingUnitExtended(schedule_type, schedule_id) + async getSchedulingUnitDetails(schedule_type, schedule_id) { + await ScheduleService.getSchedulingUnitExtended(schedule_type, schedule_id) .then(async(schedulingUnit) =>{ if (schedulingUnit) { ScheduleService.getSchedulingConstraintTemplates().then((response) => { @@ -232,9 +235,16 @@ class ViewSchedulingUnit extends Component{ }); } }); - this.actions = [ + this.actions =[]; + if(schedule_type === 'blueprint' || (schedule_type === 'draft' && this.state.scheduleunit.scheduling_unit_blueprints_ids + && this.state.scheduleunit.scheduling_unit_blueprints_ids.length === 0)) { + this.actions.push({icon: 'fa fa-trash',title:'Delete Scheduling Unit', type: 'button', actOn: 'click', props:{ callback: this.showDeleteSUConfirmation}}); + } + + this.actions.push( {icon: 'fa-window-close',title:'Click to Close Scheduling Unit View', link: this.props.history.goBack} - ]; + ); + if (this.props.match.params.type === 'draft') { this.actions.unshift({icon:'fa-file-import', title: 'Data Products To Ingest', type:'button', actOn:'click', props : { callback: this.showTaskRelationDialog} @@ -249,8 +259,8 @@ class ViewSchedulingUnit extends Component{ this.actions.unshift({icon: 'fa-sitemap',title :'View Workflow',props :{pathname:`/schedulingunit/${this.props.match.params.id}/workflow`}}); this.actions.unshift({icon: 'fa-lock', title: 'Cannot edit blueprint'}); } - - + + this.setState({actions: this.actions}); } /** @@ -348,7 +358,7 @@ class ViewSchedulingUnit extends Component{ if(type === 'draft') return ScheduleService.getTasksBySchedulingUnit(scheduleunit.id, true, true, true); else - return ScheduleService.getTaskBPWithSubtaskTemplateOfSU(scheduleunit); + return ScheduleService.getTaskBPWithSubtaskTemplateOfSU(scheduleunit); } getScheduleUnit(type, id){ @@ -404,13 +414,13 @@ class ViewSchedulingUnit extends Component{ */ confirmDeleteTasks() { if(this.selectedRows.length === 0) { - this.growl.show({severity: 'warn', summary: 'Warning', detail: 'Select Task / Blueprints to delete.'}); + this.growl.show({severity: 'warn', summary: 'Warning', detail: 'Select Task to delete.'}); } else { let dialog = this.state.dialog; dialog.type = "confirmation"; dialog.header= "Delete Task(s)"; dialog.detail = "Do you want to delete the selected Task(s)?"; - dialog.content = this.getDialogContent; + dialog.content = this.getTaskDialogContent; dialog.actions = [{id: 'yes', title: 'Yes', callback: this.deleteTasks}, {id: 'no', title: 'No', callback: this.closeDialog}]; dialog.onSubmit = this.deleteTasks; @@ -420,39 +430,95 @@ class ViewSchedulingUnit extends Component{ } } + showDeleteSUConfirmation() { + let dialog = this.state.dialog; + dialog.type = "confirmation"; + dialog.header= "Delete Scheduling Unit"; + dialog.detail = "Do you want to delete this Scheduling Unit?"; + dialog.content = this.getSUDialogContent; + dialog.actions = [{id: 'yes', title: 'Yes', callback: this.deleteSchedulingUnit}, + {id: 'no', title: 'No', callback: this.closeDialog}]; + dialog.onSubmit = this.deleteSchedulingUnit; + dialog.width = '55vw'; + dialog.showIcon = true; + this.setState({dialog: dialog, dialogVisible: true}); + } + /** * Prepare Task(s) details to show on confirmation dialog */ - getDialogContent() { + getTaskDialogContent() { let selectedTasks = []; - for(const task of this.selectedRows) { - selectedTasks.push({id:task.id, suId: this.state.scheduleunit.id, suName: this.state.scheduleunit.name, taskId: task.id, controlId: task.subTaskID, taskName: task.name, status: task.status}); - } - return <> - <DataTable value={selectedTasks} resizableColumns columnResizeMode="expand" className="card"> - <Column field="suId" header="SU Id"></Column> - <Column field="suName" header="SU Name"></Column> - <Column field="taskId" header="Task Id"></Column> - <Column field="controlId" header="Control Id"></Column> - <Column field="taskName" header="Task Name"></Column> - <Column field="status" header="Status"></Column> - </DataTable> - </> + for(const obj of this.selectedRows) { + selectedTasks.push({id:obj.id, suId: this.state.scheduleunit.id, suName: this.state.scheduleunit.name, + taskId: obj.id, controlId: obj.subTaskID, taskName: obj.name, status: obj.status}); + } + return <> + <DataTable value={selectedTasks} resizableColumns columnResizeMode="expand" className="card" style={{paddingLeft: '0em'}}> + <Column field="suId" header="Scheduling Id"></Column> + <Column field="suName" header="Scheduling Name"></Column> + <Column field="taskId" header="Task Id"></Column> + <Column field="controlId" header="Control Id"></Column> + <Column field="taskName" header="Task Name"></Column> + <Column field="status" header="Status"></Column> + </DataTable> + </> } /** - * Delete Task + * Prepare Scheduling Unit details to show on confirmation dialog */ - deleteTasks() { + getSUDialogContent() { + let selectedTasks = [{suId: this.state.scheduleunit.id, suName: this.state.scheduleunit.name, suType: (this.state.scheduleunit.draft)?'Blueprint': 'Draft'}]; + return <> + <DataTable value={selectedTasks} resizableColumns columnResizeMode="expand" className="card" style={{paddingLeft: '0em'}}> + <Column field="suId" header="Scheduling Id"></Column> + <Column field="suName" header="Scheduling Name"></Column> + <Column field="suType" header="Scheduling Type"></Column> + </DataTable> + </> + } + + /** + * Delete Task(s) + */ + async deleteTasks() { + let hasError = false; for(const task of this.selectedRows) { - TaskService.deleteTask(task.tasktype, task.id); + if(!await TaskService.deleteTask(task.tasktype, task.id)) { + hasError = true; + } + } + if(hasError){ + this.growl.show({severity: 'error', summary: 'error', detail: 'Error while deleting Task(s)'}); + this.setState({dialogVisible: false}); + } else { + this.selectedRows = []; + this.setState({dialogVisible: false}); + this.componentDidMount(); + this.growl.show({severity: 'success', summary: 'Success', detail: 'Task(s) deleted successfully'}); } - this.selectedRows = []; - this.setState({dialogVisible: false}); - this.componentDidMount(); } - + /** + * Delete Scheduling Unit + */ + async deleteSchedulingUnit() { + let hasError = false; + if(!await ScheduleService.deleteSchedulingUnit(this.state.scheduleunitType, this.state.scheduleunit.id)) { + hasError = true; + } + if(hasError){ + this.growl.show({severity: 'error', summary: 'error', detail: 'Error while deleting scheduling Unit'}); + this.setState({dialogVisible: false}); + } else { + this.selectedRows = []; + this.growl.show({severity: 'success', summary: 'Success', detail: 'Scheduling Unit is deleted successfully'}); + this.setState({dialogVisible: false, redirect: '/schedulingunit'}); + } + + } + render(){ if (this.state.redirect) { return <Redirect to={ {pathname: this.state.redirect} }></Redirect> @@ -461,7 +527,7 @@ class ViewSchedulingUnit extends Component{ <> <Growl ref={(el) => this.growl = el} /> <PageHeader location={this.props.location} title={'Scheduling Unit - Details'} - actions={this.actions}/> + actions={this.state.actions}/> { this.state.isLoading ? <AppLoader/> :this.state.scheduleunit && <> <div className="main-content"> diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js index 2c2a6d30bf63b6c7702062c0b6de418667c0eab2..8baf1ef6847c7e02493d664c00e74658f0a211fb 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/index.js @@ -1,8 +1,7 @@ import React, {Component} from 'react'; - import { TieredMenu } from 'primereact/tieredmenu'; import { Growl } from 'primereact/components/growl/Growl'; - +import _ from 'lodash'; import SchedulingUnitList from './SchedulingUnitList'; import PageHeader from '../../layout/components/PageHeader'; import SUBCreator from './sub.create'; @@ -16,15 +15,24 @@ export class Scheduling extends Component { isLoading:false, redirect: '', dialog: {header: 'Confirm', detail: 'Do you want to create blueprints for the selected drafts?'}, + dialogVisible: false }; this.optionsMenu = React.createRef(); this.menuOptions = [ {label:'Add Scheduling Set', icon: "fa fa-", command: () => {this.selectOptionMenu('Add-SU-Set') }}]; - this.createSUB = this.createSUB.bind(this); + this.checkAndCreateSUB = this.checkAndCreateSUB.bind(this); this.showOptionMenu = this.showOptionMenu.bind(this); this.selectOptionMenu = this.selectOptionMenu.bind(this); + this.closeDialog = this.closeDialog.bind(this); } + /** + * Callback function to close the dialog prompted. + */ + closeDialog() { + this.setState({dialogVisible: false}); + } + showOptionMenu(event) { this.optionsMenu.toggle(event); } @@ -44,10 +52,30 @@ export class Scheduling extends Component { /** * Function to call the SUBCreator component's function to check and create SUBs */ - createSUB() { - this.subCreator.checkAndCreateBlueprint(this.suList); + checkAndCreateSUB() { + if (this.suList.selectedRows.length > 0) { + const suBlueprintList = _.filter(this.suList.selectedRows, (schedulingUnit) => { return schedulingUnit.type.toLowerCase() === "blueprint"}); + const suDraftsList = _.filter(this.suList.selectedRows, (schedulingUnit) => { return schedulingUnit.type.toLowerCase() === "draft"}); + const hasDrafts = suDraftsList.length > 0 ? true : false; + const hasBlueprint = suBlueprintList.length > 0 ? true : false; + if (hasBlueprint && !hasDrafts) { + this.growl.show({severity: 'warn', summary: 'Warning', detail: 'Select Draft(s) to create Blueprint'}); + } else if (hasBlueprint && hasDrafts) { + this.subCreator.checkBlueprint(this.suList, true); + } else { + //this.createSUB(); + this.subCreator.checkBlueprint(this.suList, false); + } + } else { + this.growl.show({severity: 'warn', summary: 'Warning', detail: 'Select Draft(s) to create Blueprint'}); + } } + //? + /*createSUB() { + this.subCreator.checkAndCreateBlueprint(this.suList); + }*/ + render() { return ( <> @@ -56,7 +84,7 @@ export class Scheduling extends Component { <PageHeader location={this.props.location} title={'Scheduling Unit - List'} actions={[ {icon:'fa-stamp', title: 'Create Blueprint', type:'button', - actOn:'click', props : { callback: this.createSUB}}, + actOn:'click', props : { callback: this.checkAndCreateSUB}}, {icon: 'fa fa-plus-square', title: 'Add New Scheduling Unit', props: {pathname: '/schedulingunit/create'}}, diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/sub.create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/sub.create.js index 0e183e8e5e58490243facef8ba648a96267f8140..96b210f68973547264c4dcb028b4fffbe45f5b14 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/sub.create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/sub.create.js @@ -15,7 +15,10 @@ export default class SUBCreator extends Component { dialog: {header: 'Confirm', detail: 'Do you want to create blueprints for the selected drafts?'}, }; this.suList = []; + this.bluePrintSelected = false; + this.checkAndCreateBlueprint = this.checkAndCreateBlueprint.bind(this); + this.checkBlueprint = this.checkBlueprint.bind(this); this.createBlueprintTree = this.createBlueprintTree.bind(this); this.createBlueprintTreeNewOnly = this.createBlueprintTreeNewOnly.bind(this); this.warningContent = this.warningContent.bind(this); @@ -70,16 +73,34 @@ export default class SUBCreator extends Component { ); } + checkBlueprint(suList, hasBlueprint) { + if (hasBlueprint) { + this.bluePrintSelected = true; + } else { + this.bluePrintSelected = false; + } + this.checkAndCreateBlueprint(suList); + } + /** * Function to check if blueprint already exist for the selected Scheduling Units and propmt contfirmation dialog. * When confirmed will create new blueprints for the selected Scheduling Units. */ checkAndCreateBlueprint(suList) { this.suList = suList; + if(this.bluePrintSelected) { + this.suList.selectedRows = _.filter(this.suList.selectedRows, (schedulingUnit) => { return schedulingUnit.type.toLowerCase() === "draft"}); + } + if (suList.selectedRows && suList.selectedRows.length>0) { let dialog = this.state.dialog; + if (this.bluePrintSelected) { + dialog.detail = "Blueprint also selected in the list, Do you want to ignore the blueprints and create blueprint for selected drafts? And below the selected draft(s)"; + } else { + dialog.detail = "Do you want to create blueprints for the selected drafts?"; + } dialog.content = this.warningContent; - const schedulingUnitsWithBlueprint = _.filter(suList.selectedRows, schedulingUnit=> { return schedulingUnit.scheduling_unit_blueprints.length>0}); + const schedulingUnitsWithBlueprint = _.filter(suList.selectedRows, schedulingUnit=> { return schedulingUnit.scheduling_unit_blueprints && schedulingUnit.scheduling_unit_blueprints.length>0}); dialog.actions = [ {id:"yes", title: 'Yes', callback: this.createBlueprintTree}, {id:"no", title: 'No', callback: this.closeDialog} ] /* Add this action only when both new and old drafts are selected */ diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js index 92bcc89e59711eda10bc74d967f03d87a2aa2ad9..63f6dde33c60e50ec9b2b735afa0003bec366812 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Task/view.js @@ -3,7 +3,7 @@ import { Link, Redirect } from 'react-router-dom' import moment from 'moment'; import _ from 'lodash'; import Jeditor from '../../components/JSONEditor/JEditor'; - +import { Growl } from 'primereact/components/growl/Growl'; import TaskService from '../../services/task.service'; import { Chips } from 'primereact/chips'; import { Dialog } from 'primereact/dialog'; @@ -149,9 +149,9 @@ export class TaskView extends Component { let selectedTasks = [{suId: this.state.schedulingUnit.id, suName: this.state.schedulingUnit.name, taskId: this.state.task.id, controlId: this.state.task.subTaskID, taskName: this.state.task.name, status: this.state.task.status}]; return <> - <DataTable value={selectedTasks} resizableColumns columnResizeMode="expand" className="card"> - <Column field="suId" header="SU Id"></Column> - <Column field="suName" header="SU Name"></Column> + <DataTable value={selectedTasks} resizableColumns columnResizeMode="expand" className="card" style={{paddingLeft: '0em'}}> + <Column field="suId" header="Scheduling Id"></Column> + <Column field="suName" header="Scheduling Name"></Column> <Column field="taskId" header="Task Id"></Column> <Column field="controlId" header="Control Id"></Column> <Column field="taskName" header="Task Name"></Column> @@ -168,9 +168,18 @@ export class TaskView extends Component { * Delete Task */ async deleteTask() { - await TaskService.deleteTask(this.state.taskType, this.state.taskId); - this.setState({confirmDialogVisible: false}); - this.props.history.goBack(); + let hasError = false; + if(!await TaskService.deleteTask(this.state.taskType, this.state.taskId)){ + hasError = true; + } + if(hasError){ + this.growl.show({severity: 'error', summary: 'error', detail: 'Error while deleting Task'}); + this.setState({confirmDialogVisible: false}); + } else { + this.growl.show({severity: 'success', summary: 'Success', detail: 'Task deleted successfully'}); + this.setState({confirmDialogVisible: false}); + this.props.history.goBack(); + } } render() { @@ -242,6 +251,7 @@ export class TaskView extends Component { } </div> </div> */} + <Growl ref={(el) => this.growl = el} /> <PageHeader location={this.props.location} title={'Task - View'} actions={actions}/> { this.state.isLoading? <AppLoader /> : this.state.task && diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js index 072ff6ca0dcbf92f0914152c772b9ab3352e2969..aee1b1d5def371bf9c1b7efda59a041a1e165fa8 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js @@ -658,7 +658,22 @@ const ScheduleService = { console.log(error.response.data); return error.response.data; } - } + }, + /** + * Delete Scheduling Unit based on type + * @param {*} type + * @param {*} id + */ + deleteSchedulingUnit: async function(type, id) { + try { + const url = type.toLowerCase() === 'blueprint'? `/api/scheduling_unit_blueprint/${id}`: `/api/scheduling_unit_draft/${id}`; + await axios.delete(url); + return true; + } catch(error) { + console.error(error); + return false; + } + } } export default ScheduleService; \ No newline at end of file diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js index 54f6ccf57fb464ac8fc1c327a5ba263ebaaf142d..3b99780c7ae8fe731e2311362665cfe273c61d8b 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/services/task.service.js @@ -234,10 +234,11 @@ const TaskService = { deleteTask: async function(type, id) { try { const url = type.toLowerCase() === 'blueprint'? `/api/task_blueprint/${id}`: `/api/task_draft/${id}`; - const response = await axios.delete(url); - return response; + await axios.delete(url); + return true; } catch(error) { console.error(error); + return false; } } }