Skip to content

Commit e8a58d5

Browse files
committed
feat: generalize instance cards
1 parent 4be52eb commit e8a58d5

File tree

4 files changed

+153
-152
lines changed

4 files changed

+153
-152
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
<template>
2+
<div>
3+
<v-breadcrumbs :items="breadcrumbs" />
4+
5+
<v-card :loading="!instance">
6+
<v-card-title>
7+
<slot name="title" :instance="instance" />
8+
</v-card-title>
9+
10+
<v-card-subtitle>
11+
<slot name="subtitle" :instance="instance" />
12+
</v-card-subtitle>
13+
14+
<v-card-text class="mt-4">
15+
<slot :instance="instance" />
16+
</v-card-text>
17+
18+
<v-card-actions v-if="instance">
19+
<FormEdit
20+
v-if="
21+
editFields &&
22+
editFields.length > 0 &&
23+
authorization.hasPermission(endpoint, 'Write')
24+
"
25+
v-model="editInstance"
26+
:fields="editFields"
27+
:action="save"
28+
:subtitle="instance.id"
29+
>
30+
<template #default="{ props }">
31+
<v-btn color="primary" text v-bind="props">
32+
{{ $t("form.edit") }}
33+
</v-btn>
34+
</template>
35+
</FormEdit>
36+
37+
<v-spacer />
38+
39+
<FormConfirm
40+
v-if="
41+
!!deleteMessage && authorization.hasPermission(endpoint, 'Write')
42+
"
43+
:message="deleteMessage"
44+
:action="props.delete(instance.id)"
45+
>
46+
<template #default="{ props }">
47+
<v-btn v-bind="props" color="error" text>
48+
{{ $t("form.delete") }}
49+
</v-btn>
50+
</template>
51+
</FormConfirm>
52+
</v-card-actions>
53+
</v-card>
54+
</div>
55+
</template>
56+
57+
<script setup lang="ts">
58+
import { onMounted, ref, defineProps, useRouter } from "#imports";
59+
import { useAuthorizationStore } from "~/composables/authorization";
60+
61+
const props = defineProps({
62+
breadcrumbs: Array,
63+
editFields: Array,
64+
fetch: Function,
65+
delete: Function,
66+
edit: Function,
67+
endpoint: String,
68+
deleteMessage: String,
69+
});
70+
71+
const authorization = useAuthorizationStore();
72+
const router = useRouter();
73+
74+
const instance = ref(undefined);
75+
const editInstance = ref(undefined);
76+
77+
onMounted(async () => {
78+
await authorization.fetch();
79+
80+
if (!authorization.hasPermission(props.endpoint, "Read")) {
81+
return router.push("/");
82+
}
83+
84+
instance.value = await props.fetch().then((value) => value);
85+
86+
editInstance.value = JSON.parse(JSON.stringify(instance.value));
87+
});
88+
89+
const save = async () => {
90+
await props
91+
.edit(editInstance.value)()
92+
.then((value) => (instance.value = value));
93+
};
94+
</script>

