Skip to content

Commit

Permalink
fix: refresh onboarding item when context value gets updated (podman-…
Browse files Browse the repository at this point in the history
…desktop#4597) (podman-desktop#6173)

* fix: refresh onboarding item when context value gets updated (podman-desktop#4597)

Signed-off-by: lstocchi <[email protected]>

* Update packages/renderer/src/lib/onboarding/OnboardingItem.svelte

Co-authored-by: Florent BENOIT <[email protected]>
Signed-off-by: Luca Stocchi <[email protected]>

---------

Signed-off-by: lstocchi <[email protected]>
Signed-off-by: Luca Stocchi <[email protected]>
Co-authored-by: Florent BENOIT <[email protected]>
  • Loading branch information
lstocchi and benoitf authored Feb 28, 2024
1 parent e9b987f commit 8be8fa3
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 18 deletions.
1 change: 0 additions & 1 deletion packages/renderer/src/lib/onboarding/Onboarding.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -397,7 +397,6 @@ function handleEscape({ key }: any) {
<OnboardingItem
extension="{activeStep.onboarding.extension}"
item="{item}"
getContext="{() => globalContext}"
inProgressCommandExecution="{inProgressCommandExecution}" />
{/each}
</div>
Expand Down
40 changes: 30 additions & 10 deletions packages/renderer/src/lib/onboarding/OnboardingItem.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@ import { test, expect, vi } from 'vitest';
import { render, screen } from '@testing-library/svelte';
import OnboardingItem from './OnboardingItem.svelte';
import type { OnboardingStepItem } from '../../../../main/src/plugin/api/onboarding';
import { ContextUI } from '../context/context';
import { context } from '/@/stores/context';
import { configurationProperties } from '/@/stores/configurationProperties';
import { CONFIGURATION_ONBOARDING_SCOPE } from '../../../../main/src/plugin/configuration-registry-constants';
import { ContextUI } from '../context/context';

test('Expect button html when passing a button tag in markdown', async () => {
const textComponent: OnboardingStepItem = {
Expand All @@ -31,7 +32,6 @@ test('Expect button html when passing a button tag in markdown', async () => {
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
getContext: vi.fn(),
inProgressCommandExecution: vi.fn(),
});
const button = screen.getByRole('button', { name: 'label' });
Expand All @@ -46,7 +46,6 @@ test('Expect markdown html when passing a text component', async () => {
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
getContext: vi.fn(),
inProgressCommandExecution: vi.fn(),
});
const markdownSection = screen.getByLabelText('markdown-content');
Expand All @@ -58,12 +57,12 @@ test('Expect placeholders are replaced when passing a text component with placeh
const textComponent: OnboardingStepItem = {
value: '${onboardingContext:text}',
};
const context = new ContextUI();
context.setValue('extension.onboarding.text', 'placeholder content');
const globalContext = new ContextUI();
globalContext.setValue('extension.onboarding.text', 'placeholder content');
context.set(globalContext);
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
getContext: () => context,
inProgressCommandExecution: vi.fn(),
});
const markdownSection = screen.getByLabelText('markdown-content');
Expand Down Expand Up @@ -93,7 +92,6 @@ test('Expect boolean configuration placeholder to be replaced with a checkbox',
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
getContext: vi.fn(),
inProgressCommandExecution: vi.fn(),
});
const input = screen.getByLabelText('record-description');
Expand Down Expand Up @@ -126,7 +124,6 @@ test('Expect when configuration placeholder is type string and format file to be
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
getContext: vi.fn(),
inProgressCommandExecution: vi.fn(),
});
const readOnlyInput = screen.getByLabelText('record-description');
Expand Down Expand Up @@ -160,7 +157,6 @@ test('Expect a type text configuration placeholder to be replaced by a text inpu
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
getContext: vi.fn(),
inProgressCommandExecution: vi.fn(),
});
const input = screen.getByLabelText('record-description');
Expand Down Expand Up @@ -193,7 +189,6 @@ test('Expect a configuration to be visible in the onboarding even if hidden prop
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
getContext: vi.fn(),
inProgressCommandExecution: vi.fn(),
});
const input = screen.getByLabelText('record-description');
Expand All @@ -203,3 +198,28 @@ test('Expect a configuration to be visible in the onboarding even if hidden prop
expect((input as HTMLSelectElement).name).toBe('extension.text.prop');
expect((input as HTMLInputElement).placeholder).toBe('Example: text');
});

