@raclettejs/workbench 0.1.33-canary.3 → 0.1.33

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 (27) hide show
  1. package/.raclette/backend/raclette.config.js +2 -2
  2. package/.raclette/frontend/raclette.config.js +2 -2
  3. package/.raclette/frontend/yarn.lock +143 -126
  4. package/.raclette/virtual/backend/raclette.config.js +2 -2
  5. package/.raclette/virtual/frontend/raclette.config.js +2 -2
  6. package/.raclette/virtual/frontend/yarn.lock +143 -126
  7. package/CHANGELOG.md +19 -3
  8. package/i18n/de-DE.json +15 -0
  9. package/i18n/en-EU.json +15 -0
  10. package/i18n/sk-SK.json +15 -0
  11. package/package.json +5 -4
  12. package/plugins/pacifico__compositions/frontend/widgets/CompositionListWidget.vue +39 -21
  13. package/plugins/pacifico__interactionLinks/frontend/widgets/InteractionLinkListWidget.vue +39 -21
  14. package/plugins/pacifico__plugins/frontend/index.ts +3 -3
  15. package/plugins/pacifico__plugins/frontend/widgets/PluginListWidget.vue +11 -12
  16. package/plugins/pacifico__tags/frontend/widgets/TagListWidget.vue +39 -21
  17. package/plugins/pacifico__users/frontend/widgets/UserListWidget.vue +79 -57
  18. package/services/frontend/src/app/components/dynamicForm/DynamicForm.vue +139 -51
  19. package/services/frontend/src/app/components/dynamicForm/DynamicInput.vue +95 -5
  20. package/services/frontend/src/app/components/dynamicForm/ObjectListInput.vue +78 -41
  21. package/services/frontend/src/app/components/dynamicForm/TextDivider.vue +46 -6
  22. package/services/frontend/src/app/components/dynamicForm/typedInputs/ListInput.vue +118 -27
  23. package/services/frontend/src/app/components/dynamicForm/typedInputs/RecordInput.vue +131 -21
  24. package/services/frontend/src/app/components/dynamicForm/typedInputs/TagsInput.vue +1 -0
  25. package/services/frontend/src/app/components/dynamicForm/typedInputs/TriggerInput.vue +4 -4
  26. package/services/frontend/src/app/composables/useWorkbenchTableActions.ts +29 -0
  27. package/services/frontend/src/orchestrator/assets/styles/themes/light.ts +4 -3
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@raclettejs/workbench",
3
- "version": "0.1.33-canary.3",
3
+ "version": "0.1.33",
4
4
  "license": "MIT",
5
5
  "description": "racletteJS Workbench - used to configure your application, for dev and prod",
6
6
  "repository": "https://gitlab.com/raclettejs/workbench",
7
7
  "author": "Pacifico Digital Explorations GmbH",
8
8
  "type": "module",
9
9
  "scripts": {
10
+ ":install": "yarn install",
10
11
  "dev": "raclette dev",
11
12
  "down": "raclette down",
12
13
  "build": "raclette build",
@@ -33,7 +34,7 @@
33
34
  ".": "./index.ts"
34
35
  },
35
36
  "dependencies": {
36
- "@raclettejs/core": "^0.1.33-canary.3",
37
+ "@raclettejs/core": "^0.1.33",
37
38
  "@vueuse/integrations": "14.2.1",
38
39
  "fuse.js": "7.1.0",
39
40
  "three": "0.183.2",
@@ -43,7 +44,7 @@
43
44
  "@emnapi/core": "1.9.2",
44
45
  "@emnapi/runtime": "1.9.2",
45
46
  "@eslint/js": "9.35.0",
46
- "@raclettejs/types": "^0.1.33-canary.3",
47
+ "@raclettejs/types": "^0.1.33",
47
48
  "@sinclair/typebox": "0.34.48",
48
49
  "@types/ramda": "0.31.1",
49
50
  "@vueuse/core": "14.2.1",
@@ -66,7 +67,7 @@
66
67
  "uuid": "13.0.0",
67
68
  "vite": "8.0.1",
68
69
  "vue": "3.5.30",
69
- "vue-eslint-parser": "9.4.3",
70
+ "vue-eslint-parser": "10.3.0",
70
71
  "vue-i18n": "11.3.0",
71
72
  "vuetify": "4.0.5"
72
73
  }
