diff --git a/resources/js/components/ui/Listing/Listing.vue b/resources/js/components/ui/Listing/Listing.vue index 4b28f6a27c8..fd6ae070cd7 100644 --- a/resources/js/components/ui/Listing/Listing.vue +++ b/resources/js/components/ui/Listing/Listing.vue @@ -420,7 +420,7 @@ function request() { signal: source.signal, }) .then((response) => { - setColumns(response.data.meta.columns); + if (response.data.meta.columns) setColumns(response.data.meta.columns); activeFilterBadges.value = { ...response.data.meta.activeFilterBadges }; items.value = Object.values(response.data.data); meta.value = response.data.meta; diff --git a/resources/js/tests/components/Listing.test.js b/resources/js/tests/components/Listing.test.js index 0176fcdda57..e7f2989db6a 100644 --- a/resources/js/tests/components/Listing.test.js +++ b/resources/js/tests/components/Listing.test.js @@ -103,6 +103,30 @@ test('exposes select-all-matching helpers on the listing context', () => { expect(typeof listing.selectAllMatching).toBe('function'); }); +test('keeps the columns prop when the response has no columns', async () => { + axios.get.mockResolvedValue({ + data: { + data: [{ id: '1', email: 'foo@example.com' }], + meta: { last_page: 1, total: 1, per_page: 50 }, + }, + }); + + const wrapper = mountListing({ + url: '/cp/subscribers', + items: undefined, + columns: [{ field: 'email', label: 'Email', sortable: true, visible: true }], + }); + + await flushPromises(); + + const { listing } = wrapper.findComponent(Probe).vm; + + listing.setSortColumn('email'); + + expect(listing.columns.value.map((column) => column.field)).toEqual(['email']); + expect(listing.sortColumn.value).toBe('email'); +}); + test('canSelectAllMatching can be disabled via allowSelectAllMatching', async () => { axios.get.mockResolvedValue({ data: {