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

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 +13575 -2374
  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 +13517 -2336
  5. package/dist/nextcloud-vue.esm.js.map +1 -1
  6. package/package.json +11 -7
  7. package/src/components/CnActionsBar/CnActionsBar.vue +20 -2
  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 +63 -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,249 @@
1
+ <template>
2
+ <div class="cn-sidebar-tab">
3
+ <!-- Add / Edit note -->
4
+ <div class="cn-sidebar-tab__action">
5
+ <textarea
6
+ v-model="newNoteText"
7
+ class="cn-sidebar-tab__textarea"
8
+ :placeholder="addNotePlaceholder"
9
+ rows="3" />
10
+ <div class="cn-sidebar-tab__action--row">
11
+ <NcButton
12
+ v-if="editingNoteId"
13
+ type="tertiary"
14
+ @click="cancelEdit">
15
+ {{ cancelLabel }}
16
+ </NcButton>
17
+ <NcButton
18
+ type="primary"
19
+ :disabled="!newNoteText.trim() || saving"
20
+ @click="editingNoteId ? saveEdit() : addNote()">
21
+ <template #icon>
22
+ <Send :size="20" />
23
+ </template>
24
+ {{ editingNoteId ? saveLabel : addNoteLabel }}
25
+ </NcButton>
26
+ </div>
27
+ </div>
28
+
29
+ <!-- Notes list -->
30
+ <NcLoadingIcon v-if="loading" />
31
+ <div v-else-if="notes.length === 0" class="cn-sidebar-tab__empty">
32
+ {{ noNotesLabel }}
33
+ </div>
34
+ <div v-else class="cn-sidebar-tab__list">
35
+ <NcListItem
36
+ v-for="note in notes"
37
+ :key="note.id"
38
+ :name="note.actorDisplayName || note.author || 'Unknown'"
39
+ :bold="false"
40
+ :force-display-actions="true">
41
+ <template #icon>
42
+ <CommentTextOutline :size="32" />
43
+ </template>
44
+ <template #subname>
45
+ {{ note.message || note.content }}
46
+ </template>
47
+ <template #details>
48
+ {{ formatDate(note.creationDateTime || note.created) }}
49
+ </template>
50
+ <template v-if="canDelete(note)" #actions>
51
+ <NcActionButton @click="startEdit(note)">
52
+ <template #icon>
53
+ <Pencil :size="20" />
54
+ </template>
55
+ {{ editLabel }}
56
+ </NcActionButton>
57
+ <NcActionButton @click="deleteNote(note)">
58
+ <template #icon>
59
+ <Delete :size="20" />
60
+ </template>
61
+ {{ deleteLabel }}
62
+ </NcActionButton>
63
+ </template>
64
+ </NcListItem>
65
+ </div>
66
+ </div>
67
+ </template>
68
+
69
+ <script>
70
+ import { NcButton, NcListItem, NcActionButton, NcLoadingIcon } from '@nextcloud/vue'
71
+ import CommentTextOutline from 'vue-material-design-icons/CommentTextOutline.vue'
72
+ import Send from 'vue-material-design-icons/Send.vue'
73
+ import Pencil from 'vue-material-design-icons/Pencil.vue'
74
+ import Delete from 'vue-material-design-icons/Delete.vue'
75
+ import { buildHeaders } from '../../utils/index.js'
76
+
77
+ export default {
78
+ name: 'CnNotesTab',
79
+
80
+ components: { NcButton, NcListItem, NcActionButton, NcLoadingIcon, CommentTextOutline, Send, Pencil, Delete },
81
+
82
+ props: {
83
+ objectId: { type: String, required: true },
84
+ register: { type: String, default: '' },
85
+ schema: { type: String, default: '' },
86
+ apiBase: { type: String, default: '/apps/openregister/api' },
87
+ addNoteLabel: { type: String, default: 'Add note' },
88
+ addNotePlaceholder: { type: String, default: 'Write a note...' },
89
+ editLabel: { type: String, default: 'Edit' },
90
+ saveLabel: { type: String, default: 'Save' },
91
+ cancelLabel: { type: String, default: 'Cancel' },
92
+ deleteLabel: { type: String, default: 'Delete' },
93
+ noNotesLabel: { type: String, default: 'No notes yet' },
94
+ },
95
+
96
+ data() {
97
+ return {
98
+ notes: [],
99
+ loading: false,
100
+ newNoteText: '',
101
+ saving: false,
102
+ editingNoteId: null,
103
+ }
104
+ },
105
+
106
+ watch: {
107
+ objectId: {
108
+ immediate: true,
109
+ handler(id) { if (id) this.fetchNotes() },
110
+ },
111
+ },
112
+
113
+ methods: {
114
+ async fetchNotes() {
115
+ if (!this.register || !this.schema) return
116
+ this.loading = true
117
+ try {
118
+ const response = await fetch(
119
+ `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/notes`,
120
+ { headers: buildHeaders() },
121
+ )
122
+ if (response.ok) {
123
+ const data = await response.json()
124
+ this.notes = data.results || data || []
125
+ }
126
+ } catch (err) {
127
+ console.error('CnNotesTab: Failed to fetch notes', err)
128
+ } finally {
129
+ this.loading = false
130
+ }
131
+ },
132
+
133
+ async addNote() {
134
+ if (!this.newNoteText.trim()) return
135
+ this.saving = true
136
+ try {
137
+ await fetch(
138
+ `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/notes`,
139
+ {
140
+ method: 'POST',
141
+ headers: buildHeaders(),
142
+ body: JSON.stringify({ message: this.newNoteText.trim() }),
143
+ },
144
+ )
145
+ this.newNoteText = ''
146
+ await this.fetchNotes()
147
+ } catch (err) {
148
+ console.error('CnNotesTab: Failed to add note', err)
149
+ } finally {
150
+ this.saving = false
151
+ }
152
+ },
153
+
154
+ startEdit(note) {
155
+ this.editingNoteId = note.id
156
+ this.newNoteText = note.message || note.content || ''
157
+ },
158
+
159
+ cancelEdit() {
160
+ this.editingNoteId = null
161
+ this.newNoteText = ''
162
+ },
163
+
164
+ async saveEdit() {
165
+ if (!this.newNoteText.trim() || !this.editingNoteId) return
166
+ this.saving = true
167
+ try {
168
+ await fetch(
169
+ `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/notes/${this.editingNoteId}`,
170
+ {
171
+ method: 'PUT',
172
+ headers: buildHeaders(),
173
+ body: JSON.stringify({ message: this.newNoteText.trim() }),
174
+ },
175
+ )
176
+ this.editingNoteId = null
177
+ this.newNoteText = ''
178
+ await this.fetchNotes()
179
+ } catch (err) {
180
+ console.error('CnNotesTab: Failed to update note', err)
181
+ } finally {
182
+ this.saving = false
183
+ }
184
+ },
185
+
186
+ canDelete(note) {
187
+ return note.actorId === OC?.currentUser || note.author === OC?.currentUser
188
+ },
189
+
190
+ async deleteNote(note) {
191
+ try {
192
+ await fetch(
193
+ `${this.apiBase}/objects/${this.register}/${this.schema}/${this.objectId}/notes/${note.id}`,
194
+ { method: 'DELETE', headers: buildHeaders() },
195
+ )
196
+ this.notes = this.notes.filter(n => n.id !== note.id)
197
+ } catch (err) {
198
+ console.error('CnNotesTab: Failed to delete note', err)
199
+ }
200
+ },
201
+
202
+ formatDate(dateStr) {
203
+ if (!dateStr) return ''
204
+ try {
205
+ return new Date(dateStr).toLocaleString(undefined, {
206
+ year: 'numeric',
207
+ month: 'short',
208
+ day: 'numeric',
209
+ hour: '2-digit',
210
+ minute: '2-digit',
211
+ })
212
+ } catch { return dateStr }
213
+ },
214
+ },
215
+ }
216
+ </script>
217
+
218
+ <style scoped>
219
+ .cn-sidebar-tab { padding: 12px; }
220
+ .cn-sidebar-tab__action { margin-bottom: 16px; }
221
+ .cn-sidebar-tab__action--row { display: flex; gap: 8px; align-items: flex-end; }
222
+
223
+ .cn-sidebar-tab__textarea {
224
+ width: 100%;
225
+ padding: 8px;
226
+ border: 1px solid var(--color-border);
227
+ border-radius: var(--border-radius);
228
+ resize: vertical;
229
+ font-family: inherit;
230
+ font-size: 13px;
231
+ margin-bottom: 8px;
232
+ background: var(--color-main-background);
233
+ color: var(--color-main-text);
234
+ }
235
+
236
+ .cn-sidebar-tab__textarea:focus {
237
+ border-color: var(--color-primary-element);
238
+ outline: none;
239
+ }
240
+
241
+ .cn-sidebar-tab__empty {
242
+ text-align: center;
243
+ padding: 24px 12px;
244
+ color: var(--color-text-maxcontrast);
245
+ font-size: 13px;
246
+ }
247
+
248
+ .cn-sidebar-tab__list { display: flex; flex-direction: column; gap: 2px; }
249
+ </style>