@conduction/nextcloud-vue 0.1.0-beta.6 → 0.1.0-beta.7

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 (82) hide show
  1. package/dist/nextcloud-vue.cjs.js +13606 -1918
  2. package/dist/nextcloud-vue.cjs.js.map +1 -1
  3. package/dist/nextcloud-vue.css +1238 -270
  4. package/dist/nextcloud-vue.esm.js +13548 -1880
  5. package/dist/nextcloud-vue.esm.js.map +1 -1
  6. package/package.json +9 -4
  7. package/src/components/CnActionsBar/CnActionsBar.vue +6 -1
  8. package/src/components/CnAdvancedFormDialog/CnAdvancedFormDialog.vue +1 -11
  9. package/src/components/CnAdvancedFormDialog/CnPropertiesTab.vue +5 -1
  10. package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +1 -1
  11. package/src/components/CnCard/CnCard.vue +415 -0
  12. package/src/components/CnCard/index.js +1 -0
  13. package/src/components/CnCardGrid/CnCardGrid.vue +20 -20
  14. package/src/components/CnChartWidget/CnChartWidget.vue +3 -1
  15. package/src/components/CnCopyDialog/CnCopyDialog.vue +7 -1
  16. package/src/components/CnDashboardGrid/CnDashboardGrid.vue +4 -0
  17. package/src/components/CnDashboardPage/CnDashboardPage.vue +2 -0
  18. package/src/components/CnDataTable/CnDataTable.vue +6 -2
  19. package/src/components/CnDeleteDialog/CnDeleteDialog.vue +7 -1
  20. package/src/components/CnDetailCard/CnDetailCard.vue +12 -1
  21. package/src/components/CnDetailGrid/CnDetailGrid.vue +254 -0
  22. package/src/components/CnDetailGrid/index.js +1 -0
  23. package/src/components/CnDetailPage/CnDetailPage.vue +157 -11
  24. package/src/components/CnFacetSidebar/CnFacetSidebar.vue +3 -1
  25. package/src/components/CnFormDialog/CnFormDialog.vue +934 -920
  26. package/src/components/CnIcon/CnIcon.vue +1 -1
  27. package/src/components/CnIndexPage/CnIndexPage.vue +51 -9
  28. package/src/components/CnIndexSidebar/CnIndexSidebar.vue +37 -9
  29. package/src/components/CnInfoWidget/CnInfoWidget.vue +219 -0
  30. package/src/components/CnInfoWidget/index.js +1 -0
  31. package/src/components/CnJsonViewer/CnJsonViewer.vue +283 -0
  32. package/src/components/CnJsonViewer/index.js +1 -0
  33. package/src/components/CnKpiGrid/CnKpiGrid.vue +5 -1
  34. package/src/components/CnMassCopyDialog/CnMassCopyDialog.vue +7 -1
  35. package/src/components/CnMassDeleteDialog/CnMassDeleteDialog.vue +7 -1
  36. package/src/components/CnMassExportDialog/CnMassExportDialog.vue +1 -1
  37. package/src/components/CnMassImportDialog/CnMassImportDialog.vue +1 -1
  38. package/src/components/CnObjectCard/CnObjectCard.vue +1 -1
  39. package/src/components/CnObjectSidebar/CnAuditTrailTab.vue +368 -0
  40. package/src/components/CnObjectSidebar/CnFilesTab.vue +286 -0
  41. package/src/components/CnObjectSidebar/CnNotesTab.vue +249 -0
  42. package/src/components/CnObjectSidebar/CnObjectSidebar.vue +45 -668
  43. package/src/components/CnObjectSidebar/CnTagsTab.vue +258 -0
  44. package/src/components/CnObjectSidebar/CnTasksTab.vue +482 -0
  45. package/src/components/CnObjectSidebar/index.js +5 -0
  46. package/src/components/CnProgressBar/CnProgressBar.vue +262 -0
  47. package/src/components/CnProgressBar/index.js +1 -0
  48. package/src/components/CnSchemaFormDialog/CnSchemaPropertiesTab.vue +1 -1
  49. package/src/components/CnStatsBlock/CnStatsBlock.vue +27 -11
  50. package/src/components/CnStatsPanel/CnStatsPanel.vue +320 -0
  51. package/src/components/CnStatsPanel/index.js +1 -0
  52. package/src/components/CnStatusBadge/CnStatusBadge.vue +15 -2
  53. package/src/components/CnTabbedFormDialog/CnTabbedFormDialog.vue +5 -1
  54. package/src/components/CnTableWidget/CnTableWidget.vue +332 -0
  55. package/src/components/CnTableWidget/index.js +1 -0
  56. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +36 -1
  57. package/src/components/index.js +11 -0
  58. package/src/composables/useDashboardView.js +58 -12
  59. package/src/composables/useDetailView.js +3 -2
  60. package/src/composables/useListView.js +7 -6
  61. package/src/composables/useSubResource.js +3 -3
  62. package/src/css/badge.css +32 -0
  63. package/src/css/card.css +1 -0
  64. package/src/css/detail-page.css +74 -7
  65. package/src/index.js +16 -0
  66. package/src/mixins/gridLayout.js +118 -0
  67. package/src/store/createCrudStore.js +360 -0
  68. package/src/store/createSubResourcePlugin.js +5 -15
  69. package/src/store/index.js +1 -0
  70. package/src/store/plugins/auditTrails.js +346 -6
  71. package/src/store/plugins/lifecycle.js +4 -4
  72. package/src/store/plugins/registerMapping.js +18 -8
  73. package/src/store/plugins/relations.js +1 -1
  74. package/src/store/plugins/search.js +21 -8
  75. package/src/store/useObjectStore.js +30 -36
  76. package/src/utils/getTheme.js +9 -0
  77. package/src/utils/headers.js +13 -3
  78. package/src/utils/index.js +1 -0
  79. package/src/utils/schema.js +3 -3
  80. package/src/utils/widgetVisibility.js +162 -0
  81. package/src/components/CnObjectCard/eslint-setup.md +0 -235
  82. package/src/components/CnObjectCard/package.json-or.json +0 -132
