Skip to content

Commit

Permalink
fix: ui bug (#1)
Browse files Browse the repository at this point in the history
  • Loading branch information
siam-ese authored Dec 20, 2024
1 parent e6f4649 commit 7bbeaba
Show file tree
Hide file tree
Showing 31 changed files with 423 additions and 275 deletions.
4 changes: 2 additions & 2 deletions README-zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@

## **Table**

**Table** 模块负责管理用于存储和显示网页抓取结果的表格数据结构。该包包含以下功能:
**Table** 模块负责管理用于存储和显示网页采集结果的表格数据结构。该包包含以下功能:

- **`TableService.addTable()`**
向系统中添加一个新表格来管理抓取的数据
向系统中添加一个新表格来管理采集的数据

- **`TableService.deleteTable()`**
删除系统中现有的表格。
Expand Down
1 change: 1 addition & 0 deletions packages/locale/locales/EN-US.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import type { locale as zhCN } from './ZH-CN';

export const locale: typeof zhCN = {
ExportAsWith: 'Export as {text}',
Please: 'Please',
ToUseTheFeature: 'to use the feature',
SummarizeThisPage: 'Summarize this page',
Expand Down
1 change: 1 addition & 0 deletions packages/locale/locales/ZH-CN.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export const locale = {
ExportAsWith: '导出为{text}',
SummarizeThisPage: '总结当前页面',
CollectingCurrentPageData: '采集当前页面',
DataCollectionInProgress: '正在采集中...',
Expand Down
24 changes: 10 additions & 14 deletions packages/scraper/lib/scraper-service/scraper-tab.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { IPageUrlAutoExtractionConfig, IScraper, IScraperColumn, ScraperErrorCode } from '@lib/scraper';
import type { IPageUrlAutoExtractionConfig, IScraper, ScraperErrorCode } from '@lib/scraper';
import { AutoExtractionMode, PAGE_URL_SLOT } from '@lib/scraper';
import { ObservableValue } from '@univer-clipsheet-core/shared';
import type { Sheet_Cell_Type_Enum } from '@univer-clipsheet-core/table';
import { calculateRandomInterval } from '@lib/tools';
import type { ScraperTaskChannelResponse } from './scraper-channel';

Expand All @@ -23,21 +22,17 @@ function generateScraperPageUrl(scraper: IScraper, pageNo: number) {

const columnFilterInterceptor: ResponseInterceptor = async (scraperTab, rows) => {
const { scraper } = scraperTab;
// console.log('columnFilterInterceptor', scraper.columns);
const columnIndexMap = scraper.columns.reduce((map, c) => {
map.set(c.index, c);
return map;
}, new Map<number, IScraperColumn>());

// Only selected columns will be returned
rows.forEach((row) => {
row.cells = row.cells.filter((_, index) => columnIndexMap.has(index));
row.cells = scraper.columns.map((column) => {
const cell = row.cells[column.index];

row.cells.forEach((cell, cellIndex) => {
const column = columnIndexMap.get(cellIndex);
if (column) {
cell.type = column.type as unknown as Sheet_Cell_Type_Enum;
}
return {
type: column.type,
text: cell?.text || '',
url: cell?.url || '',
};
});
});

Expand Down Expand Up @@ -226,10 +221,11 @@ export class ScraperTab {

this._dispose$.next(true);
this._dispose$.dispose();

this._onError$.dispose();

const tabId = this._tab?.id;

console.log(tabId, 'scraper tab dispose tabId');
if (tabId) {
chrome.tabs.remove(tabId);
}
Expand Down
38 changes: 25 additions & 13 deletions packages/scraper/lib/scraper-service/scraper.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DrillDownService } from '@lib/drill-down-service';
import { type IDrillDownConfig, type IScraper, ScraperErrorCode } from '@lib/scraper';
import type { ActiveTabMessage, GetDataSourceMessage, IMessage, PushDataSourceMessage } from '@univer-clipsheet-core/shared';
import { ClipsheetMessageTypeEnum, defaultPageSize, ObservableValue, pushDataSource, requestConnectChannel } from '@univer-clipsheet-core/shared';
import { ClipsheetMessageTypeEnum, defaultPageSize, ObservableValue, pushDataSource, requestConnectChannel, waitFor, WindowService } from '@univer-clipsheet-core/shared';
import type { ISheet_Row_Cell } from '@univer-clipsheet-core/table';
import { createEmptyInitialSheet, Sheet_Cell_Type_Enum, TableRecordTypeEnum, TableService } from '@univer-clipsheet-core/table';
import { Inject } from '@wendellhu/redi';
Expand All @@ -12,12 +12,6 @@ import { ScraperTab } from './scraper-tab';
import type { CreateScraperMessage, DeleteScraperMessage, IGetScraperListParams, RunScraperFailedMessage, RunScraperMessage, StopScraperMessage, UpdateScraperMessage } from './scraper.message';
import { ScraperDataSourceKeyEnum, ScraperMessageTypeEnum } from './scraper.message';

function waitFor(ms: number) {
return new Promise<void>((resolve) => {
setTimeout(resolve, ms);
});
};

export class ScraperService {
private _runningScraperIds$ = new ObservableValue<string[]>([]);
private _scraperTabMap: Map<string, ScraperTab> = new Map();
Expand All @@ -26,7 +20,8 @@ export class ScraperService {
constructor(
@Inject(IScraperDataSource) private _dataSource: IScraperDataSource,
@Inject(TableService) private _tableService: TableService,
@Inject(DrillDownService) private _drillDownService: DrillDownService
@Inject(DrillDownService) private _drillDownService: DrillDownService,
@Inject(WindowService) private _windowService: WindowService
) {
this._runningScraperIds$.subscribe((runningIds) => {
const msg: PushDataSourceMessage = {
Expand Down Expand Up @@ -125,7 +120,7 @@ export class ScraperService {

private _createDrillDownTask(scraper: IScraper, rows: ScraperTaskChannelResponse['rows']) {
let dispose: () => void = () => {};
let drillDownTabs: chrome.tabs.Tab[] = [];
const drillDownTabMap = new Map<number, chrome.tabs.Tab>();

const executeDrillDown = async () => {
// Map of column index to drill down config
Expand All @@ -140,8 +135,14 @@ export class ScraperService {
});

const drillDownConfigMapEntries = Array.from(drillDownConfigMap.entries());

const windowId = (await this._windowService.ensureWindow()).id;
const drillDownTabs = await Promise.all(drillDownConfigMapEntries.map(() => chrome.tabs.create({ windowId, active: false })));

drillDownTabs.forEach((tab, index) => {
drillDownTabMap.set(index, tab);
});
// Open tabs for each drill down config
drillDownTabs = await Promise.all(drillDownConfigMapEntries.map(() => chrome.tabs.create({ active: false })));

try {
// Execute drill down row by row
Expand Down Expand Up @@ -201,26 +202,30 @@ export class ScraperService {
row.cells = row.cells.flat();
}
} finally {
drillDownTabs.forEach((tab) => {
Array.from(drillDownTabMap.values()).forEach((tab) => {
if (tab.id) {
chrome.tabs.remove(tab.id);
}
});

drillDownTabMap.clear();
}
};

return {
response: Promise.race([
new Promise<void>((resolve) => {
dispose = () => {
drillDownTabs.forEach((tab) => {
Array.from(drillDownTabMap.values()).forEach((tab) => {
const tabId = tab.id;
if (!tabId) {
return;
}
chrome.tabs.remove(tabId);
this._drillDownService.stopDrillDown(tabId);
});

drillDownTabMap.clear();
resolve();
};
}),
Expand All @@ -236,8 +241,11 @@ export class ScraperService {
return;
}

const window = await this._windowService.ensureWindow();

const { error, rows } = await this.runScraper({
scraper,
windowId: window.id,
onCreated: (scraperTab) => {
const disposers = new Set<() => void>();
scraperTab.addResponseInterceptor(async (scraperTab, rows) => {
Expand Down Expand Up @@ -295,6 +303,10 @@ export class ScraperService {
});
}

addScraper(scraper: IScraper) {
return this._dataSource.add(scraper);
}

async pushScraperList(params: IGetScraperListParams) {
return pushDataSource(ScraperDataSourceKeyEnum.ScraperList, await this._dataSource.getList(params));
}
Expand Down Expand Up @@ -375,7 +387,7 @@ export class ScraperService {
case ScraperMessageTypeEnum.CreateScraper: {
const { payload } = msg;

const res = await this._dataSource.add(payload.scraper);
const res = await this.addScraper(payload.scraper);

if (payload.toRun) {
this._executeRunScraper(res);
Expand Down
2 changes: 2 additions & 0 deletions packages/shared/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,7 @@ export * from './constants';
export * from './channel';
export * from './services/storage-service';
export * from './services/side-panel.service';
export * from './services/window.service';
export * from './utils';
export { ObjectValidator, type IObjectValidatorInit } from './object-validator';

7 changes: 1 addition & 6 deletions packages/shared/lib/observable-value.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@

export class ObservableValue<T = unknown> {
private _value: T;
private _initialValue: T;
private _subscribers = new Set<(value: T, previousValue?: T) => void>();
private _disposers = new Set<() => void>();
private _previousValue: T | undefined = undefined;

constructor(value: T) {
this._initialValue = value;
this._value = value;
}

Expand Down Expand Up @@ -36,8 +33,6 @@ export class ObservableValue<T = unknown> {
}

dispose() {
this._value = this._initialValue;
this._disposers.forEach((disposer) => disposer());
this._disposers.clear();
this._subscribers.clear();
}
}
75 changes: 75 additions & 0 deletions packages/shared/lib/services/window.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { ObservableValue } from '@lib/observable-value';

export class WindowService {
private _tabRecords = new Set<number>();
private _templatePath: string = '';

private _window: chrome.windows.Window | null = null;

private _onWindowClosedSubscription$ = new ObservableValue<void>(undefined);

get window() {
return this._window;
}

setWindowTemplatePath(path: string) {
this._templatePath = path;
}

async ensureWindow() {
if (!this._window) {
await this.createWindow();
}

return this._window!;
}

async createWindow() {
const currentWindow = await chrome.windows.getCurrent();

this._window = await chrome.windows.create({
url: this._templatePath,
width: currentWindow.width ?? 1280,
height: currentWindow.height ?? 920,
state: 'normal',
focused: false,
});
}

closeWindow() {
if (this._window) {
const windowId = this._window.id;
this._window = null;

windowId && chrome.windows.remove(windowId);
}
}

onWindowClosed(callback: () => void) {
return this._onWindowClosedSubscription$.subscribe(callback);
}

listenMessage() {
chrome.windows.onRemoved.addListener((windowId) => {
if (this._window && this._window.id === windowId) {
this._window = null;
this._onWindowClosedSubscription$.next();
}
});

chrome.tabs.onCreated.addListener((tab) => {
if (tab.id
&& tab.windowId === this._window?.id
&& tab.pendingUrl !== this._templatePath) {
this._tabRecords.add(tab.id);
}
});

chrome.tabs.onRemoved.addListener((tabId) => {
this._tabRecords.delete(tabId);
if (this._window && this._tabRecords.size === 0) {
this.closeWindow();
}
});
}
}
6 changes: 6 additions & 0 deletions packages/shared/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export function isFunction(value: any): value is Function {
return typeof value === 'function';
}

export function waitFor(ms: number) {
return new Promise<void>((resolve) => {
setTimeout(resolve, ms);
});
};
4 changes: 2 additions & 2 deletions packages/ui/client/client.controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { IMessage, PushStorageMessage, UIOpenTableScrapingDialogMessage } from '@univer-clipsheet-core/shared';
import { ClientMessageTypeEnum, ClipsheetMessageTypeEnum, IframeViewTypeEnum, UIMessageTypeEnum, UIStorageKeyEnum } from '@univer-clipsheet-core/shared';
import { ClientMessageTypeEnum, ClipsheetMessageTypeEnum, IframeViewTypeEnum, sendSetIframeViewMessage, UIMessageTypeEnum, UIStorageKeyEnum } from '@univer-clipsheet-core/shared';
import type { ScrapTablesMessage } from '@univer-clipsheet-core/table';
import { TableMessageTypeEnum, TableRecordTypeEnum } from '@univer-clipsheet-core/table';
import { Inject, Injector } from '@wendellhu/redi';
Expand All @@ -18,7 +18,7 @@ export class ClientController {
this._tableScrapingShadowComponent.active$.subscribe((active) => {
if (active) {
if (![IframeViewTypeEnum.PreviewTablePanel, IframeViewTypeEnum.None].includes(this._iframeViewController.view)) {
this._iframeViewController.setView(IframeViewTypeEnum.None);
sendSetIframeViewMessage(IframeViewTypeEnum.None);
}
}
});
Expand Down
21 changes: 12 additions & 9 deletions packages/ui/client/components/PreviewTablePanel.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { InitialSheetView } from '@components/initial-sheet-view';
import { useStorageValue } from '@lib/hooks';
import type { IScraper, IScraperColumn } from '@univer-clipsheet-core/scraper';
import type { IScraper } from '@univer-clipsheet-core/scraper';
import { ScraperStorageKeyEnum } from '@univer-clipsheet-core/scraper';
import type { IInitialSheet, IPreviewSheetStorageValue } from '@univer-clipsheet-core/table';
import { PreviewSheetFromEnum, TableStorageKeyEnum } from '@univer-clipsheet-core/table';
Expand Down Expand Up @@ -30,20 +30,23 @@ export const PreviewTablePanel = (props: PreviewTablePanelProps) => {
}

previewSheet.sheet.columnName = scraperColumns.map((column) => column.name);
const columnMap = new Map<number, IScraperColumn>();
scraperColumns.forEach((column) => {
columnMap.set(column.index, column);
});

const rows = previewSheet.sheet.rows.map((r) => {
return {
...r,
cells: r.cells.filter((cell, index) => {
return columnMap.has(index);
}).map((cell, index) => {
cells: scraperColumns.map((column) => {
const cell = r.cells[column.index];
if (!cell) {
return {
text: '',
url: '',
type: column.type,
};
}

return {
...cell,
type: columnMap.get(index)!.type,
type: column.type,
};
}),
};
Expand Down
10 changes: 8 additions & 2 deletions packages/ui/client/element-inspect/element-inspect.message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,14 @@ export async function requestElementInspection() {
});
}

export function connectElementInspection(callback: (message: ResponseElementInspectionMessage['payload']) => void) {
export function connectElementInspection(options: {
onConnectTab(): void;
onInspectElement: (payload: ResponseElementInspectionMessage['payload']) => void;
}) {
const { onConnectTab, onInspectElement } = options;
const listener = (message: ResponseElementInspectionMessage) => {
if (message.type === ElementInspectMessageTypeEnum.ResponseElementInspection) {
callback(message.payload);
onInspectElement(message.payload);
}
};

Expand All @@ -76,6 +80,8 @@ export function connectElementInspection(callback: (message: ResponseElementInsp
await waitTabComplete(tabId);
}

onConnectTab();

chrome.tabs.sendMessage(tabId, {
type: ElementInspectMessageTypeEnum.ConnectElementInspection,
});
Expand Down
Loading

0 comments on commit 7bbeaba

Please sign in to comment.