@bardioc/create-bardioc-app 0.5.3 → 0.5.5
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/README.md +10 -13
- package/package.json +5 -5
- package/templates/angular/.env.example +6 -4
- package/templates/angular/public/runtime-env.js +1 -1
- package/templates/angular/scripts/dev-auth-proxy.mjs +6 -7
- package/templates/angular/scripts/sync-runtime-env.mjs +2 -24
- package/templates/angular/src/app/app.component.ts +4 -31
- package/templates/angular/src/app/bardioc-bridge.ts +3 -3
- package/templates/angular/src/index.html +2 -2
- package/templates/angular/src/main.ts +9 -43
- package/templates/angular/src/runtime-env.ts +1 -1
- package/templates/angular/src/styles.css +84 -80
- package/templates/angular/src/vite-env.d.ts +4 -6
- package/templates/manifest.json +2 -10
- package/templates/nextjs/.env.example +5 -6
- package/templates/nextjs/app/globals.css +31 -28
- package/templates/nextjs/app/page.tsx +17 -77
- package/templates/nextjs/global.d.ts +1 -1
- package/templates/nextjs/next.config.ts +27 -16
- package/templates/nextjs/package.json +2 -2
- package/templates/nextjs/tailwind.config.ts +1 -4
- package/templates/preact/.env.example +5 -9
- package/templates/preact/index.html +2 -2
- package/templates/preact/package.json +2 -2
- package/templates/preact/src/App.tsx +6 -5
- package/templates/preact/src/index.css +31 -28
- package/templates/preact/src/main.tsx +13 -29
- package/templates/preact/src/vite-env.d.ts +2 -4
- package/templates/solid/.env.example +5 -9
- package/templates/solid/index.html +2 -2
- package/templates/solid/package.json +2 -2
- package/templates/solid/src/App.tsx +6 -5
- package/templates/solid/src/bardioc-sdk.tsx +18 -18
- package/templates/solid/src/index.css +31 -28
- package/templates/solid/src/main.tsx +17 -33
- package/templates/solid/src/vite-env.d.ts +2 -4
- package/templates/svelte/.env.example +8 -4
- package/templates/svelte/index.html +2 -2
- package/templates/svelte/package.json +2 -2
- package/templates/svelte/src/App.svelte +1 -1
- package/templates/svelte/src/index.css +31 -28
- package/templates/svelte/src/main.ts +9 -25
- package/templates/svelte/src/vite-env.d.ts +2 -4
- package/templates/vite/.env.example +5 -10
- package/templates/vite/CLAUDE.md +8 -10
- package/templates/vite/index.html +2 -2
- package/templates/vite/package.json +2 -4
- package/templates/vite/src/App.tsx +1 -2
- package/templates/vite/src/auth/onboarding.tsx +5 -7
- package/templates/vite/src/climate/conditions-chart.tsx +6 -8
- package/templates/vite/src/events/live-events-view.tsx +1 -3
- package/templates/vite/src/i18n.tsx +7 -9
- package/templates/vite/src/locales/de.json +2 -3
- package/templates/vite/src/locales/en.json +2 -3
- package/templates/vite/src/main.tsx +18 -35
- package/templates/vite/src/shell/header.tsx +1 -2
- package/templates/vite/src/vite-env.d.ts +0 -2
- package/templates/vue/.env.example +8 -4
- package/templates/vue/index.html +2 -2
- package/templates/vue/package.json +2 -2
- package/templates/vue/src/App.vue +26 -10
- package/templates/vue/src/bardioc-sdk.ts +11 -11
- package/templates/vue/src/index.css +31 -28
- package/templates/vue/src/main.ts +8 -24
- package/templates/vue/src/vite-env.d.ts +2 -4
- package/templates/nextjs/app/proxy/route.ts +0 -85
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
let { bridge = null, children }: { bridge?: HostBridge | null; children?: Snippet } = $props();
|
|
14
14
|
|
|
15
|
-
const showSdkDemo = isInsideIframe() ||
|
|
15
|
+
const showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
16
16
|
|
|
17
17
|
let result = $state<ResultState>({ status: 'idle' });
|
|
18
18
|
let running = $state(false);
|
|
@@ -1,76 +1,79 @@
|
|
|
1
1
|
@import 'tailwindcss';
|
|
2
2
|
|
|
3
3
|
* {
|
|
4
|
-
|
|
4
|
+
box-sizing: border-box;
|
|
5
5
|
}
|
|
6
6
|
|
|
7
7
|
html,
|
|
8
8
|
body,
|
|
9
9
|
#app {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
10
|
+
margin: 0;
|
|
11
|
+
padding: 0;
|
|
12
|
+
height: 100%;
|
|
13
|
+
width: 100%;
|
|
14
|
+
overflow: hidden;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
:root {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
18
|
+
--background: oklch(17.88% 0.0075 229.38);
|
|
19
|
+
--foreground: oklch(98.69% 0.0093 99.98);
|
|
20
|
+
--muted-foreground: oklch(86.03% 0.0056 95.11);
|
|
21
|
+
--border: oklch(1 0 0 / 10%);
|
|
22
|
+
--primary: oklch(97.02% 0 0);
|
|
23
|
+
--primary-foreground: oklch(36.94% 0.0053 236.64);
|
|
24
|
+
--destructive: oklch(68.04% 0.1386 21.38);
|
|
25
|
+
--ring: oklch(79.43% 0.0084 98.91);
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
body {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
background: var(--background);
|
|
30
|
+
color: var(--foreground);
|
|
31
|
+
font-family:
|
|
32
|
+
system-ui,
|
|
33
|
+
-apple-system,
|
|
34
|
+
sans-serif;
|
|
32
35
|
}
|
|
33
36
|
|
|
34
37
|
code {
|
|
35
|
-
|
|
38
|
+
font-family: inherit;
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
.bg-background {
|
|
39
|
-
|
|
42
|
+
background-color: var(--background);
|
|
40
43
|
}
|
|
41
44
|
|
|
42
45
|
.text-foreground {
|
|
43
|
-
|
|
46
|
+
color: var(--foreground);
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
.text-muted-foreground {
|
|
47
|
-
|
|
50
|
+
color: var(--muted-foreground);
|
|
48
51
|
}
|
|
49
52
|
|
|
50
53
|
.border-border {
|
|
51
|
-
|
|
54
|
+
border-color: var(--border);
|
|
52
55
|
}
|
|
53
56
|
|
|
54
57
|
.bg-primary {
|
|
55
|
-
|
|
58
|
+
background-color: var(--primary);
|
|
56
59
|
}
|
|
57
60
|
|
|
58
61
|
.text-primary-foreground {
|
|
59
|
-
|
|
62
|
+
color: var(--primary-foreground);
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
.text-destructive {
|
|
63
|
-
|
|
66
|
+
color: var(--destructive);
|
|
64
67
|
}
|
|
65
68
|
|
|
66
69
|
.focus\:ring-ring:focus {
|
|
67
|
-
|
|
70
|
+
--tw-ring-color: var(--ring);
|
|
68
71
|
}
|
|
69
72
|
|
|
70
73
|
.hover\:bg-primary\/90:hover {
|
|
71
|
-
|
|
74
|
+
background-color: oklch(from var(--primary) calc(l * 0.9) c h);
|
|
72
75
|
}
|
|
73
76
|
|
|
74
77
|
.hover\:text-foreground:hover {
|
|
75
|
-
|
|
78
|
+
color: var(--foreground);
|
|
76
79
|
}
|
|
@@ -1,42 +1,26 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
|
-
installDevBridge,
|
|
4
|
-
isDevStandalone,
|
|
5
|
-
isInsideIframe,
|
|
6
|
-
} from '@bardioc/app-sdk/dev';
|
|
7
1
|
import { createHostBridge } from '@bardioc/app-sdk';
|
|
2
|
+
import { installDevBridge, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
8
3
|
import { mount } from 'svelte';
|
|
9
4
|
import App from './App.svelte';
|
|
10
5
|
import './index.css';
|
|
11
6
|
|
|
12
7
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
13
|
-
const APP_ID = import.meta.env.VITE_APP_ID?.trim();
|
|
14
|
-
const standaloneDevAuthEnabled = import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
15
8
|
|
|
16
9
|
if (!APP_NAME) {
|
|
17
10
|
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
18
11
|
}
|
|
19
12
|
|
|
20
13
|
const insideIframe = isInsideIframe();
|
|
21
|
-
const devStandalone =
|
|
14
|
+
const devStandalone = isDevStandalone();
|
|
22
15
|
const useSdkProvider = insideIframe || devStandalone;
|
|
23
16
|
|
|
24
|
-
if (
|
|
25
|
-
|
|
17
|
+
if (devStandalone) {
|
|
18
|
+
installDevBridge({ debug: false });
|
|
26
19
|
}
|
|
27
20
|
|
|
28
|
-
|
|
29
|
-
if (devStandalone) {
|
|
30
|
-
await ensureDevAuthSession({ appId: APP_ID, appName: APP_NAME });
|
|
31
|
-
installDevBridge({ appId: APP_ID, appName: APP_NAME, debug: false });
|
|
32
|
-
}
|
|
21
|
+
const bridge = useSdkProvider ? createHostBridge({ appId: APP_NAME }) : null;
|
|
33
22
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
props: { bridge },
|
|
39
|
-
});
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
bootstrap();
|
|
23
|
+
mount(App, {
|
|
24
|
+
target: document.getElementById('app')!,
|
|
25
|
+
props: { bridge },
|
|
26
|
+
});
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
/// <reference types="vite/client" />
|
|
2
2
|
|
|
3
3
|
interface ImportMetaEnv {
|
|
4
|
-
readonly VITE_APP_NAME: string
|
|
5
|
-
readonly VITE_APP_ID: string
|
|
6
|
-
readonly VITE_ENABLE_DEV_AUTH?: string
|
|
4
|
+
readonly VITE_APP_NAME: string;
|
|
7
5
|
}
|
|
8
6
|
|
|
9
7
|
interface ImportMeta {
|
|
10
|
-
readonly env: ImportMetaEnv
|
|
8
|
+
readonly env: ImportMetaEnv;
|
|
11
9
|
}
|
|
@@ -1,14 +1,9 @@
|
|
|
1
1
|
# Hosted app slug used by local runtime/dev-auth wiring.
|
|
2
2
|
VITE_APP_NAME={{APP_NAME}}
|
|
3
3
|
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
|
|
4
|
+
# Paste the dev secret from the BardiocOS AppStore after registering your app.
|
|
5
|
+
# Used by the Vite dev-auth proxy to sign requests to the BFF.
|
|
6
|
+
DEV_SECRET=
|
|
7
7
|
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
# Required host URL for standalone dev auth. Run `bardioc login` once, then
|
|
12
|
-
# `npm run dev` will refresh DEV_SESSION_KEY automatically before Vite starts.
|
|
13
|
-
DEV_AUTH_HOST_URL=
|
|
14
|
-
DEV_SESSION_KEY=
|
|
8
|
+
# Base URL of the Bardioc BFF / backend-for-frontend (e.g. https://your-host).
|
|
9
|
+
API_BASE_URL=
|
package/templates/vite/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# {{DISPLAY_NAME}}
|
|
2
2
|
|
|
3
3
|
Bardioc hosted app. Vite + React 19 + TypeScript 6 + `@bardioc/app-sdk`, with
|
|
4
|
-
`@bardioc/ui` (components + theme)
|
|
4
|
+
`@bardioc/ui` (components + theme) and `@bardioc/i18n-core` (translations).
|
|
5
5
|
|
|
6
6
|
The starter ships a **Climate Dashboard** — a worked example of how a real Bardioc app
|
|
7
7
|
is wired: a sidebar shell with multiple views, `@bardioc/ui` components (cards, metrics,
|
|
@@ -33,7 +33,7 @@ src/
|
|
|
33
33
|
dashboard-provider.tsx # context: climate state + profile, via useDashboard()
|
|
34
34
|
use-app-notify.ts # OS host notification (useNotify) mirrored to a local toast
|
|
35
35
|
auth/
|
|
36
|
-
onboarding.tsx # Empty full-page screen with the
|
|
36
|
+
onboarding.tsx # Empty full-page screen with the DEV_SECRET dev-auth steps
|
|
37
37
|
shell/
|
|
38
38
|
app-shell.tsx # Sidebar + view routing + Toaster + OS top-menu integration (useCommandMenu)
|
|
39
39
|
about-dialog.tsx # "About" Dialog — reads public/app-manifest.json at runtime (manifest example)
|
|
@@ -75,8 +75,8 @@ pnpm bundle # → {{APP_NAME}}.zip
|
|
|
75
75
|
```
|
|
76
76
|
|
|
77
77
|
`npm run dev` runs plain Vite — a local preview shell (no transport): the dashboard renders, but
|
|
78
|
-
live SDK data comes only when the app is opened inside the host
|
|
79
|
-
`
|
|
78
|
+
live SDK data comes only when the app is opened inside the host, or when `DEV_SECRET` and
|
|
79
|
+
`API_BASE_URL` are set for standalone dev auth (see `.env.example`).
|
|
80
80
|
|
|
81
81
|
---
|
|
82
82
|
|
|
@@ -127,9 +127,9 @@ OS windows); the language switcher is `ConnectedLanguageSwitcher useI18n={useI18
|
|
|
127
127
|
|
|
128
128
|
---
|
|
129
129
|
|
|
130
|
-
## i18n — `@bardioc/i18n`
|
|
130
|
+
## i18n — `@bardioc/i18n-core`
|
|
131
131
|
|
|
132
|
-
All user-facing strings go through `t()`. Locales: `en`, `de` (
|
|
132
|
+
All user-facing strings go through `t()`. Locales: `en`, `de` (defined in `src/i18n.tsx`).
|
|
133
133
|
|
|
134
134
|
```typescript
|
|
135
135
|
import { useTranslation } from './i18n';
|
|
@@ -143,10 +143,8 @@ t('overview.updated', { fallback: 'Updated {time}', params: { time } });
|
|
|
143
143
|
- `AppI18nProvider syncWithOs` follows the OS language (`useOsConfig().language`); the header's
|
|
144
144
|
`ConnectedLanguageSwitcher` lets the user switch it manually.
|
|
145
145
|
- Always pass a `fallback` so a missing key degrades gracefully.
|
|
146
|
-
- `@bardioc/ui`
|
|
147
|
-
|
|
148
|
-
the app locales: `common.button.previous/next` and the `genericTable.*` set (DataTable pagination
|
|
149
|
-
"1 to 5 of 5", Previous/Next). Without them those strings silently fall back to English.
|
|
146
|
+
- `@bardioc/ui` component strings ship with the `@bardioc/ui` package itself — the app only
|
|
147
|
+
carries its own `en/de.json`.
|
|
150
148
|
|
|
151
149
|
---
|
|
152
150
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<!
|
|
2
|
-
<html lang="en" class="dark" style="height: 100%; margin: 0">
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" class="dark" style="height: 100%; margin: 0; color-scheme: dark">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"dev": "vite",
|
|
8
|
-
"dev:live": "BARDIOC_TUNNEL=1 vite",
|
|
9
8
|
"build": "tsc && vite build && node scripts/stamp-manifest.mjs dist",
|
|
10
9
|
"bundle": "rm -f {{APP_NAME}}.zip && tsc && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
11
10
|
"preview": "vite preview",
|
|
@@ -17,9 +16,8 @@
|
|
|
17
16
|
},
|
|
18
17
|
"dependencies": {
|
|
19
18
|
"@bardioc/app-sdk": "latest",
|
|
20
|
-
"@bardioc/i18n": "
|
|
21
|
-
"@bardioc/
|
|
22
|
-
"@bardioc/ui": "^0.2.11",
|
|
19
|
+
"@bardioc/i18n-core": "latest",
|
|
20
|
+
"@bardioc/ui": "latest",
|
|
23
21
|
"lucide-react": "^0.544.0",
|
|
24
22
|
"react": "19.2.6",
|
|
25
23
|
"react-dom": "19.2.6"
|
|
@@ -4,8 +4,7 @@ import { DashboardProvider } from './dashboard-provider';
|
|
|
4
4
|
import { AppShell } from './shell/app-shell';
|
|
5
5
|
|
|
6
6
|
export function App() {
|
|
7
|
-
const authorized =
|
|
8
|
-
isInsideIframe() || (import.meta.env.VITE_ENABLE_DEV_AUTH === 'true' && isDevStandalone());
|
|
7
|
+
const authorized = isInsideIframe() || isDevStandalone();
|
|
9
8
|
|
|
10
9
|
if (!authorized) {
|
|
11
10
|
return <Onboarding />;
|
|
@@ -18,7 +18,6 @@ function DetectedRow({ label, ok }: Readonly<{ label: string; ok: boolean }>) {
|
|
|
18
18
|
export function Onboarding() {
|
|
19
19
|
const { t } = useTranslation();
|
|
20
20
|
const insideHost = isInsideIframe();
|
|
21
|
-
const devAuth = import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
22
21
|
|
|
23
22
|
return (
|
|
24
23
|
<Empty
|
|
@@ -38,16 +37,16 @@ export function Onboarding() {
|
|
|
38
37
|
>
|
|
39
38
|
<div className="border-border bg-card mt-4 w-full max-w-md rounded-lg border p-4 text-left text-xs leading-6">
|
|
40
39
|
<p className="text-foreground mb-2 font-medium">
|
|
41
|
-
{t('auth.stepsTitle', { fallback: 'Run standalone with
|
|
40
|
+
{t('auth.stepsTitle', { fallback: 'Run standalone with dev auth:' })}
|
|
42
41
|
</p>
|
|
43
42
|
<ol className="text-muted-foreground list-decimal space-y-2 pl-4">
|
|
44
|
-
<li>{t('auth.step1', { fallback: 'Set VITE_ENABLE_DEV_AUTH=true in .env' })}</li>
|
|
45
43
|
<li>
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
{t('auth.step1', {
|
|
45
|
+
fallback: 'Set DEV_SECRET=<your-secret> and API_BASE_URL=<your-host> in .env',
|
|
46
|
+
})}
|
|
48
47
|
</li>
|
|
49
48
|
<li>
|
|
50
|
-
<div>{t('auth.
|
|
49
|
+
<div>{t('auth.step2', { fallback: 'Start the dev server:' })}</div>
|
|
51
50
|
<Kbd>pnpm dev</Kbd>
|
|
52
51
|
</li>
|
|
53
52
|
</ol>
|
|
@@ -59,7 +58,6 @@ export function Onboarding() {
|
|
|
59
58
|
label={t('auth.insideHost', { fallback: 'Inside host iframe' })}
|
|
60
59
|
ok={insideHost}
|
|
61
60
|
/>
|
|
62
|
-
<DetectedRow label={t('auth.devAuth', { fallback: 'Dev auth enabled' })} ok={devAuth} />
|
|
63
61
|
</div>
|
|
64
62
|
</div>
|
|
65
63
|
</Empty>
|
|
@@ -16,14 +16,12 @@ export function ConditionsChart({ forecast }: Readonly<ConditionsChartProps>) {
|
|
|
16
16
|
rainy: { label: t('conditions.rainy', { fallback: 'Rainy' }), color: 'var(--chart-1)' },
|
|
17
17
|
};
|
|
18
18
|
|
|
19
|
-
const seriesData = forecast.map(
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
})
|
|
26
|
-
);
|
|
19
|
+
const seriesData = forecast.map((entry): Record<string, string | number> => ({
|
|
20
|
+
day: entry.day,
|
|
21
|
+
sunny: entry.sunny,
|
|
22
|
+
cloudy: entry.cloudy,
|
|
23
|
+
rainy: entry.rainy,
|
|
24
|
+
}));
|
|
27
25
|
|
|
28
26
|
return (
|
|
29
27
|
<BarChartMultiple
|
|
@@ -24,9 +24,7 @@ export function LiveEventsView() {
|
|
|
24
24
|
return (
|
|
25
25
|
<div className="flex h-full min-w-0 flex-col gap-3">
|
|
26
26
|
<div>
|
|
27
|
-
<h2 className="text-lg font-semibold">
|
|
28
|
-
{t('events.title', { fallback: 'Live Events' })}
|
|
29
|
-
</h2>
|
|
27
|
+
<h2 className="text-lg font-semibold">{t('events.title', { fallback: 'Live Events' })}</h2>
|
|
30
28
|
<p className="text-muted-foreground text-xs">
|
|
31
29
|
{t('events.description', {
|
|
32
30
|
fallback: 'Live graph events streamed from the OS over SSE (permission "events").',
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { useOsConfig } from '@bardioc/app-sdk/react';
|
|
2
2
|
import {
|
|
3
3
|
I18nProvider as BaseI18nProvider,
|
|
4
|
-
mergeTranslations,
|
|
5
4
|
useI18n,
|
|
6
5
|
type I18nConfig,
|
|
7
6
|
type TranslationMessages,
|
|
8
|
-
} from '@bardioc/i18n';
|
|
9
|
-
import { deMessages as baseDe, enMessages as baseEn } from '@bardioc/i18n/translations';
|
|
10
|
-
import { SUPPORTED_LOCALES, type Locale } from '@bardioc/types';
|
|
7
|
+
} from '@bardioc/i18n-core';
|
|
11
8
|
import { useEffect, useMemo, type ReactNode } from 'react';
|
|
12
9
|
import deMessages from './locales/de.json';
|
|
13
10
|
import enMessages from './locales/en.json';
|
|
14
11
|
|
|
15
|
-
|
|
16
|
-
|
|
12
|
+
export const SUPPORTED_LOCALES = ['en', 'de'] as const;
|
|
13
|
+
export type Locale = (typeof SUPPORTED_LOCALES)[number];
|
|
14
|
+
|
|
17
15
|
const DEFAULT_MESSAGES: Record<Locale, TranslationMessages> = {
|
|
18
|
-
en:
|
|
19
|
-
de:
|
|
16
|
+
en: enMessages,
|
|
17
|
+
de: deMessages,
|
|
20
18
|
};
|
|
21
19
|
|
|
22
20
|
const STORAGE_KEY = '{{APP_NAME}}.locale';
|
|
@@ -65,4 +63,4 @@ export function AppI18nProvider({ children, syncWithOs = false }: Readonly<AppI1
|
|
|
65
63
|
);
|
|
66
64
|
}
|
|
67
65
|
|
|
68
|
-
export { useI18n, useTranslation } from '@bardioc/i18n';
|
|
66
|
+
export { useI18n, useTranslation } from '@bardioc/i18n-core';
|
|
@@ -42,9 +42,8 @@
|
|
|
42
42
|
"title": "Mit Bardioc OS verbinden",
|
|
43
43
|
"description": "Dieses Dashboard liest Live-Daten über den Bardioc-SDK-Transport. Es läuft in Bardioc OS oder eigenständig mit einer CLI-Dev-Session.",
|
|
44
44
|
"stepsTitle": "Eigenständig mit Dev-Session ausführen:",
|
|
45
|
-
"step1": "Setze
|
|
46
|
-
"step2": "
|
|
47
|
-
"step3": "Dev-Server starten — der Session-Key wird automatisch erzeugt und erneuert:",
|
|
45
|
+
"step1": "Setze DEV_SECRET=<dein-secret> und API_BASE_URL=<dein-host> in .env",
|
|
46
|
+
"step2": "Dev-Server starten:",
|
|
48
47
|
"detectedTitle": "Erkannte Umgebung",
|
|
49
48
|
"insideHost": "Im Host-Iframe",
|
|
50
49
|
"devAuth": "Dev-Auth aktiviert",
|
|
@@ -42,9 +42,8 @@
|
|
|
42
42
|
"title": "Connect to Bardioc OS",
|
|
43
43
|
"description": "This dashboard reads live data through the Bardioc SDK transport. It runs when opened inside Bardioc OS, or standalone with a CLI dev session.",
|
|
44
44
|
"stepsTitle": "Run standalone with a dev session:",
|
|
45
|
-
"step1": "Set
|
|
46
|
-
"step2": "
|
|
47
|
-
"step3": "Start the dev server — the session key is minted and refreshed automatically:",
|
|
45
|
+
"step1": "Set DEV_SECRET=<your-secret> and API_BASE_URL=<your-host> in .env",
|
|
46
|
+
"step2": "Start the dev server:",
|
|
48
47
|
"detectedTitle": "Detected environment",
|
|
49
48
|
"insideHost": "Inside host iframe",
|
|
50
49
|
"devAuth": "Dev auth enabled",
|
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
ensureDevAuthSession,
|
|
3
|
-
installDevBridge,
|
|
4
|
-
isDevStandalone,
|
|
5
|
-
isInsideIframe,
|
|
6
|
-
} from '@bardioc/app-sdk/dev';
|
|
1
|
+
import { installDevBridge, isDevStandalone, isInsideIframe } from '@bardioc/app-sdk/dev';
|
|
7
2
|
import { AppSdkProvider } from '@bardioc/app-sdk/react';
|
|
8
3
|
import { StrictMode } from 'react';
|
|
9
4
|
import { createRoot } from 'react-dom/client';
|
|
@@ -12,43 +7,31 @@ import { AppI18nProvider } from './i18n';
|
|
|
12
7
|
import './index.css';
|
|
13
8
|
|
|
14
9
|
const APP_NAME = import.meta.env.VITE_APP_NAME?.trim();
|
|
15
|
-
const APP_ID = import.meta.env.VITE_APP_ID?.trim();
|
|
16
|
-
const standaloneDevAuthEnabled =
|
|
17
|
-
import.meta.env.DEV && import.meta.env.VITE_ENABLE_DEV_AUTH === 'true';
|
|
18
10
|
|
|
19
11
|
if (!APP_NAME) {
|
|
20
12
|
throw new Error('Missing VITE_APP_NAME for runtime');
|
|
21
13
|
}
|
|
22
14
|
|
|
23
15
|
const insideIframe = isInsideIframe();
|
|
24
|
-
const devStandalone =
|
|
16
|
+
const devStandalone = isDevStandalone();
|
|
25
17
|
const useSdkProvider = insideIframe || devStandalone;
|
|
26
|
-
const SDK_APP_ID = APP_ID ?? APP_NAME;
|
|
27
18
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
throw new Error('Missing VITE_APP_ID for standalone dev auth');
|
|
32
|
-
}
|
|
33
|
-
await ensureDevAuthSession({ appId: APP_ID, appName: APP_NAME });
|
|
34
|
-
installDevBridge({ appId: APP_ID, appName: APP_NAME, debug: false });
|
|
35
|
-
}
|
|
19
|
+
if (devStandalone) {
|
|
20
|
+
installDevBridge({ debug: false });
|
|
21
|
+
}
|
|
36
22
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
<App />
|
|
43
|
-
</AppI18nProvider>
|
|
44
|
-
</AppSdkProvider>
|
|
45
|
-
) : (
|
|
46
|
-
<AppI18nProvider>
|
|
23
|
+
createRoot(document.getElementById('root')!).render(
|
|
24
|
+
<StrictMode>
|
|
25
|
+
{useSdkProvider ? (
|
|
26
|
+
<AppSdkProvider appId={APP_NAME}>
|
|
27
|
+
<AppI18nProvider syncWithOs>
|
|
47
28
|
<App />
|
|
48
29
|
</AppI18nProvider>
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
30
|
+
</AppSdkProvider>
|
|
31
|
+
) : (
|
|
32
|
+
<AppI18nProvider>
|
|
33
|
+
<App />
|
|
34
|
+
</AppI18nProvider>
|
|
35
|
+
)}
|
|
36
|
+
</StrictMode>
|
|
37
|
+
);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { SUPPORTED_LOCALES } from '@bardioc/types';
|
|
2
1
|
import { Button, ConnectedLanguageSwitcher } from '@bardioc/ui/components';
|
|
3
2
|
import { RefreshCw } from 'lucide-react';
|
|
4
3
|
import { LocationSelect } from '../climate/location-select';
|
|
5
4
|
import { useDashboard } from '../dashboard-provider';
|
|
6
|
-
import { useI18n, useTranslation } from '../i18n';
|
|
5
|
+
import { SUPPORTED_LOCALES, useI18n, useTranslation } from '../i18n';
|
|
7
6
|
|
|
8
7
|
export function Header() {
|
|
9
8
|
const { t } = useTranslation();
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
# Hosted app slug used by local runtime/dev-auth wiring.
|
|
1
2
|
VITE_APP_NAME={{APP_NAME}}
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
|
|
4
|
+
# Paste the dev secret from the BardiocOS AppStore after registering your app.
|
|
5
|
+
# Used by the Vite dev-auth proxy to sign requests to the BFF.
|
|
6
|
+
DEV_SECRET=
|
|
7
|
+
|
|
8
|
+
# Base URL of the Bardioc BFF / backend-for-frontend (e.g. https://your-host).
|
|
9
|
+
API_BASE_URL=
|
package/templates/vue/index.html
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
<!
|
|
2
|
-
<html lang="en" class="dark" style="height: 100%; margin: 0">
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en" class="dark" style="height: 100%; margin: 0; color-scheme: dark">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
"private": true,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"scripts": {
|
|
7
|
-
"dev": "
|
|
8
|
-
"dev:live": "BARDIOC_TUNNEL=1
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"dev:live": "BARDIOC_TUNNEL=1 vite",
|
|
9
9
|
"build": "vue-tsc -b && vite build && node scripts/stamp-manifest.mjs dist",
|
|
10
10
|
"bundle": "vue-tsc -b && vite build && node scripts/stamp-manifest.mjs dist && cd dist && zip -r ../{{APP_NAME}}.zip .",
|
|
11
11
|
"preview": "vite preview",
|
|
@@ -9,7 +9,7 @@ type ResultState =
|
|
|
9
9
|
| { status: 'success'; request: string; data: unknown }
|
|
10
10
|
| { status: 'error'; request: string; message: string };
|
|
11
11
|
|
|
12
|
-
const showSdkDemo = isInsideIframe() ||
|
|
12
|
+
const showSdkDemo = isInsideIframe() || isDevStandalone();
|
|
13
13
|
const bridge = useBardiocBridge();
|
|
14
14
|
const notify = useNotify();
|
|
15
15
|
const result = ref<ResultState>({ status: 'idle' });
|
|
@@ -67,14 +67,14 @@ function clearResult() {
|
|
|
67
67
|
|
|
68
68
|
<div class="flex flex-wrap gap-2">
|
|
69
69
|
<button
|
|
70
|
-
class="bg-primary text-primary-foreground hover:bg-primary/90
|
|
70
|
+
class="bg-primary text-primary-foreground hover:bg-primary/90 rounded px-3 py-1 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50"
|
|
71
71
|
@click="runGetProfile"
|
|
72
72
|
:disabled="running"
|
|
73
73
|
>
|
|
74
74
|
Get Profile
|
|
75
75
|
</button>
|
|
76
76
|
<button
|
|
77
|
-
class="bg-primary text-primary-foreground hover:bg-primary/90
|
|
77
|
+
class="bg-primary text-primary-foreground hover:bg-primary/90 rounded px-3 py-1 text-xs font-medium disabled:cursor-not-allowed disabled:opacity-50"
|
|
78
78
|
@click="handleNotify"
|
|
79
79
|
:disabled="running"
|
|
80
80
|
>
|
|
@@ -89,11 +89,20 @@ function clearResult() {
|
|
|
89
89
|
</button>
|
|
90
90
|
</div>
|
|
91
91
|
|
|
92
|
-
<div
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
<div
|
|
93
|
+
class="border-border bg-background flex min-h-0 flex-1 flex-col overflow-hidden rounded border"
|
|
94
|
+
>
|
|
95
|
+
<div
|
|
96
|
+
v-if="result.status === 'idle'"
|
|
97
|
+
class="text-muted-foreground flex h-full items-center justify-center p-3 text-center text-xs leading-5"
|
|
98
|
+
>
|
|
99
|
+
Run a query to see results. If the host session is missing, the transport route will
|
|
100
|
+
return 401.
|
|
95
101
|
</div>
|
|
96
|
-
<div
|
|
102
|
+
<div
|
|
103
|
+
v-else-if="result.status === 'loading'"
|
|
104
|
+
class="flex h-full flex-col items-center justify-center gap-2 p-3"
|
|
105
|
+
>
|
|
97
106
|
<div class="text-muted-foreground font-mono text-xs">{{ result.request }}</div>
|
|
98
107
|
<div class="text-muted-foreground text-xs">Loading…</div>
|
|
99
108
|
</div>
|
|
@@ -103,11 +112,18 @@ function clearResult() {
|
|
|
103
112
|
</div>
|
|
104
113
|
<div class="text-destructive whitespace-pre-wrap break-all">{{ result.message }}</div>
|
|
105
114
|
</div>
|
|
106
|
-
<div
|
|
107
|
-
|
|
115
|
+
<div
|
|
116
|
+
v-else-if="result.status === 'success'"
|
|
117
|
+
class="flex h-full flex-col gap-0 overflow-hidden"
|
|
118
|
+
>
|
|
119
|
+
<div
|
|
120
|
+
class="border-border text-muted-foreground shrink-0 border-b px-3 py-1 font-mono text-xs"
|
|
121
|
+
>
|
|
108
122
|
{{ result.request }}
|
|
109
123
|
</div>
|
|
110
|
-
<pre class="text-foreground flex-1 overflow-auto p-3 text-[11px] leading-5">{{
|
|
124
|
+
<pre class="text-foreground flex-1 overflow-auto p-3 text-[11px] leading-5">{{
|
|
125
|
+
JSON.stringify(result.data, null, 2)
|
|
126
|
+
}}</pre>
|
|
111
127
|
</div>
|
|
112
128
|
</div>
|
|
113
129
|
</div>
|