Merge pull request #1278 from danielaskdd/fix-label-missing

Improve search label display on graph view tab
This commit is contained in:
Daniel.y
2025-04-06 17:17:07 +08:00
committed by GitHub
5 changed files with 179 additions and 157 deletions

File diff suppressed because one or more lines are too long

View File

@@ -8,7 +8,7 @@
<link rel="icon" type="image/svg+xml" href="logo.png" /> <link rel="icon" type="image/svg+xml" href="logo.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Lightrag</title> <title>Lightrag</title>
<script type="module" crossorigin src="/webui/assets/index-Cma7xY0-.js"></script> <script type="module" crossorigin src="/webui/assets/index-C08hvvRm.js"></script>
<link rel="stylesheet" crossorigin href="/webui/assets/index-QU59h9JG.css"> <link rel="stylesheet" crossorigin href="/webui/assets/index-QU59h9JG.css">
</head> </head>
<body> <body>

View File

@@ -12,6 +12,7 @@ const GraphLabels = () => {
const { t } = useTranslation() const { t } = useTranslation()
const label = useSettingsStore.use.queryLabel() const label = useSettingsStore.use.queryLabel()
const allDatabaseLabels = useGraphStore.use.allDatabaseLabels() const allDatabaseLabels = useGraphStore.use.allDatabaseLabels()
const labelsFetchAttempted = useGraphStore.use.labelsFetchAttempted()
// Remove initial label fetch effect as it's now handled by fetchGraph based on lastSuccessfulQueryLabel // Remove initial label fetch effect as it's now handled by fetchGraph based on lastSuccessfulQueryLabel
@@ -56,22 +57,25 @@ const GraphLabels = () => {
[getSearchEngine] [getSearchEngine]
) )
// Validate if current queryLabel exists in allDatabaseLabels // Validate label
useEffect(() => { useEffect(() => {
// Only update label when all conditions are met:
// 1. allDatabaseLabels is loaded (length > 1, as it has at least '*' by default) if (labelsFetchAttempted) {
// 2. Current label is not the default '*' if (allDatabaseLabels.length > 1) {
// 3. Current label doesn't exist in allDatabaseLabels if (label && label !== '*' && !allDatabaseLabels.includes(label)) {
if ( console.log(`Label "${label}" not in available labels, setting to "*"`);
allDatabaseLabels.length > 1 &&
label &&
label !== '*' &&
!allDatabaseLabels.includes(label)
) {
console.log(`Label "${label}" not found in available labels, resetting to default`);
useSettingsStore.getState().setQueryLabel('*'); useSettingsStore.getState().setQueryLabel('*');
} else {
console.log(`Label "${label}" is valid`);
} }
}, [allDatabaseLabels, label]); } else if (label && allDatabaseLabels.length <= 1 && label && label !== '*') {
console.log('Available labels list is empty, setting label to empty');
useSettingsStore.getState().setQueryLabel('');
}
useGraphStore.getState().setLabelsFetchAttempted(false)
}
}, [allDatabaseLabels, label, labelsFetchAttempted]);
const handleRefresh = useCallback(() => { const handleRefresh = useCallback(() => {
// Reset fetch status flags // Reset fetch status flags

View File

@@ -96,12 +96,24 @@ export function AsyncSelect<T>({
const [searchTerm, setSearchTerm] = useState('') const [searchTerm, setSearchTerm] = useState('')
const debouncedSearchTerm = useDebounce(searchTerm, preload ? 0 : 150) const debouncedSearchTerm = useDebounce(searchTerm, preload ? 0 : 150)
const [originalOptions, setOriginalOptions] = useState<T[]>([]) const [originalOptions, setOriginalOptions] = useState<T[]>([])
const [initialValueDisplay, setInitialValueDisplay] = useState<React.ReactNode | null>(null)
useEffect(() => { useEffect(() => {
setMounted(true) setMounted(true)
setSelectedValue(value) setSelectedValue(value)
}, [value]) }, [value])
// Add an effect to handle initial value display
useEffect(() => {
if (value && (!options.length || !selectedOption)) {
// Create a temporary display until options are loaded
setInitialValueDisplay(<div>{value}</div>)
} else if (selectedOption) {
// Once we find the actual selectedOption, clear the temporary display
setInitialValueDisplay(null)
}
}, [value, options.length, selectedOption])
// Initialize selectedOption when options are loaded and value exists // Initialize selectedOption when options are loaded and value exists
useEffect(() => { useEffect(() => {
if (value && options.length > 0) { if (value && options.length > 0) {
@@ -194,7 +206,7 @@ export function AsyncSelect<T>({
tooltip={triggerTooltip} tooltip={triggerTooltip}
side="bottom" side="bottom"
> >
{selectedOption ? getDisplayValue(selectedOption) : placeholder} {value === '*' ? <div>*</div> : (selectedOption ? getDisplayValue(selectedOption) : (initialValueDisplay || placeholder))}
<ChevronsUpDown className="opacity-50" size={10} /> <ChevronsUpDown className="opacity-50" size={10} />
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>

View File

@@ -120,6 +120,10 @@ const fetchGraph = async (label: string, maxDepth: number, maxNodes: number) =>
} }
} }
// Trigger GraphLabels component to check if the label is valid
// console.log('Setting labelsFetchAttempted to true');
useGraphStore.getState().setLabelsFetchAttempted(true)
// If label is empty, use default label '*' // If label is empty, use default label '*'
const queryLabel = label || '*'; const queryLabel = label || '*';
@@ -326,7 +330,7 @@ const useLightrangeGraph = () => {
} }
}, [queryLabel, rawGraph, sigmaGraph]) }, [queryLabel, rawGraph, sigmaGraph])
// Data fetching logic // Graph data fetching logic
useEffect(() => { useEffect(() => {
// Skip if fetch is already in progress // Skip if fetch is already in progress
if (fetchInProgressRef.current) { if (fetchInProgressRef.current) {
@@ -339,6 +343,7 @@ const useLightrangeGraph = () => {
} }
// Only fetch data when graphDataFetchAttempted is false (avoids re-fetching on vite dev mode) // Only fetch data when graphDataFetchAttempted is false (avoids re-fetching on vite dev mode)
// GraphDataFetchAttempted must set to false when queryLabel is changed
if (!isFetching && !useGraphStore.getState().graphDataFetchAttempted) { if (!isFetching && !useGraphStore.getState().graphDataFetchAttempted) {
// Set flags // Set flags
fetchInProgressRef.current = true fetchInProgressRef.current = true
@@ -509,7 +514,8 @@ const useLightrangeGraph = () => {
for (const node of extendedGraph.nodes) { for (const node of extendedGraph.nodes) {
// Generate random color values // Generate random color values
seedrandom(node.id, { global: true }); seedrandom(node.id, { global: true });
const color = randomColor(); const nodeEntityType = node.properties?.entity_type as string | undefined;
const color = getNodeColorByType(nodeEntityType);
// Create a properly typed RawNodeType // Create a properly typed RawNodeType
processedNodes.push({ processedNodes.push({