Skip to content

Commit a90a6dc

Browse files
committed
Added zoom to metadata, tested rigorously
1 parent eec8678 commit a90a6dc

File tree

3 files changed

+58
-72
lines changed

3 files changed

+58
-72
lines changed

apps/dashboard/app/controllers/workflows_controller.rb

Lines changed: 41 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,7 @@ class WorkflowsController < ApplicationController
66

77
# GET /projects/:id/workflows/:id
88
def show
9-
@project = Project.find(project_id)
10-
@workflow = Workflow.find(workflow_id, project_directory)
9+
return unless load_project_and_workflow_objects
1110
launcher_ids = @workflow.launcher_ids
1211

1312
@launchers = Launcher.all(project_directory).select { |l| launcher_ids.include?(l.id) }
@@ -21,22 +20,14 @@ def new
2120

2221
# GET /projects/:id/workflows/edit
2322
def edit
24-
@workflow = Workflow.find(workflow_id, project_directory)
23+
return unless load_project_and_workflow_objects
2524
@launchers = Launcher.all(project_directory)
26-
27-
return unless @workflow.nil?
28-
redirect_to project_path(project_id), notice: I18n.t('dashboard.jobs_workflow_not_found', workflow_id: workflow_id)
2925
end
3026

3127
# TODO to remove this with launcher_ids as we will need them after new UI
3228
# PATCH /projects/:id/workflows/patch
3329
def update
34-
@workflow = Workflow.find(workflow_id, project_directory)
35-
36-
if @workflow.nil?
37-
redirect_to project_path(project_id), notice: I18n.t('dashboard.jobs_workflow_not_found', workflow_id: workflow_id)
38-
return
39-
end
30+
return unless load_project_and_workflow_objects
4031

4132
if @workflow.update(update_params, true)
4233
redirect_to project_path(project_id), notice: I18n.t('dashboard.jobs_workflow_manifest_updated')
@@ -58,12 +49,7 @@ def create
5849

5950
# DELETE /projects/:id/workflows/:id
6051
def destroy
61-
@workflow = Workflow.find(workflow_id, project_directory)
62-
63-
if @workflow.nil?
64-
redirect_to project_path(project_id), notice: I18n.t('dashboard.jobs_workflow_not_found', workflow_id: workflow_id)
65-
return
66-
end
52+
return unless load_project_and_workflow_objects
6753

6854
if @workflow.destroy!
6955
redirect_to project_path(project_id), notice: I18n.t('dashboard.jobs_workflow_deleted')
@@ -74,18 +60,8 @@ def destroy
7460

7561
# POST /projects/:project_id/workflows/:id/save
7662
def save
77-
@project = Project.find(project_id)
78-
@workflow = Workflow.find(workflow_id, project_directory)
79-
if @workflow.nil?
80-
return render json: { status: 'error', message: not_found_msg }, status: :not_found
81-
end
82-
83-
data = permit_json_data
84-
boxes = data["boxes"] || []
85-
edges = data["edges"] || []
86-
saved_at = data["saved_at"] || Time.now.to_i
87-
88-
status = @workflow.update(metadata_params(boxes, edges, saved_at))
63+
return unless load_project_and_workflow_objects(render_json: true)
64+
status = @workflow.update(metadata_params(permit_json_data))
8965
if status
9066
render json: { status: "ok", message: "Workflow saved successfully" }
9167
else
@@ -95,41 +71,30 @@ def save
9571

9672
# GET /projects/:project_id/workflows/:id/load
9773
def load
98-
@project = Project.find(project_id)
99-
@workflow = Workflow.find(workflow_id, project_directory)
100-
if @workflow.nil?
101-
return render json: { status: 'error', message: not_found_msg }, status: :not_found
102-
end
103-
74+
return unless load_project_and_workflow_objects(render_json: true)
10475
manifest_path = @workflow.manifest_file
10576
unless File.exist?(manifest_path)
10677
return render json: { status: 'error', message: 'No saved workflow manifest found.' }, status: :not_found
10778
end
10879

10980
data = YAML.load_file(manifest_path)
11081
metadata = data['metadata'] || {}
111-
11282
render json: {
11383
status: 'ok',
11484
boxes: metadata['boxes'] || [],
11585
edges: metadata['edges'] || [],
86+
zoom: metadata['zoom'] || 1.0,
11687
saved_at: metadata['saved_at'] || nil
11788
}
11889
end
11990

12091

