@burdenoff/microfe-planmagnet 2026.1001.6 → 2026.1001.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  2. package/dist/planmagnet/PlanMagnetRoutes.js +10 -6
  3. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  4. package/dist/planmagnet/automation/automationRuleTypes.d.ts +31 -19
  5. package/dist/planmagnet/automation/automationRuleTypes.d.ts.map +1 -1
  6. package/dist/planmagnet/automation/automationRuleTypes.js +4 -8
  7. package/dist/planmagnet/automation/automationRuleTypes.js.map +1 -1
  8. package/dist/planmagnet/controls/FeatureControls.d.ts +18 -1
  9. package/dist/planmagnet/controls/FeatureControls.d.ts.map +1 -1
  10. package/dist/planmagnet/controls/FeatureControls.js +259 -202
  11. package/dist/planmagnet/controls/FeatureControls.js.map +1 -1
  12. package/dist/planmagnet/controls/FeedbackControls.d.ts +70 -0
  13. package/dist/planmagnet/controls/FeedbackControls.d.ts.map +1 -0
  14. package/dist/planmagnet/controls/FeedbackControls.js +153 -0
  15. package/dist/planmagnet/controls/FeedbackControls.js.map +1 -0
  16. package/dist/planmagnet/controls/SyncControls.d.ts.map +1 -1
  17. package/dist/planmagnet/controls/SyncControls.js +1 -0
  18. package/dist/planmagnet/controls/SyncControls.js.map +1 -1
  19. package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts +47 -0
  20. package/dist/planmagnet/controls/WebhookSubscriptionControls.d.ts.map +1 -0
  21. package/dist/planmagnet/controls/WebhookSubscriptionControls.js +542 -0
  22. package/dist/planmagnet/controls/WebhookSubscriptionControls.js.map +1 -0
  23. package/dist/planmagnet/dashboards/DashboardUI.js +7 -7
  24. package/dist/planmagnet/dashboards/cards/RiskSeverityCard.js +4 -4
  25. package/dist/planmagnet/forecast/DeliveryForecastCard.js +8 -8
  26. package/dist/planmagnet/forecast/ProjectOutlookCard.js +10 -10
  27. package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +9 -9
  28. package/dist/planmagnet/forecast/ResourceForecastCard.js +6 -6
  29. package/dist/planmagnet/integrations/syncTypes.d.ts +2 -1
  30. package/dist/planmagnet/integrations/syncTypes.d.ts.map +1 -1
  31. package/dist/planmagnet/integrations/syncTypes.js +19 -9
  32. package/dist/planmagnet/integrations/syncTypes.js.map +1 -1
  33. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +8 -8
  34. package/dist/planmagnet/pages/DashboardDashboardPagePage.js +23 -23
  35. package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
  36. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +340 -248
  37. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  38. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.d.ts.map +1 -1
  39. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js +172 -167
  40. package/dist/planmagnet/pages/IntegrationsSyncDetailPagePage.js.map +1 -1
  41. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.d.ts.map +1 -1
  42. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js +92 -83
  43. package/dist/planmagnet/pages/IntegrationsSyncsPagePage.js.map +1 -1
  44. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts +2 -0
  45. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.d.ts.map +1 -0
  46. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js +175 -0
  47. package/dist/planmagnet/pages/IntegrationsWebhooksPagePage.js.map +1 -0
  48. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.d.ts.map +1 -1
  49. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js +151 -126
  50. package/dist/planmagnet/pages/ProductsFeatureDetailPagePage.js.map +1 -1
  51. package/dist/planmagnet/pages/ProductsFeaturesPagePage.d.ts.map +1 -1
  52. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js +136 -129
  53. package/dist/planmagnet/pages/ProductsFeaturesPagePage.js.map +1 -1
  54. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.d.ts.map +1 -1
  55. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js +149 -119
  56. package/dist/planmagnet/pages/ProductsNewFeaturePagePage.js.map +1 -1
  57. package/dist/planmagnet/pages/ProductsProductsPagePage.js +13 -13
  58. package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +9 -9
  59. package/dist/planmagnet/pages/ProjectsBudgetsPagePage.js +8 -8
  60. package/dist/planmagnet/pages/ProjectsProjectsPagePage.js +12 -12
  61. package/dist/planmagnet/pages/ReportsReportsPagePage.js +23 -23
  62. package/dist/planmagnet/pages/TasksMyDashboardPagePage.js +18 -18
  63. package/dist/planmagnet/pages/TasksMyWorkPagePage.js +10 -10
  64. package/dist/planmagnet/pages/TasksTimeEntriesPagePage.js +5 -5
  65. package/dist/planmagnet/pages/analytics/DeliveryHealthCards.js +8 -8
  66. package/dist/planmagnet/pages/analytics/DeliveryKpisCard.js +6 -6
  67. package/dist/planmagnet/pages/analytics/MetricsCard.js +6 -6
  68. package/dist/planmagnet/pages/analytics/QualityMetricsCard.js +6 -6
  69. package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +8 -8
  70. package/dist/planmagnet/pages/analytics/StatusFlowCard.js +7 -7
  71. package/dist/planmagnet/pages/analytics/ThroughputCard.js +7 -7
  72. package/dist/planmagnet/pages/analytics/WorkBreakdownCard.js +7 -7
  73. package/dist/planmagnet/people/People.d.ts +14 -0
  74. package/dist/planmagnet/people/People.d.ts.map +1 -1
  75. package/dist/planmagnet/people/People.js +36 -22
  76. package/dist/planmagnet/people/People.js.map +1 -1
  77. package/dist/planmagnet/webhooks/webhookTypes.d.ts +54 -0
  78. package/dist/planmagnet/webhooks/webhookTypes.d.ts.map +1 -0
  79. package/dist/planmagnet/webhooks/webhookTypes.js +17 -0
  80. package/dist/planmagnet/webhooks/webhookTypes.js.map +1 -0
  81. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"ProductsNewFeaturePagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsNewFeaturePagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, X, Star, Loader2 } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { throwOnError } from '../utils/mutationResult';\nimport { parseIntField } from '../utils/formValidation';\nimport { ProjectSelect, WorkItemSearchSelect } from '../controls/Pickers';\nimport {\n EMPTY_PRIORITIZATION_FORM,\n EMPTY_RICE_FORM,\n PrioritizationScoreFields,\n RiceScoreFields,\n prioritizationScoresValid,\n riceInputsValid,\n type PrioritizationFormValues,\n type RiceFormValues,\n} from '../controls/PrioritizationControls';\n\nconst CREATE_FEATURE_REQUEST = gql`\n mutation CreateFeatureRequest($input: PlanmagnetCreateFeatureRequestInput!) {\n planmagnetCreateFeatureRequest(input: $input) {\n id\n title\n status\n businessValue\n effortEstimate\n priorityScore\n }\n }\n`;\n\nexport function ProductsNewFeaturePagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const [form, setForm] = useState({\n title: '',\n description: '',\n status: 'SUBMITTED' as string,\n businessValue: '50',\n effortEstimate: 'medium',\n tags: '',\n projectId: '',\n workItemId: '',\n });\n // PRM-27: MoSCoW/Kano/value/effort scoring, set at creation just like at edit time.\n const [prioritization, setPrioritization] =\n useState<PrioritizationFormValues>(EMPTY_PRIORITIZATION_FORM);\n // PRM-26: RICE, next to the value/effort scores above — effortScore is riceScore's own divisor.\n const [rice, setRice] = useState<RiceFormValues>(EMPTY_RICE_FORM);\n\n // Navigate only once the service has accepted the feature: with fe-libs' errorPolicy 'all' a refused\n // mutation resolves, so the old onCompleted navigation could leave the form as if it had saved.\n const [createFeature, { loading: saving }] = useMutation(CREATE_FEATURE_REQUEST, {\n refetchQueries: ['ListFeatureRequests'],\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n // Business value is a whole number from 0 to 100 (BOFF-7833: prod had stored 150).\n const businessValue = parseIntField(form.businessValue, { min: 0, max: 100 });\n const prioritizationValid = prioritizationScoresValid(prioritization);\n const value = parseIntField(prioritization.valueScore, { min: 1, max: 10 });\n const effort = parseIntField(prioritization.effortScore, { min: 1, max: 10 });\n const riceValid = riceInputsValid(rice);\n const reach = parseIntField(rice.reach, { min: 1, max: 10 });\n const impact = parseIntField(rice.impact, { min: 1, max: 10 });\n const confidence = parseIntField(rice.confidence, { min: 1, max: 10 });\n\n const statusOptions = [\n 'SUBMITTED',\n 'UNDER_REVIEW',\n 'PLANNED',\n 'IN_PROGRESS',\n 'COMPLETED',\n ] as const;\n const efforts = ['small', 'medium', 'large', 'epic'] as const;\n\n const handleCreate = async () => {\n if (!form.title.trim() || businessValue.invalid || !prioritizationValid || !riceValid) return;\n setSaveError(null);\n try {\n await throwOnError(\n createFeature({\n variables: {\n input: {\n title: form.title,\n description: form.description || undefined,\n status: form.status,\n businessValue: businessValue.value,\n effortEstimate: form.effortEstimate,\n projectId: form.projectId || undefined,\n workItemId: form.workItemId || undefined,\n tags: form.tags\n ? form.tags\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean)\n : undefined,\n moscow: prioritization.moscow || undefined,\n kano: prioritization.kano || undefined,\n valueScore: value.value,\n effortScore: effort.value,\n reach: reach.value,\n impact: impact.value,\n confidence: confidence.value,\n },\n },\n })\n );\n navigate('/products/features-page');\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The feature could not be created.');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">New Feature</h1>\n <p className=\"text-sm text-muted-foreground\">\n Define a new feature request with business value metrics.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/products/features-page')}>\n <X className=\"mr-1 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleCreate}\n disabled={\n saving ||\n !form.title.trim() ||\n businessValue.invalid ||\n !prioritizationValid ||\n !riceValid\n }\n >\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Create Feature\n </Button>\n </div>\n </div>\n\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n Failed to create feature: {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Feature Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. Advanced Search Filters\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n placeholder=\"Describe the feature and its user value...\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Status</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm capitalize\"\n value={form.status}\n onChange={(e) => setForm({ ...form, status: e.target.value })}\n >\n {statusOptions.map((s) => (\n <option key={s} value={s}>\n {s.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Effort Estimate</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm capitalize\"\n value={form.effortEstimate}\n onChange={(e) => setForm({ ...form, effortEstimate: e.target.value })}\n >\n {efforts.map((e) => (\n <option key={e} value={e}>\n {e}\n </option>\n ))}\n </select>\n </div>\n </div>\n {/* BOFF-7966: a request could not be tied to a project or to the work item that delivers it, so the\n release readiness card's \"customer requests riding on unfinished work\" could never fill. */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"feature-project\" className=\"text-sm font-medium\">\n Project\n </label>\n <div className=\"mt-1\">\n <ProjectSelect\n id=\"feature-project\"\n value={form.projectId}\n noneLabel=\"No project\"\n onChange={(projectId) => setForm({ ...form, projectId, workItemId: '' })}\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"feature-work-item\" className=\"text-sm font-medium\">\n Delivered by work item\n </label>\n <div className=\"mt-1\">\n <WorkItemSearchSelect\n id=\"feature-work-item\"\n projectId={form.projectId || undefined}\n value={form.workItemId}\n onChange={(workItemId) => setForm({ ...form, workItemId })}\n />\n </div>\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Tags (comma-separated)</label>\n <Input\n value={form.tags}\n onChange={(e) => setForm({ ...form, tags: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. search, ux, performance\"\n />\n </div>\n </CardContent>\n </Card>\n\n {/* PRM-27: MoSCoW, Kano and Value-vs-Effort scoring — an alternative to the Business Value card below. */}\n <Card>\n <CardHeader>\n <CardTitle>Prioritization</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <PrioritizationScoreFields\n idPrefix=\"feature-new\"\n values={prioritization}\n onChange={setPrioritization}\n />\n {/* PRM-26: RICE, next to the value/effort scores above. */}\n <div className=\"border-t pt-3\">\n <p className=\"text-sm font-medium mb-1\">RICE</p>\n <RiceScoreFields\n idPrefix=\"feature-new\"\n values={rice}\n onChange={setRice}\n effortScoreMissing={effort.value == null}\n />\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Star className=\"h-4 w-4\" />\n Business Value\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label htmlFor=\"feature-business-value\" className=\"text-sm font-medium\">\n Business Value (0-100)\n </label>\n <Input\n id=\"feature-business-value\"\n type=\"number\"\n min={0}\n max={100}\n step={1}\n value={form.businessValue}\n onChange={(e) => setForm({ ...form, businessValue: e.target.value })}\n aria-invalid={businessValue.invalid}\n className=\"mt-1\"\n />\n {businessValue.invalid ? (\n <p role=\"alert\" className=\"text-xs text-destructive mt-1\">\n Business value must be a whole number from 0 to 100.\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground mt-1\">\n How much business value does this feature deliver?\n </p>\n )}\n </div>\n\n <div className=\"p-4 bg-muted rounded-md text-center\">\n <p className=\"text-xs text-muted-foreground\">Business Value Score</p>\n <p className=\"text-3xl font-bold text-primary mt-2\">\n {businessValue.invalid || businessValue.value === undefined\n ? '—'\n : businessValue.value}\n </p>\n <p className=\"text-xs text-muted-foreground\">out of 100</p>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ProductsNewFeaturePagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ProductsNewFeaturePagePage.tsx"],"sourcesContent":["// eslint-disable-next-line @typescript-eslint/ban-ts-comment\n// @ts-nocheck\nimport { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useMutation } from '@apollo/client/react';\nimport { Card, CardContent, CardHeader, CardTitle, Button, Input } from '@burdenoff/fe-libs/ui';\nimport { Save, X, Star, Loader2 } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { throwOnError } from '../utils/mutationResult';\nimport { parseIntField } from '../utils/formValidation';\nimport { ProjectSelect, WorkItemSearchSelect } from '../controls/Pickers';\nimport {\n EMPTY_PRIORITIZATION_FORM,\n EMPTY_RICE_FORM,\n PrioritizationScoreFields,\n RiceScoreFields,\n prioritizationScoresValid,\n riceInputsValid,\n type PrioritizationFormValues,\n type RiceFormValues,\n} from '../controls/PrioritizationControls';\nimport {\n AnonymousSubmissionCheckbox,\n EMPTY_FEEDBACK_FORM,\n FeedbackFields,\n type FeedbackFormValues,\n} from '../controls/FeedbackControls';\n\nconst CREATE_FEATURE_REQUEST = gql`\n mutation CreateFeatureRequest($input: PlanmagnetCreateFeatureRequestInput!) {\n planmagnetCreateFeatureRequest(input: $input) {\n id\n title\n status\n businessValue\n effortEstimate\n priorityScore\n rating\n category\n isAnonymous\n }\n }\n`;\n\nexport function ProductsNewFeaturePagePage() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const [form, setForm] = useState({\n title: '',\n description: '',\n status: 'SUBMITTED' as string,\n businessValue: '50',\n effortEstimate: 'medium',\n tags: '',\n projectId: '',\n workItemId: '',\n });\n // PRM-27: MoSCoW/Kano/value/effort scoring, set at creation just like at edit time.\n const [prioritization, setPrioritization] =\n useState<PrioritizationFormValues>(EMPTY_PRIORITIZATION_FORM);\n // PRM-26: RICE, next to the value/effort scores above — effortScore is riceScore's own divisor.\n const [rice, setRice] = useState<RiceFormValues>(EMPTY_RICE_FORM);\n // CWF-15: structured feedback — rating, category, and whether to hide the requester.\n const [feedback, setFeedback] = useState<FeedbackFormValues>(EMPTY_FEEDBACK_FORM);\n const [isAnonymous, setIsAnonymous] = useState(false);\n\n // Navigate only once the service has accepted the feature: with fe-libs' errorPolicy 'all' a refused\n // mutation resolves, so the old onCompleted navigation could leave the form as if it had saved.\n const [createFeature, { loading: saving }] = useMutation(CREATE_FEATURE_REQUEST, {\n refetchQueries: ['ListFeatureRequests'],\n });\n const [saveError, setSaveError] = useState<string | null>(null);\n // Business value is a whole number from 0 to 100 (BOFF-7833: prod had stored 150).\n const businessValue = parseIntField(form.businessValue, { min: 0, max: 100 });\n const prioritizationValid = prioritizationScoresValid(prioritization);\n const value = parseIntField(prioritization.valueScore, { min: 1, max: 10 });\n const effort = parseIntField(prioritization.effortScore, { min: 1, max: 10 });\n const riceValid = riceInputsValid(rice);\n const reach = parseIntField(rice.reach, { min: 1, max: 10 });\n const impact = parseIntField(rice.impact, { min: 1, max: 10 });\n const confidence = parseIntField(rice.confidence, { min: 1, max: 10 });\n // CWF-15: 1-5, empty means \"not set\".\n const rating = parseIntField(feedback.rating, { min: 1, max: 5 });\n\n const statusOptions = [\n 'SUBMITTED',\n 'UNDER_REVIEW',\n 'PLANNED',\n 'IN_PROGRESS',\n 'COMPLETED',\n ] as const;\n const efforts = ['small', 'medium', 'large', 'epic'] as const;\n\n const handleCreate = async () => {\n if (\n !form.title.trim() ||\n businessValue.invalid ||\n !prioritizationValid ||\n !riceValid ||\n rating.invalid\n )\n return;\n setSaveError(null);\n try {\n await throwOnError(\n createFeature({\n variables: {\n input: {\n title: form.title,\n description: form.description || undefined,\n status: form.status,\n businessValue: businessValue.value,\n effortEstimate: form.effortEstimate,\n projectId: form.projectId || undefined,\n workItemId: form.workItemId || undefined,\n tags: form.tags\n ? form.tags\n .split(',')\n .map((t) => t.trim())\n .filter(Boolean)\n : undefined,\n moscow: prioritization.moscow || undefined,\n kano: prioritization.kano || undefined,\n valueScore: value.value,\n effortScore: effort.value,\n reach: reach.value,\n impact: impact.value,\n confidence: confidence.value,\n rating: rating.value,\n category: feedback.category.trim() || undefined,\n isAnonymous,\n },\n },\n })\n );\n navigate('/products/features-page');\n } catch (e) {\n setSaveError(e instanceof Error ? e.message : 'The feature could not be created.');\n }\n };\n\n return (\n <div className=\"space-y-6 p-6 max-w-4xl\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h1 className=\"text-2xl font-semibold\">New Feature</h1>\n <p className=\"text-sm text-muted-foreground\">\n Define a new feature request with business value metrics.\n </p>\n </div>\n <div className=\"flex gap-2\">\n <Button variant=\"outline\" size=\"sm\" onClick={() => navigate('/products/features-page')}>\n <X className=\"mr-1 h-4 w-4\" />\n Cancel\n </Button>\n <Button\n size=\"sm\"\n onClick={handleCreate}\n disabled={\n saving ||\n !form.title.trim() ||\n businessValue.invalid ||\n !prioritizationValid ||\n !riceValid ||\n rating.invalid\n }\n >\n {saving ? (\n <Loader2 className=\"mr-1 h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"mr-1 h-4 w-4\" />\n )}\n Create Feature\n </Button>\n </div>\n </div>\n\n {saveError && (\n <div role=\"alert\" className=\"p-3 rounded-md bg-destructive/10 text-destructive text-sm\">\n Failed to create feature: {saveError}\n </div>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle>Feature Details</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label className=\"text-sm font-medium\">Title</label>\n <Input\n value={form.title}\n onChange={(e) => setForm({ ...form, title: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. Advanced Search Filters\"\n />\n </div>\n <div>\n <label className=\"text-sm font-medium\">Description</label>\n <textarea\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm min-h-[100px]\"\n value={form.description}\n onChange={(e) => setForm({ ...form, description: e.target.value })}\n placeholder=\"Describe the feature and its user value...\"\n />\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label className=\"text-sm font-medium\">Status</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm capitalize\"\n value={form.status}\n onChange={(e) => setForm({ ...form, status: e.target.value })}\n >\n {statusOptions.map((s) => (\n <option key={s} value={s}>\n {s.toLowerCase().replace('_', ' ')}\n </option>\n ))}\n </select>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Effort Estimate</label>\n <select\n className=\"mt-1 w-full rounded-md border border-input bg-background px-3 py-2 text-sm capitalize\"\n value={form.effortEstimate}\n onChange={(e) => setForm({ ...form, effortEstimate: e.target.value })}\n >\n {efforts.map((e) => (\n <option key={e} value={e}>\n {e}\n </option>\n ))}\n </select>\n </div>\n </div>\n {/* BOFF-7966: a request could not be tied to a project or to the work item that delivers it, so the\n release readiness card's \"customer requests riding on unfinished work\" could never fill. */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div>\n <label htmlFor=\"feature-project\" className=\"text-sm font-medium\">\n Project\n </label>\n <div className=\"mt-1\">\n <ProjectSelect\n id=\"feature-project\"\n value={form.projectId}\n noneLabel=\"No project\"\n onChange={(projectId) => setForm({ ...form, projectId, workItemId: '' })}\n />\n </div>\n </div>\n <div>\n <label htmlFor=\"feature-work-item\" className=\"text-sm font-medium\">\n Delivered by work item\n </label>\n <div className=\"mt-1\">\n <WorkItemSearchSelect\n id=\"feature-work-item\"\n projectId={form.projectId || undefined}\n value={form.workItemId}\n onChange={(workItemId) => setForm({ ...form, workItemId })}\n />\n </div>\n </div>\n </div>\n <div>\n <label className=\"text-sm font-medium\">Tags (comma-separated)</label>\n <Input\n value={form.tags}\n onChange={(e) => setForm({ ...form, tags: e.target.value })}\n className=\"mt-1\"\n placeholder=\"e.g. search, ux, performance\"\n />\n </div>\n </CardContent>\n </Card>\n\n {/* PRM-27: MoSCoW, Kano and Value-vs-Effort scoring — an alternative to the Business Value card below. */}\n <Card>\n <CardHeader>\n <CardTitle>Prioritization</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <PrioritizationScoreFields\n idPrefix=\"feature-new\"\n values={prioritization}\n onChange={setPrioritization}\n />\n {/* PRM-26: RICE, next to the value/effort scores above. */}\n <div className=\"border-t pt-3\">\n <p className=\"text-sm font-medium mb-1\">RICE</p>\n <RiceScoreFields\n idPrefix=\"feature-new\"\n values={rice}\n onChange={setRice}\n effortScoreMissing={effort.value == null}\n />\n </div>\n </CardContent>\n </Card>\n\n {/* CWF-15: structured feedback — rating, category and whether to hide the requester. */}\n <Card>\n <CardHeader>\n <CardTitle>Feedback</CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <FeedbackFields idPrefix=\"feature-new\" values={feedback} onChange={setFeedback} />\n {rating.invalid && (\n <p role=\"alert\" className=\"text-xs text-destructive\">\n Rating is a whole number from 1 to 5.\n </p>\n )}\n <AnonymousSubmissionCheckbox\n idPrefix=\"feature-new\"\n checked={isAnonymous}\n onChange={setIsAnonymous}\n />\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Star className=\"h-4 w-4\" />\n Business Value\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n <div>\n <label htmlFor=\"feature-business-value\" className=\"text-sm font-medium\">\n Business Value (0-100)\n </label>\n <Input\n id=\"feature-business-value\"\n type=\"number\"\n min={0}\n max={100}\n step={1}\n value={form.businessValue}\n onChange={(e) => setForm({ ...form, businessValue: e.target.value })}\n aria-invalid={businessValue.invalid}\n className=\"mt-1\"\n />\n {businessValue.invalid ? (\n <p role=\"alert\" className=\"text-xs text-destructive mt-1\">\n Business value must be a whole number from 0 to 100.\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground mt-1\">\n How much business value does this feature deliver?\n </p>\n )}\n </div>\n\n <div className=\"p-4 bg-muted rounded-md text-center\">\n <p className=\"text-xs text-muted-foreground\">Business Value Score</p>\n <p className=\"text-3xl font-bold text-primary mt-2\">\n {businessValue.invalid || businessValue.value === undefined\n ? '—'\n : businessValue.value}\n </p>\n <p className=\"text-xs text-muted-foreground\">out of 100</p>\n </div>\n </CardContent>\n </Card>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -7,8 +7,8 @@ import { Archive as s, GitBranch as c, Loader2 as l, Map as u, Package as d, Plu
7
7
  import { gql as m } from "@apollo/client";
8
8
  import { useQuery as h } from "@apollo/client/react";
9
9
  import { jsx as g, jsxs as _ } from "react/jsx-runtime";
10
- import { useI18n as v } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
- import { Badge as y, Button as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w } from "@burdenoff/fe-libs/ui";
10
+ import { Badge as v, Button as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C } from "@burdenoff/fe-libs/ui";
11
+ import { useI18n as w } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
12
  //#region src/planmagnet/pages/ProductsProductsPagePage.tsx
13
13
  var T = m`
14
14
  query GetProducts(
@@ -48,7 +48,7 @@ var T = m`
48
48
  }
