Unverified Commit f05c8a83 authored by Aysam Guerler's avatar Aysam Guerler Committed by GitHub
Browse files

Merge pull request #20914 from guerler/allow_creating_visualizations

Allow creation of visualizations without dataset
parents e44d3f09 f83d772f
Loading
Loading
Loading
Loading
+7 −2
Original line number Diff line number Diff line
@@ -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;
@@ -46,7 +51,7 @@ export interface ParamType {
}

export interface TestType {
    param: ParamType;
    param: TestParamType;
}

export async function fetchPlugins(datasetId?: string): Promise<Array<Plugin>> {
+25 −12
Original line number Diff line number Diff line
@@ -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(),
@@ -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,
@@ -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..." }]);
});
+13 −12
Original line number Diff line number Diff line
@@ -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";
@@ -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 [];
    }
@@ -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,
    });
@@ -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"
+7 −6
Original line number Diff line number Diff line
@@ -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}`;
        }
    }

+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