diff --git a/src/constants.search.ts b/src/constants.search.ts index e2306f601124f..fbdefa1afdc47 100644 --- a/src/constants.search.ts +++ b/src/constants.search.ts @@ -1,5 +1,14 @@ -type SearchOperatorsShortForm = '' | '=:' | '@:' | '#:' | '?:' | '~:' | 'is:'; -export type SearchOperatorsLongForm = 'message:' | 'author:' | 'commit:' | 'file:' | 'change:' | 'type:'; +type SearchOperatorsShortForm = '' | '=:' | '@:' | '#:' | '?:' | '~:' | 'is:' | 'after:' | 'before:'; +export type SearchOperatorsLongForm = + | 'message:' + | 'author:' + | 'commit:' + | 'file:' + | 'change:' + | 'type:' + | 'date:' + | 'after:' + | 'before:'; export type SearchOperators = SearchOperatorsShortForm | SearchOperatorsLongForm; export const searchOperators = new Set([ @@ -16,6 +25,9 @@ export const searchOperators = new Set([ 'change:', 'is:', 'type:', + 'date:', + 'after:', + 'before:', ]); export const searchOperatorsToLongFormMap = new Map([ @@ -32,13 +44,16 @@ export const searchOperatorsToLongFormMap = new Map=:|message:|@:|author:|#:|commit:|\?:|file:|~:|change:|is:|type:)\s?(?".+?"|\S+}?))|(?\S+)(?!(?:=|message|@|author|#|commit|\?|file|~|change|is|type):)/g; + /(?:(?=:|message:|@:|author:|#:|commit:|\?:|file:|~:|change:|is:|type:|date:|after:|before:)\s?(?".+?"|\S+}?))|(?\S+)(?!(?:=|message|@|author|#|commit|\?|file|~|change|is|type):)/g; export const searchOperationHelpRegex = - /(?:^|(\b|\s)*)((=:|message:|@:|author:|#:|commit:|\?:|file:|~:|change:|is:|type:)(?:"[^"]*"?|\w*))(?:$|(\b|\s))/g; + /(?:^|(\b|\s)*)((=:|message:|@:|author:|#:|commit:|\?:|file:|~:|change:|is:|type:|date:|after:|before:)(?:"[^"]*"?|\w*))(?:$|(\b|\s))/g; export interface SearchQuery { query: string; diff --git a/src/git/search.ts b/src/git/search.ts index 3ada9b9cdacbd..cc8efaf0f3204 100644 --- a/src/git/search.ts +++ b/src/git/search.ts @@ -213,6 +213,25 @@ export function getGitArgsFromSearchQuery( } } + break; + case 'date:': + for (const value of values) { + const date = new Date(value); + searchArgs.add('--after').add(date.toISOString()); + searchArgs.add('--before').add(new Date(date.getTime() + 1000 * 60 * 60 * 24).toISOString()); + } + break; + case 'after:': + for (const value of values) { + const date = new Date(value); + searchArgs.add('--after').add(date.toISOString()); + } + break; + case 'before:': + for (const value of values) { + const date = new Date(value); + searchArgs.add('--before').add(date.toISOString()); + } break; } } diff --git a/src/webviews/apps/shared/components/search/search-input.ts b/src/webviews/apps/shared/components/search/search-input.ts index 63f06d05a1d9d..62b0b8dad0d50 100644 --- a/src/webviews/apps/shared/components/search/search-input.ts +++ b/src/webviews/apps/shared/components/search/search-input.ts @@ -1,3 +1,4 @@ +import type { TemplateResult } from 'lit'; import { css, html } from 'lit'; import { customElement, property, query, state } from 'lit/decorators.js'; import type { SearchOperators, SearchOperatorsLongForm, SearchQuery } from '../../../../../constants.search'; @@ -389,7 +390,23 @@ export class GlSearchInput extends GlElement { this.searchHistoryPos = this.searchHistory.length - 1; } - override render(): unknown { + private padDate(date: number) { + let stringDate = date.toString(); + if (stringDate.length < 2) { + stringDate = `0${stringDate}`; + } + return stringDate; + } + + private handleInsertDateToken(tokenPrefix: string) { + const currentDate = new Date(); + const year = currentDate.getFullYear(); + const month = this.padDate(currentDate.getMonth() + 1); + const date = this.padDate(currentDate.getDate()); + this.handleInsertToken(`${tokenPrefix}${year}-${month}-${date}`); + } + + override render(): TemplateResult { return html`
type:stash or is:stash + + + + + + + + +