49
49
  `;
50
50
  function E() {
51
- let { workspaceId: m } = e(), E = t(), { t: D } = v(), [O, k] = o(!1), { data: A, loading: j, error: M } = h(T, {
51
+ let { workspaceId: m } = e(), E = t(), { t: D } = w(), [O, k] = o(!1), { data: A, loading: j, error: M } = h(T, {
52
52
  variables: {
53
53
  workspaceId: m,
54
54
  filter: O ? void 0 : { isActive: !0 },
@@ -86,13 +86,13 @@ function E() {
86
86
  children: D("planmagnet.products.subtitle", "Strategy entities that link roadmaps, releases, feature requests and OKRs")
87
87
  })] }), /* @__PURE__ */ _("div", {
88
88
  className: "flex items-center gap-2",
89
- children: [/* @__PURE__ */ _(b, {
89
+ children: [/* @__PURE__ */ _(y, {
90
90
  size: "sm",
91
91
  variant: O ? "default" : "outline",
92
92
  onClick: () => k((e) => !e),
93
93
  "data-testid": "products-toggle-archived",
94
94
  children: [/* @__PURE__ */ g(s, { className: "h-4 w-4 mr-1" }), O ? D("planmagnet.products.actions.hideArchived", "Hide archived") : D("planmagnet.products.actions.showArchived", "Show archived")]
95
- }), /* @__PURE__ */ _(b, {
95
+ }), /* @__PURE__ */ _(y, {
96
96
  size: "sm",
97
97
  onClick: () => E("/products/create-product-page"),
98
98
  children: [/* @__PURE__ */ g(f, { className: "h-4 w-4 mr-1" }), D("planmagnet.products.actions.newProduct", "New Product")]
@@ -120,7 +120,7 @@ function E() {
120
120
  icon: c,
121
121
  color: "text-purple-500"
122
122
  }
123
- ].map((e) => /* @__PURE__ */ g(x, { children: /* @__PURE__ */ g(S, {
123
+ ].map((e) => /* @__PURE__ */ g(b, { children: /* @__PURE__ */ g(x, {
124
124
  className: "pt-6",
125
125
  children: /* @__PURE__ */ _("div", {
126
126
  className: "flex items-center justify-between",
@@ -134,31 +134,31 @@ function E() {
134
134
  })
135
135
  }) }, e.label))
136
136
  }),
137
- N.length === 0 ? /* @__PURE__ */ g(x, { children: /* @__PURE__ */ g(S, {
137
+ N.length === 0 ? /* @__PURE__ */ g(b, { children: /* @__PURE__ */ g(x, {
138
138
  className: "py-12 text-center text-sm text-muted-foreground",
139
139
  children: D("planmagnet.products.empty", "No products yet. Create one to get started.")
140
140
  }) }) : /* @__PURE__ */ g("div", {
141
141
  className: "grid gap-4 md:grid-cols-2 lg:grid-cols-2",
142
- children: N.map((e) => /* @__PURE__ */ _(x, {
142
+ children: N.map((e) => /* @__PURE__ */ _(b, {
143
143
  ...a(() => E(i("/products/product-detail-page", e.id)), e.name),
144
- children: [/* @__PURE__ */ g(C, { children: /* @__PURE__ */ _("div", {
144
+ children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ _("div", {
145
145
  className: "flex items-center justify-between gap-2",
146
- children: [/* @__PURE__ */ g(w, {
146
+ children: [/* @__PURE__ */ g(C, {
147
147
  className: "text-base",
148
148
  children: e.name
149
149
  }), /* @__PURE__ */ _("div", {
150
150
  className: "flex items-center gap-1 shrink-0",
151
- children: [e.archivedAt && /* @__PURE__ */ g(y, {
151
+ children: [e.archivedAt && /* @__PURE__ */ g(v, {
152
152
  variant: "outline",
153
153
  className: "text-xs",
154
154
  children: D("planmagnet.products.shared.archived", "Archived")
155
- }), /* @__PURE__ */ g(y, {
155
+ }), /* @__PURE__ */ g(v, {
156
156
  variant: "secondary",
157
157
  className: "text-xs capitalize",
158
158
  children: r(e.lifecycleStage)
159
159
  })]
160
160
  })]
161
- }) }), /* @__PURE__ */ _(S, {
161
+ }) }), /* @__PURE__ */ _(x, {
162
162
  className: "space-y-3",
163
163
  children: [
164
164
  /* @__PURE__ */ g("p", {
@@ -10,8 +10,8 @@ import { useSearchParams as f } from "react-router";
10
10
  import { gql as p } from "@apollo/client";
11
11
  import { useQuery as m } from "@apollo/client/react";
12
12
  import { Fragment as h, jsx as g, jsxs as _ } from "react/jsx-runtime";
13
- import { useI18n as v } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
- import { Badge as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C } from "@burdenoff/fe-libs/ui";
13
+ import { Badge as v, Card as y, CardContent as b, CardHeader as x, CardTitle as S } from "@burdenoff/fe-libs/ui";
14
+ import { useI18n as C } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
15
  //#region src/planmagnet/pages/ProjectsAtRiskPagePage.tsx
16
16
  var w = 100, T = p`
