mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-18 10:31:15 +00:00
fix(editor): Insights FE fixes and improvements (#14398)
Co-authored-by: r00gm <raul00gm@gmail.com>
This commit is contained in:
@@ -111,7 +111,9 @@ const mainMenuItems = computed(() => [
|
|||||||
customIconSize: 'medium',
|
customIconSize: 'medium',
|
||||||
position: 'bottom',
|
position: 'bottom',
|
||||||
route: { to: { name: VIEWS.INSIGHTS } },
|
route: { to: { name: VIEWS.INSIGHTS } },
|
||||||
available: hasPermission(['rbac'], { rbac: { scope: 'insights:list' } }),
|
available:
|
||||||
|
settingsStore.settings.insights.enabled &&
|
||||||
|
hasPermission(['rbac'], { rbac: { scope: 'insights:list' } }),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'help',
|
id: 'help',
|
||||||
|
|||||||
@@ -380,7 +380,11 @@ const toggleTimeout = () => {
|
|||||||
|
|
||||||
const updateTimeSavedPerExecution = (value: string) => {
|
const updateTimeSavedPerExecution = (value: string) => {
|
||||||
const numValue = parseInt(value, 10);
|
const numValue = parseInt(value, 10);
|
||||||
workflowSettings.value.timeSavedPerExecution = isNaN(numValue) ? undefined : numValue;
|
workflowSettings.value.timeSavedPerExecution = isNaN(numValue)
|
||||||
|
? undefined
|
||||||
|
: numValue < 0
|
||||||
|
? 0
|
||||||
|
: numValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
onMounted(async () => {
|
onMounted(async () => {
|
||||||
@@ -826,6 +830,7 @@ onMounted(async () => {
|
|||||||
:disabled="readOnlyEnv || !workflowPermissions.update"
|
:disabled="readOnlyEnv || !workflowPermissions.update"
|
||||||
data-test-id="workflow-settings-time-saved-per-execution"
|
data-test-id="workflow-settings-time-saved-per-execution"
|
||||||
type="number"
|
type="number"
|
||||||
|
min="0"
|
||||||
@update:model-value="updateTimeSavedPerExecution"
|
@update:model-value="updateTimeSavedPerExecution"
|
||||||
/>
|
/>
|
||||||
<span>{{ i18n.baseText('workflowSettings.timeSavedPerExecution.hint') }}</span>
|
<span>{{ i18n.baseText('workflowSettings.timeSavedPerExecution.hint') }}</span>
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const generateLineChartOptions = (
|
|||||||
callbacks: {
|
callbacks: {
|
||||||
label(context: ScriptableContext<'line'>) {
|
label(context: ScriptableContext<'line'>) {
|
||||||
const label = context.dataset.label ?? '';
|
const label = context.dataset.label ?? '';
|
||||||
return `${label} ${smartDecimal(context.parsed.y)}`;
|
return `${label} ${smartDecimal(context.parsed.y).toLocaleString('en-US')}`;
|
||||||
},
|
},
|
||||||
labelColor(context: ScriptableContext<'line'>) {
|
labelColor(context: ScriptableContext<'line'>) {
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -36,38 +36,50 @@ describe('InsightsSummary', () => {
|
|||||||
[[]],
|
[[]],
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
{ id: 'total', value: 525, deviation: 85, unit: '' },
|
{ id: 'total', value: 525, deviation: 85, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failed', value: 14, deviation: 3, unit: '' },
|
{ id: 'failed', value: 14, deviation: 3, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failureRate', value: 1.9, deviation: -0.8, unit: '%' },
|
{ id: 'failureRate', value: 1.9, deviation: -0.8, unit: '%', deviationUnit: 'pp' },
|
||||||
{ id: 'timeSaved', value: 55.55555555555556, deviation: -5.164722222222222, unit: 'h' },
|
{
|
||||||
{ id: 'averageRunTime', value: 2.5, deviation: -0.5, unit: 's' },
|
id: 'timeSaved',
|
||||||
|
value: 55.55555555555556,
|
||||||
|
deviation: -5.164722222222222,
|
||||||
|
unit: 'h',
|
||||||
|
deviationUnit: 'h',
|
||||||
|
},
|
||||||
|
{ id: 'averageRunTime', value: 2.5, deviation: -0.5, unit: 's', deviationUnit: 's' },
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
{ id: 'total', value: 525, deviation: 85, unit: '' },
|
{ id: 'total', value: 525, deviation: 85, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failed', value: 14, deviation: 3, unit: '' },
|
{ id: 'failed', value: 14, deviation: 3, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failureRate', value: 1.9, deviation: -0.8, unit: '%' },
|
{ id: 'failureRate', value: 1.9, deviation: -0.8, unit: '%', deviationUnit: 'pp' },
|
||||||
{ id: 'timeSaved', value: 0, deviation: 0, unit: 'h' },
|
{ id: 'timeSaved', value: 0, deviation: 0, unit: 'h', deviationUnit: 'h' },
|
||||||
{ id: 'averageRunTime', value: 2.5, deviation: -0.5, unit: 's' },
|
{ id: 'averageRunTime', value: 2.5, deviation: -0.5, unit: 's', deviationUnit: 's' },
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
{ id: 'total', value: 525, deviation: -2, unit: '' },
|
{ id: 'total', value: 525, deviation: -2, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failed', value: 14, deviation: -3, unit: '' },
|
{ id: 'failed', value: 14, deviation: -3, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failureRate', value: 1.9, deviation: 0.8, unit: '%' },
|
{ id: 'failureRate', value: 1.9, deviation: 0.8, unit: '%', deviationUnit: 'pp' },
|
||||||
{ id: 'timeSaved', value: 55.55555555555556, deviation: 0, unit: 'h' },
|
{ id: 'timeSaved', value: 55.55555555555556, deviation: 0, unit: 'h', deviationUnit: 'h' },
|
||||||
{ id: 'averageRunTime', value: 2.5, deviation: 0.5, unit: 's' },
|
{ id: 'averageRunTime', value: 2.5, deviation: 0.5, unit: 's', deviationUnit: 's' },
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
[
|
[
|
||||||
[
|
[
|
||||||
{ id: 'total', value: 525, deviation: null, unit: '' },
|
{ id: 'total', value: 525, deviation: null, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failed', value: 14, deviation: null, unit: '' },
|
{ id: 'failed', value: 14, deviation: null, unit: '', deviationUnit: '%' },
|
||||||
{ id: 'failureRate', value: 1.9, deviation: null, unit: '%' },
|
{ id: 'failureRate', value: 1.9, deviation: null, unit: '%', deviationUnit: 'pp' },
|
||||||
{ id: 'timeSaved', value: 55.55555555555556, deviation: null, unit: 'h' },
|
{
|
||||||
{ id: 'averageRunTime', value: 2.5, deviation: null, unit: 's' },
|
id: 'timeSaved',
|
||||||
|
value: 55.55555555555556,
|
||||||
|
deviation: null,
|
||||||
|
unit: 'h',
|
||||||
|
deviationUnit: 'h',
|
||||||
|
},
|
||||||
|
{ id: 'averageRunTime', value: 2.5, deviation: null, unit: 's', deviationUnit: 's' },
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
])('should render the summary correctly', (summary) => {
|
])('should render the summary correctly', (summary) => {
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import {
|
|||||||
import type { InsightsSummaryDisplay } from '@/features/insights/insights.types';
|
import type { InsightsSummaryDisplay } from '@/features/insights/insights.types';
|
||||||
import type { InsightsSummary } from '@n8n/api-types';
|
import type { InsightsSummary } from '@n8n/api-types';
|
||||||
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
||||||
import { computed, useCssModule } from 'vue';
|
import { computed, ref, useCssModule } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute } from 'vue-router';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
@@ -20,6 +20,8 @@ const i18n = useI18n();
|
|||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
const $style = useCssModule();
|
const $style = useCssModule();
|
||||||
|
|
||||||
|
const lastNDays = ref(7);
|
||||||
|
|
||||||
const summaryTitles = computed<Record<keyof InsightsSummary, string>>(() => ({
|
const summaryTitles = computed<Record<keyof InsightsSummary, string>>(() => ({
|
||||||
total: i18n.baseText('insights.banner.title.total'),
|
total: i18n.baseText('insights.banner.title.total'),
|
||||||
failed: i18n.baseText('insights.banner.title.failed'),
|
failed: i18n.baseText('insights.banner.title.failed'),
|
||||||
@@ -35,7 +37,6 @@ const summaryWithRouteLocations = computed(() =>
|
|||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
const getSign = (n: number) => (n > 0 ? '+' : undefined);
|
|
||||||
const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
||||||
const impact = INSIGHTS_UNIT_IMPACT_MAPPING[id];
|
const impact = INSIGHTS_UNIT_IMPACT_MAPPING[id];
|
||||||
if (value === 0 || impact === INSIGHT_IMPACT_TYPES.NEUTRAL) {
|
if (value === 0 || impact === INSIGHT_IMPACT_TYPES.NEUTRAL) {
|
||||||
@@ -53,18 +54,25 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div :class="$style.insights">
|
<div :class="$style.insights">
|
||||||
<N8nHeading bold tag="h3" size="small" color="text-light" class="mb-xs">{{
|
|
||||||
i18n.baseText('insights.banner.title', { interpolate: { count: 7 } })
|
|
||||||
}}</N8nHeading>
|
|
||||||
<N8nLoading v-if="loading" :class="$style.loading" :cols="5" />
|
<N8nLoading v-if="loading" :class="$style.loading" :cols="5" />
|
||||||
<ul v-else data-test-id="insights-summary-tabs">
|
<ul v-else data-test-id="insights-summary-tabs">
|
||||||
<li
|
<li
|
||||||
v-for="{ id, value, deviation, unit, to } in summaryWithRouteLocations"
|
v-for="{ id, value, deviation, deviationUnit, unit, to } in summaryWithRouteLocations"
|
||||||
:key="id"
|
:key="id"
|
||||||
:data-test-id="`insights-summary-tab-${id}`"
|
:data-test-id="`insights-summary-tab-${id}`"
|
||||||
>
|
>
|
||||||
<router-link :to="to" :exact-active-class="$style.activeTab">
|
<router-link :to="to" :exact-active-class="$style.activeTab">
|
||||||
<strong>{{ summaryTitles[id] }}</strong>
|
<strong>
|
||||||
|
<N8nTooltip placement="bottom" :disabled="id !== 'timeSaved'">
|
||||||
|
<template #content>
|
||||||
|
{{ i18n.baseText('insights.banner.title.timeSaved.tooltip') }}
|
||||||
|
</template>
|
||||||
|
{{ summaryTitles[id] }}
|
||||||
|
</N8nTooltip>
|
||||||
|
</strong>
|
||||||
|
<small :class="$style.days">{{
|
||||||
|
i18n.baseText('insights.lastNDays', { interpolate: { count: lastNDays } })
|
||||||
|
}}</small>
|
||||||
<span v-if="value === 0 && id === 'timeSaved'" :class="$style.empty">
|
<span v-if="value === 0 && id === 'timeSaved'" :class="$style.empty">
|
||||||
<em>--</em>
|
<em>--</em>
|
||||||
<small>
|
<small>
|
||||||
@@ -84,14 +92,19 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
</span>
|
</span>
|
||||||
<span v-else>
|
<span v-else>
|
||||||
<em
|
<em
|
||||||
>{{ smartDecimal(value) }} <i>{{ unit }}</i></em
|
>{{ smartDecimal(value).toLocaleString('en-US') }} <i>{{ unit }}</i></em
|
||||||
>
|
>
|
||||||
<small v-if="deviation !== null" :class="getImpactStyle(id, deviation)">
|
<small v-if="deviation !== null" :class="getImpactStyle(id, deviation)">
|
||||||
<N8nIcon
|
<N8nIcon
|
||||||
:class="[$style.icon, getImpactStyle(id, deviation)]"
|
:class="[$style.icon, getImpactStyle(id, deviation)]"
|
||||||
:icon="deviation === 0 ? 'caret-right' : deviation > 0 ? 'caret-up' : 'caret-down'"
|
:icon="deviation === 0 ? 'caret-right' : deviation > 0 ? 'caret-up' : 'caret-down'"
|
||||||
/>
|
/>
|
||||||
{{ getSign(deviation) }}{{ smartDecimal(deviation) }}
|
<N8nTooltip placement="bottom" :disabled="id !== 'failureRate'">
|
||||||
|
<template #content>
|
||||||
|
{{ i18n.baseText('insights.banner.failureRate.deviation.tooltip') }}
|
||||||
|
</template>
|
||||||
|
{{ smartDecimal(Math.abs(deviation)).toLocaleString('en-US') }}{{ deviationUnit }}
|
||||||
|
</N8nTooltip>
|
||||||
</small>
|
</small>
|
||||||
</span>
|
</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
@@ -108,7 +121,7 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
|
|
||||||
ul {
|
ul {
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 91px;
|
height: 101px;
|
||||||
align-items: stretch;
|
align-items: stretch;
|
||||||
justify-content: space-evenly;
|
justify-content: space-evenly;
|
||||||
border: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
|
border: var(--border-width-base) var(--border-style-base) var(--color-foreground-base);
|
||||||
@@ -131,9 +144,10 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
a {
|
a {
|
||||||
display: grid;
|
display: grid;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
align-content: center;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
padding: var(--spacing-m) var(--spacing-l);
|
padding: var(--spacing-3xs) var(--spacing-l) 0;
|
||||||
border-bottom: 3px solid transparent;
|
border-bottom: 3px solid transparent;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@@ -148,17 +162,25 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
|
justify-self: flex-start;
|
||||||
color: var(--color-text-dark);
|
color: var(--color-text-dark);
|
||||||
font-size: var(--font-size-s);
|
font-size: var(--font-size-s);
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
margin-bottom: var(--spacing-2xs);
|
margin-bottom: var(--spacing-3xs);
|
||||||
|
}
|
||||||
|
|
||||||
|
.days {
|
||||||
|
padding: 0;
|
||||||
|
margin: 0 0 var(--spacing-xs);
|
||||||
|
color: var(--color-text-light);
|
||||||
|
font-size: var(--font-size-2xs);
|
||||||
|
font-weight: var(--font-weight-normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
gap: var(--spacing-xs);
|
|
||||||
|
|
||||||
&.empty {
|
&.empty {
|
||||||
em {
|
em {
|
||||||
@@ -185,7 +207,7 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
align-items: baseline;
|
align-items: baseline;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
color: var(--color-text-dark);
|
color: var(--color-text-dark);
|
||||||
font-size: var(--font-size-2xl);
|
font-size: 24px;
|
||||||
line-height: 100%;
|
line-height: 100%;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
@@ -202,9 +224,10 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
position: relative;
|
position: relative;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0 0 0 18px;
|
padding: 0 0 0 14px;
|
||||||
font-size: 14px;
|
margin: 0 0 0 var(--spacing-xs);
|
||||||
font-weight: 400;
|
font-size: var(--font-size-2xs);
|
||||||
|
font-weight: var(--font-weight-bold);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,13 +246,13 @@ const getImpactStyle = (id: keyof InsightsSummary, value: number) => {
|
|||||||
color: var(--color-text-light);
|
color: var(--color-text-light);
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
font-size: 23px;
|
font-size: 17px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon {
|
.icon {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
font-size: 32px;
|
font-size: 17px;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 50%;
|
top: 50%;
|
||||||
transform: translateY(-50%);
|
transform: translateY(-50%);
|
||||||
|
|||||||
@@ -2,62 +2,99 @@
|
|||||||
|
|
||||||
exports[`InsightsSummary > should render the summary correctly 1`] = `
|
exports[`InsightsSummary > should render the summary correctly 1`] = `
|
||||||
"<div class="insights">
|
"<div class="insights">
|
||||||
<h3 class="n8n-heading text-light size-small bold mb-xs mb-xs">Production executions for the last 7 days</h3>
|
|
||||||
<ul data-test-id="insights-summary-tabs"></ul>
|
<ul data-test-id="insights-summary-tabs"></ul>
|
||||||
</div>"
|
</div>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InsightsSummary > should render the summary correctly 2`] = `
|
exports[`InsightsSummary > should render the summary correctly 2`] = `
|
||||||
"<div class="insights">
|
"<div class="insights">
|
||||||
<h3 class="n8n-heading text-light size-small bold mb-xs mb-xs">Production executions for the last 7 days</h3>
|
|
||||||
<ul data-test-id="insights-summary-tabs">
|
<ul data-test-id="insights-summary-tabs">
|
||||||
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong>Total</strong><span><em>525 <i></i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span> +85</small></span></a></li>
|
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>525 <i></i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 85%</span>
|
||||||
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong>Failed</strong><span><em>14 <i></i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span> +3</small></span></a></li>
|
<!--teleport start-->
|
||||||
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong>Failure rate</strong><span><em>1.9 <i>%</i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span> -0.8</small></span></a></li>
|
<!--teleport end--></small></span>
|
||||||
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong>Time saved</strong><span><em>55.56 <i>h</i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span> -5.16</small></span></a></li>
|
</a></li>
|
||||||
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong>Avg. run time</strong><span><em>2.5 <i>s</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span> -0.5</small></span></a></li>
|
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failed prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>14 <i></i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 3%</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failure rate</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>1.9 <i>%</i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 0.8pp</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Time saved</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>55.56 <i>h</i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 5.16h</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Run time (avg.)</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>2.5 <i>s</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 0.5s</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>"
|
</div>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InsightsSummary > should render the summary correctly 3`] = `
|
exports[`InsightsSummary > should render the summary correctly 3`] = `
|
||||||
"<div class="insights">
|
"<div class="insights">
|
||||||
<h3 class="n8n-heading text-light size-small bold mb-xs mb-xs">Production executions for the last 7 days</h3>
|
|
||||||
<ul data-test-id="insights-summary-tabs">
|
<ul data-test-id="insights-summary-tabs">
|
||||||
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong>Total</strong><span><em>525 <i></i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span> +85</small></span></a></li>
|
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>525 <i></i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 85%</span>
|
||||||
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong>Failed</strong><span><em>14 <i></i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span> +3</small></span></a></li>
|
<!--teleport start-->
|
||||||
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong>Failure rate</strong><span><em>1.9 <i>%</i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span> -0.8</small></span></a></li>
|
<!--teleport end--></small></span>
|
||||||
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong>Time saved</strong><span class="empty"><em>--</em><small><span class="n8n-text compact size-medium regular n8n-icon icon el-tooltip__trigger el-tooltip__trigger icon el-tooltip__trigger el-tooltip__trigger n8n-icon icon el-tooltip__trigger el-tooltip__trigger icon el-tooltip__trigger el-tooltip__trigger"><svg class="svg-inline--fa fa-info-circle fa-w-16 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="info-circle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="" fill="currentColor" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path></svg></span>
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failed prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>14 <i></i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 3%</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failure rate</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>1.9 <i>%</i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 0.8pp</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Time saved</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span class="empty"><em>--</em><small><span class="n8n-text compact size-medium regular n8n-icon icon el-tooltip__trigger el-tooltip__trigger icon el-tooltip__trigger el-tooltip__trigger n8n-icon icon el-tooltip__trigger el-tooltip__trigger icon el-tooltip__trigger el-tooltip__trigger"><svg class="svg-inline--fa fa-info-circle fa-w-16 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="info-circle" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path class="" fill="currentColor" d="M256 8C119.043 8 8 119.083 8 256c0 136.997 111.043 248 248 248s248-111.003 248-248C504 119.083 392.957 8 256 8zm0 110c23.196 0 42 18.804 42 42s-18.804 42-42 42-42-18.804-42-42 18.804-42 42-42zm56 254c0 6.627-5.373 12-12 12h-88c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h12v-64h-12c-6.627 0-12-5.373-12-12v-24c0-6.627 5.373-12 12-12h64c6.627 0 12 5.373 12 12v100h12c6.627 0 12 5.373 12 12v24z"></path></svg></span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Run time (avg.)</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>2.5 <i>s</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 0.5s</span>
|
||||||
<!--teleport start-->
|
<!--teleport start-->
|
||||||
<!--teleport end--></small></span>
|
<!--teleport end--></small></span>
|
||||||
</a></li>
|
</a></li>
|
||||||
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong>Avg. run time</strong><span><em>2.5 <i>s</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span> -0.5</small></span></a></li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</div>"
|
</div>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InsightsSummary > should render the summary correctly 4`] = `
|
exports[`InsightsSummary > should render the summary correctly 4`] = `
|
||||||
"<div class="insights">
|
"<div class="insights">
|
||||||
<h3 class="n8n-heading text-light size-small bold mb-xs mb-xs">Production executions for the last 7 days</h3>
|
|
||||||
<ul data-test-id="insights-summary-tabs">
|
<ul data-test-id="insights-summary-tabs">
|
||||||
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong>Total</strong><span><em>525 <i></i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span> -2</small></span></a></li>
|
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>525 <i></i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 2%</span>
|
||||||
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong>Failed</strong><span><em>14 <i></i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span> -3</small></span></a></li>
|
<!--teleport start-->
|
||||||
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong>Failure rate</strong><span><em>1.9 <i>%</i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span> +0.8</small></span></a></li>
|
<!--teleport end--></small></span>
|
||||||
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong>Time saved</strong><span><em>55.56 <i>h</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-right fa-w-6 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><path class="" fill="currentColor" d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"></path></svg></span> 0</small></span></a></li>
|
</a></li>
|
||||||
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong>Avg. run time</strong><span><em>2.5 <i>s</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span> +0.5</small></span></a></li>
|
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failed prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>14 <i></i></em><small class="positive"><span class="n8n-text compact size-medium regular n8n-icon icon positive icon positive n8n-icon icon positive icon positive"><svg class="svg-inline--fa fa-caret-down fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-down" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M31.3 192h257.3c17.8 0 26.7 21.5 14.1 34.1L174.1 354.8c-7.8 7.8-20.5 7.8-28.3 0L17.2 226.1C4.6 213.5 13.5 192 31.3 192z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 3%</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failure rate</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>1.9 <i>%</i></em><small class="negative"><span class="n8n-text compact size-medium regular n8n-icon icon negative icon negative n8n-icon icon negative icon negative"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 0.8pp</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Time saved</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>55.56 <i>h</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-right fa-w-6 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-right" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 192 512"><path class="" fill="currentColor" d="M0 384.662V127.338c0-17.818 21.543-26.741 34.142-14.142l128.662 128.662c7.81 7.81 7.81 20.474 0 28.284L34.142 398.804C21.543 411.404 0 402.48 0 384.662z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 0h</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
|
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Run time (avg.)</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>2.5 <i>s</i></em><small class="neutral"><span class="n8n-text compact size-medium regular n8n-icon icon neutral icon neutral n8n-icon icon neutral icon neutral"><svg class="svg-inline--fa fa-caret-up fa-w-10 medium" aria-hidden="true" focusable="false" data-prefix="fas" data-icon="caret-up" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512"><path class="" fill="currentColor" d="M288.662 352H31.338c-17.818 0-26.741-21.543-14.142-34.142l128.662-128.662c7.81-7.81 20.474-7.81 28.284 0l128.662 128.662c12.6 12.599 3.676 34.142-14.142 34.142z"></path></svg></span><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> 0.5s</span>
|
||||||
|
<!--teleport start-->
|
||||||
|
<!--teleport end--></small></span>
|
||||||
|
</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>"
|
</div>"
|
||||||
`;
|
`;
|
||||||
|
|
||||||
exports[`InsightsSummary > should render the summary correctly 5`] = `
|
exports[`InsightsSummary > should render the summary correctly 5`] = `
|
||||||
"<div class="insights">
|
"<div class="insights">
|
||||||
<h3 class="n8n-heading text-light size-small bold mb-xs mb-xs">Production executions for the last 7 days</h3>
|
|
||||||
<ul data-test-id="insights-summary-tabs">
|
<ul data-test-id="insights-summary-tabs">
|
||||||
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong>Total</strong><span><em>525 <i></i></em><!--v-if--></span></a></li>
|
<li data-test-id="insights-summary-tab-total"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>525 <i></i></em><!--v-if--></span></a></li>
|
||||||
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong>Failed</strong><span><em>14 <i></i></em><!--v-if--></span></a></li>
|
<li data-test-id="insights-summary-tab-failed"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failed prod. executions</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>14 <i></i></em><!--v-if--></span></a></li>
|
||||||
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong>Failure rate</strong><span><em>1.9 <i>%</i></em><!--v-if--></span></a></li>
|
<li data-test-id="insights-summary-tab-failureRate"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Failure rate</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>1.9 <i>%</i></em><!--v-if--></span></a></li>
|
||||||
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong>Time saved</strong><span><em>55.56 <i>h</i></em><!--v-if--></span></a></li>
|
<li data-test-id="insights-summary-tab-timeSaved"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Time saved</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>55.56 <i>h</i></em><!--v-if--></span></a></li>
|
||||||
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong>Avg. run time</strong><span><em>2.5 <i>s</i></em><!--v-if--></span></a></li>
|
<li data-test-id="insights-summary-tab-averageRunTime"><a to="[object Object]" exact-active-class="activeTab"><strong><span class="el-only-child__content el-tooltip__trigger el-tooltip__trigger"> Run time (avg.)</span><!--teleport start--><!--teleport end--></strong><small class="days">Last 7 days</small><span><em>2.5 <i>s</i></em><!--v-if--></span></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>"
|
</div>"
|
||||||
`;
|
`;
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
import { Line } from 'vue-chartjs';
|
|
||||||
import { type ScriptableContext, type ChartData, Filler } from 'chart.js';
|
|
||||||
import dateformat from 'dateformat';
|
|
||||||
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
|
||||||
import {
|
import {
|
||||||
generateLinearGradient,
|
generateLinearGradient,
|
||||||
generateLineChartOptions,
|
generateLineChartOptions,
|
||||||
} from '@/features/insights/chartjs.utils';
|
} from '@/features/insights/chartjs.utils';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
import { DATE_FORMAT_MASK, INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
||||||
import { transformInsightsAverageRunTime } from '@/features/insights/insights.utils';
|
import { transformInsightsAverageRunTime } from '@/features/insights/insights.utils';
|
||||||
|
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
||||||
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
||||||
import { INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
import { type ChartData, Filler, type ScriptableContext } from 'chart.js';
|
||||||
|
import dateformat from 'dateformat';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { Line } from 'vue-chartjs';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
data: InsightsByTime[];
|
data: InsightsByTime[];
|
||||||
@@ -27,7 +27,7 @@ const chartOptions = computed(() =>
|
|||||||
callbacks: {
|
callbacks: {
|
||||||
label: (context) => {
|
label: (context) => {
|
||||||
const label = context.dataset.label ?? '';
|
const label = context.dataset.label ?? '';
|
||||||
return `${label} ${smartDecimal(context.parsed.y)}${INSIGHTS_UNIT_MAPPING[props.type]}`;
|
return `${label} ${smartDecimal(context.parsed.y)}${INSIGHTS_UNIT_MAPPING[props.type](context.parsed.y)}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -40,7 +40,7 @@ const chartData = computed<ChartData<'line'>>(() => {
|
|||||||
const data: number[] = [];
|
const data: number[] = [];
|
||||||
|
|
||||||
for (const entry of props.data) {
|
for (const entry of props.data) {
|
||||||
labels.push(dateformat(entry.date, 'd. mmm'));
|
labels.push(dateformat(entry.date, DATE_FORMAT_MASK));
|
||||||
|
|
||||||
const value = transformInsightsAverageRunTime(entry.values.averageRunTime);
|
const value = transformInsightsAverageRunTime(entry.values.averageRunTime);
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
|||||||
import { generateBarChartOptions } from '@/features/insights/chartjs.utils';
|
import { generateBarChartOptions } from '@/features/insights/chartjs.utils';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
||||||
|
import { DATE_FORMAT_MASK } from '@/features/insights/insights.constants';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
data: InsightsByTime[];
|
data: InsightsByTime[];
|
||||||
@@ -37,7 +38,7 @@ const chartData = computed<ChartData<'bar'>>(() => {
|
|||||||
const data: number[] = [];
|
const data: number[] = [];
|
||||||
|
|
||||||
for (const entry of props.data) {
|
for (const entry of props.data) {
|
||||||
labels.push(dateformat(entry.date, 'd. mmm'));
|
labels.push(dateformat(entry.date, DATE_FORMAT_MASK));
|
||||||
data.push(entry.values.failed);
|
data.push(entry.values.failed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,15 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
|
import { useI18n } from '@/composables/useI18n';
|
||||||
|
import { generateBarChartOptions } from '@/features/insights/chartjs.utils';
|
||||||
|
import { DATE_FORMAT_MASK, INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
||||||
|
import { transformInsightsFailureRate } from '@/features/insights/insights.utils';
|
||||||
|
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
||||||
|
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
||||||
|
import { useCssVar } from '@vueuse/core';
|
||||||
|
import type { ChartData } from 'chart.js';
|
||||||
|
import dateformat from 'dateformat';
|
||||||
import { computed } from 'vue';
|
import { computed } from 'vue';
|
||||||
import { Bar } from 'vue-chartjs';
|
import { Bar } from 'vue-chartjs';
|
||||||
import type { ChartData } from 'chart.js';
|
|
||||||
import { useCssVar } from '@vueuse/core';
|
|
||||||
import dateformat from 'dateformat';
|
|
||||||
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
|
||||||
import { generateBarChartOptions } from '@/features/insights/chartjs.utils';
|
|
||||||
import { useI18n } from '@/composables/useI18n';
|
|
||||||
import { transformInsightsFailureRate } from '@/features/insights/insights.utils';
|
|
||||||
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
|
||||||
import { INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
data: InsightsByTime[];
|
data: InsightsByTime[];
|
||||||
@@ -26,7 +26,7 @@ const chartOptions = computed(() =>
|
|||||||
callbacks: {
|
callbacks: {
|
||||||
label: (context) => {
|
label: (context) => {
|
||||||
const label = context.dataset.label ?? '';
|
const label = context.dataset.label ?? '';
|
||||||
return `${label} ${smartDecimal(context.parsed.y)}${INSIGHTS_UNIT_MAPPING[props.type]}`;
|
return `${label} ${smartDecimal(context.parsed.y)}${INSIGHTS_UNIT_MAPPING[props.type](context.parsed.y)}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -39,7 +39,7 @@ const chartData = computed<ChartData<'bar'>>(() => {
|
|||||||
const data: number[] = [];
|
const data: number[] = [];
|
||||||
|
|
||||||
for (const entry of props.data) {
|
for (const entry of props.data) {
|
||||||
labels.push(dateformat(entry.date, 'd. mmm'));
|
labels.push(dateformat(entry.date, DATE_FORMAT_MASK));
|
||||||
data.push(transformInsightsFailureRate(entry.values.failureRate));
|
data.push(transformInsightsFailureRate(entry.values.failureRate));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,17 @@
|
|||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed } from 'vue';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
import { Line } from 'vue-chartjs';
|
|
||||||
import { type ScriptableContext, type ChartData, Filler } from 'chart.js';
|
|
||||||
import dateformat from 'dateformat';
|
|
||||||
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
|
||||||
import {
|
import {
|
||||||
generateLinearGradient,
|
generateLinearGradient,
|
||||||
generateLineChartOptions,
|
generateLineChartOptions,
|
||||||
} from '@/features/insights/chartjs.utils';
|
} from '@/features/insights/chartjs.utils';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
|
||||||
import { transformInsightsTimeSaved } from '@/features/insights/insights.utils';
|
import { transformInsightsTimeSaved } from '@/features/insights/insights.utils';
|
||||||
import { smartDecimal } from '@n8n/utils/number/smartDecimal';
|
|
||||||
import { INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
import { DATE_FORMAT_MASK, INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
||||||
|
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
||||||
|
import { type ChartData, Filler, type ScriptableContext } from 'chart.js';
|
||||||
|
import dateformat from 'dateformat';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { Line } from 'vue-chartjs';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
data: InsightsByTime[];
|
data: InsightsByTime[];
|
||||||
@@ -27,7 +27,18 @@ const chartOptions = computed(() =>
|
|||||||
callbacks: {
|
callbacks: {
|
||||||
label: (context) => {
|
label: (context) => {
|
||||||
const label = context.dataset.label ?? '';
|
const label = context.dataset.label ?? '';
|
||||||
return `${label} ${smartDecimal(context.parsed.y)}${INSIGHTS_UNIT_MAPPING[props.type]}`;
|
const value = Number(context.parsed.y);
|
||||||
|
return `${label} ${transformInsightsTimeSaved(value).toLocaleString('en-US')}${INSIGHTS_UNIT_MAPPING[props.type](value)}`;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
scales: {
|
||||||
|
y: {
|
||||||
|
ticks: {
|
||||||
|
// eslint-disable-next-line id-denylist
|
||||||
|
callback(tickValue) {
|
||||||
|
return transformInsightsTimeSaved(Number(tickValue));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -40,9 +51,8 @@ const chartData = computed<ChartData<'line'>>(() => {
|
|||||||
const data: number[] = [];
|
const data: number[] = [];
|
||||||
|
|
||||||
for (const entry of props.data) {
|
for (const entry of props.data) {
|
||||||
labels.push(dateformat(entry.date, 'd. mmm'));
|
labels.push(dateformat(entry.date, DATE_FORMAT_MASK));
|
||||||
const timeSaved = transformInsightsTimeSaved(entry.values.timeSaved);
|
data.push(entry.values.timeSaved);
|
||||||
data.push(timeSaved);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import dateformat from 'dateformat';
|
|||||||
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
import type { InsightsByTime, InsightsSummaryType } from '@n8n/api-types';
|
||||||
import { generateBarChartOptions } from '@/features/insights/chartjs.utils';
|
import { generateBarChartOptions } from '@/features/insights/chartjs.utils';
|
||||||
import { useI18n } from '@/composables/useI18n';
|
import { useI18n } from '@/composables/useI18n';
|
||||||
|
import { DATE_FORMAT_MASK } from '@/features/insights/insights.constants';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
data: InsightsByTime[];
|
data: InsightsByTime[];
|
||||||
@@ -33,7 +34,7 @@ const chartData = computed<ChartData<'bar'>>(() => {
|
|||||||
const failedData: number[] = [];
|
const failedData: number[] = [];
|
||||||
|
|
||||||
for (const entry of props.data) {
|
for (const entry of props.data) {
|
||||||
labels.push(dateformat(entry.date, 'd. mmm'));
|
labels.push(dateformat(entry.date, DATE_FORMAT_MASK));
|
||||||
succeededData.push(entry.values.succeeded);
|
succeededData.push(entry.values.succeeded);
|
||||||
failedData.push(entry.values.failed);
|
failedData.push(entry.values.failed);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
<script lang="ts" setup="">
|
<script lang="ts" setup="">
|
||||||
|
import { useI18n } from '@/composables/useI18n';
|
||||||
import { INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
import { INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
||||||
import {
|
import {
|
||||||
transformInsightsAverageRunTime,
|
transformInsightsAverageRunTime,
|
||||||
@@ -18,6 +19,8 @@ const props = defineProps<{
|
|||||||
loading?: boolean;
|
loading?: boolean;
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
|
const i18n = useI18n();
|
||||||
|
|
||||||
type Item = InsightsByWorkflow['data'][number];
|
type Item = InsightsByWorkflow['data'][number];
|
||||||
|
|
||||||
const rows = computed(() => props.data.data);
|
const rows = computed(() => props.data.data);
|
||||||
@@ -30,39 +33,46 @@ const headers = ref<Array<TableHeader<Item>>>([
|
|||||||
disableSort: true,
|
disableSort: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Total executions',
|
title: i18n.baseText('insights.banner.title.total'),
|
||||||
key: 'total',
|
key: 'total',
|
||||||
|
value(row) {
|
||||||
|
return row.total.toLocaleString('en-US');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Total failed executions',
|
title: i18n.baseText('insights.banner.title.failed'),
|
||||||
key: 'failed',
|
key: 'failed',
|
||||||
|
value(row) {
|
||||||
|
return row.failed.toLocaleString('en-US');
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Average run time',
|
title: i18n.baseText('insights.banner.title.failureRate'),
|
||||||
key: 'failureRate',
|
key: 'failureRate',
|
||||||
value(row) {
|
value(row) {
|
||||||
return (
|
return (
|
||||||
smartDecimal(transformInsightsFailureRate(row.failureRate)) +
|
smartDecimal(transformInsightsFailureRate(row.failureRate)) +
|
||||||
INSIGHTS_UNIT_MAPPING.failureRate
|
INSIGHTS_UNIT_MAPPING.failureRate(row.failureRate)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Time saved',
|
title: i18n.baseText('insights.banner.title.timeSaved'),
|
||||||
key: 'timeSaved',
|
key: 'timeSaved',
|
||||||
value(row) {
|
value(row) {
|
||||||
return (
|
return (
|
||||||
smartDecimal(transformInsightsTimeSaved(row.timeSaved)) + INSIGHTS_UNIT_MAPPING.timeSaved
|
smartDecimal(transformInsightsTimeSaved(row.timeSaved)) +
|
||||||
|
INSIGHTS_UNIT_MAPPING.timeSaved(row.timeSaved)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Run time',
|
title: i18n.baseText('insights.banner.title.averageRunTime'),
|
||||||
key: 'averageRunTime',
|
key: 'averageRunTime',
|
||||||
value(row) {
|
value(row) {
|
||||||
return (
|
return (
|
||||||
smartDecimal(transformInsightsAverageRunTime(row.averageRunTime)) +
|
smartDecimal(transformInsightsAverageRunTime(row.averageRunTime)) +
|
||||||
INSIGHTS_UNIT_MAPPING.averageRunTime
|
INSIGHTS_UNIT_MAPPING.averageRunTime(row.averageRunTime)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -8,12 +8,23 @@ export const INSIGHTS_SUMMARY_ORDER: InsightsSummaryType[] = [
|
|||||||
'averageRunTime',
|
'averageRunTime',
|
||||||
];
|
];
|
||||||
|
|
||||||
export const INSIGHTS_UNIT_MAPPING: Record<InsightsSummaryType, string> = {
|
export const INSIGHTS_UNIT_MAPPING: Record<InsightsSummaryType, (value: number) => string> = {
|
||||||
total: '',
|
total: () => '',
|
||||||
failed: '',
|
failed: () => '',
|
||||||
failureRate: '%',
|
failureRate: () => '%',
|
||||||
timeSaved: 'h',
|
timeSaved: (value: number) => (Math.abs(value) < 3600 ? 'm' : 'h'),
|
||||||
averageRunTime: 's',
|
averageRunTime: () => 's',
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export const INSIGHTS_DEVIATION_UNIT_MAPPING: Record<
|
||||||
|
InsightsSummaryType,
|
||||||
|
(deviation: number) => string
|
||||||
|
> = {
|
||||||
|
total: () => '%',
|
||||||
|
failed: () => '%',
|
||||||
|
failureRate: () => 'pp',
|
||||||
|
timeSaved: (deviation: number) => (Math.abs(deviation) < 3600 ? 'm' : 'h'),
|
||||||
|
averageRunTime: () => 's',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
export const INSIGHT_IMPACT_TYPES = {
|
export const INSIGHT_IMPACT_TYPES = {
|
||||||
@@ -32,3 +43,5 @@ export const INSIGHTS_UNIT_IMPACT_MAPPING: Record<
|
|||||||
timeSaved: INSIGHT_IMPACT_TYPES.POSITIVE, // More time saved is good → positive (green)
|
timeSaved: INSIGHT_IMPACT_TYPES.POSITIVE, // More time saved is good → positive (green)
|
||||||
averageRunTime: INSIGHT_IMPACT_TYPES.NEUTRAL, // Not good or bad → neutral (grey)
|
averageRunTime: INSIGHT_IMPACT_TYPES.NEUTRAL, // Not good or bad → neutral (grey)
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const DATE_FORMAT_MASK = 'mmm d';
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { RouterView, type RouteRecordRaw } from 'vue-router';
|
import { RouterView, type RouteRecordRaw } from 'vue-router';
|
||||||
import { VIEWS } from '@/constants';
|
import { VIEWS } from '@/constants';
|
||||||
|
import { useInsightsStore } from '@/features/insights/insights.store';
|
||||||
|
|
||||||
const MainSidebar = async () => await import('@/components/MainSidebar.vue');
|
const MainSidebar = async () => await import('@/components/MainSidebar.vue');
|
||||||
const InsightsDashboard = async () =>
|
const InsightsDashboard = async () =>
|
||||||
@@ -8,6 +9,10 @@ const InsightsDashboard = async () =>
|
|||||||
export const insightsRoutes: RouteRecordRaw[] = [
|
export const insightsRoutes: RouteRecordRaw[] = [
|
||||||
{
|
{
|
||||||
path: '/insights',
|
path: '/insights',
|
||||||
|
beforeEnter() {
|
||||||
|
const insightsStore = useInsightsStore();
|
||||||
|
return insightsStore.isInsightsEnabled || { name: VIEWS.NOT_FOUND };
|
||||||
|
},
|
||||||
components: {
|
components: {
|
||||||
default: RouterView,
|
default: RouterView,
|
||||||
sidebar: MainSidebar,
|
sidebar: MainSidebar,
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
import type { INSIGHTS_UNIT_MAPPING } from '@/features/insights/insights.constants';
|
import type {
|
||||||
|
INSIGHTS_UNIT_MAPPING,
|
||||||
|
INSIGHTS_DEVIATION_UNIT_MAPPING,
|
||||||
|
} from '@/features/insights/insights.constants';
|
||||||
|
|
||||||
type InsightsDisplayUnits = typeof INSIGHTS_UNIT_MAPPING;
|
type InsightsDisplayUnits = typeof INSIGHTS_UNIT_MAPPING;
|
||||||
|
type InsightsDisplayDeviationUnits = typeof INSIGHTS_DEVIATION_UNIT_MAPPING;
|
||||||
|
|
||||||
export type InsightsSummaryDisplay = Array<
|
export type InsightsSummaryDisplay = Array<
|
||||||
{
|
{
|
||||||
@@ -8,7 +12,8 @@ export type InsightsSummaryDisplay = Array<
|
|||||||
id: K;
|
id: K;
|
||||||
value: number;
|
value: number;
|
||||||
deviation: number | null;
|
deviation: number | null;
|
||||||
unit: InsightsDisplayUnits[K];
|
deviationUnit: ReturnType<InsightsDisplayDeviationUnits[K]>;
|
||||||
|
unit: ReturnType<InsightsDisplayUnits[K]>;
|
||||||
};
|
};
|
||||||
}[keyof InsightsDisplayUnits]
|
}[keyof InsightsDisplayUnits]
|
||||||
>;
|
>;
|
||||||
|
|||||||
@@ -3,28 +3,46 @@ import type { InsightsSummaryDisplay } from '@/features/insights/insights.types'
|
|||||||
import {
|
import {
|
||||||
INSIGHTS_SUMMARY_ORDER,
|
INSIGHTS_SUMMARY_ORDER,
|
||||||
INSIGHTS_UNIT_MAPPING,
|
INSIGHTS_UNIT_MAPPING,
|
||||||
|
INSIGHTS_DEVIATION_UNIT_MAPPING,
|
||||||
} from '@/features/insights/insights.constants';
|
} from '@/features/insights/insights.constants';
|
||||||
|
|
||||||
export const transformInsightsTimeSaved = (value: number): number => value / 3600; // we want to show saved time in hours
|
export const transformInsightsTimeSaved = (seconds: number): number =>
|
||||||
export const transformInsightsAverageRunTime = (value: number): number => value / 1000; // we want to show average run time in seconds
|
Math.round(seconds / (Math.abs(seconds) < 3600 ? 60 : 3600)); // we want to show saved time in minutes or hours
|
||||||
|
export const transformInsightsAverageRunTime = (ms: number): number => ms / 1000; // we want to show average run time in seconds
|
||||||
export const transformInsightsFailureRate = (value: number): number => value * 100; // we want to show failure rate in percentage
|
export const transformInsightsFailureRate = (value: number): number => value * 100; // we want to show failure rate in percentage
|
||||||
|
|
||||||
export const transformInsightsValues: Partial<
|
export const transformInsightsValues: Record<InsightsSummaryType, (value: number) => number> = {
|
||||||
Record<InsightsSummaryType, (value: number) => number>
|
total: (value: number) => value,
|
||||||
> = {
|
failed: (value: number) => value,
|
||||||
timeSaved: transformInsightsTimeSaved,
|
timeSaved: transformInsightsTimeSaved,
|
||||||
averageRunTime: transformInsightsAverageRunTime,
|
averageRunTime: transformInsightsAverageRunTime,
|
||||||
failureRate: transformInsightsFailureRate,
|
failureRate: transformInsightsFailureRate,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const transformInsightsDeviation: Record<
|
||||||
|
InsightsSummaryType,
|
||||||
|
(value: number, deviation: number) => number
|
||||||
|
> = {
|
||||||
|
total: (value: number, deviation: number) => (deviation / value) * 100,
|
||||||
|
failed: (value: number, deviation: number) => (deviation / value) * 100,
|
||||||
|
timeSaved: (_: number, deviation: number) => transformInsightsTimeSaved(deviation),
|
||||||
|
averageRunTime: (_: number, deviation: number) => transformInsightsAverageRunTime(deviation),
|
||||||
|
failureRate: (_: number, deviation: number) => transformInsightsFailureRate(deviation),
|
||||||
|
};
|
||||||
|
|
||||||
export const transformInsightsSummary = (data: InsightsSummary | null): InsightsSummaryDisplay =>
|
export const transformInsightsSummary = (data: InsightsSummary | null): InsightsSummaryDisplay =>
|
||||||
data
|
data
|
||||||
? INSIGHTS_SUMMARY_ORDER.map((key) => ({
|
? INSIGHTS_SUMMARY_ORDER.map((key) => ({
|
||||||
id: key,
|
id: key,
|
||||||
value: transformInsightsValues[key]?.(data[key].value) ?? data[key].value,
|
value: transformInsightsValues[key](data[key].value),
|
||||||
deviation: data[key].deviation
|
deviation:
|
||||||
? (transformInsightsValues[key]?.(data[key].deviation) ?? data[key].deviation)
|
data[key].deviation === null
|
||||||
: null,
|
? null
|
||||||
unit: INSIGHTS_UNIT_MAPPING[key],
|
: transformInsightsDeviation[key](data[key].value, data[key].deviation),
|
||||||
|
deviationUnit:
|
||||||
|
data[key].deviation === null
|
||||||
|
? ''
|
||||||
|
: INSIGHTS_DEVIATION_UNIT_MAPPING[key](data[key].deviation),
|
||||||
|
unit: INSIGHTS_UNIT_MAPPING[key](data[key].value),
|
||||||
}))
|
}))
|
||||||
: [];
|
: [];
|
||||||
|
|||||||
@@ -3073,15 +3073,17 @@
|
|||||||
"freeAi.credits.showError.claim.message": "Enable to claim credits",
|
"freeAi.credits.showError.claim.message": "Enable to claim credits",
|
||||||
"freeAi.credits.showWarning.workflow.activation.title": "You're using free OpenAI API credits",
|
"freeAi.credits.showWarning.workflow.activation.title": "You're using free OpenAI API credits",
|
||||||
"freeAi.credits.showWarning.workflow.activation.description": "To make sure your workflow runs smoothly in the future, replace the free OpenAI API credits with your own API key.",
|
"freeAi.credits.showWarning.workflow.activation.description": "To make sure your workflow runs smoothly in the future, replace the free OpenAI API credits with your own API key.",
|
||||||
"insights.banner.title": "Production executions for the last {count} days",
|
"insights.lastNDays": "Last {count} days",
|
||||||
"insights.banner.timeSaved.tooltip": "No estimate available yet. To see potential time savings, {link} to each workflow from workflow settings.",
|
"insights.banner.timeSaved.tooltip": "No estimate available yet. To see potential time savings, {link} to each workflow from workflow settings.",
|
||||||
"insights.banner.timeSaved.tooltip.link.text": "add time estimates",
|
"insights.banner.timeSaved.tooltip.link.text": "add time estimates",
|
||||||
"insights.banner.title.total": "Total",
|
"insights.banner.title.total": "Prod. executions",
|
||||||
"insights.banner.title.failed": "Failed",
|
"insights.banner.title.failed": "Failed prod. executions",
|
||||||
"insights.banner.title.succeeded": "Succeeded",
|
"insights.banner.title.succeeded": "Successful prod. executions",
|
||||||
"insights.banner.title.failureRate": "Failure rate",
|
"insights.banner.title.failureRate": "Failure rate",
|
||||||
"insights.banner.title.timeSaved": "Time saved",
|
"insights.banner.title.timeSaved": "Time saved",
|
||||||
"insights.banner.title.timeSavedDailyAverage": "Time saved daily avg.",
|
"insights.banner.title.timeSavedDailyAverage": "Time saved daily avg.",
|
||||||
"insights.banner.title.averageRunTime": "Avg. run time",
|
"insights.banner.title.averageRunTime": "Run time (avg.)",
|
||||||
"insights.dashboard.title": "Insights"
|
"insights.dashboard.title": "Insights",
|
||||||
|
"insights.banner.title.timeSaved.tooltip": "Total time saved calculated from your estimated time savings per execution across all workflows",
|
||||||
|
"insights.banner.failureRate.deviation.tooltip": "Percentage point change from previous period"
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user