Use correct input type for type in advanced filter sidebar (#6413)

This commit is contained in:
Rijk van Zanten
2021-06-21 17:52:07 -04:00
committed by GitHub
parent f42d7b55b1
commit 6c74bf6462
3 changed files with 83 additions and 66 deletions

View File

@@ -383,6 +383,7 @@ sort_field: Sort Field
add_sort_field: Add Sort Field
sort: Sort
status: Status
remove: Remove
toggle_manual_sorting: Toggle Manual Sorting
bookmark_doesnt_exist: Bookmark Doesn't Exist
bookmark_doesnt_exist_copy: The bookmark you're trying to open couldn't be found.

View File

@@ -1,60 +1,57 @@
<template>
<div class="filter-input">
<template v-if="['between', 'nbetween'].includes(operator)">
<v-input
:type="type"
:model-value="csvValue[0]"
@update:model-value="setCSV(0, $event)"
:disabled="disabled"
:placeholder="t('lower_limit')"
autofocus
>
<template #append>
<v-icon name="vertical_align_top" />
</template>
</v-input>
<v-input
:type="type"
:model-value="csvValue[1]"
@update:model-value="setCSV(1, $event)"
:disabled="disabled"
:placeholder="t('upper_limit')"
>
<template #append>
<v-icon name="vertical_align_bottom" />
</template>
</v-input>
</template>
<template v-else-if="['in', 'nin'].includes(operator)">
<v-input
v-for="(val, index) in csvValue"
:key="index"
:model-value="val"
:type="type"
@update:model-value="setCSV(index, $event)"
:disabled="disabled"
:placeholder="t('enter_a_value')"
autofocus
>
<template v-if="csvValue.length > 1" #append>
<v-icon name="close" @click="removeCSV(val)" />
</template>
</v-input>
<div class="between" v-if="['between', 'nbetween'].includes(operator)">
<div class="field">
<component
:is="interfaceComponent"
:type="type"
:value="csvValue[0]"
:placeholder="t('lower_limit')"
autofocus
@input="setCSV(0, $event)"
/>
</div>
<div class="field">
<component
:is="interfaceComponent"
:type="type"
:value="csvValue[1]"
:placeholder="t('upper_limit')"
autofocus
@input="setCSV(1, $event)"
/>
</div>
</div>
<div class="list" v-else-if="['in', 'nin'].includes(operator)">
<div class="field" v-for="(val, index) in csvValue" :key="index">
<component
:is="interfaceComponent"
:type="type"
:value="val"
:placeholder="t('enter_a_value')"
:disabled="disabled"
autofocus
@input="setCSV(index, $event)"
/>
<small @click="removeCSV(val)" class="remove">
{{ t('remove') }}
</small>
</div>
<v-button outlined full-width dashed @click="addCSV" :disabled="disabled">
<v-icon name="add" />
{{ t('add_new') }}
</v-button>
</template>
</div>
<template v-else-if="['empty', 'nempty'].includes(operator) === false">
<v-checkbox block :label="t('active')" v-if="type === 'checkbox'" v-model="internalValue" :disabled="disabled" />
<v-input
:disabled="disabled"
v-else
autofocus
v-model="internalValue"
:nullable="false"
<component
:is="interfaceComponent"
:type="type"
:value="internalValue"
:placeholder="t('enter_a_value')"
:disabled="disabled"
autofocus
@input="internalValue = $event"
/>
</template>
</div>
@@ -63,7 +60,8 @@
<script lang="ts">
import { useI18n } from 'vue-i18n';
import { defineComponent, PropType, computed } from 'vue';
import { FilterOperator } from '@/types';
import { FilterOperator, types } from '@/types';
import { getDefaultInterfaceForType } from '@/utils/get-default-interface-for-type';
export default defineComponent({
emits: ['update:modelValue'],
@@ -73,7 +71,7 @@ export default defineComponent({
required: true,
},
type: {
type: String as PropType<'text' | 'checkbox' | 'number' | 'datetime' | 'unknown'>,
type: String as PropType<typeof types[number]>,
required: true,
},
operator: {
@@ -106,7 +104,9 @@ export default defineComponent({
},
});
return { t, internalValue, csvValue, setCSV, removeCSV, addCSV };
const interfaceComponent = computed(() => `interface-${getDefaultInterfaceForType(props.type)}`);
return { t, internalValue, csvValue, setCSV, removeCSV, addCSV, interfaceComponent };
function setCSV(index: number, value: string) {
const newValue = Object.assign([], csvValue.value, { [index]: value });
@@ -133,4 +133,26 @@ export default defineComponent({
.v-input .v-icon {
--v-icon-color: var(--foreground-subdued);
}
.list .field {
margin-bottom: 12px;
}
.list .field .remove {
display: flex;
align-items: center;
float: right;
width: max-content;
margin-bottom: 12px;
color: var(--foreground-subdued);
cursor: pointer;
}
.list .field .remove:hover {
color: var(--danger);
}
.between .field:first-child {
margin-bottom: 12px;
}
</style>

View File

@@ -1,6 +1,7 @@
import { OperatorType } from './types';
import { types } from '@/types';
export default function getAvailableOperatorsForType(type: string): OperatorType {
export default function getAvailableOperatorsForType(type: typeof types[number]): OperatorType {
/**
* @NOTE
* In the filter, you can't filter on the relational field itself, so we don't have to account
@@ -11,48 +12,41 @@ export default function getAvailableOperatorsForType(type: string): OperatorType
// Text
case 'binary':
case 'json':
case 'array':
case 'status':
case 'slug':
case 'lang':
case 'hash':
case 'string':
return {
type: 'text',
type,
operators: ['contains', 'ncontains', 'eq', 'neq', 'empty', 'nempty', 'in', 'nin'],
};
case 'uuid':
return {
type: 'text',
type,
operators: ['eq', 'neq', 'empty', 'nempty', 'in', 'nin'],
};
// Boolean
case 'boolean':
return {
type: 'checkbox',
type,
operators: ['eq', 'neq', 'empty', 'nempty'],
};
// Numbers
case 'integer':
case 'decimal':
case 'sort':
return {
type: 'number',
type,
operators: ['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'between', 'nbetween', 'empty', 'nempty', 'in', 'nin'],
};
// Datetime
case 'datetime':
case 'dateTime':
case 'date':
case 'time':
case 'datetime_created':
case 'datetime_updated':
return {
type: 'datetime',
type,
operators: ['eq', 'neq', 'lt', 'lte', 'gt', 'gte', 'between', 'nbetween', 'empty', 'nempty', 'in', 'nin'],
};
default:
return {
type: 'unknown',
type,
operators: [
'eq',
'neq',