From 31492ccc5493f5857903a7cc490424cd35d8318c Mon Sep 17 00:00:00 2001 From: skjnldsv Date: Thu, 3 Jul 2025 11:37:46 +0200 Subject: [PATCH] feat(navigation): allow updating views Signed-off-by: skjnldsv --- __tests__/view.spec.ts | 50 +++++++++++++++++++++++++++++++++++++++++- lib/navigation/view.ts | 18 +++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/__tests__/view.spec.ts b/__tests__/view.spec.ts index b63483235..fd37d0c4d 100644 --- a/__tests__/view.spec.ts +++ b/__tests__/view.spec.ts @@ -3,10 +3,11 @@ * SPDX-License-Identifier: AGPL-3.0-or-later */ -import { describe, expect, test } from 'vitest' +import { describe, expect, test, vi } from 'vitest' import { View } from '../lib/navigation/view.ts' import { Folder } from '../lib/index.ts' +import { subscribe } from '@nextcloud/event-bus' describe('Invalid View creation', () => { test('Invalid id', () => { @@ -201,3 +202,50 @@ describe('View creation', () => { await expect(view.loadChildViews?.({} as unknown as View)).resolves.toBe(undefined) }) }) + +describe('View update', () => { + test('Update a View', () => { + const view = new View({ + id: 'test', + name: 'Test', + caption: 'Test caption', + emptyTitle: 'Test empty title', + emptyCaption: 'Test empty caption', + getContents: () => Promise.reject(new Error()), + hidden: true, + icon: '', + order: 1, + params: {}, + columns: [], + emptyView: () => {}, + parent: 'parent', + sticky: false, + expanded: false, + defaultSortKey: 'key', + loadChildViews: async () => {}, + }) + + const spy = vi.fn() + subscribe('files:view:updated', spy) + + view.update({ + name: 'Updated Test', + order: 2, + icon: 'updated', + caption: 'Updated caption', + emptyTitle: 'Updated empty title', + emptyCaption: 'Updated empty caption', + }) + + expect(view.name).toBe('Updated Test') + expect(view.order).toBe(2) + expect(view.icon).toBe('updated') + expect(view.caption).toBe('Updated caption') + expect(view.emptyTitle).toBe('Updated empty title') + expect(view.emptyCaption).toBe('Updated empty caption') + + expect(() => view.update({ id: 'new-id' })).toThrowError('The view ID is immutable and cannot be changed after creation') + + expect(spy).toHaveBeenCalledOnce() + }) +}) diff --git a/lib/navigation/view.ts b/lib/navigation/view.ts index cbdb1bd5f..ac45fe758 100644 --- a/lib/navigation/view.ts +++ b/lib/navigation/view.ts @@ -7,6 +7,7 @@ import type { Node } from '../files/node' import isSvg from 'is-svg' import { Column } from './column.js' +import { emit } from '@nextcloud/event-bus' export type ContentsWithRoot = { folder: Folder, @@ -181,6 +182,23 @@ export class View implements ViewData { return this._view.loadChildViews } + /** + * Allows to update the view data. + * This will throw an error if the view is not valid. + * Warning: the view ID is immutable and cannot be changed after creation. + * @param {Partial} view the view data to update + */ + update(view: Partial) { + if (view.id && view.id !== this._view.id) { + throw new Error('The view ID is immutable and cannot be changed after creation') + } + + isValidView({ ...this._view, ...view }) + Object.assign(this._view, view) + + emit('files:view:updated', this) + } + } /**