Skip to content

Commit

Permalink
Add parentField
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloLec committed May 9, 2024
1 parent 1d713b7 commit c58b2fb
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 42 deletions.
2 changes: 1 addition & 1 deletion test-frontend/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ onMounted(async () => {

<template>
<div class="container py-10 mx-auto">
<search-form :criteria="criteria" :is-root="true" :parent-field="library"/>
<search-form :criteria="criteria" :is-root="true" :parent-field="'library'"/>
</div>
<div class="container py-10 mx-auto">
<SearchResults/>
Expand Down
15 changes: 11 additions & 4 deletions test-frontend/src/components/ui/searchForm/FieldSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<SelectValue placeholder="Field" />
</SelectTrigger>
<SelectContent>
<SelectItem v-for="(config, field) in fieldsConfiguration" :key="field" :value="field">
<SelectItem v-for="(config, field) in currentFieldsConfig" :key="field" :value="field">
{{ field }}
</SelectItem>
</SelectContent>
Expand All @@ -18,12 +18,19 @@ import {
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import {fieldsConfiguration} from '@/lib/fieldsConfiguration';
} from '@/components/ui/select';
import { computed } from 'vue';
import { fieldsConfiguration } from '@/lib/fieldsConfiguration';
const props = defineProps({
parentField: String
});
const emit = defineEmits(['update:modelValue', 'change']);
const currentFieldsConfig = computed(() => fieldsConfiguration[props.parentField]);
const handleChange = (value: string) => {
emit('update:modelValue', value);
};
</script>
</script>
14 changes: 9 additions & 5 deletions test-frontend/src/components/ui/searchForm/OperationSelector.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
<SelectValue placeholder="op" />
</SelectTrigger>
<SelectContent>
<SelectItem v-for="op in fieldsConfiguration[field].opOptions" :key="op" :value="op">
<SelectItem v-for="op in currentFieldsConfig[field]?.opOptions" :key="op" :value="op">
{{ op }}
</SelectItem>
</SelectContent>
Expand All @@ -18,16 +18,20 @@ import {
SelectItem,
SelectTrigger,
SelectValue,
} from '@/components/ui/select'
import {fieldsConfiguration} from '@/lib/fieldsConfiguration';
} from '@/components/ui/select';
import { computed } from 'vue';
import { fieldsConfiguration } from '@/lib/fieldsConfiguration';
const props = defineProps({
field: String
field: String,
parentField: String
});
const emit = defineEmits(['update:modelValue', 'change']);
const currentFieldsConfig = computed(() => fieldsConfiguration[props.parentField]);
const handleChange = (value: string) => {
emit('update:modelValue', value);
};
</script>
</script>
40 changes: 23 additions & 17 deletions test-frontend/src/components/ui/searchForm/SearchForm.vue
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
<template>
<div>
<div v-for="(criterion, index) in criteria" :key="index">
<div class="flex items-center space-x-4 my-2">
<field-selector v-model="criterion.field" @change="() => updateFieldConfig(criterion)" :parent-field="parentField" />
<operation-selector v-if="hasOperations(criterion.field)" v-model="criterion.op" :field="criterion.field" />
<value-input v-if="hasValueInput(criterion.field)" v-model="criterion.value" :field="criterion.field" />
<Button size="icon" @click="removeCriterion(index)" class="bg-orange-400">
<Minus class="w-4 h-4" />
<div class="flex items-center justify-between space-x-4 my-2">
<div class="flex flex-grow items-center space-x-4">
<field-selector v-model="criterion.field" @change="() => updateFieldConfig(criterion)" :parent-field="parentField" />
<operation-selector v-if="hasOperations(criterion.field)" v-model="criterion.op" :field="criterion.field" :parent-field="parentField" />
<value-input v-if="hasValueInput(criterion.field)" v-model="criterion.value" :field="criterion.field" :parent-field="parentField" />
</div>
<Button size="icon" @click="removeCriterion(index)" class="bg-orange-400 flex-shrink-0 w-10 h-10">
<Minus class="w-4 h-4 flex-shrink-0" />
</Button>
</div>
<div v-if="hasSubCriteria(criterion)" class="my-2 ml-6">
<search-form :criteria="criterion.subCriteria" :parent-field="criterion.field" />
<Button v-if="canHaveSubCriteria(criterion.field)" @click="() => addSubCriterion(criterion)" class="bg-emerald-600">
<Plus class="w-4 h-4" />
<div v-if="hasSubCriteria(criterion)" class="my-2 ml-6 relative">
<div class="absolute left-0 top-0 bottom-0 w-0.5 bg-gray-400" style="margin-left: -1rem;"></div>
<search-form :criteria="criterion.subCriteria" :parent-field="criterion.field" :is-root="false"/>
<Button v-if="canHaveSubCriteria(criterion.field)" @click="() => addSubCriterion(criterion)" class="bg-emerald-600 flex-shrink-0 w-10 h-10">
<Plus class="w-4 h-4 flex-shrink-0" />
</Button>
</div>
</div>
<Button v-if="isRoot" size="icon" @click="addCriterion" class="bg-emerald-400">
<Plus class="w-4 h-4" />
<Button v-if="isRoot" size="icon" @click="addCriterion" class="bg-emerald-400 flex-shrink-0 w-10 h-10">
<Plus class="w-4 h-4 flex-shrink-0" />
</Button>
</div>
</template>
Expand All @@ -30,13 +33,14 @@ import OperationSelector from './OperationSelector.vue';
import ValueInput from './ValueInput.vue';
import { Minus, Plus } from 'lucide-vue-next';
import { Button } from '@/components/ui/button';
import {computed} from "vue";
const props = defineProps({
criteria: Array as PropType<SearchCriterion[]>,
parentField: String,
isRoot: {
type: Boolean,
default: false
default: true
}
});
Expand Down Expand Up @@ -66,8 +70,10 @@ const updateFieldConfig = (criterion: SearchCriterion) => {
emit('update:criteria', props.criteria);
};
const hasOperations = (field: string) => field && fieldsConfiguration[field]?.opOptions.length > 0;
const hasValueInput = (field: string) => field && fieldsConfiguration[field]?.valueComponent;
const canHaveSubCriteria = (field: string) => field && fieldsConfiguration[field]?.canHaveSubCriteria;
const hasSubCriteria = (criterion: SearchCriterion) => criterion.subCriteria && criterion.field && fieldsConfiguration[criterion.field]?.canHaveSubCriteria;
const currentFieldsConfig = computed(() => fieldsConfiguration[props.parentField]);
const hasOperations = (field: string) => field && currentFieldsConfig.value[field]?.opOptions.length > 0;
const hasValueInput = (field: string) => field && currentFieldsConfig.value[field]?.valueComponent;
const canHaveSubCriteria = (field: string) => field && currentFieldsConfig.value[field]?.canHaveSubCriteria;
const hasSubCriteria = (criterion: SearchCriterion) => criterion.subCriteria && criterion.field && currentFieldsConfig.value[criterion.field]?.canHaveSubCriteria;
</script>
21 changes: 12 additions & 9 deletions test-frontend/src/components/ui/searchForm/ValueInput.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<Input v-if="isInput" type="text" placeholder="Value" @update:modelValue="handleChange"/>
<Input v-if="isInput" type="text" placeholder="Value" @update:modelValue="handleChange"/>
<Select v-if="isSelect" @update:modelValue="handleChange">
<SelectTrigger class="w-[180px]">
<SelectValue placeholder="Value" />
Expand All @@ -24,18 +24,21 @@ import { Input } from '@/components/ui/input'
import {computed} from 'vue';
import {fieldsConfiguration} from '@/lib/fieldsConfiguration';
const props = defineProps<{
modelValue: string | number;
field: string;
}>();
const props = defineProps({
modelValue: [String, Number],
field: String,
parentField: String
});
const emit = defineEmits(['update:modelValue']);
const isInput = computed(() => fieldsConfiguration[props.field]?.valueComponent === 'input');
const isSelect = computed(() => fieldsConfiguration[props.field]?.valueComponent === 'select');
const valueOptions = computed(() => fieldsConfiguration[props.field]?.valueOptions ?? []);
const currentFieldsConfig = computed(() => fieldsConfiguration[props.parentField]);
const handleChange = (value: string) => {
const isInput = computed(() => currentFieldsConfig.value[props.field]?.valueComponent === 'input');
const isSelect = computed(() => currentFieldsConfig.value[props.field]?.valueComponent === 'select');
const valueOptions = computed(() => currentFieldsConfig.value[props.field]?.valueOptions ?? []);
const handleChange = (value: string | number) => {
emit('update:modelValue', value);
};
</script>
43 changes: 37 additions & 6 deletions test-frontend/src/lib/fieldsConfiguration.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { FieldConfig } from './types';

export const fieldsConfiguration: Record<string, FieldConfig> = {
const libraryFieldsConfiguration: Record<string, FieldConfig> = {
name: {
opOptions: ['equals', 'contains'],
valueComponent: 'input',
Expand All @@ -11,21 +11,52 @@ export const fieldsConfiguration: Record<string, FieldConfig> = {
valueComponent: 'input',
canHaveSubCriteria: false
},
book: {
opOptions: [],
valueComponent: 'none',
canHaveSubCriteria: true
},
author: {
opOptions: ['equals', 'not equals'],
valueComponent: 'select',
valueOptions: ['Author 1', 'Author 2', 'Author 3'],
canHaveSubCriteria: false
},
book: {
opOptions: [],
valueComponent: 'none',
canHaveSubCriteria: true
},
isOpen: {
opOptions: ['is'],
valueComponent: 'select',
valueOptions: ['Open', 'Closed'],
canHaveSubCriteria: false
}
};

const bookFieldsConfiguration: Record<string, FieldConfig> = {
author: {
opOptions: ['equals', 'not equals'],
valueComponent: 'select',
valueOptions: ['Author 1', 'Author 2', 'Author 3', 'Author 4'],
canHaveSubCriteria: false
},
genre: {
opOptions: ['equals'],
valueComponent: 'select',
valueOptions: ['Fiction', 'Non-Fiction', 'Educational'],
canHaveSubCriteria: false
},
language: {
opOptions: ['equals'],
valueComponent: 'select',
valueOptions: ['English', 'French', 'Spanish'],
canHaveSubCriteria: false
},
book: {
opOptions: [],
valueComponent: 'none',
canHaveSubCriteria: true
},
};

export const fieldsConfiguration: Record<string, Record<string, FieldConfig>> = {
library: libraryFieldsConfiguration,
book: bookFieldsConfiguration
};

0 comments on commit c58b2fb

Please sign in to comment.