diff --git a/frontend/src/components/Search/Search.jsx b/frontend/src/components/Search/Search.jsx index b92de4b..ea46934 100644 --- a/frontend/src/components/Search/Search.jsx +++ b/frontend/src/components/Search/Search.jsx @@ -28,6 +28,7 @@ class Search extends React.Component { static propTypes = { loading: PropTypes.bool.isRequired, qTemp: PropTypes.string.isRequired, + dateRange: PropTypes.string.isRequired, setParams: PropTypes.func.isRequired, statusKey: PropTypes.string.isRequired, }; @@ -35,7 +36,8 @@ class Search extends React.Component { render() { const { loading, - qTemp + qTemp, + dateRange } = this.props; return ( @@ -44,7 +46,22 @@ class Search extends React.Component {
{ loading && }
-
+
+ +
+
@@ -79,6 +96,10 @@ class Search extends React.Component { this.search(e.target.value); } + onDateRangeChanged = (e) => { + this.props.setParams({dateRange: e.target.value}); + } + search = debounce((q) => { this.props.setParams({q}); }, 500) @@ -95,6 +116,7 @@ const mapStateToProps = state => { return { statusKey, qTemp: state.job.qTemp, + dateRange: state.job.dateRange, loading: state.status[statusKey].loading }; }; diff --git a/frontend/src/pages/JobsPage/JobsPage.jsx b/frontend/src/pages/JobsPage/JobsPage.jsx index 6a4a76c..004d40e 100644 --- a/frontend/src/pages/JobsPage/JobsPage.jsx +++ b/frontend/src/pages/JobsPage/JobsPage.jsx @@ -126,6 +126,7 @@ class JobsPage extends React.Component { jobs: PropTypes.array.isRequired, killJobs: PropTypes.func.isRequired, q: PropTypes.string, + dateRange: PropTypes.string, routing: PropTypes.object.isRequired, selectedIds: PropTypes.array.isRequired, setParams: PropTypes.func.isRequired, @@ -153,6 +154,7 @@ class JobsPage extends React.Component { componentDidUpdate(prevProps) { if (this.props.q !== prevProps.q || + this.props.dateRange !== prevProps.dateRange || this.props.sortColumn !== prevProps.sortColumn || this.props.sortDirection !== prevProps.sortDirection || this.props.page !== prevProps.page || @@ -315,6 +317,7 @@ class JobsPage extends React.Component { ...QUERY_PARAM_DEFAULTS, ...query, qTemp: query.q || '', + dateRange: query.dateRange || '1d', page: query.page ? parseInt(query.page) : 0, selectedIds: query.selectedIds ? query.selectedIds.split(',') : [], selectedQueue: !query.selectedQueue ? 'all' : query.selectedQueue, @@ -343,6 +346,7 @@ class JobsPage extends React.Component { const mapStateToProps = state => ({ q: state.job.q, + dateRange: state.job.dateRange, jobs: state.job.jobs, page: state.job.page, height: state.layout.height, diff --git a/frontend/src/stores/job.js b/frontend/src/stores/job.js index 629dea1..cf99a0e 100644 --- a/frontend/src/stores/job.js +++ b/frontend/src/stores/job.js @@ -24,6 +24,7 @@ export const SET_PAGE = 'SET_PAGE'; export const SET_QUEUES = 'SET_QUEUES'; export const SET_SEARCH = 'SET_SEARCH'; export const SET_SEARCH_TEMP = 'SET_SEARCH_TEMP'; +export const SET_DATE_RANGE = 'SET_DATE_RANGE'; export const SET_SELECTED_IDS = 'SET_SELECTED_IDS'; export const SET_SELECTED_QUEUE = 'SET_SELECTED_QUEUE'; export const SET_SELECTED_STATUS = 'SET_SELECTED_STATUS'; @@ -117,6 +118,7 @@ export const QUERY_PARAM_DEFAULTS = { graphType: 'area', page: 0, q: '', + dateRange: '1d', selectedIds: [], selectedQueue: '', selectedStatus: '', @@ -135,6 +137,7 @@ const initialState = { logsById: {}, page: 0, q: '', + dateRange: '1d', qTemp: '', queues: [], selectedIds: [], @@ -214,6 +217,13 @@ actions[SET_SEARCH] = (state, { payload }) => { }; }; +actions[SET_DATE_RANGE] = (state, { payload }) => { + return { + ...state, + dateRange: payload + }; +}; + actions[SET_SEARCH_TEMP] = (state, { payload }) => { return { ...state, @@ -331,6 +341,13 @@ export function setSearch(q) { }; }; +export function setDateRange(dateRange) { + return { + type: SET_DATE_RANGE, + payload: dateRange + }; +}; + export function setSearchTemp(qTemp) { return { type: SET_SEARCH_TEMP, @@ -419,6 +436,9 @@ export function setParams(params) { if (params.q !== undefined) dispatch(setSearch(params.q)); + if (params.dateRange !== undefined) + dispatch(setDateRange(params.dateRange)); + if (params.qTemp !== undefined) dispatch(setSearchTemp(params.qTemp)); @@ -515,6 +535,7 @@ export function fetchJobs() { const params = { page: state.job.page, q: state.job.q, + dateRange: state.job.dateRange, sortDirection: state.job.sortDirection, sortColumn: state.job.sortColumn }; diff --git a/handlers/handlers.go b/handlers/handlers.go index 23b7c1f..dea4d15 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -48,6 +48,7 @@ func (s *Server) Find(c echo.Context) error { c.QueryParams() search := c.QueryParam("q") + dateRange := c.QueryParam("dateRange") queuesStr := c.QueryParam("queue") statusStr := c.QueryParam("status") column := c.QueryParam("sortColumn") @@ -69,13 +70,14 @@ func (s *Server) Find(c echo.Context) error { } foundJobs, err := s.Storage.Find(&jobs.Options{ - Search: search, - Limit: defaultQueryLimit, - Offset: page * defaultQueryLimit, - Queues: queues, - SortBy: column, - SortAsc: sort, - Status: status, + Search: search, + DateRange: dateRange, + Limit: defaultQueryLimit, + Offset: page * defaultQueryLimit, + Queues: queues, + SortBy: column, + SortAsc: sort, + Status: status, }) if err != nil { diff --git a/jobs/jobs.go b/jobs/jobs.go index 3075bf7..6c2da58 100644 --- a/jobs/jobs.go +++ b/jobs/jobs.go @@ -99,21 +99,22 @@ type StatusSummary struct { // Options is the query options for the Find method to use type Options struct { - Search string - Limit int - Offset int - Queues []string - SortBy string - SortAsc bool - Status []string + Search string + DateRange string + Limit int + Offset int + Queues []string + SortBy string + SortAsc bool + Status []string } type JobStatsOptions struct { - Queues []string - Status []string - Interval int64 - Start int64 - End int64 + Queues []string + Status []string + Interval int64 + Start int64 + End int64 } type JobStats struct { diff --git a/jobs/postgres_store.go b/jobs/postgres_store.go index f755376..33863c6 100644 --- a/jobs/postgres_store.go +++ b/jobs/postgres_store.go @@ -101,7 +101,26 @@ func (pq *postgreSQLStore) Find(opts *Options) ([]*Job, error) { args = append(args, opts.Limit) args = append(args, opts.Offset) - whereClausesScan = append(whereClausesScan, "last_updated > (now() - interval '30 days')") + var interval string + switch opts.DateRange { + case "10m": + interval = "10 minutes" + case "1h": + interval = "1 hour" + case "1d": + interval = "1 day" + case "2d": + interval = "2 days" + case "3d": + interval = "3 days" + case "7d": + interval = "7 days" + case "30d": + interval = "30 days" + default: + interval = "30 days" + } + whereClausesScan = append(whereClausesScan, fmt.Sprintf("last_updated > (now() - interval '%s')", interval)) // Split search into tokens (separated by whitespace). We will search for each token separately. // If search is empty or only whitespace, tokens will be an empty array.