Skip to content

Commit 1d1e2f7

Browse files
authored
feat: enhance insights project form with old/new data toggle for fields (#3243)
1 parent 7f01a80 commit 1d1e2f7

2 files changed

Lines changed: 169 additions & 13 deletions

File tree

frontend/src/modules/admin/modules/insights-projects/components/lf-insights-project-add-details-tab.vue

Lines changed: 138 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,26 @@
22
<!-- Project name -->
33
<article class="mb-5">
44
<lf-field label-text="Project name" :required="true">
5+
<template #label>
6+
<label class="c-field__label leading-5">
7+
Project name <span class="c-field__required">*</span>
8+
</label>
9+
<div
10+
v-if="newForm && oldForm?.name !== newForm.name"
11+
class="flex items-center p-1 rounded-md bg-gray-100 gap-2 cursor-pointer text-gray-500 text-tiny font-semibold"
12+
>
13+
<span
14+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
15+
:class="switcher.name ? 'bg-white text-gray-900' : ''"
16+
@click="!switcher.name ? useOldData(['name']) : null"
17+
>Old data</span>
18+
<span
19+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
20+
:class="switcher.name ? '' : 'bg-white text-gray-900'"
21+
@click="switcher.name ? useNewData(['name']) : null"
22+
>updated data</span>
23+
</div>
24+
</template>
525
<lf-input
626
v-model="cForm.name"
727
class="h-10"
@@ -19,6 +39,26 @@
1939
<!-- Description -->
2040
<article class="mb-5">
2141
<lf-field label-text="Description" :required="true">
42+
<template #label>
43+
<label class="c-field__label leading-5">
44+
Description <span class="c-field__required">*</span>
45+
</label>
46+
<div
47+
v-if="newForm && oldForm?.description !== newForm.description"
48+
class="flex items-center p-1 rounded-md bg-gray-100 gap-2 cursor-pointer text-gray-500 text-tiny font-semibold"
49+
>
50+
<span
51+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
52+
:class="switcher.description ? 'bg-white text-gray-900' : ''"
53+
@click="!switcher.description ? useOldData(['description']) : null"
54+
>Old data</span>
55+
<span
56+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
57+
:class="switcher.description ? '' : 'bg-white text-gray-900'"
58+
@click="switcher.description ? useNewData(['description']) : null"
59+
>updated data</span>
60+
</div>
61+
</template>
2262
<lf-textarea
2363
v-model="cForm.description"
2464
:invalid="$v.description.$invalid && $v.description.$dirty"
@@ -35,6 +75,26 @@
3575
<!-- Logo -->
3676
<article class="mb-5">
3777
<lf-field label-text="Logo URL" :required="true">
78+
<template #label>
79+
<label class="c-field__label leading-5">
80+
Logo URL <span class="c-field__required">*</span>
81+
</label>
82+
<div
83+
v-if="newForm && oldForm?.logoUrl !== newForm.logoUrl"
84+
class="flex items-center p-1 rounded-md bg-gray-100 gap-2 cursor-pointer text-gray-500 text-tiny font-semibold"
85+
>
86+
<span
87+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
88+
:class="switcher.logoUrl ? 'bg-white text-gray-900' : ''"
89+
@click="!switcher.logoUrl ? useOldData(['logoUrl']) : null"
90+
>Old data</span>
91+
<span
92+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
93+
:class="switcher.logoUrl ? '' : 'bg-white text-gray-900'"
94+
@click="switcher.logoUrl ? useNewData(['logoUrl']) : null"
95+
>updated data</span>
96+
</div>
97+
</template>
3898
<lf-input
3999
v-model="cForm.logoUrl"
40100
class="h-10"
@@ -52,6 +112,24 @@
52112
<!-- topics -->
53113
<article class="mb-5">
54114
<lf-field label-text="Topics">
115+
<template #label>
116+
<label class="c-field__label leading-5"> Topics </label>
117+
<div
118+
v-if="newForm"
119+
class="flex items-center p-1 rounded-md bg-gray-100 gap-2 cursor-pointer text-gray-500 text-tiny font-semibold"
120+
>
121+
<span
122+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
123+
:class="switcher.keywords ? 'bg-white text-gray-900' : ''"
124+
@click="!switcher.keywords ? useOldData(['keywords']) : null"
125+
>Old data</span>
126+
<span
127+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
128+
:class="switcher.keywords ? '' : 'bg-white text-gray-900'"
129+
@click="switcher.keywords ? useNewData(['keywords']) : null"
130+
>updated data</span>
131+
</div>
132+
</template>
55133
<app-keywords-input
56134
v-model="cForm.keywords"
57135
:show-hint="true"
@@ -102,9 +180,32 @@
102180

103181
<hr class="my-5" />
104182

105-
<h6 class="font-semibold mb-6">
106-
Website & Social accounts
107-
</h6>
183+
<div class="flex items-center justify-between mb-6">
184+
<h6 class="font-semibold">
185+
Website & Social accounts
186+
</h6>
187+
<div
188+
v-if="newForm"
189+
class="flex items-center p-1 rounded-md bg-gray-100 gap-2 cursor-pointer text-gray-500 text-tiny font-semibold"
190+
>
191+
<span
192+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
193+
:class="switcher.website ? 'bg-white text-gray-900' : ''"
194+
@click="
195+
!switcher.website
196+
? useOldData(['website', 'github', 'twitter'])
197+
: null
198+
"
199+
>Old data</span>
200+
<span
201+
class="hover:bg-gray-200 px-1.5 py-0.5 rounded-xmd"
202+
:class="switcher.website ? '' : 'bg-white text-gray-900'"
203+
@click="
204+
switcher.website ? useNewData(['website', 'github', 'twitter']) : null
205+
"
206+
>updated data</span>
207+
</div>
208+
</div>
108209

109210
<!-- Website -->
110211
<article class="mb-5">
@@ -158,18 +259,51 @@ import LfTextarea from '@/ui-kit/textarea/Textarea.vue';
158259
import LfFieldMessages from '@/ui-kit/field-messages/FieldMessages.vue';
159260
import LfIcon from '@/ui-kit/icon/Icon.vue';
160261
import useVuelidate from '@vuelidate/core';
161-
import { reactive } from 'vue';
262+
import { reactive, ref } from 'vue';
162263
import AppKeywordsInput from '@/shared/form/keywords-input.vue';
163264
import { InsightsProjectAddFormModel } from '../models/insights-project-add-form.model';
164265
import LfInsightsProjectsAddCollectionDropdown from './add-details-tab/lf-insights-projects-add-collection-dropdown.vue';
165266
import LfInsightsProjectsAddOrganizationsDropdown from './add-details-tab/lf-insights-projects-add-organizations-dropdown.vue';
166267
167268
const props = defineProps<{
168269
form: InsightsProjectAddFormModel;
270+
oldForm?: InsightsProjectAddFormModel;
271+
newForm?: InsightsProjectAddFormModel;
169272
rules: any;
170273
}>();
171274
const cForm = reactive(props.form);
172275
const $v = useVuelidate(props.rules, cForm);
276+
const switcher = ref<Record<string, boolean>>({
277+
name: true,
278+
description: true,
279+
logoUrl: true,
280+
keywords: true,
281+
github: true,
282+
twitter: true,
283+
website: true,
284+
});
285+
286+
const useNewData = (fields: string[]) => {
287+
fields.forEach((field) => {
288+
switcher.value[field] = false;
289+
if (props.newForm) {
290+
cForm[field as keyof InsightsProjectAddFormModel] = props.newForm[
291+
field as keyof InsightsProjectAddFormModel
292+
] as any;
293+
}
294+
});
295+
};
296+
297+
const useOldData = (fields: string[]) => {
298+
fields.forEach((field) => {
299+
switcher.value[field] = true;
300+
if (props.oldForm) {
301+
cForm[field as keyof InsightsProjectAddFormModel] = props.oldForm[
302+
field as keyof InsightsProjectAddFormModel
303+
] as any;
304+
}
305+
});
306+
};
173307
</script>
174308

175309
<script lang="ts">

frontend/src/modules/admin/modules/insights-projects/components/lf-insights-project-add.vue

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@
7070
<lf-insights-project-add-details-tab
7171
v-if="activeTab === 'details'"
7272
:form="form"
73+
:old-form="oldForm"
74+
:new-form="newForm"
7375
:rules="rules"
7476
/>
7577
<lf-insights-project-add-repository-tab
@@ -129,6 +131,7 @@ import { TanstackKey } from '@/shared/types/tanstack';
129131
import LfInsightsProjectAddDetailsTab from './lf-insights-project-add-details-tab.vue';
130132
import LfInsightsProjectAddRepositoryTab from './lf-insights-project-add-repository-tab.vue';
131133
import {
134+
InsightsProjectDetailsResponse,
132135
InsightsProjectModel,
133136
InsightsProjectRequest,
134137
} from '../models/insights-project.model';
@@ -192,6 +195,8 @@ const initialFormState: InsightsProjectAddFormModel = {
192195
),
193196
};
194197
const form = reactive<InsightsProjectAddFormModel>(cloneDeep(initialFormState));
198+
let oldForm: InsightsProjectAddFormModel | undefined;
199+
let newForm: InsightsProjectAddFormModel | undefined;
195200
196201
const rules = {
197202
name: {
@@ -247,7 +252,9 @@ const { isLoading, isSuccess, data } = useQuery({
247252
});
248253
249254
const onProjectSelection = ({ project }: any) => {
250-
Object.assign(form, initialFormState);
255+
if (!isEditForm.value) {
256+
Object.assign(form, initialFormState);
257+
}
251258
fetchProjectDetails(project);
252259
fetchWidgets(project.id);
253260
@@ -328,14 +335,14 @@ const fetchProjectDetails = async (project: any) => {
328335
InsightsProjectsService.getInsightsProjectDetails(project.id)
329336
.then((res) => {
330337
if (res) {
331-
form.name = res.name || '';
332-
form.description = res.description || '';
333-
form.github = res.github || '';
334-
form.twitter = res.twitter || '';
335-
form.website = res.website || '';
336-
form.logoUrl = res.logoUrl || '';
337-
form.keywords = res.topics || [];
338-
} else {
338+
if (isEditForm.value) {
339+
oldForm = cloneDeep(form);
340+
newForm = cloneDeep(form);
341+
newForm = assignProjectDetails(res, newForm);
342+
} else {
343+
fillForm(assignProjectDetails(res, form));
344+
}
345+
} else if (isEditForm.value) {
339346
form.name = project.name;
340347
form.description = project.description;
341348
form.logoUrl = project.url;
@@ -352,6 +359,21 @@ const fetchProjectDetails = async (project: any) => {
352359
});
353360
};
354361
362+
const assignProjectDetails = (
363+
res: InsightsProjectDetailsResponse,
364+
form: InsightsProjectAddFormModel,
365+
) => {
366+
const updatedForm = cloneDeep(form);
367+
updatedForm.name = res.name || '';
368+
updatedForm.description = res.description || '';
369+
updatedForm.github = res.github || '';
370+
updatedForm.twitter = res.twitter || '';
371+
updatedForm.website = res.website || '';
372+
updatedForm.logoUrl = res.logoUrl || '';
373+
updatedForm.keywords = res.topics || [];
374+
return updatedForm;
375+
};
376+
355377
const fetchWidgets = async (segmentId: string) => {
356378
isLoadingWidgets.value = true;
357379
InsightsProjectsService.getInsightsProjectWidgets(segmentId)

0 commit comments

Comments
 (0)