feat: FE forms parts, show form
This commit is contained in:
parent
5697449f2e
commit
85a5a61e79
4 changed files with 176 additions and 33 deletions
|
@ -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>
|
|
@ -1,38 +1,54 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import {ref, reactive, type PropType} from 'vue';
|
import { ref, watch, shallowRef, type PropType } from 'vue';
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
checkBoxForm: {
|
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,
|
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);
|
// Watch for changes in the checkbox state and update the disabled state of nested fields
|
||||||
const fields = ref(checkBoxForm.value.fields);
|
watch(isChecked, (isChecked) => {
|
||||||
|
for (const key in fields.value) {
|
||||||
|
fields.value[key].disabled = !isChecked;
|
||||||
const toggleFields = () => {
|
}
|
||||||
checkBoxForm.value.fields.forEach(field => {
|
});
|
||||||
field.disabled = !field.disabled;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title>Live Stream Configuration</v-card-title>
|
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
|
<!-- Checkbox to toggle nested fields -->
|
||||||
<v-checkbox
|
<v-checkbox
|
||||||
:label="checkboxField.label"
|
:label="props.checkBoxForm.checkBoxField.label"
|
||||||
@change="toggleFields"
|
v-model="isChecked"
|
||||||
></v-checkbox>
|
></v-checkbox>
|
||||||
|
|
||||||
|
<!-- Dynamically render nested fields -->
|
||||||
|
<template v-for="(field, key) in fields" :key="key">
|
||||||
<component
|
<component
|
||||||
v-for="field in checkBoxForm.fields"
|
|
||||||
:is="field.component"
|
:is="field.component"
|
||||||
v-model="field[key]"
|
v-model="field.value"
|
||||||
:label="field.label"
|
:label="field.label"
|
||||||
:disabled="field.disabled"
|
:disabled="field.disabled"
|
||||||
:density="'compact'"
|
:density="'compact'"
|
||||||
|
@ -44,10 +60,9 @@ const toggleFields = () => {
|
||||||
:active="true"
|
:active="true"
|
||||||
v-bind="field.props || {}"
|
v-bind="field.props || {}"
|
||||||
/>
|
/>
|
||||||
|
</template>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
</v-card>
|
</v-card>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped></style>
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -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>
|
|
@ -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>
|
Loading…
Add table
Add a link
Reference in a new issue