@conduction/nextcloud-vue 0.1.0-beta.11 → 0.1.0-beta.12
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.
- package/dist/nextcloud-vue.cjs +67614 -0
- package/dist/nextcloud-vue.cjs.js +13518 -13617
- package/dist/nextcloud-vue.cjs.js.map +1 -1
- package/dist/nextcloud-vue.cjs.map +1 -0
- package/dist/nextcloud-vue.css +1796 -1800
- package/dist/nextcloud-vue.esm.js +13518 -13617
- package/dist/nextcloud-vue.esm.js.map +1 -1
- package/package.json +3 -2
- package/src/components/CnActionsBar/CnActionsBar.vue +254 -254
- package/src/components/CnAdvancedFormDialog/CnAdvancedFormDialog.vue +570 -570
- package/src/components/CnAdvancedFormDialog/CnDataTab.vue +217 -217
- package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +121 -121
- package/src/components/CnAdvancedFormDialog/CnPropertiesTab.vue +422 -422
- package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +247 -247
- package/src/components/CnCard/CnCard.vue +415 -415
- package/src/components/CnCardGrid/CnCardGrid.vue +156 -156
- package/src/components/CnCellRenderer/CnCellRenderer.vue +132 -132
- package/src/components/CnChartWidget/CnChartWidget.vue +346 -346
- package/src/components/CnConfigurationCard/CnConfigurationCard.vue +77 -77
- package/src/components/CnContextMenu/CnContextMenu.vue +142 -142
- package/src/components/CnCopyDialog/CnCopyDialog.vue +266 -266
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +229 -229
- package/src/components/CnDashboardPage/CnDashboardPage.vue +397 -397
- package/src/components/CnDataTable/CnDataTable.vue +362 -362
- package/src/components/CnDeleteDialog/CnDeleteDialog.vue +177 -177
- package/src/components/CnDetailCard/CnDetailCard.vue +225 -225
- package/src/components/CnDetailGrid/CnDetailGrid.vue +256 -256
- package/src/components/CnDetailPage/CnDetailPage.vue +432 -432
- package/src/components/CnFacetSidebar/CnFacetSidebar.vue +234 -234
- package/src/components/CnFilterBar/CnFilterBar.vue +153 -153
- package/src/components/CnFormDialog/CnFormDialog.vue +1047 -1047
- package/src/components/CnIcon/CnIcon.vue +89 -89
- package/src/components/CnIndexPage/CnIndexPage.vue +981 -980
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +536 -536
- package/src/components/CnInfoWidget/CnInfoWidget.vue +219 -219
- package/src/components/CnItemCard/CnItemCard.vue +134 -134
- package/src/components/CnJsonViewer/CnJsonViewer.vue +312 -312
- package/src/components/CnKpiGrid/CnKpiGrid.vue +93 -93
- package/src/components/CnMassActionBar/CnMassActionBar.vue +161 -161
- package/src/components/CnMassCopyDialog/CnMassCopyDialog.vue +327 -327
- package/src/components/CnMassDeleteDialog/CnMassDeleteDialog.vue +245 -245
- package/src/components/CnMassExportDialog/CnMassExportDialog.vue +191 -191
- package/src/components/CnMassImportDialog/CnMassImportDialog.vue +494 -494
- package/src/components/CnNoteCard/CnNoteCard.vue +149 -149
- package/src/components/CnNotesCard/CnNotesCard.vue +416 -416
- package/src/components/CnObjectCard/CnObjectCard.vue +294 -294
- package/src/components/CnObjectDataWidget/CnObjectDataWidget.vue +854 -854
- package/src/components/CnObjectMetadataWidget/CnObjectMetadataWidget.vue +289 -289
- package/src/components/CnObjectSidebar/CnAuditTrailTab.vue +369 -369
- package/src/components/CnObjectSidebar/CnFilesTab.vue +287 -287
- package/src/components/CnObjectSidebar/CnNotesTab.vue +250 -250
- package/src/components/CnObjectSidebar/CnObjectSidebar.vue +255 -255
- package/src/components/CnObjectSidebar/CnTagsTab.vue +259 -259
- package/src/components/CnObjectSidebar/CnTasksTab.vue +483 -483
- package/src/components/CnPageHeader/CnPageHeader.vue +61 -61
- package/src/components/CnPagination/CnPagination.vue +253 -253
- package/src/components/CnProgressBar/CnProgressBar.vue +262 -262
- package/src/components/CnRegisterMapping/CnRegisterMapping.vue +793 -793
- package/src/components/CnRowActions/CnRowActions.vue +95 -95
- package/src/components/CnSchemaFormDialog/CnSchemaConfigurationTab.vue +226 -226
- package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +788 -788
- package/src/components/CnSchemaFormDialog/CnSchemaPropertiesTab.vue +305 -305
- package/src/components/CnSchemaFormDialog/CnSchemaPropertyActions.vue +1398 -1398
- package/src/components/CnSchemaFormDialog/CnSchemaSecurityTab.vue +236 -236
- package/src/components/CnSettingsCard/CnSettingsCard.vue +92 -92
- package/src/components/CnSettingsSection/CnSettingsSection.vue +267 -267
- package/src/components/CnStatsBlock/CnStatsBlock.vue +437 -437
- package/src/components/CnStatsPanel/CnStatsPanel.vue +321 -321
- package/src/components/CnStatusBadge/CnStatusBadge.vue +90 -90
- package/src/components/CnTabbedFormDialog/CnTabbedFormDialog.vue +545 -545
- package/src/components/CnTableWidget/CnTableWidget.vue +333 -333
- package/src/components/CnTasksCard/CnTasksCard.vue +374 -374
- package/src/components/CnTileWidget/CnTileWidget.vue +159 -159
- package/src/components/CnTimelineStages/CnTimelineStages.vue +294 -294
- package/src/components/CnUserActionMenu/CnUserActionMenu.vue +436 -436
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +313 -313
- package/src/components/CnWidgetRenderer/CnWidgetRenderer.vue +180 -180
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +248 -248
|
@@ -1,256 +1,256 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
CnDetailGrid — Data-driven label-value grid for detail/info sections.
|
|
3
|
-
|
|
4
|
-
Supports two layout modes:
|
|
5
|
-
- grid (default): Responsive card grid with label stacked above value
|
|
6
|
-
- horizontal: Vertical list of rows with label on left, value on right
|
|
7
|
-
|
|
8
|
-
Items can be data-driven via the `items` prop, or customized per-item
|
|
9
|
-
via named scoped slots (#item-{index}, #label-{index}, #item-actions-{index}).
|
|
10
|
-
-->
|
|
11
|
-
<template>
|
|
12
|
-
<div
|
|
13
|
-
class="cn-detail-grid"
|
|
14
|
-
:class="rootClasses"
|
|
15
|
-
:style="rootStyles">
|
|
16
|
-
<!-- Empty state -->
|
|
17
|
-
<div v-if="!items.length && !$scopedSlots.default" class="cn-detail-grid__empty">
|
|
18
|
-
<slot name="empty">
|
|
19
|
-
{{ emptyLabel }}
|
|
20
|
-
</slot>
|
|
21
|
-
</div>
|
|
22
|
-
|
|
23
|
-
<!-- Data-driven items -->
|
|
24
|
-
<div
|
|
25
|
-
v-for="(item, index) in items"
|
|
26
|
-
:key="index"
|
|
27
|
-
class="cn-detail-grid__item"
|
|
28
|
-
:class="itemClasses">
|
|
29
|
-
<!-- Label -->
|
|
30
|
-
<div class="cn-detail-grid__label">
|
|
31
|
-
<slot :name="'label-' + index" :item="item" :index="index">
|
|
32
|
-
{{ item.label }}
|
|
33
|
-
</slot>
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<!-- Value -->
|
|
37
|
-
<div class="cn-detail-grid__value">
|
|
38
|
-
<slot :name="'item-' + index" :item="item" :index="index">
|
|
39
|
-
{{ item.value !== undefined && item.value !== null ? item.value : '-' }}
|
|
40
|
-
</slot>
|
|
41
|
-
</div>
|
|
42
|
-
|
|
43
|
-
<!-- Optional per-item actions -->
|
|
44
|
-
<div v-if="$scopedSlots['item-actions-' + index]" class="cn-detail-grid__actions">
|
|
45
|
-
<slot :name="'item-actions-' + index" :item="item" :index="index" />
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
|
-
<!-- Append slot for manual items -->
|
|
50
|
-
<slot />
|
|
51
|
-
</div>
|
|
52
|
-
</template>
|
|
53
|
-
|
|
54
|
-
<script>
|
|
55
|
-
import { translate as t } from '@nextcloud/l10n'
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* CnDetailGrid — Data-driven label-value grid for detail/info sections.
|
|
59
|
-
*
|
|
60
|
-
* @example Simple data-driven grid
|
|
61
|
-
* <CnDetailGrid :items="[
|
|
62
|
-
* { label: 'ID', value: '12345' },
|
|
63
|
-
* { label: 'Status', value: 'Active' },
|
|
64
|
-
* { label: 'Created', value: '2024-01-15' },
|
|
65
|
-
* ]" />
|
|
66
|
-
*
|
|
67
|
-
* @example Grid with custom slot content
|
|
68
|
-
* <CnDetailGrid :items="[
|
|
69
|
-
* { label: 'ID', value: item.id },
|
|
70
|
-
* { label: 'Action' },
|
|
71
|
-
* ]">
|
|
72
|
-
* <template #item-1>
|
|
73
|
-
* <CnStatusBadge :label="item.action" />
|
|
74
|
-
* </template>
|
|
75
|
-
* </CnDetailGrid>
|
|
76
|
-
*
|
|
77
|
-
* @example Horizontal row layout
|
|
78
|
-
* <CnDetailGrid layout="horizontal" :items="fields" />
|
|
79
|
-
*/
|
|
80
|
-
export default {
|
|
81
|
-
name: 'CnDetailGrid',
|
|
82
|
-
|
|
83
|
-
props: {
|
|
84
|
-
/**
|
|
85
|
-
* Array of detail items to render.
|
|
86
|
-
* @type {Array<{ label: string, value?: string|number }>}
|
|
87
|
-
*/
|
|
88
|
-
items: {
|
|
89
|
-
type: Array,
|
|
90
|
-
default: () => [],
|
|
91
|
-
},
|
|
92
|
-
/**
|
|
93
|
-
* Layout mode.
|
|
94
|
-
* - 'grid': Responsive card grid, label stacked above value
|
|
95
|
-
* - 'horizontal': Vertical list of rows, label on left, value on right
|
|
96
|
-
*/
|
|
97
|
-
layout: {
|
|
98
|
-
type: String,
|
|
99
|
-
default: 'grid',
|
|
100
|
-
validator: (v) => ['grid', 'horizontal'].includes(v),
|
|
101
|
-
},
|
|
102
|
-
/**
|
|
103
|
-
* Number of fixed grid columns. Set to 0 (default) for responsive auto-fit.
|
|
104
|
-
* Only applies to layout="grid".
|
|
105
|
-
*/
|
|
106
|
-
columns: {
|
|
107
|
-
type: Number,
|
|
108
|
-
default: 0,
|
|
109
|
-
},
|
|
110
|
-
/**
|
|
111
|
-
* Minimum width (px) for auto-fit grid items.
|
|
112
|
-
* Only applies when columns is 0 and layout is 'grid'.
|
|
113
|
-
*/
|
|
114
|
-
minItemWidth: {
|
|
115
|
-
type: Number,
|
|
116
|
-
default: 250,
|
|
117
|
-
},
|
|
118
|
-
/**
|
|
119
|
-
* Minimum width (px) for labels in horizontal mode.
|
|
120
|
-
*/
|
|
121
|
-
labelWidth: {
|
|
122
|
-
type: Number,
|
|
123
|
-
default: 150,
|
|
124
|
-
},
|
|
125
|
-
/**
|
|
126
|
-
* Whether to show the left accent border on items.
|
|
127
|
-
*/
|
|
128
|
-
accent: {
|
|
129
|
-
type: Boolean,
|
|
130
|
-
default: true,
|
|
131
|
-
},
|
|
132
|
-
/**
|
|
133
|
-
* Text shown when the items array is empty.
|
|
134
|
-
*/
|
|
135
|
-
emptyLabel: {
|
|
136
|
-
type: String,
|
|
137
|
-
default: () => t('nextcloud-vue', 'No details available'),
|
|
138
|
-
},
|
|
139
|
-
},
|
|
140
|
-
|
|
141
|
-
computed: {
|
|
142
|
-
rootClasses() {
|
|
143
|
-
return {
|
|
144
|
-
'cn-detail-grid--grid': this.layout === 'grid',
|
|
145
|
-
'cn-detail-grid--horizontal': this.layout === 'horizontal',
|
|
146
|
-
'cn-detail-grid--accent': this.accent,
|
|
147
|
-
}
|
|
148
|
-
},
|
|
149
|
-
rootStyles() {
|
|
150
|
-
if (this.layout === 'grid') {
|
|
151
|
-
if (this.columns > 0) {
|
|
152
|
-
return { 'grid-template-columns': `repeat(${this.columns}, 1fr)` }
|
|
153
|
-
}
|
|
154
|
-
return { 'grid-template-columns': `repeat(auto-fit, minmax(${this.minItemWidth}px, 1fr))` }
|
|
155
|
-
}
|
|
156
|
-
if (this.layout === 'horizontal') {
|
|
157
|
-
return { '--cn-detail-grid-label-width': this.labelWidth + 'px' }
|
|
158
|
-
}
|
|
159
|
-
return {}
|
|
160
|
-
},
|
|
161
|
-
itemClasses() {
|
|
162
|
-
return {
|
|
163
|
-
'cn-detail-grid__item--horizontal': this.layout === 'horizontal',
|
|
164
|
-
}
|
|
165
|
-
},
|
|
166
|
-
},
|
|
167
|
-
}
|
|
168
|
-
</script>
|
|
169
|
-
|
|
170
|
-
<style scoped>
|
|
171
|
-
/* ===== Grid layout (default) ===== */
|
|
172
|
-
.cn-detail-grid--grid {
|
|
173
|
-
display: grid;
|
|
174
|
-
gap: calc(4 * var(--default-grid-baseline, 4px));
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
/* ===== Horizontal layout ===== */
|
|
178
|
-
.cn-detail-grid--horizontal {
|
|
179
|
-
display: flex;
|
|
180
|
-
flex-direction: column;
|
|
181
|
-
gap: calc(3 * var(--default-grid-baseline, 4px));
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/* ===== Item (card style) ===== */
|
|
185
|
-
.cn-detail-grid__item {
|
|
186
|
-
display: flex;
|
|
187
|
-
flex-direction: column;
|
|
188
|
-
gap: var(--default-grid-baseline, 4px);
|
|
189
|
-
padding: calc(2 * var(--default-grid-baseline, 4px)) calc(3 * var(--default-grid-baseline, 4px));
|
|
190
|
-
background: var(--color-background-hover);
|
|
191
|
-
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
/* Accent border */
|
|
195
|
-
.cn-detail-grid--accent .cn-detail-grid__item {
|
|
196
|
-
border-left: 3px solid var(--color-primary-element);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
/* Horizontal item: row direction */
|
|
200
|
-
.cn-detail-grid__item--horizontal {
|
|
201
|
-
flex-direction: row;
|
|
202
|
-
align-items: center;
|
|
203
|
-
gap: calc(4 * var(--default-grid-baseline, 4px));
|
|
204
|
-
border-radius: var(--border-radius);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/* ===== Label ===== */
|
|
208
|
-
.cn-detail-grid__label {
|
|
209
|
-
font-size: 0.85em;
|
|
210
|
-
color: var(--color-text-maxcontrast);
|
|
211
|
-
font-weight: 500;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
.cn-detail-grid--horizontal .cn-detail-grid__label {
|
|
215
|
-
min-width: var(--cn-detail-grid-label-width, 150px);
|
|
216
|
-
flex-shrink: 0;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
/* ===== Value ===== */
|
|
220
|
-
.cn-detail-grid__value {
|
|
221
|
-
font-size: 1em;
|
|
222
|
-
color: var(--color-main-text);
|
|
223
|
-
word-break: break-word;
|
|
224
|
-
margin: 0.5rem;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
.cn-detail-grid--horizontal .cn-detail-grid__value {
|
|
228
|
-
flex: 1;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
/* ===== Actions ===== */
|
|
232
|
-
.cn-detail-grid__actions {
|
|
233
|
-
flex-shrink: 0;
|
|
234
|
-
display: flex;
|
|
235
|
-
align-items: center;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/* ===== Empty state ===== */
|
|
239
|
-
.cn-detail-grid__empty {
|
|
240
|
-
color: var(--color-text-maxcontrast);
|
|
241
|
-
font-style: italic;
|
|
242
|
-
padding: calc(2 * var(--default-grid-baseline, 4px));
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/* ===== Responsive ===== */
|
|
246
|
-
@media (max-width: 600px) {
|
|
247
|
-
.cn-detail-grid--grid {
|
|
248
|
-
grid-template-columns: 1fr !important;
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
.cn-detail-grid__item--horizontal {
|
|
252
|
-
flex-direction: column;
|
|
253
|
-
align-items: flex-start;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
</style>
|
|
1
|
+
<!--
|
|
2
|
+
CnDetailGrid — Data-driven label-value grid for detail/info sections.
|
|
3
|
+
|
|
4
|
+
Supports two layout modes:
|
|
5
|
+
- grid (default): Responsive card grid with label stacked above value
|
|
6
|
+
- horizontal: Vertical list of rows with label on left, value on right
|
|
7
|
+
|
|
8
|
+
Items can be data-driven via the `items` prop, or customized per-item
|
|
9
|
+
via named scoped slots (#item-{index}, #label-{index}, #item-actions-{index}).
|
|
10
|
+
-->
|
|
11
|
+
<template>
|
|
12
|
+
<div
|
|
13
|
+
class="cn-detail-grid"
|
|
14
|
+
:class="rootClasses"
|
|
15
|
+
:style="rootStyles">
|
|
16
|
+
<!-- Empty state -->
|
|
17
|
+
<div v-if="!items.length && !$scopedSlots.default" class="cn-detail-grid__empty">
|
|
18
|
+
<slot name="empty">
|
|
19
|
+
{{ emptyLabel }}
|
|
20
|
+
</slot>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<!-- Data-driven items -->
|
|
24
|
+
<div
|
|
25
|
+
v-for="(item, index) in items"
|
|
26
|
+
:key="index"
|
|
27
|
+
class="cn-detail-grid__item"
|
|
28
|
+
:class="itemClasses">
|
|
29
|
+
<!-- Label -->
|
|
30
|
+
<div class="cn-detail-grid__label">
|
|
31
|
+
<slot :name="'label-' + index" :item="item" :index="index">
|
|
32
|
+
{{ item.label }}
|
|
33
|
+
</slot>
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Value -->
|
|
37
|
+
<div class="cn-detail-grid__value">
|
|
38
|
+
<slot :name="'item-' + index" :item="item" :index="index">
|
|
39
|
+
{{ item.value !== undefined && item.value !== null ? item.value : '-' }}
|
|
40
|
+
</slot>
|
|
41
|
+
</div>
|
|
42
|
+
|
|
43
|
+
<!-- Optional per-item actions -->
|
|
44
|
+
<div v-if="$scopedSlots['item-actions-' + index]" class="cn-detail-grid__actions">
|
|
45
|
+
<slot :name="'item-actions-' + index" :item="item" :index="index" />
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
|
|
49
|
+
<!-- Append slot for manual items -->
|
|
50
|
+
<slot />
|
|
51
|
+
</div>
|
|
52
|
+
</template>
|
|
53
|
+
|
|
54
|
+
<script>
|
|
55
|
+
import { translate as t } from '@nextcloud/l10n'
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* CnDetailGrid — Data-driven label-value grid for detail/info sections.
|
|
59
|
+
*
|
|
60
|
+
* @example Simple data-driven grid
|
|
61
|
+
* <CnDetailGrid :items="[
|
|
62
|
+
* { label: 'ID', value: '12345' },
|
|
63
|
+
* { label: 'Status', value: 'Active' },
|
|
64
|
+
* { label: 'Created', value: '2024-01-15' },
|
|
65
|
+
* ]" />
|
|
66
|
+
*
|
|
67
|
+
* @example Grid with custom slot content
|
|
68
|
+
* <CnDetailGrid :items="[
|
|
69
|
+
* { label: 'ID', value: item.id },
|
|
70
|
+
* { label: 'Action' },
|
|
71
|
+
* ]">
|
|
72
|
+
* <template #item-1>
|
|
73
|
+
* <CnStatusBadge :label="item.action" />
|
|
74
|
+
* </template>
|
|
75
|
+
* </CnDetailGrid>
|
|
76
|
+
*
|
|
77
|
+
* @example Horizontal row layout
|
|
78
|
+
* <CnDetailGrid layout="horizontal" :items="fields" />
|
|
79
|
+
*/
|
|
80
|
+
export default {
|
|
81
|
+
name: 'CnDetailGrid',
|
|
82
|
+
|
|
83
|
+
props: {
|
|
84
|
+
/**
|
|
85
|
+
* Array of detail items to render.
|
|
86
|
+
* @type {Array<{ label: string, value?: string|number }>}
|
|
87
|
+
*/
|
|
88
|
+
items: {
|
|
89
|
+
type: Array,
|
|
90
|
+
default: () => [],
|
|
91
|
+
},
|
|
92
|
+
/**
|
|
93
|
+
* Layout mode.
|
|
94
|
+
* - 'grid': Responsive card grid, label stacked above value
|
|
95
|
+
* - 'horizontal': Vertical list of rows, label on left, value on right
|
|
96
|
+
*/
|
|
97
|
+
layout: {
|
|
98
|
+
type: String,
|
|
99
|
+
default: 'grid',
|
|
100
|
+
validator: (v) => ['grid', 'horizontal'].includes(v),
|
|
101
|
+
},
|
|
102
|
+
/**
|
|
103
|
+
* Number of fixed grid columns. Set to 0 (default) for responsive auto-fit.
|
|
104
|
+
* Only applies to layout="grid".
|
|
105
|
+
*/
|
|
106
|
+
columns: {
|
|
107
|
+
type: Number,
|
|
108
|
+
default: 0,
|
|
109
|
+
},
|
|
110
|
+
/**
|
|
111
|
+
* Minimum width (px) for auto-fit grid items.
|
|
112
|
+
* Only applies when columns is 0 and layout is 'grid'.
|
|
113
|
+
*/
|
|
114
|
+
minItemWidth: {
|
|
115
|
+
type: Number,
|
|
116
|
+
default: 250,
|
|
117
|
+
},
|
|
118
|
+
/**
|
|
119
|
+
* Minimum width (px) for labels in horizontal mode.
|
|
120
|
+
*/
|
|
121
|
+
labelWidth: {
|
|
122
|
+
type: Number,
|
|
123
|
+
default: 150,
|
|
124
|
+
},
|
|
125
|
+
/**
|
|
126
|
+
* Whether to show the left accent border on items.
|
|
127
|
+
*/
|
|
128
|
+
accent: {
|
|
129
|
+
type: Boolean,
|
|
130
|
+
default: true,
|
|
131
|
+
},
|
|
132
|
+
/**
|
|
133
|
+
* Text shown when the items array is empty.
|
|
134
|
+
*/
|
|
135
|
+
emptyLabel: {
|
|
136
|
+
type: String,
|
|
137
|
+
default: () => t('nextcloud-vue', 'No details available'),
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
|
|
141
|
+
computed: {
|
|
142
|
+
rootClasses() {
|
|
143
|
+
return {
|
|
144
|
+
'cn-detail-grid--grid': this.layout === 'grid',
|
|
145
|
+
'cn-detail-grid--horizontal': this.layout === 'horizontal',
|
|
146
|
+
'cn-detail-grid--accent': this.accent,
|
|
147
|
+
}
|
|
148
|
+
},
|
|
149
|
+
rootStyles() {
|
|
150
|
+
if (this.layout === 'grid') {
|
|
151
|
+
if (this.columns > 0) {
|
|
152
|
+
return { 'grid-template-columns': `repeat(${this.columns}, 1fr)` }
|
|
153
|
+
}
|
|
154
|
+
return { 'grid-template-columns': `repeat(auto-fit, minmax(${this.minItemWidth}px, 1fr))` }
|
|
155
|
+
}
|
|
156
|
+
if (this.layout === 'horizontal') {
|
|
157
|
+
return { '--cn-detail-grid-label-width': this.labelWidth + 'px' }
|
|
158
|
+
}
|
|
159
|
+
return {}
|
|
160
|
+
},
|
|
161
|
+
itemClasses() {
|
|
162
|
+
return {
|
|
163
|
+
'cn-detail-grid__item--horizontal': this.layout === 'horizontal',
|
|
164
|
+
}
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
</script>
|
|
169
|
+
|
|
170
|
+
<style scoped>
|
|
171
|
+
/* ===== Grid layout (default) ===== */
|
|
172
|
+
.cn-detail-grid--grid {
|
|
173
|
+
display: grid;
|
|
174
|
+
gap: calc(4 * var(--default-grid-baseline, 4px));
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/* ===== Horizontal layout ===== */
|
|
178
|
+
.cn-detail-grid--horizontal {
|
|
179
|
+
display: flex;
|
|
180
|
+
flex-direction: column;
|
|
181
|
+
gap: calc(3 * var(--default-grid-baseline, 4px));
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/* ===== Item (card style) ===== */
|
|
185
|
+
.cn-detail-grid__item {
|
|
186
|
+
display: flex;
|
|
187
|
+
flex-direction: column;
|
|
188
|
+
gap: var(--default-grid-baseline, 4px);
|
|
189
|
+
padding: calc(2 * var(--default-grid-baseline, 4px)) calc(3 * var(--default-grid-baseline, 4px));
|
|
190
|
+
background: var(--color-background-hover);
|
|
191
|
+
border-radius: 0 var(--border-radius) var(--border-radius) 0;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/* Accent border */
|
|
195
|
+
.cn-detail-grid--accent .cn-detail-grid__item {
|
|
196
|
+
border-left: 3px solid var(--color-primary-element);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/* Horizontal item: row direction */
|
|
200
|
+
.cn-detail-grid__item--horizontal {
|
|
201
|
+
flex-direction: row;
|
|
202
|
+
align-items: center;
|
|
203
|
+
gap: calc(4 * var(--default-grid-baseline, 4px));
|
|
204
|
+
border-radius: var(--border-radius);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* ===== Label ===== */
|
|
208
|
+
.cn-detail-grid__label {
|
|
209
|
+
font-size: 0.85em;
|
|
210
|
+
color: var(--color-text-maxcontrast);
|
|
211
|
+
font-weight: 500;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.cn-detail-grid--horizontal .cn-detail-grid__label {
|
|
215
|
+
min-width: var(--cn-detail-grid-label-width, 150px);
|
|
216
|
+
flex-shrink: 0;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
/* ===== Value ===== */
|
|
220
|
+
.cn-detail-grid__value {
|
|
221
|
+
font-size: 1em;
|
|
222
|
+
color: var(--color-main-text);
|
|
223
|
+
word-break: break-word;
|
|
224
|
+
margin: 0.5rem;
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
.cn-detail-grid--horizontal .cn-detail-grid__value {
|
|
228
|
+
flex: 1;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* ===== Actions ===== */
|
|
232
|
+
.cn-detail-grid__actions {
|
|
233
|
+
flex-shrink: 0;
|
|
234
|
+
display: flex;
|
|
235
|
+
align-items: center;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/* ===== Empty state ===== */
|
|
239
|
+
.cn-detail-grid__empty {
|
|
240
|
+
color: var(--color-text-maxcontrast);
|
|
241
|
+
font-style: italic;
|
|
242
|
+
padding: calc(2 * var(--default-grid-baseline, 4px));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/* ===== Responsive ===== */
|
|
246
|
+
@media (max-width: 600px) {
|
|
247
|
+
.cn-detail-grid--grid {
|
|
248
|
+
grid-template-columns: 1fr !important;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
.cn-detail-grid__item--horizontal {
|
|
252
|
+
flex-direction: column;
|
|
253
|
+
align-items: flex-start;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
</style>
|