Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
5 changes: 3 additions & 2 deletions packages/base/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@
"@jupytergis/schema": "^0.1.0",
"@jupyterlab/application": "^4.0.0",
"@jupyterlab/apputils": "^4.0.0",
"@jupyterlab/completer": "^4.2.4",
"@jupyterlab/console": "^4.2.4",
"@jupyterlab/coreutils": "^6.0.0",
"@jupyterlab/docregistry": "^4.0.0",
"@jupyterlab/filebrowser": "^4.0.0",
Expand Down Expand Up @@ -72,8 +74,7 @@
"styled-components": "^5.3.6",
"three": "^0.135.0",
"three-mesh-bvh": "^0.5.17",
"uuid": "^8.3.2",
"yjs-widgets": "^0.3.3"
"uuid": "^8.3.2"
},
"devDependencies": {
"@apidevtools/json-schema-ref-parser": "^9.0.9",
Expand Down
101 changes: 100 additions & 1 deletion packages/base/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { LayerBrowserWidget } from './dialogs/layerBrowserDialog';
import { SymbologyWidget } from './dialogs/symbologyDialog';
import { TerrainDialogWidget } from './dialogs/terrainDialog';
import { JupyterGISWidget } from './widget';
import { ICompletionProviderManager } from '@jupyterlab/completer';

interface ICreateEntry {
tracker: WidgetTracker<JupyterGISWidget>;
Expand All @@ -41,7 +42,8 @@ export function addCommands(
translator: ITranslator,
formSchemaRegistry: IJGISFormSchemaRegistry,
layerBrowserRegistry: IJGISLayerBrowserRegistry,
state: IStateDB
state: IStateDB,
completionProviderManager: ICompletionProviderManager | undefined
): void {
const trans = translator.load('jupyterlab');
const { commands } = app;
Expand Down Expand Up @@ -787,6 +789,63 @@ export function addCommands(
});
}
});

// Console commands
commands.addCommand(CommandIDs.toggleConsole, {
label: trans.__('Toggle console'),
isEnabled: () => {
return tracker.currentWidget
? tracker.currentWidget.context.model.sharedModel.editable
: false;
},
execute: async () => await Private.toggleConsole(tracker)
});
commands.addCommand(CommandIDs.executeConsole, {
label: trans.__('Execute console'),
isEnabled: () => {
return tracker.currentWidget
? tracker.currentWidget.context.model.sharedModel.editable
: false;
},
execute: () => Private.executeConsole(tracker)
});
commands.addCommand(CommandIDs.removeConsole, {
label: trans.__('Remove console'),
isEnabled: () => {
return tracker.currentWidget
? tracker.currentWidget.context.model.sharedModel.editable
: false;
},
execute: () => Private.removeConsole(tracker)
});

commands.addCommand(CommandIDs.invokeCompleter, {
label: trans.__('Display the completion helper.'),
execute: () => {
const currentWidget = tracker.currentWidget;
if (!currentWidget || !completionProviderManager) {
return;
}
const id = currentWidget.content.consolePanel?.id;
if (id) {
return completionProviderManager.invoke(id);
}
}
});

commands.addCommand(CommandIDs.selectCompleter, {
label: trans.__('Select the completion suggestion.'),
execute: () => {
const currentWidget = tracker.currentWidget;
if (!currentWidget || !completionProviderManager) {
return;
}
const id = currentWidget.content.consolePanel?.id;
if (id) {
return completionProviderManager.select(id);
}
}
});
}

namespace Private {
Expand Down Expand Up @@ -987,4 +1046,44 @@ namespace Private {
callback(itemId, newName);
}
}

export function executeConsole(
tracker: WidgetTracker<JupyterGISWidget>
): void {
const current = tracker.currentWidget;

if (!current) {
return;
}
current.content.executeConsole();
}

export function removeConsole(
tracker: WidgetTracker<JupyterGISWidget>
): void {
const current = tracker.currentWidget;

if (!current) {
return;
}
current.content.removeConsole();
}

export async function toggleConsole(
tracker: WidgetTracker<JupyterGISWidget>
): Promise<void> {
const current = tracker.currentWidget;

if (!current) {
return;
}
const currentPath = current.context.path.split(':');
let realPath = '';
if (currentPath.length > 1) {
realPath = currentPath[1];
} else {
realPath = currentPath[0];
}
await current.content.toggleConsole(realPath);
}
}
87 changes: 87 additions & 0 deletions packages/base/src/console/consoleview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { ConsolePanel } from '@jupyterlab/console';
import { ServiceManager } from '@jupyterlab/services';
import { BoxPanel, Widget } from '@lumino/widgets';
import { IRenderMimeRegistry } from '@jupyterlab/rendermime';
import { IEditorMimeTypeService } from '@jupyterlab/codeeditor';
import { debounce } from '../tools';
import {
closeIcon,
CommandToolbarButton,
expandIcon,
Toolbar
} from '@jupyterlab/ui-components';
import { CommandRegistry } from '@lumino/commands';

