@conduction/nextcloud-vue 2.93.0 → 2.94.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 (105) hide show
  1. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js +1 -1
  2. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue2.js.map +1 -1
  3. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js +2 -1
  4. package/dist/esm/components/CnActionsMenu/CnActionsMenu.vue3.js.map +1 -1
  5. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue.js +1 -1
  6. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js +28 -8
  7. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue2.js.map +1 -1
  8. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js +37 -2
  9. package/dist/esm/components/CnAdminSettingsShell/CnAdminSettingsShell.vue3.js.map +1 -1
  10. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue.js +1 -1
  11. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js +139 -3
  12. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue2.js.map +1 -1
  13. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js +60 -12
  14. package/dist/esm/components/CnCountdownWidget/CnCountdownWidget.vue3.js.map +1 -1
  15. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue.js +1 -1
  16. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js +91 -36
  17. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  18. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +115 -72
  19. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  20. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js +32 -3
  21. package/dist/esm/components/CnDataTable/CnDataTable.vue2.js.map +1 -1
  22. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js +7 -7
  23. package/dist/esm/components/CnDataTable/CnDataTable.vue3.js.map +1 -1
  24. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +141 -7
  25. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  26. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +5 -2
  27. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  28. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js +8 -0
  29. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue.js.map +1 -0
  30. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js +114 -0
  31. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue2.js.map +1 -0
  32. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js +45 -0
  33. package/dist/esm/components/CnPageHeader/CnHeaderTrail.vue3.js.map +1 -0
  34. package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js +38 -2
  35. package/dist/esm/components/CnPageHeader/CnPageHeader.vue2.js.map +1 -1
  36. package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js +12 -2
  37. package/dist/esm/components/CnPageHeader/CnPageHeader.vue3.js.map +1 -1
  38. package/dist/esm/components/CnPagination/CnPagination.vue2.js.map +1 -1
  39. package/dist/esm/components/CnPagination/CnPagination.vue3.js +56 -51
  40. package/dist/esm/components/CnPagination/CnPagination.vue3.js.map +1 -1
  41. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue.js +1 -1
  42. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js +3 -3
  43. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue2.js.map +1 -1
  44. package/dist/esm/components/CnRecordListWidget/CnRecordListWidget.vue3.js.map +1 -1
  45. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue.js +1 -1
  46. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js +24 -0
  47. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue2.js.map +1 -1
  48. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js +3 -1
  49. package/dist/esm/components/CnSettingsPage/CnSettingsPage.vue3.js.map +1 -1
  50. package/dist/esm/components/CnTabs/CnTabs.vue.js +1 -1
  51. package/dist/esm/components/CnTabs/CnTabs.vue2.js +39 -2
  52. package/dist/esm/components/CnTabs/CnTabs.vue2.js.map +1 -1
  53. package/dist/esm/components/CnTabs/CnTabs.vue3.js.map +1 -1
  54. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue.js +1 -1
  55. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js +85 -8
  56. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue2.js.map +1 -1
  57. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js +37 -9
  58. package/dist/esm/components/CnTabsWidget/CnTabsWidget.vue3.js.map +1 -1
  59. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue.js +1 -1
  60. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue2.js.map +1 -1
  61. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js +4 -3
  62. package/dist/esm/components/CnVersionInfoCard/CnVersionInfoCard.vue3.js.map +1 -1
  63. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue.js +1 -1
  64. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js +20 -0
  65. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue2.js.map +1 -1
  66. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js +31 -20
  67. package/dist/esm/components/CnWidgetWrapper/CnWidgetWrapper.vue3.js.map +1 -1
  68. package/dist/esm/composables/indexSources.js +9 -0
  69. package/dist/esm/composables/indexSources.js.map +1 -1
  70. package/dist/esm/library-style.js +1 -1
  71. package/dist/esm/nextcloud-vue.css +402 -262
  72. package/dist/esm/utils/dueText.js +49 -8
  73. package/dist/esm/utils/dueText.js.map +1 -1
  74. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  75. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  76. package/dist/nextcloud-vue.cjs.js +5779 -4827
  77. package/dist/nextcloud-vue.cjs.js.map +2 -2
  78. package/dist/nextcloud-vue.css +402 -262
  79. package/package.json +1 -1
  80. package/src/components/CnActionsMenu/CnActionsMenu.vue +3 -1
  81. package/src/components/CnAdminSettingsShell/CnAdminSettingsShell.vue +39 -1
  82. package/src/components/CnCountdownWidget/CnCountdownWidget.vue +222 -6
  83. package/src/components/CnDashboardPage/CnDashboardPage.vue +96 -2
  84. package/src/components/CnDataTable/CnDataTable.md +1 -0
  85. package/src/components/CnDataTable/CnDataTable.vue +39 -10
  86. package/src/components/CnIndexPage/CnIndexPage.vue +144 -7
  87. package/src/components/CnPageHeader/CnHeaderTrail.vue +140 -0
  88. package/src/components/CnPageHeader/CnPageHeader.md +11 -0
  89. package/src/components/CnPageHeader/CnPageHeader.vue +42 -0
  90. package/src/components/CnPagination/CnPagination.vue +10 -2
  91. package/src/components/CnRecordListWidget/CnRecordListWidget.vue +3 -3
  92. package/src/components/CnSettingsPage/CnSettingsPage.vue +26 -0
  93. package/src/components/CnTabs/CnTabs.vue +39 -2
  94. package/src/components/CnTabsWidget/CnTabsWidget.vue +106 -13
  95. package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +4 -3
  96. package/src/components/CnWidgetWrapper/CnWidgetWrapper.md +8 -0
  97. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +31 -2
  98. package/src/composables/indexSources.js +9 -0
  99. package/src/css/dialog.css +14 -0
  100. package/src/css/look-board-index.css +27 -1
  101. package/src/css/look-board.css +27 -0
  102. package/src/css/page-header.css +16 -0
  103. package/src/schemas/app-manifest-v2.schema.json +22 -15
  104. package/src/utils/dueText.js +49 -8
  105. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -10,7 +10,8 @@ import { parseDateValue } from './dateVariant.js';
