mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 17:46:45 +00:00
* feat(editor): Usage and plan page (#4793) feat(editor): usage and plan page * 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 * feat(editor): Get quotas data (#4866) feat(editor): get quotas data * feat(editor): In-app experience (#4875) * feat: Add license quotas endpoint * feat: Add trigger count to workflow activation process * refactor: Get quotas from db * feat: Add license information * ✨ - finalised GET /license endpoint * 🔨 - getActiveTriggerCount return 0 instead of null * 🐛 - ignore manualTrigger when counting active triggers * ✨ - add activation endpoint * ✨ - added renew endpoint * 🔨 - added return type interfaces * 🔨 - handle license errors where methods are called * 🔨 - rename function to match name from lib * feat(editor): usage add plans buttons logic * 🚨 - testing new License methods * feat(editor): usage add more business logic * chore(editor): code formatting * 🚨 - added license api tests * fix(editor): usage store * fix(editor): usage update translations * feat(editor): usage add license activation modal * feat(editor): usage change subscription app url * feat(editor): usage add contact us link * feat(editor): usage fix modal width * ✨ - Add renewal tracking metric * ✨ - add license data to pulse event * 🔨 - set default triggercount on entity model * ✨ - add db migrations for mysql and postgres * fix(editor): Usage api call data processing and error handling * fix(editor): Usage fix activation query key * 🚨 - add initDb to telemetry tests * 🔨 - move getlicensedata to licenseservice * 🔨 - return 403 instead of 404 to non owners * 🔨 - move owner checking to middleware * 🐛 - fixed incorrectly returned error from middleware * 🐛 - using mock instead of test db for pulse tests * fix(editor): Usage fix activation and add success messages * fix(editor): Usage should not renew activation right after activation * 🚨 - skipping failing pulse tests for now * fix(editor): Usage add telemetry calls and apply design review outcomes * feat(editor): Hide usage page according to BE flag * feat(editor): Usage modify key activation flow * feat(editor): Usage change subscription app url * feat(editor): Usage add telemetry for manage plan * feat(editor): Usage extend link url query params * feat(editor): Usage add line chart if there is a workflow limit * feat(editor): Usage remove query after key activation redirection * fix(editor): Usage handle limit exceeded workflow chart, add focus to input when modal opened * fix(editor): Usage activation can return router promise when removing query * fix(editor): Usage and plan design review * 🐛 - fix renew endpoint hanging issue * 🐛 - fix license activation bug * fix(editor): Usage proper translation for plans and/or editions * fix(editor): Usage apply David's review results * fix(editor): Usage page set as default and first under Settings * fix(editor): Usage open subscription app in new tab * fix(editor): Usage page having key query param a plan links * test: Fix broken test * fix(editor): Usage page address review * 🧪 Flush promises on telemetry tests * ⚡ Extract helper with `setImmediate` * 🔥 Remove leftovers * ⚡ Use Adi's helper * refactor: Comment broken tests * refactor: add Tenant id to settings * feat: add environment to license endpoints * refactor: Move license environment to general settings * fix: fix routing bug * fix(editor): Usage page some code review changes and formatting * fix(editor): Usage page remove direct usage of reusable translation keys * fix(editor): Usage page async await instead of then * fix(editor): Usage page show some content only if network requests in component mounted were successful * chore(editor): code formatting * fix(editor): Usage checking license environment * feat(editor): Improve license activation error messages (no-changelog) (#4958) * fix(editor): Usage changing activation error title * remove unnecessary import * fix(editor): Usage refactor notification showing * fix(editor): Usage using notification directly in store actions Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: freyamade <freya@n8n.io> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Mutasem <mutdmour@gmail.com> Co-authored-by: Cornelius Suermann <cornelius@n8n.io> * fix(editor): Usage change mounted lifecycle logic * fix(editor): Usage return after successful activation in mounted * fix: remove console log * test: fix tests related to settings (#4979) Co-authored-by: Omar Ajoue <krynble@gmail.com> Co-authored-by: freyamade <freya@n8n.io> Co-authored-by: Iván Ovejero <ivov.src@gmail.com> Co-authored-by: Mutasem <mutdmour@gmail.com> Co-authored-by: Cornelius Suermann <cornelius@n8n.io> Co-authored-by: Mutasem Aldmour <4711238+mutdmour@users.noreply.github.com>
249 lines
4.4 KiB
Vue
249 lines
4.4 KiB
Vue
<template>
|
|
<div :class="alertBoxClassNames" role="alert">
|
|
<div :class="$style.content">
|
|
<span v-if="showIcon || $slots.icon" :class="$style.icon">
|
|
<n8n-icon v-if="showIcon" :icon="icon" />
|
|
<slot v-else-if="$slots.icon" name="icon" />
|
|
</span>
|
|
<div :class="$style.text">
|
|
<div v-if="$slots.title || title" :class="$style.title">
|
|
<slot name="title">{{ title }}</slot>
|
|
</div>
|
|
<div
|
|
v-if="$slots.default || description"
|
|
:class="{ [$style.description]: true, [$style.hasTitle]: $slots.title || title }"
|
|
>
|
|
<slot>{{ description }}</slot>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div v-if="$slots.aside" :class="$style.aside">
|
|
<slot name="aside" />
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script lang="ts" setup>
|
|
import { computed, useCssModule } from 'vue';
|
|
import N8nIcon from '../N8nIcon';
|
|
|
|
type AlertProps = {
|
|
title?: string;
|
|
type?: 'success' | 'warning' | 'info' | 'error';
|
|
description?: string;
|
|
center?: boolean;
|
|
showIcon?: boolean;
|
|
effect?: 'light' | 'dark';
|
|
background?: boolean;
|
|
};
|
|
|
|
const props = withDefaults(defineProps<AlertProps>(), {
|
|
type: 'info',
|
|
effect: 'light',
|
|
showIcon: true,
|
|
background: true,
|
|
});
|
|
|
|
const icon = computed(() => {
|
|
/* eslint-disable prettier/prettier */
|
|
switch (props.type) {
|
|
case 'success':
|
|
return 'check-circle';
|
|
case 'warning':
|
|
return 'exclamation-triangle';
|
|
case 'error':
|
|
return 'times-circle';
|
|
default:
|
|
return 'info-circle';
|
|
}
|
|
/* eslint-enable */
|
|
});
|
|
|
|
const style = useCssModule();
|
|
const alertBoxClassNames = computed(() => {
|
|
const classNames = ['n8n-alert', style.alert];
|
|
if (props.type) {
|
|
classNames.push(style[props.type]);
|
|
}
|
|
if (props.effect) {
|
|
classNames.push(style[props.effect]);
|
|
}
|
|
if (props.center) {
|
|
classNames.push(style.center);
|
|
}
|
|
if (props.background) {
|
|
classNames.push(style.background);
|
|
}
|
|
return classNames;
|
|
});
|
|
</script>
|
|
|
|
<style lang="scss" module>
|
|
@import '../../css/common/var.scss';
|
|
|
|
.alert {
|
|
display: flex;
|
|
position: relative;
|
|
min-height: 60px;
|
|
border-bottom: 1px solid transparent;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: $alert-padding;
|
|
|
|
&.center {
|
|
justify-content: center;
|
|
}
|
|
|
|
&.success {
|
|
&.light {
|
|
color: var(--color-success);
|
|
|
|
&.background {
|
|
background-color: $color-success-lighter;
|
|
border-color: var(--color-success);
|
|
}
|
|
|
|
.el-alert__description {
|
|
color: var(--color-success);
|
|
}
|
|
}
|
|
|
|
&.dark {
|
|
color: $color-white;
|
|
|
|
&:not(.background) {
|
|
color: var(--color-success);
|
|
}
|
|
|
|
&.background {
|
|
background-color: var(--color-success);
|
|
border-color: $color-white;
|
|
}
|
|
}
|
|
}
|
|
|
|
&.info {
|
|
&.light {
|
|
color: var(--color-info);
|
|
|
|
&.background {
|
|
background-color: $alert-info-color;
|
|
border-color: var(--color-info);
|
|
}
|
|
}
|
|
|
|
&.dark {
|
|
color: $color-white;
|
|
|
|
&:not(.background) {
|
|
color: var(--color-info);
|
|
}
|
|
|
|
&.background {
|
|
background-color: var(--color-info);
|
|
border-color: $color-white;
|
|
}
|
|
}
|
|
|
|
.el-alert__description {
|
|
color: var(--color-info);
|
|
}
|
|
}
|
|
|
|
&.warning {
|
|
&.light {
|
|
color: var(--color-warning);
|
|
|
|
&.background {
|
|
background-color: $alert-warning-color;
|
|
border-color: var(--color-warning);
|
|
}
|
|
|
|
.el-alert__description {
|
|
color: var(--color-warning);
|
|
}
|
|
}
|
|
|
|
&.dark {
|
|
color: $color-white;
|
|
|
|
&:not(.background) {
|
|
color: var(--color-warning);
|
|
}
|
|
|
|
&.background {
|
|
background-color: var(--color-warning);
|
|
border-color: $color-white;
|
|
}
|
|
}
|
|
}
|
|
|
|
&.error {
|
|
&.light {
|
|
color: var(--color-danger);
|
|
|
|
&.background {
|
|
background-color: $alert-danger-color;
|
|
border-color: var(--color-danger);
|
|
}
|
|
|
|
.el-alert__description {
|
|
color: var(--color-danger);
|
|
}
|
|
}
|
|
|
|
&.dark {
|
|
color: $color-white;
|
|
|
|
&:not(.background) {
|
|
color: var(--color-danger);
|
|
}
|
|
|
|
&.background {
|
|
background-color: var(--color-danger);
|
|
border-color: $color-white;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
.content {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
}
|
|
|
|
.icon {
|
|
display: inline-flex;
|
|
color: inherit;
|
|
align-items: center;
|
|
padding-left: var(--spacing-2xs);
|
|
padding-right: var(--spacing-s);
|
|
}
|
|
|
|
.text {
|
|
display: inline-flex;
|
|
flex-direction: column;
|
|
justify-content: center;
|
|
}
|
|
|
|
.title {
|
|
font-size: $alert-title-font-size;
|
|
line-height: 18px;
|
|
font-weight: bold;
|
|
}
|
|
|
|
.description {
|
|
font-size: $alert-description-font-size;
|
|
|
|
&.hasTitle {
|
|
margin: 5px 0 0 0;
|
|
}
|
|
}
|
|
|
|
.aside {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
padding-left: var(--spacing-s);
|
|
}
|
|
</style>
|