export class ConsoleView extends BoxPanel {
constructor(options: ConsoleView.IOptions) {
super({ direction: 'top-to-bottom' });
this.addClass('jpgis-console');
const { manager, contentFactory, mimeTypeService, rendermime } = options;
const clonedRendermime = rendermime.clone();
this._consolePanel = new ConsolePanel({
manager,
contentFactory,
mimeTypeService,
rendermime: clonedRendermime,
kernelPreference: { name: 'python3', shutdownOnDispose: true }
});
this._consolePanel.console.node.dataset.jpInteractionMode = 'notebook';
this.addWidget(this._consolePanel);
BoxPanel.setStretch(this._consolePanel, 1);

this._consolePanel.toolbar.addItem('spacer', Toolbar.createSpacerItem());

this._consolePanel.toolbar.addItem(
'toggle',
new CommandToolbarButton({
label: '',
icon: expandIcon,
id: 'jupytergis:toggleConsole',
commands: options.commandRegistry
})
);
this._consolePanel.toolbar.addItem(
'close',
new CommandToolbarButton({
label: '',
icon: closeIcon,
id: 'jupytergis:removeConsole',
commands: options.commandRegistry
})
);
}

get consolePanel() {
return this._consolePanel;
}

dispose(): void {
if (this.isDisposed) {
return;
}
this._consolePanel.dispose();
super.dispose();
}
execute() {
this._consolePanel.console.execute(false);
}

protected onResize(msg: Widget.ResizeMessage): void {
super.onResize(msg);
this._resize();
}
private _consolePanel: ConsolePanel;
private _resize = debounce(() => {
window.dispatchEvent(new Event('resize'));
}, 200);
}

export namespace ConsoleView {
export interface IOptions {
manager: ServiceManager.IManager;
contentFactory: ConsolePanel.IContentFactory;
mimeTypeService: IEditorMimeTypeService;
rendermime: IRenderMimeRegistry;
commandRegistry: CommandRegistry;
}
}
1 change: 1 addition & 0 deletions packages/base/src/console/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './consoleview';
7 changes: 7 additions & 0 deletions packages/base/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,13 @@ export namespace CommandIDs {
// Terrain stuff
export const newTerrain = 'jupytergis:newTerrain';
export const removeTerrain = 'jupytergis:removeTerrain';

// Console commands
export const toggleConsole = 'jupytergis:toggleConsole';
export const invokeCompleter = 'jupytergis:invokeConsoleCompleter';
export const removeConsole = 'jupytergis:removeConsole';
export const executeConsole = 'jupytergis:executeConsole';
export const selectCompleter = 'jupytergis:selectConsoleCompleter';
}

interface IRegisteredIcon {
Expand Down
2 changes: 2 additions & 0 deletions packages/base/src/mainview/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
export * from './mainView';
export * from './mainviewwidget';
export * from './mainviewmodel';
24 changes: 24 additions & 0 deletions packages/base/src/mainview/mainviewwidget.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { ReactWidget } from '@jupyterlab/apputils';
import * as React from 'react';

import { MainView } from './mainView';
import { MainViewModel } from './mainviewmodel';

export class JupyterGISMainViewPanel extends ReactWidget {
/**
* Construct a `JupyterGISPanel`.
*
* @param context - The documents context.
*/
constructor(options: { mainViewModel: MainViewModel }) {
super();
this._mainViewModel = options.mainViewModel;
this.addClass('jp-jupytergis-panel');
}

render(): JSX.Element {
return <MainView viewModel={this._mainViewModel} />;
}

private _mainViewModel: MainViewModel;
}
2 changes: 1 addition & 1 deletion packages/base/src/panelview/components/layers.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -246,7 +246,7 @@ function LayerGroupComponent(props: ILayerGroupProps): JSX.Element {
const getExpandedState = async () => {
const groupState: ReadonlyPartialJSONValue | undefined =
await state.fetch(group.name);
setOpen(groupState ? (groupState as any)['expanded'] ?? false : false);
setOpen(groupState ? ((groupState as any)['expanded'] ?? false) : false);
};

getExpandedState();
Expand Down
3 changes: 2 additions & 1 deletion packages/base/src/panelview/components/sources.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,8 @@ function SourceComponent(props: ISourceProps): JSX.Element {
*/
useEffect(() => {
const checkUsage = () => {
setUnused(!gisModel?.getLayersBySource(sourceId).length ?? true);
const sources = gisModel?.getLayersBySource(sourceId);
setUnused(sources ? sources.length === 0 : true);
};

gisModel?.sharedLayersChanged.connect(checkUsage);
Expand Down
14 changes: 13 additions & 1 deletion packages/base/src/toolbar/usertoolbaritem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,10 +71,22 @@ export class UsersItem extends React.Component<IProps, IState> {
return el;
}

private filterDuplicated(usersList: IUserData[]): IUserData[] {
const newList: IUserData[] = [];
const selected = new Set<string>();
for (const element of usersList) {
if (!selected.has(element.userData.username)) {
selected.add(element.userData.username);
newList.push(element);
}
}
return newList;
}

render(): React.ReactNode {
return (
<div className="jGIS-toolbar-usertoolbar">
{this.state.usersList.map(item => {
{this.filterDuplicated(this.state.usersList).map(item => {
if (item.userId !== this._model.currentUserId) {
return this.createUserIcon(item);
}
Expand Down
15 changes: 14 additions & 1 deletion packages/base/src/toolbar/widget.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import {
ReactWidget,
Toolbar,
redoIcon,
undoIcon
undoIcon,
terminalIcon
} from '@jupyterlab/ui-components';
import { CommandRegistry } from '@lumino/commands';
import { Widget } from '@lumino/widgets';
Expand Down Expand Up @@ -53,6 +54,18 @@ export class ToolbarWidget extends Toolbar {
})
);

this.addItem('separator0', new Separator());

this.addItem(
'Toggle console',
new CommandToolbarButton({
id: CommandIDs.toggleConsole,
commands: options.commands,
label: '',
icon: terminalIcon
})
);

this.addItem('separator1', new Separator());

this.addItem(
Expand Down
Loading
Loading