@algoux/standard-ranklist-renderer-component-angular 0.5.1 → 0.6.1
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/README.md +48 -0
- package/dist/README.md +48 -0
- package/dist/esm2022/lib/index.mjs +1 -1
- package/dist/esm2022/lib/ranklist/ranklist.component.mjs +464 -44
- package/dist/esm2022/lib/ranklist/status-cell-template.directive.mjs +1 -1
- package/dist/esm2022/lib/ranklist/user-cell-template.directive.mjs +1 -1
- package/dist/esm2022/lib/types.mjs +1 -1
- package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs +466 -46
- package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs.map +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/ranklist/ranklist.component.d.ts +35 -4
- package/dist/lib/ranklist/status-cell-template.directive.d.ts +4 -1
- package/dist/lib/ranklist/user-cell-template.directive.d.ts +2 -0
- package/dist/lib/types.d.ts +2 -0
- package/package.json +8 -3
|
@@ -3,7 +3,7 @@ import { CommonModule } from '@angular/common';
|
|
|
3
3
|
import * as i0 from '@angular/core';
|
|
4
4
|
import { EventEmitter, ViewChild, Output, Input, Component, inject, TemplateRef, Directive, ContentChild, ChangeDetectionStrategy } from '@angular/core';
|
|
5
5
|
import { EnumTheme, formatTimeDuration, numberToAlphabet, resolveText, secToTimeStr, resolveStyle, resolveUserMarkers, canRegenerateRanklist } from '@algoux/standard-ranklist-utils';
|
|
6
|
-
import { ensureModalInteractionTracker, unlockModalBodyScroll, SRK_ANIMATED_MODAL_ROOT_CLASS, resolveModalTransformOrigin, MODAL_ANIMATION_DURATION_MS, lockModalBodyScroll, registerModalFocusScope, unregisterModalFocusScope, srkSupportedVersions, caniuse, captureModalTriggerPointFromMouseEvent } from '@algoux/standard-ranklist-renderer-component-core';
|
|
6
|
+
import { ensureModalInteractionTracker, unlockModalBodyScroll, SRK_ANIMATED_MODAL_ROOT_CLASS, resolveModalTransformOrigin, MODAL_ANIMATION_DURATION_MS, lockModalBodyScroll, registerModalFocusScope, unregisterModalFocusScope, srkSupportedVersions, calculateProblemStatisticsFooter, caniuse, shouldShowTimeColumn as shouldShowTimeColumn$1, getProblemHeaderBackgroundImage as getProblemHeaderBackgroundImage$1, getMarkerPresentation as getMarkerPresentation$1, resolveSrkAssetUrl as resolveSrkAssetUrl$1, calculateDirtPercentage, calculateSEValue, getRankProblemStatusCellPresentation, captureModalTriggerPointFromMouseEvent, formatProblemStatisticsAcceptedMinute, formatProblemStatisticsAverageHardness, formatProblemStatisticsPercent } from '@algoux/standard-ranklist-renderer-component-core';
|
|
7
7
|
|
|
8
8
|
const defaultBackgroundColor = {
|
|
9
9
|
[EnumTheme.light]: '#ffffff',
|
|
@@ -997,18 +997,86 @@ class RanklistComponent {
|
|
|
997
997
|
data;
|
|
998
998
|
theme = EnumTheme.light;
|
|
999
999
|
borderedRows = false;
|
|
1000
|
+
rowBordered = false;
|
|
1001
|
+
columnBordered = false;
|
|
1000
1002
|
stripedRows = false;
|
|
1001
1003
|
formatSrkAssetUrl;
|
|
1004
|
+
splitOrganization = false;
|
|
1005
|
+
columnTitles;
|
|
1006
|
+
statusCellPreset = 'classic';
|
|
1007
|
+
statusColorAsText = false;
|
|
1008
|
+
showProblemStatisticsFooter = false;
|
|
1009
|
+
showDirtColumn = false;
|
|
1010
|
+
showSEColumn = false;
|
|
1011
|
+
emptyStatusPlaceholder = null;
|
|
1012
|
+
userAvatarPlacement = 'user';
|
|
1002
1013
|
userClick = new EventEmitter();
|
|
1003
1014
|
solutionClick = new EventEmitter();
|
|
1004
1015
|
statusCellTemplate;
|
|
1005
1016
|
userCellTemplate;
|
|
1006
1017
|
supportedVersions = srkSupportedVersions;
|
|
1018
|
+
firstBloodStar = '\u2605';
|
|
1019
|
+
statusSeparator = ' ';
|
|
1020
|
+
problemStatisticsFooterRows = [
|
|
1021
|
+
{
|
|
1022
|
+
key: 'accepted',
|
|
1023
|
+
label: 'Accepted',
|
|
1024
|
+
tooltip: 'Number of participants who solved this problem',
|
|
1025
|
+
},
|
|
1026
|
+
{
|
|
1027
|
+
key: 'tried',
|
|
1028
|
+
label: 'Tried',
|
|
1029
|
+
tooltip: 'Number of participants who attempted this problem',
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
key: 'submitted',
|
|
1033
|
+
label: 'Submitted',
|
|
1034
|
+
tooltip: 'Total number of valid submissions for this problem',
|
|
1035
|
+
},
|
|
1036
|
+
{
|
|
1037
|
+
key: 'dirt',
|
|
1038
|
+
label: 'Dirt',
|
|
1039
|
+
tooltip: 'Wrong submissions among participants who solved this problem',
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
key: 'se',
|
|
1043
|
+
label: 'SE',
|
|
1044
|
+
tooltip: 'Average hardness, calculated as (participants - accepted) / participants',
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
key: 'firstAccepted',
|
|
1048
|
+
label: 'FB at',
|
|
1049
|
+
tooltip: 'First Blood at, also known as first solve time, in minutes',
|
|
1050
|
+
},
|
|
1051
|
+
{
|
|
1052
|
+
key: 'lastAccepted',
|
|
1053
|
+
label: 'LB at',
|
|
1054
|
+
tooltip: 'Last Blood at, also known as last solve time, in minutes',
|
|
1055
|
+
},
|
|
1056
|
+
];
|
|
1057
|
+
problemStatisticsSource;
|
|
1058
|
+
problemStatisticsCache;
|
|
1059
|
+
get problemStatistics() {
|
|
1060
|
+
if (!this.showProblemStatisticsFooter && !this.showSEColumn) {
|
|
1061
|
+
return [];
|
|
1062
|
+
}
|
|
1063
|
+
if (this.problemStatisticsSource !== this.data || !this.problemStatisticsCache) {
|
|
1064
|
+
this.problemStatisticsSource = this.data;
|
|
1065
|
+
this.problemStatisticsCache = calculateProblemStatisticsFooter(this.data);
|
|
1066
|
+
}
|
|
1067
|
+
return this.problemStatisticsCache;
|
|
1068
|
+
}
|
|
1007
1069
|
isSupportedVersion() {
|
|
1008
1070
|
return caniuse(this.data.version);
|
|
1009
1071
|
}
|
|
1010
1072
|
showTimeColumn() {
|
|
1011
|
-
return shouldShowTimeColumn(this.data.rows);
|
|
1073
|
+
return shouldShowTimeColumn$1(this.data.rows);
|
|
1074
|
+
}
|
|
1075
|
+
showAvatarInOrganization() {
|
|
1076
|
+
return this.splitOrganization && this.userAvatarPlacement === 'organization';
|
|
1077
|
+
}
|
|
1078
|
+
leftFooterColumnCount() {
|
|
1079
|
+
return this.data.series.length + 1 + 1 + (this.showTimeColumn() ? 1 : 0) + (this.splitOrganization ? 1 : 0);
|
|
1012
1080
|
}
|
|
1013
1081
|
getRankValues(row) {
|
|
1014
1082
|
return row.rankValues || this.data.series.map(() => ({ rank: null, segmentIndex: null }));
|
|
@@ -1019,6 +1087,19 @@ class RanklistComponent {
|
|
|
1019
1087
|
resolveDisplayText(text) {
|
|
1020
1088
|
return resolveText(text);
|
|
1021
1089
|
}
|
|
1090
|
+
resolveSeriesColumnTitle(series, index) {
|
|
1091
|
+
const seriesTitles = this.columnTitles?.series;
|
|
1092
|
+
if (typeof seriesTitles === 'function') {
|
|
1093
|
+
return seriesTitles(series, index) ?? series.title;
|
|
1094
|
+
}
|
|
1095
|
+
if (Array.isArray(seriesTitles)) {
|
|
1096
|
+
return seriesTitles[index] ?? series.title;
|
|
1097
|
+
}
|
|
1098
|
+
return series.title;
|
|
1099
|
+
}
|
|
1100
|
+
resolveColumnTitle(key, fallback) {
|
|
1101
|
+
return this.columnTitles?.[key] ?? fallback;
|
|
1102
|
+
}
|
|
1022
1103
|
problemAlias(problem, problemIndex) {
|
|
1023
1104
|
return problem.alias || numberToAlphabet(problemIndex);
|
|
1024
1105
|
}
|
|
@@ -1026,23 +1107,29 @@ class RanklistComponent {
|
|
|
1026
1107
|
const ratio = statistics.submitted ? ((statistics.accepted / statistics.submitted) * 100).toFixed(1) : 0;
|
|
1027
1108
|
return `${statistics.accepted} / ${statistics.submitted} (${ratio}%)`;
|
|
1028
1109
|
}
|
|
1029
|
-
problemHeaderBackgroundImage(problem) {
|
|
1030
|
-
return getProblemHeaderBackgroundImage(problem.style, this.theme);
|
|
1110
|
+
problemHeaderBackgroundImage(problem, gradientDirection = 180) {
|
|
1111
|
+
return getProblemHeaderBackgroundImage$1(problem.style, this.theme, gradientDirection);
|
|
1031
1112
|
}
|
|
1032
1113
|
resolvedUserMarkers(user) {
|
|
1033
1114
|
return resolveUserMarkers(user, this.data.markers).map((marker) => ({
|
|
1034
1115
|
marker,
|
|
1035
|
-
presentation: getMarkerPresentation(marker, this.theme),
|
|
1116
|
+
presentation: getMarkerPresentation$1(marker, this.theme),
|
|
1036
1117
|
}));
|
|
1037
1118
|
}
|
|
1038
1119
|
formatAssetUrl(url, field) {
|
|
1039
|
-
return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
|
|
1120
|
+
return resolveSrkAssetUrl$1(url, field, this.formatSrkAssetUrl);
|
|
1040
1121
|
}
|
|
1041
1122
|
formatTime(time) {
|
|
1042
1123
|
return formatTimeDuration(time, 'min', Math.floor);
|
|
1043
1124
|
}
|
|
1044
|
-
|
|
1045
|
-
return
|
|
1125
|
+
calculateDirtPercentage(row) {
|
|
1126
|
+
return calculateDirtPercentage(row);
|
|
1127
|
+
}
|
|
1128
|
+
calculateSEValue(row, problemStatistics) {
|
|
1129
|
+
return calculateSEValue(row, problemStatistics);
|
|
1130
|
+
}
|
|
1131
|
+
statusPresentation(status) {
|
|
1132
|
+
return getRankProblemStatusCellPresentation(status, this.data, this.statusCellPreset);
|
|
1046
1133
|
}
|
|
1047
1134
|
isNumber(value) {
|
|
1048
1135
|
return typeof value === 'number';
|
|
@@ -1055,6 +1142,9 @@ class RanklistComponent {
|
|
|
1055
1142
|
if (this.isStatusClickable(status)) {
|
|
1056
1143
|
classNames.push('srk--cursor-pointer');
|
|
1057
1144
|
}
|
|
1145
|
+
if (this.statusColorAsText) {
|
|
1146
|
+
classNames.push('srk-prest-status-block-color-text');
|
|
1147
|
+
}
|
|
1058
1148
|
if (status.result === 'FB') {
|
|
1059
1149
|
classNames.push('srk-prest-status-block-fb');
|
|
1060
1150
|
}
|
|
@@ -1086,6 +1176,8 @@ class RanklistComponent {
|
|
|
1086
1176
|
rowIndex,
|
|
1087
1177
|
ranklist: this.data,
|
|
1088
1178
|
markers: this.data.markers,
|
|
1179
|
+
hideOrganization: this.splitOrganization,
|
|
1180
|
+
hideAvatar: this.showAvatarInOrganization(),
|
|
1089
1181
|
onClick: (event) => this.emitUserClick(event, row, rowIndex),
|
|
1090
1182
|
};
|
|
1091
1183
|
}
|
|
@@ -1100,6 +1192,9 @@ class RanklistComponent {
|
|
|
1100
1192
|
rowIndex,
|
|
1101
1193
|
ranklist: this.data,
|
|
1102
1194
|
solutions: this.getStatusSolutions(status),
|
|
1195
|
+
statusCellPreset: this.statusCellPreset,
|
|
1196
|
+
statusColorAsText: this.statusColorAsText,
|
|
1197
|
+
emptyStatusPlaceholder: this.emptyStatusPlaceholder,
|
|
1103
1198
|
onClick: (event) => this.emitSolutionClick(event, row, rowIndex, status, problemIndex),
|
|
1104
1199
|
};
|
|
1105
1200
|
}
|
|
@@ -1141,7 +1236,7 @@ class RanklistComponent {
|
|
|
1141
1236
|
rowIndex,
|
|
1142
1237
|
problemIndex,
|
|
1143
1238
|
problemAlias: this.data.problems[problemIndex]?.alias || null,
|
|
1144
|
-
problemTitle: this.data.problems[problemIndex]
|
|
1239
|
+
problemTitle: this.data.problems[problemIndex] ? this.resolveDisplayText(this.data.problems[problemIndex].title) : null,
|
|
1145
1240
|
userId: row.user.id || null,
|
|
1146
1241
|
},
|
|
1147
1242
|
});
|
|
@@ -1161,6 +1256,9 @@ class RanklistComponent {
|
|
|
1161
1256
|
const index = rankValue.segmentIndex || rankValue.segmentIndex === 0 ? rankValue.segmentIndex : -1;
|
|
1162
1257
|
return (series?.segments || [])[index] || {};
|
|
1163
1258
|
}
|
|
1259
|
+
isSeriesSegmentedColumn(series) {
|
|
1260
|
+
return (series?.segments || []).some((segment) => typeof segment.style === 'string');
|
|
1261
|
+
}
|
|
1164
1262
|
getSeriesSegmentClass(rankValue, series) {
|
|
1165
1263
|
const segmentStyle = this.resolveSeriesSegment(rankValue, series).style;
|
|
1166
1264
|
return typeof segmentStyle === 'string' ? `srk-preset-series-segment-${segmentStyle}` : '';
|
|
@@ -1182,8 +1280,40 @@ class RanklistComponent {
|
|
|
1182
1280
|
backgroundColor: backgroundColor[this.theme],
|
|
1183
1281
|
};
|
|
1184
1282
|
}
|
|
1283
|
+
getProblemStatisticsFooterCellPrimary(key, stat) {
|
|
1284
|
+
switch (key) {
|
|
1285
|
+
case 'accepted':
|
|
1286
|
+
return stat.accepted;
|
|
1287
|
+
case 'tried':
|
|
1288
|
+
return stat.tried;
|
|
1289
|
+
case 'submitted':
|
|
1290
|
+
return stat.submitted;
|
|
1291
|
+
case 'dirt':
|
|
1292
|
+
return stat.dirt;
|
|
1293
|
+
case 'se':
|
|
1294
|
+
return formatProblemStatisticsAverageHardness(stat);
|
|
1295
|
+
case 'firstAccepted':
|
|
1296
|
+
return formatProblemStatisticsAcceptedMinute(stat.firstAcceptedTime);
|
|
1297
|
+
case 'lastAccepted':
|
|
1298
|
+
return formatProblemStatisticsAcceptedMinute(stat.lastAcceptedTime);
|
|
1299
|
+
default:
|
|
1300
|
+
return '';
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
getProblemStatisticsFooterCellSecondary(key, stat) {
|
|
1304
|
+
switch (key) {
|
|
1305
|
+
case 'accepted':
|
|
1306
|
+
return formatProblemStatisticsPercent(stat.accepted, stat.participantCount);
|
|
1307
|
+
case 'tried':
|
|
1308
|
+
return formatProblemStatisticsPercent(stat.tried, stat.participantCount);
|
|
1309
|
+
case 'dirt':
|
|
1310
|
+
return formatProblemStatisticsPercent(stat.dirt, stat.dirtSubmitted);
|
|
1311
|
+
default:
|
|
1312
|
+
return undefined;
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1185
1315
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1186
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RanklistComponent, isStandalone: true, selector: "srk-ranklist", inputs: { data: "data", theme: "theme", borderedRows: "borderedRows", stripedRows: "stripedRows", formatSrkAssetUrl: "formatSrkAssetUrl" }, outputs: { userClick: "userClick", solutionClick: "solutionClick" }, queries: [{ propertyName: "statusCellTemplate", first: true, predicate: SrkStatusCellTemplateDirective, descendants: true }, { propertyName: "userCellTemplate", first: true, predicate: SrkUserCellTemplateDirective, descendants: true }], ngImport: i0, template: `
|
|
1316
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RanklistComponent, isStandalone: true, selector: "srk-ranklist", inputs: { data: "data", theme: "theme", borderedRows: "borderedRows", rowBordered: "rowBordered", columnBordered: "columnBordered", stripedRows: "stripedRows", formatSrkAssetUrl: "formatSrkAssetUrl", splitOrganization: "splitOrganization", columnTitles: "columnTitles", statusCellPreset: "statusCellPreset", statusColorAsText: "statusColorAsText", showProblemStatisticsFooter: "showProblemStatisticsFooter", showDirtColumn: "showDirtColumn", showSEColumn: "showSEColumn", emptyStatusPlaceholder: "emptyStatusPlaceholder", userAvatarPlacement: "userAvatarPlacement" }, outputs: { userClick: "userClick", solutionClick: "solutionClick" }, queries: [{ propertyName: "statusCellTemplate", first: true, predicate: SrkStatusCellTemplateDirective, descendants: true }, { propertyName: "userCellTemplate", first: true, predicate: SrkUserCellTemplateDirective, descendants: true }], ngImport: i0, template: `
|
|
1187
1317
|
<div *ngIf="data.type !== 'general'; else versionState">
|
|
1188
1318
|
srk type "{{ data.type }}" is not supported
|
|
1189
1319
|
</div>
|
|
@@ -1197,20 +1327,30 @@ class RanklistComponent {
|
|
|
1197
1327
|
<ng-template #ranklistTable>
|
|
1198
1328
|
<div class="srk-common-table srk-main">
|
|
1199
1329
|
<table
|
|
1200
|
-
[class.srk-table-row-bordered]="borderedRows"
|
|
1330
|
+
[class.srk-table-row-bordered]="borderedRows || rowBordered"
|
|
1331
|
+
[class.srk-table-column-bordered]="columnBordered"
|
|
1201
1332
|
[class.srk-table-row-striped]="stripedRows"
|
|
1202
1333
|
>
|
|
1203
1334
|
<thead>
|
|
1204
1335
|
<tr>
|
|
1205
1336
|
<th
|
|
1206
|
-
*ngFor="let seriesItem of data.series"
|
|
1337
|
+
*ngFor="let seriesItem of data.series; let seriesIndex = index"
|
|
1207
1338
|
class="srk-series-header srk--text-right srk--nowrap"
|
|
1339
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(seriesItem)"
|
|
1208
1340
|
>
|
|
1209
|
-
{{ seriesItem
|
|
1341
|
+
{{ resolveSeriesColumnTitle(seriesItem, seriesIndex) }}
|
|
1342
|
+
</th>
|
|
1343
|
+
<th
|
|
1344
|
+
*ngIf="splitOrganization"
|
|
1345
|
+
class="srk-organization-header srk--text-left srk--nowrap"
|
|
1346
|
+
>
|
|
1347
|
+
{{ resolveColumnTitle('organization', 'Organization') }}
|
|
1348
|
+
</th>
|
|
1349
|
+
<th class="srk--text-left srk--nowrap">{{ resolveColumnTitle('user', 'Name') }}</th>
|
|
1350
|
+
<th class="srk--text-right srk--nowrap">{{ resolveColumnTitle('score', 'Score') }}</th>
|
|
1351
|
+
<th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
1352
|
+
{{ resolveColumnTitle('time', 'Time') }}
|
|
1210
1353
|
</th>
|
|
1211
|
-
<th class="srk--text-left srk--nowrap">Name</th>
|
|
1212
|
-
<th class="srk--nowrap">Score</th>
|
|
1213
|
-
<th *ngIf="showTimeColumn()" class="srk--nowrap">Time</th>
|
|
1214
1354
|
<th
|
|
1215
1355
|
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
1216
1356
|
class="srk--nowrap srk-problem-header"
|
|
@@ -1243,6 +1383,12 @@ class RanklistComponent {
|
|
|
1243
1383
|
</span>
|
|
1244
1384
|
</ng-template>
|
|
1245
1385
|
</th>
|
|
1386
|
+
<th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
|
|
1387
|
+
{{ resolveColumnTitle('dirt', 'Dirt') }}
|
|
1388
|
+
</th>
|
|
1389
|
+
<th *ngIf="showSEColumn" class="srk-se-header srk--text-right srk--nowrap">
|
|
1390
|
+
{{ resolveColumnTitle('se', 'SE') }}
|
|
1391
|
+
</th>
|
|
1246
1392
|
</tr>
|
|
1247
1393
|
</thead>
|
|
1248
1394
|
<tbody>
|
|
@@ -1251,11 +1397,32 @@ class RanklistComponent {
|
|
|
1251
1397
|
*ngFor="let rankValue of getRankValues(row); let seriesIndex = index"
|
|
1252
1398
|
class="srk--text-right srk--nowrap"
|
|
1253
1399
|
[ngClass]="getSeriesSegmentClass(rankValue, data.series[seriesIndex])"
|
|
1400
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(data.series[seriesIndex])"
|
|
1254
1401
|
[ngStyle]="getSeriesSegmentStyle(rankValue, data.series[seriesIndex])"
|
|
1255
1402
|
>
|
|
1256
1403
|
{{ getRankText(rankValue, row) }}
|
|
1257
1404
|
</td>
|
|
1258
1405
|
|
|
1406
|
+
<td
|
|
1407
|
+
*ngIf="splitOrganization"
|
|
1408
|
+
class="srk-organization-cell srk--text-left srk--nowrap"
|
|
1409
|
+
[class.srk-organization-cell-avatar]="showAvatarInOrganization() && !!row.user.avatar"
|
|
1410
|
+
>
|
|
1411
|
+
<div class="srk-organization-cell-content">
|
|
1412
|
+
<div *ngIf="showAvatarInOrganization() && row.user.avatar" class="srk-user-avatar">
|
|
1413
|
+
<img
|
|
1414
|
+
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
1415
|
+
alt="User Avatar"
|
|
1416
|
+
/>
|
|
1417
|
+
</div>
|
|
1418
|
+
<span
|
|
1419
|
+
class="srk-organization-name-text"
|
|
1420
|
+
[title]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
1421
|
+
[textContent]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
1422
|
+
></span>
|
|
1423
|
+
</div>
|
|
1424
|
+
</td>
|
|
1425
|
+
|
|
1259
1426
|
<ng-container *ngIf="userCellTemplate; else defaultUserCell">
|
|
1260
1427
|
<ng-container
|
|
1261
1428
|
[ngTemplateOutlet]="userCellTemplate.templateRef"
|
|
@@ -1272,7 +1439,7 @@ class RanklistComponent {
|
|
|
1272
1439
|
(keydown.space)="activateUserCellFromKeyboard($event, row, rowIndex)"
|
|
1273
1440
|
>
|
|
1274
1441
|
<div class="srk-user-cell-content">
|
|
1275
|
-
<div *ngIf="row.user.avatar" class="srk-user-avatar">
|
|
1442
|
+
<div *ngIf="row.user.avatar && !showAvatarInOrganization()" class="srk-user-avatar">
|
|
1276
1443
|
<img
|
|
1277
1444
|
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
1278
1445
|
alt="User Avatar"
|
|
@@ -1297,7 +1464,7 @@ class RanklistComponent {
|
|
|
1297
1464
|
</span>
|
|
1298
1465
|
</div>
|
|
1299
1466
|
<p
|
|
1300
|
-
*ngIf="row.user.organization"
|
|
1467
|
+
*ngIf="row.user.organization && !splitOrganization"
|
|
1301
1468
|
class="srk-user-secondary-text srk--text-ellipsis"
|
|
1302
1469
|
title=""
|
|
1303
1470
|
>
|
|
@@ -1330,15 +1497,27 @@ class RanklistComponent {
|
|
|
1330
1497
|
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1331
1498
|
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1332
1499
|
>
|
|
1333
|
-
<
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1500
|
+
<span
|
|
1501
|
+
*ngIf="statusColorAsText && status.result === 'FB'"
|
|
1502
|
+
class="srk-prest-status-block-fb-star"
|
|
1503
|
+
[textContent]="firstBloodStar"
|
|
1504
|
+
></span>
|
|
1505
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
1506
|
+
<ng-container *ngIf="isNumber(presentation.score); else statusText">
|
|
1507
|
+
<span class="srk-prest-status-block-score">{{ presentation.score }}</span>
|
|
1508
|
+
<span class="srk-prest-status-block-score-details">
|
|
1509
|
+
{{ presentation.scoreDetails }}
|
|
1510
|
+
</span>
|
|
1511
|
+
</ng-container>
|
|
1512
|
+
<ng-template #statusText>
|
|
1513
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
1514
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
1515
|
+
<span [textContent]="statusSeparator"></span>
|
|
1516
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
1517
|
+
</ng-container>
|
|
1518
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
1519
|
+
</ng-template>
|
|
1338
1520
|
</ng-container>
|
|
1339
|
-
<ng-template #acceptedDetails>
|
|
1340
|
-
{{ acceptedStatusDetails(status) }}
|
|
1341
|
-
</ng-template>
|
|
1342
1521
|
</td>
|
|
1343
1522
|
<ng-template #failedOrFrozenStatus>
|
|
1344
1523
|
<td
|
|
@@ -1350,16 +1529,101 @@ class RanklistComponent {
|
|
|
1350
1529
|
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1351
1530
|
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1352
1531
|
>
|
|
1353
|
-
|
|
1532
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
1533
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
1534
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
1535
|
+
<span [textContent]="statusSeparator"></span>
|
|
1536
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
1537
|
+
</ng-container>
|
|
1538
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
1539
|
+
</ng-container>
|
|
1354
1540
|
</td>
|
|
1355
1541
|
</ng-template>
|
|
1356
1542
|
<ng-template #emptyStatus>
|
|
1357
|
-
<td
|
|
1543
|
+
<td class="srk-status-placeholder-cell srk--text-center srk--nowrap">
|
|
1544
|
+
{{ emptyStatusPlaceholder }}
|
|
1545
|
+
</td>
|
|
1358
1546
|
</ng-template>
|
|
1359
1547
|
</ng-template>
|
|
1360
1548
|
</ng-container>
|
|
1549
|
+
|
|
1550
|
+
<td *ngIf="showDirtColumn" class="srk-dirt-cell srk--text-right srk--nowrap">
|
|
1551
|
+
{{ calculateDirtPercentage(row) }}
|
|
1552
|
+
</td>
|
|
1553
|
+
<td *ngIf="showSEColumn" class="srk-se-cell srk--text-right srk--nowrap">
|
|
1554
|
+
{{ calculateSEValue(row, problemStatistics) }}
|
|
1555
|
+
</td>
|
|
1361
1556
|
</tr>
|
|
1362
1557
|
</tbody>
|
|
1558
|
+
<tfoot *ngIf="showProblemStatisticsFooter">
|
|
1559
|
+
<tr
|
|
1560
|
+
*ngFor="let footerRow of problemStatisticsFooterRows"
|
|
1561
|
+
class="srk-problem-statistics-footer-row"
|
|
1562
|
+
>
|
|
1563
|
+
<td
|
|
1564
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
1565
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
1566
|
+
>
|
|
1567
|
+
<span
|
|
1568
|
+
class="srk-problem-statistics-footer-label srk--c-tooltip"
|
|
1569
|
+
[attr.data-tooltip]="footerRow.tooltip"
|
|
1570
|
+
>
|
|
1571
|
+
{{ footerRow.label }}
|
|
1572
|
+
</span>
|
|
1573
|
+
</td>
|
|
1574
|
+
<td
|
|
1575
|
+
*ngFor="let stat of problemStatistics"
|
|
1576
|
+
class="srk-problem-statistics-footer-cell srk--text-center srk--nowrap"
|
|
1577
|
+
>
|
|
1578
|
+
<span class="srk-problem-statistics-footer-primary">
|
|
1579
|
+
{{ getProblemStatisticsFooterCellPrimary(footerRow.key, stat) }}
|
|
1580
|
+
</span>
|
|
1581
|
+
<ng-container *ngIf="getProblemStatisticsFooterCellSecondary(footerRow.key, stat) !== undefined">
|
|
1582
|
+
<span> </span>
|
|
1583
|
+
<span class="srk-problem-statistics-footer-secondary">
|
|
1584
|
+
{{ getProblemStatisticsFooterCellSecondary(footerRow.key, stat) }}
|
|
1585
|
+
</span>
|
|
1586
|
+
</ng-container>
|
|
1587
|
+
</td>
|
|
1588
|
+
<td
|
|
1589
|
+
*ngIf="showDirtColumn"
|
|
1590
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
1591
|
+
>
|
|
1592
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1593
|
+
</td>
|
|
1594
|
+
<td
|
|
1595
|
+
*ngIf="showSEColumn"
|
|
1596
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
1597
|
+
>
|
|
1598
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1599
|
+
</td>
|
|
1600
|
+
</tr>
|
|
1601
|
+
<tr class="srk-problem-statistics-footer-row srk-problem-statistics-footer-problem-label-row">
|
|
1602
|
+
<td
|
|
1603
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
1604
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
1605
|
+
></td>
|
|
1606
|
+
<td
|
|
1607
|
+
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
1608
|
+
class="srk-problem-statistics-footer-cell srk-problem-statistics-footer-problem-header srk-problem-header srk--text-center srk--nowrap"
|
|
1609
|
+
[style.background-image]="problemHeaderBackgroundImage(problem, 0)"
|
|
1610
|
+
>
|
|
1611
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1612
|
+
</td>
|
|
1613
|
+
<td
|
|
1614
|
+
*ngIf="showDirtColumn"
|
|
1615
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
1616
|
+
>
|
|
1617
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1618
|
+
</td>
|
|
1619
|
+
<td
|
|
1620
|
+
*ngIf="showSEColumn"
|
|
1621
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
1622
|
+
>
|
|
1623
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1624
|
+
</td>
|
|
1625
|
+
</tr>
|
|
1626
|
+
</tfoot>
|
|
1363
1627
|
</table>
|
|
1364
1628
|
</div>
|
|
1365
1629
|
</ng-template>
|
|
@@ -1386,20 +1650,30 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1386
1650
|
<ng-template #ranklistTable>
|
|
1387
1651
|
<div class="srk-common-table srk-main">
|
|
1388
1652
|
<table
|
|
1389
|
-
[class.srk-table-row-bordered]="borderedRows"
|
|
1653
|
+
[class.srk-table-row-bordered]="borderedRows || rowBordered"
|
|
1654
|
+
[class.srk-table-column-bordered]="columnBordered"
|
|
1390
1655
|
[class.srk-table-row-striped]="stripedRows"
|
|
1391
1656
|
>
|
|
1392
1657
|
<thead>
|
|
1393
1658
|
<tr>
|
|
1394
1659
|
<th
|
|
1395
|
-
*ngFor="let seriesItem of data.series"
|
|
1660
|
+
*ngFor="let seriesItem of data.series; let seriesIndex = index"
|
|
1396
1661
|
class="srk-series-header srk--text-right srk--nowrap"
|
|
1662
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(seriesItem)"
|
|
1397
1663
|
>
|
|
1398
|
-
{{ seriesItem
|
|
1664
|
+
{{ resolveSeriesColumnTitle(seriesItem, seriesIndex) }}
|
|
1665
|
+
</th>
|
|
1666
|
+
<th
|
|
1667
|
+
*ngIf="splitOrganization"
|
|
1668
|
+
class="srk-organization-header srk--text-left srk--nowrap"
|
|
1669
|
+
>
|
|
1670
|
+
{{ resolveColumnTitle('organization', 'Organization') }}
|
|
1671
|
+
</th>
|
|
1672
|
+
<th class="srk--text-left srk--nowrap">{{ resolveColumnTitle('user', 'Name') }}</th>
|
|
1673
|
+
<th class="srk--text-right srk--nowrap">{{ resolveColumnTitle('score', 'Score') }}</th>
|
|
1674
|
+
<th *ngIf="showTimeColumn()" class="srk--text-right srk--nowrap">
|
|
1675
|
+
{{ resolveColumnTitle('time', 'Time') }}
|
|
1399
1676
|
</th>
|
|
1400
|
-
<th class="srk--text-left srk--nowrap">Name</th>
|
|
1401
|
-
<th class="srk--nowrap">Score</th>
|
|
1402
|
-
<th *ngIf="showTimeColumn()" class="srk--nowrap">Time</th>
|
|
1403
1677
|
<th
|
|
1404
1678
|
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
1405
1679
|
class="srk--nowrap srk-problem-header"
|
|
@@ -1432,6 +1706,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1432
1706
|
</span>
|
|
1433
1707
|
</ng-template>
|
|
1434
1708
|
</th>
|
|
1709
|
+
<th *ngIf="showDirtColumn" class="srk-dirt-header srk--text-right srk--nowrap">
|
|
1710
|
+
{{ resolveColumnTitle('dirt', 'Dirt') }}
|
|
1711
|
+
</th>
|
|
1712
|
+
<th *ngIf="showSEColumn" class="srk-se-header srk--text-right srk--nowrap">
|
|
1713
|
+
{{ resolveColumnTitle('se', 'SE') }}
|
|
1714
|
+
</th>
|
|
1435
1715
|
</tr>
|
|
1436
1716
|
</thead>
|
|
1437
1717
|
<tbody>
|
|
@@ -1440,11 +1720,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1440
1720
|
*ngFor="let rankValue of getRankValues(row); let seriesIndex = index"
|
|
1441
1721
|
class="srk--text-right srk--nowrap"
|
|
1442
1722
|
[ngClass]="getSeriesSegmentClass(rankValue, data.series[seriesIndex])"
|
|
1723
|
+
[class.srk-series-segmented-column]="isSeriesSegmentedColumn(data.series[seriesIndex])"
|
|
1443
1724
|
[ngStyle]="getSeriesSegmentStyle(rankValue, data.series[seriesIndex])"
|
|
1444
1725
|
>
|
|
1445
1726
|
{{ getRankText(rankValue, row) }}
|
|
1446
1727
|
</td>
|
|
1447
1728
|
|
|
1729
|
+
<td
|
|
1730
|
+
*ngIf="splitOrganization"
|
|
1731
|
+
class="srk-organization-cell srk--text-left srk--nowrap"
|
|
1732
|
+
[class.srk-organization-cell-avatar]="showAvatarInOrganization() && !!row.user.avatar"
|
|
1733
|
+
>
|
|
1734
|
+
<div class="srk-organization-cell-content">
|
|
1735
|
+
<div *ngIf="showAvatarInOrganization() && row.user.avatar" class="srk-user-avatar">
|
|
1736
|
+
<img
|
|
1737
|
+
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
1738
|
+
alt="User Avatar"
|
|
1739
|
+
/>
|
|
1740
|
+
</div>
|
|
1741
|
+
<span
|
|
1742
|
+
class="srk-organization-name-text"
|
|
1743
|
+
[title]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
1744
|
+
[textContent]="row.user.organization ? resolveDisplayText(row.user.organization) : ''"
|
|
1745
|
+
></span>
|
|
1746
|
+
</div>
|
|
1747
|
+
</td>
|
|
1748
|
+
|
|
1448
1749
|
<ng-container *ngIf="userCellTemplate; else defaultUserCell">
|
|
1449
1750
|
<ng-container
|
|
1450
1751
|
[ngTemplateOutlet]="userCellTemplate.templateRef"
|
|
@@ -1461,7 +1762,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1461
1762
|
(keydown.space)="activateUserCellFromKeyboard($event, row, rowIndex)"
|
|
1462
1763
|
>
|
|
1463
1764
|
<div class="srk-user-cell-content">
|
|
1464
|
-
<div *ngIf="row.user.avatar" class="srk-user-avatar">
|
|
1765
|
+
<div *ngIf="row.user.avatar && !showAvatarInOrganization()" class="srk-user-avatar">
|
|
1465
1766
|
<img
|
|
1466
1767
|
[src]="formatAssetUrl(row.user.avatar, 'user.avatar')"
|
|
1467
1768
|
alt="User Avatar"
|
|
@@ -1486,7 +1787,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1486
1787
|
</span>
|
|
1487
1788
|
</div>
|
|
1488
1789
|
<p
|
|
1489
|
-
*ngIf="row.user.organization"
|
|
1790
|
+
*ngIf="row.user.organization && !splitOrganization"
|
|
1490
1791
|
class="srk-user-secondary-text srk--text-ellipsis"
|
|
1491
1792
|
title=""
|
|
1492
1793
|
>
|
|
@@ -1519,15 +1820,27 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1519
1820
|
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1520
1821
|
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1521
1822
|
>
|
|
1522
|
-
<
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1823
|
+
<span
|
|
1824
|
+
*ngIf="statusColorAsText && status.result === 'FB'"
|
|
1825
|
+
class="srk-prest-status-block-fb-star"
|
|
1826
|
+
[textContent]="firstBloodStar"
|
|
1827
|
+
></span>
|
|
1828
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
1829
|
+
<ng-container *ngIf="isNumber(presentation.score); else statusText">
|
|
1830
|
+
<span class="srk-prest-status-block-score">{{ presentation.score }}</span>
|
|
1831
|
+
<span class="srk-prest-status-block-score-details">
|
|
1832
|
+
{{ presentation.scoreDetails }}
|
|
1833
|
+
</span>
|
|
1834
|
+
</ng-container>
|
|
1835
|
+
<ng-template #statusText>
|
|
1836
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
1837
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
1838
|
+
<span [textContent]="statusSeparator"></span>
|
|
1839
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
1840
|
+
</ng-container>
|
|
1841
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
1842
|
+
</ng-template>
|
|
1527
1843
|
</ng-container>
|
|
1528
|
-
<ng-template #acceptedDetails>
|
|
1529
|
-
{{ acceptedStatusDetails(status) }}
|
|
1530
|
-
</ng-template>
|
|
1531
1844
|
</td>
|
|
1532
1845
|
<ng-template #failedOrFrozenStatus>
|
|
1533
1846
|
<td
|
|
@@ -1539,16 +1852,101 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1539
1852
|
(keydown.enter)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1540
1853
|
(keydown.space)="activateStatusCellFromKeyboard($event, row, rowIndex, status, problemIndex)"
|
|
1541
1854
|
>
|
|
1542
|
-
|
|
1855
|
+
<ng-container *ngIf="statusPresentation(status) as presentation">
|
|
1856
|
+
<ng-container *ngIf="presentation.secondary !== undefined; else singleStatus">
|
|
1857
|
+
<span class="srk-prest-status-block-primary">{{ presentation.primary || '' }}</span>
|
|
1858
|
+
<span [textContent]="statusSeparator"></span>
|
|
1859
|
+
<span class="srk-prest-status-block-secondary">{{ presentation.secondary }}</span>
|
|
1860
|
+
</ng-container>
|
|
1861
|
+
<ng-template #singleStatus>{{ presentation.primary }}</ng-template>
|
|
1862
|
+
</ng-container>
|
|
1543
1863
|
</td>
|
|
1544
1864
|
</ng-template>
|
|
1545
1865
|
<ng-template #emptyStatus>
|
|
1546
|
-
<td
|
|
1866
|
+
<td class="srk-status-placeholder-cell srk--text-center srk--nowrap">
|
|
1867
|
+
{{ emptyStatusPlaceholder }}
|
|
1868
|
+
</td>
|
|
1547
1869
|
</ng-template>
|
|
1548
1870
|
</ng-template>
|
|
1549
1871
|
</ng-container>
|
|
1872
|
+
|
|
1873
|
+
<td *ngIf="showDirtColumn" class="srk-dirt-cell srk--text-right srk--nowrap">
|
|
1874
|
+
{{ calculateDirtPercentage(row) }}
|
|
1875
|
+
</td>
|
|
1876
|
+
<td *ngIf="showSEColumn" class="srk-se-cell srk--text-right srk--nowrap">
|
|
1877
|
+
{{ calculateSEValue(row, problemStatistics) }}
|
|
1878
|
+
</td>
|
|
1550
1879
|
</tr>
|
|
1551
1880
|
</tbody>
|
|
1881
|
+
<tfoot *ngIf="showProblemStatisticsFooter">
|
|
1882
|
+
<tr
|
|
1883
|
+
*ngFor="let footerRow of problemStatisticsFooterRows"
|
|
1884
|
+
class="srk-problem-statistics-footer-row"
|
|
1885
|
+
>
|
|
1886
|
+
<td
|
|
1887
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
1888
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
1889
|
+
>
|
|
1890
|
+
<span
|
|
1891
|
+
class="srk-problem-statistics-footer-label srk--c-tooltip"
|
|
1892
|
+
[attr.data-tooltip]="footerRow.tooltip"
|
|
1893
|
+
>
|
|
1894
|
+
{{ footerRow.label }}
|
|
1895
|
+
</span>
|
|
1896
|
+
</td>
|
|
1897
|
+
<td
|
|
1898
|
+
*ngFor="let stat of problemStatistics"
|
|
1899
|
+
class="srk-problem-statistics-footer-cell srk--text-center srk--nowrap"
|
|
1900
|
+
>
|
|
1901
|
+
<span class="srk-problem-statistics-footer-primary">
|
|
1902
|
+
{{ getProblemStatisticsFooterCellPrimary(footerRow.key, stat) }}
|
|
1903
|
+
</span>
|
|
1904
|
+
<ng-container *ngIf="getProblemStatisticsFooterCellSecondary(footerRow.key, stat) !== undefined">
|
|
1905
|
+
<span> </span>
|
|
1906
|
+
<span class="srk-problem-statistics-footer-secondary">
|
|
1907
|
+
{{ getProblemStatisticsFooterCellSecondary(footerRow.key, stat) }}
|
|
1908
|
+
</span>
|
|
1909
|
+
</ng-container>
|
|
1910
|
+
</td>
|
|
1911
|
+
<td
|
|
1912
|
+
*ngIf="showDirtColumn"
|
|
1913
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
1914
|
+
>
|
|
1915
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1916
|
+
</td>
|
|
1917
|
+
<td
|
|
1918
|
+
*ngIf="showSEColumn"
|
|
1919
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
1920
|
+
>
|
|
1921
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1922
|
+
</td>
|
|
1923
|
+
</tr>
|
|
1924
|
+
<tr class="srk-problem-statistics-footer-row srk-problem-statistics-footer-problem-label-row">
|
|
1925
|
+
<td
|
|
1926
|
+
class="srk-problem-statistics-footer-labels srk--text-right srk--nowrap"
|
|
1927
|
+
[attr.colspan]="leftFooterColumnCount()"
|
|
1928
|
+
></td>
|
|
1929
|
+
<td
|
|
1930
|
+
*ngFor="let problem of data.problems; let problemIndex = index"
|
|
1931
|
+
class="srk-problem-statistics-footer-cell srk-problem-statistics-footer-problem-header srk-problem-header srk--text-center srk--nowrap"
|
|
1932
|
+
[style.background-image]="problemHeaderBackgroundImage(problem, 0)"
|
|
1933
|
+
>
|
|
1934
|
+
<span class="srk--display-block">{{ problemAlias(problem, problemIndex) }}</span>
|
|
1935
|
+
</td>
|
|
1936
|
+
<td
|
|
1937
|
+
*ngIf="showDirtColumn"
|
|
1938
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
|
|
1939
|
+
>
|
|
1940
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1941
|
+
</td>
|
|
1942
|
+
<td
|
|
1943
|
+
*ngIf="showSEColumn"
|
|
1944
|
+
class="srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
|
|
1945
|
+
>
|
|
1946
|
+
<span class="srk-problem-statistics-footer-primary"></span>
|
|
1947
|
+
</td>
|
|
1948
|
+
</tr>
|
|
1949
|
+
</tfoot>
|
|
1552
1950
|
</table>
|
|
1553
1951
|
</div>
|
|
1554
1952
|
</ng-template>
|
|
@@ -1561,10 +1959,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1561
1959
|
type: Input
|
|
1562
1960
|
}], borderedRows: [{
|
|
1563
1961
|
type: Input
|
|
1962
|
+
}], rowBordered: [{
|
|
1963
|
+
type: Input
|
|
1964
|
+
}], columnBordered: [{
|
|
1965
|
+
type: Input
|
|
1564
1966
|
}], stripedRows: [{
|
|
1565
1967
|
type: Input
|
|
1566
1968
|
}], formatSrkAssetUrl: [{
|
|
1567
1969
|
type: Input
|
|
1970
|
+
}], splitOrganization: [{
|
|
1971
|
+
type: Input
|
|
1972
|
+
}], columnTitles: [{
|
|
1973
|
+
type: Input
|
|
1974
|
+
}], statusCellPreset: [{
|
|
1975
|
+
type: Input
|
|
1976
|
+
}], statusColorAsText: [{
|
|
1977
|
+
type: Input
|
|
1978
|
+
}], showProblemStatisticsFooter: [{
|
|
1979
|
+
type: Input
|
|
1980
|
+
}], showDirtColumn: [{
|
|
1981
|
+
type: Input
|
|
1982
|
+
}], showSEColumn: [{
|
|
1983
|
+
type: Input
|
|
1984
|
+
}], emptyStatusPlaceholder: [{
|
|
1985
|
+
type: Input
|
|
1986
|
+
}], userAvatarPlacement: [{
|
|
1987
|
+
type: Input
|
|
1568
1988
|
}], userClick: [{
|
|
1569
1989
|
type: Output
|
|
1570
1990
|
}], solutionClick: [{
|