17
17
  query AtRiskProjectSprints($workspaceId: ID!, $projectId: String) {
@@ -60,7 +60,7 @@ var w = 100, T = p`
60
60
  }
61
61
  `, D = "ALL";
62
62
  function O() {
63
- let { workspaceId: p } = e(), O = t(), { t: k } = v(), [A, j] = f(), M = A.get("projectId") ?? "", N = A.get("sprintId") ?? "", [P, F] = u(D);
63
+ let { workspaceId: p } = e(), O = t(), { t: k } = C(), [A, j] = f(), M = A.get("projectId") ?? "", N = A.get("sprintId") ?? "", [P, F] = u(D);
64
64
  function I(e) {
65
65
  let t = new URLSearchParams(A);
66
66
  e ? t.set("projectId", e) : t.delete("projectId"), t.delete("sprintId"), j(t, { replace: !0 });
@@ -97,12 +97,12 @@ function O() {
97
97
  }), /* @__PURE__ */ g("p", {
98
98
  className: "text-sm text-muted-foreground",
99
99
  children: k("planmagnet.forecast.atRisk.subtitle", "Open work items carrying one or more risk flags, each raised by an explicit threshold rule — never AI-generated.")
100
- })] }), /* @__PURE__ */ g(y, {
100
+ })] }), /* @__PURE__ */ g(v, {
101
101
  variant: "outline",
102
102
  children: k("planmagnet.forecast.atRisk.method", "Rule-based")
103
103
  })]
