-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(editor): Update Usage and plan page (#4842)
* feat(editor): usage and plan store * feat(editor): usage and plan page updates * feat(editor): usage and plan add buttons and alert * tes(editor): usage and plan store * tes(editor): usage remove refresh button and add link to view plans * tes(editor): usage use info tip * tes(editor): usage info style
- Loading branch information
Showing
11 changed files
with
204 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { createPinia, setActivePinia } from "pinia"; | ||
import { useUsageAndPlanStore } from "@/stores/usageAndPlan"; | ||
|
||
|
||
describe('Usage and plan store', () => { | ||
beforeEach(() => { | ||
setActivePinia(createPinia()); | ||
}); | ||
|
||
test.each([ | ||
[5, 3, .8, false], | ||
[5, 4, .8, true], | ||
[5, 4, .9, false], | ||
[10, 5, .8, false], | ||
[10, 8, .8, true], | ||
[10, 9, .8, true], | ||
[-1, 99, .8, false], | ||
[-1, 99, .1, false], | ||
])('should check if workflow usage is close to limit', (limit, value, warningThreshold, expectation) => { | ||
const store = useUsageAndPlanStore(); | ||
store.setData({ | ||
usage: { | ||
executions: { | ||
limit, | ||
value, | ||
warningThreshold, | ||
}, | ||
}, | ||
license: { | ||
planId: '', | ||
planName: '', | ||
}, | ||
}); | ||
expect(store.isCloseToLimit).toBe(expectation); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import {computed, reactive} from "vue"; | ||
import {defineStore} from "pinia"; | ||
|
||
export type UsageAndPlanState = { | ||
loading: boolean; | ||
error: Error | null; | ||
data: { | ||
usage: { | ||
executions: { | ||
limit: number, // -1 for unlimited, from license | ||
value: number, | ||
warningThreshold: number, // hardcoded value in BE | ||
}, | ||
}, | ||
license: { | ||
planId: string, // community | ||
planName: string, // defaults to Community | ||
}, | ||
} | ||
}; | ||
|
||
export const useUsageAndPlanStore = defineStore('usageAndPlan', () => { | ||
const state = reactive<UsageAndPlanState>({ | ||
loading: true, | ||
error: null, | ||
data: { | ||
usage: { | ||
executions: { | ||
limit: -1, | ||
value: 0, | ||
warningThreshold: .8, | ||
}, | ||
}, | ||
license: { | ||
planId: 'community', | ||
planName: 'Community', | ||
}, | ||
}, | ||
}); | ||
|
||
const setData = (data: UsageAndPlanState['data']) => { | ||
state.data = data; | ||
}; | ||
|
||
return { | ||
setData, | ||
planName: computed(() => state.data.license.planName), | ||
executionLimit: computed(() => state.data.usage.executions.limit), | ||
executionCount: computed(() => state.data.usage.executions.value), | ||
isCloseToLimit: computed(() => state.data.usage.executions.limit < 0 ? false : state.data.usage.executions.value / state.data.usage.executions.limit >= state.data.usage.executions.warningThreshold), | ||
}; | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,85 @@ | ||
<template> | ||
<div :class="$style.container"> | ||
<div> | ||
<n8n-heading size="2xlarge">{{ $locale.baseText('settings.usageAndPlan.title') }}</n8n-heading> | ||
<n8n-heading :class="$style.title" size="large"> | ||
{{ $locale.baseText('settings.usageAndPlan.plan', { interpolate: { plan: usageAndPlanStore.planName } }) }} | ||
</n8n-heading> | ||
<div :class="$style.quota"> | ||
<n8n-text size="medium" color="text-light">{{ $locale.baseText('settings.usageAndPlan.activeWorkflows') }}</n8n-text> | ||
<i18n :class="$style.count" path="settings.usageAndPlan.activeWorkflows.count"> | ||
<template #count>{{ usageAndPlanStore.executionCount }}</template> | ||
<template #limit> | ||
<span v-if="usageAndPlanStore.executionLimit < 0">{{ $locale.baseText('_reusableBaseText.unlimited') }}</span> | ||
<span v-else>{{ usageAndPlanStore.executionLimit }}</span> | ||
</template> | ||
</i18n> | ||
</div> | ||
<n8n-info-tip> | ||
{{ $locale.baseText('settings.usageAndPlan.activeWorkflows.hint') }} | ||
</n8n-info-tip> | ||
<div :class="$style.buttons"> | ||
<n8n-button type="secondary" size="large">{{ $locale.baseText('settings.usageAndPlan.button.activation') }}</n8n-button> | ||
<n8n-button size="large"> | ||
<a href="#">{{ $locale.baseText('settings.usageAndPlan.button.plans') }}</a> | ||
</n8n-button> | ||
</div> | ||
</div> | ||
</template> | ||
<script lang="ts" setup> | ||
import { useUsageAndPlanStore } from "@/stores/usageAndPlan"; | ||
const usageAndPlanStore = useUsageAndPlanStore(); | ||
</script> | ||
|
||
<style lang="scss" module> | ||
.container { | ||
} | ||
.spacedFlex { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
} | ||
.title { | ||
display: block; | ||
padding: var(--spacing-2xl) 0 var(--spacing-m); | ||
} | ||
.quota { | ||
display: flex; | ||
justify-content: space-between; | ||
align-items: center; | ||
height: 54px; | ||
padding: 0 var(--spacing-s); | ||
margin: 0 0 var(--spacing-xs); | ||
background: var(--color-background-xlight); | ||
border-radius: var(--border-radius-large); | ||
border: 1px solid var(--color-light-grey); | ||
.count { | ||
text-transform: lowercase; | ||
font-size: var(--font-size-s); | ||
} | ||
} | ||
.buttons { | ||
display: flex; | ||
justify-content: flex-end; | ||
padding: var(--spacing-xl) 0 0; | ||
button { | ||
margin-left: var(--spacing-xs); | ||
a { | ||
display: inline-block; | ||
color: inherit; | ||
text-decoration: none; | ||
padding: var(--spacing-xs) var(--spacing-m); | ||
margin: calc(var(--spacing-xs) * -1) calc(var(--spacing-m) * -1); | ||
} | ||
} | ||
} | ||
div[class*="info"] span { | ||
line-height: 1.4; | ||
} | ||
</style> |
Oops, something went wrong.