Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/app-showcase/objectstack.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import { ChartGalleryDashboard, OpsDashboard } from './src/dashboards/index.js';
import { ShowcaseTaskDataset, ShowcaseProjectDataset } from './src/datasets/index.js';
import { allReports } from './src/reports/index.js';
import { allActions } from './src/actions/index.js';
import { ComponentGalleryPage, ProjectWorkspacePage, ProjectDetailPage, TaskWorkbenchPage, TaskTriagePage, TaskBoardPage, TaskCalendarPage, TaskGalleryPage, TaskSchedulePage, TaskTimelinePage, TaskMapPage, TaskAllViewsPage, ActiveProjectsPage, TaskDetailPage, AccountDetailPage } from './src/pages/index.js';
import { ComponentGalleryPage, ProjectWorkspacePage, ProjectDetailPage, TaskWorkbenchPage, TaskTriagePage, TaskBoardPage, TaskCalendarPage, TaskGalleryPage, TaskSchedulePage, TaskTimelinePage, TaskMapPage, TaskAllViewsPage, ActiveProjectsPage, TaskDetailPage, AccountDetailPage, ReviewQueuePage, NewProjectWizardPage, MyWorkPage } from './src/pages/index.js';
import { allFlows } from './src/flows/index.js';
import { allWebhooks } from './src/webhooks/index.js';
import { allHooks } from './src/hooks/index.js';
Expand Down Expand Up @@ -143,7 +143,7 @@ export default defineStack({
apps: [ShowcaseApp],
portals: allPortals,
views: [TaskViews, ProjectViews],
pages: [ComponentGalleryPage, ProjectWorkspacePage, ProjectDetailPage, TaskWorkbenchPage, TaskTriagePage, TaskBoardPage, TaskCalendarPage, TaskGalleryPage, TaskSchedulePage, TaskTimelinePage, TaskMapPage, TaskAllViewsPage, ActiveProjectsPage, TaskDetailPage, AccountDetailPage],
pages: [ComponentGalleryPage, ProjectWorkspacePage, ProjectDetailPage, TaskWorkbenchPage, TaskTriagePage, TaskBoardPage, TaskCalendarPage, TaskGalleryPage, TaskSchedulePage, TaskTimelinePage, TaskMapPage, TaskAllViewsPage, ActiveProjectsPage, TaskDetailPage, AccountDetailPage, ReviewQueuePage, NewProjectWizardPage, MyWorkPage],
dashboards: [ChartGalleryDashboard, OpsDashboard],
books: allBooks,
datasets: [ShowcaseTaskDataset, ShowcaseProjectDataset],
Expand Down
3 changes: 3 additions & 0 deletions examples/app-showcase/src/apps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ export const ShowcaseApp = App.create({
label: 'Pages',
icon: 'layout',
children: [
{ id: 'nav_my_work', type: 'page', pageName: 'showcase_my_work', label: 'My Work', icon: 'home' },
{ id: 'nav_review_queue', type: 'page', pageName: 'showcase_review_queue', label: 'Approvals', icon: 'check-check' },
{ id: 'nav_new_project_wizard', type: 'page', pageName: 'showcase_new_project_wizard', label: 'New Project (Wizard)', icon: 'wand-2' },
{ id: 'nav_gallery', type: 'page', pageName: 'showcase_component_gallery', label: 'Component Gallery', icon: 'layout-template' },
{ id: 'nav_project_workspace', type: 'page', pageName: 'showcase_project_workspace', label: 'New Project + Tasks', icon: 'folder-plus' },
// ADR-0047 interface mode: same object as nav_tasks, curated surface.
Expand Down
3 changes: 3 additions & 0 deletions examples/app-showcase/src/pages/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ export { TaskTriagePage } from './task-triage.page.js';
export { ActiveProjectsPage } from './active-projects.page.js';
export { TaskDetailPage } from './task-detail.page.js';
export { AccountDetailPage } from './account-detail.page.js';
export { ReviewQueuePage } from './review-queue.page.js';
export { NewProjectWizardPage } from './new-project-wizard.page.js';
export { MyWorkPage } from './my-work.page.js';
export {
TaskBoardPage,
TaskCalendarPage,
Expand Down
62 changes: 62 additions & 0 deletions examples/app-showcase/src/pages/my-work.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

import type { Page } from '@objectstack/spec/ui';

/**
* My Work — a role-aware workspace home that *composes* live data the way a
* real landing page does, instead of listing one component per type:
* • a KPI hero row of live `object-metric` tiles (team throughput);
* • a personal work queue — `object-grid` filtered to the signed-in user
* via the `{current_user_id}` token (records I own);
* • a role-gated card (`visible` expression) that only the admin sees —
* demonstrating per-user differentiated rendering.
*/
export const MyWorkPage: Page = {
name: 'showcase_my_work',
label: 'My Work',
type: 'home',
template: 'header-sidebar-main',
isDefault: false,
kind: 'full',
regions: [
{
name: 'header',
width: 'full',
components: [
{ type: 'page:header', properties: { title: 'My Work', subtitle: 'Your queue, the team’s throughput, and what needs attention.' } },
],
},
{
name: 'main',
width: 'large',
components: [
// KPI hero row — live aggregates over the team's work.
{ type: 'object-metric', properties: { objectName: 'showcase_task', label: 'Open Tasks', icon: 'list-checks', aggregate: { field: 'id', function: 'count' }, filter: { status: { $ne: 'done' } } } },
{ type: 'object-metric', properties: { objectName: 'showcase_task', label: 'In Review', icon: 'eye', aggregate: { field: 'id', function: 'count' }, filter: { status: 'in_review' } } },
{ type: 'object-metric', properties: { objectName: 'showcase_project', label: 'At-Risk Projects', icon: 'alert-triangle', aggregate: { field: 'id', function: 'count' }, filter: { health: 'red' } } },
{ type: 'element:divider', properties: {} },
// Personal work queue — records owned by the signed-in user.
{
type: 'object-grid',
properties: {
objectName: 'showcase_task',
columns: ['title', 'project', 'status', 'priority', 'due_date'],
filters: [['owner_id', '=', '{current_user_id}']],
},
},
],
},
{
name: 'sidebar',
width: 'small',
components: [
// Role-gated: only the admin sees this card — differentiated rendering.
{
type: 'page:card',
properties: { title: 'Leadership View', visible: "current_user.email == 'admin@objectos.ai'" },
},
{ type: 'element:text', properties: { content: 'Tip: open Delivery Operations for the org-wide dashboard.' } },
],
},
],
};
43 changes: 43 additions & 0 deletions examples/app-showcase/src/pages/new-project-wizard.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

import type { Page } from '@objectstack/spec/ui';

/**
* New Project Wizard — a multi-step (wizard) form surface. The showcase
* defines wizard/tabbed/split form view *types* but had no page that actually
* walks a user through a stepped create flow. This renders `object-form` with
* `formType: 'wizard'` directly: Basics → Status → Budget, with a step
* indicator, over showcase_project.
*/
export const NewProjectWizardPage: Page = {
name: 'showcase_new_project_wizard',
label: 'New Project (Wizard)',
type: 'app',
kind: 'full',
template: 'default',
isDefault: false,
regions: [
{
name: 'main',
width: 'large',
components: [
{
type: 'object-form',
properties: {
objectName: 'showcase_project',
mode: 'create',
formType: 'wizard',
showStepIndicator: true,
title: 'Create a Project',
description: 'A three-step wizard — basics, status, then budget & schedule.',
sections: [
{ label: 'Basics', description: 'Name the project and bind its account.', fields: ['name', 'account', 'owner'] },
{ label: 'Status & Health', description: 'Where does it stand today?', fields: ['status', 'health'] },
{ label: 'Budget & Schedule', description: 'Money and dates.', fields: ['budget', 'spent', 'start_date', 'end_date'] },
],
},
},
],
},
],
};
38 changes: 38 additions & 0 deletions examples/app-showcase/src/pages/review-queue.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// Copyright (c) 2025 ObjectStack. Licensed under the Apache-2.0 license.

import type { Page } from '@objectstack/spec/ui';

/**
* Approvals · Review Queue — the human side of the approval / review flows.
* The showcase has ~20 approval & review flows but no UI where a reviewer
* sees what is waiting on them; this is that surface.
*
* An interface (list) page over tasks currently `in_review` — the work
* awaiting a decision — with the source object's actions surfaced as toolbar
* buttons (Mark done = approve & complete) and a drawer to inspect each item.
* Tabs let the reviewer pivot to urgent or blocked work.
*/
export const ReviewQueuePage: Page = {
name: 'showcase_review_queue',
label: 'Approvals',
type: 'list',
object: 'showcase_task',
kind: 'full',
template: 'default',
isDefault: false,
regions: [],
interfaceConfig: {
source: 'showcase_task',
columns: ['title', 'project', 'assignee', 'priority', 'due_date'],
// Always-on base filter: only items awaiting review reach this queue.
filterBy: [{ field: 'status', operator: 'equals', value: 'in_review' }],
sort: [{ field: 'due_date', order: 'asc' }],
appearance: { showDescription: true, allowedVisualizations: ['grid'] },
userActions: { sort: true, search: true, filter: false, rowHeight: false, addRecordForm: false },
// Object actions as toolbar buttons — "approve & complete" the reviewed item.
buttons: ['showcase_mark_done'],
// Click a row → drawer with the full record to review before deciding.
recordAction: 'drawer',
showRecordCount: true,
},
};
Loading