Skip to content

Commit

Permalink
Made components modulair
Browse files Browse the repository at this point in the history
  • Loading branch information
berrydenhartog committed Jun 24, 2024
1 parent be2f556 commit 661b626
Show file tree
Hide file tree
Showing 9 changed files with 186 additions and 18 deletions.
69 changes: 51 additions & 18 deletions frontend/src/components/BeslisboomForm.vue
Original file line number Diff line number Diff line change
@@ -1,42 +1,64 @@
<script setup lang="ts">
import { load } from 'js-yaml'
import { ref, onMounted, computed } from 'vue'
import { DecisionTree, Questions, Answer } from '../models/DecisionTree'
import { ref, computed, onMounted } from 'vue'
import { DecisionTree, Questions, Answer } from '@/models/DecisionTree'
import { fold } from 'fp-ts/lib/Either'
import * as t from 'io-ts'
import { PathReporter } from 'io-ts/PathReporter'
import SingleAnswer from '@/components/SingleAnswer.vue'
import SingleQuestion from '@/components/SingleQuestion.vue'
import FinalResult from '@/components/FinalResult.vue'
import DefaultLoader from '@/components/DefaultLoader.vue'
import DefaultError from '@/components/DefaultError.vue'
const data = ref<Questions>([])
const questionId = ref<String>('0')
const isLoading = ref<boolean>(true)
const result = ref<String>('')
const questionId = ref('0')
const isLoading = ref(true)
const result = ref<string | null>(null)
const error = ref<string | null>(null)
onMounted(async () => {
try {
const response = await fetch('/decision-tree.yaml')
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`)
throw new Error(`Error getting questionair data: ${response.status}`)
}
if (!response.headers.get('content-type')?.includes('text/yaml')) {
throw new Error(`Invalid content type: ${response.headers.get('content-type')}`)
}
const text = await response.text()
const yamlData = load(text)
const validationResult: t.Validation<any> = DecisionTree.decode(yamlData)
fold(
(errors: t.Errors) => console.error('Validation failed:', errors),
() => {
throw new Error(
`Could not validate data: ${PathReporter.report(validationResult).join('\n')}`
)
},
(validData: DecisionTree) => (data.value = validData.questions) // validData is the decoded object
)(validationResult)
} catch (e: unknown) {
if (e instanceof Error) {
error.value = e.message
} else {
error.value = 'An unknown error occurred'
}
} finally {
isLoading.value = false
}
})
const showQuestion = computed(() => {
console.log('showQuestion', questionId.value)
return data.value.find((q) => q.questionId === questionId.value)
const currentQuestion = computed(() => {
const question = data.value.find((q) => q.questionId === questionId.value)
return question
})
function givenAnswer(answer: Answer) {
console.log('givenAnswer', answer.result)
if (answer.result) {
result.value = answer.result
}
Expand All @@ -45,12 +67,23 @@ function givenAnswer(answer: Answer) {
</script>

<template>
<h1 v-if="isLoading">Loading...</h1>
<h1 v-else-if="showQuestion === undefined">{{ result }}</h1>
<div v-else>
<pre>{{ showQuestion.question }}</pre>
<li v-for="(answer, index) in showQuestion.answers" :key="index">
<button @click="givenAnswer(answer)">{{ answer.answer }}</button>
</li>
<div class="ai-decisiontree ai-decisiontree-form">
<DefaultLoader :loading="isLoading" />

<FinalResult :result="result" />

<div v-if="currentQuestion" class="ai-decisiontree ai-decisiontree-form-question">
<SingleQuestion :question="currentQuestion.question" />

<div
class="ai-decisiontree ai-decisiontree-form-answer"
v-for="(answer, index) in currentQuestion.answers"
:key="index"
>
<SingleAnswer :answer="answer" @answered="givenAnswer" />
</div>
</div>

<DefaultError :error="error" />
</div>
</template>
14 changes: 14 additions & 0 deletions frontend/src/components/DefaultError.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script setup lang="ts">
interface Props {
error?: string | null
}
defineProps<Props>()
</script>

<template>
{{ error }}
<div v-if="error" class="ai-decisiontree ai-decisiontree-error">
{{ error }}
<slot />
</div>
</template>
79 changes: 79 additions & 0 deletions frontend/src/components/DefaultLoader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<script setup lang="ts">
interface Props {
loading: boolean
}
defineProps<Props>()
</script>

<template>
<div v-if="loading" class="ai-decisiontree ai-decisiontree-loader">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</template>

<style scoped>
.ai-decisiontree-loader {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
}
.ai-decisiontree-loader div {
position: absolute;
top: 33px;
width: 13px;
height: 13px;
border-radius: 50%;
animation-timing-function: cubic-bezier(0, 1, 1, 0);
background: #408ec6;
}
.ai-decisiontree-loader div:nth-child(1) {
left: 8px;
animation: ai-decisiontree-loader1 0.6s infinite;
}
.ai-decisiontree-loader div:nth-child(2) {
left: 8px;
animation: ai-decisiontree-loader2 0.6s infinite;
}
.ai-decisiontree-loader div:nth-child(3) {
left: 32px;
animation: ai-decisiontree-loader2 0.6s infinite;
}
.ai-decisiontree-loader div:nth-child(4) {
left: 56px;
animation: ai-decisiontree-loader2 0.6s infinite;
}
.ai-decisiontree-loader div:nth-child(5) {
left: 72px;
animation: ai-decisiontree-loader3 0.6s infinite;
}
@keyframes ai-decisiontree-loader1 {
0% {
transform: scale(0);
}
100% {
transform: scale(1);
}
}
@keyframes ai-decisiontree-loader2 {
0% {
transform: translate(0, 0);
}
100% {
transform: translate(24px, 0);
}
}
@keyframes ai-decisiontree-loader3 {
0% {
transform: scale(1);
}
100% {
transform: scale(0);
}
}
</style>
<!-- #1E2761, #408EC6, #7A2048 -->
13 changes: 13 additions & 0 deletions frontend/src/components/FinalResult.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script setup lang="ts">
interface Props {
result: string | null
}
defineProps<Props>()
</script>

<template>
<div v-if="result" class="ai-decisiontree ai-decisiontree-result">
{{ result }}
<slot />
</div>
</template>
Empty file.
15 changes: 15 additions & 0 deletions frontend/src/components/SingleAnswer.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script setup lang="ts">
import { Answer } from '@/models/DecisionTree'
interface Props {
answer: Answer
}
defineProps<Props>()
defineEmits(['answered'])
</script>

<template>
<div class="ai-decisiontree ai-decisiontree-answered">
<button @click="$emit('answered', answer)">{{ answer.answer }}</button>
</div>
</template>
Empty file.
13 changes: 13 additions & 0 deletions frontend/src/components/SingleQuestion.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<script setup lang="ts">
interface Props {
question: string
}
defineProps<Props>()
</script>

<template>
<div class="ai-decisiontree ai-decisiontree-question">
{{ question }}
<slot />
</div>
</template>
1 change: 1 addition & 0 deletions infra/ingress.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ metadata:
name: ing
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
#TODO(Berry): use treafik basic auth middleware
spec:
rules:
- host: ai-act-decisiontree.apps.digilab.network
Expand Down

0 comments on commit 661b626

Please sign in to comment.