@conduction/nextcloud-vue 2.106.0 → 2.107.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 (135) hide show
  1. package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js +9 -0
  2. package/dist/esm/components/CnActionDialog/CnActionDialog.vue.js.map +1 -0
  3. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js +338 -0
  4. package/dist/esm/components/CnActionDialog/CnActionDialog.vue2.js.map +1 -0
  5. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js +249 -0
  6. package/dist/esm/components/CnActionDialog/CnActionDialog.vue3.js.map +1 -0
  7. package/dist/esm/components/CnAdvancedFormDialog/CnPropertiesTab.vue2.js +2 -2
  8. package/dist/esm/components/CnAdvancedFormDialog/CnPropertiesTab.vue2.js.map +1 -1
  9. package/dist/esm/components/CnAppNav/CnAppNav.vue2.js.map +1 -1
  10. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js +145 -138
  11. package/dist/esm/components/CnAppNav/CnAppNav.vue3.js.map +1 -1
  12. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js +102 -2
  13. package/dist/esm/components/CnAppRoot/CnAppRoot.vue2.js.map +1 -1
  14. package/dist/esm/components/CnAppRoot/CnAppRoot.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 +83 -6
  17. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue2.js.map +1 -1
  18. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js +4 -2
  19. package/dist/esm/components/CnDashboardPage/CnDashboardPage.vue3.js.map +1 -1
  20. package/dist/esm/components/CnIcon/semanticIcons.js +2 -2
  21. package/dist/esm/components/CnIcon/semanticIcons.js.map +1 -1
  22. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js +389 -20
  23. package/dist/esm/components/CnIndexPage/CnIndexPage.vue2.js.map +1 -1
  24. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js +68 -35
  25. package/dist/esm/components/CnIndexPage/CnIndexPage.vue3.js.map +1 -1
  26. package/dist/esm/components/CnIndexPage/useSelfFetchList.js +22 -2
  27. package/dist/esm/components/CnIndexPage/useSelfFetchList.js.map +1 -1
  28. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js +69 -5
  29. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue2.js.map +1 -1
  30. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js +38 -5
  31. package/dist/esm/components/CnIndexSidebar/CnIndexSidebar.vue3.js.map +1 -1
  32. package/dist/esm/components/CnMapWidget/CnMapWidget.vue.js +1 -1
  33. package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js +7 -1
  34. package/dist/esm/components/CnMapWidget/CnMapWidget.vue2.js.map +1 -1
  35. package/dist/esm/components/CnMapWidget/CnMapWidget.vue3.js.map +1 -1
  36. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue.js +8 -0
  37. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue.js.map +1 -0
  38. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js +297 -0
  39. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue2.js.map +1 -0
  40. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue3.js +24 -0
  41. package/dist/esm/components/CnPartyPicker/CnPartyPicker.vue3.js.map +1 -0
  42. package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue.js +9 -0
  43. package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue.js.map +1 -0
  44. package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue2.js +95 -0
  45. package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue2.js.map +1 -0
  46. package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue3.js +123 -0
  47. package/dist/esm/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue3.js.map +1 -0
  48. package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue.js +1 -1
  49. package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue2.js +13 -5
  50. package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue2.js.map +1 -1
  51. package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue3.js +3 -1
  52. package/dist/esm/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue3.js.map +1 -1
  53. package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue.js +1 -1
  54. package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue2.js +49 -23
  55. package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue2.js.map +1 -1
  56. package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue3.js +74 -27
  57. package/dist/esm/components/CnSavedViewShareFields/CnSavedViewShareFields.vue3.js.map +1 -1
  58. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue.js +0 -1
  59. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue.js.map +1 -1
  60. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js +18 -413
  61. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue2.js.map +1 -1
  62. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js +27 -214
  63. package/dist/esm/components/CnSavedViewsControl/CnSavedViewsControl.vue3.js.map +1 -1
  64. package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue.js +9 -0
  65. package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue.js.map +1 -0
  66. package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue2.js +190 -0
  67. package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue2.js.map +1 -0
  68. package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue3.js +270 -0
  69. package/dist/esm/components/CnSavedViewsPanel/CnSavedViewsPanel.vue3.js.map +1 -0
  70. package/dist/esm/index.js +4 -0
  71. package/dist/esm/index.js.map +1 -1
  72. package/dist/esm/l10n/en.json.js +56 -1
  73. package/dist/esm/l10n/en.json.js.map +1 -1
  74. package/dist/esm/l10n/nl.json.js +56 -1
  75. package/dist/esm/l10n/nl.json.js.map +1 -1
  76. package/dist/esm/library-style.js +1 -1
  77. package/dist/esm/mixins/savedViewsList.js +235 -0
  78. package/dist/esm/mixins/savedViewsList.js.map +1 -0
  79. package/dist/esm/nextcloud-vue.css +348 -108
  80. package/dist/esm/utils/actionsDispatcher.js +2 -2
  81. package/dist/esm/utils/actionsDispatcher.js.map +1 -1
  82. package/dist/esm/utils/builtInModals.js +39 -0
  83. package/dist/esm/utils/builtInModals.js.map +1 -0
  84. package/dist/esm/utils/mapMarkerColor.js +121 -0
  85. package/dist/esm/utils/mapMarkerColor.js.map +1 -0
  86. package/dist/esm/utils/mergeManifestDelta.js +4 -0
  87. package/dist/esm/utils/mergeManifestDelta.js.map +1 -1
  88. package/dist/esm/utils/savedViewHelpers.js +59 -7
  89. package/dist/esm/utils/savedViewHelpers.js.map +1 -1
  90. package/dist/esm/utils/savedViewMenu.js +154 -0
  91. package/dist/esm/utils/savedViewMenu.js.map +1 -0
  92. package/dist/esm/utils/searchGroupSharees.js +50 -15
  93. package/dist/esm/utils/searchGroupSharees.js.map +1 -1
  94. package/dist/esm/utils/validateManifestV2.compiled.js +3 -3
  95. package/dist/esm/utils/validateManifestV2.compiled.js.map +1 -1
  96. package/dist/nextcloud-vue.cjs.js +13351 -10855
  97. package/dist/nextcloud-vue.cjs.js.map +2 -2
  98. package/dist/nextcloud-vue.css +348 -108
  99. package/l10n/en.json +56 -1
  100. package/l10n/nl.json +56 -1
  101. package/package.json +1 -1
  102. package/src/components/CnActionDialog/CnActionDialog.vue +545 -0
  103. package/src/components/CnActionDialog/index.js +12 -0
  104. package/src/components/CnAppNav/CnAppNav.vue +17 -0
  105. package/src/components/CnAppRoot/CnAppRoot.vue +102 -2
  106. package/src/components/CnDashboardPage/CnDashboardPage.vue +86 -7
  107. package/src/components/CnIndexPage/CnIndexPage.vue +409 -23
  108. package/src/components/CnIndexPage/useSelfFetchList.js +21 -1
  109. package/src/components/CnIndexSidebar/CnIndexSidebar.md +2 -0
  110. package/src/components/CnIndexSidebar/CnIndexSidebar.vue +91 -1
  111. package/src/components/CnMapWidget/CnMapWidget.vue +16 -1
  112. package/src/components/CnPartyPicker/CnPartyPicker.vue +317 -0
  113. package/src/components/CnPartyPicker/index.js +11 -0
  114. package/src/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue +192 -0
  115. package/src/components/CnSavedViewEditDialog/index.js +11 -0
  116. package/src/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue +21 -6
  117. package/src/components/CnSavedViewShareFields/CnSavedViewShareFields.vue +130 -37
  118. package/src/components/CnSavedViewsControl/CnSavedViewsControl.vue +36 -599
  119. package/src/components/CnSavedViewsPanel/CnSavedViewsPanel.vue +459 -0
  120. package/src/components/CnSavedViewsPanel/index.js +11 -0
  121. package/src/components/index.js +4 -0
  122. package/src/css/index-page.css +16 -0
  123. package/src/css/look-board-index.css +5 -3
  124. package/src/css/look-board.css +18 -3
  125. package/src/index.js +4 -0
  126. package/src/mixins/savedViewsList.js +231 -0
  127. package/src/schemas/app-manifest-v2.schema.json +98 -3
  128. package/src/utils/actionsDispatcher.js +2 -2
  129. package/src/utils/builtInModals.js +35 -0
  130. package/src/utils/mapMarkerColor.js +117 -0
  131. package/src/utils/mergeManifestDelta.js +4 -0
  132. package/src/utils/savedViewHelpers.js +58 -6
  133. package/src/utils/savedViewMenu.js +150 -0
  134. package/src/utils/searchGroupSharees.js +49 -14
  135. package/src/utils/validateManifestV2.compiled.js +3 -3
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnPartyPicker.vue2.js","sources":["../../../../src/components/CnPartyPicker/CnPartyPicker.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnSearchSelect\n\t\tclass=\"cn-party-picker\"\n\t\t:modelValue=\"selectedOption\"\n\t\t:options=\"options\"\n\t\t:inputLabel=\"inputLabel\"\n\t\t:labelOutside=\"labelOutside\"\n\t\t:placeholder=\"placeholder ? cnTranslate(placeholder) : ''\"\n\t\t:loading=\"searching\"\n\t\t:filterable=\"false\"\n\t\t:clearable=\"clearable\"\n\t\t:disabled=\"disabled\"\n\t\tdata-testid=\"cn-party-picker\"\n\t\t@search=\"onSearch\"\n\t\t@update:modelValue=\"onPick\" />\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { CnSearchSelect } from '../CnSearchSelect/index.js'\n\n/** How long typing rests before a search runs, in ms. */\nconst SEARCH_DELAY = 250\n\n/**\n * CnPartyPicker — one search field over several kinds of party: people and\n * organisations from OpenRegister register sets (BRP persons, KvK companies,\n * an app's own clients) and the reader's Nextcloud contacts, as rows with\n * initials, the name and a second line, in one list (board DqNieuweZaak\n * \"Aanvrager\": \"Henk Visser · Inwoner · Beukenlaan 3\", \"Visser Bouw B.V. ·\n * Organisatie · KvK …\"). Built on CnSearchSelect.\n *\n * `sources`: each `{ id, register, schema, label?, title?, secondary?,\n * limit?, icon? }` searches OpenRegister with `_search`; `title` and\n * `secondary` are templates filled from the row (default `{name}` / none),\n * `label` names the kind (\"Resident\") and starts the second line. A source\n * `{ id, type: \"contacts\", label? }` searches the reader's Nextcloud contacts.\n *\n * `update:modelValue` emits the chosen row's id (a contact has none and\n * emits its contact id); `select` emits the whole choice: `{ source, id,\n * label, secondary, row }`, so a host can store more than the id (a case's\n * initiator type, source id and display name). A `modelValue` the list does\n * not hold is shown by its `selectedLabel`, else looked up by id in the\n * OpenRegister sources.\n *\n * ```vue\n * <CnPartyPicker\n * v-model=\"case.requester\"\n * input-label=\"Requester\"\n * :sources=\"[\n * { id: 'person', register: 'dossiq', schema: 'brpPerson', label: 'Resident', title: '{firstName} {lastName}', secondary: '{residence.street} {residence.houseNumber}' },\n * { id: 'company', register: 'dossiq', schema: 'kvkCompany', label: 'Organisation', title: '{tradeName}', secondary: 'KvK {sourceId}' },\n * { id: 'contact', type: 'contacts', label: 'Contact' },\n * ]\"\n * @select=\"onRequester\" />\n * ```\n */\nexport default {\n\tname: 'CnPartyPicker',\n\n\tcomponents: { CnSearchSelect },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** The chosen party's id. */\n\t\tmodelValue: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Where to search: OpenRegister sets `{ id, register, schema, label?,\n\t\t * title?, secondary?, limit?, icon? }`, or `{ id, type: \"contacts\",\n\t\t * label? }` for the reader's Nextcloud contacts.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tsources: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The field's label. */\n\t\tinputLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Draw the label above the field. */\n\t\tlabelOutside: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Placeholder (\"Name, BSN, trade name or KvK number\"), through the host translate. */\n\t\tplaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The chosen party's name, shown before the list holds it. */\n\t\tselectedLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Offer a clear button. */\n\t\tclearable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Disable the field. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** The fewest characters a search needs. */\n\t\tminLength: {\n\t\t\ttype: Number,\n\t\t\tdefault: 2,\n\t\t},\n\t},\n\n\temits: ['update:modelValue', 'select'],\n\n\tdata() {\n\t\treturn {\n\t\t\toptions: [],\n\t\t\tsearching: false,\n\t\t\tknown: null,\n\t\t\ttimer: null,\n\t\t\tsearchSeq: 0,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The option for `modelValue`: in the list, else the known choice,\n\t\t * else one named by `selectedLabel`.\n\t\t *\n\t\t * @spec openspec/changes/party-picker/specs/party-picker/spec.md#requirement-one-search-field-over-several-kinds-of-party\n\t\t * @return {object|null}\n\t\t */\n\t\tselectedOption() {\n\t\t\tconst value = this.modelValue\n\t\t\tif (value === null || value === undefined || value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst found = this.options.find((o) => String(o.id) === String(value))\n\t\t\tif (found) {\n\t\t\t\treturn found\n\t\t\t}\n\t\t\tif (this.known && String(this.known.id) === String(value)) {\n\t\t\t\treturn this.known\n\t\t\t}\n\t\t\treturn { id: value, label: this.selectedLabel || String(value), avatar: true }\n\t\t},\n\t},\n\n\twatch: {\n\t\tmodelValue: {\n\t\t\timmediate: true,\n\t\t\thandler(value) {\n\t\t\t\tif (value && !this.selectedLabel && !this.options.some((o) => String(o.id) === String(value))) {\n\t\t\t\t\tthis.lookUp(value)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n\n\tbeforeUnmount() {\n\t\tclearTimeout(this.timer)\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * A source's row as a picker option.\n\t\t *\n\t\t * @param {object} source The source.\n\t\t * @param {object} row The row.\n\t\t * @return {object|null} The option, or null without an id.\n\t\t */\n\t\toptionOf(source, row) {\n\t\t\tconst id = row && (row.id ?? row['@self']?.id ?? row.uuid)\n\t\t\tif (id === undefined || id === null || id === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst title = (source.title ? fillTemplate(source.title, row) : (row.name || row.title || row.displayName || '')).trim() || String(id)\n\t\t\tconst detail = source.secondary ? fillTemplate(source.secondary, row).trim() : ''\n\t\t\tconst kind = source.label ? this.cnTranslate(source.label) : ''\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tlabel: title,\n\t\t\t\tsecondary: [kind, detail].filter(Boolean).join(' · '),\n\t\t\t\tavatar: !source.icon,\n\t\t\t\ticon: source.icon || '',\n\t\t\t\tsource: source.id,\n\t\t\t\trow,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A Nextcloud contact as a picker option.\n\t\t *\n\t\t * @param {object} source The contacts source.\n\t\t * @param {object} contact The contactsmenu entry.\n\t\t * @return {object|null}\n\t\t */\n\t\tcontactOptionOf(source, contact) {\n\t\t\tconst id = contact && (contact.id || contact.uid)\n\t\t\tif (!id) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst mail = Array.isArray(contact.emailAddresses) ? contact.emailAddresses[0] : ''\n\t\t\tconst kind = source.label ? this.cnTranslate(source.label) : ''\n\t\t\treturn { id, label: contact.fullName || String(id), secondary: [kind, mail].filter(Boolean).join(' · '), avatar: true, source: source.id, row: contact }\n\t\t},\n\n\t\t/**\n\t\t * Search after typing rests.\n\t\t *\n\t\t * @param {string} query The typed text.\n\t\t */\n\t\tonSearch(query) {\n\t\t\tclearTimeout(this.timer)\n\t\t\tconst term = String(query || '').trim()\n\t\t\tif (term.length < this.minLength) {\n\t\t\t\tthis.options = this.selectedOption ? [this.selectedOption] : []\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.timer = setTimeout(() => this.search(term), SEARCH_DELAY)\n\t\t},\n\n\t\t/**\n\t\t * Search every source at once; a source that fails adds nothing.\n\t\t *\n\t\t * @spec openspec/changes/party-picker/specs/party-picker/spec.md#requirement-one-search-field-over-several-kinds-of-party\n\t\t * @param {string} term The search term.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync search(term) {\n\t\t\tconst seq = ++this.searchSeq\n\t\t\tthis.searching = true\n\t\t\tconst sets = await Promise.all((this.sources || []).map(async (source) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (source.type === 'contacts') {\n\t\t\t\t\t\tconst { data } = await axios.post(generateUrl('/contactsmenu/contacts'), { filter: term })\n\t\t\t\t\t\treturn (data && Array.isArray(data.contacts) ? data.contacts : []).map((c) => this.contactOptionOf(source, c))\n\t\t\t\t\t}\n\t\t\t\t\tif (!source.register || !source.schema) {\n\t\t\t\t\t\treturn []\n\t\t\t\t\t}\n\t\t\t\t\tconst { data } = await axios.get(generateUrl(`/apps/openregister/api/objects/${source.register}/${source.schema}`), { params: { _search: term, _limit: source.limit || 8 } })\n\t\t\t\t\treturn (data && Array.isArray(data.results) ? data.results : []).map((row) => this.optionOf(source, row))\n\t\t\t\t} catch {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t}))\n\t\t\tif (seq !== this.searchSeq) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.options = sets.flat().filter(Boolean)\n\t\t\tthis.searching = false\n\t\t},\n\n\t\t/**\n\t\t * Name a value the list does not hold: the first OpenRegister source\n\t\t * that has an object with that id.\n\t\t *\n\t\t * @param {string|number} id The id.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync lookUp(id) {\n\t\t\tfor (const source of (this.sources || []).filter((s) => s.register && s.schema && s.type !== 'contacts')) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { data } = await axios.get(generateUrl(`/apps/openregister/api/objects/${source.register}/${source.schema}/${encodeURIComponent(id)}`))\n\t\t\t\t\tconst option = data ? this.optionOf(source, data) : null\n\t\t\t\t\tif (option && String(this.modelValue) === String(id)) {\n\t\t\t\t\t\tthis.known = option\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Not in this source; try the next.\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Take the picked option: emit its id and the whole choice.\n\t\t *\n\t\t * @param {string|number|null} id The picked id.\n\t\t */\n\t\tonPick(id) {\n\t\t\tconst option = id === null ? null : this.options.find((o) => String(o.id) === String(id)) || null\n\t\t\tif (option) {\n\t\t\t\tthis.known = option\n\t\t\t}\n\t\t\t/** @event update:modelValue The chosen party's id, or null when cleared. */\n\t\t\tthis.$emit('update:modelValue', id)\n\t\t\t/** @event select The whole choice: `{ source, id, label, secondary, row }`, or null when cleared. */\n\t\t\tthis.$emit('select', option ? { source: option.source, id: option.id, label: option.label, secondary: option.secondary, row: option.row } : null)\n\t\t},\n\t},\n}\n</script>\n"],"names":["CnSearchSelect","axios"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { resolveComponent, openBlock, createBlock } from 'vue';
2
+
3
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
4
+ const _component_CnSearchSelect = resolveComponent("CnSearchSelect");
5
+
6
+ return (openBlock(), createBlock(_component_CnSearchSelect, {
7
+ class: "cn-party-picker",
8
+ modelValue: $options.selectedOption,
9
+ options: $data.options,
10
+ inputLabel: $props.inputLabel,
11
+ labelOutside: $props.labelOutside,
12
+ placeholder: $props.placeholder ? $options.cnTranslate($props.placeholder) : '',
13
+ loading: $data.searching,
14
+ filterable: false,
15
+ clearable: $props.clearable,
16
+ disabled: $props.disabled,
17
+ "data-testid": "cn-party-picker",
18
+ onSearch: $options.onSearch,
19
+ "onUpdate:modelValue": $options.onPick
20
+ }, null, 8 /* PROPS */, ["modelValue", "options", "inputLabel", "labelOutside", "placeholder", "loading", "clearable", "disabled", "onSearch", "onUpdate:modelValue"]))
21
+ }
22
+
23
+ export { render };
24
+ //# sourceMappingURL=CnPartyPicker.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnPartyPicker.vue3.js","sources":["../../../../src/components/CnPartyPicker/CnPartyPicker.vue?vue&type=template&id=6ac01095&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<CnSearchSelect\n\t\tclass=\"cn-party-picker\"\n\t\t:modelValue=\"selectedOption\"\n\t\t:options=\"options\"\n\t\t:inputLabel=\"inputLabel\"\n\t\t:labelOutside=\"labelOutside\"\n\t\t:placeholder=\"placeholder ? cnTranslate(placeholder) : ''\"\n\t\t:loading=\"searching\"\n\t\t:filterable=\"false\"\n\t\t:clearable=\"clearable\"\n\t\t:disabled=\"disabled\"\n\t\tdata-testid=\"cn-party-picker\"\n\t\t@search=\"onSearch\"\n\t\t@update:modelValue=\"onPick\" />\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { generateUrl } from '@nextcloud/router'\nimport { fillTemplate } from '../../utils/fillTemplate.js'\nimport { CnSearchSelect } from '../CnSearchSelect/index.js'\n\n/** How long typing rests before a search runs, in ms. */\nconst SEARCH_DELAY = 250\n\n/**\n * CnPartyPicker — one search field over several kinds of party: people and\n * organisations from OpenRegister register sets (BRP persons, KvK companies,\n * an app's own clients) and the reader's Nextcloud contacts, as rows with\n * initials, the name and a second line, in one list (board DqNieuweZaak\n * \"Aanvrager\": \"Henk Visser · Inwoner · Beukenlaan 3\", \"Visser Bouw B.V. ·\n * Organisatie · KvK …\"). Built on CnSearchSelect.\n *\n * `sources`: each `{ id, register, schema, label?, title?, secondary?,\n * limit?, icon? }` searches OpenRegister with `_search`; `title` and\n * `secondary` are templates filled from the row (default `{name}` / none),\n * `label` names the kind (\"Resident\") and starts the second line. A source\n * `{ id, type: \"contacts\", label? }` searches the reader's Nextcloud contacts.\n *\n * `update:modelValue` emits the chosen row's id (a contact has none and\n * emits its contact id); `select` emits the whole choice: `{ source, id,\n * label, secondary, row }`, so a host can store more than the id (a case's\n * initiator type, source id and display name). A `modelValue` the list does\n * not hold is shown by its `selectedLabel`, else looked up by id in the\n * OpenRegister sources.\n *\n * ```vue\n * <CnPartyPicker\n * v-model=\"case.requester\"\n * input-label=\"Requester\"\n * :sources=\"[\n * { id: 'person', register: 'dossiq', schema: 'brpPerson', label: 'Resident', title: '{firstName} {lastName}', secondary: '{residence.street} {residence.houseNumber}' },\n * { id: 'company', register: 'dossiq', schema: 'kvkCompany', label: 'Organisation', title: '{tradeName}', secondary: 'KvK {sourceId}' },\n * { id: 'contact', type: 'contacts', label: 'Contact' },\n * ]\"\n * @select=\"onRequester\" />\n * ```\n */\nexport default {\n\tname: 'CnPartyPicker',\n\n\tcomponents: { CnSearchSelect },\n\n\tinject: {\n\t\t/** The host app's translate (CnAppRoot `cnTranslate`). */\n\t\tcnTranslate: { default: () => (key) => key },\n\t},\n\n\tprops: {\n\t\t/** The chosen party's id. */\n\t\tmodelValue: {\n\t\t\ttype: [String, Number],\n\t\t\tdefault: null,\n\t\t},\n\n\t\t/**\n\t\t * Where to search: OpenRegister sets `{ id, register, schema, label?,\n\t\t * title?, secondary?, limit?, icon? }`, or `{ id, type: \"contacts\",\n\t\t * label? }` for the reader's Nextcloud contacts.\n\t\t *\n\t\t * @type {Array<object>}\n\t\t */\n\t\tsources: {\n\t\t\ttype: Array,\n\t\t\tdefault: () => [],\n\t\t},\n\n\t\t/** The field's label. */\n\t\tinputLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Draw the label above the field. */\n\t\tlabelOutside: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** Placeholder (\"Name, BSN, trade name or KvK number\"), through the host translate. */\n\t\tplaceholder: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** The chosen party's name, shown before the list holds it. */\n\t\tselectedLabel: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\n\t\t/** Offer a clear button. */\n\t\tclearable: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\n\t\t/** Disable the field. */\n\t\tdisabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\n\t\t/** The fewest characters a search needs. */\n\t\tminLength: {\n\t\t\ttype: Number,\n\t\t\tdefault: 2,\n\t\t},\n\t},\n\n\temits: ['update:modelValue', 'select'],\n\n\tdata() {\n\t\treturn {\n\t\t\toptions: [],\n\t\t\tsearching: false,\n\t\t\tknown: null,\n\t\t\ttimer: null,\n\t\t\tsearchSeq: 0,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/**\n\t\t * The option for `modelValue`: in the list, else the known choice,\n\t\t * else one named by `selectedLabel`.\n\t\t *\n\t\t * @spec openspec/changes/party-picker/specs/party-picker/spec.md#requirement-one-search-field-over-several-kinds-of-party\n\t\t * @return {object|null}\n\t\t */\n\t\tselectedOption() {\n\t\t\tconst value = this.modelValue\n\t\t\tif (value === null || value === undefined || value === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst found = this.options.find((o) => String(o.id) === String(value))\n\t\t\tif (found) {\n\t\t\t\treturn found\n\t\t\t}\n\t\t\tif (this.known && String(this.known.id) === String(value)) {\n\t\t\t\treturn this.known\n\t\t\t}\n\t\t\treturn { id: value, label: this.selectedLabel || String(value), avatar: true }\n\t\t},\n\t},\n\n\twatch: {\n\t\tmodelValue: {\n\t\t\timmediate: true,\n\t\t\thandler(value) {\n\t\t\t\tif (value && !this.selectedLabel && !this.options.some((o) => String(o.id) === String(value))) {\n\t\t\t\t\tthis.lookUp(value)\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n\n\tbeforeUnmount() {\n\t\tclearTimeout(this.timer)\n\t},\n\n\tmethods: {\n\t\t/**\n\t\t * A source's row as a picker option.\n\t\t *\n\t\t * @param {object} source The source.\n\t\t * @param {object} row The row.\n\t\t * @return {object|null} The option, or null without an id.\n\t\t */\n\t\toptionOf(source, row) {\n\t\t\tconst id = row && (row.id ?? row['@self']?.id ?? row.uuid)\n\t\t\tif (id === undefined || id === null || id === '') {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst title = (source.title ? fillTemplate(source.title, row) : (row.name || row.title || row.displayName || '')).trim() || String(id)\n\t\t\tconst detail = source.secondary ? fillTemplate(source.secondary, row).trim() : ''\n\t\t\tconst kind = source.label ? this.cnTranslate(source.label) : ''\n\t\t\treturn {\n\t\t\t\tid,\n\t\t\t\tlabel: title,\n\t\t\t\tsecondary: [kind, detail].filter(Boolean).join(' · '),\n\t\t\t\tavatar: !source.icon,\n\t\t\t\ticon: source.icon || '',\n\t\t\t\tsource: source.id,\n\t\t\t\trow,\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * A Nextcloud contact as a picker option.\n\t\t *\n\t\t * @param {object} source The contacts source.\n\t\t * @param {object} contact The contactsmenu entry.\n\t\t * @return {object|null}\n\t\t */\n\t\tcontactOptionOf(source, contact) {\n\t\t\tconst id = contact && (contact.id || contact.uid)\n\t\t\tif (!id) {\n\t\t\t\treturn null\n\t\t\t}\n\t\t\tconst mail = Array.isArray(contact.emailAddresses) ? contact.emailAddresses[0] : ''\n\t\t\tconst kind = source.label ? this.cnTranslate(source.label) : ''\n\t\t\treturn { id, label: contact.fullName || String(id), secondary: [kind, mail].filter(Boolean).join(' · '), avatar: true, source: source.id, row: contact }\n\t\t},\n\n\t\t/**\n\t\t * Search after typing rests.\n\t\t *\n\t\t * @param {string} query The typed text.\n\t\t */\n\t\tonSearch(query) {\n\t\t\tclearTimeout(this.timer)\n\t\t\tconst term = String(query || '').trim()\n\t\t\tif (term.length < this.minLength) {\n\t\t\t\tthis.options = this.selectedOption ? [this.selectedOption] : []\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.timer = setTimeout(() => this.search(term), SEARCH_DELAY)\n\t\t},\n\n\t\t/**\n\t\t * Search every source at once; a source that fails adds nothing.\n\t\t *\n\t\t * @spec openspec/changes/party-picker/specs/party-picker/spec.md#requirement-one-search-field-over-several-kinds-of-party\n\t\t * @param {string} term The search term.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync search(term) {\n\t\t\tconst seq = ++this.searchSeq\n\t\t\tthis.searching = true\n\t\t\tconst sets = await Promise.all((this.sources || []).map(async (source) => {\n\t\t\t\ttry {\n\t\t\t\t\tif (source.type === 'contacts') {\n\t\t\t\t\t\tconst { data } = await axios.post(generateUrl('/contactsmenu/contacts'), { filter: term })\n\t\t\t\t\t\treturn (data && Array.isArray(data.contacts) ? data.contacts : []).map((c) => this.contactOptionOf(source, c))\n\t\t\t\t\t}\n\t\t\t\t\tif (!source.register || !source.schema) {\n\t\t\t\t\t\treturn []\n\t\t\t\t\t}\n\t\t\t\t\tconst { data } = await axios.get(generateUrl(`/apps/openregister/api/objects/${source.register}/${source.schema}`), { params: { _search: term, _limit: source.limit || 8 } })\n\t\t\t\t\treturn (data && Array.isArray(data.results) ? data.results : []).map((row) => this.optionOf(source, row))\n\t\t\t\t} catch {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t}))\n\t\t\tif (seq !== this.searchSeq) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.options = sets.flat().filter(Boolean)\n\t\t\tthis.searching = false\n\t\t},\n\n\t\t/**\n\t\t * Name a value the list does not hold: the first OpenRegister source\n\t\t * that has an object with that id.\n\t\t *\n\t\t * @param {string|number} id The id.\n\t\t * @return {Promise<void>}\n\t\t */\n\t\tasync lookUp(id) {\n\t\t\tfor (const source of (this.sources || []).filter((s) => s.register && s.schema && s.type !== 'contacts')) {\n\t\t\t\ttry {\n\t\t\t\t\tconst { data } = await axios.get(generateUrl(`/apps/openregister/api/objects/${source.register}/${source.schema}/${encodeURIComponent(id)}`))\n\t\t\t\t\tconst option = data ? this.optionOf(source, data) : null\n\t\t\t\t\tif (option && String(this.modelValue) === String(id)) {\n\t\t\t\t\t\tthis.known = option\n\t\t\t\t\t\treturn\n\t\t\t\t\t}\n\t\t\t\t} catch {\n\t\t\t\t\t// Not in this source; try the next.\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\n\t\t/**\n\t\t * Take the picked option: emit its id and the whole choice.\n\t\t *\n\t\t * @param {string|number|null} id The picked id.\n\t\t */\n\t\tonPick(id) {\n\t\t\tconst option = id === null ? null : this.options.find((o) => String(o.id) === String(id)) || null\n\t\t\tif (option) {\n\t\t\t\tthis.known = option\n\t\t\t}\n\t\t\t/** @event update:modelValue The chosen party's id, or null when cleared. */\n\t\t\tthis.$emit('update:modelValue', id)\n\t\t\t/** @event select The whole choice: `{ source, id, label, secondary, row }`, or null when cleared. */\n\t\t\tthis.$emit('select', option ? { source: option.source, id: option.id, label: option.label, secondary: option.secondary, row: option.row } : null)\n\t\t},\n\t},\n}\n</script>\n"],"names":[],"mappings":";;;;;;AAUE,IAAA,KAAK,EAAC,iBAAiB;AACtB,IAAA,UAAU,EAAE,QAAa,CAAA,cAAA;AACzB,IAAA,OAAO,EAAE,KAAO,CAAA,OAAA;AAChB,IAAA,UAAU,EAAE,MAAK,CAAA,UAAA;AACjB,IAAA,YAAY,EAAE,MAAM,CAAA,YAAA;AACpB,IAAA,WAAW,EAAE,MAAA,CAAA,WAAK,GAAA,QAAA,CAAA,WAAA,CAAA,MAAA,CAAA,WAAA,CAAA,GAAA,EAAA;AAClB,IAAA,OAAO,EAAE,KAAS,CAAA,SAAA;AAClB,IAAA,UAAU,EAAE,KAAI;AAChB,IAAA,SAAS,EAAE,MAAS,CAAA,SAAA;;;;;;;;;;"}
@@ -0,0 +1,9 @@
1
+ import script from './CnSavedViewEditDialog.vue2.js';
2
+ import { render } from './CnSavedViewEditDialog.vue3.js';
3
+
4
+ script.render = render;
5
+ script.__scopeId = "data-v-60baacaa";
6
+ const __sfc_main = script;
7
+
8
+ export { __sfc_main as default };
9
+ //# sourceMappingURL=CnSavedViewEditDialog.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnSavedViewEditDialog.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
@@ -0,0 +1,95 @@
1
+ import { translate } from '@nextcloud/l10n';
2
+ import { NcButton, NcCheckboxRadioSwitch, NcDialog, NcLoadingIcon, NcNoteCard, NcTextField } from '@nextcloud/vue';
3
+
4
+ /**
5
+ * CnSavedViewEditDialog — rename an own saved view and, when asked, replace
6
+ * its criteria with the filters, search and sort the list shows now. Opened by
7
+ * `CnIndexPage` from the Edit entry of `CnSavedViewsControl`. Emits
8
+ * `confirm({ name, replaceCriteria })`; the parent saves and either closes the
9
+ * dialog or reports a failure through `setError()`, which keeps the form open.
10
+ *
11
+ * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3
12
+ */
13
+ var script = {
14
+ name: 'CnSavedViewEditDialog',
15
+
16
+ components: { NcButton, NcCheckboxRadioSwitch, NcDialog, NcLoadingIcon, NcNoteCard, NcTextField },
17
+
18
+ props: {
19
+ /** The view being edited (its `name` fills the field). */
20
+ view: {
21
+ type: Object,
22
+ default: () => ({}),
23
+ },
24
+
25
+ /** Dialog title; empty reads "Edit view: {name}". */
26
+ dialogTitle: {
27
+ type: String,
28
+ default: '',
29
+ },
30
+ },
31
+
32
+ emits: ['close', 'confirm'],
33
+
34
+ data() {
35
+ return {
36
+ name: (this.view && typeof this.view.name === 'string') ? this.view.name : '',
37
+ replaceCriteria: false,
38
+ loading: false,
39
+ error: '',
40
+ }
41
+ },
42
+
43
+ computed: {
44
+ /** @return {string} The title. */
45
+ resolvedTitle() {
46
+ return this.dialogTitle || translate('nextcloud-vue', 'Edit view: {name}', { name: (this.view && this.view.name) || '' })
47
+ },
48
+
49
+ /** @return {boolean} Whether the view is shared with anyone. */
50
+ isShared() {
51
+ return Array.isArray(this.view && this.view.sharedWith) && this.view.sharedWith.length > 0
52
+ },
53
+ },
54
+
55
+ methods: {
56
+ t: translate,
57
+
58
+ /**
59
+ * Save clicked with a non-empty name.
60
+ *
61
+ * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3
62
+ */
63
+ onConfirm() {
64
+ if (!this.name.trim()) {
65
+ return
66
+ }
67
+ this.loading = true;
68
+ this.error = '';
69
+ /**
70
+ * @event confirm Save clicked. Payload: `{ name, replaceCriteria }`.
71
+ * @type {object}
72
+ */
73
+ this.$emit('confirm', { name: this.name.trim(), replaceCriteria: this.replaceCriteria });
74
+ },
75
+
76
+ onClose() {
77
+ /** @event close Dialog dismissed. */
78
+ this.$emit('close');
79
+ },
80
+
81
+ /**
82
+ * Parent-callable (via ref): show a refused save and re-enable the form.
83
+ *
84
+ * @param {string} message The server's message.
85
+ * @public
86
+ */
87
+ setError(message) {
88
+ this.loading = false;
89
+ this.error = message || translate('nextcloud-vue', 'Could not save the view');
90
+ },
91
+ },
92
+ };
93
+
94
+ export { script as default };
95
+ //# sourceMappingURL=CnSavedViewEditDialog.vue2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnSavedViewEditDialog.vue2.js","sources":["../../../../src/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<NcDialog\n\t\t:name=\"resolvedTitle\"\n\t\tsize=\"small\"\n\t\t:noClose=\"loading\"\n\t\t@closing=\"onClose\">\n\t\t<div class=\"cn-edit-view\" data-testid=\"cn-modal\" data-testid-modal=\"cn-saved-view-edit-dialog\">\n\t\t\t<NcNoteCard v-if=\"error\" type=\"error\">\n\t\t\t\t{{ error }}\n\t\t\t</NcNoteCard>\n\t\t\t<p class=\"cn-edit-view__intro\">\n\t\t\t\t{{ t('nextcloud-vue', 'Give the view another name, or replace its criteria with what the list shows now.') }}\n\t\t\t</p>\n\t\t\t<NcTextField\n\t\t\t\t:modelValue=\"name\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Name')\"\n\t\t\t\t:labelVisible=\"true\"\n\t\t\t\tdata-testid=\"cn-saved-view-edit-name\"\n\t\t\t\t@update:modelValue=\"(v) => name = v\" />\n\t\t\t<fieldset class=\"cn-edit-view__criteria\" data-testid=\"cn-saved-view-edit-replace\">\n\t\t\t\t<legend>{{ t('nextcloud-vue', 'Criteria') }}</legend>\n\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname=\"cn-edit-view-criteria\"\n\t\t\t\t\tvalue=\"keep\"\n\t\t\t\t\t:modelValue=\"replaceCriteria ? 'replace' : 'keep'\"\n\t\t\t\t\tdata-testid=\"cn-saved-view-edit-keep\"\n\t\t\t\t\t@update:modelValue=\"replaceCriteria = false\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Keep what is saved') }}\n\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname=\"cn-edit-view-criteria\"\n\t\t\t\t\tvalue=\"replace\"\n\t\t\t\t\t:modelValue=\"replaceCriteria ? 'replace' : 'keep'\"\n\t\t\t\t\tdata-testid=\"cn-saved-view-edit-replace-current\"\n\t\t\t\t\t@update:modelValue=\"replaceCriteria = true\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Replace with the current search term, filters and sort') }}\n\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t</fieldset>\n\t\t\t<p v-if=\"isShared\" class=\"cn-edit-view__note\">\n\t\t\t\t{{ t('nextcloud-vue', 'Whoever you share the view with sees the change at once.') }}\n\t\t\t</p>\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"loading\" @click=\"onClose\">\n\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"loading || !name.trim()\"\n\t\t\t\tdata-testid=\"cn-saved-view-edit-confirm\"\n\t\t\t\t@click=\"onConfirm\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" :name=\"t('nextcloud-vue', 'Loading …')\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('nextcloud-vue', 'Save') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcCheckboxRadioSwitch, NcDialog, NcLoadingIcon, NcNoteCard, NcTextField } from '@nextcloud/vue'\n\n/**\n * CnSavedViewEditDialog — rename an own saved view and, when asked, replace\n * its criteria with the filters, search and sort the list shows now. Opened by\n * `CnIndexPage` from the Edit entry of `CnSavedViewsControl`. Emits\n * `confirm({ name, replaceCriteria })`; the parent saves and either closes the\n * dialog or reports a failure through `setError()`, which keeps the form open.\n *\n * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3\n */\nexport default {\n\tname: 'CnSavedViewEditDialog',\n\n\tcomponents: { NcButton, NcCheckboxRadioSwitch, NcDialog, NcLoadingIcon, NcNoteCard, NcTextField },\n\n\tprops: {\n\t\t/** The view being edited (its `name` fills the field). */\n\t\tview: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Dialog title; empty reads \"Edit view: {name}\". */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['close', 'confirm'],\n\n\tdata() {\n\t\treturn {\n\t\t\tname: (this.view && typeof this.view.name === 'string') ? this.view.name : '',\n\t\t\treplaceCriteria: false,\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {string} The title. */\n\t\tresolvedTitle() {\n\t\t\treturn this.dialogTitle || t('nextcloud-vue', 'Edit view: {name}', { name: (this.view && this.view.name) || '' })\n\t\t},\n\n\t\t/** @return {boolean} Whether the view is shared with anyone. */\n\t\tisShared() {\n\t\t\treturn Array.isArray(this.view && this.view.sharedWith) && this.view.sharedWith.length > 0\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Save clicked with a non-empty name.\n\t\t *\n\t\t * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3\n\t\t */\n\t\tonConfirm() {\n\t\t\tif (!this.name.trim()) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\t/**\n\t\t\t * @event confirm Save clicked. Payload: `{ name, replaceCriteria }`.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('confirm', { name: this.name.trim(), replaceCriteria: this.replaceCriteria })\n\t\t},\n\n\t\tonClose() {\n\t\t\t/** @event close Dialog dismissed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\t/**\n\t\t * Parent-callable (via ref): show a refused save and re-enable the form.\n\t\t *\n\t\t * @param {string} message The server's message.\n\t\t * @public\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.error = message || t('nextcloud-vue', 'Could not save the view')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-edit-view__intro,\n.cn-edit-view__note {\n\tmargin: 0;\n}\n\n.cn-edit-view__note {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-edit-view__criteria {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tborder: 0;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-edit-view__criteria legend {\n\tfont-weight: bold;\n\tmargin-bottom: 4px;\n}\n\n.cn-edit-view {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tpadding-block: 8px;\n}\n</style>\n"],"names":["t"],"mappings":";;;AAsEA;AACC;AACA;;AAEA;AACA;AACA;AACA;;AAED,aAAe;CACd,IAAI,EAAE,uBAAuB;;AAE7B,CAAA,UAAU,EAAE,EAAE,QAAQ,EAAE,qBAAqB,EAAE,QAAQ,EAAE,aAAa,EAAE,UAAU,EAAE,aAAa;;AAEjG,CAAA,KAAK,EAAE;;EAEN,IAAI,EAAE;GACL,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;EACA,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;EACD;;CAED,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;;AAE3B,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;AACN,GAAA,IAAI,EAAE,CAAC,IAAI,CAAC,IAAK,IAAG,OAAO,IAAI,CAAC,IAAI,CAAC,IAAG,KAAM,QAAQ,IAAI,IAAI,CAAC,IAAI,CAAC,IAAK,GAAE,EAAE;AAC7E,GAAA,eAAe,EAAE,KAAK;GACtB,OAAO,EAAE,KAAK;AACd,GAAA,KAAK,EAAE,EAAE;AACV,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;;AAET,EAAA,aAAa,GAAG;GACf,OAAO,IAAI,CAAC,WAAU,IAAKA,SAAC,CAAC,eAAe,EAAE,mBAAmB,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,IAAK,IAAG,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,EAAC,EAAG,CAAA;GAChH;;;EAGD,QAAQ,GAAG;AACV,GAAA,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAK,IAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAE,IAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,SAAS,CAAA;GACzF;EACD;;AAED,CAAA,OAAO,EAAE;KACRA,SAAC;;AAED;AACC;AACA;AACA;;EAED,SAAS,GAAG;AACX,GAAA,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE;IACtB,MAAK;AACN,IAAA;AACA,GAAA,IAAI,CAAC,OAAM,GAAI,KAAG;GAClB,IAAI,CAAC,KAAM,GAAE,GAAC;AACd;;;;AAIA,GAAA,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,eAAe,EAAE,IAAI,CAAC,iBAAiB,EAAA;GACvF;;AAED,EAAA,OAAO,GAAG;AACT;AACA,GAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAA;GAClB;;AAED;;AAEC;AACA;AACA;;AAED,EAAA,QAAQ,CAAC,OAAO,EAAE;AACjB,GAAA,IAAI,CAAC,OAAQ,GAAE,MAAI;GACnB,IAAI,CAAC,KAAI,GAAI,OAAQ,IAAGA,SAAC,CAAC,eAAe,EAAE,yBAAyB,EAAA;GACpE;EACD;AACF;;;;"}
@@ -0,0 +1,123 @@
1
+ import { resolveComponent, openBlock, createBlock, withCtx, createVNode, createTextVNode, toDisplayString, createCommentVNode, createElementVNode, createElementBlock } from 'vue';
2
+
3
+ const _hoisted_1 = {
4
+ class: "cn-edit-view",
5
+ "data-testid": "cn-modal",
6
+ "data-testid-modal": "cn-saved-view-edit-dialog"
7
+ };
8
+ const _hoisted_2 = { class: "cn-edit-view__intro" };
9
+ const _hoisted_3 = {
10
+ class: "cn-edit-view__criteria",
11
+ "data-testid": "cn-saved-view-edit-replace"
12
+ };
13
+ const _hoisted_4 = {
14
+ key: 1,
15
+ class: "cn-edit-view__note"
16
+ };
17
+
18
+ function render(_ctx, _cache, $props, $setup, $data, $options) {
19
+ const _component_NcNoteCard = resolveComponent("NcNoteCard");
20
+ const _component_NcTextField = resolveComponent("NcTextField");
21
+ const _component_NcCheckboxRadioSwitch = resolveComponent("NcCheckboxRadioSwitch");
22
+ const _component_NcButton = resolveComponent("NcButton");
23
+ const _component_NcLoadingIcon = resolveComponent("NcLoadingIcon");
24
+ const _component_NcDialog = resolveComponent("NcDialog");
25
+
26
+ return (openBlock(), createBlock(_component_NcDialog, {
27
+ name: $options.resolvedTitle,
28
+ size: "small",
29
+ noClose: $data.loading,
30
+ onClosing: $options.onClose
31
+ }, {
32
+ actions: withCtx(() => [
33
+ createVNode(_component_NcButton, {
34
+ disabled: $data.loading,
35
+ onClick: $options.onClose
36
+ }, {
37
+ default: withCtx(() => [
38
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'Cancel')), 1 /* TEXT */)
39
+ ]),
40
+ _: 1 /* STABLE */
41
+ }, 8 /* PROPS */, ["disabled", "onClick"]),
42
+ createVNode(_component_NcButton, {
43
+ variant: "primary",
44
+ disabled: $data.loading || !$data.name.trim(),
45
+ "data-testid": "cn-saved-view-edit-confirm",
46
+ onClick: $options.onConfirm
47
+ }, {
48
+ icon: withCtx(() => [
49
+ ($data.loading)
50
+ ? (openBlock(), createBlock(_component_NcLoadingIcon, {
51
+ key: 0,
52
+ size: 20,
53
+ name: $options.t('nextcloud-vue', 'Loading …')
54
+ }, null, 8 /* PROPS */, ["name"]))
55
+ : createCommentVNode("v-if", true)
56
+ ]),
57
+ default: withCtx(() => [
58
+ createTextVNode(" " + toDisplayString($options.t('nextcloud-vue', 'Save')), 1 /* TEXT */)
59
+ ]),
60
+ _: 1 /* STABLE */
61
+ }, 8 /* PROPS */, ["disabled", "onClick"])
62
+ ]),
63
+ default: withCtx(() => [
64
+ createElementVNode("div", _hoisted_1, [
65
+ ($data.error)
66
+ ? (openBlock(), createBlock(_component_NcNoteCard, {
67
+ key: 0,
68
+ type: "error"
69
+ }, {
70
+ default: withCtx(() => [
71
+ createTextVNode(toDisplayString($data.error), 1 /* TEXT */)
72
+ ]),
73
+ _: 1 /* STABLE */
74
+ }))
75
+ : createCommentVNode("v-if", true),
76
+ createElementVNode("p", _hoisted_2, toDisplayString($options.t('nextcloud-vue', 'Give the view another name, or replace its criteria with what the list shows now.')), 1 /* TEXT */),
77
+ createVNode(_component_NcTextField, {
78
+ modelValue: $data.name,
79
+ label: $options.t('nextcloud-vue', 'Name'),
80
+ labelVisible: true,
81
+ "data-testid": "cn-saved-view-edit-name",
82
+ "onUpdate:modelValue": _cache[0] || (_cache[0] = (v) => $data.name = v)
83
+ }, null, 8 /* PROPS */, ["modelValue", "label"]),
84
+ createElementVNode("fieldset", _hoisted_3, [
85
+ createElementVNode("legend", null, toDisplayString($options.t('nextcloud-vue', 'Criteria')), 1 /* TEXT */),
86
+ createVNode(_component_NcCheckboxRadioSwitch, {
87
+ type: "radio",
88
+ name: "cn-edit-view-criteria",
89
+ value: "keep",
90
+ modelValue: $data.replaceCriteria ? 'replace' : 'keep',
91
+ "data-testid": "cn-saved-view-edit-keep",
92
+ "onUpdate:modelValue": _cache[1] || (_cache[1] = $event => ($data.replaceCriteria = false))
93
+ }, {
94
+ default: withCtx(() => [
95
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'Keep what is saved')), 1 /* TEXT */)
96
+ ]),
97
+ _: 1 /* STABLE */
98
+ }, 8 /* PROPS */, ["modelValue"]),
99
+ createVNode(_component_NcCheckboxRadioSwitch, {
100
+ type: "radio",
101
+ name: "cn-edit-view-criteria",
102
+ value: "replace",
103
+ modelValue: $data.replaceCriteria ? 'replace' : 'keep',
104
+ "data-testid": "cn-saved-view-edit-replace-current",
105
+ "onUpdate:modelValue": _cache[2] || (_cache[2] = $event => ($data.replaceCriteria = true))
106
+ }, {
107
+ default: withCtx(() => [
108
+ createTextVNode(toDisplayString($options.t('nextcloud-vue', 'Replace with the current search term, filters and sort')), 1 /* TEXT */)
109
+ ]),
110
+ _: 1 /* STABLE */
111
+ }, 8 /* PROPS */, ["modelValue"])
112
+ ]),
113
+ ($options.isShared)
114
+ ? (openBlock(), createElementBlock("p", _hoisted_4, toDisplayString($options.t('nextcloud-vue', 'Whoever you share the view with sees the change at once.')), 1 /* TEXT */))
115
+ : createCommentVNode("v-if", true)
116
+ ])
117
+ ]),
118
+ _: 1 /* STABLE */
119
+ }, 8 /* PROPS */, ["name", "noClose", "onClosing"]))
120
+ }
121
+
122
+ export { render };
123
+ //# sourceMappingURL=CnSavedViewEditDialog.vue3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CnSavedViewEditDialog.vue3.js","sources":["../../../../src/components/CnSavedViewEditDialog/CnSavedViewEditDialog.vue?vue&type=template&id=60baacaa&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<NcDialog\n\t\t:name=\"resolvedTitle\"\n\t\tsize=\"small\"\n\t\t:noClose=\"loading\"\n\t\t@closing=\"onClose\">\n\t\t<div class=\"cn-edit-view\" data-testid=\"cn-modal\" data-testid-modal=\"cn-saved-view-edit-dialog\">\n\t\t\t<NcNoteCard v-if=\"error\" type=\"error\">\n\t\t\t\t{{ error }}\n\t\t\t</NcNoteCard>\n\t\t\t<p class=\"cn-edit-view__intro\">\n\t\t\t\t{{ t('nextcloud-vue', 'Give the view another name, or replace its criteria with what the list shows now.') }}\n\t\t\t</p>\n\t\t\t<NcTextField\n\t\t\t\t:modelValue=\"name\"\n\t\t\t\t:label=\"t('nextcloud-vue', 'Name')\"\n\t\t\t\t:labelVisible=\"true\"\n\t\t\t\tdata-testid=\"cn-saved-view-edit-name\"\n\t\t\t\t@update:modelValue=\"(v) => name = v\" />\n\t\t\t<fieldset class=\"cn-edit-view__criteria\" data-testid=\"cn-saved-view-edit-replace\">\n\t\t\t\t<legend>{{ t('nextcloud-vue', 'Criteria') }}</legend>\n\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname=\"cn-edit-view-criteria\"\n\t\t\t\t\tvalue=\"keep\"\n\t\t\t\t\t:modelValue=\"replaceCriteria ? 'replace' : 'keep'\"\n\t\t\t\t\tdata-testid=\"cn-saved-view-edit-keep\"\n\t\t\t\t\t@update:modelValue=\"replaceCriteria = false\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Keep what is saved') }}\n\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t\t<NcCheckboxRadioSwitch\n\t\t\t\t\ttype=\"radio\"\n\t\t\t\t\tname=\"cn-edit-view-criteria\"\n\t\t\t\t\tvalue=\"replace\"\n\t\t\t\t\t:modelValue=\"replaceCriteria ? 'replace' : 'keep'\"\n\t\t\t\t\tdata-testid=\"cn-saved-view-edit-replace-current\"\n\t\t\t\t\t@update:modelValue=\"replaceCriteria = true\">\n\t\t\t\t\t{{ t('nextcloud-vue', 'Replace with the current search term, filters and sort') }}\n\t\t\t\t</NcCheckboxRadioSwitch>\n\t\t\t</fieldset>\n\t\t\t<p v-if=\"isShared\" class=\"cn-edit-view__note\">\n\t\t\t\t{{ t('nextcloud-vue', 'Whoever you share the view with sees the change at once.') }}\n\t\t\t</p>\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"loading\" @click=\"onClose\">\n\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"loading || !name.trim()\"\n\t\t\t\tdata-testid=\"cn-saved-view-edit-confirm\"\n\t\t\t\t@click=\"onConfirm\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" :name=\"t('nextcloud-vue', 'Loading …')\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('nextcloud-vue', 'Save') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcCheckboxRadioSwitch, NcDialog, NcLoadingIcon, NcNoteCard, NcTextField } from '@nextcloud/vue'\n\n/**\n * CnSavedViewEditDialog — rename an own saved view and, when asked, replace\n * its criteria with the filters, search and sort the list shows now. Opened by\n * `CnIndexPage` from the Edit entry of `CnSavedViewsControl`. Emits\n * `confirm({ name, replaceCriteria })`; the parent saves and either closes the\n * dialog or reports a failure through `setError()`, which keeps the form open.\n *\n * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3\n */\nexport default {\n\tname: 'CnSavedViewEditDialog',\n\n\tcomponents: { NcButton, NcCheckboxRadioSwitch, NcDialog, NcLoadingIcon, NcNoteCard, NcTextField },\n\n\tprops: {\n\t\t/** The view being edited (its `name` fills the field). */\n\t\tview: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Dialog title; empty reads \"Edit view: {name}\". */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['close', 'confirm'],\n\n\tdata() {\n\t\treturn {\n\t\t\tname: (this.view && typeof this.view.name === 'string') ? this.view.name : '',\n\t\t\treplaceCriteria: false,\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {string} The title. */\n\t\tresolvedTitle() {\n\t\t\treturn this.dialogTitle || t('nextcloud-vue', 'Edit view: {name}', { name: (this.view && this.view.name) || '' })\n\t\t},\n\n\t\t/** @return {boolean} Whether the view is shared with anyone. */\n\t\tisShared() {\n\t\t\treturn Array.isArray(this.view && this.view.sharedWith) && this.view.sharedWith.length > 0\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\t/**\n\t\t * Save clicked with a non-empty name.\n\t\t *\n\t\t * @spec openspec/changes/saved-views-manage-and-defaults/tasks.md#task-3\n\t\t */\n\t\tonConfirm() {\n\t\t\tif (!this.name.trim()) {\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\t/**\n\t\t\t * @event confirm Save clicked. Payload: `{ name, replaceCriteria }`.\n\t\t\t * @type {object}\n\t\t\t */\n\t\t\tthis.$emit('confirm', { name: this.name.trim(), replaceCriteria: this.replaceCriteria })\n\t\t},\n\n\t\tonClose() {\n\t\t\t/** @event close Dialog dismissed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\t/**\n\t\t * Parent-callable (via ref): show a refused save and re-enable the form.\n\t\t *\n\t\t * @param {string} message The server's message.\n\t\t * @public\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.error = message || t('nextcloud-vue', 'Could not save the view')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-edit-view__intro,\n.cn-edit-view__note {\n\tmargin: 0;\n}\n\n.cn-edit-view__note {\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.cn-edit-view__criteria {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n\tborder: 0;\n\tmargin: 0;\n\tpadding: 0;\n}\n\n.cn-edit-view__criteria legend {\n\tfont-weight: bold;\n\tmargin-bottom: 4px;\n}\n\n.cn-edit-view {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tpadding-block: 8px;\n}\n</style>\n"],"names":["_createBlock","_createVNode","_createTextVNode","_createElementVNode","_toDisplayString","_createElementBlock"],"mappings":"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"}
@@ -2,7 +2,7 @@ import script from './CnSavedViewShareDialog.vue2.js';
2
2
  import { render } from './CnSavedViewShareDialog.vue3.js';
