From 896537ff2d816915773e4f0e9a5a1265d79a5546 Mon Sep 17 00:00:00 2001 From: "Burgstede, W.Y. (Ysbrand, Student B-CREA)" Date: Mon, 17 Jun 2024 13:33:43 +0200 Subject: [PATCH] Implement the choice helper --- app/Http/Controllers/ItemController.php | 3 +- questions.json | 23 +++++ .../js/CustomComponents/AttributeFilter.vue | 59 +++++++++--- resources/js/Pages/Items/Index.vue | 89 +++++++++++++++---- 4 files changed, 140 insertions(+), 34 deletions(-) create mode 100644 questions.json diff --git a/app/Http/Controllers/ItemController.php b/app/Http/Controllers/ItemController.php index cce2a8d..4e5775d 100644 --- a/app/Http/Controllers/ItemController.php +++ b/app/Http/Controllers/ItemController.php @@ -17,8 +17,6 @@ class ItemController extends Controller */ public function index(Request $request) { - // return File::json(base_path('questions.json'))['name']; - $builder = Item::query()->with('attributes.attributeType'); $filters = $request->input('filters'); foreach ($filters ?? [] as $attributeCategoryId => $attributeIds) { @@ -32,6 +30,7 @@ public function index(Request $request) 'items' => $builder->get(), 'attributeTypes' => AttributeType::with('attributes')->orderBy('created_at', 'desc')->get(), 'initialFilters' => $filters, + 'questions' => json_decode(File::get(base_path('questions.json'))), ]); } diff --git a/questions.json b/questions.json new file mode 100644 index 0000000..f71d2db --- /dev/null +++ b/questions.json @@ -0,0 +1,23 @@ +{ + "questions": [ + { + "question": "What is the correct spelling?", + "description": "Choose the correct spelling out of the buttons", + "answers": [ + {"text": "Paris", "filters": [0]}, + {"text": "Peris", "filters": [1]}, + {"text": "Baris", "filters": [2]}, + {"text": "Parice", "filters": [3]} + ] + },{ + "question": "What is the correct spelling?", + "description": "Choose the correct spelling out of the buttons", + "answers": [ + {"text":"Berlin", "filters": [4]}, + {"text":"Berline", "filters": [5]}, + {"text":"Berlen", "filters": [6]}, + {"text":"Berlun", "filters": [7]} + ] + } + ] +} diff --git a/resources/js/CustomComponents/AttributeFilter.vue b/resources/js/CustomComponents/AttributeFilter.vue index 3db58ee..8c773e4 100644 --- a/resources/js/CustomComponents/AttributeFilter.vue +++ b/resources/js/CustomComponents/AttributeFilter.vue @@ -3,7 +3,7 @@ import OpeningComponent from "@/CustomComponents/OpeningComponent.vue"; import Pill from "@/CustomComponents/Pill.vue"; import {Attribute, AttributeType} from "@/types"; -import {nextTick, ref} from "vue"; +import {computed, nextTick, ref} from "vue"; const props = withDefaults(defineProps<{ attributeTypes: AttributeType[], @@ -18,24 +18,41 @@ const emit = defineEmits<{ const check = (attributeType: AttributeType, attribute: Attribute, checked: boolean) => nextTick(() => { if (checked) { - checkedAttributes.value.set(attributeType, [...(checkedAttributes.value.get(attributeType) ?? []), attribute]); + checkedAttributesMap.value.set(attributeType, [...(checkedAttributesMap.value.get(attributeType) ?? []), attribute]); } else { - checkedAttributes.value.set(attributeType, (checkedAttributes.value.get(attributeType) ?? []).filter((checkedAttribute) => checkedAttribute.id !== attribute.id)); + checkedAttributesMap.value.set(attributeType, (checkedAttributesMap.value.get(attributeType) ?? []).filter((checkedAttribute) => checkedAttribute.id !== attribute.id)); } //filter out the attribute type if there are no attributes - if (checkedAttributes.value.get(attributeType)?.length === 0) { - checkedAttributes.value.delete(attributeType); + if (checkedAttributesMap.value.get(attributeType)?.length === 0) { + checkedAttributesMap.value.delete(attributeType); } - const allAttributes: Record = {}; - for (const [attributeType, attributes] of checkedAttributes.value.entries()) { - allAttributes[attributeType.id] = attributes.map((attribute) => attribute.id); - } - emit('update', allAttributes); + emit('update', checkedAttributes.value); }); +const addFiltersByAttributeIds = (ids: number[]) => { + ids.forEach((id) => { + addFilterByAttributeId(id); + }); +} + +const addFilterByAttributeId = (id: number) => { + const attribute = props.attributeTypes.flatMap((attributeType) => attributeType.attributes).find((attribute) => attribute?.id === id); + if (attribute) { + //find the corresponding attribute type + const attributeType = props.attributeTypes.find((attributeType) => attributeType.id === attribute.attribute_type_id); + if(attributeType && !checkedAttributesMap.value.has(attributeType)){ + check(attributeType, attribute, true); + } + } +} + +const reset = () => { + checkedAttributesMap.value.clear(); + emit('update', {}); +} -const checkedAttributes = ref(new Map()); +const checkedAttributesMap = ref(new Map()); if (props.initialFilters) { for (const [attributeTypeId, attributeIds] of Object.entries(props.initialFilters)) { const attributeType = props.attributeTypes.find((attributeType) => attributeType.id === parseInt(attributeTypeId)); @@ -50,15 +67,29 @@ if (props.initialFilters) { } } +const checkedAttributes = computed(() => { + const allAttributes: Record = {}; + for (const [attributeType, attributes] of checkedAttributesMap.value.entries()) { + allAttributes[attributeType.id] = attributes.map((attribute) => attribute.id); + } + return allAttributes; +}); + function capitalizeFirstLetter(string: string) { return string[0].toUpperCase() + string.slice(1); } + +defineExpose({ + reset, + addFiltersByAttributeIds, + checkedAttributes +})