- Run record
- loading
Loading this Run…
Loading the Revisions of this Run…
A published source file of Revision 0 of Boardly — Website Relaunch 1.0.0, shown as text in the browser.
import type { BoardMeta, BoardState, Card, Column, Label, Member, Priority } from "../types";
import boardJson from "../../public/data/board.json";
import membersJson from "../../public/data/members.json";
const STORAGE_KEY = "boardly:harbor-studio:website-relaunch:v1";
interface BoardFile {
product: string;
workspace: string;
board: string;
today: string;
fictional_notice: string;
labels: Label[];
priorities: Priority[];
columns: Column[];
cards: Card[];
}
export interface LoadedData {
meta: BoardMeta;
initial: BoardState;
}
/** The supplied data is bundled at build time so the board renders on first paint. */
export function loadData(): LoadedData {
const file = boardJson as BoardFile;
const { members } = membersJson as { members: Member[] };
const cards: Record<string, Card> = {};
for (const card of file.cards) cards[card.id] = card;
return {
meta: {
product: file.product,
workspace: file.workspace,
board: file.board,
today: file.today,
fictionalNotice: file.fictional_notice,
labels: file.labels,
priorities: file.priorities,
members,
},
initial: {
columns: file.columns.map((c) => ({ ...c, card_ids: [...c.card_ids] })),
cards,
},
};
}
/** Returns the saved board if it is structurally compatible with the supplied columns. */
export function readSaved(initial: BoardState): BoardState | null {
try {
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return null;
const saved = JSON.parse(raw) as { version: number; board: BoardState };
if (saved.version !== 1 || !saved.board) return null;
const { columns, cards } = saved.board;
if (!Array.isArray(columns) || typeof cards !== "object" || cards === null) return null;
const expected = initial.columns.map((c) => c.id).join("|");
if (columns.map((c) => c.id).join("|") !== expected) return null;
const seen = new Set<string>();
for (const column of columns) {
for (const id of column.card_ids) {
if (!cards[id] || seen.has(id)) return null;
seen.add(id);
}
}
// Keep the column definitions (titles, limits) authoritative from the data file.
return {
columns: initial.columns.map((c, i) => ({ ...c, card_ids: [...columns[i].card_ids] })),
cards,
};
} catch {
return null;
}
}
export function save(board: BoardState): void {
try {
localStorage.setItem(STORAGE_KEY, JSON.stringify({ version: 1, board }));
} catch {
/* Storage full or unavailable: the board keeps working in memory. */
}
}
export function clearSaved(): void {
try {
localStorage.removeItem(STORAGE_KEY);
} catch {
/* ignore */
}
}Source is browser-viewable only. There is no download or archive endpoint, and no additional license is granted beyond inspection and research.