Skip to content

Commit

Permalink
perf(ui): use Async component to avoid loading ressources - WF-107
Browse files Browse the repository at this point in the history
  • Loading branch information
madeindjs committed Jan 24, 2025
1 parent ef7030d commit 6b3b777
Show file tree
Hide file tree
Showing 7 changed files with 144 additions and 106 deletions.
41 changes: 41 additions & 0 deletions src/ui/src/components/core/content/CorePlotlyGraph.def.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { FieldType, WriterComponentDefinition } from "@/writerTypes";
import { cssClasses } from "@/renderer/sharedStyleFields";

const description = "A component that displays Plotly graphs.";

const defaultSpec = {
data: [
{
x: ["a", "b", "c"],
y: [22, 25, 29],
type: "bar",
},
],
};
const definition: WriterComponentDefinition = {
name: "Plotly Graph",
description,
category: "Content",
fields: {
spec: {
name: "Graph specification",
default: JSON.stringify(defaultSpec, null, 2),
desc: "Plotly graph specification. Pass it using state, e.g. @{fig}, or paste a JSON specification.",
type: FieldType.Object,
},
cssClasses,
},
events: {
"plotly-click": {
desc: "Sends a list with the clicked points.",
},
"plotly-selected": {
desc: "Sends a list with the selected points.",
},
"plotly-deselect": {
desc: "Triggered when points are deselected.",
},
},
};

export default definition;
42 changes: 2 additions & 40 deletions src/ui/src/components/core/content/CorePlotlyGraph.vue
Original file line number Diff line number Diff line change
Expand Up @@ -10,49 +10,11 @@ For example, implement cross-filtering.
</template>

<script lang="ts">
import { FieldType } from "@/writerTypes";
import { cssClasses } from "@/renderer/sharedStyleFields";
import { WdsColor } from "@/wds/tokens";
const description = "A component that displays Plotly graphs.";
import definition from "./CorePlotlyGraph.def";
const defaultSpec = {
data: [
{
x: ["a", "b", "c"],
y: [22, 25, 29],
type: "bar",
},
],
};
export default {
writer: {
name: "Plotly Graph",
description,
category: "Content",
fields: {
spec: {
name: "Graph specification",
default: JSON.stringify(defaultSpec, null, 2),
desc: "Plotly graph specification. Pass it using state, e.g. @{fig}, or paste a JSON specification.",
type: FieldType.Object,
},
cssClasses,
},
events: {
"plotly-click": {
desc: "Sends a list with the clicked points.",
},
"plotly-selected": {
desc: "Sends a list with the selected points.",
},
"plotly-deselect": {
desc: "Triggered when points are deselected.",
},
},
},
};
export default { writer: definition };
</script>

<script setup lang="ts">
Expand Down
55 changes: 55 additions & 0 deletions src/ui/src/components/core/embed/CorePDF.def.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { FieldType, WriterComponentDefinition } from "@/writerTypes";
import {
cssClasses,
separatorColor,
primaryTextColor,
containerBackgroundColor,
} from "@/renderer/sharedStyleFields";

const description = "A component to embed PDF documents.";

const definition: WriterComponentDefinition = {
name: "PDF",
description,
category: "Embed",
fields: {
source: {
name: "PDF source",
type: FieldType.Text,
desc: "A valid URL. Alternatively, you can provide a state reference to a packed PDF file.",
},
highlights: {
name: "Highlights",
default: JSON.stringify([]),
desc: "A list of highlights to be applied to the PDF as a JSON array of strings.",
type: FieldType.Object,
},
selectedMatch: {
name: "Selected highlight match",
default: null,
desc: "The index of the selected highlight match.",
type: FieldType.Number,
},
page: {
name: "Page",
type: FieldType.Number,
desc: "The page to be displayed.",
},
controls: {
name: "Controls",
type: FieldType.Text,
options: {
yes: "Yes",
no: "No",
},
desc: "Show controls to navigate the PDF.",
default: "yes",
},
containerBackgroundColor,
separatorColor,
primaryTextColor,
cssClasses,
},
};

export default definition;
58 changes: 3 additions & 55 deletions src/ui/src/components/core/embed/CorePDF.vue
Original file line number Diff line number Diff line change
Expand Up @@ -45,67 +45,15 @@
</template>

<script lang="ts">
import { FieldType } from "@/writerTypes";
import {
cssClasses,
separatorColor,
primaryTextColor,
containerBackgroundColor,
} from "@/renderer/sharedStyleFields";
import WdsControl from "@/wds/WdsControl.vue";
import definition from "./CorePDF.def";
const description = "A component to embed PDF documents.";
export default {
writer: {
name: "PDF",
description,
category: "Embed",
fields: {
source: {
name: "PDF source",
type: FieldType.Text,
desc: "A valid URL. Alternatively, you can provide a state reference to a packed PDF file.",
},
highlights: {
name: "Highlights",
default: JSON.stringify([]),
desc: "A list of highlights to be applied to the PDF as a JSON array of strings.",
type: FieldType.Object,
},
selectedMatch: {
name: "Selected highlight match",
default: null,
desc: "The index of the selected highlight match.",
type: FieldType.Number,
},
page: {
name: "Page",
type: FieldType.Number,
desc: "The page to be displayed.",
},
controls: {
name: "Controls",
type: FieldType.Text,
options: {
yes: "Yes",
no: "No",
},
desc: "Show controls to navigate the PDF.",
default: "yes",
},
containerBackgroundColor,
separatorColor,
primaryTextColor,
cssClasses,
},
},
};
export default { writer: definition };
</script>

