@conduction/nextcloud-vue 2.91.0 → 2.93.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.
Files changed (149) hide show
  1. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +57 -4
  2. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  3. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js +44 -17
  4. package/dist/esm/components/CnAppRoot/CnAppRoot.vue3.js.map +1 -1
  5. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue.js +1 -1
  6. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js +44 -2
  7. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue2.js.map +1 -1
  8. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js +140 -59
  9. package/dist/esm/components/CnChoiceCards/CnChoiceCards.vue3.js.map +1 -1
  10. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  11. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +20 -6
  12. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  13. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +3 -2
  14. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  15. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +10 -39
  16. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  17. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  18. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js +5 -3
  19. package/dist/esm/components/CnDetailPage/CnDetailPage.vue2.js.map +1 -1
  20. package/dist/esm/components/CnDetailPage/CnDetailPage.vue3.js.map +1 -1
  21. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue.js +1 -1
  22. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js +6 -4
  23. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue2.js.map +1 -1
  24. package/dist/esm/components/CnFactsWidget/CnFactsWidget.vue3.js.map +1 -1
  25. package/dist/esm/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue2.js +46 -0
  26. package/dist/esm/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue2.js.map +1 -1
  27. package/dist/esm/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue3.js +6 -2
  28. package/dist/esm/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue3.js.map +1 -1
  29. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue.js +1 -1
  30. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js +82 -9
  31. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue2.js.map +1 -1
  32. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js +104 -90
  33. package/dist/esm/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue3.js.map +1 -1
  34. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue.js +9 -0
  35. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue.js.map +1 -0
  36. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js +355 -0
  37. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue2.js.map +1 -0
  38. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js +462 -0
  39. package/dist/esm/components/CnFeaturesBoard/CnFeaturesBoard.vue3.js.map +1 -0
  40. package/dist/esm/components/CnFormDialog/CnFormDialog.vue.js +1 -1
  41. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js +39 -10
  42. package/dist/esm/components/CnFormDialog/CnFormDialog.vue2.js.map +1 -1
  43. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js +418 -399
  44. package/dist/esm/components/CnFormDialog/CnFormDialog.vue3.js.map +1 -1
  45. package/dist/esm/components/CnIcon/semanticIcons.js +2 -2
  46. package/dist/esm/components/CnIcon/semanticIcons.js.map +1 -1
  47. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue.js +1 -1
  48. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js +156 -3
  49. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue2.js.map +1 -1
  50. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js +168 -52
  51. package/dist/esm/components/CnLinkCardsPage/CnLinkCardsPage.vue3.js.map +1 -1
  52. package/dist/esm/components/CnModuleCard/CnModuleCard.vue.js +9 -0
  53. package/dist/esm/components/CnModuleCard/CnModuleCard.vue.js.map +1 -0
  54. package/dist/esm/components/CnModuleCard/CnModuleCard.vue2.js +83 -0
  55. package/dist/esm/components/CnModuleCard/CnModuleCard.vue2.js.map +1 -0
  56. package/dist/esm/components/CnModuleCard/CnModuleCard.vue3.js +119 -0
  57. package/dist/esm/components/CnModuleCard/CnModuleCard.vue3.js.map +1 -0
  58. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue.js +1 -1
  59. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue2.js +22 -1
  60. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue2.js.map +1 -1
  61. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue3.js +20 -14
  62. package/dist/esm/components/CnNcWidgetWidget/CnNcWidgetWidget.vue3.js.map +1 -1
  63. package/dist/esm/components/CnNotificationPreferences/CnNotificationPreferences.vue.js +1 -1
  64. package/dist/esm/components/CnNotificationPreferences/CnNotificationPreferences.vue2.js +2 -0
  65. package/dist/esm/components/CnNotificationPreferences/CnNotificationPreferences.vue2.js.map +1 -1
  66. package/dist/esm/components/CnNotificationPreferences/CnNotificationPreferences.vue3.js +15 -5
  67. package/dist/esm/components/CnNotificationPreferences/CnNotificationPreferences.vue3.js.map +1 -1
  68. package/dist/esm/components/CnRoadmapTab/CnRoadmapTab.vue.js +1 -1
  69. package/dist/esm/components/CnRoadmapTab/CnRoadmapTab.vue2.js +8 -30
  70. package/dist/esm/components/CnRoadmapTab/CnRoadmapTab.vue2.js.map +1 -1
  71. package/dist/esm/components/CnRoadmapTab/CnRoadmapTab.vue3.js.map +1 -1
  72. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  73. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +33 -2
  74. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  75. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  76. package/dist/esm/components/CnTextWidget/CnTextWidget.vue.js +1 -1
  77. package/dist/esm/components/CnTextWidget/CnTextWidget.vue2.js +63 -4
  78. package/dist/esm/components/CnTextWidget/CnTextWidget.vue2.js.map +1 -1
  79. package/dist/esm/components/CnTextWidget/CnTextWidget.vue3.js +19 -2
  80. package/dist/esm/components/CnTextWidget/CnTextWidget.vue3.js.map +1 -1
  81. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue.js +9 -0
  82. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue.js.map +1 -0
  83. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js +164 -0
  84. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue2.js.map +1 -0
  85. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js +93 -0
  86. package/dist/esm/components/CnUserSettingsDialog/CnUserSettingsDialog.vue3.js.map +1 -0
  87. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
  88. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +12 -0
  89. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  90. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  91. package/dist/esm/l10n/en.json.js +45 -1
  92. package/dist/esm/l10n/en.json.js.map +1 -1
  93. package/dist/esm/l10n/nl.json.js +44 -1
  94. package/dist/esm/l10n/nl.json.js.map +1 -1
  95. package/dist/esm/library-style.js +1 -1
  96. package/dist/esm/nextcloud-vue.css +1182 -328
  97. package/dist/esm/utils/boardDate.js +35 -1
  98. package/dist/esm/utils/boardDate.js.map +1 -1
  99. package/dist/esm/utils/featureCatalog.js +135 -0
  100. package/dist/esm/utils/featureCatalog.js.map +1 -0
  101. package/dist/esm/utils/fillTemplate.js +84 -4
  102. package/dist/esm/utils/fillTemplate.js.map +1 -1
  103. package/dist/esm/utils/headerMeta.js +62 -12
  104. package/dist/esm/utils/headerMeta.js.map +1 -1
  105. package/dist/esm/utils/roadmapIssues.js +86 -0
  106. package/dist/esm/utils/roadmapIssues.js.map +1 -0
  107. package/dist/esm/utils/userDisplayName.js +47 -0
  108. package/dist/esm/utils/userDisplayName.js.map +1 -0
  109. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  110. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  111. package/dist/nextcloud-vue.cjs.js +15618 -13097
  112. package/dist/nextcloud-vue.cjs.js.map +2 -2
  113. package/dist/nextcloud-vue.css +1182 -328
  114. package/l10n/en.json +45 -1
  115. package/l10n/nl.json +44 -1
  116. package/package.json +1 -1
  117. package/src/components/CnAppRoot/CnAppRoot.md +2 -0
  118. package/src/components/CnAppRoot/CnAppRoot.vue +66 -5
  119. package/src/components/CnChoiceCards/CnChoiceCards.md +27 -0
  120. package/src/components/CnChoiceCards/CnChoiceCards.vue +168 -3
  121. package/src/components/CnDashboardPage/CnDashboardPage.vue +45 -6
  122. package/src/components/CnDataTable/CnDataTable.vue +10 -39
  123. package/src/components/CnDetailPage/CnDetailPage.vue +5 -3
  124. package/src/components/CnFactsWidget/CnFactsWidget.vue +6 -4
  125. package/src/components/CnFeaturesAndRoadmapPage/CnFeaturesAndRoadmapPage.vue +51 -1
  126. package/src/components/CnFeaturesAndRoadmapView/CnFeaturesAndRoadmapView.vue +98 -13
  127. package/src/components/CnFeaturesBoard/CnFeaturesBoard.vue +1053 -0
  128. package/src/components/CnFormDialog/CnFormDialog.md +1 -0
  129. package/src/components/CnFormDialog/CnFormDialog.vue +619 -562
  130. package/src/components/CnLinkCardsPage/CnLinkCardsPage.vue +338 -5
  131. package/src/components/CnModuleCard/CnModuleCard.vue +258 -0
  132. package/src/components/CnNcWidgetWidget/CnNcWidgetWidget.vue +23 -2
  133. package/src/components/CnNotificationPreferences/CnNotificationPreferences.vue +5 -0
  134. package/src/components/CnRoadmapTab/CnRoadmapTab.vue +6 -28
  135. package/src/components/CnTabsWidget/CnTabsWidget.vue +33 -2
  136. package/src/components/CnTextWidget/CnTextWidget.vue +89 -4
  137. package/src/components/CnUserSettingsDialog/CnUserSettingsDialog.vue +305 -0
  138. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +12 -0
  139. package/src/css/dialog.css +47 -0
  140. package/src/css/look-board-detail.css +8 -0
  141. package/src/css/look-board.css +33 -0
  142. package/src/schemas/app-manifest-v2.schema.json +67 -4
  143. package/src/utils/boardDate.js +34 -0
  144. package/src/utils/featureCatalog.js +132 -0
  145. package/src/utils/fillTemplate.js +83 -3
  146. package/src/utils/headerMeta.js +62 -12
  147. package/src/utils/roadmapIssues.js +82 -0
  148. package/src/utils/userDisplayName.js +54 -0
  149. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -0,0 +1,86 @@
