mediacube-ui 0.1.365 → 0.1.367

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,10 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4
4
 
5
+ ### [0.1.367](https://github.com/MediaCubeCo/mcui/compare/v0.1.366...v0.1.367) (2025-03-24)
6
+
7
+ ### [0.1.366](https://github.com/MediaCubeCo/mcui/compare/v0.1.365...v0.1.366) (2025-03-18)
8
+
5
9
  ### [0.1.365](https://github.com/MediaCubeCo/mcui/compare/v0.1.364...v0.1.365) (2025-03-17)
6
10
 
7
11
  ### [0.1.364](https://github.com/MediaCubeCo/mcui/compare/v0.1.363...v0.1.364) (2025-03-10)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "mediacube-ui",
3
- "version": "0.1.365",
3
+ "version": "0.1.367",
4
4
  "description": "Design system for Mediacube services",
5
5
  "author": "Mediacube",
6
6
  "private": false,
@@ -126,10 +126,9 @@ export default {
126
126
  },
127
127
  commentWithLinks() {
128
128
  const regExp = /((http|https):\/\/)?(([0-9a-zA-Zа-яА-Я.-]*)\.([a-zA-Zа-яА-Я]+[^\s,.;:'"\])]+)(\/[^ ,.;\/\])]*)?)/gi
129
- if (/\.(jpg|jpeg|png|svg|pdf|csv|webp|doc|docx)$/i.test(match)) {
130
- return match
131
- }
132
129
  return this.comment.content.replace(regExp, match => {
130
+ // Проверяем, является ли match файлом
131
+ if (/\.(jpg|jpeg|png|svg|pdf|csv|webp|doc|docx)$/i.test(match)) return match
133
132
  const url = /^http/.test(match) ? match : `http://${match}`
134
133
  return `<a class="mc-chat-comment__link" href='${url}' target="_blank">${match.trim()}</a>`
135
134
  })
@@ -23,10 +23,10 @@
23
23
  <component
24
24
  :is="tag"
25
25
  v-bind="attrs"
26
+ :empty-render="{ name: 'noData' }"
26
27
  v-on="{ ...$listeners, 'sort-change': handleSort }"
27
- @scroll="handleScroll"
28
28
  @context-menu-click="contextMenuClickEvent"
29
- :empty-render="{ name: 'noData' }"
29
+ @scroll="handleScroll"
30
30
  >
31
31
  <!-- @slot Слот дочерних mc-table-col -->
32
32
  <slot />
@@ -63,6 +63,7 @@ import McTitle from '../../../elements/McTitle/McTitle'
63
63
  import McSvgIcon from '../../../elements/McSvgIcon/McSvgIcon'
64
64
  import McTableCol from '../McTableCol/McTableCol'
65
65
  import McOverlay from '../../McOverlay/McOverlay.vue'
66
+ import McInfinityLoadingIndicator from 'mediacube-ui/src/elements/McInfinityLoadingIndicator/McInfinityLoadingIndicator.vue'
66
67
 
67
68
  /**
68
69
  * More info: https://xuliangzhan.com/vxe-table, https://xuliangzhan.github.io/vxe-table
@@ -70,6 +71,7 @@ import McOverlay from '../../McOverlay/McOverlay.vue'
70
71
  export default {
71
72
  name: 'McTable',
72
73
  components: {
74
+ McInfinityLoadingIndicator,
73
75
  McTitle,
74
76
  McSvgIcon,
75
77
  McTableCol,
@@ -106,6 +108,14 @@ export default {
106
108
  type: Boolean,
107
109
  default: false,
108
110
  },
111
+ fixedFirstColumn: {
112
+ type: Boolean,
113
+ default: false,
114
+ },
115
+ fixedLastColumn: {
116
+ type: Boolean,
117
+ default: false,
118
+ },
109
119
  /**
110
120
  * Тип таблицы:
111
121
  * `table, grid`
@@ -277,6 +287,8 @@ export default {
277
287
  firstColsWidth: 253,
278
288
  hasHorizontalScroll: false,
279
289
  scrollIsBottom: false,
290
+ tableBodyScrollLeft: false,
291
+ tableBodyScrollRight: true,
280
292
  }
281
293
  },
282
294
  computed: {
@@ -286,10 +298,12 @@ export default {
286
298
  attrs() {
287
299
  const attrs = {
288
300
  ref: 'xTable',
301
+ data: this.items,
302
+ 'merge-cells': this.mergeCells,
289
303
  'context-menu': this.tableMenu,
290
304
  class: this.classes,
291
305
  'sync-resize': this.cardIsOpen,
292
- 'scroll-y': this.scrollY,
306
+ 'scroll-y': { ...this.scrollY, offset: 30, mode: 'slide' },
293
307
  'show-footer': this.canShowFooter,
294
308
  'footer-method': this.footerMethod,
295
309
  'sort-config': {
@@ -302,6 +316,7 @@ export default {
302
316
  theme: 'mcui-black',
303
317
  },
304
318
  'row-id': 'id',
319
+ 'key-field': 'id',
305
320
  'highlight-hover-row': !this.skeletonLoad,
306
321
  'highlight-current-row': true,
307
322
  'show-header-overflow': 'tooltip',
@@ -338,6 +353,10 @@ export default {
338
353
  'mc-table--clickable': this.$listeners['cell-click'],
339
354
  'mc-table--header-break-word': this.headerBreakWord,
340
355
  'mc-table--mono-font': this.monoFont,
356
+ 'mc-table--fixed-first-col': this.fixedFirstColumn,
357
+ 'mc-table--fixed-last-col': this.fixedLastColumn,
358
+ 'mc-table--scrolled-left-x-axis': !!this.tableBodyScrollLeft,
359
+ 'mc-table--scrolled-right-x-axis': !!this.tableBodyScrollRight,
341
360
  }
342
361
  },
343
362
  wrapperStyles() {
@@ -380,27 +399,6 @@ export default {
380
399
  },
381
400
  },
382
401
  watch: {
383
- canShowFooter(newValue) {
384
- newValue && this.updateData()
385
- },
386
- totalFooter: {
387
- handler: async function(newVal) {
388
- newVal && (await this.loadData(true))
389
- },
390
- deep: true,
391
- },
392
- items: {
393
- handler: async function(newVal, oldVal) {
394
- if (_isEqual(newVal, oldVal)) return
395
- if (newVal.length !== oldVal.length) {
396
- newVal && (await this.loadData(true))
397
- } else {
398
- newVal && (await this.setFirstColsWidth())
399
- await this.reloadData()
400
- }
401
- },
402
- deep: true,
403
- },
404
402
  cardIsOpen(newVal) {
405
403
  this.toggleColumns(newVal)
406
404
  },
@@ -409,8 +407,6 @@ export default {
409
407
  },
410
408
  },
411
409
  mounted() {
412
- this.loadData()
413
- !this.scrollable && this.createObserver()
414
410
  this.setFirstColsWidth()
415
411
  window.addEventListener('resize', this.checkHorizontalScroll)
416
412
  },
@@ -419,34 +415,6 @@ export default {
419
415
  window.removeEventListener('resize', this.checkHorizontalScroll)
420
416
  },
421
417
  methods: {
422
- async loadData(force = false) {
423
- if ((this.items && this.items.length) || force) {
424
- await this.$refs.xTable.loadData(this.items)
425
- !this.scrollable && this.setObserveElement()
426
- this.hasMore && this.checkOccupancy()
427
- // После обновления данных в таблице обязательно мержим ячейки, если они указаны
428
- if (this.mergeCells?.length) this.$refs.xTable.setMergeCells(this.mergeCells)
429
- }
430
- },
431
- async reloadData() {
432
- // Доастаем отсортированную колонку и выполняем сортировку вручную, чтобы предотвратить сброс на релоаде
433
- const [sortState] = this.$refs.xTable.getSortColumns() || []
434
- await this.$refs.xTable.reloadData(this.items)
435
- if (sortState) {
436
- this.$refs.xTable.sort(sortState.property, sortState.order)
437
- }
438
- },
439
- async updateData() {
440
- await this.$refs.xTable.updateData()
441
- },
442
- checkOccupancy() {
443
- if (!this.$refs.xTable || !this.items?.length) return
444
- const tableHeight = this.$refs.xTable.$el.getBoundingClientRect().height
445
- const tableDataHeight = this.$refs.xTable.rowHeight * this.items.length
446
- if (tableHeight >= tableDataHeight) {
447
- this.load()
448
- }
449
- },
450
418
  formattedNumber(value, decimals = 2, is_rtl = false) {
451
419
  if (value == null) return null
452
420
 
@@ -473,14 +441,6 @@ export default {
473
441
  }),
474
442
  ]
475
443
  },
476
- handleScroll: _throttle(function({ scrollTop, $event, type, isY, $table }) {
477
- const bottomPos = Math.ceil($event.target.scrollHeight - $event.target.clientHeight)
478
- const isLoadArea = bottomPos - scrollTop <= $table._data.rowHeight * this.rowsToStartLoad
479
- this.scrollIsBottom = scrollTop / bottomPos > 0.95
480
- if (isLoadArea && !this.$attrs.loading && this.hasMore && type === 'body' && isY) {
481
- this.load()
482
- }
483
- }, 200),
484
444
  load() {
485
445
  /**
486
446
  * Событие по подгрузке данных
@@ -488,22 +448,24 @@ export default {
488
448
  */
489
449
  this.$emit('load')
490
450
  },
491
- createObserver() {
492
- this.observer = new IntersectionObserver(
493
- entries => {
494
- const entry = entries[0]
495
- if (entry.isIntersecting) {
496
- this.load()
497
- }
498
- },
499
- { threshold: 0.1 },
500
- )
501
- this.setObserveElement()
502
- },
503
- setObserveElement() {
504
- const loader = this.$refs.xTable.$el.getElementsByClassName('mc-table-col__loader')
505
- this.observer && loader.length && this.observer.observe(loader[0])
451
+ handleScroll({ $event, type, isY, isX }) {
452
+ if (type === 'body' && isX) {
453
+ this.tableBodyScrollLeft = !!$event.target.scrollLeft
454
+ this.tableBodyScrollRight =
455
+ $event.target.scrollLeft + $event.target.clientWidth < $event.target.scrollWidth
456
+ }
457
+ if (type === 'body' && isY) {
458
+ this.checkVerticalScroll(...arguments)
459
+ }
506
460
  },
461
+ checkVerticalScroll: _throttle(function({ scrollTop, $event, type, isY, isX, $table }) {
462
+ const bottomPos = Math.ceil($event.target.scrollHeight - $event.target.clientHeight)
463
+ const isLoadArea = bottomPos - scrollTop <= $table._data.rowHeight * this.rowsToStartLoad
464
+ this.scrollIsBottom = scrollTop / bottomPos > 0.95
465
+ if (isLoadArea && !this.$attrs.loading && this.hasMore) {
466
+ this.load()
467
+ }
468
+ }, 200),
507
469
  setFirstColsWidth() {
508
470
  const columns = this.$refs.xTable.getColumns()
509
471
  const leftFixedColumnsWidth = columns.reduce((sum, curr) => {
@@ -525,14 +487,16 @@ export default {
525
487
  toggleColumns(val) {
526
488
  if (val) {
527
489
  const columns = this.$refs.xTable.getColumns()
528
- const hideColumns = columns.filter(col => col.fixed !== 'left')
490
+ const hideColumns = this.fixedFirstColumn
491
+ ? columns.filter((c, i) => !!i)
492
+ : columns.filter(col => col.fixed !== 'left')
529
493
  hideColumns.forEach(col => (col.visible = false))
530
494
  this.$refs.xTable.refreshColumn()
531
495
  } else {
532
496
  this.$refs.xTable.resetColumn()
533
497
  }
534
- this.$refs.xTable.recalculate()
535
- this.$refs.xTable.syncData() // Синхронит данные таблиц (фикс колонка === отдельная таблица)
498
+ // this.$refs.xTable.recalculate()
499
+ // this.$refs.xTable.syncData() // Синхронит данные таблиц (фикс колонка === отдельная таблица)
536
500
  this.checkHorizontalScroll()
537
501
  },
538
502
  getFixedHeight(val) {
@@ -592,6 +556,7 @@ export default {
592
556
  @import '../../../styles/mixins';
593
557
  @import '../../../tokens/font-families';
594
558
  @import '../../../tokens/animations';
559
+ @import '../../../tokens/z-indexes';
595
560
 
596
561
  @import '~vxe-table/styles/variable.scss';
597
562
 
@@ -601,10 +566,12 @@ export default {
601
566
 
602
567
  .vxe-table {
603
568
  font-family: $font-family-main;
569
+
604
570
  &--tooltip-wrapper {
605
571
  .vxe-table--tooltip-content {
606
572
  white-space: normal;
607
573
  }
574
+
608
575
  &.theme--mcui-black {
609
576
  background: $color-black;
610
577
  color: $color-white;
@@ -617,26 +584,39 @@ export default {
617
584
  padding: $space-100 $space-150;
618
585
  }
619
586
  }
587
+
620
588
  .vxe-body--row.row--cheched {
621
589
  background-color: var(--color-main-alpha-10);
622
590
  }
591
+
623
592
  .fixed-left--wrapper {
624
593
  scrollbar-width: none;
625
594
  }
595
+
596
+ &--empty-block {
597
+ display: block !important;
598
+ height: 1px;
599
+ min-height: 1px !important;
600
+ }
626
601
  }
602
+
627
603
  .mc-table-wrapper {
628
604
  position: relative;
605
+
629
606
  &__footer {
630
607
  @include position(absolute, null 0 0 0);
631
- z-index: 2;
608
+ z-index: 3;
609
+
632
610
  &--indent-bottom {
633
611
  bottom: 5px;
634
612
  }
635
613
  }
614
+
636
615
  &__tint {
637
616
  height: $size-900;
638
617
  background: linear-gradient(0deg, $color-white 0%, rgba(255, 255, 255, 0) 100%);
639
618
  }
619
+
640
620
  &__loading {
641
621
  display: flex;
642
622
  align-items: center;
@@ -645,13 +625,16 @@ export default {
645
625
  background-color: $color-white;
646
626
  color: $color-outline-gray;
647
627
  @include child-indent-right($space-100);
628
+
648
629
  .mc-title {
649
630
  width: auto;
650
631
  }
651
632
  }
633
+
652
634
  &__load-icon {
653
635
  animation: $animation-spinner;
654
636
  }
637
+
655
638
  .skeleton-load {
656
639
  &-wrapper {
657
640
  display: flex;
@@ -659,7 +642,7 @@ export default {
659
642
  max-width: 100%;
660
643
  position: absolute;
661
644
  height: 100%;
662
- z-index: 19;
645
+ z-index: $z-index-modal;
663
646
  background-color: $color-white;
664
647
  user-select: none;
665
648
  }
@@ -674,11 +657,13 @@ export default {
674
657
  padding: $space-50 0;
675
658
  }
676
659
  }
660
+
677
661
  .vxe-body--row {
678
662
  font-feature-settings: 'tnum';
679
663
  font-variant-numeric: tabular-nums;
680
664
  }
681
665
  }
666
+
682
667
  .vxe-table--footer {
683
668
  .vxe-footer--row {
684
669
  font-feature-settings: 'tnum';
@@ -686,16 +671,121 @@ export default {
686
671
  }
687
672
  }
688
673
  }
674
+
675
+ &--fixed-first-col {
676
+ .vxe-header--row,
677
+ .vxe-body--row,
678
+ .vxe-footer--row {
679
+ td:first-child,
680
+ th:first-child {
681
+ position: sticky;
682
+ left: 0;
683
+ background-color: white;
684
+ z-index: 3;
685
+ }
686
+ }
687
+
688
+ .vxe-footer--row {
689
+ td {
690
+ border-block-start: 1px solid $color-hover-gray;
691
+ }
692
+ }
693
+ }
694
+
695
+ &--fixed-last-col {
696
+ .vxe-header--row,
697
+ .vxe-body--row,
698
+ .vxe-footer--row {
699
+ td:last-child,
700
+ th:last-child {
701
+ position: sticky;
702
+ right: 0;
703
+ background-color: white;
704
+ z-index: 3;
705
+
706
+ &:empty {
707
+ display: none;
708
+ }
709
+ }
710
+ }
711
+
712
+ .vxe-footer--row {
713
+ td {
714
+ border-block-start: 1px solid $color-hover-gray;
715
+ }
716
+ }
717
+ }
718
+
719
+ &--scrolled-left-x-axis {
720
+ &.mc-table--fixed-first-col {
721
+ .vxe-header--row,
722
+ .vxe-body--row,
723
+ .vxe-footer--row {
724
+ td:first-child,
725
+ th:first-child {
726
+ &::after {
727
+ content: '';
728
+ position: absolute;
729
+ top: 0;
730
+ left: 100%;
731
+ width: 12px;
732
+ height: 100%;
733
+ background: linear-gradient(to left, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.12) 100%);
734
+ }
735
+ }
736
+ }
737
+ }
738
+ }
739
+
740
+ &--scrolled-right-x-axis {
741
+ &.mc-table--fixed-last-col {
742
+ .vxe-header--row,
743
+ .vxe-body--row,
744
+ .vxe-footer--row {
745
+ td:last-child,
746
+ th:last-child {
747
+ &::after {
748
+ content: '';
749
+ position: absolute;
750
+ top: 0;
751
+ right: 100%;
752
+ width: 12px;
753
+ height: 100%;
754
+ background: linear-gradient(to right, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.12) 100%);
755
+ }
756
+ }
757
+ }
758
+ }
759
+ }
760
+
761
+ .vxe-body--row {
762
+ &.row--current {
763
+ td,
764
+ th {
765
+ background-color: color-mix(in srgb, var(--color-main) 10%, #fff 90%) !important;
766
+ }
767
+ }
768
+
769
+ &:hover {
770
+ td,
771
+ th {
772
+ background-color: $color-hover-gray;
773
+ }
774
+ }
775
+ }
776
+
689
777
  &--open-card {
690
778
  .vxe-table--body-wrapper,
691
779
  .vxe-table--footer-wrapper {
692
780
  overflow-x: hidden;
693
781
  width: fit-content;
694
782
  }
783
+
695
784
  .vxe-table--footer {
696
785
  display: none;
697
786
  }
698
787
  }
788
+
699
789
  &--clickable {
700
790
  .vxe-table--body {
701
791
  .vxe-body--row {
@@ -703,6 +793,7 @@ export default {
703
793
  }
704
794
  }
705
795
  }
796
+
706
797
  &--header-break-word {
707
798
  .vxe-header--column {
708
799
  .vxe-cell--title {
@@ -713,12 +804,15 @@ export default {
713
804
  }
714
805
  }
715
806
  }
807
+
716
808
  &__context-menu {
717
809
  width: 250px;
810
+
718
811
  .vxe-context-menu--link {
719
812
  width: 100%;
720
813
  }
721
814
  }
815
+
722
816
  .vxe-header--row {
723
817
  .col--checkbox {
724
818
  .vxe-cell {
@@ -728,13 +822,16 @@ export default {
728
822
  }
729
823
  }
730
824
  }
825
+
731
826
  .vxe-cell--checkbox {
732
827
  z-index: 1;
828
+
733
829
  &:hover {
734
830
  .vxe-checkbox--icon::before {
735
831
  border-color: var(--color-main) !important;
736
832
  }
737
833
  }
834
+
738
835
  &.is--checked,
739
836
  &.is--indeterminate {
740
837
  .vxe-checkbox--icon::before {
@@ -743,6 +840,7 @@ export default {
743
840
  }
744
841
  }
745
842
  }
843
+
746
844
  .vxe-header--column {
747
845
  .vxe-cell {
748
846
  &--title {
@@ -750,22 +848,31 @@ export default {
750
848
  align-items: center;
751
849
  }
752
850
  }
851
+
753
852
  &.is--sortable {
754
853
  cursor: pointer;
755
854
  }
756
855
  }
856
+
757
857
  .vxe-table--footer {
758
858
  border-bottom: 1px solid $color-hover-gray;
859
+
860
+ &-wrapper {
861
+ border: none;
862
+ }
759
863
  }
864
+
760
865
  .vxe-cell {
761
866
  padding-inline-start: $space-200;
762
867
  padding-inline-end: $space-200;
763
868
  word-break: break-word;
869
+
764
870
  &--checkbox {
765
871
  display: flex;
766
872
  align-items: center;
767
873
  max-width: 100%;
768
874
  padding-inline-start: 1.8em;
875
+
769
876
  .vxe-checkbox--icon {
770
877
  margin-inline-end: $space-50;
771
878
  top: 50%;
@@ -773,8 +880,10 @@ export default {
773
880
  }
774
881
  }
775
882
  }
883
+
776
884
  @include custom-scroll();
777
885
  }
886
+
778
887
  @mixin gradient() {
779
888
  background: $color-hover-gray;
780
889
  background-image: -webkit-gradient(
@@ -803,6 +912,7 @@ export default {
803
912
  margin: 0 auto;
804
913
  width: 100%;
805
914
  overflow: hidden;
915
+
806
916
  &:after {
807
917
  content: '';
808
918
  position: absolute;
@@ -811,12 +921,14 @@ export default {
811
921
  }
812
922
  }
813
923
  }
924
+
814
925
  .loader {
815
926
  width: 100%;
816
927
  display: flex;
817
928
  align-items: center;
818
929
  height: $space-500;
819
930
  padding: $space-100 $space-200;
931
+
820
932
  .avatar {
821
933
  display: block;
822
934
  float: left;
@@ -827,12 +939,14 @@ export default {
827
939
  margin-inline-end: $space-50;
828
940
  @include gradient();
829
941
  }
942
+
830
943
  .preview-content {
831
944
  display: flex;
832
945
  flex-direction: column;
833
946
  width: 100%;
834
947
  @include child-indent-bottom($space-50);
835
948
  }
949
+
836
950
  .line {
837
951
  display: block;
838
952
  position: relative;
@@ -840,6 +954,7 @@ export default {
840
954
  width: 100%;
841
955
  @include gradient();
842
956
  }
957
+
843
958
  &--more-height {
844
959
  .line {
845
960
  height: 12px;
@@ -244,6 +244,9 @@ export default {
244
244
  width: $size-300;
245
245
  background: linear-gradient(90deg, hsla(0, 0%, 100%, 0) 0, $color-white);
246
246
  }
247
+ &:empty {
248
+ display: none;
249
+ }
247
250
  }
248
251
  &__header-right {
249
252
  @extend .mc-table-col__right;