8000 Component Props Array & Map. Stabilize reference fetching by jobelenus · Pull Request #6144 · systeminit/si · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Component Props Array & Map. Stabilize reference fetching #6144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
May 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
8000
Diff view
4 changes: 4 additions & 0 deletions app/web/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ app.config.errorHandler = (
(mappedStack) => {
const stack = mappedStack.join("\n");
observeError(err.message.toString(), stack, componentPath);
if (import.meta.env.VITE_SI_ENV === "local") {
// eslint-disable-next-line no-console
console.error(err);
}
},
{ cacheGlobally: true },
);
Expand Down
44 changes: 25 additions & 19 deletions app/web/src/newhotness/AttributePanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@
<ComponentAttribute
v-for="child in filtered.tree.children"
:key="child.id"
:component="component"
:attributeTree="child"
@save="save"
@delete="remove"
/>
</ul>
<div v-else>Oh no, no attributes!</div>
</div>
</template>

<script lang="ts" setup>
import { useQuery } from "@tanstack/vue-query";
import { computed, reactive, ref, watch } from "vue";
import { Fzf } from "fzf";
import { bifrost, useMakeArgs, useMakeKey } from "@/store/realtime/heimdall";
import {
AttributeTree,
BifrostComponent,
Expand All @@ -43,43 +43,36 @@ const props = defineProps<{
component: BifrostComponent;
}>();

const componentId = computed(() => props.component.id);

const attributeTreeMakeKey = useMakeKey();
const attributeTreeMakeArgs = useMakeArgs();
const attributeTreeQuery = useQuery<AttributeTree | null>({
queryKey: attributeTreeMakeKey("AttributeTree", componentId),
queryFn: async () => {
const args = attributeTreeMakeArgs("AttributeTree", componentId.value);
return await bifrost<AttributeTree>(args);
},
});

export interface AttrTree {
id: string;
children: AttrTree[];
parent?: string;
prop?: Prop;
attributeValue: AttributeValue;
isBuildable: boolean; // is my parent an array or map?
}

const makeAvTree = (
data: AttributeTree,
avId: string,
isBuildable: boolean,
parent?: string,
): AttrTree => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const childrenIds = data.treeInfo[avId]!.children;
const children = childrenIds.map((id) => makeAvTree(data, id, avId));
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const av = data.attributeValues[avId]!;
const prop = av.propId ? data.props[av.propId] : undefined;
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const childrenIds = data.treeInfo[avId]!.children;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok - seeing this, I haven't looked more closely, but I could smash the prop and av together in a single struct with only what we need here. I assume documentation, link, widget, etc, could live on the AV itself. Let me know what you think!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nope, this is fine I think. FWIW the "Tree" you see here isn't the prop tree you made. And its not exactly the av tree Jacob made either. I essentially took the tree info and populated it with the objects, and children objects, all the way down. Its useful to have it this way for rendering and fuzzy searching

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I know - I just mean we can return this exact shape in the MV itself.

const children = childrenIds.map((id) =>
makeAvTree(data, id, ["array", "map"].includes(prop?.kind ?? ""), avId),
);
const tree: AttrTree = {
id: avId,
children,
parent,
attributeValue: av,
prop,
isBuildable,
};
return tree;
};
Expand All @@ -89,8 +82,9 @@ const root = computed<AttrTree>(() => {
id: "",
children: [] as AttrTree[],
attributeValue: {} as AttributeValue,
isBuildable: false,
};
const raw = attributeTreeQuery.data.value;
const raw = props.component.attributeTree;
if (!raw) return empty;

// find the root node in the tree, the only one with parent null
Expand All @@ -102,7 +96,7 @@ const root = computed<AttrTree>(() => {
});
if (!rootId) return empty;

const tree = makeAvTree(raw, rootId);
const tree = makeAvTree(raw, rootId, false);
return tree;
});

