@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.
Files changed (71) hide show
  1. package/dist/nextcloud-vue.cjs +67614 -0
  2. package/dist/nextcloud-vue.cjs.js +9559 -8983
  3. package/dist/nextcloud-vue.cjs.js.map +1 -1
  4. package/dist/nextcloud-vue.cjs.map +1 -0
  5. package/dist/nextcloud-vue.css +1231 -1231
  6. package/dist/nextcloud-vue.esm.js +9559 -8983
  7. package/dist/nextcloud-vue.esm.js.map +1 -1
  8. package/package.json +14 -5
  9. package/src/components/CnActionsBar/CnActionsBar.vue +235 -235
  10. package/src/components/CnAdvancedFormDialog/CnAdvancedFormDialog.vue +579 -579
  11. package/src/components/CnAdvancedFormDialog/CnDataTab.vue +217 -217
  12. package/src/components/CnAdvancedFormDialog/CnMetadataTab.vue +121 -121
  13. package/src/components/CnAdvancedFormDialog/CnPropertiesTab.vue +418 -418
  14. package/src/components/CnAdvancedFormDialog/CnPropertyValueCell.vue +247 -247
  15. package/src/components/CnCardGrid/CnCardGrid.vue +152 -152
  16. package/src/components/CnCellRenderer/CnCellRenderer.vue +132 -132
  17. package/src/components/CnChartWidget/CnChartWidget.vue +320 -320
  18. package/src/components/CnConfigurationCard/CnConfigurationCard.vue +77 -77
  19. package/src/components/CnCopyDialog/CnCopyDialog.vue +250 -250
  20. package/src/components/CnDashboardGrid/CnDashboardGrid.vue +225 -225
  21. package/src/components/CnDashboardPage/CnDashboardPage.vue +390 -390
  22. package/src/components/CnDataTable/CnDataTable.vue +349 -349
  23. package/src/components/CnDeleteDialog/CnDeleteDialog.vue +170 -170
  24. package/src/components/CnDetailCard/CnDetailCard.vue +214 -214
  25. package/src/components/CnDetailPage/CnDetailPage.vue +285 -281
  26. package/src/components/CnFacetSidebar/CnFacetSidebar.vue +231 -231
  27. package/src/components/CnFilterBar/CnFilterBar.vue +152 -152
  28. package/src/components/CnFormDialog/CnFormDialog.vue +302 -11
  29. package/src/components/CnIcon/CnIcon.vue +89 -89
  30. package/src/components/CnIndexPage/CnIndexPage.vue +884 -874
  31. package/src/components/CnIndexSidebar/CnIndexSidebar.vue +503 -503
  32. package/src/components/CnItemCard/CnItemCard.vue +132 -132
  33. package/src/components/CnKpiGrid/CnKpiGrid.vue +89 -89
  34. package/src/components/CnMassActionBar/CnMassActionBar.vue +160 -160
  35. package/src/components/CnMassCopyDialog/CnMassCopyDialog.vue +320 -320
  36. package/src/components/CnMassDeleteDialog/CnMassDeleteDialog.vue +238 -238
  37. package/src/components/CnMassExportDialog/CnMassExportDialog.vue +190 -190
  38. package/src/components/CnMassImportDialog/CnMassImportDialog.vue +491 -491
  39. package/src/components/CnNoteCard/CnNoteCard.vue +149 -149
  40. package/src/components/CnNotesCard/CnNotesCard.vue +413 -413
  41. package/src/components/CnObjectCard/CnObjectCard.vue +292 -292
  42. package/src/components/CnObjectCard/eslint-setup.md +235 -0
  43. package/src/components/CnObjectCard/package.json-or.json +132 -0
  44. package/src/components/CnObjectSidebar/CnObjectSidebar.vue +876 -876
  45. package/src/components/CnPageHeader/CnPageHeader.vue +57 -57
  46. package/src/components/CnPagination/CnPagination.vue +252 -252
  47. package/src/components/CnRegisterMapping/CnRegisterMapping.vue +792 -792
  48. package/src/components/CnRowActions/CnRowActions.vue +95 -73
  49. package/src/components/CnSchemaFormDialog/CnSchemaConfigurationTab.vue +226 -226
  50. package/src/components/CnSchemaFormDialog/CnSchemaFormDialog.vue +787 -787
  51. package/src/components/CnSchemaFormDialog/CnSchemaPropertiesTab.vue +305 -305
  52. package/src/components/CnSchemaFormDialog/CnSchemaPropertyActions.vue +1398 -1398
  53. package/src/components/CnSchemaFormDialog/CnSchemaSecurityTab.vue +236 -236
  54. package/src/components/CnSettingsCard/CnSettingsCard.vue +92 -92
  55. package/src/components/CnSettingsSection/CnSettingsSection.vue +266 -266
  56. package/src/components/CnStatsBlock/CnStatsBlock.vue +420 -420
  57. package/src/components/CnStatusBadge/CnStatusBadge.vue +77 -77
  58. package/src/components/CnTabbedFormDialog/CnTabbedFormDialog.vue +540 -540
  59. package/src/components/CnTasksCard/CnTasksCard.vue +373 -373
  60. package/src/components/CnTileWidget/CnTileWidget.vue +159 -159
  61. package/src/components/CnTimelineStages/CnTimelineStages.vue +292 -292
  62. package/src/components/CnUserActionMenu/CnUserActionMenu.vue +435 -435
  63. package/src/components/CnVersionInfoCard/CnVersionInfoCard.vue +312 -312
  64. package/src/components/CnWidgetRenderer/CnWidgetRenderer.vue +180 -180
  65. package/src/components/CnWidgetWrapper/CnWidgetWrapper.vue +211 -211
  66. package/src/index.js +1 -1
  67. package/src/types/notification.d.ts +13 -13
  68. package/src/types/organisation.d.ts +15 -15
  69. package/src/types/schema.d.ts +13 -13
  70. package/src/types/task.d.ts +6 -6
  71. package/src/utils/headers.js +5 -3
