@c8y/style 1023.48.2 → 1023.50.2

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.
Binary file
@@ -0,0 +1,63 @@
1
+ ### New Asset Table Widget
2
+
3
+  
4
+
5
+ We're excited to introduce the **next-generation Asset Table Widget** for the Cumulocity IoT platform — delivering a more powerful, flexible, and visually refined data grid experience.
6
+ This new widget provides deeper insights into your assets, enables advanced filtering and sorting options, and introduces a smarter configuration workflow — all while maintaining backward compatibility.
7
+
8
+ <div class="p-16 m-auto col-lg-max">
9
+ <img src="./c8y-style-assets/asset-table-pr.png" alt="Asset Table Widget" class="border-all fit-w">
10
+ </div>
11
+
12
+ &nbsp;
13
+
14
+ ### Key features
15
+
16
+ &nbsp;
17
+
18
+ #### Enhanced visualization
19
+
20
+ ✅ **Modern data grid**: Experience a refreshed, responsive grid layout optimized for large datasets and improved readability.\
21
+ ✅ **Dynamic column management**: Choose exactly which fields to display, reorder them, and adjust widths intuitively.\
22
+ ✅ **Adaptive display options**: Switch between compact and detailed views to match your monitoring needs.
23
+
24
+ &nbsp;
25
+
26
+ #### Powerful filtering & sorting
27
+
28
+ ✅ **Column-based filtering**: Apply precise filters directly on any column with support for text, number, date, and boolean types.\
29
+ ✅ **Advanced date filters**: Use “from” and “to” date pickers for time-based filtering — with automatic `.date` mapping for Cumulocity fields.\
30
+ ✅ **Multi-level sorting**: Sort by one or multiple columns for detailed data analysis.
31
+
32
+ &nbsp;
33
+
34
+ #### Double-filtering mode
35
+
36
+ ✅ **Config-level filtering**: Define default filters in the configuration screen — perfect for pre-filtering large asset sets.\
37
+ ✅ **Runtime filtering**: Apply additional filters directly in the view without losing your preconfigured defaults.\
38
+ ✅ **Combined logic**: Both layers work together seamlessly, so you can refine results on the fly while preserving your configuration baseline.
39
+
40
+ &nbsp;
41
+
42
+ #### Improved customization
43
+
44
+ ✅ **Extended display options**: Tailor how your grid looks and behaves — including pagination, column visibility, and layout density.\
45
+ ✅ **Custom column types**: Easily add new column renderers, such as date, status, or icon-based representations.\
46
+ ✅ **Persistent preferences**: User-selected display and filter settings can be retained between sessions.
47
+
48
+ &nbsp;
49
+
50
+ #### Developer & admin experience
51
+
52
+ ✅ **Reusable configuration model**: Designed to integrate cleanly with the widget configuration framework.\
53
+ ✅ **Modular filtering system**: Easily extend or replace filtering logic for advanced use cases.\
54
+ ✅ **Backward compatible**: Existing configurations continue to work out of the box with no migration effort required.
55
+
56
+ &nbsp;
57
+
58
+ The new **Asset Table Widget** offers a more interactive and efficient way to explore your device and asset data.
59
+ We invite you to try it out, experiment with the new double-filtering feature, and experience the improved control and performance firsthand.
60
+
61
+ &nbsp;
62
+
63
+ ---
@@ -1,11 +1,11 @@
1
1
   
2
2
  &nbsp;
3
3
 
4
- ### 📊 Data Point Graph: Enhanced Visualization & Real-Time Insights
4
+ ### 📊 Data Graph: Enhanced Visualization & Real-Time Insights
5
5
 
6
6
   &nbsp;
7
7
 
8
- The Data Point Graph has been upgraded with new capabilities and expanded customization options, making it an even more powerful tool for visualizing and analyzing data trends. This enhancement ensures better performance, improved usability, and seamless integration with global time contexts.
8
+ The Data Graph has been upgraded with new capabilities and expanded customization options, making it an even more powerful tool for visualizing and analyzing data trends. This enhancement ensures better performance, improved usability, and seamless integration with global time contexts.
9
9
 
10
10
  With these improvements, users can effortlessly monitor alarms and events, fine-tune charts for precise analysis, and dynamically interact with their data, all within an intuitive interface.
11
11
 
@@ -69,7 +69,7 @@ These enhancements ensure users can navigate their data efficiently and gain dee
69
69
 
70
70
   &nbsp;
71
71
 
72
- This major upgrade to the Data Point Graph delivers:
72
+ This major upgrade to the Data Graph delivers:
73
73
 
74
74
   &nbsp;
