@conduction/nextcloud-vue 2.143.0 → 2.144.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 +7 -2
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -1
- package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue2.js.map +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js +1 -1
- package/dist/esm/components/CnConversationThread/CnConversationThread.vue3.js.map +1 -1
- package/dist/esm/components/CnEventsCard/CnEventsCard.vue.js +1 -1
- package/dist/esm/components/CnEventsCard/CnEventsCard.vue2.js +9 -0
- package/dist/esm/components/CnEventsCard/CnEventsCard.vue2.js.map +1 -1
- package/dist/esm/components/CnEventsCard/CnEventsCard.vue3.js +24 -13
- package/dist/esm/components/CnEventsCard/CnEventsCard.vue3.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue.js +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js +2 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue2.js.map +1 -1
- package/dist/esm/components/CnFilesBrowser/CnFilesBrowser.vue3.js.map +1 -1
- package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +3 -1
- 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/CnNotesCard/CnNotesCard.vue.js +1 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js +3 -0
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue2.js.map +1 -1
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue3.js +19 -14
- package/dist/esm/components/CnNotesCard/CnNotesCard.vue3.js.map +1 -1
- package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue.js +1 -1
- package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue2.js +30 -0
- package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue3.js +158 -102
- package/dist/esm/components/CnObjectPartiesWidget/CnObjectPartiesWidget.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 +12 -0
- package/dist/esm/components/CnRetentionWidget/CnRetentionWidget.vue3.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue.js +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js +110 -2
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue2.js.map +1 -1
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js +146 -80
- package/dist/esm/components/CnTasksWidget/CnTasksWidget.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js +45 -0
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js +67 -34
- package/dist/esm/integrations/builtin/calendar/CnCalendarCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue.js +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js +3 -22
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/CnCalendarTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/calendar/eventStatus.js +67 -0
- package/dist/esm/integrations/builtin/calendar/eventStatus.js.map +1 -0
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue.js +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js +39 -0
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js +81 -32
- package/dist/esm/integrations/builtin/deck/CnDeckCard.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue.js +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js +5 -6
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue2.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/CnDeckTab.vue3.js.map +1 -1
- package/dist/esm/integrations/builtin/deck/deckCardParts.js +59 -0
- package/dist/esm/integrations/builtin/deck/deckCardParts.js.map +1 -0
- package/dist/esm/l10n/en.json.js +6 -0
- package/dist/esm/l10n/en.json.js.map +1 -1
- package/dist/esm/l10n/nl.json.js +6 -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 +815 -363
- package/dist/esm/utils/fetchFilterCounts.js +5 -2
- package/dist/esm/utils/fetchFilterCounts.js.map +1 -1
- package/dist/esm/utils/nextcloudDirectory.js +19 -6
- package/dist/esm/utils/nextcloudDirectory.js.map +1 -1
- package/dist/nextcloud-vue.cjs.js +1347 -758
- package/dist/nextcloud-vue.cjs.js.map +2 -2
- package/dist/nextcloud-vue.css +815 -363
- package/l10n/en.json +6 -0
- package/l10n/nl.json +6 -0
- package/package.json +1 -1
- package/src/components/CnActionDialog/CnActionDialog.vue +28 -3
- package/src/components/CnConversationThread/CnConversationThread.vue +5 -2
- package/src/components/CnEventsCard/CnEventsCard.vue +27 -5
- package/src/components/CnFilesBrowser/CnFilesBrowser.vue +15 -1
- package/src/components/CnIndexPage/CnIndexPage.vue +3 -1
- package/src/components/CnNotesCard/CnNotesCard.vue +8 -0
- package/src/components/CnObjectPartiesWidget/CnObjectPartiesWidget.vue +114 -46
- package/src/components/CnRetentionWidget/CnRetentionWidget.vue +26 -1
- package/src/components/CnTasksWidget/CnTasksWidget.vue +170 -13
- package/src/css/dialog.css +7 -1
- package/src/css/kpi-card.css +3 -0
- package/src/css/look-board-detail.css +317 -0
- package/src/css/look-board-index.css +14 -0
- package/src/css/look-board.css +25 -0
- package/src/integrations/builtin/calendar/CnCalendarCard.vue +76 -11
- package/src/integrations/builtin/calendar/CnCalendarTab.vue +3 -22
- package/src/integrations/builtin/calendar/__tests__/CnCalendarCardBoardRows.spec.js +52 -0
- package/src/integrations/builtin/calendar/eventStatus.js +63 -0
- package/src/integrations/builtin/deck/CnDeckCard.vue +66 -0
- package/src/integrations/builtin/deck/CnDeckTab.vue +5 -6
- package/src/integrations/builtin/deck/__tests__/CnDeckCardBoardRows.spec.js +49 -0
- package/src/integrations/builtin/deck/deckCardParts.js +56 -0
- package/src/utils/fetchFilterCounts.js +5 -2
- package/src/utils/nextcloudDirectory.js +19 -6
package/l10n/en.json
CHANGED
|
@@ -1706,6 +1706,12 @@
|
|
|
1706
1706
|
"expires {date}": "expires {date}",
|
|
1707
1707
|
"Loading …": "Loading …",
|
|
1708
1708
|
"Reorder {item}: drag, or press the up and down arrow keys": "Reorder {item}: drag, or press the up and down arrow keys",
|
|
1709
|
+
"Board {name}": "Board {name}",
|
|
1710
|
+
"list {name}": "list {name}",
|
|
1711
|
+
"Tentative": "Tentative",
|
|
1712
|
+
"Confirmed": "Confirmed",
|
|
1713
|
+
"Cancelled": "Cancelled",
|
|
1714
|
+
"{start} until {end}": "{start} until {end}",
|
|
1709
1715
|
"No contacts linked": "No contacts linked",
|
|
1710
1716
|
"No relations yet": "No relations yet",
|
|
1711
1717
|
"Period": "Period",
|
package/l10n/nl.json
CHANGED
|
@@ -1919,6 +1919,12 @@
|
|
|
1919
1919
|
"Made {date}": "Gemaakt {date}",
|
|
1920
1920
|
"expires {date}": "verloopt {date}",
|
|
1921
1921
|
"Reorder {item}: drag, or press the up and down arrow keys": "{item} verplaatsen: slepen, of de pijltoetsen omhoog en omlaag",
|
|
1922
|
+
"Board {name}": "Bord {name}",
|
|
1923
|
+
"list {name}": "lijst {name}",
|
|
1924
|
+
"Tentative": "Voorlopig",
|
|
1925
|
+
"Confirmed": "Bevestigd",
|
|
1926
|
+
"Cancelled": "Geannuleerd",
|
|
1927
|
+
"{start} until {end}": "{start} tot {end}",
|
|
1922
1928
|
"No contacts linked": "Geen contacten gekoppeld",
|
|
1923
1929
|
"No relations yet": "Nog geen relaties",
|
|
1924
1930
|
"Period": "Periode",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@conduction/nextcloud-vue",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.144.0",
|
|
4
4
|
"description": "Shared Vue component library for Conduction Nextcloud apps — complements @nextcloud/vue with higher-level components, OpenRegister integration, and NL Design System support",
|
|
5
5
|
"homepage": "https://github.com/ConductionNL/nextcloud-vue#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -191,6 +191,7 @@ import CircleOutline from 'vue-material-design-icons/CircleOutline.vue'
|
|
|
191
191
|
import HelpCircleOutline from 'vue-material-design-icons/HelpCircleOutline.vue'
|
|
192
192
|
import CnFormField from '../CnFormField/CnFormField.vue'
|
|
193
193
|
import { fetchEndpointSource, interpolateUrlTokens } from '../../composables/useEndpointSource.js'
|
|
194
|
+
import { BUILT_IN_FORMATTERS } from '../../utils/builtInFormatters.js'
|
|
194
195
|
import { fillTemplate } from '../../utils/fillTemplate.js'
|
|
195
196
|
import { readPath } from '../../utils/readPath.js'
|
|
196
197
|
import { CnDialog } from '../CnDialog/index.js'
|
|
@@ -219,7 +220,8 @@ let reasonSeq = 0
|
|
|
219
220
|
* `eyebrow` a template filled from the record ("Close off · {identifier}").
|
|
220
221
|
* - `summary`: `{ source?, title, meta?, badge?, icon? }`: templates filled from
|
|
221
222
|
* the record (`source` an endpointSource to read it from, else `object`).
|
|
222
|
-
* - `facts`: `[{ title?, items: [{ label, value }] }]`, `value` a template
|
|
223
|
+
* - `facts`: `[{ title?, items: [{ label, value }] }]`, `value` a template; a
|
|
224
|
+
* `{path|<formatter>}` token reads through the built-in and app formatters.
|
|
223
225
|
* - `checklist`: `{ title?, source, itemsPath?, labels?, required? }`: items
|
|
224
226
|
* `{ id, met, label?, detail? }` read from `source`; `labels[id]` gives an
|
|
225
227
|
* item's `{ label, detail?, unmetDetail? }`; the ids in `required` must be
|
|
@@ -262,6 +264,8 @@ export default {
|
|
|
262
264
|
cnTranslate: { default: () => (key) => key },
|
|
263
265
|
/** The page's pre-bound action dispatcher (CnPageRenderer), for `confirm.action`. */
|
|
264
266
|
cnDispatchAction: { default: null },
|
|
267
|
+
/** The app's named formatters (CnAppRoot), for `{path|<formatter>}` in a template. */
|
|
268
|
+
cnFormatters: { default: () => ({}) },
|
|
265
269
|
},
|
|
266
270
|
|
|
267
271
|
props: {
|
|
@@ -594,7 +598,8 @@ export default {
|
|
|
594
598
|
if (typeof template !== 'string' || template === '') {
|
|
595
599
|
return ''
|
|
596
600
|
}
|
|
597
|
-
|
|
601
|
+
const formatters = { ...BUILT_IN_FORMATTERS, ...(this.cnFormatters || {}) }
|
|
602
|
+
return fillTemplate(this.cnTranslate(template), row || this.record || {}, new Date(), { formatters }).trim()
|
|
598
603
|
},
|
|
599
604
|
|
|
600
605
|
/**
|
|
@@ -836,6 +841,7 @@ export default {
|
|
|
836
841
|
.cn-action-dialog__summary-text strong {
|
|
837
842
|
font-size: 15px;
|
|
838
843
|
font-weight: 600;
|
|
844
|
+
line-height: 1.2;
|
|
839
845
|
}
|
|
840
846
|
|
|
841
847
|
.cn-action-dialog__summary-text .cn-action-dialog__muted {
|
|
@@ -949,7 +955,25 @@ export default {
|
|
|
949
955
|
padding: 12px 14px;
|
|
950
956
|
border: 2px solid var(--color-primary-element);
|
|
951
957
|
border-radius: var(--border-radius-element, 8px);
|
|
952
|
-
background: var(--color-
|
|
958
|
+
background: var(--color-main-background);
|
|
959
|
+
}
|
|
960
|
+
|
|
961
|
+
/* The box sits at the card's inset, 12px before the label, the label on
|
|
962
|
+
its first line (DqArchiveren "Sanne de Vries laten weten ..."):
|
|
963
|
+
NcCheckboxRadioSwitch pads its row and centres a 34px target. */
|
|
964
|
+
.cn-action-dialog__checkbox :deep(.checkbox-content) {
|
|
965
|
+
padding: 0;
|
|
966
|
+
gap: 12px;
|
|
967
|
+
align-items: flex-start;
|
|
968
|
+
min-height: 0;
|
|
969
|
+
}
|
|
970
|
+
|
|
971
|
+
.cn-action-dialog__checkbox :deep(.checkbox-content__icon) {
|
|
972
|
+
margin: 0;
|
|
973
|
+
}
|
|
974
|
+
|
|
975
|
+
.cn-action-dialog__checkbox :deep(.checkbox-radio-switch__input) {
|
|
976
|
+
min-height: 0;
|
|
953
977
|
}
|
|
954
978
|
|
|
955
979
|
.cn-action-dialog__checkbox-text {
|
|
@@ -961,6 +985,7 @@ export default {
|
|
|
961
985
|
.cn-action-dialog__checkbox-label {
|
|
962
986
|
font-size: 15px;
|
|
963
987
|
font-weight: 600;
|
|
988
|
+
line-height: 1.2;
|
|
964
989
|
}
|
|
965
990
|
|
|
966
991
|
.cn-action-dialog__checkbox .cn-action-dialog__muted {
|
|
@@ -17,9 +17,11 @@
|
|
|
17
17
|
class="cn-conversation-thread__title">
|
|
18
18
|
{{ title }}
|
|
19
19
|
</component>
|
|
20
|
-
<p
|
|
20
|
+
<!-- A div, not a <p>: a theme that sets every paragraph's size with
|
|
21
|
+
!important would otherwise override the 14px subtitle. -->
|
|
22
|
+
<div v-if="subtitle" class="cn-conversation-thread__subtitle" data-testid="cn-conversation-subtitle">
|
|
21
23
|
{{ subtitle }}
|
|
22
|
-
</
|
|
24
|
+
</div>
|
|
23
25
|
</div>
|
|
24
26
|
<div v-if="$slots['header-actions']" class="cn-conversation-thread__header-actions">
|
|
25
27
|
<!-- @slot header-actions Buttons beside the title, for example "Log contact". -->
|
|
@@ -633,6 +635,7 @@ export default {
|
|
|
633
635
|
.cn-conversation-thread__subtitle {
|
|
634
636
|
color: var(--color-text-maxcontrast);
|
|
635
637
|
font-size: 14px;
|
|
638
|
+
line-height: normal;
|
|
636
639
|
margin: 0;
|
|
637
640
|
}
|
|
638
641
|
|
|
@@ -28,9 +28,12 @@
|
|
|
28
28
|
:key="keyOf(event, index)"
|
|
29
29
|
class="cn-events-card__event"
|
|
30
30
|
data-testid="cn-events-card-event">
|
|
31
|
-
<span class="cn-events-
|
|
32
|
-
<span class="cn-events-
|
|
33
|
-
|
|
31
|
+
<span v-if="dayOf(event)" class="cn-events-card__day" aria-hidden="true">{{ dayOf(event) }}</span>
|
|
32
|
+
<span class="cn-events-card__text">
|
|
33
|
+
<span class="cn-events-card__summary">{{ summaryOf(event) }}</span>
|
|
34
|
+
<span class="cn-events-card__when">{{ whenOf(event) }}</span>
|
|
35
|
+
<span v-if="event.location" class="cn-events-card__where">{{ event.location }}</span>
|
|
36
|
+
</span>
|
|
34
37
|
</li>
|
|
35
38
|
</ul>
|
|
36
39
|
<p v-else class="cn-events-card__muted" data-testid="cn-events-card-empty">
|
|
@@ -292,6 +295,15 @@ export default {
|
|
|
292
295
|
return summary === '' ? t('nextcloud-vue', 'Appointment') : summary
|
|
293
296
|
},
|
|
294
297
|
|
|
298
|
+
/**
|
|
299
|
+
* @param {object} event The event.
|
|
300
|
+
* @return {string} The day of the month it starts on, '' when it has no readable start.
|
|
301
|
+
*/
|
|
302
|
+
dayOf(event) {
|
|
303
|
+
const parsed = new Date(String(event?.dtstart ?? '').trim())
|
|
304
|
+
return Number.isNaN(parsed.getTime()) ? '' : String(parsed.getDate())
|
|
305
|
+
},
|
|
306
|
+
|
|
295
307
|
/**
|
|
296
308
|
* @param {object} event The event.
|
|
297
309
|
* @return {string} When it is: its start and end, or whichever it has.
|
|
@@ -333,8 +345,7 @@ function formatMoment(value) {
|
|
|
333
345
|
|
|
334
346
|
.cn-events-card__event {
|
|
335
347
|
display: flex;
|
|
336
|
-
|
|
337
|
-
gap: 2px;
|
|
348
|
+
gap: 12px;
|
|
338
349
|
padding-bottom: 8px;
|
|
339
350
|
border-bottom: 1px solid var(--color-border);
|
|
340
351
|
}
|
|
@@ -344,6 +355,17 @@ function formatMoment(value) {
|
|
|
344
355
|
border-bottom: none;
|
|
345
356
|
}
|
|
346
357
|
|
|
358
|
+
.cn-events-card__day {
|
|
359
|
+
display: none;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.cn-events-card__text {
|
|
363
|
+
display: flex;
|
|
364
|
+
flex-direction: column;
|
|
365
|
+
gap: 2px;
|
|
366
|
+
min-width: 0;
|
|
367
|
+
}
|
|
368
|
+
|
|
347
369
|
.cn-events-card__summary {
|
|
348
370
|
font-weight: 600;
|
|
349
371
|
}
|
|
@@ -2178,7 +2178,8 @@ export default {
|
|
|
2178
2178
|
const object = {
|
|
2179
2179
|
...entry,
|
|
2180
2180
|
name: node.basename,
|
|
2181
|
-
|
|
2181
|
+
// A template drops an object value, so the Date is handed over as ISO text.
|
|
2182
|
+
modified: node.mtime instanceof Date ? node.mtime.toISOString() : node.mtime,
|
|
2182
2183
|
size: this.formatSize(node.size),
|
|
2183
2184
|
type: this.typeLabelOf(node),
|
|
2184
2185
|
...(owner ? { owner } : {}),
|
|
@@ -3648,6 +3649,19 @@ export default {
|
|
|
3648
3649
|
width: auto;
|
|
3649
3650
|
}
|
|
3650
3651
|
|
|
3652
|
+
/* The row button and the row menu stand side by side on one line, not
|
|
3653
|
+
stacked (DqZaakDocumenten: Beoordelen, then the menu, 14px apart).
|
|
3654
|
+
@spec openspec/changes/files-row-button-beside-menu/specs/files-row-button-beside-menu/spec.md#requirement-a-files-row-button-stands-beside-the-row-menu */
|
|
3655
|
+
.cn-files-browser__col-actions > .cn-files-browser__row-button,
|
|
3656
|
+
.cn-files-browser__col-actions > .cn-files-browser__row-menu {
|
|
3657
|
+
display: inline-flex;
|
|
3658
|
+
vertical-align: middle;
|
|
3659
|
+
}
|
|
3660
|
+
|
|
3661
|
+
.cn-files-browser__col-actions > .cn-files-browser__row-button + .cn-files-browser__row-menu {
|
|
3662
|
+
margin-inline-start: 14px;
|
|
3663
|
+
}
|
|
3664
|
+
|
|
3651
3665
|
.cn-files-browser__col-name {
|
|
3652
3666
|
min-width: 0;
|
|
3653
3667
|
}
|
|
@@ -9993,7 +9993,7 @@ export default {
|
|
|
9993
9993
|
]
|
|
9994
9994
|
let counts
|
|
9995
9995
|
try {
|
|
9996
|
-
counts = await fetchFilterCounts({ register: this.register, schema, entries, baseFilter: base, ctx })
|
|
9996
|
+
counts = await fetchFilterCounts({ register: this.register, schema, entries, baseFilter: base, ctx, via: 'list' })
|
|
9997
9997
|
} catch {
|
|
9998
9998
|
counts = {}
|
|
9999
9999
|
}
|
|
@@ -10050,6 +10050,8 @@ export default {
|
|
|
10050
10050
|
})),
|
|
10051
10051
|
baseFilter: resolveFilterMap(this.filter, params, ctx),
|
|
10052
10052
|
ctx,
|
|
10053
|
+
// The chips count what the list shows: the list's own request.
|
|
10054
|
+
via: 'list',
|
|
10053
10055
|
})
|
|
10054
10056
|
if (requestKey !== this.countRequestKey) {
|
|
10055
10057
|
return
|
|
@@ -96,6 +96,7 @@
|
|
|
96
96
|
:key="row.note.id"
|
|
97
97
|
class="cn-notes-card__note"
|
|
98
98
|
:class="{ 'cn-notes-card__note--reply': row.isReply }">
|
|
99
|
+
<span class="cn-notes-card__initials" aria-hidden="true">{{ initialsOf(getNoteAuthorName(row.note)) }}</span>
|
|
99
100
|
<div class="cn-notes-card__note-header">
|
|
100
101
|
<CnUserActionMenu
|
|
101
102
|
v-if="!isCurrentUser(row.note)"
|
|
@@ -175,6 +176,7 @@ import CnUserActionMenu from '../CnUserActionMenu/CnUserActionMenu.vue'
|
|
|
175
176
|
import CnVisibilityChip from '../CnVisibilityChip/CnVisibilityChip.vue'
|
|
176
177
|
import { useFileComments } from '../../composables/useFileComments.js'
|
|
177
178
|
import { buildHeaders, prefixUrl } from '../../utils/index.js'
|
|
179
|
+
import { initialsOf } from '../../utils/initials.js'
|
|
178
180
|
import { leafSourceUrl } from '../../utils/leafSourceUrl.js'
|
|
179
181
|
import { extractMentionedGroupIds, extractMentionedIds } from '../../utils/mentions.js'
|
|
180
182
|
import { quoteFor, supportsReplies, threadNotes, threadRootId } from '../../utils/noteThreads.js'
|
|
@@ -635,6 +637,8 @@ export default {
|
|
|
635
637
|
return note.actorId || note.author || ''
|
|
636
638
|
},
|
|
637
639
|
|
|
640
|
+
initialsOf,
|
|
641
|
+
|
|
638
642
|
getNoteAuthorName(note) {
|
|
639
643
|
return note.actorDisplayName || note.author || 'Unknown'
|
|
640
644
|
},
|
|
@@ -870,6 +874,10 @@ export default {
|
|
|
870
874
|
border-bottom: none;
|
|
871
875
|
}
|
|
872
876
|
|
|
877
|
+
.cn-notes-card__initials {
|
|
878
|
+
display: none;
|
|
879
|
+
}
|
|
880
|
+
|
|
873
881
|
.cn-notes-card__note-header {
|
|
874
882
|
display: flex;
|
|
875
883
|
justify-content: space-between;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
-->
|
|
5
5
|
|
|
6
6
|
<template>
|
|
7
|
-
<div class="cn-object-parties" data-testid="cn-object-parties">
|
|
7
|
+
<div class="cn-object-parties" :class="{ 'cn-object-parties--board': isBoard }" data-testid="cn-object-parties">
|
|
8
8
|
<div v-if="canAdd" class="cn-object-parties__manage">
|
|
9
9
|
<NcButton data-testid="cn-object-parties-add" @click="adding = true">
|
|
10
10
|
<template #icon>
|
|
@@ -112,51 +112,89 @@
|
|
|
112
112
|
class="cn-object-parties__party"
|
|
113
113
|
:data-party="party.partyUuid || party.contactUid"
|
|
114
114
|
data-testid="cn-object-parties-party">
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
115
|
+
<!-- The board look draws a party as one ruled row (DqZaakBetrokkenen
|
|
116
|
+
"Rollen"): an initials tile, the name over one meta line that
|
|
117
|
+
names the role, the pills at the end. -->
|
|
118
|
+
<template v-if="isBoard">
|
|
119
|
+
<span class="cn-object-parties__tile" aria-hidden="true">{{ initialsOf(nameOf(party)) }}</span>
|
|
120
|
+
<span class="cn-object-parties__text">
|
|
121
|
+
<span class="cn-object-parties__name">{{ nameOf(party) }}</span>
|
|
122
|
+
<span class="cn-object-parties__meta" data-testid="cn-object-parties-meta">{{ boardMetaOf(party, group) }}</span>
|
|
123
|
+
</span>
|
|
124
|
+
<span class="cn-object-parties__end">
|
|
125
|
+
<span
|
|
126
|
+
v-if="notAccepted(party)"
|
|
127
|
+
class="cn-status-badge cn-status-badge--warning"
|
|
128
|
+
data-testid="cn-object-parties-not-accepted">{{ label('notAccepted') }}</span>
|
|
129
|
+
<span
|
|
130
|
+
v-for="indicator in indicatorsFor(party)"
|
|
131
|
+
:key="`${party.partyUuid}-${indicator.key}`"
|
|
132
|
+
class="cn-status-badge cn-status-badge--default"
|
|
133
|
+
:class="`cn-object-parties__indicator--${indicator.severity}`"
|
|
134
|
+
:data-effect="indicator.effect"
|
|
135
|
+
:title="indicator.verdict"
|
|
136
|
+
data-testid="cn-object-parties-indicator">{{ indicator.label }}</span>
|
|
137
|
+
<NcButton
|
|
138
|
+
v-if="canRemove && party.partyUuid"
|
|
139
|
+
class="cn-object-parties__remove"
|
|
140
|
+
variant="tertiary"
|
|
141
|
+
:aria-label="removeLabel(party, group)"
|
|
142
|
+
:title="removeLabel(party, group)"
|
|
143
|
+
data-testid="cn-object-parties-remove"
|
|
144
|
+
@click="removing = { party, group }">
|
|
145
|
+
<template #icon>
|
|
146
|
+
<TrashCanOutline :size="20" />
|
|
147
|
+
</template>
|
|
148
|
+
</NcButton>
|
|
149
|
+
</span>
|
|
150
|
+
</template>
|
|
151
|
+
<template v-else>
|
|
152
|
+
<span class="cn-object-parties__name">{{ nameOf(party) }}</span>
|
|
153
|
+
<span
|
|
154
|
+
v-if="primary && party.partyUuid === primary"
|
|
155
|
+
class="cn-status-badge cn-status-badge--primary"
|
|
156
|
+
data-testid="cn-object-parties-primary">{{ label('primary') }}</span>
|
|
157
|
+
<span v-if="kindOf(party)" class="cn-object-parties__muted">{{ kindOf(party) }}</span>
|
|
158
|
+
<span
|
|
159
|
+
v-if="notAccepted(party)"
|
|
160
|
+
class="cn-status-badge cn-status-badge--warning"
|
|
161
|
+
data-testid="cn-object-parties-not-accepted">{{ label('notAccepted') }}</span>
|
|
162
|
+
<span
|
|
163
|
+
v-for="(line, index) in extraLinesOf(party)"
|
|
164
|
+
:key="`line-${index}`"
|
|
165
|
+
class="cn-object-parties__muted"
|
|
166
|
+
data-testid="cn-object-parties-extra-line">{{ line }}</span>
|
|
167
|
+
<span v-if="party.email" class="cn-object-parties__muted">{{ party.email }}</span>
|
|
168
|
+
<span
|
|
169
|
+
v-if="representedBy(party)"
|
|
170
|
+
class="cn-object-parties__muted"
|
|
171
|
+
data-testid="cn-object-parties-represented">{{ label('representedBy') }}: {{ representedBy(party) }}</span>
|
|
172
|
+
<span
|
|
173
|
+
v-if="correspondenceOf(party)"
|
|
174
|
+
class="cn-object-parties__muted"
|
|
175
|
+
:data-party-documents="party.partyUuid || party.contactUid"
|
|
176
|
+
data-testid="cn-object-parties-documents">{{ correspondenceOf(party) }}</span>
|
|
177
|
+
<span
|
|
178
|
+
v-for="indicator in indicatorsFor(party)"
|
|
179
|
+
:key="`${party.partyUuid}-${indicator.key}`"
|
|
180
|
+
class="cn-status-badge cn-status-badge--default"
|
|
181
|
+
:class="`cn-object-parties__indicator--${indicator.severity}`"
|
|
182
|
+
:data-effect="indicator.effect"
|
|
183
|
+
:title="indicator.verdict"
|
|
184
|
+
data-testid="cn-object-parties-indicator">{{ indicator.label }} · {{ indicator.verdict }}</span>
|
|
185
|
+
<NcButton
|
|
186
|
+
v-if="canRemove && party.partyUuid"
|
|
187
|
+
class="cn-object-parties__remove"
|
|
188
|
+
variant="tertiary"
|
|
189
|
+
:aria-label="removeLabel(party, group)"
|
|
190
|
+
:title="removeLabel(party, group)"
|
|
191
|
+
data-testid="cn-object-parties-remove"
|
|
192
|
+
@click="removing = { party, group }">
|
|
193
|
+
<template #icon>
|
|
194
|
+
<TrashCanOutline :size="20" />
|
|
195
|
+
</template>
|
|
196
|
+
</NcButton>
|
|
197
|
+
</template>
|
|
160
198
|
</li>
|
|
161
199
|
</ul>
|
|
162
200
|
</section>
|
|
@@ -200,6 +238,7 @@ import TrashCanOutline from 'vue-material-design-icons/TrashCanOutline.vue'
|
|
|
200
238
|
import CnConfirmDialog from '../../dialogs/CnConfirmDialog.vue'
|
|
201
239
|
import CnPartyAddDialog from '../../dialogs/CnPartyAddDialog.vue'
|
|
202
240
|
import { interpolateUrlTokens } from '../../composables/useEndpointSource.js'
|
|
241
|
+
import { normalizeLook } from '../../composables/useLook.js'
|
|
203
242
|
import innerHeading from '../../mixins/innerHeading.js'
|
|
204
243
|
import { conditionalLine } from '../../utils/conditionalLine.js'
|
|
205
244
|
import { initialsOf } from '../../utils/initials.js'
|
|
@@ -287,6 +326,7 @@ export default {
|
|
|
287
326
|
|
|
288
327
|
inject: {
|
|
289
328
|
cnTranslate: { default: () => (key) => key },
|
|
329
|
+
cnLook: { default: 'nextcloud' },
|
|
290
330
|
},
|
|
291
331
|
|
|
292
332
|
props: {
|
|
@@ -347,6 +387,11 @@ export default {
|
|
|
347
387
|
},
|
|
348
388
|
|
|
349
389
|
computed: {
|
|
390
|
+
/** @return {boolean} The board look draws one ruled row per party. */
|
|
391
|
+
isBoard() {
|
|
392
|
+
return normalizeLook(this.cnLook) === 'board'
|
|
393
|
+
},
|
|
394
|
+
|
|
350
395
|
/** @return {Array<object>} The role groups, primary first. */
|
|
351
396
|
groups() {
|
|
352
397
|
return rolesInOrder(this.listing, this.translatedMap(this.content?.roleLabels))
|
|
@@ -916,6 +961,29 @@ export default {
|
|
|
916
961
|
* @param {object} party The listing row.
|
|
917
962
|
* @return {Array<object>}
|
|
918
963
|
*/
|
|
964
|
+
/**
|
|
965
|
+
* The board row's meta line: the primary mark, the role, the kind,
|
|
966
|
+
* whom the party represents, its extra lines, e-mail and documents,
|
|
967
|
+
* separated by middots.
|
|
968
|
+
*
|
|
969
|
+
* @param {object} party The party.
|
|
970
|
+
* @param {object} group Its role group.
|
|
971
|
+
* @return {string}
|
|
972
|
+
*/
|
|
973
|
+
boardMetaOf(party, group) {
|
|
974
|
+
const parts = []
|
|
975
|
+
if (this.primary && party.partyUuid === this.primary) {
|
|
976
|
+
parts.push(this.label('primary'))
|
|
977
|
+
}
|
|
978
|
+
parts.push(group.label, this.kindOf(party))
|
|
979
|
+
const represented = this.representedBy(party)
|
|
980
|
+
if (represented) {
|
|
981
|
+
parts.push(`${this.label('representedBy')}: ${represented}`)
|
|
982
|
+
}
|
|
983
|
+
parts.push(...this.extraLinesOf(party), party.email, this.correspondenceOf(party))
|
|
984
|
+
return parts.filter((part) => typeof part === 'string' && part !== '').join(' · ')
|
|
985
|
+
},
|
|
986
|
+
|
|
919
987
|
indicatorsFor(party) {
|
|
920
988
|
const record = this.partyRecords[party.partyUuid]
|
|
921
989
|
if (!record) {
|
|
@@ -85,6 +85,7 @@
|
|
|
85
85
|
</component>
|
|
86
86
|
<ul class="cn-retention__rows">
|
|
87
87
|
<li v-for="hold in holds" :key="hold.id" class="cn-retention__row">
|
|
88
|
+
<span class="cn-retention__mark cn-retention__mark--hold" aria-hidden="true">LH</span>
|
|
88
89
|
<span class="cn-retention__row-text">
|
|
89
90
|
<span class="cn-retention__row-title">{{ hold.reason || t('nextcloud-vue', 'Legal hold') }}</span>
|
|
90
91
|
<span class="cn-retention__muted">{{ t('nextcloud-vue', 'Placed on {date} by {by}', { date: hold.placedDate, by: hold.placedBy }) }}</span>
|
|
@@ -92,6 +93,7 @@
|
|
|
92
93
|
<CnStatusBadge :label="t('nextcloud-vue', 'Active')" variant="warning" />
|
|
93
94
|
</li>
|
|
94
95
|
<li v-if="holds.length === 0" class="cn-retention__row">
|
|
96
|
+
<span class="cn-retention__mark cn-retention__mark--hold" aria-hidden="true">LH</span>
|
|
95
97
|
<span class="cn-retention__row-text">
|
|
96
98
|
<span class="cn-retention__row-title">{{ t('nextcloud-vue', 'No legal hold') }}</span>
|
|
97
99
|
<span class="cn-retention__muted">{{ t('nextcloud-vue', 'If an objection or appeal runs, destruction is suspended') }}</span>
|
|
@@ -107,6 +109,7 @@
|
|
|
107
109
|
</component>
|
|
108
110
|
<ul class="cn-retention__rows">
|
|
109
111
|
<li class="cn-retention__row">
|
|
112
|
+
<span class="cn-retention__mark" aria-hidden="true">ED</span>
|
|
110
113
|
<span class="cn-retention__row-text">
|
|
111
114
|
<span class="cn-retention__row-title">{{ transfers ? t('nextcloud-vue', 'Goes to the e-Depot') : t('nextcloud-vue', 'Not applicable') }}</span>
|
|
112
115
|
<span class="cn-retention__muted">{{ transfers ? t('nextcloud-vue', 'After the retention period the record is transferred') : t('nextcloud-vue', 'Only records appraised to keep go to the e-Depot') }}</span>
|
|
@@ -643,17 +646,39 @@ export default {
|
|
|
643
646
|
align-items: center;
|
|
644
647
|
justify-content: space-between;
|
|
645
648
|
gap: 12px;
|
|
646
|
-
padding:
|
|
649
|
+
padding: 12px 0;
|
|
647
650
|
border-top: 1px solid var(--color-border);
|
|
648
651
|
}
|
|
649
652
|
|
|
650
653
|
.cn-retention__row-text {
|
|
651
654
|
display: flex;
|
|
655
|
+
flex: 1 1 auto;
|
|
652
656
|
flex-direction: column;
|
|
653
657
|
gap: 2px;
|
|
654
658
|
min-width: 0;
|
|
655
659
|
}
|
|
656
660
|
|
|
661
|
+
/* A round mark before a hold or transfer row: LH (legal hold) on the error
|
|
662
|
+
tint, ED (e-Depot) on the chip ground (DqZaakArchivering). */
|
|
663
|
+
.cn-retention__mark {
|
|
664
|
+
display: inline-flex;
|
|
665
|
+
flex: none;
|
|
666
|
+
align-items: center;
|
|
667
|
+
justify-content: center;
|
|
668
|
+
width: 32px;
|
|
669
|
+
height: 32px;
|
|
670
|
+
border-radius: 16px;
|
|
671
|
+
background: var(--color-background-dark);
|
|
672
|
+
color: var(--color-text-maxcontrast);
|
|
673
|
+
font-size: 12px;
|
|
674
|
+
font-weight: 700;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
.cn-retention__mark--hold {
|
|
678
|
+
background: var(--color-error-light, #fcedec);
|
|
679
|
+
color: var(--color-error-text, #a30000);
|
|
680
|
+
}
|
|
681
|
+
|
|
657
682
|
.cn-retention__row-title {
|
|
658
683
|
font-weight: 600;
|
|
659
684
|
}
|