@conduction/nextcloud-vue 0.1.0-beta.4 → 0.1.0-beta.6
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 +9559 -8983
- package/dist/nextcloud-vue.cjs.js.map +1 -1
- package/dist/nextcloud-vue.cjs.map +1 -0
- package/dist/nextcloud-vue.css +1231 -1231
- package/dist/nextcloud-vue.esm.js +9559 -8983
- package/dist/nextcloud-vue.esm.js.map +1 -1
- package/package.json +14 -5
- package/src/components/CnActionsBar/CnActionsBar.vue +235 -235
- package/src/components/CnAdvancedFormDialog/CnAdvancedFormDialog.vue +579 -579
- package/src/components/CnAdvancedFormDialog/CnDataTab.vue +217 -217
- package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +121 -121
- package/src/components/CnAdvancedFormDialog/CnPropertiesTab.vue +418 -418
- package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +247 -247
- package/src/components/CnCardGrid/CnCardGrid.vue +152 -152
- package/src/components/CnCellRenderer/CnCellRenderer.vue +132 -132
- package/src/components/CnChartWidget/CnChartWidget.vue +320 -320
- package/src/components/CnConfigurationCard/CnConfigurationCard.vue +77 -77
- package/src/components/CnCopyDialog/CnCopyDialog.vue +250 -250
- package/src/components/CnDashboardGrid/CnDashboardGrid.vue +225 -225
- package/src/components/CnDashboardPage/CnDashboardPage.vue +390 -390
- package/src/components/CnDataTable/CnDataTable.vue +349 -349
- package/src/components/CnDeleteDialog/CnDeleteDialog.vue +170 -170
- package/src/components/CnDetailCard/CnDetailCard.vue +214 -214
- package/src/components/CnDetailPage/CnDetailPage.vue +285 -281
- package/src/components/CnFacetSidebar/CnFacetSidebar.vue +231 -231
- package/src/components/CnFilterBar/CnFilterBar.vue +152 -152
- package/src/components/CnFormDialog/CnFormDialog.vue +302 -11
- package/src/components/CnIcon/CnIcon.vue +89 -89
- package/src/components/CnIndexPage/CnIndexPage.vue +884 -874
- package/src/components/CnIndexSidebar/CnIndexSidebar.vue +503 -503
- package/src/components/CnItemCard/CnItemCard.vue +132 -132
- package/src/components/CnKpiGrid/CnKpiGrid.vue +89 -89
- package/src/components/CnMassActionBar/CnMassActionBar.vue +160 -160
- package/src/components/CnMassCopyDialog/CnMassCopyDialog.vue +320 -320
- package/src/components/CnMassDeleteDialog/CnMassDeleteDialog.vue +238 -238
- package/src/components/CnMassExportDialog/CnMassExportDialog.vue +190 -190
- package/src/components/CnMassImportDialog/CnMassImportDialog.vue +491 -491
- package/src/components/CnNoteCard/CnNoteCard.vue +149 -149
- package/src/components/CnNotesCard/CnNotesCard.vue +413 -413
- package/src/components/CnObjectCard/CnObjectCard.vue +292 -292
- package/src/components/CnObjectCard/eslint-setup.md +235 -0
- package/src/components/CnObjectCard/package.json-or.json +132 -0
- package/src/components/CnObjectSidebar/CnObjectSidebar.vue +876 -876
- package/src/components/CnPageHeader/CnPageHeader.vue +57 -57
- package/src/components/CnPagination/CnPagination.vue +252 -252
- package/src/components/CnRegisterMapping/CnRegisterMapping.vue +792 -792
- package/src/components/CnRowActions/CnRowActions.vue +95 -73
- package/src/components/CnSchemaFormDialog/CnSchemaConfigurationTab.vue +226 -226
- package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +787 -787
- 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 +266 -266
- package/src/components/CnStatsBlock/CnStatsBlock.vue +420 -420
- package/src/components/CnStatusBadge/CnStatusBadge.vue +77 -77
- package/src/components/CnTabbedFormDialog/CnTabbedFormDialog.vue +540 -540
- package/src/components/CnTasksCard/CnTasksCard.vue +373 -373
- package/src/components/CnTileWidget/CnTileWidget.vue +159 -159
- package/src/components/CnTimelineStages/CnTimelineStages.vue +292 -292
- package/src/components/CnUserActionMenu/CnUserActionMenu.vue +435 -435
- package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +312 -312
- package/src/components/CnWidgetRenderer/CnWidgetRenderer.vue +180 -180
- package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +211 -211
- package/src/index.js +1 -1
- package/src/types/notification.d.ts +13 -13
- package/src/types/organisation.d.ts +15 -15
- package/src/types/schema.d.ts +13 -13
- package/src/types/task.d.ts +6 -6
- package/src/utils/headers.js +5 -3
|
@@ -1,211 +1,211 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
CnWidgetWrapper — Container shell around a dashboard widget.
|
|
3
|
-
|
|
4
|
-
Provides header (icon + title), scrollable content area, and optional
|
|
5
|
-
footer with action buttons. Applies style configuration for borders,
|
|
6
|
-
backgrounds, and padding.
|
|
7
|
-
-->
|
|
8
|
-
<template>
|
|
9
|
-
<div class="cn-widget-wrapper" :style="wrapperStyles">
|
|
10
|
-
<!-- Header -->
|
|
11
|
-
<div v-if="showTitle" class="cn-widget-wrapper__header">
|
|
12
|
-
<div class="cn-widget-wrapper__header-left">
|
|
13
|
-
<img
|
|
14
|
-
v-if="iconUrl"
|
|
15
|
-
:src="iconUrl"
|
|
16
|
-
:alt="displayTitle"
|
|
17
|
-
class="cn-widget-wrapper__icon">
|
|
18
|
-
<span
|
|
19
|
-
v-else-if="iconClass"
|
|
20
|
-
:class="iconClass"
|
|
21
|
-
class="cn-widget-wrapper__icon" />
|
|
22
|
-
<h3 class="cn-widget-wrapper__title">
|
|
23
|
-
{{ displayTitle }}
|
|
24
|
-
</h3>
|
|
25
|
-
</div>
|
|
26
|
-
<div class="cn-widget-wrapper__actions">
|
|
27
|
-
<slot name="header-actions" />
|
|
28
|
-
</div>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<!-- Content -->
|
|
32
|
-
<div class="cn-widget-wrapper__content">
|
|
33
|
-
<slot />
|
|
34
|
-
</div>
|
|
35
|
-
|
|
36
|
-
<!-- Footer -->
|
|
37
|
-
<div v-if="$slots.footer || (buttons && buttons.length > 0)" class="cn-widget-wrapper__footer">
|
|
38
|
-
<slot name="footer">
|
|
39
|
-
<a
|
|
40
|
-
v-for="button in buttons"
|
|
41
|
-
:key="button.link"
|
|
42
|
-
:href="button.link"
|
|
43
|
-
class="cn-widget-wrapper__footer-link">
|
|
44
|
-
{{ button.text }}
|
|
45
|
-
</a>
|
|
46
|
-
</slot>
|
|
47
|
-
</div>
|
|
48
|
-
</div>
|
|
49
|
-
</template>
|
|
50
|
-
|
|
51
|
-
<script>
|
|
52
|
-
/**
|
|
53
|
-
* CnWidgetWrapper — Widget container with header, content, and footer.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* <CnWidgetWrapper title="My Cases" :icon-url="casesIconUrl">
|
|
57
|
-
* <MyCasesChart :data="chartData" />
|
|
58
|
-
* </CnWidgetWrapper>
|
|
59
|
-
*
|
|
60
|
-
* @example With NC widget object
|
|
61
|
-
* <CnWidgetWrapper
|
|
62
|
-
* :title="widget.title"
|
|
63
|
-
* :icon-url="widget.iconUrl"
|
|
64
|
-
* :icon-class="widget.iconClass"
|
|
65
|
-
* :buttons="widget.buttons">
|
|
66
|
-
* <CnWidgetRenderer :widget="widget" />
|
|
67
|
-
* </CnWidgetWrapper>
|
|
68
|
-
*/
|
|
69
|
-
export default {
|
|
70
|
-
name: 'CnWidgetWrapper',
|
|
71
|
-
|
|
72
|
-
props: {
|
|
73
|
-
/** Widget title */
|
|
74
|
-
title: {
|
|
75
|
-
type: String,
|
|
76
|
-
default: 'Widget',
|
|
77
|
-
},
|
|
78
|
-
/** Whether to show the header with title */
|
|
79
|
-
showTitle: {
|
|
80
|
-
type: Boolean,
|
|
81
|
-
default: true,
|
|
82
|
-
},
|
|
83
|
-
/** Icon URL (image) */
|
|
84
|
-
iconUrl: {
|
|
85
|
-
type: String,
|
|
86
|
-
default: null,
|
|
87
|
-
},
|
|
88
|
-
/** Icon CSS class (e.g., Nextcloud icon class) */
|
|
89
|
-
iconClass: {
|
|
90
|
-
type: String,
|
|
91
|
-
default: null,
|
|
92
|
-
},
|
|
93
|
-
/** Footer action buttons: [{ text, link }] */
|
|
94
|
-
buttons: {
|
|
95
|
-
type: Array,
|
|
96
|
-
default: () => [],
|
|
97
|
-
},
|
|
98
|
-
/**
|
|
99
|
-
* Style configuration for the wrapper.
|
|
100
|
-
* @type {{ backgroundColor?: string, borderStyle?: string, borderWidth?: number, borderColor?: string, borderRadius?: number, padding?: { top: number, right: number, bottom: number, left: number } }}
|
|
101
|
-
*/
|
|
102
|
-
styleConfig: {
|
|
103
|
-
type: Object,
|
|
104
|
-
default: () => ({}),
|
|
105
|
-
},
|
|
106
|
-
},
|
|
107
|
-
|
|
108
|
-
computed: {
|
|
109
|
-
displayTitle() {
|
|
110
|
-
return this.title || 'Widget'
|
|
111
|
-
},
|
|
112
|
-
|
|
113
|
-
wrapperStyles() {
|
|
114
|
-
const styles = {}
|
|
115
|
-
|
|
116
|
-
if (this.styleConfig.backgroundColor) {
|
|
117
|
-
styles.backgroundColor = this.styleConfig.backgroundColor
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
if (this.styleConfig.borderStyle && this.styleConfig.borderStyle !== 'none') {
|
|
121
|
-
styles.border = `${this.styleConfig.borderWidth || 1}px ${this.styleConfig.borderStyle} ${this.styleConfig.borderColor || 'var(--color-border)'}`
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
if (this.styleConfig.borderRadius !== undefined) {
|
|
125
|
-
styles.borderRadius = `${this.styleConfig.borderRadius}px`
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (this.styleConfig.padding) {
|
|
129
|
-
const p = this.styleConfig.padding
|
|
130
|
-
styles.padding = `${p.top || 0}px ${p.right || 0}px ${p.bottom || 0}px ${p.left || 0}px`
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
return styles
|
|
134
|
-
},
|
|
135
|
-
},
|
|
136
|
-
}
|
|
137
|
-
</script>
|
|
138
|
-
|
|
139
|
-
<style scoped>
|
|
140
|
-
.cn-widget-wrapper {
|
|
141
|
-
height: 100%;
|
|
142
|
-
display: flex;
|
|
143
|
-
flex-direction: column;
|
|
144
|
-
background: var(--color-main-background);
|
|
145
|
-
border: 1px solid var(--color-border);
|
|
146
|
-
overflow: hidden;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
.cn-widget-wrapper__header {
|
|
150
|
-
display: flex;
|
|
151
|
-
align-items: center;
|
|
152
|
-
justify-content: space-between;
|
|
153
|
-
padding: 12px 16px;
|
|
154
|
-
border-bottom: 1px solid var(--color-border);
|
|
155
|
-
flex-shrink: 0;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
.cn-widget-wrapper__header-left {
|
|
159
|
-
display: flex;
|
|
160
|
-
align-items: center;
|
|
161
|
-
gap: 8px;
|
|
162
|
-
min-width: 0;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
.cn-widget-wrapper__icon {
|
|
166
|
-
width: 24px;
|
|
167
|
-
height: 24px;
|
|
168
|
-
flex-shrink: 0;
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
.cn-widget-wrapper__title {
|
|
172
|
-
font-weight: 600;
|
|
173
|
-
font-size: 14px;
|
|
174
|
-
margin: 0;
|
|
175
|
-
white-space: nowrap;
|
|
176
|
-
overflow: hidden;
|
|
177
|
-
text-overflow: ellipsis;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
.cn-widget-wrapper__content {
|
|
181
|
-
flex: 1;
|
|
182
|
-
overflow: auto;
|
|
183
|
-
min-height: 0;
|
|
184
|
-
padding: 16px;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
.cn-widget-wrapper__actions {
|
|
188
|
-
display: flex;
|
|
189
|
-
gap: 4px;
|
|
190
|
-
flex-shrink: 0;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
.cn-widget-wrapper__footer {
|
|
194
|
-
display: flex;
|
|
195
|
-
justify-content: flex-end;
|
|
196
|
-
gap: 8px;
|
|
197
|
-
padding: 8px 16px;
|
|
198
|
-
border-top: 1px solid var(--color-border);
|
|
199
|
-
flex-shrink: 0;
|
|
200
|
-
}
|
|
201
|
-
|
|
202
|
-
.cn-widget-wrapper__footer-link {
|
|
203
|
-
font-size: 13px;
|
|
204
|
-
color: var(--color-primary-element);
|
|
205
|
-
text-decoration: none;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
.cn-widget-wrapper__footer-link:hover {
|
|
209
|
-
text-decoration: underline;
|
|
210
|
-
}
|
|
211
|
-
</style>
|
|
1
|
+
<!--
|
|
2
|
+
CnWidgetWrapper — Container shell around a dashboard widget.
|
|
3
|
+
|
|
4
|
+
Provides header (icon + title), scrollable content area, and optional
|
|
5
|
+
footer with action buttons. Applies style configuration for borders,
|
|
6
|
+
backgrounds, and padding.
|
|
7
|
+
-->
|
|
8
|
+
<template>
|
|
9
|
+
<div class="cn-widget-wrapper" :style="wrapperStyles">
|
|
10
|
+
<!-- Header -->
|
|
11
|
+
<div v-if="showTitle" class="cn-widget-wrapper__header">
|
|
12
|
+
<div class="cn-widget-wrapper__header-left">
|
|
13
|
+
<img
|
|
14
|
+
v-if="iconUrl"
|
|
15
|
+
:src="iconUrl"
|
|
16
|
+
:alt="displayTitle"
|
|
17
|
+
class="cn-widget-wrapper__icon">
|
|
18
|
+
<span
|
|
19
|
+
v-else-if="iconClass"
|
|
20
|
+
:class="iconClass"
|
|
21
|
+
class="cn-widget-wrapper__icon" />
|
|
22
|
+
<h3 class="cn-widget-wrapper__title">
|
|
23
|
+
{{ displayTitle }}
|
|
24
|
+
</h3>
|
|
25
|
+
</div>
|
|
26
|
+
<div class="cn-widget-wrapper__actions">
|
|
27
|
+
<slot name="header-actions" />
|
|
28
|
+
</div>
|
|
29
|
+
</div>
|
|
30
|
+
|
|
31
|
+
<!-- Content -->
|
|
32
|
+
<div class="cn-widget-wrapper__content">
|
|
33
|
+
<slot />
|
|
34
|
+
</div>
|
|
35
|
+
|
|
36
|
+
<!-- Footer -->
|
|
37
|
+
<div v-if="$slots.footer || (buttons && buttons.length > 0)" class="cn-widget-wrapper__footer">
|
|
38
|
+
<slot name="footer">
|
|
39
|
+
<a
|
|
40
|
+
v-for="button in buttons"
|
|
41
|
+
:key="button.link"
|
|
42
|
+
:href="button.link"
|
|
43
|
+
class="cn-widget-wrapper__footer-link">
|
|
44
|
+
{{ button.text }}
|
|
45
|
+
</a>
|
|
46
|
+
</slot>
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
|
|
51
|
+
<script>
|
|
52
|
+
/**
|
|
53
|
+
* CnWidgetWrapper — Widget container with header, content, and footer.
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* <CnWidgetWrapper title="My Cases" :icon-url="casesIconUrl">
|
|
57
|
+
* <MyCasesChart :data="chartData" />
|
|
58
|
+
* </CnWidgetWrapper>
|
|
59
|
+
*
|
|
60
|
+
* @example With NC widget object
|
|
61
|
+
* <CnWidgetWrapper
|
|
62
|
+
* :title="widget.title"
|
|
63
|
+
* :icon-url="widget.iconUrl"
|
|
64
|
+
* :icon-class="widget.iconClass"
|
|
65
|
+
* :buttons="widget.buttons">
|
|
66
|
+
* <CnWidgetRenderer :widget="widget" />
|
|
67
|
+
* </CnWidgetWrapper>
|
|
68
|
+
*/
|
|
69
|
+
export default {
|
|
70
|
+
name: 'CnWidgetWrapper',
|
|
71
|
+
|
|
72
|
+
props: {
|
|
73
|
+
/** Widget title */
|
|
74
|
+
title: {
|
|
75
|
+
type: String,
|
|
76
|
+
default: 'Widget',
|
|
77
|
+
},
|
|
78
|
+
/** Whether to show the header with title */
|
|
79
|
+
showTitle: {
|
|
80
|
+
type: Boolean,
|
|
81
|
+
default: true,
|
|
82
|
+
},
|
|
83
|
+
/** Icon URL (image) */
|
|
84
|
+
iconUrl: {
|
|
85
|
+
type: String,
|
|
86
|
+
default: null,
|
|
87
|
+
},
|
|
88
|
+
/** Icon CSS class (e.g., Nextcloud icon class) */
|
|
89
|
+
iconClass: {
|
|
90
|
+
type: String,
|
|
91
|
+
default: null,
|
|
92
|
+
},
|
|
93
|
+
/** Footer action buttons: [{ text, link }] */
|
|
94
|
+
buttons: {
|
|
95
|
+
type: Array,
|
|
96
|
+
default: () => [],
|
|
97
|
+
},
|
|
98
|
+
/**
|
|
99
|
+
* Style configuration for the wrapper.
|
|
100
|
+
* @type {{ backgroundColor?: string, borderStyle?: string, borderWidth?: number, borderColor?: string, borderRadius?: number, padding?: { top: number, right: number, bottom: number, left: number } }}
|
|
101
|
+
*/
|
|
102
|
+
styleConfig: {
|
|
103
|
+
type: Object,
|
|
104
|
+
default: () => ({}),
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
computed: {
|
|
109
|
+
displayTitle() {
|
|
110
|
+
return this.title || 'Widget'
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
wrapperStyles() {
|
|
114
|
+
const styles = {}
|
|
115
|
+
|
|
116
|
+
if (this.styleConfig.backgroundColor) {
|
|
117
|
+
styles.backgroundColor = this.styleConfig.backgroundColor
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (this.styleConfig.borderStyle && this.styleConfig.borderStyle !== 'none') {
|
|
121
|
+
styles.border = `${this.styleConfig.borderWidth || 1}px ${this.styleConfig.borderStyle} ${this.styleConfig.borderColor || 'var(--color-border)'}`
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (this.styleConfig.borderRadius !== undefined) {
|
|
125
|
+
styles.borderRadius = `${this.styleConfig.borderRadius}px`
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (this.styleConfig.padding) {
|
|
129
|
+
const p = this.styleConfig.padding
|
|
130
|
+
styles.padding = `${p.top || 0}px ${p.right || 0}px ${p.bottom || 0}px ${p.left || 0}px`
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return styles
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
}
|
|
137
|
+
</script>
|
|
138
|
+
|
|
139
|
+
<style scoped>
|
|
140
|
+
.cn-widget-wrapper {
|
|
141
|
+
height: 100%;
|
|
142
|
+
display: flex;
|
|
143
|
+
flex-direction: column;
|
|
144
|
+
background: var(--color-main-background);
|
|
145
|
+
border: 1px solid var(--color-border);
|
|
146
|
+
overflow: hidden;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.cn-widget-wrapper__header {
|
|
150
|
+
display: flex;
|
|
151
|
+
align-items: center;
|
|
152
|
+
justify-content: space-between;
|
|
153
|
+
padding: 12px 16px;
|
|
154
|
+
border-bottom: 1px solid var(--color-border);
|
|
155
|
+
flex-shrink: 0;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.cn-widget-wrapper__header-left {
|
|
159
|
+
display: flex;
|
|
160
|
+
align-items: center;
|
|
161
|
+
gap: 8px;
|
|
162
|
+
min-width: 0;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
.cn-widget-wrapper__icon {
|
|
166
|
+
width: 24px;
|
|
167
|
+
height: 24px;
|
|
168
|
+
flex-shrink: 0;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.cn-widget-wrapper__title {
|
|
172
|
+
font-weight: 600;
|
|
173
|
+
font-size: 14px;
|
|
174
|
+
margin: 0;
|
|
175
|
+
white-space: nowrap;
|
|
176
|
+
overflow: hidden;
|
|
177
|
+
text-overflow: ellipsis;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
.cn-widget-wrapper__content {
|
|
181
|
+
flex: 1;
|
|
182
|
+
overflow: auto;
|
|
183
|
+
min-height: 0;
|
|
184
|
+
padding: 16px;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
.cn-widget-wrapper__actions {
|
|
188
|
+
display: flex;
|
|
189
|
+
gap: 4px;
|
|
190
|
+
flex-shrink: 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.cn-widget-wrapper__footer {
|
|
194
|
+
display: flex;
|
|
195
|
+
justify-content: flex-end;
|
|
196
|
+
gap: 8px;
|
|
197
|
+
padding: 8px 16px;
|
|
198
|
+
border-top: 1px solid var(--color-border);
|
|
199
|
+
flex-shrink: 0;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
.cn-widget-wrapper__footer-link {
|
|
203
|
+
font-size: 13px;
|
|
204
|
+
color: var(--color-primary-element);
|
|
205
|
+
text-decoration: none;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
.cn-widget-wrapper__footer-link:hover {
|
|
209
|
+
text-decoration: underline;
|
|
210
|
+
}
|
|
211
|
+
</style>
|
package/src/index.js
CHANGED
|
@@ -30,7 +30,6 @@ export {
|
|
|
30
30
|
CnMassImportDialog,
|
|
31
31
|
CnIndexSidebar,
|
|
32
32
|
CnRegisterMapping,
|
|
33
|
-
CnDetailPage,
|
|
34
33
|
CnDashboardPage,
|
|
35
34
|
CnDashboardGrid,
|
|
36
35
|
CnWidgetWrapper,
|
|
@@ -43,6 +42,7 @@ export {
|
|
|
43
42
|
CnUserActionMenu,
|
|
44
43
|
CnNotesCard,
|
|
45
44
|
CnTasksCard,
|
|
45
|
+
CnDetailPage,
|
|
46
46
|
registerIcons,
|
|
47
47
|
} from './components/index.js'
|
|
48
48
|
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/** Notification type categories. */
|
|
2
|
+
export type TNotificationType =
|
|
3
|
+
| 'status-change'
|
|
4
|
+
| 'assignment'
|
|
5
|
+
| 'deadline'
|
|
6
|
+
| 'mention'
|
|
7
|
+
| 'comment'
|
|
8
|
+
| 'system'
|
|
9
|
+
| string
|
|
10
|
+
|
|
11
|
+
/** Notification priority levels. */
|
|
12
|
+
export type TNotificationPriority = 'urgent' | 'high' | 'normal' | 'low'
|
|
13
|
+
|
|
1
14
|
/**
|
|
2
15
|
* OpenRegister Notification entity type.
|
|
3
16
|
*
|
|
@@ -21,16 +34,3 @@ export interface TNotification {
|
|
|
21
34
|
created: string
|
|
22
35
|
updated?: string
|
|
23
36
|
}
|
|
24
|
-
|
|
25
|
-
/** Notification type categories. */
|
|
26
|
-
export type TNotificationType =
|
|
27
|
-
| 'status-change'
|
|
28
|
-
| 'assignment'
|
|
29
|
-
| 'deadline'
|
|
30
|
-
| 'mention'
|
|
31
|
-
| 'comment'
|
|
32
|
-
| 'system'
|
|
33
|
-
| string
|
|
34
|
-
|
|
35
|
-
/** Notification priority levels. */
|
|
36
|
-
export type TNotificationPriority = 'urgent' | 'high' | 'normal' | 'low'
|
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
import type { TQuota, TUsage, TCrudAuthorization } from './shared'
|
|
2
2
|
|
|
3
|
+
/** Organisation-level authorization with per-entity-type CRUD + special permissions. */
|
|
4
|
+
export interface TOrganisationAuthorization {
|
|
5
|
+
register?: TCrudAuthorization
|
|
6
|
+
schema?: TCrudAuthorization
|
|
7
|
+
object?: TCrudAuthorization
|
|
8
|
+
view?: TCrudAuthorization
|
|
9
|
+
agent?: TCrudAuthorization
|
|
10
|
+
configuration?: TCrudAuthorization
|
|
11
|
+
application?: TCrudAuthorization
|
|
12
|
+
object_publish?: string[]
|
|
13
|
+
agent_use?: string[]
|
|
14
|
+
dashboard_view?: string[]
|
|
15
|
+
llm_use?: string[]
|
|
16
|
+
}
|
|
17
|
+
|
|
3
18
|
/**
|
|
4
19
|
* OpenRegister Organisation entity type.
|
|
5
20
|
*
|
|
@@ -24,18 +39,3 @@ export interface TOrganisation {
|
|
|
24
39
|
created?: string
|
|
25
40
|
updated?: string
|
|
26
41
|
}
|
|
27
|
-
|
|
28
|
-
/** Organisation-level authorization with per-entity-type CRUD + special permissions. */
|
|
29
|
-
export interface TOrganisationAuthorization {
|
|
30
|
-
register?: TCrudAuthorization
|
|
31
|
-
schema?: TCrudAuthorization
|
|
32
|
-
object?: TCrudAuthorization
|
|
33
|
-
view?: TCrudAuthorization
|
|
34
|
-
agent?: TCrudAuthorization
|
|
35
|
-
configuration?: TCrudAuthorization
|
|
36
|
-
application?: TCrudAuthorization
|
|
37
|
-
object_publish?: string[]
|
|
38
|
-
agent_use?: string[]
|
|
39
|
-
dashboard_view?: string[]
|
|
40
|
-
llm_use?: string[]
|
|
41
|
-
}
|
package/src/types/schema.d.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { TEntityStats } from './shared'
|
|
2
2
|
|
|
3
|
+
/** Schema configuration options. */
|
|
4
|
+
export interface TSchemaConfiguration {
|
|
5
|
+
objectNameField?: string
|
|
6
|
+
objectDescriptionField?: string
|
|
7
|
+
objectSummaryField?: string
|
|
8
|
+
objectImageField?: string
|
|
9
|
+
allowFiles?: boolean
|
|
10
|
+
allowedTags?: string[]
|
|
11
|
+
unique?: boolean
|
|
12
|
+
facetCacheTtl?: number
|
|
13
|
+
autoPublish?: boolean
|
|
14
|
+
}
|
|
15
|
+
|
|
3
16
|
/**
|
|
4
17
|
* OpenRegister Schema entity type.
|
|
5
18
|
*
|
|
@@ -24,16 +37,3 @@ export interface TSchema {
|
|
|
24
37
|
extend?: string
|
|
25
38
|
stats?: TEntityStats
|
|
26
39
|
}
|
|
27
|
-
|
|
28
|
-
/** Schema configuration options. */
|
|
29
|
-
export interface TSchemaConfiguration {
|
|
30
|
-
objectNameField?: string
|
|
31
|
-
objectDescriptionField?: string
|
|
32
|
-
objectSummaryField?: string
|
|
33
|
-
objectImageField?: string
|
|
34
|
-
allowFiles?: boolean
|
|
35
|
-
allowedTags?: string[]
|
|
36
|
-
unique?: boolean
|
|
37
|
-
facetCacheTtl?: number
|
|
38
|
-
autoPublish?: boolean
|
|
39
|
-
}
|
package/src/types/task.d.ts
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
/** CalDAV task priority levels (mapped from iCal 0-9 range). */
|
|
2
|
+
export type TTaskPriority = 'urgent' | 'high' | 'normal' | 'low'
|
|
3
|
+
|
|
4
|
+
/** CalDAV task status values. */
|
|
5
|
+
export type TTaskStatus = 'needs-action' | 'in-process' | 'completed' | 'cancelled'
|
|
6
|
+
|
|
1
7
|
/**
|
|
2
8
|
* OpenRegister Task entity type.
|
|
3
9
|
*
|
|
@@ -23,9 +29,3 @@ export interface TTask {
|
|
|
23
29
|
created?: string
|
|
24
30
|
updated?: string
|
|
25
31
|
}
|
|
26
|
-
|
|
27
|
-
/** CalDAV task priority levels (mapped from iCal 0-9 range). */
|
|
28
|
-
export type TTaskPriority = 'urgent' | 'high' | 'normal' | 'low'
|
|
29
|
-
|
|
30
|
-
/** CalDAV task status values. */
|
|
31
|
-
export type TTaskStatus = 'needs-action' | 'in-process' | 'completed' | 'cancelled'
|
package/src/utils/headers.js
CHANGED
|
@@ -39,8 +39,8 @@ export function buildHeaders(contentType = 'application/json') {
|
|
|
39
39
|
/**
|
|
40
40
|
* Build a query string from a params object.
|
|
41
41
|
*
|
|
42
|
-
* Handles
|
|
43
|
-
* null/undefined/empty values.
|
|
42
|
+
* Handles array values by appending each item separately, plain object values
|
|
43
|
+
* by JSON-serializing them, and skips null/undefined/empty values.
|
|
44
44
|
*
|
|
45
45
|
* @param {object} params Key-value pairs for query parameters
|
|
46
46
|
* @return {string} Query string including leading '?' or empty string
|
|
@@ -50,13 +50,15 @@ export function buildQueryString(params = {}) {
|
|
|
50
50
|
|
|
51
51
|
for (const [key, value] of Object.entries(params)) {
|
|
52
52
|
if (value === undefined || value === null || value === '') continue
|
|
53
|
+
if (Array.isArray(value) && value.length === 0) continue
|
|
54
|
+
if (typeof value === 'object' && !Array.isArray(value) && Object.keys(value).length === 0) continue
|
|
53
55
|
if (Array.isArray(value)) {
|
|
54
56
|
for (const item of value) {
|
|
55
57
|
if (item !== undefined && item !== null && item !== '') {
|
|
56
58
|
queryParams.append(key, String(item))
|
|
57
59
|
}
|
|
58
60
|
}
|
|
59
|
-
} else if (
|
|
61
|
+
} else if (typeof value === 'object') {
|
|
60
62
|
queryParams.set(key, JSON.stringify(value))
|
|
61
63
|
} else {
|
|
62
64
|
queryParams.set(key, String(value))
|