From d3cc49d37ba260f9a285c078c57e673a32a76732 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 3 Nov 2021 13:04:45 +0100 Subject: [PATCH 01/12] Implement MySomethingList for social media, use list item slot --- .../MySomethingList/MySomethingList.spec.js | 187 +++++++++++++ .../MySomethingList/MySomethingList.vue | 261 ++++++++++++++++++ .../SocialMedia/SocialMediaListItem.spec.js | 37 +++ .../SocialMedia/SocialMediaListItem.vue | 18 ++ webapp/pages/settings/my-social-media.spec.js | 230 +++++++-------- webapp/pages/settings/my-social-media.vue | 237 +--------------- 6 files changed, 628 insertions(+), 342 deletions(-) create mode 100644 webapp/components/_new/features/MySomethingList/MySomethingList.spec.js create mode 100644 webapp/components/_new/features/MySomethingList/MySomethingList.vue create mode 100644 webapp/components/_new/features/SocialMedia/SocialMediaListItem.spec.js create mode 100644 webapp/components/_new/features/SocialMedia/SocialMediaListItem.vue diff --git a/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js b/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js new file mode 100644 index 000000000..7be290b3e --- /dev/null +++ b/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js @@ -0,0 +1,187 @@ +import { mount } from '@vue/test-utils' +import flushPromises from 'flush-promises' +import MySomethingList from './MySomethingList.vue' +import Vuex from 'vuex' +import Vue from 'vue' + +const localVue = global.localVue + +describe('MySomethingList.vue', () => { + let wrapper + let mocks + let getters + const socialMediaUrl = 'https://freeradical.zone/@mattwr18' + const newSocialMediaUrl = 'https://twitter.com/mattwr18' + + beforeEach(() => { + mocks = { + $t: jest.fn(), + $apollo: { + mutate: jest.fn(), + }, + $toast: { + error: jest.fn(), + success: jest.fn(), + }, + } + getters = { + 'auth/user': () => { + return {} + }, + } + }) + + describe('mount', () => { + let form, input, slots, submitButton + const Wrapper = () => { + const store = new Vuex.Store({ + getters, + }) + slots = { 'list-item': '
' } + return mount(MySomethingList, { store, mocks, localVue, slots }) + } + + describe('adding social media link', () => { + beforeEach(() => { + wrapper = Wrapper() + form = wrapper.find('form') + input = wrapper.find('input#addSocialMedia') + submitButton = wrapper.find('button') + }) + + it('requires the link to be a valid url', async () => { + input.setValue('some value') + form.trigger('submit') + await Vue.nextTick() + expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + }) + + it('displays an error message when not saved successfully', async () => { + mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) + input.setValue(newSocialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + await flushPromises() + expect(mocks.$toast.error).toHaveBeenCalledTimes(1) + }) + + describe('success', () => { + beforeEach(async () => { + mocks.$apollo.mutate.mockResolvedValue({ + data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, + }) + input.setValue(newSocialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + }) + + it('sends the new url to the backend', () => { + const expected = expect.objectContaining({ + variables: { url: newSocialMediaUrl }, + }) + + expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + }) + + it('displays a success message', async () => { + await flushPromises() + expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + }) + + it('clears the form', async () => { + await flushPromises() + expect(input.value).toBe(undefined) + expect(submitButton.vm.$attrs.disabled).toBe(true) + }) + }) + }) + + describe('given existing social media links', () => { + beforeEach(() => { + getters = { + 'auth/user': () => ({ + socialMedia: [{ id: 's1', url: socialMediaUrl }], + }), + } + + wrapper = Wrapper() + form = wrapper.find('form') + }) + + describe('for each item it', () => { + it('displays the item as slot "list-item"', () => { + expect(wrapper.find('.list-item').exists()).toBe(true) + }) + + it('displays the edit button', () => { + expect(wrapper.find('.base-button[data-test="edit-button"]').exists()).toBe(true) + }) + + it('displays the delete button', () => { + expect(wrapper.find('.base-button[data-test="delete-button"]').exists()).toBe(true) + }) + }) + + it('does not accept a duplicate url', async () => { + wrapper.find('input#addSocialMedia').setValue(socialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + }) + + describe('editing social media link', () => { + beforeEach(async () => { + const editButton = wrapper.find('.base-button[data-test="edit-button"]') + editButton.trigger('click') + await Vue.nextTick() + input = wrapper.find('input#editSocialMedia') + }) + + it('disables adding new links while editing', () => { + const addInput = wrapper.find('input#addSocialMedia') + + expect(addInput.exists()).toBe(false) + }) + + it('sends the new url to the backend', async () => { + const expected = expect.objectContaining({ + variables: { id: 's1', url: newSocialMediaUrl }, + }) + input.setValue(newSocialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + }) + + it('allows the user to cancel editing', async () => { + const cancelButton = wrapper.find('button#cancel') + cancelButton.trigger('click') + await Vue.nextTick() + expect(wrapper.find('input#editSocialMedia').exists()).toBe(false) + }) + }) + + describe('deleting social media link', () => { + beforeEach(async () => { + const deleteButton = wrapper.find('.base-button[data-test="delete-button"]') + deleteButton.trigger('click') + await Vue.nextTick() + }) + + it('sends the link id to the backend', () => { + const expected = expect.objectContaining({ + variables: { id: 's1' }, + }) + + expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1) + expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + }) + + it('displays a success message', async () => { + await flushPromises() + expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + }) + }) + }) + }) +}) diff --git a/webapp/components/_new/features/MySomethingList/MySomethingList.vue b/webapp/components/_new/features/MySomethingList/MySomethingList.vue new file mode 100644 index 000000000..ef374066a --- /dev/null +++ b/webapp/components/_new/features/MySomethingList/MySomethingList.vue @@ -0,0 +1,261 @@ + + + + + diff --git a/webapp/components/_new/features/SocialMedia/SocialMediaListItem.spec.js b/webapp/components/_new/features/SocialMedia/SocialMediaListItem.spec.js new file mode 100644 index 000000000..fca686dae --- /dev/null +++ b/webapp/components/_new/features/SocialMedia/SocialMediaListItem.spec.js @@ -0,0 +1,37 @@ +import { shallowMount } from '@vue/test-utils' +import SocialMediaListItem from './SocialMediaListItem.vue' + +describe('SocialMediaListItem.vue', () => { + let wrapper + let propsData + const socialMediaUrl = 'https://freeradical.zone/@mattwr18' + const faviconUrl = 'https://freeradical.zone/favicon.ico' + + beforeEach(() => { + propsData = {} + }) + + describe('shallowMount', () => { + const Wrapper = () => { + return shallowMount(SocialMediaListItem, { propsData }) + } + + describe('given existing social media links', () => { + beforeEach(() => { + propsData = { link: { id: 's1', url: socialMediaUrl, favicon: faviconUrl } } + + wrapper = Wrapper() + }) + + describe('for each link it', () => { + it('displays the favicon', () => { + expect(wrapper.find(`img[src="${faviconUrl}"]`).exists()).toBe(true) + }) + + it('displays the url', () => { + expect(wrapper.find(`a[href="${socialMediaUrl}"]`).exists()).toBe(true) + }) + }) + }) + }) +}) diff --git a/webapp/components/_new/features/SocialMedia/SocialMediaListItem.vue b/webapp/components/_new/features/SocialMedia/SocialMediaListItem.vue new file mode 100644 index 000000000..0f807fdcd --- /dev/null +++ b/webapp/components/_new/features/SocialMedia/SocialMediaListItem.vue @@ -0,0 +1,18 @@ + + + diff --git a/webapp/pages/settings/my-social-media.spec.js b/webapp/pages/settings/my-social-media.spec.js index 1aadbb750..13b507049 100644 --- a/webapp/pages/settings/my-social-media.spec.js +++ b/webapp/pages/settings/my-social-media.spec.js @@ -1,5 +1,5 @@ import { mount } from '@vue/test-utils' -import flushPromises from 'flush-promises' +// import flushPromises from 'flush-promises' import MySocialMedia from './my-social-media.vue' import Vuex from 'vuex' import Vue from 'vue' @@ -11,19 +11,19 @@ describe('my-social-media.vue', () => { let mocks let getters const socialMediaUrl = 'https://freeradical.zone/@mattwr18' - const newSocialMediaUrl = 'https://twitter.com/mattwr18' + // const newSocialMediaUrl = 'https://twitter.com/mattwr18' const faviconUrl = 'https://freeradical.zone/favicon.ico' beforeEach(() => { mocks = { $t: jest.fn(), - $apollo: { - mutate: jest.fn(), - }, - $toast: { - error: jest.fn(), - success: jest.fn(), - }, + // $apollo: { + // mutate: jest.fn(), + // }, + // $toast: { + // error: jest.fn(), + // success: jest.fn(), + // }, } getters = { 'auth/user': () => { @@ -33,7 +33,7 @@ describe('my-social-media.vue', () => { }) describe('mount', () => { - let form, input, submitButton + // let form, input, submitButton const Wrapper = () => { const store = new Vuex.Store({ getters, @@ -41,60 +41,60 @@ describe('my-social-media.vue', () => { return mount(MySocialMedia, { store, mocks, localVue }) } - describe('adding social media link', () => { - beforeEach(() => { - wrapper = Wrapper() - form = wrapper.find('form') - input = wrapper.find('input#addSocialMedia') - submitButton = wrapper.find('button') - }) + // describe('adding social media link', () => { + // beforeEach(() => { + // wrapper = Wrapper() + // form = wrapper.find('form') + // input = wrapper.find('input#addSocialMedia') + // submitButton = wrapper.find('button') + // }) - it('requires the link to be a valid url', async () => { - input.setValue('some value') - form.trigger('submit') - await Vue.nextTick() - expect(mocks.$apollo.mutate).not.toHaveBeenCalled() - }) + // it('requires the link to be a valid url', async () => { + // input.setValue('some value') + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + // }) - it('displays an error message when not saved successfully', async () => { - mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) - input.setValue(newSocialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - await flushPromises() - expect(mocks.$toast.error).toHaveBeenCalledTimes(1) - }) + // it('displays an error message when not saved successfully', async () => { + // mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // await flushPromises() + // expect(mocks.$toast.error).toHaveBeenCalledTimes(1) + // }) - describe('success', () => { - beforeEach(async () => { - mocks.$apollo.mutate.mockResolvedValue({ - data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, - }) - input.setValue(newSocialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - }) + // describe('success', () => { + // beforeEach(async () => { + // mocks.$apollo.mutate.mockResolvedValue({ + // data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, + // }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // }) - it('sends the new url to the backend', () => { - const expected = expect.objectContaining({ - variables: { url: newSocialMediaUrl }, - }) + // it('sends the new url to the backend', () => { + // const expected = expect.objectContaining({ + // variables: { url: newSocialMediaUrl }, + // }) - expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - }) + // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + // }) - it('displays a success message', async () => { - await flushPromises() - expect(mocks.$toast.success).toHaveBeenCalledTimes(1) - }) + // it('displays a success message', async () => { + // await flushPromises() + // expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + // }) - it('clears the form', async () => { - await flushPromises() - expect(input.value).toBe(undefined) - expect(submitButton.vm.$attrs.disabled).toBe(true) - }) - }) - }) + // it('clears the form', async () => { + // await flushPromises() + // expect(input.value).toBe(undefined) + // expect(submitButton.vm.$attrs.disabled).toBe(true) + // }) + // }) + // }) describe('given existing social media links', () => { beforeEach(() => { @@ -105,7 +105,7 @@ describe('my-social-media.vue', () => { } wrapper = Wrapper() - form = wrapper.find('form') + // form = wrapper.find('form') }) describe('for each link it', () => { @@ -117,75 +117,75 @@ describe('my-social-media.vue', () => { expect(wrapper.find(`a[href="${socialMediaUrl}"]`).exists()).toBe(true) }) - it('displays the edit button', () => { - expect(wrapper.find('.base-button[data-test="edit-button"]').exists()).toBe(true) - }) + // it('displays the edit button', () => { + // expect(wrapper.find('.base-button[data-test="edit-button"]').exists()).toBe(true) + // }) - it('displays the delete button', () => { - expect(wrapper.find('.base-button[data-test="delete-button"]').exists()).toBe(true) - }) + // it('displays the delete button', () => { + // expect(wrapper.find('.base-button[data-test="delete-button"]').exists()).toBe(true) + // }) }) - it('does not accept a duplicate url', async () => { - wrapper.find('input#addSocialMedia').setValue(socialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - expect(mocks.$apollo.mutate).not.toHaveBeenCalled() - }) + // it('does not accept a duplicate url', async () => { + // wrapper.find('input#addSocialMedia').setValue(socialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + // }) - describe('editing social media link', () => { - beforeEach(async () => { - const editButton = wrapper.find('.base-button[data-test="edit-button"]') - editButton.trigger('click') - await Vue.nextTick() - input = wrapper.find('input#editSocialMedia') - }) + // describe('editing social media link', () => { + // beforeEach(async () => { + // const editButton = wrapper.find('.base-button[data-test="edit-button"]') + // editButton.trigger('click') + // await Vue.nextTick() + // input = wrapper.find('input#editSocialMedia') + // }) - it('disables adding new links while editing', () => { - const addInput = wrapper.find('input#addSocialMedia') + // it('disables adding new links while editing', () => { + // const addInput = wrapper.find('input#addSocialMedia') - expect(addInput.exists()).toBe(false) - }) + // expect(addInput.exists()).toBe(false) + // }) - it('sends the new url to the backend', async () => { - const expected = expect.objectContaining({ - variables: { id: 's1', url: newSocialMediaUrl }, - }) - input.setValue(newSocialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - }) + // it('sends the new url to the backend', async () => { + // const expected = expect.objectContaining({ + // variables: { id: 's1', url: newSocialMediaUrl }, + // }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + // }) - it('allows the user to cancel editing', async () => { - const cancelButton = wrapper.find('button#cancel') - cancelButton.trigger('click') - await Vue.nextTick() - expect(wrapper.find('input#editSocialMedia').exists()).toBe(false) - }) - }) + // it('allows the user to cancel editing', async () => { + // const cancelButton = wrapper.find('button#cancel') + // cancelButton.trigger('click') + // await Vue.nextTick() + // expect(wrapper.find('input#editSocialMedia').exists()).toBe(false) + // }) + // }) - describe('deleting social media link', () => { - beforeEach(async () => { - const deleteButton = wrapper.find('.base-button[data-test="delete-button"]') - deleteButton.trigger('click') - await Vue.nextTick() - }) + // describe('deleting social media link', () => { + // beforeEach(async () => { + // const deleteButton = wrapper.find('.base-button[data-test="delete-button"]') + // deleteButton.trigger('click') + // await Vue.nextTick() + // }) - it('sends the link id to the backend', () => { - const expected = expect.objectContaining({ - variables: { id: 's1' }, - }) + // it('sends the link id to the backend', () => { + // const expected = expect.objectContaining({ + // variables: { id: 's1' }, + // }) - expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1) - expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - }) + // expect(mocks.$apollo.mutate).toHaveBeenCalledTimes(1) + // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + // }) - it('displays a success message', async () => { - await flushPromises() - expect(mocks.$toast.success).toHaveBeenCalledTimes(1) - }) - }) + // it('displays a success message', async () => { + // await flushPromises() + // expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + // }) + // }) }) }) }) diff --git a/webapp/pages/settings/my-social-media.vue b/webapp/pages/settings/my-social-media.vue index 5753fc405..57220ce17 100644 --- a/webapp/pages/settings/my-social-media.vue +++ b/webapp/pages/settings/my-social-media.vue @@ -1,236 +1,19 @@ - - From 433c5fd8836b2bf3719ab7f97a5dd68dccf5d51c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Wed, 3 Nov 2021 13:55:11 +0100 Subject: [PATCH 02/12] Implement MySomethingList for social media, use edit-item slot - Pass formData and formSchema by properties. --- .../MySomethingList/MySomethingList.spec.js | 30 ++-- .../MySomethingList/MySomethingList.vue | 35 ++-- webapp/pages/settings/my-social-media.spec.js | 167 +++++++++--------- webapp/pages/settings/my-social-media.vue | 23 ++- 4 files changed, 145 insertions(+), 110 deletions(-) diff --git a/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js b/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js index 7be290b3e..ea19bce8c 100644 --- a/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js +++ b/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js @@ -49,12 +49,12 @@ describe('MySomethingList.vue', () => { submitButton = wrapper.find('button') }) - it('requires the link to be a valid url', async () => { - input.setValue('some value') - form.trigger('submit') - await Vue.nextTick() - expect(mocks.$apollo.mutate).not.toHaveBeenCalled() - }) + // Wolle it('requires the link to be a valid url', async () => { + // input.setValue('some value') + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + // }) it('displays an error message when not saved successfully', async () => { mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) @@ -143,15 +143,15 @@ describe('MySomethingList.vue', () => { expect(addInput.exists()).toBe(false) }) - it('sends the new url to the backend', async () => { - const expected = expect.objectContaining({ - variables: { id: 's1', url: newSocialMediaUrl }, - }) - input.setValue(newSocialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - }) + // Wolle remove? or test here abstract? it('sends the new url to the backend', async () => { + // const expected = expect.objectContaining({ + // variables: { id: 's1', url: newSocialMediaUrl }, + // }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + // }) it('allows the user to cancel editing', async () => { const cancelButton = wrapper.find('button#cancel') diff --git a/webapp/components/_new/features/MySomethingList/MySomethingList.vue b/webapp/components/_new/features/MySomethingList/MySomethingList.vue index ef374066a..55c9f0808 100644 --- a/webapp/components/_new/features/MySomethingList/MySomethingList.vue +++ b/webapp/components/_new/features/MySomethingList/MySomethingList.vue @@ -16,12 +16,13 @@ - + /> --> +
@@ -87,17 +88,29 @@ import { mapGetters, mapMutations } from 'vuex' export default { name: 'MySomethingList', + props: { + useFormData: { + type: Object, + default: () => ({}), + }, + useFormSchema: { + type: Object, + default: () => ({}), + }, + }, data() { return { - formData: { - socialMediaUrl: '', - }, - formSchema: { - socialMediaUrl: { - type: 'url', - message: this.$t('common.validations.url'), - }, - }, + // Wolle formData: { + // socialMediaUrl: '', + // }, + // formSchema: { + // socialMediaUrl: { + // type: 'url', + // message: this.$t('common.validations.url'), + // }, + // }, + formData: this.useFormData, + formSchema: this.useFormSchema, disabled: true, editingLink: {}, } diff --git a/webapp/pages/settings/my-social-media.spec.js b/webapp/pages/settings/my-social-media.spec.js index 13b507049..a9d7a15d0 100644 --- a/webapp/pages/settings/my-social-media.spec.js +++ b/webapp/pages/settings/my-social-media.spec.js @@ -11,19 +11,19 @@ describe('my-social-media.vue', () => { let mocks let getters const socialMediaUrl = 'https://freeradical.zone/@mattwr18' - // const newSocialMediaUrl = 'https://twitter.com/mattwr18' + const newSocialMediaUrl = 'https://twitter.com/mattwr18' const faviconUrl = 'https://freeradical.zone/favicon.ico' beforeEach(() => { mocks = { $t: jest.fn(), - // $apollo: { - // mutate: jest.fn(), - // }, - // $toast: { - // error: jest.fn(), - // success: jest.fn(), - // }, + $apollo: { + mutate: jest.fn(), + }, + $toast: { + error: jest.fn(), + success: jest.fn(), + }, } getters = { 'auth/user': () => { @@ -34,6 +34,7 @@ describe('my-social-media.vue', () => { describe('mount', () => { // let form, input, submitButton + let form, input const Wrapper = () => { const store = new Vuex.Store({ getters, @@ -41,60 +42,60 @@ describe('my-social-media.vue', () => { return mount(MySocialMedia, { store, mocks, localVue }) } - // describe('adding social media link', () => { - // beforeEach(() => { - // wrapper = Wrapper() - // form = wrapper.find('form') - // input = wrapper.find('input#addSocialMedia') - // submitButton = wrapper.find('button') - // }) + describe('adding social media link', () => { + beforeEach(() => { + wrapper = Wrapper() + form = wrapper.find('form') + input = wrapper.find('input#addSocialMedia') + // submitButton = wrapper.find('button') + }) - // it('requires the link to be a valid url', async () => { - // input.setValue('some value') - // form.trigger('submit') - // await Vue.nextTick() - // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() - // }) + it('requires the link to be a valid url', async () => { + input.setValue('some value') + form.trigger('submit') + await Vue.nextTick() + expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + }) - // it('displays an error message when not saved successfully', async () => { - // mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) - // input.setValue(newSocialMediaUrl) - // form.trigger('submit') - // await Vue.nextTick() - // await flushPromises() - // expect(mocks.$toast.error).toHaveBeenCalledTimes(1) - // }) + // it('displays an error message when not saved successfully', async () => { + // mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // await flushPromises() + // expect(mocks.$toast.error).toHaveBeenCalledTimes(1) + // }) - // describe('success', () => { - // beforeEach(async () => { - // mocks.$apollo.mutate.mockResolvedValue({ - // data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, - // }) - // input.setValue(newSocialMediaUrl) - // form.trigger('submit') - // await Vue.nextTick() - // }) + // describe('success', () => { + // beforeEach(async () => { + // mocks.$apollo.mutate.mockResolvedValue({ + // data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, + // }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // }) - // it('sends the new url to the backend', () => { - // const expected = expect.objectContaining({ - // variables: { url: newSocialMediaUrl }, - // }) + // it('sends the new url to the backend', () => { + // const expected = expect.objectContaining({ + // variables: { url: newSocialMediaUrl }, + // }) - // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - // }) + // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + // }) - // it('displays a success message', async () => { - // await flushPromises() - // expect(mocks.$toast.success).toHaveBeenCalledTimes(1) - // }) + // it('displays a success message', async () => { + // await flushPromises() + // expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + // }) - // it('clears the form', async () => { - // await flushPromises() - // expect(input.value).toBe(undefined) - // expect(submitButton.vm.$attrs.disabled).toBe(true) - // }) - // }) - // }) + // it('clears the form', async () => { + // await flushPromises() + // expect(input.value).toBe(undefined) + // expect(submitButton.vm.$attrs.disabled).toBe(true) + // }) + // }) + }) describe('given existing social media links', () => { beforeEach(() => { @@ -105,7 +106,7 @@ describe('my-social-media.vue', () => { } wrapper = Wrapper() - // form = wrapper.find('form') + form = wrapper.find('form') }) describe('for each link it', () => { @@ -133,37 +134,37 @@ describe('my-social-media.vue', () => { // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() // }) - // describe('editing social media link', () => { - // beforeEach(async () => { - // const editButton = wrapper.find('.base-button[data-test="edit-button"]') - // editButton.trigger('click') - // await Vue.nextTick() - // input = wrapper.find('input#editSocialMedia') - // }) + describe('editing social media link', () => { + beforeEach(async () => { + const editButton = wrapper.find('.base-button[data-test="edit-button"]') + editButton.trigger('click') + await Vue.nextTick() + input = wrapper.find('input#editSocialMedia') + }) - // it('disables adding new links while editing', () => { - // const addInput = wrapper.find('input#addSocialMedia') + // it('disables adding new links while editing', () => { + // const addInput = wrapper.find('input#addSocialMedia') - // expect(addInput.exists()).toBe(false) - // }) + // expect(addInput.exists()).toBe(false) + // }) - // it('sends the new url to the backend', async () => { - // const expected = expect.objectContaining({ - // variables: { id: 's1', url: newSocialMediaUrl }, - // }) - // input.setValue(newSocialMediaUrl) - // form.trigger('submit') - // await Vue.nextTick() - // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - // }) + it.only('sends the new url to the backend', async () => { + const expected = expect.objectContaining({ + variables: { id: 's1', url: newSocialMediaUrl }, + }) + input.setValue(newSocialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + }) - // it('allows the user to cancel editing', async () => { - // const cancelButton = wrapper.find('button#cancel') - // cancelButton.trigger('click') - // await Vue.nextTick() - // expect(wrapper.find('input#editSocialMedia').exists()).toBe(false) - // }) - // }) + // it('allows the user to cancel editing', async () => { + // const cancelButton = wrapper.find('button#cancel') + // cancelButton.trigger('click') + // await Vue.nextTick() + // expect(wrapper.find('input#editSocialMedia').exists()).toBe(false) + // }) + }) // describe('deleting social media link', () => { // beforeEach(async () => { diff --git a/webapp/pages/settings/my-social-media.vue b/webapp/pages/settings/my-social-media.vue index 57220ce17..9c2bacfd8 100644 --- a/webapp/pages/settings/my-social-media.vue +++ b/webapp/pages/settings/my-social-media.vue @@ -1,8 +1,16 @@ @@ -15,5 +23,18 @@ export default { MySomethingList, SocialMediaListItem, }, + data() { + return { + useFormData: { + socialMediaUrl: '', + }, + useFormSchema: { + socialMediaUrl: { + type: 'url', + message: this.$t('common.validations.url'), + }, + }, + } + }, } From 58464fd53ef6aab52af1c2477c2615648ad889e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Thu, 4 Nov 2021 18:55:36 +0100 Subject: [PATCH 03/12] Remove input addSocialMedia --- .../MySomethingList/MySomethingList.spec.js | 190 ++++++++++-------- .../MySomethingList/MySomethingList.vue | 137 ++++++++----- webapp/pages/settings/my-social-media.spec.js | 113 ++++++----- 3 files changed, 248 insertions(+), 192 deletions(-) diff --git a/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js b/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js index ea19bce8c..0cc99c467 100644 --- a/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js +++ b/webapp/components/_new/features/MySomethingList/MySomethingList.spec.js @@ -8,12 +8,16 @@ const localVue = global.localVue describe('MySomethingList.vue', () => { let wrapper + let data let mocks let getters const socialMediaUrl = 'https://freeradical.zone/@mattwr18' - const newSocialMediaUrl = 'https://twitter.com/mattwr18' + // const newSocialMediaUrl = 'https://twitter.com/mattwr18' beforeEach(() => { + data = () => { + return {} + } mocks = { $t: jest.fn(), $apollo: { @@ -32,69 +36,75 @@ describe('MySomethingList.vue', () => { }) describe('mount', () => { - let form, input, slots, submitButton + // Wolle let form, input, slots, submitButton + let slots const Wrapper = () => { const store = new Vuex.Store({ getters, }) slots = { 'list-item': '
' } - return mount(MySomethingList, { store, mocks, localVue, slots }) + return mount(MySomethingList, { data, store, mocks, localVue, slots }) } - describe('adding social media link', () => { - beforeEach(() => { - wrapper = Wrapper() - form = wrapper.find('form') - input = wrapper.find('input#addSocialMedia') - submitButton = wrapper.find('button') - }) + // describe('adding social media link', () => { + // beforeEach(async () => { + // wrapper = Wrapper() + // form = wrapper.find('form') + // form.trigger('submit') + // await Vue.nextTick() + // console.log(wrapper.html()) + // console.log('wrapper.vm.socialMediaLinks: ', wrapper.vm.socialMediaLinks) + // input = wrapper.find('input#editSocialMedia') + // console.log('input: ', input) + // submitButton = wrapper.find('button') + // }) - // Wolle it('requires the link to be a valid url', async () => { - // input.setValue('some value') - // form.trigger('submit') - // await Vue.nextTick() - // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() - // }) + // Wolle it('requires the link to be a valid url', async () => { + // input.setValue('some value') + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + // }) - it('displays an error message when not saved successfully', async () => { - mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) - input.setValue(newSocialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - await flushPromises() - expect(mocks.$toast.error).toHaveBeenCalledTimes(1) - }) + // Wolle it('displays an error message when not saved successfully', async () => { + // mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // await flushPromises() + // expect(mocks.$toast.error).toHaveBeenCalledTimes(1) + // }) - describe('success', () => { - beforeEach(async () => { - mocks.$apollo.mutate.mockResolvedValue({ - data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, - }) - input.setValue(newSocialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - }) + // describe('success', () => { + // beforeEach(async () => { + // mocks.$apollo.mutate.mockResolvedValue({ + // data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, + // }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // }) - it('sends the new url to the backend', () => { - const expected = expect.objectContaining({ - variables: { url: newSocialMediaUrl }, - }) + // it('sends the new url to the backend', () => { + // const expected = expect.objectContaining({ + // variables: { url: newSocialMediaUrl }, + // }) - expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - }) + // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + // }) - it('displays a success message', async () => { - await flushPromises() - expect(mocks.$toast.success).toHaveBeenCalledTimes(1) - }) + // it('displays a success message', async () => { + // await flushPromises() + // expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + // }) - it('clears the form', async () => { - await flushPromises() - expect(input.value).toBe(undefined) - expect(submitButton.vm.$attrs.disabled).toBe(true) - }) - }) - }) + // it('clears the form', async () => { + // await flushPromises() + // expect(input.value).toBe(undefined) + // expect(submitButton.vm.$attrs.disabled).toBe(true) + // }) + // }) + // }) describe('given existing social media links', () => { beforeEach(() => { @@ -103,9 +113,14 @@ describe('MySomethingList.vue', () => { socialMedia: [{ id: 's1', url: socialMediaUrl }], }), } - + // Wolle propsData = { editingLink: { id: 's1', url: socialMediaUrl } } + // data = () => { + // return { + // editingLink: { id: 's2', url: socialMediaUrl }, + // } + // } wrapper = Wrapper() - form = wrapper.find('form') + // form = wrapper.find('form') }) describe('for each item it', () => { @@ -122,44 +137,47 @@ describe('MySomethingList.vue', () => { }) }) - it('does not accept a duplicate url', async () => { - wrapper.find('input#addSocialMedia').setValue(socialMediaUrl) - form.trigger('submit') - await Vue.nextTick() - expect(mocks.$apollo.mutate).not.toHaveBeenCalled() - }) + // Wolle it('does not accept a duplicate url', async () => { + // // wrapper.find('input#addSocialMedia').setValue(socialMediaUrl) + // wrapper.find('input#editSocialMedia').setValue(socialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + // }) - describe('editing social media link', () => { - beforeEach(async () => { - const editButton = wrapper.find('.base-button[data-test="edit-button"]') - editButton.trigger('click') - await Vue.nextTick() - input = wrapper.find('input#editSocialMedia') - }) + // describe('editing social media link', () => { + // beforeEach(async () => { + // const editButton = wrapper.find('.base-button[data-test="edit-button"]') + // editButton.trigger('click') + // await Vue.nextTick() + // input = wrapper.find('input#editSocialMedia') + // }) - it('disables adding new links while editing', () => { - const addInput = wrapper.find('input#addSocialMedia') + // it('disables adding new links while editing', () => { + // const addInput = wrapper.find('input#addSocialMedia') + // wrapper.find('.base-button[data-test="add-save-button"]').text(). + // expect(addInput.exists()).toBe(false) + // const submitButton = wrapper.find('.base-button[data-test="add-save-button"]') + // expect(submitButton.text()).not.toContain('settings.social-media.submit') + // }) - expect(addInput.exists()).toBe(false) - }) + // Wolle remove? or test here abstract? it('sends the new url to the backend', async () => { + // const expected = expect.objectContaining({ + // variables: { id: 's1', url: newSocialMediaUrl }, + // }) + // input.setValue(newSocialMediaUrl) + // form.trigger('submit') + // await Vue.nextTick() + // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + // }) - // Wolle remove? or test here abstract? it('sends the new url to the backend', async () => { - // const expected = expect.objectContaining({ - // variables: { id: 's1', url: newSocialMediaUrl }, - // }) - // input.setValue(newSocialMediaUrl) - // form.trigger('submit') - // await Vue.nextTick() - // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - // }) - - it('allows the user to cancel editing', async () => { - const cancelButton = wrapper.find('button#cancel') - cancelButton.trigger('click') - await Vue.nextTick() - expect(wrapper.find('input#editSocialMedia').exists()).toBe(false) - }) - }) + // it('allows the user to cancel editing', async () => { + // const cancelButton = wrapper.find('button#cancel') + // cancelButton.trigger('click') + // await Vue.nextTick() + // expect(wrapper.find('input#editSocialMedia').exists()).toBe(false) + // }) + // }) describe('deleting social media link', () => { beforeEach(async () => { diff --git a/webapp/components/_new/features/MySomethingList/MySomethingList.vue b/webapp/components/_new/features/MySomethingList/MySomethingList.vue index 55c9f0808..944ac41f3 100644 --- a/webapp/components/_new/features/MySomethingList/MySomethingList.vue +++ b/webapp/components/_new/features/MySomethingList/MySomethingList.vue @@ -8,11 +8,15 @@ @input-valid="handleInputValid" @submit="handleSubmitSocialMedia" > -
+
- {{ /* $t('settings.social-media.name') */ 'Edit "' + editingLink.url + '"' }} + {{ + /* $t('settings.social-media.name') */ editingLink.id === '' + ? 'Add new one' + : 'Edit "' + editingLink.url + '"' + }} @@ -61,18 +65,23 @@
- + /> --> - - {{ editingLink.id ? $t('actions.save') : $t('settings.social-media.submit') }} + + {{ isEditing ? $t('actions.save') : $t('settings.social-media.submit') }} - + {{ $t('actions.cancel') }} @@ -112,13 +121,19 @@ export default { formData: this.useFormData, formSchema: this.useFormSchema, disabled: true, - editingLink: {}, + editingLink: null, } }, computed: { ...mapGetters({ currentUser: 'auth/user', }), + isEditing() { + return this.editingLink !== null + }, + isCreation() { + return this.editingLink !== null && this.editingLink.id === '' + }, socialMediaLinks() { const domainRegex = /^(?:https?:\/\/)?(?:[^@\n])?(?:www\.)?([^:/\n?]+)/g const { socialMedia = [] } = this.currentUser @@ -134,7 +149,7 @@ export default { setCurrentUser: 'auth/SET_USER', }), handleCancel() { - this.editingLink = {} + this.editingLink = null this.formData.socialMediaUrl = '' this.disabled = true }, @@ -183,57 +198,69 @@ export default { } }, async handleSubmitSocialMedia() { - const isEditing = !!this.editingLink.id - const url = this.formData.socialMediaUrl + // Wolle const isEditing = (this.editingLink !== null) + if (!this.isEditing) { + // Wolle this.editingLink = { id: '', url: '' } + this.handleEditSocialMedia({ id: '', url: '' }) + } else { + // Wolle const url = this.formData.socialMediaUrl + this.editingLink.url = this.formData.socialMediaUrl - const duplicateUrl = this.socialMediaLinks.find((link) => link.url === url) - if (duplicateUrl && duplicateUrl.id !== this.editingLink.id) { - return this.$toast.error(this.$t('settings.social-media.requireUnique')) - } - - let mutation = gql` - mutation($url: String!) { - CreateSocialMedia(url: $url) { - id - url - } + const duplicateUrl = this.socialMediaLinks.find((link) => link.url === this.editingLink.url) + // Wolle console.log('duplicateUrl: ', duplicateUrl) + // console.log('this.isEditing: ', this.isEditing) + // console.log('this.editingLink: ', this.editingLink) + if (duplicateUrl && this.isEditing && duplicateUrl.id !== this.editingLink.id) { + return this.$toast.error(this.$t('settings.social-media.requireUnique')) } - ` - const variables = { url } - let successMessage = this.$t('settings.social-media.successAdd') - if (isEditing) { - mutation = gql` - mutation($id: ID!, $url: String!) { - UpdateSocialMedia(id: $id, url: $url) { - id - url + let mutation, variables, successMessage + if (this.isCreation) { + mutation = gql` + mutation($url: String!) { + CreateSocialMedia(url: $url) { + id + url + } } - } - ` - variables.id = this.editingLink.id - successMessage = this.$t('settings.data.success') - } + ` + variables = { url: this.editingLink.url } + successMessage = this.$t('settings.social-media.successAdd') + } else { + mutation = gql` + mutation($id: ID!, $url: String!) { + UpdateSocialMedia(id: $id, url: $url) { + id + url + } + } + ` + variables = { id: this.editingLink.id, url: this.editingLink.url } + successMessage = this.$t('settings.data.success') + } - try { - await this.$apollo.mutate({ - mutation, - variables, - update: (store, { data }) => { - const newSocialMedia = isEditing ? data.UpdateSocialMedia : data.CreateSocialMedia - this.setCurrentUser({ - ...this.currentUser, - socialMedia: unionBy([newSocialMedia], this.currentUser.socialMedia, 'id'), - }) - }, - }) + try { + await this.$apollo.mutate({ + mutation, + variables, + update: (_store, { data }) => { + const newSocialMedia = !this.isCreation + ? data.UpdateSocialMedia + : data.CreateSocialMedia + this.setCurrentUser({ + ...this.currentUser, + socialMedia: unionBy([newSocialMedia], this.currentUser.socialMedia, 'id'), + }) + }, + }) - this.$toast.success(successMessage) - this.formData.socialMediaUrl = '' - this.disabled = true - this.editingLink = {} - } catch (err) { - this.$toast.error(err.message) + this.$toast.success(successMessage) + this.formData.socialMediaUrl = '' + this.disabled = true + this.editingLink = null + } catch (err) { + this.$toast.error(err.message) + } } }, }, diff --git a/webapp/pages/settings/my-social-media.spec.js b/webapp/pages/settings/my-social-media.spec.js index a9d7a15d0..2da42b1d3 100644 --- a/webapp/pages/settings/my-social-media.spec.js +++ b/webapp/pages/settings/my-social-media.spec.js @@ -1,5 +1,5 @@ import { mount } from '@vue/test-utils' -// import flushPromises from 'flush-promises' +import flushPromises from 'flush-promises' import MySocialMedia from './my-social-media.vue' import Vuex from 'vuex' import Vue from 'vue' @@ -33,7 +33,7 @@ describe('my-social-media.vue', () => { }) describe('mount', () => { - // let form, input, submitButton + // Wolle let form, input, submitButton let form, input const Wrapper = () => { const store = new Vuex.Store({ @@ -43,11 +43,13 @@ describe('my-social-media.vue', () => { } describe('adding social media link', () => { - beforeEach(() => { + beforeEach(async () => { wrapper = Wrapper() form = wrapper.find('form') - input = wrapper.find('input#addSocialMedia') - // submitButton = wrapper.find('button') + form.trigger('submit') + await Vue.nextTick() + input = wrapper.find('input#editSocialMedia') + // Wolle submitButton = wrapper.find('button') }) it('requires the link to be a valid url', async () => { @@ -57,44 +59,50 @@ describe('my-social-media.vue', () => { expect(mocks.$apollo.mutate).not.toHaveBeenCalled() }) - // it('displays an error message when not saved successfully', async () => { - // mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) - // input.setValue(newSocialMediaUrl) - // form.trigger('submit') - // await Vue.nextTick() - // await flushPromises() - // expect(mocks.$toast.error).toHaveBeenCalledTimes(1) - // }) + it('displays an error message when not saved successfully', async () => { + mocks.$apollo.mutate.mockRejectedValue({ message: 'Ouch!' }) + input.setValue(newSocialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + await flushPromises() + expect(mocks.$toast.error).toHaveBeenCalledTimes(1) + }) - // describe('success', () => { - // beforeEach(async () => { - // mocks.$apollo.mutate.mockResolvedValue({ - // data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, - // }) - // input.setValue(newSocialMediaUrl) - // form.trigger('submit') - // await Vue.nextTick() - // }) + describe('success', () => { + beforeEach(async () => { + mocks.$apollo.mutate.mockResolvedValue({ + data: { CreateSocialMedia: { id: 's2', url: newSocialMediaUrl } }, + }) + input.setValue(newSocialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + }) - // it('sends the new url to the backend', () => { - // const expected = expect.objectContaining({ - // variables: { url: newSocialMediaUrl }, - // }) + it('sends the new url to the backend', () => { + const expected = expect.objectContaining({ + variables: { url: newSocialMediaUrl }, + }) + expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) + }) - // expect(mocks.$apollo.mutate).toHaveBeenCalledWith(expected) - // }) + it('displays a success message', async () => { + await flushPromises() + expect(mocks.$toast.success).toHaveBeenCalledTimes(1) + }) - // it('displays a success message', async () => { - // await flushPromises() - // expect(mocks.$toast.success).toHaveBeenCalledTimes(1) - // }) - - // it('clears the form', async () => { - // await flushPromises() - // expect(input.value).toBe(undefined) - // expect(submitButton.vm.$attrs.disabled).toBe(true) - // }) - // }) + // Wolle it('clears the form', async () => { + // await flushPromises() + // expect(input.value).toBe(undefined) + // expect(submitButton.vm.$attrs.disabled).toBe(true) + // }) + it('switches back to list', async () => { + await flushPromises() + // Wolle expect(input.value).toBe(undefined) + // expect(submitButton.vm.$attrs.disabled).toBe(true) + const submitButton = wrapper.find('.base-button[data-test="add-save-button"]') + expect(submitButton.text()).not.toContain('settings.social-media.submit') + }) + }) }) describe('given existing social media links', () => { @@ -127,12 +135,14 @@ describe('my-social-media.vue', () => { // }) }) - // it('does not accept a duplicate url', async () => { - // wrapper.find('input#addSocialMedia').setValue(socialMediaUrl) - // form.trigger('submit') - // await Vue.nextTick() - // expect(mocks.$apollo.mutate).not.toHaveBeenCalled() - // }) + it('does not accept a duplicate url', async () => { + form.trigger('submit') + await Vue.nextTick() + wrapper.find('input#editSocialMedia').setValue(socialMediaUrl) + form.trigger('submit') + await Vue.nextTick() + expect(mocks.$apollo.mutate).not.toHaveBeenCalled() + }) describe('editing social media link', () => { beforeEach(async () => { @@ -142,13 +152,14 @@ describe('my-social-media.vue', () => { input = wrapper.find('input#editSocialMedia') }) - // it('disables adding new links while editing', () => { - // const addInput = wrapper.find('input#addSocialMedia') + it('disables adding new links while editing', () => { + // Wolle const addInput = wrapper.find('input#addSocialMedia') + // expect(addInput.exists()).toBe(false) + const submitButton = wrapper.find('.base-button[data-test="add-save-button"]') + expect(submitButton.text()).not.toContain('settings.social-media.submit') + }) - // expect(addInput.exists()).toBe(false) - // }) - - it.only('sends the new url to the backend', async () => { + it('sends the new url to the backend', async () => { const expected = expect.objectContaining({ variables: { id: 's1', url: newSocialMediaUrl }, }) From 280f0f5a786b8efca6fccf3a83a37d313fbf371b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wolfgang=20Hu=C3=9F?= Date: Mon, 8 Nov 2021 13:59:26 +0100 Subject: [PATCH 04/12] Implement edit callback, fist step --- .../MySomethingList/MySomethingList.vue | 8 +++++++- webapp/pages/settings/my-social-media.vue | 19 ++++++++++++++++++- 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/webapp/components/_new/features/MySomethingList/MySomethingList.vue b/webapp/components/_new/features/MySomethingList/MySomethingList.vue index 944ac41f3..1017d3bd1 100644 --- a/webapp/components/_new/features/MySomethingList/MySomethingList.vue +++ b/webapp/components/_new/features/MySomethingList/MySomethingList.vue @@ -106,6 +106,10 @@ export default { type: Object, default: () => ({}), }, + callbackEdit: { + type: Function, + default: () => {}, + }, }, data() { return { @@ -155,7 +159,9 @@ export default { }, handleEditSocialMedia(link) { this.editingLink = link - this.formData.socialMediaUrl = link.url + // Wolle this.formData.socialMediaUrl = link.url + // Wolle this.$refs.socialMediaUrl.$el.focus() + this.callbackEdit(this, link) }, handleInput(data) { this.disabled = true diff --git a/webapp/pages/settings/my-social-media.vue b/webapp/pages/settings/my-social-media.vue index 9c2bacfd8..510bba55f 100644 --- a/webapp/pages/settings/my-social-media.vue +++ b/webapp/pages/settings/my-social-media.vue @@ -1,5 +1,9 @@