feat(filter): support temporarily disabling filter rules
Co-authored-by: staff <staff@qimaos-MacBook-Pro.local>
This commit is contained in:
1 parent
7b47edde3d
commit
ded3fdde32
1 file changed
+19
-7
@@ -7,6 +7,7 @@ type CachedStructuredFilterRule = {
|
|||||||
mode: "equals" | "not-equals" | "is-null" | "is-not-null" | "like" | "not-like" | "less-than" | "greater-than";
|
mode: "equals" | "not-equals" | "is-null" | "is-not-null" | "like" | "not-like" | "less-than" | "greater-than";
|
||||||
rawValue: string;
|
rawValue: string;
|
||||||
conjunction: "AND" | "OR";
|
conjunction: "AND" | "OR";
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
type StructuredFilterCacheState = {
|
type StructuredFilterCacheState = {
|
||||||
scopeKey: string;
|
scopeKey: string;
|
||||||
@@ -39,6 +40,7 @@ import {
|
|||||||
Code2,
|
Code2,
|
||||||
Copy,
|
Copy,
|
||||||
Eye,
|
Eye,
|
||||||
|
EyeOff,
|
||||||
Loader2,
|
Loader2,
|
||||||
X,
|
X,
|
||||||
Undo2,
|
Undo2,
|
||||||
@@ -518,6 +520,7 @@ type StructuredFilterRule = {
|
|||||||
mode: FilterMode;
|
mode: FilterMode;
|
||||||
rawValue: string;
|
rawValue: string;
|
||||||
conjunction: "AND" | "OR";
|
conjunction: "AND" | "OR";
|
||||||
|
disabled?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
const localColumnFilters = ref<Record<number, Set<string>>>({});
|
const localColumnFilters = ref<Record<number, Set<string>>>({});
|
||||||
@@ -544,7 +547,7 @@ const structuredFilterCacheKey = computed(() => props.cacheKey || [props.connect
|
|||||||
const structuredFilterScopeKey = computed(() => [props.connectionId ?? "", props.database ?? "", props.schema ?? "", props.context ?? "", props.tableMeta?.schema ?? "", props.tableMeta?.tableName ?? "", filterBuilderColumnOptions.value.join("\0")].join("\u0001"));
|
const structuredFilterScopeKey = computed(() => [props.connectionId ?? "", props.database ?? "", props.schema ?? "", props.context ?? "", props.tableMeta?.schema ?? "", props.tableMeta?.tableName ?? "", filterBuilderColumnOptions.value.join("\0")].join("\u0001"));
|
||||||
const structuredFilterRules = ref<StructuredFilterRule[]>([]);
|
const structuredFilterRules = ref<StructuredFilterRule[]>([]);
|
||||||
const appliedStructuredWhereInput = ref("");
|
const appliedStructuredWhereInput = ref("");
|
||||||
const structuredFilterCount = computed(() => structuredFilterRules.value.filter((rule) => !!rule.columnName && (!filterModeNeedsValue(rule.mode) || rule.rawValue.trim().length > 0)).length);
|
const structuredFilterCount = computed(() => structuredFilterRules.value.filter((rule) => !rule.disabled && !!rule.columnName && (!filterModeNeedsValue(rule.mode) || rule.rawValue.trim().length > 0)).length);
|
||||||
const hasStructuredFilters = computed(() => !!combineWhereInputs(undefined, appliedStructuredWhereInput.value));
|
const hasStructuredFilters = computed(() => !!combineWhereInputs(undefined, appliedStructuredWhereInput.value));
|
||||||
const formatterOpenColumn = ref<number | null>(null);
|
const formatterOpenColumn = ref<number | null>(null);
|
||||||
type FormatterDraftKind = Exclude<ColumnFormatterConfig["kind"], "custom-ref">;
|
type FormatterDraftKind = Exclude<ColumnFormatterConfig["kind"], "custom-ref">;
|
||||||
@@ -1002,6 +1005,7 @@ async function buildStructuredWhereFromRules(rules: StructuredFilterRule[]): Pro
|
|||||||
const rulesWithConditions = (
|
const rulesWithConditions = (
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
rules.map(async (rule) => {
|
rules.map(async (rule) => {
|
||||||
|
if (rule.disabled) return { rule, condition: null };
|
||||||
if (!rule.columnName) return { rule, condition: null };
|
if (!rule.columnName) return { rule, condition: null };
|
||||||
if (filterModeNeedsValue(rule.mode) && !rule.rawValue.trim()) return { rule, condition: null };
|
if (filterModeNeedsValue(rule.mode) && !rule.rawValue.trim()) return { rule, condition: null };
|
||||||
const columnInfo = filterBuilderColumns.value.find((column) => column.name === rule.columnName);
|
const columnInfo = filterBuilderColumns.value.find((column) => column.name === rule.columnName);
|
||||||
@@ -6615,7 +6619,7 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
|||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div class="grid grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)_minmax(0,1.2fr)_auto] items-center gap-2">
|
<div class="grid grid-cols-[minmax(0,1.2fr)_minmax(0,1fr)_minmax(0,1.2fr)_auto] items-center gap-2">
|
||||||
<Select :model-value="rule.columnName" @update:model-value="(value: any) => updateStructuredFilterRule(rule.id, { columnName: String(value) })">
|
<Select :model-value="rule.columnName" :disabled="rule.disabled" :class="rule.disabled ? 'opacity-45' : ''" @update:model-value="(value: any) => updateStructuredFilterRule(rule.id, { columnName: String(value) })">
|
||||||
<SelectTrigger class="h-8 w-full min-w-0 overflow-hidden text-xs [&_[data-slot=select-value]]:min-w-0 [&_[data-slot=select-value]]:truncate">
|
<SelectTrigger class="h-8 w-full min-w-0 overflow-hidden text-xs [&_[data-slot=select-value]]:min-w-0 [&_[data-slot=select-value]]:truncate">
|
||||||
<SelectValue :placeholder="t('grid.filterBuilderColumn')" />
|
<SelectValue :placeholder="t('grid.filterBuilderColumn')" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -6626,7 +6630,7 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
|||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
<Select :model-value="rule.mode" @update:model-value="(value: any) => updateStructuredFilterRule(rule.id, { mode: value as FilterMode })">
|
<Select :model-value="rule.mode" :disabled="rule.disabled" :class="rule.disabled ? 'opacity-45' : ''" @update:model-value="(value: any) => updateStructuredFilterRule(rule.id, { mode: value as FilterMode })">
|
||||||
<SelectTrigger class="h-8 w-full min-w-0 overflow-hidden text-xs [&_[data-slot=select-value]]:min-w-0 [&_[data-slot=select-value]]:truncate">
|
<SelectTrigger class="h-8 w-full min-w-0 overflow-hidden text-xs [&_[data-slot=select-value]]:min-w-0 [&_[data-slot=select-value]]:truncate">
|
||||||
<SelectValue />
|
<SelectValue />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
@@ -6641,17 +6645,25 @@ const gridContextMenuItems = computed<ContextMenuItem[]>(() => {
|
|||||||
v-if="filterModeNeedsValue(rule.mode)"
|
v-if="filterModeNeedsValue(rule.mode)"
|
||||||
:model-value="rule.rawValue"
|
:model-value="rule.rawValue"
|
||||||
class="h-8 min-w-0 text-xs"
|
class="h-8 min-w-0 text-xs"
|
||||||
|
:class="rule.disabled ? 'opacity-45' : ''"
|
||||||
|
:disabled="rule.disabled"
|
||||||
:placeholder="t('grid.filterBuilderValue')"
|
:placeholder="t('grid.filterBuilderValue')"
|
||||||
@update:model-value="(value) => updateStructuredFilterRule(rule.id, { rawValue: String(value ?? '') })"
|
@update:model-value="(value) => updateStructuredFilterRule(rule.id, { rawValue: String(value ?? '') })"
|
||||||
@keydown.enter.prevent="applyStructuredFilters"
|
@keydown.enter.prevent="applyStructuredFilters"
|
||||||
/>
|
/>
|
||||||
<div v-else class="flex h-8 min-w-0 items-center overflow-hidden rounded-md border border-dashed px-2 text-xs text-muted-foreground">
|
<div v-else class="flex h-8 min-w-0 items-center overflow-hidden rounded-md border border-dashed px-2 text-xs text-muted-foreground" :class="rule.disabled ? 'opacity-45' : ''">
|
||||||
<span class="truncate">{{ t("grid.filterBuilderNoValue") }}</span>
|
<span class="truncate">{{ t("grid.filterBuilderNoValue") }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button variant="ghost" size="icon" class="h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive" :disabled="structuredFilterRules.length === 1" @click="removeStructuredFilterRule(rule.id)">
|
<div class="flex items-center gap-1">
|
||||||
<Trash2 class="h-3.5 w-3.5" />
|
<Button variant="ghost" size="icon" class="h-8 w-8 shrink-0 text-muted-foreground hover:text-foreground" @click="updateStructuredFilterRule(rule.id, { disabled: !rule.disabled })">
|
||||||
</Button>
|
<EyeOff v-if="rule.disabled" class="h-3.5 w-3.5" />
|
||||||
|
<Eye v-else class="h-3.5 w-3.5" />
|
||||||
|
</Button>
|
||||||
|
<Button variant="ghost" size="icon" class="h-8 w-8 shrink-0 text-muted-foreground hover:text-destructive" :disabled="structuredFilterRules.length === 1" @click="removeStructuredFilterRule(rule.id)">
|
||||||
|
<Trash2 class="h-3.5 w-3.5" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in new issue
Block a user