dashboard/i18n/locales/en.json

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
"required": "required"
1616
},
1717
"prompt": {
18-
"list": "Prompts"
18+
"list": "Prompts",
19+
"title": "Title",
20+
"delete": "Are you sure you want to delete the prompt? This will also delete all fields and gathered data.",
21+
"description": "description"
1922
},
2023
"target": {
21-
"delete": "Are you sure you want to delete the target {name}? This will also delete all prompts and gathered data.",
24+
"delete": "Are you sure you want to delete the target? This will also delete all prompts and gathered data.",
2225
"name": "Name",
2326
"description": "Description"
2427
}
Lines changed: 29 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,31 @@
11
<template>
2-
<div>
3-
<v-breadcrumbs :items="breadcrumbs" />
4-
5-
<v-card :loading="!target">
6-
<v-card-title>
7-
{{ target?.name }}
8-
</v-card-title>
9-
10-
<v-card-subtitle>
11-
{{ target?.description }}
12-
</v-card-subtitle>
13-
14-
<v-card-text class="mt-4">
15-
<PromptList v-if="target" :target="target.id" />
16-
</v-card-text>
17-
18-
<v-card-actions v-if="target">
19-
<FormEdit
20-
v-if="authorization.hasPermission('Target', 'Write')"
21-
v-model="editTarget"
22-
:fields="editFields"
23-
:action="save"
24-
:subtitle="target.id"
25-
>
26-
<template #default="{ props }">
27-
<v-btn color="primary" text v-bind="props">
28-
{{ $t("form.edit") }}
29-
</v-btn>
30-
</template>
31-
</FormEdit>
32-
33-
<v-spacer />
34-
35-
<FormConfirm
36-
v-if="authorization.hasPermission('Target', 'Write')"
37-
:message="$t('target.delete', { name: target.name })"
38-
:action="deleteTarget(target.id)"
39-
>
40-
<template #default="{ props }">
41-
<v-btn v-bind="props" color="error" text>
42-
{{ $t("form.delete") }}
43-
</v-btn>
44-
</template>
45-
</FormConfirm>
46-
</v-card-actions>
47-
</v-card>
48-
</div>
2+
<InstanceCard
3+
endpoint="Target"
4+
:breadcrumbs="breadcrumbs"
5+
:editFields="editFields"
6+
:fetch="fetch"
7+
:delete="deleteTarget"
8+
:edit="edit"
9+
:deleteMessage="$t('target.delete')"
10+
>
11+
<template #title="{ instance }">
12+
{{ instance?.name }}
13+
</template>
14+
15+
<template #subtitle="{ instance }">
16+
{{ instance?.description }}
17+
</template>
18+
19+
<template #default="{ instance }">
20+
<PromptList v-if="instance" :target="instance.id" />
21+
</template>
22+
</InstanceCard>
4923
</template>
5024

