Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • aura/dashboard
1 result
Show changes
Commits on Source (4)
......@@ -14,7 +14,7 @@
"@fullcalendar/timegrid": "^6.1.8",
"@fullcalendar/vue3": "^6.1.8",
"@headlessui/vue": "^1.7.16",
"@rokoli/bnb": "^0.2.2",
"@rokoli/bnb": "^0.2.3",
"@vue/compat": "^3.3.4",
"@vueuse/core": "^10.4.1",
"@vueuse/integrations": "^10.4.1",
......@@ -1111,9 +1111,9 @@
}
},
"node_modules/@rokoli/bnb": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@rokoli/bnb/-/bnb-0.2.2.tgz",
"integrity": "sha512-yaJBG3gmQIjdqwLedmNa2riDWVNVR+6Nkl2BlwQ6bHnGlrsNWbtaG/b6uE2247CddKEEgJu5Bl9tqtYfGPwqCw==",
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@rokoli/bnb/-/bnb-0.2.3.tgz",
"integrity": "sha512-jJ4vKX5TBGwdSv1vPxgeIoQYsYITg/Vl2Oq/Nhgd9ERPgv0ksjAHMXMoDVLhAGOyZqvXS0FUsiDZ0NMGqhiTUg==",
"dependencies": {
"typescript-event-target": "^1.0.5"
},
......@@ -7740,9 +7740,9 @@
}
},
"@rokoli/bnb": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/@rokoli/bnb/-/bnb-0.2.2.tgz",
"integrity": "sha512-yaJBG3gmQIjdqwLedmNa2riDWVNVR+6Nkl2BlwQ6bHnGlrsNWbtaG/b6uE2247CddKEEgJu5Bl9tqtYfGPwqCw==",
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/@rokoli/bnb/-/bnb-0.2.3.tgz",
"integrity": "sha512-jJ4vKX5TBGwdSv1vPxgeIoQYsYITg/Vl2Oq/Nhgd9ERPgv0ksjAHMXMoDVLhAGOyZqvXS0FUsiDZ0NMGqhiTUg==",
"requires": {
"typescript-event-target": "^1.0.5"
}
......
......@@ -48,11 +48,11 @@
</FormGroup>
<FormGroup :label="t('noteEditor.contributors')" :errors="contributorErrors">
<ComboBoxSimple v-model="contributors" :choices="hosts" />
<ComboBoxSimple v-model="contributors" :choices="hostStore.items" />
</FormGroup>
<FormGroup :label="t('noteEditor.tags')" :errors="tagsErrors">
<TagInput v-model="tags" />
<TagInput v-model="noteData.tags" />
</FormGroup>
<FormGroup :label="t('noteEditor.image')" :errors="imageErrors" custom-control>
......@@ -84,9 +84,9 @@ import { computed, ref, watchEffect } from 'vue'
import { useStore } from 'vuex'
import { useI18n } from '@/i18n'
import { Host, Show, TimeSlot } from '@/types'
import { Host, Note, Show, TimeSlot } from '@/types'
import { useHostStore } from '@/stores/hosts'
import { newNote, NewNote, Note, useNoteStore } from '@/stores/notes'
import { newNote, NewNote, useNoteStore } from '@/stores/notes'
import { slugify } from '@/mixins/slugify'
import { asyncWritableComputed, useUpdatableState } from '@/util'
import ADialog from '@/components/generic/ADialog.vue'
......@@ -96,26 +96,25 @@ import ImagePicker from '@/components/images/ImagePicker.vue'
import ServerErrors from '@/components/ServerErrors.vue'
import TagInput from '@/components/generic/TagInput.vue'
import ComboBoxSimple from '@/components/ComboBoxSimple.vue'
import { useTimeSlotStore } from '@/stores/timeslots'
defineOptions({ compatConfig: { MODE: 3 } })
const props = defineProps<{
modelValue: null | number
timeslot: TimeSlot
isOpen: boolean
}>()
const emit = defineEmits<{
(e: 'update:modelValue', value: number | null): void
(e: 'show', value: boolean): void
}>()
const { t } = useI18n()
const store = useStore()
const shows = computed<Show[]>(() => store.state.shows.shows)
const show = computed(() => shows.value.find((show) => show.id === props.timeslot.showId))
const noteId = computed(() => props.modelValue)
const timeslotStore = useTimeSlotStore()
const noteStore = useNoteStore()
const { items: hosts, retrieve: retrieveHost } = useHostStore()
const { obj: storedNote } = useObjectFromStore(noteId, noteStore)
const hostStore = useHostStore()
const { obj: storedNote } = useObjectFromStore(() => props.timeslot.noteId, noteStore)
const noteData = ref<Note | NewNote>(newNote(props.timeslot.id, show.value))
const error = ref<Error>()
const { fieldErrorMap } = useServerErrors(error)
......@@ -136,21 +135,10 @@ const [
'contributorIds',
'imageId',
)
const tags = computed({
get() {
return noteData.value.tags
.split(',')
.map((t) => t.trim())
.filter((t) => t !== '')
},
set(value: string[]) {
noteData.value.tags = value.join(', ')
},
})
const contributors = asyncWritableComputed<Host[]>([], {
async get() {
const data = await Promise.all(
noteData.value.contributorIds.map((id) => retrieveHost(id, { useCached: true })),
noteData.value.contributorIds.map((id) => hostStore.retrieve(id, { useCached: true })),
)
return data.filter((obj) => obj !== null) as Host[]
},
......@@ -192,7 +180,9 @@ async function save() {
return
}
emit('update:modelValue', note.id)
if (props.timeslot.noteId !== note.id) {
await timeslotStore.partialUpdate(props.timeslot.id, { noteId: note.id })
}
emit('show', false)
}
</script>
......@@ -67,7 +67,6 @@
<Teleport to="body">
<PlaylistModal ref="playlistModal" :timeslot="timeslot" />
<NoteEditorModal
v-model="localNoteId"
:is-open="showNoteEditor"
:timeslot="timeslot"
@show="showNoteEditor = $event"
......@@ -104,10 +103,10 @@ const { t } = useI18n()
const { prettyDateTime } = usePretty()
const store = useStore()
const noteStore = useNoteStore()
// TODO: once the timeslot store is migrated to pinia we actually want to trigger
// an API update for this timeslot.
const localNoteId = ref(props.timeslot.noteId)
const { obj: note, isLoading: isLoadingNote } = useObjectFromStore(localNoteId, noteStore)
const { obj: note, isLoading: isLoadingNote } = useObjectFromStore(
() => props.timeslot.noteId,
noteStore,
)
const noteImage = useImage(computed(() => note.value?.imageId ?? null))
const duration = computed(() => calculateDurationSeconds(props.timeslot.start, props.timeslot.end))
const playlist = computed<{ id: number; description: string } | null>(() =>
......@@ -119,10 +118,7 @@ const rowClass = computed(() => {
const now = new Date()
const startDate = parseISO(props.timeslot.start)
const endDate = new Date(startDate.getTime() + duration.value * 1000)
return {
'tw-opacity-50': now > endDate,
}
return { 'tw-opacity-50': now > endDate }
})
const playlistModal = ref()
const showNoteEditor = ref(false)
......
......@@ -68,12 +68,13 @@ watchEffect(async () => {
})
watch(
() => store.getters['shows/selectedShow'],
(show) => {
if (show) {
[() => store.getters['shows/selectedShow'], () => authStore.currentUser],
([show, user]) => {
if (show && user) {
store.dispatch('playlists/fetch', { showSlug: show.slug })
}
},
{ immediate: true },
)
void authStore.init()
......@@ -10,27 +10,8 @@ import { defineStore } from 'pinia'
import { createSteeringURL } from '@/api'
import { steeringAuthInit } from '@/stores/auth'
import { Show } from '@/types'
import { Note, Show } from '@/types'
export type Note = {
id: number
title: string
slug: string
summary: string
content: string
imageId: number | null
cbaId: number | null
contributorIds: number[]
links: { type: string; url: string }[]
ownerId: number
playlist: string
tags: string
timeslotId: number
createdAt: string
createdBy: string
updatedAt: string
updatedBy: string
}
type ReadonlyAttrs = 'id' | 'createdAt' | 'createdBy' | 'updatedAt' | 'updatedBy' | 'ownerId'
export type NewNote = Omit<Note, ReadonlyAttrs>
type NoteCreateData = Omit<Note, ReadonlyAttrs>
......@@ -47,8 +28,7 @@ export function newNote(timeslotId: number, show?: Show): NewNote {
contributorIds: show?.hostIds ?? [],
links: [],
timeslotId,
tags: '',
playlist: '',
tags: [],
}
}
......
......@@ -30,3 +30,6 @@ export type MusicFocus = Required<steeringComponents['schemas']['MusicFocus']>
export type Type = Required<steeringComponents['schemas']['Type']>
export type Topic = Required<steeringComponents['schemas']['Topic']>
export type License = Required<steeringComponents['schemas']['License']>
export type Note = Required<
Omit<steeringComponents['schemas']['Note'], 'tags' | 'playlistId'> & { tags: string[] }
>
......@@ -13,7 +13,7 @@ import { version } from './package.json'
process.env.VUE_APP_VERSION = version
export default defineConfig({
base: '',
base: '/',
clearScreen: false,
// Traditionally we’ve used the VUE_ prefix for env variables as that was the default
// environment variable prefix in the vue-cli/webpack based build system.
......