12192
# POST /projects/:project_id/workflows/:id/submit
12293
def submit
123-
@project = Project.find(project_id)
124-
@workflow = Workflow.find(workflow_id, project_directory)
125-
126-
data = permit_json_data
127-
boxes = data["boxes"] || []
128-
edges = data["edges"] || []
129-
saved_at = data["saved_at"] || Time.now.to_i
130-
131-
@workflow.update(metadata_params(boxes, edges, saved_at))
132-
result = @workflow.submit(submit_params(boxes, edges))
94+
return unless load_project_and_workflow_objects(render_json: true)
95+
metadata = metadata_params(permit_json_data)
96+
@workflow.update(metadata)
97+
result = @workflow.submit(submit_params(metadata))
13398
if result
13499
render json: { status: "ok", message: "Workflow submitted successfully" }
135100
else
@@ -140,6 +105,19 @@ def submit
140105

141106
private
142107

108+
def load_project_and_workflow_objects(render_json: false)
109+
@project = Project.find(project_id)
110+
@workflow = Workflow.find(workflow_id, project_directory)
111+
return true if @workflow.present?
112+
113+
if render_json
114+
render json: { status: 'error', message: I18n.t('dashboard.jobs_workflow_not_found', workflow_id: workflow_id) }, status: :not_found
115+
else
116+
redirect_to project_path(project_id), notice: I18n.t('dashboard.jobs_workflow_not_found', workflow_id: workflow_id)
117+
end
118+
false
119+
end
120+
143121
def index_params
144122
params.permit(:project_id).to_h.symbolize_keys
145123
end
@@ -165,11 +143,12 @@ def update_params
165143
.permit(:name, :description, :id, launcher_ids: [])
166144
end
167145

168-
def submit_params(boxes, edges)
146+
def submit_params(metadata)
147+
meta = metadata[:metadata] || {}
169148
{
170-
launcher_ids: boxes.map { |b| b["id"] },
171-
source_ids: edges.map { |e| e["from"] },
172-
target_ids: edges.map { |e| e["to"] },
149+
launcher_ids: meta[:boxes].map { |b| b["id"] },
150+
source_ids: meta[:edges].map { |e| e["from"] },
151+
target_ids: meta[:edges].map { |e| e["to"] },
173152
project_dir: project_directory
174153
}
175154
end
@@ -179,11 +158,19 @@ def project_directory
179158
end
180159

181160
def permit_json_data
182-
params.permit(:project_id, :id, :saved_at, boxes: [:id, :title, :row, :col], edges: [:from, :to]).to_h
161+
params.permit(:project_id, :id, :zoom, :saved_at, boxes: [:id, :title, :row, :col], edges: [:from, :to]).to_h
183162
end
184163

185-
def metadata_params(boxes, edges, saved_at)
186-
{ metadata: { boxes: boxes, edges: edges, saved_at: saved_at} }
164+
def metadata_params(json)
165+
{
166+
metadata:
167+
{
168+
boxes: json["boxes"] || [],
169+
edges: json["edges"] || [],
170+
zoom: json["zoom"] || 1.0,
171+
saved_at: json["saved_at"] || Time.now.to_i
172+
}
173+
}
187174
end
188175

189176
def handle_workflow_error(operation)

apps/dashboard/app/javascript/workflows.js

Lines changed: 16 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@ import { DAG } from './dag.js';
66

