diff --git a/SAS/TMSS/frontend/tmss_webapp/package-lock.json b/SAS/TMSS/frontend/tmss_webapp/package-lock.json index f3438a4a4072b85ea86b5307b8e773313fe26efc..7ececae727107c3fe821be83e41c8d66969a854c 100644 --- a/SAS/TMSS/frontend/tmss_webapp/package-lock.json +++ b/SAS/TMSS/frontend/tmss_webapp/package-lock.json @@ -17,7 +17,7 @@ "cleave.js": "^1.6.0", "katex": "^0.16.11", "match-sorter": "^6.3.4", - "@astron-sd/telescope-specification": "^0.0.111", + "@astron-sd/telescope-specification": "^0.0.114", "axios": "^1.7.7", "immer": "^10.1.1", "jspdf": "^2.5.2", @@ -5243,9 +5243,9 @@ } }, "node_modules/@grafana/faro-core": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@grafana/faro-core/-/faro-core-1.12.0.tgz", - "integrity": "sha512-TRMJzoqsMJ+3QYIv+nrbDjxpcu8hlY652bH0OXSy6Uh5+g3ZH+ycb2OCEwR5X9RA00kWZNgAp7w4KeVjS6/IPg==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-core/-/faro-core-1.12.1.tgz", + "integrity": "sha512-5kZMwFMK+vaWXb2jIds18Fbb36hMOqYEFLkg3MrPxEqMh7uGzMpwrgftVQz0vNM9JAkg8BIO0cBJmR65ThHZXA==", "dependencies": { "@opentelemetry/api": "^1.9.0", "@opentelemetry/otlp-transformer": "^0.53.0" @@ -12206,9 +12206,9 @@ } }, "node_modules/@types/node": { - "version": "22.9.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.0.tgz", - "integrity": "sha512-vuyHg81vvWA1Z1ELfvLko2c8f34gyA0zaic0+Rllc5lbCnbSyuvb2Oxpm6TAUAC/2xZN3QGqxBNggD1nNR2AfQ==", + "version": "22.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.9.1.tgz", + "integrity": "sha512-p8Yy/8sw1caA8CdRIQBG5tiLHmxtQKObCijiAa9Ez+d4+PRffM4054xbju0msf+cvhJpnFEeNjxmVT/0ipktrg==", "dependencies": { "undici-types": "~6.19.8" } @@ -16579,12 +16579,12 @@ } }, "node_modules/@grafana/faro-react": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@grafana/faro-react/-/faro-react-1.12.0.tgz", - "integrity": "sha512-gWvuXPbr41syIXfIQc3So1f6wixu0CySnTMI8x1cPQIGlZukGOR0vHYCUCdWLgwgBOgSdNtqUFW7pme3ctmHvA==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-react/-/faro-react-1.12.1.tgz", + "integrity": "sha512-9Z3l0pgUh3cc7zYBcgag9y7vseHK84n9PjuOhod1nqeU3Nj0GRdwyfU8mBK5EeglpVKIh/fililnsN4DG0x3Kw==", "dependencies": { - "@grafana/faro-web-sdk": "^1.12.0", - "@grafana/faro-web-tracing": "^1.12.0", + "@grafana/faro-web-sdk": "^1.12.1", + "@grafana/faro-web-tracing": "^1.12.1", "hoist-non-react-statics": "^3.3.2" }, "peerDependencies": { @@ -16754,9 +16754,9 @@ } }, "node_modules/@astron-sd/telescope-specification": { - "version": "0.0.111", - "resolved": "https://git.astron.nl/api/v4/projects/645/packages/npm/@astron-sd/telescope-specification/-/@astron-sd/telescope-specification-0.0.111.tgz", - "integrity": "sha1-Z+kWu6UsDdhcrIqvX/l78tLlK6A=", + "version": "0.0.114", + "resolved": "https://git.astron.nl/api/v4/projects/645/packages/npm/@astron-sd/telescope-specification/-/@astron-sd/telescope-specification-0.0.114.tgz", + "integrity": "sha1-QLz99vbusAwHeK/ikjqW3t484tA=", "dependencies": { "install": "^0.13.0", "npm": "^10.8.1" @@ -16859,11 +16859,11 @@ "dev": true }, "node_modules/@grafana/faro-web-tracing": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@grafana/faro-web-tracing/-/faro-web-tracing-1.12.0.tgz", - "integrity": "sha512-yN+sP4IjtYfQheT5PbS5gVXcQxMr4y3OJtBlyca8w5Lwv8qBimTksI+WD/DrAO89omT5S37zshe7yHRenb+VhQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-web-tracing/-/faro-web-tracing-1.12.1.tgz", + "integrity": "sha512-or2q+2xe/q1vXGtaM2hVRRbwRJZun3klJL02XdKrgf9ib8M40VglqXfwGQKbqzm+MZ9eBB7PC/j5OL+GDrkLqQ==", "dependencies": { - "@grafana/faro-web-sdk": "^1.12.0", + "@grafana/faro-web-sdk": "^1.12.1", "@opentelemetry/api": "^1.9.0", "@opentelemetry/context-zone": "1.26.0", "@opentelemetry/core": "^1.26.0", @@ -19178,9 +19178,9 @@ } }, "node_modules/@kurkle/color": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.2.tgz", - "integrity": "sha512-fuscdXJ9G1qb7W8VdHi+IwRqij3lBkosAm4ydQtEmbY58OzHXqQhvlxqEkoz0yssNVn38bcpRWgA9PP+OGoisw==" + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==" }, "node_modules/@testing-library/jest-dom": { "version": "6.6.3", @@ -20534,11 +20534,11 @@ } }, "node_modules/@grafana/faro-web-sdk": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/@grafana/faro-web-sdk/-/faro-web-sdk-1.12.0.tgz", - "integrity": "sha512-EWa7Kmx7Mwf8aReZ+zTJ8I1rstnyM5plBYbpQNNYjKeh1owcc4dLUECGYVx/nuskrPsoAioKfrdxjmUksBwCEQ==", + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/@grafana/faro-web-sdk/-/faro-web-sdk-1.12.1.tgz", + "integrity": "sha512-uypcWtPG1kj7ZVenl4nTF2gy7conn32MQZM2F4/S7/e2W4Y3J8Sni4RruekQCbgbfF/7LGQls4Sa+LhUXvzXwA==", "dependencies": { - "@grafana/faro-core": "^1.12.0", + "@grafana/faro-core": "^1.12.1", "ua-parser-js": "^1.0.32", "web-vitals": "^4.0.1" } @@ -24910,9 +24910,9 @@ } }, "node_modules/immutable": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.2.tgz", - "integrity": "sha512-1NU7hWZDkV7hJ4PJ9dur9gTNQ4ePNPN4k9/0YhwjzykTi/+3Q5pF93YU5QoVj8BuOnhLgaY8gs0U2pj4kSYVcw==" + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-5.0.3.tgz", + "integrity": "sha512-P8IdPQHq3lA1xVeBRi5VPqUm5HDgKnx0Ru51wZz5mjxHr5n3RWhjIpOFU7ybkUxfB+5IToy+OLaHYDBIWsv+uw==" }, "node_modules/postcss-nesting": { "version": "10.2.0", @@ -28590,9 +28590,9 @@ } }, "node_modules/yaml": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.0.tgz", - "integrity": "sha512-a6ae//JvKDEra2kdi1qzCyrJW/WZCgFi8ydDV+eXExl95t+5R+ijnqHJbz9tmMh8FUjx3iv2fCQ4dclAQlO2UQ==", + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.6.1.tgz", + "integrity": "sha512-7r0XPzioN/Q9kXBro/XPnA6kznR73DHq+GXh5ON7ZozRO6aMjbmiBuKste2wslTFkC5d1dw0GooOCepZXJ2SAg==", "dev": true, "bin": { "yaml": "bin.mjs" diff --git a/SAS/TMSS/frontend/tmss_webapp/package.json b/SAS/TMSS/frontend/tmss_webapp/package.json index c0674d09c7e96a4bf212fc65e334177b0ef16c86..2026877d1b5fae3ed31062abbf26e85b5f442d48 100644 --- a/SAS/TMSS/frontend/tmss_webapp/package.json +++ b/SAS/TMSS/frontend/tmss_webapp/package.json @@ -5,7 +5,7 @@ "dependencies": { "@ag-grid-community/all-modules": "^24.1.0", "@apidevtools/json-schema-ref-parser": "^11.7.0", - "@astron-sd/telescope-specification": "^0.0.111", + "@astron-sd/telescope-specification": "^0.0.114", "@fortawesome/fontawesome-free": "^6.6.0", "@grafana/faro-react": "^1.9.1", "@json-editor/json-editor": "^2.14.1", diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Report/cycle/report.business.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Report/cycle/report.business.js index 1ed99904b0ddc57992a7479efc89997ce7338931..2af3d38431aa4a9ea74fdd82ded5df9ce0108869 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Report/cycle/report.business.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Report/cycle/report.business.js @@ -75,9 +75,9 @@ const ReportBusiness = { const cycleData = repData.data_ingested_per_site_and_category?.categories; categoryData['cycle'] = repData.cycle; categoryData['rawIF'] = cycleData?.["MeasurementSet Visibilities from Observation"]?.size__sum / dataConversionFactor - categoryData['rawBF'] = cycleData?.["Beamformed Timeseries"].size__sum / dataConversionFactor + categoryData['rawBF'] = cycleData?.["Beamformed Timeseries"]?.size__sum / dataConversionFactor categoryData['preprocIF'] = cycleData?.["MeasurementSet Visibilities from Pipeline"]?.size__sum / dataConversionFactor - categoryData['pulpBF'] = cycleData?.["Pulsar Dataproducts"].size__sum / dataConversionFactor + categoryData['pulpBF'] = cycleData?.["Pulsar Dataproducts"]?.size__sum / dataConversionFactor reportData.push(categoryData); return repData; }); diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.cev.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.cev.js index 191a09d9fab8ba0a8a2d7eb75b38734c1b899f8c..5b819890a58134a4618b8b4652cbfc3c2c4ad6b2 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.cev.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Reservation/reservation.cev.js @@ -504,9 +504,9 @@ export function ReservationCreate(props) { } if (reservation.duration) { - var values = reservation.duration.split(' '); - var days = values[0]; - var dValues = values[1].split(':'); + const values = reservation.duration.split(' '); + const days = values[0]; + const dValues = values[1].split(':'); delete errors['duration']; if ((days * 1) === 0 && (dValues[0] * 1) === 0 && (dValues[1] * 1) === 0 && (dValues[2] * 1) === 0) { validForm = false; 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 3911a2bc351f92529df41e9bf8f9af753d4883b8..dccf2c65d55ba70adfe8a46f8557814d814a047d 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js @@ -2917,6 +2917,7 @@ definition={this.state.scheduleunit} strategy={this.state.scheduleunit?.observation_strategy_template} disable={true} + theme="html" paramsOutput = {this.state.paramsOutput} ></SpecificationDetailsForm> } diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js index d1828cf4a405646bcfcd4d784f2efd1272beb189..6297f8de8348a0057bb3dcc0e440a75cbd4f26d1 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js @@ -2,7 +2,6 @@ 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 { publish } from "../../App"; import { Checkbox } from "primereact/checkbox"; import { InputText } from "primereact/inputtext"; @@ -11,15 +10,9 @@ import { Dropdown } from "primereact/dropdown"; import { Toast } from "primereact/toast"; import AppLoader from "../../layout/components/AppLoader"; import { - Jeditor, - UnitConverter, - SchedulingConstraints, - Stations, - Station, + UnitConverter, getConstraintTemplate, - getTaskTemplateForTask, - ParserUtility, - prepareUpdateConstraintsParameters + SpecificationDetailsForm } from "@astron-sd/telescope-specification"; import ProjectService from "../../services/project.service"; import ScheduleService from "../../services/schedule.service"; @@ -49,7 +42,6 @@ export class SchedulingUnitCreate extends Component { states: ["active"], purpose: [], }, - constraintValidEditor: false, validForm: false, validConstraints: false, validSpecification: false, @@ -64,15 +56,8 @@ export class SchedulingUnitCreate extends Component { 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: "", @@ -88,14 +73,12 @@ export class SchedulingUnitCreate extends Component { 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 @@ -118,17 +101,13 @@ export class SchedulingUnitCreate extends Component { }, }; 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); @@ -137,10 +116,10 @@ export class SchedulingUnitCreate extends Component { 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); + this.handleDefinitionCallback = this.handleDefinitionCallback.bind(this) } componentDidMount() { @@ -224,6 +203,7 @@ export class SchedulingUnitCreate extends Component { observStrategyFilter = { states: ["active"], purpose: [] }; } + this.setState({ observStrategies: await this.getMatchingObservationStrategyTemplates( observStrategyFilter @@ -233,7 +213,9 @@ export class SchedulingUnitCreate extends Component { } async getMatchingObservationStrategyTemplates(filters) { - return await queryMatchingObservationStrategyTemplates(filters); + let observationStrategyTemplates = await queryMatchingObservationStrategyTemplates(filters); + console.log("getMatchingObservationStrategyTemplates",filters,observationStrategyTemplates) + return observationStrategyTemplates } getStrategyFilterOptions(filterValues, filterId) { @@ -275,163 +257,56 @@ export class SchedulingUnitCreate extends Component { if (!this.state.isDirty) { publish("edit-dirty", true); } - + const projectValid = this.validateForm("project", projectName, schedulingUnit) + const scheduling_set_id_valid = this.validateForm("scheduling_set_id") + if (this.isDebuggLoggingEnabled) console.log("projectValid:" + projectValid + " scheduling_set_id_valid:"+scheduling_set_id_valid) 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 + validForm:projectValid && scheduling_set_id_valid + , // project is valid, we selected, but we deselected scheduling isDirty: true, }); } + + + async handleDefinitionCallback (definition , status) { + this.setState({validConstraints : status.isValidConstraintsEditor}) + this.setState({validSpecification : status.isValidTaskEditor}) + this.setState({ updatedObservStrategy: definition }); + }; + + + /** * 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({ + + console.log("changing strategy to " + strategyId,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); - console.log("so refparser is from",observStrategy.template) - console.log("so refparser is to", $strategyRefs ) - - // 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]); - console.log("and stations groups sais", stationGroups[param.name]) - } 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(() => { @@ -440,25 +315,7 @@ export class SchedulingUnitCreate extends Component { } } - /** - * 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 @@ -525,106 +382,7 @@ export class SchedulingUnitCreate extends Component { } } - 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) { - try { - this.state.constraintEditorFunction("setValue", [parentProps]); - } - catch (ex) - { - console.log("Error calling constraintsEditorFunction",ex); - } - } - } - - setConstraintsEditorOutput(jsonOutput, errors) { - let err = [...errors]; - if ( jsonOutput.scheduler === "online" || jsonOutput.scheduler === "dynamic" ) { err = err.filter((e) => e.path !== "root.time.at"); - } - console.log("setConstraintsEditorOutput",jsonOutput,errors); - 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 @@ -676,19 +434,15 @@ export class SchedulingUnitCreate extends Component { { 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 ); } } @@ -789,113 +543,24 @@ export class SchedulingUnitCreate extends Component { 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; + return validForm ; } - validateStations =()=> { - return Station.ValidateStations(this.state.stationGroups,this.state.selectedStationsOfTask,this.state.customStationsOfTask,this.state.missingStationsofTask) - - } - /** - * Function to update task parameters - */ - async updateParameters() { - let observStrategy = await this.reparseParameters(); - 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 }); - } - - - async reparseParameters() { - - - - let observStrategy = _.cloneDeep(this.state.observStrategy); - const $refs = await $RefParser.resolve(observStrategy.template); - observStrategy.template.parameters.forEach(async (param, index) => { - 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++; - } - }); - return observStrategy; - - } - - /** - * Function to update constraints - */ - updateConstraintsParams() { - const const_strategy = prepareUpdateConstraintsParameters(this.state.constraintParamsOutput, 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 }); - } @@ -903,31 +568,17 @@ export class SchedulingUnitCreate extends Component { * 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.observation_strategy_template_id = this.state.observStrategy.id; schedulingUnit.rank = schedulingUnit.rank === undefined || schedulingUnit.rank === "" ? 0 : schedulingUnit.rank.toFixed(4); schedulingUnit = await ScheduleService.saveSchedulingUnit( schedulingUnit, - newSpecificationDoc + observStrategy ); if (schedulingUnit.isSUUpdated) { if (appGrowl === null) { @@ -1001,8 +652,6 @@ export class SchedulingUnitCreate extends Component { name, version ); - console.log("Requested Constraint version "+ version, " and got ",strategyConstraint) - console.log("all templates are",this.constraintTemplates) let schedulingUnit = { ...this.state.schedulingUnit }; schedulingUnit.scheduling_constraints_template_id = strategyConstraint ? strategyConstraint.id @@ -1069,7 +718,6 @@ export class SchedulingUnitCreate extends Component { observStrategy: {}, paramsSchema: null, paramsOutput: null, - validEditor: false, validFields: {}, constraintSchema: null, constraintInitParams: null, @@ -1084,69 +732,7 @@ export class SchedulingUnitCreate extends Component { 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); @@ -1185,11 +771,9 @@ export class SchedulingUnitCreate extends Component { render() { - console.log("template",this.state.constraintSchema) + console.log("constraintSchema =",this.state.constraintSchema) let isSaveEnabled = - this.state.constraintValidEditor && - this.state.validEditor && this.state.validForm && this.state.validConstraints && this.state.validSpecification; @@ -1198,10 +782,6 @@ export class SchedulingUnitCreate extends Component { console.log( "isSaveEnabled: " + isSaveEnabled + - " constraintValidEditor: " + - this.state.constraintValidEditor + - " ,vvalidEditor:" + - this.state.validEditor + " ,validForm:" + this.state.validForm + " ,validConstraints:" + @@ -1212,30 +792,17 @@ export class SchedulingUnitCreate extends Component { 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; + const { scheduleunit_draft } = this.state.userrole; + - 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={[ { @@ -1251,17 +818,17 @@ export class SchedulingUnitCreate extends Component { <AppLoader /> ) : ( <> - <div> + <div style={{overflow:"hidden"}}> <div className="p-fluid"> <div className="p-field p-grid"> <label htmlFor="schedUnitName" - className="col-lg-2 col-md-2 col-sm-12" + className="col-lg-2 col-md-2 col-sm-2" > Name <span style={{ color: "red" }}>*</span> </label> <div - className="col-lg-3 col-md-3 col-sm-12" + className="col-lg-3 col-md-3 col-sm-3" data-testid="namediv" > <InputText @@ -1299,14 +866,14 @@ export class SchedulingUnitCreate extends Component { : "Max 128 characters"} </label> </div> - <div className="col-lg-1 col-md-1 col-sm-12"></div> + <div className="col-lg-1 col-md-1 col-sm-1"></div> <label htmlFor="description" - className="col-lg-2 col-md-2 col-sm-12" + className="col-lg-2 col-md-2 col-sm-2" > Description <span style={{ color: "red" }}>*</span> </label> - <div className="col-lg-3 col-md-3 col-sm-12"> + <div className="col-lg-3 col-md-3 col-sm-3"> <InputTextarea className={ this.state.errors.description && @@ -1363,11 +930,11 @@ export class SchedulingUnitCreate extends Component { /> } <div className="p-field p-grid"> - <label htmlFor="rank" className="col-lg-2 col-md-2 col-sm-12"> + <label htmlFor="rank" className="col-lg-2 col-md-2 col-sm-2"> Rank </label> <div - className="col-lg-3 col-md-3 col-sm-12" + className="col-lg-3 col-md-3 col-sm-3" data-testid="rank" > <input @@ -1387,14 +954,14 @@ export class SchedulingUnitCreate extends Component { } /> </div> - <div className="col-lg-1 col-md-1 col-sm-12"></div> + <div className="col-lg-1 col-md-1 col-sm-1"></div> <label htmlFor="priority_queue" - className="col-lg-2 col-md-2 col-sm-12" + className="col-lg-2 col-md-2 col-sm-2" > Priority Queue </label> - <div className="col-lg-3 col-md-3 col-sm-10"> + <div className="col-lg-3 col-md-3 col-sm-3"> <Dropdown data-testid="priority_queue" id="priority_queue" @@ -1414,7 +981,7 @@ export class SchedulingUnitCreate extends Component { <div className="p-field p-grid"> <label htmlFor="observStrategy" - className="col-lg-2 col-md-2 col-sm-12" + className="col-lg-2 col-md-2 col-sm-2" > Observation Strategy <span style={{ color: "red" }}>*</span> </label> @@ -1491,128 +1058,27 @@ export class SchedulingUnitCreate extends Component { </div> </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 - commonSchemaTemplate={ - this.state.commonSchemaTemplate - } - taskName={stnGroup} - stationGroup={ - this.state.stationGroups[stnGroup] - } - onUpdateStations={this.onUpdateStations.bind( - this - )} - height={"auto"} - key={stnGroup} - /> - ); - })} - </> - )} - </fieldset> - </div> - )} - </div> - <div style={{display:"flex"}}> - + - {this.state.paramsSchema && ( - <div className="p-fluid" style={{ width: "50%" }}> - <fieldset className="border-style"> - <div style={{ marginLeft: "-0.5em" }}> - <div className="p-col-12"> - {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> + <div style={{ width: "100%" }}> + {this.state.constraintSchema && <SpecificationDetailsForm + isDebugLoggingEnabled={true} + commonSchemaTemplate={this.state.commonSchemaTemplate} + GetSystemUTC={UtilService.getUTC} + taskFilters={this.taskFilters.data} + taskTemplates={this.taskTemplates} + constraintTemplates={this.constraintTemplates} + definition={this.state.scheduleunit} + strategy={this.state.observStrategy} + key={this.state.observStrategy.id} + definitionCallback={this.handleDefinitionCallback} + theme="html" + ></SpecificationDetailsForm> + } + </div> -{this.state.constraintSchema && ( - <div className="p-fluid" style={{ width: "50%" }}> - <fieldset className="border-style"> - <div className="p-col-12" > - <SchedulingConstraints - formatOutput = {true} - GetSystemUTC={UtilService.getUTC} - 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> <div @@ -1624,11 +1090,7 @@ export class SchedulingUnitCreate extends Component { 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 + !isSaveEnabled ? "" : "Save Scheduling Unit" }