Skip to content

Commit

Permalink
harden(model-edit): save decomposed port positions for flattened view…
Browse files Browse the repository at this point in the history
… edits (#3453)
  • Loading branch information
shawnyama authored May 1, 2024
1 parent 30abc3e commit d447dd0
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,8 @@ import type { Model } from '@/types/Types';
import type {
ModelTemplateCanvas,
ModelTemplateCard,
ModelTemplateJunction
ModelTemplateJunction,
OffsetValues
} from '@/types/model-templating';
import * as modelTemplatingService from '@/services/model-templating';
import SelectButton from 'primevue/selectbutton';
Expand Down Expand Up @@ -180,6 +181,7 @@ let isMouseOverCanvas = false;
let canvasTransform = { x: 0, y: 0, k: 1 };
let isMouseOverPort = false;
let junctionIdForNewEdge: string | null = null;
const decomposedPortOffsetValues = new Map<string, OffsetValues>();
const decomposedCanvas = ref<ModelTemplateCanvas>(modelTemplatingService.initializeCanvas());
const flattenedCanvas = ref<ModelTemplateCanvas>(modelTemplatingService.initializeCanvas());
Expand Down Expand Up @@ -297,6 +299,7 @@ function createNewEdge(cardId: string, portId: string) {
props.kernelManager,
flattenedCanvas.value,
decomposedCanvas.value,
decomposedPortOffsetValues,
outputCode,
syncWithMiraModel,
interpolatePointsForCurve
Expand Down Expand Up @@ -446,7 +449,23 @@ function refreshFlattenedCanvas() {
function onEditorFormatSwitch(newFormat: EditorFormat) {
currentModelFormat.value = newFormat;
if (newFormat === EditorFormat.Decomposed) refreshFlattenedCanvas(); // Removes unlinked decomposed templates
if (newFormat === EditorFormat.Decomposed)
refreshFlattenedCanvas(); // Removes unlinked decomposed templates
else {
// When switching to the flattened view, we save the decomposed port positions
// so that edges can be drawn correctly when relecting flattened edits to the decomposed view
decomposedPortOffsetValues.clear();
const decomposedPortElements = document.getElementsByClassName(
'port selectable'
) as HTMLCollectionOf<HTMLElement>;
Array.from(decomposedPortElements).forEach((element) =>
decomposedPortOffsetValues.set(
element.id,
modelTemplatingService.getElementOffsetValues(element)
)
);
}
}
watch(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,12 @@ const appendCode = (data: any, property: string) => {
};
const syncWithMiraModel = (data: any) => {
amr.value = data.content['application/json'];
const updatedModel = data.content?.['application/json'];
if (!updatedModel) {
logger.error('Error getting updated model from beaker');
return;
}
amr.value = updatedModel;
};
// Reset model, then execute the code
Expand Down
37 changes: 28 additions & 9 deletions packages/client/hmi-client/src/services/model-templating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ import type {
ModelTemplateCard,
ModelTemplateEdge,
ModelTemplateJunction,
ModelTemplateCanvas
ModelTemplateCanvas,
OffsetValues
} from '@/types/model-templating';
import { DecomposedModelTemplateTypes } from '@/types/model-templating';
import { KernelSessionManager } from '@/services/jupyter';
Expand Down Expand Up @@ -515,18 +516,36 @@ export function updateFlattenedTemplateInView(flattenedCanvas: ModelTemplateCanv
addTemplateInView(flattenedCanvas, flattenedModel);
}

export function getElementOffsetValues(element: HTMLElement): OffsetValues {
const { offsetLeft, offsetTop, offsetWidth, offsetHeight } = element;
return { offsetLeft, offsetTop, offsetWidth, offsetHeight };
}

// Helper function for finding port position when auto drawing junctions and edges
function getPortPosition(templateCard: ModelTemplateCard, portId: string) {
function getPortPosition(
templateCard: ModelTemplateCard,
portId: string,
potentialPortOffsetValues?: Map<string, OffsetValues>
) {
const cardWidth = 168;
const id = `${templateCard.id}-${portId}`;

// Default to fallback values for port position (top right of the card)
let x = templateCard.x + cardWidth;
let y = templateCard.y;
// Get the position of the port element
const portElement = document.getElementById(`${templateCard.id}-${portId}`);
if (portElement) {
x = templateCard.x + portElement.offsetLeft + portElement.offsetWidth - 10;
y = templateCard.y + portElement.offsetTop + portElement.offsetHeight / 2;
// Get the offset values of the port element to determine its position
let portOffsetValues: OffsetValues | null = null;
if (potentialPortOffsetValues) {
const potentialPortPosition = potentialPortOffsetValues.get(id);
if (potentialPortPosition) portOffsetValues = potentialPortPosition;
} else {
const portElement = document.getElementById(id);
if (portElement) portOffsetValues = getElementOffsetValues(portElement);
}

if (portOffsetValues) {
x = templateCard.x + portOffsetValues.offsetLeft + portOffsetValues.offsetWidth - 10;
y = templateCard.y + portOffsetValues.offsetTop + portOffsetValues.offsetHeight / 2;
}
return { x, y };
}
Expand Down Expand Up @@ -657,6 +676,7 @@ export async function reflectFlattenedEditInDecomposedView(
kernelManager: KernelSessionManager,
flattenedCanvas: ModelTemplateCanvas,
decomposedCanvas: ModelTemplateCanvas,
decomposedPortOffsetValues: Map<string, OffsetValues>,
outputCode: Function,
syncWithMiraModel: Function,
interpolatePointsFn?: Function
Expand Down Expand Up @@ -707,8 +727,7 @@ export async function reflectFlattenedEditInDecomposedView(
// Finds the decomposed template that has the port used in the flattened view
const templateCard = findTemplateCardForNewEdge(decomposedCanvas.models, sharedPortId);
if (!templateCard) return;

const portPosition = getPortPosition(templateCard, sharedPortId); // FIXME: Decomposed ports can't be referenced at this stage since we are in the flattened view
const portPosition = getPortPosition(templateCard, sharedPortId, decomposedPortOffsetValues); // Pass decomposed port offset values that were saved when we switched to the flattened view

addJunction(decomposedCanvas, portPosition);
decompJunctionId = decomposedCanvas.junctions[decomposedCanvas.junctions.length - 1].id;
Expand Down
7 changes: 7 additions & 0 deletions packages/client/hmi-client/src/types/model-templating.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,10 @@ export interface ModelTemplateEdge {
};
points: Position[];
}

export interface OffsetValues {
offsetLeft: number;
offsetTop: number;
offsetWidth: number;
offsetHeight: number;
}

0 comments on commit d447dd0

Please sign in to comment.