Skip to content

Commit

Permalink
Track merge and unmerge operations in frontend (#2532)
Browse files Browse the repository at this point in the history
Co-authored-by: Gasper Grom <[email protected]>
  • Loading branch information
skwowet and gaspergrom authored Aug 6, 2024
1 parent c100bab commit 363009e
Show file tree
Hide file tree
Showing 21 changed files with 346 additions and 8 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
<template>
<div v-if="props.contributor.activitySycning?.state === MergeActionState.IN_PROGRESS" class="pt-12 flex flex-col items-center">
<lf-icon name="loader-4-line" :size="40" class="text-gray-300 animate-spin" />
<h6 class="text-center py-3">
Syncing activities...
</h6>
<p class="text-center text-medium text-gray-500">
Re-syncing all the activities as this person was recently
{{ props.contributor.activitySycning?.operationType === 'merge' ? 'merged' : 'unmerged' }}.<br>
This process may take some minutes.
</p>
</div>
<div v-else-if="props.contributor.activitySycning?.state === MergeActionState.ERROR" class="pt-12 flex flex-col items-center">
<lf-icon name="error-warning-line" :size="40" class="text-gray-300" />
<h6 class="text-center py-3">
Error syncing activities
</h6>
<p class="text-center text-medium text-gray-500">
An error occurred while syncing this profile activities.<br>
Please contact our support team.
</p>
</div>
<app-activity-timeline
v-else
:entity="props.contributor"
entity-type="member"
:show-affiliations="true"
Expand All @@ -12,6 +34,8 @@
import { Contributor } from '@/modules/contributor/types/Contributor';
import AppActivityTimeline from '@/modules/activity/components/activity-timeline.vue';
import { useRoute } from 'vue-router';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
import LfIcon from '@/ui-kit/icon/Icon.vue';
const props = defineProps<{
contributor: Contributor,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,14 @@
<p class="text-tiny text-secondary-300 mb-2">
# of activities
</p>
<p class="text-small text-gray-600">
<lf-loading
v-if="props.contributor.activitySycning?.state === MergeActionState.IN_PROGRESS"
:count="1"
height="1rem"
width="4rem"
class="rounded"
/>
<p v-else class="text-small text-gray-600">
{{ props.contributor.activityCount && formatNumber(props.contributor.activityCount) || '-' }}
</p>
</article>
Expand All @@ -57,6 +64,8 @@ import { formatNumber } from '@/utils/number';
import LfContributorEngagementLevel from '@/modules/contributor/components/shared/contributor-engagement-level.vue';
import LfContributorSentiment from '@/modules/contributor/components/shared/contributor-sentiment.vue';
import { Contributor } from '@/modules/contributor/types/Contributor';
import LfLoading from '@/ui-kit/loading/Loading.vue';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
const props = defineProps<{
contributor: Contributor,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<div v-if="inProgress" class="mr-4 z-50">
<lf-tooltip
placement="bottom"
:content="`Re-syncing all the activities as this profile was recently
${ props.contributor.activitySycning?.operationType === 'merge' ? 'merged' : 'unmerged' }. This process may take some minutes.`"
>
<div class="flex items-center gap-1.5 cursor-default">
<lf-icon name="loader-4-fill" :size="16" class="text-secondary-400 animate-spin" />
<p class="text-small text-secondary-400 font-semibold">
Syncing activities...
</p>
</div>
</lf-tooltip>
</div>
</template>
<script setup lang="ts">
import LfTooltip from '@/ui-kit/tooltip/Tooltip.vue';
import { Contributor } from '@/modules/contributor/types/Contributor';
import { computed } from 'vue';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
import LfIcon from '@/ui-kit/icon/Icon.vue';
const props = defineProps<{
contributor: Contributor,
}>();
const inProgress = computed(() => props.contributor.activitySycning?.state === MergeActionState.IN_PROGRESS);
</script>
<script lang="ts">
export default {
name: 'LfContributorSyncingActivities',
};
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@
<lf-contributor-details-header :contributor="contributor" />
</div>
<div class="flex items-center">
<lf-contributor-last-enrichment :contributor="contributor" class="mr-4" />
<lf-contributor-syncing-activities v-if="contributor.activitySycning?.state === MergeActionState.IN_PROGRESS" :contributor="contributor" />
<lf-contributor-last-enrichment v-else :contributor="contributor" class="mr-4" />
<div @mouseover.stop @mouseout.stop>
<lf-contributor-details-actions :contributor="contributor" @reload="fetchContributor()" />
</div>
Expand Down Expand Up @@ -48,7 +49,15 @@
Overview
</lf-tab>
<lf-tab v-model="tabs" name="activities">
Activities
<div class="flex items-center gap-1">
Activities
<lf-icon
v-if="contributor.activitySycning?.state === MergeActionState.ERROR"
name="error-warning-line"
:size="16"
class="text-red-500"
/>
</div>
</lf-tab>
<lf-tab v-model="tabs" name="notes">
Notes
Expand Down Expand Up @@ -100,6 +109,8 @@ import LfContributorDetailsHeader from '@/modules/contributor/components/details
import LfContributorDetailsActions from '@/modules/contributor/components/details/contributor-details-actions.vue';
import LfContributorLastEnrichment from '@/modules/contributor/components/shared/contributor-last-enrichment.vue';
import { useContributorStore } from '@/modules/contributor/store/contributor.store';
import LfContributorSyncingActivities from '@/modules/contributor/components/shared/contributor-syncing-activities.vue';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
const { getMemberCustomAttributes } = useMemberStore();
Expand Down
15 changes: 15 additions & 0 deletions frontend/src/modules/contributor/store/contributor.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,31 @@ import { useLfSegmentsStore } from '@/modules/lf/segments/store';
import { storeToRefs } from 'pinia';
import { ContributorApiService } from '@/modules/contributor/services/contributor.api.service';
import { Contributor } from '@/modules/contributor/types/Contributor';
import { MergeActionsService } from '@/shared/modules/merge/services/merge-actions.service';
import { MergeAction } from '@/shared/modules/merge/types/MemberActions';

export default {
getContributor(id: string): Promise<Contributor> {
const { selectedProjectGroup } = storeToRefs(useLfSegmentsStore());

return ContributorApiService.find(id, [selectedProjectGroup.value?.id as string])
.then((contributor) => {
this.contributor = contributor;
this.getContributorMergeActions(id);
return Promise.resolve(contributor);
});
},
getContributorMergeActions(id: string): Promise<MergeAction[]> {
return MergeActionsService.list(id)
.then((mergeActions) => {
this.contributor = {
...this.contributor,
// eslint-disable-next-line no-nested-ternary
activitySycning: mergeActions.length > 0 ? mergeActions[0] : null,
};
return Promise.resolve(mergeActions);
});
},
updateContributor(id: string, data: Partial<Contributor>) {
const { selectedProjectGroup } = storeToRefs(useLfSegmentsStore());
return ContributorApiService.update(id, data, [selectedProjectGroup.value?.id as string])
Expand Down
4 changes: 3 additions & 1 deletion frontend/src/modules/contributor/types/Contributor.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Organization } from '@/modules/organization/types/Organization';
import { MergeAction } from '@/shared/modules/merge/types/MemberActions';

export interface ContributorAttribute {
default: string;
Expand Down Expand Up @@ -82,5 +83,6 @@ export interface Contributor {
id: string;
name: string;
activityCount: string;
}[]
}[],
activitySycning: MergeAction | null;
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ import LfButton from '@/ui-kit/button/Button.vue';
import AppMemberMergeSimilarity from '@/modules/member/components/suggestions/member-merge-similarity.vue';
import useProductTracking from '@/shared/modules/monitoring/useProductTracking';
import { EventType, FeatureEventKey } from '@/shared/modules/monitoring/types/event';
import { useContributorStore } from '@/modules/contributor/store/contributor.store';
import { MemberService } from '../member-service';
const props = defineProps({
Expand All @@ -164,6 +165,7 @@ const props = defineProps({
const emit = defineEmits(['reload']);
const { trackEvent } = useProductTracking();
const { getContributorMergeActions } = useContributorStore();
const membersToMerge = ref([]);
const primary = ref(0);
Expand Down Expand Up @@ -248,7 +250,7 @@ const ignoreSuggestion = () => {
MemberService.addToNoMerge(...membersToMerge.value.members)
.then(() => {
Message.success('Merging suggestion ignored successfully');
getContributorMergeActions();
const nextIndex = offset.value >= (count.value - 1) ? Math.max(count.value - 2, 0) : offset.value;
fetch(nextIndex);
changed.value = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,7 @@ import { storeToRefs } from 'pinia';
import useProductTracking from '@/shared/modules/monitoring/useProductTracking';
import { EventType, FeatureEventKey } from '@/shared/modules/monitoring/types/event';
import LfIcon from '@/ui-kit/icon/Icon.vue';
import { useContributorStore } from '@/modules/contributor/store/contributor.store';
import AppMemberSuggestionsDetails from './suggestions/member-merge-suggestions-details.vue';
const props = defineProps({
Expand All @@ -292,6 +293,7 @@ const { doFind } = mapActions('member');
const lsSegmentsStore = useLfSegmentsStore();
const { selectedProjectGroup } = storeToRefs(lsSegmentsStore);
const { getContributorMergeActions } = useContributorStore();
const unmerging = ref(false);
const fetchingPreview = ref(false);
Expand Down Expand Up @@ -364,6 +366,7 @@ const unmerge = () => {
MemberService.unmerge(props.modelValue?.id, preview.value)
.then(() => {
getContributorMergeActions(props.modelValue?.id);
Message.info(
"We're finalizing profiles merging. We will let you know once the process is completed.",
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,27 @@
<template>
<div v-if="props.organization.activitySycning?.state === MergeActionState.IN_PROGRESS" class="pt-12 flex flex-col items-center">
<lf-icon name="loader-4-line" :size="40" class="text-gray-300 animate-spin" />
<h6 class="text-center py-3">
Syncing activities...
</h6>
<p class="text-center text-medium text-gray-500">
Re-syncing all the activities as this organization was recently
{{ props.organization.activitySycning?.operationType === 'merge' ? 'merged' : 'unmerged' }}.<br>
This process may take some minutes.
</p>
</div>
<div v-else-if="props.organization.activitySycning?.state === MergeActionState.ERROR" class="pt-12 flex flex-col items-center">
<lf-icon name="error-warning-line" :size="40" class="text-gray-300" />
<h6 class="text-center py-3">
Error syncing activities
</h6>
<p class="text-center text-medium text-gray-500">
An error occurred while syncing this organization activities.<br>
Please contact our support team.
</p>
</div>
<app-activity-timeline
v-else
:entity="{
...props.organization,
organizations: [props.organization],
Expand All @@ -12,6 +34,8 @@
<script setup lang="ts">
import { Organization } from '@/modules/organization/types/Organization';
import AppActivityTimeline from '@/modules/activity/components/activity-timeline.vue';
import LfIcon from '@/ui-kit/icon/Icon.vue';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
const props = defineProps<{
organization: Organization,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,14 @@
<p class="text-tiny text-secondary-300 mb-2">
# of activities
</p>
<p class="text-small text-gray-600">
<lf-loading
v-if="props.organization.activitySycning?.state === MergeActionState.IN_PROGRESS"
:count="1"
height="1rem"
width="4rem"
class="rounded"
/>
<p v-else class="text-small text-gray-600">
{{ props.organization.activityCount && formatNumber(props.organization.activityCount) || '-' }}
</p>
</article>
Expand All @@ -43,6 +50,8 @@ import { Organization } from '@/modules/organization/types/Organization';
import pluralize from 'pluralize';
import { onMounted, ref } from 'vue';
import { MemberService } from '@/modules/member/member-service';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
import LfLoading from '@/ui-kit/loading/Loading.vue';
const props = defineProps<{
organization: Organization,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ import useProductTracking from '@/shared/modules/monitoring/useProductTracking';
import { EventType, FeatureEventKey } from '@/shared/modules/monitoring/types/event';
import { Platform } from '@/shared/modules/platform/types/Platform';
import LfIcon from '@/ui-kit/icon/Icon.vue';
import { useOrganizationStore } from '@/modules/organization/store/pinia';
const props = defineProps({
modelValue: {
Expand All @@ -218,6 +219,8 @@ const fetchingPreview = ref(false);
const preview = ref(null);
const selectedIdentity = ref(null);
const { getOrganizationMergeActions } = useOrganizationStore();
const parseIdentityValues = (identity) => {
const splittedIdentity = identity.value?.split(':');
Expand Down Expand Up @@ -315,6 +318,7 @@ const unmerge = () => {
OrganizationService.unmerge(props.modelValue?.id, preview.value)
.then(() => {
getOrganizationMergeActions(props.modelValue?.id);
Message.info(
'We’re syncing all activities of the unmerged organization. We will let you know once the process is completed.',
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>
<div v-if="props.organization.activitySycning?.state === MergeActionState.IN_PROGRESS" class="mr-4 z-50">
<lf-tooltip
placement="bottom"
:content="`Re-syncing all the activities as this organization was recently
${props.organization.activitySycning?.operationType === 'merge' ? 'merged' : 'unmerged'}. This process may take some minutes.`"
>
<div class="flex items-center gap-1.5 cursor-default">
<lf-icon name="loader-4-fill" :size="16" class="text-secondary-400 animate-spin" />
<p class="text-small text-secondary-400 font-semibold">
Syncing activities...
</p>
</div>
</lf-tooltip>
</div>
</template>
<script setup lang="ts">
import LfTooltip from '@/ui-kit/tooltip/Tooltip.vue';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
import LfIcon from '@/ui-kit/icon/Icon.vue';
import { Organization } from '@/modules/organization/types/Organization';
const props = defineProps<{
organization: Organization,
}>();
</script>
<script lang="ts">
export default {
name: 'LfOrganizationSyncingActivities',
};
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,12 @@
<lf-organization-details-header :organization="organization" />
</div>
<div class="flex items-center">
<lf-organization-last-enrichment :organization="organization" class="mr-4" />
<lf-organization-syncing-activities
v-if="organization.activitySycning?.state === MergeActionState.IN_PROGRESS"
:organization="organization"
class="mr-4"
/>
<lf-organization-last-enrichment v-else :organization="organization" class="mr-4" />
<div @mouseover.stop @mouseout.stop>
<lf-organization-details-actions :organization="organization" @reload="fetchOrganization()" />
</div>
Expand Down Expand Up @@ -60,7 +65,15 @@
People
</lf-tab>
<lf-tab v-model="tabs" name="activities">
Activities
<div class="flex items-center gap-1">
Activities
<lf-icon
v-if="organization.activitySycning?.state === MergeActionState.ERROR"
name="error-warning-line"
:size="16"
class="text-red-500"
/>
</div>
</lf-tab>
</lf-tabs>
</div>
Expand Down Expand Up @@ -112,6 +125,9 @@ import LfOrganizationDetailsEmails from '@/modules/organization/components/detai
import { useOrganizationStore } from '@/modules/organization/store/pinia';
import LfOrganizationDetailsContributors
from '@/modules/organization/components/details/organization-details-contributors.vue';
import LfOrganizationSyncingActivities
from '@/modules/organization/components/shared/organization-syncing-activities.vue';
import { MergeActionState } from '@/shared/modules/merge/types/MemberActions';
const lsSegmentsStore = useLfSegmentsStore();
const { selectedProjectGroup } = storeToRefs(lsSegmentsStore);
Expand Down
Loading

0 comments on commit 363009e

Please sign in to comment.