@conduction/nextcloud-vue 2.144.0 → 2.145.0
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/esm/components/CnActionDialog/CnActionDialog.vue.js +1 -1
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +1 -0
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +55 -2
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue.js +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js +16 -0
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +3 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue.js +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue2.js +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue3.js +3 -3
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue3.js.map +1 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue.js +1 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js +2 -2
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFieldListWidget/CnFieldListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +6 -3
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnMailTab/CnMailTab.vue.js +1 -1
- package/dist/esm/components/CnMailTab/CnMailTab.vue2.js.map +1 -1
- package/dist/esm/components/CnMailTab/CnMailTab.vue3.js +2 -2
- package/dist/esm/components/CnMailTab/CnMailTab.vue3.js.map +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue.js +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue2.js.map +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +73 -12
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +165 -126
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue.js +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js +14 -0
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue2.js.map +1 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js +2 -1
- package/dist/esm/components/CnSettingsField/CnSettingsField.vue3.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue.js +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js +13 -8
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue2.js.map +1 -1
- package/dist/esm/components/CnWidgetObjectTable/CnWidgetObjectTable.vue3.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue.js +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js +10 -2
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue3.js.map +1 -1
- package/dist/esm/composables/indexSources.js +35 -9
- package/dist/esm/composables/indexSources.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +2 -0
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +742 -326
- package/dist/esm/utils/builtInFormatters.js +18 -1
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- package/dist/esm/utils/localHeaderRows.js +95 -0
- package/dist/esm/utils/localHeaderRows.js.map +1 -0
- package/dist/nextcloud-vue.cjs.js +514 -179
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +742 -326
- package/l10n/nl.json +2 -0
- package/package.json +1 -1
- package/src/components/CnActionDialog/CnActionDialog.vue +8 -1
- package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +55 -2
- package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +18 -0
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue +2 -1
- package/src/components/CnFieldListWidget/CnFieldListWidget.vue +2 -2
- package/src/components/CnIndexPage/CnIndexPage.vue +6 -3
- package/src/components/CnMailTab/CnMailTab.vue +6 -4
- package/src/components/CnNotificationMatrix/CnNotificationMatrix.vue +4 -1
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +131 -20
- package/src/components/CnSettingsField/CnSettingsField.vue +15 -0
- package/src/components/CnWidgetObjectTable/CnWidgetObjectTable.vue +13 -8
- package/src/components/CnWorkspaceFilterWidget/CnWorkspaceFilterWidget.vue +10 -2
- package/src/composables/indexSources.js +35 -9
- package/src/css/dialog.css +18 -9
- package/src/css/look-board-detail.css +219 -23
- package/src/css/look-board-index.css +38 -4
- package/src/css/look-board.css +138 -8
- package/src/css/table.css +8 -1
- package/src/utils/builtInFormatters.js +17 -0
- package/src/utils/localHeaderRows.js +91 -0
package/src/css/look-board.css
CHANGED
|
@@ -664,12 +664,17 @@
|
|
|
664
664
|
}
|
|
665
665
|
|
|
666
666
|
/* Two buttons in a card's title row stand 8px apart (DqZaakContact "Live
|
|
667
|
-
gesprek", DqZaakEmail "Mail koppelen" / "Mail opstellen")
|
|
667
|
+
gesprek", DqZaakEmail "Mail koppelen" / "Mail opstellen"), also in an
|
|
668
|
+
integration card's CnDetailCard header (DqZaakTaken "Afspraken", "Kaarten").
|
|
668
669
|
@spec openspec/changes/board-card-header-actions-gap/specs/board-card-header-actions-gap/spec.md#requirement-a-board-cards-title-row-buttons-stand-8px-apart */
|
|
669
670
|
.cn-look-board .cn-widget-wrapper__actions:not(.cn-look-nextcloud *) {
|
|
670
671
|
gap: 8px;
|
|
671
672
|
}
|
|
672
673
|
|
|
674
|
+
.cn-look-board .cn-detail-card__header-right:not(.cn-look-nextcloud *) {
|
|
675
|
+
gap: 8px;
|
|
676
|
+
}
|
|
677
|
+
|
|
673
678
|
/* A detail page marked `cardButtons: "regular"` draws them at the 40px
|
|
674
679
|
control height: the case page's tab cards (DqZaakContact "Live gesprek",
|
|
675
680
|
DqZaakHistorie, DqZaakBetrokkenen), where setting and case-type pages keep 34.
|
|
@@ -1467,6 +1472,90 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .v-popper__popper.action-
|
|
|
1467
1472
|
text-decoration: underline;
|
|
1468
1473
|
}
|
|
1469
1474
|
|
|
1475
|
+
/* A plain table an app draws in a settings card (dossiq's ZGW mapping, StUF
|
|
1476
|
+
endpoints and audit log, AWB terms) reads as the board's settings tables:
|
|
1477
|
+
14px, a near-white head with muted 600 labels, 10px 12px cells, soft rules.
|
|
1478
|
+
The theme paints every th through its table header tokens, so the head
|
|
1479
|
+
hands those tokens the board's values too.
|
|
1480
|
+
@spec openspec/changes/board-settings-plain-tables/specs/settings-board-look/spec.md */
|
|
1481
|
+
.cn-look-board .settings-section table:not(.cn-data-table):not(.cn-look-nextcloud *) {
|
|
1482
|
+
width: 100%;
|
|
1483
|
+
border-collapse: collapse;
|
|
1484
|
+
font-size: 14px;
|
|
1485
|
+
line-height: 1.2;
|
|
1486
|
+
}
|
|
1487
|
+
|
|
1488
|
+
.cn-look-board .settings-section table:not(.cn-data-table):not(.cn-look-nextcloud *) th {
|
|
1489
|
+
--nldesign-component-table-header-background-color: var(--cn-board-table-head-bg, color-mix(in srgb, var(--color-background-hover) 40%, var(--color-main-background)));
|
|
1490
|
+
--nldesign-component-table-header-color: var(--color-text-maxcontrast);
|
|
1491
|
+
--nldesign-component-table-header-font-weight: 600;
|
|
1492
|
+
padding: 10px 12px;
|
|
1493
|
+
border-bottom: 1px solid var(--color-border);
|
|
1494
|
+
background: var(--cn-board-table-head-bg, color-mix(in srgb, var(--color-background-hover) 40%, var(--color-main-background)));
|
|
1495
|
+
color: var(--color-text-maxcontrast);
|
|
1496
|
+
font-size: 14px;
|
|
1497
|
+
font-weight: 600;
|
|
1498
|
+
line-height: 1.2;
|
|
1499
|
+
text-align: start;
|
|
1500
|
+
}
|
|
1501
|
+
|
|
1502
|
+
/* The working calendar's month reads as the board draws it: the month name
|
|
1503
|
+
first, at the content edge, with the previous and next month buttons after
|
|
1504
|
+
it, and the buttons add no height to the line, so the month sits 20px under
|
|
1505
|
+
the card title (DqInstellingenAlgemeen "Werkdagen en feestdagen": the
|
|
1506
|
+
arrow put the month 30px in and 28px down).
|
|
1507
|
+
@spec openspec/changes/working-calendar-board-head/specs/settings-board-look/spec.md */
|
|
1508
|
+
.cn-look-board .cn-working-calendar__title:not(.cn-look-nextcloud *) {
|
|
1509
|
+
order: -1;
|
|
1510
|
+
min-width: 0;
|
|
1511
|
+
margin-inline-end: 4px;
|
|
1512
|
+
line-height: 1.2;
|
|
1513
|
+
text-align: start;
|
|
1514
|
+
}
|
|
1515
|
+
|
|
1516
|
+
.cn-look-board .settings-section table:not(.cn-data-table):not(.cn-look-nextcloud *) td {
|
|
1517
|
+
padding: 10px 12px;
|
|
1518
|
+
border-bottom: 1px solid var(--color-background-dark);
|
|
1519
|
+
color: var(--color-main-text);
|
|
1520
|
+
font-size: 14px;
|
|
1521
|
+
line-height: 1.2;
|
|
1522
|
+
vertical-align: middle;
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
/* A strong cell's name in a settings card reads 15px bold over its muted
|
|
1526
|
+
second line, as the boards draw a connection's name (DqInstellingen
|
|
1527
|
+
"Koppelingen": <strong> 15px), not the index tables' 14px 500.
|
|
1528
|
+
@spec openspec/changes/board-settings-strong-cell-name/specs/settings-board-look/spec.md */
|
|
1529
|
+
.cn-look-board .settings-section .cn-data-table td.cn-cell--strong:not(.cn-look-nextcloud *) {
|
|
1530
|
+
font-weight: 400;
|
|
1531
|
+
}
|
|
1532
|
+
|
|
1533
|
+
.cn-look-board .settings-section .cn-data-table td.cn-cell--strong:not(.cn-look-nextcloud *) > .cn-cell-renderer {
|
|
1534
|
+
font-size: 15px;
|
|
1535
|
+
font-weight: 700;
|
|
1536
|
+
}
|
|
1537
|
+
|
|
1538
|
+
.cn-look-board .cn-working-calendar__head:not(.cn-look-nextcloud *) > .button-vue:not(.cn-working-calendar__add) {
|
|
1539
|
+
margin-block: -8px;
|
|
1540
|
+
}
|
|
1541
|
+
|
|
1542
|
+
/* In a one-column settings card a single-line field is at most 560px wide,
|
|
1543
|
+
its hint under it, as the boards draw a field on its own row
|
|
1544
|
+
(DqBeheerGeavanceerd "Financiële integratie", "Storeregister"); a text
|
|
1545
|
+
area, a note or a switch still spans the card.
|
|
1546
|
+
@spec openspec/changes/board-settings-single-field-width/specs/settings-board-look/spec.md */
|
|
1547
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--text,
|
|
1548
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--password,
|
|
1549
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--secret,
|
|
1550
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--number,
|
|
1551
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--email,
|
|
1552
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--url,
|
|
1553
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--select,
|
|
1554
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--date,
|
|
1555
|
+
.cn-look-board .cn-settings-fields__grid--1:not(.cn-look-nextcloud *) > .cn-settings-field--datetime-local {
|
|
1556
|
+
max-width: 560px;
|
|
1557
|
+
}
|
|
1558
|
+
|
|
1470
1559
|
/* Section actions sit at the end of the title row. The row is a grid, so a
|
|
1471
1560
|
long title wraps beside the buttons instead of running under them. A
|
|
1472
1561
|
half-width card keeps them there (DqVthInstellingen "Inspectiechecklists",
|
|
@@ -1523,6 +1612,24 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .v-popper__popper.action-
|
|
|
1523
1612
|
align-self: center;
|
|
1524
1613
|
}
|
|
1525
1614
|
|
|
1615
|
+
/* A switch or radio in a board settings card starts at the card's content
|
|
1616
|
+
edge, its label 12px (switch) or 10px (radio) after the control, as the
|
|
1617
|
+
boards draw them (DqBeheerinstellingen "AI-ondersteunde verwerking").
|
|
1618
|
+
NcCheckboxRadioSwitch pads its content 9px on each side, which set the
|
|
1619
|
+
control 9px in from the fields above and below it.
|
|
1620
|
+
@spec openspec/changes/board-settings-switch-radio-flush/specs/settings-board-look/spec.md */
|
|
1621
|
+
.cn-look-board .cn-settings-fields:not(.cn-look-nextcloud *) .checkbox-content {
|
|
1622
|
+
padding-inline: 0;
|
|
1623
|
+
}
|
|
1624
|
+
|
|
1625
|
+
.cn-look-board .cn-settings-fields:not(.cn-look-nextcloud *) .checkbox-content-switch {
|
|
1626
|
+
gap: 12px;
|
|
1627
|
+
}
|
|
1628
|
+
|
|
1629
|
+
.cn-look-board .cn-settings-fields:not(.cn-look-nextcloud *) .checkbox-content-radio {
|
|
1630
|
+
gap: 10px;
|
|
1631
|
+
}
|
|
1632
|
+
|
|
1526
1633
|
/* The "Uitleg tonen" toggle is a text link flush with the card's right edge
|
|
1527
1634
|
(DqBeheerinstellingen Zaak-e-mail), not a padded tertiary button.
|
|
1528
1635
|
@spec openspec/changes/board-settings-title-centred-and-link-flush/specs/settings-board-look/spec.md */
|
|
@@ -1596,8 +1703,12 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .v-popper__popper.action-
|
|
|
1596
1703
|
max-width: none;
|
|
1597
1704
|
}
|
|
1598
1705
|
|
|
1599
|
-
|
|
1600
|
-
|
|
1706
|
+
/* A board card's title and subtitle run the card's width, wide or not
|
|
1707
|
+
(DqBeheerGeavanceerd "Eerste keer", "StUF-ZKN-endpoints": the subtitle
|
|
1708
|
+
wrapped at NcSettingsSection's 900px measure, the board's does not).
|
|
1709
|
+
@spec openspec/changes/board-settings-desc-full-width/specs/settings-board-look/spec.md */
|
|
1710
|
+
.cn-look-board .settings-section:not(.cn-look-nextcloud *) .settings-section__name,
|
|
1711
|
+
.cn-look-board .settings-section:not(.cn-look-nextcloud *) .settings-section__desc {
|
|
1601
1712
|
max-width: none;
|
|
1602
1713
|
}
|
|
1603
1714
|
|
|
@@ -2156,7 +2267,7 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .v-popper__popper.action-
|
|
|
2156
2267
|
12px follows it: the boards' card is title, 6px, rule, row (DqMijnTeam
|
|
2157
2268
|
"Vastgelopen zaken", DqMijnWerk "Zaken die u volgt").
|
|
2158
2269
|
@spec openspec/changes/board-card-title-above-ruled-list/specs/board-card-title-above-ruled-list/spec.md#requirement-a-ruled-list-starts-6px-under-the-card-title */
|
|
2159
|
-
.cn-look-board .cn-dashboard-page:not(.cn-look-nextcloud *) .cn-widget-wrapper:not(.cn-widget-wrapper--nc-dashboard):not(.cn-widget-wrapper--borderless):has(> .cn-widget-wrapper__content .cn-record-list--rule-above, > .cn-widget-wrapper__content .cn-tasks-widget__list, > .cn-widget-wrapper__content .cn-decision-list__rows) .cn-widget-wrapper__header {
|
|
2270
|
+
.cn-look-board .cn-dashboard-page:not(.cn-look-nextcloud *) .cn-widget-wrapper:not(.cn-widget-wrapper--nc-dashboard):not(.cn-widget-wrapper--borderless):has(> .cn-widget-wrapper__content .cn-record-list--rule-above, > .cn-widget-wrapper__content .cn-tasks-widget__list, > .cn-widget-wrapper__content .cn-decision-list__rows, > .cn-widget-wrapper__content .cn-nc-widget-widget__body--vertical) .cn-widget-wrapper__header {
|
|
2160
2271
|
padding-bottom: 6px;
|
|
2161
2272
|
}
|
|
2162
2273
|
|
|
@@ -2692,13 +2803,13 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .v-popper__popper.action-
|
|
|
2692
2803
|
|
|
2693
2804
|
/* A vertical NC widget is the board's activity list (DqMijnWerk "Recente
|
|
2694
2805
|
activiteit"): hairline rows 12px above and below the text, a 10px dot in
|
|
2695
|
-
the icon's place, the title 14px in the main ink and wrapping
|
|
2696
|
-
|
|
2697
|
-
|
|
2806
|
+
the icon's place, the title 14px in the main ink and wrapping. Thematiq underlines links with a heavier
|
|
2807
|
+
selector, hence the !important. The first hairline stands 6px under the
|
|
2808
|
+
title, as on every Dq list card (design-system #432).
|
|
2698
2809
|
@spec openspec/changes/board-nc-widget-activity-rows/specs/board-nc-widget-activity-rows/spec.md#requirement-a-board-dashboard-nc-widget-draws-its-items-as-activity-rows */
|
|
2699
2810
|
.cn-look-board .cn-dashboard-page:not(.cn-look-nextcloud *) .cn-widget-wrapper:not(.cn-widget-wrapper--borderless) .cn-nc-widget-widget__body--vertical {
|
|
2700
2811
|
gap: 0;
|
|
2701
|
-
padding:
|
|
2812
|
+
padding: 0 var(--cn-board-dashboard-card-inset) 10px;
|
|
2702
2813
|
}
|
|
2703
2814
|
|
|
2704
2815
|
.cn-look-board .cn-dashboard-page:not(.cn-look-nextcloud *) .cn-nc-widget-widget__body--vertical a.cn-nc-widget-widget__item--vertical {
|
|
@@ -3132,6 +3243,25 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .v-popper__popper.action-
|
|
|
3132
3243
|
line-height: normal;
|
|
3133
3244
|
}
|
|
3134
3245
|
|
|
3246
|
+
/* A bar list in a framed section of a sections card is the board's small
|
|
3247
|
+
list: 13px rows 8px apart, a 150px label column, a 10px bar and a 48px
|
|
3248
|
+
value column (DqDoorlooptijd "Naleving per zaaktype").
|
|
3249
|
+
@spec openspec/changes/board-section-bar-list-compact/specs/board-section-bar-list-compact/spec.md#requirement-a-bar-list-in-a-sections-card-section-is-compact */
|
|
3250
|
+
.cn-look-board .cn-sections-widget__section .cn-chart-widget__bar-list:not(.cn-look-nextcloud *) {
|
|
3251
|
+
gap: 8px;
|
|
3252
|
+
}
|
|
3253
|
+
|
|
3254
|
+
.cn-look-board .cn-sections-widget__section .cn-chart-widget__bar-list:not(.cn-look-nextcloud *) .cn-chart-widget__bar-line {
|
|
3255
|
+
grid-template-columns: 150px minmax(0, 1fr) 48px;
|
|
3256
|
+
gap: 10px;
|
|
3257
|
+
font-size: 13px;
|
|
3258
|
+
}
|
|
3259
|
+
|
|
3260
|
+
.cn-look-board .cn-sections-widget__section .cn-chart-widget__bar-list:not(.cn-look-nextcloud *) .cn-chart-widget__bar-track {
|
|
3261
|
+
height: 10px;
|
|
3262
|
+
border-radius: 5px;
|
|
3263
|
+
}
|
|
3264
|
+
|
|
3135
3265
|
/* A bar list with the value at the bar's end (DqProcesanalyse "Doorlooptijd
|
|
3136
3266
|
per status") sets its rows in 13px, the label in the secondary text, the
|
|
3137
3267
|
value in the main ink at 600, rows 34px apart.
|
package/src/css/table.css
CHANGED
|
@@ -310,7 +310,7 @@
|
|
|
310
310
|
.cn-data-table--fit td.cn-table-col--grow.cn-cell--wrap {
|
|
311
311
|
min-width: 8em;
|
|
312
312
|
max-width: none;
|
|
313
|
-
overflow-wrap:
|
|
313
|
+
overflow-wrap: break-word;
|
|
314
314
|
white-space: normal;
|
|
315
315
|
}
|
|
316
316
|
|
|
@@ -359,6 +359,13 @@
|
|
|
359
359
|
font-weight: 500;
|
|
360
360
|
}
|
|
361
361
|
|
|
362
|
+
/* A lead cell's value reads 15px, a person's name over their function
|
|
363
|
+
(DqAfdelingen). */
|
|
364
|
+
.cn-data-table td.cn-cell--lead > .cn-cell-renderer,
|
|
365
|
+
.cn-data-table td.cn-cell--lead .cn-table-row__link > .cn-cell-renderer {
|
|
366
|
+
font-size: 15px;
|
|
367
|
+
}
|
|
368
|
+
|
|
362
369
|
.cn-data-table td.cn-cell--muted {
|
|
363
370
|
color: var(--color-text-maxcontrast);
|
|
364
371
|
}
|
|
@@ -2,6 +2,7 @@ import { translatePlural as n, translate as t } from '@nextcloud/l10n'
|
|
|
2
2
|
import { formatRelativeDate } from './boardDate.js'
|
|
3
3
|
import { formatMoney } from './formatMetric.js'
|
|
4
4
|
import { parseDuration } from './isoDuration.js'
|
|
5
|
+
import { userDisplayName } from './userDisplayName.js'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @file Built-in formatters merged into the `cnFormatters` registry
|
|
@@ -523,6 +524,21 @@ export function formatIsoDuration(value) {
|
|
|
523
524
|
return words[period.unit] ? words[period.unit]() : String(value)
|
|
524
525
|
}
|
|
525
526
|
|
|
527
|
+
/**
|
|
528
|
+
* A Nextcloud user id as its display name (`userName` registry key): the id
|
|
529
|
+
* while the name is looked up, and for a user nobody answers for.
|
|
530
|
+
*
|
|
531
|
+
* @spec openspec/changes/user-name-formatter/specs/user-name-formatter/spec.md#requirement-a-user-id-can-read-as-its-display-name
|
|
532
|
+
* @param {unknown} value The user id.
|
|
533
|
+
* @return {string} The display name, the id, or ''.
|
|
534
|
+
*/
|
|
535
|
+
export function formatUserName(value) {
|
|
536
|
+
if (value === null || value === undefined || value === '' || typeof value === 'object') {
|
|
537
|
+
return ''
|
|
538
|
+
}
|
|
539
|
+
return userDisplayName(value) || String(value)
|
|
540
|
+
}
|
|
541
|
+
|
|
526
542
|
export const BUILT_IN_FORMATTERS = {
|
|
527
543
|
date: formatDate,
|
|
528
544
|
datetime: formatDateTime,
|
|
@@ -538,4 +554,5 @@ export const BUILT_IN_FORMATTERS = {
|
|
|
538
554
|
masked: formatMasked,
|
|
539
555
|
isoDuration: formatIsoDuration,
|
|
540
556
|
valueMap: formatValueMap,
|
|
557
|
+
userName: formatUserName,
|
|
541
558
|
}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SPDX-FileCopyrightText: 2026 Conduction B.V.
|
|
3
|
+
* SPDX-License-Identifier: EUPL-1.2
|
|
4
|
+
*
|
|
5
|
+
* Header sort and filter applied to rows the table already holds (an
|
|
6
|
+
* `endpointSource` table): the same `{ field, dir }` sort and
|
|
7
|
+
* `{ paramKey: values[] }` filter map a self-fetching table sends to the
|
|
8
|
+
* server, read here in the browser.
|
|
9
|
+
*
|
|
10
|
+
* @module utils/localHeaderRows
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { CONTAINS_OPERATOR } from './columnFilters.js'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A row value as one comparable scalar: an array counts as its joined items.
|
|
17
|
+
*
|
|
18
|
+
* @param {unknown} value The raw value.
|
|
19
|
+
* @return {string|number|null} The value to compare.
|
|
20
|
+
*/
|
|
21
|
+
function scalar(value) {
|
|
22
|
+
if (value === null || value === undefined) {
|
|
23
|
+
return null
|
|
24
|
+
}
|
|
25
|
+
if (Array.isArray(value)) {
|
|
26
|
+
return value.map((item) => (item && typeof item === 'object' ? (item.title || item.name || '') : String(item))).join(', ')
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
29
|
+
return typeof value === 'boolean' ? String(value) : value
|
|
30
|
+
}
|
|
31
|
+
return typeof value === 'object' ? (value.title || value.name || '') : String(value)
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Whether a row holds a value the filter entry asks for.
|
|
36
|
+
*
|
|
37
|
+
* @param {object} row The row.
|
|
38
|
+
* @param {string} param The filter key (`field`, `field[like]`, `field[gte]`, `field[lte]`).
|
|
39
|
+
* @param {Array<string>} values The chosen values.
|
|
40
|
+
* @return {boolean} True when the row passes.
|
|
41
|
+
*/
|
|
42
|
+
function passes(row, param, values) {
|
|
43
|
+
const match = /^(.+)\[(\w+)\]$/.exec(param)
|
|
44
|
+
const field = match ? match[1] : param
|
|
45
|
+
const op = match ? match[2] : ''
|
|
46
|
+
const value = scalar(row[field])
|
|
47
|
+
if (op === CONTAINS_OPERATOR) {
|
|
48
|
+
const term = String(values[0]).toLowerCase()
|
|
49
|
+
return value !== null && String(value).toLowerCase().includes(term)
|
|
50
|
+
}
|
|
51
|
+
if (op === 'gte' || op === 'lte') {
|
|
52
|
+
if (value === null) {
|
|
53
|
+
return false
|
|
54
|
+
}
|
|
55
|
+
const left = typeof value === 'number' ? value : String(value)
|
|
56
|
+
const right = typeof value === 'number' ? Number(values[0]) : String(values[0])
|
|
57
|
+
return op === 'gte' ? left >= right : left <= right
|
|
58
|
+
}
|
|
59
|
+
return value !== null && values.map(String).includes(String(value))
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* The rows that pass every active header filter, in the header sort's order.
|
|
64
|
+
*
|
|
65
|
+
* @param {Array<object>} rows The rows.
|
|
66
|
+
* @param {{field: string, dir: string}|null} sort The header sort.
|
|
67
|
+
* @param {object} filters The header filters, `{ paramKey: values[] }`.
|
|
68
|
+
* @return {Array<object>} The rows to show (the same array when nothing applies).
|
|
69
|
+
*/
|
|
70
|
+
export function localHeaderRows(rows, sort, filters) {
|
|
71
|
+
if (!Array.isArray(rows)) {
|
|
72
|
+
return []
|
|
73
|
+
}
|
|
74
|
+
const active = Object.entries(filters || {}).filter(([, values]) => Array.isArray(values) && values.length > 0)
|
|
75
|
+
let out = active.length > 0 ? rows.filter((row) => row && active.every(([param, values]) => passes(row, param, values))) : rows
|
|
76
|
+
if (sort && sort.field) {
|
|
77
|
+
const sign = sort.dir === 'desc' ? -1 : 1
|
|
78
|
+
out = [...out].sort((a, b) => {
|
|
79
|
+
const left = scalar(a && a[sort.field])
|
|
80
|
+
const right = scalar(b && b[sort.field])
|
|
81
|
+
if (left === null || right === null) {
|
|
82
|
+
return left === right ? 0 : (left === null ? 1 : -1)
|
|
83
|
+
}
|
|
84
|
+
if (typeof left === 'number' && typeof right === 'number') {
|
|
85
|
+
return sign * (left - right)
|
|
86
|
+
}
|
|
87
|
+
return sign * String(left).localeCompare(String(right), undefined, { numeric: true, sensitivity: 'base' })
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
return out
|
|
91
|
+
}
|