@ethlete/cdk 4.47.0 → 4.48.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/CHANGELOG.md +6 -0
- package/esm2022/lib/components/bracket/components/new-bracket/bracket-new.mjs +68 -69
- package/esm2022/lib/components/bracket/components/new-bracket/draw-man.mjs +75 -32
- package/esm2022/lib/components/bracket/components/new-bracket/grid-placements.mjs +8 -3
- package/esm2022/lib/components/bracket/components/new-bracket/journey-highlight.mjs +18 -0
- package/esm2022/lib/components/bracket/components/new-bracket/new-bracket.component.mjs +47 -9
- package/fesm2022/ethlete-cdk.mjs +210 -109
- package/fesm2022/ethlete-cdk.mjs.map +1 -1
- package/lib/components/bracket/components/new-bracket/bracket-new.d.ts +12 -18
- package/lib/components/bracket/components/new-bracket/draw-man.d.ts +5 -3
- package/lib/components/bracket/components/new-bracket/grid-placements.d.ts +4 -0
- package/lib/components/bracket/components/new-bracket/journey-highlight.d.ts +2 -0
- package/lib/components/bracket/components/new-bracket/new-bracket.component.d.ts +7 -2
- package/package.json +1 -1
package/fesm2022/ethlete-cdk.mjs
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import * as i1 from '@angular/cdk/portal';
|
|
2
2
|
import { CdkPortal, PortalModule, ComponentPortal, TemplatePortal, CdkPortalOutlet } from '@angular/cdk/portal';
|
|
3
|
-
import { AsyncPipe, NgClass, NgTemplateOutlet, NgComponentOutlet, JsonPipe, DOCUMENT, Location } from '@angular/common';
|
|
3
|
+
import { AsyncPipe, NgClass, NgTemplateOutlet, isPlatformBrowser, NgComponentOutlet, JsonPipe, DOCUMENT, Location } from '@angular/common';
|
|
4
4
|
import * as i0 from '@angular/core';
|
|
5
|
-
import { Component, ViewEncapsulation, ChangeDetectionStrategy, InjectionToken, Directive, booleanAttribute, Input, ContentChild, ContentChildren, inject, ElementRef, Injector, HostBinding, input, numberAttribute, computed, signal, contentChildren, viewChild, viewChildren, isDevMode, Injectable, ChangeDetectorRef, TemplateRef, ViewContainerRef, ViewChild, assertInInjectionContext, forwardRef, EventEmitter, Output, ViewChildren, runInInjectionContext, Optional, Inject, SkipSelf, HostListener, contentChild,
|
|
5
|
+
import { Component, ViewEncapsulation, ChangeDetectionStrategy, InjectionToken, Directive, booleanAttribute, Input, ContentChild, ContentChildren, inject, ElementRef, Injector, HostBinding, input, numberAttribute, computed, PLATFORM_ID, Renderer2, effect, DestroyRef, signal, contentChildren, viewChild, viewChildren, isDevMode, Injectable, ChangeDetectorRef, TemplateRef, ViewContainerRef, ViewChild, assertInInjectionContext, forwardRef, EventEmitter, Output, ViewChildren, runInInjectionContext, Optional, Inject, SkipSelf, HostListener, contentChild, untracked, NgZone, NgModule, isSignal, Attribute } from '@angular/core';
|
|
6
6
|
import * as i1$1 from '@ethlete/core';
|
|
7
|
-
import { LetDirective, createDestroy, Memo, signalHostAttributes, signalHostClasses, previousSignalValue, signalHostStyles, nextFrame, syncSignal, signalStyles, injectHostElement, ObserveVisibilityDirective, signalVisibilityChangeClasses, IS_EMAIL, MUST_MATCH, IS_ARRAY_NOT_EMPTY, AT_LEAST_ONE_REQUIRED, equal, switchQueryListChanges, controlValueSignal, signalAttributes, ResizeObserverService, createFlipAnimation, AnimatedOverlayDirective, RuntimeError, SelectionModel, ActiveSelectionModel, KeyPressManager, signalClasses, scrollToElement, isEmptyArray, isObjectArray, isPrimitiveArray,
|
|
7
|
+
import { LetDirective, createDestroy, Memo, createComponentId, signalHostAttributes, signalHostClasses, previousSignalValue, signalHostStyles, nextFrame, syncSignal, signalStyles, injectHostElement, ObserveVisibilityDirective, signalVisibilityChangeClasses, IS_EMAIL, MUST_MATCH, IS_ARRAY_NOT_EMPTY, AT_LEAST_ONE_REQUIRED, equal, switchQueryListChanges, controlValueSignal, signalAttributes, ResizeObserverService, createFlipAnimation, AnimatedOverlayDirective, RuntimeError, SelectionModel, ActiveSelectionModel, KeyPressManager, signalClasses, scrollToElement, isEmptyArray, isObjectArray, isPrimitiveArray, ClickOutsideDirective, ANIMATED_LIFECYCLE_TOKEN, AnimatedLifecycleDirective, ObserveContentDirective, clamp, DELAYABLE_TOKEN, ObserveResizeDirective, SmartBlockScrollStrategy, signalElementDimensions, signalElementScrollState, createIsRenderedSignal, createCanAnimateSignal, useCursorDragScroll, signalElementIntersection, signalElementChildren, getIntersectionInfo, getElementScrollCoordinates, ObserveScrollStateDirective, ClickObserverService, RootBoundaryDirective, elementCanScroll, cloneFormGroup, getFormGroupValue, ViewportService, injectRoute, ROOT_BOUNDARY_TOKEN, injectQueryParam, RouterStateService, fromNextFrame, isElementVisible, AnimatedIfDirective, FocusVisibleService, inferMimeType, ScrollObserverIgnoreTargetDirective, TypedQueryList } from '@ethlete/core';
|
|
8
8
|
import { BehaviorSubject, startWith, map, switchMap, combineLatest, pairwise, tap, takeUntil, skip, of, merge, timer, takeWhile, filter, fromEvent, Subject, Observable, debounceTime, withLatestFrom, distinctUntilChanged, take, skipUntil, skipWhile, catchError, throwError, defer, partition, from, finalize, Subscription } from 'rxjs';
|
|
9
9
|
import { trigger, state, style, transition, animate } from '@angular/animations';
|
|
10
10
|
import { __decorate, __metadata } from 'tslib';
|
|
@@ -1040,12 +1040,18 @@ const BRACKET_ROUND_MIRROR_TYPE = {
|
|
|
1040
1040
|
LEFT: 'left',
|
|
1041
1041
|
RIGHT: 'right',
|
|
1042
1042
|
};
|
|
1043
|
-
const generateRoundTypeFromEthleteRoundType = (type, tournamentMode) => {
|
|
1043
|
+
const generateRoundTypeFromEthleteRoundType = (type, tournamentMode, roundMatchCount) => {
|
|
1044
1044
|
switch (type) {
|
|
1045
1045
|
case 'normal':
|
|
1046
1046
|
switch (tournamentMode) {
|
|
1047
1047
|
case 'single-elimination':
|
|
1048
|
-
|
|
1048
|
+
// This might break if the single elimination contains a 3rd place match + round
|
|
1049
|
+
if (roundMatchCount === 1) {
|
|
1050
|
+
return COMMON_BRACKET_ROUND_TYPE.FINAL;
|
|
1051
|
+
}
|
|
1052
|
+
else {
|
|
1053
|
+
return SINGLE_ELIMINATION_BRACKET_ROUND_TYPE.SINGLE_ELIMINATION_BRACKET;
|
|
1054
|
+
}
|
|
1049
1055
|
case 'group':
|
|
1050
1056
|
return GROUP_BRACKET_ROUND_TYPE.GROUP;
|
|
1051
1057
|
case 'swiss':
|
|
@@ -1164,13 +1170,18 @@ const generateRoundRelations = (bracketData) => {
|
|
|
1164
1170
|
const hasLowerRounds = lowerRounds.length > 0;
|
|
1165
1171
|
const lastLowerRound = lowerRounds[lowerRounds.length - 1] || null;
|
|
1166
1172
|
for (const [currentUpperRoundIndex, currentUpperRound] of upperRounds.entries()) {
|
|
1167
|
-
const
|
|
1168
|
-
|
|
1173
|
+
const isLeftToRight = currentUpperRound.mirrorRoundType === null ||
|
|
1174
|
+
currentUpperRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.LEFT;
|
|
1175
|
+
const relativePreviousUpperRound = upperRounds[currentUpperRoundIndex - 1] || null;
|
|
1176
|
+
const relativeNextUpperRound = upperRounds[currentUpperRoundIndex + 1] || null;
|
|
1177
|
+
const previousUpperRound = isLeftToRight ? relativePreviousUpperRound : relativeNextUpperRound;
|
|
1178
|
+
const nextUpperRound = isLeftToRight ? relativeNextUpperRound : relativePreviousUpperRound;
|
|
1169
1179
|
const currentLowerRound = lowerRounds[currentUpperRoundIndex] || null;
|
|
1170
1180
|
const previousLowerRound = lowerRounds[currentUpperRoundIndex - 1] || null;
|
|
1171
1181
|
const nextLowerRound = lowerRounds[currentUpperRoundIndex + 1] || null;
|
|
1172
|
-
const
|
|
1173
|
-
|
|
1182
|
+
const isLastUpperRound = !nextUpperRound ||
|
|
1183
|
+
(nextUpperRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT &&
|
|
1184
|
+
currentUpperRound.mirrorRoundType === null);
|
|
1174
1185
|
const isFinal = currentUpperRound.type === COMMON_BRACKET_ROUND_TYPE.FINAL;
|
|
1175
1186
|
if (isFinal && hasLowerRounds) {
|
|
1176
1187
|
// two to one relation
|
|
@@ -1286,7 +1297,7 @@ const generateRoundRelations = (bracketData) => {
|
|
|
1286
1297
|
rootRoundMatchFactor: firstUpperRound.matchCount / currentUpperRound.matchCount,
|
|
1287
1298
|
});
|
|
1288
1299
|
}
|
|
1289
|
-
else if (isFirstRound) {
|
|
1300
|
+
else if (currentUpperRound.isFirstRound) {
|
|
1290
1301
|
// nothing to one relation
|
|
1291
1302
|
if (!nextUpperRound)
|
|
1292
1303
|
throw new Error('nextUpperRound is null');
|
|
@@ -1351,10 +1362,10 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
|
|
|
1351
1362
|
const currentRelation = roundRelations.get(match.round.id);
|
|
1352
1363
|
if (!currentRelation)
|
|
1353
1364
|
throw new Error('Match round not found');
|
|
1354
|
-
const {
|
|
1365
|
+
const { nextRoundMatchPosition, previousLowerRoundMatchPosition, previousUpperRoundMatchPosition } = generateMatchRelationPositions(currentRelation, match);
|
|
1355
1366
|
switch (currentRelation.type) {
|
|
1356
1367
|
case 'nothing-to-one': {
|
|
1357
|
-
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(
|
|
1368
|
+
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
|
|
1358
1369
|
if (!nextMatch)
|
|
1359
1370
|
throw new Error('Next round match not found');
|
|
1360
1371
|
// means left is nothing. right is one
|
|
@@ -1403,7 +1414,7 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
|
|
|
1403
1414
|
break;
|
|
1404
1415
|
}
|
|
1405
1416
|
case 'one-to-one': {
|
|
1406
|
-
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(
|
|
1417
|
+
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
|
|
1407
1418
|
const previousUpperMatch = matchPositionMaps
|
|
1408
1419
|
.get(currentRelation.previousRound.id)
|
|
1409
1420
|
?.get(previousUpperRoundMatchPosition);
|
|
@@ -1418,12 +1429,7 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
|
|
|
1418
1429
|
throw new Error('Previous lower round match not found');
|
|
1419
1430
|
// can be either one to one or two to one
|
|
1420
1431
|
const isLeftOne = previousUpperRoundMatchPosition === previousLowerRoundMatchPosition;
|
|
1421
|
-
|
|
1422
|
-
if (currentRelation.currentRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT) {
|
|
1423
|
-
console.log(match, generateMatchRelationPositions(currentRelation, match));
|
|
1424
|
-
}
|
|
1425
|
-
// TODO: Implement one to two
|
|
1426
|
-
if (isLeftOne && isRightOne) {
|
|
1432
|
+
if (isLeftOne) {
|
|
1427
1433
|
// one-to-one
|
|
1428
1434
|
matchRelations.set(match.id, {
|
|
1429
1435
|
type: 'one-to-one',
|
|
@@ -1435,7 +1441,7 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
|
|
|
1435
1441
|
nextRound: currentRelation.nextRound,
|
|
1436
1442
|
});
|
|
1437
1443
|
}
|
|
1438
|
-
else
|
|
1444
|
+
else {
|
|
1439
1445
|
// two-to-one
|
|
1440
1446
|
matchRelations.set(match.id, {
|
|
1441
1447
|
type: 'two-to-one',
|
|
@@ -1449,27 +1455,10 @@ const generateMatchRelations = (bracketData, roundRelations, matchPositionMaps)
|
|
|
1449
1455
|
nextRound: currentRelation.nextRound,
|
|
1450
1456
|
});
|
|
1451
1457
|
}
|
|
1452
|
-
else if (!isRightOne) {
|
|
1453
|
-
const nextLowerMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextLowerRoundMatchPosition);
|
|
1454
|
-
if (!nextLowerMatch)
|
|
1455
|
-
throw new Error('Next lower round match not found');
|
|
1456
|
-
// one-to-two
|
|
1457
|
-
matchRelations.set(match.id, {
|
|
1458
|
-
type: 'one-to-two',
|
|
1459
|
-
currentMatch: match,
|
|
1460
|
-
currentRound: currentRelation.currentRound,
|
|
1461
|
-
previousMatch: previousUpperMatch,
|
|
1462
|
-
previousRound: currentRelation.previousRound,
|
|
1463
|
-
nextUpperMatch: nextMatch,
|
|
1464
|
-
nextUpperRound: currentRelation.nextRound,
|
|
1465
|
-
nextLowerMatch,
|
|
1466
|
-
nextLowerRound: nextLowerMatch.round,
|
|
1467
|
-
});
|
|
1468
|
-
}
|
|
1469
1458
|
break;
|
|
1470
1459
|
}
|
|
1471
1460
|
case 'two-to-one': {
|
|
1472
|
-
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(
|
|
1461
|
+
const nextMatch = matchPositionMaps.get(currentRelation.nextRound.id)?.get(nextRoundMatchPosition);
|
|
1473
1462
|
const previousUpperMatch = matchPositionMaps
|
|
1474
1463
|
.get(currentRelation.previousUpperRound.id)
|
|
1475
1464
|
?.get(previousUpperRoundMatchPosition);
|
|
@@ -1525,8 +1514,7 @@ const generateMatchRelationPositions = (currentRelation, match) => {
|
|
|
1525
1514
|
switch (currentRelation.type) {
|
|
1526
1515
|
case 'nothing-to-one': {
|
|
1527
1516
|
return {
|
|
1528
|
-
|
|
1529
|
-
nextLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
1517
|
+
nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
1530
1518
|
previousUpperRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
1531
1519
|
previousLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
1532
1520
|
};
|
|
@@ -1535,8 +1523,7 @@ const generateMatchRelationPositions = (currentRelation, match) => {
|
|
|
1535
1523
|
const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
|
|
1536
1524
|
const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
|
|
1537
1525
|
return {
|
|
1538
|
-
|
|
1539
|
-
nextLowerRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
1526
|
+
nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
1540
1527
|
previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
|
|
1541
1528
|
doubleUpperMatchCountShift),
|
|
1542
1529
|
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
|
|
@@ -1544,13 +1531,9 @@ const generateMatchRelationPositions = (currentRelation, match) => {
|
|
|
1544
1531
|
}
|
|
1545
1532
|
case 'one-to-one': {
|
|
1546
1533
|
const previousRoundHasDoubleTheMatchCount = currentRelation.previousRoundMatchFactor === 2;
|
|
1547
|
-
const nextRoundHasDoubleTheMatchCount = currentRelation.nextRoundMatchFactor === 2;
|
|
1548
1534
|
const doubleUpperMatchCountShift = previousRoundHasDoubleTheMatchCount ? 1 : 0;
|
|
1549
|
-
const doubleLowerMatchCountShift = nextRoundHasDoubleTheMatchCount ? 1 : 0;
|
|
1550
1535
|
return {
|
|
1551
|
-
|
|
1552
|
-
doubleLowerMatchCountShift),
|
|
1553
|
-
nextLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
1536
|
+
nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
1554
1537
|
previousUpperRoundMatchPosition: (generateMatchPosition(match, currentRelation.previousRoundMatchFactor) -
|
|
1555
1538
|
doubleUpperMatchCountShift),
|
|
1556
1539
|
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousRoundMatchFactor),
|
|
@@ -1558,16 +1541,14 @@ const generateMatchRelationPositions = (currentRelation, match) => {
|
|
|
1558
1541
|
}
|
|
1559
1542
|
case 'two-to-one': {
|
|
1560
1543
|
return {
|
|
1561
|
-
|
|
1562
|
-
nextUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
1544
|
+
nextRoundMatchPosition: generateMatchPosition(match, currentRelation.nextRoundMatchFactor),
|
|
1563
1545
|
previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
|
|
1564
1546
|
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
|
|
1565
1547
|
};
|
|
1566
1548
|
}
|
|
1567
1549
|
case 'two-to-nothing': {
|
|
1568
1550
|
return {
|
|
1569
|
-
|
|
1570
|
-
nextUpperRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
1551
|
+
nextRoundMatchPosition: FALLBACK_MATCH_POSITION,
|
|
1571
1552
|
previousUpperRoundMatchPosition: generateMatchPosition(match, currentRelation.previousUpperRoundMatchFactor),
|
|
1572
1553
|
previousLowerRoundMatchPosition: generateMatchPosition(match, currentRelation.previousLowerRoundMatchFactor),
|
|
1573
1554
|
};
|
|
@@ -1613,9 +1594,9 @@ const generateMatchParticipantMap = (bracketData) => {
|
|
|
1613
1594
|
let lossesTilNow = 0;
|
|
1614
1595
|
let tiesTilNow = 0;
|
|
1615
1596
|
for (const matchParticipantMatch of participant.matches.values()) {
|
|
1616
|
-
const isWinner = matchParticipantMatch.bracketMatch.
|
|
1617
|
-
const isLooser = matchParticipantMatch.bracketMatch.
|
|
1618
|
-
matchParticipantMatch.bracketMatch.
|
|
1597
|
+
const isWinner = matchParticipantMatch.bracketMatch.winnerSide === matchParticipantMatch.side;
|
|
1598
|
+
const isLooser = matchParticipantMatch.bracketMatch.winnerSide &&
|
|
1599
|
+
matchParticipantMatch.bracketMatch.winnerSide !== matchParticipantMatch.side;
|
|
1619
1600
|
const isTie = matchParticipantMatch.bracketMatch.status === 'completed' && !matchParticipantMatch.bracketMatch.winner;
|
|
1620
1601
|
if (isWinner) {
|
|
1621
1602
|
winsTilNow++;
|
|
@@ -1724,8 +1705,8 @@ const generateBracketRoundSwissGroupMaps = (bracketData, matchParticipantMap) =>
|
|
|
1724
1705
|
}
|
|
1725
1706
|
const emptyMatchIds = [];
|
|
1726
1707
|
for (const match of bracketRound.matches.values()) {
|
|
1727
|
-
const participantHome = match.home ? (matchParticipantMap.get(match.home) ?? null) : null;
|
|
1728
|
-
const participantAway = match.away ? (matchParticipantMap.get(match.away) ?? null) : null;
|
|
1708
|
+
const participantHome = match.home ? (matchParticipantMap.get(match.home.id) ?? null) : null;
|
|
1709
|
+
const participantAway = match.away ? (matchParticipantMap.get(match.away.id) ?? null) : null;
|
|
1729
1710
|
const anyParticipant = participantHome || participantAway;
|
|
1730
1711
|
if (!anyParticipant) {
|
|
1731
1712
|
emptyMatchIds.push(match.id);
|
|
@@ -1772,7 +1753,7 @@ const generateBracketDataForEthlete = (source) => {
|
|
|
1772
1753
|
if (bracketData.rounds.some((r) => r.id === currentItem.round.id)) {
|
|
1773
1754
|
throw new Error(`Round with id ${currentItem.round.id} already exists in the bracket data.`);
|
|
1774
1755
|
}
|
|
1775
|
-
const roundType = generateRoundTypeFromEthleteRoundType(currentItem.round.type, tournamentMode);
|
|
1756
|
+
const roundType = generateRoundTypeFromEthleteRoundType(currentItem.round.type, tournamentMode, currentItem.matches.length);
|
|
1776
1757
|
const bracketRound = {
|
|
1777
1758
|
type: roundType,
|
|
1778
1759
|
id: currentItem.round.id,
|
|
@@ -1800,39 +1781,46 @@ const generateBracketDataForEthlete = (source) => {
|
|
|
1800
1781
|
};
|
|
1801
1782
|
const generateAndSetBracketMatchWithParticipants = (match, options) => {
|
|
1802
1783
|
const matchId = match.id;
|
|
1803
|
-
const { bracketData, bracketRound, currentIndexInRound } = options;
|
|
1784
|
+
const { bracketData, bracketRound, currentIndexInRound, participantCounter } = options;
|
|
1785
|
+
let localParticipantCounter = participantCounter;
|
|
1804
1786
|
const bracketMatch = {
|
|
1805
1787
|
id: matchId,
|
|
1806
1788
|
indexInRound: currentIndexInRound,
|
|
1807
1789
|
position: (currentIndexInRound + 1),
|
|
1808
1790
|
data: match.data,
|
|
1809
1791
|
round: bracketRound,
|
|
1810
|
-
home:
|
|
1811
|
-
away:
|
|
1812
|
-
winner: match.winner,
|
|
1792
|
+
home: null,
|
|
1793
|
+
away: null,
|
|
1813
1794
|
status: match.status,
|
|
1795
|
+
winnerSide: match.winner,
|
|
1796
|
+
winner: null,
|
|
1814
1797
|
};
|
|
1815
1798
|
bracketData.matches.set(matchId, bracketMatch);
|
|
1816
1799
|
bracketRound.matches.set(matchId, bracketMatch);
|
|
1817
|
-
const
|
|
1818
|
-
for (const [participantIndex,
|
|
1819
|
-
if (!
|
|
1800
|
+
const participantIds = [match.home, match.away];
|
|
1801
|
+
for (const [participantIndex, participantId] of participantIds.entries()) {
|
|
1802
|
+
if (!participantId)
|
|
1820
1803
|
continue;
|
|
1821
|
-
const side = participantIndex === 0 ? '
|
|
1822
|
-
if (!bracketData.participants.has(
|
|
1823
|
-
bracketData.participants.set(
|
|
1824
|
-
id:
|
|
1804
|
+
const side = participantIndex === 0 ? 'home' : 'away';
|
|
1805
|
+
if (!bracketData.participants.has(participantId)) {
|
|
1806
|
+
bracketData.participants.set(participantId, {
|
|
1807
|
+
id: participantId,
|
|
1808
|
+
shortId: `p${localParticipantCounter++}`,
|
|
1825
1809
|
name: `${side} ${currentIndexInRound}`,
|
|
1826
1810
|
matches: new Map(),
|
|
1827
1811
|
});
|
|
1828
1812
|
}
|
|
1829
|
-
const participantData = bracketData.participants.get(
|
|
1813
|
+
const participantData = bracketData.participants.get(participantId);
|
|
1830
1814
|
if (!participantData.matches.has(bracketMatch.id)) {
|
|
1831
1815
|
participantData.matches.set(bracketMatch.id, {
|
|
1832
|
-
side:
|
|
1816
|
+
side: match.home === participantId ? 'home' : 'away',
|
|
1833
1817
|
bracketMatch,
|
|
1834
1818
|
});
|
|
1835
1819
|
}
|
|
1820
|
+
bracketMatch[side] = participantData;
|
|
1821
|
+
if (bracketMatch.winnerSide === side) {
|
|
1822
|
+
bracketMatch.winner = participantData;
|
|
1823
|
+
}
|
|
1836
1824
|
}
|
|
1837
1825
|
return bracketMatch;
|
|
1838
1826
|
};
|
|
@@ -1852,11 +1840,12 @@ const generateBracketData = (source, options) => {
|
|
|
1852
1840
|
let currentUpperBracketIndex = 0;
|
|
1853
1841
|
let currentLowerBracketIndex = 0;
|
|
1854
1842
|
const splitRoundsRest = [];
|
|
1855
|
-
for (const round of source.rounds) {
|
|
1843
|
+
for (const [roundIndex, round] of source.rounds.entries()) {
|
|
1856
1844
|
const isLowerBracket = round.type === DOUBLE_ELIMINATION_BRACKET_ROUND_TYPE.LOWER_BRACKET;
|
|
1857
1845
|
const matches = source.matches.filter((m) => m.roundId === round.id);
|
|
1858
1846
|
const roundId = round.id;
|
|
1859
1847
|
const shouldSplitRound = shouldSplitRoundsInTwo && matches.length % 2 === 0;
|
|
1848
|
+
const isFirstRound = roundIndex === 0;
|
|
1860
1849
|
if (shouldSplitRound) {
|
|
1861
1850
|
const firstHalfMatchesMaxIndex = matches.length / 2 - 1;
|
|
1862
1851
|
const firstHalfRoundId = `${roundId}--half-1`;
|
|
@@ -1871,6 +1860,7 @@ const generateBracketData = (source, options) => {
|
|
|
1871
1860
|
matchCount: matches.length / 2,
|
|
1872
1861
|
matches: new Map(),
|
|
1873
1862
|
mirrorRoundType: BRACKET_ROUND_MIRROR_TYPE.LEFT,
|
|
1863
|
+
isFirstRound,
|
|
1874
1864
|
};
|
|
1875
1865
|
const bracketRoundSecondHalf = {
|
|
1876
1866
|
type: round.type,
|
|
@@ -1882,6 +1872,7 @@ const generateBracketData = (source, options) => {
|
|
|
1882
1872
|
matchCount: matches.length / 2,
|
|
1883
1873
|
matches: new Map(),
|
|
1884
1874
|
mirrorRoundType: BRACKET_ROUND_MIRROR_TYPE.RIGHT,
|
|
1875
|
+
isFirstRound,
|
|
1885
1876
|
};
|
|
1886
1877
|
bracketData.roundIds.push(firstHalfRoundId);
|
|
1887
1878
|
bracketData.rounds.set(firstHalfRoundId, bracketRoundFirstHalf);
|
|
@@ -1891,15 +1882,20 @@ const generateBracketData = (source, options) => {
|
|
|
1891
1882
|
const matchSecond = matches[firstHalfMatchesMaxIndex + 1 + index];
|
|
1892
1883
|
if (!matchFirst || !matchSecond)
|
|
1893
1884
|
throw new Error('Match not found');
|
|
1885
|
+
const participantCounter = bracketData.participants.size;
|
|
1894
1886
|
const bracketMatchFirst = generateAndSetBracketMatchWithParticipants(matchFirst, {
|
|
1895
1887
|
bracketData,
|
|
1896
1888
|
bracketRound: bracketRoundFirstHalf,
|
|
1897
1889
|
currentIndexInRound: index,
|
|
1890
|
+
participantCounter,
|
|
1898
1891
|
});
|
|
1892
|
+
// The participant counter might have changed after the first half
|
|
1893
|
+
const updatedParticipantCounter = bracketData.participants.size;
|
|
1899
1894
|
const bracketMatchSecond = generateAndSetBracketMatchWithParticipants(matchSecond, {
|
|
1900
1895
|
bracketData,
|
|
1901
1896
|
bracketRound: bracketRoundSecondHalf,
|
|
1902
1897
|
currentIndexInRound: index,
|
|
1898
|
+
participantCounter: updatedParticipantCounter,
|
|
1903
1899
|
});
|
|
1904
1900
|
bracketData.matchIds.push(bracketMatchFirst.id, bracketMatchSecond.id);
|
|
1905
1901
|
}
|
|
@@ -1915,15 +1911,18 @@ const generateBracketData = (source, options) => {
|
|
|
1915
1911
|
matchCount: matches.length,
|
|
1916
1912
|
matches: new Map(),
|
|
1917
1913
|
mirrorRoundType: null,
|
|
1914
|
+
isFirstRound,
|
|
1918
1915
|
};
|
|
1919
1916
|
bracketData.roundIds.push(roundId);
|
|
1920
1917
|
bracketData.rounds.set(roundId, bracketRound);
|
|
1921
1918
|
let currentIndexInRound = 0;
|
|
1922
1919
|
for (const match of matches) {
|
|
1920
|
+
const participantCounter = bracketData.participants.size;
|
|
1923
1921
|
const bracketMatch = generateAndSetBracketMatchWithParticipants(match, {
|
|
1924
1922
|
bracketData,
|
|
1925
1923
|
bracketRound,
|
|
1926
1924
|
currentIndexInRound,
|
|
1925
|
+
participantCounter,
|
|
1927
1926
|
});
|
|
1928
1927
|
bracketData.matchIds.push(bracketMatch.id);
|
|
1929
1928
|
currentIndexInRound++;
|
|
@@ -1953,29 +1952,30 @@ const generateBracketData = (source, options) => {
|
|
|
1953
1952
|
return bracketData;
|
|
1954
1953
|
};
|
|
1955
1954
|
|
|
1956
|
-
const path = (d, options) => `<path d="${d}" stroke="currentColor" fill="none" stroke-width="${options.width}" stroke-dasharray="${options.dashArray}" stroke-dashoffset="${options.dashOffset}" />`;
|
|
1955
|
+
const path = (d, options) => `<path d="${d.replace(/\s+/g, ' ').trim()}" stroke="currentColor" fill="none" stroke-width="${options.width}" stroke-dasharray="${options.dashArray}" stroke-dashoffset="${options.dashOffset}" class="${options.className}" />`;
|
|
1957
1956
|
const curve = (from, to, direction, options) => {
|
|
1958
1957
|
const fromInline = from.inline.end;
|
|
1959
|
-
const fromBlock = from.block.center;
|
|
1960
1958
|
const toInline = to.inline.start;
|
|
1961
1959
|
const toBlock = to.block.center;
|
|
1962
|
-
const
|
|
1960
|
+
const fromBlock = from.block.center;
|
|
1961
|
+
const startingCurveAmount = options.lineStartingCurveAmount;
|
|
1962
|
+
const endingCurveAmount = options.lineEndingCurveAmount;
|
|
1963
1963
|
const totalSpace = toInline - fromInline;
|
|
1964
|
-
const totalSpaceMinusCurve = totalSpace -
|
|
1964
|
+
const totalSpaceMinusCurve = totalSpace - startingCurveAmount - endingCurveAmount;
|
|
1965
1965
|
const lineLength = totalSpaceMinusCurve / 2;
|
|
1966
1966
|
const straightLeftEnd = fromInline + lineLength;
|
|
1967
1967
|
const straightRightStart = toInline - lineLength;
|
|
1968
1968
|
// first 90 degree curve down
|
|
1969
1969
|
const firstCurveStartX = straightLeftEnd;
|
|
1970
|
-
const firstCurveEndX = straightLeftEnd +
|
|
1971
|
-
const firstCurveEndY = direction === 'down' ? fromBlock +
|
|
1972
|
-
const firstCurveBezierX = straightLeftEnd +
|
|
1970
|
+
const firstCurveEndX = straightLeftEnd + startingCurveAmount;
|
|
1971
|
+
const firstCurveEndY = direction === 'down' ? fromBlock + startingCurveAmount : fromBlock - startingCurveAmount;
|
|
1972
|
+
const firstCurveBezierX = straightLeftEnd + startingCurveAmount;
|
|
1973
1973
|
const firstCurveBezierY = fromBlock;
|
|
1974
1974
|
// second 90 degree curve to the right
|
|
1975
|
-
const secondCurveStartY = direction === 'down' ? toBlock -
|
|
1975
|
+
const secondCurveStartY = direction === 'down' ? toBlock - endingCurveAmount : toBlock + endingCurveAmount;
|
|
1976
1976
|
const secondCurveEndX = straightRightStart;
|
|
1977
1977
|
const secondCurveEndY = toBlock;
|
|
1978
|
-
const secondCurveBezierX = straightRightStart -
|
|
1978
|
+
const secondCurveBezierX = straightRightStart - endingCurveAmount;
|
|
1979
1979
|
const secondCurveBezierY = toBlock;
|
|
1980
1980
|
const pathStr = `
|
|
1981
1981
|
M ${fromInline} ${fromBlock}
|
|
@@ -1984,7 +1984,40 @@ const curve = (from, to, direction, options) => {
|
|
|
1984
1984
|
V ${secondCurveStartY}
|
|
1985
1985
|
Q ${secondCurveBezierX} ${secondCurveBezierY}, ${secondCurveEndX} ${secondCurveEndY}
|
|
1986
1986
|
H ${toInline}
|
|
1987
|
-
|
|
1987
|
+
`;
|
|
1988
|
+
return path(pathStr, options.path);
|
|
1989
|
+
};
|
|
1990
|
+
const curveInverted = (from, to, direction, options) => {
|
|
1991
|
+
const fromInline = from.inline.start;
|
|
1992
|
+
const fromBlock = from.block.center;
|
|
1993
|
+
const toInline = to.inline.end;
|
|
1994
|
+
const toBlock = to.block.center;
|
|
1995
|
+
const startingCurveAmount = options.lineStartingCurveAmount;
|
|
1996
|
+
const endingCurveAmount = options.lineEndingCurveAmount;
|
|
1997
|
+
const totalSpace = fromInline - toInline;
|
|
1998
|
+
const totalSpaceMinusCurve = totalSpace - startingCurveAmount - endingCurveAmount;
|
|
1999
|
+
const lineLength = totalSpaceMinusCurve / 2;
|
|
2000
|
+
const straightRightEnd = fromInline - lineLength;
|
|
2001
|
+
const straightLeftStart = toInline + lineLength;
|
|
2002
|
+
const firstCurveStartX = straightRightEnd;
|
|
2003
|
+
const firstCurveEndX = straightRightEnd - startingCurveAmount;
|
|
2004
|
+
const firstCurveEndY = direction === 'down' ? fromBlock + startingCurveAmount : fromBlock - startingCurveAmount;
|
|
2005
|
+
const firstCurveBezierX = straightRightEnd - startingCurveAmount;
|
|
2006
|
+
const firstCurveBezierY = fromBlock;
|
|
2007
|
+
// second 90 degree curve to the right
|
|
2008
|
+
const secondCurveStartY = direction === 'down' ? toBlock - endingCurveAmount : toBlock + endingCurveAmount;
|
|
2009
|
+
const secondCurveEndX = straightLeftStart;
|
|
2010
|
+
const secondCurveEndY = toBlock;
|
|
2011
|
+
const secondCurveBezierX = straightLeftStart + endingCurveAmount;
|
|
2012
|
+
const secondCurveBezierY = toBlock;
|
|
2013
|
+
const pathStr = `
|
|
2014
|
+
M ${fromInline} ${fromBlock}
|
|
2015
|
+
H ${firstCurveStartX}
|
|
2016
|
+
Q ${firstCurveBezierX} ${firstCurveBezierY}, ${firstCurveEndX} ${firstCurveEndY}
|
|
2017
|
+
V ${secondCurveStartY}
|
|
2018
|
+
Q ${secondCurveBezierX} ${secondCurveBezierY}, ${secondCurveEndX} ${secondCurveEndY}
|
|
2019
|
+
H ${toInline}
|
|
2020
|
+
`;
|
|
1988
2021
|
return path(pathStr, options.path);
|
|
1989
2022
|
};
|
|
1990
2023
|
const line = (from, to, options) => {
|
|
@@ -2062,10 +2095,14 @@ const drawMan = (items, firstRounds, dimensions) => {
|
|
|
2062
2095
|
matchHeight,
|
|
2063
2096
|
rowGap,
|
|
2064
2097
|
};
|
|
2065
|
-
|
|
2066
|
-
|
|
2067
|
-
|
|
2068
|
-
|
|
2098
|
+
const currentMatchParticipantsShortIds = [
|
|
2099
|
+
item.matchRelation.currentMatch.home?.shortId,
|
|
2100
|
+
item.matchRelation.currentMatch.away?.shortId,
|
|
2101
|
+
]
|
|
2102
|
+
.filter((id) => !!id)
|
|
2103
|
+
.join(' ');
|
|
2104
|
+
const pathOptions = { ...dimensions.path, className: currentMatchParticipantsShortIds };
|
|
2105
|
+
const currentMatchPosition = getMatchPosition(round, item.matchRelation.currentMatch.id, staticMeasurements);
|
|
2069
2106
|
// We only draw the left side of the match relation
|
|
2070
2107
|
switch (item.matchRelation.type) {
|
|
2071
2108
|
case 'nothing-to-one': {
|
|
@@ -2073,31 +2110,36 @@ const drawMan = (items, firstRounds, dimensions) => {
|
|
|
2073
2110
|
}
|
|
2074
2111
|
case 'one-to-nothing':
|
|
2075
2112
|
case 'one-to-one': {
|
|
2076
|
-
const
|
|
2077
|
-
const current = getMatchPosition(round, item.matchRelation.currentMatch.id, staticMeasurements);
|
|
2113
|
+
const previousMatchPosition = getMatchPosition(items.get(item.matchRelation.previousRound.id), item.matchRelation.previousMatch.id, staticMeasurements);
|
|
2078
2114
|
// draw a straight line
|
|
2079
|
-
svgParts.push(line(
|
|
2080
|
-
break;
|
|
2081
|
-
}
|
|
2082
|
-
case 'one-to-two': {
|
|
2083
|
-
const nextUpper = getMatchPosition(items.get(item.matchRelation.nextUpperRound.id), item.matchRelation.nextUpperMatch.id, staticMeasurements);
|
|
2084
|
-
const nextLower = getMatchPosition(items.get(item.matchRelation.nextLowerRound.id), item.matchRelation.nextLowerMatch.id, staticMeasurements);
|
|
2085
|
-
const current = getMatchPosition(round, item.matchRelation.currentMatch.id, staticMeasurements);
|
|
2086
|
-
// const curveOptions: CurveOptions = { ...dimensions.curve, path: dimensions.path };
|
|
2087
|
-
// // draw two lines that merge into one in the middle
|
|
2088
|
-
// svgParts.push(curve(nextUpper, current, 'down', curveOptions));
|
|
2089
|
-
// svgParts.push(curve(nextLower, current, 'up', curveOptions));
|
|
2115
|
+
svgParts.push(line(previousMatchPosition, currentMatchPosition, { path: pathOptions }));
|
|
2090
2116
|
break;
|
|
2091
2117
|
}
|
|
2092
2118
|
case 'two-to-nothing':
|
|
2093
2119
|
case 'two-to-one': {
|
|
2094
2120
|
const previousUpper = getMatchPosition(items.get(item.matchRelation.previousUpperRound.id), item.matchRelation.previousUpperMatch.id, staticMeasurements);
|
|
2095
2121
|
const previousLower = getMatchPosition(items.get(item.matchRelation.previousLowerRound.id), item.matchRelation.previousLowerMatch.id, staticMeasurements);
|
|
2096
|
-
const
|
|
2097
|
-
|
|
2122
|
+
const curveOptions = {
|
|
2123
|
+
...dimensions.curve,
|
|
2124
|
+
path: { ...dimensions.path, className: '' },
|
|
2125
|
+
};
|
|
2126
|
+
const curveFn = item.roundRelation.currentRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT ? curveInverted : curve;
|
|
2098
2127
|
// draw two lines that merge into one in the middle
|
|
2099
|
-
svgParts.push(
|
|
2100
|
-
|
|
2128
|
+
svgParts.push(curveFn(previousUpper, currentMatchPosition, 'down', {
|
|
2129
|
+
...curveOptions,
|
|
2130
|
+
path: { ...curveOptions.path, className: item.matchRelation.previousUpperMatch.winner?.shortId || '' },
|
|
2131
|
+
}));
|
|
2132
|
+
svgParts.push(curveFn(previousLower, currentMatchPosition, 'up', {
|
|
2133
|
+
...curveOptions,
|
|
2134
|
+
path: { ...curveOptions.path, className: item.matchRelation.previousLowerMatch.winner?.shortId || '' },
|
|
2135
|
+
}));
|
|
2136
|
+
if (item.matchRelation.currentRound.mirrorRoundType === BRACKET_ROUND_MIRROR_TYPE.RIGHT &&
|
|
2137
|
+
item.matchRelation.type === 'two-to-one' &&
|
|
2138
|
+
item.matchRelation.nextRound.mirrorRoundType === null) {
|
|
2139
|
+
// draw a straight line for the special case of connecting the final match to the mirrored semi final match
|
|
2140
|
+
const next = getMatchPosition(items.get(item.matchRelation.nextRound.id), item.matchRelation.nextMatch.id, staticMeasurements);
|
|
2141
|
+
svgParts.push(line(next, currentMatchPosition, { path: pathOptions }));
|
|
2142
|
+
}
|
|
2101
2143
|
break;
|
|
2102
2144
|
}
|
|
2103
2145
|
}
|
|
@@ -2184,10 +2226,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImpo
|
|
|
2184
2226
|
const generateBracketGridItems = (bracketData, roundTypeMap, swissGroups, roundRelations, matchRelations, options) => {
|
|
2185
2227
|
const roundHeaderComponent = options.headerComponent ?? NewBracketDefaultRoundHeaderComponent;
|
|
2186
2228
|
const matchComponent = options.matchComponent ?? NewBracketDefaultMatchComponent;
|
|
2229
|
+
const finalMatchComponent = options.finalMatchComponent ?? matchComponent;
|
|
2187
2230
|
const optionsWithDefaults = {
|
|
2188
2231
|
...options,
|
|
2189
2232
|
headerComponent: roundHeaderComponent,
|
|
2190
2233
|
matchComponent: matchComponent,
|
|
2234
|
+
finalMatchComponent: finalMatchComponent,
|
|
2191
2235
|
};
|
|
2192
2236
|
switch (bracketData.mode) {
|
|
2193
2237
|
case TOURNAMENT_MODE.DOUBLE_ELIMINATION:
|
|
@@ -2234,6 +2278,7 @@ const generateGenericGridPlacements = (bracketData, roundTypeMap, roundRelations
|
|
|
2234
2278
|
rowStart: currentMatchRow,
|
|
2235
2279
|
rowEnd: ++currentMatchRow,
|
|
2236
2280
|
component: options.headerComponent,
|
|
2281
|
+
className: 'et-bracket-new-item et-bracket-round-header-container',
|
|
2237
2282
|
roundRelation,
|
|
2238
2283
|
data: {
|
|
2239
2284
|
bracketRound: round,
|
|
@@ -2249,15 +2294,17 @@ const generateGenericGridPlacements = (bracketData, roundTypeMap, roundRelations
|
|
|
2249
2294
|
throw new Error('Match relation is missing');
|
|
2250
2295
|
}
|
|
2251
2296
|
const baseRow = match.indexInRound * matchHeight;
|
|
2297
|
+
const participantShortIds = [match.home?.shortId, match.away?.shortId].filter((id) => !!id).join(' ');
|
|
2252
2298
|
const matchItem = {
|
|
2253
2299
|
type: 'match',
|
|
2254
2300
|
id: match.id,
|
|
2255
2301
|
layoutId: `${match.id}-layout`,
|
|
2256
2302
|
rowStart: baseRow + currentMatchRow,
|
|
2257
2303
|
rowEnd: baseRow + currentMatchRow + matchHeight,
|
|
2258
|
-
component: options.matchComponent,
|
|
2304
|
+
component: round.type === COMMON_BRACKET_ROUND_TYPE.FINAL ? options.finalMatchComponent : options.matchComponent,
|
|
2259
2305
|
matchRelation,
|
|
2260
2306
|
roundRelation,
|
|
2307
|
+
className: `et-bracket-new-item et-bracket-match-container ${participantShortIds}`,
|
|
2261
2308
|
data: {
|
|
2262
2309
|
bracketRound: round,
|
|
2263
2310
|
bracketMatch: match,
|
|
@@ -2278,23 +2325,47 @@ const generateSwissWithEliminationGridPlacements = (bracketData, roundTypeMap, s
|
|
|
2278
2325
|
return gridItems;
|
|
2279
2326
|
};
|
|
2280
2327
|
|
|
2328
|
+
const createJourneyHighlight = (bracketData) => {
|
|
2329
|
+
let styles = '';
|
|
2330
|
+
for (const participant of bracketData.participants.values()) {
|
|
2331
|
+
styles += `
|
|
2332
|
+
.et-new-bracket-host:has(.${participant.shortId}:hover) {
|
|
2333
|
+
path, .et-bracket-match-container {
|
|
2334
|
+
opacity: 0.5;
|
|
2335
|
+
}
|
|
2336
|
+
|
|
2337
|
+
.${participant.shortId} {
|
|
2338
|
+
opacity: 1 !important;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
`;
|
|
2342
|
+
}
|
|
2343
|
+
return styles.replace(/\s+/g, ' ').trim();
|
|
2344
|
+
};
|
|
2345
|
+
|
|
2281
2346
|
class NewBracketComponent {
|
|
2347
|
+
#domSanitizer;
|
|
2348
|
+
#elementId;
|
|
2282
2349
|
constructor() {
|
|
2283
2350
|
this.#domSanitizer = inject(DomSanitizer);
|
|
2351
|
+
this.#elementId = createComponentId('et-new-bracket');
|
|
2284
2352
|
this.source = input.required();
|
|
2285
2353
|
this.columnWidth = input(250, { transform: numberAttribute });
|
|
2286
2354
|
this.matchHeight = input(75, { transform: numberAttribute });
|
|
2287
2355
|
this.roundHeaderHeight = input(50, { transform: numberAttribute });
|
|
2288
2356
|
this.columnGap = input(60, { transform: numberAttribute });
|
|
2289
2357
|
this.rowGap = input(30, { transform: numberAttribute });
|
|
2290
|
-
this.
|
|
2358
|
+
this.lineStartingCurveAmount = input(10, { transform: numberAttribute });
|
|
2359
|
+
this.lineEndingCurveAmount = input(0, { transform: numberAttribute });
|
|
2291
2360
|
this.lineWidth = input(2, { transform: numberAttribute });
|
|
2292
2361
|
this.lineDashArray = input(0, { transform: numberAttribute });
|
|
2293
2362
|
this.lineDashOffset = input(0, { transform: numberAttribute });
|
|
2363
|
+
this.disableJourneyHighlight = input(false, { transform: booleanAttribute });
|
|
2294
2364
|
this.layout = input(BRACKET_DATA_LAYOUT.LEFT_TO_RIGHT);
|
|
2295
2365
|
this.hideRoundHeaders = input(false, { transform: booleanAttribute });
|
|
2296
2366
|
this.roundHeaderComponent = input();
|
|
2297
2367
|
this.matchComponent = input();
|
|
2368
|
+
this.finalMatchComponent = input();
|
|
2298
2369
|
this.bracketData = computed(() => generateBracketData(this.source(), { layout: this.layout() }));
|
|
2299
2370
|
this.roundTypeMap = computed(() => generateBracketRoundTypeMap(this.bracketData()));
|
|
2300
2371
|
this.matchParticipantMap = computed(() => generateMatchParticipantMap(this.bracketData()));
|
|
@@ -2306,6 +2377,7 @@ class NewBracketComponent {
|
|
|
2306
2377
|
includeRoundHeaders: !this.hideRoundHeaders(),
|
|
2307
2378
|
headerComponent: this.roundHeaderComponent(),
|
|
2308
2379
|
matchComponent: this.matchComponent(),
|
|
2380
|
+
finalMatchComponent: this.finalMatchComponent(),
|
|
2309
2381
|
}));
|
|
2310
2382
|
this.definitions = computed(() => generateBracketGridDefinitions(this.bracketData(), this.roundTypeMap(), {
|
|
2311
2383
|
includeRoundHeaders: !this.hideRoundHeaders(),
|
|
@@ -2319,7 +2391,8 @@ class NewBracketComponent {
|
|
|
2319
2391
|
rowGap: this.rowGap(),
|
|
2320
2392
|
gridDefinitions: this.definitions(),
|
|
2321
2393
|
curve: {
|
|
2322
|
-
|
|
2394
|
+
lineEndingCurveAmount: this.lineEndingCurveAmount(),
|
|
2395
|
+
lineStartingCurveAmount: this.lineStartingCurveAmount(),
|
|
2323
2396
|
},
|
|
2324
2397
|
path: {
|
|
2325
2398
|
dashArray: this.lineDashArray(),
|
|
@@ -2327,17 +2400,45 @@ class NewBracketComponent {
|
|
|
2327
2400
|
width: this.lineWidth(),
|
|
2328
2401
|
},
|
|
2329
2402
|
})));
|
|
2403
|
+
this.journeyHighlight = computed(() => this.disableJourneyHighlight() ? null : createJourneyHighlight(this.bracketData()));
|
|
2404
|
+
const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
|
|
2405
|
+
if (!isBrowser)
|
|
2406
|
+
return;
|
|
2407
|
+
const renderer = inject(Renderer2);
|
|
2408
|
+
const styleId = `et-new-bracket-journey-highlight--${this.#elementId}`;
|
|
2409
|
+
let oldStyleEl = null;
|
|
2410
|
+
effect(() => {
|
|
2411
|
+
const newHighlightStyle = this.journeyHighlight();
|
|
2412
|
+
const head = document.head;
|
|
2413
|
+
if (oldStyleEl) {
|
|
2414
|
+
renderer.removeChild(head, oldStyleEl);
|
|
2415
|
+
}
|
|
2416
|
+
if (newHighlightStyle) {
|
|
2417
|
+
const el = renderer.createElement('style');
|
|
2418
|
+
renderer.setAttribute(el, 'id', styleId);
|
|
2419
|
+
renderer.appendChild(el, renderer.createText(newHighlightStyle));
|
|
2420
|
+
renderer.appendChild(head, el);
|
|
2421
|
+
oldStyleEl = el;
|
|
2422
|
+
}
|
|
2423
|
+
else {
|
|
2424
|
+
oldStyleEl = null;
|
|
2425
|
+
}
|
|
2426
|
+
});
|
|
2427
|
+
inject(DestroyRef).onDestroy(() => {
|
|
2428
|
+
if (oldStyleEl) {
|
|
2429
|
+
renderer.removeChild(document.head, oldStyleEl);
|
|
2430
|
+
}
|
|
2431
|
+
});
|
|
2330
2432
|
}
|
|
2331
|
-
#domSanitizer;
|
|
2332
2433
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NewBracketComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2333
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: NewBracketComponent, isStandalone: true, selector: "et-new-bracket", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, columnWidth: { classPropertyName: "columnWidth", publicName: "columnWidth", isSignal: true, isRequired: false, transformFunction: null }, matchHeight: { classPropertyName: "matchHeight", publicName: "matchHeight", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderHeight: { classPropertyName: "roundHeaderHeight", publicName: "roundHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, columnGap: { classPropertyName: "columnGap", publicName: "columnGap", isSignal: true, isRequired: false, transformFunction: null }, rowGap: { classPropertyName: "rowGap", publicName: "rowGap", isSignal: true, isRequired: false, transformFunction: null },
|
|
2434
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.12", type: NewBracketComponent, isStandalone: true, selector: "et-new-bracket", inputs: { source: { classPropertyName: "source", publicName: "source", isSignal: true, isRequired: true, transformFunction: null }, columnWidth: { classPropertyName: "columnWidth", publicName: "columnWidth", isSignal: true, isRequired: false, transformFunction: null }, matchHeight: { classPropertyName: "matchHeight", publicName: "matchHeight", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderHeight: { classPropertyName: "roundHeaderHeight", publicName: "roundHeaderHeight", isSignal: true, isRequired: false, transformFunction: null }, columnGap: { classPropertyName: "columnGap", publicName: "columnGap", isSignal: true, isRequired: false, transformFunction: null }, rowGap: { classPropertyName: "rowGap", publicName: "rowGap", isSignal: true, isRequired: false, transformFunction: null }, lineStartingCurveAmount: { classPropertyName: "lineStartingCurveAmount", publicName: "lineStartingCurveAmount", isSignal: true, isRequired: false, transformFunction: null }, lineEndingCurveAmount: { classPropertyName: "lineEndingCurveAmount", publicName: "lineEndingCurveAmount", isSignal: true, isRequired: false, transformFunction: null }, lineWidth: { classPropertyName: "lineWidth", publicName: "lineWidth", isSignal: true, isRequired: false, transformFunction: null }, lineDashArray: { classPropertyName: "lineDashArray", publicName: "lineDashArray", isSignal: true, isRequired: false, transformFunction: null }, lineDashOffset: { classPropertyName: "lineDashOffset", publicName: "lineDashOffset", isSignal: true, isRequired: false, transformFunction: null }, disableJourneyHighlight: { classPropertyName: "disableJourneyHighlight", publicName: "disableJourneyHighlight", isSignal: true, isRequired: false, transformFunction: null }, layout: { classPropertyName: "layout", publicName: "layout", isSignal: true, isRequired: false, transformFunction: null }, hideRoundHeaders: { classPropertyName: "hideRoundHeaders", publicName: "hideRoundHeaders", isSignal: true, isRequired: false, transformFunction: null }, roundHeaderComponent: { classPropertyName: "roundHeaderComponent", publicName: "roundHeaderComponent", isSignal: true, isRequired: false, transformFunction: null }, matchComponent: { classPropertyName: "matchComponent", publicName: "matchComponent", isSignal: true, isRequired: false, transformFunction: null }, finalMatchComponent: { classPropertyName: "finalMatchComponent", publicName: "finalMatchComponent", isSignal: true, isRequired: false, transformFunction: null } }, host: { classAttribute: "et-new-bracket-host" }, ngImport: i0, template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"hideRoundHeaders() ? matchHeight() : roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.layoutId) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.layoutId) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" [class]=\"item.className\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw);--bracket-line-color: red}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center;transition:opacity .2s}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}.et-bracket-new-svg path{color:var(--bracket-line-color);transition:opacity .2s}\n"], dependencies: [{ kind: "directive", type: NgComponentOutlet, selector: "[ngComponentOutlet]", inputs: ["ngComponentOutlet", "ngComponentOutletInputs", "ngComponentOutletInjector", "ngComponentOutletContent", "ngComponentOutletNgModule", "ngComponentOutletNgModuleFactory"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
2334
2435
|
}
|
|
2335
2436
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.12", ngImport: i0, type: NewBracketComponent, decorators: [{
|
|
2336
2437
|
type: Component,
|
|
2337
2438
|
args: [{ selector: 'et-new-bracket', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
2338
2439
|
class: 'et-new-bracket-host',
|
|
2339
|
-
}, imports: [NgComponentOutlet], template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.layoutId) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.layoutId) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" class=\"
|
|
2340
|
-
}] });
|
|
2440
|
+
}, imports: [NgComponentOutlet], template: "<section\n [style.--_cw.px]=\"columnWidth()\"\n [style.--_mh.px]=\"matchHeight()\"\n [style.--_rhh.px]=\"hideRoundHeaders() ? matchHeight() : roundHeaderHeight()\"\n [style.--_cg.px]=\"columnGap()\"\n [style.--_rg.px]=\"rowGap()\"\n [style.--_bcc]=\"definitions().columnCount\"\n [style.--_brc]=\"definitions().rowCount\"\n class=\"et-bracket-new\"\n>\n <svg [innerHTML]=\"drawManData()\" class=\"et-bracket-new-svg\" xmlns=\"http://www.w3.org/2000/svg\" />\n\n @for (round of items().values(); track round.layoutId) {\n <ul [style.--_c]=\"round.columnStart + ' / ' + round.columnEnd\" class=\"et-bracket-new-round\">\n @for (item of round.items.values(); track item.layoutId) {\n <li [style.--_r]=\"item.rowStart + ' / ' + item.rowEnd\" [class]=\"item.className\">\n <ng-container *ngComponentOutlet=\"item.component; inputs: item.data\" />\n </li>\n }\n </ul>\n }\n</section>\n", styles: [".et-bracket-new{display:grid;gap:var(--_cg);grid-auto-columns:var(--_cw);--bracket-line-color: red}.et-bracket-new-round{display:grid;grid-column:var(--_c);grid-row:1;list-style:none;margin:0;padding:0;gap:var(--_rg);grid-template-rows:var(--_rhh);grid-auto-rows:var(--_mh)}.et-bracket-new-item{grid-row:var(--_r);place-self:center;transition:opacity .2s}.et-bracket-new-svg{grid-column:1/calc(var(--_bcc) + 1);grid-row:1/2;inline-size:100%;block-size:100%}.et-bracket-new-svg path{color:var(--bracket-line-color);transition:opacity .2s}\n"] }]
|
|
2441
|
+
}], ctorParameters: () => [] });
|
|
2341
2442
|
|
|
2342
2443
|
var index = /*#__PURE__*/Object.freeze({
|
|
2343
2444
|
__proto__: null,
|