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:
Csaba Tuncsik 2023-05-09 18:41:38 +02:00 committed by GitHub
parent cbc4256007
commit eae3a55cc6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 57 additions and 34 deletions

View file

@ -162,26 +162,24 @@ onBeforeMount(() => {
data-test-id="execution-filter-badge"
>{{ countSelectedFilterProps }}</n8n-badge
>
{{ $locale.baseText('executionsList.filters') }}
{{ locale.baseText('executionsList.filters') }}
</n8n-button>
</template>
<div data-test-id="execution-filter-form">
<div v-if="workflows?.length" :class="$style.group">
<label for="execution-filter-workflows">{{
$locale.baseText('workflows.heading')
}}</label>
<label for="execution-filter-workflows">{{ locale.baseText('workflows.heading') }}</label>
<n8n-select
id="execution-filter-workflows"
v-model="vModel.workflowId"
:placeholder="$locale.baseText('executionsFilter.selectWorkflow')"
:placeholder="locale.baseText('executionsFilter.selectWorkflow')"
size="medium"
filterable
data-test-id="executions-filter-workflows-select"
>
<div class="ph-no-capture">
<n8n-option
v-for="item in workflows"
:key="item.id"
v-for="(item, idx) in props.workflows"
:key="idx"
:label="item.name"
:value="item.id"
/>
@ -189,12 +187,10 @@ onBeforeMount(() => {
</n8n-select>
</div>
<div v-if="showTags" :class="$style.group">
<label for="execution-filter-tags">{{
$locale.baseText('workflows.filters.tags')
}}</label>
<label for="execution-filter-tags">{{ locale.baseText('workflows.filters.tags') }}</label>
<TagsDropdown
id="execution-filter-tags"
:placeholder="$locale.baseText('workflowOpen.filterWorkflows')"
:placeholder="locale.baseText('workflowOpen.filterWorkflows')"
:currentTagIds="filter.tags"
:createEnabled="false"
@update="onTagsChange"
@ -203,19 +199,19 @@ onBeforeMount(() => {
</div>
<div :class="$style.group">
<label for="execution-filter-status">{{
$locale.baseText('executionsList.status')
locale.baseText('executionsList.status')
}}</label>
<n8n-select
id="execution-filter-status"
v-model="vModel.status"
:placeholder="$locale.baseText('executionsFilter.selectStatus')"
:placeholder="locale.baseText('executionsFilter.selectStatus')"
size="medium"
filterable
data-test-id="executions-filter-status-select"
>
<n8n-option
v-for="item in statuses"
:key="item.id"
v-for="(item, idx) in statuses"
:key="idx"
:label="item.name"
:value="item.id"
/>
@ -223,7 +219,7 @@ onBeforeMount(() => {
</div>
<div :class="$style.group">
<label for="execution-filter-start-date">{{
$locale.baseText('executionsFilter.start')
locale.baseText('executionsFilter.start')
}}</label>
<div :class="$style.dates">
<el-date-picker
@ -231,7 +227,7 @@ onBeforeMount(() => {
type="datetime"
v-model="vModel.startDate"
:format="DATE_TIME_MASK"
:placeholder="$locale.baseText('executionsFilter.startDate')"
:placeholder="locale.baseText('executionsFilter.startDate')"
data-test-id="executions-filter-start-date-picker"
/>
<span :class="$style.divider">to</span>
@ -240,7 +236,7 @@ onBeforeMount(() => {
type="datetime"
v-model="vModel.endDate"
:format="DATE_TIME_MASK"
:placeholder="$locale.baseText('executionsFilter.endDate')"
:placeholder="locale.baseText('executionsFilter.endDate')"
data-test-id="executions-filter-end-date-picker"
/>
</div>
@ -254,19 +250,19 @@ onBeforeMount(() => {
target="_blank"
href="https://docs.n8n.io/workflows/executions/custom-executions-data/"
>
{{ $locale.baseText('executionsFilter.customData.docsTooltip.link') }}
{{ locale.baseText('executionsFilter.customData.docsTooltip.link') }}
</a>
</template>
</i18n>
</template>
<span :class="$style.label">
{{ $locale.baseText('executionsFilter.savedData') }}
{{ locale.baseText('executionsFilter.savedData') }}
<n8n-icon :class="$style.tooltipIcon" icon="question-circle" size="small" />
</span>
</n8n-tooltip>
<div :class="$style.subGroup">
<label for="execution-filter-saved-data-key">{{
$locale.baseText('executionsFilter.savedDataKey')
locale.baseText('executionsFilter.savedDataKey')
}}</label>
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
<template #content>
@ -276,7 +272,7 @@ onBeforeMount(() => {
href="#"
@click.prevent="goToUpgrade"
data-test-id="executions-filter-view-plans-link"
>{{ $locale.baseText('executionsFilter.customData.inputTooltip.link') }}</a
>{{ locale.baseText('executionsFilter.customData.inputTooltip.link') }}</a
>
</template>
</i18n>
@ -287,21 +283,21 @@ onBeforeMount(() => {
type="text"
size="medium"
:disabled="!isAdvancedExecutionFilterEnabled"
:placeholder="$locale.baseText('executionsFilter.savedDataKeyPlaceholder')"
:placeholder="locale.baseText('executionsFilter.savedDataKeyPlaceholder')"
:value="filter.metadata[0]?.key"
@input="onFilterMetaChange(0, 'key', $event)"
data-test-id="execution-filter-saved-data-key-input"
/>
</n8n-tooltip>
<label for="execution-filter-saved-data-value">{{
$locale.baseText('executionsFilter.savedDataValue')
locale.baseText('executionsFilter.savedDataValue')
}}</label>
<n8n-tooltip :disabled="isAdvancedExecutionFilterEnabled" placement="top">
<template #content>
<i18n tag="span" path="executionsFilter.customData.inputTooltip">
<template #link>
<a href="#" @click.prevent="goToUpgrade">{{
$locale.baseText('executionsFilter.customData.inputTooltip.link')
locale.baseText('executionsFilter.customData.inputTooltip.link')
}}</a>
</template>
</i18n>
@ -312,7 +308,7 @@ onBeforeMount(() => {
type="text"
size="medium"
:disabled="!isAdvancedExecutionFilterEnabled"
:placeholder="$locale.baseText('executionsFilter.savedDataValuePlaceholder')"
:placeholder="locale.baseText('executionsFilter.savedDataValuePlaceholder')"
:value="filter.metadata[0]?.value"
@input="onFilterMetaChange(0, 'value', $event)"
data-test-id="execution-filter-saved-data-value-input"
@ -328,7 +324,7 @@ onBeforeMount(() => {
text
data-test-id="executions-filter-reset-button"
>
{{ $locale.baseText('executionsFilter.reset') }}
{{ locale.baseText('executionsFilter.reset') }}
</n8n-button>
</div>
</n8n-popover>

View file

@ -4,7 +4,9 @@
<div :class="$style.execListHeader">
<n8n-heading tag="h1" size="2xlarge">{{ this.pageTitle }}</n8n-heading>
<div :class="$style.execListHeaderControls">
<n8n-loading v-if="isMounting" :class="$style.filterLoader" variant="custom" />
<el-checkbox
v-else
class="mr-xl"
v-model="autoRefresh"
@change="handleAutoRefreshToggle"
@ -12,7 +14,11 @@
>
{{ $locale.baseText('executionsList.autoRefresh') }}
</el-checkbox>
<execution-filter :workflows="workflows" @filterChanged="onFilterChanged" />
<execution-filter
v-show="!isMounting"
:workflows="workflows"
@filterChanged="onFilterChanged"
/>
</div>
</div>
@ -30,7 +36,12 @@
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>
<tr>
<th>
@ -210,7 +221,7 @@
</table>
<div
v-if="!combinedExecutions.length"
v-if="!combinedExecutions.length && !isMounting && !isDataLoading"
:class="$style.loadedAll"
data-test-id="execution-list-empty"
>
@ -231,7 +242,11 @@
data-test-id="load-more-button"
/>
</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') }}
</div>
</div>
@ -300,6 +315,7 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, showMessa
},
data() {
return {
isMounting: true,
finishedExecutions: [] as IExecutionsSummary[],
finishedExecutionsCount: 0,
finishedExecutionsCountEstimated: false,
@ -326,7 +342,6 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, showMessa
},
async created() {
await this.loadWorkflows();
//await this.refreshData();
this.handleAutoRefreshToggle();
this.$externalHooks().run('executionsList.openDialog');
@ -480,10 +495,11 @@ export default mixins(externalHooks, genericHelpers, executionHelpers, showMessa
this.allExistingSelected = false;
Vue.set(this, 'selectedItems', {});
},
onFilterChanged(filter: ExecutionFilterType) {
async onFilterChanged(filter: ExecutionFilterType) {
this.filter = filter;
this.refreshData();
await this.refreshData();
this.handleClearSelection();
this.isMounting = false;
},
handleActionItemClick(commandData: { command: string; execution: IExecutionsSummary }) {
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);
color: var(--color-danger);
}
.filterLoader {
width: 220px;
height: 32px;
}
.tableLoader {
width: 100%;
height: 48px;
margin-bottom: var(--spacing-2xs);
}
</style>