[WIP] replace modals and buttons with new ui components
This commit is contained in:
parent
e0fb7f0fc4
commit
5399f9be0e
|
@ -2,7 +2,7 @@
|
||||||
import Modal from '~/components/ui/Modal.vue'
|
import Modal from '~/components/ui/Modal.vue'
|
||||||
import { computed } from 'vue'
|
import { computed } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
|
||||||
const model = defineModel<boolean>()
|
const model = defineModel<boolean>()
|
||||||
|
|
||||||
|
@ -141,9 +141,9 @@ const player = computed(() => [
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<footer class="actions">
|
<footer class="actions">
|
||||||
<button class="ui basic cancel button">
|
<Button color="secondary">
|
||||||
{{ t('components.ShortcutsModal.button.close') }}
|
{{ t('components.ShortcutsModal.button.close') }}
|
||||||
</button>
|
</Button>
|
||||||
</footer>
|
</footer>
|
||||||
</Modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -2,6 +2,8 @@
|
||||||
import type { Form } from '~/types'
|
import type { Form } from '~/types'
|
||||||
|
|
||||||
import SignupForm from '~/components/auth/SignupForm.vue'
|
import SignupForm from '~/components/auth/SignupForm.vue'
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
|
||||||
import { useVModel } from '@vueuse/core'
|
import { useVModel } from '@vueuse/core'
|
||||||
import { computed, ref } from 'vue'
|
import { computed, ref } from 'vue'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
|
@ -65,18 +67,20 @@ const move = (idx: number, increment: number) => {
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div class="ui top attached tabular menu">
|
<div class="ui top attached tabular menu">
|
||||||
<button
|
<Button
|
||||||
|
color="primary"
|
||||||
:class="[{active: !isPreviewing}, 'item']"
|
:class="[{active: !isPreviewing}, 'item']"
|
||||||
@click.stop.prevent="isPreviewing = false"
|
@click.stop.prevent="isPreviewing = false"
|
||||||
>
|
>
|
||||||
{{ t('components.admin.SignupFormBuilder.button.edit') }}
|
{{ t('components.admin.SignupFormBuilder.Button.edit') }}
|
||||||
</button>
|
</Button>
|
||||||
<button
|
<Button
|
||||||
|
color="primary"
|
||||||
:class="[{active: isPreviewing}, 'item']"
|
:class="[{active: isPreviewing}, 'item']"
|
||||||
@click.stop.prevent="isPreviewing = true"
|
@click.stop.prevent="isPreviewing = true"
|
||||||
>
|
>
|
||||||
{{ t('components.admin.SignupFormBuilder.button.preview') }}
|
{{ t('components.admin.SignupFormBuilder.Button.preview') }}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-if="isPreviewing"
|
v-if="isPreviewing"
|
||||||
|
@ -187,13 +191,13 @@ const move = (idx: number, increment: number) => {
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
<button
|
<Button
|
||||||
|
color = "primary"
|
||||||
v-if="value.fields?.length < maxFields"
|
v-if="value.fields?.length < maxFields"
|
||||||
class="ui basic button"
|
|
||||||
@click.stop.prevent="addField"
|
@click.stop.prevent="addField"
|
||||||
>
|
>
|
||||||
{{ t('components.admin.SignupFormBuilder.button.add') }}
|
{{ t('components.admin.SignupFormBuilder.button.add') }}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui hidden divider" />
|
<div class="ui hidden divider" />
|
||||||
|
|
|
@ -3,8 +3,10 @@ import type { OrderingProps } from '~/composables/navigation/useOrdering'
|
||||||
import type { Artist, BackendResponse } from '~/types'
|
import type { Artist, BackendResponse } from '~/types'
|
||||||
import type { RouteRecordName } from 'vue-router'
|
import type { RouteRecordName } from 'vue-router'
|
||||||
import type { OrderingField } from '~/store/ui'
|
import type { OrderingField } from '~/store/ui'
|
||||||
|
import Popover from "~/components/ui/Popover.vue"
|
||||||
|
import PopoverItem from "~/components/ui/popover/PopoverItem.vue"
|
||||||
|
|
||||||
import { computed, ref, watch, onMounted } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { useRouteQuery } from '@vueuse/router'
|
import { useRouteQuery } from '@vueuse/router'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import { syncRef } from '@vueuse/core'
|
import { syncRef } from '@vueuse/core'
|
||||||
|
@ -12,11 +14,10 @@ import { sortedUniq } from 'lodash-es'
|
||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
|
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import $ from 'jquery'
|
|
||||||
|
|
||||||
import TagsSelector from '~/components/library/TagsSelector.vue'
|
import TagsSelector from '~/components/library/TagsSelector.vue'
|
||||||
import RemoteSearchForm from '~/components/RemoteSearchForm.vue'
|
import RemoteSearchForm from '~/components/RemoteSearchForm.vue'
|
||||||
import SemanticModal from '~/components/semantic/Modal.vue'
|
import Modal from '~/components/ui/Modal.vue'
|
||||||
import ArtistCard from '~/components/artist/Card.vue'
|
import ArtistCard from '~/components/artist/Card.vue'
|
||||||
import Pagination from '~/components/vui/Pagination.vue'
|
import Pagination from '~/components/vui/Pagination.vue'
|
||||||
|
|
||||||
|
@ -103,13 +104,13 @@ const search = () => {
|
||||||
q.value = query.value
|
q.value = query.value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const artistOrdering = ref(false)
|
||||||
|
|
||||||
onOrderingUpdate(() => {
|
onOrderingUpdate(() => {
|
||||||
page.value = 1
|
page.value = 1
|
||||||
fetchData()
|
fetchData()
|
||||||
})
|
})
|
||||||
|
|
||||||
onMounted(() => $('.ui.dropdown').dropdown())
|
|
||||||
|
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const labels = computed(() => ({
|
const labels = computed(() => ({
|
||||||
searchPlaceholder: t('components.library.Podcasts.placeholder.search'),
|
searchPlaceholder: t('components.library.Podcasts.placeholder.search'),
|
||||||
|
@ -157,19 +158,16 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="artist-ordering">{{ t('components.library.Podcasts.ordering.label') }}</label>
|
<label for="artist-ordering">{{ t('components.library.Podcasts.ordering.label') }}</label>
|
||||||
<select
|
<Popover v-model:open="artistOrdering">
|
||||||
id="artist-ordering"
|
<OptionsButton @click="artistOrdering = !artistOrdering" id="artist-ordering" v-model="ordering"/>
|
||||||
v-model="ordering"
|
<PopoverItem
|
||||||
class="ui dropdown"
|
|
||||||
>
|
|
||||||
<option
|
|
||||||
v-for="(option, key) in orderingOptions"
|
v-for="(option, key) in orderingOptions"
|
||||||
:key="key"
|
:key="key"
|
||||||
:value="option[0]"
|
:value="option[0]"
|
||||||
>
|
>
|
||||||
{{ sharedLabels.filters[option[1]] }}
|
{{ sharedLabels.filters[option[1]] }}
|
||||||
</option>
|
</PopoverItem>
|
||||||
</select>
|
</Popover>
|
||||||
</div>
|
</div>
|
||||||
<div class="field">
|
<div class="field">
|
||||||
<label for="artist-ordering-direction">{{ t('components.library.Podcasts.ordering.direction.label') }}</label>
|
<label for="artist-ordering-direction">{{ t('components.library.Podcasts.ordering.direction.label') }}</label>
|
||||||
|
@ -259,14 +257,11 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<semantic-modal
|
<Modal
|
||||||
v-model:show="showSubscribeModal"
|
v-model:show="showSubscribeModal"
|
||||||
class="tiny"
|
title="t('components.library.Podcasts.modal.subscription.header')"
|
||||||
:fullscreen="false"
|
<!-- class="tiny" TODO: check if necessary -->
|
||||||
>
|
>
|
||||||
<h2 class="header">
|
|
||||||
{{ t('components.library.Podcasts.modal.subscription.header') }}
|
|
||||||
</h2>
|
|
||||||
<div
|
<div
|
||||||
ref="modalContent"
|
ref="modalContent"
|
||||||
class="scrolling content"
|
class="scrolling content"
|
||||||
|
@ -292,6 +287,6 @@ const paginateOptions = computed(() => sortedUniq([12, 30, 50, paginateBy.value]
|
||||||
{{ t('components.library.Podcasts.button.subscribe') }}
|
{{ t('components.library.Podcasts.button.subscribe') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</Modal>
|
||||||
</main>
|
</main>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -4,7 +4,7 @@ import type { BackendError, Playlist, APIErrorResponse } from '~/types'
|
||||||
import { filter, sortBy, flow } from 'lodash-es'
|
import { filter, sortBy, flow } from 'lodash-es'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { useI18n } from 'vue-i18n'
|
import { useI18n } from 'vue-i18n'
|
||||||
import SemanticModal from '~/components/semantic/Modal.vue'
|
import Modal from '~/components/ui/Modal.vue'
|
||||||
import PlaylistForm from '~/components/playlists/Form.vue'
|
import PlaylistForm from '~/components/playlists/Form.vue'
|
||||||
import useLogger from '~/composables/useLogger'
|
import useLogger from '~/composables/useLogger'
|
||||||
import { useStore } from '~/store'
|
import { useStore } from '~/store'
|
||||||
|
@ -78,14 +78,17 @@ const addToPlaylist = async (playlistId: number, allowDuplicates: boolean) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
store.dispatch('playlists/fetchOwn')
|
store.dispatch('playlists/fetchOwn')
|
||||||
|
const playlistIsOpen = store.state.playlists.showModal
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<semantic-modal
|
<Modal
|
||||||
v-model:show="store.state.playlists.showModal"
|
v-model=playlistIsOpen
|
||||||
|
title="t('components.playlists.PlaylistModal.header.addToPlaylist')"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
<h4 class="header">
|
||||||
<template v-if="track">
|
<template v-if="track">
|
||||||
|
// TODO: Check subheader
|
||||||
<h2 class="ui header">
|
<h2 class="ui header">
|
||||||
{{ t('components.playlists.PlaylistModal.header.addToPlaylist') }}
|
{{ t('components.playlists.PlaylistModal.header.addToPlaylist') }}
|
||||||
<div class="ui sub header">
|
<div class="ui sub header">
|
||||||
|
@ -241,5 +244,5 @@ store.dispatch('playlists/fetchOwn')
|
||||||
{{ t('components.playlists.PlaylistModal.button.cancel') }}
|
{{ t('components.playlists.PlaylistModal.button.cancel') }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</semantic-modal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -2,8 +2,11 @@
|
||||||
import { computed, ref, reactive } from 'vue'
|
import { computed, ref, reactive } from 'vue'
|
||||||
import { useUploadsStore } from '~/ui/stores/upload'
|
import { useUploadsStore } from '~/ui/stores/upload'
|
||||||
import { bytesToHumanSize } from '~/ui/composables/bytes'
|
import { bytesToHumanSize } from '~/ui/composables/bytes'
|
||||||
import UploadList from '~/ui/components/UploadList.vue'
|
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
|
import UploadList from '~/ui/components/UploadList.vue'
|
||||||
|
import Alert from '~/components/ui/Alert.vue'
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
import Modal from '~/components/ui/Modal.vue'
|
||||||
|
|
||||||
const uploads = useUploadsStore()
|
const uploads = useUploadsStore()
|
||||||
|
|
||||||
|
@ -54,6 +57,8 @@ const continueInBackground = () => {
|
||||||
return router.push('/upload/running')
|
return router.push('/upload/running')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO (whole file): Translations
|
||||||
|
|
||||||
// Sorting
|
// Sorting
|
||||||
const sortItems = reactive([
|
const sortItems = reactive([
|
||||||
{ label: 'Upload time', value: 'upload-time' },
|
{ label: 'Upload time', value: 'upload-time' },
|
||||||
|
@ -67,25 +72,24 @@ const filterItems = reactive([
|
||||||
{ label: 'All', value: 'all' }
|
{ label: 'All', value: 'all' }
|
||||||
])
|
])
|
||||||
const currentFilter = ref(filterItems[0])
|
const currentFilter = ref(filterItems[0])
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<FwModal
|
<Modal
|
||||||
v-model="libraryOpen"
|
v-model="libraryOpen"
|
||||||
title="Upload music to library"
|
title="Upload music to library"
|
||||||
>
|
>
|
||||||
<template #alert="{ closeAlert }">
|
<template #alert="closeAlert">
|
||||||
<FwAlert>
|
<Alert>
|
||||||
Before uploading, please ensure your files are tagged properly.
|
Before uploading, please ensure your files are tagged properly.
|
||||||
We recommend using Picard for that purpose.
|
We recommend using Picard for that purpose.
|
||||||
|
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<FwButton @click="closeAlert">
|
<Button @click="closeAlert">
|
||||||
Got it
|
Got it
|
||||||
</FwButton>
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</FwAlert>
|
</Alert>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<FwFileInput
|
<FwFileInput
|
||||||
|
@ -125,24 +129,25 @@ const currentFilter = ref(filterItems[0])
|
||||||
v-model="serverPath"
|
v-model="serverPath"
|
||||||
class="w-full mr-4"
|
class="w-full mr-4"
|
||||||
/>
|
/>
|
||||||
<FwButton color="secondary">
|
<Button color="secondary">
|
||||||
Import
|
Import
|
||||||
</FwButton>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template #actions>
|
<template #actions>
|
||||||
<FwButton
|
<Button
|
||||||
color="secondary"
|
color="secondary"
|
||||||
@click="cancel"
|
@click="cancel"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</FwButton>
|
</Button>
|
||||||
<FwButton @click="continueInBackground">
|
<Button @click="continueInBackground">
|
||||||
{{ uploads.queue.length ? 'Continue in background' : 'Save and close' }}
|
{{ uploads.queue.length ? 'Continue in background' : 'Save and close' }}
|
||||||
</FwButton>
|
//TODO: Translations
|
||||||
|
</Button>
|
||||||
</template>
|
</template>
|
||||||
</FwModal>
|
</Modal>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
|
|
|
@ -10,9 +10,10 @@ import axios from 'axios'
|
||||||
|
|
||||||
import PlaylistEditor from '~/components/playlists/Editor.vue'
|
import PlaylistEditor from '~/components/playlists/Editor.vue'
|
||||||
import EmbedWizard from '~/components/audio/EmbedWizard.vue'
|
import EmbedWizard from '~/components/audio/EmbedWizard.vue'
|
||||||
import SemanticModal from '~/components/semantic/Modal.vue'
|
import Modal from '~/components/ui/Modal.vue'
|
||||||
import TrackTable from '~/components/audio/track/Table.vue'
|
import TrackTable from '~/components/audio/track/Table.vue'
|
||||||
import PlayButton from '~/components/audio/PlayButton.vue'
|
import PlayButton from '~/components/audio/PlayButton.vue'
|
||||||
|
import Button from '~/components/ui/Button.vue'
|
||||||
|
|
||||||
import PlaylistDropdown from '~/components/playlists/PlaylistDropdown.vue'
|
import PlaylistDropdown from '~/components/playlists/PlaylistDropdown.vue'
|
||||||
|
|
||||||
|
@ -113,24 +114,23 @@ const deletePlaylist = async () => {
|
||||||
</play-button>
|
</play-button>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<button
|
<Button
|
||||||
v-if="store.state.auth.profile && playlist.actor.full_username === store.state.auth.fullUsername"
|
v-if="store.state.auth.profile && playlist.actor.full_username === store.state.auth.fullUsername"
|
||||||
class="ui icon labeled button"
|
|
||||||
@click="edit = !edit"
|
@click="edit = !edit"
|
||||||
|
icon="bi-pencil"
|
||||||
>
|
>
|
||||||
<i class="pencil icon" />
|
|
||||||
<template v-if="edit">
|
<template v-if="edit">
|
||||||
{{ t('views.playlists.Detail.button.stopEdit') }}
|
{{ t('views.playlists.Detail.button.stopEdit') }}
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
{{ t('views.playlists.Detail.button.edit') }}
|
{{ t('views.playlists.Detail.button.edit') }}
|
||||||
</template>
|
</template>
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
<div class="ui buttons">
|
<div class="ui buttons">
|
||||||
<button
|
<Button
|
||||||
v-if="playlist.privacy_level === 'everyone' && playlist.is_playable"
|
v-if="playlist.privacy_level === 'everyone' && playlist.is_playable"
|
||||||
class="ui icon labeled button"
|
icon="bi-code-slash"
|
||||||
@click="showEmbedModal = !showEmbedModal"
|
@click="showEmbedModal = !showEmbedModal"
|
||||||
>
|
>
|
||||||
<i class="code icon" />
|
<i class="code icon" />
|
||||||
|
@ -141,7 +141,6 @@ const deletePlaylist = async () => {
|
||||||
class="ui labeled danger icon button"
|
class="ui labeled danger icon button"
|
||||||
:action="deletePlaylist"
|
:action="deletePlaylist"
|
||||||
>
|
>
|
||||||
<i class="trash icon" />
|
|
||||||
{{ t('views.playlists.Detail.button.delete') }}
|
{{ t('views.playlists.Detail.button.delete') }}
|
||||||
<template #modal-header>
|
<template #modal-header>
|
||||||
<p>
|
<p>
|
||||||
|
@ -166,13 +165,11 @@ const deletePlaylist = async () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<semantic-modal
|
<Modal
|
||||||
v-if="playlist.privacy_level === 'everyone' && playlist.is_playable"
|
v-if="playlist.privacy_level === 'everyone' && playlist.is_playable"
|
||||||
v-model:show="showEmbedModal"
|
v-model="showEmbedModal"
|
||||||
|
title="t('views.playlists.Detail.modal.embed.header')"
|
||||||
>
|
>
|
||||||
<h4 class="header">
|
|
||||||
{{ t('views.playlists.Detail.modal.embed.header') }}
|
|
||||||
</h4>
|
|
||||||
<div class="scrolling content">
|
<div class="scrolling content">
|
||||||
<div class="description">
|
<div class="description">
|
||||||
<embed-wizard
|
<embed-wizard
|
||||||
|
@ -181,12 +178,12 @@ const deletePlaylist = async () => {
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="actions">
|
<template #actions>
|
||||||
<button class="ui basic deny button">
|
<Button variant="outline">
|
||||||
{{ t('views.playlists.Detail.button.cancel') }}
|
{{ t('views.playlists.Detail.button.cancel') }}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</template>
|
||||||
</semantic-modal>
|
</Modal>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="ui vertical stripe segment">
|
<section class="ui vertical stripe segment">
|
||||||
|
@ -214,13 +211,12 @@ const deletePlaylist = async () => {
|
||||||
<i class="list icon" />
|
<i class="list icon" />
|
||||||
{{ t('views.playlists.Detail.empty.noTracks') }}
|
{{ t('views.playlists.Detail.empty.noTracks') }}
|
||||||
</div>
|
</div>
|
||||||
<button
|
<Button
|
||||||
class="ui success icon labeled button"
|
icon="bi-pencil"
|
||||||
@click="edit = !edit"
|
@click="edit = !edit"
|
||||||
>
|
>
|
||||||
<i class="pencil icon" />
|
|
||||||
{{ t('views.playlists.Detail.button.edit') }}
|
{{ t('views.playlists.Detail.button.edit') }}
|
||||||
</button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</main>
|
</main>
|
||||||
|
|
Loading…
Reference in New Issue