Skip to content

Commit

Permalink
Frontend driven indexing
Browse files Browse the repository at this point in the history
  • Loading branch information
jtpio committed Oct 12, 2024
1 parent 09b6299 commit e7d854a
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 123 deletions.
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,8 @@
"@jupyterlab/filebrowser": "^4.2.5",
"@jupyterlab/services": "^7.2.5",
"@jupyterlab/settingregistry": "^4.2.5",
"@jupyterlab/translation": "^4.2.5"
"@jupyterlab/translation": "^4.2.5",
"minimatch": "^10.0.1"
},
"devDependencies": {
"@jupyterlab/builder": "^4.0.0",
Expand Down
133 changes: 11 additions & 122 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,125 +3,13 @@ import {
JupyterFrontEndPlugin
} from '@jupyterlab/application';
import { ICommandPalette, ModalCommandPalette } from '@jupyterlab/apputils';
import { URLExt, PathExt } from '@jupyterlab/coreutils';
import { PathExt } from '@jupyterlab/coreutils';
import { IDocumentManager } from '@jupyterlab/docmanager';
import { ServerConnection } from '@jupyterlab/services';
import { ISettingRegistry } from '@jupyterlab/settingregistry';
import { FileBrowser, IDefaultFileBrowser } from '@jupyterlab/filebrowser';
import { IDefaultFileBrowser } from '@jupyterlab/filebrowser';
import { ITranslator, nullTranslator } from '@jupyterlab/translation';
import { CommandRegistry } from '@lumino/commands';
import { ReadonlyPartialJSONObject } from '@lumino/coreutils';
import { Message } from '@lumino/messaging';
import { ISignal, Signal } from '@lumino/signaling';
import { CommandPalette } from '@lumino/widgets';

/** Structure of the JSON response from the server */
interface IQuickOpenResponse {
readonly contents: { [key: string]: string[] };
readonly scanSeconds: number;
}

/** Makes a HTTP request for the server-side quick open scan */
async function fetchContents(
path: string,
excludes: string[]
): Promise<IQuickOpenResponse> {
const query = excludes
.map(exclude => {
return 'excludes=' + encodeURIComponent(exclude);
})
.join('&');

const settings = ServerConnection.makeSettings();
const fullUrl =
URLExt.join(settings.baseUrl, 'jupyterlab-quickopen', 'api', 'files') +
'?' +
query +
'&path=' +
path;
const response = await ServerConnection.makeRequest(
fullUrl,
{ method: 'GET' },
settings
);
if (response.status !== 200) {
throw new ServerConnection.ResponseError(response);
}
return await response.json();
}

/**
* Shows files nested under directories in the root notebooks directory configured on the server.
*/
class QuickOpenWidget extends CommandPalette {
private _pathSelected = new Signal<this, string>(this);
private _settings: ReadonlyPartialJSONObject;
private _fileBrowser: FileBrowser;

constructor(
defaultBrowser: IDefaultFileBrowser,
settings: ReadonlyPartialJSONObject,
options: CommandPalette.IOptions
) {
super(options);

this.id = 'jupyterlab-quickopen';
this.title.iconClass = 'jp-SideBar-tabIcon jp-SearchIcon';
this.title.caption = 'Quick Open';

this._settings = settings;
this._fileBrowser = defaultBrowser;
}

/** Signal when a selected path is activated. */
get pathSelected(): ISignal<this, string> {
return this._pathSelected;
}

/** Current extension settings */
set settings(settings: ReadonlyPartialJSONObject) {
this._settings = settings;
}

/**
* Refreshes the widget with the paths of files on the server.
*/
protected async onActivateRequest(msg: Message): Promise<void> {
super.onActivateRequest(msg);

// Fetch the current contents from the server
const path = this._settings.relativeSearch
? this._fileBrowser.model.path
: '';
const response = await fetchContents(
path,
this._settings.excludes as string[]
);

// Remove all paths from the view
this.clearItems();

for (const category in response.contents) {
for (const fn of response.contents[category]) {
// Creates commands that are relative file paths on the server
const command = `${category}/${fn}`;
if (!this.commands.hasCommand(command)) {
// Only add the command to the registry if it does not yet exist TODO: Track disposables
// and remove
this.commands.addCommand(command, {
label: fn,
execute: () => {
// Emit a selection signal
this._pathSelected.emit(command);
}
});
}
// Make the file visible under its parent directory heading
this.addItem({ command, category });
}
}
}
}
import { QuickOpenWidget } from './quickopen';

/**
* Initialization data for the jupyterlab-quickopen extension.
Expand All @@ -144,13 +32,14 @@ const extension: JupyterFrontEndPlugin<void> = {
const settings: ISettingRegistry.ISettings = await settingRegistry.load(
extension.id
);
const widget: QuickOpenWidget = new QuickOpenWidget(
defaultFileBrowser,
settings.composite,
{
commands
}
);
const widget: QuickOpenWidget = new QuickOpenWidget({
defaultBrowser: defaultFileBrowser,
settings: settings.composite,
commandPaletteOptions: { commands },
contents: app.serviceManager.contents,
// TODO: remove
useServer: false
});

// Listen for path selection signals and show the selected files in the appropriate
// editor/viewer
Expand Down
Loading

0 comments on commit e7d854a

Please sign in to comment.