Skip to content
Snippets Groups Projects
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
create.js 63.00 KiB
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { Redirect } from 'react-router-dom';
import _ from 'lodash';
import $RefParser from "@apidevtools/json-schema-ref-parser";
import moment from 'moment';
import { publish } from '../../App';

import { Checkbox } from 'primereact/checkbox';
import { InputText } from 'primereact/inputtext';
import { InputTextarea } from 'primereact/inputtextarea';
import { Dropdown } from 'primereact/dropdown';
import { Toast } from 'primereact/toast';
import AppLoader from '../../layout/components/AppLoader';
import Jeditor from '../../components/JSONEditor/JEditor';
import UnitConversion from '../../utils/unit.converter';
import UnitConverter from '../../utils/unit.converter';
import ProjectService from '../../services/project.service';
import ScheduleService from '../../services/schedule.service';
import TaskService from '../../services/task.service';
import UIConstants from '../../utils/ui.constants';
import ParserUtility from '../../utils/parser.utility';
import PageHeader from '../../layout/components/PageHeader';
import SchedulingConstraint from './Scheduling.Constraints';
import Stations from './Stations';
import { CustomDialog } from '../../layout/components/CustomDialog';
import SchedulingSet from './schedulingset.create';
import UtilService from '../../services/util.service';
import AuthUtil from '../../utils/auth.util';
import { appGrowl, setAppGrowl } from '../../layout/components/AppGrowl';
import FormActionbar from '../../components/FormActionbar';
import { getConstraintTemplate, getTaskTemplateForTask } from "./create.helper";
import ObservationStrategySelector, {
    queryMatchingObservationStrategyTemplates
} from "./components/ObservationStrategySelector";
import ProjectScheduleSetSelector from "./components/ProjectScheduleSetSelector";

/**
 * Component to create a new SchedulingUnit from Observation strategy template
 */
export class SchedulingUnitCreate extends Component {
    constructor(props) {
        super(props);
        this.state = {
            observStrategyFilters: {
                states: ['active'],
                purpose: []
            },
            constraintValidEditor: false,
            validForm: false,
            validConstraints: false,
            validSpecification: false,
            userrole: {},
            selectedProject: {},
            showAddSet: false,
            showDialog: false,
            isDirty: false,
            isLoading: true,                        // Flag for loading spinner
            dialog: { header: '', detail: '' },      // Dialog properties
            touched: {},
            redirect: null,                         // URL to redirect
            errors: [],                             // Form Validation errors
            schedulingSets: [],                     // Scheduling set of the selected project
            missing_StationFieldsErrors: [],         // Validation for max no.of missing station
            stationOptions: [],
            stationGroups: {},
            customSelectedStations: [],             // custom stations
            selectedStationsOfTask: {},
            missingStationsofTask: {},
            missingStnErorsofTask: {},
            customStationsOfTask: {},
            stationsCollapsed: false,
            schedulingUnit: {
                name: '',
                description: '',
                project: (props.match ? props.match.params.project : null) || null,
                rank: 0.0001,
            },
            projectDisabled: (props.match ? (props.match.params.project ? true : false) : false),      // Disable project selection if
            observStrategy: {},                     // Selected strategy to create SU
            paramsSchema: null,                     // JSON Schema to be generated from strategy template to pass to JSOn editor
            constraintSchema: null,
            validEditor: false,                     // For JSON editor validation
            validFields: {},                        // For Form Validation            
            newSet: null,
            observationIdSet: [],
            createAnother: false,
            multiCreateCount: 1
        };
        this.defaultConstraints = {}
        this.taskFilters = [];                      // To get Short_Description details
        this.priorityQueueTypes = [];
        this.projects = [];                         // All projects to load project dropdown
        this.taskTemplates = [];                    // All task templates to be filtered based on tasks in selected strategy template
        this.tooltipOptions = UIConstants.tooltipOptions;
        this.constraintTemplates = [];
        this.myRoles = {};
        this.nameInput = React.createRef();         // Ref to Name field for auto focus
        this.formRules = {                          // Form validation rules
            name: { required: true, message: "Name can not be empty" },
            description: { required: true, message: "Description can not be empty" },
            project: { required: true, message: "Select project to get Scheduling Sets" },
            scheduling_set_id: { required: true, message: "Select the Scheduling Set" },
        };
        this.isDebuggLoggingEnabled = false
        this.setEditorOutput = this.setEditorOutput.bind(this);
        this.setConstraintsEditorOutput = this.setConstraintsEditorOutput.bind(this);
        this.setConstraintEditorFun = this.setConstraintEditorFun.bind(this);
        this.changeProject = this.changeProject.bind(this);
        this.changeStrategy = this.changeStrategy.bind(this);
        this.setStrategyConstraint = this.setStrategyConstraint.bind(this);
        this.setSchedUnitParams = this.setSchedUnitParams.bind(this);
        this.validateForm = this.validateForm.bind(this);
        this.validateStations = this.validateStations.bind(this);
        this.validateEditor = this.validateEditor.bind(this);
        this.setEditorFunction = this.setEditorFunction.bind(this);
        this.saveSchedulingUnit = this.saveSchedulingUnit.bind(this);
        this.cancelCreate = this.cancelCreate.bind(this);
        this.reset = this.reset.bind(this);
        this.refreshSchedulingSet = this.refreshSchedulingSet.bind(this);
        this.checkIsDirty = this.checkIsDirty.bind(this);
        this.close = this.close.bind(this);
        this.setSUSet = this.setSUSet.bind(this);
        this.updateConstraintsParams = this.updateConstraintsParams.bind(this);
        this.setCreateAnother = this.setCreateAnother.bind(this);
        this.setState = this.setState.bind(this);
        this.init = this.init.bind(this);
    }