77
// Handles boxes, edges, auto-save, auto-load and saving to workflow model
88
class WorkflowState {
9-
constructor(projectId, workflowId, boxes, edges, dag, saveUrl, submitUrl, loadUrl) {
9+
constructor(projectId, workflowId, boxes, edges, dag, pointer, baseUrl) {
1010
this.projectId = projectId;
1111
this.workflowId = workflowId;
1212
this.boxes = boxes;
1313
this.edges = edges;
1414
this.dag = dag;
15-
this.saveUrl = saveUrl;
16-
this.submitUrl = submitUrl;
17-
this.loadUrl = loadUrl;
15+
this.pointer = pointer;
16+
this.baseUrl = baseUrl;
17+
this.saveUrl = `${baseUrl}/save`;
18+
this.submitUrl = `${baseUrl}/submit`;
19+
this.loadUrl = `${baseUrl}/load`;
1820
this.STORAGE_KEY = `project_${projectId}_workflow_${workflowId}_state`;
1921
}
2022

@@ -24,6 +26,7 @@ class WorkflowState {
2426
this.edges.forEach(e => e.el.remove());
2527
this.edges.length = 0;
2628
this.dag.reset();
29+
this.pointer.resetZoom();
2730
this.#clearSession();
2831
alert('Workflow reset.');
2932
}
@@ -90,9 +93,9 @@ class WorkflowState {
9093
if (metadata.edges) {
9194
metadata.edges.forEach(e => createEdge(e.from, e.to));
9295
}
93-
94-
if(metadata == backendMetadata) {
95-
this.saveToSession();
96+
if (metadata.zoom) {
97+
this.pointer.zoomRef.value = metadata.zoom;
98+
this.pointer.applyZoomCb();
9699
}
97100
console.info('Workflow restored correctly.');
98101
} catch (err) {
@@ -112,6 +115,7 @@ class WorkflowState {
112115
from: e.fromBox.id,
113116
to: e.toBox.id
114117
})),
118+
zoom: this.pointer.zoomRef.value,
115119
saved_at: new Date().toISOString()
116120
};
117121
}
@@ -377,9 +381,7 @@ class DragController {
377381
const saveWorkflowButton = document.getElementById('btn-save-workflow');
378382
const projectId = document.getElementById('project-id').value;
379383
const workflowId = document.getElementById('workflow-id').value;
380-
const saveWorkflowUrl = document.getElementById('save-workflow-url').value;
381-
const submitWorkflowUrl = document.getElementById('submit-workflow-url').value;
382-
const loadWorkflowUrl = document.getElementById('load-workflow-url').value;
384+
const baseWorkflowUrl = document.getElementById('base-workflow-url').value;
383385
const baseLauncherUrl = document.getElementById('base-launcher-url').value;
384386
const styles = getComputedStyle(document.documentElement);
385387
const stageZoom = document.getElementById('stage-zoom');
@@ -407,7 +409,7 @@ class DragController {
407409
const boxes = new Map();
408410
const edges = [];
409411
const pointer = new Pointer(stage, zoomState, zoomStep, zoomMax, zoomMin, applyZoom);
410-
const workflowState = new WorkflowState(projectId, workflowId, boxes, edges, dag, saveWorkflowUrl, submitWorkflowUrl, loadWorkflowUrl);
412+
const workflowState = new WorkflowState(projectId, workflowId, boxes, edges, dag, pointer, baseWorkflowUrl);
411413
const workflowSaveCb = () => workflowState.saveToSession();
412414
const drag = new DragController(pointer, boxes, edges, gridCols, gridRows, cell_w, cell_h, halfGap, workflowSaveCb);
413415

@@ -521,8 +523,6 @@ class DragController {
521523
line.classList.add('selected');
522524
selectedEdge = edge;
523525
});
524-
525-
workflowSaveCb();
526526
}
527527

528528
function makeLauncher(row, col, id, title) {
@@ -568,10 +568,10 @@ class DragController {
568568
$(`#launcher_${fromId}`).removeClass('connect-queued');
569569
connectQueue = null;
570570
createEdge(fromId, toId);
571+
workflowSaveCb();
571572
}
572573
});
573574

574-
workflowSaveCb();
575575
resolve();
576576
}).fail(function() {
577577
alert('Failed to load launcher HTML. Please try again.');
@@ -632,7 +632,8 @@ class DragController {
632632
const spawn = gridSpawn();
633633
if (spawn) {
634634
await makeLauncher(spawn.row, spawn.col, launcherId, title);
635-
changeGridIfNeeded();
635+
changeGridIfNeeded();
636+
workflowSaveCb();
636637
}
637638
} finally {
638639
addLauncherButton.disabled = false;

apps/dashboard/app/views/workflows/show.html.erb

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22

33
<input type="hidden" id="project-id" value="<%= @project.id %>">
44
<input type="hidden" id="workflow-id" value="<%= @workflow.id %>">
5-
<input type="hidden" id="save-workflow-url" value="<%= save_project_workflow_path(@project.id, @workflow.id) %>">
6-
<input type="hidden" id="submit-workflow-url" value="<%= submit_project_workflow_path(@project.id, @workflow.id) %>">
7-
<input type="hidden" id="load-workflow-url" value="<%= load_project_workflow_path(@project.id, @workflow.id) %>">
5+
<input type="hidden" id="base-workflow-url" value="<%= project_workflow_path(@project.id, @workflow.id) %>">
86
<input type="hidden" id="base-launcher-url" value="<%= project_launchers_path(@project.id) %>">
97

108
<div class="app" id="app">

0 commit comments

Comments
 (0)