@conduction/nextcloud-vue 0.1.0-beta.3 → 0.1.0-beta.4

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 (152) hide show
  1. package/README.md +226 -226
  2. package/dist/nextcloud-vue.cjs.js +60455 -8755
  3. package/dist/nextcloud-vue.cjs.js.map +1 -1
  4. package/dist/nextcloud-vue.css +2062 -528
  5. package/dist/nextcloud-vue.esm.js +60411 -8731
  6. package/dist/nextcloud-vue.esm.js.map +1 -1
  7. package/package.json +75 -62
  8. package/src/components/CnActionsBar/CnActionsBar.vue +235 -225
  9. package/src/components/CnActionsBar/index.js +1 -1
  10. package/src/components/CnAdvancedFormDialog/CnAdvancedFormDialog.vue +579 -0
  11. package/src/components/CnAdvancedFormDialog/CnDataTab.vue +217 -0
  12. package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +121 -0
  13. package/src/components/CnAdvancedFormDialog/CnPropertiesTab.vue +418 -0
  14. package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +247 -0
  15. package/src/components/CnAdvancedFormDialog/index.js +1 -0
  16. package/src/components/CnCardGrid/CnCardGrid.vue +152 -152
  17. package/src/components/CnCardGrid/index.js +1 -1
  18. package/src/components/CnCellRenderer/CnCellRenderer.vue +132 -132
  19. package/src/components/CnCellRenderer/index.js +1 -1
  20. package/src/components/CnChartWidget/CnChartWidget.vue +320 -0
  21. package/src/components/CnChartWidget/index.js +1 -0
  22. package/src/components/CnConfigurationCard/CnConfigurationCard.vue +77 -77
  23. package/src/components/CnConfigurationCard/index.js +1 -1
  24. package/src/components/CnDashboardGrid/CnDashboardGrid.vue +225 -0
  25. package/src/components/CnDashboardGrid/index.js +1 -0
  26. package/src/components/CnDashboardPage/CnDashboardPage.vue +390 -0
  27. package/src/components/CnDashboardPage/index.js +1 -0
  28. package/src/components/CnDataTable/CnDataTable.vue +349 -349
  29. package/src/components/CnDataTable/index.js +1 -1
  30. package/src/components/CnDetailCard/CnDetailCard.vue +214 -0
  31. package/src/components/CnDetailCard/index.js +1 -0
  32. package/src/components/CnDetailPage/CnDetailPage.vue +281 -0
  33. package/src/components/CnDetailPage/index.js +1 -0
  34. package/src/components/CnFacetSidebar/CnFacetSidebar.vue +231 -223
  35. package/src/components/CnFacetSidebar/index.js +1 -1
  36. package/src/components/CnFilterBar/CnFilterBar.vue +152 -152
  37. package/src/components/CnFilterBar/index.js +1 -1
  38. package/src/components/CnIcon/CnIcon.vue +89 -89
  39. package/src/components/CnIcon/index.js +1 -1
  40. package/src/components/CnIndexPage/CnIndexPage.vue +874 -816
  41. package/src/components/CnIndexPage/index.js +1 -1
  42. package/src/components/CnIndexSidebar/CnIndexSidebar.vue +503 -484
  43. package/src/components/CnIndexSidebar/index.js +1 -1
  44. package/src/components/CnItemCard/CnItemCard.vue +132 -0
  45. package/src/components/CnItemCard/index.js +1 -0
  46. package/src/components/CnKpiGrid/CnKpiGrid.vue +89 -89
  47. package/src/components/CnKpiGrid/index.js +1 -1
  48. package/src/components/CnMassActionBar/CnMassActionBar.vue +160 -160
  49. package/src/components/CnMassActionBar/index.js +1 -1
  50. package/src/components/CnMassCopyDialog/CnMassCopyDialog.vue +320 -320
  51. package/src/components/CnMassCopyDialog/index.js +1 -1
  52. package/src/components/CnMassDeleteDialog/CnMassDeleteDialog.vue +238 -238
  53. package/src/components/CnMassDeleteDialog/index.js +1 -1
  54. package/src/components/CnMassExportDialog/CnMassExportDialog.vue +190 -190
  55. package/src/components/CnMassExportDialog/index.js +1 -1
  56. package/src/components/CnMassImportDialog/CnMassImportDialog.vue +491 -491
  57. package/src/components/CnMassImportDialog/index.js +1 -1
  58. package/src/components/CnNoteCard/CnNoteCard.vue +149 -0
  59. package/src/components/CnNoteCard/index.js +1 -0
  60. package/src/components/CnNotesCard/CnNotesCard.vue +413 -0
  61. package/src/components/CnNotesCard/index.js +1 -0
  62. package/src/components/CnObjectCard/CnObjectCard.vue +292 -292
  63. package/src/components/CnObjectCard/index.js +1 -1
  64. package/src/components/CnObjectSidebar/CnObjectSidebar.vue +876 -0
  65. package/src/components/CnObjectSidebar/index.js +1 -0
  66. package/src/components/CnPageHeader/CnPageHeader.vue +57 -57
  67. package/src/components/CnPageHeader/index.js +1 -1
  68. package/src/components/CnPagination/CnPagination.vue +252 -252
  69. package/src/components/CnPagination/index.js +1 -1
  70. package/src/components/CnRowActions/CnRowActions.vue +73 -73
  71. package/src/components/CnRowActions/index.js +1 -1
  72. package/src/components/CnSchemaFormDialog/CnSchemaConfigurationTab.vue +226 -0
  73. package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +787 -0
  74. package/src/components/CnSchemaFormDialog/CnSchemaPropertiesTab.vue +305 -0
  75. package/src/components/CnSchemaFormDialog/CnSchemaPropertyActions.vue +1398 -0
  76. package/src/components/CnSchemaFormDialog/CnSchemaSecurityTab.vue +236 -0
  77. package/src/components/CnSchemaFormDialog/index.js +1 -0
  78. package/src/components/CnSettingsCard/CnSettingsCard.vue +92 -92
  79. package/src/components/CnSettingsCard/index.js +1 -1
  80. package/src/components/CnSettingsSection/CnSettingsSection.vue +266 -266
  81. package/src/components/CnSettingsSection/index.js +1 -1
  82. package/src/components/CnStatsBlock/CnStatsBlock.vue +420 -366
  83. package/src/components/CnStatsBlock/index.js +1 -1
  84. package/src/components/CnStatusBadge/CnStatusBadge.vue +77 -77
  85. package/src/components/CnStatusBadge/index.js +1 -1
  86. package/src/components/CnTabbedFormDialog/CnTabbedFormDialog.vue +540 -0
  87. package/src/components/CnTabbedFormDialog/index.js +1 -0
  88. package/src/components/CnTasksCard/CnTasksCard.vue +373 -0
  89. package/src/components/CnTasksCard/index.js +1 -0
  90. package/src/components/CnTileWidget/CnTileWidget.vue +159 -0
  91. package/src/components/CnTileWidget/index.js +1 -0
  92. package/src/components/CnTimelineStages/CnTimelineStages.vue +292 -0
  93. package/src/components/CnTimelineStages/index.js +1 -0
  94. package/src/components/CnUserActionMenu/CnUserActionMenu.vue +435 -0
  95. package/src/components/CnUserActionMenu/index.js +1 -0
  96. package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +312 -312
  97. package/src/components/CnVersionInfoCard/index.js +1 -1
  98. package/src/components/CnWidgetRenderer/CnWidgetRenderer.vue +180 -0
  99. package/src/components/CnWidgetRenderer/index.js +1 -0
  100. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +211 -0
  101. package/src/components/CnWidgetWrapper/index.js +1 -0
  102. package/src/components/index.js +43 -29
  103. package/src/composables/index.js +4 -3
  104. package/src/composables/useDashboardView.js +240 -0
  105. package/src/composables/useDetailView.js +289 -132
  106. package/src/composables/useListView.js +363 -362
  107. package/src/composables/useSubResource.js +142 -142
  108. package/src/constants/metadata.js +30 -30
  109. package/src/css/CnSchemaFormDialog.css +546 -0
  110. package/src/css/__sample_nextcloud_tokens.css +110 -0
  111. package/src/css/actions-bar.css +48 -48
  112. package/src/css/badge.css +51 -51
  113. package/src/css/card.css +128 -128
  114. package/src/css/dashboard.css +70 -0
  115. package/src/css/detail-page.css +168 -0
  116. package/src/css/detail.css +68 -68
  117. package/src/css/index-page.css +44 -32
  118. package/src/css/index-sidebar.css +193 -187
  119. package/src/css/index.css +16 -12
  120. package/src/css/layout.css +90 -90
  121. package/src/css/page-header.css +33 -33
  122. package/src/css/pagination.css +72 -72
  123. package/src/css/table.css +142 -142
  124. package/src/css/timeline-stages.css +218 -0
  125. package/src/css/utilities.css +46 -46
  126. package/src/index.js +72 -53
  127. package/src/store/createSubResourcePlugin.js +135 -135
  128. package/src/store/index.js +3 -3
  129. package/src/store/plugins/auditTrails.js +17 -17
  130. package/src/store/plugins/files.js +250 -186
  131. package/src/store/plugins/index.js +7 -5
  132. package/src/store/plugins/lifecycle.js +180 -180
  133. package/src/store/plugins/relations.js +68 -68
  134. package/src/store/plugins/search.js +372 -0
  135. package/src/store/plugins/selection.js +104 -0
  136. package/src/store/useObjectStore.js +829 -686
  137. package/src/types/auditTrail.d.ts +32 -32
  138. package/src/types/file.d.ts +23 -23
  139. package/src/types/index.d.ts +35 -35
  140. package/src/types/notification.d.ts +36 -36
  141. package/src/types/object.d.ts +40 -40
  142. package/src/types/organisation.d.ts +41 -41
  143. package/src/types/register.d.ts +25 -25
  144. package/src/types/schema.d.ts +39 -39
  145. package/src/types/shared.d.ts +79 -79
  146. package/src/types/source.d.ts +14 -14
  147. package/src/types/task.d.ts +31 -31
  148. package/src/utils/errors.js +96 -96
  149. package/src/utils/headers.js +68 -50
  150. package/src/utils/id.js +13 -0
  151. package/src/utils/index.js +3 -3
  152. package/src/utils/schema.js +422 -419