1
+ import axios__default from '@nextcloud/axios';
2
+ import { generateUrl } from '@nextcloud/router';
3
+
4
+ /**
5
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
6
+ * SPDX-License-Identifier: EUPL-1.2
7
+ *
8
+ * roadmapIssues: the forge issues a roadmap shows, fetched through
9
+ * OpenRegister's `github-issue-proxy` with the curated label filter
10
+ * (`enhancement,feature`, per openregister design D23), most-reacted first.
11
+ *
12
+ * @module utils/roadmapIssues
13
+ * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues
14
+ */
15
+
16
+
17
+ /**
18
+ * Fetch the roadmap issues of a repository.
19
+ *
20
+ * `degraded` names why there are none: `pat_not_configured` (OpenRegister has
21
+ * no GitHub token), `rate_limited` (HTTP 429), `error` (anything else), or
22
+ * null when the fetch worked.
23
+ *
24
+ * @param {string} repo `<owner>/<repo>` on the forge.
25
+ * @return {Promise<{items: Array<object>, degraded: (string|null)}>} The issues, most-reacted first.
26
+ * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues
27
+ */
28
+ async function fetchRoadmapIssues(repo) {
29
+ try {
30
+ const response = await axios__default.get(generateUrl('/apps/openregister/api/github/issues'), {
31
+ params: { repo, labels: 'enhancement,feature' },
32
+ });
33
+ const data = response.data || {};
34
+ if (data.hint === 'github_pat_not_configured') {
35
+ return { items: [], degraded: 'pat_not_configured' }
36
+ }
37
+ return { items: sortByReactions(Array.isArray(data.items) ? data.items : []), degraded: null }
38
+ } catch (e) {
39
+ const status = e?.response?.status;
40
+ const code = e?.response?.data?.error;
41
+ if (status === 429 || code === 'github_rate_limited' || code === 'rate_limited') {
42
+ return { items: [], degraded: 'rate_limited' }
43
+ }
44
+ return { items: [], degraded: 'error' }
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Issues ordered by their reaction count, most first.
50
+ *
51
+ * @param {Array<object>} items The issues.
52
+ * @return {Array<object>} A sorted copy.
53
+ * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues
54
+ */
55
+ function sortByReactions(items) {
56
+ return [...items].sort((a, b) => (b.reactions?.total_count || 0) - (a.reactions?.total_count || 0))
57
+ }
58
+
59
+ /**
60
+ * The roadmap status of an issue from its labels: the first label that
61
+ * `labelStatuses` maps (case-insensitive) decides, else ''.
62
+ *
63
+ * @param {object} issue The issue, with `labels: [{name}]` or `labels: ['name']`.
64
+ * @param {object} labelStatuses Label name to status (`in_progress`, `planned`).
65
+ * @return {string} The status, or '' for no badge.
66
+ * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues
67
+ */
68
+ function issueStatus(issue, labelStatuses) {
69
+ if (!labelStatuses || typeof labelStatuses !== 'object') {
70
+ return ''
71
+ }
72
+ const map = {};
73
+ for (const [label, status] of Object.entries(labelStatuses)) {
74
+ map[label.toLowerCase()] = status;
75
+ }
76
+ for (const label of Array.isArray(issue?.labels) ? issue.labels : []) {
77
+ const name = String(typeof label === 'string' ? label : label?.name || '').toLowerCase();
78
+ if (map[name]) {
79
+ return map[name]
80
+ }
81
+ }
82
+ return ''
83
+ }
84
+
85
+ export { fetchRoadmapIssues, issueStatus, sortByReactions };
86
+ //# sourceMappingURL=roadmapIssues.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"roadmapIssues.js","sources":["../../../src/utils/roadmapIssues.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * roadmapIssues: the forge issues a roadmap shows, fetched through\n * OpenRegister's `github-issue-proxy` with the curated label filter\n * (`enhancement,feature`, per openregister design D23), most-reacted first.\n *\n * @module utils/roadmapIssues\n * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues\n */\n\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\n\n/**\n * Fetch the roadmap issues of a repository.\n *\n * `degraded` names why there are none: `pat_not_configured` (OpenRegister has\n * no GitHub token), `rate_limited` (HTTP 429), `error` (anything else), or\n * null when the fetch worked.\n *\n * @param {string} repo `<owner>/<repo>` on the forge.\n * @return {Promise<{items: Array<object>, degraded: (string|null)}>} The issues, most-reacted first.\n * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues\n */\nexport async function fetchRoadmapIssues(repo) {\n\ttry {\n\t\tconst response = await axios.get(generateUrl('/apps/openregister/api/github/issues'), {\n\t\t\tparams: { repo, labels: 'enhancement,feature' },\n\t\t})\n\t\tconst data = response.data || {}\n\t\tif (data.hint === 'github_pat_not_configured') {\n\t\t\treturn { items: [], degraded: 'pat_not_configured' }\n\t\t}\n\t\treturn { items: sortByReactions(Array.isArray(data.items) ? data.items : []), degraded: null }\n\t} catch (e) {\n\t\tconst status = e?.response?.status\n\t\tconst code = e?.response?.data?.error\n\t\tif (status === 429 || code === 'github_rate_limited' || code === 'rate_limited') {\n\t\t\treturn { items: [], degraded: 'rate_limited' }\n\t\t}\n\t\treturn { items: [], degraded: 'error' }\n\t}\n}\n\n/**\n * Issues ordered by their reaction count, most first.\n *\n * @param {Array<object>} items The issues.\n * @return {Array<object>} A sorted copy.\n * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues\n */\nexport function sortByReactions(items) {\n\treturn [...items].sort((a, b) => (b.reactions?.total_count || 0) - (a.reactions?.total_count || 0))\n}\n\n/**\n * The roadmap status of an issue from its labels: the first label that\n * `labelStatuses` maps (case-insensitive) decides, else ''.\n *\n * @param {object} issue The issue, with `labels: [{name}]` or `labels: ['name']`.\n * @param {object} labelStatuses Label name to status (`in_progress`, `planned`).\n * @return {string} The status, or '' for no badge.\n * @spec openspec/changes/screens-roadmap-board-look/specs/features-roadmap-board-look/spec.md#requirement-the-next-card-lists-the-most-requested-issues\n */\nexport function issueStatus(issue, labelStatuses) {\n\tif (!labelStatuses || typeof labelStatuses !== 'object') {\n\t\treturn ''\n\t}\n\tconst map = {}\n\tfor (const [label, status] of Object.entries(labelStatuses)) {\n\t\tmap[label.toLowerCase()] = status\n\t}\n\tfor (const label of Array.isArray(issue?.labels) ? issue.labels : []) {\n\t\tconst name = String(typeof label === 'string' ? label : label?.name || '').toLowerCase()\n\t\tif (map[name]) {\n\t\t\treturn map[name]\n\t\t}\n\t}\n\treturn ''\n}\n"],"names":["axios"],"mappings":";;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,eAAe,kBAAkB,CAAC,IAAI,EAAE;AAC/C,CAAC,IAAI;AACL,EAAE,MAAM,QAAQ,GAAG,MAAMA,cAAK,CAAC,GAAG,CAAC,WAAW,CAAC,sCAAsC,CAAC,EAAE;AACxF,GAAG,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,qBAAqB,EAAE;AAClD,GAAG,EAAC;AACJ,EAAE,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,IAAI,GAAE;AAClC,EAAE,IAAI,IAAI,CAAC,IAAI,KAAK,2BAA2B,EAAE;AACjD,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,oBAAoB,EAAE;AACvD,GAAG;AACH,EAAE,OAAO,EAAE,KAAK,EAAE,eAAe,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE;AAChG,EAAE,CAAC,OAAO,CAAC,EAAE;AACb,EAAE,MAAM,MAAM,GAAG,CAAC,EAAE,QAAQ,EAAE,OAAM;AACpC,EAAE,MAAM,IAAI,GAAG,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAK;AACvC,EAAE,IAAI,MAAM,KAAK,GAAG,IAAI,IAAI,KAAK,qBAAqB,IAAI,IAAI,KAAK,cAAc,EAAE;AACnF,GAAG,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,cAAc,EAAE;AACjD,GAAG;AACH,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;AACzC,EAAE;AACF,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,KAAK,EAAE;AACvC,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,EAAE,WAAW,IAAI,CAAC,KAAK,CAAC,CAAC,SAAS,EAAE,WAAW,IAAI,CAAC,CAAC,CAAC;AACpG,CAAC;AACD;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,WAAW,CAAC,KAAK,EAAE,aAAa,EAAE;AAClD,CAAC,IAAI,CAAC,aAAa,IAAI,OAAO,aAAa,KAAK,QAAQ,EAAE;AAC1D,EAAE,OAAO,EAAE;AACX,EAAE;AACF,CAAC,MAAM,GAAG,GAAG,GAAE;AACf,CAAC,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE;AAC9D,EAAE,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,GAAG,OAAM;AACnC,EAAE;AACF,CAAC,KAAK,MAAM,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE;AACvE,EAAE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,KAAK,KAAK,QAAQ,GAAG,KAAK,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,CAAC,CAAC,WAAW,GAAE;AAC1F,EAAE,IAAI,GAAG,CAAC,IAAI,CAAC,EAAE;AACjB,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC;AACnB,GAAG;AACH,EAAE;AACF,CAAC,OAAO,EAAE;AACV;;;;"}
@@ -0,0 +1,47 @@
1
+ import { reactive } from 'vue';
2
+ import { resolveNextcloudUser } from './userAutocomplete.js';
3
+
4
+ /**
5
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
6
+ * SPDX-License-Identifier: EUPL-1.2
7
+ *
8
+ * userDisplayName: a user id's display name for synchronous text (a template
9
+ * token), looked up once through `resolveNextcloudUser` and kept in a
10
+ * reactive cache, so a computed that read it renders again when the name
11
+ * arrives.
12
+ *
13
+ * @module utils/userDisplayName
14
+ * @spec openspec/changes/screens-header-meta-tokens/specs/detail-page-board-look/spec.md#requirement-the-header-meta-line-formats-users-long-dates-and-enum-labels
15
+ */
16
+
17
+
18
+ const names = reactive({});
19
+
20
+ /**
21
+ * The display name of a user id: the cached name, or '' while it is being
22
+ * looked up (the first call starts the lookup). A user that cannot be
23
+ * resolved reads as its id.
24
+ *
25
+ * @param {unknown} uid The user id.
26
+ * @return {string} The display name, or '' while loading.
27
+ * @spec openspec/changes/screens-header-meta-tokens/specs/detail-page-board-look/spec.md#requirement-the-header-meta-line-formats-users-long-dates-and-enum-labels
28
+ */
29
+ function userDisplayName(uid) {
30
+ if (uid === null || uid === undefined || uid === '' || typeof uid === 'object') {
31
+ return ''
32
+ }
33
+ const id = String(uid);
34
+ if (typeof names[id] === 'string') {
35
+ return names[id]
36
+ }
37
+ if (names[id] === undefined) {
38
+ names[id] = null;
39
+ resolveNextcloudUser(id)
40
+ .then((option) => { names[id] = option && option.label ? String(option.label) : id; })
41
+ .catch(() => { names[id] = id; });
42
+ }
43
+ return ''
44
+ }
45
+
46
+ export { userDisplayName };
47
+ //# sourceMappingURL=userDisplayName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"userDisplayName.js","sources":["../../../src/utils/userDisplayName.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * userDisplayName: a user id's display name for synchronous text (a template\n * token), looked up once through `resolveNextcloudUser` and kept in a\n * reactive cache, so a computed that read it renders again when the name\n * arrives.\n *\n * @module utils/userDisplayName\n * @spec openspec/changes/screens-header-meta-tokens/specs/detail-page-board-look/spec.md#requirement-the-header-meta-line-formats-users-long-dates-and-enum-labels\n */\n\nimport { reactive } from 'vue'\nimport { resolveNextcloudUser } from './userAutocomplete.js'\n\nconst names = reactive({})\n\n/**\n * The display name of a user id: the cached name, or '' while it is being\n * looked up (the first call starts the lookup). A user that cannot be\n * resolved reads as its id.\n *\n * @param {unknown} uid The user id.\n * @return {string} The display name, or '' while loading.\n * @spec openspec/changes/screens-header-meta-tokens/specs/detail-page-board-look/spec.md#requirement-the-header-meta-line-formats-users-long-dates-and-enum-labels\n */\nexport function userDisplayName(uid) {\n\tif (uid === null || uid === undefined || uid === '' || typeof uid === 'object') {\n\t\treturn ''\n\t}\n\tconst id = String(uid)\n\tif (typeof names[id] === 'string') {\n\t\treturn names[id]\n\t}\n\tif (names[id] === undefined) {\n\t\tnames[id] = null\n\t\tresolveNextcloudUser(id)\n\t\t\t.then((option) => { names[id] = option && option.label ? String(option.label) : id })\n\t\t\t.catch(() => { names[id] = id })\n\t}\n\treturn ''\n}\n\n/**\n * Forget every cached name (tests).\n *\n * @return {void}\n */\nexport function clearUserDisplayNames() {\n\tfor (const key of Object.keys(names)) {\n\t\tdelete names[key]\n\t}\n}\n"],"names":[],"mappings":";;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAGA;AACA,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,EAAC;AAC1B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,eAAe,CAAC,GAAG,EAAE;AACrC,CAAC,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,EAAE,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE;AACjF,EAAE,OAAO,EAAE;AACX,EAAE;AACF,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,GAAG,EAAC;AACvB,CAAC,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC,KAAK,QAAQ,EAAE;AACpC,EAAE,OAAO,KAAK,CAAC,EAAE,CAAC;AAClB,EAAE;AACF,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE;AAC9B,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,KAAI;AAClB,EAAE,oBAAoB,CAAC,EAAE,CAAC;AAC1B,IAAI,IAAI,CAAC,CAAC,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,MAAM,IAAI,MAAM,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAE,EAAE,CAAC;AACxF,IAAI,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,GAAG,GAAE,EAAE,EAAC;AACnC,EAAE;AACF,CAAC,OAAO,EAAE;AACV;;;;"}