@@ -1,77 +1,77 @@
1
- <template>
2
- <div class="cn-card">
3
- <div class="cn-card-header">
4
- <h3>
5
- <slot name="icon" />
6
- {{ title }}
7
- </h3>
8
- <div class="cn-card-header__actions">
9
- <slot name="actions" />
10
- </div>
11
- </div>
12
-
13
- <!-- Status badges -->
14
- <div v-if="$slots.status" class="cn-config-card__status">
15
- <slot name="status" />
16
- </div>
17
-
18
- <!-- Main content -->
19
- <div class="cn-config-card__content">
20
- <slot />
21
- </div>
22
-
23
- <!-- Footer -->
24
- <div v-if="$slots.footer" class="cn-config-card__footer">
25
- <slot name="footer" />
26
- </div>
27
- </div>
28
- </template>
29
-
30
- <script>
31
- /**
32
- * CnConfigurationCard — Configuration card with title, actions, status, and content.
33
- *
34
- * Decoupled from OpenRegister's ConfigurationCard. All data is provided via
35
- * props and slots — no store dependencies. Consumer wraps this and handles
36
- * navigation/store logic.
37
- *
38
- * @example
39
- * <CnConfigurationCard title="Database Configuration">
40
- * <template #actions>
41
- * <NcActions><NcActionButton @click="edit">Edit</NcActionButton></NcActions>
42
- * </template>
43
- * <template #status>
44
- * <CnStatusBadge label="Connected" variant="success" />
45
- * </template>
46
- * <p>PostgreSQL 15.2 on localhost:5432</p>
47
- * </CnConfigurationCard>
48
- */
49
- export default {
50
- name: 'CnConfigurationCard',
51
-
52
- props: {
53
- /** Card title */
54
- title: {
55
- type: String,
56
- default: '',
57
- },
58
- },
59
- }
60
- </script>
61
-
62
- <style scoped>
63
- .cn-config-card__status {
64
- display: flex;
65
- gap: 8px;
66
- margin-bottom: 12px;
67
- }
68
-
69
- .cn-config-card__content {
70
- margin-bottom: 8px;
71
- }
72
-
73
- .cn-config-card__footer {
74
- padding-top: 12px;
75
- border-top: 1px solid var(--color-border);
76
- }
77
- </style>
1
+ <template>
2
+ <div class="cn-card">
3
+ <div class="cn-card-header">
4
+ <h3>
5
+ <slot name="icon" />
6
+ {{ title }}
7
+ </h3>
8
+ <div class="cn-card-header__actions">
9
+ <slot name="actions" />
10
+ </div>
11
+ </div>
12
+
13
+ <!-- Status badges -->
14
+ <div v-if="$slots.status" class="cn-config-card__status">
15
+ <slot name="status" />
16
+ </div>
17
+
18
+ <!-- Main content -->
19
+ <div class="cn-config-card__content">
20
+ <slot />
21
+ </div>
22
+
23
+ <!-- Footer -->
24
+ <div v-if="$slots.footer" class="cn-config-card__footer">
25
+ <slot name="footer" />
26
+ </div>
27
+ </div>
28
+ </template>
29
+
30
+ <script>
31
+ /**
32
+ * CnConfigurationCard — Configuration card with title, actions, status, and content.
33
+ *
34
+ * Decoupled from OpenRegister's ConfigurationCard. All data is provided via
35
+ * props and slots — no store dependencies. Consumer wraps this and handles
36
+ * navigation/store logic.
37
+ *
38
+ * @example
39
+ * <CnConfigurationCard title="Database Configuration">
40
+ * <template #actions>
41
+ * <NcActions><NcActionButton @click="edit">Edit</NcActionButton></NcActions>
42
+ * </template>
43
+ * <template #status>
44
+ * <CnStatusBadge label="Connected" variant="success" />
45
+ * </template>
46
+ * <p>PostgreSQL 15.2 on localhost:5432</p>
47
+ * </CnConfigurationCard>
48
+ */
49
+ export default {
50
+ name: 'CnConfigurationCard',
51
+
52
+ props: {
53
+ /** Card title */
54
+ title: {
55
+ type: String,
56
+ default: '',
57
+ },
58
+ },
59
+ }
60
+ </script>
61
+
62
+ <style scoped>
63
+ .cn-config-card__status {
64
+ display: flex;
65
+ gap: 8px;
66
+ margin-bottom: 12px;
67
+ }
68
+
69
+ .cn-config-card__content {
70
+ margin-bottom: 8px;
71
+ }
72
+
73
+ .cn-config-card__footer {
74
+ padding-top: 12px;
75
+ border-top: 1px solid var(--color-border);
76
+ }
77
+ </style>
@@ -1,250 +1,250 @@
1
- <template>
2
- <NcDialog
3
- :name="dialogTitle"
4
- size="small"
5
- :can-close="!loading"
6
- @closing="$emit('close')">
7
- <!-- Result phase -->
8
- <div v-if="result !== null" class="cn-copy__result">
9
- <NcNoteCard v-if="result.success" type="success">
10
- {{ successText }}
11
- </NcNoteCard>
12
- <NcNoteCard v-if="result.error" type="error">
13
- {{ result.error }}
14
- </NcNoteCard>
15
- </div>
16
-
17
- <!-- Form phase -->
18
- <div v-else class="cn-copy__form">
19
- <div class="cn-copy__pattern">
20
- <label for="cn-copy-pattern">{{ patternLabel }}</label>
21
- <NcSelect
22
- input-id="cn-copy-pattern"
23
- :options="patternOptions"
24
- :value="selectedPattern"
25
- :clearable="false"
26
- @input="selectedPattern = $event" />
27
- </div>
28
-
29
- <div class="cn-copy__preview">
30
- <div class="cn-copy__preview-row">
31
- <span class="cn-copy__preview-original">{{ itemName }}</span>
32
- <span class="cn-copy__preview-arrow">&rarr;</span>
33
- <span class="cn-copy__preview-new">{{ newName }}</span>
34
- </div>
35
- </div>
36
- </div>
37
-
38
- <template #actions>
39
- <NcButton @click="$emit('close')">
40
- {{ result !== null ? closeLabel : cancelLabel }}
41
- </NcButton>
42
- <NcButton
43
- v-if="result === null"
44
- type="primary"
45
- :disabled="loading"
46
- @click="executeCopy">
47
- <template #icon>
48
- <NcLoadingIcon v-if="loading" :size="20" />
49
- <ContentCopy v-else :size="20" />
50
- </template>
51
- {{ confirmLabel }}
52
- </NcButton>
53
- </template>
54
- </NcDialog>
55
- </template>
56
-
57
- <script>
58
- import { NcDialog, NcButton, NcNoteCard, NcLoadingIcon, NcSelect } from '@nextcloud/vue'
59
- import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'
60
-
61
- /**
62
- * CnCopyDialog — Single-item copy confirmation dialog with naming pattern.
63
- *
64
- * Two-phase UI: form (with name preview) then result. The dialog does NOT
65
- * perform the copy itself — it emits a `confirm` event with the item ID
66
- * and the new name. The parent performs the actual API call and calls
67
- * `setResult()` via a ref.
68
- *
69
- * @example
70
- * <CnCopyDialog
71
- * v-if="showCopyDialog"
72
- * ref="copyDialog"
73
- * :item="itemToCopy"
74
- * @confirm="onCopyConfirm"
75
- * @close="showCopyDialog = false" />
76
- *
77
- * // In methods:
78
- * async onCopyConfirm({ id, newName }) {
79
- * try {
80
- * await store.copyItem(id, { title: newName })
81
- * this.$refs.copyDialog.setResult({ success: true })
82
- * } catch (e) {
83
- * this.$refs.copyDialog.setResult({ error: e.message })
84
- * }
85
- * }
86
- */
87
- export default {
88
- name: 'CnCopyDialog',
89
-
90
- components: {
91
- NcDialog,
92
- NcButton,
93
- NcNoteCard,
94
- NcLoadingIcon,
95
- NcSelect,
96
- ContentCopy,
97
- },
98
-
99
- props: {
100
- /** The item to copy. Must have an `id` property. */
101
- item: {
102
- type: Object,
103
- required: true,
104
- },
105
- /** Property name used for display (e.g., 'title', 'name') */
106
- nameField: {
107
- type: String,
108
- default: 'title',
109
- },
110
- /** Dialog title */
111
- dialogTitle: {
112
- type: String,
113
- default: 'Copy Item',
114
- },
115
- /** Label for the naming pattern selector */
116
- patternLabel: {
117
- type: String,
118
- default: 'Naming pattern',
119
- },
120
- /** Success message */
121
- successText: {
122
- type: String,
123
- default: 'Item successfully copied.',
124
- },
125
- cancelLabel: { type: String, default: 'Cancel' },
126
- closeLabel: { type: String, default: 'Close' },
127
- confirmLabel: { type: String, default: 'Copy' },
128
- },
129
-
130
- data() {
131
- return {
132
- loading: false,
133
- result: null,
134
- closeTimeout: null,
135
- selectedPattern: { id: 'copy-of', label: 'Copy of {name}' },
136
- }
137
- },
138
-
139
- computed: {
140
- itemName() {
141
- return this.item[this.nameField] || this.item.name || this.item.title || this.item.id
142
- },
143
-
144
- patternOptions() {
145
- return [
146
- { id: 'copy-of', label: 'Copy of {name}' },
147
- { id: 'name-copy', label: '{name} - Copy' },
148
- { id: 'name-parens', label: '{name} (Copy)' },
149
- ]
150
- },
151
-
152
- newName() {
153
- return this.applyPattern(this.itemName, this.selectedPattern.id)
154
- },
155
- },
156
-
157
- beforeDestroy() {
158
- if (this.closeTimeout) clearTimeout(this.closeTimeout)
159
- },
160
-
161
- /**
162
- * @event confirm Emitted when the user confirms copying. Payload: `{ id, newName }`.
163
- * @event close Emitted when the dialog should be closed (cancel, close button, or auto-close after success).
164
- */
165
-
166
- methods: {
167
- applyPattern(name, patternId) {
168
- switch (patternId) {
169
- case 'copy-of':
170
- return `Copy of ${name}`
171
- case 'name-copy':
172
- return `${name} - Copy`
173
- case 'name-parens':
174
- return `${name} (Copy)`
175
- default:
176
- return `Copy of ${name}`
177
- }
178
- },
179
-
180
- executeCopy() {
181
- this.loading = true
182
- this.$emit('confirm', {
183
- id: this.item.id,
184
- newName: this.newName,
185
- })
186
- },
187
-
188
- /**
189
- * Set the result of the copy operation. Call this from the parent
190
- * after the API call completes.
191
- *
192
- * @param {{ success?: boolean, error?: string }} resultData
193
- * @public
194
- */
195
- setResult(resultData) {
196
- this.loading = false
197
- this.result = resultData
198
- if (resultData.success) {
199
- this.closeTimeout = setTimeout(() => {
200
- this.$emit('close')
201
- }, 2000)
202
- }
203
- },
204
- },
205
- }
206
- </script>
207
-
208
- <style scoped>
209
- .cn-copy__pattern {
210
- margin-bottom: 16px;
211
- }
212
-
213
- .cn-copy__pattern label {
214
- display: block;
215
- font-weight: 600;
216
- margin-bottom: 4px;
217
- }
218
-
219
- .cn-copy__preview {
220
- margin-top: 12px;
221
- }
222
-
223
- .cn-copy__preview-row {
224
- display: flex;
225
- align-items: center;
226
- gap: 8px;
227
- padding: 8px 12px;
228
- background-color: var(--color-background-hover);
229
- border-radius: var(--border-radius);
230
- }
231
-
232
- .cn-copy__preview-original {
233
- color: var(--color-text-maxcontrast);
234
- overflow: hidden;
235
- text-overflow: ellipsis;
236
- white-space: nowrap;
237
- }
238
-
239
- .cn-copy__preview-arrow {
240
- flex-shrink: 0;
241
- color: var(--color-text-maxcontrast);
242
- }
243
-
244
- .cn-copy__preview-new {
245
- font-weight: 500;
246
- overflow: hidden;
247
- text-overflow: ellipsis;
248
- white-space: nowrap;
249
- }
250
- </style>
1
+ <template>
2
+ <NcDialog
3
+ :name="dialogTitle"
4
+ size="small"
5
+ :can-close="!loading"
6
+ @closing="$emit('close')">
7
+ <!-- Result phase -->
8
+ <div v-if="result !== null" class="cn-copy__result">
9
+ <NcNoteCard v-if="result.success" type="success">
10
+ {{ successText }}
11
+ </NcNoteCard>
12
+ <NcNoteCard v-if="result.error" type="error">
13
+ {{ result.error }}
14
+ </NcNoteCard>
15
+ </div>
16
+
17
+ <!-- Form phase -->
18
+ <div v-else class="cn-copy__form">
19
+ <div class="cn-copy__pattern">
20
+ <label for="cn-copy-pattern">{{ patternLabel }}</label>
21
+ <NcSelect
22
+ input-id="cn-copy-pattern"
23
+ :options="patternOptions"
24
+ :value="selectedPattern"
25
+ :clearable="false"
26
+ @input="selectedPattern = $event" />
27
+ </div>
28
+
29
+ <div class="cn-copy__preview">
30
+ <div class="cn-copy__preview-row">
31
+ <span class="cn-copy__preview-original">{{ itemName }}</span>
32
+ <span class="cn-copy__preview-arrow">&rarr;</span>
33
+ <span class="cn-copy__preview-new">{{ newName }}</span>
34
+ </div>
35
+ </div>
36
+ </div>
37
+
38
+ <template #actions>
39
+ <NcButton @click="$emit('close')">
40
+ {{ result !== null ? closeLabel : cancelLabel }}
41
+ </NcButton>
42
+ <NcButton
43
+ v-if="result === null"
44
+ type="primary"
45
+ :disabled="loading"
46
+ @click="executeCopy">
47
+ <template #icon>
48
+ <NcLoadingIcon v-if="loading" :size="20" />
49
+ <ContentCopy v-else :size="20" />
50
+ </template>
51
+ {{ confirmLabel }}
52
+ </NcButton>
53
+ </template>
54
+ </NcDialog>
55
+ </template>
56
+
57
+ <script>
58
+ import { NcDialog, NcButton, NcNoteCard, NcLoadingIcon, NcSelect } from '@nextcloud/vue'
59
+ import ContentCopy from 'vue-material-design-icons/ContentCopy.vue'
60
+
61
+ /**
62
+ * CnCopyDialog — Single-item copy confirmation dialog with naming pattern.
63
+ *
64
+ * Two-phase UI: form (with name preview) then result. The dialog does NOT
65
+ * perform the copy itself — it emits a `confirm` event with the item ID
66
+ * and the new name. The parent performs the actual API call and calls
67
+ * `setResult()` via a ref.
68
+ *
69
+ * @example
70
+ * <CnCopyDialog
71
+ * v-if="showCopyDialog"
72
+ * ref="copyDialog"
73
+ * :item="itemToCopy"
74
+ * @confirm="onCopyConfirm"
75
+ * @close="showCopyDialog = false" />
76
+ *
77
+ * // In methods:
78
+ * async onCopyConfirm({ id, newName }) {
79
+ * try {
80
+ * await store.copyItem(id, { title: newName })
81
+ * this.$refs.copyDialog.setResult({ success: true })
82
+ * } catch (e) {
83
+ * this.$refs.copyDialog.setResult({ error: e.message })
84
+ * }
85
+ * }
86
+ */
87
+ export default {
88
+ name: 'CnCopyDialog',
89
+
90
+ components: {
91
+ NcDialog,
92
+ NcButton,
93
+ NcNoteCard,
94
+ NcLoadingIcon,
95
+ NcSelect,
96
+ ContentCopy,
97
+ },
98
+
99
+ props: {
100
+ /** The item to copy. Must have an `id` property. */
101
+ item: {
102
+ type: Object,
103
+ required: true,
104
+ },
105
+ /** Property name used for display (e.g., 'title', 'name') */
106
+ nameField: {
107
+ type: String,
108
+ default: 'title',
109
+ },
110
+ /** Dialog title */
111
+ dialogTitle: {
112
+ type: String,
113
+ default: 'Copy Item',
114
+ },
115
+ /** Label for the naming pattern selector */
116
+ patternLabel: {
117
+ type: String,
118
+ default: 'Naming pattern',
119
+ },
120
+ /** Success message */
121
+ successText: {
122
+ type: String,
123
+ default: 'Item successfully copied.',
124
+ },
125
+ cancelLabel: { type: String, default: 'Cancel' },
126
+ closeLabel: { type: String, default: 'Close' },
127
+ confirmLabel: { type: String, default: 'Copy' },
128
+ },
129
+
130
+ data() {
131
+ return {
132
+ loading: false,
133
+ result: null,
134
+ closeTimeout: null,
135
+ selectedPattern: { id: 'copy-of', label: 'Copy of {name}' },
136
+ }
137
+ },
138
+
139
+ computed: {
140
+ itemName() {
141
+ return this.item[this.nameField] || this.item.name || this.item.title || this.item.id
142
+ },
143
+
144
+ patternOptions() {
145
+ return [
146
+ { id: 'copy-of', label: 'Copy of {name}' },
147
+ { id: 'name-copy', label: '{name} - Copy' },
148
+ { id: 'name-parens', label: '{name} (Copy)' },
149
+ ]
150
+ },
151
+
152
+ newName() {
153
+ return this.applyPattern(this.itemName, this.selectedPattern.id)
154
+ },
155
+ },
156
+
157
+ beforeDestroy() {
158
+ if (this.closeTimeout) clearTimeout(this.closeTimeout)
159
+ },
160
+
161
+ /**
162
+ * @event confirm Emitted when the user confirms copying. Payload: `{ id, newName }`.
163
+ * @event close Emitted when the dialog should be closed (cancel, close button, or auto-close after success).
164
+ */
165
+
166
+ methods: {
167
+ applyPattern(name, patternId) {
168
+ switch (patternId) {
169
+ case 'copy-of':
170
+ return `Copy of ${name}`
171
+ case 'name-copy':
172
+ return `${name} - Copy`
173
+ case 'name-parens':
174
+ return `${name} (Copy)`
175
+ default:
176
+ return `Copy of ${name}`
177
+ }
178
+ },
179
+
180
+ executeCopy() {
181
+ this.loading = true
182
+ this.$emit('confirm', {
183
+ id: this.item.id,
184
+ newName: this.newName,
185
+ })
186
+ },
187
+
188
+ /**
189
+ * Set the result of the copy operation. Call this from the parent
190
+ * after the API call completes.
191
+ *
192
+ * @param {{ success?: boolean, error?: string }} resultData
193
+ * @public
194
+ */
195
+ setResult(resultData) {
196
+ this.loading = false
197
+ this.result = resultData
198
+ if (resultData.success) {
199
+ this.closeTimeout = setTimeout(() => {
200
+ this.$emit('close')
201
+ }, 2000)
202
+ }
203
+ },
204
+ },
205
+ }
206
+ </script>
207
+
208
+ <style scoped>
209
+ .cn-copy__pattern {
210
+ margin-bottom: 16px;
211
+ }
212
+
213
+ .cn-copy__pattern label {
214
+ display: block;
215
+ font-weight: 600;
216
+ margin-bottom: 4px;
217
+ }
218
+
219
+ .cn-copy__preview {
220
+ margin-top: 12px;
221
+ }
222
+
223
+ .cn-copy__preview-row {
224
+ display: flex;
225
+ align-items: center;
226
+ gap: 8px;
227
+ padding: 8px 12px;
228
+ background-color: var(--color-background-hover);
229
+ border-radius: var(--border-radius);
230
+ }
231
+
232
+ .cn-copy__preview-original {
233
+ color: var(--color-text-maxcontrast);
234
+ overflow: hidden;
235
+ text-overflow: ellipsis;
236
+ white-space: nowrap;
237
+ }
238
+
239
+ .cn-copy__preview-arrow {
240
+ flex-shrink: 0;
241
+ color: var(--color-text-maxcontrast);
242
+ }
243
+
244
+ .cn-copy__preview-new {
245
+ font-weight: 500;
246
+ overflow: hidden;
247
+ text-overflow: ellipsis;
248
+ white-space: nowrap;
249
+ }
250
+ </style>