@design.estate/dees-catalog 9.3.0 → 9.4.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.
Files changed (29) hide show
  1. package/dist_bundle/bundle.js +1372 -2727
  2. package/dist_bundle/bundle.js.map +1 -1
  3. package/dist_ts_web/00_commitinfo_data.js +1 -1
  4. package/dist_ts_web/elements/00group-button/dees-button/dees-button.js +2 -1
  5. package/dist_ts_web/elements/00group-input/dees-input-quantityselector/dees-input-quantityselector.js +4 -2
  6. package/dist_ts_web/elements/00group-simple/dees-shopping-productcard/dees-shopping-productcard.d.ts +11 -9
  7. package/dist_ts_web/elements/00group-simple/dees-shopping-productcard/dees-shopping-productcard.demo.d.ts +2 -2
  8. package/dist_ts_web/elements/00group-simple/dees-shopping-productcard/dees-shopping-productcard.demo.js +148 -319
  9. package/dist_ts_web/elements/00group-simple/dees-shopping-productcard/dees-shopping-productcard.js +60 -279
  10. package/dist_ts_web/elements/00group-simple/dees-simple-appdash/dees-simple-appdash.d.ts +25 -10
  11. package/dist_ts_web/elements/00group-simple/dees-simple-appdash/dees-simple-appdash.demo.d.ts +3 -4
  12. package/dist_ts_web/elements/00group-simple/dees-simple-appdash/dees-simple-appdash.demo.js +229 -388
  13. package/dist_ts_web/elements/00group-simple/dees-simple-appdash/dees-simple-appdash.js +253 -813
  14. package/dist_ts_web/elements/00group-simple/dees-simple-login/dees-simple-login.demo.d.ts +2 -0
  15. package/dist_ts_web/elements/00group-simple/dees-simple-login/dees-simple-login.demo.js +150 -389
  16. package/dist_ts_web/elements/00group-simple/dees-simple-login/dees-simple-login.js +67 -11
  17. package/package.json +1 -1
  18. package/readme.hints.md +26 -0
  19. package/readme.md +76 -15
  20. package/scripts/bdtheme-baseline.json +0 -2
  21. package/ts_web/00_commitinfo_data.ts +1 -1
  22. package/ts_web/elements/00group-button/dees-button/dees-button.ts +1 -0
  23. package/ts_web/elements/00group-input/dees-input-quantityselector/dees-input-quantityselector.ts +3 -1
  24. package/ts_web/elements/00group-simple/dees-shopping-productcard/dees-shopping-productcard.demo.ts +67 -332
  25. package/ts_web/elements/00group-simple/dees-shopping-productcard/dees-shopping-productcard.ts +65 -322
  26. package/ts_web/elements/00group-simple/dees-simple-appdash/dees-simple-appdash.demo.ts +136 -382
  27. package/ts_web/elements/00group-simple/dees-simple-appdash/dees-simple-appdash.ts +224 -872
  28. package/ts_web/elements/00group-simple/dees-simple-login/dees-simple-login.demo.ts +116 -421
  29. package/ts_web/elements/00group-simple/dees-simple-login/dees-simple-login.ts +66 -10
@@ -1,395 +1,149 @@
1
- import { html, DeesElement, customElement, css, cssManager } from '@design.estate/dees-element';
2
- import type { IView, IGlobalMessage } from './dees-simple-appdash.js';
1
+ import { html, DeesElement, customElement, property, state, css, cssManager } from '@design.estate/dees-element';
2
+ import type { IView, DeesSimpleAppDash } from './dees-simple-appdash.js';
3
+ import { themeDefaultStyles } from '../../00theme.js';
4
+ import { demoApp } from '../../../demos/templates.js';
5
+ import { WebContainerEnvironment } from '../../00group-runtime/index.js';
3
6
  import '../../00group-form/dees-form/dees-form.js';
4
- import '../../00group-input/dees-input-text/dees-input-text.js';
5
- import '../../00group-input/dees-input-checkbox/dees-input-checkbox.js';
6
- import '../../00group-input/dees-input-dropdown/dees-input-dropdown.js';
7
- import '../../00group-input/dees-input-radiogroup/dees-input-radiogroup.js';
8
7
  import '../../00group-form/dees-form-submit/dees-form-submit.js';
