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 c03618617e060feefc148d95e95075e6079a078c..5bd338d371491e9d414c05a521374235f113afc5 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js @@ -24,11 +24,15 @@ import Schedulingtaskrelation from './Scheduling.task.relation'; import UnitConverter from '../../utils/unit.converter'; import TaskService from '../../services/task.service'; import UIConstants from '../../utils/ui.constants'; +import UtilService from '../../services/util.service'; -class ViewSchedulingUnit extends Component{ +class ViewSchedulingUnit extends Component { + lsKeySortColumn = 'SortDataViewSchedulingUnit'; + defaultSortColumn = []; ignoreSorting = ['status logs']; - constructor(props){ - super(props) + constructor(props) { + super(props); + this.setToggleBySorting(); this.state = { scheduleunit: null, schedule_unit_task: [], @@ -42,103 +46,103 @@ class ViewSchedulingUnit extends Component{ missingStationFieldsErrors: [], columnOrders: [ "Status Logs", - "Status", - "Type", - "ID", - "Control ID", - "Name", - "Description", - "Start Time", - "End Time", - "Duration (HH:mm:ss)", - "Relative Start Time (HH:mm:ss)", - "Relative End Time (HH:mm:ss)", - "#Dataproducts", - "size", - "dataSizeOnDisk", - "subtaskContent", - "tags", - "blueprint_draft", - "url", - "Cancelled", - "Created at", - "Updated at" - ], - defaultcolumns: [ { + "Status", + "Type", + "ID", + "Control ID", + "Name", + "Description", + "Start Time", + "End Time", + "Duration (HH:mm:ss)", + "Relative Start Time (HH:mm:ss)", + "Relative End Time (HH:mm:ss)", + "#Dataproducts", + "size", + "dataSizeOnDisk", + "subtaskContent", + "tags", + "blueprint_draft", + "url", + "Cancelled", + "Created at", + "Updated at" + ], + defaultcolumns: [{ status_logs: "Status Logs", - status:{ - name:"Status", - filter: "select" + status: { + name: "Status", + filter: "select" }, - tasktype:{ - name:"Type", - filter:"select" + tasktype: { + name: "Type", + filter: "select" }, id: "ID", subTaskID: 'Control ID', - name:"Name", - description:"Description", - start_time:{ - name:"Start Time", + name: "Name", + description: "Description", + start_time: { + name: "Start Time", filter: "date", - format:UIConstants.CALENDAR_DATETIME_FORMAT + format: UIConstants.CALENDAR_DATETIME_FORMAT }, - stop_time:{ - name:"End Time", + stop_time: { + name: "End Time", filter: "date", - format:UIConstants.CALENDAR_DATETIME_FORMAT + format: UIConstants.CALENDAR_DATETIME_FORMAT }, - duration:{ - name:"Duration (HH:mm:ss)", - format:UIConstants.CALENDAR_TIME_FORMAT + duration: { + name: "Duration (HH:mm:ss)", + format: UIConstants.CALENDAR_TIME_FORMAT }, - relative_start_time:"Relative Start Time (HH:mm:ss)", - relative_stop_time:"Relative End Time (HH:mm:ss)", + relative_start_time: "Relative Start Time (HH:mm:ss)", + relative_stop_time: "Relative End Time (HH:mm:ss)", noOfOutputProducts: "#Dataproducts", - do_cancel:{ + do_cancel: { name: "Cancelled", filter: "switch" }, }], - optionalcolumns: [{ + optionalcolumns: [{ size: "Data size", dataSizeOnDisk: "Data size on Disk", subtaskContent: "Subtask Content", - tags:"Tags", - blueprint_draft:"BluePrint / Task Draft link", - url:"API URL", - created_at:{ + tags: "Tags", + blueprint_draft: "BluePrint / Task Draft link", + url: "API URL", + created_at: { name: "Created at", - filter:"date", - format:UIConstants.CALENDAR_DATETIME_FORMAT + filter: "date", + format: UIConstants.CALENDAR_DATETIME_FORMAT }, - updated_at:{ + updated_at: { name: "Updated at", filter: "date", - format:UIConstants.CALENDAR_DATETIME_FORMAT + format: UIConstants.CALENDAR_DATETIME_FORMAT }, - actionpath:"actionpath" + actionpath: "actionpath" }], columnclassname: [{ "Status Logs": "filter-input-0", - "Type":"filter-input-75", - "ID":"filter-input-50", - "Control ID":"filter-input-75", - "Cancelled":"filter-input-50", - "Duration (HH:mm:ss)":"filter-input-75", - "Template ID":"filter-input-50", + "Type": "filter-input-75", + "ID": "filter-input-50", + "Control ID": "filter-input-75", + "Cancelled": "filter-input-50", + "Duration (HH:mm:ss)": "filter-input-75", + "Template ID": "filter-input-50", // "BluePrint / Task Draft link": "filter-input-100", "Relative Start Time (HH:mm:ss)": "filter-input-75", "Relative End Time (HH:mm:ss)": "filter-input-75", - "Status":"filter-input-100", - "#Dataproducts":"filter-input-75", - "Data size":"filter-input-50", - "Data size on Disk":"filter-input-50", - "Subtask Content":"filter-input-75", - "BluePrint / Task Draft link":"filter-input-50", + "Status": "filter-input-100", + "#Dataproducts": "filter-input-75", + "Data size": "filter-input-50", + "Data size on Disk": "filter-input-50", + "Subtask Content": "filter-input-75", + "BluePrint / Task Draft link": "filter-input-50", }], stationGroup: [], - dialog: {header: 'Confirm', detail: 'Do you want to create a Scheduling Unit Blueprint?'}, + dialog: { header: 'Confirm', detail: 'Do you want to create a Scheduling Unit Blueprint?' }, dialogVisible: false, actions: [] } @@ -163,29 +167,48 @@ class ViewSchedulingUnit extends Component{ componentDidUpdate(prevProps, prevState) { if (this.state.scheduleunit && this.props.match.params && (this.state.scheduleunitId !== this.props.match.params.id || - this.state.scheduleunitType !== this.props.match.params.type)) { + this.state.scheduleunitType !== this.props.match.params.type)) { this.getSchedulingUnitDetails(this.props.match.params.type, this.props.match.params.id); - } + } } - + showTaskRelationDialog() { - this.setState({ showTaskRelationDialog: !this.state.showTaskRelationDialog}); + this.setState({ showTaskRelationDialog: !this.state.showTaskRelationDialog }); } - async componentDidMount(){ + async componentDidMount() { + this.setToggleBySorting(); let schedule_id = this.props.match.params.id; let schedule_type = this.props.match.params.type; if (schedule_type && schedule_id) { this.stations = await ScheduleService.getStationGroup(); - this.setState({stationOptions: this.stations}); + this.setState({ stationOptions: this.stations }); this.subtaskTemplates = await TaskService.getSubtaskTemplates(); this.getSchedulingUnitDetails(schedule_type, schedule_id); - } + } } - subtaskComponent = (task)=> { + toggleBySorting = (sortData) => { + UtilService.localStore({ type: 'set', key: this.lsKeySortColumn, value: sortData }); + } + + setToggleBySorting() { + let sortData = UtilService.localStore({ type: 'get', key: this.lsKeySortColumn }); + if (sortData) { + if (Object.prototype.toString.call(sortData) === '[object Array]') { + this.defaultSortColumn = sortData; + } + else { + this.defaultSortColumn = [{ ...sortData }]; + } + } + this.defaultSortColumn = this.defaultSortColumn || []; + UtilService.localStore({ type: 'set', key: this.lsKeySortColumn, value: [...this.defaultSortColumn] }); + } + + subtaskComponent = (task) => { return ( - <button className="p-link" onClick={(e) => {this.setState({showStatusLogs: true, task: task})}}> + <button className="p-link" onClick={(e) => { this.setState({ showStatusLogs: true, task: task }) }}> <i className="fa fa-history"></i> </button> ); @@ -193,27 +216,27 @@ class ViewSchedulingUnit extends Component{ getSchedulingUnitDetails(schedule_type, schedule_id) { ScheduleService.getSchedulingUnitExtended(schedule_type, schedule_id) - .then(async(schedulingUnit) =>{ + .then(async (schedulingUnit) => { if (schedulingUnit) { ScheduleService.getSchedulingConstraintTemplate(schedulingUnit.scheduling_constraints_template_id) .then((template) => { - this.setState({constraintTemplate: template}) - }); + this.setState({ constraintTemplate: template }) + }); if (schedulingUnit.draft_id) { await ScheduleService.getSchedulingUnitDraftById(schedulingUnit.draft_id).then((response) => { schedulingUnit['observation_strategy_template_id'] = response.observation_strategy_template_id; }); } - let tasks = schedulingUnit.task_drafts?(await this.getFormattedTaskDrafts(schedulingUnit)):this.getFormattedTaskBlueprints(schedulingUnit); - let ingestGroup = tasks.map(task => ({name: task.name, canIngest: task.canIngest, type_value: task.type_value, id: task.id })); + let tasks = schedulingUnit.task_drafts ? (await this.getFormattedTaskDrafts(schedulingUnit)) : this.getFormattedTaskBlueprints(schedulingUnit); + let ingestGroup = tasks.map(task => ({ name: task.name, canIngest: task.canIngest, type_value: task.type_value, id: task.id })); ingestGroup = _.groupBy(_.filter(ingestGroup, 'type_value'), 'type_value'); await Promise.all(tasks.map(async task => { - task.status_logs = task.tasktype === "Blueprint"?this.subtaskComponent(task):""; + task.status_logs = task.tasktype === "Blueprint" ? this.subtaskComponent(task) : ""; //Displaying SubTask ID of the 'control' Task - const subTaskIds = task.subTasks?task.subTasks.filter(sTask => sTask.subTaskTemplate.name.indexOf('control') >= 0):[]; + const subTaskIds = task.subTasks ? task.subTasks.filter(sTask => sTask.subTaskTemplate.name.indexOf('control') >= 0) : []; const promise = []; subTaskIds.map(subTask => promise.push(ScheduleService.getSubtaskOutputDataproduct(subTask.id))); - const dataProducts = promise.length > 0? await Promise.all(promise):[]; + const dataProducts = promise.length > 0 ? await Promise.all(promise) : []; task.dataProducts = []; task.size = 0; task.dataSizeOnDisk = 0; @@ -222,111 +245,117 @@ class ViewSchedulingUnit extends Component{ // task.start_time = moment(task.start_time).format(UIConstants.CALENDAR_DATETIME_FORMAT); // task.created_at = moment(task.created_at).format(UIConstants.CALENDAR_DATETIME_FORMAT); // task.updated_at = moment(task.updated_at).format(UIConstants.CALENDAR_DATETIME_FORMAT); - task.canSelect = task.tasktype.toLowerCase() === 'blueprint' ? true:(task.tasktype.toLowerCase() === 'draft' && task.blueprint_draft.length === 0)?true:false; + task.canSelect = task.tasktype.toLowerCase() === 'blueprint' ? true : (task.tasktype.toLowerCase() === 'draft' && task.blueprint_draft.length === 0) ? true : false; if (dataProducts.length && dataProducts[0].length) { task.dataProducts = dataProducts[0]; task.noOfOutputProducts = dataProducts[0].length; task.size = _.sumBy(dataProducts[0], 'size'); - task.dataSizeOnDisk = _.sumBy(dataProducts[0], function(product) { return product.deletedSince?0:product.size}); + task.dataSizeOnDisk = _.sumBy(dataProducts[0], function (product) { return product.deletedSince ? 0 : product.size }); task.size = UnitConverter.getUIResourceUnit('bytes', (task.size)); task.dataSizeOnDisk = UnitConverter.getUIResourceUnit('bytes', (task.dataSizeOnDisk)); } - task.subTaskID = subTaskIds.length ? subTaskIds[0].id : ''; + task.subTaskID = subTaskIds.length ? subTaskIds[0].id : ''; return task; })); - - const targetObservation = _.find(tasks, (task)=> {return task.template.type_value==='observation' && task.tasktype.toLowerCase()===schedule_type && task.specifications_doc.station_groups}); + + const targetObservation = _.find(tasks, (task) => { return task.template.type_value === 'observation' && task.tasktype.toLowerCase() === schedule_type && task.specifications_doc.station_groups }); this.setState({ scheduleunitId: schedule_id, - scheduleunit : schedulingUnit, + scheduleunit: schedulingUnit, scheduleunitType: schedule_type, - schedule_unit_task : tasks, + schedule_unit_task: tasks, isLoading: false, - stationGroup: targetObservation?targetObservation.specifications_doc.station_groups:[], + stationGroup: targetObservation ? targetObservation.specifications_doc.station_groups : [], redirect: null, dialogVisible: false, - ingestGroup}); + ingestGroup + }); this.selectedRows = []; // Add Action menu this.getActionMenu(schedule_type); - } else { + } else { this.setState({ isLoading: false, redirect: "/not-found" }); } }); - } + } /** * Get action menus for page header */ getActionMenu(schedule_type) { - this.actions =[]; + this.actions = []; let canDelete = (this.state.scheduleunit && - (!this.state.scheduleunit.scheduling_unit_blueprints_ids || this.state.scheduleunit.scheduling_unit_blueprints_ids.length === 0)); - this.actions.push({icon: 'fa fa-trash',title:!canDelete? 'Cannot delete Draft when Blueprint exists':'Scheduling Unit', - type: 'button', disabled: !canDelete, 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} ); + (!this.state.scheduleunit.scheduling_unit_blueprints_ids || this.state.scheduleunit.scheduling_unit_blueprints_ids.length === 0)); + this.actions.push({ + icon: 'fa fa-trash', title: !canDelete ? 'Cannot delete Draft when Blueprint exists' : 'Scheduling Unit', + type: 'button', disabled: !canDelete, 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} + this.actions.unshift({ + icon: 'fa-file-import', title: 'Data Products To Ingest', type: 'button', + actOn: 'click', props: { callback: this.showTaskRelationDialog } }); - this.actions.unshift({icon: 'fa-edit', title: 'Click to edit', props : { pathname:`/schedulingunit/edit/${ this.props.match.params.id}`} + this.actions.unshift({ + icon: 'fa-edit', title: 'Click to edit', props: { pathname: `/schedulingunit/edit/${this.props.match.params.id}` } }); - this.actions.unshift({icon:'fa-stamp', title: 'Create Blueprint', type:'button', - actOn:'click', props : { callback: this.checkAndCreateBlueprint}, + this.actions.unshift({ + icon: 'fa-stamp', title: 'Create Blueprint', type: 'button', + actOn: 'click', props: { callback: this.checkAndCreateBlueprint }, }); } else { - 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.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}); + this.setState({ actions: this.actions }); } - + /** * Formatting the task_drafts and task_blueprints in draft view to pass to the ViewTable component * @param {Object} schedulingUnit - scheduling_unit_draft object from extended API call loaded with tasks(draft & blueprint) along with their template and subtasks */ async getFormattedTaskDrafts(schedulingUnit) { - let scheduletasklist=[]; + let scheduletasklist = []; // Common keys for Task and Blueprint - let commonkeys = ['id','created_at','description','name','tags','updated_at','url','do_cancel','relative_start_time','relative_stop_time','start_time','stop_time','duration','status']; - for(const task of schedulingUnit.task_drafts){ + let commonkeys = ['id', 'created_at', 'description', 'name', 'tags', 'updated_at', 'url', 'do_cancel', 'relative_start_time', 'relative_stop_time', 'start_time', 'stop_time', 'duration', 'status']; + for (const task of schedulingUnit.task_drafts) { let scheduletask = {}; scheduletask['tasktype'] = 'Draft'; - scheduletask['actionpath'] = '/task/view/draft/'+task['id']; + scheduletask['actionpath'] = '/task/view/draft/' + task['id']; scheduletask['blueprint_draft'] = _.map(task['task_blueprints'], 'url'); scheduletask['status'] = task['status']; //fetch task draft details - for(const key of commonkeys){ + for (const key of commonkeys) { scheduletask[key] = task[key]; } scheduletask['specifications_doc'] = task['specifications_doc']; - scheduletask.duration = moment.utc((scheduletask.duration || 0)*1000).format(UIConstants.CALENDAR_TIME_FORMAT); - scheduletask.relative_start_time = moment.utc(scheduletask.relative_start_time*1000).format(UIConstants.CALENDAR_TIME_FORMAT); - scheduletask.relative_stop_time = moment.utc(scheduletask.relative_stop_time*1000).format(UIConstants.CALENDAR_TIME_FORMAT); + scheduletask.duration = moment.utc((scheduletask.duration || 0) * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); + scheduletask.relative_start_time = moment.utc(scheduletask.relative_start_time * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); + scheduletask.relative_stop_time = moment.utc(scheduletask.relative_stop_time * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); scheduletask.template = task.specifications_template; scheduletask.type_value = task.specifications_template.type_value; scheduletask.produced_by = task.produced_by; scheduletask.produced_by_ids = task.produced_by_ids; - - for(const blueprint of task['task_blueprints']){ + + for (const blueprint of task['task_blueprints']) { let taskblueprint = {}; taskblueprint['tasktype'] = 'Blueprint'; - taskblueprint['actionpath'] = '/task/view/blueprint/'+blueprint['id']; + taskblueprint['actionpath'] = '/task/view/blueprint/' + blueprint['id']; taskblueprint['blueprint_draft'] = blueprint['draft']; taskblueprint['status'] = blueprint['status']; - - for(const key of commonkeys){ + + for (const key of commonkeys) { taskblueprint[key] = blueprint[key]; } taskblueprint['created_at'] = moment(blueprint['created_at'], moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT); taskblueprint['updated_at'] = moment(blueprint['updated_at'], moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT); - taskblueprint.duration = moment.utc((taskblueprint.duration || 0)*1000).format(UIConstants.CALENDAR_TIME_FORMAT); - taskblueprint.relative_start_time = moment.utc(taskblueprint.relative_start_time*1000).format(UIConstants.CALENDAR_TIME_FORMAT); - taskblueprint.relative_stop_time = moment.utc(taskblueprint.relative_stop_time*1000).format(UIConstants.CALENDAR_TIME_FORMAT); + taskblueprint.duration = moment.utc((taskblueprint.duration || 0) * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); + taskblueprint.relative_start_time = moment.utc(taskblueprint.relative_start_time * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); + taskblueprint.relative_stop_time = moment.utc(taskblueprint.relative_stop_time * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); taskblueprint.template = scheduletask.template; taskblueprint.subTasks = blueprint.subtasks; for (const subtask of taskblueprint.subTasks) { @@ -356,13 +385,13 @@ class ViewSchedulingUnit extends Component{ */ getFormattedTaskBlueprints(schedulingUnit) { let taskBlueprintsList = []; - for(const taskBlueprint of schedulingUnit.task_blueprints) { + for (const taskBlueprint of schedulingUnit.task_blueprints) { taskBlueprint['tasktype'] = 'Blueprint'; - taskBlueprint['actionpath'] = '/task/view/blueprint/'+taskBlueprint['id']; + taskBlueprint['actionpath'] = '/task/view/blueprint/' + taskBlueprint['id']; taskBlueprint['blueprint_draft'] = taskBlueprint['draft']; taskBlueprint['relative_start_time'] = 0; taskBlueprint['relative_stop_time'] = 0; - taskBlueprint.duration = moment.utc((taskBlueprint.duration || 0)*1000).format(UIConstants.CALENDAR_TIME_FORMAT); + taskBlueprint.duration = moment.utc((taskBlueprint.duration || 0) * 1000).format(UIConstants.CALENDAR_TIME_FORMAT); taskBlueprint.template = taskBlueprint.specifications_template; for (const subtask of taskBlueprint.subtasks) { subtask.subTaskTemplate = _.find(this.subtaskTemplates, ['id', subtask.specifications_template_id]); @@ -373,15 +402,15 @@ class ViewSchedulingUnit extends Component{ return taskBlueprintsList; } - getScheduleUnitTasks(type, scheduleunit){ - if(type === 'draft') + getScheduleUnitTasks(type, scheduleunit) { + if (type === 'draft') return ScheduleService.getTasksBySchedulingUnit(scheduleunit.id, true, true, true); else return ScheduleService.getTaskBPWithSubtaskTemplateOfSU(scheduleunit); } - - getScheduleUnit(type, id){ - if(type === 'draft') + + getScheduleUnit(type, id) { + if (type === 'draft') return ScheduleService.getSchedulingUnitDraftById(id) else return ScheduleService.getSchedulingUnitBlueprintById(id) @@ -397,14 +426,14 @@ class ViewSchedulingUnit extends Component{ dialog.onSubmit = this.createBlueprintTree; dialog.content = null; dialog.width = null; - if (this.state.scheduleunit.scheduling_unit_blueprints.length>0) { + if (this.state.scheduleunit.scheduling_unit_blueprints.length > 0) { dialog.detail = "Blueprint(s) already exist for this Scheduling Unit. Do you want to create another one?"; - } else { - dialog.detail ="Do you want to create a Scheduling Unit Blueprint?"; + } else { + dialog.detail = "Do you want to create a Scheduling Unit Blueprint?"; } - dialog.actions = [{id: 'yes', title: 'Yes', callback: this.createBlueprintTree}, - {id: 'no', title: 'No', callback: this.closeDialog}]; - this.setState({dialogVisible: true, dialog: dialog}); + dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.createBlueprintTree }, + { id: 'no', title: 'No', callback: this.closeDialog }]; + this.setState({ dialogVisible: true, dialog: dialog }); } } @@ -412,15 +441,15 @@ class ViewSchedulingUnit extends Component{ * Funtion called to create blueprint on confirmation. */ createBlueprintTree() { - this.setState({dialogVisible: false, showSpinner: true}); + this.setState({ dialogVisible: false, showSpinner: true }); ScheduleService.createSchedulingUnitBlueprintTree(this.state.scheduleunit.id) .then(blueprint => { if (blueprint) { - appGrowl.show({severity: 'success', summary: 'Success', detail: 'Blueprint created successfully!'}); - this.setState({showSpinner: false, redirect: `/schedulingunit/view/blueprint/${blueprint.id}`, isLoading: true}); - } else { - appGrowl.show({severity: 'error', summary: 'Failed', detail: 'Unable to create blueprint!'}); - this.setState({showSpinner: false}); + appGrowl.show({ severity: 'success', summary: 'Success', detail: 'Blueprint created successfully!' }); + this.setState({ showSpinner: false, redirect: `/schedulingunit/view/blueprint/${blueprint.id}`, isLoading: true }); + } else { + appGrowl.show({ severity: 'error', summary: 'Failed', detail: 'Unable to create blueprint!' }); + this.setState({ showSpinner: false }); } }); } @@ -429,46 +458,46 @@ class ViewSchedulingUnit extends Component{ * Callback function to close the dialog prompted. */ closeDialog() { - this.setState({dialogVisible: false}); + this.setState({ dialogVisible: false }); } - + onRowSelection(selectedRows) { this.selectedRows = selectedRows; } - + /** * Confirmation dialog for delete task(s) */ confirmDeleteTasks() { - if(this.selectedRows.length === 0) { - appGrowl.show({severity: 'info', summary: 'Select Row', detail: 'Select Task to delete.'}); - } else { + if (this.selectedRows.length === 0) { + appGrowl.show({ severity: 'info', summary: 'Select Row', detail: 'Select Task to delete.' }); + } else { let dialog = this.state.dialog; dialog.type = "confirmation"; - dialog.header= "Confirm to Delete Task(s)"; + dialog.header = "Confirm to Delete Task(s)"; dialog.detail = "Do you want to delete the selected Task(s)?"; dialog.content = this.getTaskDialogContent; - dialog.actions = [{id: 'yes', title: 'Yes', callback: this.deleteTasks}, - {id: 'no', title: 'No', callback: this.closeDialog}]; + dialog.actions = [{ id: 'yes', title: 'Yes', callback: this.deleteTasks }, + { id: 'no', title: 'No', callback: this.closeDialog }]; dialog.onSubmit = this.deleteTasks; dialog.width = '55vw'; dialog.showIcon = false; - this.setState({dialog: dialog, dialogVisible: true}); + this.setState({ dialog: dialog, dialogVisible: true }); } } - + showDeleteSUConfirmation() { let dialog = this.state.dialog; dialog.type = "confirmation"; - dialog.header= "Confirm to Delete Scheduling Unit"; + dialog.header = "Confirm to 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.actions = [{ id: 'yes', title: 'Yes', callback: this.deleteSchedulingUnit }, + { id: 'no', title: 'No', callback: this.closeDialog }]; dialog.onSubmit = this.deleteSchedulingUnit; dialog.width = '55vw'; dialog.showIcon = false; - this.setState({dialog: dialog, dialogVisible: true}); + this.setState({ dialog: dialog, dialogVisible: true }); } /** @@ -476,19 +505,21 @@ class ViewSchedulingUnit extends Component{ */ getTaskDialogContent() { let selectedTasks = []; - 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 Unit Id"></Column> - <Column field="suName" header="Scheduling Unit 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 Unit Id"></Column> + <Column field="suName" header="Scheduling Unit 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> </> } @@ -496,9 +527,9 @@ class ViewSchedulingUnit extends Component{ * Prepare Scheduling Unit details to show on confirmation dialog */ 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'}}> + 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 Unit Id"></Column> <Column field="suName" header="Scheduling Unit Name"></Column> <Column field="suType" header="Type"></Column> @@ -511,117 +542,117 @@ class ViewSchedulingUnit extends Component{ */ async deleteTasks() { let hasError = false; - for(const task of this.selectedRows) { - if(!await TaskService.deleteTask(task.tasktype, task.id)) { + for (const task of this.selectedRows) { + if (!await TaskService.deleteTask(task.tasktype, task.id)) { hasError = true; } } - if(hasError){ - appGrowl.show({severity: 'error', summary: 'error', detail: 'Error while deleting Task(s)'}); - this.setState({dialogVisible: false}); - } else { + if (hasError) { + appGrowl.show({ severity: 'error', summary: 'error', detail: 'Error while deleting Task(s)' }); + this.setState({ dialogVisible: false }); + } else { this.selectedRows = []; - this.setState({dialogVisible: false}); + this.setState({ dialogVisible: false }); this.componentDidMount(); - appGrowl.show({severity: 'success', summary: 'Success', detail: 'Task(s) deleted successfully'}); + appGrowl.show({ severity: 'success', summary: 'Success', detail: 'Task(s) deleted successfully' }); } } - /** - * Delete Scheduling Unit - */ + /** + * Delete Scheduling Unit + */ async deleteSchedulingUnit() { let hasError = false; - if(!await ScheduleService.deleteSchedulingUnit(this.state.scheduleunitType, this.state.scheduleunit.id)) { + if (!await ScheduleService.deleteSchedulingUnit(this.state.scheduleunitType, this.state.scheduleunit.id)) { hasError = true; } - if(hasError){ - appGrowl.show({severity: 'error', summary: 'error', detail: 'Error while deleting scheduling Unit'}); - this.setState({dialogVisible: false}); - } else { + if (hasError) { + appGrowl.show({ severity: 'error', summary: 'error', detail: 'Error while deleting scheduling Unit' }); + this.setState({ dialogVisible: false }); + } else { this.selectedRows = []; - appGrowl.show({severity: 'success', summary: 'Success', detail: 'Scheduling Unit is deleted successfully'}); - this.setState({dialogVisible: false, redirect: '/schedulingunit'}); + appGrowl.show({ severity: 'success', summary: 'Success', detail: 'Scheduling Unit is deleted successfully' }); + this.setState({ dialogVisible: false, redirect: '/schedulingunit' }); } } - - render(){ + + render() { if (this.state.redirect) { - return <Redirect to={ {pathname: this.state.redirect} }></Redirect> + return <Redirect to={{ pathname: this.state.redirect }}></Redirect> } - return( - <> - <PageHeader location={this.props.location} title={'Scheduling Unit - Details'} - actions={this.state.actions}/> - { this.state.isLoading ? <AppLoader/> :this.state.scheduleunit && - <> - <div className="main-content"> - <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12">Name</label> - <span className="p-col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.name}</span> - <label className="col-lg-2 col-md-2 col-sm-12">Description</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.description}</span> - </div> - <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12">Created At</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.created_at && moment(this.state.scheduleunit.created_at,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> - <label className="col-lg-2 col-md-2 col-sm-12">Updated At</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.created_at && moment(this.state.scheduleunit.updated_at,moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> - </div> - <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12">Start Time</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.start_time && moment(this.state.scheduleunit.start_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> - <label className="col-lg-2 col-md-2 col-sm-12">End Time</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.stop_time && moment(this.state.scheduleunit.stop_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> - </div> - <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12" >Duration (HH:mm:ss)</label> - <span className="col-lg-4 col-md-4 col-sm-12">{moment.utc((this.state.scheduleunit.duration?this.state.scheduleunit.duration:0)*1000).format(UIConstants.CALENDAR_TIME_FORMAT)}</span> - <label className="col-lg-2 col-md-2 col-sm-12">Template ID</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.observation_strategy_template_id}</span> - </div> - <div className="p-grid"> - {this.state.scheduleunit.scheduling_set_object.project_id && - <> - <label className="col-lg-2 col-md-2 col-sm-12">Project</label> - <span className="col-lg-4 col-md-4 col-sm-12"> - <Link to={`/project/view/${this.state.scheduleunit.scheduling_set_object.project_id}`}>{this.state.scheduleunit.scheduling_set_object.project_id}</Link> - </span> - </> + return ( + <> + <PageHeader location={this.props.location} title={'Scheduling Unit - Details'} + actions={this.state.actions} /> + { this.state.isLoading ? <AppLoader /> : this.state.scheduleunit && + <> + <div className="main-content"> + <div className="p-grid"> + <label className="col-lg-2 col-md-2 col-sm-12">Name</label> + <span className="p-col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.name}</span> + <label className="col-lg-2 col-md-2 col-sm-12">Description</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.description}</span> + </div> + <div className="p-grid"> + <label className="col-lg-2 col-md-2 col-sm-12">Created At</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.created_at && moment(this.state.scheduleunit.created_at, moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> + <label className="col-lg-2 col-md-2 col-sm-12">Updated At</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.created_at && moment(this.state.scheduleunit.updated_at, moment.ISO_8601).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> + </div> + <div className="p-grid"> + <label className="col-lg-2 col-md-2 col-sm-12">Start Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.start_time && moment(this.state.scheduleunit.start_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> + <label className="col-lg-2 col-md-2 col-sm-12">End Time</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.stop_time && moment(this.state.scheduleunit.stop_time).format(UIConstants.CALENDAR_DATETIME_FORMAT)}</span> + </div> + <div className="p-grid"> + <label className="col-lg-2 col-md-2 col-sm-12" >Duration (HH:mm:ss)</label> + <span className="col-lg-4 col-md-4 col-sm-12">{moment.utc((this.state.scheduleunit.duration ? this.state.scheduleunit.duration : 0) * 1000).format(UIConstants.CALENDAR_TIME_FORMAT)}</span> + <label className="col-lg-2 col-md-2 col-sm-12">Template ID</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.observation_strategy_template_id}</span> + </div> + <div className="p-grid"> + {this.state.scheduleunit.scheduling_set_object.project_id && + <> + <label className="col-lg-2 col-md-2 col-sm-12">Project</label> + <span className="col-lg-4 col-md-4 col-sm-12"> + <Link to={`/project/view/${this.state.scheduleunit.scheduling_set_object.project_id}`}>{this.state.scheduleunit.scheduling_set_object.project_id}</Link> + </span> + </> } - <label className="col-lg-2 col-md-2 col-sm-12">Scheduling set</label> - <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.scheduling_set_object.name}</span> - </div> - <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12">{this.props.match.params.type === 'blueprint' ? 'Draft' : 'Blueprints'}</label> - <span className="col-lg-4 col-md-4 col-sm-12"> - <ul className="task-list"> - {(this.state.scheduleunit.blueprintList || []).map(blueprint => ( - <li> - <Link to={{ pathname: `/schedulingunit/view/blueprint/${blueprint.id}`}}>{blueprint.name}</Link> - </li>))} - {this.state.scheduleunit.draft_object && - <li> - <Link to={{ pathname: `/schedulingunit/view/draft/${this.state.scheduleunit.draft_object.id}` }}> - {this.state.scheduleunit.draft_object.name} - </Link> - </li>} - </ul> - </span> - {this.props.match.params.type === 'blueprint' && - <label className="col-lg-2 col-md-2 col-sm-12 ">Status</label> } - {this.props.match.params.type === 'blueprint' && - <span className="col-lg-2 col-md-2 col-sm-12">{this.state.scheduleunit.status}</span>} - </div> - <div className="p-grid"> - <label className="col-lg-2 col-md-2 col-sm-12">Tags</label> - <Chips className="p-col-4 chips-readonly" disabled value={this.state.scheduleunit.tags}></Chips> + <label className="col-lg-2 col-md-2 col-sm-12">Scheduling set</label> + <span className="col-lg-4 col-md-4 col-sm-12">{this.state.scheduleunit.scheduling_set_object.name}</span> + </div> + <div className="p-grid"> + <label className="col-lg-2 col-md-2 col-sm-12">{this.props.match.params.type === 'blueprint' ? 'Draft' : 'Blueprints'}</label> + <span className="col-lg-4 col-md-4 col-sm-12"> + <ul className="task-list"> + {(this.state.scheduleunit.blueprintList || []).map(blueprint => ( + <li> + <Link to={{ pathname: `/schedulingunit/view/blueprint/${blueprint.id}` }}>{blueprint.name}</Link> + </li>))} + {this.state.scheduleunit.draft_object && + <li> + <Link to={{ pathname: `/schedulingunit/view/draft/${this.state.scheduleunit.draft_object.id}` }}> + {this.state.scheduleunit.draft_object.name} + </Link> + </li>} + </ul> + </span> + {this.props.match.params.type === 'blueprint' && + <label className="col-lg-2 col-md-2 col-sm-12 ">Status</label>} + {this.props.match.params.type === 'blueprint' && + <span className="col-lg-2 col-md-2 col-sm-12">{this.state.scheduleunit.status}</span>} + </div> + <div className="p-grid"> + <label className="col-lg-2 col-md-2 col-sm-12">Tags</label> + <Chips className="p-col-4 chips-readonly" disabled value={this.state.scheduleunit.tags}></Chips> + </div> + </div> - - </div> - </> - } - + </> + } + <div> <h3>Tasks Details</h3> </div> @@ -635,86 +666,88 @@ class ViewSchedulingUnit extends Component{ paths - specify the path for navigation - Table will set "id" value for each row in action button */} - + <div className="delete-option"> <div > <span className="p-float-label"> {this.state.schedule_unit_task && this.state.schedule_unit_task.length > 0 && - <a href="#" onClick={this.confirmDeleteTasks} title="Delete selected Task(s)"> + <a href="#" onClick={this.confirmDeleteTasks} title="Delete selected Task(s)"> <i class="fa fa-trash" aria-hidden="true" ></i> </a> } </span> - </div> + </div> </div> - {this.state.isLoading ? <AppLoader/> : (this.state.schedule_unit_task.length>0 )? - <ViewTable - data={this.state.schedule_unit_task} + {this.state.isLoading ? <AppLoader /> : (this.state.schedule_unit_task.length > 0) ? + <ViewTable + data={this.state.schedule_unit_task} defaultcolumns={this.state.defaultcolumns} optionalcolumns={this.state.optionalcolumns} columnclassname={this.state.columnclassname} columnOrders={this.state.columnOrders} - defaultSortColumn={this.state.defaultSortColumn} showaction="true" keyaccessor="id" paths={this.state.paths} unittest={this.state.unittest} tablename="scheduleunit_task_list" allowRowSelection={true} - onRowSelection = {this.onRowSelection} + onRowSelection={this.onRowSelection} ignoreSorting={this.ignoreSorting} + lsKeySortColumn={this.lsKeySortColumn} + toggleBySorting={(sortData) => this.toggleBySorting(sortData)} + defaultSortColumn={this.defaultSortColumn} /> - :<div>No Tasks found</div> + : <div>No Tasks found</div> } - - {!this.state.isLoading && + + {!this.state.isLoading && <> - {(this.state.stationGroup && this.state.stationGroup.length > 0 )? - <Stations - stationGroup={this.state.stationGroup} - targetObservation={this.state.targetObservation} - view - /> - :<> - <div style={{marginTop: "10px"}}> - <h3>Station Groups</h3> - </div> - <div>No Station Groups Specified</div> - </> - } + {(this.state.stationGroup && this.state.stationGroup.length > 0) ? + <Stations + stationGroup={this.state.stationGroup} + targetObservation={this.state.targetObservation} + view + /> + : <> + <div style={{ marginTop: "10px" }}> + <h3>Station Groups</h3> + </div> + <div>No Station Groups Specified</div> + </> + } - {this.state.scheduleunit && this.state.scheduleunit.scheduling_constraints_doc && - <SchedulingConstraint disable constraintTemplate={this.state.constraintTemplate} + {this.state.scheduleunit && this.state.scheduleunit.scheduling_constraints_doc && + <SchedulingConstraint disable constraintTemplate={this.state.constraintTemplate} initValue={this.state.scheduleunit.scheduling_constraints_doc} />} </> } {this.state.showStatusLogs && - <Dialog header={`Status change logs - ${this.state.task?this.state.task.name:""}`} - visible={this.state.showStatusLogs} maximizable maximized={false} position="left" style={{ width: '50vw' }} - onHide={() => {this.setState({showStatusLogs: false})}}> - <TaskStatusLogs taskId={this.state.task.id}></TaskStatusLogs> + <Dialog header={`Status change logs - ${this.state.task ? this.state.task.name : ""}`} + visible={this.state.showStatusLogs} maximizable maximized={false} position="left" style={{ width: '50vw' }} + onHide={() => { this.setState({ showStatusLogs: false }) }}> + <TaskStatusLogs taskId={this.state.task.id}></TaskStatusLogs> </Dialog> - } + } {/* Dialog component to show messages and get confirmation */} - + <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}/> - + 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} /> + {/* Show spinner during backend API call */} <CustomPageSpinner visible={this.state.showSpinner} /> {/* To show Data Products To Ingest */} {this.state.showTaskRelationDialog && ( - <Schedulingtaskrelation - showTaskRelationDialog={this.state.showTaskRelationDialog} - ingestGroup={this.state.ingestGroup} - toggle={this.showTaskRelationDialog} - - /> + <Schedulingtaskrelation + showTaskRelationDialog={this.state.showTaskRelationDialog} + ingestGroup={this.state.ingestGroup} + toggle={this.showTaskRelationDialog} + + /> )} - </> + </> ) } } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js index 3c9ee5f01db04b41e2ce47c0f3f2fd1ed074fd75..a260824d3f52aa7ebca2ee9a94edfd38548fb718 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js @@ -44,7 +44,7 @@ const RESERVATION_COLORS = { * Scheduling Unit timeline view component to view SU List and timeline */ export class WeekTimelineView extends Component { - lsKeySortColumn = 'SortDataWeekTimelineView'; + lsKeySortColumn = 'SortDataWeekTimelineView-WeekView'; defaultSortColumn = []; constructor(props) { super(props); @@ -859,7 +859,7 @@ export class WeekTimelineView extends Component { optionalcolumns={[{project:"Project",description: "Description", duration:"Duration (HH:mm:ss)",actionpath: "actionpath"}]} columnclassname={[{"Name":"filter-input-100", "Start Time":"filter-input-50", "End Time":"filter-input-50", "Duration (HH:mm:ss)" : "filter-input-50",}]} - defaultSortColumn= {[{id: "Start Time", desc: false}]} + defaultSortColumn= {this.defaultSortColumn} showaction="true" tablename="timeline_scheduleunit_list" showTopTotal={false} diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js index 77348c8570fd59492b1d20fdd91488694e1bca3a..d7d2e71e0d7fca34917c8492e3e9d956dca5d3e5 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Workflow/workflow.list.js @@ -11,10 +11,14 @@ import ViewTable from '../../components/ViewTable'; import WorkflowService from '../../services/workflow.service'; import ScheduleService from '../../services/schedule.service'; import UIConstants from '../../utils/ui.constants'; +import UtilService from '../../services/util.service'; class WorkflowList extends Component{ + lsKeySortColumn = 'SortDataWorkflowList'; + defaultSortColumn = []; constructor(props) { super(props); + this.setToggleBySorting(); this.state={ ftAssignstatus: '', activeWorkflow: null, @@ -65,6 +69,7 @@ class WorkflowList extends Component{ } componentDidMount() { + this.setToggleBySorting(); const promises = [ WorkflowService.getWorkflowProcesses(), WorkflowService.getWorkflowTasks(), ScheduleService.getSchedulingUnitBlueprint(),]; @@ -75,7 +80,23 @@ class WorkflowList extends Component{ this.prepareWorkflowProcesslist(); }); } + toggleBySorting = (sortData) => { + UtilService.localStore({ type: 'set', key: this.lsKeySortColumn, value: sortData }); + } + setToggleBySorting() { + let sortData = UtilService.localStore({ type: 'get', key: this.lsKeySortColumn }); + if (sortData) { + if (Object.prototype.toString.call(sortData) === '[object Array]') { + this.defaultSortColumn = sortData; + } + else { + this.defaultSortColumn = [{ ...sortData }]; + } + } + this.defaultSortColumn = this.defaultSortColumn || []; + UtilService.localStore({ type: 'set', key: this.lsKeySortColumn, value: [...this.defaultSortColumn] }); + } /** * Prepare Workflow Process data */ @@ -249,6 +270,9 @@ class WorkflowList extends Component{ showTopTotal={true} showGlobalFilter={true} showColumnFilter={true} + lsKeySortColumn={this.lsKeySortColumn} + toggleBySorting={(sortData) => this.toggleBySorting(sortData)} + defaultSortColumn= {this.defaultSortColumn} /> </> :<div>No Workflow Process SU found</div>