10
10
  *
11
11
  * "3 dagen te laat" in the danger colour, "Vandaag", the short date for a
12
12
  * day still to come ("morgen", "20 okt"), and a configured text when the
13
- * field is empty ("Geen deadline"). One formatter for record-list rows and
13
+ * field is empty ("Geen deadline"). A day to come can read as a count instead
14
+ * ("nog 4 dagen", "nog 8 weken"). One formatter for record-list rows and
14
15
  * table cells, built on the relative date (`formatRelativeDate`).
15
16
  *
16
17
  * @module utils/dueText
@@ -24,8 +25,12 @@ import { parseDateValue } from './dateVariant.js';
24
25
  * Config (all optional): `todayLabel` (default "Due today"), `overdueLabel`
25
26
  * `{ one, other }` with `{count}` (default "{count} day overdue" / "{count} days
26
27
  * overdue"), `emptyText` (shown when the field is empty; without it an empty
27
- * field reads as nothing). Texts go through `translate` before `{count}` is
28
- * filled. Tones: `danger` (overdue), `today`, `upcoming`, `empty`.
28
+ * field reads as nothing), `upcomingLabel` `{ one, other }` with `{count}`
29
+ * (a day to come reads as the days left instead of the date), and
30
+ * `upcomingWeeksLabel` `{ one, other }` (from `upcomingWeeksFrom` days left,
31
+ * default 35, it reads the weeks left, rounded). Texts go through `translate`
32
+ * before `{count}` is filled. Tones: `danger` (overdue), `today`, `upcoming`,
33
+ * `empty`.
29
34
  *
30
35
  * @param {unknown} value A Date, a timestamp or an ISO string.
31
36
  * @param {object} [config] The `due` config.
