@conduction/nextcloud-vue 2.141.0 → 2.143.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/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +27 -0
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +1 -1
- package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
- package/dist/esm/components/CnAiCompanion/CnAiChatPanel.vue2.js.map +1 -1
- package/dist/esm/components/CnAiCompanion/CnAiChatPanel.vue3.js +2 -1
- package/dist/esm/components/CnAiCompanion/CnAiChatPanel.vue3.js.map +1 -1
- package/dist/esm/components/CnAiCompanion/CnAiInput.vue2.js +9 -0
- package/dist/esm/components/CnAiCompanion/CnAiInput.vue2.js.map +1 -1
- package/dist/esm/components/CnAiCompanion/CnAiInput.vue3.js +21 -22
- package/dist/esm/components/CnAiCompanion/CnAiInput.vue3.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue.js +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js +29 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue2.js.map +1 -1
- package/dist/esm/components/CnAuditTrailCard/CnAuditTrailCard.vue3.js +28 -13
- 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.map +1 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js +2 -1
- package/dist/esm/components/CnAuditTrailWidget/CnAuditTrailWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue.js +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js +13 -0
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue2.js.map +1 -1
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.vue3.js +3 -3
- package/dist/esm/components/CnCellRenderer/CnCellRenderer.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/CnChoiceCards/CnChoiceCards.vue.js +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
- package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +21 -0
- package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +1 -1
- package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue.js +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue2.js.map +1 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js +2 -1
- package/dist/esm/components/CnDetailWidgetHost/CnDetailWidgetHost.vue3.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +34 -3
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +70 -5
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js +5 -3
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js +17 -4
- package/dist/esm/components/CnFilesBrowser/filesBrowser.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowserColumns.js +21 -1
- package/dist/esm/components/CnFilesBrowser/filesBrowserColumns.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +36 -2
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +2 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js +14 -0
- package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue.js +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js +3 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js +2 -1
- package/dist/esm/components/CnObjectSidebar/CnFilesTab.vue3.js.map +1 -1
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js +6 -1
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js.map +1 -1
- package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js.map +1 -1
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue.js +1 -1
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js +31 -1
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js.map +1 -1
- package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue3.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +12 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js +2 -2
- package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue.js +1 -1
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue.js +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js +4 -0
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue2.js.map +1 -1
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js +18 -8
- package/dist/esm/components/CnTimelineWidget/CnTimelineManage.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue.js +1 -1
- package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue2.js +52 -1
- package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue3.js +119 -65
- package/dist/esm/integrations/builtin/contacts/CnContactsTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +86 -4
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js +67 -5
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
- package/dist/esm/l10n/en.json.js +10 -1
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +12 -3
- package/dist/esm/l10n/nl.json.js.map +1 -1
- package/dist/esm/library-style.js +1 -1
- package/dist/esm/nextcloud-vue.css +976 -592
- package/dist/esm/utils/buildViewTree.js +23 -8
- package/dist/esm/utils/buildViewTree.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +1363 -734
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +976 -592
- package/l10n/en.json +10 -1
- package/l10n/nl.json +12 -3
- package/package.json +1 -1
- package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +28 -1
- package/src/components/CnAiCompanion/CnAiChatPanel.vue +12 -0
- package/src/components/CnAiCompanion/CnAiInput.vue +32 -1
- package/src/components/CnAuditTrailCard/CnAuditTrailCard.vue +34 -4
- package/src/components/CnAuditTrailWidget/CnAuditTrailWidget.vue +1 -0
- package/src/components/CnCellRenderer/CnCellRenderer.vue +15 -1
- package/src/components/CnChecklistRunWidget/CnChecklistRunWidget.vue +8 -0
- package/src/components/CnChoiceCards/CnChoiceCards.vue +1 -0
- package/src/components/CnDataTable/CnDataTable.md +1 -0
- package/src/components/CnDataTable/CnDataTable.vue +22 -1
- package/src/components/CnDetailWidgetHost/CnDetailWidgetHost.vue +1 -0
- package/src/components/CnFactsWidget/CnFactsWidget.vue +34 -3
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +72 -7
- package/src/components/CnFilesBrowser/filesBrowser.js +17 -4
- package/src/components/CnFilesBrowser/filesBrowserColumns.js +20 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +37 -2
- package/src/components/CnIndexPage/useSelfFetchList.js +14 -0
- package/src/components/CnObjectSidebar/CnFilesTab.vue +4 -1
- package/src/components/CnPageHeader/CnHeaderTrail.vue +6 -1
- package/src/components/CnPartyPicker/CnPartyPicker.vue +31 -1
- package/src/components/CnRecordListWidget/CnRecordListWidget.vue +21 -1
- package/src/components/CnSavedViewAlertWidget/CnSavedViewAlertWidget.vue +6 -0
- package/src/components/CnTimelineWidget/CnTimelineManage.vue +10 -1
- package/src/css/dialog.css +18 -0
- package/src/css/look-board-detail.css +126 -0
- package/src/css/look-board-index.css +95 -1
- package/src/css/look-board.css +90 -1
- package/src/integrations/builtin/contacts/CnContactsTab.vue +101 -26
- package/src/integrations/builtin/contacts/__tests__/CnContactsTabBoardRows.spec.js +67 -0
- package/src/integrations/builtin/deck/CnDeckCard.vue +121 -2
- package/src/integrations/builtin/deck/__tests__/CnDeckCardHeaderActions.spec.js +68 -0
- package/src/utils/buildViewTree.js +23 -8
|
@@ -284,15 +284,19 @@ export function indexRowData(data, { path = '', key = 'fileId' } = {}) {
|
|
|
284
284
|
*
|
|
285
285
|
* `visibleIf.extension` lists file extensions (no case, a leading dot is
|
|
286
286
|
* allowed); `visibleIf.mime` lists mime types, where one ending in `/` or
|
|
287
|
-
* `/*` names the whole family.
|
|
288
|
-
*
|
|
289
|
-
* `
|
|
287
|
+
* `/*` names the whole family; `visibleIf.row` maps fields of the host's row
|
|
288
|
+
* for the file to the value each must have (compared strictly, so `true` is
|
|
289
|
+
* not `"true"`). Every condition named must hold. An action without
|
|
290
|
+
* `visibleIf` is offered on every file, as before. An action with `when` is
|
|
291
|
+
* offered only while `when` is `true`.
|
|
290
292
|
*
|
|
291
293
|
* @param {object} action The declared action.
|
|
292
294
|
* @param {object} node The file (`basename`, `mime`).
|
|
295
|
+
* @param {((key: string) => unknown)|null} rowValue Reads a field of the host's row for the file; without it a `row` condition fails.
|
|
293
296
|
* @return {boolean} True when the action belongs on this file.
|
|
297
|
+
* @spec openspec/changes/files-browser-action-visible-if-row/specs/files-browser/spec.md#requirement-a-host-action-can-be-offered-by-a-field-of-the-files-row
|
|
294
298
|
*/
|
|
295
|
-
export function hostActionApplies(action, node) {
|
|
299
|
+
export function hostActionApplies(action, node, rowValue = null) {
|
|
296
300
|
// `when`: the action applies only while it is true (a case type flag).
|
|
297
301
|
// @spec openspec/changes/files-review-row-when/specs/files-review-row-when/spec.md#requirement-a-files-browser-entry-can-apply-only-when-a-condition-holds
|
|
298
302
|
if (action && typeof action === 'object' && 'when' in action && action.when !== true) {
|
|
@@ -324,5 +328,14 @@ export function hostActionApplies(action, node) {
|
|
|
324
328
|
return false
|
|
325
329
|
}
|
|
326
330
|
}
|
|
331
|
+
if (condition.row && typeof condition.row === 'object') {
|
|
332
|
+
if (typeof rowValue !== 'function') {
|
|
333
|
+
return false
|
|
334
|
+
}
|
|
335
|
+
const holds = Object.entries(condition.row).every(([key, wanted]) => rowValue(key) === wanted)
|
|
336
|
+
if (!holds) {
|
|
337
|
+
return false
|
|
338
|
+
}
|
|
339
|
+
}
|
|
327
340
|
return true
|
|
328
341
|
}
|
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
import { isAppInstalled } from '../../utils/appInstalled.js'
|
|
7
|
+
|
|
6
8
|
/**
|
|
7
9
|
* The built-in columns a host may name by string, and what each one reads.
|
|
8
10
|
*
|
|
@@ -53,12 +55,26 @@ export function isBuiltInFileColumn(name) {
|
|
|
53
55
|
return typeof name === 'string' && Object.hasOwn(BUILT_IN_FILE_COLUMNS, name)
|
|
54
56
|
}
|
|
55
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Whether the app a column leans on is enabled: one app id, or a list of which
|
|
60
|
+
* any one will do. A column without `requiredApp` always applies.
|
|
61
|
+
*
|
|
62
|
+
* @param {(string|string[]|undefined)} requiredApp The app id(s).
|
|
63
|
+
* @return {boolean} True when the column applies.
|
|
64
|
+
* @spec openspec/changes/files-column-required-app/specs/files-column-required-app/spec.md#requirement-a-file-column-can-require-another-app
|
|
65
|
+
*/
|
|
66
|
+
function requiredAppPresent(requiredApp) {
|
|
67
|
+
const ids = (Array.isArray(requiredApp) ? requiredApp : [requiredApp]).filter((id) => typeof id === 'string' && id !== '')
|
|
68
|
+
return ids.length === 0 || ids.some((id) => isAppInstalled(id))
|
|
69
|
+
}
|
|
70
|
+
|
|
56
71
|
/**
|
|
57
72
|
* Resolve a host's `columns` declaration into column objects.
|
|
58
73
|
*
|
|
59
74
|
* A string names a built-in. An object declares its own: `key`, `label`,
|
|
60
75
|
* `source` (`node`, `attribute` or `row`), `attribute`, `formatter` and
|
|
61
|
-
* `sortable
|
|
76
|
+
* `sortable`, and `requiredApp` (an app id, or a list of which any one will
|
|
77
|
+
* do; without it the column is left out). An entry naming an unknown built-in is dropped here and refused
|
|
62
78
|
* by the manifest validator, so an author hears about it at authoring time
|
|
63
79
|
* rather than finding a column missing at runtime.
|
|
64
80
|
*
|
|
@@ -83,6 +99,9 @@ export function normaliseFileColumns(columns) {
|
|
|
83
99
|
if ('when' in entry && entry.when !== true) {
|
|
84
100
|
return
|
|
85
101
|
}
|
|
102
|
+
if (!requiredAppPresent(entry.requiredApp)) {
|
|
103
|
+
return
|
|
104
|
+
}
|
|
86
105
|
if (isBuiltInFileColumn(entry.key) && entry.source === undefined) {
|
|
87
106
|
out.push({ ...BUILT_IN_FILE_COLUMNS[entry.key], ...entry, builtIn: true })
|
|
88
107
|
return
|
|
@@ -875,6 +875,7 @@
|
|
|
875
875
|
:columns="renderedColumns"
|
|
876
876
|
:pinnedCount="pinnedColumnCount"
|
|
877
877
|
:rowIcon="rowIcon"
|
|
878
|
+
:rowIconTone="rowIconTone"
|
|
878
879
|
:rowIndicators="rowIndicators"
|
|
879
880
|
:rowIndicatorCap="rowIndicatorCap"
|
|
880
881
|
:rows="displayObjects"
|
|
@@ -3185,6 +3186,17 @@ export default {
|
|
|
3185
3186
|
default: null,
|
|
3186
3187
|
},
|
|
3187
3188
|
|
|
3189
|
+
/**
|
|
3190
|
+
* The leading icon's tile tone in the board look (`primary`, `teal`,
|
|
3191
|
+
* `neutral`), from `pages[].config.rowIconTone`. Forwarded to CnDataTable.
|
|
3192
|
+
*
|
|
3193
|
+
* @type {string}
|
|
3194
|
+
*/
|
|
3195
|
+
rowIconTone: {
|
|
3196
|
+
type: String,
|
|
3197
|
+
default: 'primary',
|
|
3198
|
+
},
|
|
3199
|
+
|
|
3188
3200
|
/** Columns to exclude in schema mode */
|
|
3189
3201
|
excludeColumns: {
|
|
3190
3202
|
type: Array,
|
|
@@ -6422,6 +6434,7 @@ export default {
|
|
|
6422
6434
|
r: this.register,
|
|
6423
6435
|
s: this.exportSchemaSlug,
|
|
6424
6436
|
f: this.filter || null,
|
|
6437
|
+
a: this.effectiveActiveFilters || null,
|
|
6425
6438
|
e: this.countEntries,
|
|
6426
6439
|
// The store's total, not the error override in effectivePagination,
|
|
6427
6440
|
// so a failed fetch and its recovery do not refetch the counts.
|
|
@@ -8504,7 +8517,9 @@ export default {
|
|
|
8504
8517
|
return [
|
|
8505
8518
|
...this.searchTermChips,
|
|
8506
8519
|
...this.quickFilterActiveChips,
|
|
8507
|
-
|
|
8520
|
+
// The folder pane's own filter is not a chip: the selected folder
|
|
8521
|
+
// shows in the pane and as the heading above the list (DqAfdelingen).
|
|
8522
|
+
...this.filterChipsOf(this.effectiveActiveFilters, (key, value) => this.isFixedFilter(key, value) || ownToView(key, value) || this.isFolderFilter(key)),
|
|
8508
8523
|
]
|
|
8509
8524
|
},
|
|
8510
8525
|
|
|
@@ -9690,6 +9705,18 @@ export default {
|
|
|
9690
9705
|
* @return {boolean}
|
|
9691
9706
|
* @spec openspec/changes/index-scope-presentation/specs/index-page/spec.md#requirement-the-query-that-chose-a-preset-is-not-a-removable-filter
|
|
9692
9707
|
*/
|
|
9708
|
+
/**
|
|
9709
|
+
* Whether a filter key is the folder pane's (`folderSidebar.filterField`).
|
|
9710
|
+
*
|
|
9711
|
+
* @param {string} key The filter key.
|
|
9712
|
+
* @return {boolean}
|
|
9713
|
+
* @spec openspec/changes/board-folder-scope-outside-card/specs/index-page/spec.md#requirement-the-selected-folder-heads-the-list-from-outside-its-card
|
|
9714
|
+
*/
|
|
9715
|
+
isFolderFilter(key) {
|
|
9716
|
+
const field = this.folderSidebar && this.folderSidebar.filterField
|
|
9717
|
+
return typeof field === 'string' && field !== '' && key === field
|
|
9718
|
+
},
|
|
9719
|
+
|
|
9693
9720
|
isFixedFilter(key, value) {
|
|
9694
9721
|
const fixed = this.fixedFilters
|
|
9695
9722
|
if (!fixed || !Object.hasOwn(fixed, key)) {
|
|
@@ -10012,7 +10039,15 @@ export default {
|
|
|
10012
10039
|
const counts = await fetchFilterCounts({
|
|
10013
10040
|
register: this.register,
|
|
10014
10041
|
schema,
|
|
10015
|
-
|
|
10042
|
+
// A quick filter counts within the list as filtered (the
|
|
10043
|
+
// active filters, its own field its own); a saved view counts
|
|
10044
|
+
// its own query.
|
|
10045
|
+
entries: this.countEntries.map((entry) => ({
|
|
10046
|
+
key: entry.key,
|
|
10047
|
+
filter: entry.key.startsWith('tab:')
|
|
10048
|
+
? { ...(this.effectiveActiveFilters || {}), ...resolveFilterMap(entry.filter, params, ctx) }
|
|
10049
|
+
: resolveFilterMap(entry.filter, params, ctx),
|
|
10050
|
+
})),
|
|
10016
10051
|
baseFilter: resolveFilterMap(this.filter, params, ctx),
|
|
10017
10052
|
ctx,
|
|
10018
10053
|
})
|
|
@@ -5,7 +5,9 @@ import { useObjectStore } from '../../store/index.js'
|
|
|
5
5
|
// Both filter resolvers live in `utils/routeFilters.js` so CnLogsPage applies
|
|
6
6
|
// the same two grammars (route-param interpolation + `?key=value` deep links)
|
|
7
7
|
// without pulling in this composable's index-only sidebar/subscription wiring.
|
|
8
|
+
import { loadMyTeam } from '../../utils/myTeam.js'
|
|
8
9
|
import { withPersonalLenses } from '../../utils/personalLenses.js'
|
|
10
|
+
import { dropOptionalUnresolved, MY_TEAM_TOKEN, resolveFilterTokens } from '../../utils/resolveFilterTokens.js'
|
|
9
11
|
import { parseSortKeysFromQuery, resolveFilterMap, resolveQueryFilters } from '../../utils/routeFilters.js'
|
|
10
12
|
import { orderToSortKeys } from '../../utils/sortOrder.js'
|
|
11
13
|
|
|
@@ -392,6 +394,18 @@ export function useSelfFetchList(props, instance, inject, extras = {}) {
|
|
|
392
394
|
// a reactive getter so a runtime flip attaches/detaches accordingly.
|
|
393
395
|
// Stores without live-updates support (no `subscribe` action) are a
|
|
394
396
|
// silent no-op inside the composable, keeping this fully inert.
|
|
397
|
+
// An address carrying `@myTeam` (a shared link) waits for the team, as a
|
|
398
|
+
// saved view on it does: once read, the token becomes the team, or goes
|
|
399
|
+
// for a reader in none.
|
|
400
|
+
const carriesMyTeam = Object.values(initialActiveFilters || {})
|
|
401
|
+
.some((value) => value === MY_TEAM_TOKEN || (Array.isArray(value) && value.includes(MY_TEAM_TOKEN)))
|
|
402
|
+
if (carriesMyTeam) {
|
|
403
|
+
loadMyTeam().then(() => {
|
|
404
|
+
list.activeFilters.value = dropOptionalUnresolved(resolveFilterTokens(list.activeFilters.value, tokenCtx()))
|
|
405
|
+
list.refresh(1)
|
|
406
|
+
})
|
|
407
|
+
}
|
|
408
|
+
|
|
395
409
|
useObjectSubscription(objectStore, () => objectType.value, null, {
|
|
396
410
|
enabled: () => props.subscribe !== false,
|
|
397
411
|
})
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
:dropOverlay="dropOverlay"
|
|
17
17
|
:dropLabel="dropLabel"
|
|
18
18
|
:dropDetail="dropDetail"
|
|
19
|
+
:dropDetailValues="dropDetailValues"
|
|
19
20
|
:dropHint="dropHint"
|
|
20
21
|
:rowActions="rowActions"
|
|
21
22
|
:newActions="newActions"
|
|
@@ -360,7 +361,9 @@ export default {
|
|
|
360
361
|
/** Forwarded to CnFilesBrowser: the drop state's line ("Laat los om toe te voegen"); the library's own without it. */
|
|
361
362
|
dropLabel: { type: String, default: undefined },
|
|
362
363
|
/** Forwarded to CnFilesBrowser: the drop state's second line, `{count}` the files dragged; it also makes the overlay fill the panel. */
|
|
363
|
-
dropDetail: { type: String, default: '' },
|
|
364
|
+
dropDetail: { type: [String, Array], default: '' },
|
|
365
|
+
/** Forwarded to CnFilesBrowser: named values filled into `dropDetail`. */
|
|
366
|
+
dropDetailValues: { type: Object, default: null },
|
|
364
367
|
/** Forwarded to CnFilesBrowser: "Or drag files onto this list." under the list. */
|
|
365
368
|
dropHint: { type: Boolean, default: false },
|
|
366
369
|
/**
|
|
@@ -99,7 +99,8 @@ export default {
|
|
|
99
99
|
|
|
100
100
|
/**
|
|
101
101
|
* The crumbs for CnBreadcrumbs: each declared crumb as a link, then the
|
|
102
|
-
* current page
|
|
102
|
+
* current page, once (a last crumb that names the page is dropped).
|
|
103
|
+
* Empty without a declared crumb.
|
|
103
104
|
*
|
|
104
105
|
* @spec openspec/changes/page-header-breadcrumb/specs/page-header/spec.md#requirement-a-list-dashboard-or-settings-page-can-show-a-breadcrumb-and-a-meta-note
|
|
105
106
|
* @return {Array<object>}
|
|
@@ -121,6 +122,10 @@ export default {
|
|
|
121
122
|
return entry
|
|
122
123
|
})
|
|
123
124
|
if (this.current) {
|
|
125
|
+
// A last crumb naming the page itself is the current one, drawn once.
|
|
126
|
+
if (out.length > 0 && out[out.length - 1].label === this.current) {
|
|
127
|
+
out.pop()
|
|
128
|
+
}
|
|
124
129
|
out.push({ label: this.current })
|
|
125
130
|
}
|
|
126
131
|
return out
|
|
@@ -52,7 +52,9 @@ const SEARCH_DELAY = 250
|
|
|
52
52
|
* Organisatie · KvK …"). Built on CnSearchSelect.
|
|
53
53
|
*
|
|
54
54
|
* `sources`: each `{ id, register, schema, label?, title?, secondary?,
|
|
55
|
-
* limit?, icon? }` searches OpenRegister with `_search`; `
|
|
55
|
+
* limit?, icon?, lookup? }` searches OpenRegister with `_search`; `lookup`
|
|
56
|
+
* (`{ url, when }`) sends a term matching `when` to the app's exact lookup
|
|
57
|
+
* instead (a POST of `{ term }` answering `{ results }`); `title` and
|
|
56
58
|
* `secondary` are templates filled from the row (default `{name}` / none),
|
|
57
59
|
* `label` names the kind ("Resident") and starts the second line; `label`
|
|
58
60
|
* and `secondary` go through the host translate, so a manifest can write
|
|
@@ -284,6 +286,10 @@ export default {
|
|
|
284
286
|
const { data } = await axios.post(generateUrl('/contactsmenu/contacts'), { filter: term })
|
|
285
287
|
return (data && Array.isArray(data.contacts) ? data.contacts : []).map((c) => this.contactOptionOf(source, c))
|
|
286
288
|
}
|
|
289
|
+
if (this.isExactLookup(source, term) === true) {
|
|
290
|
+
const { data } = await axios.post(generateUrl(source.lookup.url), { term })
|
|
291
|
+
return (data && Array.isArray(data.results) ? data.results : []).map((row) => this.optionOf(source, row))
|
|
292
|
+
}
|
|
287
293
|
if (!source.register || !source.schema) {
|
|
288
294
|
return []
|
|
289
295
|
}
|
|
@@ -311,6 +317,30 @@ export default {
|
|
|
311
317
|
this.searching = false
|
|
312
318
|
},
|
|
313
319
|
|
|
320
|
+
/**
|
|
321
|
+
* Whether a typed term goes to the source's exact lookup instead of the
|
|
322
|
+
* free-text search: `source.lookup` is `{ url, when }`, `when` a regular
|
|
323
|
+
* expression the whole term must match ("^[0-9]{9}$" for a BSN). The
|
|
324
|
+
* lookup is a POST, so the term never sits in a URL or a server log line,
|
|
325
|
+
* and the app behind it may check and record who looked whom up.
|
|
326
|
+
*
|
|
327
|
+
* @param {object} source The source.
|
|
328
|
+
* @param {string} term The typed term.
|
|
329
|
+
* @return {boolean}
|
|
330
|
+
* @spec openspec/changes/party-picker-exact-lookup/specs/party-picker/spec.md#requirement-a-party-source-can-look-a-term-up-exactly
|
|
331
|
+
*/
|
|
332
|
+
isExactLookup(source, term) {
|
|
333
|
+
const lookup = source && source.lookup
|
|
334
|
+
if (!lookup || typeof lookup.url !== 'string' || lookup.url === '' || typeof lookup.when !== 'string') {
|
|
335
|
+
return false
|
|
336
|
+
}
|
|
337
|
+
try {
|
|
338
|
+
return new RegExp(lookup.when).test(term)
|
|
339
|
+
} catch {
|
|
340
|
+
return false
|
|
341
|
+
}
|
|
342
|
+
},
|
|
343
|
+
|
|
314
344
|
/**
|
|
315
345
|
* Name a value the list does not hold: the first OpenRegister source
|
|
316
346
|
* that has an object with that id.
|
|
@@ -194,6 +194,7 @@
|
|
|
194
194
|
<ul
|
|
195
195
|
v-if="group.items.length > 0"
|
|
196
196
|
class="cn-record-list__list"
|
|
197
|
+
:class="{ 'cn-record-list__list--avatar-small': avatarSmall }"
|
|
197
198
|
:aria-labelledby="group.label ? group.headingId : null"
|
|
198
199
|
:data-testid="isGrouped ? 'cn-record-list-group' : null">
|
|
199
200
|
<li
|
|
@@ -635,7 +636,7 @@ function unwrap(value) {
|
|
|
635
636
|
* `rowRoute`, `pageControls`), or `endpointSource` (an app endpoint whose
|
|
636
637
|
* payload, after `responsePath`, is the array of rows, as on the object table), or `objectRows`
|
|
637
638
|
* (`{ path, where?, valuePath? }`: rows the page record holds, such as one answer of a case); `avatar` puts a circle with the initials of a name
|
|
638
|
-
* template before the title; what differs is the drawing: `presentation` is `rows`, `feed`
|
|
639
|
+
* template before the title (`{ text, size: 32 }` draws the 32px circle 12px from the title, as DqZaakBesluiten); what differs is the drawing: `presentation` is `rows`, `feed`
|
|
639
640
|
* or `inline`, and each line is a template (`"{identifier} · {caseTypeName}"`,
|
|
640
641
|
* `"Termijn {deadline|date}"`). `cards` draws a framed card per row in a
|
|
641
642
|
* grid, with `trailing` as the large figure (board ShBank's accounts).
|
|
@@ -831,6 +832,17 @@ export default {
|
|
|
831
832
|
},
|
|
832
833
|
|
|
833
834
|
computed: {
|
|
835
|
+
/**
|
|
836
|
+
* Whether the avatar is the 32px circle (`avatar.size: 32`).
|
|
837
|
+
*
|
|
838
|
+
* @return {boolean}
|
|
839
|
+
* @spec openspec/changes/record-list-avatar-size/specs/record-list-avatar/spec.md#requirement-a-record-list-avatar-can-be-the-small-circle
|
|
840
|
+
*/
|
|
841
|
+
avatarSmall() {
|
|
842
|
+
const avatar = this.content?.avatar
|
|
843
|
+
return Boolean(avatar && typeof avatar === 'object' && Number(avatar.size) === 32)
|
|
844
|
+
},
|
|
845
|
+
|
|
834
846
|
/** @return {boolean} Whether a row's pill comes before its title (`pillAt: "start"`). */
|
|
835
847
|
pillFirst() {
|
|
836
848
|
return this.content?.pillAt === 'start'
|
|
@@ -3068,6 +3080,14 @@ export default {
|
|
|
3068
3080
|
white-space: nowrap;
|
|
3069
3081
|
}
|
|
3070
3082
|
|
|
3083
|
+
/* `avatar.size: 32`: the smaller circle, 12px from the title where the row
|
|
3084
|
+
keeps 16px between its other parts (DqZaakBesluiten Adviezen). */
|
|
3085
|
+
.cn-record-list__list--avatar-small .cn-record-list__avatar {
|
|
3086
|
+
width: 32px;
|
|
3087
|
+
height: 32px;
|
|
3088
|
+
margin-inline-end: -4px;
|
|
3089
|
+
}
|
|
3090
|
+
|
|
3071
3091
|
.cn-record-list__avatar {
|
|
3072
3092
|
align-items: center;
|
|
3073
3093
|
background: var(--color-background-hover);
|
|
@@ -243,6 +243,7 @@ export default {
|
|
|
243
243
|
}
|
|
244
244
|
|
|
245
245
|
.cn-saved-view-alert__facts {
|
|
246
|
+
padding: 0;
|
|
246
247
|
display: grid;
|
|
247
248
|
grid-template-columns: max-content 1fr;
|
|
248
249
|
gap: 6px 16px;
|
|
@@ -280,6 +281,11 @@ export default {
|
|
|
280
281
|
font-weight: 600;
|
|
281
282
|
}
|
|
282
283
|
|
|
284
|
+
/* The switch sits flush with the card edge, as the board draws it. */
|
|
285
|
+
.cn-saved-view-alert :deep(.checkbox-radio-switch__content) {
|
|
286
|
+
padding: 0;
|
|
287
|
+
}
|
|
288
|
+
|
|
283
289
|
.cn-saved-view-alert__switch-text {
|
|
284
290
|
display: flex;
|
|
285
291
|
flex-direction: column;
|
|
@@ -199,13 +199,18 @@
|
|
|
199
199
|
{{ t('nextcloud-vue', 'Goes on the timeline above, internal unless you make it visible') }}
|
|
200
200
|
</p>
|
|
201
201
|
</template>
|
|
202
|
+
<label v-if="textBlocks.length" class="cn-timeline-manage__draft-label" :for="blockId">
|
|
203
|
+
{{ t('nextcloud-vue', 'Template') }}
|
|
204
|
+
</label>
|
|
202
205
|
<NcSelect v-if="textBlocks.length"
|
|
203
206
|
v-model="chosenBlock"
|
|
204
207
|
class="cn-timeline-manage__filter"
|
|
205
208
|
:options="blockOptions"
|
|
206
209
|
:clearable="true"
|
|
207
210
|
label="label"
|
|
208
|
-
:
|
|
211
|
+
:inputId="blockId"
|
|
212
|
+
:labelOutside="true"
|
|
213
|
+
:ariaLabelCombobox="t('nextcloud-vue', 'Template')"
|
|
209
214
|
:placeholder="t('nextcloud-vue', 'Write your own')"
|
|
210
215
|
data-testid="cn-timeline-block"
|
|
211
216
|
@update:modelValue="pickBlock" />
|
|
@@ -437,6 +442,10 @@ export default {
|
|
|
437
442
|
return `cn-timeline-draft-${this.uid}`
|
|
438
443
|
},
|
|
439
444
|
|
|
445
|
+
blockId() {
|
|
446
|
+
return `cn-timeline-block-${this.uid}`
|
|
447
|
+
},
|
|
448
|
+
|
|
440
449
|
/**
|
|
441
450
|
* The kind options, the plain note first. A note is an entry with NO
|
|
442
451
|
* kind, so "Note" filters on its absence.
|
package/src/css/dialog.css
CHANGED
|
@@ -168,13 +168,22 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
168
168
|
goes to those tokens too (DqOverdragen, DqDocumentGenereren). */
|
|
169
169
|
.cn-dialog-header__subtitle {
|
|
170
170
|
--nldesign-component-paragraph-font-size: 14px;
|
|
171
|
+
--nldesign-component-paragraph-line-height: 1.5;
|
|
171
172
|
--nldesign-component-paragraph-color: var(--color-text-maxcontrast);
|
|
172
173
|
--nldesign-color-on-surface: var(--color-text-maxcontrast);
|
|
173
174
|
margin: 4px 0 0;
|
|
174
175
|
font-size: 14px;
|
|
176
|
+
line-height: 1.5;
|
|
175
177
|
color: var(--color-text-maxcontrast);
|
|
176
178
|
}
|
|
177
179
|
|
|
180
|
+
/* The saved-view edit and share forms start 22px under the subtitle, as
|
|
181
|
+
the Dq dialog boards draw a first field: the body's 16px gap and 6px. */
|
|
182
|
+
.cn-dialog-board .dialog__content .cn-edit-view,
|
|
183
|
+
.cn-dialog-board .dialog__content .cn-share-view {
|
|
184
|
+
padding-top: 6px;
|
|
185
|
+
}
|
|
186
|
+
|
|
178
187
|
/* The close button is a 36px circle. NcButton sizes an icon-only button by
|
|
179
188
|
--button-size with `!important`, so the size goes through that; the radius
|
|
180
189
|
also goes to the nldesign theme's button radius token. */
|
|
@@ -539,6 +548,15 @@ body:has(.cn-look-board):not(:has(.cn-look-nextcloud)) .modal-mask {
|
|
|
539
548
|
}
|
|
540
549
|
}
|
|
541
550
|
|
|
551
|
+
/* A choice legend in a board dialog is 14px/600 on the normal line height, as
|
|
552
|
+
the dialog boards draw it (DqDocumentGenereren "Sjabloon").
|
|
553
|
+
@spec openspec/changes/board-choice-legend-type/specs/board-choice-legend-type/spec.md#requirement-a-board-dialogs-choice-legend-is-14px-600-on-the-normal-line-height */
|
|
554
|
+
.cn-dialog-board .cn-choice-cards__legend {
|
|
555
|
+
font-size: 14px;
|
|
556
|
+
font-weight: 600;
|
|
557
|
+
line-height: normal;
|
|
558
|
+
}
|
|
559
|
+
|
|
542
560
|
/* Above a phone the boards top-align a dialog (DqNieuweZaak, DqUwWachtrij,
|
|
543
561
|
DqVolgendeStap: the top edge sits about 90px down at 1440 wide) instead of
|
|
544
562
|
centring it. `--cn-dialog-top` moves it. */
|
|
@@ -842,6 +842,29 @@
|
|
|
842
842
|
display: flex;
|
|
843
843
|
}
|
|
844
844
|
|
|
845
|
+
/* The assistant in the side column (DqZaakAssistent "Assistent") is a panel,
|
|
846
|
+
not a label card: a 17px title over a hairline, 16px 18px in, its pill at
|
|
847
|
+
the row's end, the chat flush under it. */
|
|
848
|
+
.cn-look-board .cn-detail-page__side .cn-widget-wrapper:has(.cn-ai-chat-widget) > .cn-widget-wrapper__header {
|
|
849
|
+
padding: 16px 18px;
|
|
850
|
+
border-bottom: 1px solid var(--color-border);
|
|
851
|
+
}
|
|
852
|
+
|
|
853
|
+
.cn-look-board .cn-detail-page__side .cn-widget-wrapper:has(.cn-ai-chat-widget) .cn-widget-wrapper__title {
|
|
854
|
+
color: var(--color-main-text) !important;
|
|
855
|
+
font-size: var(--cn-board-heading-size, 17px);
|
|
856
|
+
font-weight: 700;
|
|
857
|
+
line-height: 1.2;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
.cn-look-board .cn-detail-page__side .cn-widget-wrapper:has(.cn-ai-chat-widget) .cn-widget-wrapper__actions:has(.cn-detail-widget-header-items) {
|
|
861
|
+
display: flex;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.cn-look-board .cn-detail-page__side .cn-widget-wrapper:has(.cn-ai-chat-widget) > .cn-widget-wrapper__content {
|
|
865
|
+
padding: 0;
|
|
866
|
+
}
|
|
867
|
+
|
|
845
868
|
/* A widget-reported card header action in the main column is a neutral 40px
|
|
846
869
|
control: the main background, the control border, the main text at
|
|
847
870
|
14px/600, a 16px icon 8px before the label (DqZaakBesluiten "Document
|
|
@@ -1431,6 +1454,14 @@
|
|
|
1431
1454
|
display: none;
|
|
1432
1455
|
}
|
|
1433
1456
|
|
|
1457
|
+
/* ---- A file list's trail at its root (CnFilesBrowser) ------------------- */
|
|
1458
|
+
/* At the browser's root the boards draw the bar's buttons only, no trail of
|
|
1459
|
+
one crumb naming the case (DqZaakDocumenten); in a subfolder the trail shows.
|
|
1460
|
+
@spec openspec/changes/board-files-root-crumb/specs/board-files-root-crumb/spec.md#requirement-the-board-files-bar-draws-no-trail-at-the-root */
|
|
1461
|
+
.cn-look-board .cn-files-browser__crumbs--at-root:not(.cn-look-nextcloud *) {
|
|
1462
|
+
display: none;
|
|
1463
|
+
}
|
|
1464
|
+
|
|
1434
1465
|
/* ---- A file list (CnFilesBrowser) --------------------------------------- */
|
|
1435
1466
|
/* The board's compact card table (DqDocumentenBeheer): a near-white header at
|
|
1436
1467
|
14px/600 in the muted ink, 10px 12px; 14px cells, 11px 12px, a hairline
|
|
@@ -1585,6 +1616,49 @@
|
|
|
1585
1616
|
line-height: 1.2;
|
|
1586
1617
|
}
|
|
1587
1618
|
|
|
1619
|
+
/* The contacts tab's rows as DqZaakBetrokkenen "Partijen" draws them: the
|
|
1620
|
+
role heading 15px bold ink in sentence case, each person on a row 12px
|
|
1621
|
+
high-padded under a hairline, the details and the period 13px muted.
|
|
1622
|
+
@spec openspec/changes/board-contacts-rows/specs/contacts/spec.md */
|
|
1623
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__group-title {
|
|
1624
|
+
margin: 6px 0 0;
|
|
1625
|
+
font-size: 15px;
|
|
1626
|
+
font-weight: 700;
|
|
1627
|
+
letter-spacing: 0;
|
|
1628
|
+
text-transform: none;
|
|
1629
|
+
color: var(--color-main-text);
|
|
1630
|
+
}
|
|
1631
|
+
|
|
1632
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__item {
|
|
1633
|
+
align-items: center;
|
|
1634
|
+
padding: 12px 0;
|
|
1635
|
+
border-top: 1px solid var(--cn-board-hairline);
|
|
1636
|
+
border-radius: 0;
|
|
1637
|
+
}
|
|
1638
|
+
|
|
1639
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__item:first-child {
|
|
1640
|
+
margin-top: 8px;
|
|
1641
|
+
}
|
|
1642
|
+
|
|
1643
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__name {
|
|
1644
|
+
font-size: 15px;
|
|
1645
|
+
font-weight: 600;
|
|
1646
|
+
}
|
|
1647
|
+
|
|
1648
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__meta,
|
|
1649
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__period {
|
|
1650
|
+
font-size: 13px;
|
|
1651
|
+
color: var(--color-text-maxcontrast);
|
|
1652
|
+
}
|
|
1653
|
+
|
|
1654
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__period {
|
|
1655
|
+
flex: none;
|
|
1656
|
+
}
|
|
1657
|
+
|
|
1658
|
+
.cn-look-board .cn-contacts-tab .cn-contacts-tab__group {
|
|
1659
|
+
margin-bottom: 8px;
|
|
1660
|
+
}
|
|
1661
|
+
|
|
1588
1662
|
/* The contacts tab inside a detail card (DqZaakBetrokkenen "Partijen") takes
|
|
1589
1663
|
the card's padding instead of its own, and its buttons start at the card's
|
|
1590
1664
|
edge under the subtitle.
|
|
@@ -1596,3 +1670,55 @@
|
|
|
1596
1670
|
.cn-look-board .cn-detail-page__leaf-card .cn-contacts-tab .cn-contacts-tab__header {
|
|
1597
1671
|
justify-content: flex-start;
|
|
1598
1672
|
}
|
|
1673
|
+
|
|
1674
|
+
/* A body card's subtitle as the Dq boards draw it: 14px muted at line
|
|
1675
|
+
height 1.2, 3px under the title, and the content 12px under it.
|
|
1676
|
+
@spec openspec/changes/board-card-subtitle-gaps/specs/board-card/spec.md */
|
|
1677
|
+
.cn-look-board .cn-detail-page .cn-widget-wrapper:not(.cn-detail-page__side *) .cn-widget-wrapper__title-stack:has(> .cn-widget-wrapper__subtitle) {
|
|
1678
|
+
gap: 3px;
|
|
1679
|
+
}
|
|
1680
|
+
|
|
1681
|
+
.cn-look-board .cn-detail-page .cn-widget-wrapper:not(.cn-detail-page__side *) .cn-widget-wrapper__subtitle {
|
|
1682
|
+
font-size: 14px;
|
|
1683
|
+
line-height: 1.2;
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
.cn-look-board .cn-detail-page .cn-widget-wrapper:not(.cn-detail-page__side *):has(> .cn-widget-wrapper__header .cn-widget-wrapper__subtitle) > .cn-widget-wrapper__content {
|
|
1687
|
+
padding-top: 12px;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1690
|
+
/* A checklist (DqTaak): each item an 18-20px box at the card's own inset, the
|
|
1691
|
+
label 10px after it in weight 600, 12px between items, the list 2px below
|
|
1692
|
+
the title block. Nextcloud's checkbox pads its box 7px in and makes every row
|
|
1693
|
+
34px tall, which put the list 7px right and 2px apart too far per item.
|
|
1694
|
+
@spec openspec/changes/board-checklist-rows/specs/checklist-widget/spec.md#requirement-a-board-checklist-sits-at-the-card-inset */
|
|
1695
|
+
.cn-look-board .cn-checklist-widget__items {
|
|
1696
|
+
display: flex;
|
|
1697
|
+
flex-direction: column;
|
|
1698
|
+
gap: 12px;
|
|
1699
|
+
margin-top: 2px;
|
|
1700
|
+
}
|
|
1701
|
+
|
|
1702
|
+
.cn-look-board .cn-checklist-widget__item .checkbox-content {
|
|
1703
|
+
padding: 0;
|
|
1704
|
+
gap: 10px;
|
|
1705
|
+
min-height: 20px;
|
|
1706
|
+
}
|
|
1707
|
+
|
|
1708
|
+
.cn-look-board .cn-checklist-widget__item .checkbox-content.checkbox-content .checkbox-content__icon {
|
|
1709
|
+
margin: 0;
|
|
1710
|
+
}
|
|
1711
|
+
|
|
1712
|
+
.cn-look-board .cn-checklist-widget__item .checkbox-radio-switch__input {
|
|
1713
|
+
min-height: 20px;
|
|
1714
|
+
}
|
|
1715
|
+
|
|
1716
|
+
.cn-look-board .cn-checklist-widget__item .checkbox-content__wrapper,
|
|
1717
|
+
.cn-look-board .cn-checklist-widget__item .checkbox-content__text {
|
|
1718
|
+
line-height: 18px;
|
|
1719
|
+
min-height: 0;
|
|
1720
|
+
}
|
|
1721
|
+
|
|
1722
|
+
.cn-look-board .cn-checklist-widget__item .checkbox-content__text {
|
|
1723
|
+
font-weight: 600;
|
|
1724
|
+
}
|