diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 380f359efdc1c01cad2bd4aa9f8f62f865b46765..5e66729357c07d0423be54d983eaf2114fdbfce5 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -136,7 +136,7 @@ eslint: - cd front - yarn install script: - - yarn lint + - yarn lint --max-warnings 0 cache: key: "$CI_PROJECT_ID__eslint_npm_cache" paths: diff --git a/front/src/components/audio/PlayButton.vue b/front/src/components/audio/PlayButton.vue index aba5a346d04b40787297dbc92b30132322f83209..33c54c2c53343410bfbc4da39cdd399e9db16f77 100644 --- a/front/src/components/audio/PlayButton.vue +++ b/front/src/components/audio/PlayButton.vue @@ -133,20 +133,20 @@ export default { mixins: [ReportMixin, PlayOptionsMixin], props: { // we can either have a single or multiple tracks to play when clicked - tracks: { type: Array, required: false, default: () => { return [] } }, - track: { type: Object, required: false, default: () => { return {} } }, - account: { type: Object, required: false, default: () => { return {} } }, + tracks: { type: Array, required: false, default: () => { return null } }, + track: { type: Object, required: false, default: () => { return null } }, + account: { type: Object, required: false, default: () => { return null } }, dropdownIconClasses: { type: Array, required: false, default: () => { return ['dropdown'] } }, playIconClass: { type: String, required: false, default: 'play icon' }, buttonClasses: { type: Array, required: false, default: () => { return ['button'] } }, - playlist: { type: Object, required: false, default: () => { return {} } }, + playlist: { type: Object, required: false, default: () => { return null } }, discrete: { type: Boolean, default: false }, dropdownOnly: { type: Boolean, default: false }, iconOnly: { type: Boolean, default: false }, - artist: { type: Object, required: false, default: () => { return {} } }, - album: { type: Object, required: false, default: () => { return {} } }, - library: { type: Object, required: false, default: () => { return {} } }, - channel: { type: Object, required: false, default: () => { return {} } }, + artist: { type: Object, required: false, default: () => { return null } }, + album: { type: Object, required: false, default: () => { return null } }, + library: { type: Object, required: false, default: () => { return null } }, + channel: { type: Object, required: false, default: () => { return null } }, isPlayable: { type: Boolean, required: false, default: null }, playing: { type: Boolean, required: false, default: false }, paused: { type: Boolean, required: false, default: false } diff --git a/front/src/components/audio/VolumeControl.vue b/front/src/components/audio/VolumeControl.vue index aa61c89b83b8c1968b4838d6fbd3752a68de5b69..d8f45dccc8dc2333e5f5c536c41968c6d4b56166 100644 --- a/front/src/components/audio/VolumeControl.vue +++ b/front/src/components/audio/VolumeControl.vue @@ -50,7 +50,7 @@ </button> </template> <script> -import mapActions from 'vuex' +import { mapActions } from 'vuex' export default { data () { diff --git a/front/src/components/audio/podcast/Row.vue b/front/src/components/audio/podcast/Row.vue index 3b0bf43d2030771a583ebaaa6541902e3f183f21..06bec4855fdd5d3df73b3577f1379827eb2d8c08 100644 --- a/front/src/components/audio/podcast/Row.vue +++ b/front/src/components/audio/podcast/Row.vue @@ -105,7 +105,7 @@ export default { showDuration: { type: Boolean, required: false, default: true }, index: { type: Number, required: true }, track: { type: Object, required: true }, - defaultCover: { type: Object, required: false, default: () => { return {} } } + defaultCover: { type: Object, required: false, default: null } }, data () { diff --git a/front/src/components/common/AttachmentInput.vue b/front/src/components/common/AttachmentInput.vue index 72bc5264f22d3cb821f5839923e09396ad68015c..0a52dcbb26afdb057a8002a26be3679fa7ffa812 100644 --- a/front/src/components/common/AttachmentInput.vue +++ b/front/src/components/common/AttachmentInput.vue @@ -91,7 +91,7 @@ import axios from 'axios' export default { props: { - value: { type: String, required: true }, + value: { type: String, default: null }, imageClass: { type: String, default: '', required: false } }, data () { diff --git a/front/src/components/common/Duration.vue b/front/src/components/common/Duration.vue index 81a0b578f1b827e0a6f2c21d0115170ff3f7614f..a1c652695e4e860ef3d14187ea045abbe90ee83b 100644 --- a/front/src/components/common/Duration.vue +++ b/front/src/components/common/Duration.vue @@ -16,7 +16,7 @@ import { secondsToObject } from '@/filters' export default { - props: { seconds: { type: Number, required: true } }, + props: { seconds: { type: Number, default: null } }, computed: { durationData () { return secondsToObject(this.seconds) diff --git a/front/src/components/common/RenderedDescription.vue b/front/src/components/common/RenderedDescription.vue index 132faface084873745838820fc6462b7257d9546..2c4797350b849dd3e5e1ce2a0deec19dd9baf6e5 100644 --- a/front/src/components/common/RenderedDescription.vue +++ b/front/src/components/common/RenderedDescription.vue @@ -89,7 +89,7 @@ import clip from 'text-clipper' export default { props: { - content: { type: String, default: '' }, + content: { type: Object, required: false, default: null }, fieldName: { type: String, required: false, default: 'description' }, updateUrl: { required: false, type: String, default: '' }, canUpdate: { required: false, default: true, type: Boolean }, diff --git a/front/src/components/federation/LibraryWidget.vue b/front/src/components/federation/LibraryWidget.vue index 9ba011015da8f49346269031dcbc44a0c4cf3b02..62683996af24844ad88ac65456504d1749fbccec 100644 --- a/front/src/components/federation/LibraryWidget.vue +++ b/front/src/components/federation/LibraryWidget.vue @@ -33,7 +33,7 @@ :key="library.uuid" :display-scan="false" :display-follow="$store.state.auth.authenticated && library.actor.full_username != $store.state.auth.fullUsername" - :library="library" + :initial-library="library" :display-copy-fid="true" /> </div> diff --git a/front/src/components/forms/PasswordInput.vue b/front/src/components/forms/PasswordInput.vue index 5b37bf60f99510b788dc1203eea057bef1d9bad6..b9dab0e4c4ab8f963acad33fe149699afe8b7115 100644 --- a/front/src/components/forms/PasswordInput.vue +++ b/front/src/components/forms/PasswordInput.vue @@ -33,7 +33,7 @@ export default { value: { type: String, required: true }, defaultShow: { type: Boolean, default: false }, copyButton: { type: Boolean, default: false }, - fieldId: { type: Number, default: 0 } + fieldId: { type: String, required: true } }, data () { return { diff --git a/front/src/components/library/AlbumBase.vue b/front/src/components/library/AlbumBase.vue index c8bf353494bcc1cb2542124e35806c0aeef26b69..9ed85eded99994f07c3a5fabe875db4491fc5122 100644 --- a/front/src/components/library/AlbumBase.vue +++ b/front/src/components/library/AlbumBase.vue @@ -273,7 +273,7 @@ export default { ArtistLabel, AlbumDropdown }, - props: { id: { type: Number, required: true } }, + props: { id: { type: [String, Number], required: true } }, data () { return { isLoading: true, diff --git a/front/src/components/library/ArtistBase.vue b/front/src/components/library/ArtistBase.vue index cbc7d4518f142af12a5b358db7af0f17e6f9b11b..95462c09dad33fddbb610f0a4eb5ec3c3d2a11b5 100644 --- a/front/src/components/library/ArtistBase.vue +++ b/front/src/components/library/ArtistBase.vue @@ -42,7 +42,7 @@ <div class="ui buttons"> <radio-button type="artist" - :object-id="object.id" + :object-id="String(object.id)" /> </div> <div class="ui buttons"> @@ -234,7 +234,7 @@ export default { TagsList }, mixins: [ReportMixin], - props: { id: { type: Number, required: true } }, + props: { id: { type: [String, Number], required: true } }, data () { return { isLoading: true, diff --git a/front/src/components/library/ArtistDetail.vue b/front/src/components/library/ArtistDetail.vue index fff1a6183b9a594b069e245a608256fe02608a82..7f8248925a3c79afdf7dd6a625e93f35785c36b3 100644 --- a/front/src/components/library/ArtistDetail.vue +++ b/front/src/components/library/ArtistDetail.vue @@ -120,8 +120,8 @@ export default { tracks: { type: Array, required: true }, albums: { type: Array, required: true }, isLoadingAlbums: { type: Boolean, required: true }, - nextTracksUrl: { type: String, required: true }, - nextAlbumsUrl: { type: String, required: true } + nextTracksUrl: { type: String, default: null }, + nextAlbumsUrl: { type: String, default: null } }, data () { return { diff --git a/front/src/components/library/EditForm.vue b/front/src/components/library/EditForm.vue index 60175df3d6f4508b87b2c3d4db3981032613882e..90c6b22b68f47e316424059a52bdf6baa5fd7d25 100644 --- a/front/src/components/library/EditForm.vue +++ b/front/src/components/library/EditForm.vue @@ -182,11 +182,11 @@ </translate> </button> </template> - <div v-if="!lodash.isEqual(values[fieldConfig.id], initialValues[fieldConfig.id])"> + <div v-if="fieldValuesChanged(fieldConfig.id)"> <button class="ui tiny basic right floated reset button" form="noop" - @click.prevent="values[fieldConfig.id] = lodash.clone(initialValues[fieldConfig.id])" + @click.prevent="resetField(fieldConfig.id)" > <i class="undo icon" /> <translate translate-context="Content/Library/Button.Label"> @@ -361,7 +361,14 @@ export default { self.isLoading = false } ) + }, + fieldValuesChanged (fieldId) { + return !_.isEqual(this.values[fieldId], this.initialValues[fieldId]) + }, + resetField (fieldId) { + this.values[fieldId] = _.clone(this.initialValues[fieldId]) } } + } </script> diff --git a/front/src/components/library/TrackBase.vue b/front/src/components/library/TrackBase.vue index 5107cc58a7a0c468ec0a6e7cdcda7a6e9c62712b..fd809c74ee4c48bc45224b968fe2eabffebb8d04 100644 --- a/front/src/components/library/TrackBase.vue +++ b/front/src/components/library/TrackBase.vue @@ -252,7 +252,7 @@ export default { EmbedWizard }, mixins: [ReportMixin], - props: { id: { type: Number, required: true } }, + props: { id: { type: [String, Number], required: true } }, data () { return { time, diff --git a/front/src/components/library/TrackDetail.vue b/front/src/components/library/TrackDetail.vue index 182eba921d163ce4c7ea1a40c38f1bd25d0c2698..276edcba9f4891cf94cbd09c7941cacdda5c4a2d 100644 --- a/front/src/components/library/TrackDetail.vue +++ b/front/src/components/library/TrackDetail.vue @@ -301,7 +301,7 @@ export default { }, props: { track: { type: Object, required: true }, - libraries: { type: Array, required: true } + libraries: { type: Array, default: null } }, data () { return { diff --git a/front/src/components/library/TrackEdit.vue b/front/src/components/library/TrackEdit.vue index add5c4485214259e2e5512d47ed5c7026e4e32f3..ce5422796bba857e9117533689fdb0c7d3b10ce3 100644 --- a/front/src/components/library/TrackEdit.vue +++ b/front/src/components/library/TrackEdit.vue @@ -53,7 +53,7 @@ export default { props: { objectType: { type: String, required: true }, object: { type: Object, required: true }, - libraries: { type: Array, required: true } + libraries: { type: Array, default: null } }, data () { return { diff --git a/front/src/components/moderation/ReportCategoryDropdown.vue b/front/src/components/moderation/ReportCategoryDropdown.vue index abab26b27663cb5a65bbd9544d2d6c9852753f9a..e15bc50d29a6976166f891f611e2c3b60ccb6a26 100644 --- a/front/src/components/moderation/ReportCategoryDropdown.vue +++ b/front/src/components/moderation/ReportCategoryDropdown.vue @@ -30,11 +30,11 @@ import lodash from '@/lodash' export default { mixins: [TranslationsMixin], props: { - value: { type: String, required: true }, - all: { type: String, required: true }, - label: { type: String, required: true }, - empty: { type: String, required: true }, - required: { type: String, required: true }, + value: { type: String, default: null }, + all: { type: String, default: null }, + label: { type: Boolean }, + empty: { type: Boolean }, + required: { type: Boolean }, restrictTo: { type: Array, default: () => { return [] } } }, computed: { diff --git a/front/src/components/notifications/NotificationRow.vue b/front/src/components/notifications/NotificationRow.vue index 3eaa16d965b1f151cfcf250a9875c759c550dc01..9668d5351a545ed36f8135f699556526203d31c3 100644 --- a/front/src/components/notifications/NotificationRow.vue +++ b/front/src/components/notifications/NotificationRow.vue @@ -107,7 +107,7 @@ export default { let acceptFollow = null let rejectFollow = null let message = null - if (a.related_object.approved === null) { + if (a.related_object && a.related_object.approved === null) { message = this.labels.libraryPendingFollowMessage acceptFollow = { buttonClass: 'success', @@ -121,7 +121,7 @@ export default { label: this.$pgettext('Content/*/Button.Label/Verb', 'Reject'), handler: () => { self.rejectLibraryFollow(a.related_object) } } - } else if (a.related_object.approved) { + } else if (a.related_object && a.related_object.approved) { message = this.labels.libraryFollowMessage } else { message = this.labels.libraryRejectMessage diff --git a/front/src/components/radios/Button.vue b/front/src/components/radios/Button.vue index 107ea38663f603d03be86f2d6c7d31db5bbc5572..d3cead016e92926998e20e935eda8d6a00cd9982 100644 --- a/front/src/components/radios/Button.vue +++ b/front/src/components/radios/Button.vue @@ -25,10 +25,10 @@ import lodash from '@/lodash' export default { props: { - customRadioId: { type: Number, default: 0, required: false }, + customRadioId: { type: Number, required: false, default: null }, type: { type: String, required: false, default: '' }, clientOnly: { type: Boolean, default: false }, - objectId: { type: String, default: null } + objectId: { type: [String, Number, Object], default: null } }, computed: { running () { diff --git a/front/src/components/radios/Card.vue b/front/src/components/radios/Card.vue index 9d5cd182b44347ac31b41aae46235edd795dded3..d71c7d0b24159e32592b5fdbde07a1fbe8c5df3b 100644 --- a/front/src/components/radios/Card.vue +++ b/front/src/components/radios/Card.vue @@ -53,11 +53,11 @@ export default { props: { type: { type: String, required: true, default: '' }, customRadio: { type: Object, required: false, default: () => { return {} } }, - objectId: { type: String, required: false, default: '' } + objectId: { type: String, required: false, default: null } }, computed: { radio () { - if (this.customRadio) { + if (Object.keys(this.customRadio).length > 0) { return this.customRadio } return this.$store.getters['radios/types'][this.type] diff --git a/front/src/views/Notifications.vue b/front/src/views/Notifications.vue index b97bedc71eb5f88ab382587fa89c6b810974f618..26bc12c3978cb90795b29ee0fd4810d00182e7e4 100644 --- a/front/src/views/Notifications.vue +++ b/front/src/views/Notifications.vue @@ -197,7 +197,7 @@ <notification-row v-for="item in notifications.results" :key="item.id" - :item="item" + :initial-item="item" /> </tbody> </table> diff --git a/front/src/views/content/remote/Card.vue b/front/src/views/content/remote/Card.vue index c66ed4d94005a8e616d265a0460bbee9cb9bef82..813ed48c0d3fecc97e806c02abbfb8c9837e104b 100644 --- a/front/src/views/content/remote/Card.vue +++ b/front/src/views/content/remote/Card.vue @@ -244,7 +244,7 @@ export default { isLoadingFollow: false, showScan: false, scanTimeout: null, - latestScan: this.library.latest_scan + latestScan: this.initialLibrary.latest_scan } }, computed: { diff --git a/front/src/views/library/DetailOverview.vue b/front/src/views/library/DetailOverview.vue index 14db9f12ada7fa5af0bc2a8bea5a4616bdc07700..d66984814406f5a057b09b1a12daf94aac772d22 100644 --- a/front/src/views/library/DetailOverview.vue +++ b/front/src/views/library/DetailOverview.vue @@ -46,7 +46,7 @@ export default { ArtistWidget }, props: { - object: { type: String, required: true }, + object: { type: Object, required: true }, isOwner: { type: Boolean, required: true } }, data () { diff --git a/front/src/views/playlists/Detail.vue b/front/src/views/playlists/Detail.vue index 272a0d535a57816be5e6d8d23d56ccb626d9420d..8cc6fa6d20fcad8741d73a2fa4c0d823b3538e8d 100644 --- a/front/src/views/playlists/Detail.vue +++ b/front/src/views/playlists/Detail.vue @@ -189,7 +189,7 @@ export default { EmbedWizard }, props: { - id: { type: Number, required: true }, + id: { type: [Number, String], required: true }, defaultEdit: { type: Boolean, default: false } }, data: function () {