From 45142bf24b72825621c9a3f2bb9f82c85d8bc9dc Mon Sep 17 00:00:00 2001 From: Eliot Berriot <contact@eliotberriot.com> Date: Tue, 9 Apr 2019 11:03:45 +0200 Subject: [PATCH] Added better dropdown for choosing licenses --- api/funkwhale_api/common/mutations.py | 6 +++- api/tests/music/test_mutations.py | 12 ++++++++ front/src/components/library/EditForm.vue | 35 ++++++++++++++++++++-- front/src/components/library/TrackEdit.vue | 24 +++++++++++++-- front/src/edits.js | 4 +-- 5 files changed, 74 insertions(+), 7 deletions(-) diff --git a/api/funkwhale_api/common/mutations.py b/api/funkwhale_api/common/mutations.py index 25abaede..c3e92c15 100644 --- a/api/funkwhale_api/common/mutations.py +++ b/api/funkwhale_api/common/mutations.py @@ -115,9 +115,13 @@ class UpdateMutationSerializer(serializers.ModelSerializer, MutationSerializer): # payload for field, attr in self.serialized_relations.items(): try: - data[field] = getattr(data[field], attr) + obj = data[field] except KeyError: continue + if obj is None: + data[field] = None + else: + data[field] = getattr(obj, attr) return data def create(self, validated_data): diff --git a/api/tests/music/test_mutations.py b/api/tests/music/test_mutations.py index d6b8223d..062d00f9 100644 --- a/api/tests/music/test_mutations.py +++ b/api/tests/music/test_mutations.py @@ -13,6 +13,18 @@ def test_track_license_mutation(factories, now): assert track.license.code == "cc-by-sa-4.0" +def test_track_null_license_mutation(factories, now): + track = factories["music.Track"](license="cc-by-sa-4.0") + mutation = factories["common.Mutation"]( + type="update", target=track, payload={"license": None} + ) + licenses.load(licenses.LICENSES) + mutation.apply() + track.refresh_from_db() + + assert track.license is None + + def test_track_title_mutation(factories, now): track = factories["music.Track"](title="foo") mutation = factories["common.Mutation"]( diff --git a/front/src/components/library/EditForm.vue b/front/src/components/library/EditForm.vue index 00010811..a2df96c0 100644 --- a/front/src/components/library/EditForm.vue +++ b/front/src/components/library/EditForm.vue @@ -59,10 +59,28 @@ <label :for="fieldConfig.id">{{ fieldConfig.label }}</label> <input :type="fieldConfig.inputType || 'text'" v-model="values[fieldConfig.id]" :required="fieldConfig.required" :name="fieldConfig.id" :id="fieldConfig.id"> </template> + <template v-else-if="fieldConfig.type === 'license'"> + <label :for="fieldConfig.id">{{ fieldConfig.label }}</label> + + <select + ref="license" + v-model="values[fieldConfig.id]" + :required="fieldConfig.required" + :id="fieldConfig.id" + class="ui fluid search dropdown"> + <option :value="null"><translate translate-context="*/*/*">N/A</translate></option> + <option v-for="license in licenses" :key="license.code" :value="license.code">{{ license.name}}</option> + </select> + <button class="ui tiny basic left floated button" form="noop" @click.prevent="values[fieldConfig.id] = null"> + <i class="x icon"></i> + <translate translate-context="Content/Library/Button.Label">Clear</translate> + </button> + + </template> <div v-if="values[fieldConfig.id] != initialValues[fieldConfig.id]"> <button class="ui tiny basic right floated reset button" form="noop" @click.prevent="values[fieldConfig.id] = initialValues[fieldConfig.id]"> <i class="undo icon"></i> - <translate translate-context="Content/Library/Button.Label" :translate-params="{value: initialValues[fieldConfig.id]}">Reset to initial value: %{ value }</translate> + <translate translate-context="Content/Library/Button.Label" :translate-params="{value: initialValues[fieldConfig.id] || ''}">Reset to initial value: %{ value }</translate> </button> </div> </div> @@ -87,6 +105,7 @@ </template> <script> +import $ from 'jquery' import _ from '@/lodash' import axios from "axios" import EditList from '@/components/library/EditList' @@ -94,7 +113,7 @@ import EditCard from '@/components/library/EditCard' import edits from '@/edits' export default { - props: ["objectType", "object"], + props: ["objectType", "object", "licenses"], components: { EditList, EditCard @@ -113,6 +132,9 @@ export default { created () { this.setValues() }, + mounted() { + $(".ui.dropdown").dropdown({fullTextSearch: true}) + }, computed: { configs: edits.getConfigs, config: edits.getConfig, @@ -182,6 +204,15 @@ export default { } ) } + }, + watch: { + 'values.license' (newValue) { + if (newValue === null) { + $(this.$refs.license).dropdown('clear') + } else { + $(this.$refs.license).dropdown('set selected', newValue) + } + } } } </script> diff --git a/front/src/components/library/TrackEdit.vue b/front/src/components/library/TrackEdit.vue index 7e26d1df..32b3a627 100644 --- a/front/src/components/library/TrackEdit.vue +++ b/front/src/components/library/TrackEdit.vue @@ -6,7 +6,12 @@ <translate v-if="canEdit" key="1" translate-context="Content/*/Title">Edit this track</translate> <translate v-else key="2" translate-context="Content/*/Title">Suggest an edit on this track</translate> </h2> - <edit-form :object-type="objectType" :object="object" :can-edit="canEdit"></edit-form> + <edit-form + v-if="!isLoadingLicenses" + :object-type="objectType" + :object="object" + :can-edit="canEdit" + :licenses="licenses"></edit-form> </div> </section> </template> @@ -19,12 +24,27 @@ export default { props: ["objectType", "object", "libraries"], data() { return { - id: this.object.id + id: this.object.id, + isLoadingLicenses: false, + licenses: [] } }, components: { EditForm }, + created () { + this.fetchLicenses() + }, + methods: { + fetchLicenses () { + let self = this + self.isLoadingLicenses = true + axios.get('licenses/').then((response) => { + self.isLoadingLicenses = false + self.licenses = response.data.results + }) + } + }, computed: { canEdit () { return true diff --git a/front/src/edits.js b/front/src/edits.js index ccc9c16b..4e6a85c7 100644 --- a/front/src/edits.js +++ b/front/src/edits.js @@ -12,10 +12,10 @@ export default { }, { id: 'license', - type: 'text', + type: 'license', required: false, label: this.$pgettext('Content/*/*/Noun', 'License'), - getValue: (obj) => { return obj.license } + getValue: (obj) => { return obj.license }, }, { id: 'position', -- GitLab