Expand Down Expand Up @@ -195,6 +189,7 @@ watch(
const newDomain = matchesAsTree[domain.value.id];
filtered.tree = newDomain ?? {};
},
{ immediate: true },
);

const api = useApi();
Expand All @@ -210,6 +205,17 @@ const save = async (path: string, _id: string, value: string) => {
await call.put<UpdateComponentAttributesArgs>(payload);
};

const remove = async (path: string, _id: string) => {
const call = api.endpoint<{ success: boolean }>(
routes.UpdateComponentAttributes,
{ id: props.component.id },
);
const payload: UpdateComponentAttributesArgs = {};
path = path.replace("root", ""); // endpoint doesn't want it
payload[path] = { $source: null };
await call.put<UpdateComponentAttributesArgs>(payload);
};

// attributeValue is not "value" for maps.. look at children! i suspect the same for arrays, etc
// figure out "how to display the details of an array item" rather than just empty
</script>
23 changes: 6 additions & 17 deletions app/web/src/newhotness/CodePanel.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<ul class="p-xs flex flex-col gap-xs">
<template v-if="componentId && codes">
<template v-if="component.id && codes">
<CodeViewer
v-for="(item, index) in codes"
:key="item.name ?? index"
Expand All @@ -20,32 +20,21 @@
</template>

<script lang="ts" setup>
import { useQuery } from "@tanstack/vue-query";
import { computed } from "vue";
import { bifrost, makeArgs, makeKey } from "@/store/realtime/heimdall";
import { AttributeTree } from "@/workers/types/dbinterface";
import { BifrostComponent } from "@/workers/types/dbinterface";
import CodeViewer from "@/components/CodeViewer.vue";
import EmptyStateCard from "@/components/EmptyStateCard.vue";
import { findAvsAtPropPath } from "./util";

const props = defineProps<{
componentId: string;
component: BifrostComponent;
}>();

const attributeTreeMakeKey = makeKey("AttributeTree", props.componentId);
const attributeTreeMakeArgs = makeArgs("AttributeTree", props.componentId);
const attributeTreeQuery = useQuery<AttributeTree | null>({
queryKey: attributeTreeMakeKey,
queryFn: async () => await bifrost<AttributeTree>(attributeTreeMakeArgs),
});

const root = computed(() => attributeTreeQuery.data.value);

