diff --git a/packages/editor-ui/src/components/Projects/ProjectHeader.vue b/packages/editor-ui/src/components/Projects/ProjectHeader.vue index 80a45bfeb6ad3..f786a3163120f 100644 --- a/packages/editor-ui/src/components/Projects/ProjectHeader.vue +++ b/packages/editor-ui/src/components/Projects/ProjectHeader.vue @@ -140,6 +140,7 @@ const onSelect = (action: string) => { +
diff --git a/packages/editor-ui/src/features/insights/InsightsSummary.vue b/packages/editor-ui/src/features/insights/InsightsSummary.vue new file mode 100644 index 0000000000000..a4048678fe069 --- /dev/null +++ b/packages/editor-ui/src/features/insights/InsightsSummary.vue @@ -0,0 +1,110 @@ + + + + + diff --git a/packages/editor-ui/src/features/insights/insights.store.ts b/packages/editor-ui/src/features/insights/insights.store.ts new file mode 100644 index 0000000000000..bfd3a87df9868 --- /dev/null +++ b/packages/editor-ui/src/features/insights/insights.store.ts @@ -0,0 +1,61 @@ +import { defineStore } from 'pinia'; + +export type Summary = { + id: string; + title: string; + count: number; + sign?: string; + deviation: number; + evaluation?: 'positive' | 'negative'; +}; + +export const useInsightsStore = defineStore('insights', () => { + const fetchSummary = async (): Promise => { + return [ + { + id: 'executions', + title: 'Executions', + count: 525, + deviation: 85, + sign: undefined, + evaluation: 'positive' as const, + }, + { + id: 'failed', + title: 'Failed executions', + count: 14, + deviation: 3, + sign: undefined, + evaluation: 'negative' as const, + }, + { + id: 'failureRate', + title: 'Failure rate', + count: 1.9, + deviation: -5, + sign: '%', + evaluation: 'negative' as const, + }, + { + id: 'runTime', + title: 'Avg. run time', + count: 2.5, + deviation: -5, + sign: 's', + evaluation: 'positive' as const, + }, + { + id: 'timeSaved', + title: 'Time saved', + count: 54, + deviation: -5, + sign: 'h', + evaluation: 'negative' as const, + }, + ]; + }; + + return { + fetchSummary, + }; +}); diff --git a/packages/editor-ui/src/plugins/icons/index.ts b/packages/editor-ui/src/plugins/icons/index.ts index 18e8113fca4ec..563a14a90f0ff 100644 --- a/packages/editor-ui/src/plugins/icons/index.ts +++ b/packages/editor-ui/src/plugins/icons/index.ts @@ -23,6 +23,8 @@ import { faBrain, faCalculator, faCalendar, + faCaretDown, + faCaretUp, faChartBar, faCheck, faCheckCircle, @@ -198,6 +200,8 @@ export const FontAwesomePlugin: Plugin = { addIcon(faBrain); addIcon(faCalculator); addIcon(faCalendar); + addIcon(faCaretDown); + addIcon(faCaretUp); addIcon(faChartBar); addIcon(faCheck); addIcon(faCheckCircle); diff --git a/packages/editor-ui/src/views/WorkflowsView.vue b/packages/editor-ui/src/views/WorkflowsView.vue index e67099f78a311..fc667be87151c 100644 --- a/packages/editor-ui/src/views/WorkflowsView.vue +++ b/packages/editor-ui/src/views/WorkflowsView.vue @@ -40,6 +40,9 @@ import ProjectHeader from '@/components/Projects/ProjectHeader.vue'; import { getEasyAiWorkflowJson } from '@/utils/easyAiWorkflowUtils'; import { useDebounce } from '@/composables/useDebounce'; import { createEventBus } from 'n8n-design-system/utils'; +import { useInsightsStore } from '@/features/insights/insights.store'; +import InsightsSummary from '@/features/insights/InsightsSummary.vue'; +import { useAsyncState } from '@vueuse/core'; interface Filters extends BaseFilters { status: string | boolean; @@ -76,6 +79,11 @@ const tagsStore = useTagsStore(); const documentTitle = useDocumentTitle(); const { callDebounced } = useDebounce(); +const insightsStore = useInsightsStore(); +const { state: summaries } = useAsyncState(insightsStore.fetchSummary, [], { + immediate: true, +}); + const loading = ref(false); const filters = ref({ search: '', @@ -446,7 +454,9 @@ const onWorkflowActiveToggle = (data: { id: string; active: boolean }) => { @sort="onSortUpdated" >