Loading client/src/api/plugins.ts +7 −2 Original line number Diff line number Diff line Loading @@ -29,16 +29,21 @@ export interface Plugin { html: string; logo?: string; name: string; params?: Record<string, ParamType>; target?: string; tags?: Array<string>; tests?: Array<TestType>; } export interface ParamType { required?: boolean; } export interface PluginData { hdas: Array<Dataset>; } export interface ParamType { export interface TestParamType { ftype?: string; label?: string; name: string; Loading @@ -46,7 +51,7 @@ export interface ParamType { } export interface TestType { param: ParamType; param: TestParamType; } export async function fetchPlugins(datasetId?: string): Promise<Array<Plugin>> { Loading client/src/components/Visualizations/VisualizationCreate.test.js +25 −12 Original line number Diff line number Diff line Loading @@ -4,11 +4,20 @@ import { createPinia, defineStore, setActivePinia } from "pinia"; import { getLocalVue } from "tests/jest/helpers"; import { ref } from "vue"; import { fetchPluginHistoryItems } from "@/api/plugins"; import { fetchPlugin, fetchPluginHistoryItems } from "@/api/plugins"; import VisualizationCreate from "./VisualizationCreate.vue"; import FormCardSticky from "@/components/Form/FormCardSticky.vue"; const PLUGIN = { name: "scatterplot", description: "A great scatterplot plugin.", html: "Scatterplot Plugin", logo: "/logo.png", help: "Some help text", tags: ["tag1", "tag2"], }; jest.mock("vue-router/composables", () => ({ useRouter: () => ({ push: jest.fn(), Loading @@ -18,22 +27,13 @@ jest.mock("vue-router/composables", () => ({ jest.mock("@/api/plugins", () => ({ fetchPlugin: jest.fn(() => Promise.resolve({ name: "scatterplot", description: "A great scatterplot plugin.", html: "Scatterplot Plugin", logo: "/logo.png", help: "Some help text", tags: ["tag1", "tag2"], params: { dataset_id: { required: true } }, ...PLUGIN, }), ), fetchPluginHistoryItems: jest.fn(() => Promise.resolve({ hdas: [] })), })); jest.mock("./utilities", () => ({ getTestExtensions: jest.fn(() => ["txt"]), getTestUrls: jest.fn(() => [{ name: "Example", url: "https://example.com/data.txt" }]), })); let mockedStore; jest.mock("@/stores/historyStore", () => ({ useHistoryStore: () => mockedStore, Loading Loading @@ -95,3 +95,16 @@ it("adds hid to dataset names when fetching history items", async () => { { id: "dataset2", name: "102: Second Dataset" }, ]); }); it("displays create new visualization option if dataset is not required", async () => { fetchPlugin.mockResolvedValueOnce(PLUGIN); const wrapper = mount(VisualizationCreate, { localVue, propsData: { visualization: "scatterplot", }, }); await wrapper.vm.$nextTick(); const results = await wrapper.vm.doQuery(); expect(results).toEqual([{ id: "", name: "Open visualization..." }]); }); client/src/components/Visualizations/VisualizationCreate.vue +13 −12 Original line number Diff line number Diff line Loading @@ -3,12 +3,12 @@ import { storeToRefs } from "pinia"; import { computed, onMounted, type Ref, ref } from "vue"; import { useRouter } from "vue-router/composables"; import { type Dataset, fetchPlugin, fetchPluginHistoryItems, type Plugin } from "@/api/plugins"; import { fetchPlugin, fetchPluginHistoryItems, type Plugin } from "@/api/plugins"; import type { OptionType } from "@/components/SelectionField/types"; import { useMarkdown } from "@/composables/markdown"; import { useHistoryStore } from "@/stores/historyStore"; import { getTestExtensions, getTestUrls } from "./utilities"; import { getRequiresDataset, getTestExtensions, getTestUrls } from "./utilities"; import VisualizationExamples from "./VisualizationExamples.vue"; import Heading from "@/components/Common/Heading.vue"; Loading @@ -27,20 +27,20 @@ const props = defineProps<{ }>(); const errorMessage = ref(""); const formatsVisible = ref(false); const plugin: Ref<Plugin | undefined> = ref(); const urlData = computed(() => getTestUrls(plugin.value)); const extensions = computed(() => getTestExtensions(plugin.value)); const formatsVisible = ref(false); function addHidToName(hdas: Array<Dataset>) { return hdas.map((entry) => ({ id: entry.id, name: `${entry.hid}: ${entry.name}` })); } const requiresDataset = computed(() => getRequiresDataset(plugin.value)); const testUrls = computed(() => getTestUrls(plugin.value)); async function doQuery() { if (currentHistoryId.value && plugin.value) { const data = await fetchPluginHistoryItems(plugin.value.name, currentHistoryId.value); return addHidToName(data.hdas); return [ ...(!requiresDataset.value ? [{ id: "", name: `Open visualization...` }] : []), ...data.hdas.map((hda) => ({ id: hda.id, name: `${hda.hid}: ${hda.name}` })), ]; } else { return []; } Loading @@ -51,7 +51,8 @@ async function getPlugin() { } function onSelect(dataset: OptionType) { router.push(`/visualizations/display?visualization=${plugin.value?.name}&dataset_id=${dataset.id}`, { const query = dataset.id ? `&dataset_id=${dataset.id}` : ""; router.push(`/visualizations/display?visualization=${plugin.value?.name}${query}`, { // @ts-ignore title: dataset.name, }); Loading @@ -73,11 +74,11 @@ defineExpose({ doQuery }); :logo="plugin?.logo" :name="plugin?.html"> <template v-slot:buttons> <VisualizationExamples :url-data="urlData" /> <VisualizationExamples :url-data="testUrls" /> </template> <div class="my-3"> <SelectionField object-name="Select a dataset..." object-name="Make a selection..." object-title="Select to Visualize" object-type="history_dataset_id" :object-query="doQuery" Loading client/src/components/Visualizations/VisualizationFrame.vue +7 −6 Original line number Diff line number Diff line Loading @@ -23,16 +23,17 @@ const iframeRef = ref<HTMLIFrameElement | null>(null); const srcWithRoot = computed(() => { let url = ""; if (props.visualization === "trackster") { if (props.datasetId) { url = `/visualization/trackster?dataset_id=${props.datasetId}`; } else { if (props.visualizationId) { url = `/visualization/trackster?id=${props.visualizationId}`; } } else { if (props.datasetId) { url = `/plugins/visualizations/${props.visualization}/show?dataset_id=${props.datasetId}`; url = `/visualization/trackster?dataset_id=${props.datasetId}`; } } else { if (props.visualizationId) { url = `/plugins/visualizations/${props.visualization}/saved?id=${props.visualizationId}`; } else { const query = props.datasetId ? `?dataset_id=${props.datasetId}` : ""; url = `/plugins/visualizations/${props.visualization}/show${query}`; } } Loading client/src/components/Visualizations/utilities.test.js +10 −2 Original line number Diff line number Diff line import { getFilename, getTestUrls } from "./utilities"; import { getFilename, getRequiresDataset, getTestUrls } from "./utilities"; describe("Utility Functions", () => { describe("getTestUrls", () => { describe("getRequiresDataset and getTestUrls", () => { it("return wether the visualization requires a dataset or not", () => { expect(getRequiresDataset({})).toEqual(false); const plugin = { params: { dataset_id: { required: true } }, }; expect(getRequiresDataset(plugin)).toEqual(true); }); it("returns empty array when plugin is undefined", () => { expect(getTestUrls()).toEqual([]); }); Loading Loading
client/src/api/plugins.ts +7 −2 Original line number Diff line number Diff line Loading @@ -29,16 +29,21 @@ export interface Plugin { html: string; logo?: string; name: string; params?: Record<string, ParamType>; target?: string; tags?: Array<string>; tests?: Array<TestType>; } export interface ParamType { required?: boolean; } export interface PluginData { hdas: Array<Dataset>; } export interface ParamType { export interface TestParamType { ftype?: string; label?: string; name: string; Loading @@ -46,7 +51,7 @@ export interface ParamType { } export interface TestType { param: ParamType; param: TestParamType; } export async function fetchPlugins(datasetId?: string): Promise<Array<Plugin>> { Loading
client/src/components/Visualizations/VisualizationCreate.test.js +25 −12 Original line number Diff line number Diff line Loading @@ -4,11 +4,20 @@ import { createPinia, defineStore, setActivePinia } from "pinia"; import { getLocalVue } from "tests/jest/helpers"; import { ref } from "vue"; import { fetchPluginHistoryItems } from "@/api/plugins"; import { fetchPlugin, fetchPluginHistoryItems } from "@/api/plugins"; import VisualizationCreate from "./VisualizationCreate.vue"; import FormCardSticky from "@/components/Form/FormCardSticky.vue"; const PLUGIN = { name: "scatterplot", description: "A great scatterplot plugin.", html: "Scatterplot Plugin", logo: "/logo.png", help: "Some help text", tags: ["tag1", "tag2"], }; jest.mock("vue-router/composables", () => ({ useRouter: () => ({ push: jest.fn(), Loading @@ -18,22 +27,13 @@ jest.mock("vue-router/composables", () => ({ jest.mock("@/api/plugins", () => ({ fetchPlugin: jest.fn(() => Promise.resolve({ name: "scatterplot", description: "A great scatterplot plugin.", html: "Scatterplot Plugin", logo: "/logo.png", help: "Some help text", tags: ["tag1", "tag2"], params: { dataset_id: { required: true } }, ...PLUGIN, }), ), fetchPluginHistoryItems: jest.fn(() => Promise.resolve({ hdas: [] })), })); jest.mock("./utilities", () => ({ getTestExtensions: jest.fn(() => ["txt"]), getTestUrls: jest.fn(() => [{ name: "Example", url: "https://example.com/data.txt" }]), })); let mockedStore; jest.mock("@/stores/historyStore", () => ({ useHistoryStore: () => mockedStore, Loading Loading @@ -95,3 +95,16 @@ it("adds hid to dataset names when fetching history items", async () => { { id: "dataset2", name: "102: Second Dataset" }, ]); }); it("displays create new visualization option if dataset is not required", async () => { fetchPlugin.mockResolvedValueOnce(PLUGIN); const wrapper = mount(VisualizationCreate, { localVue, propsData: { visualization: "scatterplot", }, }); await wrapper.vm.$nextTick(); const results = await wrapper.vm.doQuery(); expect(results).toEqual([{ id: "", name: "Open visualization..." }]); });
client/src/components/Visualizations/VisualizationCreate.vue +13 −12 Original line number Diff line number Diff line Loading @@ -3,12 +3,12 @@ import { storeToRefs } from "pinia"; import { computed, onMounted, type Ref, ref } from "vue"; import { useRouter } from "vue-router/composables"; import { type Dataset, fetchPlugin, fetchPluginHistoryItems, type Plugin } from "@/api/plugins"; import { fetchPlugin, fetchPluginHistoryItems, type Plugin } from "@/api/plugins"; import type { OptionType } from "@/components/SelectionField/types"; import { useMarkdown } from "@/composables/markdown"; import { useHistoryStore } from "@/stores/historyStore"; import { getTestExtensions, getTestUrls } from "./utilities"; import { getRequiresDataset, getTestExtensions, getTestUrls } from "./utilities"; import VisualizationExamples from "./VisualizationExamples.vue"; import Heading from "@/components/Common/Heading.vue"; Loading @@ -27,20 +27,20 @@ const props = defineProps<{ }>(); const errorMessage = ref(""); const formatsVisible = ref(false); const plugin: Ref<Plugin | undefined> = ref(); const urlData = computed(() => getTestUrls(plugin.value)); const extensions = computed(() => getTestExtensions(plugin.value)); const formatsVisible = ref(false); function addHidToName(hdas: Array<Dataset>) { return hdas.map((entry) => ({ id: entry.id, name: `${entry.hid}: ${entry.name}` })); } const requiresDataset = computed(() => getRequiresDataset(plugin.value)); const testUrls = computed(() => getTestUrls(plugin.value)); async function doQuery() { if (currentHistoryId.value && plugin.value) { const data = await fetchPluginHistoryItems(plugin.value.name, currentHistoryId.value); return addHidToName(data.hdas); return [ ...(!requiresDataset.value ? [{ id: "", name: `Open visualization...` }] : []), ...data.hdas.map((hda) => ({ id: hda.id, name: `${hda.hid}: ${hda.name}` })), ]; } else { return []; } Loading @@ -51,7 +51,8 @@ async function getPlugin() { } function onSelect(dataset: OptionType) { router.push(`/visualizations/display?visualization=${plugin.value?.name}&dataset_id=${dataset.id}`, { const query = dataset.id ? `&dataset_id=${dataset.id}` : ""; router.push(`/visualizations/display?visualization=${plugin.value?.name}${query}`, { // @ts-ignore title: dataset.name, }); Loading @@ -73,11 +74,11 @@ defineExpose({ doQuery }); :logo="plugin?.logo" :name="plugin?.html"> <template v-slot:buttons> <VisualizationExamples :url-data="urlData" /> <VisualizationExamples :url-data="testUrls" /> </template> <div class="my-3"> <SelectionField object-name="Select a dataset..." object-name="Make a selection..." object-title="Select to Visualize" object-type="history_dataset_id" :object-query="doQuery" Loading
client/src/components/Visualizations/VisualizationFrame.vue +7 −6 Original line number Diff line number Diff line Loading @@ -23,16 +23,17 @@ const iframeRef = ref<HTMLIFrameElement | null>(null); const srcWithRoot = computed(() => { let url = ""; if (props.visualization === "trackster") { if (props.datasetId) { url = `/visualization/trackster?dataset_id=${props.datasetId}`; } else { if (props.visualizationId) { url = `/visualization/trackster?id=${props.visualizationId}`; } } else { if (props.datasetId) { url = `/plugins/visualizations/${props.visualization}/show?dataset_id=${props.datasetId}`; url = `/visualization/trackster?dataset_id=${props.datasetId}`; } } else { if (props.visualizationId) { url = `/plugins/visualizations/${props.visualization}/saved?id=${props.visualizationId}`; } else { const query = props.datasetId ? `?dataset_id=${props.datasetId}` : ""; url = `/plugins/visualizations/${props.visualization}/show${query}`; } } Loading
client/src/components/Visualizations/utilities.test.js +10 −2 Original line number Diff line number Diff line import { getFilename, getTestUrls } from "./utilities"; import { getFilename, getRequiresDataset, getTestUrls } from "./utilities"; describe("Utility Functions", () => { describe("getTestUrls", () => { describe("getRequiresDataset and getTestUrls", () => { it("return wether the visualization requires a dataset or not", () => { expect(getRequiresDataset({})).toEqual(false); const plugin = { params: { dataset_id: { required: true } }, }; expect(getRequiresDataset(plugin)).toEqual(true); }); it("returns empty array when plugin is undefined", () => { expect(getTestUrls()).toEqual([]); }); Loading