Refined demo workspace creation skill (rebased, review fixes) (#19274)
## Summary Rebased version of #19051 with all review comments addressed. Clean branch on latest main, lint/typecheck/tests passing. ### Changes from original PR - AI can now create, update, and delete **view filters** (`ViewFilterToolsFactory`) and **view sorts** (`ViewSortToolsFactory`) - `create_view` now accepts `calendarFieldName`, `calendarLayout`, and `fieldNames` to configure views at creation time - Three new standard skills: `view-building`, `view-filters-and-sorts`, `custom-objects-cleanup` - `workspace-demo-seeding` skill reworked to keep standard objects and enrich them with custom fields - Cache invalidation for nav menu items when object `isActive` changes - Dashboard tool descriptions improved (RECORD_TABLE widget workflow) ### Review comments addressed (all 10 from #19051) 1. **Sentry + Cubic**: Calendar field DATE/DATE_TIME validation — added `resolveCalendarFieldMetadataId` using `isFieldMetadataDateKind` 2. **Cubic**: "navigate tool" → "navigate_app tool" in skill metadata (all 7 occurrences) 3. **Copilot**: KANBAN views now require `mainGroupByFieldName` — throws clear error if missing 4. **Copilot**: CALENDAR views now require both `calendarFieldName` and `calendarLayout` — validated before DB call 5. **Copilot**: Mock field fixtures include `type` property (DATE_TIME, TEXT, SELECT) 6. **Copilot**: `ViewFilterValue` type assertion instead of unsafe `as string` casts (3 locations) 7. **FelixMalfait**: Removed `NavigationMenuItemObjectDeactivationListener` — replaced with cache invalidation 8. **FelixMalfait**: Consolidated `ViewFilterToolProvider` and `ViewSortToolProvider` into single `ViewToolProvider` 9. Removed `VIEW_FILTER` and `VIEW_SORT` from `ToolCategory` enum (merged into `VIEW`) 10. Removed stale `existingFeatureFlagsMap` param incompatible with current main ## Test plan - [x] `npx nx lint:diff-with-main twenty-server` — passes - [x] `npx nx typecheck twenty-server` — passes - [x] `view-tools.factory.spec.ts` — all 20 tests pass (including 3 new validation tests) Supersedes #19051 https://claude.ai/code/session_01QPV74NU6vzmJb32e4i899E --------- Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
+9
-1
@@ -25,7 +25,7 @@ const widgetSchema = z.object({
|
||||
.uuid()
|
||||
.optional()
|
||||
.describe(
|
||||
'REQUIRED for GRAPH widgets: UUID of the object to aggregate (e.g., opportunity, company)',
|
||||
'REQUIRED for GRAPH and RECORD_TABLE widgets: UUID of the object to aggregate or display',
|
||||
),
|
||||
configuration: widgetConfigurationSchema,
|
||||
});
|
||||
@@ -82,6 +82,14 @@ WIDGET TYPES:
|
||||
|
||||
6. STANDALONE_RICH_TEXT: { type: "STANDALONE_RICH_TEXT", configuration: { configurationType: "STANDALONE_RICH_TEXT", body: { ... } } }
|
||||
|
||||
7. RECORD_TABLE: displays a live, filterable record list directly on the dashboard.
|
||||
- IMPORTANT: you MUST create a dedicated view for the widget BEFORE creating the widget. Use create_view to create a new TABLE view for the object, then pass its ID as viewId. Never reuse an existing index-page view — widget views and record index views must not overlap.
|
||||
- Requires: objectMetadataId (top-level, UUID of the object to display) AND configuration.viewId (UUID of the dedicated view you just created)
|
||||
- configuration.configurationType must be "RECORD_TABLE"
|
||||
- Recommended size: rowSpan 8-10, columnSpan 12 (full width)
|
||||
- Workflow: (1) call create_view with type TABLE for the object → get the viewId, (2) call create_many_view_fields to add visible columns to that view, (3) create the widget with that viewId
|
||||
- Example: { type: "RECORD_TABLE", objectMetadataId: "<object-uuid>", configuration: { configurationType: "RECORD_TABLE", viewId: "<dedicated-view-uuid>" } }
|
||||
|
||||
AGGREGATION OPERATIONS: COUNT, SUM, AVG, MIN, MAX, COUNT_EMPTY, COUNT_NOT_EMPTY`,
|
||||
inputSchema: createCompleteDashboardSchema,
|
||||
execute: async (parameters: {
|
||||
|
||||
Reference in New Issue
Block a user