@raclettejs/core 0.1.31 → 0.1.32-nightly

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 (83) hide show
  1. package/CHANGELOG.md +31 -4
  2. package/dist/cli.js +94 -94
  3. package/dist/cli.js.map +3 -3
  4. package/dist/index.js +3 -3
  5. package/dist/index.js.map +1 -1
  6. package/package.json +4 -4
  7. package/services/backend/.yarn/install-state.gz +0 -0
  8. package/services/backend/dist/core/eventBus/index.js +7 -0
  9. package/services/backend/dist/core/pluginSystem/configGenerator/index.js +346 -0
  10. package/services/backend/dist/core/sockets/index.js +95 -0
  11. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/account/events/index.js +31 -0
  12. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/account/index.js +48 -0
  13. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/account/routes/index.js +15 -0
  14. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/composition/events/index.js +22 -0
  15. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/composition/index.js +51 -0
  16. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/composition/routes/index.js +19 -0
  17. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/interactionLink/events/index.js +22 -0
  18. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/interactionLink/index.js +48 -0
  19. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/interactionLink/routes/index.js +19 -0
  20. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/project/events/index.js +31 -0
  21. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/project/index.js +49 -0
  22. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/project/routes/index.js +16 -0
  23. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/tag/events/index.js +39 -0
  24. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/tag/index.js +50 -0
  25. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/tag/routes/index.js +19 -0
  26. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/user/events/index.js +31 -0
  27. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/user/index.js +51 -0
  28. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/user/routes/index.js +21 -0
  29. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/workSession/events/index.js +31 -0
  30. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/workSession/index.js +48 -0
  31. package/services/backend/dist/corePlugins/raclette__core/backend/datatypes/workSession/routes/index.js +15 -0
  32. package/services/backend/dist/corePlugins/raclette__core/backend/index.js +34 -0
  33. package/services/backend/dist/domains/index.js +11 -0
  34. package/services/backend/dist/domains/system/index.js +11 -0
  35. package/services/backend/dist/domains/system/routes/index.js +17 -0
  36. package/services/backend/dist/helpers/index.js +14 -0
  37. package/services/backend/dist/index.js +3 -0
  38. package/services/backend/dist/modules/authentication/index.js +253 -0
  39. package/services/backend/dist/shared/types/core/index.js +8 -0
  40. package/services/backend/dist/shared/types/dataTypes/index.js +6 -0
  41. package/services/backend/dist/shared/types/index.js +8 -0
  42. package/services/backend/dist/shared/types/plugins/index.js +8 -0
  43. package/services/backend/dist/types/index.js +12 -0
  44. package/services/backend/dist/utils/index.js +2 -0
  45. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/routes/route.user.patchOwn.ts +1 -1
  46. package/services/backend/src/corePlugins/raclette__core/backend/datatypes/user/user.service.ts +22 -1
  47. package/services/backend/yarn.lock +1 -1
  48. package/services/frontend/.yarn/install-state.gz +0 -0
  49. package/services/frontend/package.json +2 -2
  50. package/services/frontend/src/core/lib/data/dataApi.ts +1 -2
  51. package/services/frontend/src/orchestrator/ProductOrchestrator.vue +8 -1
  52. package/services/frontend/src/orchestrator/assets/styles/layers.css +1 -4
  53. package/services/frontend/src/orchestrator/assets/styles/tailwindStyles.css +3 -3
  54. package/services/frontend/src/orchestrator/assets/styles/vuetifyStyles.scss +4 -1
  55. package/services/frontend/src/orchestrator/components/dataExport/DataExporter.vue +303 -0
  56. package/services/frontend/src/orchestrator/components/dataTable/BaseDataTable.vue +473 -0
  57. package/services/frontend/src/orchestrator/components/dataTable/FileUpload.vue +83 -0
  58. package/services/frontend/src/orchestrator/components/dataTable/SelectionDialog.vue +169 -0
  59. package/services/frontend/src/orchestrator/components/dataTable/SummaryDialog.vue +211 -0
  60. package/services/frontend/src/orchestrator/components/index.ts +2 -0
  61. package/services/frontend/src/orchestrator/composables/index.ts +1 -0
  62. package/services/frontend/src/orchestrator/composables/useExport/formats/builtins.ts +124 -0
  63. package/services/frontend/src/orchestrator/composables/useExport/index.ts +176 -0
  64. package/services/frontend/src/orchestrator/composables/useExport/types.ts +141 -0
  65. package/services/frontend/src/orchestrator/i18n/de-DE.json +26 -1
  66. package/services/frontend/src/orchestrator/i18n/en-EU.json +26 -1
  67. package/services/frontend/src/orchestrator/i18n/sk.json +26 -1
  68. package/services/frontend/src/orchestrator/i18n/tl-TL.json +14 -0
  69. package/services/frontend/src/orchestrator/setup/vuetify.ts +0 -1
  70. package/services/frontend/yarn.lock +4854 -0
  71. package/types/index.ts +1 -1
  72. package/package/LICENSE.md +0 -699
  73. package/package/README.md +0 -49
  74. package/package/dev/README.md +0 -4
  75. package/package/index.js +0 -11
  76. package/package/raclette.default.config.yaml +0 -60
  77. package/package/services/backend/README.md +0 -172
  78. package/package/services/backend/yarn.lock +0 -5320
  79. package/package/services/frontend/README.md +0 -511
  80. package/package/services/frontend/src/core/lib/eggs/readme.md +0 -75
  81. package/package/services/frontend/yarn.lock +0 -0
  82. package/package/src/README.md +0 -404
  83. package/package/templates/README.md +0 -0
