@kelpie/ui 0.3.0 → 0.4.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/ApiProvider.d.ts +3 -3
- package/dist/api/ApiProvider.d.ts.map +1 -1
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +4 -1
- package/dist/api/client.js.map +1 -1
- package/dist/api/resources/agentTasks.d.ts +2 -2
- package/dist/api/resources/agentTasks.d.ts.map +1 -1
- package/dist/api/resources/candidates.d.ts +4 -4
- package/dist/api/resources/candidates.d.ts.map +1 -1
- package/dist/api/resources/companies.d.ts +4 -4
- package/dist/api/resources/companies.d.ts.map +1 -1
- package/dist/api/resources/deals.d.ts +6 -6
- package/dist/api/resources/deals.d.ts.map +1 -1
- package/dist/api/resources/decisions.d.ts +3 -3
- package/dist/api/resources/decisions.d.ts.map +1 -1
- package/dist/api/resources/forms.d.ts +3 -3
- package/dist/api/resources/forms.d.ts.map +1 -1
- package/dist/api/resources/handbookPages.d.ts +3 -3
- package/dist/api/resources/handbookPages.d.ts.map +1 -1
- package/dist/api/resources/notes.d.ts +2 -2
- package/dist/api/resources/notes.d.ts.map +1 -1
- package/dist/api/resources/opportunities.d.ts +6 -6
- package/dist/api/resources/opportunities.d.ts.map +1 -1
- package/dist/api/resources/partnerships.d.ts +7 -7
- package/dist/api/resources/partnerships.d.ts.map +1 -1
- package/dist/api/resources/people.d.ts +4 -4
- package/dist/api/resources/people.d.ts.map +1 -1
- package/dist/api/resources/planItems.d.ts +6 -6
- package/dist/api/resources/planItems.d.ts.map +1 -1
- package/dist/api/resources/positions.d.ts +3 -3
- package/dist/api/resources/positions.d.ts.map +1 -1
- package/dist/api/resources/raises.d.ts +6 -6
- package/dist/api/resources/raises.d.ts.map +1 -1
- package/dist/api/resources/roles.d.ts +3 -3
- package/dist/api/resources/roles.d.ts.map +1 -1
- package/dist/api/resources/webhooks.d.ts +2 -2
- package/dist/api/resources/webhooks.d.ts.map +1 -1
- package/dist/app/KelpieApp.d.ts.map +1 -1
- package/dist/app/KelpieApp.js +16 -1
- package/dist/app/KelpieApp.js.map +1 -1
- package/dist/components/DataTable.d.ts +10 -10
- package/dist/components/DataTable.d.ts.map +1 -1
- package/dist/components/EntitySearch.d.ts +10 -10
- package/dist/components/EntitySearch.d.ts.map +1 -1
- package/dist/components/KanbanBoard.d.ts +2 -2
- package/dist/components/KanbanBoard.d.ts.map +1 -1
- package/dist/components/Shell.d.ts.map +1 -1
- package/dist/components/Shell.js +3 -16
- package/dist/components/Shell.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/pages/account/AccountLayout.d.ts.map +1 -1
- package/dist/pages/account/AccountLayout.js +15 -7
- package/dist/pages/account/AccountLayout.js.map +1 -1
- package/dist/registry/context.d.ts +1 -2
- package/dist/registry/context.d.ts.map +1 -1
- package/dist/registry/context.js +0 -3
- package/dist/registry/context.js.map +1 -1
- package/dist/registry/contributions.d.ts +1 -12
- package/dist/registry/contributions.d.ts.map +1 -1
- package/dist/registry/contributions.js +0 -7
- package/dist/registry/contributions.js.map +1 -1
- package/dist/registry/registry.d.ts +1 -3
- package/dist/registry/registry.d.ts.map +1 -1
- package/dist/registry/registry.js +0 -6
- package/dist/registry/registry.js.map +1 -1
- package/dist/registry/visibleNav.d.ts +3 -0
- package/dist/registry/visibleNav.d.ts.map +1 -0
- package/dist/registry/visibleNav.js +27 -0
- package/dist/registry/visibleNav.js.map +1 -0
- package/package.json +2 -2
- package/src/api/ApiProvider.tsx +3 -3
- package/src/api/client.ts +4 -1
- package/src/api/resources/agentTasks.ts +2 -2
- package/src/api/resources/candidates.ts +4 -4
- package/src/api/resources/companies.ts +4 -4
- package/src/api/resources/deals.ts +6 -6
- package/src/api/resources/decisions.ts +3 -3
- package/src/api/resources/forms.ts +3 -3
- package/src/api/resources/handbookPages.ts +3 -3
- package/src/api/resources/notes.ts +2 -2
- package/src/api/resources/opportunities.ts +6 -6
- package/src/api/resources/partnerships.ts +7 -7
- package/src/api/resources/people.ts +4 -4
- package/src/api/resources/planItems.ts +6 -6
- package/src/api/resources/positions.ts +3 -3
- package/src/api/resources/raises.ts +6 -6
- package/src/api/resources/roles.ts +3 -3
- package/src/api/resources/webhooks.ts +2 -2
- package/src/app/KelpieApp.tsx +26 -1
- package/src/components/DataTable.tsx +12 -12
- package/src/components/EntitySearch.tsx +10 -10
- package/src/components/KanbanBoard.tsx +2 -2
- package/src/components/Shell.tsx +3 -22
- package/src/index.ts +1 -4
- package/src/pages/account/AccountLayout.tsx +20 -9
- package/src/registry/context.ts +0 -5
- package/src/registry/contributions.ts +1 -20
- package/src/registry/registry.ts +0 -11
- package/src/registry/visibleNav.ts +38 -0
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
import { NavLink, Outlet } from 'react-router'
|
|
2
2
|
|
|
3
|
+
import type { NavItem } from '../../registry/contributions.ts'
|
|
4
|
+
import { useNavItems } from '../../registry/context.ts'
|
|
5
|
+
import { useVisibleNavItems } from '../../registry/visibleNav.ts'
|
|
6
|
+
|
|
3
7
|
/**
|
|
4
8
|
* Tabs across the account's own settings, from the mockup's `AccountNav`.
|
|
5
9
|
*
|
|
6
|
-
* Three of its five tabs are
|
|
7
|
-
*
|
|
10
|
+
* Three of its five tabs are core's. The rest come from `nav.account`, which is
|
|
11
|
+
* where a module's own account page announces itself: a module route mounts as
|
|
12
|
+
* a sibling of `/account` rather than a child of it, so without this the page
|
|
13
|
+
* would render with no tab strip and nothing anywhere pointing at it.
|
|
14
|
+
*
|
|
15
|
+
* Core numbers itself in hundreds, the same convention the shell's sidebar
|
|
16
|
+
* uses, so a module can land between two core tabs without core renumbering.
|
|
8
17
|
*/
|
|
9
18
|
|
|
10
|
-
const
|
|
11
|
-
{ to: '/account/profile', label: 'Profile' },
|
|
12
|
-
{ to: '/account/security', label: 'Security' },
|
|
13
|
-
{ to: '/account/preferences', label: 'Preferences' },
|
|
14
|
-
]
|
|
19
|
+
const CORE_TABS: readonly NavItem[] = [
|
|
20
|
+
{ id: 'profile', to: '/account/profile', label: 'Profile', order: 100 },
|
|
21
|
+
{ id: 'security', to: '/account/security', label: 'Security', order: 200 },
|
|
22
|
+
{ id: 'preferences', to: '/account/preferences', label: 'Preferences', order: 300 },
|
|
23
|
+
]
|
|
15
24
|
|
|
16
25
|
function tabClass({ isActive }: { isActive: boolean }): string {
|
|
17
26
|
return [
|
|
@@ -23,11 +32,13 @@ function tabClass({ isActive }: { isActive: boolean }): string {
|
|
|
23
32
|
}
|
|
24
33
|
|
|
25
34
|
export function AccountLayout(): React.JSX.Element {
|
|
35
|
+
const tabs = useVisibleNavItems(CORE_TABS, useNavItems('account'))
|
|
36
|
+
|
|
26
37
|
return (
|
|
27
38
|
<div className="animate-fade-in mx-auto max-w-4xl">
|
|
28
39
|
<nav className="mb-6 flex flex-wrap gap-1 border-b border-border pb-3">
|
|
29
|
-
{
|
|
30
|
-
<NavLink key={tab.
|
|
40
|
+
{tabs.map((tab) => (
|
|
41
|
+
<NavLink key={tab.id} to={tab.to} className={tabClass}>
|
|
31
42
|
{tab.label}
|
|
32
43
|
</NavLink>
|
|
33
44
|
))}
|
package/src/registry/context.ts
CHANGED
|
@@ -4,7 +4,6 @@ import type { ComponentType } from 'react'
|
|
|
4
4
|
import type {
|
|
5
5
|
DashboardCard,
|
|
6
6
|
ExtensibleRecordType,
|
|
7
|
-
IntegrationProvider,
|
|
8
7
|
NavItem,
|
|
9
8
|
NavSlot,
|
|
10
9
|
RecordSidebarCard,
|
|
@@ -54,10 +53,6 @@ export function useDashboardCards(): readonly DashboardCard[] {
|
|
|
54
53
|
return useUiExtensions().dashboardCards()
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
export function useIntegrationProviders(): readonly IntegrationProvider[] {
|
|
58
|
-
return useUiExtensions().integrationProviders()
|
|
59
|
-
}
|
|
60
|
-
|
|
61
56
|
/**
|
|
62
57
|
* The component to render for an overridable: a module's replacement, or core's
|
|
63
58
|
* own. Core calls this instead of rendering its component directly.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensibleRecordType } from '@kelpie/schemas'
|
|
2
|
-
import type {
|
|
2
|
+
import type { ReactNode } from 'react'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* What a UI module may add to the shell, per the slot table in `modules.md`.
|
|
@@ -68,22 +68,3 @@ export interface DashboardCard {
|
|
|
68
68
|
readonly render: () => ReactNode
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
export const INTEGRATION_CATEGORIES = [
|
|
72
|
-
'messaging',
|
|
73
|
-
'identity',
|
|
74
|
-
'enrichment',
|
|
75
|
-
'email',
|
|
76
|
-
'calendar',
|
|
77
|
-
] as const
|
|
78
|
-
|
|
79
|
-
export type IntegrationCategory = (typeof INTEGRATION_CATEGORIES)[number]
|
|
80
|
-
|
|
81
|
-
/** A catalog entry on the admin integrations page. Core owns the page and the connection lifecycle. */
|
|
82
|
-
export interface IntegrationProvider {
|
|
83
|
-
readonly id: string
|
|
84
|
-
readonly name: string
|
|
85
|
-
readonly category: IntegrationCategory
|
|
86
|
-
readonly description: string
|
|
87
|
-
/** Rendered on the provider's own settings panel once connected. */
|
|
88
|
-
readonly settings?: ComponentType<Record<string, never>>
|
|
89
|
-
}
|
package/src/registry/registry.ts
CHANGED
|
@@ -3,7 +3,6 @@ import type { ComponentType } from 'react'
|
|
|
3
3
|
import type {
|
|
4
4
|
DashboardCard,
|
|
5
5
|
ExtensibleRecordType,
|
|
6
|
-
IntegrationProvider,
|
|
7
6
|
NavItem,
|
|
8
7
|
NavSlot,
|
|
9
8
|
RecordSidebarCard,
|
|
@@ -32,7 +31,6 @@ export interface UiModuleContext {
|
|
|
32
31
|
recordTab(objectType: ExtensibleRecordType, tab: RecordTab): void
|
|
33
32
|
recordSidebarCard(objectType: ExtensibleRecordType, card: RecordSidebarCard): void
|
|
34
33
|
dashboardCard(card: DashboardCard): void
|
|
35
|
-
integrationProvider(provider: IntegrationProvider): void
|
|
36
34
|
/** Replaces a core component. Prefer a slot; see `modules.md`. */
|
|
37
35
|
override<Props>(token: Overridable<Props>, component: ComponentType<Props>): void
|
|
38
36
|
}
|
|
@@ -49,7 +47,6 @@ export interface UiExtensions {
|
|
|
49
47
|
recordTabs(objectType: ExtensibleRecordType): readonly RecordTab[]
|
|
50
48
|
recordSidebarCards(objectType: ExtensibleRecordType): readonly RecordSidebarCard[]
|
|
51
49
|
dashboardCards(): readonly DashboardCard[]
|
|
52
|
-
integrationProviders(): readonly IntegrationProvider[]
|
|
53
50
|
componentFor<Props>(token: Overridable<Props>): ComponentType<Props>
|
|
54
51
|
}
|
|
55
52
|
|
|
@@ -73,7 +70,6 @@ interface Accumulator {
|
|
|
73
70
|
readonly recordTabs: Map<ExtensibleRecordType, RecordTab[]>
|
|
74
71
|
readonly recordSidebarCards: Map<ExtensibleRecordType, RecordSidebarCard[]>
|
|
75
72
|
readonly dashboardCards: DashboardCard[]
|
|
76
|
-
readonly integrationProviders: IntegrationProvider[]
|
|
77
73
|
readonly overrides: OverrideStore
|
|
78
74
|
}
|
|
79
75
|
|
|
@@ -138,11 +134,6 @@ function createModuleContext(
|
|
|
138
134
|
accumulator.dashboardCards.push(card)
|
|
139
135
|
},
|
|
140
136
|
|
|
141
|
-
integrationProvider(provider) {
|
|
142
|
-
claim(taken, module.id, 'admin.integrations.catalog', provider.id)
|
|
143
|
-
accumulator.integrationProviders.push(provider)
|
|
144
|
-
},
|
|
145
|
-
|
|
146
137
|
override(token, component) {
|
|
147
138
|
if (accumulator.overrides.has(token.key)) {
|
|
148
139
|
throw new UiModuleError(
|
|
@@ -167,7 +158,6 @@ export function registerUiModules(modules: readonly UiModule[]): UiExtensions {
|
|
|
167
158
|
recordTabs: new Map(),
|
|
168
159
|
recordSidebarCards: new Map(),
|
|
169
160
|
dashboardCards: [],
|
|
170
|
-
integrationProviders: [],
|
|
171
161
|
overrides: createOverrideStore(),
|
|
172
162
|
}
|
|
173
163
|
const taken = new Set<string>()
|
|
@@ -189,7 +179,6 @@ export function registerUiModules(modules: readonly UiModule[]): UiExtensions {
|
|
|
189
179
|
recordSidebarCards: (objectType) =>
|
|
190
180
|
inSlotOrder(accumulator.recordSidebarCards.get(objectType) ?? []),
|
|
191
181
|
dashboardCards: () => inSlotOrder(accumulator.dashboardCards),
|
|
192
|
-
integrationProviders: () => accumulator.integrationProviders,
|
|
193
182
|
componentFor: (token) => accumulator.overrides.get(token),
|
|
194
183
|
}
|
|
195
184
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useModuleSettings } from '../api/resources/moduleSettings.ts'
|
|
2
|
+
import type { NavItem } from './contributions.ts'
|
|
3
|
+
import { inSlotOrder } from './registry.ts'
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Core's nav items merged with a slot's module contributions, ordered, with the
|
|
7
|
+
* entries belonging to a disabled module removed.
|
|
8
|
+
*
|
|
9
|
+
* One hook rather than the rule written out at each nav surface. The shell's
|
|
10
|
+
* sidebar and the account tab strip both render a slot, and a workspace that
|
|
11
|
+
* switched a module off should stop seeing it in both. Two copies of this
|
|
12
|
+
* filter is exactly the sort of pair that drifts, and the symptom is a tab that
|
|
13
|
+
* survives its module being disabled and leads to a page answering 403.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* A nav item whose id does not match its module id. Everything else looks itself
|
|
18
|
+
* up directly, which is what keeps a toggleable module's own nav entry working
|
|
19
|
+
* with no change here when one is added later.
|
|
20
|
+
*/
|
|
21
|
+
const NAV_ID_TO_MODULE_ID: Readonly<Record<string, string>> = {
|
|
22
|
+
fundraising: 'raises',
|
|
23
|
+
data: 'import-export',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export function useVisibleNavItems(
|
|
27
|
+
coreItems: readonly NavItem[],
|
|
28
|
+
moduleItems: readonly NavItem[],
|
|
29
|
+
): readonly NavItem[] {
|
|
30
|
+
const { settings } = useModuleSettings()
|
|
31
|
+
const disabledModuleIds = new Set(
|
|
32
|
+
settings.filter((setting) => !setting.enabled).map((setting) => setting.moduleId),
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
return inSlotOrder([...coreItems, ...moduleItems]).filter(
|
|
36
|
+
(item) => !disabledModuleIds.has(NAV_ID_TO_MODULE_ID[item.id] ?? item.id),
|
|
37
|
+
)
|
|
38
|
+
}
|