Skip to content

Commit c8b4109

Browse files
committed
ENH: constructors filter by type and name
1 parent afb459e commit c8b4109

6 files changed

Lines changed: 87 additions & 46 deletions

File tree

packages/frontend/src/analysis/analysis_editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ export function AnalysisNotebookEditor(props: { liveAnalysis: LiveAnalysisDoc })
3737
notebook={liveDoc().doc.notebook}
3838
changeNotebook={(f) => liveDoc().changeDoc((doc) => f(doc.notebook))}
3939
formalCellEditor={AnalysisCellEditor}
40-
cellConstructors={cellConstructors()}
40+
cellConstructors={cellConstructors}
4141
noShortcuts={true}
4242
/>
4343
</LiveAnalysisContext.Provider>

packages/frontend/src/diagram/diagram_editor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export function DiagramNotebookEditor(props: { liveDiagram: LiveDiagramDoc }) {
4141
liveDoc().changeDoc((doc) => f(doc.notebook));
4242
}}
4343
formalCellEditor={DiagramCellEditor}
44-
cellConstructors={cellConstructors()}
44+
cellConstructors={cellConstructors}
4545
cellLabel={judgmentLabel}
4646
duplicateCell={duplicateDiagramJudgment}
4747
/>

packages/frontend/src/model/model_editor.tsx

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,9 @@ import {
2626
export function ModelNotebookEditor(props: { liveModel: LiveModelDoc }) {
2727
const liveDoc = () => props.liveModel.liveDoc;
2828

29-
const cellConstructors = () => {
30-
// const cells = liveDoc().doc.notebook.cellOrder;
31-
// console.log(cells);
32-
29+
const cellConstructors = (cellType?: string, cellName?: string) => {
3330
const theory = props.liveModel.theory();
34-
return theory ? modelCellConstructors(theory) : [];
31+
return theory ? modelCellConstructors(theory, cellType, cellName) : [];
3532
};
3633

3734
return (
@@ -44,7 +41,7 @@ export function ModelNotebookEditor(props: { liveModel: LiveModelDoc }) {
4441
liveDoc().changeDoc((doc) => f(doc.notebook));
4542
}}
4643
formalCellEditor={ModelCellEditor}
47-
cellConstructors={cellConstructors()}
44+
cellConstructors={cellConstructors}
4845
cellLabel={judgmentLabel}
4946
duplicateCell={duplicateModelJudgment}
5047
/>
@@ -57,7 +54,6 @@ export function ModelCellEditor(props: FormalCellEditorProps<ModelJudgment>) {
5754
const liveModel = useContext(LiveModelContext);
5855
invariant(liveModel, "Live model should be provided as context");
5956

60-
console.log(props);
6157
return (
6258
<Switch>
6359
<Match when={props.content.tag === "object" && liveModel().theory()}>
@@ -98,9 +94,13 @@ export function ModelCellEditor(props: FormalCellEditorProps<ModelJudgment>) {
9894
);
9995
}
10096

101-
function modelCellConstructors(theory: Theory): CellConstructor<ModelJudgment>[] {
97+
function modelCellConstructors(
98+
theory: Theory,
99+
cellType?: string,
100+
cellName?: string,
101+
): CellConstructor<ModelJudgment>[] {
102102
const constructors: CellConstructor<ModelJudgment>[] = [];
103-
if (theory.theory.canInstantiateModels()) {
103+
if (theory.theory.canInstantiateModels() && !cellType && !cellName) {
104104
constructors.push({
105105
name: "Instantiate",
106106
description: "Instantiate an existing model into this one",
@@ -112,7 +112,13 @@ function modelCellConstructors(theory: Theory): CellConstructor<ModelJudgment>[]
112112
}
113113

114114
for (const meta of theory.modelTypes ?? []) {
115-
constructors.push(modelCellConstructor(meta));
115+
if (cellName && cellType) {
116+
if (meta.name !== cellName && meta.tag === cellType) {
117+
constructors.push(modelCellConstructor(meta));
118+
}
119+
} else {
120+
constructors.push(modelCellConstructor(meta));
121+
}
116122
}
117123
return constructors;
118124
}

packages/frontend/src/notebook/notebook_cell.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,10 @@
5050
/* border-radius: 50%; */
5151
top: -2px;
5252
}
53+
54+
button.plain {
55+
background: transparent;
56+
border: none;
57+
color: darkgray;
58+
font-size: 11pt;
59+
}

packages/frontend/src/notebook/notebook_editor.tsx

Lines changed: 57 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
keyEventHasModifier,
2323
type ModifierKey,
2424
} from "catcolab-ui-components";
25-
import type { Cell, Notebook, MorType, ObType } from "catlog-wasm";
25+
import type { Cell, MorType, Notebook, ObType } from "catlog-wasm";
2626
import {
2727
type CellActions,
2828
type FormalCellEditorProps,
@@ -72,7 +72,7 @@ export function NotebookEditor<T>(props: {
7272
changeNotebook: (f: (nb: Notebook<T>) => void) => void;
7373

7474
formalCellEditor: Component<FormalCellEditorProps<T>>;
75-
cellConstructors?: CellConstructor<T>[];
75+
cellConstructors: (cellType?: string, cellName?: string) => CellConstructor<T>[];
7676
cellLabel?: (content: T) => string | undefined;
7777

7878
/** Called to duplicate an existing cell.
@@ -143,16 +143,28 @@ export function NotebookEditor<T>(props: {
143143
return cell.tag === "formal";
144144
};
145145

146-
const isObType = (content: any): content is { tag: "object"; obType: ObType } => {
147-
return content && content.tag === "object";
146+
const isObType = (content: unknown): content is { tag: "object"; obType: ObType } => {
147+
return (
148+
typeof content === "object" &&
149+
content !== null &&
150+
"tag" in content &&
151+
content.tag === "object"
152+
);
148153
};
149154

150-
const isMorType = (content: any): content is { tag: "morphism"; morType: MorType } => {
151-
return content && content.tag === "morphism";
155+
const isMorType = (content: unknown): content is { tag: "morphism"; morType: MorType } => {
156+
return (
157+
typeof content === "object" &&
158+
content !== null &&
159+
"tag" in content &&
160+
content.tag === "morphism"
161+
);
152162
};
153163

154164
const retypeCellAs = (i: number, newCell: Cell<T>) => {
155-
if (!newCell || !isFormalCell(newCell)) return;
165+
if (!newCell || !isFormalCell(newCell)) {
166+
return;
167+
}
156168
const mutator = (cellContent: T) => {
157169
if (isObType(cellContent) && isObType(newCell.content)) {
158170
cellContent.obType = newCell.content.obType;
@@ -161,19 +173,22 @@ export function NotebookEditor<T>(props: {
161173
}
162174
};
163175
props.changeNotebook((nb) => {
164-
NotebookUtils.retypeCell(nb, i, mutator);
176+
NotebookUtils.retypeCell(nb, i, mutator);
165177
});
166-
setActiveCell(i);
167178
};
168179

169-
const cellConstructors = (): CellConstructor<T>[] => [
170-
{
171-
name: "Text",
172-
description: "Start writing text",
173-
shortcut: ["T"],
174-
construct: () => newRichTextCell(),
175-
},
176-
...(props.cellConstructors ?? []),
180+
const cellConstructors = (cellType?: string, cellName?: string): CellConstructor<T>[] => [
181+
...(cellType && cellName
182+
? []
183+
: [
184+
{
185+
name: "Text",
186+
description: "Start writing text",
187+
shortcut: ["T"],
188+
construct: () => newRichTextCell(),
189+
},
190+
]),
191+
...(props.cellConstructors(cellType, cellName) ?? []),
177192
];
178193

179194
const replaceCommands = (i: number): Completion[] =>
@@ -187,8 +202,8 @@ export function NotebookEditor<T>(props: {
187202
};
188203
});
189204

190-
const retypeCommands = (i: number): Completion[] =>
191-
cellConstructors().map((cc) => {
205+
const retypeCommands = (i: number, cellType?: string, cellName?: string): Completion[] =>
206+
cellConstructors(cellType, cellName).map((cc) => {
192207
const { name, description, shortcut } = cc;
193208
return {
194209
name,
@@ -327,18 +342,25 @@ export function NotebookEditor<T>(props: {
327342
const cell = props.notebook.cellContents[cellId];
328343
invariant(cell, `Failed to find contents for cell '${cellId}'`);
329344

330-
// const tag = (cell.tag === "formal" ? props.cellLabel?.(cell.content) : undefined) as string;
331-
const cellName = (cell: Cell<T>) =>
345+
const cellName = (cell: Cell<T>) =>
332346
(cell.tag === "formal"
333347
? props.cellLabel?.(cell.content)
334348
: undefined) as string;
335-
// const cellType = isFormalCell(cell)
336-
// ? isObType(cell.content)
337-
// ? "ObType"
338-
// : isMorType(cell.content)
339-
// ? "MorType"
340-
// : ""
341-
// : "";
349+
350+
const cellType = (cell: Cell<T>) =>
351+
cell.tag === "formal"
352+
? isObType(cell.content)
353+
? "ObType"
354+
: "MorType"
355+
: undefined;
356+
357+
// if (isObType(cellContent) && isObType(newCell.content)) {
358+
// cellContent.obType = newCell.content.obType;
359+
// } else if (isMorType(cellContent) && isMorType(newCell.content)) {
360+
// cellContent.morType = newCell.content.morType;
361+
// }
362+
363+
// const cellType = "ObType";
342364

343365
if (cell.tag !== "rich-text") {
344366
cellActions.duplicate = () => {
@@ -360,13 +382,15 @@ export function NotebookEditor<T>(props: {
360382
cellId={cell.id}
361383
index={i()}
362384
actions={cellActions}
363-
tag={
364-
cellName(cell)
365-
}
385+
tag={cellName(cell)}
366386
currentDropTarget={currentDropTarget()}
367387
setCurrentDropTarget={setCurrentDropTarget}
368-
isActive={isActive()}
369-
replaceCommands={retypeCommands(i())}
388+
isActive={isActive()}
389+
replaceCommands={retypeCommands(
390+
i(),
391+
cellType(cell),
392+
cellName(cell),
393+
)}
370394
>
371395
<Switch>
372396
<Match when={cell.tag === "rich-text"}>

packages/frontend/src/notebook/types.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,11 @@ export namespace NotebookUtils {
131131
return notebook.cellOrder.some((cellId) => notebook.cellContents[cellId]?.tag === "formal");
132132
}
133133

134-
export function retypeCell<T>(notebook: Notebook<T>, index: number, mutator: (cellContent: T) => void) {
134+
export function retypeCell<T>(
135+
notebook: Notebook<T>,
136+
index: number,
137+
mutator: (cellContent: T) => void,
138+
) {
135139
const cellId = getCellIdByIndex(notebook, index);
136140
cellId && mutateCellContentById(notebook, cellId, mutator);
137141
}

0 commit comments

Comments
 (0)