216216 <icon-menu-order class =" handle w-5 h-5" />
217217 </button >
218218 <template v-if =" isSlide (element )" >
219- <div class =" flex-1 truncate" >{{ element.title }}</div >
219+ <div
220+ class =" flex-1 truncate cursor-pointer"
221+ @click =" openEditSlide(index, element)"
222+ >
223+ <span class =" rounded-sm inline-flex items-center bg-blade-300 dark:bg-blade-750 gap-2 py-1 px-2" >
224+ <icon-notes class =" w-5 h-5 stroke-1.5" />
225+ {{ element.title }}
226+ </span >
227+ </div >
220228 </template >
221229 <template v-else >
222230 <div class =" flex items-center" >
258266 <button class =" px-3 py-2 text-blade-500" aria-label =" Cancel" @click.prevent =" emit('closed')" >
259267 {{ t('button.cancel') }}
260268 </button >
269+ <secondary-button @click =" openAddSlide()" >
270+ <icon-notes class =" w-5 h-5 stroke-1.5" />
271+ {{ t('button.addSlide') }}
272+ </secondary-button >
261273 <primary-button @click =" setSetlist" >
262274 <span v-if =" !existing" >{{ t('button.createSetlist') }}</span >
263275 <span v-else >{{ t('button.updateSetlist') }}</span >
269281 </primary-button >
270282 </div >
271283 </modal-dialog >
284+ <!-- modal: add/edit slide -->
285+ <slide-set
286+ :active =" showModal.slide"
287+ :initial-slide =" slideEdit.data"
288+ :child =" true"
289+ @closed =" showModal.slide = false"
290+ @save =" saveSlide"
291+ />
272292</template >
273293
274294<script setup lang="ts">
@@ -283,14 +303,15 @@ import { ref, reactive, computed, watch, type PropType } from 'vue';
283303import { useI18n } from ' vue-i18n' ;
284304import { useRouter } from ' vue-router' ;
285305import { SongLanguage , SongTag as SongTagEnum } from ' @backend/definitions' ;
286- import type { SetlistEntity , SetlistEntry , SetlistSong } from ' @backend/models' ;
306+ import type { SetlistEntity , SetlistEntry , SetlistSlide , SetlistSong } from ' @backend/models' ;
287307import { VueDatePicker as Datepicker } from ' @vuepic/vue-datepicker' ;
288308import draggable from ' vuedraggable' ;
289309import DropDown from ' @/elements/DropDown.vue' ;
290310import ModalDialog from ' @/elements/ModalDialog.vue' ;
291311import PrimaryButton from ' @/elements/PrimaryButton.vue' ;
292312import SecondaryButton from ' @/elements/SecondaryButton.vue' ;
293313import SongTag from ' @/elements/SongTag.vue' ;
314+ import SlideSet from ' @/modals/SlideSet.vue' ;
294315
295316// icons
296317import {
@@ -304,6 +325,7 @@ import {
304325 IconLoader2 ,
305326 IconMenuOrder ,
306327 IconMusic ,
328+ IconNotes ,
307329 IconPlaylist ,
308330 IconPlus ,
309331 IconTags ,
@@ -393,6 +415,34 @@ const removeEntry = (index: number) => {
393415 setlist .value .entries .splice (index , 1 );
394416};
395417
418+ // active modals state
419+ const showModal = reactive ({ slide: false });
420+
421+ // slide currently being added (index -1) or edited (index of entry)
422+ const slideEdit = ref <{ index: number ; data: SetlistSlide | null }>({ index: - 1 , data: null });
423+
424+ // open the slide modal to add a new slide
425+ const openAddSlide = () => {
426+ slideEdit .value = { index: - 1 , data: null };
427+ showModal .slide = true ;
428+ };
429+
430+ // open the slide modal to edit an existing slide
431+ const openEditSlide = (index : number , data : SetlistSlide ) => {
432+ slideEdit .value = { index , data };
433+ showModal .slide = true ;
434+ };
435+
436+ // add or update the slide in the current entry selection
437+ const saveSlide = (slide : SetlistSlide ) => {
438+ if (slideEdit .value .index === - 1 ) {
439+ setlist .value .entries .push (slide );
440+ } else {
441+ setlist .value .entries [slideEdit .value .index ] = slide ;
442+ }
443+ showModal .slide = false ;
444+ };
445+
396446// check if given song exists on current song selection
397447const idExists = (id : string ) => setlist .value ?.entries .some ((s ) => ! isSlide (s ) && s .id === id );
398448
0 commit comments