Skip to content

Commit

Permalink
merge: #3948
Browse files Browse the repository at this point in the history
3948: Restore components & edges from base change set r=wendybujalski a=jhelwig

# Back end

## Include Components only in the base change set that would be actively removed by a change set when building the summary diagram

We now look at the series of updates that would be applied if we were to merge a change set into its base, and include "virtual" summary diagram component entries for any Components that would be removed and that only exist in the base change set. These virtual entries will have `from_base_change_set` set to true to signal that they don't actually exist in the snapshot for the change set.

## List edges from base change set that would be actively removed on merge

## Allow importing a Component from another snapshot graph

This allows us to "undelete"/"restore" a Component from the base change set if we've removed it from the current change set, and change our mind.

## Restore Component->Component connections from base changeset whenever possible

Rather than creating a new API endpoint & method for attempting to restore a `Component -> Component` (`Output Socket -> Input Socket`) connection, `Component::connect` (and by extension `diagram/create_connection`) will now check the base change set to see if an equivalent connection exists there. If it does, then we import that pre-existing connection into the current change set. If it does not, then we'll create the connection as a brand new one.

This means that if you remove a connection, decide you didn’t actually want to do that, and re-draw it instead of clicking the “restore connection” button, we’ll do the right thing and restore it, so you don’t end up seeing a remove+add of the “same” connection, and should generally help reduce the potential churn in looking at diffs.

## Only try to create Component -> Component connections when both are in the current change set

Since we display "virtual" Components of some things that aren't actually in the current change set, we need to make sure that we don't try to create a connection to them as that would effectively be a dangling pointer.

Co-authored-by: Jacob Helwig <[email protected]>
Co-authored-by: John Obelenus <[email protected]>
Co-authored-by: wendybujalski <[email protected]>
  • Loading branch information
4 people authored Jun 28, 2024
2 parents 874540e + 70b72cb commit d70ad77
Show file tree
Hide file tree
Showing 15 changed files with 1,088 additions and 102 deletions.
1 change: 1 addition & 0 deletions app/web/src/api/sdf/dal/component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export interface RawComponent {
updatedInfo: ActorAndTimestamp;
toDelete: boolean;
canBeUpgraded: boolean;
fromBaseChangeSet: boolean;
}