    componentDidMount() {
        this.init();
    }
    async init() {
        const permission = await AuthUtil.getUserPermissionByModule('scheduleunit_draft');
        this.setState({ userrole: permission });
        const promises = [ProjectService.getProjectList(false, 'name,url'),
        TaskService.getTaskTemplates(),
        ScheduleService.getSchedulingConstraintTemplates(),
        UtilService.getPriorityQueueType(),
        TaskService.getTaskFilterDefinition('draft'),
        ScheduleService.getStrategyPurpose(),
        ScheduleService.getStrategyState(),
        ProjectService.getMyRoles(),
        ];
        Promise.all(promises).then(async (responses) => {
            this.projects = responses[0];
            this.taskTemplates = responses[1];
            this.constraintTemplates = responses[2];
            this.priorityQueueTypes = responses[3];
            this.taskFilters = responses[4];
            this.templatePurposes = this.getStrategyFilterOptions(responses[5], 'purpose');
            this.templateState = this.getStrategyFilterOptions(responses[6], 'state');
            this.myRoles = responses[7];
            const systemRoles = this.myRoles.system_roles.map(role => {
                return role.toLowerCase()
            });
            const projectRoles = Object.fromEntries(
                Object.entries(this.myRoles.project_roles).map(([project, roles]) => [project.toLowerCase(), roles])
            );
            // Users with system_roles other than superuser, operator & support can view the projects for which they have shared_support project_role
            if (_.intersection(systemRoles, ['superuser', 'operator', 'support']).length < 1) {
                this.projects = _.filter(this.projects, (project) => {
                    return _.includes(projectRoles[project.name.toLowerCase()], 'shared_support')
                })
            }
            if (this.state.schedulingUnit.project) {
                const selectedProject = _.filter(this.projects, { 'name': this.state.schedulingUnit.project });
                const projectSchedSets = await ScheduleService.getSchedulingSets(`project=${encodeURIComponent(this.state.schedulingUnit.project)}`);
                let tmpSU = this.state.schedulingUnit;
                tmpSU['output_pinned'] = selectedProject[0].auto_pin;
                this.setState({
                    isLoading: false,
                    schedulingSets: projectSchedSets,
                    selectedProject: selectedProject,
                    schedulingUnit: tmpSU
                });
            } else {
                this.setState({ isLoading: false });
            }
        });
        let observStrategyFilter = UtilService.localStore({ type: 'get', key: 'strategyFilterSUCreate' });
        if (Object.keys(observStrategyFilter).length === 0) {
            observStrategyFilter = { states: ['active'], purpose: [] }
        }

        this.setState({
            observStrategies: await this.getMatchingObservationStrategyTemplates(observStrategyFilter),
            observStrategyFilters: observStrategyFilter
        });
    }

    async getMatchingObservationStrategyTemplates(filters) {
        return await queryMatchingObservationStrategyTemplates(filters)
    }

    getStrategyFilterOptions(filterValues, filterId) {
        if (filterValues) {
            let optionList = [];
            filterValues.forEach(choice => {
                const tmpVar = { name: choice.value, value: choice.value };
                if (filterId === 'purpose') {
                    optionList.push(tmpVar);
                }
                if (filterId === 'state' && tmpVar.value !== 'obsolete') {
                    optionList.push(tmpVar);
                }
            });
            return _.sortBy(optionList, ['name']);
        }
    }


    /**
     * Function to call on change of project and reload scheduling set dropdown
     * @param {string} projectName
     */
    async changeProject(projectName) {
        const projectSchedSets = await ScheduleService.getSchedulingSets(`project=${encodeURIComponent(projectName)}`);
        let schedulingUnit = this.state.schedulingUnit;
        schedulingUnit.project = projectName;

        if (projectSchedSets?.length==1) {
            schedulingUnit.scheduling_set_id  = projectSchedSets[0].id;

        } else  { schedulingUnit.scheduling_set_id = null;}

        const selectedProject = _.filter(this.projects, { 'name': projectName });
        schedulingUnit['output_pinned'] = selectedProject[0].auto_pin;
        if (!this.state.isDirty) {
            publish('edit-dirty', true);
        }

        this.setState({
            selectedProject: selectedProject,
            schedulingUnit: schedulingUnit,
            schedulingSets: projectSchedSets,
            validForm: this.validateForm('project', projectName, schedulingUnit) && this.validateForm('scheduling_set_id'),  // project is valid, we selected, but we deselected scheduling
            isDirty: true
        });


    }

  

    /**
     * Function called when observation strategy template is changed.
     * It generates the JSON schema for JSON editor and defult vales for the parameters to be captured
     * @param {number} strategyId
     */
    async changeStrategy(strategyId, isSecondRound = false) {
        if (this.isDebuggLoggingEnabled) console.log("changing strategy to " + strategyId)
        const observStrategy = _.cloneDeep(_.find(this.state.observStrategies, { 'id': strategyId }));
        if (ParserUtility.addStationParameters(observStrategy)) {
            this.setState({
                observStrategy: observStrategy,
                constraintSchema: null
            });
        }
        let stationGroups = {};
        const tasks = observStrategy.template.tasks;
        const parameters = observStrategy.template.parameters;
        let paramsOutput = {};
        let schema = {
            type: 'object', additionalProperties: false,
            properties: {}, definitions: {}
        };
        let observationType = null;
        let bandPassFilter = null;
        // Take the constraint template schema as mentioned in the observing strategy
        this.setStrategyConstraint(observStrategy.template.scheduling_constraints_template.name, observStrategy.template.scheduling_constraints_template.version);
        if (this.isDebuggLoggingEnabled) console.log(" was one changing strategy to " + strategyId)

        const $strategyRefs = await $RefParser.resolve(observStrategy.template);
        // TODo: This schema reference resolving code has to be moved to common file and needs to rework
        for (const param of parameters) {
            // TODO: make parameter handling more generic, instead of task specific.
            if (!param.refs[0].startsWith("#/tasks/")) {
                continue;
            }

            let taskPaths = param.refs[0].split("/");
            const taskName = taskPaths[2];
            /**
             * For Short_Description, the task path length will be 4, so added below condition to get short_description details
             *  #/tasks/Combined Observation/short_description
             */
            taskPaths = taskPaths.slice((taskPaths.length === 4 ? 3 : 4), taskPaths.length);
            const task = tasks[taskName];
            if (task) {
                if (taskPaths.includes("station_groups")) {
                    stationGroups[param.name] = $strategyRefs.get(param.refs[0]);
                } else {
                    const taskTemplate = getTaskTemplateForTask(this.taskTemplates, task);
                    if (this.isDebuggLoggingEnabled) console.log("changing strategy to " + strategyId)
                    if (['target observation', 'beamforming observation'].indexOf(taskTemplate.name.toLowerCase()) >= 0) {
                        observationType = taskTemplate.name;
                    }
                    if (this.isDebuggLoggingEnabled) console.log("observation type changed to " + observationType)
                    // Get the default Bandpass filter and pass to the editor for frequency calculation from subband list
                    if (taskTemplate.type_value === 'observation' && task.specifications_doc.station_configuration?.filter) {
                        bandPassFilter = task.specifications_doc.station_configuration?.filter;
                    } else if (taskTemplate.type_value === 'observation' && taskTemplate.ref_resolved_schema.definitions.filter) {
                        bandPassFilter = taskTemplate.ref_resolved_schema.definitions.filter.default;
                    }
                    schema.definitions = { ...schema.definitions, ...taskTemplate?.ref_resolved_schema.definitions };
                    taskPaths.reverse();
                    const paramProp = await ParserUtility.getParamProperty($strategyRefs, taskPaths, taskTemplate.ref_resolved_schema, this.taskFilters);
                    schema.properties[param.name] = _.cloneDeep(paramProp);
                    if (schema.properties[param.name]) {
                        schema.properties[param.name].title = param.name;
                        try {
                            schema.properties[param.name].default = $strategyRefs.get(param.refs[0]);
                        } catch (err) { /* empty */ }
                        paramsOutput[param.name] = schema.properties[param.name].default || ParserUtility.getDefaultParamValue(schema.properties[param.name].type);
                    }
                }
            }
        }

        if (!this.state.isDirty) {
            publish('edit-dirty', true);
        }
        if (this.isDebuggLoggingEnabled) console.log("changing strategy in progress " + schema, stationGroups, paramsOutput, bandPassFilter)
        this.setState({
            observStrategy: observStrategy, paramsSchema: _.cloneDeep(schema), constraintParamsOutput: null,
            observationType: observationType, stationsCollapsed: false,
            paramsOutput: paramsOutput, stationGroups: stationGroups,
            bandPassFilter: bandPassFilter, isDirty: true
        }, this.state.callbackFunction);
        // Function called to clear the JSON Editor fields and reload with new schema
        if (!isSecondRound) {
            setTimeout(() => { this.changeStrategy(strategyId, true) }, 1);
        }
    }

