Skip to content
This repository was archived by the owner on Feb 6, 2026. It is now read-only.

Commit 67bf979

Browse files
Merge pull request #8331 from systeminit/wendy/map-upgrades-pt1
feat(web) - helpful hiding functionality for Map view
2 parents 8e0cdf9 + 86277e6 commit 67bf979

File tree

7 files changed

+190
-49
lines changed

7 files changed

+190
-49
lines changed

app/web/src/newhotness/Explore.vue

Lines changed: 83 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,14 @@
146146
</Transition>
147147
</div>
148148
</div>
149-
<div class="flex-none flex flex-row flex-wrap items-center gap-xs">
149+
<div :class="
150+
clsx(
151+
'flex-none flex flex-row flex-wrap items-center gap-xs',
152+
!showGrid && (mapRef?.selectedComponents.size ?? 0) > 0
153+
? 'pr-[440px]' // right padding to accommodate the ExploreGridTile in the Map view
154+
: 'max-w-[100vw]', // prevents the buttons from going offscreen on smaller window sizes
155+
)"
156+
>
150157
<TabGroupToggle ref="groupRef" :aOrB="urlGridOrMap === 'grid'" @toggle="storeViewMode">
151158
<template #a="{ selected, toggle }">
152159
<ExploreModeTile icon="grid" label="Grid" :selected="selected" @toggle="toggle" />
@@ -156,48 +163,46 @@
156163
</template>
157164
</TabGroupToggle>
158165
<template v-if="!showGrid">
159-
<button
160-
v-if="!ctx.onHead.value"
161-
:class="
162-
clsx(
163-
'flex flex-row gap-xs items-center border rounded-sm',
164-
'p-2xs mb-[-1px] h-7',
165-
'font-mono text-[13px] text-left truncate relative',
166-
themeClasses(
167-
'border-neutral-400 hover:border-action-500',
168-
'border-neutral-600 hover:border-action-300',
169-
),
170-
queryOnlyDiff
171-
? themeClasses('bg-action-200', 'bg-action-900')
172-
: themeClasses('bg-neutral-100', 'bg-neutral-900'),
173-
)
174-
"
166+
<NewButton
167+
tone="toggle"
168+
size="xs"
169+
label="See only diffs"
170+
truncateText
171+
icon="tilde-circle"
172+
:iconClasses="themeClasses('text-warning-500', 'text-warning-300')"
173+
:active="queryOnlyDiff"
175174
@click="toggleOnlyDiff"
176-
>
177-
<Icon name="tilde-circle" :class="themeClasses('text-warning-500', 'text-warning-300')" size="xs" />
178-
<span>See only diffs</span>
179-
</button>
180-
<button
181-
v-if="mapRef?.selectedComponents.size || 0 > 0"
182-
:class="
183-
clsx(
184-
'flex flex-row gap-xs items-center border rounded-sm',
185-
'p-2xs mb-[-1px] h-7',
186-
'font-mono text-[13px] text-left truncate relative',
187-
themeClasses(
188-
'border-neutral-400 hover:border-action-500',
189-
'border-neutral-600 hover:border-action-300',
190-
),
191-
queryHideSubscriptions
192-
? themeClasses('bg-action-200', 'bg-action-900')
193-
: themeClasses('bg-neutral-100', 'bg-neutral-900'),
194-
)
195-
"
175+
/>
176+
<NewButton
177+
v-if="(mapRef?.selectedComponents.size ?? 0) > 0"
178+
tone="toggle"
179+
size="xs"
180+
label="Hide unconnected components"
181+
truncateText
182+
icon="hide"
183+
:active="queryHideSubscriptions"
196184
@click="toggleHide"
197-
>
198-
<Icon name="hide" size="xs" />
199-
<span>Hide unconnected components</span>
200-
</button>
185+
/>
186+
<template v-if="featureFlagsStore.MAP_VIEW_UPGRADES">
187+
<NewButton
188+
tone="toggle"
189+
size="xs"
190+
label="Show credential components"
191+
truncateText
192+
icon="eye"
193+
:active="queryShowCredentials"
194+
@click="toggleShowCredentials"
195+
/>
196+
<NewButton
197+
tone="toggle"
198+
size="xs"
199+
label="Show components with no connections"
200+
truncateText
201+
icon="eye"
202+
:active="queryShowNoConnections"
203+
@click="toggleShowNoConnections"
204+
/>
205+
</template>
201206
</template>
202207
<div v-if="showGrid" class="ml-auto flex flex-row flex-wrap gap-xs">
203208
<DefaultSubscriptionsButton
@@ -567,6 +572,9 @@ import { ExploreGridRowData } from "./explore_grid/ExploreGridRow.vue";
567572
import { useDefaultSubscription } from "./logic_composables/default_subscriptions";
568573
import { useContext } from "./logic_composables/context";
569574
import { generateMockActions } from "./logic_composables/mock_data";
575+
import { useFeatureFlagsStore } from "@/store/feature_flags.store";
576+
577+
const featureFlagsStore = useFeatureFlagsStore();
570578
571579
const router = useRouter();
572580
const route = useRoute();
@@ -630,7 +638,6 @@ const queryOnlyDiff = computed(() => {
630638
};
631639
return query.showDiff === "1";
632640
});
633-
634641
const toggleOnlyDiff = () => {
635642
const query: SelectionsInQueryString = {
636643
...router.currentRoute.value?.query,
@@ -648,7 +655,6 @@ const queryHideSubscriptions = computed(() => {
648655
};
649656
return query.hideSubscriptions === "1";
650657
});
651-
652658
const toggleHide = () => {
653659
const query: SelectionsInQueryString = {
654660
...router.currentRoute.value?.query,
@@ -660,6 +666,40 @@ const toggleHide = () => {
660666
}
661667
router.replace({ query });
662668
};
669+
const queryShowCredentials = computed(() => {
670+
const query: SelectionsInQueryString = {
671+
...router.currentRoute.value?.query,
672+
};
673+
return query.showCredentials === "1";
674+
});
675+
const toggleShowCredentials = () => {
676+
const query: SelectionsInQueryString = {
677+
...router.currentRoute.value?.query,
678+
};
679+
if (queryShowCredentials.value) {
680+
delete query.showCredentials;
681+
} else {
682+
query.showCredentials = "1";
683+
}
684+
router.replace({ query });
685+
};
686+
const queryShowNoConnections = computed(() => {
687+
const query: SelectionsInQueryString = {
688+
...router.currentRoute.value?.query,
689+
};
690+
return query.showNoConnections === "1";
691+
});
692+
const toggleShowNoConnections = () => {
693+
const query: SelectionsInQueryString = {
694+
...router.currentRoute.value?.query,
695+
};
696+
if (queryShowNoConnections.value) {
697+
delete query.showNoConnections;
698+
} else {
699+
query.showNoConnections = "1";
700+
}
701+
router.replace({ query });
702+
};
663703
664704
const urlGridOrMap = computed((): "grid" | "map" => {
665705
const q: SelectionsInQueryString = router.currentRoute.value?.query;

app/web/src/newhotness/Map.vue

Lines changed: 65 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,8 @@ export type GraphData = {
5757
id="map"
5858
:class="
5959
clsx(
60-
'grid h-full',
60+
'grid h-full border-t',
61+
themeClasses('border-neutral-200 bg-white', 'border-neutral-800 bg-neutral-900'),
6162
showSkeleton && 'hidden', // Since the svgs need a target to be drawn, we need to have this in the DOM
6263
)
6364
"
@@ -247,12 +248,15 @@ import { pickBrandIconByString } from "./util";
247248
import ComponentContextMenu from "./ComponentContextMenu.vue";
248249
import { truncateString } from "./logic_composables/string_funcs";
249250
import MiniMap from "./MiniMap.vue";
251+
import { useFeatureFlagsStore } from "@/store/feature_flags.store";
250252
251253
const MAX_STRING_LENGTH = 18;
252254
253255
const router = useRouter();
254256
const { theme } = useTheme();
255257
258+
const featureFlagsStore = useFeatureFlagsStore();
259+
256260
const props = defineProps<{
257261
active: boolean;
258262
components: ComponentInList[];
@@ -955,6 +959,8 @@ const onEscape = () => {
955959
delete query.map;
956960
delete query.c;
957961
delete query.hideSubscriptions; // Also clear hideSubscriptions when closing map
962+
delete query.showCredentials; // Also clear showCredentials when closing map
963+
delete query.showNoConnections; // Also clear showNoConnections when closing map
958964
delete query.showDiff;
959965
query.grid = "1";
960966
router.push({ query });
@@ -1052,6 +1058,13 @@ const connections = useQuery<IncomingConnections[]>({
10521058
},
10531059
});
10541060
1061+
const isCredentialSchema = (schemaName: string | undefined) => {
1062+
if (schemaName) {
1063+
return schemaName.toLowerCase().includes("credential");
1064+
}
1065+
return false;
1066+
};
1067+
10551068
const mapData = computed(() => {
10561069
const nodes = new Set<string>();
10571070
const edges = new Set<string>();
@@ -1064,6 +1077,8 @@ const mapData = computed(() => {
10641077
const shouldHideUnconnected = router.currentRoute.value.query.hideSubscriptions === "1";
10651078
10661079
const showOnlyDiff = router.currentRoute.value.query.showDiff === "1";
1080+
const showCredentials = router.currentRoute.value.query.showCredentials === "1" || !featureFlagsStore.MAP_VIEW_UPGRADES;
1081+
const showNoConnections = router.currentRoute.value.query.showNoConnections === "1" || !featureFlagsStore.MAP_VIEW_UPGRADES;
10671082
10681083
const hasSelectedComponents = selectedComponents.value.size > 0;
10691084
@@ -1074,7 +1089,14 @@ const mapData = computed(() => {
10741089
connections.data.value.forEach((c) => {
10751090
const component = componentsById.value[c.id];
10761091
if (!component) return;
1092+
// If showOnlyDiff is enabled, only show components with diffs
10771093
if (showOnlyDiff && component.diffStatus === "None") return;
1094+
1095+
// If showCredentials is disabled, hide components which are credentials
1096+
if (!showCredentials && isCredentialSchema(component.schemaName)) {
1097+
return;
1098+
}
1099+
10781100
allComponents.set(c.id, component);
10791101
10801102
c.connections.forEach((e) => {
@@ -1085,6 +1107,41 @@ const mapData = computed(() => {
10851107
});
10861108
});
10871109
1110+
// If showNoConnections is disabled, filter out components which have no connections
1111+
if (!showNoConnections) {
1112+
allComponents.forEach((component) => {
1113+
let keepComponent = false;
1114+
for (const connection of allConnections) {
1115+
if (connection.includes(component.id)) {
1116+
if (showCredentials) {
1117+
// if showCredentials is true then this is a valid connection
1118+
keepComponent = true;
1119+
break;
1120+
} else {
1121+
// otherwise, filter out connections to a credential
1122+
const ids = connection.split("-");
1123+
const id1 = ids[0];
1124+
const id2 = ids[1];
1125+
if (
1126+
(id1 && isCredentialSchema(componentsById.value[id1]?.schemaName)) ||
1127+
(id2 && isCredentialSchema(componentsById.value[id2]?.schemaName))
1128+
) {
1129+
// one of the components connected via this connection is a credential, so ignore it
1130+
continue;
1131+
} else {
1132+
// this connection is a valid one
1133+
keepComponent = true;
1134+
break;
1135+
}
1136+
}
1137+
}
1138+
}
1139+
if (!keepComponent) {
1140+
allComponents.delete(component.id)
1141+
}
1142+
});
1143+
}
1144+
10881145
// If we're in hideSubscriptions mode and have selected components, filter the data
10891146
if (shouldHideUnconnected && hasSelectedComponents) {
10901147
// Get the connected component IDs (including selected ones)
@@ -1098,6 +1155,9 @@ const mapData = computed(() => {
10981155
// Add directly connected components
10991156
selectedComponents.value.forEach((selectedComp) => {
11001157
if (showOnlyDiff && selectedComp.diffStatus === "None") return;
1158+
if (!showCredentials && isCredentialSchema(selectedComp.schemaName)) {
1159+
return;
1160+
}
11011161
11021162
const selectedId = selectedComp.id;
11031163
@@ -1132,7 +1192,10 @@ const mapData = computed(() => {
11321192
} else {
11331193
// Normal mode: include all components
11341194
allComponents.forEach((component, componentId) => {
1135-
if (!showOnlyDiff || (showOnlyDiff && component.diffStatus !== "None")) {
1195+
if (
1196+
(showCredentials || !isCredentialSchema(component.schemaName)) &&
1197+
(!showOnlyDiff || component.diffStatus !== "None")
1198+
) {
11361199
nodes.add(componentId);
11371200
components[componentId] = component;
11381201
}

app/web/src/newhotness/Workspace.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ export type SelectionsInQueryString = Partial<{
542542
retainSessionState: string; // If set, the component should load up with the last state it had on this tab. Used by Explore.vue
543543
hideSubscriptions: string; // Flag to hide unconnected components when navigating to map
544544
showDiff: string; // Flag to show only components with diff on the map
545+
showCredentials: string; // Flag to show or hide credential components from the map
546+
showNoConnections: string; // Flag to show or hide components with no subscriptions from the map
545547
}>;
546548
547549
const tokenFailStatus = ref();

app/web/src/newhotness/skeletons/ExploreMapSkeleton.vue

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
<template>
22
<DelayedComponent>
3-
<section :class="clsx('h-full w-full', themeClasses('bg-white', 'bg-neutral-950'))">
3+
<section :class="
4+
clsx(
5+
'h-full w-full border-t',
6+
themeClasses('border-neutral-200 bg-white', 'border-neutral-800 bg-neutral-900'),
7+
)
8+
">
49
<div
510
:class="
611
clsx(

app/web/src/pages/DebugPage.vue

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,8 @@ const getButtonTooltip = (variant: string) => {
231231
return "The nostyle variant is used to clear ALL styles";
232232
} else if (variant === "flat") {
233233
return "Similar to the neutral style, but meant to have the same bg color as the things it is sitting on top of (e.g. appear to not have a separate bg color)";
234+
} else if (variant === "toggle") {
235+
return "A special tone used only for the buttons at the top of the Explore page in the area below the search bar";
234236
} else {
235237
return undefined;
236238
}

app/web/src/store/feature_flags.store.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const USER_FLAG_MAPPING = {
1919
SHOW_WS_DISCONNECT: "show-ws-disconnect",
2020
SHOW_POLICIES: "show-policies",
2121
SHOW_AUTHORING_NAV: "authoring-in-nav",
22+
MAP_VIEW_UPGRADES: "map-view-upgrades",
2223
} as const;
2324
const WORKSPACE_FLAG_MAPPING: Record<string, string> = {
2425
// STORE_FLAG_NAME: "posthogFlagName",

0 commit comments

Comments
 (0)