@fayz-ai/plugin-reports 0.12.0 → 0.12.2
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/{chunk-5SO5HWV2.js → chunk-4QIHTUXD.js} +60 -5
- package/dist/chunk-4QIHTUXD.js.map +1 -0
- package/dist/components/ExportDropdown.d.ts +7 -1
- package/dist/components/ExportDropdown.d.ts.map +1 -1
- package/dist/{excel-LDM5H5IW.js → excel-DSORXL4O.js} +6 -5
- package/dist/excel-DSORXL4O.js.map +1 -0
- package/dist/export/csv.d.ts.map +1 -1
- package/dist/export/excel.d.ts.map +1 -1
- package/dist/index.js +37 -19
- package/dist/index.js.map +1 -1
- package/dist/lib/columns.d.ts +27 -0
- package/dist/lib/columns.d.ts.map +1 -1
- package/dist/{pdf-XA2AR6B4.js → pdf-DH4CJMV5.js} +3 -3
- package/dist/{pdf-XA2AR6B4.js.map → pdf-DH4CJMV5.js.map} +1 -1
- package/dist/types.d.ts +5 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/views/AnalyticsReportViewer.d.ts.map +1 -1
- package/package.json +6 -5
- package/dist/chunk-5SO5HWV2.js.map +0 -1
- package/dist/excel-LDM5H5IW.js.map +0 -1
package/dist/lib/columns.d.ts
CHANGED
|
@@ -1,5 +1,32 @@
|
|
|
1
1
|
import type { ColumnDef } from '@tanstack/react-table';
|
|
2
2
|
import type { ReportColumnDef } from '../types';
|
|
3
|
+
/** A single cell value as text, whatever shape it arrived in. Arrays join, an
|
|
4
|
+
* open bag prints as "Chave: valor · Chave: valor" — never "[object Object]",
|
|
5
|
+
* which is what a JSON column looked like in a spreadsheet. */
|
|
6
|
+
export declare function plainValue(value: any): string;
|
|
7
|
+
/** `hair_remaining` / `hairRemaining` → "Hair remaining". A key that arrives
|
|
8
|
+
* already humanized ("Estilo") comes back unchanged. */
|
|
9
|
+
export declare function humanizeKey(key: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Expand every `expand` column into one column PER KEY found in the rows, and
|
|
12
|
+
* flatten those keys onto the rows so no consumer needs a special case.
|
|
13
|
+
*
|
|
14
|
+
* The keys cannot be declared on the card — each landing page asks something
|
|
15
|
+
* different, and typing them here would make the NEXT form invisible. So they
|
|
16
|
+
* are discovered from the rows themselves, in first-seen order, and the bag
|
|
17
|
+
* column steps aside. "Estilo" as a real column can be read down and sorted;
|
|
18
|
+
* "Estilo: House · Perfil: Outros" crammed into one cell cannot, and a raw JSON
|
|
19
|
+
* blob is worse still.
|
|
20
|
+
*
|
|
21
|
+
* Used by the report table AND by the writers, so the screen and the file show
|
|
22
|
+
* the same columns.
|
|
23
|
+
*
|
|
24
|
+
* Columns that are not `expand` pass through untouched, order included.
|
|
25
|
+
*/
|
|
26
|
+
export declare function expandBagColumns(columns: ReportColumnDef[], data: Record<string, any>[]): {
|
|
27
|
+
columns: ReportColumnDef[];
|
|
28
|
+
rows: Record<string, any>[];
|
|
29
|
+
};
|
|
3
30
|
export declare function formatValuePlain(value: any, col: ReportColumnDef, currency?: string): string;
|
|
4
31
|
export declare function reportColumnsToTanstack(columns: ReportColumnDef[], currency?: string): ColumnDef<Record<string, any>>[];
|
|
5
32
|
//# sourceMappingURL=columns.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../src/lib/columns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAqD/C,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../src/lib/columns.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAA;AAqD/C;;gEAEgE;AAChE,wBAAgB,UAAU,CAAC,KAAK,EAAE,GAAG,GAAG,MAAM,CAW7C;AAED;yDACyD;AACzD,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAG/C;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,eAAe,EAAE,EAC1B,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,GAC1B;IAAE,OAAO,EAAE,eAAe,EAAE,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAA;CAAE,CAyC7D;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAwB5F;AAMD,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,eAAe,EAAE,EAC1B,QAAQ,CAAC,EAAE,MAAM,GAChB,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAmFlC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { formatValuePlain } from './chunk-
|
|
1
|
+
import { formatValuePlain } from './chunk-4QIHTUXD.js';
|
|
2
2
|
|
|
3
3
|
// src/export/pdf.ts
|
|
4
4
|
var load = (m) => new Function("m", "return import(m)")(m);
|
|
@@ -33,5 +33,5 @@ async function isPdfAvailable() {
|
|
|
33
33
|
}
|
|
34
34
|
|
|
35
35
|
export { exportToPdf, isPdfAvailable };
|
|
36
|
-
//# sourceMappingURL=pdf-
|
|
37
|
-
//# sourceMappingURL=pdf-
|
|
36
|
+
//# sourceMappingURL=pdf-DH4CJMV5.js.map
|
|
37
|
+
//# sourceMappingURL=pdf-DH4CJMV5.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/export/pdf.ts"],"names":[],"mappings":";;;AAKA,IAAM,IAAA,GAAO,CAAC,CAAA,KAAc,IAAI,SAAS,GAAA,EAAK,kBAAkB,EAAE,CAAC,CAAA;AAEnE,eAAsB,WAAA,CACpB,OAAA,EACA,IAAA,EACA,QAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,KAAK,OAAO,CAAA;AAC7C,EAAA,MAAM,KAAK,iBAAiB,CAAA;AAE5B,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,KAAK,CAAA;AAE7D,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,EAAE,WAAA,EAAa,YAAY,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,UAAA,EAAY,CAAA;AAExF,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,GAAA,CAAI,YAAY,EAAE,CAAA;AAClB,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAA,EAAI,EAAE,CAAA;AAAA,EAChC;AAEC,EAAC,IAAY,SAAA,CAAU;AAAA,IACtB,MAAA,EAAQ,OAAA,EAAS,KAAA,GAAQ,EAAA,GAAK,EAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,IACtC,MAAM,IAAA,CAAK,GAAA;AAAA,MAAI,CAAC,GAAA,KACd,WAAA,CAAY,GAAA,CAAI,CAAC,GAAA,KAAQ,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,EAAG,GAAA,EAAK,OAAA,EAAS,QAAQ,CAAC;AAAA,KACjF;AAAA,IACA,MAAA,EAAQ,EAAE,QAAA,EAAU,CAAA,EAAE;AAAA,IACtB,YAAY,EAAE,SAAA,EAAW,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAAE,GAC1C,CAAA;AAED,EAAA,GAAA,CAAI,IAAA,CAAK,CAAA,EAAG,QAAQ,CAAA,IAAA,CAAM,CAAA;AAC5B;AAEA,eAAsB,cAAA,GAAmC;AACvD,EAAA,IAAI;AACF,IAAA,MAAM,KAAK,OAAO,CAAA;AAClB,IAAA,MAAM,KAAK,iBAAiB,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"pdf-
|
|
1
|
+
{"version":3,"sources":["../src/export/pdf.ts"],"names":[],"mappings":";;;AAKA,IAAM,IAAA,GAAO,CAAC,CAAA,KAAc,IAAI,SAAS,GAAA,EAAK,kBAAkB,EAAE,CAAC,CAAA;AAEnE,eAAsB,WAAA,CACpB,OAAA,EACA,IAAA,EACA,QAAA,EACA,OAAA,EACe;AACf,EAAA,MAAM,EAAE,OAAA,EAAS,KAAA,EAAM,GAAI,MAAM,KAAK,OAAO,CAAA;AAC7C,EAAA,MAAM,KAAK,iBAAiB,CAAA;AAE5B,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,KAAK,CAAA;AAE7D,EAAA,MAAM,GAAA,GAAM,IAAI,KAAA,CAAM,EAAE,WAAA,EAAa,YAAY,MAAA,GAAS,CAAA,GAAI,WAAA,GAAc,UAAA,EAAY,CAAA;AAExF,EAAA,IAAI,SAAS,KAAA,EAAO;AAClB,IAAA,GAAA,CAAI,YAAY,EAAE,CAAA;AAClB,IAAA,GAAA,CAAI,IAAA,CAAK,OAAA,CAAQ,KAAA,EAAO,EAAA,EAAI,EAAE,CAAA;AAAA,EAChC;AAEC,EAAC,IAAY,SAAA,CAAU;AAAA,IACtB,MAAA,EAAQ,OAAA,EAAS,KAAA,GAAQ,EAAA,GAAK,EAAA;AAAA,IAC9B,IAAA,EAAM,CAAC,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,CAAA,CAAE,KAAK,CAAC,CAAA;AAAA,IACtC,MAAM,IAAA,CAAK,GAAA;AAAA,MAAI,CAAC,GAAA,KACd,WAAA,CAAY,GAAA,CAAI,CAAC,GAAA,KAAQ,gBAAA,CAAiB,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA,EAAG,GAAA,EAAK,OAAA,EAAS,QAAQ,CAAC;AAAA,KACjF;AAAA,IACA,MAAA,EAAQ,EAAE,QAAA,EAAU,CAAA,EAAE;AAAA,IACtB,YAAY,EAAE,SAAA,EAAW,CAAC,GAAA,EAAK,GAAA,EAAK,GAAG,CAAA;AAAE,GAC1C,CAAA;AAED,EAAA,GAAA,CAAI,IAAA,CAAK,CAAA,EAAG,QAAQ,CAAA,IAAA,CAAM,CAAA;AAC5B;AAEA,eAAsB,cAAA,GAAmC;AACvD,EAAA,IAAI;AACF,IAAA,MAAM,KAAK,OAAO,CAAA;AAClB,IAAA,MAAM,KAAK,iBAAiB,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"pdf-DH4CJMV5.js","sourcesContent":["import type { ReportColumnDef } from '../types'\nimport { formatValuePlain } from '../lib/columns'\n\n// Opaque dynamic import — hidden from Vite's static analysis so it won't\n// fail when jspdf is not installed (it's an optional peer dependency).\nconst load = (m: string) => new Function('m', 'return import(m)')(m) as Promise<any>\n\nexport async function exportToPdf(\n columns: ReportColumnDef[],\n data: Record<string, any>[],\n filename: string,\n options?: { title?: string; currency?: string },\n): Promise<void> {\n const { default: jsPDF } = await load('jspdf')\n await load('jspdf-autotable')\n\n const visibleCols = columns.filter((c) => c.visible !== false)\n\n const doc = new jsPDF({ orientation: visibleCols.length > 6 ? 'landscape' : 'portrait' })\n\n if (options?.title) {\n doc.setFontSize(14)\n doc.text(options.title, 14, 20)\n }\n\n ;(doc as any).autoTable({\n startY: options?.title ? 30 : 14,\n head: [visibleCols.map((c) => c.label)],\n body: data.map((row) =>\n visibleCols.map((col) => formatValuePlain(row[col.key], col, options?.currency)),\n ),\n styles: { fontSize: 8 },\n headStyles: { fillColor: [100, 100, 100] },\n })\n\n doc.save(`${filename}.pdf`)\n}\n\nexport async function isPdfAvailable(): Promise<boolean> {\n try {\n await load('jspdf')\n await load('jspdf-autotable')\n return true\n } catch {\n return false\n }\n}\n"]}
|
package/dist/types.d.ts
CHANGED
|
@@ -21,6 +21,11 @@ export interface ReportColumnDef {
|
|
|
21
21
|
align?: 'left' | 'center' | 'right';
|
|
22
22
|
/** Aggregate for optional summary row */
|
|
23
23
|
aggregate?: 'sum' | 'avg' | 'count' | 'min' | 'max';
|
|
24
|
+
/** Open bag of key/values: expanded into one column per key. See
|
|
25
|
+
* AnalyticsColumnDef.expand. */
|
|
26
|
+
expand?: boolean;
|
|
27
|
+
/** Stored code → the word a person reads ('new' → 'Novo'). */
|
|
28
|
+
valueMap?: Record<string, string>;
|
|
24
29
|
}
|
|
25
30
|
export type ReportFilterOption = {
|
|
26
31
|
label: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AAM9C;;gFAEgF;AAChF,MAAM,MAAM,eAAe,GAAG,SAAS,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,CAAA;AAE3E,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,eAAe,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gEAAgE;IAChE,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,mFAAmF;IACnF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,KAAK,CAAC,SAAS,CAAA;IACtD,yDAAyD;IACzD,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,yDAAyD;IACzD,KAAK,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAA;IACnC,yCAAyC;IACzC,SAAS,CAAC,EAAE,KAAK,GAAG,KAAK,GAAG,OAAO,GAAG,KAAK,GAAG,KAAK,CAAA;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AnalyticsReportViewer.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsReportViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"AnalyticsReportViewer.d.ts","sourceRoot":"","sources":["../../src/views/AnalyticsReportViewer.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAkHzB,wBAAgB,qBAAqB,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,qBA8CpE"}
|
package/package.json
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fayz-ai/plugin-reports",
|
|
3
3
|
"fayz": {
|
|
4
|
-
"status": "preview"
|
|
4
|
+
"status": "preview",
|
|
5
|
+
"dependencies": []
|
|
5
6
|
},
|
|
6
|
-
"version": "0.12.
|
|
7
|
+
"version": "0.12.2",
|
|
7
8
|
"description": "[experimental] Fayz SDK — plugin-reports plugin",
|
|
8
9
|
"type": "module",
|
|
9
10
|
"sideEffects": false,
|
|
@@ -27,9 +28,9 @@
|
|
|
27
28
|
},
|
|
28
29
|
"dependencies": {
|
|
29
30
|
"@tanstack/react-table": "^8.20.0",
|
|
30
|
-
"@fayz-ai/core": "^0.
|
|
31
|
-
"@fayz-ai/ui": "^0.
|
|
32
|
-
"@fayz-ai/admin": "^0.
|
|
31
|
+
"@fayz-ai/core": "^0.17.0",
|
|
32
|
+
"@fayz-ai/ui": "^0.17.0",
|
|
33
|
+
"@fayz-ai/admin": "^0.17.0"
|
|
33
34
|
},
|
|
34
35
|
"devDependencies": {
|
|
35
36
|
"@types/react": "^18.3.0",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/lib/columns.ts"],"names":["formatCurrencyLocale","formatDateLocale","formatDateTimeLocale"],"mappings":"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","file":"chunk-5SO5HWV2.js","sourcesContent":["import React from 'react'\nimport type { ColumnDef } from '@tanstack/react-table'\nimport type { ReportColumnDef } from '../types'\nimport { PersonLink } from '@fayz-ai/admin'\nimport {\n formatCurrency as formatCurrencyLocale,\n formatDate as formatDateLocale,\n formatDateTime as formatDateTimeLocale,\n} from '@fayz-ai/core'\n\n// ---------------------------------------------------------------------------\n// Formatters (mirrors fieldToColumn.tsx logic)\n// ---------------------------------------------------------------------------\n\nfunction formatCurrency(value: any, currency?: string): string {\n const num = typeof value === 'number' ? value : parseFloat(value)\n if (isNaN(num)) return '—'\n return formatCurrencyLocale(num, currency)\n}\n\nfunction formatDate(value: any): string {\n if (!value) return '—'\n return formatDateLocale(value)\n}\n\nfunction formatDateTime(value: any): string {\n if (!value) return '—'\n return formatDateTimeLocale(value)\n}\n\nfunction formatNumber(value: any): string {\n if (value == null) return '—'\n return typeof value === 'number' ? value.toLocaleString() : String(value)\n}\n\nfunction formatPercent(value: any): string {\n const num = typeof value === 'number' ? value : parseFloat(value)\n return isNaN(num) ? '—' : `${num.toLocaleString(undefined, { maximumFractionDigits: 2 })}%`\n}\n\n/** Durations are stored in HOURS, matching the analytics card renderer. */\nfunction formatDuration(value: any): string {\n const hours = typeof value === 'number' ? value : parseFloat(value)\n if (isNaN(hours) || hours <= 0) return '—'\n const minutes = Math.round(hours * 60)\n if (minutes < 60) return `${minutes}min`\n const h = Math.floor(minutes / 60)\n const m = minutes % 60\n return m ? `${h}h ${m}min` : `${h}h`\n}\n\n// ---------------------------------------------------------------------------\n// Plain-text formatter for exports\n// ---------------------------------------------------------------------------\n\nexport function formatValuePlain(value: any, col: ReportColumnDef, currency?: string): string {\n if (value == null || value === '') return ''\n switch (col.type) {\n case 'currency':\n return formatCurrency(value, col.currency ?? currency)\n case 'date':\n return formatDate(value)\n case 'datetime':\n return formatDateTime(value)\n case 'number':\n return formatNumber(value)\n case 'percent':\n return formatPercent(value)\n case 'duration':\n return formatDuration(value)\n case 'boolean':\n return value ? 'Yes' : 'No'\n default:\n return String(value)\n }\n}\n\n// ---------------------------------------------------------------------------\n// ReportColumnDef[] → TanStack ColumnDef[]\n// ---------------------------------------------------------------------------\n\nexport function reportColumnsToTanstack(\n columns: ReportColumnDef[],\n currency?: string,\n): ColumnDef<Record<string, any>>[] {\n return columns\n .filter((c) => c.visible !== false)\n .map((col): ColumnDef<Record<string, any>> => {\n const sortable = col.sortable\n ?? ['text', 'number', 'percent', 'duration', 'currency', 'date', 'datetime', 'email'].includes(col.type)\n const alignRight = col.align === 'right'\n || (!col.align && ['currency', 'number', 'percent', 'duration'].includes(col.type))\n const alignCenter = col.align === 'center'\n\n return {\n accessorKey: col.key,\n header: col.label,\n enableSorting: sortable,\n cell: (ctx) => {\n const value = ctx.getValue()\n const row = ctx.row.original\n\n if (col.renderCell) {\n return col.renderCell(value, row)\n }\n\n if (value == null || value === '') {\n return React.createElement('span', { className: 'text-muted-foreground' }, '—')\n }\n\n let content: React.ReactNode\n switch (col.type) {\n case 'person':\n content = React.createElement(PersonLink, {\n personId: col.idKey ? row[col.idKey] : null,\n name: String(value),\n kind: col.personKind,\n size: 'sm',\n className: 'text-xs',\n })\n break\n case 'currency':\n content = formatCurrency(value, col.currency ?? currency)\n break\n case 'date':\n content = formatDate(value)\n break\n case 'datetime':\n content = formatDateTime(value)\n break\n case 'boolean':\n content = value\n ? React.createElement('svg', { className: 'h-4 w-4 text-success', viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2' },\n React.createElement('polyline', { points: '20 6 9 17 4 12' }),\n )\n : React.createElement('span', { className: 'text-muted-foreground' }, '—')\n break\n case 'number':\n content = formatNumber(value)\n break\n case 'percent':\n content = formatPercent(value)\n break\n case 'duration':\n content = formatDuration(value)\n break\n default:\n content = String(value)\n }\n\n const cls = alignRight ? 'text-right' : alignCenter ? 'text-center' : undefined\n return cls\n ? React.createElement('div', { className: cls }, content)\n : React.createElement(React.Fragment, null, content)\n },\n meta: { align: alignRight ? 'right' : alignCenter ? 'center' : 'left' },\n }\n })\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/export/excel.ts"],"names":[],"mappings":";;;AAKA,IAAM,IAAA,GAAO,CAAC,CAAA,KAAc,IAAI,SAAS,GAAA,EAAK,kBAAkB,EAAE,CAAC,CAAA;AAEnE,eAAsB,aAAA,CACpB,OAAA,EACA,IAAA,EACA,QAAA,EACA,QAAA,EACe;AACf,EAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,MAAM,CAAA;AAC9B,EAAA,MAAM,cAAc,OAAA,CAAQ,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,YAAY,KAAK,CAAA;AAE7D,EAAA,MAAM,SAAS,WAAA,CAAY,GAAA,CAAI,CAAC,CAAA,KAAM,EAAE,KAAK,CAAA;AAC7C,EAAA,MAAM,OAAO,IAAA,CAAK,GAAA;AAAA,IAAI,CAAC,GAAA,KACrB,WAAA,CAAY,GAAA,CAAI,CAAC,GAAA,KAAQ;AACvB,MAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,GAAA,CAAI,GAAG,CAAA;AACzB,MAAA,IAAI,GAAA,CAAI,IAAA,KAAS,QAAA,IAAY,GAAA,CAAI,SAAS,UAAA,EAAY;AACpD,QAAA,MAAM,MAAM,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,WAAW,KAAK,CAAA;AAChE,QAAA,OAAO,KAAA,CAAM,GAAG,CAAA,GAAI,EAAA,GAAK,GAAA;AAAA,MAC3B;AACA,MAAA,OAAO,gBAAA,CAAiB,KAAA,EAAO,GAAA,EAAK,QAAQ,CAAA;AAAA,IAC9C,CAAC;AAAA,GACH;AAEA,EAAA,MAAM,EAAA,GAAK,KAAK,KAAA,CAAM,YAAA,CAAa,CAAC,MAAA,EAAQ,GAAG,IAAI,CAAC,CAAA;AACpD,EAAA,MAAM,EAAA,GAAK,IAAA,CAAK,KAAA,CAAM,QAAA,EAAS;AAC/B,EAAA,IAAA,CAAK,KAAA,CAAM,iBAAA,CAAkB,EAAA,EAAI,EAAA,EAAI,QAAQ,CAAA;AAC7C,EAAA,IAAA,CAAK,SAAA,CAAU,EAAA,EAAI,CAAA,EAAG,QAAQ,CAAA,KAAA,CAAO,CAAA;AACvC;AAEA,eAAsB,gBAAA,GAAqC;AACzD,EAAA,IAAI;AACF,IAAA,MAAM,KAAK,MAAM,CAAA;AACjB,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF","file":"excel-LDM5H5IW.js","sourcesContent":["import type { ReportColumnDef } from '../types'\nimport { formatValuePlain } from '../lib/columns'\n\n// Opaque dynamic import — hidden from Vite's static analysis so it won't\n// fail when xlsx is not installed (it's an optional peer dependency).\nconst load = (m: string) => new Function('m', 'return import(m)')(m) as Promise<any>\n\nexport async function exportToExcel(\n columns: ReportColumnDef[],\n data: Record<string, any>[],\n filename: string,\n currency?: string,\n): Promise<void> {\n const XLSX = await load('xlsx')\n const visibleCols = columns.filter((c) => c.visible !== false)\n\n const header = visibleCols.map((c) => c.label)\n const rows = data.map((row) =>\n visibleCols.map((col) => {\n const value = row[col.key]\n if (col.type === 'number' || col.type === 'currency') {\n const num = typeof value === 'number' ? value : parseFloat(value)\n return isNaN(num) ? '' : num\n }\n return formatValuePlain(value, col, currency)\n }),\n )\n\n const ws = XLSX.utils.aoa_to_sheet([header, ...rows])\n const wb = XLSX.utils.book_new()\n XLSX.utils.book_append_sheet(wb, ws, 'Report')\n XLSX.writeFile(wb, `${filename}.xlsx`)\n}\n\nexport async function isExcelAvailable(): Promise<boolean> {\n try {\n await load('xlsx')\n return true\n } catch {\n return false\n }\n}\n"]}
|