Skip to content

Commit

Permalink
Add ExecutionsUsage component
Browse files Browse the repository at this point in the history
  • Loading branch information
RicardoE105 committed May 3, 2023
1 parent deb4c04 commit a87b0b6
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 2 deletions.
1 change: 1 addition & 0 deletions packages/design-system/src/components/N8nMenu/Menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
</el-menu>
</div>
<div :class="[$style.lowerContent, 'pb-2xs']">
<slot name="beforeLowerMenu"></slot>
<el-menu :defaultActive="defaultActive" :collapse="collapsed" v-on="$listeners">
<n8n-menu-item
v-for="item in lowerMenuItems"
Expand Down
33 changes: 33 additions & 0 deletions packages/editor-ui/src/Interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1443,3 +1443,36 @@ export type VersionControlPreferences = {
branchColor: string;
publicKey?: string;
};

export interface PlanData {
planSpec: PlanSpec;
instance: Instance;
usage: Usage;
}

export interface PlanSpec {
planId: number;
monthlyExecutionsLimit: number;
activeWorkflowsLimit: number;
credentialsLimit: number;
isActive: boolean;
displayName: string;
metadata: Metadata;
}
export interface Metadata {
version: string;
group: string;
slug: string;
trial: Trial;
}
export interface Trial {
length: number;
gracePeriod: number;
}
export interface Instance {
createdAt: string;
}
export interface Usage {
executions: number;
activeWorkflows: number;
}
184 changes: 184 additions & 0 deletions packages/editor-ui/src/components/ExecutionsUsage.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
<template>
<div v-if="userIsTrialing" :class="$style.container">
<div v-if="!isTrialExpired && trialHasExecutionsLeft" :class="$style.usageText">
<i18n path="executionUsage.currentUsage">
<template #text>
<n8n-text size="xsmall" color="text-dark">
{{ locale.baseText('executionUsage.currentUsage.text') }}
</n8n-text>
</template>
<template #count>
<n8n-text size="xsmall" :bold="true" color="warning">
{{ daysLeftOnTrial }} {{ locale.baseText('executionUsage.currentUsage.count') }}
</n8n-text>
</template>
</i18n>
</div>
<div v-if="isTrialExpired" :class="$style.usageText">
<n8n-text size="xsmall" color="danger">
{{ locale.baseText('executionUsage.expired.text') }}
</n8n-text>
</div>
<div v-if="!trialHasExecutionsLeft" :class="$style.usageText">
<n8n-text size="xsmall">
{{ locale.baseText('executionUsage.ranOutOfExecutions.text') }}
</n8n-text>
</div>
<div v-if="!isTrialExpired" :class="$style.usageCounter">
<div :class="$style.progressBarSection">
<progress
:class="[
trialHasExecutionsLeft ? $style.progressBarSuccess : $style.progressBarDanger,
$style.progressBar,
]"
:value="currentExecutions"
:max="maxExecutions"
></progress>
</div>
<div :class="$style.executionsCountSection">
<n8n-text size="xsmall" :color="trialHasExecutionsLeft ? 'text-dark' : 'danger'">
{{ currentExecutions }}/{{ maxExecutions }}
</n8n-text>
<n8n-text size="xsmall" :color="trialHasExecutionsLeft ? 'text-dark' : 'danger'">{{
locale.baseText('executionUsage.label.executions')
}}</n8n-text>
</div>
</div>

<div :class="$style.upgradeButtonSection">
<n8n-button
:label="locale.baseText('executionUsage.button.upgrade')"
size="mini"
icon="gem"
type="success"
@click="onUpgradeClicked"
/>
</div>
</div>
</template>

<script setup lang="ts">
import { onMounted, ref, computed } from 'vue';
import { i18n as locale } from '@/plugins/i18n';
import type { PlanData } from '@/Interface';
import { DateTime } from 'luxon';
const currentPlan = ref<PlanData>({
planSpec: {
planId: 43039,
monthlyExecutionsLimit: 200,
activeWorkflowsLimit: 10,
credentialsLimit: 100,
isActive: false,
displayName: 'Trial',
metadata: {
version: 'v1',
group: 'trial',
slug: 'trial-1',
trial: {
length: 7,
gracePeriod: 3,
},
},
},
instance: {
createdAt: '2023-05-01T01:47:47Z',
},
usage: {
executions: 100,
activeWorkflows: 10,
},
});
const now = DateTime.utc();
onMounted(async () => {});
const daysLeftOnTrial = computed(() => {
const { days = 0 } = now.diff(getPlanStartingDate(), ['days']).toObject();
return Math.trunc(days);
});
const isTrialExpired = computed(() => {
const trialEndsAt = getPlanStartingDate()
.plus({ days: currentPlan.value.planSpec.metadata.trial.length })
.endOf('day');
return now.toMillis() > trialEndsAt.toMillis();
});
const getPlanStartingDate = () =>
DateTime.fromISO(currentPlan.value.instance.createdAt).startOf('day');
const trialHasExecutionsLeft = computed(
() => currentPlan.value.usage.executions < currentPlan.value.planSpec.monthlyExecutionsLimit,
);
const userIsTrialing = computed(() => currentPlan.value.planSpec.metadata.group === 'trial');
const currentExecutions = computed(() => currentPlan.value.usage.executions);
const maxExecutions = computed(() => currentPlan.value.planSpec.monthlyExecutionsLimit);
const onUpgradeClicked = () => {};
</script>

