feat: FE forms parts, show form

This commit is contained in:
Michael 2025-03-26 10:34:36 +01:00
parent 5697449f2e
commit 85a5a61e79
4 changed files with 176 additions and 33 deletions

View file

@ -0,0 +1,56 @@
<script setup lang="ts">
import {computed, ref} from "vue";
import type {PropType} from "vue";
import {type Show, showForm} from "@models/show/show";
const props = defineProps({
show: {
type: Object as PropType<Show>,
required: true,
},
});
const show = ref(props.show);
const showFields = showForm(show.value);
const goToSchedule = () => {
}
</script>
<template>
<v-card>
<v-card-title>
<h3>Trasmissione</h3>
</v-card-title>
<ShowScheduleRules />
<v-form>
<v-card-text>
<v-row no-gutters>
<v-col v-for="(field, key) in showFields" :key="key" cols="5" md="6" lg="4">
<Component
:is="field.component"
v-model="show[key]"
:label="field.label"
:disabled="field.disabled"
:density="'compact'"
rows="2"
item-title="type_name"
hide-details="auto"
class="mb-2"
clearable
:active="true"
v-bind="field.props || {}"
/>
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-btn color="accent" @click="$emit('goBack')">Torna indietro</v-btn>
<v-btn color="accent" @click="goToSchedule">Salva</v-btn>
</v-card-actions>
</v-form>
</v-card>
</template>
<style scoped></style>

View file

@ -1,53 +1,68 @@
<script setup lang="ts">
import {ref, reactive, type PropType} from 'vue';
import { ref, watch, shallowRef, type PropType } from 'vue';
const props = defineProps({
checkBoxForm: {
type: Object,
type: Object as PropType<{
checkBoxField: { label: string };
fields: Record<string, {
label: string;
component: any;
value: any;
disabled: boolean;
props?: Record<string, any>;
}>;
}>,
required: true,
},
value: {
type: Boolean,
required: true,
},
});
const checkBoxForm = ref(props.checkBoxForm);
// Reactive state for the checkbox and nested fields
const isChecked = ref(props.value);
// TODO performance issue by using ref, but losing connectivity to main data struct if not
// Either cycle trough each field and add it to a ref var, so its value is updated but the rest is not tracked
const fields = ref(props.checkBoxForm.fields);
const checkBoxField = ref(checkBoxForm.checkBoxField);
const fields = ref(checkBoxForm.value.fields);
const toggleFields = () => {
checkBoxForm.value.fields.forEach(field => {
field.disabled = !field.disabled;
});
};
// Watch for changes in the checkbox state and update the disabled state of nested fields
watch(isChecked, (isChecked) => {
for (const key in fields.value) {
fields.value[key].disabled = !isChecked;
}
});
</script>
<template>
<v-card>
<v-card-title>Live Stream Configuration</v-card-title>
<v-card-text>
<!-- Checkbox to toggle nested fields -->
<v-checkbox
:label="checkboxField.label"
@change="toggleFields"
:label="props.checkBoxForm.checkBoxField.label"
v-model="isChecked"
></v-checkbox>
<component
v-for="field in checkBoxForm.fields"
:is="field.component"
v-model="field[key]"
:label="field.label"
:disabled="field.disabled"
:density="'compact'"
rows="2"
item-title="type_name"
hide-details="auto"
class="mb-2"
clearable
:active="true"
v-bind="field.props || {}"
/>
<!-- Dynamically render nested fields -->
<template v-for="(field, key) in fields" :key="key">
<component
:is="field.component"
v-model="field.value"
:label="field.label"
:disabled="field.disabled"
:density="'compact'"
rows="2"
item-title="type_name"
hide-details="auto"
class="mb-2"
clearable
:active="true"
v-bind="field.props || {}"
/>
</template>
</v-card-text>
</v-card>
</template>
<style scoped>
</style>
<style scoped></style>

View file

@ -0,0 +1,37 @@
<script setup lang="ts">
import {watch, ref} from 'vue';
const emit = defineEmits([
'color-selected'
])
const props = defineProps({
color: {
default: '',
type: String
}
})
const localColor = ref(props.color)
const menu = ref(false)
const saveColor = (color: string) => {
menu.value = false;
emit('color-selected', color);
}
</script>
<template>
<v-menu offset-x :close-on-content-click="false" v-model="menu">
<template v-slot:activator="{ props }">
<v-btn v-bind="props" :color="localColor">
{{ localColor || 'Select Color' }}
</v-btn>
</template>
<v-color-picker v-model="localColor" mode="hex"></v-color-picker>
</v-menu>
</template>
<style scoped>
</style>

View file

@ -0,0 +1,35 @@
<script setup lang="ts">
import {onMounted, ref} from "vue";
import axios from "axios";
const props = defineProps({
value: {
type: Number,
required: true,
},
})
const selectedPlaylist = ref(props.value);
let playlists = [];
onMounted(async () => {
return await axios.get(`/playlist`).then((response) => {
playlists = response.data.data;
})
})
// TODO In the vselect, object object is rendered instead of the playlist name, don't know why
</script>
<template>
<VSelect
v-model="selectedPlaylist"
:items="playlists"
item-title="name"
item-value="id"
label="Seleziona playlist"
/>
</template>
<style scoped>
</style>