5125
<script setup lang="ts">
52-
import {
53-
useRouter,
54-
onMounted,
55-
ref,
56-
useNuxtApp,
57-
useRoute,
58-
useI18n,
59-
useLocalePath,
60-
} from "#imports";
61-
import { useAuthorizationStore } from "~/composables/authorization";
26+
import { ref, useNuxtApp, useRoute, useI18n, useLocalePath } from "#imports";
6227
import { useRpcOptions } from "~/composables/grpc";
6328
64-
const authorization = useAuthorizationStore();
65-
const router = useRouter();
6629
const route = useRoute();
6730
const { $feedbackFusion } = useNuxtApp();
6831
const { t } = useI18n();
@@ -78,8 +41,6 @@ const breadcrumbs = ref([
7841
to: localePath(`/target/${route.params.target}`),
7942
},
8043
]);
81-
const target = ref(undefined);
82-
const editTarget = ref(undefined);
8344
8445
const editFields = ref([
8546
{
@@ -95,27 +56,19 @@ const editFields = ref([
9556
},
9657
]);
9758
98-
onMounted(async () => {
99-
await authorization.fetch();
100-
101-
if (!authorization.hasPermission("Target", "Read")) {
102-
return router.push("/");
103-
}
104-
105-
target.value = await $feedbackFusion
59+
const fetch = async () => {
60+
return await $feedbackFusion
10661
.getTarget({ id: route.params.target }, useRpcOptions())
10762
.then((value) => value.response);
108-
109-
editTarget.value = JSON.parse(JSON.stringify(target.value));
110-
});
63+
};
11164
11265
const deleteTarget = (id: number) => async () => {
11366
await $feedbackFusion.deleteTarget({ id }, useRpcOptions());
11467
};
11568
116-
const save = async () => {
117-
await $feedbackFusion
118-
.updateTarget(editTarget.value, useRpcOptions())
119-
.then((value) => (target.value = value.response));
69+
const edit = (target) => async () => {
70+
return await $feedbackFusion
71+
.updateTarget(target, useRpcOptions())
72+
.then((value) => value.response);
12073
};
12174
</script>
Lines changed: 25 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,28 @@
11
<template>
2-
<div>
3-
<v-breadcrumbs :items="breadcrumbs" />
4-
5-
<v-card :loading="!prompt">
6-
<v-card-title>
7-
{{ prompt?.title }}
8-
</v-card-title>
9-
10-
<v-card-subtitle>
11-
{{ prompt?.description }}
12-
</v-card-subtitle>
13-
14-
<v-card-text class="mt-4"> </v-card-text>
15-
16-
<v-card-actions v-if="prompt">
17-
<FormEdit
18-
v-if="authorization.hasPermission('Prompt', 'Write')"
19-
v-model="editPrompt"
20-
:fields="editFields"
21-
:action="save"
22-
:subtitle="prompt.id"
23-
>
24-
<template #default="{ props }">
25-
<v-btn color="primary" text v-bind="props">
26-
{{ $t("form.edit") }}
27-
</v-btn>
28-
</template>
29-
</FormEdit>
30-
31-
<v-spacer />
32-
33-
<FormConfirm
34-
v-if="authorization.hasPermission('Prompt', 'Write')"
35-
:message="$t('prompt.delete', { name: prompt.name })"
36-
:action="deletePrompt(prompt.id)"
37-
>
38-
<template #default="{ props }">
39-
<v-btn v-bind="props" color="error" text>
40-
{{ $t("form.delete") }}
41-
</v-btn>
42-
</template>
43-
</FormConfirm>
44-
</v-card-actions>
45-
</v-card>
46-
</div>
2+
<InstanceCard
3+
endpoint="Prompt"
4+
:breadcrumbs="breadcrumbs"
5+
:editFields="editFields"
6+
:fetch="fetch"
7+
:delete="deletePrompt"
8+
:edit="edit"
9+
:deleteMessage="$t('prompt.delete')"
10+
>
11+
<template #title="{ instance }">
12+
{{ instance?.title }}
13+
</template>
14+
15+
<template #subtitle="{ instance }">
16+
{{ instance?.description }}
17+
</template>
18+
</InstanceCard>
4719
</template>
4820

4921
<script setup lang="ts">
50-
import {
51-
useRouter,
52-
onMounted,
53-
ref,
54-
useNuxtApp,
55-
useRoute,
56-
useI18n,
57-
useLocalePath,
58-
} from "#imports";
59-
import { useAuthorizationStore } from "~/composables/authorization";
22+
import { ref, useNuxtApp, useRoute, useI18n, useLocalePath } from "#imports";
6023
import { useRpcOptions } from "~/composables/grpc";
6124
6225
const localePath = useLocalePath();
63-
const authorization = useAuthorizationStore();
64-
const router = useRouter();
6526
const route = useRoute();
6627
const { $feedbackFusion, $publicFeedbackFusion } = useNuxtApp();
6728
const { t } = useI18n();
@@ -86,8 +47,6 @@ const breadcrumbs = ref([
8647
disabled: false,
8748
},
8849
]);
89-
const prompt = ref(undefined);
90-
const editPrompt = ref(undefined);
9150
9251
const editFields = ref([
9352
{
@@ -104,27 +63,19 @@ const editFields = ref([
10463
},
10564
]);
10665
107-
onMounted(async () => {
108-
await authorization.fetch();
109-
110-
if (!authorization.hasPermission("Prompt", "Read")) {
111-
return router.push("/");
112-
}
113-
114-
prompt.value = await $publicFeedbackFusion
66+
const fetch = async () => {
67+
return await $publicFeedbackFusion
11568
.getPrompt({ id: route.params.prompt }, useRpcOptions())
11669
.then((value) => value.response);
117-
118-
editPrompt.value = JSON.parse(JSON.stringify(prompt.value));
119-
});
70+
};
12071
12172
const deletePrompt = (id: number) => async () => {
12273
await $feedbackFusion.deletePrompt({ id }, useRpcOptions());
12374
};
12475
125-
const save = async () => {
126-
await $feedbackFusion
127-
.updatePrompt(editPrompt.value, useRpcOptions())
128-
.then((value) => (prompt.value = value.response));
76+
const edit = (prompt) => async () => {
77+
return await $feedbackFusion
78+
.updatePrompt(prompt, useRpcOptions())
79+
.then((value) => value.response);
12980
};
13081
</script>

0 commit comments

Comments
 (0)