Skip to content

Commit 1505a0b

Browse files
committed
improving fronend UI handling for readonly files (esp jupyter) in misc ways
1 parent 19d61b0 commit 1505a0b

File tree

9 files changed

+51
-15
lines changed

9 files changed

+51
-15
lines changed

src/packages/frontend/frame-editors/jupyter-editor/actions.ts

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,11 @@ export class JupyterEditorActions extends BaseActions<JupyterEditorState> {
9090
this.setState({ has_unsaved_changes });
9191
});
9292

93-
this.watch_for_introspect();
94-
this.watch_for_connection_file_change();
93+
this.watchFrameEditorStore();
94+
this.watchJupyterStore();
9595
}
9696

97-
private watch_for_introspect(): void {
97+
private watchFrameEditorStore = (): void => {
9898
const store = this.store;
9999
let introspect = store.get("introspect");
100100
store.on("change", () => {
@@ -108,14 +108,22 @@ export class JupyterEditorActions extends BaseActions<JupyterEditorState> {
108108
introspect = i;
109109
}
110110
});
111-
}
111+
};
112112

113-
private watch_for_connection_file_change(): void {
113+
private watchJupyterStore = (): void => {
114114
const store = this.jupyter_actions.store;
115115
let connection_file = store.get("connection_file");
116-
this.jupyter_actions.store.on("change", () => {
116+
store.on("change", () => {
117+
// sync read only state -- source of true is jupyter_actions.store.get('read_only')
118+
const read_only = store.get("read_only");
119+
if (read_only != this.store.get("read_only")) {
120+
this.setState({ read_only });
121+
}
122+
// sync connection file
117123
const c = store.get("connection_file");
118-
if (c == connection_file) return;
124+
if (c == connection_file) {
125+
return;
126+
}
119127
connection_file = c;
120128
const id = this._get_most_recent_shell_id("jupyter");
121129
if (id == null) {
@@ -125,7 +133,7 @@ export class JupyterEditorActions extends BaseActions<JupyterEditorState> {
125133
// This will update the connection file
126134
this.shell(id, true);
127135
});
128-
}
136+
};
129137

130138
public focus(id?: string): void {
131139
const actions = this.get_frame_actions(id);

src/packages/frontend/frame-editors/jupyter-editor/cell-notebook/actions.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,9 @@ export class NotebookFrameActions {
356356
***/
357357

358358
set_mode(mode: "escape" | "edit"): void {
359+
if (this.jupyter_actions.store.get("read_only") && mode == "edit") {
360+
return;
361+
}
359362
if (mode == "edit") {
360363
// If we're changing to edit mode and current cell is a markdown
361364
// cell, switch it to the codemirror editor view.

src/packages/frontend/frame-editors/time-travel-editor/revert-file.tsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,10 @@ export class RevertFile extends Component<Props> {
2222
if (this.props.version != null)
2323
this.props.actions.revert(this.props.version);
2424
}}
25-
disabled={this.props.version == null}
25+
disabled={
26+
this.props.version == null ||
27+
this.props.actions.syncdoc?.is_read_only()
28+
}
2629
>
2730
<Icon name="undo" /> Revert
2831
</Button>

src/packages/frontend/jupyter/cell-input.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,16 @@ export const CellInput: React.FC<CellInputProps> = React.memo(
112112
actions={props.actions}
113113
id={props.id}
114114
dragHandle={props.dragHandle}
115+
read_only={props.is_readonly}
115116
/>
116117
</HiddenXS>
117118
);
118119
}
119120

120121
function handle_md_double_click(): void {
122+
if (props.is_readonly) {
123+
return;
124+
}
121125
frameActions.current?.switch_md_cell_to_edit(props.cell.get("id"));
122126
}
123127

@@ -186,7 +190,8 @@ export const CellInput: React.FC<CellInputProps> = React.memo(
186190
function render_markdown_edit_button(): Rendered {
187191
if (
188192
props.actions == null ||
189-
props.cell.getIn(["metadata", "editable"]) === false
193+
props.cell.getIn(["metadata", "editable"]) === false ||
194+
props.is_readonly
190195
) {
191196
return;
192197
}
@@ -238,6 +243,9 @@ export const CellInput: React.FC<CellInputProps> = React.memo(
238243
<MostlyStaticMarkdown
239244
value={value}
240245
onChange={(value) => {
246+
if (props.is_readonly) {
247+
return;
248+
}
241249
// user checked a checkbox.
242250
props.actions?.set_cell_input(props.id, value, true);
243251
}}

src/packages/frontend/jupyter/cell-list.tsx

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ interface CellListProps {
9797
use_windowed_list?: boolean;
9898
llmTools?: LLMTools;
9999
computeServerId?: number;
100+
read_only?: boolean;
100101
}
101102

102103
export const CellList: React.FC<CellListProps> = (props: CellListProps) => {
@@ -126,6 +127,7 @@ export const CellList: React.FC<CellListProps> = (props: CellListProps) => {
126127
use_windowed_list,
127128
llmTools,
128129
computeServerId,
130+
read_only,
129131
} = props;
130132

131133
const cell_list_node = useRef<HTMLElement | null>(null);
@@ -478,6 +480,7 @@ export const CellList: React.FC<CellListProps> = (props: CellListProps) => {
478480
isFirst={isFirst}
479481
isLast={isLast}
480482
dragHandle={dragHandle}
483+
read_only={read_only}
481484
/>
482485
</div>
483486
);

src/packages/frontend/jupyter/cell.tsx

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ interface Props {
5959
isFirst?: boolean;
6060
isLast?: boolean;
6161
dragHandle?: JSX.Element;
62+
read_only?: boolean;
6263
}
6364

6465
function areEqual(props: Props, nextProps: Props): boolean {
@@ -86,7 +87,8 @@ function areEqual(props: Props, nextProps: Props): boolean {
8687
(nextProps.llmTools?.model ?? "") !== (props.llmTools?.model ?? "") ||
8788
(nextProps.complete !== props.complete && // only worry about complete when editing this cell
8889
(nextProps.is_current || props.is_current)) ||
89-
nextProps.dragHandle !== props.dragHandle
90+
nextProps.dragHandle !== props.dragHandle ||
91+
nextProps.read_only !== props.read_only
9092
);
9193
}
9294

@@ -101,7 +103,10 @@ export const Cell: React.FC<Props> = React.memo((props: Props) => {
101103
}
102104

103105
function is_editable(): boolean {
104-
return props.cell.getIn(["metadata", "editable"], true) as any;
106+
return (
107+
!props.read_only &&
108+
(props.cell.getIn(["metadata", "editable"], true) as any)
109+
);
105110
}
106111

107112
function is_deletable(): boolean {
@@ -175,6 +180,9 @@ export const Cell: React.FC<Props> = React.memo((props: Props) => {
175180
}
176181

177182
function double_click(event: any): void {
183+
if (props.read_only) {
184+
return;
185+
}
178186
if (props.cell.getIn(["metadata", "editable"]) === false) {
179187
return;
180188
}
@@ -378,7 +386,7 @@ export const Cell: React.FC<Props> = React.memo((props: Props) => {
378386
// Note that the cell id is used for scroll functionality, so *is* important.
379387
return (
380388
<>
381-
{render_insert_cell("above")}
389+
{!props.read_only && render_insert_cell("above")}
382390
<div
383391
style={getCellStyle()}
384392
onMouseUp={props.is_current ? undefined : click_on_cell}
@@ -390,7 +398,7 @@ export const Cell: React.FC<Props> = React.memo((props: Props) => {
390398
{render_cell_input(props.cell)}
391399
{render_cell_output(props.cell)}
392400
</div>
393-
{render_insert_cell("below")}
401+
{!props.read_only && render_insert_cell("below")}
394402
</>
395403
);
396404
}, areEqual);

src/packages/frontend/jupyter/main.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ export const JupyterEditor: React.FC<Props> = React.memo((props: Props) => {
144144
const directory: undefined | string = useRedux([name, "directory"]);
145145
// const version: undefined | any = useRedux([name, "version"]);
146146
const about: undefined | boolean = useRedux([name, "about"]);
147+
const read_only = useRedux([name, "read_only"]);
147148
const backend_kernel_info: undefined | immutable.Map<any, any> = useRedux([
148149
name,
149150
"backend_kernel_info",
@@ -281,6 +282,7 @@ export const JupyterEditor: React.FC<Props> = React.memo((props: Props) => {
281282
return (
282283
<CellList
283284
actions={actions}
285+
read_only={read_only}
284286
cell_list={cell_list}
285287
cell_toolbar={cell_toolbar}
286288
cells={cells}

src/packages/frontend/jupyter/prompt/base.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ export interface InputPromptProps {
2626
id?: string;
2727
style?: CSSProperties;
2828
dragHandle?: JSX.Element;
29+
read_only?: boolean;
2930
}
3031

3132
export const OUTPUT_STYLE: React.CSSProperties = {

src/packages/frontend/jupyter/prompt/input.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export const InputPrompt: React.FC<InputPromptProps> = (props) => {
9292
);
9393
}
9494

95-
if (props.dragHandle != null) {
95+
if (!props.read_only && props.dragHandle != null) {
9696
return (
9797
<div>
9898
<div style={{ float: "left" }}>{props.dragHandle}</div>

0 commit comments

Comments
 (0)