const codes = computed(() => {
const codes: { code: string; name: string | undefined }[] = [];
if (!root.value) return codes;
if (!props.component.attributeTree) return codes;

const data = findAvsAtPropPath(root.value, [
const data = findAvsAtPropPath(props.component.attributeTree, [
"root",
"code",
"codeItem",
Expand All @@ -56,7 +45,7 @@ const codes = computed(() => {

attributeValues.forEach((av) => {
codes.push({
code: av.value,
code: av.value ?? "",
name: av.path?.split("/")[2], // "/code/<name>/code"
});
});
Expand Down
4 changes: 2 additions & 2 deletions app/web/src/newhotness/Component.vue
Original file line number Diff line number Diff line change
Expand Up @@ -161,14 +161,14 @@
<Icon v-else name="refresh-hex-outline" size="sm" tone="shade" />
Resource
</template>
<ResourcePanel :componentId="component.id" />
<ResourcePanel :component="component" />
</CollapsingFlexItem>
<CollapsingFlexItem>
<template #header>
<Icon name="brackets-curly" size="sm" />
Generated Code
</template>
<CodePanel :componentId="component.id" />
<CodePanel :component="component" />
</CollapsingFlexItem>
<CollapsingFlexItem>
<template #header>
Expand Down
15 changes: 1 addition & 14 deletions app/web/src/newhotness/QualificationPanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,9 @@
</template>

<script lang="ts" setup>
import { useQuery } from "@tanstack/vue-query";
import { computed } from "vue";
import { bifrost, useMakeArgs, useMakeKey } from "@/store/realtime/heimdall";
import {
AttributeValue,
AttributeTree,
BifrostComponent,
Prop,
} from "@/workers/types/dbinterface";
Expand All @@ -34,17 +31,7 @@ const props = defineProps<{
component: BifrostComponent;
}>();

const componentId = computed(() => props.component.id);

const key = useMakeKey();
const args = useMakeArgs();
const attributeTreeQuery = useQuery<AttributeTree | null>({
queryKey: key("AttributeTree", componentId),
queryFn: async () =>
await bifrost<AttributeTree>(args("AttributeTree", componentId.value)),
});

const root = computed(() => attributeTreeQuery.data.value);
const root = computed(() => props.component.attributeTree);

const qualItems = computed<QualItem[]>(() => {
const items: QualItem[] = [];
Expand Down
26 changes: 8 additions & 18 deletions app/web/src/newhotness/ResourcePanel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,33 +14,23 @@
</template>

<script lang="ts" setup>
import { useQuery } from "@tanstack/vue-query";
import { computed } from "vue";
import { bifrost, useMakeArgs, useMakeKey } from "@/store/realtime/heimdall";
import { AttributeTree } from "@/workers/types/dbinterface";
import { BifrostComponent } from "@/workers/types/dbinterface";
import CodeViewer from "@/components/CodeViewer.vue";
import EmptyStateCard from "@/components/EmptyStateCard.vue";
import { findAvsAtPropPath } from "./util";

const props = defineProps<{
componentId?: string;
component: BifrostComponent;
}>();

const componentId = computed(() => props.componentId ?? "");

const key = useMakeKey();
const args = useMakeArgs();
const attributeTreeQuery = useQuery<AttributeTree | null>({
queryKey: key("AttributeTree", componentId),
queryFn: async () =>
await bifrost<AttributeTree>(args("AttributeTree", componentId.value)),
});

const root = computed(() => attributeTreeQuery.data.value);

const resourcePayload = computed(() => {
if (!root.value) return;
const data = findAvsAtPropPath(root.value, ["root", "resource", "payload"]);
if (!props.component.attributeTree) return;
const data = findAvsAtPropPath(props.component.attributeTree, [
"root",
"resource",
"payload",
]);
if (!data) return;
const { attributeValues } = data;
// only one AV for /resource/payload
Expand Down
3 changes: 3 additions & 0 deletions app/web/src/newhotness/Workspace.vue
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,9 @@ onBeforeMount(async () => {

// Initial setup with resolved change set ID
heimdall.niflheim(props.workspacePk, props.changeSetId, true);
// NOTE: onBeforeMount doesn't wait on promises, so I could
// throw an await here, but it has no effect...
// leaving it off to communicate that the page will load before execution finishes
});

watch(
Expand Down
4 changes: 2 additions & 2 deletions app/web/src/newhotness/api_composables/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export class APICall<Response> {
}

async put<D = Record<string, unknown>>(data: D, params?: URLSearchParams) {
if (this.ctx.onHead) throw new Error("Can't make changes on head");
if (this.ctx.onHead.value) throw new Error("Can't make changes on head");

const req = await sdf<Response>({
method: "PUT",
Expand All @@ -255,7 +255,7 @@ export class APICall<Response> {
}

async post<D = Record<string, unknown>>(data: D, params?: URLSearchParams) {
if (this.ctx.onHead) throw new Error("Can't make changes on head");
if (this.ctx.onHead.value) throw new Error("Can't make changes on head");

const req = await sdf<Response>({
method: "POST",
Expand Down
41A0
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@
<!-- This represents the header & container for component attributes page -->
<dl class="ml-xs border-l-2 my-xs">
<!-- this is the left indent & line -->
<dt class="bg-neutral-800 p-xs" @click="() => (open = !open)">
<dt
class="bg-neutral-800 p-xs flex flex-row items-center"
@click="() => (open = !open)"
>
<slot name="header" />
</dt>
<dd v-if="open">
Expand Down
Loading
0