diff --git a/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js b/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js index 1a4f0d4290cde1e5be6ce84333dad9622678693a..7cc46ca9851a7529b85dd822b454b4164aa53c20 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/components/JSONEditor/JEditor.js @@ -40,17 +40,25 @@ function Jeditor(props) { if (property["$ref"] && !property["$ref"].startsWith("#")) { // 1st level reference of the object const refUrl = property["$ref"]; let newRef = refUrl.substring(refUrl.indexOf("#")); - if (refUrl.endsWith("/pointing")) { // For type pointing - schema.definitions["pointing"] = (await $RefParser.resolve(refUrl)).get(newRef); - property["$ref"] = newRef; - } else { // General object to resolve if any reference in child level - property = await resolveSchema((await $RefParser.resolve(refUrl)).get(newRef)); - } + //>>>>>> TODO if pointin works fine, remove these commented lines + // if (refUrl.endsWith("/pointing")) { // For type pointing + // schema.definitions["pointing"] = (await $RefParser.resolve(refUrl)).get(newRef); + // property["$ref"] = newRef; + // } else { // General object to resolve if any reference in child level + // property = await resolveSchema((await $RefParser.resolve(refUrl)).get(newRef)); + // } + let defKey = refUrl.substring(refUrl.lastIndexOf("/")+1); + schema.definitions[defKey] = (await $RefParser.resolve(refUrl)).get(newRef); + property["$ref"] = newRef; } else if(property["type"] === "array") { // reference in array items definition let resolvedItems = await resolveSchema(property["items"]); schema.definitions = {...schema.definitions, ...resolvedItems.definitions}; delete resolvedItems['definitions']; property["items"] = resolvedItems; + } else if(property["type"] === "object" && property.properties) { + property = await resolveSchema(property); + schema.definitions = {...schema.definitions, ...property.definitions}; + delete property['definitions']; } properties[propertyKey] = property; } @@ -64,19 +72,34 @@ function Jeditor(props) { } else if (schema["$ref"] && !schema["$ref"].startsWith("#")) { //reference in oneOf list item const refUrl = schema["$ref"]; let newRef = refUrl.substring(refUrl.indexOf("#")); - if (refUrl.endsWith("/pointing")) { - schema.definitions["pointing"] = (await $RefParser.resolve(refUrl)).get(newRef); - schema["$ref"] = newRef; - } else { - schema = await resolveSchema((await $RefParser.resolve(refUrl)).get(newRef)); + //>>>>>> TODO: If pointing works fine, remove these commented lines + // if (refUrl.endsWith("/pointing")) { + // schema.definitions["pointing"] = (await $RefParser.resolve(refUrl)).get(newRef); + // schema["$ref"] = newRef; + // } else { + // schema = await resolveSchema((await $RefParser.resolve(refUrl)).get(newRef)); + // } + let defKey = refUrl.substring(refUrl.lastIndexOf("/")+1); + schema.definitions[defKey] = (await $RefParser.resolve(refUrl)).get(newRef); + if (schema.definitions[defKey].properties) { + let property = await resolveSchema(schema.definitions[defKey]); + schema.definitions = {...schema.definitions, ...property.definitions}; + delete property['definitions']; + schema.definitions[defKey] = property; } + schema["$ref"] = newRef; } return schema; } const init = async () => { - const element = document.getElementById('editor_holder'); + const element = document.getElementById(props.id?props.id:'editor_holder'); let schema = await resolveExternalRef(); + /** If any formatting is done at the parent/implementation component pass the resolved schema + and get the formatted schema like adding validation type, field ordering, etc.,*/ + if (props.defintionFormatter) { + props.defintionFormatter(schema); + } pointingProps = []; // Customize the pointing property to capture angle1 and angle2 to specified format for (const definitionKey in schema.definitions) { @@ -541,7 +564,7 @@ function Jeditor(props) { return ( <React.Fragment> - <div id='editor_holder'></div> + <div id={props.id?props.id:'editor_holder'}></div> </React.Fragment> ); }; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/Scheduling.Constraints.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/Scheduling.Constraints.js index 1bcbcefcbd4a7cd6a5bbb2c2cf96eb7c4b7c2800..fb4232f12ba8e52cbbb9851ef37f428012dba601 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/Scheduling.Constraints.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/Scheduling.Constraints.js @@ -117,20 +117,31 @@ export default (props) => { list.push('disable-field'); } ref.editors['root.time.at'].container.className = list.join(' '); - Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('input')).forEach(input => input.disabled = true); - Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('button')).forEach(button => button.disabled = true); + if (ref.editors['root.time.at'].control) { + Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('input')).forEach(input => input.disabled = true); + Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('button')).forEach(button => button.disabled = true); + } } else { ref.editors['root.time.at'].container.className = ref.editors['root.time.at'].container.className.replace('disable-field', ''); - Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('input')).forEach(input => input.disabled = false); - Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('button')).forEach(button => button.disabled = false); + if (ref.editors['root.time.at'].control) { + Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('input')).forEach(input => input.disabled = false); + Array.prototype.slice.call(ref.editors['root.time.at'].control.getElementsByTagName('button')).forEach(button => button.disabled = false); + } } if (props.callback) { + // Remove 'time' fields if it is empty + for (const key of _.keys(jsonOutput.time)) { + if (!jsonOutput.time[key]) { + delete jsonOutput.time[key]; + } + } props.callback(jsonOutput, errors); } } const constraintStrategy = () => { - const constraintTemplate = { ...props.constraintTemplate } + // const constraintTemplate = { ...props.constraintTemplate } + const constraintTemplate = _.cloneDeep(props.constraintTemplate); if (constraintTemplate.schema) { configureProperties(constraintTemplate.schema.properties); configureDefinitions(constraintTemplate.schema); @@ -183,13 +194,15 @@ export default (props) => { return ( <> {constraintSchema && React.createElement(Jeditor, { + id: "constraint_editor", title: "Scheduling Constraints specification", schema: constraintSchema.schema, callback: onEditForm, initValue: initialValue, disabled: props.disable, formatOutput: props.formatOutput, - parentFunction: parentFunction + parentFunction: parentFunction, + defintionFormatter: configureDefinitions })} </> ); 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 57919d4da296971a9a0523dceb4c9acf00172280..5a25a62050f2652843210ebe61992ffb126ac661 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/ViewSchedulingUnit.js @@ -38,6 +38,7 @@ class ViewSchedulingUnit extends Component{ filter:"select" }, id: "ID", + subTaskID: 'Control ID', name:"Name", description:"Description", created_at:{ @@ -69,6 +70,7 @@ class ViewSchedulingUnit extends Component{ "Status Logs": "filter-input-0", "Type":"filter-input-75", "ID":"filter-input-50", + "Control ID":"filter-input-75", "Cancelled":"filter-input-50", "Duration (HH:mm:ss)":"filter-input-75", "Template ID":"filter-input-50", @@ -128,6 +130,9 @@ class ViewSchedulingUnit extends Component{ .then(tasks =>{ tasks.map(task => { task.status_logs = task.tasktype === "Blueprint"?this.subtaskComponent(task):""; + //Displaying SubTask ID of the 'control' Task + const subTaskIds = task.subTasks?task.subTasks.filter(sTask => sTask.subTaskTemplate.name.indexOf('control') > 1):[]; + task.subTaskID = subTaskIds.length ? subTaskIds[0].id : ''; return task; }); const targetObservation = _.find(tasks, (task)=> {return task.template.type_value==='observation' && task.tasktype.toLowerCase()===schedule_type && task.specifications_doc.station_groups}); @@ -165,9 +170,9 @@ class ViewSchedulingUnit extends Component{ getScheduleUnitTasks(type, scheduleunit){ if(type === 'draft') - return ScheduleService.getTasksBySchedulingUnit(scheduleunit.id, true); + return ScheduleService.getTasksBySchedulingUnit(scheduleunit.id, true, true, true); else - return ScheduleService.getTaskBlueprintsBySchedulingUnit(scheduleunit, true); + return ScheduleService.getTaskBPWithSubtaskTemplateOfSU(scheduleunit); } getScheduleUnit(type, id){ 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 4dba59e7cc582d9ff47663d3130e2dd9efdea3ab..02547c1bc763eb13b960a1f5582a5b6b18b69073 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/create.js @@ -200,7 +200,7 @@ export class SchedulingUnitCreate extends Component { setConstraintsEditorOutput(jsonOutput, errors) { let err = [ ...errors ]; - if (jsonOutput.scheduler === 'online') { + if (jsonOutput.scheduler === 'online' || jsonOutput.scheduler === 'dynamic') { err = err.filter(e => e.path !== 'root.time.at'); } this.constraintParamsOutput = jsonOutput; @@ -299,7 +299,7 @@ export class SchedulingUnitCreate extends Component { async saveSchedulingUnit() { const constStrategy = _.cloneDeep(this.state.constraintParamsOutput); for (let type in constStrategy.time) { - if (constStrategy.scheduler === 'online') { + if (constStrategy.scheduler === 'online' || constStrategy.scheduler === 'dynamic') { delete constStrategy.time.at; } if (!constStrategy.time.after) { diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/summary.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/summary.js index 94ca5e5213e2ac906c878a8d712292d3a6629635..53b1672422eac8ec3525cf2742413f98582656c8 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/summary.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Scheduling/summary.js @@ -171,10 +171,10 @@ export class SchedulingUnitSummary extends Component { <label>Tasks:</label> <ViewTable data={suTaskList} - defaultcolumns={[{id: "ID", start_time:"Start Time", stop_time:"End Time", status: "Status", + defaultcolumns={[{id: "ID", subTaskID: 'Control ID', start_time:"Start Time", stop_time:"End Time", status: "Status", antenna_set: "Antenna Set", band: 'Band'}]} optionalcolumns={[{actionpath: "actionpath"}]} - columnclassname={[{"ID": "filter-input-50", "Start Time": "filter-input-75", "End Time": "filter-input-75", + columnclassname={[{"ID": "filter-input-50","Control ID":"filter-input-75", "Start Time": "filter-input-75", "End Time": "filter-input-75", "Status": "filter-input-75", "Antenna Set": "filter-input-75", "Band": "filter-input-75"}]} defaultSortColumn= {[{id: "ID", desc: false}]} showaction="false" diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js index d1c5a388e915e938b83657ae9e5bf9d3e279de94..b3832124a2b3eef1fe158ff7f64ce7d528cef4eb 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/view.js @@ -150,9 +150,12 @@ export class TimelineView extends Component { canExtendSUList: false, canShrinkSUList:false}); if (fetchDetails) { const suBlueprint = _.find(this.state.suBlueprints, {id: (this.state.stationView?parseInt(item.id.split('-')[0]):item.id)}); - ScheduleService.getTaskBlueprintsBySchedulingUnit(suBlueprint, true) + ScheduleService.getTaskSubTaskBlueprintsBySchedulingUnit(suBlueprint, true) .then(taskList => { for (let task of taskList) { + //Control Task Id + const subTaskIds = (task.subTasks || []).filter(sTask => sTask.subTaskTemplate.name.indexOf('control') > 1); + task. subTaskID = subTaskIds.length ? subTaskIds[0].id : ''; if (task.template.type_value.toLowerCase() === "observation") { task.antenna_set = task.specifications_doc.antenna_set; task.band = task.specifications_doc.filter; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js index 98da19ce7b846b5145f369cc2034e6b4691e21f2..b0fecffd4a08a38fb1a3be8239962d0e5b0b7d6d 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/routes/Timeline/week.view.js @@ -167,10 +167,13 @@ export class WeekTimelineView extends Component { canExtendSUList: false, canShrinkSUList:false}); if (fetchDetails) { const suBlueprint = _.find(this.state.suBlueprints, {id: parseInt(item.id.split('-')[0])}); - ScheduleService.getTaskBlueprintsBySchedulingUnit(suBlueprint, true) + ScheduleService.getTaskSubTaskBlueprintsBySchedulingUnit(suBlueprint) .then(taskList => { const observationTask = _.find(taskList, (task)=> {return task.template.type_value==='observation' && task.specifications_doc.station_groups}); for (let task of taskList) { + //Control Task ID + const subTaskIds = (task.subTasks || []).filter(sTask => sTask.subTaskTemplate.name.indexOf('control') > 1); + task. subTaskID = subTaskIds.length ? subTaskIds[0].id : ''; if (task.template.type_value.toLowerCase() === "observation") { task.antenna_set = task.specifications_doc.antenna_set; task.band = task.specifications_doc.filter; diff --git a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js index 3fc174325d2fb243e1bcaf1bbfaae1e59386e2dd..6e65a0019fe412d16ca82b46e114a9cbc2dd6c92 100644 --- a/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js +++ b/SAS/TMSS/frontend/tmss_webapp/src/services/schedule.service.js @@ -30,6 +30,36 @@ const ScheduleService = { } return res; }, + //>>>>>> TODO: Remove this method by using/modifying other functions with additional parameters + getTaskBPWithSubtaskTemplate: async function(id) { + let result; + try { + result = await axios.get('/api/task_blueprint/'+id); + if (result.data) { + result.data.template = await TaskService.getTaskTemplate(result.data.specifications_template_id); + } + if (result.data) { + let subTasks = []; + let subTasktemplate = {} + for (const subtaskId of result.data.subtasks_ids) { + const subTask = await TaskService.getSubtaskDetails(subtaskId); + //To avoid repeated api call for template if it has already loaded + if (subTasktemplate[subTask.specifications_template_id]) { + subTask.subTaskTemplate = subTasktemplate[subTask.specifications_template_id]; + } else { + const subTaskTemplate = await TaskService.getSubtaskTemplate(subTask.specifications_template_id); + subTask.subTaskTemplate = subTaskTemplate; + subTasktemplate[subTask.specifications_template_id] = subTaskTemplate; + } + subTasks.push((subTask)); + } + result.data.subTasks = subTasks; + } + } catch(error) { + console.error('[schedule.services.getTaskBlueprintById]',error); + } + return result; + }, getSchedulingUnitBlueprintById: async function (id){ try { const response = await axios.get('/api/scheduling_unit_blueprint/'+id); @@ -95,7 +125,27 @@ const ScheduleService = { } return taskblueprintsList; }, - getTasksBySchedulingUnit: async function(id, loadTemplate){ + //>>>>>> TODO: Remove this method by using/modifying other functions with additional parameters + getTaskBPWithSubtaskTemplateOfSU: async function(scheduleunit){ + // there no single api to fetch associated task_blueprint, so iterate the task_blueprint id to fetch associated task_blueprint + let taskblueprintsList = []; + if (scheduleunit.task_blueprints_ids){ + for(const id of scheduleunit.task_blueprints_ids) { + await this.getTaskBPWithSubtaskTemplate(id).then(response =>{ + let taskblueprint = response.data; + taskblueprint['tasktype'] = 'Blueprint'; + taskblueprint['actionpath'] = '/task/view/blueprint/'+taskblueprint['id']; + taskblueprint['blueprint_draft'] = taskblueprint['draft']; + taskblueprint['relative_start_time'] = 0; + taskblueprint['relative_stop_time'] = 0; + taskblueprint.duration = moment.utc((taskblueprint.duration || 0)*1000).format('HH:mm:ss'); + taskblueprintsList.push(taskblueprint); + }) + } + } + return taskblueprintsList; + }, + getTasksBySchedulingUnit: async function(id, loadTemplate, loadSubtasks, loadSubtaskTemplate){ let scheduletasklist=[]; // let taskblueprints = []; // Common keys for Task and Blueprint @@ -132,6 +182,7 @@ const ScheduleService = { // if (o.draft_id === task['id']) return o; // }); + let subTasktemplate = {} for(const blueprint of draftBlueprints){ let taskblueprint = []; taskblueprint['tasktype'] = 'Blueprint'; @@ -150,6 +201,24 @@ const ScheduleService = { if (loadTemplate) { taskblueprint.template = scheduletask.template; } + if (loadSubtasks) { + let subTasks = []; + for (const subtaskId of blueprint.subtasks_ids) { + const subTask = await TaskService.getSubtaskDetails(subtaskId); + if (loadSubtaskTemplate) { + //To avoid repeated api call for template if it has already loaded + if (subTasktemplate[subTask.specifications_template_id]) { + subTask.subTaskTemplate = subTasktemplate[subTask.specifications_template_id]; + } else { + const subTaskTemplate = await TaskService.getSubtaskTemplate(subTask.specifications_template_id); + subTask.subTaskTemplate = subTaskTemplate; + subTasktemplate[subTask.specifications_template_id] = subTaskTemplate; + } + } + subTasks.push((subTask)); + } + taskblueprint.subTasks = subTasks; + } //Add Blue print details to array scheduletasklist.push(taskblueprint); } diff --git a/SAS/TMSS/src/tmss/settings.py b/SAS/TMSS/src/tmss/settings.py index 17ce37cd4ad04d34e3ed17887fb58f27b9319167..7c6334e185e7e757cad6d70c0d69e0ea5cedb546 100644 --- a/SAS/TMSS/src/tmss/settings.py +++ b/SAS/TMSS/src/tmss/settings.py @@ -92,7 +92,8 @@ INSTALLED_APPS = [ 'drf_yasg', 'django_filters', 'material', - 'material.frontend'] + 'material.frontend' + ] MIDDLEWARE = [ 'django.middleware.gzip.GZipMiddleware', diff --git a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py index a657a6531ec6a608c64768ac2905a436e20bec7d..167e451e352b06bbb99c7ad3fdfd337e707a45ca 100644 --- a/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py +++ b/SAS/TMSS/src/tmss/tmssapp/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.9 on 2020-11-30 08:59 +# Generated by Django 3.0.9 on 2020-12-02 20:16 from django.conf import settings import django.contrib.postgres.fields diff --git a/SAS/TMSS/src/tmss/urls.py b/SAS/TMSS/src/tmss/urls.py index 81258f3d806a1fd7937d85240769739c532fbe9e..42c6ac8971fdf9632d1c2de771c1387f8c6845c1 100644 --- a/SAS/TMSS/src/tmss/urls.py +++ b/SAS/TMSS/src/tmss/urls.py @@ -237,6 +237,7 @@ if bool(os.environ.get('TMSS_ENABLE_VIEWFLOW', False)): viewflow_router.register('scheduling_unit_flow/qa_pi_verification', workflow_viewsets.PIVerificationViewSet, basename='qa_pi_verification') viewflow_router.register('scheduling_unit_flow/qa_decide_acceptance', workflow_viewsets.DecideAcceptanceViewSet, basename='qa_decide_acceptance') viewflow_router.register('scheduling_unit_flow/qa_scheduling_unit_process', workflow_viewsets.SchedulingUnitProcessViewSet, basename='qa_scheduling_unit_process') + viewflow_router.register('scheduling_unit_flow/qa_scheduling_unit_task', workflow_viewsets.SchedulingUnitTaskViewSet, basename='qa_scheduling_unit_task') viewflow_urlpatterns.extend(viewflow_router.urls) diff --git a/SAS/TMSS/src/tmss/workflowapp/apps.py b/SAS/TMSS/src/tmss/workflowapp/apps.py index 3ba8ab2cdb3c7e994ebf6bea7850ddc6128b9428..b4d7b07f0d004048aa3fac119f0354ee4bf5a38e 100644 --- a/SAS/TMSS/src/tmss/workflowapp/apps.py +++ b/SAS/TMSS/src/tmss/workflowapp/apps.py @@ -4,5 +4,5 @@ from django.apps import AppConfig class WorkflowappConfig(AppConfig): - name = 'lofar.sas.tmss.tmss.workflowapp' + name = 'workflowapp' diff --git a/SAS/TMSS/src/tmss/workflowapp/flows/schedulingunitflow.py b/SAS/TMSS/src/tmss/workflowapp/flows/schedulingunitflow.py index bcd8c2bdd182d7c82f438054dea08940bf124282..0bf572d1e31c9c7817a845a12d8d6abdbbb23f8f 100644 --- a/SAS/TMSS/src/tmss/workflowapp/flows/schedulingunitflow.py +++ b/SAS/TMSS/src/tmss/workflowapp/flows/schedulingunitflow.py @@ -66,6 +66,7 @@ class Condition(Signal): activation.prepare() if activation.flow_task.condition_check(activation, instance): activation.done() + def ready(self): """Resolve internal `this`-references. and subscribe to the signal.""" @@ -205,7 +206,6 @@ class SchedulingUnitFlow(Flow): logger.info("End of schedulingunit workflow: can_delete: %s, results_accepted: %s", activation.process.can_delete, activation.process.results_accepted) return activation - def check_condition_scheduled(self, activation, instance): if instance is None: instance = activation.process.su diff --git a/SAS/TMSS/src/tmss/workflowapp/migrations/0001_initial.py b/SAS/TMSS/src/tmss/workflowapp/migrations/0001_initial.py index aa03e1a4d75db411590a57f4ec385e3e0d39bd10..8119f3254e3b5d89bd1593f16b715b9d6f2d0d7a 100644 --- a/SAS/TMSS/src/tmss/workflowapp/migrations/0001_initial.py +++ b/SAS/TMSS/src/tmss/workflowapp/migrations/0001_initial.py @@ -1,4 +1,4 @@ -# Generated by Django 3.0.9 on 2020-11-26 09:54 +# Generated by Django 3.0.9 on 2020-12-02 20:16 from django.db import migrations, models import django.db.models.deletion @@ -9,6 +9,7 @@ class Migration(migrations.Migration): initial = True dependencies = [ + ('tmssapp', '0001_initial'), ('viewflow', '0008_jsonfield_and_artifact'), ] @@ -45,19 +46,6 @@ class Migration(migrations.Migration): ('operator_accept', models.BooleanField(default=False)), ], ), - migrations.CreateModel( - name='HelloWorldProcess', - fields=[ - ], - options={ - 'verbose_name': 'World Request', - 'verbose_name_plural': 'World Requests', - 'proxy': True, - 'indexes': [], - 'constraints': [], - }, - bases=('viewflow.process',), - ), migrations.CreateModel( name='SchedulingUnitProcess', fields=[ diff --git a/SAS/TMSS/src/tmss/workflowapp/models/__init__.py b/SAS/TMSS/src/tmss/workflowapp/models/__init__.py index a0ae3713747c0b28c5595736d06f4bcb800da5b5..bfdfbc84e07beb363937412fd7fb6d5788c684d0 100644 --- a/SAS/TMSS/src/tmss/workflowapp/models/__init__.py +++ b/SAS/TMSS/src/tmss/workflowapp/models/__init__.py @@ -1,2 +1 @@ -from .helloworldflow import * from .schedulingunitflow import * \ No newline at end of file diff --git a/SAS/TMSS/src/tmss/workflowapp/models/schedulingunitflow.py b/SAS/TMSS/src/tmss/workflowapp/models/schedulingunitflow.py index c883b4fc9a3c857e2c2913df064c629d16239619..d33f462ed653833794709d701e3d0e0be47f05a4 100644 --- a/SAS/TMSS/src/tmss/workflowapp/models/schedulingunitflow.py +++ b/SAS/TMSS/src/tmss/workflowapp/models/schedulingunitflow.py @@ -1,7 +1,9 @@ # Create your models here. from django.db.models import CharField, IntegerField,BooleanField, ForeignKey, CASCADE, Model,NullBooleanField -from viewflow.models import Process +from viewflow.models import Process, Task +from viewflow.fields import FlowReferenceField +from viewflow.compat import _ from lofar.sas.tmss.tmss.tmssapp.models import SchedulingUnitBlueprint diff --git a/SAS/TMSS/src/tmss/workflowapp/serializers/schedulingunitflow.py b/SAS/TMSS/src/tmss/workflowapp/serializers/schedulingunitflow.py index 884061c224168ac706def57a833c5ee9cb7952bd..86a87874a523eb8c481e97d28141c2ed221f675f 100644 --- a/SAS/TMSS/src/tmss/workflowapp/serializers/schedulingunitflow.py +++ b/SAS/TMSS/src/tmss/workflowapp/serializers/schedulingunitflow.py @@ -4,6 +4,8 @@ from lofar.sas.tmss.tmss.workflowapp import models from django.views import generic from django.forms.models import modelform_factory +from viewflow.models import Task + from .. import forms @@ -31,5 +33,10 @@ class DecideAcceptanceSerializer(ModelSerializer): class SchedulingUnitProcessSerializer(ModelSerializer): class Meta: - model = models.SchedulingUnitProcess - fields = '__all__' \ No newline at end of file + model = models.SchedulingUnitProcess + fields = ['su','active_task','qa_reporting_to','qa_reporting_sos','pi_verification','decide_acceptance','can_delete','results_accepted','created','finished'] + +class SchedulingUnitTaskSerializer(ModelSerializer): + class Meta: + model = Task + fields = '__all__' \ No newline at end of file diff --git a/SAS/TMSS/src/tmss/workflowapp/viewsets/schedulingunitflow.py b/SAS/TMSS/src/tmss/workflowapp/viewsets/schedulingunitflow.py index 530d4cb8f9c0207c4c12212c1a4bce7832aa8d29..acaa7459631c3341df848686df8f8ba371f2dbd4 100644 --- a/SAS/TMSS/src/tmss/workflowapp/viewsets/schedulingunitflow.py +++ b/SAS/TMSS/src/tmss/workflowapp/viewsets/schedulingunitflow.py @@ -11,6 +11,7 @@ from viewflow.flow.views.utils import get_next_task_url from django.forms import CharField, CheckboxInput from django.forms.models import modelform_factory +from viewflow.models import Task from .. import forms, models, serializers @@ -36,6 +37,10 @@ class SchedulingUnitProcessViewSet(viewsets.ModelViewSet): queryset = models.SchedulingUnitProcess.objects.all() serializer_class = serializers.SchedulingUnitProcessSerializer +class SchedulingUnitTaskViewSet(viewsets.ModelViewSet): + queryset = Task.objects.all() + serializer_class = serializers.SchedulingUnitTaskSerializer + class QAReportingTOView(FlowMixin, generic.CreateView): template_name = 'qa_reporting.html' model = models.QAReportingTO