diff --git a/packages/webview/package.json b/packages/webview/package.json
index ed5af8e1..64bd6dc4 100644
--- a/packages/webview/package.json
+++ b/packages/webview/package.json
@@ -18,7 +18,8 @@
"dependencies": {
"deep-chat": "^2.2.0",
"inversify": "^7.5.1",
- "svelte-preprocess": "^6.0.3"
+ "svelte-preprocess": "^6.0.3",
+ "tinro": "^0.6.12"
},
"devDependencies": {
"@fortawesome/fontawesome-free": "^6.7.2",
diff --git a/packages/webview/src/App.svelte b/packages/webview/src/App.svelte
new file mode 100644
index 00000000..7e8aaa5e
--- /dev/null
+++ b/packages/webview/src/App.svelte
@@ -0,0 +1,26 @@
+
+
+
+
+
+
+
diff --git a/packages/webview/src/MainContextAware.svelte b/packages/webview/src/MainContextAware.svelte
index cbe4238a..821e4bf4 100644
--- a/packages/webview/src/MainContextAware.svelte
+++ b/packages/webview/src/MainContextAware.svelte
@@ -3,7 +3,7 @@ import { setContext } from 'svelte';
import type { MainContext } from './main';
import { States } from './state/states';
-import ResourcesCount from './component/ResourcesCount.svelte';
+import App from './App.svelte';
interface Props {
context: MainContext;
@@ -20,9 +20,5 @@ initialized = true;
{#if initialized}
- Kubernetes Dashboard
-
-
-
-
+
{/if}
diff --git a/packages/webview/src/Navigation.svelte b/packages/webview/src/Navigation.svelte
new file mode 100644
index 00000000..8359f1cf
--- /dev/null
+++ b/packages/webview/src/Navigation.svelte
@@ -0,0 +1,29 @@
+
+
+
diff --git a/packages/webview/src/Route.svelte b/packages/webview/src/Route.svelte
new file mode 100644
index 00000000..1dfab5f1
--- /dev/null
+++ b/packages/webview/src/Route.svelte
@@ -0,0 +1,52 @@
+
+
+{#if showContent}
+
+{/if}
diff --git a/packages/webview/src/component/Dashboard.svelte b/packages/webview/src/component/Dashboard.svelte
new file mode 100644
index 00000000..4e0deb67
--- /dev/null
+++ b/packages/webview/src/component/Dashboard.svelte
@@ -0,0 +1,5 @@
+
+
+
diff --git a/packages/webview/src/component/ResourcesCount.svelte b/packages/webview/src/component/ResourcesCount.svelte
index b488e397..a34b237c 100644
--- a/packages/webview/src/component/ResourcesCount.svelte
+++ b/packages/webview/src/component/ResourcesCount.svelte
@@ -1,14 +1,19 @@
-{#if resourcesCount.data?.counts}
-
- {#each resourcesCount.data.counts as count, index (index)}
- - {count.contextName}/{count.resourceName}: {count.count}
- {/each}
-
-{/if}
+
+ {#snippet content()}
+ {#if resourcesCount.data?.counts}
+
+ {#each resourcesCount.data.counts as count, index (index)}
+ - {count.contextName}/{count.resourceName}: {count.count}
+ {/each}
+
+ {/if}
+ {/snippet}
+
diff --git a/packages/webview/src/main.ts b/packages/webview/src/main.ts
index 0e259551..aaf13f86 100644
--- a/packages/webview/src/main.ts
+++ b/packages/webview/src/main.ts
@@ -22,20 +22,22 @@ import { InversifyBinding } from './inject/inversify-binding';
import { IDisposable } from '/@common/types/disposable';
import { States } from './state/states';
import { StateObject } from './state/util/state-object.svelte';
+import type { WebviewApi } from '@podman-desktop/webview-api';
export interface MainContext {
states: States;
+ webviewApi: WebviewApi;
}
export class Main implements IDisposable {
private disposables: IDisposable[] = [];
async init(): Promise {
- const webViewApi = acquirePodmanDesktopApi();
+ const webviewApi = acquirePodmanDesktopApi();
- const rpcBrowser: RpcBrowser = new RpcBrowser(window, webViewApi);
+ const rpcBrowser: RpcBrowser = new RpcBrowser(window, webviewApi);
- const inversifyBinding = new InversifyBinding(rpcBrowser, webViewApi);
+ const inversifyBinding = new InversifyBinding(rpcBrowser, webviewApi);
const container = await inversifyBinding.initBindings();
// Grab all state object instances
@@ -52,6 +54,7 @@ export class Main implements IDisposable {
const mainContext: MainContext = {
states: await container.getAsync(States),
+ webviewApi,
};
return mainContext;
diff --git a/packages/webview/src/models/router-state.ts b/packages/webview/src/models/router-state.ts
new file mode 100644
index 00000000..76cc77e6
--- /dev/null
+++ b/packages/webview/src/models/router-state.ts
@@ -0,0 +1,21 @@
+/**********************************************************************
+ * Copyright (C) 2025 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
+ ***********************************************************************/
+
+export interface RouterState {
+ url: string;
+}
diff --git a/packages/webview/tailwind.config.cjs b/packages/webview/tailwind.config.cjs
index d77fae1b..d6a38443 100644
--- a/packages/webview/tailwind.config.cjs
+++ b/packages/webview/tailwind.config.cjs
@@ -21,6 +21,38 @@ module.exports = {
'5xl': '30px',
'6xl': '36px',
},
+ extend: {
+ boxShadow: {
+ "titlebar": 'inset 0px -1px 0px 0 rgb(54 54 61 / 0.6)', // highlight for bottom of titlebar
+ "pageheader": 'inset 0 0px 10px 0 rgb(0 0 0 / 0.4)',
+ "nav": 'inset 7px -4px 6px 0 rgb(0 0 0 / 0.15)',
+ },
+ transitionProperty: {
+ width: 'width',
+ },
+ width: {
+ 'leftnavbar': '54px',
+ 'leftsidebar': '225px',
+ },
+ minWidth: {
+ 'leftnavbar': '54px',
+ 'leftsidebar': '225px',
+ },
+ typography: (theme) => ({
+ DEFAULT: {
+ css: {
+ color: 'var(--pd-details-body-text)',
+ '--tw-prose-body': 'var(--pd-details-body-text)',
+ '--tw-prose-bold': 'var(--pd-details-body-text)',
+ '--tw-prose-headings': 'var(--pd-details-body-text)',
+ '--tw-prose-quotes': 'var(--pd-details-body-text)',
+ '--tw-prose-hr': 'var(--pd-details-body-text)',
+ '--tw-prose-links': 'var(--pd-link)',
+ '--tw-prose-code': 'var(--pd-details-body-text)',
+ },
+ },
+ }),
+ },
colors: {
'charcoal': {
600: '#27272a',
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 330093c4..a11abb77 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -180,6 +180,9 @@ importers:
svelte-preprocess:
specifier: ^6.0.3
version: 6.0.3(postcss-load-config@6.0.1(jiti@2.4.2)(postcss@8.5.6))(postcss@8.5.6)(svelte@5.34.9)(typescript@5.8.3)
+ tinro:
+ specifier: ^0.6.12
+ version: 0.6.12
devDependencies:
'@fortawesome/fontawesome-free':
specifier: ^6.7.2
@@ -3328,6 +3331,9 @@ packages:
peerDependencies:
tslib: ^2
+ tinro@0.6.12:
+ resolution: {integrity: sha512-YYLh0a21GXXpS66ilZbywfXcPTKQQ+bv3tihoqKqSFQP6/F11N7ZmtRbFWcyZXXPFRSzNxmPJBB8ZhP0GkoS0Q==}
+
tinybench@2.9.0:
resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==}
@@ -6930,6 +6936,8 @@ snapshots:
dependencies:
tslib: 2.8.1
+ tinro@0.6.12: {}
+
tinybench@2.9.0: {}
tinyexec@0.3.2: {}
diff --git a/types/additional.d.ts b/types/additional.d.ts
new file mode 100644
index 00000000..a96a1610
--- /dev/null
+++ b/types/additional.d.ts
@@ -0,0 +1,19 @@
+/**********************************************************************
+ * Copyright (C) 2025 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
+ ***********************************************************************/
+
+declare module 'tinro/dist/tinro_lib';