@kelpie/ui 0.6.0 → 0.8.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 +58 -5
- 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/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/forms.d.ts.map +1 -1
- package/dist/api/resources/forms.js +6 -20
- 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 +3 -1
- package/dist/api/resources/importJobs.d.ts.map +1 -1
- package/dist/api/resources/importJobs.js +1 -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/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/publicConfig.d.ts +8 -0
- package/dist/api/resources/publicConfig.d.ts.map +1 -0
- package/dist/api/resources/publicConfig.js +22 -0
- package/dist/api/resources/publicConfig.js.map +1 -0
- 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 +30 -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 +5 -2
- package/dist/app/KelpieApp.js.map +1 -1
- package/dist/components/ActivitiesPanel.d.ts.map +1 -1
- package/dist/components/ActivitiesPanel.js +2 -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/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/EnvironmentBanner.d.ts +14 -0
- package/dist/components/EnvironmentBanner.d.ts.map +1 -0
- package/dist/components/EnvironmentBanner.js +23 -0
- package/dist/components/EnvironmentBanner.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/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 +1 -0
- package/dist/components/Shell.js.map +1 -1
- 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 +17 -14
- package/dist/pages/CompanyDetail.js.map +1 -1
- package/dist/pages/DealDetail.d.ts.map +1 -1
- package/dist/pages/DealDetail.js +3 -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 +50 -8
- package/dist/pages/DecisionsPage.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 +188 -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 +3 -1
- package/dist/pages/OpportunityDetail.js.map +1 -1
- package/dist/pages/PartnershipDetail.d.ts.map +1 -1
- package/dist/pages/PartnershipDetail.js +3 -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 +102 -3
- package/dist/pages/PeoplePage.js.map +1 -1
- package/dist/pages/PersonDetail.d.ts.map +1 -1
- package/dist/pages/PersonDetail.js +5 -3
- package/dist/pages/PersonDetail.js.map +1 -1
- package/dist/pages/PlanningPage.d.ts.map +1 -1
- package/dist/pages/PlanningPage.js +85 -17
- package/dist/pages/PlanningPage.js.map +1 -1
- package/dist/pages/RaiseDetail.d.ts.map +1 -1
- package/dist/pages/RaiseDetail.js +3 -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/admin/DataPage.d.ts.map +1 -1
- package/dist/pages/admin/DataPage.js +126 -16
- package/dist/pages/admin/DataPage.js.map +1 -1
- 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/forms/SubmissionsTable.d.ts.map +1 -1
- package/dist/pages/forms/SubmissionsTable.js +2 -1
- package/dist/pages/forms/SubmissionsTable.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 +149 -31
- package/src/api/resources/companies.ts +7 -1
- package/src/api/resources/decisions.ts +3 -0
- package/src/api/resources/emailDomainLinker.ts +43 -0
- package/src/api/resources/forms.ts +5 -23
- package/src/api/resources/handbookPages.ts +1 -1
- package/src/api/resources/importJobs.ts +4 -0
- package/src/api/resources/listMembers.ts +173 -0
- package/src/api/resources/lists.ts +61 -0
- package/src/api/resources/people.ts +4 -1
- package/src/api/resources/publicConfig.ts +33 -0
- package/src/api/resources/roles.ts +3 -1
- package/src/api/resources/sampleData.ts +56 -0
- package/src/api/resources/webhooks.ts +8 -24
- package/src/app/KelpieApp.tsx +11 -0
- package/src/components/ActivitiesPanel.tsx +2 -10
- package/src/components/ColumnPicker.tsx +124 -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/EnvironmentBanner.tsx +30 -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/PlanPanel.tsx +2 -10
- package/src/components/Shell.tsx +1 -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 +62 -62
- package/src/pages/DealDetail.tsx +3 -0
- package/src/pages/DealsPage.tsx +178 -24
- package/src/pages/DecisionsPage.tsx +73 -18
- 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 +408 -0
- package/src/pages/ListsPage.tsx +281 -0
- package/src/pages/OpportunitiesPage.tsx +130 -24
- package/src/pages/OpportunityDetail.tsx +3 -0
- package/src/pages/PartnershipDetail.tsx +3 -0
- package/src/pages/PartnershipsPage.tsx +149 -24
- package/src/pages/PeoplePage.tsx +137 -11
- package/src/pages/PersonDetail.tsx +5 -3
- package/src/pages/PlanningPage.tsx +256 -29
- package/src/pages/RaiseDetail.tsx +3 -0
- package/src/pages/RoleDetail.tsx +21 -26
- package/src/pages/admin/DataPage.tsx +359 -36
- 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/forms/SubmissionsTable.tsx +3 -10
- 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
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
import type { Workspace } from '@kelpie/schemas'
|
|
2
|
-
import { useState } from 'react'
|
|
1
|
+
import type { Company, Workspace } from '@kelpie/schemas'
|
|
2
|
+
import { useMemo, useState } from 'react'
|
|
3
3
|
import type { FormEvent, ReactNode } from 'react'
|
|
4
4
|
import { useNavigate } from 'react-router'
|
|
5
5
|
|
|
6
|
+
import {
|
|
7
|
+
useCompanies,
|
|
8
|
+
useCreateCompany,
|
|
9
|
+
useUpdateCompany,
|
|
10
|
+
} from '../../api/resources/companies.ts'
|
|
6
11
|
import { useSession } from '../../api/resources/session.ts'
|
|
7
12
|
import {
|
|
8
13
|
useDeleteWorkspace,
|
|
9
14
|
useUpdateWorkspace,
|
|
10
15
|
useWorkspace,
|
|
11
16
|
} from '../../api/resources/workspace.ts'
|
|
17
|
+
import { EntitySearch } from '../../components/EntitySearch.tsx'
|
|
18
|
+
import type { SearchOption } from '../../components/EntitySearch.tsx'
|
|
12
19
|
import { PageHeader } from '../../components/PageHeader.tsx'
|
|
13
20
|
import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
|
|
14
21
|
|
|
@@ -190,11 +197,136 @@ function WorkspaceSettingsForm({
|
|
|
190
197
|
)}
|
|
191
198
|
</form>
|
|
192
199
|
|
|
200
|
+
<OwnCompanySection canEdit={canEdit} />
|
|
201
|
+
|
|
193
202
|
{session?.role === 'owner' && <DangerZone slug={workspace.slug} />}
|
|
194
203
|
</div>
|
|
195
204
|
)
|
|
196
205
|
}
|
|
197
206
|
|
|
207
|
+
/**
|
|
208
|
+
* Mark one or more Companies as "us" — the workspace's own organisation.
|
|
209
|
+
*
|
|
210
|
+
* Backed by `companies.is_own`. Zero or many rows may carry it (a parent and a
|
|
211
|
+
* subsidiary is the intended case), so the surface is a list plus an add
|
|
212
|
+
* picker rather than a single-select. Picking a name that does not exist
|
|
213
|
+
* creates the Company with `is_own: true` in one call.
|
|
214
|
+
*/
|
|
215
|
+
function OwnCompanySection({ canEdit }: { readonly canEdit: boolean }): React.JSX.Element {
|
|
216
|
+
const own = useCompanies({ isOwn: true })
|
|
217
|
+
const [search, setSearch] = useState('')
|
|
218
|
+
// The picker's options: workspace companies that are NOT already marked.
|
|
219
|
+
// Server-side search on the term the user types.
|
|
220
|
+
const searchable = useCompanies({
|
|
221
|
+
isOwn: false,
|
|
222
|
+
term: search.trim().length > 0 ? search.trim() : undefined,
|
|
223
|
+
})
|
|
224
|
+
const update = useUpdateCompany()
|
|
225
|
+
const create = useCreateCompany()
|
|
226
|
+
|
|
227
|
+
const options: SearchOption[] = useMemo(
|
|
228
|
+
() =>
|
|
229
|
+
searchable.records.map((company) => ({
|
|
230
|
+
id: company.id,
|
|
231
|
+
label: company.name,
|
|
232
|
+
meta: company.domain ?? undefined,
|
|
233
|
+
})),
|
|
234
|
+
[searchable.records],
|
|
235
|
+
)
|
|
236
|
+
|
|
237
|
+
function mark(companyId: string): void {
|
|
238
|
+
update.run({ id: companyId, changes: { isOwn: true } })
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function unmark(companyId: string): void {
|
|
242
|
+
update.run({ id: companyId, changes: { isOwn: false } })
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
function createAndMark(name: string): void {
|
|
246
|
+
// The API defaults every other field; `is_own: true` lands the row in the
|
|
247
|
+
// list this section shows and nowhere else.
|
|
248
|
+
create.run({ name, isOwn: true })
|
|
249
|
+
setSearch('')
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const busy = update.isPending || create.isPending
|
|
253
|
+
|
|
254
|
+
return (
|
|
255
|
+
<section className="space-y-3 rounded-lg border border-border bg-surface p-4">
|
|
256
|
+
<div>
|
|
257
|
+
<h2 className="text-[13px] font-semibold text-ink">This company</h2>
|
|
258
|
+
<p className="mt-1 max-w-xl text-[12px] text-ink-muted">
|
|
259
|
+
Mark the company (or companies) in the CRM that represent this workspace itself. Used
|
|
260
|
+
later to separate own records from prospects.
|
|
261
|
+
</p>
|
|
262
|
+
</div>
|
|
263
|
+
|
|
264
|
+
{own.isLoading ? (
|
|
265
|
+
<p className="text-[12px] text-ink-faint">Loading…</p>
|
|
266
|
+
) : own.records.length === 0 ? (
|
|
267
|
+
<p className="text-[12px] text-ink-faint">Nothing marked yet.</p>
|
|
268
|
+
) : (
|
|
269
|
+
<ul className="divide-y divide-border rounded-md border border-border">
|
|
270
|
+
{own.records.map((company: Company) => (
|
|
271
|
+
<li
|
|
272
|
+
key={company.id}
|
|
273
|
+
className="flex items-center justify-between gap-3 px-3 py-2.5"
|
|
274
|
+
>
|
|
275
|
+
<div className="min-w-0">
|
|
276
|
+
<div className="truncate text-[13px] font-medium text-ink">{company.name}</div>
|
|
277
|
+
{company.domain !== null && company.domain.length > 0 && (
|
|
278
|
+
<div className="truncate text-[11px] text-ink-faint">{company.domain}</div>
|
|
279
|
+
)}
|
|
280
|
+
</div>
|
|
281
|
+
{canEdit && (
|
|
282
|
+
<button
|
|
283
|
+
type="button"
|
|
284
|
+
onClick={() => {
|
|
285
|
+
unmark(company.id)
|
|
286
|
+
}}
|
|
287
|
+
disabled={busy}
|
|
288
|
+
className="shrink-0 rounded-md border border-border bg-surface-raised px-2.5 py-1 text-[11px] font-medium text-ink hover:border-danger hover:text-danger disabled:opacity-50"
|
|
289
|
+
>
|
|
290
|
+
Unmark
|
|
291
|
+
</button>
|
|
292
|
+
)}
|
|
293
|
+
</li>
|
|
294
|
+
))}
|
|
295
|
+
</ul>
|
|
296
|
+
)}
|
|
297
|
+
|
|
298
|
+
{canEdit && (
|
|
299
|
+
<div className="max-w-md">
|
|
300
|
+
<label className="mb-1.5 block text-[12px] font-medium text-ink">
|
|
301
|
+
{own.records.length === 0 ? 'Pick or create' : 'Add another'}
|
|
302
|
+
</label>
|
|
303
|
+
<EntitySearch
|
|
304
|
+
options={options}
|
|
305
|
+
value=""
|
|
306
|
+
onChange={mark}
|
|
307
|
+
onQueryChange={setSearch}
|
|
308
|
+
onCreate={createAndMark}
|
|
309
|
+
createLabel={(query) => `Create “${query}” and mark it`}
|
|
310
|
+
placeholder="Search companies…"
|
|
311
|
+
emptyMessage="No matches — type a new name to create one"
|
|
312
|
+
/>
|
|
313
|
+
</div>
|
|
314
|
+
)}
|
|
315
|
+
|
|
316
|
+
{update.error !== null && (
|
|
317
|
+
<div className="max-w-xl">
|
|
318
|
+
<ErrorPanel error={update.error} />
|
|
319
|
+
</div>
|
|
320
|
+
)}
|
|
321
|
+
{create.error !== null && (
|
|
322
|
+
<div className="max-w-xl">
|
|
323
|
+
<ErrorPanel error={create.error} />
|
|
324
|
+
</div>
|
|
325
|
+
)}
|
|
326
|
+
</section>
|
|
327
|
+
)
|
|
328
|
+
}
|
|
329
|
+
|
|
198
330
|
/**
|
|
199
331
|
* Deleting the workspace, behind the workspace's own name.
|
|
200
332
|
*
|
|
@@ -8,6 +8,7 @@ import { useCompanies } from '../../api/resources/companies.ts'
|
|
|
8
8
|
import { usePeople } from '../../api/resources/people.ts'
|
|
9
9
|
import { DataTable } from '../../components/DataTable.tsx'
|
|
10
10
|
import type { Column } from '../../components/DataTable.tsx'
|
|
11
|
+
import { Paginator } from '../../components/Paginator.tsx'
|
|
11
12
|
import { ErrorPanel, LoadingPanel } from '../../components/QueryState.tsx'
|
|
12
13
|
import { SectionHeader } from '../../components/SectionHeader.tsx'
|
|
13
14
|
import { formatDateTime } from '../../lib/dates.ts'
|
|
@@ -100,22 +101,14 @@ export function SubmissionsTable({ form, submissions }: SubmissionsTableProps):
|
|
|
100
101
|
title="Submissions"
|
|
101
102
|
description="Inbound answers, and the records each one created or matched."
|
|
102
103
|
/>
|
|
104
|
+
<Paginator list={submissions} placement="top" />
|
|
103
105
|
<DataTable
|
|
104
106
|
columns={columns}
|
|
105
107
|
rows={submissions.records}
|
|
106
108
|
getRowId={(submission) => submission.id}
|
|
107
109
|
emptyMessage="No submissions yet"
|
|
108
110
|
/>
|
|
109
|
-
{submissions
|
|
110
|
-
<button
|
|
111
|
-
type="button"
|
|
112
|
-
onClick={submissions.loadMore}
|
|
113
|
-
disabled={submissions.isLoadingMore}
|
|
114
|
-
className="mt-3 rounded-md border border-border px-3 py-1.5 text-[12px] font-medium text-ink transition hover:border-border-strong hover:bg-surface-sunken disabled:opacity-50"
|
|
115
|
-
>
|
|
116
|
-
{submissions.isLoadingMore ? 'Loading…' : 'Load more'}
|
|
117
|
-
</button>
|
|
118
|
-
)}
|
|
111
|
+
<Paginator list={submissions} />
|
|
119
112
|
</div>
|
|
120
113
|
)
|
|
121
114
|
}
|
|
@@ -234,7 +234,7 @@ export function HandbookLayout(): React.JSX.Element {
|
|
|
234
234
|
{flat.length === 0 && (
|
|
235
235
|
<p className="px-2 py-6 text-center text-[12px] text-ink-faint">No pages yet.</p>
|
|
236
236
|
)}
|
|
237
|
-
{pages.
|
|
237
|
+
{pages.hasNext && (
|
|
238
238
|
<p className="px-2 py-3 text-center text-[11px] text-ink-faint">
|
|
239
239
|
This handbook has more pages than one request returns, so the tree below is
|
|
240
240
|
incomplete.
|
|
@@ -45,7 +45,7 @@ export function useRoleCandidateCounts(roleIds: readonly string[]): RoleCandidat
|
|
|
45
45
|
return {
|
|
46
46
|
countFor: (roleId) => countByRole.get(roleId) ?? 0,
|
|
47
47
|
isLoading: candidates.isLoading,
|
|
48
|
-
isComplete: !candidates.
|
|
48
|
+
isComplete: !candidates.hasNext,
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -95,7 +95,7 @@ export function useCandidateNotes(candidateIds: readonly string[]): CandidateNot
|
|
|
95
95
|
return {
|
|
96
96
|
noteFor: (candidateId) => newestByCandidate.get(candidateId),
|
|
97
97
|
isLoading: notes.isLoading,
|
|
98
|
-
isComplete: !notes.
|
|
98
|
+
isComplete: !notes.hasNext,
|
|
99
99
|
}
|
|
100
100
|
}
|
|
101
101
|
|
|
@@ -2,6 +2,7 @@ import { useState } from 'react'
|
|
|
2
2
|
import type { FormEvent } from 'react'
|
|
3
3
|
import { Link, Navigate, useNavigate } from 'react-router'
|
|
4
4
|
|
|
5
|
+
import { useInstallSampleData } from '../../api/resources/sampleData.ts'
|
|
5
6
|
import { useCreateWorkspace, useSession } from '../../api/resources/session.ts'
|
|
6
7
|
import { ErrorPanel } from '../../components/QueryState.tsx'
|
|
7
8
|
import { SubmitButton, TextField } from '../auth/AuthForm.tsx'
|
|
@@ -48,10 +49,12 @@ export function WorkspaceStepPage(): React.JSX.Element {
|
|
|
48
49
|
const navigate = useNavigate()
|
|
49
50
|
const { isSignedOut } = useSession()
|
|
50
51
|
const createWorkspace = useCreateWorkspace()
|
|
52
|
+
const installSampleData = useInstallSampleData()
|
|
51
53
|
const [name, setName] = useState('')
|
|
52
54
|
const [slug, setSlug] = useState('')
|
|
53
55
|
const [slugEdited, setSlugEdited] = useState(false)
|
|
54
56
|
const [timezone] = useState(browserTimezone)
|
|
57
|
+
const [seedSample, setSeedSample] = useState(false)
|
|
55
58
|
|
|
56
59
|
function changeName(value: string): void {
|
|
57
60
|
setName(value)
|
|
@@ -71,7 +74,18 @@ export function WorkspaceStepPage(): React.JSX.Element {
|
|
|
71
74
|
|
|
72
75
|
createWorkspace
|
|
73
76
|
.runAsync({ name: name.trim(), slug: slug.trim(), timezone })
|
|
74
|
-
.then(() =>
|
|
77
|
+
.then(async (workspace) => {
|
|
78
|
+
if (seedSample) {
|
|
79
|
+
// A refusal here does not block the wizard: the workspace itself is
|
|
80
|
+
// already created, and the invites step is what comes next either
|
|
81
|
+
// way. The error stays on screen so the reader sees what failed.
|
|
82
|
+
await installSampleData
|
|
83
|
+
.runAsync({ workspaceId: workspace.id })
|
|
84
|
+
.catch(() => undefined)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
navigate('/onboarding/invites', { replace: true })
|
|
88
|
+
})
|
|
75
89
|
.catch(() => undefined)
|
|
76
90
|
}
|
|
77
91
|
|
|
@@ -110,11 +124,25 @@ export function WorkspaceStepPage(): React.JSX.Element {
|
|
|
110
124
|
<p className="text-[11px] text-ink-faint">
|
|
111
125
|
Timezone: {timezone}. Change it later in Admin → Workspace.
|
|
112
126
|
</p>
|
|
127
|
+
<label className="flex items-start gap-2 text-[12px] text-ink">
|
|
128
|
+
<input
|
|
129
|
+
type="checkbox"
|
|
130
|
+
checked={seedSample}
|
|
131
|
+
onChange={(event) => setSeedSample(event.target.checked)}
|
|
132
|
+
className="mt-0.5 h-4 w-4 rounded border-border text-accent focus:ring-accent"
|
|
133
|
+
/>
|
|
134
|
+
<span>
|
|
135
|
+
Install sample data — a small set of companies, people, deals, opportunities,
|
|
136
|
+
fundraising, partnerships, and hiring so the workspace has something to look at.
|
|
137
|
+
You can delete it later.
|
|
138
|
+
</span>
|
|
139
|
+
</label>
|
|
113
140
|
{createWorkspace.error !== null && <ErrorPanel error={createWorkspace.error} />}
|
|
141
|
+
{installSampleData.error !== null && <ErrorPanel error={installSampleData.error} />}
|
|
114
142
|
<SubmitButton
|
|
115
143
|
label="Continue"
|
|
116
|
-
pendingLabel=
|
|
117
|
-
isPending={createWorkspace.isPending}
|
|
144
|
+
pendingLabel={installSampleData.isPending ? 'Installing sample data…' : 'Creating…'}
|
|
145
|
+
isPending={createWorkspace.isPending || installSampleData.isPending}
|
|
118
146
|
/>
|
|
119
147
|
</form>
|
|
120
148
|
</AuthLayout>
|
|
@@ -64,7 +64,7 @@ export function usePeopleDirectory(personIds: readonly string[]): PeopleDirector
|
|
|
64
64
|
.map((held) => companyNameById.get(held.companyId))
|
|
65
65
|
.filter((name): name is string => name !== undefined),
|
|
66
66
|
isLoading: positions.isLoading || companies.isLoading,
|
|
67
|
-
isComplete: !positions.
|
|
67
|
+
isComplete: !positions.hasNext && !companies.hasNext,
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
@@ -93,6 +93,6 @@ export function useCompanyHeadcounts(companyIds: readonly string[]): CompanyHead
|
|
|
93
93
|
return {
|
|
94
94
|
countFor: (companyId) => countByCompany.get(companyId) ?? 0,
|
|
95
95
|
isLoading: positions.isLoading,
|
|
96
|
-
isComplete: !positions.
|
|
96
|
+
isComplete: !positions.hasNext,
|
|
97
97
|
}
|
|
98
98
|
}
|
package/src/styles.css
CHANGED
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
--surface-raised: #ffffff;
|
|
59
59
|
--surface-sunken: #f4f4f5;
|
|
60
60
|
--ink: #18181b;
|
|
61
|
-
--ink-muted: #
|
|
62
|
-
--ink-faint: #
|
|
61
|
+
--ink-muted: #52525b;
|
|
62
|
+
--ink-faint: #71717a;
|
|
63
63
|
--border: #e4e4e7;
|
|
64
64
|
--border-strong: #d4d4d8;
|
|
65
65
|
--accent: #0f766e;
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
--warning-soft: #fffbeb;
|
|
76
76
|
--sidebar: #fafafa;
|
|
77
77
|
--sidebar-ink: #18181b;
|
|
78
|
-
--sidebar-muted: #
|
|
78
|
+
--sidebar-muted: #52525b;
|
|
79
79
|
--sidebar-hover: #f4f4f5;
|
|
80
80
|
--sidebar-active: #ececef;
|
|
81
81
|
--sidebar-border: #e4e4e7;
|