3
3
 
4
4
  script.render = render;
5
- script.__scopeId = "data-v-f44dbce0";
5
+ script.__scopeId = "data-v-346505e6";
6
6
  const __sfc_main = script;
7
7
 
8
8
  export { __sfc_main as default };
@@ -1,6 +1,7 @@
1
1
  import { translate } from '@nextcloud/l10n';
2
2
  import { NcButton, NcDialog, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue';
3
3
  import __sfc_main from '../CnSavedViewShareFields/CnSavedViewShareFields.vue.js';
4
+ import { normalizeSharedWith } from '../../utils/savedViewHelpers.js';
4
5
 
5
6
  /**
6
7
  * CnSavedViewShareDialog — change who a saved view is shared with. Opened by
@@ -20,10 +21,10 @@ var script = {
20
21
  default: () => ({}),
21
22
  },
22
23
 
23
- /** Dialog title. */
24
+ /** Dialog title; empty reads "Share view: {name}". */
24
25
  dialogTitle: {
25
26
  type: String,
26
- default: () => translate('nextcloud-vue', 'Share view'),
27
+ default: '',
27
28
  },
28
29
  },
29
30
 
@@ -31,12 +32,19 @@ var script = {
31
32
 
32
33
  data() {
33
34
  return {
34
- sharedWith: Array.isArray(this.view && this.view.sharedWith) ? this.view.sharedWith.map((e) => ({ group: e.group, mode: e.mode === 'write' ? 'write' : 'read' })) : [],
35
+ sharedWith: normalizeSharedWith(this.view && this.view.sharedWith),
35
36
  loading: false,
36
37
  error: '',
37
38
  }
38
39
  },
39
40
 
41
+ computed: {
42
+ /** @return {string} The title: `dialogTitle`, else "Share view: {name}". */
43
+ resolvedTitle() {
44
+ return this.dialogTitle || translate('nextcloud-vue', 'Share view: {name}', { name: (this.view && this.view.name) || '' })
45
+ },
46
+ },
47
+
40
48
  methods: {
41
49
  t: translate,
42
50
 
@@ -44,8 +52,8 @@ var script = {
44
52
  this.loading = true;
45
53
  this.error = '';
46
54
  /**
47
- * @event confirm Save clicked. Payload: the audience, `[{ group, mode }]` (`[]` to stop sharing).
48
- * @type {Array<{group: string, mode: string}>}
55
+ * @event confirm Save clicked. Payload: the audience, `[{ group, mode }]` and `[{ user, mode }]` (`[]` to stop sharing).
56
+ * @type {Array<{group?: string, user?: string, mode: string}>}
49
57
  */
50
58
  this.$emit('confirm', this.sharedWith);
51
59
  },
@@ -1 +1 @@
1
- {"version":3,"file":"CnSavedViewShareDialog.vue2.js","sources":["../../../../src/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<NcDialog\n\t\t:name=\"dialogTitle\"\n\t\tsize=\"small\"\n\t\t:noClose=\"loading\"\n\t\t@closing=\"onClose\">\n\t\t<div class=\"cn-share-view\" data-testid=\"cn-modal\" data-testid-modal=\"cn-saved-view-share-dialog\">\n\t\t\t<NcNoteCard v-if=\"error\" type=\"error\">\n\t\t\t\t{{ error }}\n\t\t\t</NcNoteCard>\n\t\t\t<CnSavedViewShareFields v-model=\"sharedWith\" />\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"loading\" @click=\"onClose\">\n\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"loading\"\n\t\t\t\tdata-testid=\"cn-saved-view-share-confirm\"\n\t\t\t\t@click=\"onConfirm\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" :name=\"t('nextcloud-vue', 'Loading …')\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('nextcloud-vue', 'Save sharing') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcDialog, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport CnSavedViewShareFields from '../CnSavedViewShareFields/CnSavedViewShareFields.vue'\n\n/**\n * CnSavedViewShareDialog — change who a saved view is shared with. Opened by\n * `CnIndexPage` from the Share entry of an own view in `CnSavedViewsControl`.\n * Emits `confirm(sharedWith)`; the parent saves and either closes the dialog\n * or reports a failure through `setError()`, which keeps the form open.\n */\nexport default {\n\tname: 'CnSavedViewShareDialog',\n\n\tcomponents: { CnSavedViewShareFields, NcButton, NcDialog, NcLoadingIcon, NcNoteCard },\n\n\tprops: {\n\t\t/** The view being shared (its `sharedWith` seeds the fields). */\n\t\tview: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Dialog title. */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Share view'),\n\t\t},\n\t},\n\n\temits: ['close', 'confirm'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsharedWith: Array.isArray(this.view && this.view.sharedWith) ? this.view.sharedWith.map((e) => ({ group: e.group, mode: e.mode === 'write' ? 'write' : 'read' })) : [],\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tonConfirm() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\t/**\n\t\t\t * @event confirm Save clicked. Payload: the audience, `[{ group, mode }]` (`[]` to stop sharing).\n\t\t\t * @type {Array<{group: string, mode: string}>}\n\t\t\t */\n\t\t\tthis.$emit('confirm', this.sharedWith)\n\t\t},\n\n\t\tonClose() {\n\t\t\t/** @event close Dialog dismissed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\t/**\n\t\t * Parent-callable (via ref): show the server's message and re-enable the form.\n\t\t *\n\t\t * @param {string} message The message.\n\t\t * @public\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.error = message || t('nextcloud-vue', 'Failed to save sharing')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-share-view {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tpadding-block: 8px;\n}\n</style>\n"],"names":["CnSavedViewShareFields","t"],"mappings":";;;;AAuCA;AACC;AACA;AACA;;;AAGD,aAAe;CACd,IAAI,EAAE,wBAAwB;;AAE9B,CAAA,UAAU,EAAE,0BAAEA,UAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY;;AAErF,CAAA,KAAK,EAAE;;EAEN,IAAI,EAAE;GACL,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;EACA,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,MAAMC,SAAC,CAAC,eAAe,EAAE,YAAY,CAAC;GAC/C;EACD;;CAED,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;;AAE3B,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;AACN,GAAA,UAAU,EAAE,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,CAAE,GAAE,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAK,KAAI,OAAM,GAAI,OAAQ,GAAE,QAAQ,CAAC,CAAE,GAAE,EAAE;GACtK,OAAO,EAAE,KAAK;AACd,GAAA,KAAK,EAAE,EAAE;AACV,GAAA;EACA;;AAED,CAAA,OAAO,EAAE;KACRA,SAAC;;EAED,SAAS,GAAG;AACX,GAAA,IAAI,CAAC,OAAM,GAAI,KAAG;GAClB,IAAI,CAAC,KAAM,GAAE,GAAC;AACd;AACC;AACA;;AAED,GAAA,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAA;GACrC;;AAED,EAAA,OAAO,GAAG;AACT;AACA,GAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAA;GAClB;;AAED;AACC;AACA;AACA;AACA;;AAED,EAAA,QAAQ,CAAC,OAAO,EAAE;AACjB,GAAA,IAAI,CAAC,OAAQ,GAAE,MAAI;GACnB,IAAI,CAAC,KAAI,GAAI,OAAQ,IAAGA,SAAC,CAAC,eAAe,EAAE,wBAAwB,EAAA;GACnE;EACD;AACF;;;;"}
1
+ {"version":3,"file":"CnSavedViewShareDialog.vue2.js","sources":["../../../../src/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<NcDialog\n\t\t:name=\"resolvedTitle\"\n\t\tsize=\"small\"\n\t\t:noClose=\"loading\"\n\t\t@closing=\"onClose\">\n\t\t<div class=\"cn-share-view\" data-testid=\"cn-modal\" data-testid-modal=\"cn-saved-view-share-dialog\">\n\t\t\t<NcNoteCard v-if=\"error\" type=\"error\">\n\t\t\t\t{{ error }}\n\t\t\t</NcNoteCard>\n\t\t\t<p class=\"cn-share-view__intro\">\n\t\t\t\t{{ t('nextcloud-vue', 'Whoever gets the view sees it under Shared with me. It is yours and stays yours.') }}\n\t\t\t</p>\n\t\t\t<CnSavedViewShareFields v-model=\"sharedWith\" />\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"loading\" @click=\"onClose\">\n\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"loading\"\n\t\t\t\tdata-testid=\"cn-saved-view-share-confirm\"\n\t\t\t\t@click=\"onConfirm\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" :name=\"t('nextcloud-vue', 'Loading …')\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('nextcloud-vue', 'Save sharing') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcDialog, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport CnSavedViewShareFields from '../CnSavedViewShareFields/CnSavedViewShareFields.vue'\nimport { normalizeSharedWith } from '../../utils/savedViewHelpers.js'\n\n/**\n * CnSavedViewShareDialog — change who a saved view is shared with. Opened by\n * `CnIndexPage` from the Share entry of an own view in `CnSavedViewsControl`.\n * Emits `confirm(sharedWith)`; the parent saves and either closes the dialog\n * or reports a failure through `setError()`, which keeps the form open.\n */\nexport default {\n\tname: 'CnSavedViewShareDialog',\n\n\tcomponents: { CnSavedViewShareFields, NcButton, NcDialog, NcLoadingIcon, NcNoteCard },\n\n\tprops: {\n\t\t/** The view being shared (its `sharedWith` seeds the fields). */\n\t\tview: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Dialog title; empty reads \"Share view: {name}\". */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['close', 'confirm'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsharedWith: normalizeSharedWith(this.view && this.view.sharedWith),\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {string} The title: `dialogTitle`, else \"Share view: {name}\". */\n\t\tresolvedTitle() {\n\t\t\treturn this.dialogTitle || t('nextcloud-vue', 'Share view: {name}', { name: (this.view && this.view.name) || '' })\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tonConfirm() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\t/**\n\t\t\t * @event confirm Save clicked. Payload: the audience, `[{ group, mode }]` and `[{ user, mode }]` (`[]` to stop sharing).\n\t\t\t * @type {Array<{group?: string, user?: string, mode: string}>}\n\t\t\t */\n\t\t\tthis.$emit('confirm', this.sharedWith)\n\t\t},\n\n\t\tonClose() {\n\t\t\t/** @event close Dialog dismissed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\t/**\n\t\t * Parent-callable (via ref): show the server's message and re-enable the form.\n\t\t *\n\t\t * @param {string} message The message.\n\t\t * @public\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.error = message || t('nextcloud-vue', 'Failed to save sharing')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-share-view__intro {\n\tmargin: 0;\n}\n\n.cn-share-view {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tpadding-block: 8px;\n}\n</style>\n"],"names":["CnSavedViewShareFields","t"],"mappings":";;;;;AA2CA;AACC;AACA;AACA;;;AAGD,aAAe;CACd,IAAI,EAAE,wBAAwB;;AAE9B,CAAA,UAAU,EAAE,0BAAEA,UAAsB,EAAE,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY;;AAErF,CAAA,KAAK,EAAE;;EAEN,IAAI,EAAE;GACL,IAAI,EAAE,MAAM;AACZ,GAAA,OAAO,EAAE,OAAO,EAAE,CAAC;GACnB;;AAED;EACA,WAAW,EAAE;GACZ,IAAI,EAAE,MAAM;GACZ,OAAO,EAAE,EAAE;GACX;EACD;;CAED,KAAK,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC;;AAE3B,CAAA,IAAI,GAAG;AACN,EAAA,OAAO;AACN,GAAA,UAAU,EAAE,mBAAmB,CAAC,IAAI,CAAC,IAAK,IAAG,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC;GAClE,OAAO,EAAE,KAAK;AACd,GAAA,KAAK,EAAE,EAAE;AACV,GAAA;EACA;;AAED,CAAA,QAAQ,EAAE;AACT;AACA,EAAA,aAAa,GAAG;GACf,OAAO,IAAI,CAAC,WAAU,IAAKC,SAAC,CAAC,eAAe,EAAE,oBAAoB,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,CAAC,IAAG,IAAK,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,EAAC,EAAG,CAAA;GACjH;EACD;;AAED,CAAA,OAAO,EAAE;KACRA,SAAC;;EAED,SAAS,GAAG;AACX,GAAA,IAAI,CAAC,OAAM,GAAI,KAAG;GAClB,IAAI,CAAC,KAAM,GAAE,GAAC;AACd;;;;AAIA,GAAA,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,EAAA;GACrC;;AAED,EAAA,OAAO,GAAG;AACT;AACA,GAAA,IAAI,CAAC,KAAK,CAAC,OAAO,EAAA;GAClB;;AAED;AACC;AACA;AACA;AACA;;AAED,EAAA,QAAQ,CAAC,OAAO,EAAE;AACjB,GAAA,IAAI,CAAC,OAAQ,GAAE,MAAI;GACnB,IAAI,CAAC,KAAI,GAAI,OAAQ,IAAGA,SAAC,CAAC,eAAe,EAAE,wBAAwB,EAAA;GACnE;EACD;AACF;;;;"}
@@ -5,6 +5,7 @@ const _hoisted_1 = {
5
5
  "data-testid": "cn-modal",
6
6
  "data-testid-modal": "cn-saved-view-share-dialog"
7
7
  };
8
+ const _hoisted_2 = { class: "cn-share-view__intro" };
8
9
 
9
10
  function render(_ctx, _cache, $props, $setup, $data, $options) {
10
11
  const _component_NcNoteCard = resolveComponent("NcNoteCard");
@@ -14,7 +15,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
14
15
  const _component_NcDialog = resolveComponent("NcDialog");
15
16
 
16
17
  return (openBlock(), createBlock(_component_NcDialog, {
17
- name: $props.dialogTitle,
18
+ name: $options.resolvedTitle,
18
19
  size: "small",
19
20
  noClose: $data.loading,
20
21
  onClosing: $options.onClose
@@ -63,6 +64,7 @@ function render(_ctx, _cache, $props, $setup, $data, $options) {
63
64
  _: 1 /* STABLE */
64
65
  }))
65
66
  : createCommentVNode("v-if", true),
67
+ createElementVNode("p", _hoisted_2, toDisplayString($options.t('nextcloud-vue', 'Whoever gets the view sees it under Shared with me. It is yours and stays yours.')), 1 /* TEXT */),
66
68
  createVNode(_component_CnSavedViewShareFields, {
67
69
  modelValue: $data.sharedWith,
68
70
  "onUpdate:modelValue": _cache[0] || (_cache[0] = $event => (($data.sharedWith) = $event))
@@ -1 +1 @@
1
- {"version":3,"file":"CnSavedViewShareDialog.vue3.js","sources":["../../../../src/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue?vue&type=template&id=f44dbce0&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<NcDialog\n\t\t:name=\"dialogTitle\"\n\t\tsize=\"small\"\n\t\t:noClose=\"loading\"\n\t\t@closing=\"onClose\">\n\t\t<div class=\"cn-share-view\" data-testid=\"cn-modal\" data-testid-modal=\"cn-saved-view-share-dialog\">\n\t\t\t<NcNoteCard v-if=\"error\" type=\"error\">\n\t\t\t\t{{ error }}\n\t\t\t</NcNoteCard>\n\t\t\t<CnSavedViewShareFields v-model=\"sharedWith\" />\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"loading\" @click=\"onClose\">\n\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"loading\"\n\t\t\t\tdata-testid=\"cn-saved-view-share-confirm\"\n\t\t\t\t@click=\"onConfirm\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" :name=\"t('nextcloud-vue', 'Loading …')\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('nextcloud-vue', 'Save sharing') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcDialog, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport CnSavedViewShareFields from '../CnSavedViewShareFields/CnSavedViewShareFields.vue'\n\n/**\n * CnSavedViewShareDialog — change who a saved view is shared with. Opened by\n * `CnIndexPage` from the Share entry of an own view in `CnSavedViewsControl`.\n * Emits `confirm(sharedWith)`; the parent saves and either closes the dialog\n * or reports a failure through `setError()`, which keeps the form open.\n */\nexport default {\n\tname: 'CnSavedViewShareDialog',\n\n\tcomponents: { CnSavedViewShareFields, NcButton, NcDialog, NcLoadingIcon, NcNoteCard },\n\n\tprops: {\n\t\t/** The view being shared (its `sharedWith` seeds the fields). */\n\t\tview: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Dialog title. */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: () => t('nextcloud-vue', 'Share view'),\n\t\t},\n\t},\n\n\temits: ['close', 'confirm'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsharedWith: Array.isArray(this.view && this.view.sharedWith) ? this.view.sharedWith.map((e) => ({ group: e.group, mode: e.mode === 'write' ? 'write' : 'read' })) : [],\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tonConfirm() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\t/**\n\t\t\t * @event confirm Save clicked. Payload: the audience, `[{ group, mode }]` (`[]` to stop sharing).\n\t\t\t * @type {Array<{group: string, mode: string}>}\n\t\t\t */\n\t\t\tthis.$emit('confirm', this.sharedWith)\n\t\t},\n\n\t\tonClose() {\n\t\t\t/** @event close Dialog dismissed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\t/**\n\t\t * Parent-callable (via ref): show the server's message and re-enable the form.\n\t\t *\n\t\t * @param {string} message The message.\n\t\t * @public\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.error = message || t('nextcloud-vue', 'Failed to save sharing')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-share-view {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tpadding-block: 8px;\n}\n</style>\n"],"names":["_createBlock","_createVNode","_createTextVNode","_createElementVNode"],"mappings":";;;AAcO,EAAA,KAAK,EAAC,eAAe;AAAC,EAAA,aAAW,EAAC,UAAQ;AAAA,EAAA,mBAAA,EAAA,4BAAA;;;;;;;;;;uBAL/CA;AACC,IAAA,IAAI,EAAE,MAAW,CAAA,WAAA;AACjB,IAAA,IAAG,EAAC,OAAQ;AACX,IAAA,OAAM,OAAI,CAAA,OAAA;AACX,IAAA,SAAO,EAAE,QAAG,CAAA,OAAA;;AAOJ,IAAA,OAAA,UACP,MAEU;MAFVC,WAEU,CAAA,mBAAA,EAAA;AAFA,QAAA,QAAM,EAAA,KAAA,CAAA,OAAA;AAAA,QAAA,OAAA,EAAA,QAAA,CAAA,OAAA;;yBAChB,MAAkB;0CAAf,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,QAAA,CAAA,CAAA,EAAA,CAAA,YAAA;;;;MAEJA;AACA,QAAA,OAAO,EAAC,SAAO;AACd,QAAA,QAAQ,EAAE,KAAO,CAAA,OAAA;AAClB,QAAA,aAAU,EAAA,6BAAA;AACT,QAAA,OAAK,EAAE,QAAS,CAAA,SAAA;;AACR,QAAA,IAAA,UACR,MAAO;WAAA,KAAA,CAAA,OAAA;4BAAPD,WAAO,CAAA,wBAAA,EAAA;;AAAA,gBAAA,IAAA,EAAA,EAAA;AAAA,gBAAA,IAAA,EAAA,QAAA,CAAA,CAAA,CAAA,eAAA,EAAA,WAAA,CAAA;;;;yBACD;AAAA,UAAAE,eAAA,CAAA;;;;;qBAjBR,MAKK;AALL,MAAAC,kBAAA,CAKK,OALL,UAKK,EAAA;SAJD,KAAA,CAAA,KAAA;0BAAJH,WAEa,CAAA,qBAAA,EAAA;;AAFT,cAAA,IAAA,EAAA,OAAA;;+BACH,MAAW;gDAAR,KAAK,CAAA,KAAA,CAAA,EAAA,CAAA,YAAA;;;;;QAERC,WAAiC,CAAA,iCAAA,EAAA;sBAAD,KAAC,CAAA,UAAA;uEAAD,KAAC,CAAA,UAAA,IAAA,MAAA,CAAA,CAAA;;;;;;;;;;"}
1
+ {"version":3,"file":"CnSavedViewShareDialog.vue3.js","sources":["../../../../src/components/CnSavedViewShareDialog/CnSavedViewShareDialog.vue?vue&type=template&id=346505e6&lang.js"],"sourcesContent":["<!--\n - SPDX-FileCopyrightText: 2026 Conduction B.V.\n - SPDX-License-Identifier: EUPL-1.2\n-->\n<template>\n\t<NcDialog\n\t\t:name=\"resolvedTitle\"\n\t\tsize=\"small\"\n\t\t:noClose=\"loading\"\n\t\t@closing=\"onClose\">\n\t\t<div class=\"cn-share-view\" data-testid=\"cn-modal\" data-testid-modal=\"cn-saved-view-share-dialog\">\n\t\t\t<NcNoteCard v-if=\"error\" type=\"error\">\n\t\t\t\t{{ error }}\n\t\t\t</NcNoteCard>\n\t\t\t<p class=\"cn-share-view__intro\">\n\t\t\t\t{{ t('nextcloud-vue', 'Whoever gets the view sees it under Shared with me. It is yours and stays yours.') }}\n\t\t\t</p>\n\t\t\t<CnSavedViewShareFields v-model=\"sharedWith\" />\n\t\t</div>\n\t\t<template #actions>\n\t\t\t<NcButton :disabled=\"loading\" @click=\"onClose\">\n\t\t\t\t{{ t('nextcloud-vue', 'Cancel') }}\n\t\t\t</NcButton>\n\t\t\t<NcButton\n\t\t\t\tvariant=\"primary\"\n\t\t\t\t:disabled=\"loading\"\n\t\t\t\tdata-testid=\"cn-saved-view-share-confirm\"\n\t\t\t\t@click=\"onConfirm\">\n\t\t\t\t<template #icon>\n\t\t\t\t\t<NcLoadingIcon v-if=\"loading\" :size=\"20\" :name=\"t('nextcloud-vue', 'Loading …')\" />\n\t\t\t\t</template>\n\t\t\t\t{{ t('nextcloud-vue', 'Save sharing') }}\n\t\t\t</NcButton>\n\t\t</template>\n\t</NcDialog>\n</template>\n\n<script>\nimport { translate as t } from '@nextcloud/l10n'\nimport { NcButton, NcDialog, NcLoadingIcon, NcNoteCard } from '@nextcloud/vue'\nimport CnSavedViewShareFields from '../CnSavedViewShareFields/CnSavedViewShareFields.vue'\nimport { normalizeSharedWith } from '../../utils/savedViewHelpers.js'\n\n/**\n * CnSavedViewShareDialog — change who a saved view is shared with. Opened by\n * `CnIndexPage` from the Share entry of an own view in `CnSavedViewsControl`.\n * Emits `confirm(sharedWith)`; the parent saves and either closes the dialog\n * or reports a failure through `setError()`, which keeps the form open.\n */\nexport default {\n\tname: 'CnSavedViewShareDialog',\n\n\tcomponents: { CnSavedViewShareFields, NcButton, NcDialog, NcLoadingIcon, NcNoteCard },\n\n\tprops: {\n\t\t/** The view being shared (its `sharedWith` seeds the fields). */\n\t\tview: {\n\t\t\ttype: Object,\n\t\t\tdefault: () => ({}),\n\t\t},\n\n\t\t/** Dialog title; empty reads \"Share view: {name}\". */\n\t\tdialogTitle: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\temits: ['close', 'confirm'],\n\n\tdata() {\n\t\treturn {\n\t\t\tsharedWith: normalizeSharedWith(this.view && this.view.sharedWith),\n\t\t\tloading: false,\n\t\t\terror: '',\n\t\t}\n\t},\n\n\tcomputed: {\n\t\t/** @return {string} The title: `dialogTitle`, else \"Share view: {name}\". */\n\t\tresolvedTitle() {\n\t\t\treturn this.dialogTitle || t('nextcloud-vue', 'Share view: {name}', { name: (this.view && this.view.name) || '' })\n\t\t},\n\t},\n\n\tmethods: {\n\t\tt,\n\n\t\tonConfirm() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = ''\n\t\t\t/**\n\t\t\t * @event confirm Save clicked. Payload: the audience, `[{ group, mode }]` and `[{ user, mode }]` (`[]` to stop sharing).\n\t\t\t * @type {Array<{group?: string, user?: string, mode: string}>}\n\t\t\t */\n\t\t\tthis.$emit('confirm', this.sharedWith)\n\t\t},\n\n\t\tonClose() {\n\t\t\t/** @event close Dialog dismissed. */\n\t\t\tthis.$emit('close')\n\t\t},\n\n\t\t/**\n\t\t * Parent-callable (via ref): show the server's message and re-enable the form.\n\t\t *\n\t\t * @param {string} message The message.\n\t\t * @public\n\t\t */\n\t\tsetError(message) {\n\t\t\tthis.loading = false\n\t\t\tthis.error = message || t('nextcloud-vue', 'Failed to save sharing')\n\t\t},\n\t},\n}\n</script>\n\n<style scoped>\n.cn-share-view__intro {\n\tmargin: 0;\n}\n\n.cn-share-view {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 12px;\n\tpadding-block: 8px;\n}\n</style>\n"],"names":["_createBlock","_createVNode","_createTextVNode","_createElementVNode","_toDisplayString"],"mappings":";;;AAcO,EAAA,KAAK,EAAC,eAAe;AAAC,EAAA,aAAK,EAAA,UAAA;AAAA,EAAA,mBAAA,EAAA,4BAAA;;AAI5B,MAAA,UAAA,GAAA,EAAA,KAAC,EAAA,sBAAA,GAAA;;;;;;;;;uBATLA;AACC,IAAA,IAAI,EAAE,QAAa,CAAA,aAAA;AACnB,IAAA,IAAG,EAAC,OAAQ;AACX,IAAA,OAAM,OAAI,CAAA,OAAA;AACX,IAAA,SAAO,EAAE,QAAG,CAAA,OAAA;;AAUJ,IAAA,OAAA,UACP,MAEU;MAFVC,WAEU,CAAA,mBAAA,EAAA;AAFA,QAAA,QAAM,EAAA,KAAA,CAAA,OAAA;AAAA,QAAA,OAAA,EAAA,QAAA,CAAA,OAAA;;yBAChB,MAAkB;0CAAf,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,QAAA,CAAA,CAAA,EAAA,CAAA,YAAA;;;;MAEJA;AACA,QAAA,OAAO,EAAC,SAAO;AACd,QAAA,QAAQ,EAAE,KAAO,CAAA,OAAA;AAClB,QAAA,aAAU,EAAA,6BAAA;AACT,QAAA,OAAK,EAAE,QAAS,CAAA,SAAA;;AACR,QAAA,IAAA,UACR,MAAO;WAAA,KAAA,CAAA,OAAA;4BAAPD,WAAO,CAAA,wBAAA,EAAA;;AAAA,gBAAA,IAAA,EAAA,EAAA;AAAA,gBAAA,IAAA,EAAA,QAAA,CAAA,CAAA,CAAA,eAAA,EAAA,WAAA,CAAA;;;;yBACD;AAAA,UAAAE,eAAA,CAAA;;;;;qBApBR,MAQK;AARL,MAAAC,kBAAA,CAQK,OARL,UAQK,EAAA;SAPa,KAAK,CAAA,KAAA;0BAAtBH,WAEY,CAAA,qBAAA,EAAA;;AAFY,cAAA,IAAI,EAAC,OAAO;;+BACpC,MAAE;gDAAA,KAAA,CAAA,KAAA,CAAA,EAAA,CAAA,YAAA;;;;;QAEHG,kBAEI,CAAA,GAAA,EAFJ,UAEI,EAAAC,eAAA,CADA,QAAC,CAAA,CAAA,CAAA,eAAA,EAAA,kFAAA,CAAA,CAAA,EAAA,CAAA,YAAA;QAEJH,WAAiC,CAAA,iCAAA,EAAA;sBAAD,KAAC,CAAA,UAAA;uEAAD,KAAC,CAAA,UAAA,IAAA,MAAA,CAAA,CAAA;;;;;;;;;;"}
@@ -2,7 +2,7 @@ import script from './CnSavedViewShareFields.vue2.js';
2
2
  import { render } from './CnSavedViewShareFields.vue3.js';
3
3
 
4
4
  script.render = render;
5
- script.__scopeId = "data-v-50093771";
5
+ script.__scopeId = "data-v-1ffd06b8";
6
6
  const __sfc_main = script;
7
7
 
8
8
  export { __sfc_main as default };