Skip to content

Commit

Permalink
feat(undo/redo): added undo redo buttons to header
Browse files Browse the repository at this point in the history
  • Loading branch information
kirangadhave committed Nov 15, 2023
1 parent 2818c74 commit 88beb55
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 6 deletions.
6 changes: 3 additions & 3 deletions examples/test_ext_widget.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -163,15 +163,15 @@
"execution_count": 3,
"id": "621bf69a-bb31-407f-ab20-e75792f3e61d",
"metadata": {
"__GENERATED_DATAFRAMES__": "ᯡࠣ䅬Ԁ朤壠ᜣ琢〹夤゠⹰〮⁁䁻қ䚾ኊ㇠നСࠩ瀮晼Ƭ穅5愠៤⠠ ",
"__GENERATED_DATAFRAMES__": "ᯢ粠 ",
"__has_persist_output": true,
"trrack_graph": "ᯡ࠽䈌ʀ匦㢠⹰Ӡ㬠ణ㇆⠵䁍6੐ځዚ䈢ᠡ柃ⅻ䦿¼ĸ㦀ᣪβ⠠䭈⑁槒瀲僅⍡䦫᭮ẉ紤䀡傠ǐѕ冧兀ॢȠம䠸Žᢀ㜰䁾巗怢扏⨠Ꮃ䤠ව׵樈ᱬ䠸嵞⁡䫯/ጢ→ぐᠺ橮㥙ᝠஃːᬨ䀬悰勋ࢤ൑ػ嗄堣⴪ܞ嚰桠៷⧻⠣ᠹ磌ࢭ炰ᰭ☼喀ԐY杽幐㹶勤ѹ殏さᭀ䃤ጘᠮㄧਣ౨⟂䆑㡨ྴ͈ᭁõ乨ᝁ⎱硁䡫剌⬩ṃɄ獾嘿梡繫שኀ㡜ࢪ⏩⑥ᆬ拑沎ហႢ⁞*砒ʛ⮪⍦撸攻ୡ棘䪠佲㑢⽨ "
"trrack_graph": "ᯡ࠽䈌ʀ匦㢠⹰ৠܡⰠ〸挼倶䀻CᑤƄ唠晢ȸ畀ᧁ⠧ゑ䍪త憯抣ैkᑄᄉ夐ࢷዃ⽩嗛᜾㺣䍤ð䀡塕ᆨ㵀ॢȠநƸŽᢀ眰䅽忒Π˼リ$熒‣㐡㨦䍇ᦲଠ探ࢁ壡‡犀␠⌧ିᇦ䙆ዲ䮈ؠ嬸ඣ౤æҡ哻䑀妨䢣⥕䀺慰戩瞤∡㸦ƶ䬳ۡǵण䍔愊㘠传ϒ緯澣潸䎪川ฬ玄ࡄ婲䭢䕆撶䤩⑸柢║ᾣ䡢ᆣ∰慈㲪ԡ惐ٌǦ磶䷔䒱䁲斨撫ౠ⃕䜁䥐属ѣ၈㞪䣦ヸ乗௠ࢤᅗ䎠ż䄰䤎狩墥༼凰䔕ᒵ偳㨰҄ "
},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "c7de26ed7bd649eb9116ef4e6dc9927b",
"model_id": "015a8b480aa64a52b8cecae352b4e0b1",
"version_major": 2,
"version_minor": 0
},
Expand Down
2 changes: 2 additions & 0 deletions persist_ext/internals/widgets/base/output_processor.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,8 @@ def _apply_category(self, interaction, data, chart):
category = action["category"]
if chart:
params = getattr(chart, "params", [])
if params is Undefined:
params = []
params_with_views = filter(lambda x: hasattr(x, "views"), params)
view_names_only = map(lambda x: x.views, params_with_views)
view_names = sum(view_names_only, [])
Expand Down
55 changes: 52 additions & 3 deletions src/widgets/header/Header.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { useModelState } from '@anywidget/react';
import React, { useCallback } from 'react';
import React, { useCallback, useEffect, useMemo } from 'react';
import { TrrackableCell } from '../../cells';
import { Button, Divider, Group } from '@mantine/core';
import { Button, Divider, Group, Tooltip } from '@mantine/core';
import { PersistCommands } from '../../commands';
import { IconFilterMinus, IconFilterPlus } from '@tabler/icons-react';
import {
IconArrowBackUp,
IconArrowForwardUp,
IconFilterMinus,
IconFilterPlus
} from '@tabler/icons-react';
import { CommandButton } from './CommandButton';
import { Annotate } from './Annotate';
import { UseSignal } from '@jupyterlab/apputils';
Expand All @@ -12,12 +17,15 @@ import { DropColumnPopover } from './DropColumnPopover';
import { EditCategoryPopover } from './EditCategoryPopover';
import { AssignCategoryPopover } from './AssignCategoryPopover';
import { GeneratedRecord } from '../utils/dataframe';
import { HeaderActionIcon } from './StyledActionIcon';
import { useHookstate } from '@hookstate/core';