    /**
     * This is the callback method to be passed to the JSON editor.
     * JEditor will call this function when there is change in the editor.
     * @param {Object} jsonOutput
     * @param {Array} errors
     */
    setEditorOutput(jsonOutput, errors) {
        this.paramsOutput = jsonOutput;
        this.validEditor = errors.length === 0;
        this.updateParameters();
        if (errors.length > 0) {
            this.setState({ errors: [...errors] })
        }
        this.setState({
            paramsOutput: jsonOutput,
            validEditor: errors.length === 0,
            validForm: this.validateForm()
        });
    }

    /**
     * Common function validate specification
     * @param {String} template Template url
     * @param {Object} updatedSpecificationDoc Object which needs to be validated
     */
    async validateSpecificationsDoc(updatedObservStrategy) {

        if (updatedObservStrategy) {
            const promises = [];
            promises.push(ScheduleService.validateSpecificationsDoc(updatedObservStrategy.scheduling_unit_template, updatedObservStrategy.template))
            const validation_result = await Promise.all(promises);
            if (this.isDebuggLoggingEnabled) console.log("validateSpecificationsDoc", updatedObservStrategy, validation_result)
            if (validation_result.length > 0) {
                let validationMessage = validation_result[0]['message'];
                if (validation_result[0]['valid']) {
                    validationMessage = "Task Parameters specification is valid"
                }
                this.setState({
                    validSpecification: validation_result[0]['valid'],
                    validSpecificationMessage: validationMessage
                });
            }
        }
    }

    async validateSchedulingConstraints(updatedConstraintParmas) {
        if (updatedConstraintParmas) {
            let schedulingConstraintsDoc = updatedConstraintParmas.scheduling_constraints_doc;
            if (schedulingConstraintsDoc.time)
                for (const key of _.keys(schedulingConstraintsDoc.time)) {
                    if (!schedulingConstraintsDoc.time[key]) {
                        delete schedulingConstraintsDoc.time[key];
                    }
                }
            const promises = [];
            promises.push(ScheduleService.validateSpecificationsDoc(updatedConstraintParmas.constraint.url, schedulingConstraintsDoc))
            const validation_result = await Promise.all(promises);
            if (validation_result.length > 0) {
                let validationMessage = validation_result[0]['message'];
                if (validation_result[0]['valid']) {
                    validationMessage = "Constraints specification is valid"
                }
                this.setState({
                    validConstraints: validation_result[0]['valid'],
                    validConstraintMessage: validationMessage
                });
            }
        }
    }

    loadConstraints(properties, parentProps, defaultValues) {
        parentProps = parentProps ? parentProps : _.cloneDeep(this.defaultConstraints);
        for (const key in properties) {
            let propertyValue = properties[key];
            if (propertyValue instanceof Object && key !== "reference_pointing") {
                if (defaultValues) {
                    parentProps[key] = propertyValue;
                    this.loadConstraints(propertyValue, parentProps[key], true);
                } else {
                    this.loadConstraints(propertyValue, parentProps[key], false);
                }
            } else {
                if (_.includes(['from', 'to'], key)) {
                    propertyValue = (propertyValue < 0 ? '-' : '') + UnitConverter.getSecsToHHmmss(propertyValue);
                }
                if (!_.includes(_.keys(parentProps), "angle1") && _.includes(['sun', 'moon', 'jupiter', 'target', 'calibrator'], key) && !defaultValues) {
                    propertyValue = ((propertyValue * 180) / Math.PI).toFixed(2);
                }
                if (_.includes(['between', 'not_between'], key)) {
                    propertyValue = [];
                }
                parentProps[key] = propertyValue;
            }
        }
        if (defaultValues) {
            this.defaultConstraints = parentProps;
        } else {
            this.setState({ constraintInitParams: parentProps });
        }
        // After converting the sky values, set the value directly in the JSON editor using the function passed from the editor
        if (this.state.constraintEditorFunction) {
            this.state.constraintEditorFunction("setValue", [parentProps]);
        }
    }

    setConstraintsEditorOutput(jsonOutput, errors) {
        let err = [...errors];
        if (jsonOutput.scheduler === 'online' || jsonOutput.scheduler === 'dynamic') {
            err = err.filter(e => e.path !== 'root.time.at');
        }
        this.constraintParamsOutput = jsonOutput;
        // When the constraint template is changed, get the default values from the template and overwrite with values from strategy
        if (!this.state.constraintParamsOutput) {
            if (this.state.observStrategy.template !== undefined) {
                this.loadConstraints(_.cloneDeep(this.state.observStrategy.template.scheduling_constraints_doc), _.cloneDeep(jsonOutput), false);
            }
        }
        this.constraintValidEditor = err.length === 0;
        if (!this.state.isDirty && this.state.constraintParamsOutput && !_.isEqual(this.state.constraintParamsOutput, jsonOutput)) {
            if (!_.isEmpty(this.state.observStrategy)) {
                if (!this.state.isDirty) {
                    publish('edit-dirty', true);
                }
                this.setState({
                    constraintParamsOutput: jsonOutput,
                    constraintValidEditor: err.length === 0,
                    validForm: this.validateForm(),
                    isDirty: true
                });
            }
        } else {
            this.setState({
                constraintParamsOutput: jsonOutput,
                constraintValidEditor: err.length === 0,
                validForm: this.validateForm()
            });
        }
        this.updateConstraintsParams();
    }