@@ -0,0 +1 @@
1
+ export { default as CnObjectSidebar } from './CnObjectSidebar.vue'
@@ -1,57 +1,57 @@
1
- <template>
2
- <div class="cn-page-header">
3
- <div v-if="icon || $slots.icon" class="cn-page-header__icon">
4
- <slot name="icon">
5
- <CnIcon :name="icon" :size="iconSize" />
6
- </slot>
7
- </div>
8
- <div class="cn-page-header__text">
9
- <h1 class="cn-page-header__title">{{ title }}</h1>
10
- <p v-if="description" class="cn-page-header__description">{{ description }}</p>
11
- </div>
12
- <slot name="extra" />
13
- </div>
14
- </template>
15
-
16
- <script>
17
- import { CnIcon } from '../CnIcon/index.js'
18
-
19
- /**
20
- * CnPageHeader — Reusable page header with optional icon, title, and description.
21
- *
22
- * @example
23
- * <CnPageHeader title="Clients" description="Manage your clients" icon="AccountGroup" />
24
- */
25
- export default {
26
- name: 'CnPageHeader',
27
-
28
- components: {
29
- CnIcon,
30
- },
31
-
32
- props: {
33
- /** Page title text */
34
- title: {
35
- type: String,
36
- required: true,
37
- },
38
- /** Optional description shown below the title */
39
- description: {
40
- type: String,
41
- default: '',
42
- },
43
- /** Optional MDI icon name (rendered via CnIcon) */
44
- icon: {
45
- type: String,
46
- default: '',
47
- },
48
- /** Icon size in pixels */
49
- iconSize: {
50
- type: Number,
51
- default: 28,
52
- },
53
- },
54
- }
55
- </script>
56
-
57
- <!-- Styles in css/page-header.css -->
1
+ <template>
2
+ <div class="cn-page-header">
3
+ <div v-if="icon || $slots.icon" class="cn-page-header__icon">
4
+ <slot name="icon">
5
+ <CnIcon :name="icon" :size="iconSize" />
6
+ </slot>
7
+ </div>
8
+ <div class="cn-page-header__text">
9
+ <h1 class="cn-page-header__title">{{ title }}</h1>
10
+ <p v-if="description" class="cn-page-header__description">{{ description }}</p>
11
+ </div>
12
+ <slot name="extra" />
13
+ </div>
14
+ </template>
15
+
16
+ <script>
17
+ import { CnIcon } from '../CnIcon/index.js'
18
+
19
+ /**
20
+ * CnPageHeader — Reusable page header with optional icon, title, and description.
21
+ *
22
+ * @example
23
+ * <CnPageHeader title="Clients" description="Manage your clients" icon="AccountGroup" />
24
+ */
25
+ export default {
26
+ name: 'CnPageHeader',
27
+
28
+ components: {
29
+ CnIcon,
30
+ },
31
+
32
+ props: {
33
+ /** Page title text */
34
+ title: {
35
+ type: String,
36
+ required: true,
37
+ },
38
+ /** Optional description shown below the title */
39
+ description: {
40
+ type: String,
41
+ default: '',
42
+ },
43
+ /** Optional MDI icon name (rendered via CnIcon) */
44
+ icon: {
45
+ type: String,
46
+ default: '',
47
+ },
48
+ /** Icon size in pixels */
49
+ iconSize: {
50
+ type: Number,
51
+ default: 28,
52
+ },
53
+ },
54
+ }
55
+ </script>
56
+
57
+ <!-- Styles in css/page-header.css -->
@@ -1 +1 @@
1
- export { default as CnPageHeader } from './CnPageHeader.vue'
1
+ export { default as CnPageHeader } from './CnPageHeader.vue'
@@ -1,252 +1,252 @@
1
- <template>
2
- <div v-if="totalPages > 1 || totalItems > minItemsToShow" class="cn-pagination">
3
- <!-- Page info -->
4
- <div class="cn-pagination__info">
5
- <span class="cn-pagination__page-info">
6
- {{ pageInfoText }}
7
- </span>
8
- </div>
9
-
10
- <!-- Page navigation -->
11
- <div v-if="totalPages > 1" class="cn-pagination__nav">
12
- <NcButton
13
- :disabled="currentPage === 1"
14
- @click="changePage(1)">
15
- {{ firstLabel }}
16
- </NcButton>
17
-
18
- <NcButton
19
- :disabled="currentPage === 1"
20
- @click="changePage(currentPage - 1)">
21
- {{ previousLabel }}
22
- </NcButton>
23
-
24
- <div class="cn-pagination__numbers">
25
- <template v-for="page in visiblePages">
26
- <span v-if="page === '...'" :key="'ellipsis-' + page" class="cn-pagination__ellipsis">...</span>
27
- <NcButton
28
- v-else
29
- :key="page"
30
- :type="page === currentPage ? 'primary' : 'secondary'"
31
- :disabled="page === currentPage"
32
- @click="changePage(page)">
33
- {{ page }}
34
- </NcButton>
35
- </template>
36
- </div>
37
-
38
- <NcButton
39
- :disabled="currentPage === totalPages"
40
- @click="changePage(currentPage + 1)">
41
- {{ nextLabel }}
42
- </NcButton>
43
-
44
- <NcButton
45
- :disabled="currentPage === totalPages"
46
- @click="changePage(totalPages)">
47
- {{ lastLabel }}
48
- </NcButton>
49
- </div>
50
-
51
- <!-- Page size selector -->
52
- <div class="cn-pagination__page-size">
53
- <label :for="pageSizeId">{{ itemsPerPageLabel }}</label>
54
- <NcSelect
55
- :input-id="pageSizeId"
56
- class="cn-pagination__page-size-select"
57
- :value="currentPageSizeOption"
58
- :options="pageSizeOptions"
59
- :clearable="false"
60
- :input-label="itemsPerPageLabel"
61
- @option:selected="changePageSize" />
62
- </div>
63
- </div>
64
- </template>
65
-
66
- <script>
67
- import { NcButton, NcSelect } from '@nextcloud/vue'
68
-
69
- /**
70
- * CnPagination — Full pagination with page numbers, navigation, and page size selector.
71
- *
72
- * Extracted from OpenRegister's PaginationComponent. Zero store dependencies.
73
- * Supports First/Previous/Next/Last buttons, smart page number display with
74
- * ellipsis, and configurable page size.
75
- *
76
- * NL Design tokens used:
77
- * - Inherits from cn-pagination CSS class (see css/pagination.css)
78
- *
79
- * @example
80
- * <CnPagination
81
- * :current-page="page"
82
- * :total-pages="totalPages"
83
- * :total-items="totalItems"
84
- * :current-page-size="limit"
85
- * @page-changed="onPageChange"
86
- * @page-size-changed="onPageSizeChange" />
87
- */
88
- export default {
89
- name: 'CnPagination',
90
-
91
- components: {
92
- NcButton,
93
- NcSelect,
94
- },
95
-
96
- props: {
97
- /** Current page number (1-based) */
98
- currentPage: {
99
- type: Number,
100
- default: 1,
101
- },
102
- /** Total number of pages */
103
- totalPages: {
104
- type: Number,
105
- default: 1,
106
- },
107
- /** Total number of items across all pages */
108
- totalItems: {
109
- type: Number,
110
- default: 0,
111
- },
112
- /** Current items per page */
113
- currentPageSize: {
114
- type: Number,
115
- default: 20,
116
- },
117
- /** Available page size options */
118
- pageSizeOptions: {
119
- type: Array,
120
- default: () => [
121
- { value: 10, label: '10' },
122
- { value: 20, label: '20' },
123
- { value: 50, label: '50' },
124
- { value: 100, label: '100' },
125
- { value: 250, label: '250' },
126
- { value: 500, label: '500' },
127
- { value: 1000, label: '1000' },
128
- ],
129
- },
130
- /** Minimum items before pagination is shown */
131
- minItemsToShow: {
132
- type: Number,
133
- default: 10,
134
- },
135
- /** Label for "First" button */
136
- firstLabel: {
137
- type: String,
138
- default: 'First',
139
- },
140
- /** Label for "Previous" button */
141
- previousLabel: {
142
- type: String,
143
- default: 'Previous',
144
- },
145
- /** Label for "Next" button */
146
- nextLabel: {
147
- type: String,
148
- default: 'Next',
149
- },
150
- /** Label for "Last" button */
151
- lastLabel: {
152
- type: String,
153
- default: 'Last',
154
- },
155
- /** Label for "Items per page:" */
156
- itemsPerPageLabel: {
157
- type: String,
158
- default: 'Items per page:',
159
- },
160
- /**
161
- * Page info format string. Use {current} and {total} as placeholders.
162
- * @example "Page {current} of {total}"
163
- */
164
- pageInfoFormat: {
165
- type: String,
166
- default: 'Page {current} of {total}',
167
- },
168
- },
169
-
170
- computed: {
171
- pageSizeId() {
172
- return 'cn-page-size-' + this._uid
173
- },
174
-
175
- currentPageSizeOption() {
176
- return this.pageSizeOptions.find(
177
- (option) => option.value === this.currentPageSize,
178
- ) || this.pageSizeOptions[1]
179
- },
180
-
181
- pageInfoText() {
182
- return this.pageInfoFormat
183
- .replace('{current}', this.currentPage)
184
- .replace('{total}', this.totalPages)
185
- },
186
-
187
- /**
188
- * Calculate visible page numbers with ellipsis for large page counts.
189
- * Shows up to 7 page numbers at a time.
190
- */
191
- visiblePages() {
192
- const current = this.currentPage
193
- const total = this.totalPages
194
- const pages = []
195
-
196
- if (total <= 7) {
197
- for (let i = 1; i <= total; i++) {
198
- pages.push(i)
199
- }
200
- } else {
201
- pages.push(1)
202
-
203
- if (current <= 4) {
204
- for (let i = 2; i <= 5; i++) {
205
- pages.push(i)
206
- }
207
- pages.push('...')
208
- pages.push(total)
209
- } else if (current >= total - 3) {
210
- pages.push('...')
211
- for (let i = total - 4; i <= total; i++) {
212
- pages.push(i)
213
- }
214
- } else {
215
- pages.push('...')
216
- for (let i = current - 1; i <= current + 1; i++) {
217
- pages.push(i)
218
- }
219
- pages.push('...')
220
- pages.push(total)
221
- }
222
- }
223
-
224
- return pages
225
- },
226
- },
227
-
228
- methods: {
229
- /**
230
- * Navigate to a specific page.
231
- * @param {number} page Target page number
232
- */
233
- changePage(page) {
234
- if (page !== this.currentPage && page >= 1 && page <= this.totalPages) {
235
- /** @event page-changed Emitted when page changes. Payload: new page number. */
236
- this.$emit('page-changed', page)
237
- }
238
- },
239
-
240
- /**
241
- * Change the page size.
242
- * @param {object} option Selected page size option { value, label }
243
- */
244
- changePageSize(option) {
245
- if (option.value !== this.currentPageSize) {
246
- /** @event page-size-changed Emitted when page size changes. Payload: new page size. */
247
- this.$emit('page-size-changed', option.value)
248
- }
249
- },
250
- },
251
- }
252
- </script>
1
+ <template>
2
+ <div v-if="totalPages > 1 || totalItems > minItemsToShow" class="cn-pagination">
3
+ <!-- Page info -->
4
+ <div class="cn-pagination__info">
5
+ <span class="cn-pagination__page-info">
6
+ {{ pageInfoText }}
7
+ </span>
8
+ </div>
9
+
10
+ <!-- Page navigation -->
11
+ <div v-if="totalPages > 1" class="cn-pagination__nav">
12
+ <NcButton
13
+ :disabled="currentPage === 1"
14
+ @click="changePage(1)">
15
+ {{ firstLabel }}
16
+ </NcButton>
17
+
18
+ <NcButton
19
+ :disabled="currentPage === 1"
20
+ @click="changePage(currentPage - 1)">
21
+ {{ previousLabel }}
22
+ </NcButton>
23
+
24
+ <div class="cn-pagination__numbers">
25
+ <template v-for="page in visiblePages">
26
+ <span v-if="page === '...'" :key="'ellipsis-' + page" class="cn-pagination__ellipsis">...</span>
27
+ <NcButton
28
+ v-else
29
+ :key="page"
30
+ :type="page === currentPage ? 'primary' : 'secondary'"
31
+ :disabled="page === currentPage"
32
+ @click="changePage(page)">
33
+ {{ page }}
34
+ </NcButton>
35
+ </template>
36
+ </div>
37
+
38
+ <NcButton
39
+ :disabled="currentPage === totalPages"
40
+ @click="changePage(currentPage + 1)">
41
+ {{ nextLabel }}
42
+ </NcButton>
43
+
44
+ <NcButton
45
+ :disabled="currentPage === totalPages"
46
+ @click="changePage(totalPages)">
47
+ {{ lastLabel }}
48
+ </NcButton>
49
+ </div>
50
+
51
+ <!-- Page size selector -->
52
+ <div class="cn-pagination__page-size">
53
+ <label :for="pageSizeId">{{ itemsPerPageLabel }}</label>
54
+ <NcSelect
55
+ :input-id="pageSizeId"
56
+ class="cn-pagination__page-size-select"
57
+ :value="currentPageSizeOption"
58
+ :options="pageSizeOptions"
59
+ :clearable="false"
60
+ :input-label="itemsPerPageLabel"
61
+ @option:selected="changePageSize" />
62
+ </div>
63
+ </div>
64
+ </template>
65
+
66
+ <script>
67
+ import { NcButton, NcSelect } from '@nextcloud/vue'
68
+
69
+ /**
70
+ * CnPagination — Full pagination with page numbers, navigation, and page size selector.
71
+ *
72
+ * Extracted from OpenRegister's PaginationComponent. Zero store dependencies.
73
+ * Supports First/Previous/Next/Last buttons, smart page number display with
74
+ * ellipsis, and configurable page size.
75
+ *
76
+ * NL Design tokens used:
77
+ * - Inherits from cn-pagination CSS class (see css/pagination.css)
78
+ *
79
+ * @example
80
+ * <CnPagination
81
+ * :current-page="page"
82
+ * :total-pages="totalPages"
83
+ * :total-items="totalItems"
84
+ * :current-page-size="limit"
85
+ * @page-changed="onPageChange"
86
+ * @page-size-changed="onPageSizeChange" />
87
+ */
88
+ export default {
89
+ name: 'CnPagination',
90
+
91
+ components: {
92
+ NcButton,
93
+ NcSelect,
94
+ },
95
+
96
+ props: {
97
+ /** Current page number (1-based) */
98
+ currentPage: {
99
+ type: Number,
100
+ default: 1,
101
+ },
102
+ /** Total number of pages */
103
+ totalPages: {
104
+ type: Number,
105
+ default: 1,
106
+ },
107
+ /** Total number of items across all pages */
108
+ totalItems: {
109
+ type: Number,
110
+ default: 0,
111
+ },
112
+ /** Current items per page */
113
+ currentPageSize: {
114
+ type: Number,
115
+ default: 20,
116
+ },
117
+ /** Available page size options */
118
+ pageSizeOptions: {
119
+ type: Array,
120
+ default: () => [
121
+ { value: 10, label: '10' },
122
+ { value: 20, label: '20' },
123
+ { value: 50, label: '50' },
124
+ { value: 100, label: '100' },
125
+ { value: 250, label: '250' },
126
+ { value: 500, label: '500' },
127
+ { value: 1000, label: '1000' },
128
+ ],
129
+ },
130
+ /** Minimum items before pagination is shown */
131
+ minItemsToShow: {
132
+ type: Number,
133
+ default: 10,
134
+ },
135
+ /** Label for "First" button */
136
+ firstLabel: {
137
+ type: String,
138
+ default: 'First',
139
+ },
140
+ /** Label for "Previous" button */
141
+ previousLabel: {
142
+ type: String,
143
+ default: 'Previous',
144
+ },
145
+ /** Label for "Next" button */
146
+ nextLabel: {
147
+ type: String,
148
+ default: 'Next',
149
+ },
150
+ /** Label for "Last" button */
151
+ lastLabel: {
152
+ type: String,
153
+ default: 'Last',
154
+ },
155
+ /** Label for "Items per page:" */
156
+ itemsPerPageLabel: {
157
+ type: String,
158
+ default: 'Items per page:',
159
+ },
160
+ /**
161
+ * Page info format string. Use {current} and {total} as placeholders.
162
+ * @example "Page {current} of {total}"
163
+ */
164
+ pageInfoFormat: {
165
+ type: String,
166
+ default: 'Page {current} of {total}',
167
+ },
168
+ },
169
+
170
+ computed: {
171
+ pageSizeId() {
172
+ return 'cn-page-size-' + this._uid
173
+ },
174
+
175
+ currentPageSizeOption() {
176
+ return this.pageSizeOptions.find(
177
+ (option) => option.value === this.currentPageSize,
178
+ ) || this.pageSizeOptions[1]
179
+ },
180
+
181
+ pageInfoText() {
182
+ return this.pageInfoFormat
183
+ .replace('{current}', this.currentPage)
184
+ .replace('{total}', this.totalPages)
185
+ },
186
+
187
+ /**
188
+ * Calculate visible page numbers with ellipsis for large page counts.
189
+ * Shows up to 7 page numbers at a time.
190
+ */
191
+ visiblePages() {
192
+ const current = this.currentPage
193
+ const total = this.totalPages
194
+ const pages = []
195
+
196
+ if (total <= 7) {
197
+ for (let i = 1; i <= total; i++) {
198
+ pages.push(i)
199
+ }
200
+ } else {
201
+ pages.push(1)
202
+
203
+ if (current <= 4) {
204
+ for (let i = 2; i <= 5; i++) {
205
+ pages.push(i)
206
+ }
207
+ pages.push('...')
208
+ pages.push(total)
209
+ } else if (current >= total - 3) {
210
+ pages.push('...')
211
+ for (let i = total - 4; i <= total; i++) {
212
+ pages.push(i)
213
+ }
214
+ } else {
215
+ pages.push('...')
216
+ for (let i = current - 1; i <= current + 1; i++) {
217
+ pages.push(i)
218
+ }
219
+ pages.push('...')
220
+ pages.push(total)
221
+ }
222
+ }
223
+
224
+ return pages
225
+ },
226
+ },
227
+
228
+ methods: {
229
+ /**
230
+ * Navigate to a specific page.
231
+ * @param {number} page Target page number
232
+ */
233
+ changePage(page) {
234
+ if (page !== this.currentPage && page >= 1 && page <= this.totalPages) {
235
+ /** @event page-changed Emitted when page changes. Payload: new page number. */
236
+ this.$emit('page-changed', page)
237
+ }
238
+ },
239
+
240
+ /**
241
+ * Change the page size.
242
+ * @param {object} option Selected page size option { value, label }
243
+ */
244
+ changePageSize(option) {
245
+ if (option.value !== this.currentPageSize) {
246
+ /** @event page-size-changed Emitted when page size changes. Payload: new page size. */
247
+ this.$emit('page-size-changed', option.value)
248
+ }
249
+ },
250
+ },
251
+ }
252
+ </script>
@@ -1 +1 @@
1
- export { default as CnPagination } from './CnPagination.vue'
1
+ export { default as CnPagination } from './CnPagination.vue'