Skip to content

Commit

Permalink
Frontend display for syncing activities
Browse files Browse the repository at this point in the history
  • Loading branch information
gaspergrom committed Aug 1, 2024
1 parent 6e6fa8d commit c61f6de
Show file tree
Hide file tree
Showing 12 changed files with 216 additions and 3 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
<template>
<div v-if="props.contributor.activitySycning === 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 merged.<br>
This process may take some minutes.
</p>
</div>
<app-activity-timeline
v-else
:entity="props.contributor"
entity-type="member"
:show-affiliations="true"
Expand All @@ -12,6 +23,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 === 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 merged. 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 === MergeActionState.IN_PROGRESS);
// const error = computed(() => props.contributor.activitySycning === MergeActionState.ERROR);
</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" :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 @@ -100,6 +101,7 @@ 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';
const { getMemberCustomAttributes } = useMemberStore();
Expand Down
17 changes: 17 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,33 @@ 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) => {
const inProgress = mergeActions.some((action) => action.state === 'in-progress');
const error = mergeActions.some((action) => action.state === 'error');
this.contributor = {
...this.contributor,
// eslint-disable-next-line no-nested-ternary
activitySycning: inProgress ? 'in-progress' : (error ? 'error' : ''),
};
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
3 changes: 2 additions & 1 deletion frontend/src/modules/contributor/types/Contributor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,5 +82,6 @@ export interface Contributor {
id: string;
name: string;
activityCount: string;
}[]
}[],
activitySycning: string;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import authAxios from '@/shared/axios/auth-axios';
import { AuthService } from '@/modules/auth/services/auth.service';
import { MergeAction } from '@/shared/modules/merge/types/MemberActions';

export class MergeActionsService {
static async list(entityId: string, type: string = 'member'): Promise<MergeAction[]> {
const tenantId = AuthService.getTenantId();

const response = await authAxios.get(
`/tenant/${tenantId}/mergeActions`,
{
params: {
filter: {
entityId,
type,
},
},
},
);

return response.data;
}
}
12 changes: 12 additions & 0 deletions frontend/src/shared/modules/merge/types/MemberActions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export enum MergeActionState {
IN_PROGRESS = 'in-progress',
DONE = 'done',
ERROR = 'error',
}

export interface MergeAction {
operationType: string;
primaryId: string;
secondaryId: string;
state: MergeActionState;
}
1 change: 1 addition & 0 deletions frontend/src/ui-kit/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
@import 'dropdown/dropdown';
@import 'field/field';
@import 'input/input';
@import 'loading/loading';
@import 'modal/modal';
@import 'field-message/field-message';
@import 'radio/radio';
Expand Down
34 changes: 34 additions & 0 deletions frontend/src/ui-kit/loading/Loading.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import LfLoading from './Loading.vue';

export default {
title: 'LinuxFoundation/Loading',
component: LfLoading,
tags: ['autodocs'],
argTypes: {
// Propr
height: {
description: 'Loader height',
defaultValue: '100px',
control: 'text',
},
width: {
description: 'Loader width',
defaultValue: '100%',
control: 'text',
},
count: {
description: 'Number of loaders',
defaultValue: '1',
control: 'number',
},
},
};

export const Default = {
label: 'Primary',
args: {
height: '100px',
width: '100%',
count: 1,
},
};
29 changes: 29 additions & 0 deletions frontend/src/ui-kit/loading/Loading.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<template>
<div>
<div
v-for="el of new Array(props.count)"
:key="el"
class="c-loading"
v-bind="$attrs"
:style="{ height: props.height, width: props.width }"
/>
</div>
</template>

<script setup lang="ts">
const props = withDefaults(defineProps<{
height?: string,
width?: string,
count?: number,
}>(), {
height: '100px',
width: '100%',
count: 1,
});
</script>

<script lang="ts">
export default {
name: 'LfLoading',
};
</script>
36 changes: 36 additions & 0 deletions frontend/src/ui-kit/loading/loading.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* ---------------------------------- *\
Loading
\* ---------------------------------- */

@keyframes shimmer {
100% {
transform: translateX(100%);
}
}

.c-loading {
display: inline-block;
height: 1em;
position: relative;
overflow: hidden;
background-color: var(--lf-color-secondary-50);

&:after {
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
transform: translateX(-100%);
background-image: linear-gradient(
90deg,
rgba(255, 255, 255, 0) 0%,
rgba(255, 255, 255, 0.2) 20.24%,
rgba(255, 255, 255, 0.5) 42.57%,
rgba(255, 255, 255, 0) 66.35%
);
animation: shimmer 1.5s infinite;
content: '';
}
}

0 comments on commit c61f6de

Please sign in to comment.