    /**
     * This function is mainly added for Unit Tests. If this function is removed Unit Tests will fail.
     */
    validateEditor() {
        return this.validEditor && this.constraintValidEditor ? true : false;
    }

    /**
     * Function to set form values to the SU object
     * @param {string} key
     * @param {object} value
     */
    async setSchedUnitParams(key, value) {
        if (this.isDebuggLoggingEnabled) console.log("setSchedUnitParams", key, value)
        this.setState({
            touched: {
                ...this.state.touched,
                [key]: true
            }
        });
        let schedulingUnit = _.cloneDeep(this.state.schedulingUnit);
        if (key === 'rank') {
            const previousValue = schedulingUnit.rank;
            value = value.replace(/([^0-9.]+)/, "");
            const match = /(\d{0,1})[^.]*((?:\.\d{0,4})?)/g.exec(value);
            const val = match[1] + match[2];
            if (val === '' || (val >= 0 && val <= 1)) {
                schedulingUnit[key] = val === '' ? '' : Number(val);
            } else {
                schedulingUnit[key] = previousValue;
            }
        } else if (key === 'scheduling_set_id') {
            schedulingUnit[key] = value;
            let schedulingUnitList = await ScheduleService.getSchedulingBySet(value, 'observation_strategy_template_id');
            let observationIdSet = _.uniq(_.map(schedulingUnitList, 'observation_strategy_template_id'));
            this.setState({ observationIdSet: observationIdSet });
        } else {
            schedulingUnit[key] = value;
        }

        if (!this.state.isDirty && !_.isEqual(this.state.schedulingUnit, schedulingUnit)) {
            if (!this.state.isDirty) {
                publish('edit-dirty', true);
            }
            this.setState({ schedulingUnit: schedulingUnit, validForm: this.validateForm(key, value), validEditor: this.validateEditor(), isDirty: true }, this.validateEditor);
        } else {
            this.setState({ schedulingUnit: schedulingUnit, validForm: this.validateForm(key, value), validEditor: this.validateEditor() }, this.validateEditor);
        }



    }


    /**
     * JEditor's function that to be called when parent wants to trigger change in the JSON Editor
     * @param {Function} editorFunction
     */
    setEditorFunction(editorFunction) {
        this.setState({ editorFunction: editorFunction });
    }

    setConstraintEditorFun(editorFunction) {
        this.setState({ constraintEditorFunction: editorFunction });
    }

    /**
     * Validation function to validate the form or field based on the form rules.
     * If no argument passed for fieldName, validates all fields in the form.
     * @param {string} fieldName
     */
    validateForm(fieldName, value = this.state.schedulingUnit[fieldName], schedulingUnit = this.state.schedulingUnit) {

        if (this.isDebuggLoggingEnabled) console.log("validateForm validating " + fieldName + " with value " + value, this.state.schedulingUnit)

        let validForm = false;
        let errors = this.state.errors;
        let validFields = this.state.validFields;

        if (fieldName) {
            delete errors[fieldName];
            delete validFields[fieldName];
            if (this.formRules[fieldName]) {
                const rule = this.formRules[fieldName];
                const fieldValue = value

                if (rule.required) {
                    if (!fieldValue) {

                        if (this.isDebuggLoggingEnabled) console.log(" Not Filled. validateForm", fieldName, rule, fieldValue, this.state.schedulingUnit)
                        errors[fieldName] = rule.message ? rule.message : `${fieldName} is required`;
                    } else {

                        if (this.isDebuggLoggingEnabled) console.log(" All Good validateForm", fieldName, rule, fieldValue, this.state.schedulingUnit)
                        validFields[fieldName] = true;
                    }
                }
            }
        } else {

            errors = {};
            validFields = {};
            for (const fieldName in this.formRules) {
                const rule = this.formRules[fieldName];
                const fieldValue = schedulingUnit[fieldName];
                if (rule.required) {
                    if (!fieldValue) {
                        errors[fieldName] = rule.message ? rule.message : `${fieldName} is required`;
                    } else {
                        validFields[fieldName] = true;
                    }
                }
            }
        }
        const updatedErrors = errors.length > 0 ? [...this.state.errors, errors] : this.state.errors
        const updatedValidFields = validFields ? { ...this.state.validFields, ...validFields } : this.state.validFields;
        if (this.isDebuggLoggingEnabled) console.log("set state validFields", updatedValidFields)
        this.setState({ errors: updatedErrors, validFields: updatedValidFields });
        let lengthkeys = Object.keys(validFields).length;
        let lengthRules = Object.keys(this.formRules).length;

        if (lengthkeys === lengthRules) {
            validForm = true;
        }
        const validStations = this.validateStations();
        let sumofstations = _.sum(_.values(this.state.missingStnErorsofTask)) <= 0;
        if (this.isDebuggLoggingEnabled) console.log("Validating Form result:" + validForm, " validStations:", validStations, " sumofstations:" + sumofstations, "lengthkeys+" + lengthkeys + " , lengthRules+", lengthRules, validFields, this.formRules, schedulingUnit)
        return validForm && validStations && sumofstations;
    }

