mirror of
https://github.com/n8n-io/n8n.git
synced 2024-11-10 06:34:05 -08:00
fix(editor): Add loading skeletons to Executions list page (#6184)
* fix(editor): Add loading skeletons to Executions list page * fix(editor): lint fix * fix(editor): fix loading * fix(editor): fix loading * fix(editor): fix keys * fix(editor): fix localization * fix(editor): fix key
This commit is contained in:
parent
cbc4256007
commit
eae3a55cc6
|
@ -162,26 +162,24 @@ onBeforeMount(() => {
|
||||||
data-test-id="execution-filter-badge"
|
data-test-id="execution-filter-badge"
|
||||||
>{{ countSelectedFilterProps }}</n8n-badge
|
>{{ countSelectedFilterProps }}</n8n-badge
|
||||||
>
|
>
|
||||||
{{ $locale.baseText('executionsList.filters') }}
|
{{ locale.baseText('executionsList.filters') }}
|
||||||
</n8n-button>
|
</n8n-button>
|
||||||
</template>
|
</template>
|
||||||
<div data-test-id="execution-filter-form">
|
<div data-test-id="execution-filter-form">
|
||||||
<div v-if="workflows?.length" :class="$style.group">
|
<div v-if="workflows?.length" :class="$style.group">
|
||||||
<label for="execution-filter-workflows">{{
|
<label for="execution-filter-workflows">{{ locale.baseText('workflows.heading') }}</label>
|
||||||
$locale.baseText('workflows.heading')
|
|
||||||
}}</label>
|
|
||||||
<n8n-select
|
<n8n-select
|
||||||
id="execution-filter-workflows"
|
id="execution-filter-workflows"
|
||||||
v-model="vModel.workflowId"
|
v-model="vModel.workflowId"
|
||||||
:placeholder="$locale.baseText('executionsFilter.selectWorkflow')"
|
:placeholder="locale.baseText('executionsFilter.selectWorkflow')"
|
||||||
size="medium"
|
size="medium"
|
||||||
filterable
|
filterable
|
||||||
data-test-id="executions-filter-workflows-select"
|
data-test-id="executions-filter-workflows-select"
|
||||||
>
|
>
|
||||||
<div class="ph-no-capture">
|
<div class="ph-no-capture">
|
||||||
<n8n-option
|
<n8n-option
|
||||||
v-for="item in workflows"
|
v-for="(item, idx) in props.workflows"
|
||||||
:key="item.id"
|
:key="idx"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
|
@ -189,12 +187,10 @@ onBeforeMount(() => {
|
||||||
</n8n-select>
|
</n8n-select>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="showTags" :class="$style.group">
|
<div v-if="showTags" :class="$style.group">
|
||||||
<label for="execution-filter-tags">{{
|
<label for="execution-filter-tags">{{ locale.baseText('workflows.filters.tags') }}</label>
|
||||||
$locale.baseText('workflows.filters.tags')
|
|
||||||
}}</label>
|
|
||||||
<TagsDropdown
|
<TagsDropdown
|
||||||
id="execution-filter-tags"
|
id="execution-filter-tags"
|
||||||
:placeholder="$locale.baseText('workflowOpen.filterWorkflows')"
|
:placeholder="locale.baseText('workflowOpen.filterWorkflows')"
|
||||||
:currentTagIds="filter.tags"
|
:currentTagIds="filter.tags"
|
||||||
:createEnabled="false"
|
:createEnabled="false"
|
||||||
@update="onTagsChange"
|
@update="onTagsChange"
|
||||||
|
@ -203,19 +199,19 @@ onBeforeMount(() => {
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.group">
|
<div :class="$style.group">
|
||||||
<label for="execution-filter-status">{{
|
<label for="execution-filter-status">{{
|
||||||
$locale.baseText('executionsList.status')
|
locale.baseText('executionsList.status')
|
||||||
}}</label>
|
}}</label>
|
||||||
<n8n-select
|
<n8n-select
|
||||||
id="execution-filter-status"
|
id="execution-filter-status"
|
||||||
v-model="vModel.status"
|
v-model="vModel.status"
|
||||||
:placeholder="$locale.baseText('executionsFilter.selectStatus')"
|
:placeholder="locale.baseText('executionsFilter.selectStatus')"
|
||||||
size="medium"
|
size="medium"
|
||||||
filterable
|
filterable
|
||||||
data-test-id="executions-filter-status-select"
|
data-test-id="executions-filter-status-select"
|
||||||
>
|
>
|
||||||
<n8n-option
|
<n8n-option
|
||||||
v-for="item in statuses"
|
v-for="(item, idx) in statuses"
|
||||||
:key="item.id"
|
:key="idx"
|
||||||
:label="item.name"
|
:label="item.name"
|
||||||
:value="item.id"
|
:value="item.id"
|
||||||
/>
|
/>
|
||||||
|
@ -223,7 +219,7 @@ onBeforeMount(() => {
|
||||||
</div>
|
</div>
|
||||||
<div :class="$style.group">
|
<div :class="$style.group">
|
||||||
<label for="execution-filter-start-date">{{
|
<label for="execution-filter-start-date">{{
|
||||||
$locale.baseText('executionsFilter.start')
|
locale.baseText('executionsFilter.start')
|
||||||
}}</label>
|
}}</label>
|
||||||
<div :class="$style.dates">
|
<div :class="$style.dates">
|
||||||
<el-date-picker
|
<el-date-picker
|
||||||
|
@ -231,7 +227,7 @@ onBeforeMount(() => {
|
||||||
type="datetime"
|
type="datetime"
|
||||||
v-model="vModel.startDate"
|
v-model="vModel.startDate"
|
||||||
:format="DATE_TIME_MASK"
|
:format="DATE_TIME_MASK"
|
||||||
:placeholder="$locale.baseText('executionsFilter.startDate')"
|
:placeholder="locale.baseText('executionsFilter.startDate')"
|
||||||
data-test-id="executions-filter-start-date-picker"
|
data-test-id="executions-filter-start-date-picker"
|
||||||
/>
|
/>
|
||||||
<span :class="$style.divider">to</span>
|
<span :class="$style.divider">to</span>
|
||||||
|
@ -240,7 +236,7 @@ onBeforeMount(() => {
|
||||||
type="datetime"
|
type="datetime"
|
||||||
v-model="vModel.endDate"
|
v-model="vModel.endDate"
|
||||||
:format="DATE_TIME_MASK"
|
:format="DATE_TIME_MASK"
|
||||||
:placeholder="$locale.baseText('executionsFilter.endDate')"
|
:placeholder="locale.baseText('executionsFilter.endDate')"
|
||||||
data-test-id="executions-filter-end-date-picker"
|
data-test-id="executions-filter-end-date-picker"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -254,19 +250,19 @@ onBeforeMount(() => {
|
||||||
target="_blank"
|
target="_blank"
|
||||||
href="https://docs.n8n.io/workflows/executions/custom-executions-data/"
|
href="https://docs.n8n.io/workflows/executions/custom-executions-data/"
|
||||||
>
|
>
|
||||||
{{ $locale.baseText('executionsFilter.customData.docsTooltip.link') }}
|
{{ locale.baseText('executionsFilter.customData.docsTooltip.link') }}
|
||||||
</a>
|
</a>
|
||||||
</template>
|
</template>
|
||||||
</i18n>
|
</i18n>
|
||||||
</template>
|
</template>
|
||||||
<span :class="$style.label">
|
<span :class="$style.label">
|
||||||
{{ $locale.baseText('executionsFilter.savedData') }}
|
{{ locale.baseText('executionsFilter.savedData') }}
|
||||||
<n8n-icon :class="$style.tooltipIcon" icon="question-circle" size="small" />
|
<n8n-icon :class="$style.tooltipIcon" icon="question-circle" size="small" />
|
||||||
</span>
|
</span>
|
||||||
</n8n-tooltip>
|
</n8n-tooltip>
|
||||||
<div :class="$style.subGroup">
|
<div :class="$style.subGroup">
|
||||||
<label for="execution-filter-saved-data-key">{{
|
<label for="execution-filter-saved-data-key">{{
|
||||||
$locale.baseText('executionsFilter.savedDataKey')
|
locale.baseText('executionsFilter.savedDataKey')
|
||||||
}}</label>
|
}}</label>
|
||||||
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
|
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
|
@ -276,7 +272,7 @@ onBeforeMount(() => {
|
||||||
href="#"
|
href="#"
|
||||||
@click.prevent="goToUpgrade"
|
@click.prevent="goToUpgrade"
|
||||||
data-test-id="executions-filter-view-plans-link"
|
data-test-id="executions-filter-view-plans-link"
|
||||||
>{{ $locale.baseText('executionsFilter.customData.inputTooltip.link') }}</a
|
>{{ locale.baseText('executionsFilter.customData.inputTooltip.link') }}</a
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
</i18n>
|
</i18n>
|
||||||
|
@ -287,21 +283,21 @@ onBeforeMount(() => {
|
||||||
type="text"
|
type="text"
|
||||||
size="medium"
|
size="medium"
|
||||||
:disabled="!isAdvancedExecutionFilterEnabled"
|
:disabled="!isAdvancedExecutionFilterEnabled"
|
||||||
:placeholder="$locale.baseText('executionsFilter.savedDataKeyPlaceholder')"
|
:placeholder="locale.baseText('executionsFilter.savedDataKeyPlaceholder')"
|
||||||
:value="filter.metadata[0]?.key"
|
:value="filter.metadata[0]?.key"
|
||||||
@input="onFilterMetaChange(0, 'key', $event)"
|
@input="onFilterMetaChange(0, 'key', $event)"
|
||||||
data-test-id="execution-filter-saved-data-key-input"
|
data-test-id="execution-filter-saved-data-key-input"
|
||||||
/>
|
/>
|
||||||
</n8n-tooltip>
|
</n8n-tooltip>
|
||||||
<label for="execution-filter-saved-data-value">{{
|
<label for="execution-filter-saved-data-value">{{
|
||||||
$locale.baseText('executionsFilter.savedDataValue')
|
locale.baseText('executionsFilter.savedDataValue')
|
||||||
}}</label>
|
}}</label>
|
||||||
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
|
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
|
||||||
<template #content>
|
<template #content>
|
||||||
<i18n tag="span" path="executionsFilter.customData.inputTooltip">
|
<i18n tag="span" path="executionsFilter.customData.inputTooltip">
|
||||||
<template #link>
|
<template #link>
|
||||||
<a href="#" @click.prevent="goToUpgrade">{{
|
<a href="#" @click.prevent="goToUpgrade">{{
|
||||||
$locale.baseText('executionsFilter.customData.inputTooltip.link')
|
locale.baseText('executionsFilter.customData.inputTooltip.link')
|
||||||
}}</a>
|
}}</a>
|
||||||
</template>
|
</template>
|
||||||
</i18n>
|
</i18n>
|
||||||
|
@ -312,7 +308,7 @@ onBeforeMount(() => {
|
||||||
type="text"
|
type="text"
|
||||||
size="medium"
|
size="medium"
|
||||||
:disabled="!isAdvancedExecutionFilterEnabled"
|
:disabled="!isAdvancedExecutionFilterEnabled"
|
||||||
:placeholder="$locale.baseText('executionsFilter.savedDataValuePlaceholder')"
|
:placeholder="locale.baseText('executionsFilter.savedDataValuePlaceholder')"
|
||||||
:value="filter.metadata[0]?.value"
|
:value="filter.metadata[0]?.value"
|
||||||
@input="onFilterMetaChange(0, 'value', $event)"
|
@input="onFilterMetaChange(0, 'value', $event)"
|
||||||
data-test-id="execution-filter-saved-data-value-input"
|
data-test-id="execution-filter-saved-data-value-input"
|
||||||
|
@ -328,7 +324,7 @@ onBeforeMount(() => {
|
||||||
text
|
text
|
||||||
data-test-id="executions-filter-reset-button"
|
data-test-id="executions-filter-reset-button"
|
||||||
>
|
>
|
||||||
{{ $locale.baseText('executionsFilter.reset') }}
|
{{ locale.baseText('executionsFilter.reset') }}
|
||||||
</n8n-button>
|
</n8n-button>
|
||||||
</div>
|
</div>
|
||||||
</n8n-popover>
|
</n8n-popover>
|
||||||
|
|
|
@ -4,7 +4,9 @@
|
||||||
<div :class="$style.execListHeader">
|
<div :class="$style.execListHeader">
|
||||||
<n8n-heading tag="h1" size="2xlarge">{{ this.pageTitle }}</n8n-heading>
|
<n8n-heading tag="h1" size="2xlarge">{{ this.pageTitle }}</n8n-heading>
|
||||||
<div :class="$style.execListHeaderControls">
|
<div :class="$style.execListHeaderControls">
|
||||||
|
<n8n-loading v-if="isMounting" :class="$style.filterLoader" variant="custom" />
|
||||||
<el-checkbox
|
<el-checkbox
|
||||||
|
v-else
|
||||||
class="mr-xl"
|
class="mr-xl"
|
||||||
v-model="autoRefresh"
|
v-model="autoRefresh"
|
||||||
@change="handleAutoRefreshToggle"
|
@change="handleAutoRefreshToggle"
|
||||||
|
@ -12,7 +14,11 @@
|
||||||
>
|
>
|
||||||
{{ $locale.baseText('executionsList.autoRefresh') }}
|
{{ $locale.baseText('executionsList.autoRefresh') }}
|
||||||
</el-checkbox>
|
</el-checkbox>
|
||||||
<execution-filter :workflows="workflows" @filterChanged="onFilterChanged" />
|
<execution-filter
|
||||||
|
v-show="!isMounting"
|
||||||
|
:workflows="workflows"
|
||||||
|
@filterChanged="onFilterChanged"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -30,7 +36,12 @@
|
||||||
data-test-id="select-all-executions-checkbox"
|
data-test-id="select-all-executions-checkbox"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<table :class="$style.execTable">
|
<div v-if="isMounting">
|
||||||
|
<n8n-loading :class="$style.tableLoader" variant="custom" />
|
||||||
|
<n8n-loading :class="$style.tableLoader" variant="custom" />
|
||||||
|
<n8n-loading :class="$style.tableLoader" variant="custom" />
|
||||||
|
</div>
|
||||||
|
<table v-else :class="$style.execTable">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
|
@ -210,7 +221,7 @@
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
v-if="!combinedExecutions.length"
|
v-if="!combinedExecutions.length && !isMounting && !isDataLoading"
|
||||||
:class="$style.loadedAll"
|
:class="$style.loadedAll"
|
||||||
data-test-id="execution-list-empty"
|
data-test-id="execution-list-empty"
|
||||||
>
|
>
|
||||||
|
@ -231,7 +242,11 @@
|
||||||
data-test-id="load-more-button"
|
data-test-id="load-more-button"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else :class="$style.loadedAll" data-test-id="execution-all-loaded">
|
<div
|
||||||
|
v-else-if="!isMounting && !isDataLoading"
|
||||||
|
:class="$style.loadedAll"
|
||||||
|
data-test-id="execution-all-loaded"
|
||||||
|
>
|
||||||
{{ $locale.baseText('executionsList.loadedAll') }}
|
{{ $locale.baseText('executionsList.loadedAll') }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -300,6 +315,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, showMessa
|
||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
isMounting: true,
|
||||||
finishedExecutions: [] as IExecutionsSummary[],
|
finishedExecutions: [] as IExecutionsSummary[],
|
||||||
finishedExecutionsCount: 0,
|
finishedExecutionsCount: 0,
|
||||||
finishedExecutionsCountEstimated: false,
|
finishedExecutionsCountEstimated: false,
|
||||||
|
@ -326,7 +342,6 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, showMessa
|
||||||
},
|
},
|
||||||
async created() {
|
async created() {
|
||||||
await this.loadWorkflows();
|
await this.loadWorkflows();
|
||||||
//await this.refreshData();
|
|
||||||
this.handleAutoRefreshToggle();
|
this.handleAutoRefreshToggle();
|
||||||
|
|
||||||
this.$externalHooks().run('executionsList.openDialog');
|
this.$externalHooks().run('executionsList.openDialog');
|
||||||
|
@ -480,10 +495,11 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, showMessa
|
||||||
this.allExistingSelected = false;
|
this.allExistingSelected = false;
|
||||||
Vue.set(this, 'selectedItems', {});
|
Vue.set(this, 'selectedItems', {});
|
||||||
},
|
},
|
||||||
onFilterChanged(filter: ExecutionFilterType) {
|
async onFilterChanged(filter: ExecutionFilterType) {
|
||||||
this.filter = filter;
|
this.filter = filter;
|
||||||
this.refreshData();
|
await this.refreshData();
|
||||||
this.handleClearSelection();
|
this.handleClearSelection();
|
||||||
|
this.isMounting = false;
|
||||||
},
|
},
|
||||||
handleActionItemClick(commandData: { command: string; execution: IExecutionsSummary }) {
|
handleActionItemClick(commandData: { command: string; execution: IExecutionsSummary }) {
|
||||||
if (['currentlySaved', 'original'].includes(commandData.command)) {
|
if (['currentlySaved', 'original'].includes(commandData.command)) {
|
||||||
|
@ -1134,4 +1150,15 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, showMessa
|
||||||
margin: 0 0 var(--spacing-s) var(--spacing-s);
|
margin: 0 0 var(--spacing-s) var(--spacing-s);
|
||||||
color: var(--color-danger);
|
color: var(--color-danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.filterLoader {
|
||||||
|
width: 220px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.tableLoader {
|
||||||
|
width: 100%;
|
||||||
|
height: 48px;
|
||||||
|
margin-bottom: var(--spacing-2xs);
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
Loading…
Reference in a new issue