Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@
<link
rel="preload"
as="style"
href="https://cdn.jsdelivr.net/npm/remixicon@3.1.1/fonts/remixicon.css"
href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css"
/>

<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/remixicon@3.1.1/fonts/remixicon.css"
href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css"
media="print"
onload="this.media='all'"
/>
Expand All @@ -60,7 +60,7 @@
/>
<link
as="style"
href="https://cdn.jsdelivr.net/npm/remixicon@3.1.1/fonts/remixicon.css"
href="https://cdn.jsdelivr.net/npm/remixicon@3.5.0/fonts/remixicon.css"
/>
</noscript>
<script type="text/javascript">
Expand Down
29 changes: 5 additions & 24 deletions frontend/src/modules/automation/automation-limit.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,13 @@
import Plans from '@/security/plans';
import { router } from '@/router';
import ConfirmDialog from '@/shared/dialog/confirm-dialog';

const workflowMax = {
scale: 'unlimited',
enterprise: 'unlimited',
growth: 10,
essential: 2,
};
import { planLimits } from '@/security/plans-limits';

/**
* @param {*} plan tenant plan (Essential | Growth | Enterprise)
* @returns maximum number of workflows
*/
export const getWorkflowMax = (plan) => {
if (plan === Plans.values.scale) {
return workflowMax.scale;
}
if (plan === Plans.values.enterprise) {
return workflowMax.enterprise;
}
if (
plan === Plans.values.growth
) {
return workflowMax.growth;
}

return workflowMax.essential;
};
export const getWorkflowMax = (plan) => planLimits.automation[plan];

