Skip to content

Commit

Permalink
Fix suggestion position
Browse files Browse the repository at this point in the history
  • Loading branch information
trungleduc committed Dec 18, 2024
1 parent d722959 commit d119bcb
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 48 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ export class LocalSuggestionsManager
case SuggestionType.delete: {
const currentNotebook = notebook.content;
const { defaultCell } = currentNotebook.notebookConfig;
const deleted = deleteCellById({
const deleted = await deleteCellById({
currentNotebook,
cellId,
defaultCell
Expand Down
5 changes: 1 addition & 4 deletions packages/base/src/suggestionCellMenu/cellToolbarMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,7 @@ const Menu = React.forwardRef((props: IMenuProps, ref) => {
<editIcon.react />
</div>
<div
onClick={() => {
console.log('aaaa');
executeAddSuggestion();
}}
onClick={executeAddSuggestion}
style={{ padding: 0 }}
className="lm-Menu-itemLabel"
>
Expand Down
7 changes: 6 additions & 1 deletion packages/base/src/suggestionCellMenu/style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,12 @@ export const toolbarMenuItemStyle = style({
},
'& > .lm-Menu-itemIcon': {
display: 'inline-block',
verticalAlign: 'middle'
verticalAlign: 'middle',
$nest: {
'& > div': {
display: 'flex'
}
}
}
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function _SuggestionToolbarReact(props: IProps) {
state.changed.disconnect(handler);
};
}, [state]);
const userData = props.metadata.author;
const userData = props.metadata?.author;
return (
<div className={toolbarStyle}>
{userData && (
Expand Down
77 changes: 55 additions & 22 deletions packages/base/src/suggestionsPanel/widget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,28 +61,53 @@ export class SuggestionsWidget extends PanelWithToolbar {
suggestionData: suggestion
});
const cellIdx = this._model.getCellIndex(cellId);
let cellSuggestionPanel = this._cellSuggestionsPanel.get(cellId);
if (!cellSuggestionPanel) {
cellSuggestionPanel = new Panel();
this._cellSuggestionsPanel.set(cellId, cellSuggestionPanel);
this._suggestionsArea.insertWidget(cellIdx, cellSuggestionPanel);
let cellSuggestionPanelData = this._cellSuggestionsPanel.get(cellId);

if (!cellSuggestionPanelData) {
const cellSuggestionPanel = new Panel();
cellSuggestionPanelData = {
panel: cellSuggestionPanel,
cellIndex: cellIdx
};
this._cellSuggestionsPanel.set(cellId, cellSuggestionPanelData);
let elementBefore: Widget | undefined = undefined;
const allIndex = [...this._cellSuggestionsPanel.values()].sort(
(a, b) => a.cellIndex - b.cellIndex
);
for (const element of allIndex) {
if (element.cellIndex < cellIdx) {
elementBefore = element.panel;
} else {
break;
}
}
let indexToInsert = 0;
if (elementBefore) {
indexToInsert =
this._suggestionsArea.widgets.indexOf(elementBefore) + 1;
}
this._suggestionsArea.insertWidget(
indexToInsert,
cellSuggestionPanel
);
}
cellSuggestionPanel.addWidget(widget);
cellSuggestionPanelData.panel.addWidget(widget);

this._highlightCellSuggestions(cellId);
}
break;
}
case 'deleted': {
const cellSuggestionsPanel = this._cellSuggestionsPanel.get(cellId);
if (!cellSuggestionsPanel) {
const cellSuggestionsData = this._cellSuggestionsPanel.get(cellId);
if (!cellSuggestionsData) {
break;
}
const allWidgets = [...cellSuggestionsPanel.widgets];
const allWidgets = [...cellSuggestionsData.panel.widgets];
for (const element of allWidgets) {
if (element.id === suggestionId) {
element.dispose();
element.parent = null;

break;
}
}
Expand All @@ -108,16 +133,17 @@ export class SuggestionsWidget extends PanelWithToolbar {
}
private _highlightCellSuggestions(cellId: string): void {
this._cellSuggestionsPanel.forEach((p, k) => {
const { panel } = p;
if (k === cellId) {
p.addClass(suggestionCellSelectedStyle);
panel.addClass(suggestionCellSelectedStyle);
let lastElement: Widget | undefined = undefined;
for (const element of p.widgets) {
for (const element of panel.widgets) {
(element as BaseCellwidget).toggleMinimized(false);
lastElement = element;
}
this._scrollToWidget(p, lastElement);
this._scrollToWidget(panel, lastElement);
} else {
p.removeClass(suggestionCellSelectedStyle);
panel.removeClass(suggestionCellSelectedStyle);
}
});
}
Expand All @@ -134,24 +160,28 @@ export class SuggestionsWidget extends PanelWithToolbar {
private _renderSuggestions() {
const allSuggestions = this._model.allSuggestions;

this._cellSuggestionsPanel.forEach(p => {
const allWidgets = [...p.widgets];
this._cellSuggestionsPanel.forEach(it => {
const { panel } = it;
const allWidgets = [...panel.widgets];
for (const element of allWidgets) {
p.layout?.removeWidget(element);
panel.layout?.removeWidget(element);
element.dispose();
element.parent = null;
}
p.dispose();
p.parent = null;
this._suggestionsArea.layout?.removeWidget(p);
panel.dispose();
panel.parent = null;
this._suggestionsArea.layout?.removeWidget(panel);
});
this._cellSuggestionsPanel.clear();
if (allSuggestions) {
const suggestionPanelByIndex: IDict<Panel> = {};
for (const [cellId, val] of allSuggestions.entries()) {
const cellSuggestionPanel = new Panel();
this._cellSuggestionsPanel.set(cellId, cellSuggestionPanel);
const cellIdx = this._model.getCellIndex(cellId);
this._cellSuggestionsPanel.set(cellId, {
panel: cellSuggestionPanel,
cellIndex: cellIdx
});
suggestionPanelByIndex[cellIdx] = cellSuggestionPanel;
Object.entries(val).forEach(([suggestionId, suggestionData]) => {
const { widget } = this._widgetFactory({
Expand Down Expand Up @@ -182,7 +212,7 @@ export class SuggestionsWidget extends PanelWithToolbar {
private _updatePanelTitle(): void {
let count = 0;
this._cellSuggestionsPanel.forEach(it => {
count += it.widgets.length;
count += it.panel.widgets.length;
});
if (count !== 0) {
this.title.label = `All Suggestions (${count})`;
Expand Down Expand Up @@ -270,7 +300,10 @@ export class SuggestionsWidget extends PanelWithToolbar {
}

private _suggestionsArea = new Panel();
private _cellSuggestionsPanel = new Map<string, Panel>();
private _cellSuggestionsPanel = new Map<
string,
{ panel: Panel; cellIndex: number }
>();
private _model: ISuggestionsModel;
}

Expand Down
31 changes: 25 additions & 6 deletions packages/base/src/tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
import { Notebook, NotebookPanel } from '@jupyterlab/notebook';

import { IDict } from './types';
import { PromiseDelegate } from '@lumino/coreutils';

export const COMMAND_IDS = {
/**
Expand Down Expand Up @@ -55,6 +56,7 @@ export function detectCellChangedEvent(changed: NotebookChange):
| {
event: 'deleted' | 'moved';
movedCells?: ISharedCell[];
deletedIdx?: number;
}
| undefined {
const { cellsChange } = changed;
Expand All @@ -63,22 +65,26 @@ export function detectCellChangedEvent(changed: NotebookChange):
let haveDelete = false;
let haveInsert: ISharedCell[] | undefined;
let haveRetain = false;
let retainIndex = 0;
let deleteIndex = 0;
for (const c of cellsChange) {
if (c.delete !== undefined) {
haveDelete = true;
deleteIndex = c.delete;
}
if (c.insert !== undefined) {
haveInsert = c.insert;
}
if (c.retain !== undefined) {
haveRetain = true;
retainIndex = c.retain;
}
}
if (haveDelete) {
if (haveRetain && haveInsert) {
return { event: 'moved', movedCells: haveInsert };
}
return { event: 'deleted' };
return { event: 'deleted', deletedIdx: retainIndex + deleteIndex - 1 };
}
}
return;
Expand Down Expand Up @@ -136,16 +142,16 @@ export function cellModelFromYCell(options: {
* sharedModel: ISharedDocument;
* }} options
*/
export function deleteCellById(options: {
export async function deleteCellById(options: {
cellId: string;
sharedModel?: YNotebook;
defaultCell?: string;
currentNotebook?: Notebook;
}): boolean {
let deleted = false;
}): Promise<boolean> {
const { cellId, defaultCell, currentNotebook } = options;
let sharedModel = options.sharedModel;

const pd = new PromiseDelegate<boolean>();
if (currentNotebook) {
sharedModel = currentNotebook.model?.sharedModel as YNotebook;
}
Expand All @@ -159,10 +165,21 @@ export function deleteCellById(options: {
break;
}
}

if (cellIndex !== -1) {
const handler = (nb: YNotebook, changed: NotebookChange) => {
const cellChangedEvent = detectCellChangedEvent(changed);
if (cellChangedEvent?.event === 'deleted') {
const deletedIndex = cellChangedEvent.deletedIdx;
if (deletedIndex === cellIndex) {
pd.resolve(true);
sharedModel.changed.disconnect(handler);
}
}
};
sharedModel.changed.connect(handler);
sharedModel.transact(() => {
sharedModel.deleteCell(cellIndex);
deleted = true;
// Add a new cell if the notebook is empty. This is done
// within the compound operation to make the deletion of
// a notebook's last cell undoable.
Expand All @@ -183,8 +200,10 @@ export function deleteCellById(options: {
});
currentNotebook?.deselectAll();
}
} else {
pd.resolve(false);
}
return deleted;
return pd.promise;
}

export function cloneCellModel(
Expand Down
43 changes: 33 additions & 10 deletions python/jupyter_suggestions_rtc/src/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,20 @@ export class RtcSuggestionsManager
async getAllSuggestions(
notebook: NotebookPanel
): Promise<IAllSuggestionData> {
const rootDocId = notebook.context.model.sharedModel.getState(
const path = notebook.context.localPath;
let rootDocId = notebook.context.model.sharedModel.getState(
'document_id'
) as string;
) as string | undefined;
let format = 'json';
let type = 'notebook';
if (rootDocId) {
[format, type] = rootDocId.split(':');
} else {
const docSession = await requestDocSession(format, type, path);
rootDocId = `${format}:${type}:${docSession.fileId}`;
this._serverSession = docSession.sessionId;
}

const [format, type] = rootDocId.split(':');
const path = notebook.context.localPath;
if (!this._serverSession) {
const docSession = await requestDocSession(format, type, path);
this._serverSession = docSession.sessionId;
Expand Down Expand Up @@ -171,7 +179,24 @@ export class RtcSuggestionsManager
cellId: string;
suggestionId: string;
}): Promise<boolean> {
const { suggestionId } = options;
const { suggestionId, cellId, notebook } = options;
const notebookPath = notebook.context.localPath;
const suggestionData = await this.getSuggestion({
notebookPath,
cellId,
suggestionId
});
if (!suggestionData) {
return false;
}
const suggestionType = suggestionData.type;
if (suggestionType === SuggestionType.delete) {
const sharedModel = this._allSharedNotebook.get(suggestionId);
const deleted = await deleteCellById({ sharedModel, cellId });
if (!deleted) {
return deleted;
}
}
try {
this._removeSharedNotebook(suggestionId);
await this._forkManager.deleteFork({ forkId: suggestionId, merge: true });
Expand Down Expand Up @@ -259,6 +284,7 @@ export class RtcSuggestionsManager
forkCellId: string;
forkRoomId: string;
notebookPath: string;
suggestionType: SuggestionType;
}
) {
const { forkCellMimeType, forkCellId, forkRoomId, notebookPath } = options;
Expand Down Expand Up @@ -326,10 +352,6 @@ export class RtcSuggestionsManager
mimeType: mimeType ?? 'text/plain',
forkMeta
});
if (suggestionType === SuggestionType.delete) {
const sharedModel = this._allSharedNotebook.get(suggestionId);
deleteCellById({ sharedModel, cellId });
}
const suggestionContent: ISuggestionData = {
originalCellId: cellId,
cellModel,
Expand Down Expand Up @@ -370,7 +392,8 @@ export class RtcSuggestionsManager
forkCellMimeType: mimeType,
forkCellId: cellId,
forkRoomId,
notebookPath: forkMeta.path!
notebookPath: forkMeta.path!,
suggestionType: forkMeta.suggestionType
});
shared.changed.connect(handler);
shared.disposed.connect(() => {
Expand Down
6 changes: 3 additions & 3 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10332,7 +10332,7 @@ __metadata:

"typescript@patch:typescript@>=3 < 6#~builtin<compat/typescript>, typescript@patch:typescript@^5#~builtin<compat/typescript>":
version: 5.7.2
resolution: "typescript@patch:typescript@npm%3A5.7.2#~builtin<compat/typescript>::version=5.7.2&hash=e012d7"
resolution: "typescript@patch:typescript@npm%3A5.7.2#~builtin<compat/typescript>::version=5.7.2&hash=85af82"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
Expand All @@ -10342,11 +10342,11 @@ __metadata:

"typescript@patch:typescript@~5.0.2#~builtin<compat/typescript>":
version: 5.0.4
resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin<compat/typescript>::version=5.0.4&hash=b5f058"
resolution: "typescript@patch:typescript@npm%3A5.0.4#~builtin<compat/typescript>::version=5.0.4&hash=85af82"
bin:
tsc: bin/tsc
tsserver: bin/tsserver
checksum: d26b6ba97b6d163c55dbdffd9bbb4c211667ebebc743accfeb2c8c0154aace7afd097b51165a72a5bad2cf65a4612259344ff60f8e642362aa1695c760d303ac
checksum: bb309d320c59a26565fb3793dba550576ab861018ff3fd1b7fccabbe46ae4a35546bc45f342c0a0b6f265c801ccdf64ffd68f548f117ceb7f0eac4b805cd52a9
languageName: node
linkType: hard

Expand Down

0 comments on commit d119bcb

Please sign in to comment.