@conduction/nextcloud-vue 2.144.0 → 2.146.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/CnAiCompanion/CnAiChatPanel.vue2.js.map +1 -1
- package/dist/esm/components/CnAiCompanion/CnAiChatPanel.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/CnChecklistRunWidget/CnChecklistRunWidget.vue.js +1 -1
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnChecklistRunWidget/CnChecklistRunWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +12 -2
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +42 -30
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +22 -0
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js +2 -1
- package/dist/esm/components/CnDetailPage/CnDetailPage.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/CnFactsWidget/CnFactsWidget.vue.js +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +46 -8
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js +3 -3
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.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/CnNotesCard/CnNotesCard.vue.js +1 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js.map +1 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue3.js +1 -0
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue3.js.map +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue.js +1 -1
- package/dist/esm/components/CnNotificationMatrix/CnNotificationMatrix.vue2.js +21 -2
- 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/CnRetentionWidget/CnRetentionWidget.vue.js +1 -1
- package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.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/CnTabsWidget/CnTabsWidget.vue.js +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTabsWidget/CnTabsWidget.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 +1204 -467
- package/dist/esm/utils/builtInFormatters.js +18 -1
- package/dist/esm/utils/builtInFormatters.js.map +1 -1
- package/dist/esm/utils/detailObjectContext.js +7 -2
- package/dist/esm/utils/detailObjectContext.js.map +1 -1
- package/dist/esm/utils/localHeaderRows.js +95 -0
- package/dist/esm/utils/localHeaderRows.js.map +1 -0
- package/dist/esm/utils/validateManifestV2.compiled.js +2 -2
- package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
- package/dist/esm/utils/visibleWhen.js +6 -0
- package/dist/esm/utils/visibleWhen.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +686 -239
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +1204 -467
- package/l10n/nl.json +2 -0
- package/package.json +1 -1
- package/src/components/CnActionDialog/CnActionDialog.vue +8 -1
- package/src/components/CnAiCompanion/CnAiChatPanel.vue +3 -0
- package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +55 -2
- package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +18 -0
- package/src/components/CnChecklistRunWidget/CnChecklistRunWidget.vue +4 -2
- package/src/components/CnDataTable/CnDataTable.vue +19 -2
- package/src/components/CnDetailPage/CnDetailPage.md +1 -0
- package/src/components/CnDetailPage/CnDetailPage.vue +23 -0
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHeaderItems.vue +3 -1
- package/src/components/CnFactsWidget/CnFactsWidget.vue +74 -9
- 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/CnNotesCard/CnNotesCard.vue +7 -2
- package/src/components/CnNotificationMatrix/CnNotificationMatrix.vue +25 -3
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +132 -20
- package/src/components/CnRetentionWidget/CnRetentionWidget.vue +2 -0
- package/src/components/CnSettingsField/CnSettingsField.vue +15 -0
- package/src/components/CnTabsWidget/CnTabsWidget.vue +6 -1
- 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 +25 -9
- package/src/css/look-board-detail.css +370 -30
- package/src/css/look-board-index.css +116 -4
- package/src/css/look-board.css +168 -8
- package/src/css/table.css +17 -1
- package/src/schemas/app-manifest-v2.schema.json +2 -2
- package/src/utils/builtInFormatters.js +17 -0
- package/src/utils/detailObjectContext.js +7 -2
- package/src/utils/localHeaderRows.js +91 -0
- package/src/utils/validateManifestV2.compiled.js +2 -2
- package/src/utils/visibleWhen.js +6 -0
|
@@ -331,6 +331,23 @@ import {
|
|
|
331
331
|
* @event {object} digest-change — A channel's digest was set. Payload: `{ channelId, mode, timeOfDay }`.
|
|
332
332
|
* @event {object} test-send — A test was asked for. Payload: `{ channelId }`.
|
|
333
333
|
*/
|
|
334
|
+
/**
|
|
335
|
+
* An event's shipped default in one channel: one boolean for every channel,
|
|
336
|
+
* or the channel's own entry when the default differs per channel.
|
|
337
|
+
*
|
|
338
|
+
* @param {object} event The event.
|
|
339
|
+
* @param {object} channel The channel.
|
|
340
|
+
* @return {boolean} The default.
|
|
341
|
+
* @spec openspec/changes/notification-matrix-default-per-channel/specs/notification-matrix/spec.md
|
|
342
|
+
*/
|
|
343
|
+
function appDefaultFor(event, channel) {
|
|
344
|
+
const value = event?.appDefault
|
|
345
|
+
if (value !== null && typeof value === 'object') {
|
|
346
|
+
return value[channel?.id] === true
|
|
347
|
+
}
|
|
348
|
+
return value === true
|
|
349
|
+
}
|
|
350
|
+
|
|
334
351
|
export default {
|
|
335
352
|
name: 'CnNotificationMatrix',
|
|
336
353
|
|
|
@@ -342,7 +359,9 @@ export default {
|
|
|
342
359
|
props: {
|
|
343
360
|
/**
|
|
344
361
|
* The events, each `{ id, label, group, groupLabel, immediate,
|
|
345
|
-
* appDefault }`. From the host's catalogue.
|
|
362
|
+
* appDefault }`. From the host's catalogue. `appDefault` is one
|
|
363
|
+
* boolean for every channel, or `{ [channelId]: boolean }` when the
|
|
364
|
+
* default differs per channel (an opt-in e-mail is off by default).
|
|
346
365
|
*/
|
|
347
366
|
events: {
|
|
348
367
|
type: Array,
|
|
@@ -607,7 +626,7 @@ export default {
|
|
|
607
626
|
})
|
|
608
627
|
|
|
609
628
|
return resolvePreference({
|
|
610
|
-
appDefault: event
|
|
629
|
+
appDefault: appDefaultFor(event, channel),
|
|
611
630
|
groupValue: this.at(this.groupValues, event, channel),
|
|
612
631
|
personalValue: narrow.value === null
|
|
613
632
|
? this.at(this.personalValues, event, channel)
|
|
@@ -1135,7 +1154,10 @@ export default {
|
|
|
1135
1154
|
min-inline-size: 20px;
|
|
1136
1155
|
block-size: 20px;
|
|
1137
1156
|
min-block-size: 20px;
|
|
1138
|
-
|
|
1157
|
+
/* A block box, so the line's baseline adds no height: the row is
|
|
1158
|
+
42px as on the board (10px, the 1px-low checkbox, 10px, the rule). */
|
|
1159
|
+
display: block;
|
|
1160
|
+
margin: 1px auto 0;
|
|
1139
1161
|
}
|
|
1140
1162
|
|
|
1141
1163
|
.cn-notification-matrix__group {
|
|
@@ -53,15 +53,37 @@
|
|
|
53
53
|
scope="col"
|
|
54
54
|
:aria-sort="col.sortable ? sortStateOf(col.key) : undefined"
|
|
55
55
|
:class="{ 'cn-record-list__cell--end': col.align === 'end' }">
|
|
56
|
-
<
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
56
|
+
<span v-if="col.sortable || tableFilterable" class="cn-record-list__head">
|
|
57
|
+
<button
|
|
58
|
+
v-if="col.sortable"
|
|
59
|
+
type="button"
|
|
60
|
+
class="cn-record-list__sort"
|
|
61
|
+
:data-testid="`cn-record-list-sort-${col.key}`"
|
|
62
|
+
@click="toggleTableSort(col.key)">
|
|
63
|
+
{{ col.label }}
|
|
64
|
+
<span class="cn-record-list__sort-mark" aria-hidden="true">{{ sortMarkOf(col.key) }}</span>
|
|
65
|
+
</button>
|
|
66
|
+
<template v-else>
|
|
67
|
+
{{ col.label }}
|
|
68
|
+
</template>
|
|
69
|
+
<!-- `content.filterable`: the head offers the values the column holds and keeps the rows with a chosen one. -->
|
|
70
|
+
<NcActions
|
|
71
|
+
v-if="tableFilterable"
|
|
72
|
+
class="cn-record-list__head-filter"
|
|
73
|
+
:aria-label="filterLabelOf(col.label)"
|
|
74
|
+
:data-testid="`cn-record-list-filter-${col.key}`">
|
|
75
|
+
<template #icon>
|
|
76
|
+
<FilterOutline :size="14" />
|
|
77
|
+
</template>
|
|
78
|
+
<NcActionCheckbox
|
|
79
|
+
v-for="option in tableFilterOptions(col.key)"
|
|
80
|
+
:key="option"
|
|
81
|
+
:modelValue="(tableFilters[col.key] || []).includes(option)"
|
|
82
|
+
@update:modelValue="toggleTableFilter(col.key, option)">
|
|
83
|
+
{{ option }}
|
|
84
|
+
</NcActionCheckbox>
|
|
85
|
+
</NcActions>
|
|
86
|
+
</span>
|
|
65
87
|
<template v-else>
|
|
66
88
|
{{ col.label }}
|
|
67
89
|
</template>
|
|
@@ -550,10 +572,11 @@
|
|
|
550
572
|
import { subscribe, unsubscribe } from '@nextcloud/event-bus'
|
|
551
573
|
import { translate as t } from '@nextcloud/l10n'
|
|
552
574
|
import { generateUrl } from '@nextcloud/router'
|
|
553
|
-
import { NcActionButton, NcActionLink, NcActions, NcButton, NcLoadingIcon } from '@nextcloud/vue'
|
|
575
|
+
import { NcActionButton, NcActionCheckbox, NcActionLink, NcActions, NcButton, NcLoadingIcon } from '@nextcloud/vue'
|
|
554
576
|
import { inject, ref } from 'vue'
|
|
555
577
|
import Check from 'vue-material-design-icons/Check.vue'
|
|
556
578
|
import ChevronRight from 'vue-material-design-icons/ChevronRight.vue'
|
|
579
|
+
import FilterOutline from 'vue-material-design-icons/FilterOutline.vue'
|
|
557
580
|
import CnIcon from '../CnIcon/CnIcon.vue'
|
|
558
581
|
import CnStatusBadge from '../CnStatusBadge/CnStatusBadge.vue'
|
|
559
582
|
import CnRecordNoteRows from './CnRecordNoteRows.vue'
|
|
@@ -649,7 +672,7 @@ function unwrap(value) {
|
|
|
649
672
|
export default {
|
|
650
673
|
name: 'CnRecordListWidget',
|
|
651
674
|
|
|
652
|
-
components: { Check, ChevronRight, CnIcon, CnRecordNoteRows, CnStatusBadge, NcActionButton, NcActionLink, NcActions, NcButton, NcLoadingIcon },
|
|
675
|
+
components: { Check, ChevronRight, CnIcon, CnRecordNoteRows, CnStatusBadge, FilterOutline, NcActionButton, NcActionCheckbox, NcActionLink, NcActions, NcButton, NcLoadingIcon },
|
|
653
676
|
|
|
654
677
|
inject: {
|
|
655
678
|
/** Detail-page object context (`{ objectId, object, register, schema }`). */
|
|
@@ -714,6 +737,8 @@ export default {
|
|
|
714
737
|
* without a value.
|
|
715
738
|
* `density: "compact"` draws the rows 10px above and below, at least
|
|
716
739
|
* 56px tall, with the title at 500 (DqProcesanalyse).
|
|
740
|
+
* On `cards` it draws the small framed card: 12px 14px in, the title
|
|
741
|
+
* 15px/700 with the pill at its end (DqInspectie).
|
|
717
742
|
* `density: "stacked"` stands the rows 10px apart with no rule and no
|
|
718
743
|
* row padding (DqDagAfsluiten "Morgen eerst").
|
|
719
744
|
* In `rows`, `text` is a line under the meta line ("12 dagen stil"),
|
|
@@ -809,6 +834,8 @@ export default {
|
|
|
809
834
|
return {
|
|
810
835
|
/** The reader's sort of a `table`: the column key and `ascending` or `descending`. */
|
|
811
836
|
tableSort: { key: '', dir: '' },
|
|
837
|
+
/** The reader's head filters of a `table`: `{ [columnKey]: cellTexts[] }`. */
|
|
838
|
+
tableFilters: {},
|
|
812
839
|
rows: [],
|
|
813
840
|
/** The `aggregates` figures per row id: `{ [rowId]: { [key]: value } }`. */
|
|
814
841
|
aggregateValues: {},
|
|
@@ -1183,7 +1210,16 @@ export default {
|
|
|
1183
1210
|
const isTemplate = (value) => typeof value === 'string' || (Array.isArray(value) && value.length > 0 && value.every((entry) => typeof entry === 'string'))
|
|
1184
1211
|
return columns
|
|
1185
1212
|
.filter((col) => col && typeof col === 'object' && isTemplate(col.value))
|
|
1186
|
-
.map((col, index) => ({ ...col, key: `col-${index}`, label: typeof col.label === 'string' ? this.translate(col.label) : '' }))
|
|
1213
|
+
.map((col, index) => ({ ...col, key: `col-${index}`, label: typeof col.label === 'string' ? this.translate(col.label) : '', sortable: col.sortable === true || this.content?.sortable === true }))
|
|
1214
|
+
},
|
|
1215
|
+
|
|
1216
|
+
/**
|
|
1217
|
+
* Whether the `table` heads filter (`content.filterable`).
|
|
1218
|
+
*
|
|
1219
|
+
* @return {boolean}
|
|
1220
|
+
*/
|
|
1221
|
+
tableFilterable() {
|
|
1222
|
+
return this.content?.filterable === true
|
|
1187
1223
|
},
|
|
1188
1224
|
|
|
1189
1225
|
/**
|
|
@@ -1193,8 +1229,27 @@ export default {
|
|
|
1193
1229
|
* @spec openspec/changes/record-list-table/specs/record-list-table/spec.md#requirement-a-record-list-can-draw-its-rows-as-a-small-table
|
|
1194
1230
|
*/
|
|
1195
1231
|
tableRows() {
|
|
1232
|
+
const rows = this.tableAllRows.filter((row) => Object.entries(this.tableFilters).every(([key, values]) => {
|
|
1233
|
+
const index = this.tableColumns.findIndex((col) => col.key === key)
|
|
1234
|
+
return values.length === 0 || index < 0 || values.includes(row.cells[index].text)
|
|
1235
|
+
}))
|
|
1236
|
+
const { key, dir } = this.tableSort
|
|
1237
|
+
const index = this.tableColumns.findIndex((col) => col.key === key)
|
|
1238
|
+
if (index < 0 || !dir) {
|
|
1239
|
+
return rows
|
|
1240
|
+
}
|
|
1241
|
+
const sign = dir === 'descending' ? -1 : 1
|
|
1242
|
+
return [...rows].sort((a, b) => sign * compareCells(a.cells[index].text, b.cells[index].text))
|
|
1243
|
+
},
|
|
1244
|
+
|
|
1245
|
+
/**
|
|
1246
|
+
* Every `table` row, before the reader's head filters and sort.
|
|
1247
|
+
*
|
|
1248
|
+
* @return {Array<object>} `{ key, cells: [{ key, text, align, alert }] }`.
|
|
1249
|
+
*/
|
|
1250
|
+
tableAllRows() {
|
|
1196
1251
|
const indentPath = this.content?.indentPath
|
|
1197
|
-
|
|
1252
|
+
return this.items.map((item) => ({
|
|
1198
1253
|
key: item.key,
|
|
1199
1254
|
row: item.row,
|
|
1200
1255
|
rowActions: this.rowActions.length > 0 ? this.rowActionsOf(item.row) : [],
|
|
@@ -1215,13 +1270,6 @@ export default {
|
|
|
1215
1270
|
}
|
|
1216
1271
|
}),
|
|
1217
1272
|
}))
|
|
1218
|
-
const { key, dir } = this.tableSort
|
|
1219
|
-
const index = this.tableColumns.findIndex((col) => col.key === key)
|
|
1220
|
-
if (index < 0 || !dir) {
|
|
1221
|
-
return rows
|
|
1222
|
-
}
|
|
1223
|
-
const sign = dir === 'descending' ? -1 : 1
|
|
1224
|
-
return [...rows].sort((a, b) => sign * compareCells(a.cells[index].text, b.cells[index].text))
|
|
1225
1273
|
},
|
|
1226
1274
|
|
|
1227
1275
|
/**
|
|
@@ -2246,6 +2294,41 @@ export default {
|
|
|
2246
2294
|
this.tableSort = { key, dir }
|
|
2247
2295
|
},
|
|
2248
2296
|
|
|
2297
|
+
/**
|
|
2298
|
+
* The values a `table` column's head filter offers: each text the column holds, once.
|
|
2299
|
+
*
|
|
2300
|
+
* @param {string} key The column key.
|
|
2301
|
+
* @return {Array<string>} The texts, in row order.
|
|
2302
|
+
*/
|
|
2303
|
+
tableFilterOptions(key) {
|
|
2304
|
+
const index = this.tableColumns.findIndex((col) => col.key === key)
|
|
2305
|
+
if (index < 0) {
|
|
2306
|
+
return []
|
|
2307
|
+
}
|
|
2308
|
+
return [...new Set(this.tableAllRows.map((row) => row.cells[index].text).filter((text) => text !== ''))]
|
|
2309
|
+
},
|
|
2310
|
+
|
|
2311
|
+
/**
|
|
2312
|
+
* Keep or drop one value of a `table` column's head filter.
|
|
2313
|
+
*
|
|
2314
|
+
* @param {string} key The column key.
|
|
2315
|
+
* @param {string} value The cell text.
|
|
2316
|
+
*/
|
|
2317
|
+
toggleTableFilter(key, value) {
|
|
2318
|
+
const current = this.tableFilters[key] || []
|
|
2319
|
+
this.tableFilters = { ...this.tableFilters, [key]: current.includes(value) ? current.filter((v) => v !== value) : [...current, value] }
|
|
2320
|
+
},
|
|
2321
|
+
|
|
2322
|
+
/**
|
|
2323
|
+
* The accessible name of a column's head filter.
|
|
2324
|
+
*
|
|
2325
|
+
* @param {string} label The column label.
|
|
2326
|
+
* @return {string}
|
|
2327
|
+
*/
|
|
2328
|
+
filterLabelOf(label) {
|
|
2329
|
+
return t('nextcloud-vue', 'Filter by {column}', { column: label })
|
|
2330
|
+
},
|
|
2331
|
+
|
|
2249
2332
|
/**
|
|
2250
2333
|
* The rows of a read with `flattenPath` set: each entry of the list at
|
|
2251
2334
|
* that path on a record becomes a row, with the record at `@parent`.
|
|
@@ -3232,6 +3315,16 @@ export default {
|
|
|
3232
3315
|
font-size: 10px;
|
|
3233
3316
|
}
|
|
3234
3317
|
|
|
3318
|
+
.cn-record-list__head {
|
|
3319
|
+
display: inline-flex;
|
|
3320
|
+
gap: 4px;
|
|
3321
|
+
align-items: center;
|
|
3322
|
+
}
|
|
3323
|
+
|
|
3324
|
+
.cn-record-list__head-filter {
|
|
3325
|
+
--button-size: 22px;
|
|
3326
|
+
}
|
|
3327
|
+
|
|
3235
3328
|
.cn-record-list__table .cn-record-list__cell--end {
|
|
3236
3329
|
padding-inline-start: 12px;
|
|
3237
3330
|
text-align: end;
|
|
@@ -3320,6 +3413,7 @@ export default {
|
|
|
3320
3413
|
font-weight: 600;
|
|
3321
3414
|
height: 34px;
|
|
3322
3415
|
justify-content: center;
|
|
3416
|
+
margin: 0;
|
|
3323
3417
|
padding: 0 14px;
|
|
3324
3418
|
text-decoration: none;
|
|
3325
3419
|
}
|
|
@@ -3383,6 +3477,24 @@ export default {
|
|
|
3383
3477
|
text-decoration: none;
|
|
3384
3478
|
}
|
|
3385
3479
|
|
|
3480
|
+
/* `density: "compact"` on cards: the boards' small framed rows (DqInspectie
|
|
3481
|
+
"Molenweg 4" and the outbox): 12px 14px in, the title 15px/700 on an
|
|
3482
|
+
18px line with the pill at its end, the meta 6px under it. */
|
|
3483
|
+
.cn-record-list--compact .cn-record-list__card {
|
|
3484
|
+
gap: 6px;
|
|
3485
|
+
padding: 12px 14px;
|
|
3486
|
+
}
|
|
3487
|
+
|
|
3488
|
+
.cn-record-list--compact .cn-record-list__card-head {
|
|
3489
|
+
align-items: flex-start;
|
|
3490
|
+
}
|
|
3491
|
+
|
|
3492
|
+
.cn-record-list--compact .cn-record-list__card .cn-record-list__title {
|
|
3493
|
+
font-size: 15px;
|
|
3494
|
+
font-weight: 700;
|
|
3495
|
+
line-height: 1.2;
|
|
3496
|
+
}
|
|
3497
|
+
|
|
3386
3498
|
.cn-record-list__card--link:hover,
|
|
3387
3499
|
.cn-record-list__card--link:focus-visible {
|
|
3388
3500
|
border-color: var(--color-border-dark, var(--color-border));
|
|
@@ -604,6 +604,7 @@ export default {
|
|
|
604
604
|
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
|
605
605
|
gap: 12px 24px;
|
|
606
606
|
margin: 0;
|
|
607
|
+
padding: 0;
|
|
607
608
|
}
|
|
608
609
|
|
|
609
610
|
/* The server draws every dt as a 130px right-aligned inline block and pads
|
|
@@ -621,6 +622,7 @@ export default {
|
|
|
621
622
|
padding: 0;
|
|
622
623
|
color: var(--color-text-maxcontrast);
|
|
623
624
|
font-size: 13px;
|
|
625
|
+
line-height: 1.2;
|
|
624
626
|
}
|
|
625
627
|
|
|
626
628
|
.cn-retention__fact dd {
|
|
@@ -275,6 +275,7 @@
|
|
|
275
275
|
type="number"
|
|
276
276
|
:min="field.min"
|
|
277
277
|
:max="field.max"
|
|
278
|
+
:step="numberStep"
|
|
278
279
|
:modelValue="stringValue"
|
|
279
280
|
:readonly="field.readOnly"
|
|
280
281
|
:error="!!error"
|
|
@@ -424,6 +425,20 @@ export default {
|
|
|
424
425
|
return INPUT_TYPES.includes(this.kind) ? this.kind : 'text'
|
|
425
426
|
},
|
|
426
427
|
|
|
428
|
+
/**
|
|
429
|
+
* The number input's step: the field's own, 1 for a whole number, else
|
|
430
|
+
* any, so a decimal value (0.8) is not invalid to the browser.
|
|
431
|
+
*
|
|
432
|
+
* @return {string}
|
|
433
|
+
* @spec openspec/changes/settings-number-decimal-step/specs/settings-fields/spec.md#requirement-a-number-setting-steps-as-it-is-declared
|
|
434
|
+
*/
|
|
435
|
+
numberStep() {
|
|
436
|
+
if (typeof this.field.step === 'number' || (typeof this.field.step === 'string' && this.field.step !== '')) {
|
|
437
|
+
return String(this.field.step)
|
|
438
|
+
}
|
|
439
|
+
return this.field.integer ? '1' : 'any'
|
|
440
|
+
},
|
|
441
|
+
|
|
427
442
|
/** @return {string} The label. */
|
|
428
443
|
label() {
|
|
429
444
|
return String(this.field.label || this.field.key || '')
|
|
@@ -1566,12 +1566,17 @@ export default {
|
|
|
1566
1566
|
|
|
1567
1567
|
.cn-tabs-widget__panel-heading-text {
|
|
1568
1568
|
display: flex;
|
|
1569
|
-
flex: 1 1 260px;
|
|
1570
1569
|
flex-direction: column;
|
|
1571
1570
|
gap: 4px;
|
|
1572
1571
|
min-width: 0;
|
|
1573
1572
|
}
|
|
1574
1573
|
|
|
1574
|
+
/* The 260px basis is a width in the actions row; in the column heading it
|
|
1575
|
+
would be a height. */
|
|
1576
|
+
.cn-tabs-widget__panel-heading--actions > .cn-tabs-widget__panel-heading-text {
|
|
1577
|
+
flex: 1 1 260px;
|
|
1578
|
+
}
|
|
1579
|
+
|
|
1575
1580
|
.cn-tabs-widget__panel-actions {
|
|
1576
1581
|
display: flex;
|
|
1577
1582
|
justify-content: flex-end;
|
|
@@ -118,9 +118,10 @@ import CnConfirmDialog from '../../dialogs/CnConfirmDialog.vue'
|
|
|
118
118
|
import CnDataTable from '../CnDataTable/CnDataTable.vue'
|
|
119
119
|
import { getByPath, useEndpointSource } from '../../composables/useEndpointSource.js'
|
|
120
120
|
import { useObjectStore } from '../../store/useObjectStore.js'
|
|
121
|
-
import { dispatchAction, resolveObjectOpType } from '../../utils/actionsDispatcher.js'
|
|
121
|
+
import { dispatchAction, interpolateActionTarget, resolveObjectOpType } from '../../utils/actionsDispatcher.js'
|
|
122
122
|
import { resolveObjectTokenContext } from '../../utils/detailObjectContext.js'
|
|
123
123
|
import { headerFilterParams, nextHeaderFilters, withSortableColumns } from '../../utils/headerFilterState.js'
|
|
124
|
+
import { localHeaderRows } from '../../utils/localHeaderRows.js'
|
|
124
125
|
import { pageFilter, pageSort } from '../../utils/pageControls.js'
|
|
125
126
|
import { readPath } from '../../utils/readPath.js'
|
|
126
127
|
import { dropOptionalUnresolved, hasUnresolvedTokens, resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
@@ -869,9 +870,9 @@ export default {
|
|
|
869
870
|
if (this.endpointActive && this.columns.some((col) => col && typeof col === 'object' && col.labelPath)) {
|
|
870
871
|
inner.columns = this.labelledColumns(inner.columns || this.columns)
|
|
871
872
|
}
|
|
872
|
-
// Header sort and filter (`sortable`, `filterable`)
|
|
873
|
-
//
|
|
874
|
-
if (this.selfFetchActive && (this.sortable !== false || this.filterable)) {
|
|
873
|
+
// Header sort and filter (`sortable`, `filterable`): the server sorts
|
|
874
|
+
// and filters a self-fetch; endpoint rows are sorted and filtered here.
|
|
875
|
+
if ((this.selfFetchActive || this.endpointActive) && (this.sortable !== false || this.filterable)) {
|
|
875
876
|
inner.columns = withSortableColumns(inner.columns || this.columns, this.sortable)
|
|
876
877
|
inner.filterable = this.filterable
|
|
877
878
|
inner.activeFilters = this.headerFilters
|
|
@@ -889,7 +890,7 @@ export default {
|
|
|
889
890
|
}
|
|
890
891
|
}
|
|
891
892
|
if (this.endpointActive) {
|
|
892
|
-
inner.rows = this.endpointRows
|
|
893
|
+
inner.rows = localHeaderRows(this.endpointRows, this.headerSort, this.headerFilters)
|
|
893
894
|
inner.loading = this.epLoading || this.loading
|
|
894
895
|
}
|
|
895
896
|
if (this.rowRoute) {
|
|
@@ -1159,9 +1160,13 @@ export default {
|
|
|
1159
1160
|
return { ok: false, error: '' }
|
|
1160
1161
|
}
|
|
1161
1162
|
if (action.type !== 'object-op') {
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
: action
|
|
1163
|
+
let wrapped = action
|
|
1164
|
+
if (!action.type || action.type === 'handler') {
|
|
1165
|
+
wrapped = { ...action, args: [...(action.args || []), row] }
|
|
1166
|
+
} else if (action.type === 'navigate' && row) {
|
|
1167
|
+
// A row's navigate reads that row: `{objectId}` / `@objectId` is its id, `@object.<field>` its fields.
|
|
1168
|
+
wrapped = { ...action, target: interpolateActionTarget(action.target, { objectId: row.id, object: row }) }
|
|
1169
|
+
}
|
|
1165
1170
|
if (typeof this.cnDispatchAction === 'function') {
|
|
1166
1171
|
this.cnDispatchAction(wrapped)
|
|
1167
1172
|
} else {
|
|
@@ -880,15 +880,23 @@ export default {
|
|
|
880
880
|
*/
|
|
881
881
|
/**
|
|
882
882
|
* The value an input starts with: `content.default`, else the current
|
|
883
|
-
* quarter or year for those types, else empty.
|
|
883
|
+
* quarter or year for those types, else empty. For a quarter or year
|
|
884
|
+
* input, `default: "previous"` is the last complete one (DqTermijnen
|
|
885
|
+
* opens on the last complete quarter).
|
|
884
886
|
*
|
|
885
887
|
* @return {string}
|
|
886
888
|
*/
|
|
887
889
|
inputDefault() {
|
|
890
|
+
const today = new Date()
|
|
891
|
+
if (this.content.default === 'previous' && this.inputType === 'quarter') {
|
|
892
|
+
return quarterKey(new Date(today.getFullYear(), today.getMonth() - 3, 1))
|
|
893
|
+
}
|
|
894
|
+
if (this.content.default === 'previous' && this.inputType === 'year') {
|
|
895
|
+
return String(today.getFullYear() - 1)
|
|
896
|
+
}
|
|
888
897
|
if (this.content.default !== undefined && this.content.default !== null) {
|
|
889
898
|
return String(this.content.default)
|
|
890
899
|
}
|
|
891
|
-
const today = new Date()
|
|
892
900
|
if (this.inputType === 'quarter') {
|
|
893
901
|
return quarterKey(today)
|
|
894
902
|
}
|
|
@@ -1109,7 +1109,9 @@ function fillRowTemplate(template, row) {
|
|
|
1109
1109
|
* template, "{case.title}") or `linkedField` (a path) fills the "Linked"
|
|
1110
1110
|
* column, drawn when a kind declares one; `sourceConfig.linkedLabel` names it.
|
|
1111
1111
|
* `subtitleTemplate` ("Case {identifier}", translated) fills the line under a
|
|
1112
|
-
* result, else `subtitleField
|
|
1112
|
+
* result, else `subtitleField`; `subtitleResolve` (`{ field, schema, labelField,
|
|
1113
|
+
* as }`) names a referenced object for it as `{as}`. `sourceConfig.titleWrap`
|
|
1114
|
+
* wraps a long result title instead of cutting it.
|
|
1113
1115
|
* `linkedUser: true` reads that value as a user id and shows the user's
|
|
1114
1116
|
* display name. `sourceConfig.columnWidths` sets a width per column key.
|
|
1115
1117
|
* The page's title and count line can name the term as `{term}`, and the
|
|
@@ -1226,9 +1228,32 @@ function searchSource(config = {}, context = {}) {
|
|
|
1226
1228
|
return ''
|
|
1227
1229
|
}
|
|
1228
1230
|
|
|
1229
|
-
|
|
1231
|
+
// `subtitleResolve`: `{ field, schema, register?, labelField?, as }` names
|
|
1232
|
+
// the object a reference points at, for the subtitle template as `{as}`.
|
|
1233
|
+
const subtitleLabels = async (kind) => {
|
|
1234
|
+
const resolve = kind.subtitleResolve
|
|
1235
|
+
if (!resolve || !resolve.schema || !resolve.field) {
|
|
1236
|
+
return null
|
|
1237
|
+
}
|
|
1238
|
+
const objects = await fetchReferenceObjects({ register: resolve.register || kind.register, schema: resolve.schema }).catch(() => [])
|
|
1239
|
+
const labels = new Map()
|
|
1240
|
+
for (const object of objects) {
|
|
1241
|
+
const id = object.id || object.uuid || (object['@self'] && object['@self'].id)
|
|
1242
|
+
const label = readPath(object, resolve.labelField || 'title') ?? object.name
|
|
1243
|
+
if (id !== undefined && label !== undefined && label !== null) {
|
|
1244
|
+
labels.set(String(id), String(label))
|
|
1245
|
+
}
|
|
1246
|
+
}
|
|
1247
|
+
return labels
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
const subtitleOf = (kind, object, labels = null) => {
|
|
1230
1251
|
if (kind.subtitleTemplate) {
|
|
1231
|
-
|
|
1252
|
+
const resolve = kind.subtitleResolve
|
|
1253
|
+
const data = labels && resolve
|
|
1254
|
+
? { ...object, [resolve.as || resolve.field]: labels.get(String(readPath(object, resolve.field) ?? '')) ?? '' }
|
|
1255
|
+
: object
|
|
1256
|
+
return fillTemplate(translate(kind.subtitleTemplate), data)
|
|
1232
1257
|
}
|
|
1233
1258
|
return kind.subtitleField ? String(readPath(object, kind.subtitleField) ?? '') : ''
|
|
1234
1259
|
}
|
|
@@ -1247,6 +1272,7 @@ function searchSource(config = {}, context = {}) {
|
|
|
1247
1272
|
const results = Array.isArray(body.results) ? body.results : (Array.isArray(body) ? body : [])
|
|
1248
1273
|
const labels = kind.statusResolve && kind.statusField ? await statusLabels(kind) : null
|
|
1249
1274
|
const userNames = kind.linkedUser === true ? await linkedUserNames(kind, results) : null
|
|
1275
|
+
const subtitleNames = await subtitleLabels(kind)
|
|
1250
1276
|
return {
|
|
1251
1277
|
total: typeof body.total === 'number' ? body.total : results.length,
|
|
1252
1278
|
rows: results.map((object) => {
|
|
@@ -1261,7 +1287,7 @@ function searchSource(config = {}, context = {}) {
|
|
|
1261
1287
|
kindLabel: kind.label,
|
|
1262
1288
|
kindText: kindTextOf(kind, object),
|
|
1263
1289
|
title: String(readPath(object, kind.titleField || 'title') ?? object.name ?? id ?? ''),
|
|
1264
|
-
subtitle: subtitleOf(kind, object),
|
|
1290
|
+
subtitle: subtitleOf(kind, object, subtitleNames),
|
|
1265
1291
|
status,
|
|
1266
1292
|
linked: userNames ? (userNames.get(linkedOf(kind, object)) || linkedOf(kind, object)) : linkedOf(kind, object),
|
|
1267
1293
|
href: kind.href ? generateUrl(fillRowTemplate(kind.href, { ...object, id })) : '',
|
|
@@ -1372,7 +1398,7 @@ function searchSource(config = {}, context = {}) {
|
|
|
1372
1398
|
loading: () => state.loading,
|
|
1373
1399
|
|
|
1374
1400
|
columns: withColumnWidths([
|
|
1375
|
-
{ key: 'title', label: t('nextcloud-vue', 'Result'), secondary: 'subtitle', sortable: true },
|
|
1401
|
+
{ key: 'title', label: t('nextcloud-vue', 'Result'), secondary: 'subtitle', sortable: true, ...(config && config.titleWrap === true ? { cellClass: 'cn-cell--wrap' } : {}) },
|
|
1376
1402
|
// `kindAsText`: what one row is, as plain text ("Zaak", "Lantaarnpaal",
|
|
1377
1403
|
// DqZoekresultaten), instead of the plural kind as a pill.
|
|
1378
1404
|
config && config.kindAsText === true
|
|
@@ -1619,10 +1645,10 @@ function usersSource() {
|
|
|
1619
1645
|
loading: () => state.loading,
|
|
1620
1646
|
|
|
1621
1647
|
columns: [
|
|
1622
|
-
{ key: 'displayname', label: t('nextcloud-vue', 'Employee'), secondary: 'function' },
|
|
1623
|
-
{ key: 'roles', label: t('nextcloud-vue', 'Roles') },
|
|
1624
|
-
{ key: 'email', label: t('nextcloud-vue', 'E-mail') },
|
|
1625
|
-
{ key: 'today', label: t('nextcloud-vue', 'Today'), widget: 'badge', widgetProps: { colorMap: presenceColors, variant: 'warning' } },
|
|
1648
|
+
{ key: 'displayname', label: t('nextcloud-vue', 'Employee'), secondary: 'function', sortable: true, cellClass: 'cn-cell--lead' },
|
|
1649
|
+
{ key: 'roles', label: t('nextcloud-vue', 'Roles'), sortable: true },
|
|
1650
|
+
{ key: 'email', label: t('nextcloud-vue', 'E-mail'), sortable: true },
|
|
1651
|
+
{ key: 'today', label: t('nextcloud-vue', 'Today'), widget: 'badge', widgetProps: { colorMap: presenceColors, variant: 'warning' }, sortable: true },
|
|
1626
1652
|
],
|
|
1627
1653
|
|
|
1628
1654
|
searchFields: {
|
package/src/css/dialog.css
CHANGED
|
@@ -177,11 +177,14 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
177
177
|
color: var(--color-text-maxcontrast);
|
|
178
178
|
}
|
|
179
179
|
|
|
180
|
-
/*
|
|
181
|
-
|
|
180
|
+
/* A body starts 22px under the subtitle, as the Dq dialog boards draw a
|
|
181
|
+
first field: the header's foot and the body gap alone, so the saved-view
|
|
182
|
+
edit and share forms and the confirm sentence pad nothing on top
|
|
183
|
+
(r29 on :8080: 28, 28 and 26px with their own padding). */
|
|
182
184
|
.cn-dialog-board .dialog__content .cn-edit-view,
|
|
183
|
-
.cn-dialog-board .dialog__content .cn-share-view
|
|
184
|
-
|
|
185
|
+
.cn-dialog-board .dialog__content .cn-share-view,
|
|
186
|
+
.cn-dialog-board .dialog__content .cn-confirm__confirm {
|
|
187
|
+
padding-top: 0;
|
|
185
188
|
}
|
|
186
189
|
|
|
187
190
|
/* The close button is a 36px circle. NcButton sizes an icon-only button by
|
|
@@ -218,7 +221,9 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
218
221
|
10px 14px padding, the checkbox row at the 24px minimum target instead of
|
|
219
222
|
NcCheckboxRadioSwitch's 34px, the note at 1.2 line height; the card's
|
|
220
223
|
corners 8px and the label on an 18px line, as the board draws them. */
|
|
221
|
-
|
|
224
|
+
/* `.dialog` outranks the component's scoped rule (class + attribute), which
|
|
225
|
+
loads after this sheet and kept 12px 14px and 12px corners on :8080 (r29). */
|
|
226
|
+
.cn-dialog-board .dialog .cn-assign-dialog__toggle {
|
|
222
227
|
padding: 10px 14px;
|
|
223
228
|
border-radius: 8px;
|
|
224
229
|
}
|
|
@@ -272,6 +277,13 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
272
277
|
border-top: 1px solid var(--color-border);
|
|
273
278
|
}
|
|
274
279
|
|
|
280
|
+
/* NcDialog's scoped `.dialog__actions[data-v-…]` margin (6px 0 12px) has the
|
|
281
|
+
rule above's specificity and, loaded later, put the footer 6px low under the
|
|
282
|
+
body (DqVolgendeStap). This one outranks it. */
|
|
283
|
+
.cn-dialog-board .dialog .dialog__actions {
|
|
284
|
+
margin: 0;
|
|
285
|
+
}
|
|
286
|
+
|
|
275
287
|
.cn-dialog-board .dialog__actions .button-vue,
|
|
276
288
|
.cn-dialog-board .dialog__actions button {
|
|
277
289
|
min-height: var(--cn-board-control-height, 40px);
|
|
@@ -347,10 +359,14 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
347
359
|
border and radius 8 (PlanItemDialog, DqWerkvoorraad). NcInputField draws
|
|
348
360
|
its border as a 65%-transparent shadow, which on the white dialog read as
|
|
349
361
|
an empty band, and floats its label inside the border. A field with
|
|
350
|
-
`labelOutside` keeps the app's own label and takes the same control.
|
|
362
|
+
`labelOutside` keeps the app's own label and takes the same control. The
|
|
363
|
+
label's box starts where the field starts and the control 23px under it,
|
|
364
|
+
as on every dialog board (72 fields on 11 boards): the label at the font's
|
|
365
|
+
normal line, 21px of room plus the control's 2px focus inset, the label
|
|
366
|
+
4px above that room's end. */
|
|
351
367
|
.cn-dialog-board .dialog__content .input-field:has(.input-field__label),
|
|
352
368
|
.cn-dialog-board .dialog__content .textarea:has(.textarea__label) {
|
|
353
|
-
margin-block-start:
|
|
369
|
+
margin-block-start: 21px;
|
|
354
370
|
}
|
|
355
371
|
|
|
356
372
|
/* NcSelect's search is an NcInputField inside the select, and the select's
|
|
@@ -359,7 +375,7 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
359
375
|
select makes the label's room instead.
|
|
360
376
|
@spec openspec/changes/board-dialog-select-label-room/specs/board-dialog-select-label-room/spec.md#requirement-a-board-dialog-select-makes-room-for-its-raised-label */
|
|
361
377
|
.cn-dialog-board .dialog__content .v-select:has(.input-field__label) {
|
|
362
|
-
margin-block-start:
|
|
378
|
+
margin-block-start: 21px;
|
|
363
379
|
}
|
|
364
380
|
|
|
365
381
|
/* A select in a form dialog sits under its label and over its help line
|
|
@@ -420,7 +436,7 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
420
436
|
color: var(--color-main-text);
|
|
421
437
|
font-size: var(--cn-field-label-size, 14px);
|
|
422
438
|
font-weight: 600;
|
|
423
|
-
line-height:
|
|
439
|
+
line-height: normal;
|
|
424
440
|
pointer-events: auto;
|
|
425
441
|
transition: none;
|
|
426
442
|
}
|