75
75
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c8y/style",
3
- "version": "1023.48.2",
3
+ "version": "1023.50.2",
4
4
  "license": "Apache-2.0",
5
5
  "author": "Cumulocity GmbH",
6
6
  "description": "Styles for Cumulocity IoT applications",
@@ -1,8 +1,7 @@
1
-
2
- @import "../../../../variables/_dlt-c8y-icons-vars.less";
3
- @import "../../../animations/_component-animations.less";
4
- @import "../../../core/buttons/_buttons.less";
5
- @import "../../../mixins/_tab-focus.less";
1
+ @import '../../../../variables/_dlt-c8y-icons-vars.less';
2
+ @import '../../../animations/_component-animations.less';
3
+ @import '../../../core/buttons/_buttons.less';
4
+ @import '../../../mixins/_tab-focus.less';
6
5
 
7
6
  /**
8
7
  * C8Y List Group - Modern list component with flexible layouts
@@ -67,7 +66,7 @@
67
66
  &.highlighted {
68
67
  background-color: var(--brand-80, var(--c8y-brand-80));
69
68
  }
70
- &.selected{
69
+ &.selected {
71
70
  border-left: @size-4 solid @component-color-active;
72
71
  background-color: @component-background-default;
73
72
  }
@@ -77,14 +76,15 @@
77
76
  outline-offset: -2px;
78
77
  border-radius: @component-border-radius-focus !important;
79
78
  }
80
- bs-dropdown-container &, c8y-typeahead .dropdown &, .c8y-select-v2 .dropdown & {
79
+ bs-dropdown-container &,
80
+ c8y-typeahead .dropdown &,
81
+ .c8y-select-v2 .dropdown & {
81
82
  &.active,
82
83
  &.selectable:not(:has(c8y-li-checkbox)):active {
83
84
  color: @component-color-active;
84
85
 
85
86
  .c8y-list__item__body {
86
-
87
- &:after{
87
+ &:after {
88
88
  display: inline-block;
89
89
  text-transform: none;
90
90
  font-weight: normal;
@@ -96,7 +96,7 @@
96
96
  -moz-osx-font-smoothing: grayscale;
97
97
 
98
98
  float: right;
99
- content: @dlt-c8y-icon-check;
99
+ content: @dlt-c8y-icon-check;
100
100
  font-size: 18px;
101
101
  }
102
102
  }
@@ -106,7 +106,8 @@
106
106
  * @Carlos: There are items that are not selectable that
107
107
  * don't get that class. E.g. the "No results found" item.
108
108
  **/
109
- &.selectable:hover:not(.active), &.highlighted {
109
+ &.selectable:hover:not(.active),
110
+ &.highlighted {
110
111
  background-color: @component-background-hover;
111
112
  }
112
113
 
@@ -117,29 +118,29 @@
117
118
  }
118
119
  }
119
120
 
