Skip to content

Commit c58619a

Browse files
committed
feat: add routing and first pages
1 parent f8700b2 commit c58619a

File tree

12 files changed

+220
-16
lines changed

12 files changed

+220
-16
lines changed

packages/webview/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
"dependencies": {
1919
"deep-chat": "^2.2.0",
2020
"inversify": "^7.5.1",
21-
"svelte-preprocess": "^6.0.3"
21+
"svelte-preprocess": "^6.0.3",
22+
"tinro": "^0.6.12"
2223
},
2324
"devDependencies": {
2425
"@fortawesome/fontawesome-free": "^6.7.2",

packages/webview/src/App.svelte

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<script lang="ts">
2+
import Dashboard from "./component/Dashboard.svelte";
3+
import ResourcesCount from "./component/ResourcesCount.svelte";
4+
import Navigation from "./Navigation.svelte";
5+
import Route from "./Route.svelte";
6+
7+
let isMounted = false;
8+
9+
</script>
10+
11+
<Route path="/*" isAppMounted={isMounted} let:meta>
12+
<main class="flex flex-col w-screen h-screen overflow-hidden bg-[var(--pd-content-bg)] text-base">
13+
<div class="flex flex-row w-full h-full overflow-hidden">
14+
<Navigation meta={meta} />
15+
16+
<div class="flex flex-col w-full h-full">
17+
18+
<Route path="/">
19+
<Dashboard />
20+
</Route>
21+
22+
<Route path="/resources-count">
23+
<ResourcesCount />
24+
</Route>
25+
</div>
26+
27+
</div>
28+
</main>
29+
</Route>

packages/webview/src/MainContextAware.svelte

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { setContext } from 'svelte';
44
import type { MainContext } from './main';
55
import { States } from './state/states';
66
import ResourcesCount from './component/ResourcesCount.svelte';
7+
import App from './App.svelte';
78
89
interface Props {
910
context: MainContext;
@@ -20,9 +21,5 @@ initialized = true;
2021
</script>
2122

2223
{#if initialized}
23-
Kubernetes Dashboard
24-
25-
<div>
26-
<ResourcesCount />
27-
</div>
24+
<App />
2825
{/if}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<script lang="ts">
2+
import type { TinroRouteMeta } from 'tinro';
3+
import { SettingsNavItem } from '@podman-desktop/ui-svelte';
4+
import Fa from 'svelte-fa';
5+
6+
export let meta: TinroRouteMeta;
7+
</script>
8+
9+
10+
<nav
11+
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]"
12+
aria-label="PreferencesNavigation">
13+
<div class="flex items-center">
14+
<div class="pt-4 pl-3 px-5 mb-10 flex items-center ml-[4px]">
15+
<p class="text-xl first-letter:uppercase text-[color:var(--pd-secondary-nav-header-text)]">Kubernetes</p>
16+
</div>
17+
</div>
18+
<div class="h-full overflow-hidden hover:overflow-y-auto" style="margin-bottom:auto">
19+
<SettingsNavItem title="Dashboard" selected={meta.url === '/'} href="/" />
20+
21+
<div class="pl-3 mt-2 ml-[4px]">
22+
<span class="text-[color:var(--pd-secondary-nav-header-text)]">STATES</span>
23+
</div>
24+
25+
<SettingsNavItem
26+
title="Resources count"
27+
selected={meta.url === '/resources-count'}
28+
href="/resources-count" />
29+
</div>
30+
</nav>

packages/webview/src/Route.svelte

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<script lang="ts">
2+
import { createRouteObject } from 'tinro/dist/tinro_lib';
3+
import type { TinroRouteMeta } from 'tinro';
4+
import type { RouterState } from './models/router-state';
5+
import type { WebviewApi } from '@podman-desktop/webview-api';
6+
import { getContext } from 'svelte';
7+
8+
export let path = '/*';
9+
export let fallback = false;
10+
export let redirect = false;
11+
export let firstmatch = false;
12+
13+
export let isAppMounted: boolean = false;
14+
15+
let showContent = false;
16+
let params: Record<string, string> = {};
17+
let meta: TinroRouteMeta = {} as TinroRouteMeta;
18+
19+
const webviewApi = getContext<WebviewApi>('WebviewApi');
20+
21+
const route = createRouteObject({
22+
fallback,
23+
onShow() {
24+
showContent = true;
25+
},
26+
onHide() {
27+
showContent = false;
28+
},
29+
onMeta(newMeta: TinroRouteMeta) {
30+
meta = newMeta;
31+
params = meta.params;
32+
33+
if (isAppMounted) {
34+
saveRouterState({ url: newMeta.url });
35+
}
36+
},
37+
});
38+
39+
$: route.update({
40+
path,
41+
redirect,
42+
firstmatch,
43+
});
44+
45+
async function saveRouterState(state: RouterState): Promise<void> {
46+
await webviewApi.setState(state);
47+
};
48+
</script>
49+
50+
{#if showContent}
51+
<slot params={params} meta={meta} />
52+
{/if}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<script lang="ts">
2+
import { NavPage } from "@podman-desktop/ui-svelte";
3+
4+
</script>
5+
6+
<NavPage title="Dashboard" searchEnabled={false}>
7+
</NavPage>
Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
<script lang="ts">
22
import { getContext } from 'svelte';
33
import { States } from '/@/state/states';
4+
import { NavPage } from '@podman-desktop/ui-svelte';
45
56
const resourcesCount = getContext<States>(States).stateResourcesCountInfoUI;
67
</script>
78

8-
{#if resourcesCount.data?.counts}
9-
<ul>
10-
{#each resourcesCount.data.counts as count, index (index)}
11-
<li>{count.contextName}/{count.resourceName}: {count.count}</li>
12-
{/each}
13-
</ul>
14-
{/if}
9+
<NavPage title="Resources count" searchEnabled={false}>
10+
{#snippet content()}
11+
{#if resourcesCount.data?.counts}
12+
<ul>
13+
{#each resourcesCount.data.counts as count, index (index)}
14+
<li>{count.contextName}/{count.resourceName}: {count.count}</li>
15+
{/each}
16+
</ul>
17+
{/if}
18+
{/snippet}
19+
</NavPage>

packages/webview/src/main.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,22 @@ import { InversifyBinding } from './inject/inversify-binding';
2222
import { IDisposable } from '/@common/types/disposable';
2323
import { States } from './state/states';
2424
import { StateObject } from './state/util/state-object.svelte';
25+
import type { WebviewApi } from '@podman-desktop/webview-api';
2526

2627
export interface MainContext {
2728
states: States;
29+
webviewApi: WebviewApi;
2830
}
2931

3032
export class Main implements IDisposable {
3133
private disposables: IDisposable[] = [];
3234

3335
async init(): Promise<MainContext> {
34-
const webViewApi = acquirePodmanDesktopApi();
36+
const webviewApi = acquirePodmanDesktopApi();
3537

36-
const rpcBrowser: RpcBrowser = new RpcBrowser(window, webViewApi);
38+
const rpcBrowser: RpcBrowser = new RpcBrowser(window, webviewApi);
3739

38-
const inversifyBinding = new InversifyBinding(rpcBrowser, webViewApi);
40+
const inversifyBinding = new InversifyBinding(rpcBrowser, webviewApi);
3941
const container = await inversifyBinding.initBindings();
4042

4143
// Grab all state object instances
@@ -52,6 +54,7 @@ export class Main implements IDisposable {
5254

5355
const mainContext: MainContext = {
5456
states: await container.getAsync<States>(States),
57+
webviewApi,
5558
};
5659

5760
return mainContext;
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**********************************************************************
2+
* Copyright (C) 2024 Red Hat, Inc.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*
16+
* SPDX-License-Identifier: Apache-2.0
17+
***********************************************************************/
18+
19+
export interface RouterState {
20+
url: string;
21+
}

packages/webview/tailwind.config.cjs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,38 @@ module.exports = {
2121
'5xl': '30px',
2222
'6xl': '36px',
2323
},
24+
extend: {
25+
boxShadow: {
26+
"titlebar": 'inset 0px -1px 0px 0 rgb(54 54 61 / 0.6)', // highlight for bottom of titlebar
27+
"pageheader": 'inset 0 0px 10px 0 rgb(0 0 0 / 0.4)',
28+
"nav": 'inset 7px -4px 6px 0 rgb(0 0 0 / 0.15)',
29+
},
30+
transitionProperty: {
31+
width: 'width',
32+
},
33+
width: {
34+
'leftnavbar': '54px',
35+
'leftsidebar': '225px',
36+
},
37+
minWidth: {
38+
'leftnavbar': '54px',
39+
'leftsidebar': '225px',
40+
},
41+
typography: (theme) => ({
42+
DEFAULT: {
43+
css: {
44+
color: 'var(--pd-details-body-text)',
45+
'--tw-prose-body': 'var(--pd-details-body-text)',
46+
'--tw-prose-bold': 'var(--pd-details-body-text)',
47+
'--tw-prose-headings': 'var(--pd-details-body-text)',
48+
'--tw-prose-quotes': 'var(--pd-details-body-text)',
49+
'--tw-prose-hr': 'var(--pd-details-body-text)',
50+
'--tw-prose-links': 'var(--pd-link)',
51+
'--tw-prose-code': 'var(--pd-details-body-text)',
52+
},
53+
},
54+
}),
55+
},
2456
colors: {
2557
'charcoal': {
2658
600: '#27272a',

0 commit comments

Comments
 (0)