Skip to content

Commit

Permalink
Automatic enrichment frontend - lfx (#2002)
Browse files Browse the repository at this point in the history
Co-authored-by: Gasper Grom <gasper.grom@gmail.com>
Co-authored-by: Uros Marolt <uros@crowd.dev>
  • Loading branch information
3 people authored Jan 3, 2024
1 parent ea365ae commit 25775d1
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 354 deletions.
6 changes: 6 additions & 0 deletions frontend/public/icons/crowd-icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
163 changes: 1 addition & 162 deletions frontend/src/modules/member/components/list/member-list-toolbar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,6 @@
<i class="ri-lg ri-group-line mr-1" />
Merge contributors
</el-dropdown-item>
<el-tooltip
placement="top"
content="Selected contributors lack an associated GitHub profile or Email"
:disabled="
elegibleEnrichmentMembersIds.length
|| isEditLockedForSampleData
"
popper-class="max-w-[260px]"
>
<span>
<el-dropdown-item
:command="{ action: 'enrichMember' }"
:disabled="
!elegibleEnrichmentMembersIds.length
|| isEditLockedForSampleData
"
class="mb-1"
>
<app-svg
name="enrichment"
class="max-w-[16px] h-4"
color="#9CA3AF"
/>
<span class="ml-2">{{
enrichmentLabel
}}</span>
</el-dropdown-item>
</span>
</el-tooltip>
<el-dropdown-item
:command="{
action: 'markAsTeamMember',
Expand Down Expand Up @@ -115,7 +86,6 @@
</template>

<script setup>
import { computed, ref } from 'vue';
import { MemberPermissions } from '@/modules/member/member-permissions';
import { useMemberStore } from '@/modules/member/store/pinia';
Expand All @@ -126,21 +96,14 @@ import ConfirmDialog from '@/shared/dialog/confirm-dialog';
import Message from '@/shared/message/message';
import pluralize from 'pluralize';
import { getExportMax, showExportDialog, showExportLimitDialog } from '@/modules/member/member-export-limit';
import {
checkEnrichmentLimit,
checkEnrichmentPlan,
getEnrichmentMax,
showEnrichmentLoadingMessage,
} from '@/modules/member/member-enrichment';
import AppBulkEditAttributePopover from '@/modules/member/components/bulk/bulk-edit-attribute-popover.vue';
import AppTagPopover from '@/modules/tag/components/tag-popover.vue';
import AppSvg from '@/shared/svg/svg.vue';
const { currentUser, currentTenant } = mapGetters('auth');
const { doRefreshCurrentUser } = mapActions('auth');
const memberStore = useMemberStore();
const { selectedMembers, filters } = storeToRefs(memberStore);
const { fetchMembers, getMemberCustomAttributes } = memberStore;
const { fetchMembers } = memberStore;
const bulkTagsUpdateVisible = ref(false);
const bulkAttributesUpdateVisible = ref(false);
Expand All @@ -166,37 +129,6 @@ const isDeleteLockedForSampleData = computed(() => (
).destroyLockedForSampleData
));
const elegibleEnrichmentMembersIds = computed(() => selectedMembers.value
.filter(
(r) => r.username?.github?.length || r.emails?.length,
)
.map((item) => item.id));
const enrichedMembers = computed(() => selectedMembers.value.filter((r) => r.lastEnriched)
.length);
const enrichmentLabel = computed(() => {
if (
enrichedMembers.value
&& enrichedMembers.value
=== elegibleEnrichmentMembersIds.value.length
) {
return `Re-enrich ${pluralize(
'contributor',
selectedIds.value.length,
false,
)}`;
}
return `Enrich ${pluralize(
'contributor',
selectedIds.value.length,
false,
)}`;
});
const selectedIds = computed(() => selectedMembers.value.map((item) => item.id));
const markAsTeamMemberOptions = computed(() => {
const isTeamView = filters.value.settings.teamMember === 'filter';
const membersCopy = pluralize(
Expand Down Expand Up @@ -362,99 +294,6 @@ const handleCommand = async (command) => {
await handleAddTags();
} else if (command.action === 'destroyAll') {
await doDestroyAllWithConfirm();
} else if (command.action === 'enrichMember') {
const enrichments = elegibleEnrichmentMembersIds.value.length;
let doEnrich = false;
let reEnrichmentMessage = null;
if (enrichedMembers.value) {
reEnrichmentMessage = enrichedMembers.value === 1
? 'You selected 1 contributor that was already enriched. If you proceed, this contributor will be re-enriched and counted towards your quota.'
: `You selected ${enrichedMembers.value} contributors that were already enriched. If you proceed,
these contributors will be re-enriched and counted towards your quota.`;
}
// All members are elegible for enrichment
if (enrichments === selectedIds.value.length) {
if (!enrichedMembers.value) {
doEnrich = true;
} else {
try {
await ConfirmDialog({
type: 'warning',
title: 'Some contributors were already enriched',
message: reEnrichmentMessage,
confirmButtonText: `Proceed with enrichment (${pluralize(
'contributor',
enrichments,
true,
)})`,
cancelButtonText: 'Cancel',
icon: 'ri-alert-line',
});
doEnrich = true;
} catch (error) {
console.error(error);
}
}
} else {
try {
await ConfirmDialog({
type: 'warning',
title:
'Some contributors lack an associated GitHub profile or Email',
message:
'Contributor enrichment requires an associated GitHub profile or Email. If you proceed, only the contributors who fulfill '
+ 'this requirement will be enriched and counted towards your quota.',
confirmButtonText: `Proceed with enrichment (${pluralize(
'contributor',
enrichments,
true,
)})`,
highlightedInfo: reEnrichmentMessage,
cancelButtonText: 'Cancel',
icon: 'ri-alert-line',
});
doEnrich = true;
} catch (error) {
console.error(error);
}
}
if (doEnrich) {
const { memberEnrichmentCount } = currentTenant.value;
const planEnrichmentCountMax = getEnrichmentMax(
currentTenant.value.plan,
);
// Check if it is trying to enrich more members than
// the number available for the current tenant plan
if (
checkEnrichmentPlan({
enrichmentCount:
memberEnrichmentCount + elegibleEnrichmentMembersIds.value.length,
planEnrichmentCountMax,
})
) {
return;
}
// Check if it has reached enrichment maximum
// If so, show dialog to upgrade plan
if (checkEnrichmentLimit(planEnrichmentCountMax)) {
return;
}
// Show enrichment loading message
showEnrichmentLoadingMessage({ isBulk: true });
await MemberService.enrichMemberBulk(elegibleEnrichmentMembersIds.value);
fetchMembers({ reload: true });
await getMemberCustomAttributes();
}
}
};
</script>
Expand Down
59 changes: 7 additions & 52 deletions frontend/src/modules/member/components/member-dropdown-content.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,39 +19,6 @@
<span class="text-xs">Edit contributor</span>
</button>
</router-link>
<el-tooltip
placement="top"
content="
Contributor enrichment requires an associated GitHub profile or Email
"
:disabled="!isEnrichmentDisabledForMember"
popper-class="max-w-[260px]"
>
<span>
<button
class="h-10 el-dropdown-menu__item w-full mb-1"
type="button"
@click="
handleCommand({
action: Actions.ENRICH_CONTACT,
member,
})
"
>
<app-svg name="enrichment" class="max-w-[16px] h-4" color="#9CA3AF" />
<span
class="ml-2 text-xs"
:class="{
'text-gray-400': isEnrichmentDisabledForMember,
}"
>{{
member.lastEnriched
? 'Re-enrich contributor'
: 'Enrich contributor'
}}</span>
</button>
</span>
</el-tooltip>
<button
v-if="isFindGitHubFeatureEnabled"
class="h-10 el-dropdown-menu__item w-full mb-1"
Expand Down Expand Up @@ -219,10 +186,12 @@ import { useMemberStore } from '@/modules/member/store/pinia';
import { CrowdIntegrations } from '@/integrations/integrations-config';
import { HubspotEntity } from '@/integrations/hubspot/types/HubspotEntity';
import { HubspotApiService } from '@/integrations/hubspot/hubspot.api.service';
import {
FeatureFlag, FEATURE_FLAGS,
} from '@/utils/featureFlag';
import { useStore } from 'vuex';
import { useRoute } from 'vue-router';
import { computed } from 'vue';
import { FEATURE_FLAGS, FeatureFlag } from '@/utils/featureFlag';
import { Member } from '../types/Member';
enum Actions {
Expand All @@ -233,7 +202,6 @@ enum Actions {
MARK_CONTACT_AS_BOT = 'markContactAsBot',
UNMARK_CONTACT_AS_BOT = 'unmarkContactAsBot',
MERGE_CONTACT = 'mergeContact',
ENRICH_CONTACT = 'enrichContact',
FIND_GITHUB = 'findGithub'
}
Expand All @@ -246,7 +214,7 @@ const store = useStore();
const route = useRoute();
const { currentUser, currentTenant } = mapGetters('auth');
const { doFind, doEnrich } = mapActions('member');
const { doFind } = mapActions('member');
const memberStore = useMemberStore();
Expand All @@ -260,12 +228,10 @@ const isDeleteLockedForSampleData = computed(
.destroyLockedForSampleData,
);
const isEnrichmentDisabledForMember = computed(
() => !props.member.username?.github?.length && !props.member.emails?.length,
const isSyncingWithHubspot = computed(
() => props.member.attributes?.syncRemote?.hubspot || false,
);
const isSyncingWithHubspot = computed(() => props.member.attributes?.syncRemote?.hubspot || false);
const isHubspotConnected = computed(() => {
const hubspot = CrowdIntegrations.getMappedConfig('hubspot', store);
const enabledFor = hubspot.settings?.enabledFor || [];
Expand All @@ -282,7 +248,7 @@ const isHubspotDisabledForMember = computed(
const isHubspotActionDisabled = computed(() => !isHubspotConnected.value || isHubspotDisabledForMember.value);
const isFindingGitHubDisabled = computed(() => (
props.member.username?.github
!!props.member.username?.github
));
const isFindGitHubFeatureEnabled = computed(() => FeatureFlag.isFlagEnabled(
Expand Down Expand Up @@ -443,17 +409,6 @@ const handleCommand = async (command: {
return;
}
// Enrich contact
if (command.action === Actions.ENRICH_CONTACT) {
doManualAction({
actionFn: doEnrich(command.member.id, command.member.segmentIds),
}).then(() => {
memberStore.fetchMembers({ reload: true });
});
return;
}
if (command.action === Actions.FIND_GITHUB) {
emit('closeDropdown');
emit('findGithub');
Expand Down
Loading

0 comments on commit 25775d1

Please sign in to comment.