test('Expect value rendered is updated if context value is updated', async () => {
const textComponent: OnboardingStepItem = {
value: '${onboardingContext:text}',
};
const globalContext = new ContextUI();
globalContext.setValue('extension.onboarding.text', 'first value');
context.set(globalContext);
render(OnboardingItem, {
extension: 'extension',
item: textComponent,
inProgressCommandExecution: vi.fn(),
});
const markdownSection = screen.getByLabelText('markdown-content');
expect(markdownSection).toBeInTheDocument();
expect(markdownSection.innerHTML.includes('first value')).toBe(true);

// simulate the value in context is updated
globalContext.setValue('extension.onboarding.text', 'second value');
context.set(globalContext);

await new Promise(resolve => setTimeout(resolve, 100));
const markdownSection2 = screen.getByLabelText('markdown-content');
expect(markdownSection2.innerHTML.includes('second value')).toBe(true);
});
32 changes: 25 additions & 7 deletions packages/renderer/src/lib/onboarding/OnboardingItem.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { onMount } from 'svelte';
import { onDestroy, onMount } from 'svelte';
import type { OnboardingStepItem } from '../../../../main/src/plugin/api/onboarding';
import Markdown from '../markdown/Markdown.svelte';
import type { ContextUI } from '../context/context';
Expand All @@ -9,9 +9,10 @@ import { configurationProperties } from '/@/stores/configurationProperties';
import PreferencesRenderingItem from '../preferences/PreferencesRenderingItem.svelte';
import { CONFIGURATION_ONBOARDING_SCOPE } from '../../../../main/src/plugin/configuration-registry-constants';
import { isTargetScope } from '../preferences/Util';
import { context } from '/@/stores/context';
import type { Unsubscriber } from 'svelte/store';
export let extension: string;
export let item: OnboardingStepItem;
export let getContext: () => ContextUI;
export let inProgressCommandExecution: (
command: string,
state: 'starting' | 'failed' | 'successful',
Expand All @@ -25,6 +26,9 @@ let configurationItems: IConfigurationPropertyRecordedSchema[];
let configurationItem: IConfigurationPropertyRecordedSchema | undefined;
$: configurationItem;
let globalContext: ContextUI;
let contextsUnsubscribe: Unsubscriber;
onMount(() => {
configurationProperties.subscribe(value => {
configurationItems = value;
Expand All @@ -39,22 +43,36 @@ onMount(() => {
}
});
const itemHtml = replacePlaceholders(item.value);
html = itemHtml;
contextsUnsubscribe = context.subscribe(value => {
globalContext = value;
updateHtml();
});
updateHtml();
});
onDestroy(() => {
contextsUnsubscribe?.();
});
function updateHtml(): void {
const itemHtml = replacePlaceholders(item.value);
if (html !== itemHtml) {
html = itemHtml;
}
}
function replacePlaceholders(label: string): string {
let newLabel = label;
const context = getContext();
newLabel = replaceContextKeyPlaceholders(newLabel, extension, context);
newLabel = replaceContextKeyPlaceholders(newLabel, extension, globalContext);
newLabel = replaceContextKeyPlaceHoldersByRegex(configurationRegex, newLabel, undefined, undefined, '');
return newLabel;
}
</script>

<div class="flex justify-center {item.highlight ? 'bg-charcoal-600' : ''} p-3 m-2 rounded-md min-w-[500px]">
{#if html}
<Markdown inProgressMarkdownCommandExecutionCallback="{inProgressCommandExecution}">{html}</Markdown>
<Markdown inProgressMarkdownCommandExecutionCallback="{inProgressCommandExecution}" markdown="{html}" />
{/if}
{#if configurationItem}
<div class="min-w-[500px] bg-charcoal-600 rounded-md">
Expand Down

0 comments on commit 8be8fa3

Please sign in to comment.