<script setup lang="ts">
import { inject, ref, watch, computed, onMounted } from "vue";
import injectionKeys from "@/injectionKeys";
import WdsControl from "@/wds/WdsControl.vue";
import "@tato30/vue-pdf/style.css";
type MatchType = { str: string; page: number; index: number };
Expand Down
39 changes: 32 additions & 7 deletions src/ui/src/core/templateMap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import CoreIcon from "../components/core/content/CoreIcon.vue";
import CoreImage from "../components/core/content/CoreImage.vue";
import CoreMessage from "../components/core/content/CoreMessage.vue";
import CoreMetric from "../components/core/content/CoreMetric.vue";
import CorePlotlyGraph from "../components/core/content/CorePlotlyGraph.vue";
import CorePlotlyGraphDefinition from "../components/core/content/CorePlotlyGraph.def";
import CoreText from "../components/core/content/CoreText.vue";
import CoreVegaLiteChart from "../components/core/content/CoreVegaLiteChart.vue";
import CoreVideoPlayer from "../components/core/content/CoreVideoPlayer.vue";
Expand Down Expand Up @@ -57,7 +57,7 @@ import CoreTimer from "../components/core/other/CoreTimer.vue";
import CoreWebcamCapture from "../components/core/other/CoreWebcamCapture.vue";
import CoreReuse from "../components/core/other/CoreReuse.vue";
// embed
import CorePDF from "../components/core/embed/CorePDF.vue";
import CorePDFDefinition from "../components/core/embed/CorePDF.def";
import CoreIFrame from "../components/core/embed/CoreIFrame.vue";
import CoreGoogleMaps from "../components/core/embed/CoreGoogleMaps.vue";
// root
Expand All @@ -76,7 +76,7 @@ import type {
TemplateMap,
WriterComponentDefinition,
} from "@/writerTypes";
import { h } from "vue";
import { defineAsyncComponent, h } from "vue";

const templateMap: TemplateMap = {
root: CoreRoot,
Expand All @@ -99,7 +99,12 @@ const templateMap: TemplateMap = {
horizontalstack: CoreHorizontalStack,
separator: CoreSeparator,
image: CoreImage,
pdf: CorePDF,
pdf: {
definition: CorePDFDefinition,
asyncComponent: defineAsyncComponent(
() => import("../components/core/embed/CorePDF.vue"),
),
},
iframe: CoreIFrame,
googlemaps: CoreGoogleMaps,
mapbox: CoreMapbox,
Expand All @@ -121,7 +126,12 @@ const templateMap: TemplateMap = {
fileinput: CoreFileInput,
webcamcapture: CoreWebcamCapture,
vegalitechart: CoreVegaLiteChart,
plotlygraph: CorePlotlyGraph,
plotlygraph: {
asyncComponent: defineAsyncComponent(
() => import("../components/core/content/CorePlotlyGraph.vue"),
),
definition: CorePlotlyGraphDefinition,
},
metric: CoreMetric,
message: CoreMessage,
videoplayer: CoreVideoPlayer,
Expand Down Expand Up @@ -201,18 +211,33 @@ function getMergedAbstractTemplate(type: string) {
};
}

export function getTemplate(type: string) {
export function getTemplate(type: string): TemplateMap[0] {
return (
getMergedAbstractTemplate(type) ??
templateMap[type] ??
fallbackTemplate(type)
);
}

export function getComponentTemplate(type: string): VueComponent {
const template = getTemplate(type);

if (template === undefined) return undefined;
if (typeof template === "object" && "asyncComponent" in template)
return template.asyncComponent;
return template;
}

export function getComponentDefinition(
type: string,
): WriterComponentDefinition {
return getTemplate(type)?.writer;
const template = getTemplate(type);

if (template === undefined) return undefined;
if (typeof template === "object" && "definition" in template)
return template.definition;
// @ts-expect-error writer is defined
return template.writer;
}

export function getSupportedComponentTypes() {
Expand Down
4 changes: 2 additions & 2 deletions src/ui/src/renderer/ComponentProxy.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts">
import { PropType, VNode, computed, h, inject, provide, ref, watch } from "vue";
import { getTemplate } from "@/core/templateMap";
import { getComponentTemplate, getTemplate } from "@/core/templateMap";
import injectionKeys from "@/injectionKeys";
import {
Component,
Expand All @@ -25,7 +25,7 @@ export default {
const ssbm = inject(injectionKeys.builderManager);
const componentId = props.componentId;
const component = computed(() => wf.getComponentById(componentId));
const template = getTemplate(component.value.type);
const template = getComponentTemplate(component.value.type);
const instancePath = props.instancePath;
const instanceData = props.instanceData;
const { getEvaluatedFields, isComponentVisible } = useEvaluator(wf);
Expand Down
11 changes: 9 additions & 2 deletions src/ui/src/writerTypes.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { Component as VueComponent } from "vue";
import type { AsyncComponentLoader, Component as VueComponent } from "vue";
import { generateCore } from "./core";
import { generateBuilderManager } from "./builder/builderManager";

Expand Down Expand Up @@ -163,4 +163,11 @@ export type AbstractTemplate = {
writer: WriterComponentDefinition;
};

export type TemplateMap = Record<string, VueComponent>;
export type TemplateMap = Record<
string,
| VueComponent
| {
definition: WriterComponentDefinition;
asyncComponent: AsyncComponentLoader;
}
>;

0 comments on commit 6b3b777

Please sign in to comment.