diff --git a/packages/frontend/src/App.svelte b/packages/frontend/src/App.svelte index fc268cec..3940eb49 100644 --- a/packages/frontend/src/App.svelte +++ b/packages/frontend/src/App.svelte @@ -13,6 +13,7 @@ import Examples from './Examples.svelte'; import Navigation from './Navigation.svelte'; import DiskImagesList from './lib/disk-image/DiskImagesList.svelte'; import Dashboard from './lib/dashboard/Dashboard.svelte'; +import ExampleDetails from './lib/ExampleDetails.svelte'; router.mode.hash(); @@ -41,6 +42,10 @@ onMount(() => { + + + + diff --git a/packages/frontend/src/lib/ExampleCard.spec.ts b/packages/frontend/src/lib/ExampleCard.spec.ts index 66760f9a..042749c4 100644 --- a/packages/frontend/src/lib/ExampleCard.spec.ts +++ b/packages/frontend/src/lib/ExampleCard.spec.ts @@ -72,16 +72,16 @@ test('renders ExampleCard with correct content', async () => { expect(architectureText).toBeInTheDocument(); }); -test('openURL function is called when Source button is clicked', async () => { +test('redirection to /example/:id is called when More details button is clicked', async () => { // Render the component with the example prop render(ExampleCard, { props: { example } }); - // Find and click the "Source" button - const sourceButton = screen.getByTitle('Source'); - await fireEvent.click(sourceButton); + // Find and click the "More details" button + const detailsButton = screen.getByTitle('More Details'); + await fireEvent.click(detailsButton); - // Ensure bootcClient.openLink is called with the correct URL - expect(bootcClient.openLink).toHaveBeenCalledWith('https://example.com/example1'); + // Ensure the router.goto is called with the correct path + expect(router.goto).toHaveBeenCalledWith('/example/example1'); }); test('pullImage function is called when Pull image button is clicked', async () => { diff --git a/packages/frontend/src/lib/ExampleCard.svelte b/packages/frontend/src/lib/ExampleCard.svelte index e92bfd17..cae60b38 100644 --- a/packages/frontend/src/lib/ExampleCard.svelte +++ b/packages/frontend/src/lib/ExampleCard.svelte @@ -16,7 +16,8 @@ let { example }: Props = $props(); let pullInProgress = $state(false); async function openURL(): Promise { - await bootcClient.openLink(example.repository); + //await bootcClient.openLink(example.repository); + router.goto(`/example/${example.id}`); } async function pullImage(): Promise { @@ -76,10 +77,10 @@ async function gotoBuild(): Promise { + class="mr-2">More Details {#if example?.state === 'pulled'} + + + + + + + diff --git a/packages/frontend/src/lib/ExampleDetailsLayout.spec.ts b/packages/frontend/src/lib/ExampleDetailsLayout.spec.ts new file mode 100644 index 00000000..cb1dac07 --- /dev/null +++ b/packages/frontend/src/lib/ExampleDetailsLayout.spec.ts @@ -0,0 +1,38 @@ +/********************************************************************** + * Copyright (C) 2024 Red Hat, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * SPDX-License-Identifier: Apache-2.0 + ***********************************************************************/ + +import '@testing-library/jest-dom/vitest'; +import { render, screen } from '@testing-library/svelte'; +import { expect, test } from 'vitest'; +import DetailsComponent from './ExampleDetailsLayout.svelte'; + +test('renders DetailsComponent with title and content slots', async () => { + const detailsTitle = 'Test Title'; + const detailsLabel = 'Test Label'; + + render(DetailsComponent, { props: { detailsTitle, detailsLabel } }); + + // Verify title + const titleElement = screen.getByText(detailsTitle); + expect(titleElement).toBeInTheDocument(); + + // Verify content + const detailsPanel = screen.getByLabelText(`${detailsLabel} panel`); + expect(detailsPanel).toBeInTheDocument(); + expect(detailsPanel).toBeVisible(); +}); diff --git a/packages/frontend/src/lib/ExampleDetailsLayout.svelte b/packages/frontend/src/lib/ExampleDetailsLayout.svelte new file mode 100644 index 00000000..1d299de8 --- /dev/null +++ b/packages/frontend/src/lib/ExampleDetailsLayout.svelte @@ -0,0 +1,44 @@ + + +
+ +
+
+ +
+
+
+
+
+
+ {detailsTitle} + +
+ +
+
+
+ +
+
+
+
+
diff --git a/packages/frontend/src/lib/ExamplesCard.svelte b/packages/frontend/src/lib/ExamplesCard.svelte index bace0d40..ad1faccd 100644 --- a/packages/frontend/src/lib/ExamplesCard.svelte +++ b/packages/frontend/src/lib/ExamplesCard.svelte @@ -36,7 +36,6 @@ onMount(async () => { // Function to update examples based on available images function updateExamplesWithPulledImages() { if (bootcAvailableImages) { - console.log('updateExamplesWithPulledImages'); // Set each state to 'unpulled' by default before updating, as this prevents 'flickering' // and unsure states when images are being updated for (const example of examples) { diff --git a/packages/frontend/src/lib/markdown/MarkdownRenderer.svelte b/packages/frontend/src/lib/markdown/MarkdownRenderer.svelte new file mode 100644 index 00000000..e8057e61 --- /dev/null +++ b/packages/frontend/src/lib/markdown/MarkdownRenderer.svelte @@ -0,0 +1,9 @@ + + +
+ +