@kelpie/ui 0.1.0
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.
- package/LICENSE +661 -0
- package/README.md +44 -0
- package/dist/ServiceStatus.d.ts +6 -0
- package/dist/ServiceStatus.d.ts.map +1 -0
- package/dist/ServiceStatus.js +35 -0
- package/dist/ServiceStatus.js.map +1 -0
- package/dist/api/ApiProvider.d.ts +19 -0
- package/dist/api/ApiProvider.d.ts.map +1 -0
- package/dist/api/ApiProvider.js +18 -0
- package/dist/api/ApiProvider.js.map +1 -0
- package/dist/api/client.d.ts +83 -0
- package/dist/api/client.d.ts.map +1 -0
- package/dist/api/client.js +162 -0
- package/dist/api/client.js.map +1 -0
- package/dist/api/context.d.ts +14 -0
- package/dist/api/context.d.ts.map +1 -0
- package/dist/api/context.js +20 -0
- package/dist/api/context.js.map +1 -0
- package/dist/api/errors.d.ts +9 -0
- package/dist/api/errors.d.ts.map +1 -0
- package/dist/api/errors.js +14 -0
- package/dist/api/errors.js.map +1 -0
- package/dist/api/health.d.ts +15 -0
- package/dist/api/health.d.ts.map +1 -0
- package/dist/api/health.js +22 -0
- package/dist/api/health.js.map +1 -0
- package/dist/api/json.d.ts +3 -0
- package/dist/api/json.d.ts.map +1 -0
- package/dist/api/json.js +5 -0
- package/dist/api/json.js.map +1 -0
- package/dist/api/queryClient.d.ts +17 -0
- package/dist/api/queryClient.d.ts.map +1 -0
- package/dist/api/queryClient.js +33 -0
- package/dist/api/queryClient.js.map +1 -0
- package/dist/api/resource.d.ts +110 -0
- package/dist/api/resource.d.ts.map +1 -0
- package/dist/api/resource.js +238 -0
- package/dist/api/resource.js.map +1 -0
- package/dist/api/resources/account.d.ts +49 -0
- package/dist/api/resources/account.d.ts.map +1 -0
- package/dist/api/resources/account.js +146 -0
- package/dist/api/resources/account.js.map +1 -0
- package/dist/api/resources/activities.d.ts +8 -0
- package/dist/api/resources/activities.d.ts.map +1 -0
- package/dist/api/resources/activities.js +21 -0
- package/dist/api/resources/activities.js.map +1 -0
- package/dist/api/resources/agentTasks.d.ts +31 -0
- package/dist/api/resources/agentTasks.d.ts.map +1 -0
- package/dist/api/resources/agentTasks.js +103 -0
- package/dist/api/resources/agentTasks.js.map +1 -0
- package/dist/api/resources/candidates.d.ts +17 -0
- package/dist/api/resources/candidates.d.ts.map +1 -0
- package/dist/api/resources/candidates.js +40 -0
- package/dist/api/resources/candidates.js.map +1 -0
- package/dist/api/resources/companies.d.ts +22 -0
- package/dist/api/resources/companies.d.ts.map +1 -0
- package/dist/api/resources/companies.js +36 -0
- package/dist/api/resources/companies.js.map +1 -0
- package/dist/api/resources/dashboard.d.ts +8 -0
- package/dist/api/resources/dashboard.d.ts.map +1 -0
- package/dist/api/resources/dashboard.js +27 -0
- package/dist/api/resources/dashboard.js.map +1 -0
- package/dist/api/resources/deals.d.ts +30 -0
- package/dist/api/resources/deals.d.ts.map +1 -0
- package/dist/api/resources/deals.js +38 -0
- package/dist/api/resources/deals.js.map +1 -0
- package/dist/api/resources/decisions.d.ts +13 -0
- package/dist/api/resources/decisions.d.ts.map +1 -0
- package/dist/api/resources/decisions.js +38 -0
- package/dist/api/resources/decisions.js.map +1 -0
- package/dist/api/resources/forms.d.ts +82 -0
- package/dist/api/resources/forms.d.ts.map +1 -0
- package/dist/api/resources/forms.js +129 -0
- package/dist/api/resources/forms.js.map +1 -0
- package/dist/api/resources/handbookPages.d.ts +33 -0
- package/dist/api/resources/handbookPages.d.ts.map +1 -0
- package/dist/api/resources/handbookPages.js +49 -0
- package/dist/api/resources/handbookPages.js.map +1 -0
- package/dist/api/resources/importJobs.d.ts +72 -0
- package/dist/api/resources/importJobs.d.ts.map +1 -0
- package/dist/api/resources/importJobs.js +145 -0
- package/dist/api/resources/importJobs.js.map +1 -0
- package/dist/api/resources/invites.d.ts +19 -0
- package/dist/api/resources/invites.d.ts.map +1 -0
- package/dist/api/resources/invites.js +78 -0
- package/dist/api/resources/invites.js.map +1 -0
- package/dist/api/resources/mcpTools.d.ts +8 -0
- package/dist/api/resources/mcpTools.d.ts.map +1 -0
- package/dist/api/resources/mcpTools.js +23 -0
- package/dist/api/resources/mcpTools.js.map +1 -0
- package/dist/api/resources/members.d.ts +40 -0
- package/dist/api/resources/members.d.ts.map +1 -0
- package/dist/api/resources/members.js +67 -0
- package/dist/api/resources/members.js.map +1 -0
- package/dist/api/resources/moduleSettings.d.ts +14 -0
- package/dist/api/resources/moduleSettings.d.ts.map +1 -0
- package/dist/api/resources/moduleSettings.js +43 -0
- package/dist/api/resources/moduleSettings.js.map +1 -0
- package/dist/api/resources/mutation.d.ts +18 -0
- package/dist/api/resources/mutation.d.ts.map +1 -0
- package/dist/api/resources/mutation.js +12 -0
- package/dist/api/resources/mutation.js.map +1 -0
- package/dist/api/resources/notes.d.ts +14 -0
- package/dist/api/resources/notes.d.ts.map +1 -0
- package/dist/api/resources/notes.js +39 -0
- package/dist/api/resources/notes.js.map +1 -0
- package/dist/api/resources/opportunities.d.ts +29 -0
- package/dist/api/resources/opportunities.d.ts.map +1 -0
- package/dist/api/resources/opportunities.js +38 -0
- package/dist/api/resources/opportunities.js.map +1 -0
- package/dist/api/resources/partnerships.d.ts +33 -0
- package/dist/api/resources/partnerships.d.ts.map +1 -0
- package/dist/api/resources/partnerships.js +39 -0
- package/dist/api/resources/partnerships.js.map +1 -0
- package/dist/api/resources/people.d.ts +22 -0
- package/dist/api/resources/people.d.ts.map +1 -0
- package/dist/api/resources/people.js +36 -0
- package/dist/api/resources/people.js.map +1 -0
- package/dist/api/resources/pipelineStages.d.ts +22 -0
- package/dist/api/resources/pipelineStages.d.ts.map +1 -0
- package/dist/api/resources/pipelineStages.js +61 -0
- package/dist/api/resources/pipelineStages.js.map +1 -0
- package/dist/api/resources/planItems.d.ts +31 -0
- package/dist/api/resources/planItems.d.ts.map +1 -0
- package/dist/api/resources/planItems.js +60 -0
- package/dist/api/resources/planItems.js.map +1 -0
- package/dist/api/resources/positions.d.ts +23 -0
- package/dist/api/resources/positions.d.ts.map +1 -0
- package/dist/api/resources/positions.js +31 -0
- package/dist/api/resources/positions.js.map +1 -0
- package/dist/api/resources/raises.d.ts +30 -0
- package/dist/api/resources/raises.d.ts.map +1 -0
- package/dist/api/resources/raises.js +38 -0
- package/dist/api/resources/raises.js.map +1 -0
- package/dist/api/resources/roles.d.ts +20 -0
- package/dist/api/resources/roles.d.ts.map +1 -0
- package/dist/api/resources/roles.js +31 -0
- package/dist/api/resources/roles.js.map +1 -0
- package/dist/api/resources/search.d.ts +12 -0
- package/dist/api/resources/search.d.ts.map +1 -0
- package/dist/api/resources/search.js +37 -0
- package/dist/api/resources/search.js.map +1 -0
- package/dist/api/resources/session.d.ts +58 -0
- package/dist/api/resources/session.d.ts.map +1 -0
- package/dist/api/resources/session.js +157 -0
- package/dist/api/resources/session.js.map +1 -0
- package/dist/api/resources/webhooks.d.ts +45 -0
- package/dist/api/resources/webhooks.d.ts.map +1 -0
- package/dist/api/resources/webhooks.js +106 -0
- package/dist/api/resources/webhooks.js.map +1 -0
- package/dist/api/resources/workspace.d.ts +20 -0
- package/dist/api/resources/workspace.d.ts.map +1 -0
- package/dist/api/resources/workspace.js +63 -0
- package/dist/api/resources/workspace.js.map +1 -0
- package/dist/app/KelpieApp.d.ts +18 -0
- package/dist/app/KelpieApp.d.ts.map +1 -0
- package/dist/app/KelpieApp.js +59 -0
- package/dist/app/KelpieApp.js.map +1 -0
- package/dist/app/SessionGate.d.ts +14 -0
- package/dist/app/SessionGate.d.ts.map +1 -0
- package/dist/app/SessionGate.js +33 -0
- package/dist/app/SessionGate.js.map +1 -0
- package/dist/components/ActivitiesPanel.d.ts +28 -0
- package/dist/components/ActivitiesPanel.d.ts.map +1 -0
- package/dist/components/ActivitiesPanel.js +75 -0
- package/dist/components/ActivitiesPanel.js.map +1 -0
- package/dist/components/AgentTasks.d.ts +16 -0
- package/dist/components/AgentTasks.d.ts.map +1 -0
- package/dist/components/AgentTasks.js +166 -0
- package/dist/components/AgentTasks.js.map +1 -0
- package/dist/components/Chip.d.ts +10 -0
- package/dist/components/Chip.d.ts.map +1 -0
- package/dist/components/Chip.js +21 -0
- package/dist/components/Chip.js.map +1 -0
- package/dist/components/CopyButton.d.ts +7 -0
- package/dist/components/CopyButton.d.ts.map +1 -0
- package/dist/components/CopyButton.js +30 -0
- package/dist/components/CopyButton.js.map +1 -0
- package/dist/components/DataTable.d.ts +36 -0
- package/dist/components/DataTable.d.ts.map +1 -0
- package/dist/components/DataTable.js +43 -0
- package/dist/components/DataTable.js.map +1 -0
- package/dist/components/DecisionsPanel.d.ts +14 -0
- package/dist/components/DecisionsPanel.d.ts.map +1 -0
- package/dist/components/DecisionsPanel.js +73 -0
- package/dist/components/DecisionsPanel.js.map +1 -0
- package/dist/components/DeleteRecord.d.ts +19 -0
- package/dist/components/DeleteRecord.d.ts.map +1 -0
- package/dist/components/DeleteRecord.js +22 -0
- package/dist/components/DeleteRecord.js.map +1 -0
- package/dist/components/EntitySearch.d.ts +33 -0
- package/dist/components/EntitySearch.d.ts.map +1 -0
- package/dist/components/EntitySearch.js +111 -0
- package/dist/components/EntitySearch.js.map +1 -0
- package/dist/components/ErrorBoundary.d.ts +21 -0
- package/dist/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/components/ErrorBoundary.js +26 -0
- package/dist/components/ErrorBoundary.js.map +1 -0
- package/dist/components/InlineEdit.d.ts +37 -0
- package/dist/components/InlineEdit.d.ts.map +1 -0
- package/dist/components/InlineEdit.js +77 -0
- package/dist/components/InlineEdit.js.map +1 -0
- package/dist/components/KanbanBoard.d.ts +24 -0
- package/dist/components/KanbanBoard.d.ts.map +1 -0
- package/dist/components/KanbanBoard.js +92 -0
- package/dist/components/KanbanBoard.js.map +1 -0
- package/dist/components/MarkdownView.d.ts +4 -0
- package/dist/components/MarkdownView.d.ts.map +1 -0
- package/dist/components/MarkdownView.js +45 -0
- package/dist/components/MarkdownView.js.map +1 -0
- package/dist/components/NotesPanel.d.ts +17 -0
- package/dist/components/NotesPanel.d.ts.map +1 -0
- package/dist/components/NotesPanel.js +53 -0
- package/dist/components/NotesPanel.js.map +1 -0
- package/dist/components/PageHeader.d.ts +20 -0
- package/dist/components/PageHeader.d.ts.map +1 -0
- package/dist/components/PageHeader.js +15 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/PhonesField.d.ts +7 -0
- package/dist/components/PhonesField.d.ts.map +1 -0
- package/dist/components/PhonesField.js +92 -0
- package/dist/components/PhonesField.js.map +1 -0
- package/dist/components/PlanAttention.d.ts +40 -0
- package/dist/components/PlanAttention.d.ts.map +1 -0
- package/dist/components/PlanAttention.js +86 -0
- package/dist/components/PlanAttention.js.map +1 -0
- package/dist/components/PlanPanel.d.ts +18 -0
- package/dist/components/PlanPanel.d.ts.map +1 -0
- package/dist/components/PlanPanel.js +102 -0
- package/dist/components/PlanPanel.js.map +1 -0
- package/dist/components/QueryState.d.ts +24 -0
- package/dist/components/QueryState.d.ts.map +1 -0
- package/dist/components/QueryState.js +34 -0
- package/dist/components/QueryState.js.map +1 -0
- package/dist/components/RecordTabs.d.ts +16 -0
- package/dist/components/RecordTabs.d.ts.map +1 -0
- package/dist/components/RecordTabs.js +15 -0
- package/dist/components/RecordTabs.js.map +1 -0
- package/dist/components/SectionHeader.d.ts +15 -0
- package/dist/components/SectionHeader.d.ts.map +1 -0
- package/dist/components/SectionHeader.js +14 -0
- package/dist/components/SectionHeader.js.map +1 -0
- package/dist/components/SegmentedControl.d.ts +13 -0
- package/dist/components/SegmentedControl.d.ts.map +1 -0
- package/dist/components/SegmentedControl.js +14 -0
- package/dist/components/SegmentedControl.js.map +1 -0
- package/dist/components/Shell.d.ts +2 -0
- package/dist/components/Shell.d.ts.map +1 -0
- package/dist/components/Shell.js +143 -0
- package/dist/components/Shell.js.map +1 -0
- package/dist/components/SidebarField.d.ts +8 -0
- package/dist/components/SidebarField.d.ts.map +1 -0
- package/dist/components/SidebarField.js +6 -0
- package/dist/components/SidebarField.js.map +1 -0
- package/dist/components/SocialProfilesField.d.ts +8 -0
- package/dist/components/SocialProfilesField.d.ts.map +1 -0
- package/dist/components/SocialProfilesField.js +176 -0
- package/dist/components/SocialProfilesField.js.map +1 -0
- package/dist/components/StageSettings.d.ts +16 -0
- package/dist/components/StageSettings.d.ts.map +1 -0
- package/dist/components/StageSettings.js +107 -0
- package/dist/components/StageSettings.js.map +1 -0
- package/dist/components/SummaryBlock.d.ts +12 -0
- package/dist/components/SummaryBlock.d.ts.map +1 -0
- package/dist/components/SummaryBlock.js +12 -0
- package/dist/components/SummaryBlock.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +55 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/dates.d.ts +26 -0
- package/dist/lib/dates.d.ts.map +1 -0
- package/dist/lib/dates.js +71 -0
- package/dist/lib/dates.js.map +1 -0
- package/dist/lib/money.d.ts +7 -0
- package/dist/lib/money.d.ts.map +1 -0
- package/dist/lib/money.js +13 -0
- package/dist/lib/money.js.map +1 -0
- package/dist/lib/names.d.ts +9 -0
- package/dist/lib/names.d.ts.map +1 -0
- package/dist/lib/names.js +13 -0
- package/dist/lib/names.js.map +1 -0
- package/dist/lib/plan.d.ts +67 -0
- package/dist/lib/plan.d.ts.map +1 -0
- package/dist/lib/plan.js +96 -0
- package/dist/lib/plan.js.map +1 -0
- package/dist/lib/theme.d.ts +19 -0
- package/dist/lib/theme.d.ts.map +1 -0
- package/dist/lib/theme.js +30 -0
- package/dist/lib/theme.js.map +1 -0
- package/dist/pages/CompaniesPage.d.ts +2 -0
- package/dist/pages/CompaniesPage.d.ts.map +1 -0
- package/dist/pages/CompaniesPage.js +77 -0
- package/dist/pages/CompaniesPage.js.map +1 -0
- package/dist/pages/CompanyDetail.d.ts +2 -0
- package/dist/pages/CompanyDetail.d.ts.map +1 -0
- package/dist/pages/CompanyDetail.js +177 -0
- package/dist/pages/CompanyDetail.js.map +1 -0
- package/dist/pages/DealDetail.d.ts +2 -0
- package/dist/pages/DealDetail.d.ts.map +1 -0
- package/dist/pages/DealDetail.js +192 -0
- package/dist/pages/DealDetail.js.map +1 -0
- package/dist/pages/DealStageSettingsPage.d.ts +7 -0
- package/dist/pages/DealStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/DealStageSettingsPage.js +38 -0
- package/dist/pages/DealStageSettingsPage.js.map +1 -0
- package/dist/pages/DealsPage.d.ts +2 -0
- package/dist/pages/DealsPage.d.ts.map +1 -0
- package/dist/pages/DealsPage.js +177 -0
- package/dist/pages/DealsPage.js.map +1 -0
- package/dist/pages/DecisionsPage.d.ts +2 -0
- package/dist/pages/DecisionsPage.d.ts.map +1 -0
- package/dist/pages/DecisionsPage.js +121 -0
- package/dist/pages/DecisionsPage.js.map +1 -0
- package/dist/pages/FormDetail.d.ts +2 -0
- package/dist/pages/FormDetail.d.ts.map +1 -0
- package/dist/pages/FormDetail.js +56 -0
- package/dist/pages/FormDetail.js.map +1 -0
- package/dist/pages/FormsPage.d.ts +2 -0
- package/dist/pages/FormsPage.d.ts.map +1 -0
- package/dist/pages/FormsPage.js +67 -0
- package/dist/pages/FormsPage.js.map +1 -0
- package/dist/pages/FundraisingPage.d.ts +2 -0
- package/dist/pages/FundraisingPage.d.ts.map +1 -0
- package/dist/pages/FundraisingPage.js +187 -0
- package/dist/pages/FundraisingPage.js.map +1 -0
- package/dist/pages/HiringPage.d.ts +9 -0
- package/dist/pages/HiringPage.d.ts.map +1 -0
- package/dist/pages/HiringPage.js +73 -0
- package/dist/pages/HiringPage.js.map +1 -0
- package/dist/pages/NotFoundPage.d.ts +10 -0
- package/dist/pages/NotFoundPage.d.ts.map +1 -0
- package/dist/pages/NotFoundPage.js +14 -0
- package/dist/pages/NotFoundPage.js.map +1 -0
- package/dist/pages/OpportunitiesPage.d.ts +2 -0
- package/dist/pages/OpportunitiesPage.d.ts.map +1 -0
- package/dist/pages/OpportunitiesPage.js +184 -0
- package/dist/pages/OpportunitiesPage.js.map +1 -0
- package/dist/pages/OpportunityDetail.d.ts +2 -0
- package/dist/pages/OpportunityDetail.d.ts.map +1 -0
- package/dist/pages/OpportunityDetail.js +132 -0
- package/dist/pages/OpportunityDetail.js.map +1 -0
- package/dist/pages/OpportunityStageSettingsPage.d.ts +3 -0
- package/dist/pages/OpportunityStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/OpportunityStageSettingsPage.js +34 -0
- package/dist/pages/OpportunityStageSettingsPage.js.map +1 -0
- package/dist/pages/PartnershipDetail.d.ts +2 -0
- package/dist/pages/PartnershipDetail.d.ts.map +1 -0
- package/dist/pages/PartnershipDetail.js +179 -0
- package/dist/pages/PartnershipDetail.js.map +1 -0
- package/dist/pages/PartnershipStageSettingsPage.d.ts +3 -0
- package/dist/pages/PartnershipStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/PartnershipStageSettingsPage.js +34 -0
- package/dist/pages/PartnershipStageSettingsPage.js.map +1 -0
- package/dist/pages/PartnershipsPage.d.ts +2 -0
- package/dist/pages/PartnershipsPage.d.ts.map +1 -0
- package/dist/pages/PartnershipsPage.js +182 -0
- package/dist/pages/PartnershipsPage.js.map +1 -0
- package/dist/pages/PeoplePage.d.ts +10 -0
- package/dist/pages/PeoplePage.d.ts.map +1 -0
- package/dist/pages/PeoplePage.js +71 -0
- package/dist/pages/PeoplePage.js.map +1 -0
- package/dist/pages/PersonDetail.d.ts +2 -0
- package/dist/pages/PersonDetail.d.ts.map +1 -0
- package/dist/pages/PersonDetail.js +193 -0
- package/dist/pages/PersonDetail.js.map +1 -0
- package/dist/pages/PlanningPage.d.ts +2 -0
- package/dist/pages/PlanningPage.d.ts.map +1 -0
- package/dist/pages/PlanningPage.js +112 -0
- package/dist/pages/PlanningPage.js.map +1 -0
- package/dist/pages/RaiseDetail.d.ts +2 -0
- package/dist/pages/RaiseDetail.d.ts.map +1 -0
- package/dist/pages/RaiseDetail.js +198 -0
- package/dist/pages/RaiseDetail.js.map +1 -0
- package/dist/pages/RaiseStageSettingsPage.d.ts +3 -0
- package/dist/pages/RaiseStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/RaiseStageSettingsPage.js +34 -0
- package/dist/pages/RaiseStageSettingsPage.js.map +1 -0
- package/dist/pages/RoleDetail.d.ts +2 -0
- package/dist/pages/RoleDetail.d.ts.map +1 -0
- package/dist/pages/RoleDetail.js +177 -0
- package/dist/pages/RoleDetail.js.map +1 -0
- package/dist/pages/SearchPage.d.ts +2 -0
- package/dist/pages/SearchPage.d.ts.map +1 -0
- package/dist/pages/SearchPage.js +51 -0
- package/dist/pages/SearchPage.js.map +1 -0
- package/dist/pages/account/AccountLayout.d.ts +2 -0
- package/dist/pages/account/AccountLayout.d.ts.map +1 -0
- package/dist/pages/account/AccountLayout.js +25 -0
- package/dist/pages/account/AccountLayout.js.map +1 -0
- package/dist/pages/account/Field.d.ts +8 -0
- package/dist/pages/account/Field.d.ts.map +1 -0
- package/dist/pages/account/Field.js +6 -0
- package/dist/pages/account/Field.js.map +1 -0
- package/dist/pages/account/PreferencesPage.d.ts +2 -0
- package/dist/pages/account/PreferencesPage.d.ts.map +1 -0
- package/dist/pages/account/PreferencesPage.js +92 -0
- package/dist/pages/account/PreferencesPage.js.map +1 -0
- package/dist/pages/account/ProfilePage.d.ts +14 -0
- package/dist/pages/account/ProfilePage.d.ts.map +1 -0
- package/dist/pages/account/ProfilePage.js +71 -0
- package/dist/pages/account/ProfilePage.js.map +1 -0
- package/dist/pages/account/SecurityPage.d.ts +11 -0
- package/dist/pages/account/SecurityPage.d.ts.map +1 -0
- package/dist/pages/account/SecurityPage.js +78 -0
- package/dist/pages/account/SecurityPage.js.map +1 -0
- package/dist/pages/admin/DataPage.d.ts +3 -0
- package/dist/pages/admin/DataPage.d.ts.map +1 -0
- package/dist/pages/admin/DataPage.js +210 -0
- package/dist/pages/admin/DataPage.js.map +1 -0
- package/dist/pages/admin/McpPage.d.ts +2 -0
- package/dist/pages/admin/McpPage.d.ts.map +1 -0
- package/dist/pages/admin/McpPage.js +128 -0
- package/dist/pages/admin/McpPage.js.map +1 -0
- package/dist/pages/admin/ModulesPage.d.ts +2 -0
- package/dist/pages/admin/ModulesPage.d.ts.map +1 -0
- package/dist/pages/admin/ModulesPage.js +53 -0
- package/dist/pages/admin/ModulesPage.js.map +1 -0
- package/dist/pages/admin/TeamPage.d.ts +2 -0
- package/dist/pages/admin/TeamPage.d.ts.map +1 -0
- package/dist/pages/admin/TeamPage.js +99 -0
- package/dist/pages/admin/TeamPage.js.map +1 -0
- package/dist/pages/admin/WebhookDeliveries.d.ts +4 -0
- package/dist/pages/admin/WebhookDeliveries.d.ts.map +1 -0
- package/dist/pages/admin/WebhookDeliveries.js +88 -0
- package/dist/pages/admin/WebhookDeliveries.js.map +1 -0
- package/dist/pages/admin/WebhooksPage.d.ts +2 -0
- package/dist/pages/admin/WebhooksPage.d.ts.map +1 -0
- package/dist/pages/admin/WebhooksPage.js +152 -0
- package/dist/pages/admin/WebhooksPage.js.map +1 -0
- package/dist/pages/admin/WorkspaceSettingsPage.d.ts +2 -0
- package/dist/pages/admin/WorkspaceSettingsPage.d.ts.map +1 -0
- package/dist/pages/admin/WorkspaceSettingsPage.js +117 -0
- package/dist/pages/admin/WorkspaceSettingsPage.js.map +1 -0
- package/dist/pages/auth/AuthForm.d.ts +46 -0
- package/dist/pages/auth/AuthForm.d.ts.map +1 -0
- package/dist/pages/auth/AuthForm.js +32 -0
- package/dist/pages/auth/AuthForm.js.map +1 -0
- package/dist/pages/auth/AuthLayout.d.ts +24 -0
- package/dist/pages/auth/AuthLayout.d.ts.map +1 -0
- package/dist/pages/auth/AuthLayout.js +19 -0
- package/dist/pages/auth/AuthLayout.js.map +1 -0
- package/dist/pages/auth/ForgotPasswordPage.d.ts +13 -0
- package/dist/pages/auth/ForgotPasswordPage.d.ts.map +1 -0
- package/dist/pages/auth/ForgotPasswordPage.js +39 -0
- package/dist/pages/auth/ForgotPasswordPage.js.map +1 -0
- package/dist/pages/auth/JoinPage.d.ts +12 -0
- package/dist/pages/auth/JoinPage.d.ts.map +1 -0
- package/dist/pages/auth/JoinPage.js +43 -0
- package/dist/pages/auth/JoinPage.js.map +1 -0
- package/dist/pages/auth/ResetPasswordPage.d.ts +13 -0
- package/dist/pages/auth/ResetPasswordPage.d.ts.map +1 -0
- package/dist/pages/auth/ResetPasswordPage.js +58 -0
- package/dist/pages/auth/ResetPasswordPage.js.map +1 -0
- package/dist/pages/auth/SignInPage.d.ts +2 -0
- package/dist/pages/auth/SignInPage.d.ts.map +1 -0
- package/dist/pages/auth/SignInPage.js +38 -0
- package/dist/pages/auth/SignInPage.js.map +1 -0
- package/dist/pages/auth/SignUpPage.d.ts +13 -0
- package/dist/pages/auth/SignUpPage.d.ts.map +1 -0
- package/dist/pages/auth/SignUpPage.js +43 -0
- package/dist/pages/auth/SignUpPage.js.map +1 -0
- package/dist/pages/candidateFields.d.ts +22 -0
- package/dist/pages/candidateFields.d.ts.map +1 -0
- package/dist/pages/candidateFields.js +82 -0
- package/dist/pages/candidateFields.js.map +1 -0
- package/dist/pages/dashboard/DashboardPage.d.ts +2 -0
- package/dist/pages/dashboard/DashboardPage.d.ts.map +1 -0
- package/dist/pages/dashboard/DashboardPage.js +40 -0
- package/dist/pages/dashboard/DashboardPage.js.map +1 -0
- package/dist/pages/dashboard/attention.d.ts +41 -0
- package/dist/pages/dashboard/attention.d.ts.map +1 -0
- package/dist/pages/dashboard/attention.js +146 -0
- package/dist/pages/dashboard/attention.js.map +1 -0
- package/dist/pages/dashboard/sections.d.ts +20 -0
- package/dist/pages/dashboard/sections.d.ts.map +1 -0
- package/dist/pages/dashboard/sections.js +60 -0
- package/dist/pages/dashboard/sections.js.map +1 -0
- package/dist/pages/fields.d.ts +11 -0
- package/dist/pages/fields.d.ts.map +1 -0
- package/dist/pages/fields.js +17 -0
- package/dist/pages/fields.js.map +1 -0
- package/dist/pages/forms/EmbedPanel.d.ts +14 -0
- package/dist/pages/forms/EmbedPanel.d.ts.map +1 -0
- package/dist/pages/forms/EmbedPanel.js +19 -0
- package/dist/pages/forms/EmbedPanel.js.map +1 -0
- package/dist/pages/forms/FieldsEditor.d.ts +6 -0
- package/dist/pages/forms/FieldsEditor.d.ts.map +1 -0
- package/dist/pages/forms/FieldsEditor.js +115 -0
- package/dist/pages/forms/FieldsEditor.js.map +1 -0
- package/dist/pages/forms/FormSettings.d.ts +6 -0
- package/dist/pages/forms/FormSettings.d.ts.map +1 -0
- package/dist/pages/forms/FormSettings.js +47 -0
- package/dist/pages/forms/FormSettings.js.map +1 -0
- package/dist/pages/forms/SubmissionsTable.d.ts +8 -0
- package/dist/pages/forms/SubmissionsTable.d.ts.map +1 -0
- package/dist/pages/forms/SubmissionsTable.js +91 -0
- package/dist/pages/forms/SubmissionsTable.js.map +1 -0
- package/dist/pages/forms/fieldList.d.ts +70 -0
- package/dist/pages/forms/fieldList.d.ts.map +1 -0
- package/dist/pages/forms/fieldList.js +126 -0
- package/dist/pages/forms/fieldList.js.map +1 -0
- package/dist/pages/forms/template.d.ts +18 -0
- package/dist/pages/forms/template.d.ts.map +1 -0
- package/dist/pages/forms/template.js +34 -0
- package/dist/pages/forms/template.js.map +1 -0
- package/dist/pages/handbook/HandbookPage.d.ts +2 -0
- package/dist/pages/handbook/HandbookPage.d.ts.map +1 -0
- package/dist/pages/handbook/HandbookPage.js +197 -0
- package/dist/pages/handbook/HandbookPage.js.map +1 -0
- package/dist/pages/handbook/tree.d.ts +62 -0
- package/dist/pages/handbook/tree.d.ts.map +1 -0
- package/dist/pages/handbook/tree.js +222 -0
- package/dist/pages/handbook/tree.js.map +1 -0
- package/dist/pages/hiringDirectory.d.ts +60 -0
- package/dist/pages/hiringDirectory.d.ts.map +1 -0
- package/dist/pages/hiringDirectory.js +81 -0
- package/dist/pages/hiringDirectory.js.map +1 -0
- package/dist/pages/onboarding/HandbookStepPage.d.ts +14 -0
- package/dist/pages/onboarding/HandbookStepPage.d.ts.map +1 -0
- package/dist/pages/onboarding/HandbookStepPage.js +29 -0
- package/dist/pages/onboarding/HandbookStepPage.js.map +1 -0
- package/dist/pages/onboarding/InvitesStepPage.d.ts +2 -0
- package/dist/pages/onboarding/InvitesStepPage.d.ts.map +1 -0
- package/dist/pages/onboarding/InvitesStepPage.js +77 -0
- package/dist/pages/onboarding/InvitesStepPage.js.map +1 -0
- package/dist/pages/onboarding/WorkspaceStepPage.d.ts +2 -0
- package/dist/pages/onboarding/WorkspaceStepPage.d.ts.map +1 -0
- package/dist/pages/onboarding/WorkspaceStepPage.js +72 -0
- package/dist/pages/onboarding/WorkspaceStepPage.js.map +1 -0
- package/dist/pages/positionDirectory.d.ts +20 -0
- package/dist/pages/positionDirectory.d.ts.map +1 -0
- package/dist/pages/positionDirectory.js +58 -0
- package/dist/pages/positionDirectory.js.map +1 -0
- package/dist/registry/UiExtensionProvider.d.ts +12 -0
- package/dist/registry/UiExtensionProvider.d.ts.map +1 -0
- package/dist/registry/UiExtensionProvider.js +10 -0
- package/dist/registry/UiExtensionProvider.js.map +1 -0
- package/dist/registry/context.d.ts +31 -0
- package/dist/registry/context.d.ts.map +1 -0
- package/dist/registry/context.js +45 -0
- package/dist/registry/context.js.map +1 -0
- package/dist/registry/contributions.d.ts +71 -0
- package/dist/registry/contributions.d.ts.map +1 -0
- package/dist/registry/contributions.js +25 -0
- package/dist/registry/contributions.js.map +1 -0
- package/dist/registry/overridable.d.ts +27 -0
- package/dist/registry/overridable.d.ts.map +1 -0
- package/dist/registry/overridable.js +29 -0
- package/dist/registry/overridable.js.map +1 -0
- package/dist/registry/registry.d.ts +68 -0
- package/dist/registry/registry.d.ts.map +1 -0
- package/dist/registry/registry.js +112 -0
- package/dist/registry/registry.js.map +1 -0
- package/dist/testing/inputs.d.ts +13 -0
- package/dist/testing/inputs.d.ts.map +1 -0
- package/dist/testing/inputs.js +16 -0
- package/dist/testing/inputs.js.map +1 -0
- package/dist/testing/stubClient.d.ts +42 -0
- package/dist/testing/stubClient.d.ts.map +1 -0
- package/dist/testing/stubClient.js +29 -0
- package/dist/testing/stubClient.js.map +1 -0
- package/package.json +73 -0
- package/src/ServiceStatus.tsx +61 -0
- package/src/api/ApiProvider.tsx +40 -0
- package/src/api/client.ts +267 -0
- package/src/api/context.ts +25 -0
- package/src/api/errors.ts +14 -0
- package/src/api/health.ts +38 -0
- package/src/api/json.ts +4 -0
- package/src/api/queryClient.ts +35 -0
- package/src/api/resource.ts +412 -0
- package/src/api/resources/account.ts +220 -0
- package/src/api/resources/activities.ts +31 -0
- package/src/api/resources/agentTasks.ts +172 -0
- package/src/api/resources/candidates.ts +69 -0
- package/src/api/resources/companies.ts +72 -0
- package/src/api/resources/dashboard.ts +39 -0
- package/src/api/resources/deals.ts +82 -0
- package/src/api/resources/decisions.ts +60 -0
- package/src/api/resources/forms.ts +218 -0
- package/src/api/resources/handbookPages.ts +77 -0
- package/src/api/resources/importJobs.ts +229 -0
- package/src/api/resources/invites.ts +112 -0
- package/src/api/resources/mcpTools.ts +28 -0
- package/src/api/resources/members.ts +105 -0
- package/src/api/resources/moduleSettings.ts +67 -0
- package/src/api/resources/mutation.ts +31 -0
- package/src/api/resources/notes.ts +62 -0
- package/src/api/resources/opportunities.ts +84 -0
- package/src/api/resources/partnerships.ts +89 -0
- package/src/api/resources/people.ts +72 -0
- package/src/api/resources/pipelineStages.ts +93 -0
- package/src/api/resources/planItems.ts +103 -0
- package/src/api/resources/positions.ts +70 -0
- package/src/api/resources/raises.ts +82 -0
- package/src/api/resources/roles.ts +65 -0
- package/src/api/resources/search.ts +49 -0
- package/src/api/resources/session.ts +220 -0
- package/src/api/resources/webhooks.ts +157 -0
- package/src/api/resources/workspace.ts +81 -0
- package/src/app/KelpieApp.tsx +162 -0
- package/src/app/SessionGate.tsx +42 -0
- package/src/components/ActivitiesPanel.tsx +235 -0
- package/src/components/AgentTasks.tsx +473 -0
- package/src/components/Chip.tsx +36 -0
- package/src/components/CopyButton.tsx +48 -0
- package/src/components/DataTable.tsx +209 -0
- package/src/components/DecisionsPanel.tsx +233 -0
- package/src/components/DeleteRecord.tsx +73 -0
- package/src/components/EntitySearch.tsx +268 -0
- package/src/components/ErrorBoundary.tsx +58 -0
- package/src/components/InlineEdit.tsx +179 -0
- package/src/components/KanbanBoard.tsx +234 -0
- package/src/components/MarkdownView.tsx +73 -0
- package/src/components/NotesPanel.tsx +169 -0
- package/src/components/PageHeader.tsx +61 -0
- package/src/components/PhonesField.tsx +204 -0
- package/src/components/PlanAttention.tsx +249 -0
- package/src/components/PlanPanel.tsx +317 -0
- package/src/components/QueryState.tsx +83 -0
- package/src/components/RecordTabs.tsx +69 -0
- package/src/components/SectionHeader.tsx +63 -0
- package/src/components/SegmentedControl.tsx +48 -0
- package/src/components/Shell.tsx +300 -0
- package/src/components/SidebarField.tsx +18 -0
- package/src/components/SocialProfilesField.tsx +356 -0
- package/src/components/StageSettings.tsx +319 -0
- package/src/components/SummaryBlock.tsx +27 -0
- package/src/index.ts +190 -0
- package/src/lib/dates.ts +90 -0
- package/src/lib/money.ts +12 -0
- package/src/lib/names.ts +13 -0
- package/src/lib/plan.ts +147 -0
- package/src/lib/theme.ts +53 -0
- package/src/pages/CompaniesPage.tsx +143 -0
- package/src/pages/CompanyDetail.tsx +502 -0
- package/src/pages/DealDetail.tsx +512 -0
- package/src/pages/DealStageSettingsPage.tsx +67 -0
- package/src/pages/DealsPage.tsx +342 -0
- package/src/pages/DecisionsPage.tsx +211 -0
- package/src/pages/FormDetail.tsx +130 -0
- package/src/pages/FormsPage.tsx +151 -0
- package/src/pages/FundraisingPage.tsx +354 -0
- package/src/pages/HiringPage.tsx +169 -0
- package/src/pages/NotFoundPage.tsx +27 -0
- package/src/pages/OpportunitiesPage.tsx +349 -0
- package/src/pages/OpportunityDetail.tsx +337 -0
- package/src/pages/OpportunityStageSettingsPage.tsx +63 -0
- package/src/pages/PartnershipDetail.tsx +490 -0
- package/src/pages/PartnershipStageSettingsPage.tsx +63 -0
- package/src/pages/PartnershipsPage.tsx +353 -0
- package/src/pages/PeoplePage.tsx +145 -0
- package/src/pages/PersonDetail.tsx +526 -0
- package/src/pages/PlanningPage.tsx +318 -0
- package/src/pages/RaiseDetail.tsx +498 -0
- package/src/pages/RaiseStageSettingsPage.tsx +63 -0
- package/src/pages/RoleDetail.tsx +455 -0
- package/src/pages/SearchPage.tsx +135 -0
- package/src/pages/account/AccountLayout.tsx +38 -0
- package/src/pages/account/Field.tsx +20 -0
- package/src/pages/account/PreferencesPage.tsx +224 -0
- package/src/pages/account/ProfilePage.tsx +147 -0
- package/src/pages/account/SecurityPage.tsx +237 -0
- package/src/pages/admin/DataPage.tsx +772 -0
- package/src/pages/admin/McpPage.tsx +404 -0
- package/src/pages/admin/ModulesPage.tsx +113 -0
- package/src/pages/admin/TeamPage.tsx +386 -0
- package/src/pages/admin/WebhookDeliveries.tsx +184 -0
- package/src/pages/admin/WebhooksPage.tsx +443 -0
- package/src/pages/admin/WorkspaceSettingsPage.tsx +274 -0
- package/src/pages/auth/AuthForm.tsx +118 -0
- package/src/pages/auth/AuthLayout.tsx +74 -0
- package/src/pages/auth/ForgotPasswordPage.tsx +80 -0
- package/src/pages/auth/JoinPage.tsx +85 -0
- package/src/pages/auth/ResetPasswordPage.tsx +124 -0
- package/src/pages/auth/SignInPage.tsx +83 -0
- package/src/pages/auth/SignUpPage.tsx +93 -0
- package/src/pages/candidateFields.tsx +175 -0
- package/src/pages/dashboard/DashboardPage.tsx +108 -0
- package/src/pages/dashboard/attention.ts +206 -0
- package/src/pages/dashboard/sections.tsx +269 -0
- package/src/pages/fields.ts +21 -0
- package/src/pages/forms/EmbedPanel.tsx +95 -0
- package/src/pages/forms/FieldsEditor.tsx +412 -0
- package/src/pages/forms/FormSettings.tsx +159 -0
- package/src/pages/forms/SubmissionsTable.tsx +171 -0
- package/src/pages/forms/fieldList.ts +209 -0
- package/src/pages/forms/template.ts +37 -0
- package/src/pages/handbook/HandbookPage.tsx +500 -0
- package/src/pages/handbook/tree.ts +327 -0
- package/src/pages/hiringDirectory.ts +146 -0
- package/src/pages/onboarding/HandbookStepPage.tsx +75 -0
- package/src/pages/onboarding/InvitesStepPage.tsx +180 -0
- package/src/pages/onboarding/WorkspaceStepPage.tsx +122 -0
- package/src/pages/positionDirectory.ts +98 -0
- package/src/registry/UiExtensionProvider.tsx +20 -0
- package/src/registry/context.ts +67 -0
- package/src/registry/contributions.ts +89 -0
- package/src/registry/overridable.ts +62 -0
- package/src/registry/registry.ts +204 -0
- package/src/styles.css +175 -0
- package/src/testing/inputs.ts +18 -0
- package/src/testing/stubClient.ts +78 -0
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
Dashboard,
|
|
3
|
+
DashboardPlanItem,
|
|
4
|
+
DashboardStaleContact,
|
|
5
|
+
DashboardTouchpoint,
|
|
6
|
+
PipelineKind,
|
|
7
|
+
RecordTargetType,
|
|
8
|
+
} from '@kelpie/schemas'
|
|
9
|
+
|
|
10
|
+
import type { ChipTone } from '../../components/Chip.tsx'
|
|
11
|
+
import { formatDay } from '../../lib/dates.ts'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Reading the workspace snapshot as a page: one attention list, and the brief
|
|
15
|
+
* above it.
|
|
16
|
+
*
|
|
17
|
+
* Pure functions over the decoded response, so the page renders and these are
|
|
18
|
+
* tested separately. Nothing here recomputes a signal: the service already
|
|
19
|
+
* decided what is overdue, against the workspace's own day, and a browser that
|
|
20
|
+
* re-derived it from its own clock would disagree with the totals beside it.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/** Where each kind of record lives. A Candidate has no page of its own: it is reached through its Role. */
|
|
24
|
+
const ROUTES: Readonly<Record<RecordTargetType, string | undefined>> = {
|
|
25
|
+
person: '/people',
|
|
26
|
+
company: '/companies',
|
|
27
|
+
deal: '/deals',
|
|
28
|
+
opportunity: '/opportunities',
|
|
29
|
+
partnership: '/partnerships',
|
|
30
|
+
raise: '/fundraising',
|
|
31
|
+
candidate: undefined,
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const TARGET_TYPE_LABELS: Readonly<Record<RecordTargetType, string>> = {
|
|
35
|
+
person: 'Person',
|
|
36
|
+
company: 'Company',
|
|
37
|
+
deal: 'Deal',
|
|
38
|
+
opportunity: 'Opportunity',
|
|
39
|
+
partnership: 'Partnership',
|
|
40
|
+
raise: 'Fundraising',
|
|
41
|
+
candidate: 'Candidate',
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export function targetTypeLabel(targetType: RecordTargetType): string {
|
|
45
|
+
return TARGET_TYPE_LABELS[targetType]
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @returns The record's page, or undefined when it has none. A row without a
|
|
50
|
+
* link renders as plain text rather than as a link to nowhere.
|
|
51
|
+
*/
|
|
52
|
+
export function targetHref(targetType: RecordTargetType, targetId: string): string | undefined {
|
|
53
|
+
const route = ROUTES[targetType]
|
|
54
|
+
|
|
55
|
+
return route === undefined ? undefined : `${route}/${targetId}`
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** How a target reads when it is named on another record's row. */
|
|
59
|
+
export function targetDescription(item: {
|
|
60
|
+
readonly targetType: RecordTargetType
|
|
61
|
+
readonly targetName: string | null
|
|
62
|
+
}): string {
|
|
63
|
+
const label = targetTypeLabel(item.targetType)
|
|
64
|
+
|
|
65
|
+
return item.targetName === null ? label : `${label} · ${item.targetName}`
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface AttentionRow {
|
|
69
|
+
readonly id: string
|
|
70
|
+
/** What kind of signal this is, shown as a chip. */
|
|
71
|
+
readonly label: string
|
|
72
|
+
readonly tone: ChipTone
|
|
73
|
+
/** The date or interval that makes it urgent. */
|
|
74
|
+
readonly meta: string
|
|
75
|
+
readonly title: string
|
|
76
|
+
readonly detail: string
|
|
77
|
+
readonly href: string | undefined
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function planItemRow(item: DashboardPlanItem, overdue: boolean): AttentionRow {
|
|
81
|
+
return {
|
|
82
|
+
id: `plan-${item.id}`,
|
|
83
|
+
label: overdue ? 'Plan item overdue' : 'Plan item due soon',
|
|
84
|
+
tone: overdue ? 'danger' : 'warning',
|
|
85
|
+
meta: formatDay(item.date),
|
|
86
|
+
title: item.title,
|
|
87
|
+
detail: targetDescription(item),
|
|
88
|
+
href: targetHref(item.targetType, item.targetId),
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function touchpointRow(touchpoint: DashboardTouchpoint): AttentionRow {
|
|
93
|
+
return {
|
|
94
|
+
id: `touchpoint-${touchpoint.id}`,
|
|
95
|
+
label: touchpoint.overdue ? 'Touchpoint overdue' : 'Touchpoint soon',
|
|
96
|
+
tone: touchpoint.overdue ? 'danger' : 'warning',
|
|
97
|
+
meta: `Touchpoint ${formatDay(touchpoint.nextTouchpoint)}`,
|
|
98
|
+
title: touchpoint.name,
|
|
99
|
+
detail: touchpoint.summary,
|
|
100
|
+
href: `/partnerships/${touchpoint.id}`,
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function staleContactRow(contact: DashboardStaleContact): AttentionRow {
|
|
105
|
+
return {
|
|
106
|
+
id: `stale-${contact.id}`,
|
|
107
|
+
label: 'Stale contact',
|
|
108
|
+
tone: 'neutral',
|
|
109
|
+
meta: `${String(contact.daysSinceContact)} days since contact`,
|
|
110
|
+
title: contact.name,
|
|
111
|
+
detail: contact.summary,
|
|
112
|
+
href: `/people/${contact.id}`,
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The signals behind the brief, most urgent first.
|
|
118
|
+
*
|
|
119
|
+
* The groups are concatenated rather than sorted: each arrives from the API in
|
|
120
|
+
* its own order — plan items soonest first, contacts coldest first — and a
|
|
121
|
+
* re-sort across the three would throw that away for a single column that means
|
|
122
|
+
* a different thing in each.
|
|
123
|
+
*/
|
|
124
|
+
export function attentionRows(dashboard: Dashboard): readonly AttentionRow[] {
|
|
125
|
+
const touchpoints = dashboard.partnershipTouchpoints.items
|
|
126
|
+
|
|
127
|
+
return [
|
|
128
|
+
...dashboard.overduePlanItems.items.map((item) => planItemRow(item, true)),
|
|
129
|
+
...touchpoints.filter((touchpoint) => touchpoint.overdue).map(touchpointRow),
|
|
130
|
+
...dashboard.dueSoonPlanItems.items.map((item) => planItemRow(item, false)),
|
|
131
|
+
...touchpoints.filter((touchpoint) => !touchpoint.overdue).map(touchpointRow),
|
|
132
|
+
...dashboard.staleContacts.items.map(staleContactRow),
|
|
133
|
+
]
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function plural(count: number, singular: string, pluralForm = `${singular}s`): string {
|
|
137
|
+
return `${String(count)} ${count === 1 ? singular : pluralForm}`
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* How a count of open records reads mid-sentence.
|
|
142
|
+
*
|
|
143
|
+
* Not `PIPELINE_KIND_LABELS`: that one is nav wording, where a Raise is filed
|
|
144
|
+
* under "Fundraising", and "3 fundraisings" is not a sentence. Written out
|
|
145
|
+
* rather than suffixed, because "opportunitys" is not one either.
|
|
146
|
+
*/
|
|
147
|
+
const OPEN_PIPELINE_NOUNS: Readonly<
|
|
148
|
+
Record<PipelineKind, { readonly one: string; readonly many: string }>
|
|
149
|
+
> = {
|
|
150
|
+
deal: { one: 'deal', many: 'deals' },
|
|
151
|
+
opportunity: { one: 'opportunity', many: 'opportunities' },
|
|
152
|
+
raise: { one: 'raise', many: 'raises' },
|
|
153
|
+
partnership: { one: 'partnership', many: 'partnerships' },
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* The brief, built from the totals rather than from the rows.
|
|
158
|
+
*
|
|
159
|
+
* A list is capped by the request's limit and a total is not, so counting the
|
|
160
|
+
* rows on screen would understate every workspace with more than a page of them.
|
|
161
|
+
*/
|
|
162
|
+
export function briefLines(dashboard: Dashboard): readonly string[] {
|
|
163
|
+
const lines: string[] = []
|
|
164
|
+
|
|
165
|
+
if (dashboard.overduePlanItems.total > 0) {
|
|
166
|
+
lines.push(
|
|
167
|
+
`${plural(dashboard.overduePlanItems.total, 'plan item')} overdue — triage Planning first.`,
|
|
168
|
+
)
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
if (dashboard.dueSoonPlanItems.total > 0) {
|
|
172
|
+
lines.push(
|
|
173
|
+
`${plural(dashboard.dueSoonPlanItems.total, 'plan item')} due in the next ${plural(dashboard.upcomingDays, 'day')}.`,
|
|
174
|
+
)
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (dashboard.partnershipTouchpoints.total > 0) {
|
|
178
|
+
lines.push(
|
|
179
|
+
`${plural(dashboard.partnershipTouchpoints.total, 'partnership touchpoint')} at hand.`,
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
if (dashboard.staleContacts.total > 0) {
|
|
184
|
+
lines.push(
|
|
185
|
+
`${plural(dashboard.staleContacts.total, 'contact')} past the ${String(dashboard.staleContactDays)}-day touch threshold.`,
|
|
186
|
+
)
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const open = dashboard.pipelines.filter((pipeline) => pipeline.open > 0)
|
|
190
|
+
|
|
191
|
+
if (open.length > 0) {
|
|
192
|
+
lines.push(
|
|
193
|
+
`Open: ${open
|
|
194
|
+
.map((pipeline) => {
|
|
195
|
+
const noun = OPEN_PIPELINE_NOUNS[pipeline.kind]
|
|
196
|
+
|
|
197
|
+
return plural(pipeline.open, noun.one, noun.many)
|
|
198
|
+
})
|
|
199
|
+
.join(', ')}.`,
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return lines.length === 0
|
|
204
|
+
? ['Nothing urgent. Pipeline and relationships look quiet today.']
|
|
205
|
+
: lines
|
|
206
|
+
}
|
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
ActivityKind,
|
|
3
|
+
DashboardActivity,
|
|
4
|
+
DashboardDecision,
|
|
5
|
+
DashboardNote,
|
|
6
|
+
TargetRef,
|
|
7
|
+
} from '@kelpie/schemas'
|
|
8
|
+
import type { ReactNode } from 'react'
|
|
9
|
+
import { Link } from 'react-router'
|
|
10
|
+
|
|
11
|
+
import { Chip } from '../../components/Chip.tsx'
|
|
12
|
+
import { SectionHeader } from '../../components/SectionHeader.tsx'
|
|
13
|
+
import { formatDate, formatRelativeTime } from '../../lib/dates.ts'
|
|
14
|
+
import { targetHref, targetTypeLabel } from './attention.ts'
|
|
15
|
+
import type { AttentionRow } from './attention.ts'
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* The four lists the workspace home is made of.
|
|
19
|
+
*
|
|
20
|
+
* Every row here points at a record other than the one being looked at, which is
|
|
21
|
+
* what makes the dashboard different from a record's own panels: the response
|
|
22
|
+
* carries `targetName` already resolved, so nothing below fetches anything.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/** Two letters per kind, as the mockup's timeline gutter shows them. */
|
|
26
|
+
const KIND_GLYPHS: Readonly<Record<ActivityKind, string>> = {
|
|
27
|
+
created: 'Cr',
|
|
28
|
+
updated: 'Up',
|
|
29
|
+
stage_changed: 'St',
|
|
30
|
+
note_added: 'Nt',
|
|
31
|
+
email: 'Em',
|
|
32
|
+
call: 'Ca',
|
|
33
|
+
meeting: 'Mt',
|
|
34
|
+
linked: 'Ln',
|
|
35
|
+
unlinked: 'Un',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** A record's name, as a link when it has a page and as text when it does not. */
|
|
39
|
+
function TargetLink({
|
|
40
|
+
target,
|
|
41
|
+
className = 'text-ink-muted hover:text-accent hover:underline',
|
|
42
|
+
}: {
|
|
43
|
+
readonly target: TargetRef
|
|
44
|
+
readonly className?: string
|
|
45
|
+
}): React.JSX.Element {
|
|
46
|
+
const href = targetHref(target.targetType, target.targetId)
|
|
47
|
+
const label = target.targetName ?? targetTypeLabel(target.targetType)
|
|
48
|
+
|
|
49
|
+
if (href === undefined) {
|
|
50
|
+
return <span className={className}>{label}</span>
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
return (
|
|
54
|
+
<Link to={href} className={className}>
|
|
55
|
+
{label}
|
|
56
|
+
</Link>
|
|
57
|
+
)
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
function EmptyOr({
|
|
61
|
+
isEmpty,
|
|
62
|
+
empty,
|
|
63
|
+
children,
|
|
64
|
+
}: {
|
|
65
|
+
readonly isEmpty: boolean
|
|
66
|
+
readonly empty: string
|
|
67
|
+
readonly children: ReactNode
|
|
68
|
+
}): React.JSX.Element {
|
|
69
|
+
return isEmpty ? <p className="text-[13px] text-ink-faint">{empty}</p> : <>{children}</>
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function AttentionList({ rows }: { readonly rows: readonly AttentionRow[] }): React.JSX.Element {
|
|
73
|
+
return (
|
|
74
|
+
<section>
|
|
75
|
+
<SectionHeader title="Needs attention" description="The signals behind the brief." />
|
|
76
|
+
<EmptyOr isEmpty={rows.length === 0} empty="Nothing urgent right now.">
|
|
77
|
+
<ul className="divide-y divide-border border-y border-border">
|
|
78
|
+
{rows.map((row) => (
|
|
79
|
+
<li key={row.id} className="py-3">
|
|
80
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
81
|
+
<Chip tone={row.tone}>{row.label}</Chip>
|
|
82
|
+
<span className="text-[11px] text-ink-faint">{row.meta}</span>
|
|
83
|
+
</div>
|
|
84
|
+
{row.href === undefined ? (
|
|
85
|
+
<p className="mt-1.5 text-[13px] font-medium text-ink">{row.title}</p>
|
|
86
|
+
) : (
|
|
87
|
+
<Link
|
|
88
|
+
to={row.href}
|
|
89
|
+
className="mt-1.5 block text-[13px] font-medium text-ink hover:text-accent"
|
|
90
|
+
>
|
|
91
|
+
{row.title}
|
|
92
|
+
</Link>
|
|
93
|
+
)}
|
|
94
|
+
{row.detail !== '' && (
|
|
95
|
+
<p className="mt-0.5 line-clamp-2 text-[12px] text-ink-muted">{row.detail}</p>
|
|
96
|
+
)}
|
|
97
|
+
</li>
|
|
98
|
+
))}
|
|
99
|
+
</ul>
|
|
100
|
+
</EmptyOr>
|
|
101
|
+
</section>
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export function ActivityFeed({
|
|
106
|
+
activities,
|
|
107
|
+
nameById,
|
|
108
|
+
now,
|
|
109
|
+
}: {
|
|
110
|
+
readonly activities: readonly DashboardActivity[]
|
|
111
|
+
readonly nameById: ReadonlyMap<string, string>
|
|
112
|
+
readonly now: Date
|
|
113
|
+
}): React.JSX.Element {
|
|
114
|
+
return (
|
|
115
|
+
<section>
|
|
116
|
+
<SectionHeader
|
|
117
|
+
title="Recent activity"
|
|
118
|
+
description="The latest events across people, companies, and pipelines."
|
|
119
|
+
/>
|
|
120
|
+
<EmptyOr isEmpty={activities.length === 0} empty="No activity yet.">
|
|
121
|
+
<ol className="divide-y divide-border border-y border-border">
|
|
122
|
+
{activities.map((activity, index) => (
|
|
123
|
+
<li key={activity.id} className="flex gap-2 py-3">
|
|
124
|
+
<div className="relative flex w-5 shrink-0 justify-center">
|
|
125
|
+
{index < activities.length - 1 && (
|
|
126
|
+
<span
|
|
127
|
+
aria-hidden
|
|
128
|
+
className="absolute top-5 bottom-[-12px] left-1/2 w-px -translate-x-1/2 bg-border"
|
|
129
|
+
/>
|
|
130
|
+
)}
|
|
131
|
+
<div
|
|
132
|
+
className="relative z-10 flex h-5 w-5 items-center justify-center rounded border border-border bg-surface text-[9px] font-medium tracking-wide text-ink-muted uppercase"
|
|
133
|
+
title={activity.kind}
|
|
134
|
+
>
|
|
135
|
+
{KIND_GLYPHS[activity.kind]}
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
<div className="min-w-0 flex-1">
|
|
139
|
+
<div className="flex items-baseline justify-between gap-3">
|
|
140
|
+
<p className="min-w-0 text-[12px] leading-snug text-ink">
|
|
141
|
+
<span className="font-semibold">{actorNameFor(activity, nameById)}</span>{' '}
|
|
142
|
+
<span className="text-ink-muted">{activity.action}</span>
|
|
143
|
+
</p>
|
|
144
|
+
<time
|
|
145
|
+
dateTime={activity.createdAt.toISOString()}
|
|
146
|
+
className="shrink-0 text-[11px] text-ink-faint"
|
|
147
|
+
>
|
|
148
|
+
{formatRelativeTime(activity.createdAt, now)}
|
|
149
|
+
</time>
|
|
150
|
+
</div>
|
|
151
|
+
<p className="text-[11px] leading-snug text-ink-faint">
|
|
152
|
+
on <span className="text-ink-muted">{targetTypeLabel(activity.targetType)}</span>
|
|
153
|
+
{' · '}
|
|
154
|
+
<TargetLink target={activity} />
|
|
155
|
+
</p>
|
|
156
|
+
{activity.detail !== null && (
|
|
157
|
+
<p className="text-[11px] leading-snug text-ink-faint">{activity.detail}</p>
|
|
158
|
+
)}
|
|
159
|
+
</div>
|
|
160
|
+
</li>
|
|
161
|
+
))}
|
|
162
|
+
</ol>
|
|
163
|
+
</EmptyOr>
|
|
164
|
+
</section>
|
|
165
|
+
)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Exactly one of the two actor columns is set. `actorLabel` carries the display
|
|
170
|
+
* name when nothing on the team did this: "Form", "Gmail", "API key".
|
|
171
|
+
*/
|
|
172
|
+
function actorNameFor(
|
|
173
|
+
activity: DashboardActivity,
|
|
174
|
+
nameById: ReadonlyMap<string, string>,
|
|
175
|
+
): string {
|
|
176
|
+
if (activity.actorMemberId === null) {
|
|
177
|
+
return activity.actorLabel ?? 'System'
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
return nameById.get(activity.actorMemberId) ?? 'Unknown'
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
export function NotesList({
|
|
184
|
+
notes,
|
|
185
|
+
nameById,
|
|
186
|
+
now,
|
|
187
|
+
}: {
|
|
188
|
+
readonly notes: readonly DashboardNote[]
|
|
189
|
+
readonly nameById: ReadonlyMap<string, string>
|
|
190
|
+
readonly now: Date
|
|
191
|
+
}): React.JSX.Element {
|
|
192
|
+
return (
|
|
193
|
+
<section>
|
|
194
|
+
<SectionHeader title="Recent notes" description="Pinned notes surface first." />
|
|
195
|
+
<EmptyOr isEmpty={notes.length === 0} empty="No notes yet.">
|
|
196
|
+
<ul className="divide-y divide-border border-y border-border">
|
|
197
|
+
{notes.map((note) => (
|
|
198
|
+
<li key={note.id} className="py-3">
|
|
199
|
+
<div className="flex items-start justify-between gap-2">
|
|
200
|
+
<p className="line-clamp-3 text-[13px] leading-relaxed text-ink">{note.body}</p>
|
|
201
|
+
{note.pinned && (
|
|
202
|
+
<span className="shrink-0 text-[10px] font-medium tracking-wide text-accent uppercase">
|
|
203
|
+
Pinned
|
|
204
|
+
</span>
|
|
205
|
+
)}
|
|
206
|
+
</div>
|
|
207
|
+
<div className="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-ink-faint">
|
|
208
|
+
<TargetLink target={note} />
|
|
209
|
+
<span>·</span>
|
|
210
|
+
<span>{targetTypeLabel(note.targetType)}</span>
|
|
211
|
+
<span>·</span>
|
|
212
|
+
<span>{note.authorId === null ? 'System' : (nameById.get(note.authorId) ?? 'Unknown')}</span>
|
|
213
|
+
<span>·</span>
|
|
214
|
+
<span>{formatRelativeTime(note.createdAt, now)}</span>
|
|
215
|
+
</div>
|
|
216
|
+
</li>
|
|
217
|
+
))}
|
|
218
|
+
</ul>
|
|
219
|
+
</EmptyOr>
|
|
220
|
+
</section>
|
|
221
|
+
)
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export function DecisionsList({
|
|
225
|
+
decisions,
|
|
226
|
+
nameById,
|
|
227
|
+
}: {
|
|
228
|
+
readonly decisions: readonly DashboardDecision[]
|
|
229
|
+
readonly nameById: ReadonlyMap<string, string>
|
|
230
|
+
}): React.JSX.Element {
|
|
231
|
+
return (
|
|
232
|
+
<section>
|
|
233
|
+
<div className="mb-3 flex items-start justify-between gap-2">
|
|
234
|
+
<div className="min-w-0">
|
|
235
|
+
<h2 className="text-[13px] font-semibold text-ink">Recent decisions</h2>
|
|
236
|
+
<p className="mt-0.5 text-[11px] text-ink-faint">
|
|
237
|
+
Commitments agents should not contradict.
|
|
238
|
+
</p>
|
|
239
|
+
</div>
|
|
240
|
+
<Link to="/decisions" className="shrink-0 text-[12px] font-medium text-accent hover:underline">
|
|
241
|
+
View all
|
|
242
|
+
</Link>
|
|
243
|
+
</div>
|
|
244
|
+
<EmptyOr isEmpty={decisions.length === 0} empty="No decisions yet.">
|
|
245
|
+
<ul className="divide-y divide-border border-y border-border">
|
|
246
|
+
{decisions.map((decision) => (
|
|
247
|
+
<li key={decision.id} className="py-3">
|
|
248
|
+
<p className="text-[13px] font-medium text-ink">{decision.body}</p>
|
|
249
|
+
{decision.rationale !== null && (
|
|
250
|
+
<p className="mt-0.5 line-clamp-2 text-[12px] text-ink-muted">
|
|
251
|
+
{decision.rationale}
|
|
252
|
+
</p>
|
|
253
|
+
)}
|
|
254
|
+
<div className="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-ink-faint">
|
|
255
|
+
<TargetLink target={decision} />
|
|
256
|
+
<span>·</span>
|
|
257
|
+
<span>{formatDate(decision.decidedAt)}</span>
|
|
258
|
+
<span>·</span>
|
|
259
|
+
<span>
|
|
260
|
+
{decision.ownerId === null ? '—' : (nameById.get(decision.ownerId) ?? 'Unknown')}
|
|
261
|
+
</span>
|
|
262
|
+
</div>
|
|
263
|
+
</li>
|
|
264
|
+
))}
|
|
265
|
+
</ul>
|
|
266
|
+
</EmptyOr>
|
|
267
|
+
</section>
|
|
268
|
+
)
|
|
269
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/** Small conversions the detail pages share, kept out of their markup. */
|
|
2
|
+
|
|
3
|
+
/** `decision_maker` reads as `decision maker` in a label. The stored value never changes. */
|
|
4
|
+
export function labelize(value: string): string {
|
|
5
|
+
return value.replace(/_/gu, ' ')
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
/** A fixed value set as `InlineEdit` select options. */
|
|
9
|
+
export function toOptions(
|
|
10
|
+
values: readonly string[],
|
|
11
|
+
): readonly { readonly value: string; readonly label: string }[] {
|
|
12
|
+
return values.map((value) => ({ value, label: labelize(value) }))
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/** The comma-separated tag box, back into the array the API takes. */
|
|
16
|
+
export function toTags(value: string): readonly string[] {
|
|
17
|
+
return value
|
|
18
|
+
.split(',')
|
|
19
|
+
.map((tag) => tag.trim())
|
|
20
|
+
.filter((tag) => tag.length > 0)
|
|
21
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import type { Form } from '@kelpie/schemas'
|
|
2
|
+
|
|
3
|
+
import { useFormEmbed } from '../../api/resources/forms.ts'
|
|
4
|
+
import { CopyButton } from '../../components/CopyButton.tsx'
|
|
5
|
+
import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
|
|
6
|
+
import { SectionHeader } from '../../components/SectionHeader.tsx'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* What to paste into a website.
|
|
10
|
+
*
|
|
11
|
+
* The URL and both snippets come from the API rather than being built here. The
|
|
12
|
+
* embed page is served by the service, so its address depends on where the
|
|
13
|
+
* service is reached, which the server knows from the request and the browser
|
|
14
|
+
* only happens to share while the two are same-origin.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
export interface EmbedPanelProps {
|
|
18
|
+
readonly form: Form
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function EmbedPanel({ form }: EmbedPanelProps): React.JSX.Element {
|
|
22
|
+
const { snippets, isLoading, error } = useFormEmbed(form.id)
|
|
23
|
+
|
|
24
|
+
if (error !== null) {
|
|
25
|
+
return <ErrorPanel error={error} />
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (isLoading || snippets === undefined) {
|
|
29
|
+
return <LoadingPanel label="Loading embed details…" />
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div className="max-w-2xl space-y-5">
|
|
34
|
+
<SectionHeader
|
|
35
|
+
title="Embed"
|
|
36
|
+
description="The page below is served by Kelpie, so a site embedding it loads nothing else."
|
|
37
|
+
/>
|
|
38
|
+
|
|
39
|
+
<div>
|
|
40
|
+
<span className="mb-1.5 block text-[12px] font-medium text-ink">Hosted page</span>
|
|
41
|
+
<div className="flex flex-wrap items-center gap-2">
|
|
42
|
+
<code className="flex-1 overflow-x-auto rounded-md border border-border bg-surface-raised px-3 py-2 font-mono text-[12px] text-ink">
|
|
43
|
+
{snippets.url}
|
|
44
|
+
</code>
|
|
45
|
+
<a
|
|
46
|
+
href={snippets.url}
|
|
47
|
+
target="_blank"
|
|
48
|
+
rel="noreferrer"
|
|
49
|
+
className="rounded-md bg-accent px-3 py-2 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover"
|
|
50
|
+
>
|
|
51
|
+
Open
|
|
52
|
+
</a>
|
|
53
|
+
</div>
|
|
54
|
+
</div>
|
|
55
|
+
|
|
56
|
+
<Snippet
|
|
57
|
+
label="iframe"
|
|
58
|
+
hint="One tag, no JavaScript, fixed height."
|
|
59
|
+
value={snippets.iframeSnippet}
|
|
60
|
+
/>
|
|
61
|
+
<Snippet
|
|
62
|
+
label="iframe with auto-resize"
|
|
63
|
+
hint="Adds a listener that follows the page as fields appear and as the thank-you replaces the form."
|
|
64
|
+
value={snippets.scriptSnippet}
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function Snippet({
|
|
71
|
+
label,
|
|
72
|
+
hint,
|
|
73
|
+
value,
|
|
74
|
+
}: {
|
|
75
|
+
readonly label: string
|
|
76
|
+
readonly hint: string
|
|
77
|
+
readonly value: string
|
|
78
|
+
}): React.JSX.Element {
|
|
79
|
+
return (
|
|
80
|
+
<div>
|
|
81
|
+
<div className="mb-1.5 flex items-center justify-between gap-2">
|
|
82
|
+
<span className="text-[12px] font-medium text-ink">{label}</span>
|
|
83
|
+
<CopyButton value={value} label={`Copy the ${label} snippet`} />
|
|
84
|
+
</div>
|
|
85
|
+
<textarea
|
|
86
|
+
readOnly
|
|
87
|
+
value={value}
|
|
88
|
+
rows={value.split('\n').length + 1}
|
|
89
|
+
aria-label={`${label} snippet`}
|
|
90
|
+
className="w-full resize-y rounded-md border border-border bg-surface-raised px-3 py-2 font-mono text-[11px] text-ink outline-none"
|
|
91
|
+
/>
|
|
92
|
+
<p className="mt-1 text-[11px] text-ink-faint">{hint}</p>
|
|
93
|
+
</div>
|
|
94
|
+
)
|
|
95
|
+
}
|