@ramme-io/create-app 1.1.1 → 1.1.2
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/template/package-lock.json +11 -2838
- package/template/src/adaptors/.gitkeep +0 -0
- package/template/src/components/AppHeader.tsx +1 -1
- package/template/src/config/app.manifest.ts +48 -79
- package/template/src/config/navigation.ts +86 -0
- package/template/src/templates/settings/SettingsLayout.tsx +1 -1
- package/template/src/types/schema.ts +75 -13
|
File without changes
|
|
@@ -22,7 +22,7 @@ import {
|
|
|
22
22
|
import { useAuth } from '../contexts/AuthContext';
|
|
23
23
|
|
|
24
24
|
// --- STRATEGIC IMPORTS ---
|
|
25
|
-
import { appManifest } from '../config/
|
|
25
|
+
import { appManifest } from '../config/navigation';
|
|
26
26
|
import type { ManifestLink } from '../core/manifest-types';
|
|
27
27
|
import TemplateSwitcher from './TemplateSwitcher';
|
|
28
28
|
import rammeLogo from '../assets/orange.png'; // <-- 1. IMPORT THE LOGO
|
|
@@ -1,86 +1,55 @@
|
|
|
1
|
+
import type { AppSpecification } from '../types/schema';
|
|
2
|
+
|
|
1
3
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* This is the
|
|
6
|
-
*
|
|
4
|
+
* ------------------------------------------------------------------
|
|
5
|
+
* THE APP MANIFEST (The "Brain")
|
|
6
|
+
* ------------------------------------------------------------------
|
|
7
|
+
* This file is the Single Source of Truth for the application's
|
|
8
|
+
* domain logic. It defines the signals (data), entities (things),
|
|
9
|
+
* and global configuration.
|
|
10
|
+
* * In the "App Builder" workflow, this file is programmatically
|
|
11
|
+
* generated by the AI Assistant.
|
|
7
12
|
*/
|
|
8
|
-
import type { ManifestLink } from '../core/manifest-types';
|
|
9
13
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
14
|
+
export const appManifest: AppSpecification = {
|
|
15
|
+
meta: {
|
|
16
|
+
name: "My Ramme App",
|
|
17
|
+
version: "0.1.0",
|
|
18
|
+
description: "A prototype application generated by Ramme.",
|
|
19
|
+
author: "Ramme User",
|
|
20
|
+
createdAt: new Date().toISOString(),
|
|
21
|
+
},
|
|
15
22
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
//
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
{
|
|
31
|
-
id: 'user.settings',
|
|
32
|
-
// --- FIX: Point to the settings layout base ---
|
|
33
|
-
path: '/settings', // Correct path
|
|
34
|
-
title: 'Settings',
|
|
35
|
-
icon: 'settings',
|
|
36
|
-
},
|
|
37
|
-
// --- REMOVED: Logout link is redundant ---
|
|
38
|
-
// {
|
|
39
|
-
// id: 'user.logout',
|
|
40
|
-
// path: '/login', // Was pointing here, but onClick is better
|
|
41
|
-
// title: 'Log Out',
|
|
42
|
-
// icon: 'logOut',
|
|
43
|
-
// },
|
|
44
|
-
],
|
|
23
|
+
// The Data Layer
|
|
24
|
+
domain: {
|
|
25
|
+
// 1. Signals: The raw data points (Sensors, Statuses, Commands)
|
|
26
|
+
signals: [
|
|
27
|
+
// Example placeholder:
|
|
28
|
+
// {
|
|
29
|
+
// id: 'temp_01',
|
|
30
|
+
// label: 'Living Room Temp',
|
|
31
|
+
// kind: 'sensor',
|
|
32
|
+
// source: 'mock',
|
|
33
|
+
// unit: '°C',
|
|
34
|
+
// defaultValue: 22
|
|
35
|
+
// }
|
|
36
|
+
],
|
|
45
37
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
{
|
|
58
|
-
id: 'settings.billing',
|
|
59
|
-
path: '/settings/billing',
|
|
60
|
-
title: 'Billing',
|
|
61
|
-
icon: 'creditCard',
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
id: 'settings.team',
|
|
65
|
-
path: '/settings/team',
|
|
66
|
-
title: 'Team Members',
|
|
67
|
-
icon: 'users',
|
|
68
|
-
},
|
|
69
|
-
],
|
|
38
|
+
// 2. Entities: The logical groupings (Devices, Rooms, Systems)
|
|
39
|
+
entities: [
|
|
40
|
+
// Example placeholder:
|
|
41
|
+
// {
|
|
42
|
+
// id: 'dev_thermostat',
|
|
43
|
+
// name: 'Smart Thermostat',
|
|
44
|
+
// type: 'device',
|
|
45
|
+
// signals: ['temp_01']
|
|
46
|
+
// }
|
|
47
|
+
],
|
|
48
|
+
},
|
|
70
49
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
id: 'footer.help',
|
|
77
|
-
path: '/help',
|
|
78
|
-
title: 'Help Center',
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
id: 'footer.terms',
|
|
82
|
-
path: '/terms',
|
|
83
|
-
title: 'Terms of Service',
|
|
84
|
-
},
|
|
85
|
-
],
|
|
50
|
+
// Global Config
|
|
51
|
+
config: {
|
|
52
|
+
theme: 'system',
|
|
53
|
+
mockMode: true, // Default to "Mock Mode" for instant prototyping
|
|
54
|
+
},
|
|
86
55
|
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file navigation.ts
|
|
3
|
+
* @repository ramme-app-starter
|
|
4
|
+
* @description
|
|
5
|
+
* This is the central manifest for all GLOBAL, shared navigation elements.
|
|
6
|
+
* Corrected paths to point within the /settings layout.
|
|
7
|
+
*/
|
|
8
|
+
import type { ManifestLink } from '../core/manifest-types';
|
|
9
|
+
|
|
10
|
+
interface AppManifest {
|
|
11
|
+
userMenu: ManifestLink[];
|
|
12
|
+
settingsMenu: ManifestLink[];
|
|
13
|
+
footerLinks: ManifestLink[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export const appManifest: AppManifest = {
|
|
17
|
+
/**
|
|
18
|
+
* Used for the user dropdown menu in the AppHeader.
|
|
19
|
+
* NOTE: Logout is handled by the onClick={logout} in AppHeader,
|
|
20
|
+
* so it's removed from this manifest.
|
|
21
|
+
*/
|
|
22
|
+
userMenu: [
|
|
23
|
+
{
|
|
24
|
+
id: 'user.profile',
|
|
25
|
+
// --- FIX: Point to the settings layout ---
|
|
26
|
+
path: '/settings/profile', // Correct path
|
|
27
|
+
title: 'Your Profile',
|
|
28
|
+
icon: 'user',
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
id: 'user.settings',
|
|
32
|
+
// --- FIX: Point to the settings layout base ---
|
|
33
|
+
path: '/settings', // Correct path
|
|
34
|
+
title: 'Settings',
|
|
35
|
+
icon: 'settings',
|
|
36
|
+
},
|
|
37
|
+
// --- REMOVED: Logout link is redundant ---
|
|
38
|
+
// {
|
|
39
|
+
// id: 'user.logout',
|
|
40
|
+
// path: '/login', // Was pointing here, but onClick is better
|
|
41
|
+
// title: 'Log Out',
|
|
42
|
+
// icon: 'logOut',
|
|
43
|
+
// },
|
|
44
|
+
],
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Used for a dedicated settings page (e.g., /settings/...)
|
|
48
|
+
* These paths were already correct.
|
|
49
|
+
*/
|
|
50
|
+
settingsMenu: [
|
|
51
|
+
{
|
|
52
|
+
id: 'settings.account',
|
|
53
|
+
path: '/settings/profile',
|
|
54
|
+
title: 'Account',
|
|
55
|
+
icon: 'user',
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: 'settings.billing',
|
|
59
|
+
path: '/settings/billing',
|
|
60
|
+
title: 'Billing',
|
|
61
|
+
icon: 'creditCard',
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
id: 'settings.team',
|
|
65
|
+
path: '/settings/team',
|
|
66
|
+
title: 'Team Members',
|
|
67
|
+
icon: 'users',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Used in the AppFooter. (Placeholders)
|
|
73
|
+
*/
|
|
74
|
+
footerLinks: [
|
|
75
|
+
{
|
|
76
|
+
id: 'footer.help',
|
|
77
|
+
path: '/help',
|
|
78
|
+
title: 'Help Center',
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
id: 'footer.terms',
|
|
82
|
+
path: '/terms',
|
|
83
|
+
title: 'Terms of Service',
|
|
84
|
+
},
|
|
85
|
+
],
|
|
86
|
+
};
|
|
@@ -29,7 +29,7 @@ import {
|
|
|
29
29
|
import { settingsSitemap } from './settings.sitemap';
|
|
30
30
|
import rammeLogo from '../../assets/orange.png';
|
|
31
31
|
import { useAuth } from '../../contexts/AuthContext';
|
|
32
|
-
import { appManifest } from '../../config/
|
|
32
|
+
import { appManifest } from '../../config/navigation';
|
|
33
33
|
import type { ManifestLink } from '../../core/manifest-types';
|
|
34
34
|
import { SitemapProvider } from '../../contexts/SitemapContext';
|
|
35
35
|
import PageTitleUpdater from '../../components/PageTitleUpdater';
|
|
@@ -1,26 +1,88 @@
|
|
|
1
|
-
// src/types/schema.ts
|
|
2
1
|
import { z } from 'zod';
|
|
3
2
|
|
|
4
|
-
//
|
|
3
|
+
// ------------------------------------------------------------------
|
|
4
|
+
// 1. Signal Schema (The "Nerve")
|
|
5
|
+
// Defines a single data point (e.g., "Living Room Temp", "Light Switch")
|
|
6
|
+
// ------------------------------------------------------------------
|
|
5
7
|
export const SignalSchema = z.object({
|
|
6
|
-
id: z.string(),
|
|
8
|
+
id: z.string().min(1, "Signal ID is required"),
|
|
7
9
|
label: z.string(),
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
description: z.string().optional(),
|
|
11
|
+
|
|
12
|
+
// Classification
|
|
13
|
+
kind: z.enum(['sensor', 'actuator', 'setpoint', 'metric', 'status']),
|
|
14
|
+
|
|
15
|
+
// Data Source Configuration (CRITICAL for the Adapter Factory)
|
|
16
|
+
source: z.enum(['mock', 'mqtt', 'http', 'derived', 'local']),
|
|
17
|
+
|
|
18
|
+
// Source-Specific Config
|
|
19
|
+
topic: z.string().optional(), // For MQTT (e.g., "home/living/temp")
|
|
20
|
+
endpoint: z.string().optional(), // For HTTP (e.g., "/api/v1/weather")
|
|
21
|
+
refreshRate: z.number().default(1000),
|
|
22
|
+
|
|
23
|
+
// Value Configuration
|
|
24
|
+
defaultValue: z.any().optional(),
|
|
25
|
+
unit: z.string().optional(),
|
|
26
|
+
|
|
27
|
+
// Validation
|
|
10
28
|
min: z.number().optional(),
|
|
11
29
|
max: z.number().optional(),
|
|
12
30
|
});
|
|
13
31
|
|
|
14
|
-
|
|
15
|
-
|
|
32
|
+
export type SignalDefinition = z.infer<typeof SignalSchema>;
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// ------------------------------------------------------------------
|
|
36
|
+
// 2. Entity Schema (The "Atom")
|
|
37
|
+
// Defines a grouping of signals into a logical object (e.g., "Smart Thermostat")
|
|
38
|
+
// ------------------------------------------------------------------
|
|
39
|
+
export const EntitySchema = z.object({
|
|
40
|
+
id: z.string(),
|
|
16
41
|
name: z.string(),
|
|
17
42
|
description: z.string().optional(),
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
43
|
+
|
|
44
|
+
// Taxonomy
|
|
45
|
+
type: z.string(), // e.g., 'device', 'room', 'service'
|
|
46
|
+
category: z.enum(['hardware', 'software', 'logical']).default('logical'),
|
|
47
|
+
|
|
48
|
+
// The Signals that belong to this entity (References Signal IDs)
|
|
49
|
+
signals: z.array(z.string()),
|
|
50
|
+
|
|
51
|
+
// UI Hints (How should this entity look?)
|
|
52
|
+
ui: z.object({
|
|
53
|
+
icon: z.string().optional(), // IconName
|
|
54
|
+
color: z.string().optional(),
|
|
55
|
+
dashboardComponent: z.string().optional(), // e.g., 'DeviceCard'
|
|
56
|
+
}).optional(),
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
export type EntityDefinition = z.infer<typeof EntitySchema>;
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
// ------------------------------------------------------------------
|
|
63
|
+
// 3. App Specification (The "Master Plan")
|
|
64
|
+
// This is the JSON structure the App Builder will generate.
|
|
65
|
+
// ------------------------------------------------------------------
|
|
66
|
+
export const AppSpecificationSchema = z.object({
|
|
67
|
+
meta: z.object({
|
|
68
|
+
name: z.string(),
|
|
69
|
+
version: z.string(),
|
|
70
|
+
description: z.string().optional(),
|
|
71
|
+
author: z.string().optional(),
|
|
72
|
+
createdAt: z.string().optional(),
|
|
73
|
+
}),
|
|
74
|
+
|
|
75
|
+
// The Data Layer
|
|
76
|
+
domain: z.object({
|
|
77
|
+
signals: z.array(SignalSchema),
|
|
78
|
+
entities: z.array(EntitySchema),
|
|
79
|
+
}),
|
|
80
|
+
|
|
81
|
+
// Global Config
|
|
82
|
+
config: z.object({
|
|
83
|
+
theme: z.enum(['light', 'dark', 'system']).default('system'),
|
|
84
|
+
mockMode: z.boolean().default(true),
|
|
85
|
+
}),
|
|
22
86
|
});
|
|
23
87
|
|
|
24
|
-
// Export the Types
|
|
25
|
-
export type SignalDef = z.infer<typeof SignalSchema>;
|
|
26
88
|
export type AppSpecification = z.infer<typeof AppSpecificationSchema>;
|