    /*
     * Checks if at least one station selected for each station_group parameter and max_nr_missing station value is entered.
     * @returns Boolean
     */
    validateStations() {
        let validStations = false;
        // Check if at least one station selected for all station groups(parameters)
        // Break the loop if any of the required condition check is not satisfied
        for (const stationGroup of _.keys(this.state.stationGroups)) {
            // Check if the selected stations and custom stations are not empty
            if (this.state.selectedStationsOfTask[stationGroup] && this.state.customStationsOfTask[stationGroup]) {
                // Get the stations list for the station group(parameter)
                const stationsList = this.state.selectedStationsOfTask[stationGroup].concat(this.state.customStationsOfTask[stationGroup]);
                //If stationsList is empty then no station group and custom stations are selected
                if (stationsList.length === 0) {
                    validStations = false;
                    break;
                } else {
                    //If predefined station group(Dutch, Remote, etc.,) is/are selected, validate if max_nr_missing is entered
                    if (this.state.selectedStationsOfTask[stationGroup].length > 0) {
                        for (const selectedStations of this.state.selectedStationsOfTask[stationGroup]) {
                            const selectedGroup = this.state.missingStationsofTask[stationGroup][selectedStations]
                            if (selectedGroup) {
                                if (selectedGroup.max_nr_missing === "") {
                                    validStations = false;
                                    break;
                                } else {
                                    validStations = true;
                                }
                            }
                        }
                        if (!validStations) {
                            break;
                        } else {
                            validStations = true;
                        }
                    }
                    //If custom station group(s) is/are selected, validate if max_nr_missing is entered
                    if (this.state.customStationsOfTask[stationGroup].length > 0) {
                        for (const customStations of this.state.customStationsOfTask[stationGroup]) {
                            if (customStations.max_nr_missing === "") {
                                validStations = false;
                                break;
                            } else {
                                validStations = true;
                            }
                        }
                        if (!validStations) {
                            break;
                        } else {
                            validStations = true;
                        }
                    }
                }
            } else {
                validStations = false;
                break;
            }
        }
        return validStations;
    }

    /**
     * Function to update task parameters
     */
    async updateParameters() {
        let observStrategy = _.cloneDeep(this.state.observStrategy);
        const $refs = await $RefParser.resolve(observStrategy.template);
        observStrategy.template.parameters.forEach(async (param, index) => {
            // $refs.set(observStrategy.template.parameters[index]['refs'][0], this.state.paramsOutput[param.name]);
            let refIndex = 0;
            for (const ref of param.refs) {
                let station_groups = [];
                if (ref.includes("station_groups")) {
                    if (this.state.selectedStationsOfTask[param.name])
                        for (const selectedGroup of this.state.selectedStationsOfTask[param.name]) {
                            const stnGroup = this.state.missingStationsofTask[param.name][selectedGroup];
                            station_groups.push({
                                stations: stnGroup.stations,
                                max_nr_missing: parseInt(stnGroup.max_nr_missing)
                            });
                        }

                    if (this.state.customStationsOfTask[param.name])
                        for (const customGroup of this.state.customStationsOfTask[param.name]) {
                            station_groups.push({
                                stations: customGroup.stations,
                                max_nr_missing: parseInt(customGroup.max_nr_missing)
                            });
                        }
                    $refs.set(observStrategy.template.parameters[index]['refs'][refIndex], station_groups);
                } else {
                    $refs.set(observStrategy.template.parameters[index]['refs'][refIndex], this.state.paramsOutput[param.name]);
                }
                refIndex++;
            }
        });
        if (this.state.validEditor) {
            this.validateSpecificationsDoc(observStrategy);
        } else {
            let message = 'Task Parameters specification is not valid: '
            this.state.errors.forEach(error => {
                message = message + error.message + "\n"
            })
            this.setState({
                validSpecification: false,
                validSpecificationMessage: message
            })
        }
        this.setState({ updatedObservStrategy: observStrategy });
    }

    /**
     * Function to update constraints
     */
    updateConstraintsParams() {
        const constStrategy = _.cloneDeep(this.state.constraintParamsOutput);
        if (constStrategy)
            for (let type in constStrategy.time) {
                if (constStrategy.scheduler === 'online' || constStrategy.scheduler === 'dynamic') {
                    // delete constStrategy.time.at;
                }
                if (!constStrategy.time.after) {
                    delete constStrategy.time.after;
                }
                if (!constStrategy.time.before) {
                    delete constStrategy.time.before;
                }
                if (constStrategy.time[type] && constStrategy.time[type].length > 0) {
                    if (typeof constStrategy.time[type] === 'string') {
                        constStrategy.time[type] = `${moment(constStrategy.time[type]).format("YYYY-MM-DDTHH:mm:ss.SSSSS", { trim: false })}Z`;
                    } else {
                        constStrategy.time[type].forEach(time => {
                            for (let key in time) {
                                time[key] = `${moment(time[key]).format("YYYY-MM-DDTHH:mm:ss.SSSSS", { trim: false })}Z`;
                            }
                        })
                    }
                }
            }
        if (constStrategy?.sky.transit_offset) {
            constStrategy.sky.transit_offset.from = UnitConversion.getHHmmssToSecs(constStrategy.sky.transit_offset.from);
            constStrategy.sky.transit_offset.to = UnitConversion.getHHmmssToSecs(constStrategy.sky.transit_offset.to);
        }

        UnitConversion.degreeToRadians(constStrategy?.sky);
        const const_strategy = {
            scheduling_constraints_doc: constStrategy,
            id: this.state.constraintSchema.id,
            constraint: this.state.constraintSchema
        };
        if (this.state.constraintValidEditor) {
            this.validateSchedulingConstraints(const_strategy)
        } else {
            this.setState({ validConstraints: false, validConstraintMessage: 'Constraints specification is not valid' })
        }
        this.setState({ updatedConstraintParmas: const_strategy });
    }

    /**
     * Function to create Scheduling unit
     */
    async saveSchedulingUnit() {
        await this.updateParameters();
        let observStrategy = _.cloneDeep(this.state.updatedObservStrategy);
        let newSpecificationDoc = {}
        for (const parameter of observStrategy.template.parameters) {
            for (const ref of parameter.refs) {
                let paramPath = ref.replace(new RegExp('#/', "g"), "");
                paramPath = paramPath.replace(new RegExp('/', "g"), '.');
                const value = _.get(observStrategy.template, paramPath);
                if (value !== undefined) {
                    newSpecificationDoc = _.set(newSpecificationDoc, paramPath, value);
                }
            }
        }
        newSpecificationDoc['scheduling_constraints_doc'] = _.cloneDeep(this.state.updatedConstraintParmas).scheduling_constraints_doc;
        let schedulingUnit = this.state.schedulingUnit;
        schedulingUnit.observation_strategy_template_id = observStrategy.id;
        schedulingUnit.rank = schedulingUnit.rank === undefined || schedulingUnit.rank === '' ? 0 : schedulingUnit.rank.toFixed(4);
        schedulingUnit = await ScheduleService.saveSchedulingUnit(schedulingUnit, newSpecificationDoc);
        if (schedulingUnit.isSUUpdated) {
            if (appGrowl === null) {
                setAppGrowl(this.growl);
            }
            appGrowl.show({
                severity: 'success',
                summary: 'Success',
                detail: 'Scheduling Unit and Tasks are created successfully'
            });
            if (this.state.createAnother) {
                this.setState({ schedulingUnit: schedulingUnit.data, isDirty: false });
                this.reset();
            } else {
                this.setState({
                    schedulingUnit: schedulingUnit.data,
                    isDirty: false,
                    redirect: `/schedulingunit/view/draft/${schedulingUnit.data.id}`
                });
            }
            publish('edit-dirty', false);
        } else {
            this.growl.show({
                severity: 'error',
                summary: 'Error Occured',
                detail: schedulingUnit.message || 'Unable to save Scheduling Unit/Tasks'
            });
        }
    }

