@algoux/standard-ranklist-renderer-component-vue 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/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import "@algoux/standard-ranklist-renderer-component-styles";
2
- import { defineComponent, ref, computed, watch, watchEffect, onMounted, onBeforeUnmount, openBlock, createElementBlock, normalizeClass, createElementVNode, normalizeStyle, toDisplayString, createCommentVNode, renderSlot, nextTick, createBlock, withCtx, Fragment, renderList, unref, withDirectives, vModelText, h, withModifiers, createVNode, mergeProps } from "vue";
3
- import { SRK_ANIMATED_MODAL_ROOT_CLASS, MODAL_ANIMATION_DURATION_MS, lockModalBodyScroll, unlockModalBodyScroll, ensureModalInteractionTracker, resolveModalTransformOrigin, registerModalFocusScope, unregisterModalFocusScope, getSolutionModalTitle, getSolutionResultMeta, formatSolutionTimestamp, getMarkerPresentation, resolveSrkAssetUrl, getProgressMaxAvailableMinutes, getProgressDurationMinutes, isProgressEnded, getProgressMetrics, getProblemHeaderBackgroundImage, getAcceptedStatusDetails, captureModalTriggerPointFromMouseEvent, caniuse, shouldShowTimeColumn, srkSupportedVersions } from "@algoux/standard-ranklist-renderer-component-core";
2
+ import { defineComponent, ref, computed, watch, watchEffect, onMounted, onBeforeUnmount, openBlock, createElementBlock, normalizeClass, createElementVNode, normalizeStyle, toDisplayString, createCommentVNode, renderSlot, nextTick, createBlock, withCtx, Fragment, renderList, unref, withDirectives, vModelText, h, withModifiers, createVNode, mergeProps, createTextVNode } from "vue";
3
+ import { SRK_ANIMATED_MODAL_ROOT_CLASS, MODAL_ANIMATION_DURATION_MS, lockModalBodyScroll, unlockModalBodyScroll, ensureModalInteractionTracker, resolveModalTransformOrigin, registerModalFocusScope, unregisterModalFocusScope, getSolutionModalTitle, getSolutionResultMeta, formatSolutionTimestamp, getMarkerPresentation, resolveSrkAssetUrl, getProgressMaxAvailableMinutes, getProgressDurationMinutes, isProgressEnded, getProgressMetrics, getProblemHeaderBackgroundImage, getRankProblemStatusCellPresentation, captureModalTriggerPointFromMouseEvent, caniuse, shouldShowTimeColumn, calculateProblemStatisticsFooter, calculateDirtPercentage, calculateSEValue, srkSupportedVersions, formatProblemStatisticsAcceptedMinute, formatProblemStatisticsAverageHardness, formatProblemStatisticsPercent } from "@algoux/standard-ranklist-renderer-component-core";
4
4
  import { EnumTheme, resolveUserMarkers, resolveText, secToTimeStr, numberToAlphabet, formatTimeDuration, resolveStyle } from "@algoux/standard-ranklist-utils";
5
5
  const _hoisted_1$7 = ["data-srk-modal-state"];
6
- const _hoisted_2$6 = ["aria-labelledby"];
6
+ const _hoisted_2$7 = ["aria-labelledby"];
7
7
  const _hoisted_3$5 = { class: "srk-modal-content" };
8
8
  const _hoisted_4$5 = {
9
9
  key: 0,
@@ -188,14 +188,14 @@ const _sfc_main$7 = defineComponent({
188
188
  renderSlot(_ctx.$slots, "default")
189
189
  ])
190
190
  ])
191
- ], 12, _hoisted_2$6)
191
+ ], 12, _hoisted_2$7)
192
192
  ], 34)
193
193
  ], 10, _hoisted_1$7)) : createCommentVNode("", true);
194
194
  };
195
195
  }
196
196
  });
197
197
  const _hoisted_1$6 = { class: "srk-common-table srk-solutions-table" };
198
- const _hoisted_2$5 = { class: "srk--text-right" };
198
+ const _hoisted_2$6 = { class: "srk--text-right" };
199
199
  const _sfc_main$6 = defineComponent({
200
200
  __name: "DefaultSolutionModal",
201
201
  props: {
@@ -262,7 +262,7 @@ const _sfc_main$6 = defineComponent({
262
262
  class: normalizeClass(["srk-solution-result-text", unref(getSolutionResultMeta)(solution.result).className])
263
263
  }, toDisplayString(unref(getSolutionResultMeta)(solution.result).label), 3)
264
264
  ]),
265
- createElementVNode("td", _hoisted_2$5, toDisplayString(unref(formatSolutionTimestamp)(solution)), 1)
265
+ createElementVNode("td", _hoisted_2$6, toDisplayString(unref(formatSolutionTimestamp)(solution)), 1)
266
266
  ]);
267
267
  }), 128))
268
268
  ])
@@ -274,7 +274,7 @@ const _sfc_main$6 = defineComponent({
274
274
  }
275
275
  });
276
276
  const _hoisted_1$5 = { class: "srk-user-modal-info" };