@@ -42,10 +47,9 @@ function resolveDue(value, config, translate$1 = (text) => text, now = new Date(
42
47
  }
43
48
  const days = ageInDays(date, now);
44
49
  if (days > 0) {
45
- const labels = cfg.overdueLabel && typeof cfg.overdueLabel === 'object' ? cfg.overdueLabel : null;
46
- if (labels && (labels.one || labels.other)) {
47
- const template = translate$1((days === 1 ? labels.one : labels.other) || labels.other || labels.one);
48
- return { text: template.replace(/\{count\}/g, String(days)), tone: 'danger' }
50
+ const overdue = pluralLabel(cfg.overdueLabel, days, translate$1);
51
+ if (overdue !== null) {
52
+ return { text: overdue, tone: 'danger' }
49
53
  }
50
54
  return { text: translatePlural('nextcloud-vue', '{count} day overdue', '{count} days overdue', days, { count: days }), tone: 'danger' }
51
55
  }
@@ -53,7 +57,44 @@ function resolveDue(value, config, translate$1 = (text) => text, now = new Date(
53
57
  const label = typeof cfg.todayLabel === 'string' && cfg.todayLabel !== '' ? translate$1(cfg.todayLabel) : translate('nextcloud-vue', 'Due today');
54
58
  return { text: label, tone: 'today' }
55
59
  }
56
- return { text: formatRelativeDate(date, { now }), tone: 'upcoming' }
60
+ return { text: upcomingText(-days, cfg, translate$1) ?? formatRelativeDate(date, { now }), tone: 'upcoming' }
61
+ }
62
+
63
+ /**
64
+ * The days or weeks left before a date to come, or null without `upcomingLabel`.
65
+ *
66
+ * @param {number} left Whole days left, at least 1.
67
+ * @param {object} cfg The `due` config.
68
+ * @param {(text: string) => string} translate The host's translate.
69
+ * @return {string|null} The text, or null.
70
+ * @spec openspec/changes/due-text-upcoming-count/specs/due-text-upcoming-count/spec.md#requirement-a-due-date-to-come-can-read-as-the-time-left
71
+ */
72
+ function upcomingText(left, cfg, translate) {
73
+ const from = Number(cfg.upcomingWeeksFrom);
74
+ const weeksFrom = Number.isFinite(from) && from > 0 ? from : 35;
75
+ if (left >= weeksFrom) {
76
+ const weeks = pluralLabel(cfg.upcomingWeeksLabel, Math.round(left / 7), translate);
77
+ if (weeks !== null) {
78
+ return weeks
79
+ }
80
+ }
81
+ return pluralLabel(cfg.upcomingLabel, left, translate)
82
+ }
83
+
84
+ /**
85
+ * A `{ one, other }` label with `{count}` filled, or null when none is configured.
86
+ *
87
+ * @param {unknown} labels The configured label pair.
88
+ * @param {number} count The count.
89
+ * @param {(text: string) => string} translate The host's translate.
90
+ * @return {string|null} The text, or null.
91
+ */
92
+ function pluralLabel(labels, count, translate) {
93
+ if (!labels || typeof labels !== 'object' || !(labels.one || labels.other)) {
94
+ return null
95
+ }
96
+ const template = translate((count === 1 ? labels.one : labels.other) || labels.other || labels.one);
97
+ return template.replace(/\{count\}/g, String(count))
57
98
  }
58
99
 
59
100
  export { resolveDue };
@@ -1 +1 @@
1
- {"version":3,"file":"dueText.js","sources":["../../../src/utils/dueText.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * dueText: the text of a due date and the tone it is drawn in.\n *\n * \"3 dagen te laat\" in the danger colour, \"Vandaag\", the short date for a\n * day still to come (\"morgen\", \"20 okt\"), and a configured text when the\n * field is empty (\"Geen deadline\"). One formatter for record-list rows and\n * table cells, built on the relative date (`formatRelativeDate`).\n *\n * @module utils/dueText\n * @spec openspec/changes/screens-due-text/specs/due-text/spec.md#requirement-a-due-date-reads-as-text-with-a-tone\n */\n\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { ageInDays, formatRelativeDate } from './boardDate.js'\nimport { parseDateValue } from './dateVariant.js'\n\n/**\n * The text and tone of a due date.\n *\n * Config (all optional): `todayLabel` (default \"Due today\"), `overdueLabel`\n * `{ one, other }` with `{count}` (default \"{count} day overdue\" / \"{count} days\n * overdue\"), `emptyText` (shown when the field is empty; without it an empty\n * field reads as nothing). Texts go through `translate` before `{count}` is\n * filled. Tones: `danger` (overdue), `today`, `upcoming`, `empty`.\n *\n * @param {unknown} value A Date, a timestamp or an ISO string.\n * @param {object} [config] The `due` config.\n * @param {(text: string) => string} [translate] The host's translate.\n * @param {Date} [now] The reference moment.\n * @return {{text: string, tone: string}|null} The text and tone, or null when there is nothing to show.\n */\nexport function resolveDue(value, config, translate = (text) => text, now = new Date()) {\n\tconst cfg = config && typeof config === 'object' ? config : {}\n\tconst date = parseDateValue(value)\n\tif (date === null) {\n\t\tconst empty = typeof cfg.emptyText === 'string' && cfg.emptyText !== '' ? translate(cfg.emptyText) : ''\n\t\treturn empty === '' ? null : { text: empty, tone: 'empty' }\n\t}\n\tconst days = ageInDays(date, now)\n\tif (days > 0) {\n\t\tconst labels = cfg.overdueLabel && typeof cfg.overdueLabel === 'object' ? cfg.overdueLabel : null\n\t\tif (labels && (labels.one || labels.other)) {\n\t\t\tconst template = translate((days === 1 ? labels.one : labels.other) || labels.other || labels.one)\n\t\t\treturn { text: template.replace(/\\{count\\}/g, String(days)), tone: 'danger' }\n\t\t}\n\t\treturn { text: n('nextcloud-vue', '{count} day overdue', '{count} days overdue', days, { count: days }), tone: 'danger' }\n\t}\n\tif (days === 0) {\n\t\tconst label = typeof cfg.todayLabel === 'string' && cfg.todayLabel !== '' ? translate(cfg.todayLabel) : t('nextcloud-vue', 'Due today')\n\t\treturn { text: label, tone: 'today' }\n\t}\n\treturn { text: formatRelativeDate(date, { now }), tone: 'upcoming' }\n}\n"],"names":["translate","n","t"],"mappings":";;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,UAAU,CAAC,KAAK,EAAE,MAAM,EAAEA,WAAS,GAAG,CAAC,IAAI,KAAK,IAAI,EAAE,GAAG,GAAG,IAAI,IAAI,EAAE,EAAE;AACxF,CAAC,MAAM,GAAG,GAAG,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ,GAAG,MAAM,GAAG,GAAE;AAC/D,CAAC,MAAM,IAAI,GAAG,cAAc,CAAC,KAAK,EAAC;AACnC,CAAC,IAAI,IAAI,KAAK,IAAI,EAAE;AACpB,EAAE,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,SAAS,KAAK,QAAQ,IAAI,GAAG,CAAC,SAAS,KAAK,EAAE,GAAGA,WAAS,CAAC,GAAG,CAAC,SAAS,CAAC,GAAG,GAAE;AACzG,EAAE,OAAO,KAAK,KAAK,EAAE,GAAG,IAAI,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;AAC7D,EAAE;AACF,CAAC,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,GAAG,EAAC;AAClC,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE;AACf,EAAE,MAAM,MAAM,GAAG,GAAG,CAAC,YAAY,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ,GAAG,GAAG,CAAC,YAAY,GAAG,KAAI;AACnG,EAAE,IAAI,MAAM,KAAK,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,KAAK,CAAC,EAAE;AAC9C,GAAG,MAAM,QAAQ,GAAGA,WAAS,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,KAAK,KAAK,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,EAAC;AACrG,GAAG,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE;AAChF,GAAG;AACH,EAAE,OAAO,EAAE,IAAI,EAAEC,eAAC,CAAC,eAAe,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE;AAC3H,EAAE;AACF,CAAC,IAAI,IAAI,KAAK,CAAC,EAAE;AACjB,EAAE,MAAM,KAAK,GAAG,OAAO,GAAG,CAAC,UAAU,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,KAAK,EAAE,GAAGD,WAAS,CAAC,GAAG,CAAC,UAAU,CAAC,GAAGE,SAAC,CAAC,eAAe,EAAE,WAAW,EAAC;AACzI,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE;AACvC,EAAE;AACF,CAAC,OAAO,EAAE,IAAI,EAAE,kBAAkB,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE;AACrE;;;;"}
1
+ {"version":3,"file":"dueText.js","sources":["../../../src/utils/dueText.js"],"sourcesContent":["/**\n * SPDX-FileCopyrightText: 2026 Conduction B.V.\n * SPDX-License-Identifier: EUPL-1.2\n *\n * dueText: the text of a due date and the tone it is drawn in.\n *\n * \"3 dagen te laat\" in the danger colour, \"Vandaag\", the short date for a\n * day still to come (\"morgen\", \"20 okt\"), and a configured text when the\n * field is empty (\"Geen deadline\"). A day to come can read as a count instead\n * (\"nog 4 dagen\", \"nog 8 weken\"). One formatter for record-list rows and\n * table cells, built on the relative date (`formatRelativeDate`).\n *\n * @module utils/dueText\n * @spec openspec/changes/screens-due-text/specs/due-text/spec.md#requirement-a-due-date-reads-as-text-with-a-tone\n */\n\nimport { translatePlural as n, translate as t } from '@nextcloud/l10n'\nimport { ageInDays, formatRelativeDate } from './boardDate.js'\nimport { parseDateValue } from './dateVariant.js'\n\n/**\n * The text and tone of a due date.\n *\n * Config (all optional): `todayLabel` (default \"Due today\"), `overdueLabel`\n * `{ one, other }` with `{count}` (default \"{count} day overdue\" / \"{count} days\n * overdue\"), `emptyText` (shown when the field is empty; without it an empty\n * field reads as nothing), `upcomingLabel` `{ one, other }` with `{count}`\n * (a day to come reads as the days left instead of the date), and\n * `upcomingWeeksLabel` `{ one, other }` (from `upcomingWeeksFrom` days left,\n * default 35, it reads the weeks left, rounded). Texts go through `translate`\n * before `{count}` is filled. Tones: `danger` (overdue), `today`, `upcoming`,\n * `empty`.\n *\n * @param {unknown} value A Date, a timestamp or an ISO string.\n * @param {object} [config] The `due` config.\n * @param {(text: string) => string} [translate] The host's translate.\n * @param {Date} [now] The reference moment.\n * @return {{text: string, tone: string}|null} The text and tone, or null when there is nothing to show.\n */\nexport function resolveDue(value, config, translate = (text) => text, now = new Date()) {\n\tconst cfg = config && typeof config === 'object' ? config : {}\n\tconst date = parseDateValue(value)\n\tif (date === null) {\n\t\tconst empty = typeof cfg.emptyText === 'string' && cfg.emptyText !== '' ? translate(cfg.emptyText) : ''\n\t\treturn empty === '' ? null : { text: empty, tone: 'empty' }\n\t}\n\tconst days = ageInDays(date, now)\n\tif (days > 0) {\n\t\tconst overdue = pluralLabel(cfg.overdueLabel, days, translate)\n\t\tif (overdue !== null) {\n\t\t\treturn { text: overdue, tone: 'danger' }\n\t\t}\n\t\treturn { text: n('nextcloud-vue', '{count} day overdue', '{count} days overdue', days, { count: days }), tone: 'danger' }\n\t}\n\tif (days === 0) {\n\t\tconst label = typeof cfg.todayLabel === 'string' && cfg.todayLabel !== '' ? translate(cfg.todayLabel) : t('nextcloud-vue', 'Due today')\n\t\treturn { text: label, tone: 'today' }\n\t}\n\treturn { text: upcomingText(-days, cfg, translate) ?? formatRelativeDate(date, { now }), tone: 'upcoming' }\n}\n\n/**\n * The days or weeks left before a date to come, or null without `upcomingLabel`.\n *\n * @param {number} left Whole days left, at least 1.\n * @param {object} cfg The `due` config.\n * @param {(text: string) => string} translate The host's translate.\n * @return {string|null} The text, or null.\n * @spec openspec/changes/due-text-upcoming-count/specs/due-text-upcoming-count/spec.md#requirement-a-due-date-to-come-can-read-as-the-time-left\n */\nfunction upcomingText(left, cfg, translate) {\n\tconst from = Number(cfg.upcomingWeeksFrom)\n\tconst weeksFrom = Number.isFinite(from) && from > 0 ? from : 35\n\tif (left >= weeksFrom) {\n\t\tconst weeks = pluralLabel(cfg.upcomingWeeksLabel, Math.round(left / 7), translate)\n\t\tif (weeks !== null) {\n\t\t\treturn weeks\n\t\t}\n\t}\n\treturn pluralLabel(cfg.upcomingLabel, left, translate)\n}\n\n/**\n * A `{ one, other }` label with `{count}` filled, or null when none is configured.\n *\n * @param {unknown} labels The configured label pair.\n * @param {number} count The count.\n * @param {(text: string) => string} translate The host's translate.\n * @return {string|null} The text, or null.\n */\nfunction pluralLabel(labels, count, translate) {\n\tif (!labels || typeof labels !== 'object' || !(labels.one || labels.other)) {\n\t\treturn null\n\t}\n\tconst template = translate((count === 1 ? labels.one : labels.other) || labels.other || labels.one)\n\treturn template.replace(/\\{count\\}/g, String(count))\n}\n"],"names":["translate","n","t"],"mappings":"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"}