@@ -2,6 +2,7 @@ import { defineStack } from '@objectstack/spec';
22import { App } from '@objectstack/spec/ui' ;
33import { KitchenSinkObject } from './src/objects/kitchen_sink.object' ;
44import { AccountObject } from './src/objects/account.object' ;
5+ import { ShowcaseObject } from './src/objects/showcase.object' ;
56
67// Helper to create dates relative to today
78const daysFromNow = ( days : number ) => {
@@ -13,7 +14,8 @@ const daysFromNow = (days: number) => {
1314export default defineStack ( {
1415 objects : [
1516 KitchenSinkObject ,
16- AccountObject
17+ AccountObject ,
18+ ShowcaseObject
1719 ] ,
1820 apps : [
1921 App . create ( {
@@ -39,6 +41,20 @@ export default defineStack({
3941 label : 'All Field Types' ,
4042 icon : 'test-tubes' ,
4143 } ,
44+ {
45+ id : 'nav_showcase' ,
46+ type : 'object' ,
47+ objectName : 'showcase' ,
48+ label : 'Feature Showcase' ,
49+ icon : 'sparkles' ,
50+ } ,
51+ {
52+ id : 'nav_templates' ,
53+ type : 'page' ,
54+ pageName : 'template_showcase' ,
55+ label : 'Page Templates' ,
56+ icon : 'layout-template' ,
57+ } ,
4258 {
4359 id : 'nav_help' ,
4460 type : 'page' ,
@@ -162,6 +178,109 @@ export default defineStack({
162178 } ,
163179 ] ,
164180 pages : [
181+ // Template Showcase Page — demonstrates page templates
182+ {
183+ name : 'template_showcase' ,
184+ label : 'Page Templates' ,
185+ type : 'app' ,
186+ template : 'header-sidebar-main' ,
187+ regions : [
188+ {
189+ name : 'header' ,
190+ components : [
191+ {
192+ type : 'container' ,
193+ properties : {
194+ className : 'bg-muted/30 rounded-lg p-6 border' ,
195+ children : [
196+ { type : 'text' , properties : { value : '📐 Page Template Showcase' , className : 'text-2xl font-bold mb-2 block' } } ,
197+ { type : 'text' , properties : { value : 'This page uses the "header-sidebar-main" template — a full-width header with sidebar + main content below.' , className : 'text-muted-foreground block' } } ,
198+ ] ,
199+ } ,
200+ } ,
201+ ] ,
202+ } ,
203+ {
204+ name : 'sidebar' ,
205+ width : 'medium' ,
206+ components : [
207+ {
208+ type : 'container' ,
209+ properties : {
210+ className : 'bg-card rounded-lg p-4 border space-y-3' ,
211+ children : [
212+ { type : 'text' , properties : { value : '🧭 Available Templates' , className : 'font-semibold mb-3 block' } } ,
213+ { type : 'text' , properties : { value : '• **default** — Full-width single column' , className : 'text-sm block' } } ,
214+ { type : 'text' , properties : { value : '• **header-sidebar-main** — Header + sidebar/main (this page)' , className : 'text-sm block' } } ,
215+ { type : 'text' , properties : { value : '• **three-column** — Sidebar + main + aside' , className : 'text-sm block' } } ,
216+ { type : 'text' , properties : { value : '• **dashboard** — 2-column grid layout' , className : 'text-sm block' } } ,
217+ ] ,
218+ } ,
219+ } ,
220+ {
221+ type : 'container' ,
222+ properties : {
223+ className : 'bg-card rounded-lg p-4 border space-y-3 mt-4' ,
224+ children : [
225+ { type : 'text' , properties : { value : '🔧 New Features' , className : 'font-semibold mb-3 block' } } ,
226+ { type : 'text' , properties : { value : '✅ **dependsOn** — Fields shown when parent has a value' , className : 'text-sm block' } } ,
227+ { type : 'text' , properties : { value : '✅ **visibleOn** — Fields shown based on expression' , className : 'text-sm block' } } ,
228+ { type : 'text' , properties : { value : '✅ **ActionParams** — Parameter dialog before actions' , className : 'text-sm block' } } ,
229+ { type : 'text' , properties : { value : '✅ **Page Templates** — Predefined page layouts' , className : 'text-sm block' } } ,
230+ ] ,
231+ } ,
232+ } ,
233+ ] ,
234+ } ,
235+ {
236+ name : 'main' ,
237+ components : [
238+ {
239+ type : 'container' ,
240+ properties : {
241+ className : 'space-y-6' ,
242+ children : [
243+ {
244+ type : 'container' ,
245+ properties : {
246+ className : 'bg-card rounded-lg p-6 border' ,
247+ children : [
248+ { type : 'text' , properties : { value : '## FormField.dependsOn' , className : 'text-xl font-semibold mb-3 block' } } ,
249+ { type : 'text' , properties : { value : 'Fields with `dependsOn` are only shown when the parent field has a value. For example, "Sub-Category" depends on "Category" — it only appears after a category is selected.' , className : 'text-muted-foreground mb-3 block' } } ,
250+ { type : 'text' , properties : { value : '```typescript\n{ field: "sub_category", dependsOn: "category" }\n```' , className : 'font-mono text-sm bg-muted/50 p-3 rounded block' } } ,
251+ ] ,
252+ } ,
253+ } ,
254+ {
255+ type : 'container' ,
256+ properties : {
257+ className : 'bg-card rounded-lg p-6 border' ,
258+ children : [
259+ { type : 'text' , properties : { value : '## FormField.visibleOn' , className : 'text-xl font-semibold mb-3 block' } } ,
260+ { type : 'text' , properties : { value : 'Fields with `visibleOn` are shown/hidden based on a dynamic expression. For example, pricing fields only appear when status is "active" or "review".' , className : 'text-muted-foreground mb-3 block' } } ,
261+ { type : 'text' , properties : { value : '```typescript\n{ field: "price", visibleOn: "${data.status === \'active\'}" }\n```' , className : 'font-mono text-sm bg-muted/50 p-3 rounded block' } } ,
262+ ] ,
263+ } ,
264+ } ,
265+ {
266+ type : 'container' ,
267+ properties : {
268+ className : 'bg-card rounded-lg p-6 border' ,
269+ children : [
270+ { type : 'text' , properties : { value : '## ActionParam Collection' , className : 'text-xl font-semibold mb-3 block' } } ,
271+ { type : 'text' , properties : { value : 'Actions can define `params` to collect from the user before execution. A dialog with form fields is shown automatically. Supports text, number, boolean, select, date, and textarea inputs.' , className : 'text-muted-foreground mb-3 block' } } ,
272+ { type : 'text' , properties : { value : '```typescript\nactions: [{\n name: "assign_owner",\n type: "api",\n params: [\n { name: "owner_email", label: "Email", type: "text", required: true },\n { name: "notify", label: "Notify", type: "boolean", defaultValue: true }\n ]\n}]\n```' , className : 'font-mono text-sm bg-muted/50 p-3 rounded block' } } ,
273+ ] ,
274+ } ,
275+ } ,
276+ ] ,
277+ } ,
278+ } ,
279+ ] ,
280+ } ,
281+ ] ,
282+ } ,
283+ // Help page
165284 {
166285 name : 'showcase_help' ,
167286 label : 'Help & Resources' ,
@@ -176,11 +295,13 @@ export default defineStack({
176295 className : 'prose max-w-3xl mx-auto p-8 text-foreground' ,
177296 children : [
178297 { type : 'text' , properties : { value : '# Platform Showcase' , className : 'text-3xl font-bold mb-6 block' } } ,
179- { type : 'text' , properties : { value : 'This app demonstrates the full range of ObjectStack capabilities — all field types, dashboard widgets, and page layouts.' , className : 'text-muted-foreground mb-6 block' } } ,
298+ { type : 'text' , properties : { value : 'This app demonstrates the full range of ObjectStack capabilities — all field types, dashboard widgets, page layouts, conditional forms, and action parameters .' , className : 'text-muted-foreground mb-6 block' } } ,
180299 { type : 'text' , properties : { value : '## Supported Field Types' , className : 'text-xl font-semibold mb-3 block' } } ,
181300 { type : 'text' , properties : { value : '- **Text** — Text, Textarea, Code, Password, Rich Text\n- **Number** — Integer, Currency, Percentage, Rating\n- **Date** — Date, DateTime\n- **Selection** — Select (single), Multi-Select\n- **Contact** — Email, URL, Phone\n- **Media** — Image, File, Avatar, Signature\n- **Special** — Boolean, Color, Location, Formula, Auto Number\n- **Relations** — Lookup (references other objects)' , className : 'whitespace-pre-line mb-6 block' } } ,
182301 { type : 'text' , properties : { value : '## Dashboard Widgets' , className : 'text-xl font-semibold mb-3 block' } } ,
183302 { type : 'text' , properties : { value : '- **Metric** — KPI cards with trends\n- **Bar Chart** — Categorical comparisons\n- **Donut Chart** — Proportional breakdowns\n- **Area Chart** — Time-series trends\n- **Line Chart** — Multi-series trends\n- **Table** — Tabular data summaries' , className : 'whitespace-pre-line mb-6 block' } } ,
303+ { type : 'text' , properties : { value : '## New Features' , className : 'text-xl font-semibold mb-3 block' } } ,
304+ { type : 'text' , properties : { value : '- **FormField.dependsOn** — Conditional field visibility based on parent field value\n- **FormField.visibleOn** — Expression-based field visibility\n- **ActionParam UI** — Parameter collection dialog before action execution\n- **Page Templates** — Predefined page layout templates (default, header-sidebar-main, three-column, dashboard)' , className : 'whitespace-pre-line mb-6 block' } } ,
184305 { type : 'text' , properties : { value : '## View Types' , className : 'text-xl font-semibold mb-3 block' } } ,
185306 { type : 'text' , properties : { value : '- **Grid** — Default tabular view with sort, filter, search\n- **Kanban** — Card board grouped by any select field\n- **Calendar** — Date-based event visualization\n- **Gantt** — Project timeline with dependencies\n- **Timeline** — Chronological activity stream\n- **Map** — Geographic data on interactive map\n- **Gallery** — Visual card grid layout' , className : 'whitespace-pre-line block' } } ,
186307 ] ,
@@ -196,7 +317,7 @@ export default defineStack({
196317 version : '1.0.0' ,
197318 type : 'app' ,
198319 name : 'Platform Showcase' ,
199- description : 'Demonstrates all field types, views, and dashboard widgets' ,
320+ description : 'Demonstrates all field types, views, dashboard widgets, conditional forms, actions, and page templates ' ,
200321 data : [
201322 {
202323 object : 'kitchen_sink' ,
@@ -286,6 +407,97 @@ export default defineStack({
286407 } ,
287408 ] ,
288409 } ,
410+ {
411+ object : 'showcase' ,
412+ mode : 'upsert' ,
413+ records : [
414+ {
415+ title : 'Cloud Infrastructure Setup' ,
416+ description : 'Setting up cloud infrastructure for production deployment' ,
417+ category : 'software' ,
418+ sub_category : 'web_app' ,
419+ priority : 'high' ,
420+ status : 'active' ,
421+ price : 4500 ,
422+ discount_percent : 10 ,
423+ start_date : daysFromNow ( - 10 ) ,
424+ end_date : daysFromNow ( 30 ) ,
425+ owner_email : 'alice@example.com' ,
426+ is_featured : true ,
427+ tags : [ 'new' , 'premium' ] ,
428+ } ,
429+ {
430+ title : 'Server Rack Procurement' ,
431+ description : 'Purchasing new server racks for data center expansion' ,
432+ category : 'hardware' ,
433+ sub_category : 'server' ,
434+ priority : 'medium' ,
435+ status : 'review' ,
436+ price : 12000 ,
437+ discount_percent : 5 ,
438+ start_date : daysFromNow ( - 5 ) ,
439+ end_date : daysFromNow ( 60 ) ,
440+ owner_email : 'bob@example.com' ,
441+ is_featured : false ,
442+ tags : [ 'popular' ] ,
443+ } ,
444+ {
445+ title : 'Security Consulting' ,
446+ description : 'Annual security audit and consulting engagement' ,
447+ category : 'service' ,
448+ sub_category : 'consulting' ,
449+ priority : 'critical' ,
450+ status : 'active' ,
451+ price : 8000 ,
452+ start_date : daysFromNow ( 0 ) ,
453+ end_date : daysFromNow ( 90 ) ,
454+ owner_email : 'carol@example.com' ,
455+ is_featured : true ,
456+ tags : [ 'premium' ] ,
457+ } ,
458+ {
459+ title : 'Mobile App Redesign' ,
460+ description : 'Redesigning the mobile application with new UX patterns' ,
461+ category : 'software' ,
462+ sub_category : 'mobile_app' ,
463+ priority : 'high' ,
464+ status : 'draft' ,
465+ start_date : daysFromNow ( 15 ) ,
466+ owner_email : 'dave@example.com' ,
467+ is_featured : false ,
468+ tags : [ 'new' ] ,
469+ } ,
470+ {
471+ title : 'Laptop Refresh Program' ,
472+ description : 'Annual laptop replacement for engineering team' ,
473+ category : 'hardware' ,
474+ sub_category : 'laptop' ,
475+ priority : 'low' ,
476+ status : 'completed' ,
477+ price : 25000 ,
478+ discount_percent : 15 ,
479+ start_date : daysFromNow ( - 60 ) ,
480+ end_date : daysFromNow ( - 5 ) ,
481+ owner_email : 'eve@example.com' ,
482+ is_featured : false ,
483+ tags : [ 'sale' ] ,
484+ } ,
485+ {
486+ title : 'Team Training Workshop' ,
487+ description : 'Advanced TypeScript and React training for the team' ,
488+ category : 'service' ,
489+ sub_category : 'training' ,
490+ priority : 'medium' ,
491+ status : 'active' ,
492+ price : 3000 ,
493+ start_date : daysFromNow ( 20 ) ,
494+ end_date : daysFromNow ( 22 ) ,
495+ owner_email : 'frank@example.com' ,
496+ is_featured : true ,
497+ tags : [ 'popular' , 'new' ] ,
498+ } ,
499+ ] ,
500+ } ,
289501 ] ,
290502 } ,
291503} ) ;
0 commit comments