@@ -1,37 +1,40 @@
1
1
  <template>
2
- <div>
2
+ <div class="tw:p-4">
3
3
  <BaseDataTable
4
4
  :items="parsedCompositions"
5
5
  :exportable-items="exportableCompositions"
6
6
  :loading="compositionsLoading || tagsLoading"
7
7
  :headers="headers"
8
- create-interaction-link-id="compositionCreateInteractionLink"
9
- edit-interaction-link-id="compositionEditInteractionLink"
8
+ :row-click-handler="handleRowClick"
10
9
  :data-name="$t('workbench.compositionList.dataName')"
11
- :data-article="$t('workbench.compositionList.dataArticle')"
12
- @delete="deleteComposition"
10
+ :show-filters="true"
13
11
  :items-deleted="showDeleted"
14
12
  :on-file-loaded="handleFileUpload"
15
13
  >
16
- <template #toolbar-leading>
17
- <v-tooltip
18
- :text="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
14
+ <template #toolbar-end>
15
+ <v-btn
16
+ prepend-icon="mdi-plus"
17
+ variant="flat"
18
+ color="success"
19
+ :text="$t('core.baseDataTable.createDataButton', { dataName: $t('workbench.compositionList.dataName') })"
20
+ @click="goToCreate('compositionCreateInteractionLink')"
21
+ />
22
+ </template>
23
+ <template #toolbar-actions-menu>
24
+ <v-list-item
25
+ :title="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
26
+ prepend-icon="mdi-delete-outline"
19
27
  >
20
- <template #activator="{ props: activatorProps }">
21
- <v-btn-toggle
22
- density="compact"
23
- v-bind="activatorProps"
28
+ <template #append>
29
+ <v-switch
24
30
  v-model="showDeleted"
25
- mandatory
26
- :color="showDeleted ? 'error' : 'success'"
27
- >
28
- <v-btn :value="true">
29
- <v-icon>mdi-table-eye-off</v-icon>
30
- </v-btn>
31
- <v-btn :value="false"><v-icon>mdi-table-eye</v-icon></v-btn>
32
- </v-btn-toggle>
31
+ color="error"
32
+ density="compact"
33
+ hide-details
34
+ inset
35
+ />
33
36
  </template>
34
- </v-tooltip>
37
+ </v-list-item>
35
38
  </template>
36
39
  <!-- Custom status column -->
37
40
  <template #[`item.status`]="{ item }">
@@ -55,6 +58,15 @@
55
58
  icon="mdi-delete-restore"
56
59
  />
57
60
  </template>
61
+ <template #row-actions="{ item }">
62
+ <v-btn
63
+ icon="mdi-delete"
64
+ size="small"
65
+ variant="text"
66
+ color="error"
67
+ @click.stop.prevent="deleteComposition(item)"
68
+ />
69
+ </template>
58
70
  </BaseDataTable>
59
71
  <!-- Import Selection Dialog -->
60
72
  <ImportSelectionDialog
@@ -93,10 +105,12 @@ import {
93
105
  parseAndNormalizeWorkbenchImportJson,
94
106
  resolveWorkbenchImportSelection,
95
107
  } from "@app/lib/jsonTools"
108
+ import { useWorkbenchTableActions } from "@app/composables/useWorkbenchTableActions"
96
109
  import ImportSelectionDialog from "@raclettejs/core/orchestrator/components/dataImport/ImportSelectionDialog.vue"
97
110
  import ImportSummaryDialog from "@raclettejs/core/orchestrator/components/dataImport/ImportSummaryDialog.vue"
98
111
 
99
112
  const { t } = useI18n()
113
+ const { goToCreate, goToEditById } = useWorkbenchTableActions()
100
114
  const showDeleted = ref(false)
101
115
  const showImportDialog = ref(false)
102
116
  const showImportSummary = ref(false)