export const showWorkflowLimitDialog = ({
planWorkflowCountMax,
Expand All @@ -36,10 +16,11 @@ export const showWorkflowLimitDialog = ({
vertical: true,
type: 'danger',
title:
`You have reached the limit of ${planWorkflowCountMax} automations on your current plan`,
`You have reached the limit of ${planWorkflowCountMax} active automations on your current plan`,
message:
'Upgrade your plan to get unlimited automations and take full advantage of this feature',
'Upgrade your plan to increase the active automations quota and take full advantage of this feature',
confirmButtonText: 'Upgrade plan',
showCancelButton: false,
}).then(() => {
router.push('settings?activeTab=plans');
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,19 @@
</el-dropdown-item>
<el-tooltip
placement="top"
content="Selected members lack an associated GitHub profile or Email"
:content="!isEnrichmentFeatureEnabled()
? 'Upgrade your plan to increase your quota of available member enrichments'
: 'Selected members lack an associated GitHub profile or Email'"
:disabled="
elegibleEnrichmentMembersIds.length
|| isEditLockedForSampleData
|| isEditLockedForSampleData || isEnrichmentFeatureEnabled()
"
popper-class="max-w-[260px]"
>
<span>
<el-dropdown-item
:command="{ action: 'enrichMember' }"
:disabled="
!elegibleEnrichmentMembersIds.length
|| isEditLockedForSampleData
"
:disabled="isEnrichmentActionDisabled"
class="mb-1"
>
<app-svg
Expand Down Expand Up @@ -116,7 +115,7 @@

<script setup>

import { computed, ref } from 'vue';
import { computed, ref, onMounted } from 'vue';
import { MemberPermissions } from '@/modules/member/member-permissions';
import { useMemberStore } from '@/modules/member/store/pinia';
import { storeToRefs } from 'pinia';
Expand All @@ -127,7 +126,7 @@ import Message from '@/shared/message/message';
import pluralize from 'pluralize';
import { getExportMax, showExportDialog, showExportLimitDialog } from '@/modules/member/member-export-limit';
import {
checkEnrichmentLimit,
isEnrichmentFeatureEnabled,
checkEnrichmentPlan,
getEnrichmentMax,
showEnrichmentLoadingMessage,
Expand Down Expand Up @@ -220,6 +219,9 @@ const markAsTeamMemberOptions = computed(() => {
};
});

const isEnrichmentActionDisabled = computed(() => !elegibleEnrichmentMembersIds.value.length
|| isEditLockedForSampleData.value || !isEnrichmentFeatureEnabled());

const handleMergeMembers = () => {
const [firstMember, secondMember] = selectedMembers.value;
return MemberService.merge(firstMember, secondMember)
Expand All @@ -232,6 +234,10 @@ const handleMergeMembers = () => {
});
};

onMounted(() => {
doRefreshCurrentUser({});
});

const doDestroyAllWithConfirm = () => ConfirmDialog({
type: 'danger',
title: 'Delete members',
Expand Down Expand Up @@ -421,7 +427,7 @@ const handleCommand = async (command) => {

// Check if it has reached enrichment maximum
// If so, show dialog to upgrade plan
if (checkEnrichmentLimit(planEnrichmentCountMax)) {
if (!isEnrichmentFeatureEnabled()) {
return;
}

Expand Down
110 changes: 70 additions & 40 deletions frontend/src/modules/member/components/member-dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,10 @@
</router-link>
<el-tooltip
placement="top"
content="Member enrichment requires an associated GitHub profile or Email"
:disabled="!isEnrichmentDisabled"
:content="!isEnrichmentFeatureEnabled()
? 'Upgrade your plan to increase your quota of available member enrichments'
: 'Member enrichment requires an associated GitHub profile or Email'"
:disabled="isEnrichmentDisabledForMember || isEnrichmentFeatureEnabled()"
popper-class="max-w-[260px]"
>
<span>
Expand All @@ -48,10 +50,7 @@
member,
}"
class="h-10 mb-1"
:disabled="
isEnrichmentDisabled
|| isEditLockedForSampleData
"
:disabled="isEnrichmentActionDisabled"
>
<app-svg
name="enrichment"
Expand All @@ -61,7 +60,7 @@
<span
class="ml-2 text-xs"
:class="{
'text-gray-400': isEnrichmentDisabled,
'text-gray-400': isEnrichmentDisabledForMember,
}"
>{{
member.lastEnriched
Expand All @@ -85,34 +84,43 @@
</el-dropdown-item>

<!-- Hubspot -->
<el-dropdown-item
v-if="!isSyncingWithHubspot"
class="h-10"
:command="{
action: 'syncHubspot',
member: member,
}"
:disabled="!isHubspotConnected || member.emails.length === 0"
>
<app-svg name="hubspot" class="h-4 w-4 text-current" />
<span
class="text-xs pl-2"
>Sync with HubSpot</span>
</el-dropdown-item>
<el-dropdown-item
v-else
class="h-10"
:command="{
action: 'stopSyncHubspot',
member: member,
}"
:disabled="!isHubspotConnected || member.emails.length === 0"
<el-tooltip
placement="top"
content="Upgrade your plan to create a 2-way sync with HubSpot"
:disabled="isHubspotFeatureEnabled"
popper-class="max-w-[260px]"
>
<app-svg name="hubspot" class="h-4 w-4 text-current" />
<span
class="text-xs pl-2"
>Stop sync with HubSpot</span>
</el-dropdown-item>
<span>
<el-dropdown-item
v-if="!isSyncingWithHubspot"
class="h-10"
:command="{
action: 'syncHubspot',
member: member,
}"
:disabled="isHubspotActionDisabled"
>
<app-svg name="hubspot" class="h-4 w-4 text-current" />
<span
class="text-xs pl-2"
>Sync with HubSpot</span>
</el-dropdown-item>
<el-dropdown-item
v-else
class="h-10"
:command="{
action: 'stopSyncHubspot',
member: member,
}"
:disabled="isHubspotActionDisabled"
>
<app-svg name="hubspot" class="h-4 w-4 text-current" />
<span
class="text-xs pl-2"
>Stop sync with HubSpot</span>
</el-dropdown-item>
</span>
</el-tooltip>

<el-dropdown-item
v-if="!member.attributes.isTeamMember?.default"
Expand Down Expand Up @@ -206,6 +214,8 @@ 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 { isEnrichmentFeatureEnabled } from '@/modules/member/member-enrichment';
import { FeatureFlag, FEATURE_FLAGS } from '@/utils/featureFlag';

export default {
name: 'AppMemberDropdown',
Expand All @@ -227,6 +237,7 @@ export default {
pair: [],
};
},

computed: {
...mapGetters({
currentTenant: 'auth/currentTenant',
Expand All @@ -240,12 +251,6 @@ export default {
).edit === false
);
},
isEnrichmentDisabled() {
return (
!this.member.username?.github?.length
&& !this.member.emails?.length
);
},
isEditLockedForSampleData() {
return new MemberPermissions(
this.currentTenant,
Expand All @@ -258,6 +263,15 @@ export default {
this.currentUser,
).destroyLockedForSampleData;
},
isEnrichmentDisabledForMember() {
return (
!this.member.username?.github?.length
&& !this.member.emails?.length
);
},
isEnrichmentActionDisabled() {
return this.isEnrichmentDisabledForMember || this.isEditLockedForSampleData || !this.isEnrichmentFeatureEnabled();
},
isSyncingWithHubspot() {
return this.member.attributes?.syncRemote?.hubspot || false;
},
Expand All @@ -266,12 +280,27 @@ export default {
const enabledFor = hubspot.settings?.enabledFor || [];
return hubspot.status === 'done' && enabledFor.includes(HubspotEntity.MEMBERS);
},
isHubspotDisabledForMember() {
return props.member.emails.length === 0;
},
isHubspotFeatureEnabled() {
return FeatureFlag.isFlagEnabled(
FEATURE_FLAGS.hubspot,
);
},
isHubspotActionDisabled() {
return !this.isHubspotConnected || this.isHubspotDisabledForMember || !this.isHubspotFeatureEnabled;
},
},
created() {
this.doRefreshCurrentUser({});
},
methods: {
...mapActions({
doFind: 'member/doFind',
doDestroy: 'member/doDestroy',
doEnrich: 'member/doEnrich',
doRefreshCurrentUser: 'auth/doRefreshCurrentUser',
}),
...piniaMapActions(useMemberStore, ['fetchMembers']),
async doDestroyWithConfirm(id) {
Expand Down Expand Up @@ -362,6 +391,7 @@ export default {

return null;
},
isEnrichmentFeatureEnabled,
},
};
</script>
Expand Down
Loading