8
+ import '../../00group-input/dees-input-text/dees-input-text.js';
9
+ import '../../00group-input/dees-input-toggle/dees-input-toggle.js';
9
10
  import '../../00group-dataview/dees-statsgrid/dees-statsgrid.js';
10
- import type { IStatsTile } from '../../00group-dataview/dees-statsgrid/dees-statsgrid.js';
11
+ import '../../00group-dataview/dees-table/dees-table.js';
12
+ import type { Column, ITableAction } from '../../00group-dataview/dees-table/types.js';
11
13
 
12
- // Create demo view components
13
- @customElement('demo-view-dashboard')
14
- class DemoViewDashboard extends DeesElement {
15
- static styles = [
16
- cssManager.defaultStyles,
17
- css`
18
- :host {
19
- display: block;
20
- padding: 40px;
21
- }
22
- h1 {
23
- margin: 0 0 20px 0;
24
- color: ${cssManager.bdTheme('#000', '#fff')};
25
- }
26
- dees-statsgrid {
27
- margin-top: 20px;
28
- }
29
- `
30
- ];
31
-
32
- private statsTiles: IStatsTile[] = [
33
- {
34
- id: 'users',
35
- title: 'Active Users',
36
- value: 1234,
37
- type: 'number',
38
- icon: 'faUsers',
39
- description: '+15% from last week',
40
- color: '#22c55e'
41
- },
42
- {
43
- id: 'pageviews',
44
- title: 'Page Views',
45
- value: 56700,
46
- type: 'number',
47
- icon: 'faEye',
48
- description: '56.7k total views',
49
- color: '#3b82f6'
50
- },
51
- {
52
- id: 'uptime',
53
- title: 'System Uptime',
54
- value: 89,
55
- unit: '%',
56
- type: 'gauge',
57
- icon: 'faServer',
58
- description: 'Last 30 days',
59
- color: '#10b981',
60
- gaugeOptions: {
61
- min: 0,
62
- max: 100,
63
- thresholds: [
64
- { value: 80, color: '#ef4444' },
65
- { value: 90, color: '#f59e0b' },
66
- { value: 100, color: '#10b981' }
67
- ]
68
- }
69
- },
70
- {
71
- id: 'response',
72
- title: 'Avg Response Time',
73
- value: 3.2,
74
- unit: 's',
75
- type: 'number',
76
- icon: 'faClock',
77
- description: '-0.5s improvement',
78
- color: '#f59e0b'
79
- },
80
- {
81
- id: 'revenue',
82
- title: 'Monthly Revenue',
83
- value: 48520,
84
- unit: '$',
85
- type: 'trend',
86
- icon: 'faDollarSign',
87
- description: '+8.2% growth',
88
- color: '#22c55e',
89
- trendData: [35000, 38000, 37500, 41000, 39800, 42000, 44100, 43200, 45600, 47100, 46800, 48520]
90
- },
91
- {
92
- id: 'traffic',
93
- title: 'Traffic Trend',
94
- value: 1680,
95
- type: 'trend',
96
- icon: 'faChartLine',
97
- description: 'Last 7 days',
98
- color: '#3b82f6',
99
- trendData: [1200, 1350, 1100, 1450, 1600, 1550, 1680]
100
- }
101
- ];
102
-
103
- render() {
104
- return html`
105
- <h1>Dashboard</h1>
106
- <p>Welcome to your application dashboard. Here's an overview of your metrics:</p>
107
- <dees-statsgrid
108
- .tiles=${this.statsTiles}
109
- @tile-action=${(e: CustomEvent) => {
110
- console.log('Tile action:', e.detail);
111
- }}
112
- ></dees-statsgrid>
14
+ interface IStudioProject { id: string; name: string; client: string; state: string; }
15
+ interface IStudioState { name: string; projects: IStudioProject[]; notifications: boolean; activity: string[]; }
16
+ const initialState = (): IStudioState => ({ name: 'Studio', notifications: true, projects: [
17
+ { id: 'atlas', name: 'Atlas identity', client: 'Atlas', state: 'In progress' },
18
+ { id: 'field', name: 'Field notes', client: 'Fieldwork', state: 'Ready for review' },
19
+ { id: 'mono', name: 'Mono storefront', client: 'Mono', state: 'Completed' },
20
+ ], activity: ['Alex shared the first Atlas concepts.', 'Field notes is ready for a final review.', 'Mono storefront was delivered to the client.'] });
113
21
 
114
- <h2 style="margin-top: 40px;">Recent Activity</h2>
115
- <p>Below is a log of recent system events and user activity to demonstrate scrollable content.</p>
22
+ type TStudioPage = 'Overview' | 'Projects' | 'Profile' | 'Notifications';
23
+ type TStudioAction = { type: 'archive'; id: string } | { type: 'navigate'; page: TStudioPage } | { type: 'profile'; name: string } | { type: 'notifications'; enabled: boolean };
116
24
 
117
- ${[
118
- { time: '2 min ago', event: 'User john@example.com logged in from 192.168.1.42', type: 'info' },
119
- { time: '5 min ago', event: 'Deployment v3.52.1 completed successfully on production', type: 'success' },
120
- { time: '12 min ago', event: 'Database backup finished 2.4 GB compressed', type: 'info' },
121
- { time: '18 min ago', event: 'SSL certificate renewed for api.example.com (expires 2027-04-03)', type: 'success' },
122
- { time: '25 min ago', event: 'Memory usage spike on worker-03 (92%) auto-scaled to 4 instances', type: 'warning' },
123
- { time: '31 min ago', event: 'New user registration: sarah@company.io', type: 'info' },
124
- { time: '45 min ago', event: 'Scheduled job "cleanup-temp-files" completed removed 1,247 files', type: 'info' },
125
- { time: '1 hour ago', event: 'API rate limit reached for client app-mobile-client (429 responses)', type: 'warning' },
126
- { time: '1.5 hours ago', event: 'CDN cache purged for /assets/* — 340 objects invalidated', type: 'info' },
127
- { time: '2 hours ago', event: 'Failed login attempt for admin@example.com from 203.0.113.50 (blocked)', type: 'error' },
128
- { time: '2.5 hours ago', event: 'Webhook delivery to https://hooks.slack.com succeeded (200 OK)', type: 'info' },
129
- { time: '3 hours ago', event: 'Cron job "generate-reports" started processing Q1 2026 data', type: 'info' },
130
- { time: '3.5 hours ago', event: 'Load balancer health check: all 8 nodes healthy', type: 'success' },
131
- { time: '4 hours ago', event: 'DNS propagation complete for new subdomain staging.example.com', type: 'success' },
132
- ].map(item => html`
133
- <div style="
134
- display: flex;
135
- align-items: baseline;
136
- gap: 12px;
137
- padding: 10px 0;
138
- border-bottom: 1px solid ${cssManager.bdTheme('hsl(0 0% 90%)', 'hsl(0 0% 12%)')};
139
- font-size: 13px;
140
- ">
141
- <span style="
142
- flex-shrink: 0;
143
- width: 100px;
144
- font-size: 11px;
145
- color: ${cssManager.bdTheme('hsl(0 0% 55%)', 'hsl(0 0% 45%)')};
146
- ">${item.time}</span>
147
- <span style="
148
- color: ${item.type === 'error' ? cssManager.bdTheme('hsl(0 72% 50%)', 'hsl(0 72% 65%)') :
149
- item.type === 'warning' ? cssManager.bdTheme('hsl(25 95% 50%)', 'hsl(25 95% 63%)') :
150
- item.type === 'success' ? cssManager.bdTheme('hsl(142 70% 40%)', 'hsl(142 70% 55%)') :
151
- cssManager.bdTheme('hsl(0 0% 30%)', 'hsl(0 0% 75%)')};
152
- ">${item.event}</span>
153
- </div>
154
- `)}
155
- `;
25
+ class DeesDemoSimpleView extends DeesElement {
26
+ @property({ attribute: false }) accessor model = initialState();
27
+ protected page: TStudioPage = 'Overview';
28
+ private action(detail: TStudioAction): void { this.dispatchEvent(new CustomEvent('studio-action', { detail, bubbles: true, composed: true })); }
29
+ public static styles = [themeDefaultStyles, cssManager.defaultStyles, css`
30
+ :host { display: block; container-type: inline-size; font: 13px/1.5 var(--dees-font-family); color: var(--dees-color-text-primary); }
31
+ main { display: grid; gap: 28px; max-width: 1040px; margin: auto; padding: 32px; }
32
+ h1 { font-size: 28px; line-height: 1.2; font-weight: 600; letter-spacing: -.035em; margin: 0 0 8px; }
33
+ h2 { font-size: 15px; font-weight: 600; margin: 0; }
34
+ p { margin: 0; color: var(--dees-color-text-secondary); }
35
+ .eyebrow { font-size: 12px; color: var(--dees-color-text-secondary); margin-bottom: 12px; }
36
+ .sectionHeader { display: flex; gap: 12px; align-items: center; justify-content: space-between; margin-bottom: 12px; }
37
+ .project { display: flex; flex-wrap: wrap; align-items: center; gap: 16px; padding: 20px; border: 1px solid var(--dees-color-border-subtle); border-radius: var(--dees-radius-xl); background: var(--dees-color-bg-primary); }
38
+ .project > dees-icon { color: var(--dees-color-text-secondary); }
39
+ .project .text { flex: 1 1 140px; }
40
+ .project p { font-size: 12px; margin-top: 4px; }
41
+ .activity { list-style: none; padding: 0; margin: 0; }
42
+ .activity li { display: flex; align-items: baseline; gap: 12px; padding: 14px 0; border-bottom: 1px solid var(--dees-color-border-subtle); }
43
+ .activity li::before { content: ''; width: 5px; height: 5px; flex-shrink: 0; background: var(--dees-color-text-muted); border-radius: 50%; }
44
+ dees-form { display: grid; gap: 24px; max-width: 440px; }
45
+ .settings { padding: 20px; border-radius: var(--dees-radius-xl); border: 1px solid var(--dees-color-border-subtle); background: var(--dees-color-bg-primary); }
46
+ @container (max-width: 600px) { main { padding: 24px 20px; gap: 24px; } h1 { font-size: 24px; } }
47
+ `];
48
+ public render() {
49
+ const model = this.model;
50
+ if (this.page === 'Projects') {
51
+ const columns: Column<IStudioProject>[] = [{ key: 'name', header: 'Project' }, { key: 'client', header: 'Client' }, { key: 'state', header: 'Status' }];
52
+ const actions: ITableAction<IStudioProject>[] = [{ name: 'Archive project', iconName: 'lucide:Archive', type: ['inRow', 'contextmenu'], actionFunc: async ({ item }) => this.action({ type: 'archive', id: item.id }) }];
53
+ return html`<main><header><h1>Projects</h1><p>Everything your studio is working on.</p></header>
54
+ <dees-table heading1="Studio projects" heading2="Archive a delivered project to clear space." dataName="projects" .data=${model.projects} .columns=${columns} rowKey="id" .dataActions=${actions}></dees-table></main>`;
55
+ }
56
+ if (this.page === 'Profile') return html`<main><header><h1>Make it yours.</h1><p>A name for the space you work in.</p></header>
57
+ <dees-form @formData=${(event: CustomEvent) => this.action({ type: 'profile', name: String(event.detail.data.name).trim() })}>
58
+ <dees-input-text key="name" label="Workspace name" .value=${model.name} required></dees-input-text>
59
+ <dees-form-submit type="accent" icon="lucide:check">Save changes</dees-form-submit>
60
+ </dees-form></main>`;
61
+ if (this.page === 'Notifications') return html`<main><header><h1>Stay in the loop.</h1><p>Choose how this workspace keeps you informed.</p></header><div class="settings">
62
+ <dees-input-toggle label="Project updates" description="Show a notice when a project is archived." .value=${model.notifications}
63
+ @newValue=${(event: CustomEvent<boolean>) => this.action({ type: 'notifications', enabled: event.detail })}></dees-input-toggle>
64
+ </div></main>`;
65
+ return html`<main><header><div class="eyebrow">Your workspace</div><h1>Room for good work.</h1><p>A clear view of your projects, people, and progress.</p></header>
66
+ <dees-statsgrid .minTileWidth=${160} .tiles=${[
67
+ { id: 'projects', title: 'Open projects', value: model.projects.length, type: 'number', icon: 'lucide:Layers', description: 'Across the studio' },
68
+ { id: 'review', title: 'Ready for review', value: model.projects.filter(project => project.state === 'Ready for review').length, type: 'number', icon: 'lucide:CircleCheck', description: 'Waiting for your feedback' },
69
+ { id: 'people', title: 'Collaborators', value: 4, type: 'number', icon: 'lucide:Users', description: 'One shared workspace' },
70
+ ]}></dees-statsgrid>
71
+ <section><div class="sectionHeader"><h2>On your desk</h2><dees-button type="ghost" size="sm" text="View projects" icon="lucide:arrowUpRight" @clicked=${() => this.action({ type: 'navigate', page: 'Projects' })}></dees-button></div>
72
+ <div class="project"><dees-icon icon="lucide:folderOpen" iconSize="28"></dees-icon><div class="text"><h2>${model.projects[0]?.name || 'A fresh start'}</h2><p>${model.projects[0]?.state || 'All projects are archived. Reset the demo to start again.'}</p></div>
73
+ ${model.projects.length ? html`<dees-button type="outline" text="Open projects" @clicked=${() => this.action({ type: 'navigate', page: 'Projects' })}></dees-button>` : ''}</div>
74
+ </section><section><div class="sectionHeader"><h2>Recent activity</h2></div><ul class="activity">${model.activity.map(entry => html`<li>${entry}</li>`)}</ul></section>
75
+ </main>`;
156
76
  }
157
77
  }
78
+ @customElement('dees-demo-simple-overview') class DeesDemoSimpleOverview extends DeesDemoSimpleView {}
79
+ @customElement('dees-demo-simple-projects') class DeesDemoSimpleProjects extends DeesDemoSimpleView { protected override page: TStudioPage = 'Projects'; }
80
+ @customElement('dees-demo-simple-profile') class DeesDemoSimpleProfile extends DeesDemoSimpleView { protected override page: TStudioPage = 'Profile'; }
81
+ @customElement('dees-demo-simple-notifications') class DeesDemoSimpleNotifications extends DeesDemoSimpleView { protected override page: TStudioPage = 'Notifications'; }
158
82
 
159
- @customElement('demo-view-analytics')
160
- class DemoViewAnalytics extends DeesElement {
161
- static styles = [
162
- cssManager.defaultStyles,
163
- css`
164
- :host {
165
- display: block;
166
- padding: 40px;
167
- }
168
- h1 {
169
- margin: 0 0 20px 0;
170
- color: ${cssManager.bdTheme('#000', '#fff')};
171
- }
172
- `
83
+ @customElement('dees-demo-simple-studio')
84
+ class DeesDemoSimpleStudio extends DeesElement {
85
+ @state() private accessor model = initialState();
86
+ @state() private accessor signedOut = false;
87
+ @state() private accessor message = 'Local sample workspace. Archive a project or change its settings.';
88
+ private environment = new WebContainerEnvironment();
89
+ private views: IView[] = [
90
+ { name: 'Overview', iconName: 'layoutGrid', element: DeesDemoSimpleOverview },
91
+ { name: 'Projects', iconName: 'folder', element: DeesDemoSimpleProjects },
92
+ { name: 'Settings', iconName: 'settings2', subViews: [
93
+ { name: 'Profile', iconName: 'contact', element: DeesDemoSimpleProfile },
94
+ { name: 'Notifications', iconName: 'bell', element: DeesDemoSimpleNotifications },
95
+ ] },
173
96
  ];
174
-
175
- render() {
176
- return html`
177
- <h1>Analytics</h1>
178
- <p>This is the analytics view. You can add charts and metrics here.</p>
179
- `;
97
+ private get app(): DeesSimpleAppDash | null { return this.shadowRoot?.querySelector('dees-simple-appdash') || null; }
98
+ public static styles = [themeDefaultStyles, cssManager.defaultStyles, css`
99
+ :host { display: grid; height: 100%; min-height: 600px; grid-template-rows: auto minmax(0, 1fr) auto; gap: 16px; font: 12px/1.5 var(--dees-font-family); }
100
+ .toolbar { display: flex; gap: 12px; align-items: center; justify-content: space-between; flex-wrap: wrap; color: var(--dees-color-text-secondary); }
101
+ .toolbar div { display: flex; flex-wrap: wrap; gap: 8px; }
102
+ .frame { min-height: 0; overflow: hidden; border-radius: var(--dees-radius-2xl); corner-shape: var(--dees-corner-shape); border: 1px solid var(--dees-color-border-default); }
103
+ output { color: var(--dees-color-text-secondary); }
104
+ .signedOut { height: 100%; display: grid; place-content: center; justify-items: center; gap: 16px; }
105
+ .signedOut h2 { margin: 0; font-size: 24px; letter-spacing: -.025em; }
106
+ `];
107
+ private syncView(): void {
108
+ const view = this.app?.shadowRoot?.querySelector('.appcontent')?.firstElementChild as DeesDemoSimpleView | null;
109
+ if (view) view.model = this.model;
180
110
  }
181
- }
182
-
183
- @customElement('demo-view-settings')
184
- class DemoViewSettings extends DeesElement {
185
- static styles = [
186
- cssManager.defaultStyles,
187
- css`
188
- :host {
189
- display: block;
190
- padding: 40px;
191
- }
192
- h1 {
193
- margin: 0 0 20px 0;
194
- color: ${cssManager.bdTheme('#000', '#fff')};
195
- }
196
- .settings-section {
197
- margin-top: 30px;
198
- }
199
- .settings-section h2 {
200
- font-size: 18px;
201
- margin: 0 0 15px 0;
202
- color: ${cssManager.bdTheme('#333', '#ccc')};
203
- }
204
- .horizontal-form-section {
205
- background: ${cssManager.bdTheme('#f5f5f5', '#1a1a1a')};
206
- padding: 20px;
207
- border-radius: 8px;
208
- margin: 15px 0;
209
- }
210
- `
211
- ];
212
-
213
- render() {
214
- return html`
215
- <h1>Settings</h1>
216
- <p>Configure your application settings below:</p>
217
-
218
- <div class="settings-section">
219
- <h2>General Settings</h2>
220
- <dees-form>
221
- <dees-input-text key="appName" label="Application Name" value="My App"></dees-input-text>
222
- <dees-input-text key="apiEndpoint" label="API Endpoint" value="https://api.example.com"></dees-input-text>
223
- <dees-input-dropdown
224
- key="environment"
225
- label="Environment"
226
- .options=${[
227
- { option: 'Development', key: 'dev' },
228
- { option: 'Staging', key: 'staging' },
229
- { option: 'Production', key: 'prod' }
230
- ]}
231
- .selectedOption=${{ option: 'Production', key: 'prod' }}
232
- ></dees-input-dropdown>
233
- <dees-input-checkbox key="enableNotifications" label="Enable Notifications" value="true"></dees-input-checkbox>
234
- <dees-input-checkbox key="enableAnalytics" label="Enable Analytics" value="false"></dees-input-checkbox>
235
- <dees-form-submit>Save General Settings</dees-form-submit>
236
- </dees-form>
237
- </div>
238
-
239
- <div class="settings-section">
240
- <h2>Display Preferences</h2>
241
- <div class="horizontal-form-section">
242
- <p style="margin-top: 0; margin-bottom: 16px;">Quick display settings using horizontal layout:</p>
243
- <dees-form horizontal-layout>
244
- <dees-input-dropdown
245
- key="theme"
246
- label="Theme"
247
- .enableSearch=${false}
248
- .options=${[
249
- { option: 'Light', key: 'light' },
250
- { option: 'Dark', key: 'dark' },
251
- { option: 'Auto', key: 'auto' }
252
- ]}
253
- .selectedOption=${{ option: 'Dark', key: 'dark' }}
254
- ></dees-input-dropdown>
255
- <dees-input-dropdown
256
- key="language"
257
- label="Language"
258
- .enableSearch=${false}
259
- .options=${[
260
- { option: 'English', key: 'en' },
261
- { option: 'German', key: 'de' },
262
- { option: 'Spanish', key: 'es' },
263
- { option: 'French', key: 'fr' }
264
- ]}
265
- .selectedOption=${{ option: 'English', key: 'en' }}
266
- ></dees-input-dropdown>
267
- <dees-input-checkbox key="compactMode" label="Compact Mode"></dees-input-checkbox>
268
- </dees-form>
269
- </div>
270
- </div>
271
-
272
- <div class="settings-section">
273
- <h2>Notification Settings</h2>
274
- <dees-form>
275
- <dees-input-radiogroup
276
- .label=${'Email Frequency'}
277
- .options=${['Real-time', 'Daily Digest', 'Weekly Summary', 'Never']}
278
- .selectedOption=${'Real-time'}
279
- .key=${'emailFrequency'}
280
- ></dees-input-radiogroup>
281
- <dees-input-checkbox key="pushNotifications" label="Enable Push Notifications" value="true"></dees-input-checkbox>
282
- <dees-input-checkbox key="soundAlerts" label="Play Sound for Alerts" value="true"></dees-input-checkbox>
283
- <dees-form-submit>Update Notifications</dees-form-submit>
284
- </dees-form>
285
- </div>
286
- `;
111
+ public updated(changes: Map<string, unknown>): void { super.updated(changes); this.syncView(); }
112
+ private async resetDemo(): Promise<void> {
113
+ this.model = initialState(); this.signedOut = false; this.message = 'Workspace reset.';
114
+ await this.updateComplete;
115
+ this.app?.clearMessages();
116
+ await this.app?.loadView(this.views[0]);
287
117
  }
288
- }
289
-
290
- export const demoFunc = () => html`
291
- <style>
292
- body {
293
- margin: 0;
294
- padding: 0;
295
- }
296
- .demo-container {
297
- width: 100%;
298
- height: 100%;
299
- position: absolute;
300
- top: 0;
301
- left: 0;
118
+ private navigate(page: TStudioPage): void {
119
+ const view = this.views.flatMap(entry => [entry, ...(entry.subViews || [])]).find(entry => entry.name === page);
120
+ if (view) void this.app?.loadView(view);
121
+ }
122
+ private handleAction(event: CustomEvent<TStudioAction>): void {
123
+ const action = event.detail;
124
+ if (action.type === 'navigate') { this.navigate(action.page); return; }
125
+ if (action.type === 'archive') {
126
+ const project = this.model.projects.find(project => project.id === action.id);
127
+ if (!project) return;
128
+ this.message = `${project.name} archived.`;
129
+ this.model = { ...this.model, projects: this.model.projects.filter(project => project.id !== action.id), activity: [this.message, ...this.model.activity].slice(0, 6) };
130
+ this.app?.removeMessage('storage');
131
+ if (this.model.notifications) this.app?.addMessage({ id: 'project-update', type: 'success', message: this.message });
132
+ } else if (action.type === 'profile' && action.name) {
133
+ this.model = { ...this.model, name: action.name }; this.message = 'Workspace name saved.';
134
+ this.app?.addMessage({ id: 'settings-update', type: 'success', message: this.message });
135
+ } else if (action.type === 'notifications') {
136
+ this.model = { ...this.model, notifications: action.enabled }; this.message = `Project notices ${action.enabled ? 'enabled' : 'disabled'}.`;
302
137
  }
303
- </style>
304
- <div class="demo-container">
305
- <dees-simple-appdash
306
- name="My Application"
307
- terminalSetupCommand="echo 'Welcome to the terminal!'"
308
- .globalMessages=${[
309
- {
310
- id: 'update',
311
- type: 'info',
312
- message: 'A new version (v3.50.0) is available with performance improvements and bug fixes.',
313
- dismissible: true,
314
- actions: [
315
- {
316
- name: 'Update Now',
317
- iconName: 'lucide:download',
318
- action: () => alert('Updating...'),
319
- },
320
- {
321
- name: 'Release Notes',
322
- action: () => alert('Opening release notes...'),
323
- },
324
- ],
325
- },
326
- {
327
- id: 'maintenance',
328
- type: 'warning',
329
- message: 'Scheduled maintenance window: April 5, 2026 02:00–06:00 UTC. Some services may be temporarily unavailable.',
330
- dismissible: true,
331
- },
332
- {
333
- id: 'critical',
334
- type: 'error',
335
- message: 'Your SSL certificate expires in 3 days. Renew now to avoid service disruption.',
336
- dismissible: false,
337
- actions: [
338
- {
339
- name: 'Renew Certificate',
340
- iconName: 'lucide:shieldCheck',
341
- action: () => alert('Renewing certificate...'),
342
- },
343
- ],
344
- },
345
- ] as IGlobalMessage[]}
346
- .viewTabs=${[
347
- {
348
- name: 'Dashboard',
349
- iconName: 'lucide:home',
350
- element: DemoViewDashboard,
351
- },
352
- {
353
- name: 'Analytics',
354
- iconName: 'lucide:lineChart',
355
- element: DemoViewAnalytics,
356
- subViews: [
357
- {
358
- name: 'Overview',
359
- iconName: 'lucide:activity',
360
- element: DemoViewAnalytics,
361
- },
362
- {
363
- name: 'Reports',
364
- iconName: 'lucide:fileText',
365
- element: DemoViewDashboard,
366
- },
367
- ],
368
- },
369
- {
370
- name: 'Settings',
371
- iconName: 'lucide:settings',
372
- subViews: [
373
- {
374
- name: 'Profile',
375
- iconName: 'lucide:user',
376
- element: DemoViewSettings,
377
- },
378
- {
379
- name: 'Billing',
380
- iconName: 'lucide:creditCard',
381
- element: DemoViewSettings,
382
- },
383
- ],
384
- },
385
- ] as IView[]}
386
- @logout=${() => {
387
- console.log('Logout event triggered');
388
- alert('Logout clicked!');
389
- }}
390
- @view-select=${(e: CustomEvent) => {
391
- console.log('View selected:', e.detail.view.name);
392
- }}
393
- ></dees-simple-appdash>
394
- </div>
395
- `;
138
+ }
139
+ public render() {
140
+ return html`<div class="toolbar"><span>Simple app · One connected studio</span><div>
141
+ <dees-button type="outline" size="sm" text="Show storage notice" @clicked=${() => this.app?.addMessage({ id: 'storage', type: 'warning', message: 'Your workspace is nearly full. Archive a delivered project to make room.', dismissible: false, actions: [{ name: 'Review projects', action: async () => this.navigate('Projects') }] })}></dees-button>
142
+ <dees-button type="ghost" size="sm" text="Reset demo" @clicked=${this.resetDemo}></dees-button>
143
+ </div></div><div class="frame">${this.signedOut ? html`<div class="signedOut"><dees-icon icon="lucide:layers" iconSize="32"></dees-icon><h2>See you soon.</h2><dees-button type="accent" text="Return to Studio" @clicked=${() => { this.signedOut = false; }}></dees-button></div>` : html`
144
+ <dees-simple-appdash .name=${this.model.name} .viewTabs=${this.views} .executionEnvironment=${this.environment}
145
+ @view-select=${this.syncView} @studio-action=${this.handleAction} @logout=${() => { this.signedOut = true; this.message = 'Signed out of the sample workspace.'; }}></dees-simple-appdash>`}
146
+ </div><output role="status">${this.message}</output>`;
147
+ }
148
+ }
149
+ export const demoFunc = () => demoApp(html`<dees-demo-simple-studio></dees-demo-simple-studio>`);