feat: add visual green board activation presets
Publish GitHub Pages output / publish (push) Successful in 31s
Publish GitHub Pages output / publish (push) Successful in 31s
This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
import test from 'node:test';
|
||||
import assert from 'node:assert/strict';
|
||||
import { readFileSync } from 'node:fs';
|
||||
import { activateGreenNodePreset, type GreenNodePreset } from './board-green-presets.ts';
|
||||
|
||||
const summary = JSON.parse(readFileSync(new URL('../data/boards-summary.json', import.meta.url), 'utf8'));
|
||||
const expected: Record<GreenNodePreset, string[]> = {
|
||||
3: ['G-001', 'G-002', 'G-005'],
|
||||
5: ['G-001', 'G-002', 'G-003', 'G-004', 'G-005'],
|
||||
7: ['G-001', 'G-002', 'G-003', 'G-004', 'G-005', 'G-006', 'G-007']
|
||||
};
|
||||
|
||||
for (const count of [3, 5, 7] as const) {
|
||||
test(`${count}칸은 모든 멤버의 지정 초록 노드만 활성화한다`, () => {
|
||||
const result = activateGreenNodePreset({}, summary.members, summary.models, count);
|
||||
assert.equal(Object.keys(result).length, summary.members.length);
|
||||
for (const member of summary.members) {
|
||||
assert.deepEqual(result[member.id].toSorted(), expected[count], member.id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
test('7칸 적용 후 3칸·5칸을 반복 적용해도 기존 활성 상태를 보존하며 원본을 변경하지 않는다', () => {
|
||||
const memberId = summary.members[0].id;
|
||||
const original = { [memberId]: ['B-001', 'Y-001', 'G-001', 'G-008'], other: ['R-001'] };
|
||||
const snapshot = structuredClone(original);
|
||||
const seven = activateGreenNodePreset(original, summary.members, summary.models, 7);
|
||||
const three = activateGreenNodePreset(seven, summary.members, summary.models, 3);
|
||||
const five = activateGreenNodePreset(three, summary.members, summary.models, 5);
|
||||
assert.deepEqual(original, snapshot);
|
||||
assert.deepEqual(five, seven);
|
||||
assert.deepEqual(five[memberId].toSorted(), ['B-001', ...expected[7], 'G-008', 'Y-001']);
|
||||
assert.deepEqual(five.other, ['R-001']);
|
||||
});
|
||||
|
||||
test('선택 좌표에 다른 색 노드가 있으면 활성화하지 않는다', () => {
|
||||
const models = { model: [{ groupId: 'B-001', x: 0, y: -1 }, { groupId: 'Y-001', x: -1, y: -2 }] };
|
||||
assert.deepEqual(activateGreenNodePreset({}, [{ id: 'a', positionGroupId: 'model' }], models, 7), { a: [] });
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
export type GreenNodePreset = 3 | 5 | 7;
|
||||
|
||||
type BoardPosition = { groupId: string; x: number; y: number };
|
||||
type BoardMember = { id: string; positionGroupId: string };
|
||||
|
||||
// Ordered so the first 3, 5 or 7 coordinates define each preset and its preview.
|
||||
export const greenNodePresetPositions = [
|
||||
{ x: 0, y: -1 }, { x: 0, y: -2 }, { x: 0, y: -3 },
|
||||
{ x: -1, y: -2 }, { x: 1, y: -2 },
|
||||
{ x: 0, y: -4 }, { x: 0, y: -5 }
|
||||
] as const;
|
||||
|
||||
/** Add the central green branch without resetting any existing board progress. */
|
||||
export function activateGreenNodePreset(
|
||||
memberBoards: Readonly<Record<string, readonly string[]>>,
|
||||
members: readonly BoardMember[],
|
||||
models: Readonly<Record<string, readonly BoardPosition[]>>,
|
||||
count: GreenNodePreset
|
||||
): Record<string, string[]> {
|
||||
const result = Object.fromEntries(Object.entries(memberBoards).map(([id, nodes]) => [id, [...nodes]]));
|
||||
const coordinates = greenNodePresetPositions.slice(0, count);
|
||||
for (const member of members) {
|
||||
const nodes = (models[member.positionGroupId] ?? []).filter(({ groupId, x, y }) =>
|
||||
groupId.startsWith('G-') && coordinates.some((position) => position.x === x && position.y === y)
|
||||
);
|
||||
result[member.id] = [...new Set([...(result[member.id] ?? []), ...nodes.map((node) => node.groupId)])];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
Reference in New Issue
Block a user