Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/webview/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
26 changes: 26 additions & 0 deletions packages/webview/src/App.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<script lang="ts">
import Dashboard from './component/Dashboard.svelte';
import ResourcesCount from './component/ResourcesCount.svelte';
import Navigation from './Navigation.svelte';
import Route from './Route.svelte';

let isMounted = false;
</script>

<Route path="/*" isAppMounted={isMounted} let:meta>
<main class="flex flex-col w-screen h-screen overflow-hidden bg-[var(--pd-content-bg)] text-base">
<div class="flex flex-row w-full h-full overflow-hidden">
<Navigation meta={meta} />

<div class="flex flex-col w-full h-full">
<Route path="/">
<Dashboard />
</Route>

<Route path="/resources-count">
<ResourcesCount />
</Route>
</div>
</div>
</main>
</Route>
8 changes: 2 additions & 6 deletions packages/webview/src/MainContextAware.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -20,9 +20,5 @@ initialized = true;
</script>

{#if initialized}
Kubernetes Dashboard

<div>
<ResourcesCount />
</div>
<App />
{/if}
29 changes: 29 additions & 0 deletions packages/webview/src/Navigation.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<script lang="ts">
import type { TinroRouteMeta } from 'tinro';
import { SettingsNavItem } from '@podman-desktop/ui-svelte';

interface Props {
meta: TinroRouteMeta;
}

const { meta }: Props = $props();
</script>

<nav
class="z-1 w-leftsidebar min-w-leftsidebar shadow-xs flex-col justify-between flex transition-all duration-500 ease-in-out bg-[var(--pd-secondary-nav-bg)] border-[var(--pd-global-nav-bg-border)] border-r-[1px]"
aria-label="PreferencesNavigation">
<div class="flex items-center">
<div class="pt-4 pl-3 px-5 mb-10 flex items-center ml-[4px]">
<p class="text-xl first-letter:uppercase text-[color:var(--pd-secondary-nav-header-text)]">Kubernetes</p>
</div>
</div>
<div class="h-full overflow-hidden hover:overflow-y-auto" style="margin-bottom:auto">
<SettingsNavItem title="Dashboard" selected={meta.url === '/'} href="/" />

<div class="pl-3 mt-2 ml-[4px]">
<span class="text-[color:var(--pd-secondary-nav-header-text)]">STATES</span>
</div>

<SettingsNavItem title="Resources count" selected={meta.url === '/resources-count'} href="/resources-count" />
</div>
</nav>
52 changes: 52 additions & 0 deletions packages/webview/src/Route.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<script lang="ts">
import { createRouteObject } from 'tinro/dist/tinro_lib';
import type { TinroRouteMeta } from 'tinro';
import type { RouterState } from './models/router-state';
import type { WebviewApi } from '@podman-desktop/webview-api';
import { getContext } from 'svelte';

export let path = '/*';
export let fallback = false;
export let redirect = false;
export let firstmatch = false;

export let isAppMounted: boolean = false;

let showContent = false;
let params: Record<string, string> = {};
let meta: TinroRouteMeta = {} as TinroRouteMeta;

const webviewApi = getContext<WebviewApi>('WebviewApi');

const route = createRouteObject({
fallback,
onShow() {
showContent = true;
},
onHide() {
showContent = false;
},
onMeta(newMeta: TinroRouteMeta) {
meta = newMeta;
params = meta.params;

if (isAppMounted) {
saveRouterState({ url: newMeta.url }).catch(console.error);
}
},
});

$: route.update({
path,
redirect,
firstmatch,
});

async function saveRouterState(state: RouterState): Promise<void> {
await webviewApi.setState(state);
}
</script>

{#if showContent}
<slot params={params} meta={meta} />
{/if}
5 changes: 5 additions & 0 deletions packages/webview/src/component/Dashboard.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<script lang="ts">
import { NavPage } from '@podman-desktop/ui-svelte';
</script>

<NavPage title="Dashboard" searchEnabled={false}></NavPage>
19 changes: 12 additions & 7 deletions packages/webview/src/component/ResourcesCount.svelte
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
<script lang="ts">
import { getContext } from 'svelte';
import { States } from '/@/state/states';
import { NavPage } from '@podman-desktop/ui-svelte';

const resourcesCount = getContext<States>(States).stateResourcesCountInfoUI;
</script>

{#if resourcesCount.data?.counts}
<ul>
{#each resourcesCount.data.counts as count, index (index)}
<li>{count.contextName}/{count.resourceName}: {count.count}</li>
{/each}
</ul>
{/if}
<NavPage title="Resources count" searchEnabled={false}>
{#snippet content()}
{#if resourcesCount.data?.counts}
<ul>
{#each resourcesCount.data.counts as count, index (index)}
<li>{count.contextName}/{count.resourceName}: {count.count}</li>
{/each}
</ul>
{/if}
{/snippet}
</NavPage>
9 changes: 6 additions & 3 deletions packages/webview/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<MainContext> {
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
Expand All @@ -52,6 +54,7 @@ export class Main implements IDisposable {

const mainContext: MainContext = {
states: await container.getAsync<States>(States),
webviewApi,
};

return mainContext;
Expand Down
21 changes: 21 additions & 0 deletions packages/webview/src/models/router-state.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**********************************************************************
* 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
***********************************************************************/

export interface RouterState {
url: string;
}
32 changes: 32 additions & 0 deletions packages/webview/tailwind.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions types/additional.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**********************************************************************
* Copyright (C) 2023-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';