From a600121e0df4428ca4c599353c412f7b59897495 Mon Sep 17 00:00:00 2001 From: suryac Date: Tue, 18 Aug 2026 11:08:40 +0530 Subject: [PATCH] fix: limit for select option and pdf limit --- src/api/config.ts | 2 +- src/components/forms/LogVisitForm.tsx | 4 +- src/components/forms/fields/WfLookupField.tsx | 2 +- src/components/maps/DailyLogMap.tsx | 7 -- src/components/reusable/AnalyticsChart.tsx | 12 +-- src/components/rv/RecordView.tsx | 11 +-- src/lib/format.ts | 4 + src/screens/DailySalesReportPage.tsx | 78 +++++++++++++------ 8 files changed, 75 insertions(+), 45 deletions(-) diff --git a/src/api/config.ts b/src/api/config.ts index d373aa3..aff1339 100644 --- a/src/api/config.ts +++ b/src/api/config.ts @@ -260,7 +260,7 @@ export const SALES_REPORT_SO_NAMES = [ // --- Pipeline Endpoints --- export const PIPELINE = { endpoints: { - nearestStores: '/api/papi2/nearest-stores', + nearestStores: '/api/p/krishna-group/v1/nearest-stores', dailySalesReport: '/api/papi2/daily-sales-report', productiveCallSummary: '/api/papi2/productive-call-summary', salesOfficers: '/api/papi2/sales-officers' diff --git a/src/components/forms/LogVisitForm.tsx b/src/components/forms/LogVisitForm.tsx index 350f43c..c6a9f91 100644 --- a/src/components/forms/LogVisitForm.tsx +++ b/src/components/forms/LogVisitForm.tsx @@ -184,7 +184,7 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: activityId, fieldId: 'select_store', formData: formDataToSend, - limit: 200, + limit: 400, }); const arr = Array.isArray(lookupRes) @@ -253,7 +253,7 @@ export function LogVisitForm({ client, onSuccess, onCancel, onActivityChange }: activityId, fieldId: 'daily_log', formData: payload, - limit: 200, + limit: 400, }); const arr = Array.isArray(dailyLogLookupRes) diff --git a/src/components/forms/fields/WfLookupField.tsx b/src/components/forms/fields/WfLookupField.tsx index 00c6ac9..b215559 100644 --- a/src/components/forms/fields/WfLookupField.tsx +++ b/src/components/forms/fields/WfLookupField.tsx @@ -31,7 +31,7 @@ export function WfLookupField({ label, required, value, onChange, client, config activityId, fieldId, formData: JSON.parse(formDataStr), - limit: 200 + limit: 400 }) .then(res => { if (!mounted) return; diff --git a/src/components/maps/DailyLogMap.tsx b/src/components/maps/DailyLogMap.tsx index d6712b1..1df5c5e 100644 --- a/src/components/maps/DailyLogMap.tsx +++ b/src/components/maps/DailyLogMap.tsx @@ -71,13 +71,6 @@ export function DailyLogMap({ { latitude: lat, longitude: lng - }, - { - 'accept': 'application/json, text/plain, */*', - 'groupid': '25', - 'orgid': '57', - 'templateid': '189', - 'x-pipeline-version': 'latest' } ); diff --git a/src/components/reusable/AnalyticsChart.tsx b/src/components/reusable/AnalyticsChart.tsx index 2f4c81f..0f3242e 100644 --- a/src/components/reusable/AnalyticsChart.tsx +++ b/src/components/reusable/AnalyticsChart.tsx @@ -102,10 +102,7 @@ export function AnalyticsChart({ data, gridCols }: AnalyticsChartProps) { const fullSpanClass = gridCols === 2 ? 'lg:col-span-2' : 'lg:col-span-3'; - // Calculate a dynamic width if there's a lot of data to allow horizontal scrolling - const minChartWidth = chartType === 0 || chartType === 1 || chartType === 2 - ? Math.max(100, finalData.length * (hasSeries ? seriesKeys.length * 15 + 40 : 60)) - : 100; + const minChartWidth = 100; const renderChartContent = () => { return ( @@ -125,8 +122,11 @@ export function AnalyticsChart({ data, gridCols }: AnalyticsChartProps) { dataKey="dimension" axisLine={false} tickLine={false} - tick={{ fontSize: 12, fill: '#64748B' }} + tick={{ fontSize: 11, fill: '#64748B', angle: -45, textAnchor: 'end' }} + interval={0} dy={10} + dx={-5} + height={70} /> -
100 ? 'overflow-x-auto scrollbar-slim' : ''}`}> +
100 ? 'overflow-x-auto scrollbar-slim' : ''}`}> {chartType === 5 ? (
diff --git a/src/components/rv/RecordView.tsx b/src/components/rv/RecordView.tsx index fc12c40..605d09f 100644 --- a/src/components/rv/RecordView.tsx +++ b/src/components/rv/RecordView.tsx @@ -77,13 +77,16 @@ export function RecordView({ const [internalSortBy, setInternalSortBy] = useState(sortBy); const [internalSortDir, setInternalSortDir] = useState<'asc' | 'desc' | undefined>(sortDir); + const [isUserSorted, setIsUserSorted] = useState(false); useEffect(() => { setInternalSortBy(sortBy); setInternalSortDir(sortDir); + setIsUserSorted(false); }, [sortBy, sortDir]); const handleSort = (fieldKey: string) => { + setIsUserSorted(true); if (internalSortBy === fieldKey) { if (internalSortDir === 'asc') { setInternalSortDir('desc'); @@ -190,10 +193,8 @@ export function RecordView({ .map((k) => byKey.get(k) ?? ({ field_key: k, output_label: k, data_type: 'string', is_filter: false, is_search: false } as RecordViewField)) .filter(Boolean); } - if (omitColumns) { - const omitSet = new Set(omitColumns); - result = result.filter((f) => !omitSet.has(f.field_key)); - } + const omitSet = new Set([...(omitColumns || []), 'instance_id']); + result = result.filter((f) => !omitSet.has(f.field_key)); return result; }, [resp, columns, omitColumns]); @@ -368,7 +369,7 @@ export function RecordView({ >
{f.output_label} - {internalSortBy === f.field_key && ( + {internalSortBy === f.field_key && isUserSorted && ( internalSortDir === 'asc' ? : )}
diff --git a/src/lib/format.ts b/src/lib/format.ts index a822d93..ac6e051 100644 --- a/src/lib/format.ts +++ b/src/lib/format.ts @@ -79,6 +79,10 @@ export function formatValue(value: unknown, fieldKey?: string): string { if ('business_name_2' in o && o.business_name_2 != null) return String(o.business_name_2); if ('business_name_3' in o && o.business_name_3 != null) return String(o.business_name_3); if ('business_name' in o && o.business_name != null) return String(o.business_name); + + // Location JSON + if ('latitude' in o && 'longitude' in o) return `latitude:${o.latitude},longitude:${o.longitude}`; + if ('lat' in o && 'lng' in o) return `latitude:${o.lat},longitude:${o.lng}`; } try { diff --git a/src/screens/DailySalesReportPage.tsx b/src/screens/DailySalesReportPage.tsx index 70f10d8..7e6d6a7 100644 --- a/src/screens/DailySalesReportPage.tsx +++ b/src/screens/DailySalesReportPage.tsx @@ -16,7 +16,7 @@ export function DailySalesReportPage() { const [route, setRoute] = useState(''); const [distributor, setDistributor] = useState(''); const [soEmail, setSoEmail] = useState(''); - const [soOptions, setSoOptions] = useState<{value: string, label: string}[]>([]); + const [soOptions, setSoOptions] = useState<{ value: string, label: string }[]>([]); const [busy, setBusy] = useState(false); const [error, setError] = useState(null); @@ -64,7 +64,7 @@ export function DailySalesReportPage() { doc.setFontSize(12); doc.setFont('helvetica', 'bold'); doc.text('DAILY ORDER REPORT', centerX, 30, { align: 'center' }); - + // Simple underline for DAILY ORDER REPORT const textWidth = doc.getTextWidth('DAILY ORDER REPORT'); doc.setLineWidth(0.5); @@ -72,35 +72,65 @@ export function DailySalesReportPage() { // Meta Info doc.setFontSize(10); - doc.text(`Distributor Name : ${distributor}`, 14, 40); - doc.text(`Date : ${date}`, rightMargin, 40, { align: 'right' }); - const selectedSo = soOptions.find(o => o.value === soEmail); - doc.text(`SO Name : ${selectedSo ? selectedSo.label : soEmail}`, rightMargin, 45, { align: 'right' }); + + let leftY = 40; + if (distributor) { + doc.text(`Distributor Name : ${distributor}`, 14, leftY); + leftY += 5; + } + + let rightY = 40; + if (date) { + doc.text(`Date : ${date}`, rightMargin, rightY, { align: 'right' }); + rightY += 5; + } + + if (soEmail) { + const selectedSo = soOptions.find(o => o.value === soEmail); + doc.text(`SO Name : ${selectedSo ? selectedSo.label : soEmail}`, rightMargin, rightY, { align: 'right' }); + rightY += 5; + } }; - // Split headers into chunks to avoid jspdf-autotable's horizontal page break bugs - // This allows us to keep the 2-tier header perfectly intact and break at heading boundaries. - const MAX_SKUS_PER_CHUNK = 14; + // Split headers into chunks of exactly MAX_SKUS_PER_CHUNK, even if it means splitting a brand. + const MAX_SKUS_PER_CHUNK = 20; const headerChunks: any[][] = []; let currentChunk: any[] = []; let currentSkuCount = 0; reportData?.response?.headers?.forEach((h: any) => { - const skus = h.skus || []; - if (currentSkuCount + skus.length > MAX_SKUS_PER_CHUNK && currentSkuCount > 0) { - headerChunks.push(currentChunk); - currentChunk = []; - currentSkuCount = 0; + const allSkus = h.skus || []; + if (allSkus.length === 0) return; + + let remainingSkus = [...allSkus]; + + while (remainingSkus.length > 0) { + const availableSpace = MAX_SKUS_PER_CHUNK - currentSkuCount; + + // Take as many SKUs as we can fit in the current chunk + const skusToTake = remainingSkus.splice(0, availableSpace); + + currentChunk.push({ + ...h, + skus: skusToTake + }); + + currentSkuCount += skusToTake.length; + + if (currentSkuCount >= MAX_SKUS_PER_CHUNK) { + headerChunks.push(currentChunk); + currentChunk = []; + currentSkuCount = 0; + } } - currentChunk.push(h); - currentSkuCount += skus.length; }); + if (currentChunk.length > 0) { headerChunks.push(currentChunk); } if (headerChunks.length === 0) { - drawPageHeader(); // Fallback if no data + drawPageHeader(); // Fallback if no data } headerChunks.forEach((chunkHeaders, index) => { @@ -116,14 +146,14 @@ export function DailySalesReportPage() { { content: 'Store', rowSpan: 2, styles: { halign: 'center', valign: 'middle' } } ]; const headRow2: any[] = []; - + chunkHeaders.forEach((h: any) => { headRow1.push({ content: h.br_code, colSpan: h.skus?.length || 1, styles: { halign: 'center' } }); h.skus?.forEach((sku: string) => { headRow2.push({ content: sku, styles: { halign: 'center' } }); }); }); - + const isLastChunk = index === headerChunks.length - 1; if (isLastChunk) { headRow1.push({ content: 'Total', rowSpan: 2, styles: { halign: 'center', valign: 'middle' } }); @@ -161,7 +191,7 @@ export function DailySalesReportPage() { startY: 50, theme: 'grid', horizontalPageBreak: false, - styles: { fontSize: 6, textColor: [0, 0, 0], lineColor: [0, 0, 0], lineWidth: 0.2, cellPadding: 1, minCellWidth: 10 }, + styles: { fontSize: 6, textColor: [0, 0, 0], lineColor: [0, 0, 0], lineWidth: 0.2, cellPadding: 1, minCellWidth: 10, halign: 'center', valign: 'middle' }, headStyles: { fillColor: [243, 244, 246], fontStyle: 'bold', halign: 'center' }, didParseCell: (data) => { if (data.section === 'body' && reportData?.response?.total_row && data.row.index === body.length - 1) { @@ -289,10 +319,12 @@ export function DailySalesReportPage() {
-
Distributor Name : {distributor}
+
+ {distributor &&
Distributor Name : {distributor}
} +
-
Date : {date}
-
SO Name : {soOptions.find(o => o.value === soEmail)?.label || soEmail}
+ {date &&
Date : {date}
} + {soEmail &&
SO Name : {soOptions.find(o => o.value === soEmail)?.label || soEmail}
}