104
104
  }),
105
- /* @__PURE__ */ g(b, { children: /* @__PURE__ */ _(x, {
105
+ /* @__PURE__ */ g(y, { children: /* @__PURE__ */ _(b, {
106
106
  className: "flex flex-wrap items-end gap-3 pt-4",
107
107
  children: [/* @__PURE__ */ _("div", {
108
108
  className: "space-y-1",
@@ -159,7 +159,7 @@ function O() {
159
159
  ")"
160
160
  ]
161
161
  }, e))]
162
- }), /* @__PURE__ */ _(b, { children: [/* @__PURE__ */ g(S, { children: /* @__PURE__ */ g(C, { children: V && !B ? k("planmagnet.forecast.loading", "Loading…") : k("planmagnet.forecast.atRisk.count", "{{count}} flagged item(s)", { count: G.length }) }) }), /* @__PURE__ */ _(x, {
162
+ }), /* @__PURE__ */ _(y, { children: [/* @__PURE__ */ g(x, { children: /* @__PURE__ */ g(S, { children: V && !B ? k("planmagnet.forecast.loading", "Loading…") : k("planmagnet.forecast.atRisk.count", "{{count}} flagged item(s)", { count: G.length }) }) }), /* @__PURE__ */ _(b, {
163
163
  className: "space-y-3",
164
164
  children: [V && !B ? /* @__PURE__ */ g("div", {
165
165
  className: "flex justify-center py-12",
@@ -197,12 +197,12 @@ function O() {
197
197
  className: "flex items-start gap-2 text-xs",
198
198
  children: [
199
199
  /* @__PURE__ */ g(c(e.kind), { className: "mt-0.5 h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
200
- /* @__PURE__ */ g(y, {
200
+ /* @__PURE__ */ g(v, {
201
201
  variant: l(e.severity),
202
202
  className: "shrink-0",
203
203
  children: r(e.severity)
204
204
  }),
205
- /* @__PURE__ */ g(y, {
205
+ /* @__PURE__ */ g(v, {
206
206
  variant: "outline",
207
207
  className: "shrink-0",
208
208
  children: r(e.kind)
@@ -221,7 +221,7 @@ function O() {
221
221
  total: U.totalCount
222
222
  })
223
223
  })]
224
- })] })] }) : /* @__PURE__ */ g(b, { children: /* @__PURE__ */ g(x, {
224
+ })] })] }) : /* @__PURE__ */ g(y, { children: /* @__PURE__ */ g(b, {
225
225
  className: "py-10 text-center text-sm text-muted-foreground",
226
226
  children: k("planmagnet.forecast.atRisk.noProject", "Choose a project to see its at-risk work.")
227
227
  }) })
@@ -10,8 +10,8 @@ import { useSearchParams as h } from "react-router";
10
10
  import { gql as g } from "@apollo/client";
11
11
  import { useQuery as _ } from "@apollo/client/react";
12
12
  import { jsx as v, jsxs as y } from "react/jsx-runtime";
13
- import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
- import { Card as x, CardContent as S, CardHeader as C, CardTitle as w, Input as T } from "@burdenoff/fe-libs/ui";
13
+ import { Card as b, CardContent as x, CardHeader as S, CardTitle as C, Input as w } from "@burdenoff/fe-libs/ui";
14
+ import { useI18n as T } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
15
15
  //#region src/planmagnet/pages/ProjectsBudgetsPagePage.tsx
16
16
  var E = g`
17
17
  query BudgetsList(
@@ -38,7 +38,7 @@ var E = g`
38
38
  }
39
39
  `, D = ["ALL", ...u];
40
40
  function O() {
41
- let { workspaceId: u } = e(), g = t(), { t: O } = b(), [k] = h(), [A, j] = p(k.get("projectId") ?? ""), [M, N] = p("ALL"), [P, F] = p(""), I = f(P.trim()), L = {
41
+ let { workspaceId: u } = e(), g = t(), { t: O } = T(), [k] = h(), [A, j] = p(k.get("projectId") ?? ""), [M, N] = p("ALL"), [P, F] = p(""), I = f(P.trim()), L = {
42
42
  ...A ? { projectId: A } : {},
43
43
  ...M === "ALL" ? {} : { status: M },
44
44
  ...I ? { search: I } : {}
@@ -76,7 +76,7 @@ function O() {
76
76
  onChange: j,
77
77
  noneLabel: O("planmagnet.budgets.allProjects", "All projects")
78
78
  })
79
- }), /* @__PURE__ */ v(T, {
79
+ }), /* @__PURE__ */ v(w, {
80
80
  "aria-label": O("planmagnet.budgets.search", "Search budgets"),
81
81
  placeholder: O("planmagnet.budgets.searchPlaceholder", "Search by name or description"),
82
82
  className: "w-full max-w-xs",
@@ -117,13 +117,13 @@ function O() {
117
117
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
118
118
  children: V.map((e) => {
119
119
  let t = i(e.plannedAmount, e.spentAmount), l = n[r(t)], u = t === null ? null : Math.round(t * 100);
120
- return /* @__PURE__ */ y(x, {
120
+ return /* @__PURE__ */ y(b, {
121
121
  ...c(() => g(s("/projects/budget-detail-page", e.id)), e.name),
122
- children: [/* @__PURE__ */ v(C, {
122
+ children: [/* @__PURE__ */ v(S, {
123
123
  className: "pb-2",
124
124
  children: /* @__PURE__ */ y("div", {
125
125
  className: "flex items-center justify-between gap-2",
126
- children: [/* @__PURE__ */ y(w, {
126
+ children: [/* @__PURE__ */ y(C, {
127
127
  className: "text-base flex items-center gap-2",
128
128
  children: [/* @__PURE__ */ v(m, { className: "h-4 w-4 text-primary" }), e.name]
129
129
  }), /* @__PURE__ */ v("span", {
@@ -131,7 +131,7 @@ function O() {
131
131
  children: o(e.status)
132
132
  })]
133
133
  })
134
- }), /* @__PURE__ */ y(S, {
134
+ }), /* @__PURE__ */ y(x, {
135
135
  className: "space-y-3",
136
136
  children: [
137
137
  /* @__PURE__ */ v("p", {
@@ -6,8 +6,8 @@ import { CheckSquare as s, FolderKanban as c, LayoutTemplate as l, Plus as u, Tr
6
6
  import { gql as p } from "@apollo/client";
7
7
  import { useQuery as m } from "@apollo/client/react";
8
8
  import { jsx as h, jsxs as g } from "react/jsx-runtime";
9
- import { useI18n as _ } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
10
- import { Badge as v, Button as y, Card as b, CardContent as x, CardHeader as S, CardTitle as C } from "@burdenoff/fe-libs/ui";
9
+ import { Badge as _, Button as v, Card as y, CardContent as b, CardHeader as x, CardTitle as S } from "@burdenoff/fe-libs/ui";
10
+ import { useI18n as C } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
11
11
  //#region src/planmagnet/pages/ProjectsProjectsPagePage.tsx
12
12
  var w = p`
13
13
  query GetProjects($workspaceId: ID!) {
@@ -37,7 +37,7 @@ var w = p`
37
37
  CUSTOM: "bg-amber-100 text-amber-800"
38
38
  }, E = (e) => e === "ACTIVE" ? "default" : "secondary";
39
39
  function D() {
40
- let p = t(), { workspaceId: D } = e(), { t: O } = _(), { data: k, loading: A, error: j } = m(w, { variables: { workspaceId: D ?? "default" } }), M = i();
40
+ let p = t(), { workspaceId: D } = e(), { t: O } = C(), { data: k, loading: A, error: j } = m(w, { variables: { workspaceId: D ?? "default" } }), M = i();
41
41
  if (A && !k) return /* @__PURE__ */ h("div", {
42
42
  className: "flex items-center justify-center p-12",
43
43
  children: /* @__PURE__ */ h("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
@@ -69,13 +69,13 @@ function D() {
69
69
  children: O("planmagnet.projects.subtitle", "Manage and track all projects across teams")
70
70
  })] }), /* @__PURE__ */ g("div", {
71
71
  className: "flex gap-2",
72
- children: [/* @__PURE__ */ g(y, {
72
+ children: [/* @__PURE__ */ g(v, {
73
73
  size: "sm",
74
74
  variant: "outline",
75
75
  onClick: () => p("/templates/templates-page"),
76
76
  "data-testid": "projects-templates-link",
77
77
  children: [/* @__PURE__ */ h(l, { className: "mr-1 h-4 w-4" }), "Templates"]
78
- }), /* @__PURE__ */ g(y, {
78
+ }), /* @__PURE__ */ g(v, {
79
79
  size: "sm",
80
80
  onClick: () => p("/projects/create-project-page"),
81
81
  children: [/* @__PURE__ */ h(u, { className: "mr-1 h-4 w-4" }), O("planmagnet.projects.actions.newProject", "New Project")]
@@ -105,7 +105,7 @@ function D() {
105
105
  value: P.onHold,
106
106
  icon: d
107
107
  }
108
- ].map((e) => /* @__PURE__ */ h(b, { children: /* @__PURE__ */ g(x, {
108
+ ].map((e) => /* @__PURE__ */ h(y, { children: /* @__PURE__ */ g(b, {
109
109
  className: "pt-4",
110
110
  children: [/* @__PURE__ */ g("div", {
111
111
  className: "flex items-center gap-2 text-muted-foreground text-sm",
@@ -118,13 +118,13 @@ function D() {
118
118
  }),
119
119
  /* @__PURE__ */ h("div", {
120
120
  className: "grid grid-cols-1 md:grid-cols-2 gap-4",
121
- children: N.map((e) => /* @__PURE__ */ g(b, {
121
+ children: N.map((e) => /* @__PURE__ */ g(y, {
122
122
  ...o(() => p(a("/projects/project-detail-page", e.id)), e.name),
123
- children: [/* @__PURE__ */ h(S, {
123
+ children: [/* @__PURE__ */ h(x, {
124
124
  className: "pb-2",
125
125
  children: /* @__PURE__ */ g("div", {
126
126
  className: "flex items-center justify-between",
127
- children: [/* @__PURE__ */ h(C, {
127
+ children: [/* @__PURE__ */ h(S, {
128
128
  className: "text-base",
129
129
  children: e.name
130
130
  }), /* @__PURE__ */ h("span", {
@@ -132,7 +132,7 @@ function D() {
132
132
  children: e.key
133
133
  })]
134
134
  })
135
- }), /* @__PURE__ */ g(x, {
135
+ }), /* @__PURE__ */ g(b, {
136
136
  className: "space-y-3",
137
137
  children: [
138
138
  /* @__PURE__ */ h("p", {
@@ -141,7 +141,7 @@ function D() {
141
141
  }),
142
142
  /* @__PURE__ */ g("div", {
143
143
  className: "flex gap-2",
144
- children: [/* @__PURE__ */ h(v, {
144
+ children: [/* @__PURE__ */ h(_, {
145
145
  variant: E(e.status),
146
146
  className: "capitalize",
147
147
  children: e.status.toLowerCase().replace("_", " ")
@@ -152,7 +152,7 @@ function D() {
152
152
  }),
153
153
  e.tags.length > 0 && /* @__PURE__ */ h("div", {
154
154
  className: "flex gap-1 flex-wrap",
155
- children: e.tags.map((e) => /* @__PURE__ */ h(v, {
155
+ children: e.tags.map((e) => /* @__PURE__ */ h(_, {
156
156
  variant: "outline",
157
157
  className: "text-xs",
158
158
  children: e
@@ -9,8 +9,8 @@ import { useDeferredValue as g, useState as _ } from "react";
9
9
  import { BarChart3 as v, LayoutTemplate as y, Plus as b } from "lucide-react";
10
10
  import { useMutation as x, useQuery as S } from "@apollo/client/react";
11
11
  import { jsx as C, jsxs as w } from "react/jsx-runtime";
12
- import { useI18n as T } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
13
- import { Badge as E, Button as D, Card as O, CardContent as k, CardDescription as A, CardHeader as j, CardTitle as M, Input as N, Tabs as P, TabsContent as F, TabsList as I, TabsTrigger as L } from "@burdenoff/fe-libs/ui";
12
+ import { Badge as T, Button as E, Card as D, CardContent as O, CardDescription as k, CardHeader as A, CardTitle as j, Input as M, Tabs as N, TabsContent as P, TabsList as F, TabsTrigger as I } from "@burdenoff/fe-libs/ui";
13
+ import { useI18n as L } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
14
14
  //#region src/planmagnet/pages/ReportsReportsPagePage.tsx
15
15
  function R({ report: e, isOwner: r, onDuplicate: i, onDelete: a }) {
16
16
  let s = t();
@@ -32,7 +32,7 @@ function R({ report: e, isOwner: r, onDuplicate: i, onDelete: a }) {
32
32
  /* @__PURE__ */ w("p", {
33
33
  className: "mt-0.5 text-xs text-muted-foreground",
34
34
  children: [
35
- /* @__PURE__ */ C(E, {
35
+ /* @__PURE__ */ C(T, {
36
36
  variant: e.visibility === "WORKSPACE" ? "secondary" : "outline",
37
37
  className: "mr-1.5",
38
38
  children: e.visibility === "WORKSPACE" ? "Workspace" : "Private"
@@ -48,7 +48,7 @@ function R({ report: e, isOwner: r, onDuplicate: i, onDelete: a }) {
48
48
  }), /* @__PURE__ */ w("div", {
49
49
  className: "flex shrink-0 items-center gap-1.5",
50
50
  onClick: u,
51
- children: [/* @__PURE__ */ C(D, {
51
+ children: [/* @__PURE__ */ C(E, {
52
52
  size: "sm",
53
53
  variant: "outline",
54
54
  onClick: () => i(e.id),
@@ -92,7 +92,7 @@ function z({ mine: n }) {
92
92
  } catch (e) {
93
93
  y(r(e, "This report could not be duplicated."));
94
94
  }
95
- }, M = async (e) => {
95
+ }, N = async (e) => {
96
96
  y(null);
97
97
  try {
98
98
  await a(k({ variables: { id: e } }));
@@ -103,7 +103,7 @@ function z({ mine: n }) {
103
103
  return /* @__PURE__ */ w("div", {
104
104
  className: "space-y-3",
105
105
  children: [
106
- /* @__PURE__ */ C(N, {
106
+ /* @__PURE__ */ C(M, {
107
107
  value: u,
108
108
  onChange: (e) => d(e.target.value),
109
109
  placeholder: "Search reports",
@@ -126,14 +126,14 @@ function z({ mine: n }) {
126
126
  report: e,
127
127
  isOwner: !!o?.id && o.id === e.ownerId,
128
128
  onDuplicate: (e) => void j(e),
129
- onDelete: (e) => void M(e)
129
+ onDelete: (e) => void N(e)
130
130
  }, e.id))
131
131
  })
132
132
  ]
133
133
  });
134
134
  }
135
135
  function B() {
136
- let { workspaceId: n } = e(), o = t(), { data: l, loading: u, error: f } = S(h), [p, { loading: m }] = x(d), [g, v] = _(null), [b, T] = _(null), E = async (e) => {
136
+ let { workspaceId: n } = e(), o = t(), { data: l, loading: u, error: f } = S(h), [p, { loading: m }] = x(d), [g, v] = _(null), [b, T] = _(null), M = async (e) => {
137
137
  if (n) {
138
138
  T(null), v(e.key);
139
139
  try {
@@ -171,23 +171,23 @@ function B() {
171
171
  className: "space-y-3",
172
172
  children: [b && /* @__PURE__ */ C(s, { message: b }), /* @__PURE__ */ C("div", {
173
173
  className: "grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3",
174
- children: N.map((e) => /* @__PURE__ */ w(O, {
174
+ children: N.map((e) => /* @__PURE__ */ w(D, {
175
175
  "data-testid": "report-template",
176
- children: [/* @__PURE__ */ w(j, { children: [/* @__PURE__ */ w(M, {
176
+ children: [/* @__PURE__ */ w(A, { children: [/* @__PURE__ */ w(j, {
177
177
  className: "flex items-center gap-2 text-sm",
178
178
  children: [/* @__PURE__ */ C(y, { className: "h-4 w-4" }), e.name]
179
- }), /* @__PURE__ */ C(A, { children: e.description })] }), /* @__PURE__ */ w(k, { children: [/* @__PURE__ */ w("p", {
179
+ }), /* @__PURE__ */ C(k, { children: e.description })] }), /* @__PURE__ */ w(O, { children: [/* @__PURE__ */ w("p", {
180
180
  className: "mb-3 text-xs text-muted-foreground",
181
181
  children: [
182
182
  e.definition.widgets.length,
183
183
  " widget",
184
184
  e.definition.widgets.length === 1 ? "" : "s"
185
185
  ]
186
- }), /* @__PURE__ */ C(D, {
186
+ }), /* @__PURE__ */ C(E, {
187
187
  size: "sm",
188
188
  className: "w-full",
189
189
  disabled: m,
190
- onClick: () => void E(e),
190
+ onClick: () => void M(e),
191
191
  children: g === e.key ? "Creating…" : "Start from template"
192
192
  })] })]
193
193
  }, e.key))
@@ -195,7 +195,7 @@ function B() {
195
195
  });
196
196
  }
197
197
  function V() {
198
- let { t: e } = T(), n = t();
198
+ let { t: e } = L(), n = t();
199
199
  return /* @__PURE__ */ w("div", {
200
200
  className: "space-y-6 p-6",
201
201
  children: [/* @__PURE__ */ w("div", {
@@ -206,41 +206,41 @@ function V() {
206
206
  }), /* @__PURE__ */ C("p", {
207
207
  className: "text-sm text-muted-foreground",
208
208
  children: e("planmagnet.reports.subtitle", "Build, run, share and schedule reports over your PlanMagnet data.")
209
- })] }), /* @__PURE__ */ w(D, {
209
+ })] }), /* @__PURE__ */ w(E, {
210
210
  size: "sm",
211
211
  onClick: () => n("/reports/create-report-page"),
212
212
  "data-testid": "report-new",
213
213
  children: [/* @__PURE__ */ C(b, { className: "mr-1 h-4 w-4" }), e("planmagnet.reports.newBlank", "New blank report")]
214
214
  })]
215
- }), /* @__PURE__ */ w(P, {
215
+ }), /* @__PURE__ */ w(N, {
216
216
  defaultValue: "mine",
217
217
  children: [
218
- /* @__PURE__ */ w(I, { children: [
219
- /* @__PURE__ */ C(L, {
218
+ /* @__PURE__ */ w(F, { children: [
219
+ /* @__PURE__ */ C(I, {
220
220
  value: "mine",
221
221
  "data-testid": "report-list",
222
222
  children: "My reports"
223
223
  }),
224
- /* @__PURE__ */ C(L, {
224
+ /* @__PURE__ */ C(I, {
225
225
  value: "workspace",
226
226
  children: "Workspace"
227
227
  }),
228
- /* @__PURE__ */ C(L, {
228
+ /* @__PURE__ */ C(I, {
229
229
  value: "templates",
230
230
  children: "Templates"
231
231
  })
232
232
  ] }),
233
- /* @__PURE__ */ C(F, {
233
+ /* @__PURE__ */ C(P, {
234
234
  value: "mine",
235
235
  className: "mt-4",
236
236
  children: /* @__PURE__ */ C(z, { mine: !0 })
237
237
  }),
238
- /* @__PURE__ */ C(F, {
238
+ /* @__PURE__ */ C(P, {
239
239
  value: "workspace",
240
240
  className: "mt-4",
241
241
  children: /* @__PURE__ */ C(z, { mine: !1 })
242
242
  }),
243
- /* @__PURE__ */ C(F, {
243
+ /* @__PURE__ */ C(P, {
244
244
  value: "templates",
245
245
  className: "mt-4",
246
246
  children: /* @__PURE__ */ C(B, {})