chore(repo): checkpoint current capakraken implementation state
This commit is contained in:
@@ -424,6 +424,13 @@ export function TimelineProvider({
|
||||
const { resourceMap, allocsByResource, resources } = useMemo(() => {
|
||||
const resourceMap = new Map<string, ResourceBrief>();
|
||||
const allocsByResource = new Map<string, TimelineAssignmentEntry[]>();
|
||||
const firstAssignmentByResource = new Map<string, TimelineAssignmentEntry>();
|
||||
const projectIdsByResource = new Map<string, Set<string>>();
|
||||
const clientIdsByResource = new Map<string, Set<string>>();
|
||||
const chapterFilter = new Set(filters.chapters);
|
||||
const eidFilter = new Set(filters.eids);
|
||||
const projectFilter = new Set(filters.projectIds);
|
||||
const clientFilter = new Set(filters.clientIds);
|
||||
|
||||
if (eidFilterData?.resources) {
|
||||
for (const r of eidFilterData.resources as {
|
||||
@@ -445,6 +452,7 @@ export function TimelineProvider({
|
||||
|
||||
for (const entry of visibleAssignments) {
|
||||
if (!entry.resourceId) continue;
|
||||
firstAssignmentByResource.set(entry.resourceId, entry);
|
||||
if (!resourceMap.has(entry.resourceId)) {
|
||||
resourceMap.set(entry.resourceId, {
|
||||
id: entry.resource!.id,
|
||||
@@ -456,13 +464,23 @@ export function TimelineProvider({
|
||||
const arr = allocsByResource.get(entry.resourceId) ?? [];
|
||||
arr.push(entry);
|
||||
allocsByResource.set(entry.resourceId, arr);
|
||||
|
||||
const projectIds = projectIdsByResource.get(entry.resourceId) ?? new Set<string>();
|
||||
projectIds.add(entry.projectId);
|
||||
projectIdsByResource.set(entry.resourceId, projectIds);
|
||||
|
||||
if (typeof entry.project.clientId === "string") {
|
||||
const clientIds = clientIdsByResource.get(entry.resourceId) ?? new Set<string>();
|
||||
clientIds.add(entry.project.clientId);
|
||||
clientIdsByResource.set(entry.resourceId, clientIds);
|
||||
}
|
||||
}
|
||||
|
||||
// Merge cross-project context allocations so they appear during drag
|
||||
if (isDragging && contextAllocations.length > 0) {
|
||||
for (const ca of contextAllocations) {
|
||||
if (!ca.resourceId) continue;
|
||||
const existing = visibleAssignments.find((entry) => entry.resourceId === ca.resourceId);
|
||||
const existing = firstAssignmentByResource.get(ca.resourceId);
|
||||
if (existing && !resourceMap.has(ca.resourceId)) {
|
||||
resourceMap.set(ca.resourceId, {
|
||||
id: existing.resource!.id,
|
||||
@@ -477,32 +495,35 @@ export function TimelineProvider({
|
||||
let resources = [...resourceMap.values()].sort((a, b) =>
|
||||
a.displayName.localeCompare(b.displayName),
|
||||
);
|
||||
if (filters.chapters.length > 0) {
|
||||
resources = resources.filter((r) => r.chapter && filters.chapters.includes(r.chapter));
|
||||
if (chapterFilter.size > 0) {
|
||||
resources = resources.filter((r) => r.chapter && chapterFilter.has(r.chapter));
|
||||
}
|
||||
if (filters.eids.length > 0) {
|
||||
resources = resources.filter((r) => filters.eids.includes(r.eid));
|
||||
if (eidFilter.size > 0) {
|
||||
resources = resources.filter((r) => eidFilter.has(r.eid));
|
||||
}
|
||||
if (filters.projectIds.length > 0) {
|
||||
resources = resources.filter((r) =>
|
||||
visibleAssignments.some(
|
||||
(e) => e.resourceId === r.id && filters.projectIds.includes(e.projectId),
|
||||
),
|
||||
);
|
||||
if (projectFilter.size > 0) {
|
||||
resources = resources.filter((r) => {
|
||||
const projectIds = projectIdsByResource.get(r.id);
|
||||
if (!projectIds) return false;
|
||||
for (const projectId of projectIds) {
|
||||
if (projectFilter.has(projectId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
if (filters.clientIds.length > 0) {
|
||||
resources = resources.filter((r) =>
|
||||
visibleAssignments.some(
|
||||
(entry) => {
|
||||
const clientId = entry.project.clientId;
|
||||
return (
|
||||
entry.resourceId === r.id &&
|
||||
typeof clientId === "string" &&
|
||||
filters.clientIds.includes(clientId)
|
||||
);
|
||||
},
|
||||
),
|
||||
);
|
||||
if (clientFilter.size > 0) {
|
||||
resources = resources.filter((r) => {
|
||||
const clientIds = clientIdsByResource.get(r.id);
|
||||
if (!clientIds) return false;
|
||||
for (const clientId of clientIds) {
|
||||
if (clientFilter.has(clientId)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
return { resourceMap, allocsByResource, resources };
|
||||
@@ -520,6 +541,14 @@ export function TimelineProvider({
|
||||
// ─── Project groups (for project view) ────────────────────────────────────
|
||||
const projectGroups = useMemo(() => {
|
||||
const projectGroupMap = new Map<string, ProjectGroup>();
|
||||
const resourceRowMapByProject = new Map<
|
||||
string,
|
||||
Map<string, ProjectGroup["resourceRows"][number]>
|
||||
>();
|
||||
const chapterFilter = new Set(filters.chapters);
|
||||
const eidFilter = new Set(filters.eids);
|
||||
const clientFilter = new Set(filters.clientIds);
|
||||
const projectFilter = new Set(filters.projectIds);
|
||||
const allGroupEntries: TimelineProjectEntry[] = [...visibleAssignments, ...visibleDemands];
|
||||
for (const entry of allGroupEntries) {
|
||||
let group = projectGroupMap.get(entry.projectId);
|
||||
@@ -537,43 +566,37 @@ export function TimelineProvider({
|
||||
resourceRows: [],
|
||||
};
|
||||
projectGroupMap.set(entry.projectId, group);
|
||||
resourceRowMapByProject.set(entry.projectId, new Map());
|
||||
}
|
||||
const currentGroup = group;
|
||||
if (!currentGroup) continue;
|
||||
if (entry.kind === "assignment" && entry.resourceId) {
|
||||
const existingRow = currentGroup.resourceRows.find(
|
||||
(r) => r.resource.id === entry.resourceId,
|
||||
);
|
||||
const rowMap = resourceRowMapByProject.get(entry.projectId);
|
||||
const existingRow = rowMap?.get(entry.resourceId);
|
||||
if (existingRow) {
|
||||
existingRow.allocs.push(entry);
|
||||
} else {
|
||||
const res = resourceMap.get(entry.resourceId);
|
||||
if (res) {
|
||||
currentGroup.resourceRows.push({ resource: res, allocs: [entry] });
|
||||
const row = { resource: res, allocs: [entry] };
|
||||
currentGroup.resourceRows.push(row);
|
||||
rowMap?.set(entry.resourceId, row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (const group of projectGroupMap.values()) {
|
||||
group.resourceRows = group.resourceRows.filter(({ resource, allocs }) => {
|
||||
if (filters.chapters.length > 0) {
|
||||
if (!resource.chapter || !filters.chapters.includes(resource.chapter)) {
|
||||
group.resourceRows = group.resourceRows.filter(({ resource }) => {
|
||||
if (chapterFilter.size > 0) {
|
||||
if (!resource.chapter || !chapterFilter.has(resource.chapter)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (filters.eids.length > 0 && !filters.eids.includes(resource.eid)) {
|
||||
if (eidFilter.size > 0 && !eidFilter.has(resource.eid)) {
|
||||
return false;
|
||||
}
|
||||
if (filters.clientIds.length > 0) {
|
||||
const matchesClient = allocs.some(
|
||||
(alloc) => {
|
||||
const clientId = alloc.project.clientId;
|
||||
return typeof clientId === "string" && filters.clientIds.includes(clientId);
|
||||
},
|
||||
);
|
||||
if (!matchesClient) {
|
||||
return false;
|
||||
}
|
||||
if (clientFilter.size > 0 && (!group.clientId || !clientFilter.has(group.clientId))) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
});
|
||||
@@ -584,18 +607,18 @@ export function TimelineProvider({
|
||||
return [...projectGroupMap.values()]
|
||||
.sort((a, b) => a.startDate.getTime() - b.startDate.getTime())
|
||||
.filter((pg) => {
|
||||
if (filters.projectIds.length > 0 && !filters.projectIds.includes(pg.id)) return false;
|
||||
if (projectFilter.size > 0 && !projectFilter.has(pg.id)) return false;
|
||||
if (
|
||||
filters.clientIds.length > 0 &&
|
||||
(!pg.clientId || !filters.clientIds.includes(pg.clientId))
|
||||
clientFilter.size > 0 &&
|
||||
(!pg.clientId || !clientFilter.has(pg.clientId))
|
||||
)
|
||||
return false;
|
||||
if (
|
||||
filters.chapters.length > 0 &&
|
||||
chapterFilter.size > 0 &&
|
||||
pg.resourceRows.length === 0
|
||||
)
|
||||
return false;
|
||||
if (filters.eids.length > 0 && pg.resourceRows.length === 0)
|
||||
if (eidFilter.size > 0 && pg.resourceRows.length === 0)
|
||||
return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user