feat(core): workspace indexing settings

This commit is contained in:
yoyoyohamapi 2025-04-18 14:53:44 +08:00 committed by 德布劳外 · 贾贵
parent 6c9f28e08b
commit fbeca51e0f
5 changed files with 118 additions and 0 deletions

View File

@ -0,0 +1,29 @@
import { Entity, LiveData } from '@toeverything/infra';
import type { IndexerStore } from '../stores/indexer';
import type { WorkspaceService } from '@affine/core/modules/workspace';
export interface IndexerConfig {
type: 'local' | 'cloud';
lastIndexedAt?: Date;
status: 'idle' | 'indexing' | 'error';
error?: string;
}
export class Indexer extends Entity {
status$ = new LiveData<number>(this.store.status);
constructor(
private readonly workspaceService: WorkspaceService,
private readonly store: IndexerStore,
) {
super();
}
async startIndexing() {
await this.store.startIndexing();
}
override dispose(): void {
super.dispose();
}
}

View File

@ -0,0 +1,6 @@
import { Service } from '@toeverything/infra';
import { Indexer } from '../entities/indexer';
export class IndexerService extends Service {
indexer = this.framework.createEntity(Indexer);
}

View File

@ -0,0 +1,22 @@
import { Store, LiveData } from '@toeverything/infra';
import type { WorkspaceServerService } from '@affine/core/modules/cloud';
export class IndexerStore extends Store {
private readonly _status$ = new LiveData<number>(0);
constructor(private readonly workspaceServerService: WorkspaceServerService) {
super();
}
get status() {
return this._status$.value;
}
startIndexing() {
if (!this.workspaceServerService.server) {
throw new Error('[IndexerStore]No Server');
}
this.workspaceServerService.server.gql({});
}
}

View File

@ -3,6 +3,7 @@ import { useI18n } from '@affine/i18n';
import type React from 'react';
import { EmbeddingSettings } from './embedding-settings';
import { IndexerSettings } from './indexer-settings';
export const IndexerEmbeddingSettings: React.FC = () => {
const t = useI18n();
@ -17,6 +18,7 @@ export const IndexerEmbeddingSettings: React.FC = () => {
/>
<EmbeddingSettings />
<IndexerSettings />
</>
);
};

View File

@ -0,0 +1,59 @@
import React, { useState } from 'react';
import { Button, Progress } from '@affine/component';
import {
SettingRow,
SettingWrapper,
} from '@affine/component/setting-components';
import { useI18n } from '@affine/i18n';
interface IndexerSettingsProps {}
export const IndexerSettings: React.FC<IndexerSettingsProps> = ({}) => {
const t = useI18n();
const [indexingProgress, setIndexingProgress] = useState(0);
const [isIndexing, setIsIndexing] = useState(false);
const handleReindexClick = React.useCallback(() => {
setIsIndexing(true);
setIndexingProgress(0);
// Simulated progress for demo
const interval = setInterval(() => {
setIndexingProgress(prev => {
if (prev >= 100) {
clearInterval(interval);
setIsIndexing(false);
return 100;
}
return prev + 10;
});
}, 1000);
}, []);
return (
<SettingWrapper title={t['Indexer']()}>
<SettingRow
name=""
desc={t[
'The indexer can choose from cloud and local sources. If the indexer is local, it may consume more memory.'
]()}
></SettingRow>
<SettingRow
name={t['Indexing Progress']()}
data-testid="indexer-indexing-progress-setting-row"
style={{ marginBottom: 10 }}
>
<Button onClick={handleReindexClick} disabled={isIndexing}>
{isIndexing ? t['Indexing...']() : t['Resync Indexing']()}
</Button>
</SettingRow>
<Progress
readonly
value={indexingProgress}
style={{ width: '100%', height: '20px' }}
/>
</SettingWrapper>
);
};