Skip to content

Commit 166817a

Browse files
lcompleteclaude
andcommitted
feat(mcp,extension,client): date-range search, agent abort support, i18n fixes
Server: - Add date range filtering (start_date/end_date/date_field) and pagination to MCP search tool - Add collectionId/collectedAt fields to McpPageItem and all builder paths in McpUtils - Add structured filter fields (contentType, libraryFilter, alreadyRead, searchTitleOnly) to SearchQuery - Add new MCP tools: ListCollections, ListCollectionContent, GetXSaveRules - Refactor McpServerController tool dispatch with getToolArguments/executeTool helpers - Refactor LuceneService search option resolution; add buildSearchDateRangeQuery Extension: - Add AbortSignal support to createAgentToolContext and MCP client loading - Add getCurrentTimeTool for time-aware AI responses - Add retry button to UserMessage component - Increase agent tool loop max steps from 5 to 50 Client: - Fix i18n: translate document titles and nav labels in settings pages and PageList Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent fa2c7e4 commit 166817a

33 files changed

Lines changed: 1656 additions & 100 deletions

app/client/src/components/PageList.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {useInView} from "react-intersection-observer";
77
import React, {ReactElement, useEffect, useState, useRef, useCallback, useMemo} from "react";
88
import {Button} from "@mui/material";
99
import Loading from "./Loading";
10-
import {NavLabel} from "./Navigation/shared/NavLabels";
10+
import {getTranslatedLabel, NavLabel} from "./Navigation/shared/NavLabels";
1111
import SubHeader, {ButtonOptions} from "./SubHeader";
1212
import {PageOperateEvent, PageOperation} from "./PageOperationButtons";
1313
import {PageQueryKey} from "../domain/pageQueryKey";
@@ -80,7 +80,7 @@ const PageList = (props: PageListProps) => {
8080
const queryClient = useQueryClient();
8181
const [params, setParams] = useSearchParams();
8282
const { markReadOnScroll } = useGlobalSettings();
83-
const { t } = useTranslation(['page']);
83+
const { t, i18n } = useTranslation(['page', 'navigation']);
8484

8585
// ============ Basic State ============
8686
const selectedPageId = safeInt(params.get("p"));
@@ -436,11 +436,11 @@ const PageList = (props: PageListProps) => {
436436

437437
useEffect(() => {
438438
if (selectedPageId === 0) {
439-
setDocTitle(navLabel.labelText);
439+
setDocTitle(getTranslatedLabel(navLabel));
440440
} else {
441441
setLastVisitPageId(selectedPageId);
442442
}
443-
}, [selectedPageId, navLabel]);
443+
}, [selectedPageId, navLabel, i18n.language]);
444444

445445
useEffect(() => {
446446
if (inView && !isLoading && !isFetchingNextPage) {

app/client/src/pages/Highlights.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,13 +314,13 @@ const Highlights: React.FC = () => {
314314

315315
React.useEffect(() => {
316316
setDocTitle(t('page:myHighlightsTitle'));
317-
}, []);
317+
}, [t]);
318318

319319
React.useEffect(() => {
320320
if (selectedPageId === 0) {
321321
setDocTitle(t('page:myHighlightsTitle'));
322322
}
323-
}, [selectedPageId]);
323+
}, [selectedPageId, t]);
324324

325325
const allHighlights = data?.pages.flatMap(page => page?.content || []) || [];
326326
const totalCount = data?.pages[0]?.totalElements || 0;

