@bardioc/create-bardioc-app 0.5.8 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/templates/_base/public/app-manifest.json +1 -2
- package/templates/angular/package.json +1 -1
- package/templates/angular/scripts/dev-env.mjs +31 -10
- package/templates/angular/scripts/dev.mjs +37 -8
- package/templates/angular/src/app/app.component.ts +42 -24
- package/templates/angular/src/app/bardioc.token.ts +2 -2
- package/templates/angular/src/main.ts +6 -8
- package/templates/nextjs/app/page.tsx +8 -8
- package/templates/nextjs/package.json +1 -1
- package/templates/nextjs/scripts/dev-env.mjs +31 -10
- package/templates/nextjs/scripts/dev.mjs +37 -8
- package/templates/preact/package.json +1 -1
- package/templates/preact/src/App.tsx +5 -5
- package/templates/preact/src/main.tsx +3 -3
- package/templates/solid/package.json +1 -1
- package/templates/solid/src/App.tsx +5 -5
- package/templates/solid/src/bardioc-sdk.tsx +11 -23
- package/templates/solid/src/main.tsx +5 -3
- package/templates/svelte/package.json +1 -1
- package/templates/svelte/src/App.svelte +7 -7
- package/templates/svelte/src/main.ts +5 -5
- package/templates/vite/package.json +1 -1
- package/templates/vite/public/app-manifest.json +0 -1
- package/templates/vite/src/auth/onboarding.tsx +4 -2
- package/templates/vite/src/climate/stations-view.tsx +1 -8
- package/templates/vite/src/climate/use-climate.ts +6 -6
- package/templates/vite/src/events/live-events-view.tsx +7 -9
- package/templates/vite/src/graph/explorer-view.tsx +4 -11
- package/templates/vite/src/graph/requests.ts +16 -19
- package/templates/vite/src/locales/de.json +5 -6
- package/templates/vite/src/locales/en.json +6 -7
- package/templates/vite/src/main.tsx +3 -3
- package/templates/vite/src/profile/profile-view.tsx +1 -8
- package/templates/vite/src/profile/use-profile.ts +3 -3
- package/templates/vite/src/shell/about-dialog.tsx +2 -8
- package/templates/vite/src/shell/app-shell.tsx +48 -11
- package/templates/vue/package.json +1 -1
- package/templates/vue/src/App.vue +7 -7
- package/templates/vue/src/bardioc-sdk.ts +6 -15
- package/templates/vue/src/main.ts +5 -4
- package/templates/angular/src/app/bardioc-bridge.ts +0 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BardiocLogoIcon, Dialog } from '@bardioc/ui/components';
|
|
2
|
-
import { HashIcon, PackageIcon,
|
|
2
|
+
import { HashIcon, PackageIcon, TagIcon } from 'lucide-react';
|
|
3
3
|
import { useEffect, useState, type ReactNode } from 'react';
|
|
4
4
|
import { useTranslation } from '../i18n';
|
|
5
5
|
|
|
@@ -8,7 +8,6 @@ interface AppManifest {
|
|
|
8
8
|
name: string;
|
|
9
9
|
description: string;
|
|
10
10
|
version: string;
|
|
11
|
-
permissions?: string[];
|
|
12
11
|
}
|
|
13
12
|
|
|
14
13
|
interface AboutDialogProps {
|
|
@@ -18,7 +17,7 @@ interface AboutDialogProps {
|
|
|
18
17
|
|
|
19
18
|
// Reads the app's own manifest (public/app-manifest.json) at runtime. The manifest is served at
|
|
20
19
|
// the Vite base path, so the same code works in dev and inside the host — this is the example of
|
|
21
|
-
// reading metadata (name, version,
|
|
20
|
+
// reading metadata (name, version, description) from the manifest instead of hard-coding it.
|
|
22
21
|
async function loadManifest(): Promise<AppManifest> {
|
|
23
22
|
const response = await fetch(`${import.meta.env.BASE_URL}app-manifest.json`, {
|
|
24
23
|
cache: 'no-store',
|
|
@@ -112,11 +111,6 @@ export function AboutDialog({ open, onOpenChange }: Readonly<AboutDialogProps>)
|
|
|
112
111
|
label={t('about.description', { fallback: 'Description' })}
|
|
113
112
|
value={manifest?.description ?? dash}
|
|
114
113
|
/>
|
|
115
|
-
<AboutRow
|
|
116
|
-
icon={<ShieldCheckIcon className="size-4" />}
|
|
117
|
-
label={t('about.permissions', { fallback: 'Permissions' })}
|
|
118
|
-
value={manifest?.permissions?.join(', ') ?? dash}
|
|
119
|
-
/>
|
|
120
114
|
</div>
|
|
121
115
|
)}
|
|
122
116
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { MenuRoot } from '@bardioc/app-sdk';
|
|
2
2
|
import { useCommandMenu, type AppCommand } from '@bardioc/app-sdk/react';
|
|
3
3
|
import {
|
|
4
4
|
BardiocLogoIcon,
|
|
@@ -28,13 +28,50 @@ import { AboutDialog } from './about-dialog';
|
|
|
28
28
|
import { Header } from './header';
|
|
29
29
|
|
|
30
30
|
// `icon` is the sidebar's React component; `iconName` is the matching lucide export name the
|
|
31
|
-
// OS resolves for the top-menu entry (host calls resolveLucideIcon on the string).
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
31
|
+
// OS resolves for the top-menu entry (host calls resolveLucideIcon on the string). `titleKey` is
|
|
32
|
+
// the view's Page title, which can say more than its short navigation label.
|
|
33
|
+
const NAV: Array<{
|
|
34
|
+
id: ViewId;
|
|
35
|
+
icon: LucideIcon;
|
|
36
|
+
iconName: string;
|
|
37
|
+
labelKey: string;
|
|
38
|
+
titleKey: string;
|
|
39
|
+
}> = [
|
|
40
|
+
{
|
|
41
|
+
id: 'overview',
|
|
42
|
+
icon: LayoutDashboard,
|
|
43
|
+
iconName: 'LayoutDashboard',
|
|
44
|
+
labelKey: 'nav.overview',
|
|
45
|
+
titleKey: 'nav.overview',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
id: 'stations',
|
|
49
|
+
icon: Table2,
|
|
50
|
+
iconName: 'Table2',
|
|
51
|
+
labelKey: 'nav.stations',
|
|
52
|
+
titleKey: 'stations.title',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
id: 'explorer',
|
|
56
|
+
icon: Network,
|
|
57
|
+
iconName: 'Network',
|
|
58
|
+
labelKey: 'nav.explorer',
|
|
59
|
+
titleKey: 'explorer.title',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
id: 'events',
|
|
63
|
+
icon: Activity,
|
|
64
|
+
iconName: 'Activity',
|
|
65
|
+
labelKey: 'nav.events',
|
|
66
|
+
titleKey: 'events.title',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
id: 'profile',
|
|
70
|
+
icon: UserRound,
|
|
71
|
+
iconName: 'UserRound',
|
|
72
|
+
labelKey: 'nav.profile',
|
|
73
|
+
titleKey: 'profile.title',
|
|
74
|
+
},
|
|
38
75
|
];
|
|
39
76
|
|
|
40
77
|
function ViewContent({ view }: Readonly<{ view: ViewId }>) {
|
|
@@ -99,7 +136,7 @@ export function AppShell() {
|
|
|
99
136
|
[t, view]
|
|
100
137
|
);
|
|
101
138
|
|
|
102
|
-
const menu = useMemo<
|
|
139
|
+
const menu = useMemo<MenuRoot[]>(
|
|
103
140
|
() => [
|
|
104
141
|
{
|
|
105
142
|
label: t('app.title', { fallback: 'Weather Dashboard' }),
|
|
@@ -122,13 +159,13 @@ export function AppShell() {
|
|
|
122
159
|
useCommandMenu(commands, menu);
|
|
123
160
|
|
|
124
161
|
const activeNav = NAV.find(entry => entry.id === view);
|
|
125
|
-
const pageTitle = activeNav ? t(activeNav.
|
|
162
|
+
const pageTitle = activeNav ? t(activeNav.titleKey, { fallback: activeNav.id }) : undefined;
|
|
126
163
|
|
|
127
164
|
const header = (
|
|
128
165
|
<div className="flex items-center gap-2 px-2 py-1">
|
|
129
166
|
<BardiocLogoIcon className="size-5" />
|
|
130
167
|
<span className="truncate text-sm font-semibold">
|
|
131
|
-
{t('app.title', { fallback: '
|
|
168
|
+
{t('app.title', { fallback: 'Weather Dashboard' })}
|
|
132
169
|
</span>
|
|
133
170
|
</div>
|
|
134
171
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
3
3
|
import { ref } from 'vue';
|
|
4
|
-
import {
|
|
4
|
+
import { useBardioc, useNotify } from './bardioc-sdk';
|
|
5
5
|
|
|
6
6
|
type ResultState =
|
|
7
7
|
| { status: 'idle' }
|
|
@@ -10,23 +10,23 @@ type ResultState =
|
|
|
10
10
|
| { status: 'error'; request: string; message: string };
|
|
11
11
|
|
|
12
12
|
const showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
13
|
-
const
|
|
13
|
+
const bardioc = useBardioc();
|
|
14
14
|
const notify = useNotify();
|
|
15
15
|
const result = ref<ResultState>({ status: 'idle' });
|
|
16
16
|
const running = ref(false);
|
|
17
17
|
|
|
18
18
|
async function runGetProfile() {
|
|
19
|
-
if (running.value) return;
|
|
19
|
+
if (running.value || !bardioc) return;
|
|
20
20
|
running.value = true;
|
|
21
21
|
|
|
22
|
-
const request = '
|
|
22
|
+
const request = 'os.profile.get()';
|
|
23
23
|
result.value = { status: 'loading', request };
|
|
24
24
|
|
|
25
25
|
const startTime = Date.now();
|
|
26
26
|
notify('Getting user profile…', 'info');
|
|
27
27
|
|
|
28
28
|
try {
|
|
29
|
-
const data = await
|
|
29
|
+
const data = await bardioc.os.profile.get();
|
|
30
30
|
|
|
31
31
|
const duration = Date.now() - startTime;
|
|
32
32
|
notify(`Profile loaded (${duration}ms).`, 'success');
|
|
@@ -44,7 +44,7 @@ function handleNotify() {
|
|
|
44
44
|
notify('Hello from {{DISPLAY_NAME}}.', 'info');
|
|
45
45
|
result.value = {
|
|
46
46
|
status: 'success',
|
|
47
|
-
request: '
|
|
47
|
+
request: 'ui.notify',
|
|
48
48
|
data: { ok: true, message: 'Notification sent to OS' },
|
|
49
49
|
};
|
|
50
50
|
}
|
|
@@ -110,7 +110,7 @@ function clearResult() {
|
|
|
110
110
|
<div class="text-muted-foreground border-border border-b pb-2 font-mono text-xs">
|
|
111
111
|
{{ result.request }}
|
|
112
112
|
</div>
|
|
113
|
-
<div class="text-destructive
|
|
113
|
+
<div class="text-destructive whitespace-pre-wrap break-all">{{ result.message }}</div>
|
|
114
114
|
</div>
|
|
115
115
|
<div
|
|
116
116
|
v-else-if="result.status === 'success'"
|
|
@@ -1,23 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Bardioc, NotifyLevel } from '@bardioc/app-sdk';
|
|
2
2
|
import { inject, type InjectionKey } from 'vue';
|
|
3
3
|
|
|
4
|
-
export const
|
|
4
|
+
export const BARDIOC_KEY: InjectionKey<Bardioc> = Symbol('bardioc');
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function useBardiocBridge(): HostBridge {
|
|
11
|
-
const bridge = inject(BARDIOC_BRIDGE_KEY);
|
|
12
|
-
if (!bridge) {
|
|
13
|
-
throw new Error('useBardiocBridge() must be used after providing BARDIOC_BRIDGE_KEY');
|
|
14
|
-
}
|
|
15
|
-
return bridge;
|
|
16
|
-
}
|
|
6
|
+
/** The host connection, or null while the app runs outside Bardioc. */
|
|
7
|
+
export const useBardioc = (): Bardioc | null => inject(BARDIOC_KEY, null);
|
|
17
8
|
|
|
18
9
|
export function useNotify() {
|
|
19
|
-
const
|
|
10
|
+
const bardioc = useBardioc();
|
|
20
11
|
return (message: string, level?: NotifyLevel) => {
|
|
21
|
-
|
|
12
|
+
bardioc?.ui.notify(message, level).catch(console.error);
|
|
22
13
|
};
|
|
23
14
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { connect } from '@bardioc/app-sdk';
|
|
2
|
+
import { installDevHost, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
2
3
|
import { createApp } from 'vue';
|
|
3
4
|
import App from './App.vue';
|
|
4
|
-
import {
|
|
5
|
+
import { BARDIOC_KEY } from './bardioc-sdk';
|
|
5
6
|
import './index.css';
|
|
6
7
|
|
|
7
8
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
@@ -15,13 +16,13 @@ const devStandalone = isDevStandalone();
|
|
|
15
16
|
const useSdkProvider = insideIframe || devStandalone;
|
|
16
17
|
|
|
17
18
|
if (devStandalone) {
|
|
18
|
-
|
|
19
|
+
installDevHost({ appId: APP_NAME });
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
const app = createApp(App);
|
|
22
23
|
|
|
23
24
|
if (useSdkProvider) {
|
|
24
|
-
app.provide(
|
|
25
|
+
app.provide(BARDIOC_KEY, await connect());
|
|
25
26
|
}
|
|
26
27
|
|
|
27
28
|
app.mount('#app');
|