feat: AI Create Card on the dashboard#156
Open
parth0025 wants to merge 1 commit into
Open
Conversation
Adds an "AI Create Card" button beside the existing "+ Add Card" on
the dashboard. Clicking it opens a sidebar where the user types a
natural-language request ("show me a pie chart of urgent open tasks
for the AlianHub project"). The AI returns a fully-populated card
definition, the user previews it, and on confirm the card commits via
the exact same backend write path the manual modal already uses — no
new dashboard routes, no schema changes.
What landed in this PR:
== Backend ==
- utils/aiPrompts.json: new prompt entry "Dashboard Card Generator"
(_id 67ff000000000000aicard001). The prompt now includes:
* USER_REQUEST / CARD_CATALOGUE / USER_CONTEXT substitution keys.
* responseFormat: {type: "json_object"} so the model is contractually
required to return parseable JSON.
* temperature: 0.2 for deterministic output.
* Six few-shot examples covering pie/bar charts, task list with
multi-filter, assignee filter, time-tracked summary, task counts
with measure/calculation/timerange, TASKLIST.fields multi-select,
and QueueListComp.statusArray.
* Per-field-type output rules (enum id vs name, multi-select arrays,
project/user/status id resolution).
- Modules/AI/controller.js:
* Fixed pre-existing outputFormat duplication bug — was appended once
per matched substitution key (3x for our prompt). Now appended once
after the substitution loop. Backwards-compatible.
* Non-streaming branch now forwards optional responseFormat and
temperature from the prompt entry to OpenAI. Existing prompts
without these fields keep OpenAI defaults.
== Frontend ==
- frontend/src/plugins/dashboard/components/AICardSidebar.vue (new):
Self-contained sidebar. Bypasses composable/aiHelper.js because the
existing helper has two silent-bail bugs documented inline (companyUsers
not-array TypeError + permission=null routing to projectRules).
Replicates only the plan check + Swal upgrade dialog and POSTs to
/api/v1/generatePrompt directly. Server-side quota tracking
(limitCountUpdate) is preserved.
Schema-aware catalogue summary in buildCatalogueSummary:
* One indented line per configurable field with type, required flag,
enum {id=name, ...} mapping for dropdowns, default value.
* Distinguishes single-select vs multi-select (Array.isArray of
default value) and emits "array of enum ids" vs "enum" so the model
knows TASKLIST.fields takes [3, 4, 5] not 3.
* Skips fields with disabled:true / hidden:true / type:"filter" so
the AI doesn't try to populate them.
* Resolves dashboardCard.<description> via vue-i18n into a human
sentence per card.
Per-field validateField with type-specific coercion:
* text → trimmed string capped by rules max length.
* radio → coerced boolean.
* dropdown w/ options → exact id → numeric coercion ("3" → 3) →
name fallback ("both" → 3) → catalogue default (with $numberLong
normalisation so TASKLIST.groupBy "0" comes through as 0).
* multi-select dropdown → maps every supplied value through the
coercer, de-dupes, falls back to array default.
* projectId → resolveProjectIds (exact _id, case-insensitive name,
first-project fallback).
* AssigneeUserId → resolveMemberIds (userId, Employee_Name).
* statusArray (QueueListComp) → resolveStatusKeys against
USER_CONTEXT.statusKeys.
* Disabled/hidden fields inherit the catalogue default unconditionally.
Runtime context (buildUserContext): { projects, statusKeys,
priorityKeys, members, taskTypes } so the model has the IDs it needs
for filters and member resolution.
Modern minimalist UI:
* Heading + subtitle, no asterisk-on-label.
* 10px-radius textarea with indigo focus ring.
* Live char counter (current / 500) + dynamic helper text
("Minimum 5 characters" idle, "X more to go" warning).
* Five quick-pick chips (workload, assignee, urgent, calendar,
time-tracking) filtered against the catalogue's available
cardTypes. Clicking populates the textarea.
* dl-based preview with subtle row dividers and indigo filter tags.
* Indigo primary / outline secondary buttons with proper disabled
treatment.
* Loading spinner with min-height so the panel doesn't collapse.
* Responsive: <=767px → full-viewport width, 16px font (avoids iOS
auto-zoom on focus), buttons stack column-reverse.
- frontend/src/plugins/dashboard/views/HomePage.vue:
Mounts <AICardSidebar/> beside the existing AdvanceSearchModal,
exposes openAiSidebar() via defineExpose alongside handleToggle, and
routes the card-generated event through handleCardAddOnDashboard so
the AI path lands on the same backend write as the manual modal.
- frontend/src/plugins/dashboard/views/Home.vue:
New "AI Create Card" button beside "+ Add Card", gated by
selectedCompany.planFeature.aiPermission so users on plans without
AI never see the entry point.
- frontend/src/locales/en.js:
New AICard.* section (button label, sidebar copy, helper text, chip
labels + their full prompts, preview labels, error messages). The
other 10 locales fall back to English via vue-i18n until translators
backfill (follow-up task already spawned).
== Card schemas covered (full catalogue audit) ==
Verified each catalogue entry against its renderer. The AI now emits
fully-populated cardData for:
- TASKLIST: fields (multi-select 1-7), groupBy (0/2/3/4), projectId.
- QueueListComp: statusArray from company status keys.
- TimeEstimatedComp / TimeTrackComp / TimeEstimatedWorkloadComp:
logtype enum (1-3), timerange enum (1-8), AssigneeUserId, projectId.
- TotalUrgentTasksComp: measure enum (1-3 with $numberLong handling),
calculation enum (1-6), timerange, taskLabel, AssigneeUserId.
- WorkloadByStatus* / TasksByAssignee*: isPercentage, isShowLegend,
isShowDataLabels, isParentTask, projectId.
- CalendarCard: projectId only (its renderer reads only projectId).
== Deferred (separate follow-ups) ==
- Streaming generation, chat-style refinement, inline preview editing.
- Server-side card validation hardening (benefits the manual flow too).
- 3x duplicate TotalUrgentTasksComp entries in cardComponent.json.
- Translation backfill for the 10 non-English locales.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an "AI Create Card" button beside the existing "+ Add Card" on the dashboard. Clicking it opens a sidebar where the user types a natural-language request ("show me a pie chart of urgent open tasks for the AlianHub project"). The AI returns a fully-populated card definition, the user previews it, and on confirm the card commits via the exact same backend write path the manual modal already uses — no new dashboard routes, no schema changes.
What landed in this PR:
== Backend ==
== Frontend ==
frontend/src/plugins/dashboard/components/AICardSidebar.vue (new): Self-contained sidebar. Bypasses composable/aiHelper.js because the existing helper has two silent-bail bugs documented inline (companyUsers not-array TypeError + permission=null routing to projectRules). Replicates only the plan check + Swal upgrade dialog and POSTs to /api/v1/generatePrompt directly. Server-side quota tracking (limitCountUpdate) is preserved.
Schema-aware catalogue summary in buildCatalogueSummary:
Per-field validateField with type-specific coercion:
Runtime context (buildUserContext): { projects, statusKeys,
priorityKeys, members, taskTypes } so the model has the IDs it needs
for filters and member resolution.
Modern minimalist UI:
frontend/src/plugins/dashboard/views/HomePage.vue: Mounts beside the existing AdvanceSearchModal, exposes openAiSidebar() via defineExpose alongside handleToggle, and routes the card-generated event through handleCardAddOnDashboard so the AI path lands on the same backend write as the manual modal.
frontend/src/plugins/dashboard/views/Home.vue: New "AI Create Card" button beside "+ Add Card", gated by selectedCompany.planFeature.aiPermission so users on plans without AI never see the entry point.
frontend/src/locales/en.js: New AICard.* section (button label, sidebar copy, helper text, chip labels + their full prompts, preview labels, error messages). The other 10 locales fall back to English via vue-i18n until translators backfill (follow-up task already spawned).
== Card schemas covered (full catalogue audit) ==
Verified each catalogue entry against its renderer. The AI now emits fully-populated cardData for:
== Deferred (separate follow-ups) ==
Pull Request Template Chooser
Please click the link that matches your contribution type to load the correct format.
Bug Fix
Use this for fixing broken logic or UI glitches.
New Feature
Use this for adding new functionality or components.
Refactor
Use this for code cleanup, performance tweaks, or technical debt.
General Summary
If you don't want to use a specific template, please provide a brief summary of your changes below.