app/client/src/pages/Home.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ const Home = () => {
249249
<MainContainer>
250250
<SubHeader
251251
navLabel={navLabels.home}
252+
documentTitle={t('navigation:home')}
252253
buttonOptions={{ markRead: false, viewSwitch: false }}
253254
/>
254255
<Box sx={{ p: { xs: 2, md: 4 }, maxWidth: '100vw', overflowX: 'hidden' }}>

app/client/src/pages/Page.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ const Page = () => {
4949
<MainContainer>
5050
<SubHeader
5151
navLabel={articleNavLabel}
52+
documentTitle={pageDisplayTitle || t('page:article')}
5253
buttonOptions={{ markRead: false, viewSwitch: false }}
5354
hideSearchOnMobile={true}
5455
/>

app/client/src/pages/Search.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import SearchIcon from "@mui/icons-material/Search";
2323
export default function Search() {
2424
const {ref: inViewRef, inView} = useInView();
2525
const {enqueueSnackbar} = useSnackbar();
26-
const { t } = useTranslation(['search']);
26+
const { t } = useTranslation(['search', 'navigation']);
2727
const [searchParams, setSearchParams] = useSearchParams();
2828
const q = searchParams.get('q');
2929
const options = searchParams.get("op");
@@ -32,6 +32,7 @@ export default function Search() {
3232
const [draftQuery, setDraftQuery] = useState('');
3333
const [draftOptions, setDraftOptions] = useState<string[]>([]);
3434
const [focusSignal, setFocusSignal] = useState(0);
35+
const searchDocumentTitle = t('navigation:search');
3536

3637
// Quick search suggestions with their keywords
3738
const quickSearchSuggestions = [
@@ -50,11 +51,11 @@ export default function Search() {
5051

5152
useEffect(() => {
5253
if (hasSearchQuery) {
53-
setDocTitle(q + " - Search");
54+
setDocTitle(`${q} - ${searchDocumentTitle}`);
5455
} else {
55-
setDocTitle("Search");
56+
setDocTitle(searchDocumentTitle);
5657
}
57-
}, [q, hasSearchQuery]);
58+
}, [q, hasSearchQuery, searchDocumentTitle]);
5859

5960
const query: SearchQuery = {q, size: 10, queryOptions: options};
6061
const queryKey = [PageQueryKey.Search, query];

app/client/src/pages/settings/SettingsAccount.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import AccountSetting from "../../components/SettingModal/AccountSetting";
33
import SubHeader from "../../components/SubHeader";
44
import AccountBoxIcon from '@mui/icons-material/AccountBox';
55
import "../../styles/settings.css";
6+
import { useTranslation } from "react-i18next";
67

78
const SettingsAccount = () => {
9+
const { t } = useTranslation('settings');
10+
811
return (
912
<MainContainer>
1013
<SubHeader
11-
documentTitle="Account Settings"
12-
navLabel={{ labelText: 'Account', labelIcon: AccountBoxIcon }}
14+
documentTitle={t('account')}
15+
navLabel={{ labelText: t('account'), labelIcon: AccountBoxIcon }}
1316
buttonOptions={{ markRead: false }}
1417
/>
1518
<div className="settings-page-content p-6 max-w-4xl">

app/client/src/pages/settings/SettingsFeeds.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import { FeedsSetting } from "../../components/SettingModal/FeedsSetting";
33
import SubHeader from "../../components/SubHeader";
44
import RssFeedIcon from '@mui/icons-material/RssFeed';
55
import "../../styles/settings.css";
6+
import { useTranslation } from "react-i18next";
67

78
const SettingsFeeds = () => {
9+
const { t } = useTranslation('settings');
10+
811
return (
912
<MainContainer>
1013
<SubHeader
11-
documentTitle="Feeds Settings"
12-
navLabel={{ labelText: 'Feeds', labelIcon: RssFeedIcon }}
14+
documentTitle={t('feeds')}
15+
navLabel={{ labelText: t('feeds'), labelIcon: RssFeedIcon }}
1316
buttonOptions={{ markRead: false }}
1417
/>
1518
<div className="settings-page-content p-6 max-w-4xl">

app/client/src/pages/settings/SettingsGeneral.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import GeneralSetting from "../../components/SettingModal/GeneralSetting";
33
import SubHeader from "../../components/SubHeader";
44
import SettingsIcon from '@mui/icons-material/Settings';
55
import "../../styles/settings.css";
6+
import { useTranslation } from "react-i18next";
67

78
const SettingsGeneral = () => {
9+
const { t } = useTranslation('settings');
10+
811
return (
912
<MainContainer>
1013
<SubHeader
11-
documentTitle="General Settings"
12-
navLabel={{ labelText: 'General', labelIcon: SettingsIcon }}
14+
documentTitle={t('general')}
15+
navLabel={{ labelText: t('general'), labelIcon: SettingsIcon }}
1316
buttonOptions={{ markRead: false }}
1417
/>
1518
<div className="settings-page-content p-6 max-w-4xl">

app/client/src/pages/settings/SettingsGithub.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import { GithubSetting } from "../../components/SettingModal/GithubSetting";
33
import SubHeader from "../../components/SubHeader";
44
import GitHubIcon from '@mui/icons-material/GitHub';
55
import "../../styles/settings.css";
6+
import { useTranslation } from "react-i18next";
67

78
const SettingsGithub = () => {
9+
const { t } = useTranslation('settings');
10+
811
return (
912
<MainContainer>
1013
<SubHeader
11-
documentTitle="GitHub Settings"
12-
navLabel={{ labelText: 'GitHub', labelIcon: GitHubIcon }}
14+
documentTitle={t('github')}
15+
navLabel={{ labelText: t('github'), labelIcon: GitHubIcon }}
1316
buttonOptions={{ markRead: false }}
1417
/>
1518
<div className="settings-page-content p-6 max-w-4xl">

app/client/src/pages/settings/SettingsHuntlyAI.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@ import HuntlyAISetting from "../../components/SettingModal/HuntlyAISetting";
33
import SubHeader from "../../components/SubHeader";
44
import AutoAwesomeIcon from '@mui/icons-material/AutoAwesome';
55
import "../../styles/settings.css";
6+
import { useTranslation } from "react-i18next";
67

78
const SettingsHuntlyAI = () => {
9+
const { t } = useTranslation('settings');
10+
811
return (
912
<MainContainer>
1013
<SubHeader
11-
documentTitle="Huntly AI Settings"
12-
navLabel={{ labelText: 'Huntly AI', labelIcon: AutoAwesomeIcon }}
14+
documentTitle={t('huntlyAI')}
15+
navLabel={{ labelText: t('huntlyAI'), labelIcon: AutoAwesomeIcon }}
1316
buttonOptions={{ markRead: false }}
1417
/>
1518
<div className="settings-page-content p-6 max-w-4xl">

0 commit comments

Comments
 (0)