export type EdgeId = string;
Expand Down
1 change: 1 addition & 0 deletions app/web/src/components/ComponentCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
'p-xs border-l-4 border relative',
titleCard ? 'mb-xs' : 'rounded-md',
component.toDelete && 'opacity-70',
component.fromBaseChangeSet && 'opacity-70',
)
"
:style="{
Expand Down
6 changes: 3 additions & 3 deletions app/web/src/components/DetailsPanelTimestamps.vue
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
class="shrink-0"
tone="inherit"
/>
<div class="grow truncate">
<div v-if="created" class="grow truncate">
{{ formatters.timeAgo(created.timestamp) }} by
{{ created.actor.label }}
</div>
Expand All @@ -42,7 +42,7 @@
class="shrink-0"
tone="inherit"
/>
<div class="grow truncate">
<div v-if="modified" class="grow truncate">
{{ formatters.timeAgo(modified?.timestamp) }} by
{{ modified?.actor.label }}
</div>
Expand All @@ -58,7 +58,7 @@
class="shrink-0"
tone="inherit"
/>
<div class="grow truncate">
<div v-if="deleted" class="grow truncate">
{{ formatters.timeAgo(deleted?.timestamp) }} by
{{ deleted?.actor.label }}
</div>
Expand Down
5 changes: 4 additions & 1 deletion app/web/src/components/ModelingDiagram/DiagramGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,10 @@ const size = computed(
);
const isDeleted = computed(
() => props.group.def.changeStatus === "deleted" || props.group.def.toDelete,
() =>
props.group.def.changeStatus === "deleted" ||
props.group.def.toDelete ||
props.group.def.fromBaseChangeSet,
);
const isModified = computed(() => props.group.def.changeStatus === "modified");
const isAdded = computed(() => props.group.def.changeStatus === "added");
Expand Down
5 changes: 4 additions & 1 deletion app/web/src/components/ModelingDiagram/DiagramNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,10 @@ const diagramContext = useDiagramContext();
const { edgeDisplayMode } = diagramContext;
const isDeleted = computed(
() => props.node.def.changeStatus === "deleted" || props.node.def.toDelete,
() =>
props.node.def.changeStatus === "deleted" ||
props.node.def.toDelete ||
props.node.def.fromBaseChangeSet,
);
const isModified = computed(() => props.node.def.changeStatus === "modified");
const isAdded = computed(() => props.node.def.changeStatus === "added");
Expand Down
2 changes: 2 additions & 0 deletions app/web/src/components/ModelingDiagram/diagram_types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ export type DiagramNodeDef = {
changeStatus?: ChangeStatus;
/** component will be deleted after next action run */
toDelete: boolean;
/** component is deleted in this changeset, but exists in base change set */
fromBaseChangeSet: boolean;
/** can the component be upgraded */
canBeUpgraded: boolean;
};
Expand Down
23 changes: 20 additions & 3 deletions app/web/src/components/ModelingView/RestoreSelectionModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
import { computed, onBeforeUnmount, onMounted, ref } from "vue";
import { useComponentsStore } from "@/store/components.store";
import { ComponentId } from "@/api/sdf/dal/component";
const componentsStore = useComponentsStore();
const selectedEdge = computed(() => componentsStore.selectedEdge);
Expand Down Expand Up @@ -77,9 +78,25 @@ function open() {
}
async function onConfirmRestore() {
if (componentsStore.selectedComponentIds) {
await componentsStore.RESTORE_COMPONENTS(
componentsStore.selectedComponentIds,
if (
componentsStore.selectedComponentIds &&
componentsStore.selectedComponentIds.length > 0
) {
const data = {} as Record<ComponentId, boolean>;
componentsStore.selectedComponentIds.forEach((cId) => {
data[cId] = !!componentsStore.componentsById[cId]?.fromBaseChangeSet;
});
await componentsStore.RESTORE_COMPONENTS(data);
} else if (componentsStore.selectedEdge) {
await componentsStore.CREATE_COMPONENT_CONNECTION(
{
componentId: componentsStore.selectedEdge.fromComponentId,
socketId: componentsStore.selectedEdge.fromSocketId,
},
{
componentId: componentsStore.selectedEdge.toComponentId,
socketId: componentsStore.selectedEdge.toSocketId,
},
);
}
componentsStore.setSelectedComponentId(null);
Expand Down
13 changes: 9 additions & 4 deletions app/web/src/store/components.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1431,28 +1431,33 @@ export const useComponentsStore = (forceChangeSetId?: ChangeSetId) => {
});
},

async RESTORE_COMPONENTS(componentIds: ComponentId[]) {
async RESTORE_COMPONENTS(components: Record<ComponentId, boolean>) {
if (changeSetsStore.creatingChangeSet)
throw new Error("race, wait until the change set is created");
if (changeSetId === changeSetsStore.headChangeSetId)
changeSetsStore.creatingChangeSet = true;

const payload = [];
for (const [key, value] of Object.entries(components)) {
payload.push({ componentId: key, fromBaseChangeSet: value });
}
return new ApiRequest({
method: "post",
url: "diagram/remove_delete_intent",
keyRequestStatusBy: componentIds,
keyRequestStatusBy: Object.keys(components),
params: {
componentIds,
components: payload,
...visibilityParams,
},
onSuccess: () => {
for (const componentId of componentIds) {
for (const componentId of Object.keys(components)) {
const component = this.rawComponentsById[componentId];
if (component) {
this.rawComponentsById[componentId] = {
...component,
changeStatus: "unmodified",
toDelete: false,
fromBaseChangeSet: false,
deletedInfo: undefined,
};
}
Expand Down
Loading

0 comments on commit d70ad77

Please sign in to comment.