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} - -{/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';