@@ -0,0 +1,258 @@
1
+ <template>
2
+ <div class="cn-sidebar-tab">
3
+ <!-- Add tag -->
4
+ <div class="cn-sidebar-tab__action">
5
+ <div class="cn-sidebar-tab__action--row">
6
+ <NcTextField
7
+ v-model="newTagName"
8
+ :label="addTagPlaceholder"
9
+ @input="filterSuggestions"
10
+ @keyup.enter="addTag"
11
+ @focus="showSuggestions = true" />
12
+ <NcButton
13
+ type="primary"
14
+ :disabled="!newTagName.trim() || saving"
15
+ @click="addTag">
16
+ <template #icon>
17
+ <Plus :size="20" />
18
+ </template>
19
+ </NcButton>
20
+ </div>
21
+ <!-- Tag suggestions dropdown -->
22
+ <div
23
+ v-if="showSuggestions && filtered.length > 0"
24
+ class="cn-sidebar-tab__tag-suggestions">
25
+ <button
26
+ v-for="suggestion in filtered"
27
+ :key="suggestion"
28
+ class="cn-sidebar-tab__tag-suggestion"
29
+ @mousedown.prevent="selectSuggestion(suggestion)">
30
+ <TagOutline :size="16" />
31
+ {{ suggestion }}
32
+ </button>
33
+ </div>
34
+ </div>
35
+
36
+ <!-- Tags list -->
37
+ <NcLoadingIcon v-if="loading" />
38
+ <div v-else-if="tags.length === 0" class="cn-sidebar-tab__empty">
39
+ {{ noTagsLabel }}
40
+ </div>
41
+ <div v-else class="cn-sidebar-tab__tags">
42
+ <span
43
+ v-for="tag in tags"
44
+ :key="tag"
45
+ class="cn-sidebar-tab__tag">
46
+ {{ tag }}
47
+ <button
48
+ class="cn-sidebar-tab__tag-remove"
49
+ :aria-label="'Remove ' + tag"
50
+ @click="removeTag(tag)">
51
+ <Close :size="14" />
52
+ </button>
53
+ </span>
54
+ </div>
55
+ </div>
56
+ </template>
57
+
58
+ <script>
59
+ import { NcButton, NcTextField, NcLoadingIcon } from '@nextcloud/vue'
60
+ import TagOutline from 'vue-material-design-icons/TagOutline.vue'
61
+ import Plus from 'vue-material-design-icons/Plus.vue'
62
+ import Close from 'vue-material-design-icons/Close.vue'
63
+ import { buildHeaders } from '../../utils/index.js'
64
+
65
+ export default {
66
+ name: 'CnTagsTab',
67
+
68
+ components: { NcButton, NcTextField, NcLoadingIcon, TagOutline, Plus, Close },
69
+
70
+ props: {
71
+ objectId: { type: String, required: true },
72
+ register: { type: String, default: '' },
73
+ schema: { type: String, default: '' },
74
+ apiBase: { type: String, default: '/apps/openregister/api' },
75
+ addTagPlaceholder: { type: String, default: 'Add tag...' },
76
+ noTagsLabel: { type: String, default: 'No tags' },
77
+ },
78
+
79
+ data() {
80
+ return {
81
+ tags: [],
82
+ loading: false,
83
+ newTagName: '',
84
+ saving: false,
85
+ availableTags: [],
86
+ filtered: [],
87
+ showSuggestions: false,
88
+ }
89
+ },
90
+
91
+ watch: {
92
+ objectId: {
93
+ immediate: true,
94
+ handler(id) {
95
+ if (id) {
96
+ this.fetchTags()
97
+ this.fetchAvailableTags()
98
+ }
99
+ },
100
+ },
101
+ },
102
+
103
+ methods: {
104
+ async fetchTags() {
105
+ if (!this.register || !this.schema) return
106
+ this.loading = true
107
+ try {
108
+ const response = await fetch(
109
+ `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/tags`,
110
+ { headers: buildHeaders() },
111
+ )
112
+ if (response.ok) {
113
+ this.tags = await response.json()
114
+ }
115
+ } catch (err) {
116
+ console.error('CnTagsTab: Failed to fetch tags', err)
117
+ } finally {
118
+ this.loading = false
119
+ }
120
+ },
121
+
122
+ async fetchAvailableTags() {
123
+ try {
124
+ const response = await fetch(`${this.apiBase}/tags`, { headers: buildHeaders() })
125
+ if (response.ok) {
126
+ this.availableTags = await response.json()
127
+ }
128
+ } catch (err) {
129
+ console.error('CnTagsTab: Failed to fetch available tags', err)
130
+ }
131
+ },
132
+
133
+ filterSuggestions() {
134
+ const query = this.newTagName.trim().toLowerCase()
135
+ if (!query) {
136
+ this.filtered = this.availableTags.filter(t => !this.tags.includes(t))
137
+ return
138
+ }
139
+ this.filtered = this.availableTags.filter(
140
+ t => t.toLowerCase().includes(query) && !this.tags.includes(t),
141
+ )
142
+ },
143
+
144
+ selectSuggestion(tagName) {
145
+ this.newTagName = tagName
146
+ this.showSuggestions = false
147
+ this.addTag()
148
+ },
149
+
150
+ async addTag() {
151
+ if (!this.newTagName.trim() || !this.register || !this.schema) return
152
+ this.saving = true
153
+ this.showSuggestions = false
154
+ try {
155
+ const response = await fetch(
156
+ `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/tags`,
157
+ {
158
+ method: 'POST',
159
+ headers: buildHeaders(),
160
+ body: JSON.stringify({ tag: this.newTagName.trim() }),
161
+ },
162
+ )
163
+ if (response.ok) {
164
+ this.tags = await response.json()
165
+ }
166
+ this.newTagName = ''
167
+ this.fetchAvailableTags()
168
+ } catch (err) {
169
+ console.error('CnTagsTab: Failed to add tag', err)
170
+ } finally {
171
+ this.saving = false
172
+ }
173
+ },
174
+
175
+ async removeTag(tagName) {
176
+ if (!this.register || !this.schema) return
177
+ try {
178
+ const response = await fetch(
179
+ `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/tags/${encodeURIComponent(tagName)}`,
180
+ { method: 'DELETE', headers: buildHeaders() },
181
+ )
182
+ if (response.ok) {
183
+ this.tags = await response.json()
184
+ }
185
+ } catch (err) {
186
+ console.error('CnTagsTab: Failed to remove tag', err)
187
+ }
188
+ },
189
+ },
190
+ }
191
+ </script>
192
+
193
+ <style scoped>
194
+ .cn-sidebar-tab { padding: 12px; }
195
+ .cn-sidebar-tab__action { margin-bottom: 16px; }
196
+ .cn-sidebar-tab__action--row { display: flex; gap: 8px; align-items: flex-end; }
197
+
198
+ .cn-sidebar-tab__empty {
199
+ text-align: center;
200
+ padding: 24px 12px;
201
+ color: var(--color-text-maxcontrast);
202
+ font-size: 13px;
203
+ }
204
+
205
+ .cn-sidebar-tab__tags { display: flex; flex-wrap: wrap; gap: 6px; padding: 4px 0; }
206
+
207
+ .cn-sidebar-tab__tag {
208
+ display: inline-flex;
209
+ align-items: center;
210
+ gap: 4px;
211
+ padding: 3px 8px;
212
+ border-radius: var(--border-radius-pill, 16px);
213
+ background: var(--color-primary-element-light, rgba(0, 130, 201, 0.1));
214
+ color: var(--color-primary-element);
215
+ font-size: 12px;
216
+ font-weight: 500;
217
+ }
218
+
219
+ .cn-sidebar-tab__tag-remove {
220
+ display: flex;
221
+ align-items: center;
222
+ justify-content: center;
223
+ background: none;
224
+ border: none;
225
+ padding: 0;
226
+ cursor: pointer;
227
+ color: var(--color-primary-element);
228
+ opacity: 0.6;
229
+ border-radius: 50%;
230
+ }
231
+
232
+ .cn-sidebar-tab__tag-remove:hover { opacity: 1; background: rgba(0, 0, 0, 0.08); }
233
+
234
+ .cn-sidebar-tab__tag-suggestions {
235
+ margin-top: 4px;
236
+ border: 1px solid var(--color-border);
237
+ border-radius: var(--border-radius);
238
+ background: var(--color-main-background);
239
+ max-height: 160px;
240
+ overflow-y: auto;
241
+ }
242
+
243
+ .cn-sidebar-tab__tag-suggestion {
244
+ display: flex;
245
+ align-items: center;
246
+ gap: 8px;
247
+ width: 100%;
248
+ padding: 6px 12px;
249
+ border: none;
250
+ background: none;
251
+ cursor: pointer;
252
+ font-size: 13px;
253
+ color: var(--color-main-text);
254
+ text-align: left;
255
+ }
256
+
257
+ .cn-sidebar-tab__tag-suggestion:hover { background: var(--color-background-hover); }
258
+ </style>