    /**
     * warn before cancel the page if any changes detected
     */
    checkIsDirty() {
        if (this.state.isDirty) {
            this.setState({ showDialog: true });
        } else {
            this.cancelCreate();
        }
    }

    close() {
        this.setState({ showDialog: false });
    }

    /**
     * Cancel SU creation and redirect
     */
    cancelCreate() {
        publish('edit-dirty', false);
        if (this.state.multiCreateCount > 1) {
            if (this.state.isDirty) {
                this.props.history.push(`/schedulingunit`);
            } else {
                this.props.history.go(this.state.multiCreateCount * -1);
            }
        } else {
            this.props.history.length > 1 ? this.state.isDirty ? this.props.history.go(-2) : this.props.history.go(-1) : this.props.history.push(`/schedulingunit`);
        }
        this.setState({ showDialog: false });
    }

    async setStrategyConstraint(name, version) {
        let strategyConstraint = getConstraintTemplate(this.constraintTemplates, name, version)
        let schedulingUnit = { ...this.state.schedulingUnit };
        schedulingUnit.scheduling_constraints_template_id = strategyConstraint ? strategyConstraint.id : '';
        strategyConstraint.ref_resolved_schema.properties.sky.properties.transit_offset.properties.from.default = UnitConversion.getSecsToHHmmssWithSign(strategyConstraint.ref_resolved_schema.properties.sky.properties.transit_offset.properties.from.default);
        strategyConstraint.ref_resolved_schema.properties.sky.properties.transit_offset.properties.to.default = UnitConversion.getSecsToHHmmssWithSign(strategyConstraint.ref_resolved_schema.properties.sky.properties.transit_offset.properties.to.default);
        strategyConstraint.ref_resolved_schema.properties.sky.properties.min_distance.properties.sun.propertyOrder = 1;
        strategyConstraint.ref_resolved_schema.properties.sky.properties.min_distance.properties.moon.propertyOrder = 2;
        strategyConstraint.ref_resolved_schema.properties.sky.properties.min_distance.properties.jupiter.propertyOrder = 3;
        this.setState({ constraintSchema: strategyConstraint, schedulingUnit });
    }

    /**
     * Reset function to be called when user wants to create new SU
     */
    reset() {
        const schedulingSets = this.state.schedulingSets;
        this.nameInput.focus();
        const selectedProject = this.props.match?.params?.project;
        let multiCreateCount = this.state.multiCreateCount;
        this.setState({
            isDirty: false,
            dialog: { header: '', detail: '' },
            errors: [],
            schedulingSets: this.props.match?.params?.project ? schedulingSets : [],
            schedulingUnit: {
                name: '',
                description: '',
                project: selectedProject || null,
                scheduling_constraints_template_id: this.constraintTemplates[0].id,
                rank: '',
                output_pinned: this.props.match?.params?.project ? ((_.find(this.projects, { 'name': selectedProject }))?.auto_pin) : null
            },
            projectDisabled: (this.props.match?.params?.project ? true : false),
            observStrategy: {},
            paramsSchema: null,
            paramsOutput: null,
            validEditor: false,
            validFields: {},
            constraintSchema: null,
            constraintInitParams: null,
            selectedStations: null,
            selectedStationsOfTask: {},
            customStationsOfTask: {},
            touched: false,
            stationGroups: {},
            multiCreateCount: ++multiCreateCount
        });

        this.state.editorFunction();

    }

    onUpdateStations = (state, selectedStations, missing_StationFieldsErrors, customSelectedStations, taskName) => {
        let selectedStationsOfTask = this.state.selectedStationsOfTask;
        let taskStations = selectedStationsOfTask[taskName] || [];
        let customStationsOfTask = this.state.customStationsOfTask;
        let taskCustomStations = customStationsOfTask[taskName] || [];
        let missingStationsofTask = this.state.missingStationsofTask;
        let missingStnErorsofTask = this.state.missingStnErorsofTask;
        selectedStationsOfTask[taskName] = selectedStations;
        customStationsOfTask[taskName] = customSelectedStations;
        missingStationsofTask[taskName] = state;
        missingStnErorsofTask[taskName] = missing_StationFieldsErrors;
        if (!this.state.isDirty) {
            if (!_.isEqual(taskStations, selectedStations) || !_.isEqual(taskCustomStations, customSelectedStations)) {
                this.setState({
                    missingStationsofTask,
                    selectedStationsOfTask,
                    missingStnErorsofTask,
                    customStationsOfTask
                }, () => {
                    this.setState({ validForm: this.validateForm(), isDirty: true });
                    if (!this.state.isDirty) {
                        publish('edit-dirty', true);
                    }
                });
            } else {
                this.setState({
                    missingStationsofTask,
                    selectedStationsOfTask,
                    missingStnErorsofTask,
                    customStationsOfTask
                }, () => {
                    this.setState({ validForm: this.validateForm() });
                });
            }
        } else {
            this.setState({
                missingStationsofTask,
                selectedStationsOfTask,
                missingStnErorsofTask,
                customStationsOfTask
            }, () => {
                this.setState({ validForm: this.validateForm() });
            });
        }
    };

    async refreshSchedulingSet() {
        let tmpSU = _.cloneDeep(this.state.schedulingUnit);
        const schedulingSets = await ScheduleService.getSchedulingSets(`project=${encodeURIComponent(this.state.schedulingUnit.project)}`);
        if (this.state.newSet) {
            tmpSU.scheduling_set_id = this.state.newSet.id;
            this.setState({
                schedulingUnit: tmpSU,
                newSet: null
            });
        }
        this.setState({ saveDialogVisible: false, showAddSet: false, schedulingSets: schedulingSets });
    }

