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
1 change: 1 addition & 0 deletions examples/app-showcase/src/apps/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export const ShowcaseApp = App.create({
{ id: 'nav_tasks', type: 'object', objectName: 'showcase_task', label: 'Tasks', icon: 'check-square' },
{ id: 'nav_accounts', type: 'object', objectName: 'showcase_account', label: 'Accounts', icon: 'building' },
{ id: 'nav_invoices', type: 'object', objectName: 'showcase_invoice', label: 'Invoices', icon: 'receipt' },
{ id: 'nav_products', type: 'object', objectName: 'showcase_product', label: 'Products', icon: 'package' },
{ id: 'nav_teams', type: 'object', objectName: 'showcase_team', label: 'Teams', icon: 'users' },
{ id: 'nav_categories', type: 'object', objectName: 'showcase_category', label: 'Categories', icon: 'list-tree' },
{ id: 'nav_field_zoo', type: 'object', objectName: 'showcase_field_zoo', label: 'Field Zoo', icon: 'shapes' },
Expand Down
16 changes: 15 additions & 1 deletion examples/app-showcase/src/data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Project } from '../objects/project.object.js';
import { Task } from '../objects/task.object.js';
import { Category } from '../objects/category.object.js';
import { Team, ProjectMembership } from '../objects/team.object.js';
import { Product } from '../objects/invoice.object.js';

/**
* Seed data sized to "feed every view": every Kanban column is populated,
Expand Down Expand Up @@ -77,6 +78,19 @@ const teams = defineSeed(Team, {
],
});

// Catalog products the invoice line's `product` lookup picks from. Selecting
// one auto-fills the line's description + unit_price (matching field names).
const products = defineSeed(Product, {
mode: 'upsert',
externalId: 'sku',
records: [
{ sku: 'WIDGET-A', name: 'Widget A', description: 'Standard widget', unit_price: 29.99, active: true },
{ sku: 'WIDGET-B', name: 'Widget B', description: 'Deluxe widget', unit_price: 49.99, active: true },
{ sku: 'GADGET-X', name: 'Gadget X', description: 'Premium gadget', unit_price: 99.0, active: true },
{ sku: 'SERVICE-HR', name: 'Consulting Hour', description: 'Professional services, per hour', unit_price: 150.0, active: true },
],
});

const memberships = defineSeed(ProjectMembership, {
mode: 'insert',
records: [
Expand All @@ -86,4 +100,4 @@ const memberships = defineSeed(ProjectMembership, {
],
});

export const ShowcaseSeedData = [accounts, projects, tasks, categories, teams, memberships];
export const ShowcaseSeedData = [accounts, products, projects, tasks, categories, teams, memberships];
2 changes: 1 addition & 1 deletion examples/app-showcase/src/objects/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ export { Project } from './project.object.js';
export { Task } from './task.object.js';
export { Category } from './category.object.js';
export { Team, ProjectMembership } from './team.object.js';
export { Invoice, InvoiceLine } from './invoice.object.js';
export { Product, Invoice, InvoiceLine } from './invoice.object.js';
export { FieldZoo } from './field-zoo.object.js';
28 changes: 27 additions & 1 deletion examples/app-showcase/src/objects/invoice.object.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,29 @@

import { ObjectSchema, Field } from '@objectstack/spec/data';

/**
* Product — a small price-book / catalog. The invoice line's `product` lookup
* points here; selecting a product auto-fills the line's `description` and
* `unit_price` (the line-item grid copies matching field names from the chosen
* record — the catalog typeahead every invoicing tool has: QuickBooks
* "Product/Service", Stripe price catalog, NetSuite item column).
*/
export const Product = ObjectSchema.create({
name: 'showcase_product',
label: 'Product',
pluralLabel: 'Products',
icon: 'package',
description: 'A sellable product with a catalog price.',

fields: {
name: Field.text({ label: 'Name', required: true, searchable: true, maxLength: 120 }),
sku: Field.text({ label: 'SKU', searchable: true, maxLength: 40 }),
description: Field.text({ label: 'Description', maxLength: 200 }),
unit_price: Field.currency({ label: 'Unit Price', scale: 2, min: 0 }),
active: Field.boolean({ label: 'Active', defaultValue: true }),
},
});

/**
* Invoice + Invoice Line — the canonical master-detail "header + line items"
* shape. Unlike project↔task (a task is added to a project over time), an
Expand Down Expand Up @@ -58,7 +81,10 @@ export const InvoiceLine = ObjectSchema.create({
inlineEdit: 'grid',
inlineTitle: 'Line Items',
}),
product: Field.text({ label: 'Product', required: true, maxLength: 200 }),
// Catalog lookup. Picking a product auto-fills `description` + `unit_price`
// (the grid copies same-named fields from the selected product record).
product: Field.lookup('showcase_product', { label: 'Product', required: true }),
description: Field.text({ label: 'Description', maxLength: 200 }),
quantity: Field.number({ label: 'Qty', required: true, min: 0, defaultValue: 1 }),
unit_price: Field.currency({ label: 'Unit Price', scale: 2, min: 0 }),
// Amount = Qty × Unit Price. Kept as a *stored* currency column (so the
Expand Down