Skip to content

Commit

Permalink
selectView and selection outline bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
wendybujalski committed Dec 17, 2024
1 parent ab45c1d commit 91c6a8b
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 65 deletions.
15 changes: 12 additions & 3 deletions app/web/src/components/ModelingDiagram/DiagramGroup.vue
Original file line number Diff line number Diff line change
Expand Up @@ -439,7 +439,9 @@ import {
GROUP_RESIZE_HANDLE_SIZE,
GROUP_TITLE_FONT_SIZE,
SELECTION_COLOR,
MIN_NODE_DIMENSION,
NODE_SUBTITLE_TEXT_HEIGHT,
SOCKET_MARGIN_TOP,
NODE_PADDING_BOTTOM,
} from "@/components/ModelingDiagram/diagram_constants";
import {
QualificationStatus,
Expand Down Expand Up @@ -514,11 +516,18 @@ const irect = computed(() => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const r = viewStore.groups[props.group.def.id]!;
const minimum =
NODE_SUBTITLE_TEXT_HEIGHT +
SOCKET_MARGIN_TOP +
NODE_PADDING_BOTTOM +
30 +
NODE_HEADER_HEIGHT;
return {
x: r.x,
y: r.y,
width: Math.max(r.width, MIN_NODE_DIMENSION),
height: Math.max(r.height, MIN_NODE_DIMENSION),
width: Math.max(r.width, minimum),
height: Math.max(r.height, minimum),
};
});
Expand Down
10 changes: 5 additions & 5 deletions app/web/src/components/ModelingDiagram/DiagramView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ import DiagramIcon from "./DiagramIcon.vue";
const { theme } = useTheme();
const viewStore = useViewsStore();
const viewsStore = useViewsStore();
const props = defineProps<{
view: DiagramViewDef;
Expand Down Expand Up @@ -148,7 +148,7 @@ interface ViewStats {
const statusIcons = computed(() => {
const icons: ViewStats[] = [];
const stats = viewStore.viewStats[props.view.id];
const stats = viewsStore.viewStats[props.view.id];
if (!stats) return icons;
if (stats.components > 0)
Expand Down Expand Up @@ -246,17 +246,17 @@ const config = computed(() => {
function onMouseOver(evt: KonvaEventObject<MouseEvent>, type?: string) {
evt.cancelBubble = true;
viewStore.setHoveredComponentId(
viewsStore.setHoveredComponentId(
props.view.id,
type ? ({ type } as ElementHoverMeta) : undefined,
);
}
function onMouseOut() {
viewStore.setHoveredComponentId(null);
viewsStore.setHoveredComponentId(null);
}
const goto = () => {
viewStore.selectView(props.view.id);
viewsStore.selectView(props.view.id);
};
</script>
46 changes: 25 additions & 21 deletions app/web/src/components/ViewCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
)
"
>
<div class="flex-grow min-w-0" @click="() => viewStore.selectView(view.id)">
<div
class="flex-grow min-w-0"
@click="() => viewsStore.selectView(view.id)"
>
<div class="flex flex-col">
<TruncateWithTooltip class="w-full">
<span class="text-sm">
Expand All @@ -23,21 +26,21 @@
<div
class="flex place-content-center items-center min-w-fit text-xs gap-0.5 truncate text-success-600 font-bold"
>
<div>{{ viewStore.viewStats[view.id]?.components }}</div>
<div>{{ viewsStore.viewStats[view.id]?.components }}</div>
<Icon name="check-hex-outline" tone="success" size="sm" />
</div>
<div
v-if="viewStore.viewStats[view.id]?.components || 0 > 0"
v-if="viewsStore.viewStats[view.id]?.components || 0 > 0"
class="flex place-content-center items-center min-w-fit x text-xs gap-0.5 truncate text-success-600 font-bold"
>
<div>{{ viewStore.viewStats[view.id]?.resources }}</div>
<div>{{ viewsStore.viewStats[view.id]?.resources }}</div>
<Icon name="check-hex" tone="success" size="sm" />
</div>
<div
v-if="viewStore.viewStats[view.id]?.failed || 0 > 0"
v-if="viewsStore.viewStats[view.id]?.failed || 0 > 0"
class="flex place-content-center items-center min-w-fit text-xs gap-0.5 truncate text-destructive-600 font-bold"
>
<div>{{ viewStore.viewStats[view.id]?.failed }}</div>
<div>{{ viewsStore.viewStats[view.id]?.failed }}</div>
<Icon name="x-hex-outline" tone="destructive" size="sm" />
</div>
</div>
Expand All @@ -55,12 +58,13 @@
/>
<DropdownMenuItem
:disabled="
viewStore.selectedViewId === view.id && !viewStore.viewNodes[view.id]
viewsStore.selectedViewId === view.id &&
!viewsStore.viewNodes[view.id]
"
label="Add to Diagram"
icon="plus"
@click="(e: MouseEvent) => {
if (viewStore.selectedViewId === view.id && !viewStore.viewNodes[view.id]) return;
if (viewsStore.selectedViewId === view.id && !viewsStore.viewNodes[view.id]) return;
onAdd(view.id, e);
}"
/>
Expand All @@ -69,7 +73,7 @@
icon="eye"
:onSelect="
() => {
viewStore.selectView(view.id);
viewsStore.selectView(view.id);
}
"
/>
Expand All @@ -78,7 +82,7 @@
icon="bullet-list-indented"
:onSelect="
() => {
viewStore.setOutlinerView(view.id);
viewsStore.setOutlinerView(view.id);
}
"
/>
Expand Down Expand Up @@ -154,7 +158,7 @@ import NodeSkeleton from "@/components/NodeSkeleton.vue";
import DetailsPanelMenuIcon from "./DetailsPanelMenuIcon.vue";
const toast = useToast();
const viewStore = useViewsStore();
const viewsStore = useViewsStore();
const props = defineProps<{
selected?: boolean;
Expand All @@ -175,8 +179,8 @@ const updateMouseNode = (e: MouseEvent) => {
const onMouseDown = (e: MouseEvent) => {
updateMouseNode(e);
if (viewStore.addComponentId) {
viewStore.cancelAdd();
if (viewsStore.addComponentId) {
viewsStore.cancelAdd();
}
};
Expand All @@ -195,19 +199,19 @@ onBeforeUnmount(() => {
});
const addingView = computed(() => {
if (viewStore.addViewId)
return viewStore.viewList.find((v) => v.id === viewStore.addViewId);
if (viewsStore.addViewId)
return viewsStore.viewList.find((v) => v.id === viewsStore.addViewId);
return undefined;
});
function onAdd(id: string, e: MouseEvent) {
// cannot dupe views
if (Object.keys(viewStore.viewNodes).includes(id)) return;
if (Object.keys(viewsStore.viewNodes).includes(id)) return;
if (viewStore.addViewId === id) {
viewStore.cancelAdd();
if (viewsStore.addViewId === id) {
viewsStore.cancelAdd();
} else {
viewStore.addViewId = id;
viewsStore.addViewId = id;
if (e) {
nextTick(() => {
updateMouseNode(e);
Expand All @@ -227,14 +231,14 @@ const updateName = (e?: Event) => {
if (!viewName.value) {
labelRef.value?.setError("Name is required");
} else {
viewStore.UPDATE_VIEW_NAME(props.view.id, viewName.value);
viewsStore.UPDATE_VIEW_NAME(props.view.id, viewName.value);
modalRef.value?.close();
viewName.value = "";
}
};
const deleteView = async (view: ViewDescription) => {
const resp = await viewStore.DELETE_VIEW(view.id);
const resp = await viewsStore.DELETE_VIEW(view.id);
if (!resp.result.success) {
if (resp.result.statusCode === 409) {
/* We cannot easily pass JSON data as an error, punting for now with a generic message
Expand Down
24 changes: 15 additions & 9 deletions app/web/src/components/layout/navbar/Collaborators.vue
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ import { useRoute, useRouter } from "vue-router";
import Popover from "@/components/Popover.vue";
import { usePresenceStore } from "@/store/presence.store";
import { useChangeSetsStore } from "@/store/change_sets.store";
import { useViewsStore } from "@/store/views.store";
import UserIcon from "./UserIcon.vue";
import UserCard from "./UserCard.vue";
Expand Down Expand Up @@ -283,15 +284,20 @@ function goToUserChangeSet(user: UserInfo) {
if (!user || !user.changeSet) return;
if (user.view) {
router.push({
name: "workspace-compose-view",
params: {
...route.params,
changeSetId: user.changeSet,
viewId: user.view,
},
query: route.query,
});
if (user.changeSet === changeSetsStore.selectedChangeSetId) {
const viewsStore = useViewsStore(); // have to access the store here to prevent ending up with the none change set views store
viewsStore.selectView(user.view);
} else {
router.push({
name: "workspace-compose-view",
params: {
...route.params,
changeSetId: user.changeSet,
viewId: user.view,
},
query: route.query,
});
}
return;
}
Expand Down
38 changes: 11 additions & 27 deletions app/web/src/store/views.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as _ from "lodash-es";
import { addStoreHooks, ApiRequest, URLPattern } from "@si/vue-lib/pinia";
import { IRect, Vector2d } from "konva/lib/types";
import { useToast } from "vue-toastification";
import { watch } from "vue";
import { IconNames } from "@si/vue-lib/design-system";
import { ChangeSetId } from "@/api/sdf/dal/change_set";
import {
Expand Down Expand Up @@ -592,17 +591,19 @@ export const useViewsStore = (forceChangeSetId?: ChangeSetId) => {
this.selectedComponentIds = valid;
this.syncSelectionIntoUrl();
},
selectView(id: ViewId) {
async selectView(id: ViewId) {
const view = this.viewsById[id];
if (view) {
const route = router.currentRoute;
const params = {
...route.value.params,
viewId: id,
};
router.push({
name: "workspace-compose-view",
params: {
...route.value.params,
viewId: id,
},
params,
});

// move the currently selected view to the top of the
if (this.selectedViewId) {
this.pushRecentView(this.selectedViewId);
Expand All @@ -628,7 +629,10 @@ export const useViewsStore = (forceChangeSetId?: ChangeSetId) => {
// to begin, and then adjust it via delta when things move
this.sockets = view.sockets;
} else {
throw new Error(`${id} does not exist`);
const res = await this.FETCH_VIEW(id);
if (!res.result.success) {
throw new Error(`${id} does not exist`);
}
}
},
closeRecentView(id: ViewId) {
Expand Down Expand Up @@ -1575,25 +1579,6 @@ export const useViewsStore = (forceChangeSetId?: ChangeSetId) => {
}
this.LIST_VIEWS();

// TODO: prob want to take loading state into consideration as this will set it before its loaded
const stopWatchingUrl = watch(
router.currentRoute,
() => {
if (
router.currentRoute.value.name === "workspace-compose" ||
router.currentRoute.value.name === "workspace-compose-view"
)
this.syncUrlIntoSelection();
const viewId = router.currentRoute.value.params.viewId;
if (viewId && this.selectedViewId !== viewId) {
this.selectView(viewId as string);
}
},
{
immediate: true,
},
);

if (router.currentRoute.value.name === "workspace-compose") {
const key = `${changeSetId}_selected_component`;
const lastId = window.localStorage.getItem(key);
Expand Down Expand Up @@ -1984,7 +1969,6 @@ export const useViewsStore = (forceChangeSetId?: ChangeSetId) => {
this.selectedComponentIds = [];
this.selectedEdgeId = null;
actionUnsub();
stopWatchingUrl();
realtimeStore.unsubscribe(`${this.$id}-changeset`);
realtimeStore.unsubscribe(`${this.$id}-workspace`);
};
Expand Down

0 comments on commit 91c6a8b

Please sign in to comment.