<style module lang="scss">
.container {
display: flex;
flex-direction: column;
background-color: var(--color-background-light);
border-radius: 0px;
margin: 0;
border: var(--border-base);
border-right: 0;
}
.progressBar {
width: 62.4px;
}
.progressBarSuccess {
accent-color: var(--color-foreground-xdark);
}
.progressBarDanger {
accent-color: var(--color-danger);
}
.usageText {
margin-left: var(--spacing-s);
margin-right: var(--spacing-s);
margin-top: var(--spacing-xs);
line-height: 12.5px;
}
.usageCounter {
display: flex;
flex-direction: row;
align-items: center;
margin-left: var(--spacing-s);
margin-top: var(--spacing-2xs);
font-size: var(--font-size-3xs);
}
.progressBarSection {
width: 62.4px;
justify-content: center;
margin-right: 0px;
}
.danger {
color: var(--color-danger);
}
.executionsCountSection {
margin-left: var(--spacing-xs);
}
.upgradeButtonSection {
margin: var(--spacing-s);
}
.upgradeButtonSection > * {
width: 100%;
}
</style>
4 changes: 4 additions & 0 deletions packages/editor-ui/src/components/MainSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
/>
</div>
</template>

<template #beforeLowerMenu> <ExecutionsUsage v-if="!isCollapsed" /></template>
<template #menuSuffix>
<div v-if="hasVersionUpdates || versionControlStore.state.currentBranch">
<div v-if="hasVersionUpdates" :class="$style.updates" @click="openUpdatesPanel">
Expand Down Expand Up @@ -134,6 +136,7 @@ import { useRootStore } from '@/stores/n8nRootStore';
import { useVersionsStore } from '@/stores/versions';
import { isNavigationFailure } from 'vue-router';
import { useVersionControlStore } from '@/stores/versionControl';
import ExecutionsUsage from '@/components/ExecutionsUsage.vue';
export default mixins(
genericHelpers,
Expand All @@ -147,6 +150,7 @@ export default mixins(
components: {
GiftNotificationIcon,
WorkflowSettings,
ExecutionsUsage,
},
data() {
return {
Expand Down
2 changes: 1 addition & 1 deletion packages/editor-ui/src/n8n-theme-variables.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ $header-height: 65px;

// sidebar
$sidebar-width: 65px;
$sidebar-expanded-width: 200px;
$sidebar-expanded-width: 202px;
$sidebar-inactive-color: var(--color-foreground-xdark);
$sidebar-active-color: $color-primary;

Expand Down
9 changes: 8 additions & 1 deletion packages/editor-ui/src/plugins/i18n/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1811,5 +1811,12 @@
"userActivationSurveyModal.sharedFeedback.success": "Thanks for your feedback",
"userActivationSurveyModal.sharedFeedback.error": "Problem sharing feedback, try again",
"sso.login.divider": "or",
"sso.login.button": "Continue with SSO"
"sso.login.button": "Continue with SSO",
"executionUsage.currentUsage": "{text} {count}",
"executionUsage.currentUsage.text": "You are in a free trial with limited executions. You have",
"executionUsage.currentUsage.count": "days left.",
"executionUsage.label.executions": "Executions",
"executionUsage.button.upgrade": "Upgrade plan",
"executionUsage.expired.text": "You're trial is over. Upgrade now to keep your automation data",
"executionUsage.ranOutOfExecutions.text": "You’re out of executions. Upgrade your plan to keep automating."
}
2 changes: 2 additions & 0 deletions packages/editor-ui/src/plugins/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ import {
faTree,
faStickyNote as faSolidStickyNote,
faUserLock,
faGem,
} from '@fortawesome/free-solid-svg-icons';
import { faVariable } from './custom';
import { faStickyNote } from '@fortawesome/free-regular-svg-icons';
Expand Down Expand Up @@ -264,5 +265,6 @@ addIcon(faVariable);
addIcon(faVideo);
addIcon(faTree);
addIcon(faUserLock);
addIcon(faGem);

Vue.component('font-awesome-icon', FontAwesomeIcon);

0 comments on commit a87b0b6

Please sign in to comment.