Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .jules/bolt.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@
## 2024-05-18 - [Extract Repeated array filter into O(N) reduce]
**Learning:** Multiple consecutive `.filter()` assignments on identical arrays (like `P.tickets`) in heavily invoked functions (`buildContext`, `generateLocalResponse`) degrade overall component efficiency by repeatedly traversing arrays O(N) over N times when a single loop suffices.
**Action:** Consolidate multiple independent `.filter()` passes and sum calculations (`.reduce`) into a single `.reduce()` step. By pushing matches to category-specific accumulator arrays and counting aggregate fields (like sums/counts) simultaneously, you accomplish what took ~5 traversals into one O(N) pass, reducing time complexity significantly (benchmarked from ~350ms to ~45ms for large arrays).

## 2024-05-18 - Optimize nested filtering mapping in Dashboard and Reports
**Learning:** In React components like `DashboardModule.jsx` and `ReportsModule.jsx`, mapping over static category lists (like priorities) and then calling `.filter(t => t.priority === p).length` inside the loop causes an O(N*M) time complexity traversal where N is the number of tickets and M is the number of priorities.
**Action:** Replace the nested `.filter().length` with an O(N) `.reduce()` that builds a hash map of frequencies (`const counts = tickets.reduce(...)`), and then use O(1) hash map lookups (`counts[p] || 0`) inside the `.map()` loop to significantly improve rendering performance.
15 changes: 10 additions & 5 deletions src/components/DashboardModule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,13 +233,18 @@ export default function Dash({ P }) {
weekday: "long", day: "numeric", month: "long",
});

const distribution = useMemo(() => (
["critical", "high", "medium", "low"].map(p => {
const cnt = P.tickets.filter(t => t.priority === p).length;
// ⚡ Bolt Optimization: Replace O(N*M) nested loop with O(N) hash map lookup
const distribution = useMemo(() => {
const counts = P.tickets.reduce((acc, t) => {
acc[t.priority] = (acc[t.priority] || 0) + 1;
return acc;
}, {});
return ["critical", "high", "medium", "low"].map(p => {
const cnt = counts[p] || 0;
const pct = P.tickets.length ? Math.round((cnt / P.tickets.length) * 100) : 0;
return { p, cnt, pct };
})
), [P.tickets]);
});
}, [P.tickets]);

return (
<motion.div
Expand Down
7 changes: 6 additions & 1 deletion src/components/ReportsModule.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@ export default function Rpt({ P }) {
}, [P.tickets, P.tasks]);

// Memoize priority distributions
// ⚡ Bolt Optimization: Replace O(N*M) nested loop with O(N) hash map lookup
const priorityDist = useMemo(() => {
const counts = P.tickets.reduce((acc, t) => {
acc[t.priority] = (acc[t.priority] || 0) + 1;
return acc;
}, {});
const priorities = ["critical", "high", "medium", "low"];
const colors = { critical: "#dc2626", high: "#ea580c", medium: "#d97706", low: "#2563eb" };
return priorities.map(p => {
const cnt = P.tickets.filter(t => t.priority === p).length;
const cnt = counts[p] || 0;
const pct = stats.totalTickets > 0 ? Math.round((cnt / stats.totalTickets) * 100) : 0;
return { p, cnt, pct, color: colors[p] };
});
Expand Down