From 74adad39daf031cff673ea1165541301430b67b4 Mon Sep 17 00:00:00 2001 From: guerler Date: Fri, 12 Jan 2024 20:57:53 +0300 Subject: [PATCH 01/15] Add batch operations to grid list --- client/src/components/Grid/GridList.vue | 42 +++++++++++++++++-- .../src/components/Grid/configs/histories.ts | 14 ++++++- client/src/components/Grid/configs/types.ts | 10 +++++ 3 files changed, 62 insertions(+), 4 deletions(-) diff --git a/client/src/components/Grid/GridList.vue b/client/src/components/Grid/GridList.vue index 3db89944ecb0..d516ea6f2b60 100644 --- a/client/src/components/Grid/GridList.vue +++ b/client/src/components/Grid/GridList.vue @@ -4,10 +4,11 @@ import { faCaretDown, faCaretUp, faShieldAlt } from "@fortawesome/free-solid-svg import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { useDebounceFn, useEventBus } from "@vueuse/core"; import { BAlert, BButton, BPagination } from "bootstrap-vue"; +import type { Ref } from "vue"; import { computed, onMounted, onUnmounted, ref, watch } from "vue"; import { useRouter } from "vue-router/composables"; -import { FieldHandler, GridConfig, Operation, RowData } from "./configs/types"; +import { BatchOperation, FieldHandler, GridConfig, Operation, RowData } from "./configs/types"; import GridBoolean from "./GridElements/GridBoolean.vue"; import GridDatasets from "./GridElements/GridDatasets.vue"; @@ -48,6 +49,7 @@ const gridData = ref(); const errorMessage = ref(""); const operationMessage = ref(""); const operationStatus = ref(""); +const selected: Ref<{ [key: number]: boolean }> = ref({}); // page references const currentPage = ref(1); @@ -172,6 +174,15 @@ function onFilter(filter?: string) { } } +function onBatch(operation: BatchOperation) { + alert(operation.title); +} + +function onSelect(rowIndex: number) { + selected.value[rowIndex] = !selected.value[rowIndex]; + selected.value = { ...selected.value }; +} + /** * Initialize grid data */ @@ -242,6 +253,7 @@ watch(operationMessage, () => { + +
Select {
+ + + {
- diff --git a/client/src/components/Grid/configs/histories.ts b/client/src/components/Grid/configs/histories.ts index a5713964bcba..8c9b32a769dd 100644 --- a/client/src/components/Grid/configs/histories.ts +++ b/client/src/components/Grid/configs/histories.ts @@ -17,7 +17,7 @@ import Filtering, { contains, equals, expandNameTag, toBool, type ValidFilter } import _l from "@/utils/localization"; import { errorMessageAsString, rethrowSimple } from "@/utils/simple-error"; -import type { ActionArray, FieldArray, GridConfig } from "./types"; +import type { ActionArray, BatchOperationArray, FieldArray, GridConfig } from "./types"; const { emit } = useEventBus("grid-router-push"); @@ -208,6 +208,17 @@ const fields: FieldArray = [ }, ]; +const batch: BatchOperationArray = [ + { + title: "Delete", + icon: faTrash, + handler: (data: Array) => { + // Delete all + console.log(data); + }, + }, +]; + /** * Declare filter options */ @@ -258,6 +269,7 @@ const gridConfig: GridConfig = { fields: fields, filtering: new Filtering(validFilters, undefined, false, false), getData: getData, + batch: batch, plural: "Histories", sortBy: "update_time", sortDesc: true, diff --git a/client/src/components/Grid/configs/types.ts b/client/src/components/Grid/configs/types.ts index fcc27b69bd53..45f599eb09a3 100644 --- a/client/src/components/Grid/configs/types.ts +++ b/client/src/components/Grid/configs/types.ts @@ -17,6 +17,7 @@ export interface GridConfig { fields: FieldArray; filtering: Filtering; getData: (offset: number, limit: number, search: string, sort_by: string, sort_desc: boolean) => Promise; + batch?: BatchOperationArray; plural: string; sortBy: string; sortKeys: Array; @@ -39,6 +40,15 @@ export interface FieldEntry { export type FieldHandler = (data: RowData) => void; +export interface BatchOperation { + title: string; + icon: IconDefinition; + condition?: (data: Array, config: GalaxyConfiguration) => boolean; + handler: (data: Array) => OperationHandlerReturn; +} + +export type BatchOperationArray = Array; + export interface Operation { title: string; icon: IconDefinition; From cde0e79d85f07d86512d1dff2b0d6df5189e8808 Mon Sep 17 00:00:00 2001 From: guerler Date: Sat, 13 Jan 2024 07:41:30 +0300 Subject: [PATCH 02/15] Use set to collect selected rows, add operation condition --- client/src/components/Grid/GridList.vue | 54 +++++++++++-------- .../src/components/Grid/configs/histories.ts | 24 +++++---- client/src/components/Grid/configs/types.ts | 2 +- 3 files changed, 46 insertions(+), 34 deletions(-) diff --git a/client/src/components/Grid/GridList.vue b/client/src/components/Grid/GridList.vue index d516ea6f2b60..2b277e182cb9 100644 --- a/client/src/components/Grid/GridList.vue +++ b/client/src/components/Grid/GridList.vue @@ -4,7 +4,6 @@ import { faCaretDown, faCaretUp, faShieldAlt } from "@fortawesome/free-solid-svg import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import { useDebounceFn, useEventBus } from "@vueuse/core"; import { BAlert, BButton, BPagination } from "bootstrap-vue"; -import type { Ref } from "vue"; import { computed, onMounted, onUnmounted, ref, watch } from "vue"; import { useRouter } from "vue-router/composables"; @@ -49,7 +48,7 @@ const gridData = ref(); const errorMessage = ref(""); const operationMessage = ref(""); const operationStatus = ref(""); -const selected: Ref<{ [key: number]: boolean }> = ref({}); +const selected = ref(new Set()); // page references const currentPage = ref(1); @@ -124,6 +123,15 @@ async function getGridData() { /** * Execute grid operation and display message if available */ +async function onBatchOperation(operation: BatchOperation, rowDataArray: Array) { + const response = await operation.handler(rowDataArray); + if (response) { + await getGridData(); + operationMessage.value = response.message; + operationStatus.value = response.status || "success"; + } +} + async function onOperation(operation: Operation, rowData: RowData) { const response = await operation.handler(rowData); if (response) { @@ -174,13 +182,14 @@ function onFilter(filter?: string) { } } -function onBatch(operation: BatchOperation) { - alert(operation.title); -} - -function onSelect(rowIndex: number) { - selected.value[rowIndex] = !selected.value[rowIndex]; - selected.value = { ...selected.value }; +// Select multiple rows +function onSelect(rowData: RowData) { + if (selected.value.has(rowData)) { + selected.value.delete(rowData); + } else { + selected.value.add(rowData); + } + selected.value = new Set(selected.value); } /** @@ -276,9 +285,9 @@ watch(operationMessage, () => { - + @@ -326,17 +335,18 @@ watch(operationMessage, () => {