Skip to content

Commit

Permalink
Merge pull request #17070 from guerler/router_event
Browse files Browse the repository at this point in the history
Use eventbus to emit route request in grid list
  • Loading branch information
dannon authored Nov 27, 2023
2 parents 4aae2aa + 7306bca commit c050dcb
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 26 deletions.
9 changes: 1 addition & 8 deletions client/src/components/Grid/GridList.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { mount } from "@vue/test-utils";
import flushPromises from "flush-promises";
import { getLocalVue } from "tests/jest/helpers";
import { useRouter } from "vue-router/composables";

import Filtering from "@/utils/filtering";

Expand All @@ -10,9 +9,6 @@ import MountTarget from "./GridList.vue";
const localVue = getLocalVue();

jest.useFakeTimers();
jest.mock("vue-router/composables");

useRouter.mockImplementation(() => "router");

const testGrid = {
actions: [
Expand Down Expand Up @@ -147,10 +143,7 @@ describe("GridList", () => {
await dropdownItems.at(0).trigger("click");
const clickHandler = testGrid.fields[2].operations[0].handler;
expect(clickHandler).toHaveBeenCalledTimes(1);
expect(clickHandler.mock.calls[0]).toEqual([
{ id: "id-1", link: "link-1", operation: "operation-1" },
"router",
]);
expect(clickHandler.mock.calls[0]).toEqual([{ id: "id-1", link: "link-1", operation: "operation-1" }]);
await dropdownItems.at(1).trigger("click");
await flushPromises();
const alert = wrapper.find(".alert");
Expand Down
27 changes: 21 additions & 6 deletions client/src/components/Grid/GridList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
import { library } from "@fortawesome/fontawesome-svg-core";
import { faCaretDown, faCaretUp } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { useDebounceFn } from "@vueuse/core";
import { useDebounceFn, useEventBus } from "@vueuse/core";
import { BAlert, BButton, BLink, BPagination } from "bootstrap-vue";
import { computed, onMounted, ref, watch } from "vue";
import { computed, onMounted, onUnmounted, ref, watch } from "vue";
import { useRouter } from "vue-router/composables";
import { Config, FieldHandler, Operation, RowData } from "./configs/types";
Expand All @@ -18,9 +18,11 @@ import LoadingSpan from "@/components/LoadingSpan.vue";
import StatelessTags from "@/components/TagsMultiselect/StatelessTags.vue";
import UtcDate from "@/components/UtcDate.vue";
library.add(faCaretDown, faCaretUp);
const eventBus = useEventBus<string>("grid-router-push");
const router = useRouter();
library.add(faCaretDown, faCaretUp);
interface Props {
// provide a grid configuration
config: Config;
Expand Down Expand Up @@ -107,14 +109,21 @@ async function getGridData() {
* Execute grid operation and display message if available
*/
async function onOperation(operation: Operation, rowData: RowData) {
const response = await operation.handler(rowData, router);
const response = await operation.handler(rowData);
if (response) {
await getGridData();
operationMessage.value = response.message;
operationStatus.value = response.status || "success";
}
}
/**
* Handle router push request emitted by grid module
*/
function onRouterPush(route: string) {
router.push(route);
}
/**
* Apply backend formatted filter and execute grid search
*/
Expand Down Expand Up @@ -147,11 +156,17 @@ function onFilter(filter?: string) {
applyFilter(filter, true);
}
}
/**
* Initialize grid data
*/
onMounted(() => {
getGridData();
eventBus.on(onRouterPush);
});
onUnmounted(() => {
eventBus.off(onRouterPush);
});
/**
Expand Down Expand Up @@ -195,7 +210,7 @@ watch(operationMessage, () => {
size="sm"
variant="primary"
:data-description="`grid action ${action.title.toLowerCase()}`"
@click="action.handler(router)">
@click="action.handler()">
<Icon :icon="action.icon" class="mr-1" />
<span v-localize>{{ action.title }}</span>
</BButton>
Expand Down Expand Up @@ -244,7 +259,7 @@ watch(operationMessage, () => {
<GridLink
v-else-if="fieldEntry.type == 'link'"
:text="rowData[fieldEntry.key]"
@click="fieldEntry.handler && fieldEntry.handler(rowData, router)" />
@click="fieldEntry.handler && fieldEntry.handler(rowData)" />
<SharingIndicators
v-else-if="fieldEntry.type == 'sharing'"
:object="rowData"
Expand Down
11 changes: 6 additions & 5 deletions client/src/components/Grid/configs/types.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { IconDefinition } from "@fortawesome/fontawesome-svg-core";
import type Router from "vue-router";

import Filtering from "@/utils/filtering";

export interface Action {
title: string;
icon?: IconDefinition;
handler: (router: Router) => void;
handler: () => void;
}

export type ActionArray = Array<Action>;
Expand All @@ -30,19 +29,19 @@ export interface FieldEntry {
title: string;
condition?: (data: RowData) => boolean;
disabled?: boolean;
type: string;
type: validTypes;
operations?: Array<Operation>;
handler?: FieldHandler;
width?: number;
}

export type FieldHandler = (data: RowData, router?: Router) => void;
export type FieldHandler = (data: RowData) => void;

export interface Operation {
title: string;
icon: IconDefinition;
condition?: (data: RowData) => boolean;
handler: (data: RowData, router: Router) => OperationHandlerReturn;
handler: (data: RowData) => OperationHandlerReturn;
}

interface OperationHandlerMessage {
Expand All @@ -53,3 +52,5 @@ interface OperationHandlerMessage {
type OperationHandlerReturn = Promise<OperationHandlerMessage> | void;

export type RowData = Record<string, unknown>;

type validTypes = "date" | "link" | "operations" | "sharing" | "tags" | "text";
16 changes: 9 additions & 7 deletions client/src/components/Grid/configs/visualizations.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { faCopy, faEdit, faEye, faPlus, faShareAlt, faTrash, faTrashRestore } from "@fortawesome/free-solid-svg-icons";
import { useEventBus } from "@vueuse/core";
import axios from "axios";
import type Router from "vue-router";

import { fetcher } from "@/api/schema";
import { getGalaxyInstance } from "@/app";
Expand All @@ -10,6 +10,8 @@ import { errorMessageAsString, rethrowSimple } from "@/utils/simple-error";

import type { ActionArray, Config, FieldArray } from "./types";

const { emit } = useEventBus<string>("grid-router-push");

/**
* Api endpoint handlers
*/
Expand Down Expand Up @@ -52,8 +54,8 @@ const actions: ActionArray = [
{
title: "Create",
icon: faPlus,
handler: (router: Router) => {
router.push(`/visualizations`);
handler: () => {
emit("/visualizations");
},
},
];
Expand Down Expand Up @@ -81,8 +83,8 @@ const fields: FieldArray = [
title: "Edit Attributes",
icon: faEdit,
condition: (data: VisualizationEntry) => !data.deleted,
handler: (data: VisualizationEntry, router: Router) => {
router.push(`/visualizations/edit?id=${data.id}`);
handler: (data: VisualizationEntry) => {
emit(`/visualizations/edit?id=${data.id}`);
},
},
{
Expand Down Expand Up @@ -115,8 +117,8 @@ const fields: FieldArray = [
title: "Share and Publish",
icon: faShareAlt,
condition: (data: VisualizationEntry) => !data.deleted,
handler: (data: VisualizationEntry, router: Router) => {
router.push(`/visualizations/sharing?id=${data.id}`);
handler: (data: VisualizationEntry) => {
emit(`/visualizations/sharing?id=${data.id}`);
},
},
{
Expand Down

0 comments on commit c050dcb

Please sign in to comment.