120
- &.selectable.active{
121
+ &.selectable.active {
121
122
  .c8y-list__item__body {
122
- &:after{
123
+ &:after {
123
124
  display: inline-block;
124
125
  text-transform: none;
125
126
  font-weight: normal;
126
127
  font-style: normal;
127
128
  font-variant: normal;
128
- font-family: "dlt-c8y-icons" !important;
129
+ font-family: 'dlt-c8y-icons' !important;
129
130
  line-height: 1;
130
131
  -webkit-font-smoothing: antialiased;
131
132
  -moz-osx-font-smoothing: grayscale;
132
133
 
133
134
  float: right;
134
- content: @dlt-c8y-icon-check;
135
+ content: @dlt-c8y-icon-check;
135
136
  }
136
137
  }
137
138
  color: @component-color-active;
138
139
  }
139
- &:not(.selectable){
140
+ &:not(.selectable) {
140
141
  transition: border-left 0.15s linear;
141
142
  }
142
- &.active:not(.selectable){
143
+ &.active:not(.selectable) {
143
144
  border-left: @size-4 solid @component-color-active;
144
145
  }
145
146
 
@@ -172,7 +173,7 @@
172
173
  }
173
174
  &--overflow-visible {
174
175
  .c8y-list__item__body {
175
- overflow: visible!important;
176
+ overflow: visible !important;
176
177
  }
177
178
  }
178
179
 
@@ -207,16 +208,15 @@
207
208
 
208
209
  // hide collapse-btn when displaying in a modal for instance
209
210
  &--no-expand {
210
- > div > .c8y-list__item__block > .c8y-list__item__actions >
211
- .collapse-btn {
211
+ > div > .c8y-list__item__block > .c8y-list__item__actions > .collapse-btn {
212
212
  display: none;
213
213
  pointer-events: none;
214
214
  }
215
215
  }
216
- &__btn{
216
+ &__btn {
217
217
  .btn-clean();
218
218
  white-space: normal;
219
- &:focus{
219
+ &:focus {
220
220
  outline: none;
221
221
  }
222
222
  }
@@ -235,7 +235,6 @@
235
235
  }
236
236
  }
237
237
 
238
-
239
238
  &--pulse {
240
239
  .component-pulse();
241
240
  }
@@ -283,16 +282,19 @@ c8y-load-more.c8y-list__item {
283
282
  background-color: inherit;
284
283
  }
285
284
 
286
- c8y-li-drag-handle, c8y-list-item-drag-handle {
285
+ c8y-li-drag-handle,
286
+ c8y-list-item-drag-handle {
287
287
  display: flex;
288
288
  align-items: center;
289
289
  align-self: stretch;
290
290
  flex-shrink: 0;
291
291
  max-width: 0;
292
+ padding-left: @margin-4;
292
293
  overflow: hidden;
293
294
  transition: all 0.25s ease;
294
295
 
295
- c8y-li-drag-handle, c8y-list-item-drag-handle {
296
+ c8y-li-drag-handle,
297
+ c8y-list-item-drag-handle {
296
298
  padding: 0 !important;
297
299
  cursor: move;
298
300
  max-width: fit-content !important;
@@ -306,7 +308,7 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
306
308
  }
307
309
  }
308
310
 
309
- + c8y-li-checkbox{
311
+ + c8y-li-checkbox {
310
312
  padding-left: 0;
311
313
  }
312
314
  .cdk-drag-disabled & {
@@ -322,7 +324,7 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
322
324
  }
323
325
 
324
326
  .no-card-context {
325
- .c8y-list__item{
327
+ .c8y-list__item {
326
328
  c8y-li-drag-handle:not(.cdk-drag-disabled) + * {
327
329
  padding-left: 0;
328
330
  }
@@ -333,15 +335,14 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
333
335
  }
334
336
  }
335
337
 
336
- .c8y-list__item:hover {
338
+ .c8y-list__item:not(:has(.c8y-list__item)):hover {
337
339
  c8y-li-drag-handle:not(:empty) {
338
- max-width: 100px;
339
- padding-left: @size-8;
340
+ // max-width: 16px;
341
+ overflow: visible;
340
342
  }
341
343
 
342
344
  c8y-list-item-drag-handle:not(:empty) {
343
- max-width: 100px;
344
- padding-left: @size-8;
345
+ overflow: visible;
345
346
  }
346
347
  }
347
348
 
@@ -402,7 +403,9 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
402
403
  .c8y-list__item__colorpicker,
403
404
  .c8y-list__item__actions {
404
405
  min-height: 56px;
405
- bs-dropdown-container &, c8y-typeahead .dropdown &, .c8y-list__item--dense & {
406
+ bs-dropdown-container &,
407
+ c8y-typeahead .dropdown &,
408
+ .c8y-list__item--dense & {
406
409
  min-height: 36px;
407
410
  padding-top: @size-base;
408
411
  padding-bottom: @size-base;
@@ -416,11 +419,11 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
416
419
  * @Carlos: Would be nice to not only have the dense class
417
420
  * pm the list but also on the list items if [dense] is set.
418
421
  **/
419
- .dropdown-menu &, .c8y-list__item--dense & {
422
+ .dropdown-menu &,
423
+ .c8y-list__item--dense & {
420
424
  padding-top: @size-base;
421
425
  padding-bottom: @size-base;
422
426
  }
423
-
424
427
  }
425
428
 
426
429
  .card,
@@ -437,14 +440,14 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
437
440
  padding-bottom: 7px;
438
441
  }
439
442
 
440
- .c8y-list__item__actions {
441
- padding-top: 0;
442
- padding-bottom: 0;
443
- }
444
-
445
443
  .c8y-list__item__body {
446
- padding-top: @size-10;
447
- padding-bottom: @size-10;
444
+ padding-top: 10px;
445
+ padding-bottom: 10px;
446
+ &:has(.btn, .c8y-dropdown) {
447
+ padding-top: 6px;
448
+ padding-bottom: 6px;
449
+ overflow: visible !important;
450
+ }
448
451
  }
449
452
  }
450
453
 
@@ -518,7 +521,7 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
518
521
  > * {
519
522
  padding: 0.5rem 0 0 0;
520
523
  }
521
- > c8y-li-footer{
524
+ > c8y-li-footer {
522
525
  width: 100%;
523
526
  }
524
527
  }
@@ -532,7 +535,7 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
532
535
  @media (min-width: @screen-md-min) {
533
536
  padding: @component-padding calc(@size-48 + 6px) 2rem;
534
537
  }
535
- .full-w-collapse &{
538
+ .full-w-collapse & {
536
539
  padding: @component-padding;
537
540
  }
538
541
  }
@@ -547,17 +550,17 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
547
550
  }
548
551
  }
549
552
 
550
- .c8y-list__item--sticky-top{
551
- .c8y-list__item__block{
553
+ .c8y-list__item--sticky-top {
554
+ .c8y-list__item__block {
552
555
  position: sticky;
553
556
  top: 0;
554
557
  z-index: 10;
555
558
  background-color: inherit;
556
- &:has(.dropdown.open){
559
+ &:has(.dropdown.open) {
557
560
  z-index: 11;
558
561
  }
559
562
  }
560
- .c8y-list__item__collapse--container{
563
+ .c8y-list__item__collapse--container {
561
564
  position: relative;
562
565
  z-index: 8;
563
566
  }
@@ -567,7 +570,7 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
567
570
  .c8y-list--timeline {
568
571
  box-shadow: none;
569
572
  // --c8y-component-background-default: @palette-high;
570
- >.c8y-list--timeline__item {
573
+ > .c8y-list--timeline__item {
571
574
  &:first-child::before {
572
575
  top: 50%;
573
576
  }
@@ -580,7 +583,8 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
580
583
  position: relative;
581
584
  align-items: center;
582
585
  box-shadow: none;
583
- &:focus-within, &:has(.dropdown.open) {
586
+ &:focus-within,
587
+ &:has(.dropdown.open) {
584
588
  z-index: 10;
585
589
  }
586
590
  &::after {
@@ -713,7 +717,7 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
713
717
  z-index: 10;
714
718
  }
715
719
 
716
- &:not(:has(>button))::before {
720
+ &:not(:has(> button))::before {
717
721
  position: absolute;
718
722
  top: 50%;
719
723
  left: calc(-1 * @size-10);
@@ -727,7 +731,7 @@ c8y-li-drag-handle, c8y-list-item-drag-handle {
727
731
  transition: border-color 0.15s linear !important;
728
732
  }
729
733
 
730
- &:not(:has(>button))::after {
734
+ &:not(:has(> button))::after {
731
735
  position: absolute;
732
736
  top: 50%;
733
737
  left: calc(-1 * @size-8);
@@ -42,7 +42,6 @@
42
42
  border: 0;
43
43
  box-shadow: inset 0 -1px 0 @component-border-color;
44
44
 
45
-
46
45
  &.draggable-after {
47
46
  position: relative;
48
47
  display: flex;
@@ -572,7 +572,7 @@ c8y-filtering-form {
572
572
 
573
573
  .data-grid__dropdown {
574
574
  .cdk-header-cell & {
575
- width: 300px;
575
+ // width: 300px;
576
576
  }
577
577
 
578
578
  c8y-object-type div p {
@@ -599,7 +599,7 @@ c8y-filtering-form {
599
599
  max-height: calc(100vh - 500px);
600
600
  }
601
601
  max-height: calc(100vh - 480px);
602
- max-width: 240px;
602
+ max-width: 280px;
603
603
  }
604
604
 
605
605
  c8y-filtering-form-renderer {
@@ -600,7 +600,7 @@ c8y-filtering-form {
600
600
  max-height: calc(100vh - 500px);
601
601
  }
602
602
  max-height: calc(100vh - 480px);
603
- max-width: 240px;
603
+ max-width: 280px;
604
604
  }
605
605
 
606
606
  c8y-filtering-form-renderer {
@@ -8,7 +8,7 @@
8
8
  /**
9
9
  * Forms - Form controls, inputs, labels, and validation
10
10
  *
11
- * Note: Uses @form-control-*; @form-label-*; @form-legend-*, and @size-* tokens.
11
+ * Note: Uses @form-control-*, @form-label-*, @form-legend-*, and @size-* tokens.
12
12
  *
13
13
  * Intentionally hardcoded values:
14
14
  * - rem-based values (1rem, 0.25rem, 1.1428571429em, 1.5em, 0.9rem): Relative sizing for fieldsets
@@ -382,7 +382,7 @@ select.form-control {
382
382
  .c8y-select-wrapper {
383
383
  position: relative;
384
384
  select {
385
- padding-right: @size-24;
385
+ padding-right: @size-24!important;
386
386
  background-image: none;
387
387
 
388
388
  -webkit-appearance: none;
@@ -723,6 +723,11 @@ file-picker ~ .help-block {
723
723
  .table-data-grid & {
724
724
  display: none !important;
725
725
  }
726
+ &:has(formly-validation-message:empty) {
727
+ &::before {
728
+ display: none;
729
+ }
730
+ }
726
731
  }
727
732
 
728
733
  .has-info {
@@ -919,8 +924,10 @@ label.editable {
919
924
  font-size: inherit;
920
925
  cursor: pointer;
921
926
  .form-control {
922
- min-width: 4ch;
923
- max-width: 100%;
927
+ min-inline-size: 6ch;
928
+ max-inline-size: 100%;
929
+ max-block-size: 100%;
930
+ width: auto!important;
924
931
 
925
932
  -moz-appearance: textfield;
926
933
  appearance: textfield;
@@ -943,6 +950,14 @@ label.editable {
943
950
  margin-top: 0.9rem;
944
951
  color: @component-brand-primary;
945
952
  content: @dlt-c8y-icon-pencil;
953
+ &:has(.input-sm) {
954
+ margin-top: 0.6rem;
955
+ }
956
+ }
957
+ &:has(.input-sm) {
958
+ &:has(.ng-pristine):after {
959
+ margin-top: 0.6rem;
960
+ }
946
961
  }
947
962
 
948
963
  .form-control + span {
@@ -384,7 +384,7 @@ select.form-control {
384
384
  .c8y-select-wrapper {
385
385
  position: relative;
386
386
  select {
387
- padding-right: $size-24;
387
+ padding-right: $size-24!important;
388
388
  background-image: none;
389
389
 
390
390
  -webkit-appearance: none;
@@ -725,6 +725,11 @@ file-picker ~ .help-block {
725
725
  .table-data-grid & {
726
726
  display: none !important;
727
727
  }
728
+ &:has(formly-validation-message:empty) {
729
+ &::before {
730
+ display: none;
731
+ }
732
+ }
728
733
  }
729
734
 
730
735
  .has-info {
@@ -921,8 +926,10 @@ label.editable {
921
926
  font-size: inherit;
922
927
  cursor: pointer;
923
928
  .form-control {
924
- min-width: 4ch;
925
- max-width: 100%;
929
+ min-inline-size: 6ch;
930
+ max-inline-size: 100%;
931
+ max-block-size: 100%;
932
+ width: auto!important;
926
933
 
927
934
  -moz-appearance: textfield;
928
935
  appearance: textfield;
@@ -405,3 +405,28 @@ body fieldset > .dashboard-preview-slot {
405
405
  color: inherit;
406
406
  }
407
407
  }
408
+ // Prevent interactions in dashboard preview slots except for maps
409
+ .dashboard-preview-slot:not(:has(c8y-map)){
410
+ pointer-events: none;
411
+ cursor: forbidden;
412
+ }
413
+
414
+
415
+
416
+
417
+ // data-grid--custom-column-header- styles
418
+ .dashboard-preview-slot,
419
+ .card-dashboard{
420
+ .table-data-grid-header > .h4{
421
+ display: none;
422
+ }
423
+ .content-fullpage{
424
+ height: 100%!important;
425
+ }
426
+ &:has(c8y-asset-table-auto-refresh){
427
+ .content-fullpage{
428
+ height: calc(100% - 40px)!important;
429
+ }
430
+ }
431
+ }
432
+
@@ -407,3 +407,25 @@ body fieldset > .dashboard-preview-slot {
407
407
  color: inherit;
408
408
  }
409
409
  }
410
+
411
+ // Prevent interactions in dashboard preview slots except for maps
412
+ .dashboard-preview-slot:not(:has(c8y-map)){
413
+ pointer-events: none;
414
+ cursor: forbidden;
415
+ }
416
+
417
+ // data-grid--custom-column-header- styles
418
+ .dashboard-preview-slot,
419
+ .card-dashboard{
420
+ .table-data-grid-header > .h4{
421
+ display: none;
422
+ }
423
+ .content-fullpage{
424
+ height: 100%!important;
425
+ }
426
+ &:has(c8y-asset-table-auto-refresh){
427
+ .content-fullpage{
428
+ height: calc(100% - 40px)!important;
429
+ }
430
+ }
431
+ }
@@ -56,3 +56,15 @@
56
56
  }
57
57
  }
58
58
  }
59
+
60
+ // for when there are two bottom drawers open
61
+ c8y-bottom-drawer + c8y-bottom-drawer {
62
+ .bottom-drawer {
63
+ margin-top: 40px;
64
+ }
65
+ }
66
+ c8y-bottom-drawer + c8y-bottom-drawer + c8y-bottom-drawer {
67
+ .bottom-drawer {
68
+ margin-top: 80px;
69
+ }
70
+ }