277
- const _hoisted_2$4 = { class: "srk-user-modal-info-user-name" };
277
+ const _hoisted_2$5 = { class: "srk-user-modal-info-user-name" };
278
278
  const _hoisted_3$4 = {
279
279
  key: 0,
280
280
  class: "srk-user-modal-info-user-second-name"
@@ -285,15 +285,15 @@ const _hoisted_6$3 = {
285
285
  key: 1,
286
286
  class: "srk-user-modal-info-team-members"
287
287
  };
288
- const _hoisted_7$2 = {
288
+ const _hoisted_7$3 = {
289
289
  key: 0,
290
290
  class: "srk-user-modal-info-team-members-slash"
291
291
  };
292
- const _hoisted_8$2 = {
292
+ const _hoisted_8$3 = {
293
293
  key: 2,
294
294
  class: "srk-user-modal-info-photo"
295
295
  };
296
- const _hoisted_9$2 = ["src"];
296
+ const _hoisted_9$3 = ["src"];
297
297
  const _sfc_main$5 = defineComponent({
298
298
  __name: "DefaultUserModal",
299
299
  props: {
@@ -339,7 +339,7 @@ const _sfc_main$5 = defineComponent({
339
339
  }, {
340
340
  default: withCtx(() => [
341
341
  createElementVNode("div", _hoisted_1$5, [
342
- createElementVNode("h3", _hoisted_2$4, toDisplayString(unref(resolveText)(cachedUser.value.name)), 1),
342
+ createElementVNode("h3", _hoisted_2$5, toDisplayString(unref(resolveText)(cachedUser.value.name)), 1),
343
343
  cachedUser.value.organization ? (openBlock(), createElementBlock("p", _hoisted_3$4, toDisplayString(unref(resolveText)(cachedUser.value.organization)), 1)) : createCommentVNode("", true),
344
344
  createElementVNode("div", _hoisted_4$4, [
345
345
  createElementVNode("span", _hoisted_5$4, toDisplayString(cachedUser.value.official === false ? "\uFF0A \u975E\u6B63\u5F0F\u53C2\u52A0\u8005" : "\u6B63\u5F0F\u53C2\u52A0\u8005"), 1),
@@ -356,17 +356,17 @@ const _sfc_main$5 = defineComponent({
356
356
  return openBlock(), createElementBlock(Fragment, {
357
357
  key: unref(resolveText)(member.name)
358
358
  }, [
359
- index > 0 ? (openBlock(), createElementBlock("span", _hoisted_7$2, " / ")) : createCommentVNode("", true),
359
+ index > 0 ? (openBlock(), createElementBlock("span", _hoisted_7$3, " / ")) : createCommentVNode("", true),
360
360
  createElementVNode("span", null, toDisplayString(unref(resolveText)(member.name)), 1)
361
361
  ], 64);
362
362
  }), 128))
363
363
  ])) : createCommentVNode("", true),
364
- cachedUser.value.photo ? (openBlock(), createElementBlock("div", _hoisted_8$2, [
364
+ cachedUser.value.photo ? (openBlock(), createElementBlock("div", _hoisted_8$3, [
365
365
  createElementVNode("img", {
366
366
  src: formatAssetUrl(cachedUser.value.photo, "user.photo"),
367
367
  alt: "User portrait",
368
368
  class: "srk-user-modal-info-photo-img"
369
- }, null, 8, _hoisted_9$2)
369
+ }, null, 8, _hoisted_9$3)
370
370
  ])) : createCommentVNode("", true)
371
371
  ])
372
372
  ]),
@@ -376,7 +376,7 @@ const _sfc_main$5 = defineComponent({
376
376
  }
377
377
  });
378
378
  const _hoisted_1$4 = { class: "srk-progress-bar-container" };
379
- const _hoisted_2$3 = { class: "srk-progress-bar" };
379
+ const _hoisted_2$4 = { class: "srk-progress-bar" };
380
380
  const _hoisted_3$3 = { class: "srk-progress-bar-body" };
381
381
  const _hoisted_4$3 = {
382
382
  key: 0,
@@ -384,16 +384,16 @@ const _hoisted_4$3 = {
384
384
  };
385
385
  const _hoisted_5$3 = ["max", "title"];
386
386
  const _hoisted_6$2 = { class: "srk-progress-secondary-area" };
387
- const _hoisted_7$1 = { class: "srk-progress-secondary-area-center" };
388
- const _hoisted_8$1 = {
387
+ const _hoisted_7$2 = { class: "srk-progress-secondary-area-center" };
388
+ const _hoisted_8$2 = {
389
389
  key: 0,
390
390
  class: "srk-progress-time-machine-status"
391
391
  };
392
- const _hoisted_9$1 = {
392
+ const _hoisted_9$2 = {
393
393
  key: 1,
394
394
  class: "srk-progress-live-text"
395
395
  };
396
- const _hoisted_10 = {
396
+ const _hoisted_10$1 = {
397
397
  key: 2,
398
398
  style: { "visibility": "hidden" }
399
399
  };
@@ -475,7 +475,7 @@ const _sfc_main$4 = defineComponent({
475
475
  });
476
476
  return (_ctx, _cache) => {
477
477
  return openBlock(), createElementBlock("div", _hoisted_1$4, [
478
- createElementVNode("div", _hoisted_2$3, [
478
+ createElementVNode("div", _hoisted_2$4, [
479
479
  createElementVNode("div", _hoisted_3$3, [
480
480
  createElementVNode("div", {
481
481
  class: "srk-progress-bar-segment srk-progress-bar-normal",
@@ -533,10 +533,10 @@ const _sfc_main$4 = defineComponent({
533
533
  class: "srk-progress-secondary-area-left",
534
534
  style: normalizeStyle(__props.live || inTimeMachine.value ? {} : { display: "none" })
535
535
  }, " Elapsed: " + toDisplayString(unref(secToTimeStr)(Math.round(progressMetrics.value.elapsed / 1e3))), 5),
536
- createElementVNode("div", _hoisted_7$1, [
537
- inTimeMachine.value ? (openBlock(), createElementBlock("div", _hoisted_8$1, [..._cache[1] || (_cache[1] = [
536
+ createElementVNode("div", _hoisted_7$2, [
537
+ inTimeMachine.value ? (openBlock(), createElementBlock("div", _hoisted_8$2, [..._cache[1] || (_cache[1] = [
538
538
  createElementVNode("div", { class: "srk-progress-time-machine-text" }, "Time Travel Mode", -1)
539
- ])])) : __props.live && !isEnded.value ? (openBlock(), createElementBlock("div", _hoisted_9$1, "Live")) : (openBlock(), createElementBlock("div", _hoisted_10, "SRK"))
539
+ ])])) : __props.live && !isEnded.value ? (openBlock(), createElementBlock("div", _hoisted_9$2, "Live")) : (openBlock(), createElementBlock("div", _hoisted_10$1, "SRK"))
540
540
  ]),
541
541
  createElementVNode("div", {
542
542
  class: "srk-progress-secondary-area-right",
@@ -548,7 +548,7 @@ const _sfc_main$4 = defineComponent({
548
548
  }
549
549
  });
550
550
  const _hoisted_1$3 = ["href"];
551
- const _hoisted_2$2 = { class: "srk--display-block" };
551
+ const _hoisted_2$3 = { class: "srk--display-block" };
552
552
  const _hoisted_3$2 = ["title"];
553
553
  const _hoisted_4$2 = { class: "srk--display-block" };
554
554
  const _hoisted_5$2 = ["title"];
@@ -583,7 +583,7 @@ const _sfc_main$3 = defineComponent({
583
583
  rel: "noopener noreferrer",
584
584
  style: { "color": "unset" }
585
585
  }, [
586
- createElementVNode("span", _hoisted_2$2, toDisplayString(alias.value), 1),
586
+ createElementVNode("span", _hoisted_2$3, toDisplayString(alias.value), 1),
587
587
  stat.value ? (openBlock(), createElementBlock("span", {
588
588
  key: 0,
589
589
  class: "srk--display-block srk-problem-stats",
@@ -601,7 +601,15 @@ const _sfc_main$3 = defineComponent({
601
601
  };
602
602
  }
603
603
  });
604
- const _hoisted_1$2 = { key: 4 };
604
+ const _hoisted_1$2 = {
605
+ key: 0,
606
+ class: "srk-prest-status-block-fb-star"
607
+ };
608
+ const _hoisted_2$2 = {
609
+ key: 4,
610
+ class: "srk-status-placeholder-cell srk--text-center srk--nowrap"
611
+ };
612
+ const fbStar = "\u2605";
605
613
  const _sfc_main$2 = defineComponent({
606
614
  __name: "StatusCell",
607
615
  props: {
@@ -612,7 +620,10 @@ const _sfc_main$2 = defineComponent({
612
620
  row: {},
613
621
  rowIndex: {},
614
622
  ranklist: {},
615
- onSolutionClick: { type: Function }
623
+ onSolutionClick: {},
624
+ statusCellPreset: { default: "classic" },
625
+ statusColorAsText: { type: Boolean, default: false },
626
+ emptyStatusPlaceholder: { default: null }
616
627
  },
617
628
  setup(__props) {
618
629
  const props = __props;
@@ -622,7 +633,10 @@ const _sfc_main$2 = defineComponent({
622
633
  "srk-prest-status-block",
623
634
  "srk--text-center",
624
635
  "srk--nowrap",
625
- { "srk--cursor-pointer": isClickable.value }
636
+ {
637
+ "srk--cursor-pointer": isClickable.value,
638
+ "srk-prest-status-block-color-text": props.statusColorAsText
639
+ }
626
640
  ]);
627
641
  function emitSolutionClick(event) {
628
642
  var _a, _b;
@@ -635,7 +649,7 @@ const _sfc_main$2 = defineComponent({
635
649
  rowIndex: props.rowIndex,
636
650
  problemIndex: props.problemIndex,
637
651
  problemAlias: ((_a = props.problem) == null ? void 0 : _a.alias) || null,
638
- problemTitle: props.problem ? props.problem.title : null,
652
+ problemTitle: props.problem ? resolveText(props.problem.title) : null,
639
653
  userId: props.user.id || null
640
654
  }
641
655
  });
@@ -650,24 +664,41 @@ const _sfc_main$2 = defineComponent({
650
664
  ranklist: props.ranklist
651
665
  });
652
666
  }
653
- const AcceptedStatusBody = defineComponent({
667
+ const StatusBody = defineComponent({
654
668
  props: {
655
669
  status: {
656
670
  type: Object,
657
671
  required: true
672
+ },
673
+ ranklist: {
674
+ type: Object,
675
+ required: true
676
+ },
677
+ preset: {
678
+ type: String,
679
+ required: true
658
680
  }
659
681
  },
660
682
  setup(childProps) {
661
683
  return () => {
662
684
  const status = childProps.status;
663
- const details = getAcceptedStatusDetails(status);
664
- if (typeof status.score === "number") {
685
+ const ranklist = childProps.ranklist;
686
+ const preset = childProps.preset;
687
+ const presentation = getRankProblemStatusCellPresentation(status, ranklist, preset);
688
+ if (typeof presentation.score === "number") {
665
689
  return [
666
- h("span", { class: "srk-prest-status-block-score" }, status.score),
667
- h("span", { class: "srk-prest-status-block-score-details" }, details)
690
+ h("span", { class: "srk-prest-status-block-score" }, presentation.score),
691
+ h("span", { class: "srk-prest-status-block-score-details" }, presentation.scoreDetails)
668
692
  ];
669
693
  }
670
- return details;
694
+ if (presentation.secondary !== void 0) {
695
+ return [
696
+ h("span", { class: "srk-prest-status-block-primary" }, presentation.primary || ""),
697
+ " ",
698
+ h("span", { class: "srk-prest-status-block-secondary" }, presentation.secondary)
699
+ ];
700
+ }
701
+ return presentation.primary || "";
671
702
  };
672
703
  }
673
704
  });
@@ -677,22 +708,43 @@ const _sfc_main$2 = defineComponent({
677
708
  class: normalizeClass([commonClassName.value, "srk-prest-status-block-fb"]),
678
709
  onClick: withModifiers(emitSolutionClick, ["prevent"])
679
710
  }, [
680
- createVNode(unref(AcceptedStatusBody), { status: __props.status }, null, 8, ["status"])
711
+ __props.statusColorAsText ? (openBlock(), createElementBlock("span", _hoisted_1$2, toDisplayString(fbStar))) : createCommentVNode("", true),
712
+ createVNode(unref(StatusBody), {
713
+ status: __props.status,
714
+ ranklist: __props.ranklist,
715
+ preset: __props.statusCellPreset
716
+ }, null, 8, ["status", "ranklist", "preset"])
681
717
  ], 2)) : __props.status.result === "AC" ? (openBlock(), createElementBlock("td", {
682
718
  key: 1,
683
719
  class: normalizeClass([commonClassName.value, "srk-prest-status-block-accepted"]),
684
720
  onClick: withModifiers(emitSolutionClick, ["prevent"])
685
721
  }, [
686
- createVNode(unref(AcceptedStatusBody), { status: __props.status }, null, 8, ["status"])
722
+ createVNode(unref(StatusBody), {
723
+ status: __props.status,
724
+ ranklist: __props.ranklist,
725
+ preset: __props.statusCellPreset
726
+ }, null, 8, ["status", "ranklist", "preset"])
687
727
  ], 2)) : __props.status.result === "?" ? (openBlock(), createElementBlock("td", {
688
728
  key: 2,
689
729
  class: normalizeClass([commonClassName.value, "srk-prest-status-block-frozen"]),
690
730
  onClick: withModifiers(emitSolutionClick, ["prevent"])
691
- }, toDisplayString(__props.status.tries), 3)) : __props.status.result === "RJ" ? (openBlock(), createElementBlock("td", {
731
+ }, [
732
+ createVNode(unref(StatusBody), {
733
+ status: __props.status,
734
+ ranklist: __props.ranklist,
735
+ preset: __props.statusCellPreset
736
+ }, null, 8, ["status", "ranklist", "preset"])
737
+ ], 2)) : __props.status.result === "RJ" ? (openBlock(), createElementBlock("td", {
692
738
  key: 3,
693
739
  class: normalizeClass([commonClassName.value, "srk-prest-status-block-failed"]),
694
740
  onClick: withModifiers(emitSolutionClick, ["prevent"])
695
- }, toDisplayString(__props.status.tries), 3)) : (openBlock(), createElementBlock("td", _hoisted_1$2));
741
+ }, [
742
+ createVNode(unref(StatusBody), {
743
+ status: __props.status,
744
+ ranklist: __props.ranklist,
745
+ preset: __props.statusCellPreset
746
+ }, null, 8, ["status", "ranklist", "preset"])
747
+ ], 2)) : (openBlock(), createElementBlock("td", _hoisted_2$2, toDisplayString(__props.emptyStatusPlaceholder), 1));
696
748
  };
697
749
  }
698
750
  });
@@ -705,9 +757,9 @@ const _hoisted_3$1 = ["src"];
705
757
  const _hoisted_4$1 = { class: "srk-user-body" };
706
758
  const _hoisted_5$1 = { class: "srk-user-name-row" };
707
759
  const _hoisted_6$1 = ["title"];
708
- const _hoisted_7 = { class: "srk-marker-dot-group" };
709
- const _hoisted_8 = ["data-tooltip"];
710
- const _hoisted_9 = {
760
+ const _hoisted_7$1 = { class: "srk-marker-dot-group" };
761
+ const _hoisted_8$1 = ["data-tooltip"];
762
+ const _hoisted_9$1 = {
711
763
  key: 0,
712
764
  class: "srk-user-secondary-text srk--text-ellipsis",
713
765
  title: ""
@@ -722,7 +774,9 @@ const _sfc_main$1 = defineComponent({
722
774
  markers: { default: () => [] },
723
775
  theme: { default: EnumTheme.light },
724
776
  formatSrkAssetUrl: {},
725
- onUserClick: {}
777
+ onUserClick: {},
778
+ hideOrganization: { type: Boolean, default: false },
779
+ hideAvatar: { type: Boolean, default: false }
726
780
  },
727
781
  setup(__props) {
728
782
  const props = __props;
@@ -756,7 +810,7 @@ const _sfc_main$1 = defineComponent({
756
810
  onClick: withModifiers(emitUserClick, ["prevent"])
757
811
  }, [
758
812
  createElementVNode("div", _hoisted_1$1, [
759
- __props.user.avatar ? (openBlock(), createElementBlock("div", _hoisted_2$1, [
813
+ __props.user.avatar && !__props.hideAvatar ? (openBlock(), createElementBlock("div", _hoisted_2$1, [
760
814
  createElementVNode("img", {
761
815
  src: __props.formatSrkAssetUrl(__props.user.avatar, "user.avatar"),
762
816
  alt: "User Avatar"
@@ -768,18 +822,18 @@ const _sfc_main$1 = defineComponent({
768
822
  class: "srk-user-name-text",
769
823
  title: name.value
770
824
  }, toDisplayString(name.value), 9, _hoisted_6$1),
771
- createElementVNode("span", _hoisted_7, [
825
+ createElementVNode("span", _hoisted_7$1, [
772
826
  (openBlock(true), createElementBlock(Fragment, null, renderList(resolvedMarkers.value, (marker) => {
773
827
  return openBlock(), createElementBlock("span", {
774
828
  key: marker.marker.id,
775
829
  class: normalizeClass(["srk-marker srk-marker-dot srk--c-tooltip", marker.presentation.className]),
776
830
  style: normalizeStyle(marker.presentation.style),
777
831
  "data-tooltip": unref(resolveText)(marker.marker.label)
778
- }, null, 14, _hoisted_8);
832
+ }, null, 14, _hoisted_8$1);
779
833
  }), 128))
780
834
  ])
781
835
  ]),
782
- __props.user.organization ? (openBlock(), createElementBlock("p", _hoisted_9, toDisplayString(unref(resolveText)(__props.user.organization)), 1)) : createCommentVNode("", true)
836
+ __props.user.organization && !__props.hideOrganization ? (openBlock(), createElementBlock("p", _hoisted_9$1, toDisplayString(unref(resolveText)(__props.user.organization)), 1)) : createCommentVNode("", true)
783
837
  ])
784
838
  ])
785
839
  ], 2);
@@ -794,21 +848,85 @@ const _hoisted_3 = {
794
848
  };
795
849
  const _hoisted_4 = {
796
850
  key: 0,
797
- class: "srk--nowrap"
851
+ class: "srk-organization-header srk--text-left srk--nowrap"
852
+ };
853
+ const _hoisted_5 = { class: "srk--text-left srk--nowrap" };
854
+ const _hoisted_6 = { class: "srk--text-right srk--nowrap" };
855
+ const _hoisted_7 = {
856
+ key: 1,
857
+ class: "srk--text-right srk--nowrap"
798
858
  };
799
- const _hoisted_5 = { class: "srk--text-right srk--nowrap" };
800
- const _hoisted_6 = {
859
+ const _hoisted_8 = {
860
+ key: 2,
861
+ class: "srk-dirt-header srk--text-right srk--nowrap"
862
+ };
863
+ const _hoisted_9 = {
864
+ key: 3,
865
+ class: "srk-se-header srk--text-right srk--nowrap"
866
+ };
867
+ const _hoisted_10 = { class: "srk-organization-cell-content" };
868
+ const _hoisted_11 = {
801
869
  key: 0,
870
+ class: "srk-user-avatar"
871
+ };
872
+ const _hoisted_12 = ["src"];
873
+ const _hoisted_13 = ["title"];
874
+ const _hoisted_14 = { class: "srk--text-right srk--nowrap" };
875
+ const _hoisted_15 = {
876
+ key: 1,
802
877
  class: "srk--text-right srk--nowrap"
803
878
  };
879
+ const _hoisted_16 = {
880
+ key: 2,
881
+ class: "srk-dirt-cell srk--text-right srk--nowrap"
882
+ };
883
+ const _hoisted_17 = {
884
+ key: 3,
885
+ class: "srk-se-cell srk--text-right srk--nowrap"
886
+ };
887
+ const _hoisted_18 = { key: 0 };
888
+ const _hoisted_19 = ["colspan"];
889
+ const _hoisted_20 = ["data-tooltip"];
890
+ const _hoisted_21 = { class: "srk-problem-statistics-footer-primary" };
891
+ const _hoisted_22 = { class: "srk-problem-statistics-footer-secondary" };
892
+ const _hoisted_23 = {
893
+ key: 0,
894
+ class: "srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
895
+ };
896
+ const _hoisted_24 = {
897
+ key: 1,
898
+ class: "srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
899
+ };
900
+ const _hoisted_25 = { class: "srk-problem-statistics-footer-row srk-problem-statistics-footer-problem-label-row" };
901
+ const _hoisted_26 = ["colspan"];
902
+ const _hoisted_27 = { class: "srk--display-block" };
903
+ const _hoisted_28 = {
904
+ key: 0,
905
+ class: "srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-dirt-footer-cell srk--nowrap"
906
+ };
907
+ const _hoisted_29 = {
908
+ key: 1,
909
+ class: "srk-problem-statistics-footer-cell srk-extra-statistics-footer-cell srk-se-footer-cell srk--nowrap"
910
+ };
804
911
  const _sfc_main = defineComponent({
805
912
  __name: "Ranklist",
806
913
  props: {
807
914
  data: {},
808
915
  theme: { default: EnumTheme.light },
809
916
  borderedRows: { type: Boolean, default: false },
917
+ rowBordered: { type: Boolean, default: false },
918
+ columnBordered: { type: Boolean, default: false },
810
919
  stripedRows: { type: Boolean, default: false },
811
- formatSrkAssetUrl: {}
920
+ formatSrkAssetUrl: {},
921
+ splitOrganization: { type: Boolean, default: false },
922
+ columnTitles: {},
923
+ statusCellPreset: { default: "classic" },
924
+ statusColorAsText: { type: Boolean, default: false },
925
+ showProblemStatisticsFooter: { type: Boolean, default: false },
926
+ showDirtColumn: { type: Boolean, default: false },
927
+ showSEColumn: { type: Boolean, default: false },
928
+ emptyStatusPlaceholder: { default: null },
929
+ userAvatarPlacement: { default: "user" }
812
930
  },
813
931
  emits: ["userClick", "solutionClick"],
814
932
  setup(__props, { emit: __emit }) {
@@ -818,6 +936,46 @@ const _sfc_main = defineComponent({
818
936
  const supportedVersions = srkSupportedVersions;
819
937
  const isSupportedVersion = computed(() => caniuse(props.data.version));
820
938
  const showTimeColumn = computed(() => shouldShowTimeColumn(props.data.rows));
939
+ const showAvatarInOrganization = computed(() => props.splitOrganization && props.userAvatarPlacement === "organization");
940
+ const problemStatistics = computed(() => props.showProblemStatisticsFooter || props.showSEColumn ? calculateProblemStatisticsFooter(props.data) : []);
941
+ const leftFooterColumnCount = computed(() => props.data.series.length + 1 + 1 + (showTimeColumn.value ? 1 : 0) + (props.splitOrganization ? 1 : 0));
942
+ const problemStatisticsFooterRows = [
943
+ {
944
+ key: "accepted",
945
+ label: "Accepted",
946
+ tooltip: "Number of participants who solved this problem"
947
+ },
948
+ {
949
+ key: "tried",
950
+ label: "Tried",
951
+ tooltip: "Number of participants who attempted this problem"
952
+ },
953
+ {
954
+ key: "submitted",
955
+ label: "Submitted",
956
+ tooltip: "Total number of valid submissions for this problem"
957
+ },
958
+ {
959
+ key: "dirt",
960
+ label: "Dirt",
961
+ tooltip: "Wrong submissions among participants who solved this problem"
962
+ },
963
+ {
964
+ key: "se",
965
+ label: "SE",
966
+ tooltip: "Average hardness, calculated as (participants - accepted) / participants"
967
+ },
968
+ {
969
+ key: "firstAccepted",
970
+ label: "FB at",
971
+ tooltip: "First Blood at, also known as first solve time, in minutes"
972
+ },
973
+ {
974
+ key: "lastAccepted",
975
+ label: "LB at",
976
+ tooltip: "Last Blood at, also known as last solve time, in minutes"
977
+ }
978
+ ];
821
979
  function formatAssetUrl(url, field) {
822
980
  return resolveSrkAssetUrl(url, field, props.formatSrkAssetUrl);
823
981
  }
@@ -827,6 +985,24 @@ const _sfc_main = defineComponent({
827
985
  function getRankText(rankValue, row) {
828
986
  return rankValue.rank ? rankValue.rank : row.user.official === false ? "\uFF0A" : "";
829
987
  }
988
+ function isSeriesSegmentedColumn(series) {
989
+ return ((series == null ? void 0 : series.segments) || []).some((segment) => typeof segment.style === "string");
990
+ }
991
+ function resolveSeriesColumnTitle(series, index) {
992
+ var _a, _b, _c;
993
+ const seriesTitles = (_a = props.columnTitles) == null ? void 0 : _a.series;
994
+ if (typeof seriesTitles === "function") {
995
+ return (_b = seriesTitles(series, index)) != null ? _b : series.title;
996
+ }
997
+ if (Array.isArray(seriesTitles)) {
998
+ return (_c = seriesTitles[index]) != null ? _c : series.title;
999
+ }
1000
+ return series.title;
1001
+ }
1002
+ function resolveColumnTitle(key, fallback) {
1003
+ var _a, _b;
1004
+ return (_b = (_a = props.columnTitles) == null ? void 0 : _a[key]) != null ? _b : fallback;
1005
+ }
830
1006
  function resolveSeriesSegment(rankValue, series) {
831
1007
  const index = rankValue.segmentIndex || rankValue.segmentIndex === 0 ? rankValue.segmentIndex : -1;
832
1008
  return ((series == null ? void 0 : series.segments) || [])[index] || {};
@@ -855,6 +1031,38 @@ const _sfc_main = defineComponent({
855
1031
  function getStatusSolutions(status) {
856
1032
  return [...status.solutions || []].reverse();
857
1033
  }
1034
+ function getProblemStatisticsFooterCellPrimary(key, stat) {
1035
+ switch (key) {
1036
+ case "accepted":
1037
+ return stat.accepted;
1038
+ case "tried":
1039
+ return stat.tried;
1040
+ case "submitted":
1041
+ return stat.submitted;
1042
+ case "dirt":
1043
+ return stat.dirt;
1044
+ case "se":
1045
+ return formatProblemStatisticsAverageHardness(stat);
1046
+ case "firstAccepted":
1047
+ return formatProblemStatisticsAcceptedMinute(stat.firstAcceptedTime);
1048
+ case "lastAccepted":
1049
+ return formatProblemStatisticsAcceptedMinute(stat.lastAcceptedTime);
1050
+ default:
1051
+ return "";
1052
+ }
1053
+ }
1054
+ function getProblemStatisticsFooterCellSecondary(key, stat) {
1055
+ switch (key) {
1056
+ case "accepted":
1057
+ return formatProblemStatisticsPercent(stat.accepted, stat.participantCount);
1058
+ case "tried":
1059
+ return formatProblemStatisticsPercent(stat.tried, stat.participantCount);
1060
+ case "dirt":
1061
+ return formatProblemStatisticsPercent(stat.dirt, stat.dirtSubmitted);
1062
+ default:
1063
+ return void 0;
1064
+ }
1065
+ }
858
1066
  function emitUserClick(payloadOrRow, rowIndex, event) {
859
1067
  if ("ranklist" in payloadOrRow) {
860
1068
  emit("userClick", payloadOrRow);
@@ -911,19 +1119,24 @@ const _sfc_main = defineComponent({
911
1119
  return (_ctx, _cache) => {
912
1120
  return __props.data.type !== "general" ? (openBlock(), createElementBlock("div", _hoisted_1, 'srk type "' + toDisplayString(__props.data.type) + '" is not supported', 1)) : !isSupportedVersion.value ? (openBlock(), createElementBlock("div", _hoisted_2, ' srk version "' + toDisplayString(__props.data.version) + '" is not supported (current supported: ' + toDisplayString(unref(supportedVersions)) + ") ", 1)) : (openBlock(), createElementBlock("div", _hoisted_3, [
913
1121
  createElementVNode("table", {
914
- class: normalizeClass({ "srk-table-row-bordered": __props.borderedRows, "srk-table-row-striped": __props.stripedRows })
1122
+ class: normalizeClass({
1123
+ "srk-table-row-bordered": __props.borderedRows || __props.rowBordered,
1124
+ "srk-table-column-bordered": __props.columnBordered,
1125
+ "srk-table-row-striped": __props.stripedRows
1126
+ })
915
1127
  }, [
916
1128
  createElementVNode("thead", null, [
917
1129
  createElementVNode("tr", null, [
918
- (openBlock(true), createElementBlock(Fragment, null, renderList(__props.data.series, (seriesItem) => {
1130
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.data.series, (seriesItem, seriesIndex) => {
919
1131
  return openBlock(), createElementBlock("th", {
920
1132
  key: seriesItem.title,
921
- class: "srk-series-header srk--text-right srk--nowrap"
922
- }, toDisplayString(seriesItem.title), 1);
1133
+ class: normalizeClass(["srk-series-header srk--text-right srk--nowrap", { "srk-series-segmented-column": isSeriesSegmentedColumn(seriesItem) }])
1134
+ }, toDisplayString(resolveSeriesColumnTitle(seriesItem, seriesIndex)), 3);
923
1135
  }), 128)),
924
- _cache[0] || (_cache[0] = createElementVNode("th", { class: "srk--text-left srk--nowrap" }, "Name", -1)),
925
- _cache[1] || (_cache[1] = createElementVNode("th", { class: "srk--nowrap" }, "Score", -1)),
926
- showTimeColumn.value ? (openBlock(), createElementBlock("th", _hoisted_4, "Time")) : createCommentVNode("", true),
1136
+ __props.splitOrganization ? (openBlock(), createElementBlock("th", _hoisted_4, toDisplayString(resolveColumnTitle("organization", "Organization")), 1)) : createCommentVNode("", true),
1137
+ createElementVNode("th", _hoisted_5, toDisplayString(resolveColumnTitle("user", "Name")), 1),
1138
+ createElementVNode("th", _hoisted_6, toDisplayString(resolveColumnTitle("score", "Score")), 1),
1139
+ showTimeColumn.value ? (openBlock(), createElementBlock("th", _hoisted_7, toDisplayString(resolveColumnTitle("time", "Time")), 1)) : createCommentVNode("", true),
927
1140
  (openBlock(true), createElementBlock(Fragment, null, renderList(__props.data.problems, (problem, problemIndex) => {
928
1141
  return renderSlot(_ctx.$slots, "problem-header-cell", mergeProps({
929
1142
  key: problem.alias || unref(resolveText)(problem.title) || problemIndex,
@@ -935,7 +1148,9 @@ const _sfc_main = defineComponent({
935
1148
  theme: resolvedTheme.value
936
1149
  }, null, 8, ["problem", "index", "theme"])
937
1150
  ]);
938
- }), 128))
1151
+ }), 128)),
1152
+ __props.showDirtColumn ? (openBlock(), createElementBlock("th", _hoisted_8, toDisplayString(resolveColumnTitle("dirt", "Dirt")), 1)) : createCommentVNode("", true),
1153
+ __props.showSEColumn ? (openBlock(), createElementBlock("th", _hoisted_9, toDisplayString(resolveColumnTitle("se", "SE")), 1)) : createCommentVNode("", true)
939
1154
  ])
940
1155
  ]),
941
1156
  createElementVNode("tbody", null, [
@@ -947,10 +1162,30 @@ const _sfc_main = defineComponent({
947
1162
  var _a;
948
1163
  return openBlock(), createElementBlock("td", {
949
1164
  key: ((_a = __props.data.series[seriesIndex]) == null ? void 0 : _a.title) || seriesIndex,
950
- class: normalizeClass(["srk--text-right srk--nowrap", getSeriesSegmentClass(rankValue, __props.data.series[seriesIndex])]),
1165
+ class: normalizeClass(["srk--text-right srk--nowrap", [
1166
+ getSeriesSegmentClass(rankValue, __props.data.series[seriesIndex]),
1167
+ { "srk-series-segmented-column": isSeriesSegmentedColumn(__props.data.series[seriesIndex]) }
1168
+ ]]),
951
1169
  style: normalizeStyle(getSeriesSegmentStyle(rankValue, __props.data.series[seriesIndex]))
952
1170
  }, toDisplayString(getRankText(rankValue, row)), 7);
953
1171
  }), 128)),
1172
+ __props.splitOrganization ? (openBlock(), createElementBlock("td", {
1173
+ key: 0,
1174
+ class: normalizeClass(["srk-organization-cell srk--text-left srk--nowrap", { "srk-organization-cell-avatar": showAvatarInOrganization.value && !!row.user.avatar }])
1175
+ }, [
1176
+ createElementVNode("div", _hoisted_10, [
1177
+ showAvatarInOrganization.value && row.user.avatar ? (openBlock(), createElementBlock("div", _hoisted_11, [
1178
+ createElementVNode("img", {
1179
+ src: formatAssetUrl(row.user.avatar, "user.avatar"),
1180
+ alt: "User Avatar"
1181
+ }, null, 8, _hoisted_12)
1182
+ ])) : createCommentVNode("", true),
1183
+ createElementVNode("span", {
1184
+ class: "srk-organization-name-text",
1185
+ title: row.user.organization ? unref(resolveText)(row.user.organization) : ""
1186
+ }, toDisplayString(row.user.organization ? unref(resolveText)(row.user.organization) : ""), 9, _hoisted_13)
1187
+ ])
1188
+ ], 2)) : createCommentVNode("", true),
954
1189
  renderSlot(_ctx.$slots, "user-cell", mergeProps({ ref_for: true }, {
955
1190
  user: row.user,
956
1191
  row,
@@ -958,6 +1193,8 @@ const _sfc_main = defineComponent({
958
1193
  ranklist: __props.data,
959
1194
  markers: __props.data.markers,
960
1195
  theme: resolvedTheme.value,
1196
+ hideOrganization: __props.splitOrganization,
1197
+ hideAvatar: showAvatarInOrganization.value,
961
1198
  onClick: (event) => emitUserClick(row, rowIndex, event)
962
1199
  }), () => [
963
1200
  createVNode(_sfc_main$1, {
@@ -968,11 +1205,13 @@ const _sfc_main = defineComponent({
968
1205
  markers: __props.data.markers,
969
1206
  theme: resolvedTheme.value,
970
1207
  "format-srk-asset-url": formatAssetUrl,
971
- "on-user-click": emitUserClick
972
- }, null, 8, ["user", "row", "row-index", "ranklist", "markers", "theme"])
1208
+ "on-user-click": emitUserClick,
1209
+ "hide-organization": __props.splitOrganization,
1210
+ "hide-avatar": showAvatarInOrganization.value
1211
+ }, null, 8, ["user", "row", "row-index", "ranklist", "markers", "theme", "hide-organization", "hide-avatar"])
973
1212
  ]),
974
- createElementVNode("td", _hoisted_5, toDisplayString(row.score.value), 1),
975
- showTimeColumn.value ? (openBlock(), createElementBlock("td", _hoisted_6, toDisplayString(row.score.time ? unref(formatTimeDuration)(row.score.time, "min", Math.floor) : "-"), 1)) : createCommentVNode("", true),
1213
+ createElementVNode("td", _hoisted_14, toDisplayString(row.score.value), 1),
1214
+ showTimeColumn.value ? (openBlock(), createElementBlock("td", _hoisted_15, toDisplayString(row.score.time ? unref(formatTimeDuration)(row.score.time, "min", Math.floor) : "-"), 1)) : createCommentVNode("", true),
976
1215
  (openBlock(true), createElementBlock(Fragment, null, renderList(row.statuses, (status, problemIndex) => {
977
1216
  var _a;
978
1217
  return renderSlot(_ctx.$slots, "status-cell", mergeProps({
@@ -987,6 +1226,9 @@ const _sfc_main = defineComponent({
987
1226
  rowIndex,
988
1227
  ranklist: __props.data,
989
1228
  solutions: getStatusSolutions(status),
1229
+ statusCellPreset: __props.statusCellPreset,
1230
+ statusColorAsText: __props.statusColorAsText,
1231
+ emptyStatusPlaceholder: __props.emptyStatusPlaceholder,
990
1232
  onClick: (event) => emitSolutionClick(row, rowIndex, status, problemIndex, event)
991
1233
  }), () => [
992
1234
  createVNode(_sfc_main$2, {
@@ -997,13 +1239,76 @@ const _sfc_main = defineComponent({
997
1239
  row,
998
1240
  "row-index": rowIndex,
999
1241
  ranklist: __props.data,
1000
- "on-solution-click": emitSolutionClick
1001
- }, null, 8, ["status", "problem", "problem-index", "user", "row", "row-index", "ranklist"])
1242
+ "on-solution-click": emitSolutionClick,
1243
+ "status-cell-preset": __props.statusCellPreset,
1244
+ "status-color-as-text": __props.statusColorAsText,
1245
+ "empty-status-placeholder": __props.emptyStatusPlaceholder
1246
+ }, null, 8, ["status", "problem", "problem-index", "user", "row", "row-index", "ranklist", "status-cell-preset", "status-color-as-text", "empty-status-placeholder"])
1002
1247
  ]);
1003
- }), 128))
1248
+ }), 128)),
1249
+ __props.showDirtColumn ? (openBlock(), createElementBlock("td", _hoisted_16, toDisplayString(unref(calculateDirtPercentage)(row)), 1)) : createCommentVNode("", true),
1250
+ __props.showSEColumn ? (openBlock(), createElementBlock("td", _hoisted_17, toDisplayString(unref(calculateSEValue)(row, problemStatistics.value)), 1)) : createCommentVNode("", true)
1004
1251
  ]);
1005
1252
  }), 128))
1006
- ])
1253
+ ]),
1254
+ __props.showProblemStatisticsFooter ? (openBlock(), createElementBlock("tfoot", _hoisted_18, [
1255
+ (openBlock(), createElementBlock(Fragment, null, renderList(problemStatisticsFooterRows, (footerRow) => {
1256
+ return createElementVNode("tr", {
1257
+ key: footerRow.key,
1258
+ class: "srk-problem-statistics-footer-row"
1259
+ }, [
1260
+ createElementVNode("td", {
1261
+ class: "srk-problem-statistics-footer-labels srk--text-right srk--nowrap",
1262
+ colspan: leftFooterColumnCount.value
1263
+ }, [
1264
+ createElementVNode("span", {
1265
+ class: "srk-problem-statistics-footer-label srk--c-tooltip",
1266
+ "data-tooltip": footerRow.tooltip
1267
+ }, toDisplayString(footerRow.label), 9, _hoisted_20)
1268
+ ], 8, _hoisted_19),
1269
+ (openBlock(true), createElementBlock(Fragment, null, renderList(problemStatistics.value, (stat, problemIndex) => {
1270
+ var _a;
1271
+ return openBlock(), createElementBlock("td", {
1272
+ key: ((_a = __props.data.problems[problemIndex]) == null ? void 0 : _a.alias) || problemIndex,
1273
+ class: "srk-problem-statistics-footer-cell srk--text-center srk--nowrap"
1274
+ }, [
1275
+ createElementVNode("span", _hoisted_21, toDisplayString(getProblemStatisticsFooterCellPrimary(footerRow.key, stat)), 1),
1276
+ getProblemStatisticsFooterCellSecondary(footerRow.key, stat) !== void 0 ? (openBlock(), createElementBlock(Fragment, { key: 0 }, [
1277
+ _cache[0] || (_cache[0] = createTextVNode(toDisplayString(" ") + " ", -1)),
1278
+ createElementVNode("span", _hoisted_22, toDisplayString(getProblemStatisticsFooterCellSecondary(footerRow.key, stat)), 1)
1279
+ ], 64)) : createCommentVNode("", true)
1280
+ ]);
1281
+ }), 128)),
1282
+ __props.showDirtColumn ? (openBlock(), createElementBlock("td", _hoisted_23, [..._cache[1] || (_cache[1] = [
1283
+ createElementVNode("span", { class: "srk-problem-statistics-footer-primary" }, null, -1)
1284
+ ])])) : createCommentVNode("", true),
1285
+ __props.showSEColumn ? (openBlock(), createElementBlock("td", _hoisted_24, [..._cache[2] || (_cache[2] = [
1286
+ createElementVNode("span", { class: "srk-problem-statistics-footer-primary" }, null, -1)
1287
+ ])])) : createCommentVNode("", true)
1288
+ ]);
1289
+ }), 64)),
1290
+ createElementVNode("tr", _hoisted_25, [
1291
+ createElementVNode("td", {
1292
+ class: "srk-problem-statistics-footer-labels srk--text-right srk--nowrap",
1293
+ colspan: leftFooterColumnCount.value
1294
+ }, null, 8, _hoisted_26),
1295
+ (openBlock(true), createElementBlock(Fragment, null, renderList(__props.data.problems, (problem, problemIndex) => {
1296
+ return openBlock(), createElementBlock("td", {
1297
+ key: problem.alias || unref(resolveText)(problem.title) || problemIndex,
1298
+ class: "srk-problem-statistics-footer-cell srk-problem-statistics-footer-problem-header srk-problem-header srk--text-center srk--nowrap",
1299
+ style: normalizeStyle({ backgroundImage: unref(getProblemHeaderBackgroundImage)(problem.style, resolvedTheme.value, 0) })
1300
+ }, [
1301
+ createElementVNode("span", _hoisted_27, toDisplayString(problem.alias || unref(numberToAlphabet)(problemIndex)), 1)
1302
+ ], 4);
1303
+ }), 128)),
1304
+ __props.showDirtColumn ? (openBlock(), createElementBlock("td", _hoisted_28, [..._cache[3] || (_cache[3] = [
1305
+ createElementVNode("span", { class: "srk-problem-statistics-footer-primary" }, null, -1)
1306
+ ])])) : createCommentVNode("", true),
1307
+ __props.showSEColumn ? (openBlock(), createElementBlock("td", _hoisted_29, [..._cache[4] || (_cache[4] = [
1308
+ createElementVNode("span", { class: "srk-problem-statistics-footer-primary" }, null, -1)
1309
+ ])])) : createCommentVNode("", true)
1310
+ ])
1311
+ ])) : createCommentVNode("", true)
1007
1312
  ], 2)
1008
1313
  ]));
1009
1314
  };