client/app/pages/admin/OutdatedQueries.jsx (166 lines of code) (raw):

import { map } from "lodash"; import React from "react"; import Switch from "antd/lib/switch"; import * as Grid from "antd/lib/grid"; import routeWithUserSession from "@/components/ApplicationArea/routeWithUserSession"; import Paginator from "@/components/Paginator"; import { QueryTagsControl } from "@/components/tags-control/TagsControl"; import SchedulePhrase from "@/components/queries/SchedulePhrase"; import TimeAgo from "@/components/TimeAgo"; import Layout from "@/components/admin/Layout"; import { wrap as itemsList, ControllerType } from "@/components/items-list/ItemsList"; import { ItemsSource } from "@/components/items-list/classes/ItemsSource"; import { StateStorage } from "@/components/items-list/classes/StateStorage"; import LoadingState from "@/components/items-list/components/LoadingState"; import { PageSizeSelect } from "@/components/items-list/components/Sidebar"; import ItemsTable, { Columns } from "@/components/items-list/components/ItemsTable"; import { axios } from "@/services/axios"; import { Query } from "@/services/query"; import recordEvent from "@/services/recordEvent"; import routes from "@/services/routes"; class OutdatedQueries extends React.Component { static propTypes = { controller: ControllerType.isRequired, }; listColumns = [ { title: "ID", field: "id", width: "1%", align: "right", sorter: true, }, Columns.custom.sortable( (text, item) => ( <React.Fragment> <a className="table-main-title" href={"queries/" + item.id}> {item.name} </a> <QueryTagsControl className="d-block" tags={item.tags} isDraft={item.is_draft} isArchived={item.is_archived} /> </React.Fragment> ), { title: "Name", field: "name", width: null, } ), Columns.avatar({ field: "user", className: "p-l-0 p-r-0" }, name => `Created by ${name}`), Columns.dateTime.sortable({ title: "Created At", field: "created_at" }), Columns.duration.sortable({ title: "Runtime", field: "runtime" }), Columns.dateTime.sortable({ title: "Last Executed At", field: "retrieved_at", orderByField: "executed_at" }), Columns.custom.sortable((text, item) => <SchedulePhrase schedule={item.schedule} isNew={item.isNew()} />, { title: "Update Schedule", field: "schedule", }), ]; state = { autoUpdate: true, }; _updateTimer = null; componentDidMount() { recordEvent("view", "page", "admin/queries/outdated"); this.update(true); } componentWillUnmount() { clearTimeout(this._updateTimer); } update = (isInitialCall = false) => { if (!isInitialCall && this.state.autoUpdate) { this.props.controller.update(); } this._updateTimer = setTimeout(this.update, 60 * 1000); }; render() { const { controller } = this.props; return ( <Layout activeTab={controller.params.currentPage}> <Grid.Row className="m-15"> <Grid.Col span={16}> <div> <label htmlFor="auto-update-switch" className="m-0"> Auto update </label> <Switch id="auto-update-switch" className="m-l-10" checked={this.state.autoUpdate} onChange={autoUpdate => this.setState({ autoUpdate })} /> </div> {controller.params.lastUpdatedAt && ( <div className="m-t-5"> Last updated: <TimeAgo date={controller.params.lastUpdatedAt * 1000} /> </div> )} </Grid.Col> <Grid.Col span={8}> {controller.isLoaded && !controller.isEmpty && ( <PageSizeSelect options={controller.pageSizeOptions} value={controller.itemsPerPage} onChange={itemsPerPage => controller.updatePagination({ itemsPerPage })} /> )} </Grid.Col> </Grid.Row> {!controller.isLoaded && <LoadingState />} {controller.isLoaded && controller.isEmpty && ( <div className="text-center p-15">There are no outdated queries.</div> )} {controller.isLoaded && !controller.isEmpty && ( <div className="bg-white tiled table-responsive"> <ItemsTable items={controller.pageItems} columns={this.listColumns} orderByField={controller.orderByField} orderByReverse={controller.orderByReverse} toggleSorting={controller.toggleSorting} /> <Paginator totalCount={controller.totalItemsCount} itemsPerPage={controller.itemsPerPage} page={controller.page} onChange={page => controller.updatePagination({ page })} /> </div> )} </Layout> ); } } const OutdatedQueriesPage = itemsList( OutdatedQueries, () => new ItemsSource({ doRequest(request, context) { return ( axios .get("/api/admin/queries/outdated") // eslint-disable-next-line camelcase .then(({ queries, updated_at }) => { context.setCustomParams({ lastUpdatedAt: parseFloat(updated_at) }); return queries; }) ); }, processResults(items) { return map(items, item => new Query(item)); }, isPlainList: true, }), () => new StateStorage({ orderByField: "created_at", orderByReverse: true }) ); routes.register( "Admin.OutdatedQueries", routeWithUserSession({ path: "/admin/queries/outdated", title: "Outdated Queries", render: pageProps => <OutdatedQueriesPage {...pageProps} currentPage="outdated_queries" />, }) );