/* * Simple Todo — minimal CRUD example. * * One Custom Object (`simple_todo__c`) with name / status / priority / due date / notes, * one section, one list view ("Open todos"), one page layout, and one SDUI page that * renders the records via ObjectListView. No SDUI beyond ObjectListView. * * simple_todo__c ← name, status, priority, due_date, notes * * Run: * yarn tsn examples/manifest/simple-todo-app/simple-todo-app.ts \ * > examples/manifest/simple-todo-app/manifest.json */ import { App, Category, CustomObject, CustomObjectFieldSection, CustomObjectPageLayout, DateField, ListViewDef, LongTextField, ManifestBuilder, ManifestFunction, SduiPage, SelectField, } from '@rippling/rippling-sdk/lib/manifest'; const manifest = new ManifestBuilder({ key: 'simple_todo_app', name: 'Simple Todo', description: 'A minimal CRUD todo app: one Custom Object rendered as an SDUI ObjectListView', }); const todoCategory = new Category(manifest, { apiName: 'simple_todo__c', name: 'Tasks', description: 'Container for todo records', }); // ── Todo object ───────────────────────────────────────────────────────────── const todoObj = new CustomObject(manifest, { apiName: 'simple_todo__c', name: 'Todo', pluralLabel: 'Todos', category: todoCategory, description: 'A single task with status, priority, and due date', icon: { emoji: '✅' }, }); const detailsSection = new CustomObjectFieldSection(todoObj, { name: 'Details', sectionId: 'sec_todo_details', }); const statusField = new SelectField(todoObj, { apiName: 'status__c', displayName: 'Status', description: 'Status field', options: ['To Do', 'In Progress', 'Done'], required: true, section: detailsSection, }); const priorityField = new SelectField(todoObj, { apiName: 'priority__c', displayName: 'Priority', description: 'Priority field', options: ['Low', 'Medium', 'High'], section: detailsSection, }); const dueDateField = new DateField(todoObj, { apiName: 'due_date__c', displayName: 'Due date', description: 'Due date field', section: detailsSection, }); const notesField = new LongTextField(todoObj, { apiName: 'notes__c', displayName: 'Notes', description: 'Notes field', maxLength: 4000, section: detailsSection, }); // ── List view: Open todos ─────────────────────────────────────────────────── new ListViewDef(todoObj, { viewId: 'view_simple_todo_open', name: 'Open todos', description: 'Everything that is not Done, ordered by due date', fields: ['name', statusField, priorityField, dueDateField], orderBy: dueDateField, sortOrder: 'ASC', isPublic: true, objectScope: 'all', rqlFilter: "(status__c != 'Done')", }); // ── Page layout ───────────────────────────────────────────────────────────── new CustomObjectPageLayout(todoObj, { apiName: 'default', name: 'Todo', layoutId: 'layout_simple_todo', tabEdits: { newTabs: [ { key: 'todo', name: 'Todo', type: 'tab_with_sections', sections: [ { name: 'Details', type: 'fields_section', section: detailsSection, fields: [{ field: 'name', editable: true }, statusField, priorityField, dueDateField, notesField], }, ], }, ], systemTabEdits: {}, tabsOrder: ['todo'], }, visibilityConditions: {}, }); // ── SDUI page (ObjectListView) ────────────────────────────────────────────── const todoListFn = new ManifestFunction(manifest, { apiName: 'simple_todo_list_fn', name: 'renderTodos', description: 'SDUI ObjectListView for todo records', codeFile: './examples/manifest/simple-todo-app/functions/todo-list.ts', dependencies: { '@rippling/rippling-sdk': '^0.2.0-alpha.33', '@rippling/pebble-sdui-web': '^0.3.0' }, isAsync: false, }); const todoListPage = new SduiPage(manifest, { sduiPageId: 'simple_todo_page', name: 'Todos', function: todoListFn, }); new App(manifest, { apiName: 'simple_todo_app', name: 'Simple Todo', description: 'Minimal todo app: one Custom Object with an SDUI ObjectListView page', appType: 'custom', pages: [todoListPage], }); console.log(manifest.preview());