Skip to content
Merged

staging #1602

Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
78c2c14
chore(deps): bump playwright from 1.58.2 to 1.59.0 (#1581)
dependabot[bot] Apr 3, 2026
d9f138a
fix(deps): upgrade dompurify to 3.3.3 to resolve security vulnerabili…
gkorland Apr 5, 2026
5255f81
ci(playwright): install firefox browser for TLS and cluster tests
gkorland Apr 5, 2026
4c5a27b
feat(storage): implement connection-scoped localStorage helpers for m…
Anchel123 Apr 5, 2026
b687605
ci(playwright): include workflow file in cache key
gkorland Apr 5, 2026
ebc25e4
chore(deps): bump docker/login-action from 4.0.0 to 4.1.0 (#1591)
dependabot[bot] Apr 5, 2026
6766a56
feat: add max items for search functionality in graph settings and UI
Anchel123 Apr 5, 2026
6be57b3
Merge pull request #1590 from FalkorDB/fix/dompurify-security-upgrade
Anchel123 Apr 5, 2026
7cf4bd3
Merge branch 'staging' into improve-local-storage
barakb Apr 5, 2026
2d79164
Merge branch 'staging' into add-max-items-for-search
barakb Apr 5, 2026
46069d6
feat(storage): implement migration to connection-scoped storage and c…
Anchel123 Apr 5, 2026
bb64c40
Merge branch 'improve-local-storage' of https://github.com/FalkorDB/f…
Anchel123 Apr 5, 2026
702cd0b
feat: implement max items for search functionality and enhance UI layout
Anchel123 Apr 5, 2026
557f537
feat: add info tooltip to limit setting in BrowserSettings
Anchel123 Apr 5, 2026
385c3ae
Merge pull request #1593 from FalkorDB/add-max-items-for-search
Anchel123 Apr 5, 2026
ae56532
Merge pull request #1592 from FalkorDB/improve-local-storage
Anchel123 Apr 5, 2026
9d011af
Merge pull request #1594 from FalkorDB/add-info-tooltip-to-limit
shahar-biron Apr 5, 2026
3f42dd6
chore(deps-dev): bump @types/node in the npm-minor-patch group
dependabot[bot] Apr 6, 2026
5e5b0de
chore(deps-dev): bump eslint-config-prettier from 9.1.2 to 10.1.8
dependabot[bot] Apr 6, 2026
efbe786
chore(deps): bump react-resizable-panels from 4.8.0 to 4.9.0
dependabot[bot] Apr 6, 2026
e2823e7
chore(deps): bump echarts from 5.6.0 to 6.0.0
dependabot[bot] Apr 6, 2026
1e87af8
chore(deps): bump lucide-react from 0.475.0 to 1.7.0
dependabot[bot] Apr 6, 2026
46ca4fd
Merge pull request #1597 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 6, 2026
f52903d
Merge pull request #1601 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 6, 2026
e2fc30c
Merge pull request #1600 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 6, 2026
de6bdcb
Merge pull request #1599 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 6, 2026
df98f07
Merge pull request #1598 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 6, 2026
2264865
chore(deps-dev): bump @typescript-eslint/parser from 8.57.2 to 8.58.0
dependabot[bot] Apr 7, 2026
94b9427
chore(deps): bump the npm-minor-patch group across 1 directory with 2…
dependabot[bot] Apr 8, 2026
5345b4e
Refactor upload route to include session validation and improve error…
Anchel123 Apr 8, 2026
82ae143
Merge pull request #1610 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 9, 2026
1a7f528
Merge pull request #1607 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 9, 2026
41b5704
fix: defer collapse of current panel to next frame for smoother trans…
Anchel123 Apr 9, 2026
8ca4c25
chore(deps): bump the npm-minor-patch group with 4 updates
dependabot[bot] Apr 9, 2026
fb034f2
chore(deps): bump lucide-react from 1.7.0 to 1.8.0
dependabot[bot] Apr 9, 2026
4068ac9
Merge pull request #1614 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 9, 2026
3639b94
Merge branch 'staging' into dependabot/npm_and_yarn/staging/lucide-re…
barakb Apr 9, 2026
84de2d1
Merge pull request #1611 from FalkorDB/fix-upload-route
Anchel123 Apr 9, 2026
38ffced
Merge branch 'staging' into fix-panel
Anchel123 Apr 9, 2026
6d8d3c7
fix: defer collapse of current panel to next frame and ensure cleanup…
Anchel123 Apr 9, 2026
cb420ef
Merge pull request #1615 from FalkorDB/dependabot/npm_and_yarn/stagin…
barakb Apr 9, 2026
ed3b253
Merge pull request #1613 from FalkorDB/fix-panel
shahar-biron Apr 9, 2026
adcec7a
fix: enhance connection storage handling and improve UI accessibility
Anchel123 Apr 9, 2026
cf7a507
fix: downgrade echarts to 5.6.0 and update zrender version to 5.6.1
Anchel123 Apr 9, 2026
b4cc802
Merge pull request #1616 from FalkorDB/fix-ai-comments
shahar-biron Apr 9, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ jobs:
~/.npm
node_modules
~/.cache/ms-playwright
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }}
restore-keys: |
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-node-
- name: Install dependencies with enhanced retry logic
Expand Down Expand Up @@ -82,7 +83,7 @@ jobs:
fi
done
- name: Install Playwright Browsers
run: npx playwright install --with-deps chromium
run: npx playwright install --with-deps chromium firefox
- name: Build application
run: npm run build
- name: Upload build output
Expand Down Expand Up @@ -127,8 +128,9 @@ jobs:
~/.npm
node_modules
~/.cache/ms-playwright
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }}
restore-keys: |
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-node-
- name: Download build output
Expand Down Expand Up @@ -204,8 +206,9 @@ jobs:
~/.npm
node_modules
~/.cache/ms-playwright
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }}
restore-keys: |
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-node-
- name: Download build output
Expand Down Expand Up @@ -340,8 +343,9 @@ jobs:
~/.npm
node_modules
~/.cache/ms-playwright
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}
key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-${{ hashFiles('.github/workflows/playwright.yml') }}
restore-keys: |
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('**/playwright.config.ts') }}-
${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }}-
${{ runner.os }}-node-
- name: Download build output
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release-image.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

