@algoux/standard-ranklist-renderer-component-angular 0.6.2 → 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 +2 -0
- package/dist/README.md +2 -0
- 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 +14 -9
- 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 +45 -181
- 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 +2 -1
- 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;
|
|
@@ -1009,6 +868,7 @@ class RanklistComponent {
|
|
|
1009
868
|
showSEColumn = false;
|
|
1010
869
|
emptyStatusPlaceholder = null;
|
|
1011
870
|
userAvatarPlacement = 'user';
|
|
871
|
+
languages;
|
|
1012
872
|
userClick = new EventEmitter();
|
|
1013
873
|
solutionClick = new EventEmitter();
|
|
1014
874
|
statusCellTemplate;
|
|
@@ -1023,8 +883,8 @@ class RanklistComponent {
|
|
|
1023
883
|
tooltip: 'Number of participants who solved this problem',
|
|
1024
884
|
},
|
|
1025
885
|
{
|
|
1026
|
-
key: '
|
|
1027
|
-
label: '
|
|
886
|
+
key: 'attempted',
|
|
887
|
+
label: 'Attempted',
|
|
1028
888
|
tooltip: 'Number of participants who attempted this problem',
|
|
1029
889
|
},
|
|
1030
890
|
{
|
|
@@ -1069,7 +929,7 @@ class RanklistComponent {
|
|
|
1069
929
|
return caniuse(this.data.version);
|
|
1070
930
|
}
|
|
1071
931
|
showTimeColumn() {
|
|
1072
|
-
return shouldShowTimeColumn
|
|
932
|
+
return shouldShowTimeColumn(this.data.rows);
|
|
1073
933
|
}
|
|
1074
934
|
showAvatarInOrganization() {
|
|
1075
935
|
return this.splitOrganization && this.userAvatarPlacement === 'organization';
|
|
@@ -1084,7 +944,7 @@ class RanklistComponent {
|
|
|
1084
944
|
return rankValue.rank ? rankValue.rank : row.user.official === false ? '*' : '';
|
|
1085
945
|
}
|
|
1086
946
|
resolveDisplayText(text) {
|
|
1087
|
-
return resolveText(text);
|
|
947
|
+
return resolveText(text, this.languages);
|
|
1088
948
|
}
|
|
1089
949
|
resolveSeriesColumnTitle(series, index) {
|
|
1090
950
|
const seriesTitles = this.columnTitles?.series;
|
|
@@ -1107,16 +967,16 @@ class RanklistComponent {
|
|
|
1107
967
|
return `${statistics.accepted} / ${statistics.submitted} (${ratio}%)`;
|
|
1108
968
|
}
|
|
1109
969
|
problemHeaderBackgroundImage(problem, gradientDirection = 180) {
|
|
1110
|
-
return getProblemHeaderBackgroundImage
|
|
970
|
+
return getProblemHeaderBackgroundImage(problem.style, this.theme, gradientDirection);
|
|
1111
971
|
}
|
|
1112
972
|
resolvedUserMarkers(user) {
|
|
1113
973
|
return resolveUserMarkers(user, this.data.markers).map((marker) => ({
|
|
1114
974
|
marker,
|
|
1115
|
-
presentation: getMarkerPresentation
|
|
975
|
+
presentation: getMarkerPresentation(marker, this.theme),
|
|
1116
976
|
}));
|
|
1117
977
|
}
|
|
1118
978
|
formatAssetUrl(url, field) {
|
|
1119
|
-
return resolveSrkAssetUrl
|
|
979
|
+
return resolveSrkAssetUrl(url, field, this.formatSrkAssetUrl);
|
|
1120
980
|
}
|
|
1121
981
|
formatTime(time) {
|
|
1122
982
|
return formatTimeDuration(time, 'min', Math.floor);
|
|
@@ -1177,6 +1037,7 @@ class RanklistComponent {
|
|
|
1177
1037
|
markers: this.data.markers,
|
|
1178
1038
|
hideOrganization: this.splitOrganization,
|
|
1179
1039
|
hideAvatar: this.showAvatarInOrganization(),
|
|
1040
|
+
languages: this.languages,
|
|
1180
1041
|
onClick: (event) => this.emitUserClick(event, row, rowIndex),
|
|
1181
1042
|
};
|
|
1182
1043
|
}
|
|
@@ -1194,6 +1055,7 @@ class RanklistComponent {
|
|
|
1194
1055
|
statusCellPreset: this.statusCellPreset,
|
|
1195
1056
|
statusColorAsText: this.statusColorAsText,
|
|
1196
1057
|
emptyStatusPlaceholder: this.emptyStatusPlaceholder,
|
|
1058
|
+
languages: this.languages,
|
|
1197
1059
|
onClick: (event) => this.emitSolutionClick(event, row, rowIndex, status, problemIndex),
|
|
1198
1060
|
};
|
|
1199
1061
|
}
|
|
@@ -1283,8 +1145,8 @@ class RanklistComponent {
|
|
|
1283
1145
|
switch (key) {
|
|
1284
1146
|
case 'accepted':
|
|
1285
1147
|
return stat.accepted;
|
|
1286
|
-
case '
|
|
1287
|
-
return stat.
|
|
1148
|
+
case 'attempted':
|
|
1149
|
+
return stat.attempted;
|
|
1288
1150
|
case 'submitted':
|
|
1289
1151
|
return stat.submitted;
|
|
1290
1152
|
case 'dirt':
|
|
@@ -1303,8 +1165,8 @@ class RanklistComponent {
|
|
|
1303
1165
|
switch (key) {
|
|
1304
1166
|
case 'accepted':
|
|
1305
1167
|
return formatProblemStatisticsPercent(stat.accepted, stat.participantCount);
|
|
1306
|
-
case '
|
|
1307
|
-
return formatProblemStatisticsPercent(stat.
|
|
1168
|
+
case 'attempted':
|
|
1169
|
+
return formatProblemStatisticsPercent(stat.attempted, stat.participantCount);
|
|
1308
1170
|
case 'dirt':
|
|
1309
1171
|
return formatProblemStatisticsPercent(stat.dirt, stat.dirtSubmitted);
|
|
1310
1172
|
default:
|
|
@@ -1312,7 +1174,7 @@ class RanklistComponent {
|
|
|
1312
1174
|
}
|
|
1313
1175
|
}
|
|
1314
1176
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: RanklistComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
1315
|
-
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" }, 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: `
|
|
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: `
|
|
1316
1178
|
<div *ngIf="data.type !== 'general'; else versionState">
|
|
1317
1179
|
srk type "{{ data.type }}" is not supported
|
|
1318
1180
|
</div>
|
|
@@ -1982,6 +1844,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImpo
|
|
|
1982
1844
|
type: Input
|
|
1983
1845
|
}], userAvatarPlacement: [{
|
|
1984
1846
|
type: Input
|
|
1847
|
+
}], languages: [{
|
|
1848
|
+
type: Input
|
|
1985
1849
|
}], userClick: [{
|
|
1986
1850
|
type: Output
|
|
1987
1851
|
}], solutionClick: [{
|