@@ -0,0 +1,303 @@
1
+ <template>
2
+ <v-menu
3
+ v-model="isOpen"
4
+ :close-on-content-click="false"
5
+ location="bottom end"
6
+ offset="8"
7
+ :max-width="520"
8
+ :min-width="360"
9
+ >
10
+ <template #activator="{ props: menuProps }">
11
+ <slot v-if="$slots.default" v-bind="triggerSlotProps" />
12
+ <v-btn
13
+ v-else
14
+ v-bind="{ ...menuProps, ...$attrs }"
15
+ :disabled="disabled"
16
+ :variant="$attrs.variant || 'tonal'"
17
+ color="info"
18
+ prepend-icon="mdi-export-variant"
19
+ class="tw:font-medium"
20
+ density="compact"
21
+ @click="open"
22
+ >
23
+ {{ buttonLabel }}
24
+ </v-btn>
25
+ </template>
26
+
27
+ <v-card rounded="lg" elevation="8" :style="{ width: '360px' }">
28
+ <!-- Header -->
29
+ <div class="tw:flex tw:items-center tw:justify-between tw:px-4 tw:pt-4 tw:pb-2">
30
+ <div class="tw:flex tw:items-center tw:gap-2">
31
+ <v-icon icon="mdi-export-variant" size="18" color="primary" />
32
+ <span class="tw:text-sm tw:font-semibold tw:tracking-wide tw:uppercase tw:opacity-70">
33
+ {{ $t("core.dataExporter.title") }}
34
+ </span>
35
+ </div>
36
+ <v-btn icon="mdi-close" variant="text" size="x-small" @click="isOpen = false" />
37
+ </div>
38
+
39
+ <v-divider />
40
+
41
+ <!-- Format tabs -->
42
+ <div class="tw:px-4 tw:pt-3 tw:pb-1">
43
+ <v-chip-group
44
+ v-model="activeFormatId"
45
+ mandatory
46
+ selected-class="text-primary"
47
+ class="tw:gap-1"
48
+ >
49
+ <v-chip
50
+ v-for="fmt in resolvedFormats"
51
+ :key="fmt.id"
52
+ :value="fmt.id"
53
+ size="small"
54
+ variant="tonal"
55
+ class="tw:font-mono tw:text-xs"
56
+ >
57
+ {{ fmt.label }}
58
+ </v-chip>
59
+ </v-chip-group>
60
+ </div>
61
+
62
+ <!-- Data scope switch — only shown when both items AND meta exist -->
63
+ <div
64
+ v-if="showScopeSwitch"
65
+ class="tw:px-4 tw:py-1 tw:flex tw:items-center tw:justify-between tw:gap-2"
66
+ >
67
+ <span class="tw:text-xs tw:opacity-60 tw:uppercase tw:tracking-wide">
68
+ {{ $t("core.dataExporter.scopeLabel") }}
69
+ </span>
70
+ <v-btn-toggle v-model="selectedScope" divided density="compact" mandatory>
71
+ <v-btn value="combined" size="x-small">
72
+ {{ $t("core.dataExporter.scopeCombined") }}
73
+ </v-btn>
74
+ <v-btn value="items" size="x-small">
75
+ {{ $t("core.dataExporter.scopeItems") }}
76
+ </v-btn>
77
+ <v-btn value="meta" size="x-small">
78
+ {{ $t("core.dataExporter.scopeMeta") }}
79
+ </v-btn>
80
+ </v-btn-toggle>
81
+ </div>
82
+
83
+ <!-- No formats warning -->
84
+ <div v-if="resolvedFormats.length === 0" class="tw:px-4 tw:py-6 tw:text-center">
85
+ <v-icon icon="mdi-alert-circle-outline" color="warning" class="tw:mb-2" />
86
+ <p class="tw:text-sm tw:opacity-60">{{ $t("core.dataExporter.noValidFormats") }}</p>
87
+ </div>
88
+
89
+ <!-- Preview pane -->
90
+ <div v-else class="tw:px-4 tw:pt-1 tw:pb-4">
91
+ <!-- Preview toggle -->
92
+ <v-btn
93
+ variant="text"
94
+ density="compact"
95
+ class="tw:mb-1.5 tw:w-full tw:justify-start tw:normal-case tw:text-xs tw:opacity-60 hover:tw:opacity-90"
96
+ @click="previewOpen = !previewOpen"
97
+ >
98
+ <template #prepend>
99
+ <v-icon
100
+ :icon="previewOpen ? 'mdi-chevron-down' : 'mdi-chevron-right'"
101
+ size="14"
102
+ />
103
+ </template>
104
+ {{ $t("core.dataExporter.preview") }}
105
+ </v-btn>
106
+
107
+ <!-- Fixed-height container prevents width reflow when toggling -->
108
+ <div class="tw:overflow-hidden" :style="{ height: previewOpen ? 'auto' : '0px', minHeight: previewOpen ? '0px' : undefined }">
109
+ <v-expand-transition>
110
+ <div v-show="previewOpen">
111
+ <!-- Serialization error -->
112
+ <v-alert
113
+ v-if="!serializeResult.ok"
114
+ type="error"
115
+ variant="tonal"
116
+ density="compact"
117
+ class="tw:mb-2 tw:font-mono tw:text-xs"
118
+ >
119
+ <pre class="tw:whitespace-pre-wrap tw:break-all">{{ serializeResult.error }}</pre>
120
+ </v-alert>
121
+
122
+ <!-- Preview code block -->
123
+ <div
124
+ v-else
125
+ class="tw:rounded-lg tw:overflow-hidden tw:border tw:border-black/10 dark:tw:border-white/10"
126
+ >
127
+ <!-- Toolbar -->
128
+ <div
129
+ class="tw:flex tw:items-center tw:justify-between tw:px-3 tw:py-1.5 tw:bg-black/5 dark:tw:bg-white/5 tw:border-b tw:border-black/10 dark:tw:border-white/10"
130
+ >
131
+ <span class="tw:font-mono tw:text-[10px] tw:uppercase tw:tracking-widest tw:opacity-50">
132
+ {{ activeFormatId }}
133
+ </span>
134
+ <span class="tw:font-mono tw:text-[10px] tw:opacity-40">
135
+ {{ previewLines.lineCount }}
136
+ {{ $t("core.dataExporter.lines") }}
137
+ </span>
138
+ </div>
139
+
140
+ <!-- Code content -->
141
+ <pre
142
+ class="tw:text-xs tw:font-mono tw:p-3 tw:max-h-52 tw:overflow-auto tw:leading-relaxed tw:bg-black/[0.03] dark:tw:bg-white/[0.03] tw:m-0"
143
+ >{{ previewLines.text }}</pre>
144
+
145
+ <!-- Truncation notice -->
146
+ <div
147
+ v-if="previewLines.truncated"
148
+ class="tw:text-[10px] tw:text-center tw:py-1 tw:opacity-40 tw:bg-black/5 dark:tw:bg-white/5 tw:border-t tw:border-black/10 dark:tw:border-white/10"
149
+ >
150
+ {{ $t("core.dataExporter.previewTruncatedAt", { count: PREVIEW_LINE_LIMIT }) }}
151
+ </div>
152
+ </div>
153
+ </div>
154
+ </v-expand-transition>
155
+ </div>
156
+
157
+ <!-- Action Buttons -->
158
+ <div class="tw:flex tw:gap-2 tw:mt-3">
159
+ <v-btn
160
+ v-if="clipboardSupported"
161
+ :disabled="!serializeResult.ok"
162
+ :color="copyState === 'success' ? 'success' : copyState === 'error' ? 'error' : 'primary'"
163
+ variant="tonal"
164
+ size="small"
165
+ class="tw:flex-1 tw:font-medium"
166
+ :prepend-icon="
167
+ copyState === 'success' ? 'mdi-check'
168
+ : copyState === 'error' ? 'mdi-alert-circle'
169
+ : 'mdi-content-copy'
170
+ "
171
+ @click="copyToClipboard"
172
+ >
173
+ {{
174
+ copyState === "success" ? $t("core.dataExporter.copied")
175
+ : copyState === "error" ? $t("core.dataExporter.copyFailed")
176
+ : $t("core.dataExporter.copy")
177
+ }}
178
+ </v-btn>
179
+ <v-btn
180
+ :disabled="!serializeResult.ok"
181
+ color="primary"
182
+ variant="flat"
183
+ size="small"
184
+ class="tw:flex-1 tw:font-medium"
185
+ prepend-icon="mdi-download"
186
+ @click="downloadFile"
187
+ >
188
+ {{ $t("core.dataExporter.download") }}
189
+ </v-btn>
190
+ </div>
191
+ </div>
192
+ </v-card>
193
+ </v-menu>
194
+ </template>
195
+
196
+ <script setup lang="ts">
197
+ import { ref, computed, watch } from "vue"
198
+ import type {
199
+ RacletteExportProps,
200
+ FormatEntry,
201
+ ExportSuccessPayload,
202
+ ExportErrorPayload,
203
+ TriggerSlotProps,
204
+ ExportDataScope,
205
+ } from "@racletteOrchestrator/composables/useExport/types"
206
+ import { useExport } from "@racletteOrchestrator/composables/useExport"
207
+
208
+ defineOptions({ inheritAttrs: false })
209
+
210
+ const props = withDefaults(defineProps<RacletteExportProps>(), {
211
+ filename: "export",
212
+ formats: () => ["json", "yaml", "csv", "text"] as FormatEntry[],
213
+ buttonLabel: "Export",
214
+ disabled: false,
215
+ previewCollapsed: true,
216
+ showDataScopeSwitch: true,
217
+ })
218
+
219
+ const emit = defineEmits<{
220
+ "export-success": [payload: ExportSuccessPayload]
221
+ "export-error": [payload: ExportErrorPayload]
222
+ }>()
223
+
224
+ // ─── Popover State ────────────────────────────────────────────────────────────
225
+
226
+ const isOpen = ref(false)
227
+ const previewOpen = ref(!props.previewCollapsed)
228
+
229
+ const hasItems = computed(() => props.data.items !== undefined)
230
+ const hasMeta = computed(() => props.data.meta !== undefined)
231
+
232
+ // Only show the toggle when BOTH sources exist and the prop allows it
233
+ const showScopeSwitch = computed(
234
+ () => props.showDataScopeSwitch && hasItems.value && hasMeta.value,
235
+ )
236
+
237
+ // Derive the correct default: items if available, else meta, else combined
238
+ const defaultScope = computed<ExportDataScope>(() => {
239
+ if (hasItems.value) return "items"
240
+ if (hasMeta.value) return "meta"
241
+ return "combined"
242
+ })
243
+
244
+ const selectedScope = ref<ExportDataScope>(defaultScope.value)
245
+
246
+ // Keep scope valid when data shape changes at runtime
247
+ watch(defaultScope, (next) => {
248
+ selectedScope.value = next
249
+ })
250
+
251
+ const scopedData = computed(() => {
252
+ if (selectedScope.value === "items") return props.data.items
253
+ if (selectedScope.value === "meta") return props.data.meta ?? {}
254
+ return props.data
255
+ })
256
+
257
+ const open = () => {
258
+ if (!props.disabled) isOpen.value = true
259
+ }
260
+
261
+ // ─── Export Logic ─────────────────────────────────────────────────────────────
262
+
263
+ const {
264
+ resolvedFormats,
265
+ activeFormatId,
266
+ serializeResult,
267
+ copyToClipboard,
268
+ downloadFile,
269
+ copyState,
270
+ clipboardSupported,
271
+ } = useExport({
272
+ data: () => scopedData.value,
273
+ formats: () => props.formats,
274
+ defaultFormat: () => props.defaultFormat,
275
+ filename: () => props.filename,
276
+ enabled: () => isOpen.value,
277
+ onSuccess: (p) => emit("export-success", p),
278
+ onError: (p) => emit("export-error", p),
279
+ })
280
+
281
+ // ─── Trigger Slot Props ───────────────────────────────────────────────────────
282
+
283
+ const triggerSlotProps = computed<TriggerSlotProps>(() => ({
284
+ open,
285
+ isOpen: isOpen.value,
286
+ disabled: props.disabled,
287
+ }))
288
+
289
+ // ─── Preview lines ────────────────────────────────────────────────────────────
290
+
291
+ const PREVIEW_LINE_LIMIT = 200
292
+
293
+ const previewLines = computed<{ text: string; lineCount: number; truncated: boolean }>(() => {
294
+ if (!serializeResult.value.ok) return { text: "", lineCount: 0, truncated: false }
295
+ const lines = serializeResult.value.value.split("\n")
296
+ const truncated = lines.length > PREVIEW_LINE_LIMIT
297
+ return {
298
+ text: truncated ? lines.slice(0, PREVIEW_LINE_LIMIT).join("\n") : serializeResult.value.value,
299
+ lineCount: lines.length,
300
+ truncated,
301
+ }
302
+ })
303
+ </script>