@algoux/standard-ranklist-renderer-component-angular 0.6.1 → 0.6.3
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 +5 -1
- package/dist/README.md +5 -1
- package/dist/esm2022/lib/modal/default-solution-modal.component.mjs +6 -3
- package/dist/esm2022/lib/modal/default-user-modal.component.mjs +23 -15
- package/dist/esm2022/lib/progress/progress-utils.mjs +2 -45
- package/dist/esm2022/lib/ranklist/ranklist-utils.mjs +2 -110
- package/dist/esm2022/lib/ranklist/ranklist.component.mjs +20 -18
- 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 +51 -190
- package/dist/fesm2022/algoux-standard-ranklist-renderer-component-angular.mjs.map +1 -1
- package/dist/lib/modal/default-solution-modal.component.d.ts +2 -1
- package/dist/lib/modal/default-user-modal.component.d.ts +5 -3
- package/dist/lib/progress/progress-bar.component.d.ts +1 -1
- package/dist/lib/progress/progress-utils.d.ts +1 -15
- package/dist/lib/ranklist/ranklist-utils.d.ts +1 -22
- package/dist/lib/ranklist/ranklist.component.d.ts +3 -3
- package/dist/lib/ranklist/status-cell-template.directive.d.ts +1 -0
- package/dist/lib/ranklist/user-cell-template.directive.d.ts +1 -0
- package/dist/lib/types.d.ts +1 -29
- package/package.json +3 -3
|
@@ -2,116 +2,8 @@ import * as i1 from '@angular/common';
|
|
|
2
2
|
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
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
const defaultBackgroundColor = {
|
|
9
|
-
[EnumTheme.light]: '#ffffff',
|
|
10
|
-
[EnumTheme.dark]: '#191919',
|
|
11
|
-
};
|
|
12
|
-
function resolveSrkAssetUrl(url, field, formatter) {
|
|
13
|
-
if (typeof formatter === 'function') {
|
|
14
|
-
return formatter(url, field);
|
|
15
|
-
}
|
|
16
|
-
if (url.startsWith('//')) {
|
|
17
|
-
return url;
|
|
18
|
-
}
|
|
19
|
-
const protocolMatch = url.match(/^([a-zA-Z][a-zA-Z0-9+.-]*):/);
|
|
20
|
-
if (protocolMatch) {
|
|
21
|
-
const protocol = protocolMatch[1].toLowerCase();
|
|
22
|
-
if (protocol === 'http' || protocol === 'https' || protocol === 'data') {
|
|
23
|
-
return url;
|
|
24
|
-
}
|
|
25
|
-
console.warn(`unsupported protocol "${protocol}" in srk asset url:`, url);
|
|
26
|
-
return '';
|
|
27
|
-
}
|
|
28
|
-
console.warn('unsupported srk asset url:', url);
|
|
29
|
-
return '';
|
|
30
|
-
}
|
|
31
|
-
function getAcceptedStatusDetails(status) {
|
|
32
|
-
return `${status.tries}/${status.time ? formatTimeDuration(status.time, 'min', Math.floor) : '-'}`;
|
|
33
|
-
}
|
|
34
|
-
function getSolutionResultMeta(result) {
|
|
35
|
-
switch (result) {
|
|
36
|
-
case 'FB':
|
|
37
|
-
return { label: 'First Blood', className: 'srk-preset-result-fb' };
|
|
38
|
-
case 'AC':
|
|
39
|
-
return { label: 'Accepted', className: 'srk-preset-result-ac' };
|
|
40
|
-
case 'RJ':
|
|
41
|
-
return { label: 'Rejected', className: 'srk-preset-result-rj' };
|
|
42
|
-
case '?':
|
|
43
|
-
return { label: 'Frozen', className: 'srk-preset-result-fz' };
|
|
44
|
-
case 'WA':
|
|
45
|
-
return { label: 'Wrong Answer', className: 'srk-preset-result-rj' };
|
|
46
|
-
case 'PE':
|
|
47
|
-
return { label: 'Presentation Error', className: 'srk-preset-result-rj' };
|
|
48
|
-
case 'TLE':
|
|
49
|
-
return { label: 'Time Limit Exceeded', className: 'srk-preset-result-rj' };
|
|
50
|
-
case 'MLE':
|
|
51
|
-
return { label: 'Memory Limit Exceeded', className: 'srk-preset-result-rj' };
|
|
52
|
-
case 'OLE':
|
|
53
|
-
return { label: 'Output Limit Exceeded', className: 'srk-preset-result-rj' };
|
|
54
|
-
case 'RTE':
|
|
55
|
-
return { label: 'Runtime Error', className: 'srk-preset-result-rj' };
|
|
56
|
-
case 'NOUT':
|
|
57
|
-
return { label: 'No Output' };
|
|
58
|
-
case 'CE':
|
|
59
|
-
return { label: 'Compile Error' };
|
|
60
|
-
case 'UKE':
|
|
61
|
-
return { label: 'Unknown Error' };
|
|
62
|
-
case null:
|
|
63
|
-
return { label: '--' };
|
|
64
|
-
default:
|
|
65
|
-
return { label: result };
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
function getSolutionModalTitle(problemIndex, user) {
|
|
69
|
-
return `Solutions of ${numberToAlphabet(problemIndex)} (${resolveText(user.name)})`;
|
|
70
|
-
}
|
|
71
|
-
function formatSolutionTimestamp(solution) {
|
|
72
|
-
return secToTimeStr(formatTimeDuration(solution.time, 's'));
|
|
73
|
-
}
|
|
74
|
-
function getProblemHeaderBackgroundImage(style, theme) {
|
|
75
|
-
const { backgroundColor } = resolveStyle(style || {});
|
|
76
|
-
const resolvedColor = backgroundColor[theme] || defaultBackgroundColor[theme];
|
|
77
|
-
const bgColorAlphaStr = withAlpha(resolvedColor, 0.27);
|
|
78
|
-
return `linear-gradient(180deg, ${resolvedColor} 0%, ${resolvedColor} 10%, ${bgColorAlphaStr} 10%, transparent 100%)`;
|
|
79
|
-
}
|
|
80
|
-
function getMarkerPresentation(marker, theme) {
|
|
81
|
-
if (typeof marker.style === 'string') {
|
|
82
|
-
return { className: `srk-preset-marker-${marker.style}` };
|
|
83
|
-
}
|
|
84
|
-
if (marker.style) {
|
|
85
|
-
return {
|
|
86
|
-
style: {
|
|
87
|
-
backgroundColor: resolveStyle(marker.style).backgroundColor[theme],
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
return {};
|
|
92
|
-
}
|
|
93
|
-
function shouldShowTimeColumn(rows) {
|
|
94
|
-
return rows.some((row) => Boolean(row.score?.time));
|
|
95
|
-
}
|
|
96
|
-
function withAlpha(color, alpha) {
|
|
97
|
-
const hexMatch = color.match(/^#([0-9a-f]{6})$/i);
|
|
98
|
-
if (hexMatch) {
|
|
99
|
-
const value = hexMatch[1];
|
|
100
|
-
const red = parseInt(value.slice(0, 2), 16);
|
|
101
|
-
const green = parseInt(value.slice(2, 4), 16);
|
|
102
|
-
const blue = parseInt(value.slice(4, 6), 16);
|
|
103
|
-
return `rgba(${red}, ${green}, ${blue}, ${alpha})`;
|
|
104
|
-
}
|
|
105
|
-
const rgbMatch = color.match(/^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i);
|
|
106
|
-
if (rgbMatch) {
|
|
107
|
-
return `rgba(${rgbMatch[1]}, ${rgbMatch[2]}, ${rgbMatch[3]}, ${alpha})`;
|
|
108
|
-
}
|
|
109
|
-
const rgbaMatch = color.match(/^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*[\d.]+\s*\)$/i);
|
|
110
|
-
if (rgbaMatch) {
|
|
111
|
-
return `rgba(${rgbaMatch[1]}, ${rgbaMatch[2]}, ${rgbaMatch[3]}, ${alpha})`;
|
|
112
|
-
}
|
|
113
|
-
return color;
|
|
114
|
-
}
|
|
5
|
+
import { ensureModalInteractionTracker, unlockModalBodyScroll, SRK_ANIMATED_MODAL_ROOT_CLASS, resolveModalTransformOrigin, MODAL_ANIMATION_DURATION_MS, lockModalBodyScroll, registerModalFocusScope, unregisterModalFocusScope, formatSolutionTimestamp, getSolutionModalTitle, getSolutionResultMeta, getMarkerPresentation, resolveSrkAssetUrl, formatTeamMemberName, getProgressDurationMinutes, getProgressMaxAvailableMinutes, isProgressEnded, getProgressMetrics, srkSupportedVersions, calculateProblemStatisticsFooter, caniuse, shouldShowTimeColumn, getProblemHeaderBackgroundImage, calculateDirtPercentage, calculateSEValue, getRankProblemStatusCellPresentation, captureModalTriggerPointFromMouseEvent, formatProblemStatisticsAcceptedMinute, formatProblemStatisticsAverageHardness, formatProblemStatisticsPercent } from '@algoux/standard-ranklist-renderer-component-core';
|
|
6
|
+
import { EnumTheme, resolveUserMarkers, resolveText, secToTimeStr, numberToAlphabet, formatTimeDuration, resolveStyle } from '@algoux/standard-ranklist-utils';
|
|
115
7
|
|
|
116
8
|
class ModalComponent {
|
|
117
9
|
open = false;
|
|
@@ -382,6 +274,7 @@ class DefaultSolutionModalComponent {
|
|
|
382
274
|
rootClassName = 'srk-general-modal-root';
|
|
383
275
|
wrapClassName = 'srk-solutions-modal';
|
|
384
276
|
panelStyle = {};
|
|
277
|
+
languages;
|
|
385
278
|
openChange = new EventEmitter();
|
|
386
279
|
close = new EventEmitter();
|
|
387
280
|
formatSolutionTimestamp = formatSolutionTimestamp;
|
|
@@ -398,7 +291,7 @@ class DefaultSolutionModalComponent {
|
|
|
398
291
|
}
|
|
399
292
|
}
|
|
400
293
|
resolvedTitle() {
|
|
401
|
-
return this.title || (this.cachedUser ? getSolutionModalTitle(this.cachedProblemIndex, this.cachedUser) : '');
|
|
294
|
+
return this.title || (this.cachedUser ? getSolutionModalTitle(this.cachedProblemIndex, this.cachedUser, this.languages) : '');
|
|
402
295
|
}
|
|
403
296
|
solutionMeta(solution) {
|
|
404
297
|
return getSolutionResultMeta(solution.result);
|
|
@@ -407,7 +300,7 @@ class DefaultSolutionModalComponent {
|
|
|
407
300
|
return `${solution.result}_${solution.time?.[0]}_${index}`;
|
|
408
301
|
}
|
|
409
302
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultSolutionModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
410
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultSolutionModalComponent, isStandalone: true, selector: "srk-default-solution-modal", inputs: { open: "open", user: "user", problem: "problem", problemIndex: "problemIndex", solutions: "solutions", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
303
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultSolutionModalComponent, isStandalone: true, selector: "srk-default-solution-modal", inputs: { open: "open", user: "user", problem: "problem", problemIndex: "problemIndex", solutions: "solutions", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle", languages: "languages" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
411
304
|
<srk-modal
|
|
412
305
|
*ngIf="cachedUser"
|
|
413
306
|
[open]="open"
|
|
@@ -505,6 +398,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
505
398
|
type: Input
|
|
506
399
|
}], panelStyle: [{
|
|
507
400
|
type: Input
|
|
401
|
+
}], languages: [{
|
|
402
|
+
type: Input
|
|
508
403
|
}], openChange: [{
|
|
509
404
|
type: Output
|
|
510
405
|
}], close: [{
|
|
@@ -522,9 +417,9 @@ class DefaultUserModalComponent {
|
|
|
522
417
|
wrapClassName = 'srk-user-modal';
|
|
523
418
|
panelStyle = {};
|
|
524
419
|
formatSrkAssetUrl;
|
|
420
|
+
languages;
|
|
525
421
|
openChange = new EventEmitter();
|
|
526
422
|
close = new EventEmitter();
|
|
527
|
-
resolveText = resolveText;
|
|
528
423
|
cachedUser = null;
|
|
529
424
|
ngOnChanges(_changes) {
|
|
530
425
|
if (this.user) {
|
|
@@ -543,14 +438,20 @@ class DefaultUserModalComponent {
|
|
|
543
438
|
formatAssetUrl(url, field) {
|
|
544
439
|
return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
|
|
545
440
|
}
|
|
441
|
+
resolveDisplayText(text) {
|
|
442
|
+
return resolveText(text, this.languages);
|
|
443
|
+
}
|
|
444
|
+
formatMemberName(member) {
|
|
445
|
+
return formatTeamMemberName(member, this.languages);
|
|
446
|
+
}
|
|
546
447
|
trackByMarkerId(_index, entry) {
|
|
547
448
|
return entry.marker.id;
|
|
548
449
|
}
|
|
549
|
-
trackByMemberName(_index, member) {
|
|
550
|
-
return
|
|
551
|
-
}
|
|
450
|
+
trackByMemberName = (_index, member) => {
|
|
451
|
+
return this.resolveDisplayText(member.name);
|
|
452
|
+
};
|
|
552
453
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: DefaultUserModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
553
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultUserModalComponent, isStandalone: true, selector: "srk-default-user-modal", inputs: { open: "open", user: "user", markers: "markers", theme: "theme", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle", formatSrkAssetUrl: "formatSrkAssetUrl" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
454
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: DefaultUserModalComponent, isStandalone: true, selector: "srk-default-user-modal", inputs: { open: "open", user: "user", markers: "markers", theme: "theme", title: "title", width: "width", rootClassName: "rootClassName", wrapClassName: "wrapClassName", panelStyle: "panelStyle", formatSrkAssetUrl: "formatSrkAssetUrl", languages: "languages" }, outputs: { openChange: "openChange", close: "close" }, usesOnChanges: true, ngImport: i0, template: `
|
|
554
455
|
<srk-modal
|
|
555
456
|
*ngIf="cachedUser as modalUser"
|
|
556
457
|
[open]="open"
|
|
@@ -563,9 +464,9 @@ class DefaultUserModalComponent {
|
|
|
563
464
|
(openChange)="openChange.emit($event)"
|
|
564
465
|
>
|
|
565
466
|
<div class="srk-user-modal-info">
|
|
566
|
-
<h3 class="srk-user-modal-info-user-name">{{
|
|
467
|
+
<h3 class="srk-user-modal-info-user-name">{{ resolveDisplayText(modalUser.name) }}</h3>
|
|
567
468
|
<p *ngIf="modalUser.organization" class="srk-user-modal-info-user-second-name">
|
|
568
|
-
{{
|
|
469
|
+
{{ resolveDisplayText(modalUser.organization) }}
|
|
569
470
|
</p>
|
|
570
471
|
<div class="srk-user-modal-info-labels">
|
|
571
472
|
<span class="srk-user-modal-info-labels-label srk-user-modal-info-labels-label-preset-general">
|
|
@@ -577,13 +478,13 @@ class DefaultUserModalComponent {
|
|
|
577
478
|
[ngClass]="entry.presentation.className"
|
|
578
479
|
[ngStyle]="entry.presentation.style"
|
|
579
480
|
>
|
|
580
|
-
{{
|
|
481
|
+
{{ resolveDisplayText(entry.marker.label) }}
|
|
581
482
|
</span>
|
|
582
483
|
</div>
|
|
583
484
|
<div *ngIf="modalUser.teamMembers?.length" class="srk-user-modal-info-team-members">
|
|
584
485
|
<ng-container *ngFor="let member of modalUser.teamMembers; let index = index; trackBy: trackByMemberName">
|
|
585
486
|
<span *ngIf="index > 0" class="srk-user-modal-info-team-members-slash"> / </span>
|
|
586
|
-
<span>{{
|
|
487
|
+
<span>{{ formatMemberName(member) }}</span>
|
|
587
488
|
</ng-container>
|
|
588
489
|
</div>
|
|
589
490
|
<div *ngIf="modalUser.photo" class="srk-user-modal-info-photo">
|
|
@@ -616,9 +517,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
616
517
|
(openChange)="openChange.emit($event)"
|
|
617
518
|
>
|
|
618
519
|
<div class="srk-user-modal-info">
|
|
619
|
-
<h3 class="srk-user-modal-info-user-name">{{
|
|
520
|
+
<h3 class="srk-user-modal-info-user-name">{{ resolveDisplayText(modalUser.name) }}</h3>
|
|
620
521
|
<p *ngIf="modalUser.organization" class="srk-user-modal-info-user-second-name">
|
|
621
|
-
{{
|
|
522
|
+
{{ resolveDisplayText(modalUser.organization) }}
|
|
622
523
|
</p>
|
|
623
524
|
<div class="srk-user-modal-info-labels">
|
|
624
525
|
<span class="srk-user-modal-info-labels-label srk-user-modal-info-labels-label-preset-general">
|
|
@@ -630,13 +531,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
630
531
|
[ngClass]="entry.presentation.className"
|
|
631
532
|
[ngStyle]="entry.presentation.style"
|
|
632
533
|
>
|
|
633
|
-
{{
|
|
534
|
+
{{ resolveDisplayText(entry.marker.label) }}
|
|
634
535
|
</span>
|
|
635
536
|
</div>
|
|
636
537
|
<div *ngIf="modalUser.teamMembers?.length" class="srk-user-modal-info-team-members">
|
|
637
538
|
<ng-container *ngFor="let member of modalUser.teamMembers; let index = index; trackBy: trackByMemberName">
|
|
638
539
|
<span *ngIf="index > 0" class="srk-user-modal-info-team-members-slash"> / </span>
|
|
639
|
-
<span>{{
|
|
540
|
+
<span>{{ formatMemberName(member) }}</span>
|
|
640
541
|
</ng-container>
|
|
641
542
|
</div>
|
|
642
543
|
<div *ngIf="modalUser.photo" class="srk-user-modal-info-photo">
|
|
@@ -670,56 +571,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
670
571
|
type: Input
|
|
671
572
|
}], formatSrkAssetUrl: [{
|
|
672
573
|
type: Input
|
|
574
|
+
}], languages: [{
|
|
575
|
+
type: Input
|
|
673
576
|
}], openChange: [{
|
|
674
577
|
type: Output
|
|
675
578
|
}], close: [{
|
|
676
579
|
type: Output
|
|
677
580
|
}] } });
|
|
678
581
|
|
|
679
|
-
function getProgressDurationMinutes(contest) {
|
|
680
|
-
return formatTimeDuration(contest.duration, 'min');
|
|
681
|
-
}
|
|
682
|
-
function getProgressMaxAvailableMinutes(contest, localTime, td = 0) {
|
|
683
|
-
const startAt = new Date(contest.startAt).getTime();
|
|
684
|
-
const currentTime = localTime - td;
|
|
685
|
-
return Math.min(Math.max(Math.floor((currentTime - startAt) / 60000), 0), getProgressDurationMinutes(contest));
|
|
686
|
-
}
|
|
687
|
-
function isProgressEnded(contest, localTime, td = 0) {
|
|
688
|
-
const startAt = new Date(contest.startAt).getTime();
|
|
689
|
-
const endAt = startAt + formatTimeDuration(contest.duration, 'ms');
|
|
690
|
-
const currentTime = localTime - td;
|
|
691
|
-
return currentTime >= endAt;
|
|
692
|
-
}
|
|
693
|
-
function getProgressMetrics(data, localTime, td, timeTravelCurrentValue, inTimeMachine) {
|
|
694
|
-
const { contest } = data;
|
|
695
|
-
const startAt = new Date(contest.startAt).getTime();
|
|
696
|
-
const endAt = startAt + formatTimeDuration(contest.duration, 'ms');
|
|
697
|
-
const frozenLength = contest.frozenDuration ? formatTimeDuration(contest.frozenDuration, 'ms') : 0;
|
|
698
|
-
const currentTime = localTime - td;
|
|
699
|
-
const length = endAt - startAt;
|
|
700
|
-
const frozenBreakpoint = length ? 1 - frozenLength / length : 1;
|
|
701
|
-
const elapsed = Math.min(Math.max(currentTime - startAt, 0), length);
|
|
702
|
-
const remaining = length - elapsed;
|
|
703
|
-
const frozenAt = endAt - frozenLength;
|
|
704
|
-
const percent = length ? (elapsed / length) * 100 : 0;
|
|
705
|
-
const normalPercent = length ? (Math.max(Math.min(currentTime, frozenAt) - startAt, 0) / length) * 100 : 0;
|
|
706
|
-
const normalInnerPercent = Math.min(100, frozenBreakpoint ? normalPercent / frozenBreakpoint : 0);
|
|
707
|
-
const frozenPercent = percent - normalPercent;
|
|
708
|
-
const frozenInnerPercent = Math.min(100, 1 - frozenBreakpoint ? frozenPercent / (1 - frozenBreakpoint) : 0);
|
|
709
|
-
const timeTravelElapsed = timeTravelCurrentValue * 60 * 1000;
|
|
710
|
-
const timeTravelRemaining = length - timeTravelElapsed;
|
|
711
|
-
return {
|
|
712
|
-
elapsed: inTimeMachine ? timeTravelElapsed : elapsed,
|
|
713
|
-
remaining: inTimeMachine ? timeTravelRemaining : remaining,
|
|
714
|
-
frozenBreakpoint,
|
|
715
|
-
normalInnerPercent,
|
|
716
|
-
frozenInnerPercent,
|
|
717
|
-
timeTravelElapsed,
|
|
718
|
-
timeTravelRemaining,
|
|
719
|
-
supportRegen: canRegenerateRanklist(data),
|
|
720
|
-
};
|
|
721
|
-
}
|
|
722
|
-
|
|
723
582
|
class ProgressBarComponent {
|
|
724
583
|
data;
|
|
725
584
|
enableTimeTravel = false;
|
|
@@ -996,10 +855,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
996
855
|
class RanklistComponent {
|
|
997
856
|
data;
|
|
998
857
|
theme = EnumTheme.light;
|
|
999
|
-
borderedRows = false;
|
|
1000
858
|
rowBordered = false;
|
|
1001
859
|
columnBordered = false;
|
|
1002
|
-
|
|
860
|
+
rowStriped = false;
|
|
1003
861
|
formatSrkAssetUrl;
|
|
1004
862
|
splitOrganization = false;
|
|
1005
863
|
columnTitles;
|
|
@@ -1010,6 +868,7 @@ class RanklistComponent {
|
|
|
1010
868
|
showSEColumn = false;
|
|
1011
869
|
emptyStatusPlaceholder = null;
|
|
1012
870
|
userAvatarPlacement = 'user';
|
|
871
|
+
languages;
|
|
1013
872
|
userClick = new EventEmitter();
|
|
1014
873
|
solutionClick = new EventEmitter();
|
|
1015
874
|
statusCellTemplate;
|
|
@@ -1024,8 +883,8 @@ class RanklistComponent {
|
|
|
1024
883
|
tooltip: 'Number of participants who solved this problem',
|
|
1025
884
|
},
|
|
1026
885
|
{
|
|
1027
|
-
key: '
|
|
1028
|
-
label: '
|
|
886
|
+
key: 'attempted',
|
|
887
|
+
label: 'Attempted',
|
|
1029
888
|
tooltip: 'Number of participants who attempted this problem',
|
|
1030
889
|
},
|
|
1031
890
|
{
|
|
@@ -1070,7 +929,7 @@ class RanklistComponent {
|
|
|
1070
929
|
return caniuse(this.data.version);
|
|
1071
930
|
}
|
|
1072
931
|
showTimeColumn() {
|
|
1073
|
-
return shouldShowTimeColumn
|
|
932
|
+
return shouldShowTimeColumn(this.data.rows);
|
|
1074
933
|
}
|
|
1075
934
|
showAvatarInOrganization() {
|
|
1076
935
|
return this.splitOrganization && this.userAvatarPlacement === 'organization';
|
|
@@ -1085,7 +944,7 @@ class RanklistComponent {
|
|
|
1085
944
|
return rankValue.rank ? rankValue.rank : row.user.official === false ? '*' : '';
|
|
1086
945
|
}
|
|
1087
946
|
resolveDisplayText(text) {
|
|
1088
|
-
return resolveText(text);
|
|
947
|
+
return resolveText(text, this.languages);
|
|
1089
948
|
}
|
|
1090
949
|
resolveSeriesColumnTitle(series, index) {
|
|
1091
950
|
const seriesTitles = this.columnTitles?.series;
|
|
@@ -1108,16 +967,16 @@ class RanklistComponent {
|
|
|
1108
967
|
return `${statistics.accepted} / ${statistics.submitted} (${ratio}%)`;
|
|
1109
968
|
}
|
|
1110
969
|
problemHeaderBackgroundImage(problem, gradientDirection = 180) {
|
|
1111
|
-
return getProblemHeaderBackgroundImage
|
|
970
|
+
return getProblemHeaderBackgroundImage(problem.style, this.theme, gradientDirection);
|
|
1112
971
|
}
|
|
1113
972
|
resolvedUserMarkers(user) {
|
|
1114
973
|
return resolveUserMarkers(user, this.data.markers).map((marker) => ({
|
|
1115
974
|
marker,
|
|
1116
|
-
presentation: getMarkerPresentation
|
|
975
|
+
presentation: getMarkerPresentation(marker, this.theme),
|
|
1117
976
|
}));
|
|
1118
977
|
}
|
|
1119
978
|
formatAssetUrl(url, field) {
|
|
1120
|
-
return resolveSrkAssetUrl
|
|
979
|
+
return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
|
|
1121
980
|
}
|
|
1122
981
|
formatTime(time) {
|
|
1123
982
|
return formatTimeDuration(time, 'min', Math.floor);
|
|
@@ -1178,6 +1037,7 @@ class RanklistComponent {
|
|
|
1178
1037
|
markers: this.data.markers,
|
|
1179
1038
|
hideOrganization: this.splitOrganization,
|
|
1180
1039
|
hideAvatar: this.showAvatarInOrganization(),
|
|
1040
|
+
languages: this.languages,
|
|
1181
1041
|
onClick: (event) => this.emitUserClick(event, row, rowIndex),
|
|
1182
1042
|
};
|
|
1183
1043
|
}
|
|
@@ -1195,6 +1055,7 @@ class RanklistComponent {
|
|
|
1195
1055
|
statusCellPreset: this.statusCellPreset,
|
|
1196
1056
|
statusColorAsText: this.statusColorAsText,
|
|
1197
1057
|
emptyStatusPlaceholder: this.emptyStatusPlaceholder,
|
|
1058
|
+
languages: this.languages,
|
|
1198
1059
|
onClick: (event) => this.emitSolutionClick(event, row, rowIndex, status, problemIndex),
|
|
1199
1060
|
};
|
|
1200
1061
|
}
|
|
@@ -1284,8 +1145,8 @@ class RanklistComponent {
|
|
|
1284
1145
|
switch (key) {
|
|
1285
1146
|
case 'accepted':
|
|
1286
1147
|
return stat.accepted;
|
|
1287
|
-
case '
|
|
1288
|
-
return stat.
|
|
1148
|
+
case 'attempted':
|
|
1149
|
+
return stat.attempted;
|
|
1289
1150
|
case 'submitted':
|
|
1290
1151
|
return stat.submitted;
|
|
1291
1152
|
case 'dirt':
|
|
@@ -1304,8 +1165,8 @@ class RanklistComponent {
|
|
|
1304
1165
|
switch (key) {
|
|
1305
1166
|
case 'accepted':
|
|
1306
1167
|
return formatProblemStatisticsPercent(stat.accepted, stat.participantCount);
|
|
1307
|
-
case '
|
|
1308
|
-
return formatProblemStatisticsPercent(stat.
|
|
1168
|
+
case 'attempted':
|
|
1169
|
+
return formatProblemStatisticsPercent(stat.attempted, stat.participantCount);
|
|
1309
1170
|
case 'dirt':
|
|
1310
1171
|
return formatProblemStatisticsPercent(stat.dirt, stat.dirtSubmitted);
|
|
1311
1172
|
default:
|
|
@@ -1313,7 +1174,7 @@ class RanklistComponent {
|
|
|
1313
1174
|
}
|
|
1314
1175
|
}
|
|
1315
1176
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
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",
|
|
1177
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: RanklistComponent, isStandalone: true, selector: "srk-ranklist", inputs: { data: "data", theme: "theme", rowBordered: "rowBordered", columnBordered: "columnBordered", rowStriped: "rowStriped", formatSrkAssetUrl: "formatSrkAssetUrl", splitOrganization: "splitOrganization", columnTitles: "columnTitles", statusCellPreset: "statusCellPreset", statusColorAsText: "statusColorAsText", showProblemStatisticsFooter: "showProblemStatisticsFooter", showDirtColumn: "showDirtColumn", showSEColumn: "showSEColumn", emptyStatusPlaceholder: "emptyStatusPlaceholder", userAvatarPlacement: "userAvatarPlacement", languages: "languages" }, 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: `
|
|
1317
1178
|
<div *ngIf="data.type !== 'general'; else versionState">
|
|
1318
1179
|
srk type "{{ data.type }}" is not supported
|
|
1319
1180
|
</div>
|
|
@@ -1327,9 +1188,9 @@ class RanklistComponent {
|
|
|
1327
1188
|
<ng-template #ranklistTable>
|
|
1328
1189
|
<div class="srk-common-table srk-main">
|
|
1329
1190
|
<table
|
|
1330
|
-
[class.srk-table-row-bordered]="
|
|
1191
|
+
[class.srk-table-row-bordered]="rowBordered"
|
|
1331
1192
|
[class.srk-table-column-bordered]="columnBordered"
|
|
1332
|
-
[class.srk-table-row-striped]="
|
|
1193
|
+
[class.srk-table-row-striped]="rowStriped"
|
|
1333
1194
|
>
|
|
1334
1195
|
<thead>
|
|
1335
1196
|
<tr>
|
|
@@ -1650,9 +1511,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1650
1511
|
<ng-template #ranklistTable>
|
|
1651
1512
|
<div class="srk-common-table srk-main">
|
|
1652
1513
|
<table
|
|
1653
|
-
[class.srk-table-row-bordered]="
|
|
1514
|
+
[class.srk-table-row-bordered]="rowBordered"
|
|
1654
1515
|
[class.srk-table-column-bordered]="columnBordered"
|
|
1655
|
-
[class.srk-table-row-striped]="
|
|
1516
|
+
[class.srk-table-row-striped]="rowStriped"
|
|
1656
1517
|
>
|
|
1657
1518
|
<thead>
|
|
1658
1519
|
<tr>
|
|
@@ -1957,13 +1818,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1957
1818
|
args: [{ required: true }]
|
|
1958
1819
|
}], theme: [{
|
|
1959
1820
|
type: Input
|
|
1960
|
-
}], borderedRows: [{
|
|
1961
|
-
type: Input
|
|
1962
1821
|
}], rowBordered: [{
|
|
1963
1822
|
type: Input
|
|
1964
1823
|
}], columnBordered: [{
|
|
1965
1824
|
type: Input
|
|
1966
|
-
}],
|
|
1825
|
+
}], rowStriped: [{
|
|
1967
1826
|
type: Input
|
|
1968
1827
|
}], formatSrkAssetUrl: [{
|
|
1969
1828
|
type: Input
|
|
@@ -1985,6 +1844,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1985
1844
|
type: Input
|
|
1986
1845
|
}], userAvatarPlacement: [{
|
|
1987
1846
|
type: Input
|
|
1847
|
+
}], languages: [{
|
|
1848
|
+
type: Input
|
|
1988
1849
|
}], userClick: [{
|
|
1989
1850
|
type: Output
|
|
1990
1851
|
}], solutionClick: [{
|