From 00710ab58cbd8ef0fff24da70fe27131064df76d Mon Sep 17 00:00:00 2001 From: Julian-Wogersien Date: Wed, 20 Aug 2025 15:36:52 +0200 Subject: [PATCH 1/4] feat: allow searching for text in each entry --- packages/frontend/src/graphql/index.tsx | 3 +- .../src/graphql/queries/archive-page-data.gql | 1 + packages/frontend/src/pages/archive-page.tsx | 58 ++++++++++++++----- 3 files changed, 47 insertions(+), 15 deletions(-) diff --git a/packages/frontend/src/graphql/index.tsx b/packages/frontend/src/graphql/index.tsx index 9c2f792..72b3d5a 100644 --- a/packages/frontend/src/graphql/index.tsx +++ b/packages/frontend/src/graphql/index.tsx @@ -756,7 +756,7 @@ export type AlexaLinkingUrlQuery = { __typename?: 'Query', alexaLinkingUrl?: str export type ArchivePageDataQueryVariables = Exact<{ [key: string]: never; }>; -export type ArchivePageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time: number }> }> } | undefined> }; +export type ArchivePageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time: number, text: string }> }> } | undefined> }; export type CommentBoxDataQueryVariables = Exact<{ [key: string]: never; }>; @@ -1480,6 +1480,7 @@ export const ArchivePageDataDocument = gql` entries { id time + text } } __typename diff --git a/packages/frontend/src/graphql/queries/archive-page-data.gql b/packages/frontend/src/graphql/queries/archive-page-data.gql index 6afe8cc..3232fe0 100644 --- a/packages/frontend/src/graphql/queries/archive-page-data.gql +++ b/packages/frontend/src/graphql/queries/archive-page-data.gql @@ -17,6 +17,7 @@ query ArchivePageData { entries { id time + text } } __typename diff --git a/packages/frontend/src/pages/archive-page.tsx b/packages/frontend/src/pages/archive-page.tsx index 54bc3d1..267edbd 100644 --- a/packages/frontend/src/pages/archive-page.tsx +++ b/packages/frontend/src/pages/archive-page.tsx @@ -23,7 +23,7 @@ import { PrimaryButton } from '../components/button' import { CheckBox } from '../components/checkbox' import Illustrations from '../components/illustration' import Loader from '../components/loader' -import { Report, ReportStatus, useArchivePageDataQuery } from '../graphql' +import { DayStatusEnum, Report, ReportStatus, useArchivePageDataQuery } from '../graphql' import DateHelper from '../helper/date-helper' import { useFetchPdf } from '../hooks/use-fetch-pdf' import { useIsDarkMode } from '../hooks/use-is-dark-mode' @@ -36,6 +36,7 @@ interface ArchiveFilter { week?: number yearEnd?: number weekEnd?: number + searchText?: string } interface SelectedReports { @@ -48,8 +49,29 @@ interface ArchivePageState extends ArchiveFilter { } const searchFilter = - ({ department, year, week, yearEnd, weekEnd }: ArchiveFilter) => - (report?: Pick): boolean => { + ({ department, year, week, yearEnd, weekEnd, searchText }: ArchiveFilter) => + ( + report?: + | { + __typename: 'Report' + id: string + week: number + year: number + status: ReportStatus + department?: string | undefined + days: { + __typename?: 'Day' | undefined + status?: DayStatusEnum | undefined + entries: { + __typename?: 'Entry' | undefined + id: string + time: number + text: string + }[] + }[] + } + | undefined + ): boolean => { if (!report) { return false } @@ -62,14 +84,21 @@ const searchFilter = const departmentMatch = !department || (report.department && report.department.trim().toLowerCase().match(department)) - return Boolean(yearMatch && weekMatch && departmentMatch && yearSpanMatch && weekSpanMatch) + let textMatch = true + if (searchText) { + textMatch = report.days.some((day) => + day.entries.some((entry) => entry.text.toLowerCase().includes(searchText.toLowerCase())) + ) + } + + console.log('days: ', report.days) + + return Boolean(yearMatch && weekMatch && departmentMatch && yearSpanMatch && weekSpanMatch && textMatch) } const ArchivePage: React.FunctionComponent = () => { const [fetchPdf, pdfLoading] = useFetchPdf() - const { loading, data } = useArchivePageDataQuery() - const isDarkMode = useIsDarkMode(data?.currentUser) const [state, setState] = React.useState({ @@ -92,11 +121,9 @@ const ArchivePage: React.FunctionComponent = () => { const getCheckState = (id: string): boolean => { const { checkedReports } = state - if (checkedReports === null) { return false } - return checkedReports[id] } @@ -122,11 +149,9 @@ const ArchivePage: React.FunctionComponent = () => { const getCheckedReports = React.useCallback((): Pick[] => { const { checkedReports } = state - if (checkedReports === null) { return [] } - return filteredReports.filter((report) => report && checkedReports[report.id]) as Pick[] }, [filteredReports, state]) @@ -150,13 +175,14 @@ const ArchivePage: React.FunctionComponent = () => { const onInput = (event: React.FormEvent) => { const value = (event.target as HTMLInputElement).value.toLowerCase() const yearMonthRegex = /([0-9]{4}):([0-9]{1,2})/ - const departmentRegex = /([a-z A-Z]+)/ + const departmentRegex = /(department:|dep:)([a-z A-Z]+)/ const timespanRegex = /(([0-9]{4}):([0-9]{1,2})) ?- ?(([0-9]{4}):([0-9]{1,2}))/ let year: number | undefined = undefined let week: number | undefined = undefined let department: string | undefined = undefined let yearEnd: number | undefined = undefined let weekEnd: number | undefined = undefined + let searchText: string | undefined = undefined const yearMatch = yearMonthRegex.exec(value) if (yearMonthRegex.test(value) && yearMatch) { @@ -173,8 +199,12 @@ const ArchivePage: React.FunctionComponent = () => { } const departmentMatch = departmentRegex.exec(value) - if (departmentRegex.test(value) && departmentMatch) { - department = departmentMatch[0].replace(/\s/g, '').trim() + if (departmentMatch) { + department = departmentMatch[2].replace(/\s/g, '').trim() + } + + if (!departmentMatch) { + searchText = value } setState({ @@ -184,6 +214,7 @@ const ArchivePage: React.FunctionComponent = () => { week, yearEnd, weekEnd, + searchText, }) } @@ -236,7 +267,6 @@ const ArchivePage: React.FunctionComponent = () => { )} - {filteredReports.map((report) => { if (!report) { From 9f91ace62b313fc6fc0a51cdf2b55ba52783ab80 Mon Sep 17 00:00:00 2001 From: Julian-Wogersien Date: Wed, 20 Aug 2025 15:42:48 +0200 Subject: [PATCH 2/4] chore: update locales, and remove unneded console.log --- packages/frontend/src/locales/de.ts | 2 +- packages/frontend/src/locales/en.ts | 2 +- packages/frontend/src/pages/archive-page.tsx | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/locales/de.ts b/packages/frontend/src/locales/de.ts index a829b56..632b609 100644 --- a/packages/frontend/src/locales/de.ts +++ b/packages/frontend/src/locales/de.ts @@ -54,7 +54,7 @@ const germanTranslation: Translation = { noResult: { title: 'Leider habe ich nichts gefunden', caption: - 'Bitte überprüfe deine Sucheingabe und versuche es erneut. {0} Mit {1} kannst du eine bestimmte Kalenderwoche suchen oder mit {2} nach einem Zeitraum.', + 'Bitte überprüfe deine Sucheingabe und versuche es erneut. {0} Mit {1} kannst du eine bestimmte Kalenderwoche suchen oder mit {2} nach einem Zeitraum, oder mit dep: nach einem Department.', }, initial: { title: 'Hier gibt es noch nichts', diff --git a/packages/frontend/src/locales/en.ts b/packages/frontend/src/locales/en.ts index ebf452a..29a9b53 100644 --- a/packages/frontend/src/locales/en.ts +++ b/packages/frontend/src/locales/en.ts @@ -52,7 +52,7 @@ const englishTranslation: Translation = { noResult: { title: "Sadly, I didn't find anything.", caption: - 'Please check your search entry and try again. {0} With {1} you can search for a specific calendar week or with {2} for a time period.', + 'Please check your search entry and try again. {0} With {1} you can search for a specific calendar week or with {2} for a time period, or with dep: for a Department.', }, initial: { title: "There's nothing here yet.", diff --git a/packages/frontend/src/pages/archive-page.tsx b/packages/frontend/src/pages/archive-page.tsx index 267edbd..ec7f919 100644 --- a/packages/frontend/src/pages/archive-page.tsx +++ b/packages/frontend/src/pages/archive-page.tsx @@ -91,8 +91,6 @@ const searchFilter = ) } - console.log('days: ', report.days) - return Boolean(yearMatch && weekMatch && departmentMatch && yearSpanMatch && weekSpanMatch && textMatch) } From e179a804ab464ee1977d7e0071bd926735061dc3 Mon Sep 17 00:00:00 2001 From: Julian-Wogersien Date: Fri, 22 Aug 2025 09:32:13 +0200 Subject: [PATCH 3/4] fix: ignore timespan & year/w search + dont match until full week is written --- packages/frontend/src/pages/archive-page.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/frontend/src/pages/archive-page.tsx b/packages/frontend/src/pages/archive-page.tsx index ec7f919..bd7d3b8 100644 --- a/packages/frontend/src/pages/archive-page.tsx +++ b/packages/frontend/src/pages/archive-page.tsx @@ -172,9 +172,9 @@ const ArchivePage: React.FunctionComponent = () => { const onInput = (event: React.FormEvent) => { const value = (event.target as HTMLInputElement).value.toLowerCase() - const yearMonthRegex = /([0-9]{4}):([0-9]{1,2})/ + const yearMonthRegex = /([0-9]{4}):([0-9]{2})/ const departmentRegex = /(department:|dep:)([a-z A-Z]+)/ - const timespanRegex = /(([0-9]{4}):([0-9]{1,2})) ?- ?(([0-9]{4}):([0-9]{1,2}))/ + const timespanRegex = /(([0-9]{4}):([0-9]{2})) ?- ?(([0-9]{4}):([0-9]{2}))/ let year: number | undefined = undefined let week: number | undefined = undefined let department: string | undefined = undefined @@ -201,7 +201,7 @@ const ArchivePage: React.FunctionComponent = () => { department = departmentMatch[2].replace(/\s/g, '').trim() } - if (!departmentMatch) { + if (!departmentMatch && !timeSpanMatch && !yearMatch) { searchText = value } From 05643ae947923b7d4d1c475ac4ff1ae1142ddf66 Mon Sep 17 00:00:00 2001 From: Julian-Wogersien Date: Fri, 22 Aug 2025 11:25:07 +0200 Subject: [PATCH 4/4] feat: add search for summary/remarks --- packages/frontend/src/graphql/index.tsx | 3 ++- packages/frontend/src/graphql/queries/archive-page-data.gql | 1 + packages/frontend/src/pages/archive-page.tsx | 4 ++++ 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/frontend/src/graphql/index.tsx b/packages/frontend/src/graphql/index.tsx index 72b3d5a..37cddb6 100644 --- a/packages/frontend/src/graphql/index.tsx +++ b/packages/frontend/src/graphql/index.tsx @@ -756,7 +756,7 @@ export type AlexaLinkingUrlQuery = { __typename?: 'Query', alexaLinkingUrl?: str export type ArchivePageDataQueryVariables = Exact<{ [key: string]: never; }>; -export type ArchivePageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time: number, text: string }> }> } | undefined> }; +export type ArchivePageDataQuery = { __typename?: 'Query', currentUser?: { __typename?: 'Admin', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainee', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | { __typename?: 'Trainer', id: string, theme?: string | undefined, firstName: string, lastName: string, language?: string | undefined } | undefined, reports: Array<{ __typename: 'Report', id: string, week: number, year: number, status: ReportStatus, department?: string | undefined, summary?: string | undefined, days: Array<{ __typename?: 'Day', status?: DayStatusEnum | undefined, entries: Array<{ __typename?: 'Entry', id: string, time: number, text: string }> }> } | undefined> }; export type CommentBoxDataQueryVariables = Exact<{ [key: string]: never; }>; @@ -1475,6 +1475,7 @@ export const ArchivePageDataDocument = gql` year status department + summary days { status entries { diff --git a/packages/frontend/src/graphql/queries/archive-page-data.gql b/packages/frontend/src/graphql/queries/archive-page-data.gql index 3232fe0..78dcb92 100644 --- a/packages/frontend/src/graphql/queries/archive-page-data.gql +++ b/packages/frontend/src/graphql/queries/archive-page-data.gql @@ -12,6 +12,7 @@ query ArchivePageData { year status department + summary days { status entries { diff --git a/packages/frontend/src/pages/archive-page.tsx b/packages/frontend/src/pages/archive-page.tsx index bd7d3b8..666c33e 100644 --- a/packages/frontend/src/pages/archive-page.tsx +++ b/packages/frontend/src/pages/archive-page.tsx @@ -59,6 +59,7 @@ const searchFilter = year: number status: ReportStatus department?: string | undefined + summary?: string | undefined days: { __typename?: 'Day' | undefined status?: DayStatusEnum | undefined @@ -89,6 +90,9 @@ const searchFilter = textMatch = report.days.some((day) => day.entries.some((entry) => entry.text.toLowerCase().includes(searchText.toLowerCase())) ) + if (!textMatch && report.summary) { + textMatch = report.summary.toLowerCase().includes(searchText.toLowerCase()) + } } return Boolean(yearMatch && weekMatch && departmentMatch && yearSpanMatch && weekSpanMatch && textMatch)