    /**
     * Set newly created as current SU Set
     * @param {SU Set Name} suSet
     */
    setSUSet(suSet) {
        this.setState({ newSet: suSet });
    }

    /**
     * Select/Unselect the create another check box
     * @param {*} e
     */
    setCreateAnother(e) {
        this.setState({ 'createAnother': e.target.checked })
    }

    render() {
        let isSaveEnabled = (this.state.constraintValidEditor && this.state.validEditor && this.state.validForm && this.state.validConstraints && this.state.validSpecification)
        if (this.isDebuggLoggingEnabled) console.log("isSaveEnabled: " + isSaveEnabled + " constraintValidEditor: " + this.state.constraintValidEditor + " ,vvalidEditor:" + this.state.validEditor + " ,validForm:" + this.state.validForm + " ,validConstraints:" + this.state.validConstraints + " ,validSpecification:" + this.state.validSpecification);
        if (this.state.redirect) {
            return <Redirect to={{ pathname: this.state.redirect }}></Redirect>
        }
        const schema = this.state.paramsSchema;
        const { scheduleunit_draft } = this.state.userrole;
        let jeditor = null;
        if (schema) {
            jeditor = React.createElement(Jeditor, {
                title: "Task Parameters",
                schema: schema,
                initValue: this.state.paramsOutput,
                callback: this.setEditorOutput,
                parentFunction: this.setEditorFunction,
                bandPassFilter: this.state.bandPassFilter,
                observationType: this.state.observationType,
                theme: 'bootstrap4'
            });
        }
        return (
            <React.Fragment>
                <Toast ref={(el) => this.growl = el} />
                <PageHeader location={this.props.location} className="SchedulingUnit-PageHeader" title={'Scheduling Unit - Add'}
                    actions={[{
                        icon: 'fa-window-close', title: 'Click to close Scheduling Unit creation',
                        type: 'button', actOn: 'click', props: { callback: this.checkIsDirty }
                    }]} />
                {this.state.isLoading ? <AppLoader /> :
                    <>
                        <div>
                            <div className="p-fluid">
                                <div className="p-field p-grid">
                                    <label htmlFor="schedUnitName" className="col-lg-2 col-md-2 col-sm-12">Name <span
                                        style={{ color: 'red' }}>*</span></label>
                                    <div className="col-lg-3 col-md-3 col-sm-12" data-testid="namediv">
                                        <InputText
                                            className={(this.state.errors.name && this.state.touched.name) ? 'input-error' : ''}
                                            id="name" data-testid="name"
                                            tooltip="Enter name of the Scheduling Unit"
                                            tooltipOptions={this.tooltipOptions} maxLength="128"
                                            ref={input => {
                                                this.nameInput = input;
                                            }}
                                            value={this.state.schedulingUnit.name} autoFocus
                                            onChange={(e) => this.setSchedUnitParams('name', e.target.value)}
                                            onBlur={(e) => this.setSchedUnitParams('name', e.target.value)} />
                                        <label
                                            className={(this.state.errors.name && this.state.touched.name) ? "error" : "info"}>
                                            {this.state.errors.name && this.state.touched.name ? this.state.errors.name : "Max 128 characters"}
                                        </label>
                                    </div>
                                    <div className="col-lg-1 col-md-1 col-sm-12"></div>
                                    <label htmlFor="description"
                                        className="col-lg-2 col-md-2 col-sm-12">Description <span
                                            style={{ color: 'red' }}>*</span></label>
                                    <div className="col-lg-3 col-md-3 col-sm-12">
                                        <InputTextarea
                                            className={(this.state.errors.description && this.state.touched.description) ? 'input-error' : ''}
                                            rows={3} cols={30}
                                            tooltip="Longer description of the scheduling unit"
                                            tooltipOptions={this.tooltipOptions} maxLength="128"
                                            data-testid="description" value={this.state.schedulingUnit.description}
                                            onChange={(e) => this.setSchedUnitParams('description', e.target.value)}
                                            onBlur={(e) => this.setSchedUnitParams('description', e.target.value)} />
                                        <label
                                            className={(this.state.errors.description && this.state.touched.description) ? "error" : "info"}>
                                            {(this.state.errors.description && this.state.touched.description) ? this.state.errors.description : "Max 255 characters"}
                                        </label>
                                    </div>
                                </div>
                                {<ProjectScheduleSetSelector
                                    selectedProject={this.state.schedulingUnit.project}
                                    projectDisabled={this.state.projectDisabled}
                                    allProjects={this.projects}
                                    projectErrors={this.state.errors.project}
                                    touchedProject={this.state.touched.project}
                                    changeProject={this.changeProject}
                                    selectedSchedulingSet={this.state.schedulingUnit.scheduling_set_id}
                                    allSchedulingSets={this.state.schedulingSets}
                                    schedulingSetErrors={this.state.errors.scheduling_set_id}
                                    touchedSchedulingSet={this.state.touched.scheduling_set_id}
                                    setSchedUnitParams={this.setSchedUnitParams}
                                    scheduleUnitDraft={scheduleunit_draft}
                                    setState={this.setState}
                                />}
                                <div className="p-field p-grid">
                                    <label htmlFor="rank" className="col-lg-2 col-md-2 col-sm-12">Rank</label>
                                    <div className="col-lg-3 col-md-3 col-sm-12" data-testid="rank">
                                        <input type="number"
                                            data-for="reacttooltip"
                                            data-iscapture="true"
                                            data-tip="Priority of this scheduling unit w.r.t. other scheduling units within the same queue and project.. Min-0.0000, Max-1.0000"
                                            id="proj-rank" name="rank" data-testid="rank"
                                            className="p-inputtext p-component p-filled"
                                            value={this.state.schedulingUnit.rank}
                                            step="0.0001"
                                            lang="en"
                                            onChange={(e) => this.setSchedUnitParams('rank', e.target.value)} />
                                    </div>
                                    <div className="col-lg-1 col-md-1 col-sm-12"></div>
                                    <label htmlFor="priority_queue" className="col-lg-2 col-md-2 col-sm-12">Priority
                                        Queue</label>
                                    <div className="col-lg-3 col-md-3 col-sm-10">
                                        <Dropdown data-testid="priority_queue" id="priority_queue" optionLabel="value"
                                            optionValue="value"
                                            tooltip="Priority queue of this scheduling unit. Queues provide a strict ordering between scheduling units."
                                            tooltipOptions={this.tooltipOptions}
                                            value={this.state.schedulingUnit.priority_queue}
                                            options={this.priorityQueueTypes}
                                            onChange={(e) => {
                                                this.setSchedUnitParams('priority_queue', e.value)
                                            }}
                                            placeholder="Select Priority Queue" />

                                    </div>
                                </div>
                                <div className="p-field p-grid">
                                    <label htmlFor="observStrategy" className="col-lg-2 col-md-2 col-sm-12">
                                        Observation Strategy <span style={{ color: 'red' }}>*</span>
                                    </label>
                                    {<ObservationStrategySelector
                                        selectedPurpose={this.state.observStrategyFilters.purpose}
                                        allPurposes={this.templatePurposes}
                                        selectedState={this.state.observStrategyFilters.states}
                                        allStates={this.templateState}
                                        selectedObservationStrategy={this.state.observStrategy}
                                        allObservationStrategies={this.state.observStrategies}
                                        observationIdSet={this.state.observationIdSet}
                                        changeStrategy={this.changeStrategy}
                                        localStoreKey={"strategyFilterSUCreate"}
                                        setState={this.setState}
                                    />}
                                    <div className="col-lg-1 col-md-1 col-sm-12"></div>
                                    <label htmlFor="autodeletion" className="col-lg-2 col-md-2 col-sm-12">Pin
                                        Data</label>
                                    <div className="col-lg-3 col-md-3 col-sm-12" data-testid="autodeletion">
                                        <Checkbox inputId="trigger" role="trigger"
                                            tooltip="Do not delete data automatically after successful ingest"
                                            tooltipOptions={this.tooltipOptions}
                                            checked={this.state.schedulingUnit.output_pinned}
                                            onChange={(e) => this.setSchedUnitParams('output_pinned', e.target.checked)}
                                        ></Checkbox>
                                    </div>

                                </div>
                                {_.keys(this.state.stationGroups).length > 0 &&
                                    <div className='grouping'>
                                        <fieldset>
                                            <h3 className="card-title level-1 je-object__title"
                                                style={{ display: "inline-block" }}>
                                                <button type="button"
                                                    title={this.state.stationsCollapsed ? "Expand" : "Collapse"}
                                                    className="btn btn-secondary btn-sm json-editor-btn-collapse json-editor-btntype-toggle"
                                                    onClick={() => this.setState({ stationsCollapsed: !this.state.stationsCollapsed })}>
                                                    <i className={this.state.stationsCollapsed ? "fas fa-caret-right" : "fas fa-caret-down"}></i>
                                                </button>
                                                <label>Station specification</label>
                                            </h3>
                                            {!this.state.stationsCollapsed &&
                                                <>
                                                    {_.keys(this.state.stationGroups).map((stnGroup) => {
                                                        return <Stations
                                                            taskName={stnGroup}
                                                            stationGroup={this.state.stationGroups[stnGroup]}
                                                            onUpdateStations={this.onUpdateStations.bind(this)}
                                                            height={'auto'}
                                                            key={stnGroup}
                                                        />
                                                    })}
                                                </>
                                            }
                                        </fieldset>
                                    </div>
                                }
                            </div>
                            {this.state.constraintSchema && <div className="p-fluid">
                                <fieldset className="border-style">
                                    <div className="p-col-12" style={{ width: "100%" }}>
                                        <SchedulingConstraint
                                            constraintTemplate={this.state.constraintSchema}
                                            //  initValue={this.state.constraintInitParams}     // No need to pass this value as the values are set with callback
                                            callback={this.setConstraintsEditorOutput}
                                            parentFunction={this.setConstraintEditorFun} />
                                    </div>
                                </fieldset>
                                <div className="p-col-12"
                                    style={{ marginLeft: '0.4em', marginTop: '-10px', paddingTop: '0px' }}>
                                    <label className={this.state.validConstraints ? "info" : "error"}>
                                        {this.state.validConstraintMessage ? this.state.validConstraintMessage : ""}
                                    </label>
                                </div>
                            </div>}
                            <div></div>
                            {this.state.paramsSchema &&
                                <div className="p-fluid">
                                    <fieldset className="border-style">
                                        <div style={{ marginLeft: '-0.5em' }}>
                                            <div className="p-col-12" style={{ width: "100%" }}>
                                                {jeditor}
                                            </div>
                                        </div>
                                    </fieldset>
                                    <div className="p-col-12" style={{
                                        marginLeft: '0.4em',
                                        marginTop: '-10px',
                                        paddingTop: '0px',
                                        marginBottom: "2em"
                                    }}>
                                        <label className={this.state.validSpecification ? "info" : "error"} data-testid="validation-spec-msg">
                                            {this.state.validSpecificationMessage}
                                        </label>
                                    </div>
                                </div>
                            }
                        </div>
                        <div className="p-breadcrumb footer-long-div actions" style={{ marginLeft: '2em !important' }}>
                            <FormActionbar createAnotherCallBack={this.setCreateAnother}
                                createAnother={this.state.createAnother}
                                tooltip="Select checkbox to create another Scheduling Unit after saving this Scheduling Unit"
                                submitTitle={(!this.state.constraintValidEditor || !this.state.validEditor || !this.state.validForm || !this.state.validConstraints || !this.state.validSpecification) ? "" : "Save Scheduling Unit"}
                                onSubmit={this.saveSchedulingUnit}
                                disableSaveBtn={!isSaveEnabled}
                                onCancel={this.checkIsDirty} />
                        </div>
                    </>
                }

                {/* Dialog component to show messages and get input */}
                <div className="p-grid" data-testid="confirm_dialog">
                    {this.state.showAddSet &&
                        <SchedulingSet callbackFunction={this.setSUSet} project={this.state.selectedProject[0]}
                            onCancel={this.refreshSchedulingSet} />
                    }
                    <CustomDialog type="confirmation" visible={this.state.showDialog} width="40vw"
                        header={'Add Scheduling Unit'}
                        message={'Do you want to discard your changes? A new Scheduling Unit will not be created'}
                        content={''} onClose={this.close} actions={[{
                            id: "yes",
                            title: 'Discard',
                            callback: this.cancelCreate,
                            className: 'act-btn-dispose'
                        },
                        { id: "no", title: 'Cancel', className: 'act-btn-cancel', callback: this.close }]}
                    >
                    </CustomDialog>
                </div>
            </React.Fragment>
        );
    }
}

SchedulingUnitCreate.propTypes = {
    match: PropTypes.object,
    history: PropTypes.object,
    location: PropTypes.oneOfType([PropTypes.object, PropTypes.string])
}

export default SchedulingUnitCreate;