type Props = {
cell: TrrackableCell;
};

export function Header({ cell }: Props) {
const current = useHookstate(cell.trrackManager.trrack.current.id); // Trrack current change
const [hasSelections] = useModelState<boolean>('df_has_selections');
const [generatedRecord, setGeneratedRecord] =
useModelState<GeneratedRecord>('gdr_record');
Expand All @@ -34,13 +42,54 @@ export function Header({ cell }: Props) {
setGeneratedRecord(newRecord);
}, []);

useEffect(() => {
const manager = cell.trrackManager;
function onCurrentNodeChange() {
current.set(manager.trrack.current.id);
}

cell.trrackManager.currentChange.connect(onCurrentNodeChange);

return () => {
cell.trrackManager.currentChange.disconnect(onCurrentNodeChange);
};
}, [cell, current]);

const { canUndo, canRedo } = useMemo(() => {
return {
canUndo: cell.trrackManager.trrack.root.id !== current.value,
canRedo: cell.trrackGraph?.nodes[current.value]?.children?.length || 0 > 0
};
}, [cell, current.value]);

return (
<Group
style={{
borderBottom: '2px solid rgb(0, 0, 0, 10%)',
padding: '1em'
}}
>
<HeaderActionIcon
disabled={!canUndo}
onClick={() => {
cell.trrackManager.trrack.undo();
}}
>
<Tooltip.Floating label="Undo" offset={20}>
<IconArrowBackUp />
</Tooltip.Floating>
</HeaderActionIcon>
<HeaderActionIcon
disabled={!canRedo}
onClick={() => {
cell.trrackManager.trrack.redo();
}}
>
<Tooltip.Floating label="Redo" offset={20}>
<IconArrowForwardUp />
</Tooltip.Floating>
</HeaderActionIcon>
<Divider orientation="vertical" />
<RenameColumnPopover cell={cell} />
<DropColumnPopover cell={cell} />
<Divider orientation="vertical" />
Expand Down
14 changes: 14 additions & 0 deletions src/widgets/trrack/manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import {
TrrackProvenance,
TrrackEvents
} from './types';
import { hookstate } from '@hookstate/core';

const defaultTrrackState: TrrackState = {
id: UUID(),
Expand Down Expand Up @@ -44,6 +45,11 @@ export class TrrackManager {
private _unsubscribeCurrentChangeListener: Nullable<UnsubscribeCurrentChangeListener> =
null;

undoRedoStatus = hookstate({
canUndo: false,
canRedo: false
});

constructor(private _cell: TrrackableCell) {
TrrackManager._instanceMaps.set(_cell, this);
this._addInteractionAction = this._registerAddInteractionAction();
Expand Down Expand Up @@ -71,6 +77,14 @@ export class TrrackManager {
loadTrrack(graphToLoad: Nullable<TrrackGraph> = null) {
const onCurrentChange = () => {
this._cell.trrackGraphState.set(this._graph);
this.undoRedoStatus
.nested('canUndo')
.set(this.trrack.current.id !== this.trrack.root.id);

this.undoRedoStatus
.nested('canRedo')
.set(this.trrack.current.children.length > 0);

window.Persist.Commands.registry.notifyCommandChanged();
this._notifyCurrentChange.emit(this._trrack.current.id);
};
Expand Down

0 comments on commit 88beb55

Please sign in to comment.