@kelpie/ui 0.8.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 +1 -1
- package/dist/api/resource.d.ts.map +1 -1
- package/dist/api/resource.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/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 +41 -0
- package/dist/api/resources/forms.js.map +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/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/sampleData.d.ts.map +1 -1
- package/dist/api/resources/sampleData.js +1 -0
- package/dist/api/resources/sampleData.js.map +1 -1
- package/dist/app/KelpieApp.d.ts.map +1 -1
- package/dist/app/KelpieApp.js +7 -1
- package/dist/app/KelpieApp.js.map +1 -1
- package/dist/components/ActivitiesPanel.d.ts.map +1 -1
- package/dist/components/ActivitiesPanel.js +1 -0
- package/dist/components/ActivitiesPanel.js.map +1 -1
- 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/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/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/Shell.d.ts.map +1 -1
- package/dist/components/Shell.js +3 -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/pages/CompanyDetail.d.ts.map +1 -1
- package/dist/pages/CompanyDetail.js +24 -2
- package/dist/pages/CompanyDetail.js.map +1 -1
- package/dist/pages/DealDetail.d.ts.map +1 -1
- package/dist/pages/DealDetail.js +18 -1
- package/dist/pages/DealDetail.js.map +1 -1
- package/dist/pages/DecisionsPage.d.ts.map +1 -1
- package/dist/pages/DecisionsPage.js +2 -0
- 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/ListDetail.d.ts.map +1 -1
- package/dist/pages/ListDetail.js +27 -1
- package/dist/pages/ListDetail.js.map +1 -1
- package/dist/pages/OpportunityDetail.d.ts.map +1 -1
- package/dist/pages/OpportunityDetail.js +62 -3
- package/dist/pages/OpportunityDetail.js.map +1 -1
- package/dist/pages/PartnershipDetail.d.ts.map +1 -1
- package/dist/pages/PartnershipDetail.js +17 -1
- package/dist/pages/PartnershipDetail.js.map +1 -1
- package/dist/pages/PeoplePage.d.ts.map +1 -1
- package/dist/pages/PeoplePage.js +17 -0
- package/dist/pages/PeoplePage.js.map +1 -1
- package/dist/pages/PersonDetail.d.ts.map +1 -1
- package/dist/pages/PersonDetail.js +63 -3
- package/dist/pages/PersonDetail.js.map +1 -1
- package/dist/pages/PlanningPage.d.ts.map +1 -1
- package/dist/pages/PlanningPage.js +3 -0
- package/dist/pages/PlanningPage.js.map +1 -1
- package/dist/pages/RaiseDetail.d.ts.map +1 -1
- package/dist/pages/RaiseDetail.js +11 -1
- package/dist/pages/RaiseDetail.js.map +1 -1
- package/dist/pages/RoleDetail.js +1 -1
- 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 +18 -3
- 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/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 +56 -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/onboarding/WorkspaceStepPage.js +1 -1
- package/dist/pages/onboarding/WorkspaceStepPage.js.map +1 -1
- package/package.json +2 -2
- package/src/api/resource.ts +6 -1
- package/src/api/resources/consentPurposes.ts +83 -0
- package/src/api/resources/customFields.ts +88 -0
- package/src/api/resources/enquiries.ts +118 -0
- package/src/api/resources/forms.ts +58 -0
- package/src/api/resources/importJobs.ts +9 -0
- package/src/api/resources/opportunities.ts +3 -0
- package/src/api/resources/sampleData.ts +1 -0
- package/src/app/KelpieApp.tsx +12 -0
- package/src/components/ActivitiesPanel.tsx +1 -0
- package/src/components/CustomFieldsPanel.tsx +330 -0
- package/src/components/FormsPanel.tsx +86 -0
- package/src/components/PlanAttention.tsx +20 -3
- package/src/components/Shell.tsx +3 -0
- package/src/components/useHasCustomFields.ts +18 -0
- package/src/pages/CompanyDetail.tsx +36 -1
- package/src/pages/DealDetail.tsx +31 -0
- package/src/pages/DecisionsPage.tsx +2 -0
- 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/ListDetail.tsx +62 -0
- package/src/pages/OpportunityDetail.tsx +165 -2
- package/src/pages/PartnershipDetail.tsx +32 -0
- package/src/pages/PeoplePage.tsx +20 -0
- package/src/pages/PersonDetail.tsx +152 -3
- package/src/pages/PlanningPage.tsx +3 -0
- package/src/pages/RaiseDetail.tsx +21 -0
- package/src/pages/RoleDetail.tsx +1 -1
- package/src/pages/SearchPage.tsx +1 -0
- package/src/pages/admin/DataPage.tsx +51 -3
- package/src/pages/admin/FieldsPage.tsx +455 -0
- package/src/pages/admin/PrivacyPage.tsx +461 -0
- 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 +109 -16
- package/src/pages/forms/fieldList.ts +68 -5
- package/src/pages/forms/template.ts +103 -0
- package/src/pages/onboarding/WorkspaceStepPage.tsx +1 -1
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Form } from '@kelpie/schemas'
|
|
2
|
+
import { useEffect, useId, useState } from 'react'
|
|
2
3
|
|
|
3
4
|
import { useFormEmbed } from '../../api/resources/forms.ts'
|
|
4
5
|
import { CopyButton } from '../../components/CopyButton.tsx'
|
|
@@ -12,14 +13,21 @@ import { SectionHeader } from '../../components/SectionHeader.tsx'
|
|
|
12
13
|
* embed page is served by the service, so its address depends on where the
|
|
13
14
|
* service is reached, which the server knows from the request and the browser
|
|
14
15
|
* only happens to share while the two are same-origin.
|
|
16
|
+
*
|
|
17
|
+
* Each iframe snippet has a Preview that opens the bare embed document in a
|
|
18
|
+
* modal — fields only, the same document the snippet iframes — fixed height for
|
|
19
|
+
* the plain iframe, auto-resize for the script variant.
|
|
15
20
|
*/
|
|
16
21
|
|
|
17
22
|
export interface EmbedPanelProps {
|
|
18
23
|
readonly form: Form
|
|
19
24
|
}
|
|
20
25
|
|
|
26
|
+
type PreviewMode = 'fixed' | 'resize'
|
|
27
|
+
|
|
21
28
|
export function EmbedPanel({ form }: EmbedPanelProps): React.JSX.Element {
|
|
22
29
|
const { snippets, isLoading, error } = useFormEmbed(form.id)
|
|
30
|
+
const [preview, setPreview] = useState<PreviewMode | null>(null)
|
|
23
31
|
|
|
24
32
|
if (error !== null) {
|
|
25
33
|
return <ErrorPanel error={error} />
|
|
@@ -33,7 +41,7 @@ export function EmbedPanel({ form }: EmbedPanelProps): React.JSX.Element {
|
|
|
33
41
|
<div className="max-w-2xl space-y-5">
|
|
34
42
|
<SectionHeader
|
|
35
43
|
title="Embed"
|
|
36
|
-
description="
|
|
44
|
+
description="Hosted page is the standalone URL with Kelpie chrome. The iframe snippets load a bare form — fields only — so they sit inside your own site."
|
|
37
45
|
/>
|
|
38
46
|
|
|
39
47
|
<div>
|
|
@@ -57,12 +65,31 @@ export function EmbedPanel({ form }: EmbedPanelProps): React.JSX.Element {
|
|
|
57
65
|
label="iframe"
|
|
58
66
|
hint="One tag, no JavaScript, fixed height."
|
|
59
67
|
value={snippets.iframeSnippet}
|
|
68
|
+
onPreview={() => {
|
|
69
|
+
setPreview('fixed')
|
|
70
|
+
}}
|
|
60
71
|
/>
|
|
61
72
|
<Snippet
|
|
62
73
|
label="iframe with auto-resize"
|
|
63
74
|
hint="Adds a listener that follows the page as fields appear and as the thank-you replaces the form."
|
|
64
75
|
value={snippets.scriptSnippet}
|
|
76
|
+
onPreview={() => {
|
|
77
|
+
setPreview('resize')
|
|
78
|
+
}}
|
|
65
79
|
/>
|
|
80
|
+
|
|
81
|
+
{preview !== null && (
|
|
82
|
+
<EmbedPreviewModal
|
|
83
|
+
formId={form.id}
|
|
84
|
+
formName={form.name}
|
|
85
|
+
formTitle={form.title}
|
|
86
|
+
url={snippets.embedUrl}
|
|
87
|
+
mode={preview}
|
|
88
|
+
onClose={() => {
|
|
89
|
+
setPreview(null)
|
|
90
|
+
}}
|
|
91
|
+
/>
|
|
92
|
+
)}
|
|
66
93
|
</div>
|
|
67
94
|
)
|
|
68
95
|
}
|
|
@@ -71,16 +98,27 @@ function Snippet({
|
|
|
71
98
|
label,
|
|
72
99
|
hint,
|
|
73
100
|
value,
|
|
101
|
+
onPreview,
|
|
74
102
|
}: {
|
|
75
103
|
readonly label: string
|
|
76
104
|
readonly hint: string
|
|
77
105
|
readonly value: string
|
|
106
|
+
readonly onPreview: () => void
|
|
78
107
|
}): React.JSX.Element {
|
|
79
108
|
return (
|
|
80
109
|
<div>
|
|
81
110
|
<div className="mb-1.5 flex items-center justify-between gap-2">
|
|
82
111
|
<span className="text-[12px] font-medium text-ink">{label}</span>
|
|
83
|
-
<
|
|
112
|
+
<div className="flex items-center gap-2">
|
|
113
|
+
<button
|
|
114
|
+
type="button"
|
|
115
|
+
onClick={onPreview}
|
|
116
|
+
className="rounded-md bg-accent px-3 py-1.5 text-[12px] font-semibold text-accent-fg transition hover:bg-accent-hover"
|
|
117
|
+
>
|
|
118
|
+
Preview
|
|
119
|
+
</button>
|
|
120
|
+
<CopyButton value={value} label={`Copy the ${label} snippet`} />
|
|
121
|
+
</div>
|
|
84
122
|
</div>
|
|
85
123
|
<textarea
|
|
86
124
|
readOnly
|
|
@@ -93,3 +131,126 @@ function Snippet({
|
|
|
93
131
|
</div>
|
|
94
132
|
)
|
|
95
133
|
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Frames the hosted embed the way each snippet would: fixed 720px for the plain
|
|
137
|
+
* iframe, or listening for the height postMessage when previewing auto-resize.
|
|
138
|
+
*/
|
|
139
|
+
function EmbedPreviewModal({
|
|
140
|
+
formId,
|
|
141
|
+
formName,
|
|
142
|
+
formTitle,
|
|
143
|
+
url,
|
|
144
|
+
mode,
|
|
145
|
+
onClose,
|
|
146
|
+
}: {
|
|
147
|
+
readonly formId: string
|
|
148
|
+
readonly formName: string
|
|
149
|
+
readonly formTitle: string
|
|
150
|
+
readonly url: string
|
|
151
|
+
readonly mode: PreviewMode
|
|
152
|
+
readonly onClose: () => void
|
|
153
|
+
}): React.JSX.Element {
|
|
154
|
+
const titleId = useId()
|
|
155
|
+
const heading = formTitle.trim().length > 0 ? formTitle : formName
|
|
156
|
+
const [height, setHeight] = useState(720)
|
|
157
|
+
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (mode !== 'resize') {
|
|
160
|
+
return
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
function onMessage(event: MessageEvent): void {
|
|
164
|
+
const data = event.data as { kelpie?: string; formId?: string; height?: number } | null
|
|
165
|
+
|
|
166
|
+
if (
|
|
167
|
+
data === null ||
|
|
168
|
+
typeof data !== 'object' ||
|
|
169
|
+
data.kelpie !== 'height' ||
|
|
170
|
+
data.formId !== formId ||
|
|
171
|
+
typeof data.height !== 'number' ||
|
|
172
|
+
!Number.isFinite(data.height)
|
|
173
|
+
) {
|
|
174
|
+
return
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
setHeight(Math.max(320, Math.ceil(data.height)))
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
window.addEventListener('message', onMessage)
|
|
181
|
+
|
|
182
|
+
return () => {
|
|
183
|
+
window.removeEventListener('message', onMessage)
|
|
184
|
+
}
|
|
185
|
+
}, [formId, mode])
|
|
186
|
+
|
|
187
|
+
useEffect(() => {
|
|
188
|
+
function onKeyDown(event: KeyboardEvent): void {
|
|
189
|
+
if (event.key === 'Escape') {
|
|
190
|
+
onClose()
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
window.addEventListener('keydown', onKeyDown)
|
|
195
|
+
|
|
196
|
+
return () => {
|
|
197
|
+
window.removeEventListener('keydown', onKeyDown)
|
|
198
|
+
}
|
|
199
|
+
}, [onClose])
|
|
200
|
+
|
|
201
|
+
return (
|
|
202
|
+
<div
|
|
203
|
+
className="fixed inset-0 z-50 flex items-end justify-center bg-ink/40 p-4 sm:items-center"
|
|
204
|
+
role="dialog"
|
|
205
|
+
aria-modal="true"
|
|
206
|
+
aria-labelledby={titleId}
|
|
207
|
+
onClick={onClose}
|
|
208
|
+
>
|
|
209
|
+
<div
|
|
210
|
+
className="animate-slide-in flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-md border border-border bg-surface-raised shadow-lg"
|
|
211
|
+
onClick={(event) => {
|
|
212
|
+
event.stopPropagation()
|
|
213
|
+
}}
|
|
214
|
+
>
|
|
215
|
+
<div className="flex shrink-0 items-start justify-between gap-3 border-b border-border px-4 py-3">
|
|
216
|
+
<div className="min-w-0">
|
|
217
|
+
<h2 id={titleId} className="truncate text-[14px] font-semibold text-ink">
|
|
218
|
+
Preview · {heading}
|
|
219
|
+
</h2>
|
|
220
|
+
<p className="mt-0.5 text-[11px] text-ink-faint">
|
|
221
|
+
{mode === 'resize'
|
|
222
|
+
? 'Bare iframe embed with auto-resize — fields only, height follows the form.'
|
|
223
|
+
: 'Bare iframe embed — fields only, fixed height.'}
|
|
224
|
+
</p>
|
|
225
|
+
</div>
|
|
226
|
+
<button
|
|
227
|
+
type="button"
|
|
228
|
+
onClick={onClose}
|
|
229
|
+
className="shrink-0 rounded-md px-2 py-1 text-[12px] font-medium text-ink-muted transition hover:text-ink"
|
|
230
|
+
>
|
|
231
|
+
Close
|
|
232
|
+
</button>
|
|
233
|
+
</div>
|
|
234
|
+
|
|
235
|
+
<div className="min-h-0 flex-1 overflow-y-auto bg-[#f4f4f5] p-4">
|
|
236
|
+
<div className="overflow-hidden rounded-md border border-[#d4d4d8] bg-white shadow-sm">
|
|
237
|
+
<iframe
|
|
238
|
+
src={url}
|
|
239
|
+
title={`${heading} preview`}
|
|
240
|
+
style={{
|
|
241
|
+
width: '100%',
|
|
242
|
+
border: 0,
|
|
243
|
+
height: mode === 'fixed' ? '720px' : `${String(height)}px`,
|
|
244
|
+
colorScheme: 'normal',
|
|
245
|
+
}}
|
|
246
|
+
className="block bg-transparent"
|
|
247
|
+
/>
|
|
248
|
+
</div>
|
|
249
|
+
<p className="mt-2 text-center text-[11px] text-ink-faint">
|
|
250
|
+
Simulated host page — the iframe uses its own neutral styles, not Kelpie's.
|
|
251
|
+
</p>
|
|
252
|
+
</div>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
)
|
|
256
|
+
}
|