client/routes/domain/workflow-archival/advanced.vue (215 lines of code) (raw):
<script>
// Copyright (c) 2017-2024 Uber Technologies Inc.
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import debounce from 'lodash-es/debounce';
import { ArchivalTable, ArchivalTableRow } from './components';
import { LOADING_MESSAGE_DELAY } from './constants';
import WorkflowArchivalService from './workflow-archival-service';
import { mapArchivedWorkflowResponse } from './helpers';
import pagedGrid from '~components/paged-grid';
import {
ButtonFill,
ErrorMessage,
FlexGrid,
FlexGridItem,
LoadingSpinner,
LoadingMessage,
NoResults,
TextInput,
} from '~components';
import { getErrorMessage } from '~helpers';
export default pagedGrid({
name: 'workflow-archival-advanced',
props: ['clusterName', 'dateFormat', 'domain', 'timeFormat', 'timezone'],
data() {
return {
error: undefined,
loading: false,
loadingMessageDelay: LOADING_MESSAGE_DELAY,
nextPageToken: undefined,
npt: undefined,
results: undefined,
};
},
computed: {
formattedResults() {
const { dateFormat, results, timeFormat, timezone } = this;
return mapArchivedWorkflowResponse({
dateFormat,
results,
timeFormat,
timezone,
});
},
queryString() {
const { queryString = '' } = this.$route.query || {};
return queryString;
},
},
created() {
const { domain, queryString } = this;
this.workflowArchivalService = WorkflowArchivalService({ domain });
this.onQueryChange({ queryString });
},
methods: {
resetState() {
this.error = undefined;
this.loading = false;
this.results = undefined;
this.npt = undefined;
this.nextPageToken = undefined;
},
fetchArchivalRecord: debounce(async function fetchArchivalRecord(
queryParams
) {
if (!queryParams || !queryParams.queryString) {
return;
}
this.loading = true;
try {
const {
results,
nextPageToken,
} = await this.workflowArchivalService.fetchArchivalRecords(
queryParams
);
this.results = this.results ? this.results.concat(results) : results;
this.npt = nextPageToken;
} catch (error) {
this.npt = undefined;
this.error = getErrorMessage(error);
}
this.loading = false;
},
200),
onQueryChange(queryParams) {
this.resetState();
if (queryParams) {
this.fetchArchivalRecord({ ...queryParams, nextPageToken: undefined });
}
},
onNextTokenChange(queryParams) {
this.fetchArchivalRecord(queryParams);
},
onTextChange({ target: { name, value } }) {
this.setQueryParam(name, value);
},
setQueryParam(name, value) {
this.$router.replaceQueryParam(name, value);
},
},
watch: {
queryString(queryString) {
this.onQueryChange({ queryString });
},
nextPageToken(nextPageToken) {
const { queryString } = this;
if (nextPageToken && queryString) {
this.onNextTokenChange({ queryString, nextPageToken });
}
},
},
components: {
'archival-table': ArchivalTable,
'archival-table-row': ArchivalTableRow,
'button-fill': ButtonFill,
'error-message': ErrorMessage,
'flex-grid': FlexGrid,
'flex-grid-item': FlexGridItem,
'loading-message': LoadingMessage,
'loading-spinner': LoadingSpinner,
'no-results': NoResults,
'text-input': TextInput,
},
});
</script>
<template>
<section class="workflow-archival-basic">
<header>
<flex-grid>
<flex-grid-item grow="1">
<text-input
label="Query"
name="queryString"
type="search"
:value="queryString"
@input="onTextChange"
/>
</flex-grid-item>
<flex-grid-item width="85px">
<button-fill
label="BASIC"
tag="router-link"
:to="{
name: 'workflow-archival-basic',
params: { clusterName },
}"
/>
</flex-grid-item>
</flex-grid>
</header>
<section class="results">
<archival-table
v-infinite-scroll="nextPage"
infinite-scroll-disabled="disableInfiniteScroll"
infinite-scroll-distance="20"
infinite-scroll-immediate-check="false"
>
<archival-table-row
v-for="result in formattedResults"
:close-status="result.closeStatus"
:close-time="result.closeTime"
:cluster-name="clusterName"
:domain-name="result.domainName"
:key="result.runId"
:run-id="result.runId"
:start-time="result.startTime"
:workflow-id="result.workflowId"
:workflow-name="result.workflowName"
/>
</archival-table>
<error-message :error="error" />
<no-results :results="results" />
<loading-spinner v-if="loading" />
<loading-message :delay="loadingMessageDelay" :loading="loading">
<p>It looks like this request is taking some time to process.</p>
<p>Try reducing CloseTime range to improve search time.</p>
</loading-message>
</section>
</section>
</template>
<style lang="stylus">
section.workflow-archival-basic {
display: flex;
flex: 1 1 auto;
flex-direction: column;
overflow-y: auto;
header {
padding: 16px;
}
section.results {
margin-top: 16px;
min-height: 100px;
overflow: auto;
}
paged-grid();
}
</style>