@digilogiclabs/saas-factory-ui 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +46 -4
- package/dist/index.d.ts +46 -4
- package/dist/index.js +131 -7
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +131 -7
- package/dist/index.mjs.map +1 -1
- package/dist/web/index.d.mts +46 -4
- package/dist/web/index.d.ts +46 -4
- package/dist/web/index.js +131 -7
- package/dist/web/index.js.map +1 -1
- package/dist/web/index.mjs +131 -7
- package/dist/web/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/web/index.mjs
CHANGED
|
@@ -31140,9 +31140,26 @@ function standardSeeding(participants) {
|
|
|
31140
31140
|
const sorted = [...participants].sort(
|
|
31141
31141
|
(a, b) => (a.seed ?? 999) - (b.seed ?? 999)
|
|
31142
31142
|
);
|
|
31143
|
+
const n = sorted.length;
|
|
31143
31144
|
const pairs = [];
|
|
31144
|
-
|
|
31145
|
-
|
|
31145
|
+
if (n < 2 || (n & n - 1) !== 0) {
|
|
31146
|
+
for (let i = 0; i + 1 < n; i += 2) {
|
|
31147
|
+
pairs.push([sorted[i], sorted[i + 1]]);
|
|
31148
|
+
}
|
|
31149
|
+
return pairs;
|
|
31150
|
+
}
|
|
31151
|
+
let order = [1, 2];
|
|
31152
|
+
while (order.length < n) {
|
|
31153
|
+
const total = order.length * 2 + 1;
|
|
31154
|
+
const next = [];
|
|
31155
|
+
for (const r of order) {
|
|
31156
|
+
next.push(r);
|
|
31157
|
+
next.push(total - r);
|
|
31158
|
+
}
|
|
31159
|
+
order = next;
|
|
31160
|
+
}
|
|
31161
|
+
for (let i = 0; i < order.length; i += 2) {
|
|
31162
|
+
pairs.push([sorted[order[i] - 1], sorted[order[i + 1] - 1]]);
|
|
31146
31163
|
}
|
|
31147
31164
|
return pairs;
|
|
31148
31165
|
}
|
|
@@ -31496,6 +31513,7 @@ function BracketGenerator({
|
|
|
31496
31513
|
theme: theme5 = "blue",
|
|
31497
31514
|
darkMode,
|
|
31498
31515
|
seedingStrategy = "standard",
|
|
31516
|
+
resumeMatches,
|
|
31499
31517
|
onMatchComplete,
|
|
31500
31518
|
onChampion,
|
|
31501
31519
|
onStateChange,
|
|
@@ -31574,6 +31592,47 @@ function BracketGenerator({
|
|
|
31574
31592
|
);
|
|
31575
31593
|
const [miniMapHidden, setMiniMapHidden] = useState68(false);
|
|
31576
31594
|
const miniMapDragRef = useRef41(false);
|
|
31595
|
+
const resumeRef = useRef41(resumeMatches);
|
|
31596
|
+
const hydrateFromResume = useCallback42(() => {
|
|
31597
|
+
const resume = resumeRef.current;
|
|
31598
|
+
if (!resume?.length) return null;
|
|
31599
|
+
const n = effectiveParticipants.length;
|
|
31600
|
+
if (n < 2 || (n & n - 1) !== 0) return null;
|
|
31601
|
+
const rounds = Math.log2(n);
|
|
31602
|
+
if (resume.length !== n - 1) return null;
|
|
31603
|
+
const byId = new Map(effectiveParticipants.map((p) => [p.id, p]));
|
|
31604
|
+
const resolve = (id) => {
|
|
31605
|
+
if (!id) return null;
|
|
31606
|
+
const found = byId.get(id);
|
|
31607
|
+
if (found) return found;
|
|
31608
|
+
if (id.startsWith("__bye_")) {
|
|
31609
|
+
return { id, name: "BYE", seed: 999, isBye: true };
|
|
31610
|
+
}
|
|
31611
|
+
return void 0;
|
|
31612
|
+
};
|
|
31613
|
+
const matches = [];
|
|
31614
|
+
for (const rm of resume) {
|
|
31615
|
+
if (rm.round < 0 || rm.round >= rounds) return null;
|
|
31616
|
+
const a = resolve(rm.aId);
|
|
31617
|
+
const b = resolve(rm.bId);
|
|
31618
|
+
const winner = resolve(rm.winnerId);
|
|
31619
|
+
if (a === void 0 || b === void 0 || winner === void 0)
|
|
31620
|
+
return null;
|
|
31621
|
+
matches.push({
|
|
31622
|
+
id: rm.id,
|
|
31623
|
+
round: rm.round,
|
|
31624
|
+
slot: rm.slot,
|
|
31625
|
+
a,
|
|
31626
|
+
b,
|
|
31627
|
+
scoreA: rm.scoreA,
|
|
31628
|
+
scoreB: rm.scoreB,
|
|
31629
|
+
winner
|
|
31630
|
+
});
|
|
31631
|
+
}
|
|
31632
|
+
matches.sort((x, y) => x.round - y.round || x.slot - y.slot);
|
|
31633
|
+
const finalMatch = matches.find((m) => m.round === rounds - 1);
|
|
31634
|
+
return { matches, rounds, champion: finalMatch?.winner ?? null };
|
|
31635
|
+
}, [effectiveParticipants]);
|
|
31577
31636
|
const seedBracket = useCallback42(() => {
|
|
31578
31637
|
const { matches, rounds } = buildBracket(
|
|
31579
31638
|
effectiveParticipants,
|
|
@@ -31684,12 +31743,47 @@ function BracketGenerator({
|
|
|
31684
31743
|
onStateChange?.(next);
|
|
31685
31744
|
prevBracketStateRef.current = next;
|
|
31686
31745
|
}, [bracketState, onMatchComplete, onChampion, onStateChange]);
|
|
31746
|
+
const structuralKey = useMemo27(
|
|
31747
|
+
() => `${seedingStrategy}|${effectiveParticipants.map((p) => `${p.id}:${p.seed ?? ""}`).join(",")}`,
|
|
31748
|
+
[effectiveParticipants, seedingStrategy]
|
|
31749
|
+
);
|
|
31750
|
+
const seededKeyRef = useRef41(null);
|
|
31751
|
+
useEffect53(() => {
|
|
31752
|
+
if (seededKeyRef.current === structuralKey) {
|
|
31753
|
+
setBracketState((prev) => {
|
|
31754
|
+
if (!prev.matches.length) return prev;
|
|
31755
|
+
const byId = new Map(effectiveParticipants.map((p) => [p.id, p]));
|
|
31756
|
+
const swap = (p) => p && !p.isBye ? byId.get(p.id) ?? p : p;
|
|
31757
|
+
let changed = false;
|
|
31758
|
+
const matches = prev.matches.map((m) => {
|
|
31759
|
+
const a = swap(m.a);
|
|
31760
|
+
const b = swap(m.b);
|
|
31761
|
+
const winner = swap(m.winner);
|
|
31762
|
+
if (a === m.a && b === m.b && winner === m.winner) return m;
|
|
31763
|
+
changed = true;
|
|
31764
|
+
return { ...m, a, b, winner };
|
|
31765
|
+
});
|
|
31766
|
+
if (!changed) return prev;
|
|
31767
|
+
return { ...prev, matches, champion: swap(prev.champion) };
|
|
31768
|
+
});
|
|
31769
|
+
return;
|
|
31770
|
+
}
|
|
31771
|
+
seededKeyRef.current = structuralKey;
|
|
31772
|
+
if (autoRef.current) clearTimeout(autoRef.current);
|
|
31773
|
+
setSimulating(false);
|
|
31774
|
+
const resumed = hydrateFromResume();
|
|
31775
|
+
resumeRef.current = void 0;
|
|
31776
|
+
if (resumed) {
|
|
31777
|
+
setBracketState(resumed);
|
|
31778
|
+
} else {
|
|
31779
|
+
seedBracket();
|
|
31780
|
+
}
|
|
31781
|
+
}, [structuralKey, effectiveParticipants, hydrateFromResume, seedBracket]);
|
|
31687
31782
|
useEffect53(() => {
|
|
31688
|
-
seedBracket();
|
|
31689
31783
|
return () => {
|
|
31690
31784
|
if (autoRef.current) clearTimeout(autoRef.current);
|
|
31691
31785
|
};
|
|
31692
|
-
}, [
|
|
31786
|
+
}, []);
|
|
31693
31787
|
useLayoutEffect2(() => {
|
|
31694
31788
|
if (contentSize.w > 0) {
|
|
31695
31789
|
const timer = setTimeout(fit, 50);
|
|
@@ -40267,6 +40361,27 @@ function generateSchedule(teams, roundLabel) {
|
|
|
40267
40361
|
}
|
|
40268
40362
|
return rounds;
|
|
40269
40363
|
}
|
|
40364
|
+
function hydrateResumeRounds(resume, teams) {
|
|
40365
|
+
if (!resume?.length || teams.length < 2) return [];
|
|
40366
|
+
const expected = teams.length % 2 === 0 ? teams.length - 1 : teams.length;
|
|
40367
|
+
if (resume.length !== expected) return [];
|
|
40368
|
+
const roster = new Set(teams.map((t) => t.toLowerCase()));
|
|
40369
|
+
for (const round of resume) {
|
|
40370
|
+
for (const m of round.matchups) {
|
|
40371
|
+
for (const side of [m.home, m.away]) {
|
|
40372
|
+
if (side !== BYE_TOKEN && !roster.has(side.toLowerCase())) return [];
|
|
40373
|
+
}
|
|
40374
|
+
}
|
|
40375
|
+
}
|
|
40376
|
+
return resume.map((round) => ({
|
|
40377
|
+
label: round.label,
|
|
40378
|
+
matchups: round.matchups.map((m) => ({
|
|
40379
|
+
home: m.home,
|
|
40380
|
+
away: m.away,
|
|
40381
|
+
isBye: m.home === BYE_TOKEN || m.away === BYE_TOKEN
|
|
40382
|
+
}))
|
|
40383
|
+
}));
|
|
40384
|
+
}
|
|
40270
40385
|
var DEFAULT_LABELS4 = {
|
|
40271
40386
|
inputPlaceholder: "Team or player name (comma-separated for batch)",
|
|
40272
40387
|
addButton: "Add",
|
|
@@ -40287,6 +40402,7 @@ function RoundRobinScheduler({
|
|
|
40287
40402
|
darkMode,
|
|
40288
40403
|
minTeams = 3,
|
|
40289
40404
|
defaultTeams = [],
|
|
40405
|
+
resumeRounds,
|
|
40290
40406
|
onTeamsChange,
|
|
40291
40407
|
onGenerate,
|
|
40292
40408
|
labels,
|
|
@@ -40300,7 +40416,9 @@ function RoundRobinScheduler({
|
|
|
40300
40416
|
const L = { ...DEFAULT_LABELS4, ...labels };
|
|
40301
40417
|
const [teams, setTeams] = useState77(defaultTeams);
|
|
40302
40418
|
const [input, setInput] = useState77("");
|
|
40303
|
-
const [rounds, setRounds] = useState77(
|
|
40419
|
+
const [rounds, setRounds] = useState77(
|
|
40420
|
+
() => hydrateResumeRounds(resumeRounds, defaultTeams)
|
|
40421
|
+
);
|
|
40304
40422
|
const inputRef = useRef50(null);
|
|
40305
40423
|
useEffect62(() => {
|
|
40306
40424
|
onTeamsChange?.(teams);
|
|
@@ -40826,6 +40944,8 @@ function Scoreboard({
|
|
|
40826
40944
|
maxTeams = 8,
|
|
40827
40945
|
scoreButtons = [-1, 1, 5, 10],
|
|
40828
40946
|
defaultTeams,
|
|
40947
|
+
initialRound = 1,
|
|
40948
|
+
initialHistory,
|
|
40829
40949
|
onTeamsChange,
|
|
40830
40950
|
onRoundAdvance,
|
|
40831
40951
|
onNewGame,
|
|
@@ -40841,8 +40961,12 @@ function Scoreboard({
|
|
|
40841
40961
|
const [teams, setTeams] = useState78(
|
|
40842
40962
|
() => defaultTeams && defaultTeams.length >= minTeams ? defaultTeams.slice(0, maxTeams) : createDefaultTeams(seedCount, L.teamNamePrefix)
|
|
40843
40963
|
);
|
|
40844
|
-
const [round, setRound] = useState78(
|
|
40845
|
-
|
|
40964
|
+
const [round, setRound] = useState78(
|
|
40965
|
+
() => Number.isFinite(initialRound) ? Math.max(1, Math.floor(initialRound)) : 1
|
|
40966
|
+
);
|
|
40967
|
+
const [history, setHistory] = useState78(
|
|
40968
|
+
() => initialHistory && initialHistory.length > 0 ? initialHistory.slice() : []
|
|
40969
|
+
);
|
|
40846
40970
|
const [historyOpen, setHistoryOpen] = useState78(false);
|
|
40847
40971
|
const rootRef = useRef51(null);
|
|
40848
40972
|
const [containerWidth, setContainerWidth] = useState78(0);
|