- name: Login to DockerHub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0

- name: Login to DockerHub
uses: docker/login-action@b45d80f862d83dbcd57f89517bcf500b2ab88fb2 # v4.0.0
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}
Expand Down
1 change: 0 additions & 1 deletion app/api/graph/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
/* eslint-disable one-var */
/* eslint-disable no-param-reassign */
/* eslint-disable @typescript-eslint/no-explicit-any */

import { Data, getMetaStats, GraphData, InfoLabel, InfoRelationship, Label, Link, LinkCell, MemoryValue, Node, NodeCell, Relationship, ToastFn, Value } from "@/lib/utils";

// Color palette for node customization
Expand Down
53 changes: 37 additions & 16 deletions app/api/upload/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,53 @@ import { promisify } from "util";
import { pipeline } from "stream";
import fs from "fs";
import { getCorsHeaders } from "../utils";
import { getClient } from "../auth/[...nextauth]/options";

const pump = promisify(pipeline);

// eslint-disable-next-line import/prefer-default-export
export async function POST(request: NextRequest) {
const formData = await request.formData();
try {
const session = await getClient(request);

const file = formData.get("file") as File;
if (session instanceof NextResponse) {
return session;
}

if (!file) {
return NextResponse.json({ error: "No files received." }, { status: 400, headers: getCorsHeaders(request) });
}
const formData = await request.formData();

const filename = file.name.replaceAll(" ", "_");
const filePath = path.join(process.cwd(), `public/assets/${filename}`);
const file = formData.get("file") as File;

try {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
await pump(file.stream(), fs.createWriteStream(filePath));
return NextResponse.json({ path: filePath, status: 200 }, { headers: getCorsHeaders(request) });
} catch (error) {
console.error(error);
if (!file) {
return NextResponse.json({ error: "No files received." }, { status: 400, headers: getCorsHeaders(request) });
}

const filename = path.basename(file.name).replaceAll(" ", "_");
const filePath = path.join(process.cwd(), "public", "assets", filename);

// Guard against path traversal
const assetsDir = path.join(process.cwd(), "public", "assets");
if (!filePath.startsWith(assetsDir)) {
return NextResponse.json({ error: "Invalid file name." }, { status: 400, headers: getCorsHeaders(request) });
}

try {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
await pump(file.stream(), fs.createWriteStream(filePath));
return NextResponse.json({ path: filePath, status: 200 }, { headers: getCorsHeaders(request) });
} catch (error) {
console.error(error);
return NextResponse.json(
{ message: (error as Error).message },
{ status: 400, headers: getCorsHeaders(request) }
);
}
} catch (err) {
console.error(err);
return NextResponse.json(
{ message: (error as Error).message },
{ status: 400, headers: getCorsHeaders(request) }
{ message: (err as Error).message },
{ status: 500, headers: getCorsHeaders(request) }
);
}
}
8 changes: 8 additions & 0 deletions app/components/provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ type BrowserSettingsContextType = {
graphInfo: {
newRefreshInterval: number;
setNewRefreshInterval: Dispatch<SetStateAction<number>>;
newMaxItemsForSearch: number;
setNewMaxItemsForSearch: Dispatch<SetStateAction<number>>;
};
};
settings: {
Expand Down Expand Up @@ -109,6 +111,8 @@ type BrowserSettingsContextType = {
showMemoryUsage: boolean;
refreshInterval: number;
setRefreshInterval: Dispatch<SetStateAction<number>>;
maxItemsForSearch: number;
setMaxItemsForSearch: Dispatch<SetStateAction<number>>;
};
};
hasChanges: boolean;
Expand Down Expand Up @@ -257,6 +261,8 @@ export const BrowserSettingsContext = createContext<BrowserSettingsContextType>(
graphInfo: {
newRefreshInterval: 0,
setNewRefreshInterval: () => { },
newMaxItemsForSearch: 0,
setNewMaxItemsForSearch: () => { },
},
},
settings: {
Expand Down Expand Up @@ -306,6 +312,8 @@ export const BrowserSettingsContext = createContext<BrowserSettingsContextType>(
showMemoryUsage: false,
refreshInterval: 0,
setRefreshInterval: () => { },
maxItemsForSearch: 0,
setMaxItemsForSearch: () => { },
},
},
hasChanges: false,
Expand Down
10 changes: 6 additions & 4 deletions app/graph/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { GraphContext, IndicatorContext, QueryLoadingContext, BrowserSettingsCon
import { EventType } from "../api/chat/route";
import ToastButton from "../components/ToastButton";
import { ShineBorder } from "@/components/ui/shine-border";
import { getConnectionItem, setConnectionItem, getConnectionPrefix } from "@/lib/connection-storage";

// Function to get the last maxSavedMessages user messages and all messages in between
const getLastUserMessagesWithContext = (allMessages: Message[], maxUserMessages: number) => {
Expand Down Expand Up @@ -108,19 +109,20 @@ export default function Chat({ onClose }: Props) {

// Load messages and cypher only preference for current graph on mount
useEffect(() => {
const savedMessages = localStorage.getItem(`chat-${graphName}`);
if (!getConnectionPrefix()) return;
const savedMessages = getConnectionItem(`chat-${graphName}`);
const currentMessages = JSON.parse(savedMessages || "[]");
setMessages(currentMessages);

const savedCypherOnly = localStorage.getItem(`cypherOnly-${graphName}`);
const savedCypherOnly = getConnectionItem(`cypherOnly-${graphName}`);
setCypherOnly(savedCypherOnly === "true");
}, [graphName, maxSavedMessages]);

useEffect(() => {
let statusGroup: Message[];

if (messages.length > 0) {
localStorage.setItem(`chat-${graphName}`, JSON.stringify(getLastUserMessagesWithContext(messages, maxSavedMessages)));
setConnectionItem(`chat-${graphName}`, JSON.stringify(getLastUserMessagesWithContext(messages, maxSavedMessages)));
}

const newMessagesList = messages.map((message, i): Message | [Message[], boolean] | undefined => {
Expand Down Expand Up @@ -536,7 +538,7 @@ export default function Chat({ onClose }: Props) {
onClick={() => {
const next = !cypherOnly;
setCypherOnly(next);
localStorage.setItem(`cypherOnly-${graphName}`, String(next));
setConnectionItem(`cypherOnly-${graphName}`, String(next));
}}
className={cn(
"shrink-0 flex items-center justify-center rounded-md transition-all duration-150 active:scale-[0.96]",
Expand Down
3 changes: 2 additions & 1 deletion app/graph/GraphView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { cn, GraphRef, Tab, Label, Link, Node, Relationship, HistoryQuery } from
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { GraphContext, ForceGraphContext } from "@/app/components/provider";
import ForceGraph from "@/app/components/ForceGraph";
import { setConnectionItem } from "@/lib/connection-storage";
import Button from "../components/ui/Button";
import TableView from "./TableView";
import Toolbar from "./toolbar";
Expand Down Expand Up @@ -283,7 +284,7 @@ function GraphView({

const newQueries = prev.queries.map(q => q.text === newQuery.text ? newQuery : q);

localStorage.setItem("query history", JSON.stringify(newQueries));
setConnectionItem("query history", JSON.stringify(newQueries));

return {
...prev,
Expand Down
11 changes: 6 additions & 5 deletions app/graph/Selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useTheme } from "next-themes";
import { Popover, PopoverContent, PopoverTrigger } from "@/components/ui/popover";
import Button from "../components/ui/Button";
import { BrowserSettingsContext, GraphContext, IndicatorContext } from "../components/provider";
import { setConnectionItem, removeConnectionItem } from "@/lib/connection-storage";
import CypherEditor, { CYPHER_LANGUAGE_NAME } from "../components/CypherEditor";
import EditorComponent from "../components/EditorComponent";
import DialogComponent from "../components/DialogComponent";
Expand Down Expand Up @@ -319,8 +320,8 @@ export default function Selector<T extends "Graph" | "Schema" = "Graph" | "Schem

const newQueries = historyQuery.queries.filter((_, idx) => !deleteElements.some((removeIndex) => idx === removeIndex));

if (newQueries.length === 0) localStorage.removeItem("query history");
else localStorage.setItem("query history", JSON.stringify(newQueries));
if (newQueries.length === 0) removeConnectionItem("query history");
else setConnectionItem("query history", JSON.stringify(newQueries));

// Check if counter points to a deleted query (counter is 1-indexed, so counter - 1 is the index)
const isCounterDeleted = historyQuery.counter > 0 && deleteElements.includes(historyQuery.counter - 1);
Expand Down Expand Up @@ -359,7 +360,7 @@ export default function Selector<T extends "Graph" | "Schema" = "Graph" | "Schem
q.timestamp === item.timestamp ? { ...q, fav: !q.fav, name } : q
);

localStorage.setItem("query history", JSON.stringify(newQueries));
setConnectionItem("query history", JSON.stringify(newQueries));

setHistoryQuery(prev => ({
...prev,
Expand Down Expand Up @@ -559,7 +560,7 @@ export default function Selector<T extends "Graph" | "Schema" = "Graph" | "Schem
data-testid="queryHistoryDelete"
title="Remove all queries from history"
onClick={() => {
localStorage.removeItem("query history");
removeConnectionItem("query history");
setHistoryQuery(prev => ({
...prev,
queries: [],
Expand All @@ -580,7 +581,7 @@ export default function Selector<T extends "Graph" | "Schema" = "Graph" | "Schem
title="Clear all favorites"
onClick={() => {
const newQueries = historyQuery.queries.map(q => ({ ...q, fav: false, name: undefined }));
localStorage.setItem("query history", JSON.stringify(newQueries));
setConnectionItem("query history", JSON.stringify(newQueries));
setHistoryQuery(prev => ({
...prev,
queries: newQueries,
Expand Down
Loading
Loading