@squaredr/fieldcraft-pro 1.6.4 → 1.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/LICENSE.txt +51 -51
- package/README.md +139 -139
- package/dist/{chunk-VECQKSWS.mjs → chunk-4MMKB2EW.mjs} +60 -86
- package/dist/{chunk-CFVT2R42.mjs → chunk-CYXJGOQH.mjs} +904 -206
- package/dist/{chunk-ANBMT5AW.mjs → chunk-GXKQCXIB.mjs} +470 -228
- package/dist/chunk-IW654Z3M.mjs +1108 -0
- package/dist/{chunk-5LKGCZAW.mjs → chunk-MLP5EDWP.mjs} +167 -178
- package/dist/form-builder/index.d.mts +176 -6
- package/dist/form-builder/index.d.ts +176 -6
- package/dist/form-builder/index.js +604 -365
- package/dist/form-builder/index.mjs +2 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +3221 -984
- package/dist/index.mjs +332 -125
- package/dist/response-viewer/index.d.mts +1 -1
- package/dist/response-viewer/index.d.ts +1 -1
- package/dist/response-viewer/index.js +169 -204
- package/dist/response-viewer/index.mjs +2 -2
- package/dist/styles.css +1 -1
- package/dist/templates/index.d.mts +43 -0
- package/dist/templates/index.d.ts +43 -0
- package/dist/templates/index.js +1116 -0
- package/dist/templates/index.mjs +1 -0
- package/dist/theme-editor/index.d.mts +11 -5
- package/dist/theme-editor/index.d.ts +11 -5
- package/dist/theme-editor/index.js +907 -232
- package/dist/theme-editor/index.mjs +2 -2
- package/dist/types-bFHsZT1n.d.mts +217 -0
- package/dist/types-bFHsZT1n.d.ts +217 -0
- package/package.json +23 -11
- package/theme-editor/styles.css +468 -466
- package/dist/index-D19524df.d.mts +0 -387
- package/dist/index-D19524df.d.ts +0 -387
|
@@ -7,27 +7,6 @@ var clsx = require('clsx');
|
|
|
7
7
|
var tailwindMerge = require('tailwind-merge');
|
|
8
8
|
|
|
9
9
|
// ../license/dist/index.mjs
|
|
10
|
-
var PRO_FEATURES = [
|
|
11
|
-
"SchemaEditor",
|
|
12
|
-
"ResponseViewer",
|
|
13
|
-
"ThemeEditor",
|
|
14
|
-
"FormBuilder",
|
|
15
|
-
"ApiManager",
|
|
16
|
-
"Analytics"
|
|
17
|
-
];
|
|
18
|
-
var ALL_FEATURES = [
|
|
19
|
-
...PRO_FEATURES,
|
|
20
|
-
"Telehealth"
|
|
21
|
-
];
|
|
22
|
-
var TIER_FEATURES = {
|
|
23
|
-
starter: ["SchemaEditor", "ResponseViewer"],
|
|
24
|
-
pro: PRO_FEATURES,
|
|
25
|
-
business: ALL_FEATURES,
|
|
26
|
-
enterprise: ALL_FEATURES
|
|
27
|
-
};
|
|
28
|
-
function tierHasFeature(tier, featureName) {
|
|
29
|
-
return TIER_FEATURES[tier]?.includes(featureName) ?? false;
|
|
30
|
-
}
|
|
31
10
|
var DEV_HOSTNAMES = /* @__PURE__ */ new Set([
|
|
32
11
|
"localhost",
|
|
33
12
|
"127.0.0.1",
|
|
@@ -99,7 +78,8 @@ function isProductionEnvironment() {
|
|
|
99
78
|
}
|
|
100
79
|
return false;
|
|
101
80
|
}
|
|
102
|
-
|
|
81
|
+
typeof process !== "undefined" && process.env?.NEXT_PUBLIC_FCPRO_PING_URL || "https://fieldcraft.dev/api/license/ping";
|
|
82
|
+
var defaultContext = { status: "validating" };
|
|
103
83
|
var LicenseCtx = react.createContext(defaultContext);
|
|
104
84
|
function useLicense() {
|
|
105
85
|
return react.useContext(LicenseCtx);
|
|
@@ -299,7 +279,7 @@ function UnlicensedOverlay({ featureName, reason, children }) {
|
|
|
299
279
|
}
|
|
300
280
|
function requireLicense(Component, featureName) {
|
|
301
281
|
function LicenseGated(props) {
|
|
302
|
-
const { status
|
|
282
|
+
const { status } = useLicense();
|
|
303
283
|
const isProduction = isProductionEnvironment();
|
|
304
284
|
if (!isProduction) {
|
|
305
285
|
return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props });
|
|
@@ -307,8 +287,7 @@ function requireLicense(Component, featureName) {
|
|
|
307
287
|
if (status === "validating") {
|
|
308
288
|
return null;
|
|
309
289
|
}
|
|
310
|
-
|
|
311
|
-
if (isLicensed) {
|
|
290
|
+
if (status === "valid") {
|
|
312
291
|
return /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props });
|
|
313
292
|
}
|
|
314
293
|
let reason = "A valid license is required for production use.";
|
|
@@ -320,14 +299,127 @@ function requireLicense(Component, featureName) {
|
|
|
320
299
|
reason = "This license key has been revoked. Please contact support or purchase a new license.";
|
|
321
300
|
} else if (status === "domain_mismatch") {
|
|
322
301
|
reason = "This license key is registered to a different domain. Each key can only be used on one production domain. Please purchase a new license for this domain.";
|
|
323
|
-
} else if (!tier || !tierHasFeature(tier, featureName)) {
|
|
324
|
-
reason = "Your license does not include this feature. Please upgrade your plan.";
|
|
325
302
|
}
|
|
326
303
|
return /* @__PURE__ */ jsxRuntime.jsx(UnlicensedOverlay, { featureName, reason, children: /* @__PURE__ */ jsxRuntime.jsx(Component, { ...props }) });
|
|
327
304
|
}
|
|
328
305
|
LicenseGated.displayName = `requireLicense(${Component.displayName || Component.name || "Component"})`;
|
|
329
306
|
return LicenseGated;
|
|
330
307
|
}
|
|
308
|
+
function formatDuration(ms) {
|
|
309
|
+
if (ms == null) return "\u2014";
|
|
310
|
+
const totalSeconds = Math.round(ms / 1e3);
|
|
311
|
+
if (totalSeconds < 60) return `${totalSeconds}s`;
|
|
312
|
+
const minutes = Math.floor(totalSeconds / 60);
|
|
313
|
+
const seconds = totalSeconds % 60;
|
|
314
|
+
return `${minutes}m ${seconds}s`;
|
|
315
|
+
}
|
|
316
|
+
function countAnswered(values) {
|
|
317
|
+
let count = 0;
|
|
318
|
+
for (const v of Object.values(values)) {
|
|
319
|
+
if (v !== void 0 && v !== null && v !== "") count++;
|
|
320
|
+
}
|
|
321
|
+
return count;
|
|
322
|
+
}
|
|
323
|
+
function getTotalFieldCount(schema) {
|
|
324
|
+
let count = 0;
|
|
325
|
+
for (const section of schema.sections) {
|
|
326
|
+
for (const q of section.questions) {
|
|
327
|
+
if (!DISPLAY_ONLY_TYPES.has(q.type)) count++;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
return count;
|
|
331
|
+
}
|
|
332
|
+
function ResponseTable({
|
|
333
|
+
schema,
|
|
334
|
+
responses,
|
|
335
|
+
onRowClick,
|
|
336
|
+
selectable,
|
|
337
|
+
selectedIds,
|
|
338
|
+
onToggleSelect,
|
|
339
|
+
onSelectAll
|
|
340
|
+
}) {
|
|
341
|
+
const totalFields = getTotalFieldCount(schema);
|
|
342
|
+
const allPageSelected = selectable && responses.length > 0 && responses.every(
|
|
343
|
+
(r) => r.sessionToken && selectedIds?.has(r.sessionToken)
|
|
344
|
+
);
|
|
345
|
+
const colCount = 4 + (selectable ? 1 : 0);
|
|
346
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-[13px]", children: [
|
|
347
|
+
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "bg-muted", children: [
|
|
348
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 w-8 border-b-2 border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
349
|
+
"input",
|
|
350
|
+
{
|
|
351
|
+
type: "checkbox",
|
|
352
|
+
checked: allPageSelected,
|
|
353
|
+
onChange: () => onSelectAll?.(),
|
|
354
|
+
className: "accent-primary"
|
|
355
|
+
}
|
|
356
|
+
) }),
|
|
357
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-foreground border-b-2 border-border whitespace-nowrap", children: "Submitted" }),
|
|
358
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-foreground border-b-2 border-border whitespace-nowrap", children: "Completion Time" }),
|
|
359
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-foreground border-b-2 border-border whitespace-nowrap", children: "Fields Answered" }),
|
|
360
|
+
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-foreground border-b-2 border-border whitespace-nowrap", children: "Score" })
|
|
361
|
+
] }) }),
|
|
362
|
+
/* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
|
|
363
|
+
responses.map((response, idx) => {
|
|
364
|
+
const answered = countAnswered(response.values);
|
|
365
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
366
|
+
"tr",
|
|
367
|
+
{
|
|
368
|
+
onClick: () => onRowClick?.(response),
|
|
369
|
+
className: onRowClick ? "cursor-pointer border-b border-border hover:bg-accent transition-colors" : "border-b border-border",
|
|
370
|
+
children: [
|
|
371
|
+
selectable && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 w-8", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
372
|
+
"input",
|
|
373
|
+
{
|
|
374
|
+
type: "checkbox",
|
|
375
|
+
checked: !!(response.sessionToken && selectedIds?.has(response.sessionToken)),
|
|
376
|
+
onChange: (e) => {
|
|
377
|
+
e.stopPropagation();
|
|
378
|
+
if (response.sessionToken) onToggleSelect?.(response.sessionToken);
|
|
379
|
+
},
|
|
380
|
+
onClick: (e) => e.stopPropagation(),
|
|
381
|
+
className: "accent-primary"
|
|
382
|
+
}
|
|
383
|
+
) }),
|
|
384
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 text-foreground whitespace-nowrap", children: new Date(response.submittedAt).toLocaleString() }),
|
|
385
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 text-foreground whitespace-nowrap", children: formatDuration(response.completionTimeMs) }),
|
|
386
|
+
/* @__PURE__ */ jsxRuntime.jsxs("td", { className: "px-3 py-2 text-foreground whitespace-nowrap", children: [
|
|
387
|
+
answered,
|
|
388
|
+
"/",
|
|
389
|
+
totalFields
|
|
390
|
+
] }),
|
|
391
|
+
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 text-foreground whitespace-nowrap", children: response.totalScore ?? "\u2014" })
|
|
392
|
+
]
|
|
393
|
+
},
|
|
394
|
+
response.sessionToken || idx
|
|
395
|
+
);
|
|
396
|
+
}),
|
|
397
|
+
responses.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
398
|
+
"td",
|
|
399
|
+
{
|
|
400
|
+
colSpan: colCount,
|
|
401
|
+
className: "px-3 py-8 text-center text-muted-foreground",
|
|
402
|
+
children: "No responses yet"
|
|
403
|
+
}
|
|
404
|
+
) })
|
|
405
|
+
] })
|
|
406
|
+
] }) });
|
|
407
|
+
}
|
|
408
|
+
var DISPLAY_ONLY_TYPES = /* @__PURE__ */ new Set([
|
|
409
|
+
"info-block",
|
|
410
|
+
"info_block",
|
|
411
|
+
"section-header",
|
|
412
|
+
"page-break",
|
|
413
|
+
"image",
|
|
414
|
+
"divider",
|
|
415
|
+
"spacer",
|
|
416
|
+
"video",
|
|
417
|
+
"rich-text",
|
|
418
|
+
"welcome-screen",
|
|
419
|
+
"thank-you-screen",
|
|
420
|
+
"hidden",
|
|
421
|
+
"calculated"
|
|
422
|
+
]);
|
|
331
423
|
|
|
332
424
|
// src/response-viewer/clinical-display-data.ts
|
|
333
425
|
var BODY_REGION_LABELS = {
|
|
@@ -465,166 +557,6 @@ function getScoreSeverity(instrumentKey, score) {
|
|
|
465
557
|
if (!thresholds) return void 0;
|
|
466
558
|
return thresholds.find((t) => score >= t.min && score <= t.max);
|
|
467
559
|
}
|
|
468
|
-
function ResponseTable({
|
|
469
|
-
schema,
|
|
470
|
-
responses,
|
|
471
|
-
onRowClick,
|
|
472
|
-
selectable,
|
|
473
|
-
selectedIds,
|
|
474
|
-
onToggleSelect,
|
|
475
|
-
onSelectAll
|
|
476
|
-
}) {
|
|
477
|
-
const questions = getAllQuestions(schema);
|
|
478
|
-
const allPageSelected = selectable && responses.length > 0 && responses.every(
|
|
479
|
-
(r) => r.sessionToken && selectedIds?.has(r.sessionToken)
|
|
480
|
-
);
|
|
481
|
-
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "overflow-auto", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { className: "w-full border-collapse text-[13px]", children: [
|
|
482
|
-
/* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { className: "bg-muted", children: [
|
|
483
|
-
selectable && /* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 w-8 border-b-2 border-border", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
484
|
-
"input",
|
|
485
|
-
{
|
|
486
|
-
type: "checkbox",
|
|
487
|
-
checked: allPageSelected,
|
|
488
|
-
onChange: () => onSelectAll?.(),
|
|
489
|
-
className: "accent-primary"
|
|
490
|
-
}
|
|
491
|
-
) }),
|
|
492
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-foreground border-b-2 border-border whitespace-nowrap", children: "Submitted" }),
|
|
493
|
-
questions.map((q) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
494
|
-
"th",
|
|
495
|
-
{
|
|
496
|
-
className: "px-3 py-2 text-left font-semibold text-foreground border-b-2 border-border whitespace-nowrap",
|
|
497
|
-
children: q.label
|
|
498
|
-
},
|
|
499
|
-
q.id
|
|
500
|
-
)),
|
|
501
|
-
/* @__PURE__ */ jsxRuntime.jsx("th", { className: "px-3 py-2 text-left font-semibold text-foreground border-b-2 border-border whitespace-nowrap", children: "Score" })
|
|
502
|
-
] }) }),
|
|
503
|
-
/* @__PURE__ */ jsxRuntime.jsxs("tbody", { children: [
|
|
504
|
-
responses.map((response, idx) => /* @__PURE__ */ jsxRuntime.jsxs(
|
|
505
|
-
"tr",
|
|
506
|
-
{
|
|
507
|
-
onClick: () => onRowClick?.(response),
|
|
508
|
-
className: onRowClick ? "cursor-pointer border-b border-border hover:bg-accent transition-colors" : "border-b border-border",
|
|
509
|
-
children: [
|
|
510
|
-
selectable && /* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 w-8", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
511
|
-
"input",
|
|
512
|
-
{
|
|
513
|
-
type: "checkbox",
|
|
514
|
-
checked: !!(response.sessionToken && selectedIds?.has(response.sessionToken)),
|
|
515
|
-
onChange: (e) => {
|
|
516
|
-
e.stopPropagation();
|
|
517
|
-
if (response.sessionToken) onToggleSelect?.(response.sessionToken);
|
|
518
|
-
},
|
|
519
|
-
onClick: (e) => e.stopPropagation(),
|
|
520
|
-
className: "accent-primary"
|
|
521
|
-
}
|
|
522
|
-
) }),
|
|
523
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 text-foreground max-w-50 overflow-hidden text-ellipsis whitespace-nowrap", children: new Date(response.submittedAt).toLocaleString() }),
|
|
524
|
-
questions.map((q) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
525
|
-
"td",
|
|
526
|
-
{
|
|
527
|
-
className: "px-3 py-2 text-foreground max-w-50 overflow-hidden text-ellipsis whitespace-nowrap",
|
|
528
|
-
children: formatCellValue(response.values[q.id], q.type)
|
|
529
|
-
},
|
|
530
|
-
q.id
|
|
531
|
-
)),
|
|
532
|
-
/* @__PURE__ */ jsxRuntime.jsx("td", { className: "px-3 py-2 text-foreground max-w-50 overflow-hidden text-ellipsis whitespace-nowrap", children: response.totalScore ?? "\u2014" })
|
|
533
|
-
]
|
|
534
|
-
},
|
|
535
|
-
response.sessionToken || idx
|
|
536
|
-
)),
|
|
537
|
-
responses.length === 0 && /* @__PURE__ */ jsxRuntime.jsx("tr", { children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
538
|
-
"td",
|
|
539
|
-
{
|
|
540
|
-
colSpan: questions.length + 2 + (selectable ? 1 : 0),
|
|
541
|
-
className: "px-3 py-8 text-center text-muted-foreground",
|
|
542
|
-
children: "No responses yet"
|
|
543
|
-
}
|
|
544
|
-
) })
|
|
545
|
-
] })
|
|
546
|
-
] }) });
|
|
547
|
-
}
|
|
548
|
-
function getAllQuestions(schema) {
|
|
549
|
-
const questions = [];
|
|
550
|
-
for (const section of schema.sections) {
|
|
551
|
-
for (const q of section.questions) {
|
|
552
|
-
if (q.type === "info-block" || q.type === "section-header" || q.type === "page-break") {
|
|
553
|
-
continue;
|
|
554
|
-
}
|
|
555
|
-
questions.push(q);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
return questions;
|
|
559
|
-
}
|
|
560
|
-
function formatCellValue(value, type) {
|
|
561
|
-
if (value == null) return "\u2014";
|
|
562
|
-
if (type) {
|
|
563
|
-
switch (type) {
|
|
564
|
-
case "vitals_entry": {
|
|
565
|
-
if (typeof value !== "object" || value === null) break;
|
|
566
|
-
const v = value;
|
|
567
|
-
const parts = [];
|
|
568
|
-
if (v.systolicBp && v.diastolicBp) parts.push(`BP ${v.systolicBp}/${v.diastolicBp}`);
|
|
569
|
-
if (v.heartRate) parts.push(`HR ${v.heartRate}`);
|
|
570
|
-
if (v.temperature) parts.push(`${v.temperature}\xB0F`);
|
|
571
|
-
if (v.oxygenSaturation) parts.push(`SpO\u2082 ${v.oxygenSaturation}%`);
|
|
572
|
-
return parts.length > 0 ? parts.join(", ") : "\u2014";
|
|
573
|
-
}
|
|
574
|
-
case "medication_list":
|
|
575
|
-
if (Array.isArray(value)) return `${value.length} medication${value.length !== 1 ? "s" : ""}`;
|
|
576
|
-
break;
|
|
577
|
-
case "allergy_list":
|
|
578
|
-
if (Array.isArray(value)) return `${value.length} allerg${value.length !== 1 ? "ies" : "y"}`;
|
|
579
|
-
break;
|
|
580
|
-
case "body_diagram":
|
|
581
|
-
if (Array.isArray(value)) {
|
|
582
|
-
const labels = value.map((id) => BODY_REGION_LABELS[id] ?? id);
|
|
583
|
-
return labels.join(", ");
|
|
584
|
-
}
|
|
585
|
-
break;
|
|
586
|
-
case "pain_scale":
|
|
587
|
-
if (typeof value === "number") return `${value}/10`;
|
|
588
|
-
break;
|
|
589
|
-
case "bmi_calculator": {
|
|
590
|
-
if (typeof value !== "object" || value === null) break;
|
|
591
|
-
const d = value;
|
|
592
|
-
if (d.bmi != null) return `BMI ${d.bmi}`;
|
|
593
|
-
break;
|
|
594
|
-
}
|
|
595
|
-
case "payment": {
|
|
596
|
-
if (typeof value !== "object" || value === null) break;
|
|
597
|
-
const p = value;
|
|
598
|
-
const status = p.status;
|
|
599
|
-
return status ? status.charAt(0).toUpperCase() + status.slice(1) : "\u2014";
|
|
600
|
-
}
|
|
601
|
-
case "insurance_card": {
|
|
602
|
-
if (typeof value !== "object" || value === null) break;
|
|
603
|
-
const ins = value;
|
|
604
|
-
const parts = [ins.carrierId, ins.planName].filter(Boolean);
|
|
605
|
-
return parts.length > 0 ? parts.join(" \u2014 ") : "Card uploaded";
|
|
606
|
-
}
|
|
607
|
-
case "legal_name": {
|
|
608
|
-
if (typeof value !== "object" || value === null) break;
|
|
609
|
-
const n = value;
|
|
610
|
-
return [n.first, n.last].filter(Boolean).join(" ") || "\u2014";
|
|
611
|
-
}
|
|
612
|
-
case "address": {
|
|
613
|
-
if (typeof value !== "object" || value === null) break;
|
|
614
|
-
const a = value;
|
|
615
|
-
return [a.city, a.state].filter(Boolean).join(", ") || "\u2014";
|
|
616
|
-
}
|
|
617
|
-
case "consent":
|
|
618
|
-
return value === true || value === "true" || value === "agreed" ? "Agreed" : "Not agreed";
|
|
619
|
-
case "signature":
|
|
620
|
-
return typeof value === "string" && value.startsWith("data:image") ? "Signed" : "\u2014";
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
if (typeof value === "boolean") return value ? "Yes" : "No";
|
|
624
|
-
if (Array.isArray(value)) return value.join(", ");
|
|
625
|
-
if (typeof value === "object") return JSON.stringify(value);
|
|
626
|
-
return String(value);
|
|
627
|
-
}
|
|
628
560
|
function ResponseCard({
|
|
629
561
|
response,
|
|
630
562
|
fields,
|
|
@@ -1622,13 +1554,26 @@ function exportToJson(responses, filename = "responses.json") {
|
|
|
1622
1554
|
const content = JSON.stringify(responses, null, 2);
|
|
1623
1555
|
downloadBlob(content, filename, "application/json;charset=utf-8;");
|
|
1624
1556
|
}
|
|
1557
|
+
var DISPLAY_ONLY_TYPES2 = /* @__PURE__ */ new Set([
|
|
1558
|
+
"info-block",
|
|
1559
|
+
"info_block",
|
|
1560
|
+
"section-header",
|
|
1561
|
+
"page-break",
|
|
1562
|
+
"image",
|
|
1563
|
+
"divider",
|
|
1564
|
+
"spacer",
|
|
1565
|
+
"video",
|
|
1566
|
+
"rich-text",
|
|
1567
|
+
"welcome-screen",
|
|
1568
|
+
"thank-you-screen",
|
|
1569
|
+
"hidden",
|
|
1570
|
+
"calculated"
|
|
1571
|
+
]);
|
|
1625
1572
|
function getExportableQuestions(schema) {
|
|
1626
1573
|
const questions = [];
|
|
1627
1574
|
for (const section of schema.sections) {
|
|
1628
1575
|
for (const q of section.questions) {
|
|
1629
|
-
if (
|
|
1630
|
-
continue;
|
|
1631
|
-
}
|
|
1576
|
+
if (DISPLAY_ONLY_TYPES2.has(q.type)) continue;
|
|
1632
1577
|
questions.push(q);
|
|
1633
1578
|
}
|
|
1634
1579
|
}
|
|
@@ -1694,6 +1639,10 @@ function formatExportValue(value, type) {
|
|
|
1694
1639
|
return String(value);
|
|
1695
1640
|
}
|
|
1696
1641
|
function escapeCsvField(field) {
|
|
1642
|
+
const first = field.charAt(0);
|
|
1643
|
+
if (first === "=" || first === "+" || first === "-" || first === "@" || first === " " || first === "\r") {
|
|
1644
|
+
field = `'${field}`;
|
|
1645
|
+
}
|
|
1697
1646
|
if (field.includes(",") || field.includes('"') || field.includes("\n")) {
|
|
1698
1647
|
return `"${field.replace(/"/g, '""')}"`;
|
|
1699
1648
|
}
|
|
@@ -1708,7 +1657,7 @@ function downloadBlob(content, filename, mimeType) {
|
|
|
1708
1657
|
document.body.appendChild(link);
|
|
1709
1658
|
link.click();
|
|
1710
1659
|
document.body.removeChild(link);
|
|
1711
|
-
URL.revokeObjectURL(url);
|
|
1660
|
+
setTimeout(() => URL.revokeObjectURL(url), 1e4);
|
|
1712
1661
|
}
|
|
1713
1662
|
|
|
1714
1663
|
// src/response-viewer/pagination-utils.ts
|
|
@@ -1944,9 +1893,12 @@ function ResponseViewerInner({
|
|
|
1944
1893
|
[responses, searchQuery, schema]
|
|
1945
1894
|
);
|
|
1946
1895
|
const isFiltered = hasActiveFilters(filterState);
|
|
1947
|
-
const filteredResponses =
|
|
1896
|
+
const filteredResponses = react.useMemo(
|
|
1897
|
+
() => applyFilters(searchedResponses, filterState),
|
|
1898
|
+
[searchedResponses, filterState]
|
|
1899
|
+
);
|
|
1948
1900
|
const pag = paginate(filteredResponses, currentPage, effectivePageSize);
|
|
1949
|
-
const questions =
|
|
1901
|
+
const questions = getAllQuestions(schema);
|
|
1950
1902
|
const isSelectable = selectable && (!!onBulkDelete || !!onBulkExport);
|
|
1951
1903
|
function handleSelect(response) {
|
|
1952
1904
|
setSelectedResponse(response);
|
|
@@ -2048,7 +2000,7 @@ function ResponseViewerInner({
|
|
|
2048
2000
|
});
|
|
2049
2001
|
}
|
|
2050
2002
|
function getFields(response) {
|
|
2051
|
-
return questions.map((q) => ({
|
|
2003
|
+
return questions.filter((q) => response.values[q.id] !== void 0).map((q) => ({
|
|
2052
2004
|
questionId: q.id,
|
|
2053
2005
|
label: q.label,
|
|
2054
2006
|
type: q.type,
|
|
@@ -2201,10 +2153,10 @@ function ResponseViewerInner({
|
|
|
2201
2153
|
className: "h-7 text-xs",
|
|
2202
2154
|
onClick: () => {
|
|
2203
2155
|
const csvFilename = filename ? filename.replace(/\.\w+$/, ".csv") : "responses.csv";
|
|
2204
|
-
exportToCsv(schema,
|
|
2205
|
-
onExport?.("csv",
|
|
2156
|
+
exportToCsv(schema, filteredResponses, csvFilename, { dateFormat, columnLabels });
|
|
2157
|
+
onExport?.("csv", filteredResponses.length);
|
|
2206
2158
|
},
|
|
2207
|
-
disabled:
|
|
2159
|
+
disabled: filteredResponses.length === 0,
|
|
2208
2160
|
children: "Export CSV"
|
|
2209
2161
|
}
|
|
2210
2162
|
),
|
|
@@ -2216,10 +2168,10 @@ function ResponseViewerInner({
|
|
|
2216
2168
|
className: "h-7 text-xs",
|
|
2217
2169
|
onClick: () => {
|
|
2218
2170
|
const jsonFilename = filename ? filename.replace(/\.\w+$/, ".json") : "responses.json";
|
|
2219
|
-
exportToJson(
|
|
2220
|
-
onExport?.("json",
|
|
2171
|
+
exportToJson(filteredResponses, jsonFilename);
|
|
2172
|
+
onExport?.("json", filteredResponses.length);
|
|
2221
2173
|
},
|
|
2222
|
-
disabled:
|
|
2174
|
+
disabled: filteredResponses.length === 0,
|
|
2223
2175
|
children: "Export JSON"
|
|
2224
2176
|
}
|
|
2225
2177
|
)
|
|
@@ -2500,13 +2452,26 @@ function ResponseViewerInner({
|
|
|
2500
2452
|
}
|
|
2501
2453
|
);
|
|
2502
2454
|
}
|
|
2503
|
-
|
|
2455
|
+
var DISPLAY_ONLY_TYPES3 = /* @__PURE__ */ new Set([
|
|
2456
|
+
"info-block",
|
|
2457
|
+
"info_block",
|
|
2458
|
+
"section-header",
|
|
2459
|
+
"page-break",
|
|
2460
|
+
"image",
|
|
2461
|
+
"divider",
|
|
2462
|
+
"spacer",
|
|
2463
|
+
"video",
|
|
2464
|
+
"rich-text",
|
|
2465
|
+
"welcome-screen",
|
|
2466
|
+
"thank-you-screen",
|
|
2467
|
+
"hidden",
|
|
2468
|
+
"calculated"
|
|
2469
|
+
]);
|
|
2470
|
+
function getAllQuestions(schema) {
|
|
2504
2471
|
const questions = [];
|
|
2505
2472
|
for (const section of schema.sections) {
|
|
2506
2473
|
for (const q of section.questions) {
|
|
2507
|
-
if (
|
|
2508
|
-
continue;
|
|
2509
|
-
}
|
|
2474
|
+
if (DISPLAY_ONLY_TYPES3.has(q.type)) continue;
|
|
2510
2475
|
questions.push(q);
|
|
2511
2476
|
}
|
|
2512
2477
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { ResponseViewer } from '../chunk-
|
|
1
|
+
export { ResponseViewer } from '../chunk-MLP5EDWP.mjs';
|
|
2
2
|
import '../chunk-QQ4JZGTD.mjs';
|
|
3
|
-
import '../chunk-
|
|
3
|
+
import '../chunk-4MMKB2EW.mjs';
|