@kelpie/ui 0.7.0 → 0.9.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/dist/api/resource.d.ts +59 -6
- package/dist/api/resource.d.ts.map +1 -1
- package/dist/api/resource.js +106 -24
- package/dist/api/resource.js.map +1 -1
- package/dist/api/resources/companies.d.ts +2 -0
- package/dist/api/resources/companies.d.ts.map +1 -1
- package/dist/api/resources/companies.js +5 -1
- package/dist/api/resources/companies.js.map +1 -1
- package/dist/api/resources/consentPurposes.d.ts +13 -0
- package/dist/api/resources/consentPurposes.d.ts.map +1 -0
- package/dist/api/resources/consentPurposes.js +39 -0
- package/dist/api/resources/consentPurposes.js.map +1 -0
- package/dist/api/resources/customFields.d.ts +15 -0
- package/dist/api/resources/customFields.d.ts.map +1 -0
- package/dist/api/resources/customFields.js +41 -0
- package/dist/api/resources/customFields.js.map +1 -0
- package/dist/api/resources/decisions.d.ts +2 -0
- package/dist/api/resources/decisions.d.ts.map +1 -1
- package/dist/api/resources/decisions.js +1 -0
- package/dist/api/resources/decisions.js.map +1 -1
- package/dist/api/resources/emailDomainLinker.d.ts +16 -0
- package/dist/api/resources/emailDomainLinker.d.ts.map +1 -0
- package/dist/api/resources/emailDomainLinker.js +16 -0
- package/dist/api/resources/emailDomainLinker.js.map +1 -0
- package/dist/api/resources/enquiries.d.ts +39 -0
- package/dist/api/resources/enquiries.d.ts.map +1 -0
- package/dist/api/resources/enquiries.js +68 -0
- package/dist/api/resources/enquiries.js.map +1 -0
- package/dist/api/resources/forms.d.ts +21 -1
- package/dist/api/resources/forms.d.ts.map +1 -1
- package/dist/api/resources/forms.js +44 -17
- package/dist/api/resources/forms.js.map +1 -1
- package/dist/api/resources/handbookPages.d.ts +1 -1
- package/dist/api/resources/handbookPages.js +1 -1
- package/dist/api/resources/importJobs.d.ts +5 -0
- package/dist/api/resources/importJobs.d.ts.map +1 -1
- package/dist/api/resources/importJobs.js +3 -0
- package/dist/api/resources/importJobs.js.map +1 -1
- package/dist/api/resources/listMembers.d.ts +27 -0
- package/dist/api/resources/listMembers.d.ts.map +1 -0
- package/dist/api/resources/listMembers.js +108 -0
- package/dist/api/resources/listMembers.js.map +1 -0
- package/dist/api/resources/lists.d.ts +14 -0
- package/dist/api/resources/lists.d.ts.map +1 -0
- package/dist/api/resources/lists.js +34 -0
- package/dist/api/resources/lists.js.map +1 -0
- package/dist/api/resources/opportunities.d.ts +2 -0
- package/dist/api/resources/opportunities.d.ts.map +1 -1
- package/dist/api/resources/opportunities.js +1 -0
- package/dist/api/resources/opportunities.js.map +1 -1
- package/dist/api/resources/people.d.ts.map +1 -1
- package/dist/api/resources/people.js +4 -1
- package/dist/api/resources/people.js.map +1 -1
- package/dist/api/resources/roles.d.ts +2 -0
- package/dist/api/resources/roles.d.ts.map +1 -1
- package/dist/api/resources/roles.js +1 -1
- package/dist/api/resources/roles.js.map +1 -1
- package/dist/api/resources/sampleData.d.ts +17 -0
- package/dist/api/resources/sampleData.d.ts.map +1 -0
- package/dist/api/resources/sampleData.js +31 -0
- package/dist/api/resources/sampleData.js.map +1 -0
- package/dist/api/resources/webhooks.d.ts.map +1 -1
- package/dist/api/resources/webhooks.js +7 -22
- package/dist/api/resources/webhooks.js.map +1 -1
- package/dist/app/KelpieApp.d.ts.map +1 -1
- package/dist/app/KelpieApp.js +9 -1
- package/dist/app/KelpieApp.js.map +1 -1
- package/dist/components/ActivitiesPanel.d.ts.map +1 -1
- package/dist/components/ActivitiesPanel.js +3 -1
- package/dist/components/ActivitiesPanel.js.map +1 -1
- package/dist/components/ColumnPicker.d.ts +24 -0
- package/dist/components/ColumnPicker.d.ts.map +1 -0
- package/dist/components/ColumnPicker.js +56 -0
- package/dist/components/ColumnPicker.js.map +1 -0
- package/dist/components/CustomFieldsPanel.d.ts +23 -0
- package/dist/components/CustomFieldsPanel.d.ts.map +1 -0
- package/dist/components/CustomFieldsPanel.js +116 -0
- package/dist/components/CustomFieldsPanel.js.map +1 -0
- package/dist/components/DataTable.d.ts +16 -1
- package/dist/components/DataTable.d.ts.map +1 -1
- package/dist/components/DataTable.js +51 -10
- package/dist/components/DataTable.js.map +1 -1
- package/dist/components/DecisionsPanel.d.ts.map +1 -1
- package/dist/components/DecisionsPanel.js +4 -3
- package/dist/components/DecisionsPanel.js.map +1 -1
- package/dist/components/EntitySearch.d.ts.map +1 -1
- package/dist/components/EntitySearch.js +11 -5
- package/dist/components/EntitySearch.js.map +1 -1
- package/dist/components/FormsPanel.d.ts +18 -0
- package/dist/components/FormsPanel.d.ts.map +1 -0
- package/dist/components/FormsPanel.js +37 -0
- package/dist/components/FormsPanel.js.map +1 -0
- package/dist/components/ListsPanel.d.ts +14 -0
- package/dist/components/ListsPanel.d.ts.map +1 -0
- package/dist/components/ListsPanel.js +56 -0
- package/dist/components/ListsPanel.js.map +1 -0
- package/dist/components/NotesPanel.d.ts.map +1 -1
- package/dist/components/NotesPanel.js +6 -5
- package/dist/components/NotesPanel.js.map +1 -1
- package/dist/components/Paginator.d.ts +26 -0
- package/dist/components/Paginator.d.ts.map +1 -0
- package/dist/components/Paginator.js +16 -0
- package/dist/components/Paginator.js.map +1 -0
- package/dist/components/PlanAttention.d.ts +3 -2
- package/dist/components/PlanAttention.d.ts.map +1 -1
- package/dist/components/PlanAttention.js +7 -3
- package/dist/components/PlanAttention.js.map +1 -1
- package/dist/components/PlanPanel.d.ts.map +1 -1
- package/dist/components/PlanPanel.js +2 -1
- package/dist/components/PlanPanel.js.map +1 -1
- package/dist/components/Shell.d.ts.map +1 -1
- package/dist/components/Shell.js +4 -0
- package/dist/components/Shell.js.map +1 -1
- package/dist/components/useHasCustomFields.d.ts +13 -0
- package/dist/components/useHasCustomFields.d.ts.map +1 -0
- package/dist/components/useHasCustomFields.js +16 -0
- package/dist/components/useHasCustomFields.js.map +1 -0
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/listView.d.ts +15 -0
- package/dist/lib/listView.d.ts.map +1 -0
- package/dist/lib/listView.js +66 -0
- package/dist/lib/listView.js.map +1 -0
- package/dist/lib/sort.d.ts +43 -0
- package/dist/lib/sort.d.ts.map +1 -0
- package/dist/lib/sort.js +102 -0
- package/dist/lib/sort.js.map +1 -0
- package/dist/pages/CompaniesPage.d.ts.map +1 -1
- package/dist/pages/CompaniesPage.js +88 -3
- package/dist/pages/CompaniesPage.js.map +1 -1
- package/dist/pages/CompanyDetail.d.ts.map +1 -1
- package/dist/pages/CompanyDetail.js +40 -15
- package/dist/pages/CompanyDetail.js.map +1 -1
- package/dist/pages/DealDetail.d.ts.map +1 -1
- package/dist/pages/DealDetail.js +20 -1
- package/dist/pages/DealDetail.js.map +1 -1
- package/dist/pages/DealsPage.d.ts.map +1 -1
- package/dist/pages/DealsPage.js +134 -14
- package/dist/pages/DealsPage.js.map +1 -1
- package/dist/pages/DecisionsPage.d.ts.map +1 -1
- package/dist/pages/DecisionsPage.js +52 -8
- package/dist/pages/DecisionsPage.js.map +1 -1
- package/dist/pages/EnquiriesPage.d.ts +2 -0
- package/dist/pages/EnquiriesPage.d.ts.map +1 -0
- package/dist/pages/EnquiriesPage.js +251 -0
- package/dist/pages/EnquiriesPage.js.map +1 -0
- package/dist/pages/EnquiryDetail.d.ts +2 -0
- package/dist/pages/EnquiryDetail.d.ts.map +1 -0
- package/dist/pages/EnquiryDetail.js +207 -0
- package/dist/pages/EnquiryDetail.js.map +1 -0
- package/dist/pages/EnquiryStageSettingsPage.d.ts +3 -0
- package/dist/pages/EnquiryStageSettingsPage.d.ts.map +1 -0
- package/dist/pages/EnquiryStageSettingsPage.js +34 -0
- package/dist/pages/EnquiryStageSettingsPage.js.map +1 -0
- package/dist/pages/FormDetail.d.ts.map +1 -1
- package/dist/pages/FormDetail.js +19 -1
- package/dist/pages/FormDetail.js.map +1 -1
- package/dist/pages/FormsPage.d.ts.map +1 -1
- package/dist/pages/FormsPage.js +53 -2
- package/dist/pages/FormsPage.js.map +1 -1
- package/dist/pages/FundraisingPage.d.ts.map +1 -1
- package/dist/pages/FundraisingPage.js +116 -14
- package/dist/pages/FundraisingPage.js.map +1 -1
- package/dist/pages/HiringPage.d.ts.map +1 -1
- package/dist/pages/HiringPage.js +27 -4
- package/dist/pages/HiringPage.js.map +1 -1
- package/dist/pages/ListDetail.d.ts +11 -0
- package/dist/pages/ListDetail.d.ts.map +1 -0
- package/dist/pages/ListDetail.js +214 -0
- package/dist/pages/ListDetail.js.map +1 -0
- package/dist/pages/ListsPage.d.ts +9 -0
- package/dist/pages/ListsPage.d.ts.map +1 -0
- package/dist/pages/ListsPage.js +125 -0
- package/dist/pages/ListsPage.js.map +1 -0
- package/dist/pages/OpportunitiesPage.d.ts.map +1 -1
- package/dist/pages/OpportunitiesPage.js +97 -14
- package/dist/pages/OpportunitiesPage.js.map +1 -1
- package/dist/pages/OpportunityDetail.d.ts.map +1 -1
- package/dist/pages/OpportunityDetail.js +64 -3
- package/dist/pages/OpportunityDetail.js.map +1 -1
- package/dist/pages/PartnershipDetail.d.ts.map +1 -1
- package/dist/pages/PartnershipDetail.js +19 -1
- package/dist/pages/PartnershipDetail.js.map +1 -1
- package/dist/pages/PartnershipsPage.d.ts.map +1 -1
- package/dist/pages/PartnershipsPage.js +111 -14
- package/dist/pages/PartnershipsPage.js.map +1 -1
- package/dist/pages/PeoplePage.d.ts.map +1 -1
- package/dist/pages/PeoplePage.js +119 -3
- package/dist/pages/PeoplePage.js.map +1 -1
- package/dist/pages/PersonDetail.d.ts.map +1 -1
- package/dist/pages/PersonDetail.js +67 -5
- package/dist/pages/PersonDetail.js.map +1 -1
- package/dist/pages/PlanningPage.d.ts.map +1 -1
- package/dist/pages/PlanningPage.js +88 -17
- package/dist/pages/PlanningPage.js.map +1 -1
- package/dist/pages/RaiseDetail.d.ts.map +1 -1
- package/dist/pages/RaiseDetail.js +13 -1
- package/dist/pages/RaiseDetail.js.map +1 -1
- package/dist/pages/RoleDetail.d.ts.map +1 -1
- package/dist/pages/RoleDetail.js +5 -4
- package/dist/pages/RoleDetail.js.map +1 -1
- package/dist/pages/SearchPage.d.ts.map +1 -1
- package/dist/pages/SearchPage.js +1 -0
- package/dist/pages/SearchPage.js.map +1 -1
- package/dist/pages/admin/DataPage.d.ts.map +1 -1
- package/dist/pages/admin/DataPage.js +126 -13
- package/dist/pages/admin/DataPage.js.map +1 -1
- package/dist/pages/admin/FieldsPage.d.ts +2 -0
- package/dist/pages/admin/FieldsPage.d.ts.map +1 -0
- package/dist/pages/admin/FieldsPage.js +164 -0
- package/dist/pages/admin/FieldsPage.js.map +1 -0
- package/dist/pages/admin/PrivacyPage.d.ts +9 -0
- package/dist/pages/admin/PrivacyPage.d.ts.map +1 -0
- package/dist/pages/admin/PrivacyPage.js +170 -0
- package/dist/pages/admin/PrivacyPage.js.map +1 -0
- package/dist/pages/admin/WebhookDeliveries.d.ts.map +1 -1
- package/dist/pages/admin/WebhookDeliveries.js +3 -2
- package/dist/pages/admin/WebhookDeliveries.js.map +1 -1
- package/dist/pages/admin/WebhooksPage.d.ts.map +1 -1
- package/dist/pages/admin/WebhooksPage.js +3 -2
- package/dist/pages/admin/WebhooksPage.js.map +1 -1
- package/dist/pages/admin/WorkspaceSettingsPage.d.ts.map +1 -1
- package/dist/pages/admin/WorkspaceSettingsPage.js +45 -2
- package/dist/pages/admin/WorkspaceSettingsPage.js.map +1 -1
- package/dist/pages/dashboard/attention.d.ts.map +1 -1
- package/dist/pages/dashboard/attention.js +3 -0
- package/dist/pages/dashboard/attention.js.map +1 -1
- package/dist/pages/forms/AddFieldMenu.d.ts +17 -0
- package/dist/pages/forms/AddFieldMenu.d.ts.map +1 -0
- package/dist/pages/forms/AddFieldMenu.js +43 -0
- package/dist/pages/forms/AddFieldMenu.js.map +1 -0
- package/dist/pages/forms/EmbedPanel.d.ts +4 -0
- package/dist/pages/forms/EmbedPanel.d.ts.map +1 -1
- package/dist/pages/forms/EmbedPanel.js +62 -3
- package/dist/pages/forms/EmbedPanel.js.map +1 -1
- package/dist/pages/forms/FieldsEditor.d.ts.map +1 -1
- package/dist/pages/forms/FieldsEditor.js +179 -36
- package/dist/pages/forms/FieldsEditor.js.map +1 -1
- package/dist/pages/forms/FormActions.d.ts +6 -0
- package/dist/pages/forms/FormActions.d.ts.map +1 -0
- package/dist/pages/forms/FormActions.js +149 -0
- package/dist/pages/forms/FormActions.js.map +1 -0
- package/dist/pages/forms/FormSettings.d.ts.map +1 -1
- package/dist/pages/forms/FormSettings.js +15 -19
- package/dist/pages/forms/FormSettings.js.map +1 -1
- package/dist/pages/forms/SubmissionDetail.d.ts +2 -0
- package/dist/pages/forms/SubmissionDetail.d.ts.map +1 -0
- package/dist/pages/forms/SubmissionDetail.js +76 -0
- package/dist/pages/forms/SubmissionDetail.js.map +1 -0
- package/dist/pages/forms/SubmissionsTable.d.ts.map +1 -1
- package/dist/pages/forms/SubmissionsTable.js +57 -8
- package/dist/pages/forms/SubmissionsTable.js.map +1 -1
- package/dist/pages/forms/fieldList.d.ts +11 -5
- package/dist/pages/forms/fieldList.d.ts.map +1 -1
- package/dist/pages/forms/fieldList.js +66 -6
- package/dist/pages/forms/fieldList.js.map +1 -1
- package/dist/pages/forms/template.d.ts +17 -0
- package/dist/pages/forms/template.d.ts.map +1 -1
- package/dist/pages/forms/template.js +93 -0
- package/dist/pages/forms/template.js.map +1 -1
- package/dist/pages/handbook/HandbookPage.js +1 -1
- package/dist/pages/hiringDirectory.js +2 -2
- package/dist/pages/onboarding/WorkspaceStepPage.d.ts.map +1 -1
- package/dist/pages/onboarding/WorkspaceStepPage.js +15 -2
- package/dist/pages/onboarding/WorkspaceStepPage.js.map +1 -1
- package/dist/pages/positionDirectory.js +2 -2
- package/package.json +2 -2
- package/src/api/resource.ts +155 -32
- package/src/api/resources/companies.ts +7 -1
- package/src/api/resources/consentPurposes.ts +83 -0
- package/src/api/resources/customFields.ts +88 -0
- package/src/api/resources/decisions.ts +3 -0
- package/src/api/resources/emailDomainLinker.ts +43 -0
- package/src/api/resources/enquiries.ts +118 -0
- package/src/api/resources/forms.ts +59 -19
- package/src/api/resources/handbookPages.ts +1 -1
- package/src/api/resources/importJobs.ts +9 -0
- package/src/api/resources/listMembers.ts +173 -0
- package/src/api/resources/lists.ts +61 -0
- package/src/api/resources/opportunities.ts +3 -0
- package/src/api/resources/people.ts +4 -1
- package/src/api/resources/roles.ts +3 -1
- package/src/api/resources/sampleData.ts +57 -0
- package/src/api/resources/webhooks.ts +8 -24
- package/src/app/KelpieApp.tsx +16 -0
- package/src/components/ActivitiesPanel.tsx +3 -10
- package/src/components/ColumnPicker.tsx +124 -0
- package/src/components/CustomFieldsPanel.tsx +330 -0
- package/src/components/DataTable.tsx +89 -10
- package/src/components/DecisionsPanel.tsx +4 -12
- package/src/components/EntitySearch.tsx +12 -5
- package/src/components/FormsPanel.tsx +86 -0
- package/src/components/ListsPanel.tsx +176 -0
- package/src/components/NotesPanel.tsx +6 -14
- package/src/components/Paginator.tsx +78 -0
- package/src/components/PlanAttention.tsx +20 -3
- package/src/components/PlanPanel.tsx +2 -10
- package/src/components/Shell.tsx +4 -0
- package/src/components/useHasCustomFields.ts +18 -0
- package/src/index.ts +10 -1
- package/src/lib/listView.ts +149 -0
- package/src/lib/sort.ts +143 -0
- package/src/pages/CompaniesPage.tsx +125 -11
- package/src/pages/CompanyDetail.tsx +98 -63
- package/src/pages/DealDetail.tsx +34 -0
- package/src/pages/DealsPage.tsx +178 -24
- package/src/pages/DecisionsPage.tsx +75 -18
- package/src/pages/EnquiriesPage.tsx +434 -0
- package/src/pages/EnquiryDetail.tsx +554 -0
- package/src/pages/EnquiryStageSettingsPage.tsx +63 -0
- package/src/pages/FormDetail.tsx +23 -1
- package/src/pages/FormsPage.tsx +81 -17
- package/src/pages/FundraisingPage.tsx +152 -24
- package/src/pages/HiringPage.tsx +39 -11
- package/src/pages/ListDetail.tsx +470 -0
- package/src/pages/ListsPage.tsx +281 -0
- package/src/pages/OpportunitiesPage.tsx +130 -24
- package/src/pages/OpportunityDetail.tsx +168 -2
- package/src/pages/PartnershipDetail.tsx +35 -0
- package/src/pages/PartnershipsPage.tsx +149 -24
- package/src/pages/PeoplePage.tsx +157 -11
- package/src/pages/PersonDetail.tsx +157 -6
- package/src/pages/PlanningPage.tsx +259 -29
- package/src/pages/RaiseDetail.tsx +24 -0
- package/src/pages/RoleDetail.tsx +21 -26
- package/src/pages/SearchPage.tsx +1 -0
- package/src/pages/admin/DataPage.tsx +324 -13
- package/src/pages/admin/FieldsPage.tsx +455 -0
- package/src/pages/admin/PrivacyPage.tsx +461 -0
- package/src/pages/admin/WebhookDeliveries.tsx +10 -15
- package/src/pages/admin/WebhooksPage.tsx +14 -19
- package/src/pages/admin/WorkspaceSettingsPage.tsx +134 -2
- package/src/pages/dashboard/attention.ts +3 -0
- package/src/pages/forms/AddFieldMenu.tsx +121 -0
- package/src/pages/forms/EmbedPanel.tsx +163 -2
- package/src/pages/forms/FieldsEditor.tsx +539 -165
- package/src/pages/forms/FormActions.tsx +552 -0
- package/src/pages/forms/FormSettings.tsx +29 -70
- package/src/pages/forms/SubmissionDetail.tsx +249 -0
- package/src/pages/forms/SubmissionsTable.tsx +112 -26
- package/src/pages/forms/fieldList.ts +68 -5
- package/src/pages/forms/template.ts +103 -0
- package/src/pages/handbook/HandbookPage.tsx +1 -1
- package/src/pages/hiringDirectory.ts +2 -2
- package/src/pages/onboarding/WorkspaceStepPage.tsx +31 -3
- package/src/pages/positionDirectory.ts +2 -2
- package/src/styles.css +3 -3
|
@@ -31,4 +31,97 @@ export const NEW_SELECT_OPTIONS = [
|
|
|
31
31
|
{ key: 'option_a', value: 'Option A', valueType: 'string' },
|
|
32
32
|
{ key: 'option_b', value: 'Option B', valueType: 'string' },
|
|
33
33
|
];
|
|
34
|
+
/**
|
|
35
|
+
* One ready-made field per CRM mapping target, in the target enum's order.
|
|
36
|
+
*
|
|
37
|
+
* "Add field" offers these so adding the company field is one click, not
|
|
38
|
+
* add-then-configure. Only one field may carry a CRM target, so the menu shows
|
|
39
|
+
* each preset only while its target is free — `unusedCrmPresets` in
|
|
40
|
+
* `fieldList.ts` does that filtering.
|
|
41
|
+
*/
|
|
42
|
+
export const CRM_FIELD_PRESETS = [
|
|
43
|
+
{ label: 'Name', type: 'text', required: false, mapTo: 'person.name', placeholder: 'Your name' },
|
|
44
|
+
// The other way to ask for a name. A form takes one box or this pair; the
|
|
45
|
+
// menu hides whichever is already mapped, so both are offered and neither
|
|
46
|
+
// ends up used twice.
|
|
47
|
+
{
|
|
48
|
+
label: 'First name',
|
|
49
|
+
type: 'text',
|
|
50
|
+
required: false,
|
|
51
|
+
mapTo: 'person.first_name',
|
|
52
|
+
placeholder: 'First name',
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
label: 'Last name',
|
|
56
|
+
type: 'text',
|
|
57
|
+
required: false,
|
|
58
|
+
mapTo: 'person.last_name',
|
|
59
|
+
placeholder: 'Last name',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
label: 'Email',
|
|
63
|
+
type: 'email',
|
|
64
|
+
required: true,
|
|
65
|
+
mapTo: 'person.email',
|
|
66
|
+
placeholder: 'you@company.com',
|
|
67
|
+
},
|
|
68
|
+
{ label: 'Company', type: 'text', required: false, mapTo: 'company.name', placeholder: 'Company name' },
|
|
69
|
+
{
|
|
70
|
+
label: 'Company website',
|
|
71
|
+
type: 'text',
|
|
72
|
+
required: false,
|
|
73
|
+
mapTo: 'company.domain',
|
|
74
|
+
placeholder: 'company.com',
|
|
75
|
+
},
|
|
76
|
+
{ label: 'Job title', type: 'text', required: false, mapTo: 'position.title', placeholder: 'Your role' },
|
|
77
|
+
{ label: 'Enquiry name', type: 'text', required: false, mapTo: 'enquiry.name', placeholder: null },
|
|
78
|
+
{ label: 'Deal name', type: 'text', required: false, mapTo: 'deal.name', placeholder: null },
|
|
79
|
+
{ label: 'Opportunity name', type: 'text', required: false, mapTo: 'opportunity.name', placeholder: null },
|
|
80
|
+
{ label: 'Partnership name', type: 'text', required: false, mapTo: 'partnership.name', placeholder: null },
|
|
81
|
+
];
|
|
82
|
+
/** The submission-only fields "Add field" always offers; they may repeat freely. */
|
|
83
|
+
export const SUBMISSION_FIELD_PRESETS = [
|
|
84
|
+
{ menuLabel: 'Text', field: NEW_FIELD },
|
|
85
|
+
{
|
|
86
|
+
menuLabel: 'Text area',
|
|
87
|
+
field: { label: 'Message', type: 'textarea', required: false, mapTo: 'submission', placeholder: null },
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
menuLabel: 'Select',
|
|
91
|
+
field: {
|
|
92
|
+
label: 'New select',
|
|
93
|
+
type: 'select',
|
|
94
|
+
required: false,
|
|
95
|
+
mapTo: 'submission',
|
|
96
|
+
placeholder: null,
|
|
97
|
+
options: NEW_SELECT_OPTIONS,
|
|
98
|
+
},
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
menuLabel: 'Consent',
|
|
102
|
+
field: {
|
|
103
|
+
label: 'Consent',
|
|
104
|
+
type: 'consent',
|
|
105
|
+
required: false,
|
|
106
|
+
mapTo: 'person.consent',
|
|
107
|
+
placeholder: null,
|
|
108
|
+
statement: 'Please tell us how we can contact you.',
|
|
109
|
+
consentPurposeIds: [],
|
|
110
|
+
consentPurposeLabels: {},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
menuLabel: 'Notice',
|
|
115
|
+
field: {
|
|
116
|
+
label: 'Privacy notice',
|
|
117
|
+
type: 'notice',
|
|
118
|
+
required: false,
|
|
119
|
+
mapTo: 'person.consent',
|
|
120
|
+
placeholder: null,
|
|
121
|
+
statement: 'By submitting this form you agree to us storing your information and using it to contact you about your enquiry.',
|
|
122
|
+
consentPurposeIds: [],
|
|
123
|
+
consentPurposeLabels: {},
|
|
124
|
+
},
|
|
125
|
+
},
|
|
126
|
+
];
|
|
34
127
|
//# sourceMappingURL=template.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/pages/forms/template.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAA8B;IAC5D,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,WAAW,EAAE;IAC/F;QACE,KAAK,EAAE,OAAO;QACd,IAAI,EAAE,OAAO;QACb,QAAQ,EAAE,IAAI;QACd,KAAK,EAAE,cAAc;QACrB,WAAW,EAAE,iBAAiB;KAC/B;IACD,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE;IACtF,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,gBAAgB,EAAE,WAAW,EAAE,WAAW,EAAE;IACvF,EAAE,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE;CAC7F,CAAA;AAED,kGAAkG;AAClG,MAAM,CAAC,MAAM,SAAS,GAAmB;IACvC,KAAK,EAAE,WAAW;IAClB,IAAI,EAAE,MAAM;IACZ,QAAQ,EAAE,KAAK;IACf,KAAK,EAAE,YAAY;IACnB,WAAW,EAAE,IAAI;CAClB,CAAA;AAED,+EAA+E;AAC/E,MAAM,CAAC,MAAM,kBAAkB,GAAG;IAChC,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,QAAiB,EAAE;IACpE,EAAE,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,QAAiB,EAAE;CACrE,CAAA"}
|
|
1
|
+
{"version":3,"file":"template.js","sourceRoot":"","sources":["../../../src/pages/forms/template.ts"],"names":[],"mappings":"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"}
|
|
@@ -129,7 +129,7 @@ export function HandbookLayout() {
|
|
|
129
129
|
void addPage(item.id);
|
|
130
130
|
}, onDelete: () => {
|
|
131
131
|
void removePage(item.page);
|
|
132
|
-
} }, item.id))) }) }), _jsx(DragOverlay, { dropAnimation: null, children: dragging === undefined ? null : (_jsx("div", { className: "rounded-md border border-accent bg-surface-raised px-2.5 py-1.5 text-[13px] font-medium text-ink", style: { marginLeft: (liveDepth ?? dragging.depth) * INDENT }, children: dragging.page.title })) })] }), flat.length === 0 && (_jsx("p", { className: "px-2 py-6 text-center text-[12px] text-ink-faint", children: "No pages yet." })), pages.
|
|
132
|
+
} }, item.id))) }) }), _jsx(DragOverlay, { dropAnimation: null, children: dragging === undefined ? null : (_jsx("div", { className: "rounded-md border border-accent bg-surface-raised px-2.5 py-1.5 text-[13px] font-medium text-ink", style: { marginLeft: (liveDepth ?? dragging.depth) * INDENT }, children: dragging.page.title })) })] }), flat.length === 0 && (_jsx("p", { className: "px-2 py-6 text-center text-[12px] text-ink-faint", children: "No pages yet." })), pages.hasNext && (_jsx("p", { className: "px-2 py-3 text-center text-[11px] text-ink-faint", children: "This handbook has more pages than one request returns, so the tree below is incomplete." }))] })] }), _jsx("div", { className: "min-w-0 flex-1", children: active === undefined ? (_jsx("div", { className: "flex h-full items-center justify-center text-[13px] text-ink-faint", children: "No handbook pages yet." })) : (_jsx(HandbookEditor, { page: active, authorName: active.updatedBy === null ? undefined : members.nameById.get(active.updatedBy), isSaving: updatePage.isPending, error: updatePage.error ?? deletePage.error, onSave: (changes) => {
|
|
133
133
|
updatePage.run({ id: active.id, changes });
|
|
134
134
|
}, onAddChild: () => {
|
|
135
135
|
void addPage(active.id);
|
|
@@ -25,7 +25,7 @@ export function useRoleCandidateCounts(roleIds) {
|
|
|
25
25
|
return {
|
|
26
26
|
countFor: (roleId) => countByRole.get(roleId) ?? 0,
|
|
27
27
|
isLoading: candidates.isLoading,
|
|
28
|
-
isComplete: !candidates.
|
|
28
|
+
isComplete: !candidates.hasNext,
|
|
29
29
|
};
|
|
30
30
|
}
|
|
31
31
|
/**
|
|
@@ -51,7 +51,7 @@ export function useCandidateNotes(candidateIds) {
|
|
|
51
51
|
return {
|
|
52
52
|
noteFor: (candidateId) => newestByCandidate.get(candidateId),
|
|
53
53
|
isLoading: notes.isLoading,
|
|
54
|
-
isComplete: !notes.
|
|
54
|
+
isComplete: !notes.hasNext,
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
57
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceStepPage.d.ts","sourceRoot":"","sources":["../../../src/pages/onboarding/WorkspaceStepPage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"WorkspaceStepPage.d.ts","sourceRoot":"","sources":["../../../src/pages/onboarding/WorkspaceStepPage.tsx"],"names":[],"mappings":"AA+CA,wBAAgB,iBAAiB,IAAI,KAAK,CAAC,GAAG,CAAC,OAAO,CAsGrD"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { useState } from 'react';
|
|
3
3
|
import { Link, Navigate, useNavigate } from 'react-router';
|
|
4
|
+
import { useInstallSampleData } from '../../api/resources/sampleData.js';
|
|
4
5
|
import { useCreateWorkspace, useSession } from '../../api/resources/session.js';
|
|
5
6
|
import { ErrorPanel } from '../../components/QueryState.js';
|
|
6
7
|
import { SubmitButton, TextField } from '../auth/AuthForm.js';
|
|
@@ -43,10 +44,12 @@ export function WorkspaceStepPage() {
|
|
|
43
44
|
const navigate = useNavigate();
|
|
44
45
|
const { isSignedOut } = useSession();
|
|
45
46
|
const createWorkspace = useCreateWorkspace();
|
|
47
|
+
const installSampleData = useInstallSampleData();
|
|
46
48
|
const [name, setName] = useState('');
|
|
47
49
|
const [slug, setSlug] = useState('');
|
|
48
50
|
const [slugEdited, setSlugEdited] = useState(false);
|
|
49
51
|
const [timezone] = useState(browserTimezone);
|
|
52
|
+
const [seedSample, setSeedSample] = useState(false);
|
|
50
53
|
function changeName(value) {
|
|
51
54
|
setName(value);
|
|
52
55
|
if (!slugEdited) {
|
|
@@ -61,12 +64,22 @@ export function WorkspaceStepPage() {
|
|
|
61
64
|
event.preventDefault();
|
|
62
65
|
createWorkspace
|
|
63
66
|
.runAsync({ name: name.trim(), slug: slug.trim(), timezone })
|
|
64
|
-
.then(() =>
|
|
67
|
+
.then(async (workspace) => {
|
|
68
|
+
if (seedSample) {
|
|
69
|
+
// A refusal here does not block the wizard: the workspace itself is
|
|
70
|
+
// already created, and the invites step is what comes next either
|
|
71
|
+
// way. The error stays on screen so the reader sees what failed.
|
|
72
|
+
await installSampleData
|
|
73
|
+
.runAsync({ workspaceId: workspace.id })
|
|
74
|
+
.catch(() => undefined);
|
|
75
|
+
}
|
|
76
|
+
navigate('/onboarding/invites', { replace: true });
|
|
77
|
+
})
|
|
65
78
|
.catch(() => undefined);
|
|
66
79
|
}
|
|
67
80
|
if (isSignedOut) {
|
|
68
81
|
return _jsx(Navigate, { to: "/login", replace: true });
|
|
69
82
|
}
|
|
70
|
-
return (_jsx(AuthLayout, { step: 1, title: "Create your workspace", description: "A workspace is your company brain \u2014 CRM records, handbook, and team.", footer: _jsx(Link, { to: "/login", className: "font-medium text-accent hover:underline", children: "Sign in as somebody else" }), children: _jsxs("form", { onSubmit: submit, className: "mt-5 space-y-3", children: [_jsx(TextField, { label: "Workspace name", value: name, onChange: changeName, placeholder: "Acme Labs", autoComplete: "organization", required: true }), _jsx(TextField, { label: "Slug", value: slug, onChange: changeSlug, hint: "Lowercase letters, digits, and hyphens. It appears in URLs.", mono: true, required: true }), _jsxs("p", { className: "text-[11px] text-ink-faint", children: ["Timezone: ", timezone, ". Change it later in Admin \u2192 Workspace."] }), createWorkspace.error !== null && _jsx(ErrorPanel, { error: createWorkspace.error }), _jsx(SubmitButton, { label: "Continue", pendingLabel:
|
|
83
|
+
return (_jsx(AuthLayout, { step: 1, title: "Create your workspace", description: "A workspace is your company brain \u2014 CRM records, handbook, and team.", footer: _jsx(Link, { to: "/login", className: "font-medium text-accent hover:underline", children: "Sign in as somebody else" }), children: _jsxs("form", { onSubmit: submit, className: "mt-5 space-y-3", children: [_jsx(TextField, { label: "Workspace name", value: name, onChange: changeName, placeholder: "Acme Labs", autoComplete: "organization", required: true }), _jsx(TextField, { label: "Slug", value: slug, onChange: changeSlug, hint: "Lowercase letters, digits, and hyphens. It appears in URLs.", mono: true, required: true }), _jsxs("p", { className: "text-[11px] text-ink-faint", children: ["Timezone: ", timezone, ". Change it later in Admin \u2192 Workspace."] }), _jsxs("label", { className: "flex items-start gap-2 text-[12px] text-ink", children: [_jsx("input", { type: "checkbox", checked: seedSample, onChange: (event) => setSeedSample(event.target.checked), className: "mt-0.5 h-4 w-4 rounded border-border text-accent focus:ring-accent" }), _jsx("span", { children: "Install sample data \u2014 a small set of companies, people, deals, enquiries, opportunities, fundraising, partnerships, and hiring so the workspace has something to look at. You can delete it later." })] }), createWorkspace.error !== null && _jsx(ErrorPanel, { error: createWorkspace.error }), installSampleData.error !== null && _jsx(ErrorPanel, { error: installSampleData.error }), _jsx(SubmitButton, { label: "Continue", pendingLabel: installSampleData.isPending ? 'Installing sample data…' : 'Creating…', isPending: createWorkspace.isPending || installSampleData.isPending })] }) }));
|
|
71
84
|
}
|
|
72
85
|
//# sourceMappingURL=WorkspaceStepPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WorkspaceStepPage.js","sourceRoot":"","sources":["../../../src/pages/onboarding/WorkspaceStepPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEhC,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAE1D,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAiC,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,qBAAsB,CAAA;AAC9D,OAAO,EAAE,UAAU,EAAE,MAAM,uBAAwB,CAAA;AAEnD;;;;;;;;;;;;;;;GAeG;AAEH,yEAAyE;AACzE,SAAS,OAAO,CAAC,IAAY;IAC3B,OAAO,IAAI;SACR,WAAW,EAAE;SACb,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC;SAC5B,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC;SACxB,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AACjB,CAAC;AAED;;;;;;GAMG;AACH,SAAS,eAAe;IACtB,OAAO,IAAI,CAAC,cAAc,EAAE,CAAC,eAAe,EAAE,CAAC,QAAQ,CAAA;AACzD,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,EAAE,WAAW,EAAE,GAAG,UAAU,EAAE,CAAA;IACpC,MAAM,eAAe,GAAG,kBAAkB,EAAE,CAAA;IAC5C,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACpC,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAA;IACpC,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IACnD,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC,eAAe,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"WorkspaceStepPage.js","sourceRoot":"","sources":["../../../src/pages/onboarding/WorkspaceStepPage.tsx"],"names":[],"mappings":"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"}
|
|
@@ -37,7 +37,7 @@ export function usePeopleDirectory(personIds) {
|
|
|
37
37
|
.map((held) => companyNameById.get(held.companyId))
|
|
38
38
|
.filter((name) => name !== undefined),
|
|
39
39
|
isLoading: positions.isLoading || companies.isLoading,
|
|
40
|
-
isComplete: !positions.
|
|
40
|
+
isComplete: !positions.hasNext && !companies.hasNext,
|
|
41
41
|
};
|
|
42
42
|
}
|
|
43
43
|
export function useCompanyHeadcounts(companyIds) {
|
|
@@ -52,7 +52,7 @@ export function useCompanyHeadcounts(companyIds) {
|
|
|
52
52
|
return {
|
|
53
53
|
countFor: (companyId) => countByCompany.get(companyId) ?? 0,
|
|
54
54
|
isLoading: positions.isLoading,
|
|
55
|
-
isComplete: !positions.
|
|
55
|
+
isComplete: !positions.hasNext,
|
|
56
56
|
};
|
|
57
57
|
}
|
|
58
58
|
//# sourceMappingURL=positionDirectory.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kelpie/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.9.0",
|
|
4
4
|
"description": "React UI for Kelpie: components, pages, API client, and the extension registry an assembly composes modules through.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"kelpie",
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
"@dnd-kit/core": "^6.3.1",
|
|
49
49
|
"@dnd-kit/sortable": "^10.0.0",
|
|
50
50
|
"@dnd-kit/utilities": "^3.2.2",
|
|
51
|
-
"@kelpie/schemas": "^0.
|
|
51
|
+
"@kelpie/schemas": "^0.9.0",
|
|
52
52
|
"@tanstack/react-query": "^5.101.4",
|
|
53
53
|
"react-markdown": "^10.1.0",
|
|
54
54
|
"react-router": "^8.3.0",
|
package/src/api/resource.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
useQueryClient,
|
|
7
7
|
} from '@tanstack/react-query'
|
|
8
8
|
import type { InfiniteData, QueryClient } from '@tanstack/react-query'
|
|
9
|
+
import { useEffect, useState } from 'react'
|
|
9
10
|
|
|
10
11
|
import { ApiError } from './client.ts'
|
|
11
12
|
import type { Decoder, Page, QueryParameters } from './client.ts'
|
|
@@ -25,14 +26,44 @@ import { toError } from './errors.ts'
|
|
|
25
26
|
* and leaves the cache library replaceable without touching a page.
|
|
26
27
|
*/
|
|
27
28
|
|
|
28
|
-
/**
|
|
29
|
-
|
|
29
|
+
/**
|
|
30
|
+
* The default page size when a caller does not name one via `query.limit`.
|
|
31
|
+
* Matches the `/v1` default from `api.md`.
|
|
32
|
+
*/
|
|
33
|
+
export const DEFAULT_PAGE_SIZE = 50
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The pagination controls a list surface renders. Split out from
|
|
37
|
+
* `RecordListResult` so the `Paginator` component can accept just this subset
|
|
38
|
+
* and stay generic in the record type.
|
|
39
|
+
*/
|
|
40
|
+
export interface Paged {
|
|
41
|
+
/** Zero-based index of the page currently on screen. */
|
|
42
|
+
readonly pageIndex: number
|
|
43
|
+
/** Number of records the API returns per page, from `?limit=`. */
|
|
44
|
+
readonly pageSize: number
|
|
45
|
+
readonly hasPrev: boolean
|
|
46
|
+
readonly hasNext: boolean
|
|
47
|
+
/** True while fetching a not-yet-cached page. Prev on a cached page is instant. */
|
|
48
|
+
readonly isChangingPage: boolean
|
|
49
|
+
readonly prevPage: () => void
|
|
50
|
+
readonly nextPage: () => void
|
|
51
|
+
/**
|
|
52
|
+
* Changes the API `?limit=` and returns the reader to page 1. The API caps
|
|
53
|
+
* `?limit=` at 200 (`api.md`); a larger value is coerced by the server, not
|
|
54
|
+
* refused by this hook.
|
|
55
|
+
*/
|
|
56
|
+
readonly setPageSize: (size: number) => void
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* A list, one page at a time. Records are the current page only, not the
|
|
61
|
+
* accumulation across pages a `Load more` reader would give.
|
|
62
|
+
*/
|
|
63
|
+
export interface RecordListResult<TRecord> extends Paged {
|
|
30
64
|
readonly records: readonly TRecord[]
|
|
31
65
|
readonly isLoading: boolean
|
|
32
66
|
readonly error: Error | null
|
|
33
|
-
readonly hasMore: boolean
|
|
34
|
-
readonly isLoadingMore: boolean
|
|
35
|
-
readonly loadMore: () => void
|
|
36
67
|
}
|
|
37
68
|
|
|
38
69
|
export interface RecordResult<TRecord> {
|
|
@@ -184,6 +215,114 @@ function removeRecordEverywhere<TRecord extends { readonly id: string }>(
|
|
|
184
215
|
)
|
|
185
216
|
}
|
|
186
217
|
|
|
218
|
+
export interface PagedListInput<TRecord> {
|
|
219
|
+
/**
|
|
220
|
+
* The React Query cache key for this list, without `?limit=`. `usePagedList`
|
|
221
|
+
* appends the current page size so the cache splits by size — swapping page
|
|
222
|
+
* sizes has to fetch, or the cursors from one size would page a list saved
|
|
223
|
+
* under another.
|
|
224
|
+
*/
|
|
225
|
+
readonly queryKey: readonly unknown[]
|
|
226
|
+
readonly path: string
|
|
227
|
+
readonly decode: Decoder<TRecord>
|
|
228
|
+
/** Query parameters other than `limit` and `cursor`. `usePagedList` sends both itself. */
|
|
229
|
+
readonly query: QueryParameters
|
|
230
|
+
readonly enabled?: boolean
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The paged reader every list hook uses: `createResourceHooks`'s `useList`,
|
|
235
|
+
* and the three custom collections whose paths carry a parent id
|
|
236
|
+
* (`useFormSubmissions`, `useListMembers`, `useWebhookDeliveries`).
|
|
237
|
+
*
|
|
238
|
+
* The API is cursor-only (`api.md`), so pages are fetched forward. Already
|
|
239
|
+
* fetched pages stay cached in `useInfiniteQuery`, and `pageIndex` selects
|
|
240
|
+
* which one is on screen — so going back to a visited page is instant and
|
|
241
|
+
* going forward past the fetched set kicks off exactly one new request.
|
|
242
|
+
*/
|
|
243
|
+
export function usePagedList<TRecord>(input: PagedListInput<TRecord>): RecordListResult<TRecord> {
|
|
244
|
+
const client = useApiClient()
|
|
245
|
+
const enabled = input.enabled ?? true
|
|
246
|
+
const requestedLimit = input.query.limit
|
|
247
|
+
const initialPageSize =
|
|
248
|
+
typeof requestedLimit === 'number' && Number.isFinite(requestedLimit) && requestedLimit > 0
|
|
249
|
+
? requestedLimit
|
|
250
|
+
: DEFAULT_PAGE_SIZE
|
|
251
|
+
const [pageSize, setPageSize] = useState<number>(initialPageSize)
|
|
252
|
+
const [pageIndex, setPageIndex] = useState<number>(0)
|
|
253
|
+
|
|
254
|
+
const queryKey = [...input.queryKey, { limit: pageSize }] as const
|
|
255
|
+
const queryKeySignature = JSON.stringify(queryKey)
|
|
256
|
+
|
|
257
|
+
// A filter or sort change lands as a fresh `useInfiniteQuery`, so the page
|
|
258
|
+
// number the user was on no longer makes sense. Effect over signature keeps
|
|
259
|
+
// this cheap: same key, no re-render.
|
|
260
|
+
useEffect(() => {
|
|
261
|
+
setPageIndex(0)
|
|
262
|
+
}, [queryKeySignature])
|
|
263
|
+
|
|
264
|
+
const result = useInfiniteQuery({
|
|
265
|
+
queryKey,
|
|
266
|
+
queryFn: ({ pageParam }) =>
|
|
267
|
+
client.list(input.path, input.decode, {
|
|
268
|
+
...input.query,
|
|
269
|
+
limit: pageSize,
|
|
270
|
+
...(pageParam === null ? {} : { cursor: pageParam }),
|
|
271
|
+
}),
|
|
272
|
+
initialPageParam: null as string | null,
|
|
273
|
+
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
|
274
|
+
// Without this a keystroke in the filter box blanks the table while the
|
|
275
|
+
// next query runs, which reads as "no results" for as long as it takes.
|
|
276
|
+
placeholderData: keepPreviousData,
|
|
277
|
+
enabled,
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
const pages = result.data?.pages ?? []
|
|
281
|
+
// A shrinking cache — a delete followed by a refetch — can leave the index
|
|
282
|
+
// past the last page. Clamp so a stale index never renders a blank table.
|
|
283
|
+
const safeIndex = pages.length === 0 ? 0 : Math.min(pageIndex, pages.length - 1)
|
|
284
|
+
const currentPage = pages[safeIndex]
|
|
285
|
+
const hasCachedNext = safeIndex + 1 < pages.length
|
|
286
|
+
const hasNext = hasCachedNext || result.hasNextPage
|
|
287
|
+
const hasPrev = safeIndex > 0
|
|
288
|
+
|
|
289
|
+
return {
|
|
290
|
+
records: currentPage?.items ?? [],
|
|
291
|
+
// A disabled query stays pending forever, which is not the same as loading.
|
|
292
|
+
isLoading: result.isPending && enabled,
|
|
293
|
+
error: toError(result.error),
|
|
294
|
+
pageIndex: safeIndex,
|
|
295
|
+
pageSize,
|
|
296
|
+
hasPrev,
|
|
297
|
+
hasNext,
|
|
298
|
+
isChangingPage: result.isFetchingNextPage,
|
|
299
|
+
prevPage: () => {
|
|
300
|
+
setPageIndex((current) => Math.max(0, current - 1))
|
|
301
|
+
},
|
|
302
|
+
nextPage: () => {
|
|
303
|
+
if (hasCachedNext) {
|
|
304
|
+
setPageIndex((current) => current + 1)
|
|
305
|
+
return
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (!result.hasNextPage) {
|
|
309
|
+
return
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
void result.fetchNextPage().then((r) => {
|
|
313
|
+
if (r.error === null) {
|
|
314
|
+
setPageIndex((current) => current + 1)
|
|
315
|
+
}
|
|
316
|
+
})
|
|
317
|
+
},
|
|
318
|
+
// Query key includes `limit`, so the effect above resets `pageIndex` to 0
|
|
319
|
+
// once React sees the new key.
|
|
320
|
+
setPageSize: (size) => {
|
|
321
|
+
setPageSize(size)
|
|
322
|
+
},
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
187
326
|
/**
|
|
188
327
|
* The read half: `useList` and `useRecord`, and nothing that writes.
|
|
189
328
|
*
|
|
@@ -197,34 +336,13 @@ export function createReadOnlyResourceHooks<TRecord>(
|
|
|
197
336
|
const keys = keysFor(definition.name)
|
|
198
337
|
|
|
199
338
|
function useList(query: QueryParameters = {}, options: ListOptions = {}): RecordListResult<TRecord> {
|
|
200
|
-
|
|
201
|
-
const enabled = options.enabled ?? true
|
|
202
|
-
const result = useInfiniteQuery({
|
|
339
|
+
return usePagedList<TRecord>({
|
|
203
340
|
queryKey: keys.list(query),
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
}),
|
|
209
|
-
initialPageParam: null as string | null,
|
|
210
|
-
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
|
211
|
-
// Without this a keystroke in the filter box blanks the table while the
|
|
212
|
-
// next query runs, which reads as "no results" for as long as it takes.
|
|
213
|
-
placeholderData: keepPreviousData,
|
|
214
|
-
enabled,
|
|
341
|
+
path: definition.path,
|
|
342
|
+
decode: definition.decode,
|
|
343
|
+
query,
|
|
344
|
+
enabled: options.enabled ?? true,
|
|
215
345
|
})
|
|
216
|
-
|
|
217
|
-
return {
|
|
218
|
-
records: result.data?.pages.flatMap((page) => page.items) ?? [],
|
|
219
|
-
// A disabled query stays pending forever, which is not the same as loading.
|
|
220
|
-
isLoading: result.isPending && enabled,
|
|
221
|
-
error: toError(result.error),
|
|
222
|
-
hasMore: result.hasNextPage,
|
|
223
|
-
isLoadingMore: result.isFetchingNextPage,
|
|
224
|
-
loadMore: () => {
|
|
225
|
-
void result.fetchNextPage()
|
|
226
|
-
},
|
|
227
|
-
}
|
|
228
346
|
}
|
|
229
347
|
|
|
230
348
|
function useRecord(id: string | undefined): RecordResult<TRecord> {
|
|
@@ -249,7 +367,12 @@ export function createReadOnlyResourceHooks<TRecord>(
|
|
|
249
367
|
export function createResourceHooks<
|
|
250
368
|
TRecord extends { readonly id: string },
|
|
251
369
|
TCreateInput,
|
|
252
|
-
|
|
370
|
+
// The constraint is deliberately looser than `Partial<TRecord>`. A merge-patch
|
|
371
|
+
// field (a record whose value type includes `null` to clear a key) does not
|
|
372
|
+
// fit `Partial<TRecord>` when the record's own value type is non-null, and
|
|
373
|
+
// that shape reaches the record for real (custom-fields, and any later
|
|
374
|
+
// module that carries one). `mergeDefined` needs no more than an object here.
|
|
375
|
+
TUpdateInput extends object,
|
|
253
376
|
>(
|
|
254
377
|
definition: ResourceDefinition<TRecord, TCreateInput, TUpdateInput>,
|
|
255
378
|
): ResourceHooks<TRecord, TCreateInput, TUpdateInput> {
|
|
@@ -25,7 +25,10 @@ const companies = createResourceHooks<Company, CreateCompanyInput, CompanyInput>
|
|
|
25
25
|
updateBody: companyBody,
|
|
26
26
|
// Every write here emits an activity server-side, in the same transaction, so
|
|
27
27
|
// a timeline rendered on this record is stale the moment the write lands.
|
|
28
|
-
|
|
28
|
+
// Creating or renaming a domain may also auto-link Positions to workspace
|
|
29
|
+
// people whose email is at it, which changes position lists and the
|
|
30
|
+
// `?company_id=` people list that names the far side of each new row.
|
|
31
|
+
alsoInvalidates: ['activities', 'positions', 'people'],
|
|
29
32
|
})
|
|
30
33
|
|
|
31
34
|
/** The documented filters on `GET /v1/companies`. */
|
|
@@ -34,6 +37,8 @@ export interface CompanyFilters {
|
|
|
34
37
|
readonly term?: string | undefined
|
|
35
38
|
/** Companies where any of these people holds a position. Repeats on the wire. */
|
|
36
39
|
readonly personIds?: readonly string[] | undefined
|
|
40
|
+
/** true = only the workspace's own companies; false = only the rest. */
|
|
41
|
+
readonly isOwn?: boolean | undefined
|
|
37
42
|
readonly limit?: number | undefined
|
|
38
43
|
/** `field` ascending, `-field` descending. Only `name`, `created_at`, `updated_at` are sortable. */
|
|
39
44
|
readonly sort?: string | undefined
|
|
@@ -43,6 +48,7 @@ function companyQuery(filters: CompanyFilters): QueryParameters {
|
|
|
43
48
|
return {
|
|
44
49
|
q: filters.term,
|
|
45
50
|
person_id: filters.personIds,
|
|
51
|
+
is_own: filters.isOwn === undefined ? undefined : String(filters.isOwn),
|
|
46
52
|
limit: filters.limit,
|
|
47
53
|
sort: filters.sort,
|
|
48
54
|
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import {
|
|
2
|
+
consentPurposeBody,
|
|
3
|
+
consentPurposeSchema,
|
|
4
|
+
createConsentPurposeBody,
|
|
5
|
+
} from '@kelpie/schemas'
|
|
6
|
+
import type {
|
|
7
|
+
ConsentPurpose,
|
|
8
|
+
ConsentPurposeInput,
|
|
9
|
+
CreateConsentPurposeInput,
|
|
10
|
+
} from '@kelpie/schemas'
|
|
11
|
+
|
|
12
|
+
import type { QueryParameters } from '../client.ts'
|
|
13
|
+
import { createResourceHooks } from '../resource.ts'
|
|
14
|
+
import type {
|
|
15
|
+
ListOptions,
|
|
16
|
+
MutationResult,
|
|
17
|
+
RecordListResult,
|
|
18
|
+
RecordResult,
|
|
19
|
+
UpdateArguments,
|
|
20
|
+
} from '../resource.ts'
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* `/v1/consent_purposes`. Workspace-defined consent purposes.
|
|
24
|
+
*
|
|
25
|
+
* Every capture site — form consent fields, lists, imports, the manual
|
|
26
|
+
* override on a Person — names one of these. Reads are open to any member;
|
|
27
|
+
* writes need the admin role, enforced server-side.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
const consentPurposes = createResourceHooks<
|
|
31
|
+
ConsentPurpose,
|
|
32
|
+
CreateConsentPurposeInput,
|
|
33
|
+
ConsentPurposeInput
|
|
34
|
+
>({
|
|
35
|
+
name: 'consent_purposes',
|
|
36
|
+
path: '/consent_purposes',
|
|
37
|
+
decode: consentPurposeSchema.parse,
|
|
38
|
+
createBody: createConsentPurposeBody,
|
|
39
|
+
updateBody: consentPurposeBody,
|
|
40
|
+
})
|
|
41
|
+
|
|
42
|
+
export interface ConsentPurposeFilters {
|
|
43
|
+
readonly term?: string | undefined
|
|
44
|
+
readonly limit?: number | undefined
|
|
45
|
+
readonly sort?: string | undefined
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function consentPurposeQuery(filters: ConsentPurposeFilters): QueryParameters {
|
|
49
|
+
return {
|
|
50
|
+
q: filters.term,
|
|
51
|
+
limit: filters.limit,
|
|
52
|
+
sort: filters.sort,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export function useConsentPurposes(
|
|
57
|
+
filters: ConsentPurposeFilters = {},
|
|
58
|
+
options: ListOptions = {},
|
|
59
|
+
): RecordListResult<ConsentPurpose> {
|
|
60
|
+
return consentPurposes.useList(consentPurposeQuery(filters), options)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export function useConsentPurpose(id: string | undefined): RecordResult<ConsentPurpose> {
|
|
64
|
+
return consentPurposes.useRecord(id)
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export function useCreateConsentPurpose(): MutationResult<
|
|
68
|
+
CreateConsentPurposeInput,
|
|
69
|
+
ConsentPurpose
|
|
70
|
+
> {
|
|
71
|
+
return consentPurposes.useCreate()
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export function useUpdateConsentPurpose(): MutationResult<
|
|
75
|
+
UpdateArguments<ConsentPurposeInput>,
|
|
76
|
+
ConsentPurpose
|
|
77
|
+
> {
|
|
78
|
+
return consentPurposes.useUpdate()
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export function useDeleteConsentPurpose(): MutationResult<string, void> {
|
|
82
|
+
return consentPurposes.useRemove()
|
|
83
|
+
}
|