Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
router_ui.src.components.QueryList.jsx Maven / Gradle / Ivy
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import React from "react";
import {
formatDataSizeBytes,
formatShortTime,
getHumanReadableState,
getProgressBarPercentage,
getProgressBarTitle,
getQueryStateColor,
GLYPHICON_DEFAULT,
GLYPHICON_HIGHLIGHT,
parseDataSize,
parseDuration,
truncateString
} from "../utils";
export class QueryListItem extends React.Component {
static stripQueryTextWhitespace(queryText) {
const lines = queryText.split("\n");
let minLeadingWhitespace = -1;
for (let i = 0; i < lines.length; i++) {
if (minLeadingWhitespace === 0) {
break;
}
if (lines[i].trim().length === 0) {
continue;
}
const leadingWhitespace = lines[i].search(/\S/);
if (leadingWhitespace > -1 && ((leadingWhitespace < minLeadingWhitespace) || minLeadingWhitespace === -1)) {
minLeadingWhitespace = leadingWhitespace;
}
}
let formattedQueryText = "";
for (let i = 0; i < lines.length; i++) {
const trimmedLine = lines[i].substring(minLeadingWhitespace).replace(/\s+$/g, '');
if (trimmedLine.length > 0) {
formattedQueryText += trimmedLine;
if (i < (lines.length - 1)) {
formattedQueryText += "\n";
}
}
}
return truncateString(formattedQueryText, 300);
}
render() {
const query = this.props.query;
const progressBarStyle = {width: getProgressBarPercentage(query) + "%", backgroundColor: getQueryStateColor(query)};
const splitDetails = (
{query.queryStats.completedDrivers}
{(query.state === "FINISHED" || query.state === "FAILED") ? 0 : query.queryStats.runningDrivers}
{(query.state === "FINISHED" || query.state === "FAILED") ? 0 : query.queryStats.queuedDrivers}
);
const timingDetails = (
{query.queryStats.executionTime}
{query.queryStats.elapsedTime}
{query.queryStats.totalCpuTime}
);
const memoryDetails = (
{query.queryStats.totalMemoryReservation}
{query.queryStats.peakTotalMemoryReservation}
{formatDataSizeBytes(query.queryStats.cumulativeUserMemory / 1000.0)}
);
let user = ({query.session.user} );
if (query.session.principal) {
user = (
{query.session.user}
);
}
return (
{formatShortTime(new Date(Date.parse(query.queryStats.createTime)))}
{truncateString(user, 35)}
{truncateString(query.session.source, 35)}
{splitDetails}
{timingDetails}
{memoryDetails}
{getProgressBarTitle(query)}
{QueryListItem.stripQueryTextWhitespace(query.query)}
);
}
}
class DisplayedQueriesList extends React.Component {
render() {
const queryNodes = this.props.queries.map(function (query) {
return (
);
}.bind(this));
return (
{queryNodes}
);
}
}
const FILTER_TYPE = {
RUNNING: function (query) {
return !(query.state === "QUEUED" || query.state === "FINISHED" || query.state === "FAILED");
},
QUEUED: function (query) { return query.state === "QUEUED"},
FINISHED: function (query) { return query.state === "FINISHED"},
};
const SORT_TYPE = {
CREATED: function (query) {return Date.parse(query.queryStats.createTime)},
ELAPSED: function (query) {return parseDuration(query.queryStats.elapsedTime)},
EXECUTION: function (query) {return parseDuration(query.queryStats.executionTime)},
CPU: function (query) {return parseDuration(query.queryStats.totalCpuTime)},
CUMULATIVE_MEMORY: function (query) {return query.queryStats.cumulativeUserMemory},
CURRENT_MEMORY: function (query) {return parseDataSize(query.queryStats.userMemoryReservation)},
};
const ERROR_TYPE = {
USER_ERROR: function (query) {return query.state === "FAILED" && query.errorType === "USER_ERROR"},
INTERNAL_ERROR: function (query) {return query.state === "FAILED" && query.errorType === "INTERNAL_ERROR"},
INSUFFICIENT_RESOURCES: function (query) {return query.state === "FAILED" && query.errorType === "INSUFFICIENT_RESOURCES"},
EXTERNAL: function (query) {return query.state === "FAILED" && query.errorType === "EXTERNAL"},
};
const SORT_ORDER = {
ASCENDING: function (value) {return value},
DESCENDING: function (value) {return -value}
};
export class QueryList extends React.Component {
constructor(props) {
super(props);
this.state = {
allQueries: [],
displayedQueries: [],
reorderInterval: 5000,
currentSortType: SORT_TYPE.CREATED,
currentSortOrder: SORT_ORDER.DESCENDING,
stateFilters: [FILTER_TYPE.RUNNING, FILTER_TYPE.QUEUED],
errorTypeFilters: [ERROR_TYPE.INTERNAL_ERROR, ERROR_TYPE.INSUFFICIENT_RESOURCES, ERROR_TYPE.EXTERNAL],
searchString: '',
maxQueries: 100,
lastRefresh: Date.now(),
lastReorder: Date.now(),
initialized: false
};
this.refreshLoop = this.refreshLoop.bind(this);
this.handleSearchStringChange = this.handleSearchStringChange.bind(this);
this.executeSearch = this.executeSearch.bind(this);
this.handleSortClick = this.handleSortClick.bind(this);
}
sortAndLimitQueries(queries, sortType, sortOrder, maxQueries) {
queries.sort(function (queryA, queryB) {
return sortOrder(sortType(queryA) - sortType(queryB));
}, this);
if (maxQueries !== 0 && queries.length > maxQueries) {
queries.splice(maxQueries, (queries.length - maxQueries));
}
}
filterQueries(queries, stateFilters, errorTypeFilters, searchString) {
const stateFilteredQueries = queries.filter(function (query) {
for (let i = 0; i < stateFilters.length; i++) {
if (stateFilters[i](query)) {
return true;
}
}
for (let i = 0; i < errorTypeFilters.length; i++) {
if (errorTypeFilters[i](query)) {
return true;
}
}
return false;
});
if (searchString === '') {
return stateFilteredQueries;
}
else {
return stateFilteredQueries.filter(function (query) {
const term = searchString.toLowerCase();
if (query.queryId.toLowerCase().indexOf(term) !== -1 ||
getHumanReadableState(query).toLowerCase().indexOf(term) !== -1 ||
query.query.toLowerCase().indexOf(term) !== -1) {
return true;
}
if (query.session.user && query.session.user.toLowerCase().indexOf(term) !== -1) {
return true;
}
if (query.session.source && query.session.source.toLowerCase().indexOf(term) !== -1) {
return true;
}
if (query.resourceGroupId && query.resourceGroupId.join(".").toLowerCase().indexOf(term) !== -1) {
return true;
}
}, this);
}
}
resetTimer() {
clearTimeout(this.timeoutId);
// stop refreshing when query finishes or fails
if (this.state.query === null || !this.state.ended) {
this.timeoutId = setTimeout(this.refreshLoop, 1000);
}
}
refreshLoop() {
clearTimeout(this.timeoutId); // to stop multiple series of refreshLoop from going on simultaneously
clearTimeout(this.searchTimeoutId);
$.get('/v1/query', function (queryList) {
const queryMap = queryList.reduce(function (map, query) {
map[query.queryId] = query;
return map;
}, {});
let updatedQueries = [];
this.state.displayedQueries.forEach(function (oldQuery) {
if (oldQuery.queryId in queryMap) {
updatedQueries.push(queryMap[oldQuery.queryId]);
queryMap[oldQuery.queryId] = false;
}
});
let newQueries = [];
for (const queryId in queryMap) {
if (queryMap[queryId]) {
newQueries.push(queryMap[queryId]);
}
}
newQueries = this.filterQueries(newQueries, this.state.stateFilters, this.state.errorTypeFilters, this.state.searchString);
const lastRefresh = Date.now();
let lastReorder = this.state.lastReorder;
if (this.state.reorderInterval !== 0 && ((lastRefresh - lastReorder) >= this.state.reorderInterval)) {
updatedQueries = this.filterQueries(updatedQueries, this.state.stateFilters, this.state.errorTypeFilters, this.state.searchString);
updatedQueries = updatedQueries.concat(newQueries);
this.sortAndLimitQueries(updatedQueries, this.state.currentSortType, this.state.currentSortOrder, 0);
lastReorder = Date.now();
}
else {
this.sortAndLimitQueries(newQueries, this.state.currentSortType, this.state.currentSortOrder, 0);
updatedQueries = updatedQueries.concat(newQueries);
}
if (this.state.maxQueries !== 0 && (updatedQueries.length > this.state.maxQueries)) {
updatedQueries.splice(this.state.maxQueries, (updatedQueries.length - this.state.maxQueries));
}
this.setState({
allQueries: queryList,
displayedQueries: updatedQueries,
lastRefresh: lastRefresh,
lastReorder: lastReorder,
initialized: true
});
this.resetTimer();
}.bind(this))
.error(function () {
this.setState({
initialized: true,
});
this.resetTimer();
}.bind(this));
}
componentDidMount() {
this.refreshLoop();
}
handleSearchStringChange(event) {
const newSearchString = event.target.value;
clearTimeout(this.searchTimeoutId);
this.setState({
searchString: newSearchString
});
this.searchTimeoutId = setTimeout(this.executeSearch, 200);
}
executeSearch() {
clearTimeout(this.searchTimeoutId);
const newDisplayedQueries = this.filterQueries(this.state.allQueries, this.state.stateFilters, this.state.errorTypeFilters, this.state.searchString);
this.sortAndLimitQueries(newDisplayedQueries, this.state.currentSortType, this.state.currentSortOrder, this.state.maxQueries);
this.setState({
displayedQueries: newDisplayedQueries
});
}
renderMaxQueriesListItem(maxQueries, maxQueriesText) {
return (
{maxQueriesText}
);
}
handleMaxQueriesClick(newMaxQueries) {
const filteredQueries = this.filterQueries(this.state.allQueries, this.state.stateFilters, this.state.errorTypeFilters, this.state.searchString);
this.sortAndLimitQueries(filteredQueries, this.state.currentSortType, this.state.currentSortOrder, newMaxQueries);
this.setState({
maxQueries: newMaxQueries,
displayedQueries: filteredQueries
});
}
renderReorderListItem(interval, intervalText) {
return (
{intervalText}
);
}
handleReorderClick(interval) {
if (this.state.reorderInterval !== interval) {
this.setState({
reorderInterval: interval,
});
}
}
renderSortListItem(sortType, sortText) {
if (this.state.currentSortType === sortType) {
const directionArrow = this.state.currentSortOrder === SORT_ORDER.ASCENDING ? :
;
return (
{sortText} {directionArrow}
);
}
else {
return (
{sortText}
);
}
}
handleSortClick(sortType) {
const newSortType = sortType;
let newSortOrder = SORT_ORDER.DESCENDING;
if (this.state.currentSortType === sortType && this.state.currentSortOrder === SORT_ORDER.DESCENDING) {
newSortOrder = SORT_ORDER.ASCENDING;
}
const newDisplayedQueries = this.filterQueries(this.state.allQueries, this.state.stateFilters, this.state.errorTypeFilters, this.state.searchString);
this.sortAndLimitQueries(newDisplayedQueries, newSortType, newSortOrder, this.state.maxQueries);
this.setState({
displayedQueries: newDisplayedQueries,
currentSortType: newSortType,
currentSortOrder: newSortOrder
});
}
renderFilterButton(filterType, filterText) {
let checkmarkStyle = {color: '#57aac7'};
let classNames = "btn btn-sm btn-info style-check";
if (this.state.stateFilters.indexOf(filterType) > -1) {
classNames += " active";
checkmarkStyle = {color: '#ffffff'};
}
return (
{filterText}
);
}
handleStateFilterClick(filter) {
const newFilters = this.state.stateFilters.slice();
if (this.state.stateFilters.indexOf(filter) > -1) {
newFilters.splice(newFilters.indexOf(filter), 1);
}
else {
newFilters.push(filter);
}
const filteredQueries = this.filterQueries(this.state.allQueries, newFilters, this.state.errorTypeFilters, this.state.searchString);
this.sortAndLimitQueries(filteredQueries, this.state.currentSortType, this.state.currentSortOrder);
this.setState({
stateFilters: newFilters,
displayedQueries: filteredQueries
});
}
renderErrorTypeListItem(errorType, errorTypeText) {
let checkmarkStyle = {color: '#ffffff'};
if (this.state.errorTypeFilters.indexOf(errorType) > -1) {
checkmarkStyle = GLYPHICON_HIGHLIGHT;
}
return (
{errorTypeText}
);
}
handleErrorTypeFilterClick(errorType) {
const newFilters = this.state.errorTypeFilters.slice();
if (this.state.errorTypeFilters.indexOf(errorType) > -1) {
newFilters.splice(newFilters.indexOf(errorType), 1);
}
else {
newFilters.push(errorType);
}
const filteredQueries = this.filterQueries(this.state.allQueries, this.state.stateFilters, newFilters, this.state.searchString);
this.sortAndLimitQueries(filteredQueries, this.state.currentSortType, this.state.currentSortOrder);
this.setState({
errorTypeFilters: newFilters,
displayedQueries: filteredQueries
});
}
render() {
let queryList = ;
if (this.state.displayedQueries === null || this.state.displayedQueries.length === 0) {
let label = (Loading...
);
if (this.state.initialized) {
if (this.state.allQueries === null || this.state.allQueries.length === 0) {
label = "No queries";
}
else {
label = "No queries matched filters";
}
}
queryList = (
);
}
return (
State:
{this.renderFilterButton(FILTER_TYPE.RUNNING, "Running")}
{this.renderFilterButton(FILTER_TYPE.QUEUED, "Queued")}
{this.renderFilterButton(FILTER_TYPE.FINISHED, "Finished")}
Failed
{this.renderErrorTypeListItem(ERROR_TYPE.INTERNAL_ERROR, "Internal Error")}
{this.renderErrorTypeListItem(ERROR_TYPE.EXTERNAL, "External Error")}
{this.renderErrorTypeListItem(ERROR_TYPE.INSUFFICIENT_RESOURCES, "Resources Error")}
{this.renderErrorTypeListItem(ERROR_TYPE.USER_ERROR, "User Error")}
Sort
{this.renderSortListItem(SORT_TYPE.CREATED, "Creation Time")}
{this.renderSortListItem(SORT_TYPE.ELAPSED, "Elapsed Time")}
{this.renderSortListItem(SORT_TYPE.CPU, "CPU Time")}
{this.renderSortListItem(SORT_TYPE.EXECUTION, "Execution Time")}
{this.renderSortListItem(SORT_TYPE.CURRENT_MEMORY, "Current Memory")}
{this.renderSortListItem(SORT_TYPE.CUMULATIVE_MEMORY, "Cumulative User Memory")}
Reorder Interval
{this.renderReorderListItem(1000, "1s")}
{this.renderReorderListItem(5000, "5s")}
{this.renderReorderListItem(10000, "10s")}
{this.renderReorderListItem(30000, "30s")}
{this.renderReorderListItem(0, "Off")}
Show
{this.renderMaxQueriesListItem(20, "20 queries")}
{this.renderMaxQueriesListItem(50, "50 queries")}
{this.renderMaxQueriesListItem(100, "100 queries")}
{this.renderMaxQueriesListItem(0, "All queries")}
{queryList}
);
}
}