@@ -273,6 +287,10 @@ const deleteComposition = async (composition: Composition) => {
273
287
  const restore = (_id: string) => {
274
288
  executeRestore({ _id })
275
289
  }
290
+
291
+ const handleRowClick = (item: Composition) =>
292
+ goToEditById("compositionEditInteractionLink", item._id)
293
+
276
294
  $socket.on("compositionCreated", () =>
277
295
  execute({ isDeleted: showDeleted.value }),
278
296
  )
@@ -1,37 +1,40 @@
1
1
  <template>
2
- <div>
2
+ <div class="tw:p-4">
3
3
  <BaseDataTable
4
4
  :items="parsedInteractionLinks"
5
5
  :exportable-items="exportableInteractionLinks"
6
6
  :loading="interactionLinksLoading || tagsLoading"
7
7
  :headers="headers"
8
- create-interaction-link-id="interactionLinkCreateInteractionLink"
9
- edit-interaction-link-id="interactionLinkEditInteractionLink"
8
+ :row-click-handler="handleRowClick"
10
9
  :data-name="$t('workbench.interactionLinkList.dataName')"
11
- :data-article="$t('workbench.interactionLinkList.dataArticle')"
12
- @delete="deleteInteractionLink"
10
+ :show-filters="true"
13
11
  :items-deleted="showDeleted"
14
12
  :on-file-loaded="handleFileUpload"
15
13
  >
16
- <template #toolbar-leading>
17
- <v-tooltip
18
- :text="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
14
+ <template #toolbar-end>
15
+ <v-btn
16
+ prepend-icon="mdi-plus"
17
+ variant="flat"
18
+ color="success"
19
+ :text="$t('core.baseDataTable.createDataButton', { dataName: $t('workbench.interactionLinkList.dataName') })"
20
+ @click="goToCreate('interactionLinkCreateInteractionLink')"
21
+ />
22
+ </template>
23
+ <template #toolbar-actions-menu>
24
+ <v-list-item
25
+ :title="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
26
+ prepend-icon="mdi-delete-outline"
19
27
  >
20
- <template #activator="{ props: activatorProps }">
21
- <v-btn-toggle
22
- density="compact"
23
- v-bind="activatorProps"
28
+ <template #append>
29
+ <v-switch
24
30
  v-model="showDeleted"
25
- mandatory
26
- :color="showDeleted ? 'error' : 'success'"
27
- >
28
- <v-btn :value="true">
29
- <v-icon>mdi-table-eye-off</v-icon>
30
- </v-btn>
31
- <v-btn :value="false"><v-icon>mdi-table-eye</v-icon></v-btn>
32
- </v-btn-toggle>
31
+ color="error"
32
+ density="compact"
33
+ hide-details
34
+ inset
35
+ />
33
36
  </template>
34
- </v-tooltip>
37
+ </v-list-item>
35
38
  </template>
36
39
  <!-- Custom triggers column -->
37
40
  <template #[`item.triggers`]="{ item }">
@@ -54,6 +57,15 @@
54
57
  icon="mdi-delete-restore"
55
58
  />
56
59
  </template>
60
+ <template #row-actions="{ item }">
61
+ <v-btn
62
+ icon="mdi-delete"
63
+ size="small"
64
+ variant="text"
65
+ color="error"
66
+ @click.stop.prevent="deleteInteractionLink(item)"
67
+ />
68
+ </template>
57
69
  </BaseDataTable>
58
70
  <!-- Import Selection Dialog -->
59
71
  <ImportSelectionDialog
@@ -94,6 +106,7 @@ import {
94
106
  } from "@app/lib/jsonTools"
95
107
  import ImportSelectionDialog from "@raclettejs/core/orchestrator/components/dataImport/ImportSelectionDialog.vue"
96
108
  import ImportSummaryDialog from "@raclettejs/core/orchestrator/components/dataImport/ImportSummaryDialog.vue"
109
+ import { useWorkbenchTableActions } from "@app/composables/useWorkbenchTableActions"
97
110
  const showDeleted = ref(false)
98
111
  const showImportDialog = ref(false)
99
112
  const showImportSummary = ref(false)
@@ -103,6 +116,7 @@ const importedItems = ref<any[]>([])
103
116
  const pendingImportById = ref<Record<string, any>>({})
104
117
 
105
118
  const { t } = useI18n()
119
+ const { goToCreate, goToEditById } = useWorkbenchTableActions()
106
120
 
107
121
  const headers = computed<{ title: string; key: keyof InteractionLink }[]>(
108
122
  () => [
@@ -211,6 +225,10 @@ const exportableInteractionLinks = computed(() =>
211
225
  const restore = async (_id: string) => {
212
226
  executeRestore({ _id })
213
227
  }
228
+
229
+ const handleRowClick = (item: InteractionLink) =>
230
+ goToEditById("interactionLinkEditInteractionLink", item._id)
231
+
214
232
  const deleteInteractionLink = async (interactionLink: InteractionLink) => {
215
233
  if (showDeleted.value) {
216
234
  await executeHardDelete({ _id: interactionLink._id })
@@ -4,7 +4,7 @@ export default defineRaclettePluginFrontend({
4
4
  i18n: {
5
5
  de: {
6
6
  pluginList: {
7
- dataName: "Plugin",
7
+ dataName: "Plugins",
8
8
  dataArticle: "das",
9
9
  tableHeaders: {
10
10
  name: "Name",
@@ -16,7 +16,7 @@ export default defineRaclettePluginFrontend({
16
16
  },
17
17
  en: {
18
18
  pluginList: {
19
- dataName: "Plugin",
19
+ dataName: "Plugins",
20
20
  dataArticle: "the",
21
21
  tableHeaders: {
22
22
  name: "Name",
@@ -28,7 +28,7 @@ export default defineRaclettePluginFrontend({
28
28
  },
29
29
  sk: {
30
30
  pluginList: {
31
- dataName: "Plugin",
31
+ dataName: "Plugins",
32
32
  dataArticle: "",
33
33
  tableHeaders: {
34
34
  name: "Názov",
@@ -1,16 +1,15 @@
1
1
  <template>
2
- <BaseDataTable
3
- :items="pluginMetadataFiles"
4
- :headers
5
- :data-name="$i18n.t('pluginList.dataName')"
6
- :data-article="$i18n.t('pluginList.dataArticle')"
7
- :show-create-button="false"
8
- :show-delete-action="false"
9
- :show-actions-column="false"
10
- :row-click-handler="onRowClick"
11
- :show-export="false"
12
- >
13
- </BaseDataTable>
2
+ <div class="tw:p-4">
3
+ <BaseDataTable
4
+ :items="pluginMetadataFiles"
5
+ :headers
6
+ :data-name="$i18n.t('pluginList.dataName')"
7
+ :show-filters="true"
8
+ :show-actions-column="false"
9
+ :row-click-handler="onRowClick"
10
+ :show-export="false"
11
+ />
12
+ </div>
14
13
  </template>
15
14
 
16
15
  <script setup lang="ts">
@@ -1,37 +1,40 @@
1
1
  <template>
2
- <div>
2
+ <div class="tw:p-4">
3
3
  <BaseDataTable
4
4
  :items="parsedTags"
5
5
  :exportable-items="exportableTags"
6
6
  :loading="tagsLoading"
7
7
  :headers="headers"
8
- create-interaction-link-id="tagCreateInteractionLink"
9
- edit-interaction-link-id="tagEditInteractionLink"
8
+ :row-click-handler="handleRowClick"
10
9
  :data-name="$t('workbench.tagList.dataName')"
11
- :data-article="$t('workbench.tagList.dataArticle')"
12
- @delete="deleteTag"
10
+ :show-filters="true"
13
11
  :items-deleted="showDeleted"
14
12
  :on-file-loaded="handleFileUpload"
15
13
  >
16
- <template #toolbar-leading>
17
- <v-tooltip
18
- :text="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
14
+ <template #toolbar-end>
15
+ <v-btn
16
+ prepend-icon="mdi-plus"
17
+ variant="flat"
18
+ color="success"
19
+ :text="$t('core.baseDataTable.createDataButton', { dataName: $t('workbench.tagList.dataName') })"
20
+ @click="goToCreate('tagCreateInteractionLink')"
21
+ />
22
+ </template>
23
+ <template #toolbar-actions-menu>
24
+ <v-list-item
25
+ :title="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
26
+ prepend-icon="mdi-delete-outline"
19
27
  >
20
- <template #activator="{ props: activatorProps }">
21
- <v-btn-toggle
22
- density="compact"
23
- v-bind="activatorProps"
28
+ <template #append>
29
+ <v-switch
24
30
  v-model="showDeleted"
25
- mandatory
26
- :color="showDeleted ? 'error' : 'success'"
27
- >
28
- <v-btn :value="true">
29
- <v-icon>mdi-table-eye-off</v-icon>
30
- </v-btn>
31
- <v-btn :value="false"><v-icon>mdi-table-eye</v-icon></v-btn>
32
- </v-btn-toggle>
31
+ color="error"
32
+ density="compact"
33
+ hide-details
34
+ inset
35
+ />
33
36
  </template>
34
- </v-tooltip>
37
+ </v-list-item>
35
38
  </template>
36
39
  <template #prepend-row-actions="{ item }">
37
40
  <v-icon
@@ -47,6 +50,15 @@
47
50
  icon="mdi-delete-restore"
48
51
  />
49
52
  </template>
53
+ <template #row-actions="{ item }">
54
+ <v-btn
55
+ icon="mdi-delete"
56
+ size="small"
57
+ variant="text"
58
+ color="error"
59
+ @click.stop.prevent="deleteTag(item)"
60
+ />
61
+ </template>
50
62
  </BaseDataTable>
51
63
  <!-- Import Selection Dialog -->
52
64
  <ImportSelectionDialog
@@ -87,8 +99,10 @@ import {
87
99
  } from "@app/lib/jsonTools"
88
100
  import ImportSelectionDialog from "@raclettejs/core/orchestrator/components/dataImport/ImportSelectionDialog.vue"
89
101
  import ImportSummaryDialog from "@raclettejs/core/orchestrator/components/dataImport/ImportSummaryDialog.vue"
102
+ import { useWorkbenchTableActions } from "@app/composables/useWorkbenchTableActions"
90
103
  const showDeleted = ref(false)
91
104
  const { t } = useI18n()
105
+ const { goToCreate, goToEditById } = useWorkbenchTableActions()
92
106
  const showImportDialog = ref(false)
93
107
  const showImportSummary = ref(false)
94
108
 
@@ -214,6 +228,10 @@ const finalizeImport = async () => {
214
228
  const restore = async (_id: string) => {
215
229
  executeRestore({ _id })
216
230
  }
231
+
232
+ const handleRowClick = (item: Tag) =>
233
+ goToEditById("tagEditInteractionLink", item._id)
234
+
217
235
  $socket.on("tagCreated", () => execute({ isDeleted: showDeleted.value }))
218
236
  watch(
219
237
  showDeleted,
@@ -1,52 +1,70 @@
1
1
  <template>
2
- <BaseDataTable
3
- :items="parsedUsers"
4
- :exportable-items="exportableUsers"
5
- :loading="usersLoading || tagsLoading"
6
- :headers="headers"
7
- create-interaction-link-id="userCreateInteractionLink"
8
- edit-interaction-link-id="userEditInteractionLink"
9
- :data-name="$t('workbench.userList.dataName')"
10
- :data-article="$t('workbench.userList.dataArticle')"
11
- :delete-validator="(user) => user._id !== $user?._id"
12
- @delete="deleteUser"
13
- :items-deleted="showDeleted"
14
- >
15
- <template #toolbar-leading>
16
- <v-tooltip
17
- :text="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
18
- >
19
- <template #activator="{ props: activatorProps }">
20
- <v-btn-toggle
21
- density="compact"
22
- v-bind="activatorProps"
23
- v-model="showDeleted"
24
- mandatory
25
- :color="showDeleted ? 'error' : 'success'"
26
- >
27
- <v-btn :value="true">
28
- <v-icon>mdi-table-eye-off</v-icon>
29
- </v-btn>
30
- <v-btn :value="false"><v-icon>mdi-table-eye</v-icon></v-btn>
31
- </v-btn-toggle>
32
- </template>
33
- </v-tooltip>
34
- </template>
35
- <template #prepend-row-actions="{ item }">
36
- <v-icon
37
- v-if="showDeleted"
38
- color="green"
39
- class="mr-2"
40
- @click.stop.prevent="restore(item._id)"
41
- :title="
42
- $t('workbench.baseDataTable.restoreDataTitle', {
43
- dataName: item.title,
44
- })
45
- "
46
- icon="mdi-delete-restore"
47
- />
48
- </template>
49
- </BaseDataTable>
2
+ <div class="tw:p-4">
3
+ <BaseDataTable
4
+ :items="parsedUsers"
5
+ :exportable-items="exportableUsers"
6
+ :loading="usersLoading || tagsLoading"
7
+ :headers="headers"
8
+ :row-click-handler="handleRowClick"
9
+ :data-name="$t('workbench.userList.dataName')"
10
+ :show-filters="true"
11
+ :items-deleted="showDeleted"
12
+ >
13
+ <template #toolbar-end>
14
+ <v-btn
15
+ prepend-icon="mdi-plus"
16
+ variant="flat"
17
+ color="success"
18
+ :text="
19
+ $t('core.baseDataTable.createDataButton', {
20
+ dataName: $t('workbench.userList.dataName'),
21
+ })
22
+ "
23
+ @click="goToCreate('userCreateInteractionLink')"
24
+ />
25
+ </template>
26
+ <template #toolbar-actions-menu>
27
+ <v-list-item
28
+ :title="showDeleted ? $t('core.hideDeleted') : $t('core.showDeleted')"
29
+ prepend-icon="mdi-delete-outline"
30
+ >
31
+ <template #append>
32
+ <v-switch
33
+ v-model="showDeleted"
34
+ color="error"
35
+ density="compact"
36
+ hide-details
37
+ inset
38
+ />
39
+ </template>
40
+ </v-list-item>
41
+ </template>
42
+ <template #prepend-row-actions="{ item }">
43
+ <v-icon
44
+ v-if="showDeleted"
45
+ color="green"
46
+ class="mr-2"
47
+ @click.stop.prevent="restore(item._id)"
48
+ :title="
49
+ $t('workbench.baseDataTable.restoreDataTitle', {
50
+ dataName: item.title,
51
+ })
52
+ "
53
+ icon="mdi-delete-restore"
54
+ />
55
+ </template>
56
+ <template #row-actions="{ item }">
57
+ <v-btn
58
+ v-if="item._id !== $user?._id"
59
+ icon="mdi-delete"
60
+ size="small"
61
+ variant="text"
62
+ color="error"
63
+ @click.stop.prevent="deleteUser(item)"
64
+ />
65
+ </template>
66
+ </BaseDataTable>
67
+ </div>
50
68
  </template>
51
69
 
52
70
  <script setup lang="ts">
@@ -56,6 +74,7 @@ import type { User } from "@raclettejs/core"
56
74
  import { formatDistance } from "date-fns"
57
75
  import { useI18n } from "vue-i18n"
58
76
  import BaseDataTable from "@raclettejs/core/orchestrator/components/dataTable/BaseDataTable.vue"
77
+ import { useWorkbenchTableActions } from "@app/composables/useWorkbenchTableActions"
59
78
  const showDeleted = ref(false)
60
79
 
61
80
  const props = defineProps<{
@@ -63,6 +82,7 @@ const props = defineProps<{
63
82
  }>()
64
83
 
65
84
  const { t } = useI18n()
85
+ const { goToCreate, goToEditById } = useWorkbenchTableActions()
66
86
 
67
87
  const headers = computed<{ title: string; key: keyof User }[]>(() => [
68
88
  {
@@ -108,15 +128,13 @@ const userTableRows = (relativeUpdatedAt: boolean) => {
108
128
  return []
109
129
  }
110
130
 
111
- return Object.values(users.value as { [key: string]: User }).map(
112
- (user) => ({
113
- ...user,
114
- tags: user.tags.map((tag) => tags.value?.[tag]),
115
- ...(relativeUpdatedAt
116
- ? { updatedAt: formatDistance(new Date(user.updatedAt), new Date()) }
117
- : {}),
118
- }),
119
- )
131
+ return Object.values(users.value as { [key: string]: User }).map((user) => ({
132
+ ...user,
133
+ tags: user.tags.map((tag) => tags.value?.[tag]),
134
+ ...(relativeUpdatedAt
135
+ ? { updatedAt: formatDistance(new Date(user.updatedAt), new Date()) }
136
+ : {}),
137
+ }))
120
138
  }
121
139
 
122
140
  const parsedUsers = computed(() => userTableRows(true))
@@ -132,6 +150,10 @@ const deleteUser = async (user: User) => {
132
150
  const restore = async (_id: string) => {
133
151
  executeRestore({ _id })
134
152
  }
153
+
154
+ const handleRowClick = (item: User) =>
155
+ goToEditById("userEditInteractionLink", item._id)
156
+
135
157
  $socket.on("userCreated", () => execute({ isDeleted: showDeleted.value }))
136
158
  watch(
137
159
  showDeleted,