chore: track external changes when displaying configuration values

fixes https://github.com/containers/podman-desktop/issues/8794
Signed-off-by: Florent Benoit <fbenoit@redhat.com>
This commit is contained in:
Florent Benoit 2024-09-07 18:34:00 +02:00 committed by Florent BENOIT
parent 21b67f930d
commit b5f0c7dd50
2 changed files with 64 additions and 1 deletions

View file

@ -28,6 +28,7 @@ import { tick } from 'svelte';
import { beforeAll, expect, test, vi } from 'vitest';
import { getInitialValue } from '/@/lib/preferences/Util';
import { onDidChangeConfiguration } from '/@/stores/configurationProperties';
import type { IConfigurationPropertyRecordedSchema } from '../../../../main/src/plugin/configuration-registry';
import PreferencesRenderingItemFormat from './PreferencesRenderingItemFormat.svelte';
@ -290,3 +291,41 @@ test('Expect a text input when record is type integer', async () => {
expect(inputField.type).toBe('text');
expect(inputField.name).toBe('record');
});
test('Expect value is updated from an external change', async () => {
const recordId = 'record';
const record: IConfigurationPropertyRecordedSchema = {
id: recordId,
title: 'Hello',
parentId: 'parent.record',
description: 'record-description',
type: 'integer',
scope: 'DEFAULT',
default: 1,
minimum: 1,
maximum: 15,
};
await awaitRender(record, {});
const inputField = screen.getByRole('textbox', { name: 'record-description' }) as HTMLInputElement;
expect(inputField).toBeInTheDocument();
// initial value should be 1
expect(inputField.value).toBe('1');
// change getConfigurationValue to return 5
(window as any).getConfigurationValue = vi.fn().mockResolvedValue(5);
// now update the configuration value
onDidChangeConfiguration.dispatchEvent(
new CustomEvent(recordId, {
detail: {
key: 'record',
value: 5,
},
}),
);
// initial value should be 5
await vi.waitFor(() => expect(inputField.value).toBe('5'));
});

View file

@ -1,5 +1,6 @@
<script lang="ts">
import { ErrorMessage } from '@podman-desktop/ui-svelte';
import { onDestroy, onMount } from 'svelte';
import BooleanItem from '/@/lib/preferences/item-formats/BooleanItem.svelte';
import EnumItem from '/@/lib/preferences/item-formats/EnumItem.svelte';
@ -7,10 +8,11 @@ import FileItem from '/@/lib/preferences/item-formats/FileItem.svelte';
import NumberItem from '/@/lib/preferences/item-formats/NumberItem.svelte';
import SliderItem from '/@/lib/preferences/item-formats/SliderItem.svelte';
import StringItem from '/@/lib/preferences/item-formats/StringItem.svelte';
import { onDidChangeConfiguration } from '/@/stores/configurationProperties';
import type { IConfigurationPropertyRecordedSchema } from '../../../../main/src/plugin/configuration-registry';
import Markdown from '../markdown/Markdown.svelte';
import { getNormalizedDefaultNumberValue } from './Util';
import { getInitialValue, getNormalizedDefaultNumberValue } from './Util';
let invalidText: string | undefined = undefined;
export let invalidRecord = (_error: string) => {};
@ -32,6 +34,28 @@ let recordValue: string | boolean | number | undefined;
$: recordValue;
$: updateResetButtonVisibility?.(recordValue);
let callBack: EventListenerOrEventListenerObject | undefined = undefined;
let callbackId: string | undefined = undefined;
onMount(() => {
if (record.id && record.scope === 'DEFAULT') {
callbackId = record.id;
callBack = () => {
getInitialValue(record).then(v => {
if (v) {
recordValue = v;
}
});
};
onDidChangeConfiguration.addEventListener(record.id, callBack);
}
});
onDestroy(() => {
if (callBack && callbackId) {
onDidChangeConfiguration.removeEventListener(callbackId, callBack);
}
});
$: if (resetToDefault) {
recordValue = record.type === 'number' ? getNormalizedDefaultNumberValue(record) : record.default;
if (ensureType(recordValue)) {