mirror of
https://gitee.com/devlive-community/datacap.git
synced 2024-12-02 20:17:45 +08:00
[Core] [Refactor] [UI] [Source] [Manager] Add row filter
This commit is contained in:
parent
e9c22eb9bc
commit
2ccdee9129
@ -85,6 +85,9 @@ export default {
|
||||
copyRows: 'Copy Rows',
|
||||
deleteRows: 'Delete Rows',
|
||||
visibleColumn: 'Visible Column',
|
||||
filterData: 'Filter Data',
|
||||
filterCondition: 'Filter Condition',
|
||||
addFilter: 'Add Filter',
|
||||
},
|
||||
tip: {
|
||||
selectSource: 'Please select a source',
|
||||
|
@ -85,6 +85,9 @@ export default {
|
||||
copyRows: '复制行',
|
||||
deleteRows: '删除行',
|
||||
visibleColumn: '可见列',
|
||||
filterData: '筛选数据',
|
||||
filterCondition: '筛选条件',
|
||||
addFilter: '添加筛选条件',
|
||||
},
|
||||
tip: {
|
||||
selectSource: '请选择数据源',
|
||||
|
@ -82,6 +82,20 @@ export interface ColumnFilter
|
||||
value?: any
|
||||
}
|
||||
|
||||
export class ColumnFilterRequest
|
||||
{
|
||||
public static of(): ColumnFilter
|
||||
{
|
||||
return {
|
||||
index: 0,
|
||||
column: undefined,
|
||||
operator: undefined,
|
||||
operations: Array<Operator>(),
|
||||
value: undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export interface SqlColumn
|
||||
{
|
||||
column?: string
|
||||
|
@ -95,11 +95,18 @@
|
||||
</div>
|
||||
</template>
|
||||
<template #extra>
|
||||
<Tooltip :content="$t('source.common.visibleColumn')">
|
||||
<Button size="icon" class="w-6 h-6" @click="handlerVisibleColumn(null, true)">
|
||||
<Columns :size="15"/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<div class="space-x-2">
|
||||
<Tooltip :content="$t('source.common.visibleColumn')">
|
||||
<Button size="icon" class="w-6 h-6" @click="handlerVisibleColumn(null, true)">
|
||||
<Columns :size="15"/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
<Tooltip :content="$t('source.common.filterData')">
|
||||
<Button size="icon" class="w-6 h-6" @click="handlerFilterConfigure(true)">
|
||||
<Filter :size="15"/>
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<CircularLoading v-if="refererLoading" :show="refererLoading"/>
|
||||
<AgGridVue class="ag-theme-datacap" style="width: 100%; min-height: 460px; height: 460px;" :gridOptions="gridOptions" :columnDefs="configure.headers"
|
||||
@ -113,6 +120,8 @@
|
||||
@close="handlerSelectedChangedPreview(false)"/>
|
||||
<TableColumn v-if="visibleColumn.show" :isVisible="visibleColumn.show" :columns="visibleColumn.columns" @close="handlerVisibleColumn($event, false)"
|
||||
@change="handlerVisibleColumn($event, false)"/>
|
||||
<TableRowFilter v-if="filterConfigure.show" :isVisible="filterConfigure.show" :columns="filterConfigure.columns" :types="filterConfigure.types"
|
||||
:configure="filterConfigure.configure" @apply="handlerApplyFilter" @close="handlerFilterConfigure(false)"/>
|
||||
<SqlInfo v-if="visibleContent.show" :isVisible="visibleContent.show" :content="visibleContent.content" @close="handlerVisibleContent(false)"/>
|
||||
</div>
|
||||
</template>
|
||||
@ -136,16 +145,18 @@ import { ToastUtils } from '@/utils/toast'
|
||||
import Button from '@/views/ui/button'
|
||||
import Tooltip from '@/views/ui/tooltip'
|
||||
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'
|
||||
import { ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, Cog, Columns, Copy, Eye, Minus, Plus, RectangleEllipsis, RefreshCw } from 'lucide-vue-next'
|
||||
import { ArrowLeft, ArrowLeftToLine, ArrowRight, ArrowRightToLine, Cog, Columns, Copy, Eye, Filter, Minus, Plus, RectangleEllipsis, RefreshCw } from 'lucide-vue-next'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import TableCellInfo from '@/views/pages/admin/source/components/TableCellInfo.vue'
|
||||
import TableRowDelete from '@/views/pages/admin/source/components/TableRowDelete.vue'
|
||||
import SqlInfo from '@/views/components/sql/SqlInfo.vue'
|
||||
import TableColumn from '@/views/pages/admin/source/components/TableColumn.vue'
|
||||
import TableRowFilter from '@/views/pages/admin/source/components/TableRowFilter.vue'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TableData',
|
||||
components: {
|
||||
TableRowFilter,
|
||||
TableColumn,
|
||||
SqlInfo,
|
||||
TableRowDelete,
|
||||
@ -157,7 +168,7 @@ export default defineComponent({
|
||||
Button,
|
||||
Tooltip,
|
||||
Popover, PopoverContent, PopoverTrigger,
|
||||
ArrowLeftToLine, ArrowLeft, ArrowRight, ArrowRightToLine, Cog, Plus, RectangleEllipsis, Copy, Minus, Eye, RefreshCw, Columns
|
||||
ArrowLeftToLine, ArrowLeft, ArrowRight, ArrowRightToLine, Cog, Plus, RectangleEllipsis, Copy, Minus, Eye, RefreshCw, Columns, Filter
|
||||
},
|
||||
props: {
|
||||
info: {
|
||||
|
@ -0,0 +1,191 @@
|
||||
<template>
|
||||
<Dialog :is-visible="visible" :title="$t('source.common.filterData')">
|
||||
<div class="space-y-2 pl-3 pr-3">
|
||||
<FormField name="condition">
|
||||
<FormItem class="space-y-1">
|
||||
<FormLabel>{{ $t('source.common.filterCondition') }}</FormLabel>
|
||||
<FormMessage/>
|
||||
<Select v-model="formState.condition">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select"/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem value="AND">AND</SelectItem>
|
||||
<SelectItem value="OR">OR</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<Divider class="mt-2 mb-4"/>
|
||||
<div v-for="(item, index) in formState.filters">
|
||||
<div class="grid w-full grid-cols-3 gap-2 pt-1 pl-3 pr-3">
|
||||
<FormField name="column">
|
||||
<FormItem class="space-y-1">
|
||||
<FormMessage/>
|
||||
<Select v-model="item.index" @update:modelValue="handlerFetchOperations($event, item)">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select"/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem v-for="(column, index) in columns" :value="index.toString()" class="cursor-pointer">{{ column }}</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<FormField name="operator">
|
||||
<FormItem class="space-y-1">
|
||||
<FormMessage/>
|
||||
<Select v-model="item.operator" :disabled="!item.index">
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Select"/>
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectGroup>
|
||||
<SelectItem v-for="operation in item.operations" :value="Object.keys(OPERATOR)[Object.values(OPERATOR).indexOf(operation)]" class="cursor-pointer">
|
||||
{{ operation }}
|
||||
</SelectItem>
|
||||
</SelectGroup>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
<FormField name="value">
|
||||
<FormItem class="space-y-1 flex items-center">
|
||||
<FormMessage/>
|
||||
<div class="flex space-x-2 items-center">
|
||||
<Input v-model="item.value" :disabled="!item.operator"/>
|
||||
<Button size="icon" color="#ed4014" class="rounded-full w-4 h-4" @click="handlerRemoveFilter(index)">
|
||||
<Minus/>
|
||||
</Button>
|
||||
</div>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</div>
|
||||
</div>
|
||||
<FormField name="button">
|
||||
<FormItem class="space-y-1">
|
||||
<FormLabel>{{ $t('source.common.filterCondition') }}</FormLabel>
|
||||
<Button size="sm" class="ml-2" @click="handlerAddFilter">
|
||||
{{ $t('source.common.addFilter') }}
|
||||
</Button>
|
||||
</FormItem>
|
||||
</FormField>
|
||||
</div>
|
||||
<template #footer>
|
||||
<div class="space-x-5">
|
||||
<Button variant="outline" size="sm" @click="handlerCancel">
|
||||
{{ $t('common.cancel') }}
|
||||
</Button>
|
||||
<Button size="sm" @click="handlerApplyFilter">
|
||||
{{ $t('common.apply') }}
|
||||
</Button>
|
||||
</div>
|
||||
</template>
|
||||
</Dialog>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue'
|
||||
import { ColumnFilter, ColumnFilterRequest, Operator } from '@/model/table'
|
||||
import { cloneDeep } from 'lodash'
|
||||
import Dialog from '@/views/ui/dialog'
|
||||
import Button from '@/views/ui/button'
|
||||
import Divider from '@/views/ui/divider'
|
||||
import { FormControl, FormField, FormItem, FormLabel, FormMessage } from '@/components/ui/form'
|
||||
import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue } from '@/components/ui/select'
|
||||
import { Input } from '@/components/ui/input'
|
||||
import { Minus } from 'lucide-vue-next'
|
||||
|
||||
export default defineComponent({
|
||||
name: 'TableRowFilter',
|
||||
components: {
|
||||
Minus,
|
||||
Input,
|
||||
FormMessage,
|
||||
Dialog,
|
||||
Button,
|
||||
Divider,
|
||||
FormControl, FormField, FormItem, FormLabel,
|
||||
Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get(): boolean
|
||||
{
|
||||
return this.isVisible
|
||||
},
|
||||
set(value: boolean)
|
||||
{
|
||||
this.$emit('close', value)
|
||||
}
|
||||
}
|
||||
},
|
||||
props: {
|
||||
isVisible: {
|
||||
type: Boolean
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: [] as number[]
|
||||
},
|
||||
types: {
|
||||
type: Array,
|
||||
default: [] as number[]
|
||||
},
|
||||
configure: {
|
||||
type: Object as () => any
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
if (this.configure) {
|
||||
this.formState = cloneDeep(this.configure)
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
OPERATOR: Operator,
|
||||
formState: {
|
||||
condition: 'AND',
|
||||
filters: [] as any[]
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
handlerAddFilter()
|
||||
{
|
||||
const filter: ColumnFilter = ColumnFilterRequest.of()
|
||||
this.formState.filters.push(filter)
|
||||
},
|
||||
handlerRemoveFilter(index: number)
|
||||
{
|
||||
this.formState.filters.splice(index, 1)
|
||||
},
|
||||
handlerFetchOperations(value: any, filter: ColumnFilter)
|
||||
{
|
||||
const type = this.types[value]
|
||||
filter.column = this.columns[value] as string
|
||||
if (type === 'Long' || type === 'Double' || type === 'Integer') {
|
||||
filter.operations = [Operator.EQ, Operator.NEQ, Operator.GT, Operator.LT, Operator.GTE, Operator.LTE]
|
||||
}
|
||||
else {
|
||||
filter.operations = [Operator.EQ, Operator.NEQ, Operator.LIKE, Operator.NLIKE, Operator.NULL, Operator.NNULL]
|
||||
}
|
||||
},
|
||||
handlerApplyFilter()
|
||||
{
|
||||
this.$emit('apply', this.formState)
|
||||
this.handlerCancel()
|
||||
},
|
||||
handlerCancel()
|
||||
{
|
||||
this.visible = false
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
@ -1,19 +1,19 @@
|
||||
import {OrderFilter} from "@/model/OrderFilter";
|
||||
import {Pagination} from "@/entity/Pagination";
|
||||
import {Operator} from "@/enum/Operator";
|
||||
import { OrderFilter } from '@/model/OrderFilter'
|
||||
import { Pagination } from '@/entity/Pagination'
|
||||
import { Operator } from '@/enum/Operator'
|
||||
|
||||
export class TableFilter
|
||||
{
|
||||
pagination?: Pagination;
|
||||
orders?: Array<OrderFilter>;
|
||||
type?: SqlType;
|
||||
columns?: Array<SqlColumn>;
|
||||
original?: Map<string, string>;
|
||||
preview?: boolean;
|
||||
value?: string;
|
||||
filter: Filter;
|
||||
newColumns?: Array<any>;
|
||||
columnId?: number;
|
||||
pagination?: Pagination
|
||||
orders?: Array<OrderFilter>
|
||||
type?: SqlType
|
||||
columns?: Array<SqlColumn>
|
||||
original?: Map<string, string>
|
||||
preview?: boolean
|
||||
value?: string
|
||||
filter: Filter
|
||||
newColumns?: Array<any>
|
||||
columnId?: number
|
||||
}
|
||||
|
||||
export enum SqlType
|
||||
@ -32,22 +32,22 @@ export enum SqlType
|
||||
|
||||
export class SqlColumn
|
||||
{
|
||||
column?: string;
|
||||
value?: string;
|
||||
original?: Map<string, object>;
|
||||
column?: string
|
||||
value?: string
|
||||
original?: Map<string, object>
|
||||
}
|
||||
|
||||
export class ColumnFilter
|
||||
{
|
||||
index: number;
|
||||
column: string;
|
||||
operator: string;
|
||||
operations: Array<Operator>;
|
||||
index: number
|
||||
column: string
|
||||
operator: string
|
||||
operations: Array<Operator>
|
||||
value: any
|
||||
}
|
||||
|
||||
export class Filter
|
||||
{
|
||||
condition: string;
|
||||
filters: Array<ColumnFilter>;
|
||||
condition: string
|
||||
filters: Array<ColumnFilter>
|
||||
}
|
||||
|
@ -1,81 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<Drawer v-model="visible"
|
||||
:title="$t('source.manager.visibleColumn')"
|
||||
:mask-closable="false"
|
||||
@close="handlerCancel">
|
||||
<CheckboxGroup v-model="applyColumns">
|
||||
<List header=""
|
||||
footer="">
|
||||
<ListItem v-for="column in columns"
|
||||
:key="column">
|
||||
<Checkbox :label="column.field"></Checkbox>
|
||||
</ListItem>
|
||||
</List>
|
||||
</CheckboxGroup>
|
||||
<template #close>
|
||||
<Tooltip :content="$t('common.apply')"
|
||||
transfer>
|
||||
<Button size="small"
|
||||
type="primary"
|
||||
:style="{marginTop: '3px'}"
|
||||
@click="handlerCancel">
|
||||
{{ $t('common.apply') }}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
</template>
|
||||
</Drawer>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import {defineComponent} from "vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "TableColumn",
|
||||
props: {
|
||||
isVisible: {
|
||||
type: Boolean
|
||||
},
|
||||
columns: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data()
|
||||
{
|
||||
return {
|
||||
applyColumns: []
|
||||
}
|
||||
},
|
||||
created()
|
||||
{
|
||||
this.handlerInitialize();
|
||||
},
|
||||
methods: {
|
||||
handlerInitialize()
|
||||
{
|
||||
this.columns.filter((item: { checked: any; }) => item.checked)
|
||||
.forEach((item: { field: any; }) => {
|
||||
this.applyColumns.push(item.field)
|
||||
})
|
||||
},
|
||||
handlerCancel()
|
||||
{
|
||||
this.$emit('onClose', this.applyColumns)
|
||||
this.visible = false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
visible: {
|
||||
get(): boolean
|
||||
{
|
||||
return this.isVisible;
|
||||
},
|
||||
set(value: boolean)
|
||||
{
|
||||
this.$emit('close', value);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
Loading…
Reference in New Issue
Block a user