@@ -17,7 +17,7 @@ import {
1717import { BrandedToolbar , HelpButton } from "../page" ;
1818import { TheoryLibraryContext } from "../stdlib" ;
1919import type { ModelTypeMeta } from "../theory" ;
20- import { PermissionsButton } from "../user" ;
20+ import { MaybePermissionsButton } from "../user" ;
2121import { LiveModelContext } from "./context" ;
2222import { type LiveModelDocument , type ModelDocument , enlivenModelDocument } from "./document" ;
2323import { MorphismCellEditor } from "./morphism_cell_editor" ;
@@ -51,23 +51,19 @@ export default function ModelPage() {
5151 return enlivenModelDocument ( refId , liveDoc , theories ) ;
5252 } ) ;
5353
54- return (
55- < Show when = { liveModel ( ) } >
56- { ( liveModel ) => < ModelDocumentEditor liveModel = { liveModel ( ) } /> }
57- </ Show >
58- ) ;
54+ return < ModelDocumentEditor liveModel = { liveModel ( ) } /> ;
5955}
6056
6157export function ModelDocumentEditor ( props : {
62- liveModel : LiveModelDocument ;
58+ liveModel ? : LiveModelDocument ;
6359} ) {
6460 const rpc = useContext ( RpcContext ) ;
6561 invariant ( rpc , "Missing context for model document editor" ) ;
6662
6763 const navigate = useNavigate ( ) ;
6864
69- const createDiagram = async ( ) => {
70- const init = newDiagramDocument ( props . liveModel . refId ) ;
65+ const createDiagram = async ( modelRefId : string ) => {
66+ const init = newDiagramDocument ( modelRefId ) ;
7167
7268 const result = await rpc . new_ref . mutate ( {
7369 content : init as JsonValue ,
@@ -81,8 +77,8 @@ export function ModelDocumentEditor(props: {
8177 navigate ( `/diagram/${ newRef } ` ) ;
8278 } ;
8379
84- const createAnalysis = async ( ) => {
85- const init = newAnalysisDocument ( props . liveModel . refId ) ;
80+ const createAnalysis = async ( modelRefId : string ) => {
81+ const init = newAnalysisDocument ( modelRefId ) ;
8682
8783 const result = await rpc . new_ref . mutate ( {
8884 content : init as JsonValue ,
@@ -100,38 +96,47 @@ export function ModelDocumentEditor(props: {
10096 < div class = "growable-container" >
10197 < BrandedToolbar >
10298 < HelpButton />
103- < PermissionsButton permissions = { props . liveModel . liveDoc . permissions } />
104- < Show when = { props . liveModel . theory ( ) ?. instanceTypes . length } >
105- < IconButton onClick = { createDiagram } tooltip = "Create a diagram in this model" >
99+ < MaybePermissionsButton permissions = { props . liveModel ?. liveDoc . permissions } />
100+ < Show when = { props . liveModel ?. theory ( ) ?. supportsInstances } >
101+ < IconButton
102+ onClick = { ( ) => props . liveModel && createDiagram ( props . liveModel . refId ) }
103+ tooltip = "Create a diagram in this model"
104+ >
106105 < Network />
107106 </ IconButton >
108107 </ Show >
109- < IconButton onClick = { createAnalysis } tooltip = "Analyze this model" >
108+ < IconButton
109+ onClick = { ( ) => props . liveModel && createAnalysis ( props . liveModel . refId ) }
110+ tooltip = "Analyze this model"
111+ >
110112 < ChartSpline />
111113 </ IconButton >
112114 </ BrandedToolbar >
113- < ModelPane liveModel = { props . liveModel } />
115+ < Show when = { props . liveModel } >
116+ { ( liveModel ) => < ModelPane liveModel = { liveModel ( ) } /> }
117+ </ Show >
114118 </ div >
115119 ) ;
116120}
117121
122+ /** Pane containing a model notebook plus a header with the title and theory.
123+ */
118124export function ModelPane ( props : {
119125 liveModel : LiveModelDocument ;
120126} ) {
121127 const theories = useContext ( TheoryLibraryContext ) ;
122128 invariant ( theories , "Library of theories should be provided as context" ) ;
123129
124- const liveModel = ( ) => props . liveModel ;
125- const doc = ( ) => props . liveModel . liveDoc . doc ;
126- const changeDoc = ( f : ( doc : ModelDocument ) => void ) => props . liveModel . liveDoc . changeDoc ( f ) ;
130+ const liveDoc = ( ) => props . liveModel . liveDoc ;
131+
127132 return (
128133 < div class = "notebook-container" >
129134 < div class = "model-head" >
130- < div class = "model- title" >
135+ < div class = "title" >
131136 < InlineInput
132- text = { doc ( ) . name }
137+ text = { liveDoc ( ) . doc . name }
133138 setText = { ( text ) => {
134- changeDoc ( ( doc ) => {
139+ liveDoc ( ) . changeDoc ( ( doc ) => {
135140 doc . name = text ;
136141 } ) ;
137142 } }
@@ -141,34 +146,46 @@ export function ModelPane(props: {
141146 < TheorySelectorDialog
142147 theory = { props . liveModel . theory ( ) }
143148 setTheory = { ( id ) => {
144- changeDoc ( ( model ) => {
149+ liveDoc ( ) . changeDoc ( ( model ) => {
145150 model . theory = id ;
146151 } ) ;
147152 } }
148153 theories = { theories }
149- disabled = { doc ( ) . notebook . cells . some ( ( cell ) => cell . tag === "formal" ) }
154+ disabled = { liveDoc ( ) . doc . notebook . cells . some ( ( cell ) => cell . tag === "formal" ) }
150155 />
151156 </ div >
152- < LiveModelContext . Provider value = { props . liveModel } >
153- < NotebookEditor
154- handle = { liveModel ( ) . liveDoc . docHandle }
155- path = { [ "notebook" ] }
156- notebook = { doc ( ) . notebook }
157- changeNotebook = { ( f ) => {
158- changeDoc ( ( doc ) => f ( doc . notebook ) ) ;
159- } }
160- formalCellEditor = { ModelCellEditor }
161- cellConstructors = { modelCellConstructors ( liveModel ( ) . theory ( ) ?. modelTypes ?? [ ] ) }
162- cellLabel = { judgmentLabel }
163- />
164- </ LiveModelContext . Provider >
157+ < ModelNotebookEditor liveModel = { props . liveModel } />
165158 </ div >
166159 ) ;
167160}
168161
169- /** Editor for a cell in a model of a double theory.
162+ /** Notebook editor for a model of a double theory.
163+ */
164+ export function ModelNotebookEditor ( props : {
165+ liveModel : LiveModelDocument ;
166+ } ) {
167+ const liveDoc = ( ) => props . liveModel . liveDoc ;
168+
169+ return (
170+ < LiveModelContext . Provider value = { props . liveModel } >
171+ < NotebookEditor
172+ handle = { liveDoc ( ) . docHandle }
173+ path = { [ "notebook" ] }
174+ notebook = { liveDoc ( ) . doc . notebook }
175+ changeNotebook = { ( f ) => {
176+ liveDoc ( ) . changeDoc ( ( doc ) => f ( doc . notebook ) ) ;
177+ } }
178+ formalCellEditor = { ModelCellEditor }
179+ cellConstructors = { modelCellConstructors ( props . liveModel . theory ( ) ?. modelTypes ?? [ ] ) }
180+ cellLabel = { judgmentLabel }
181+ />
182+ </ LiveModelContext . Provider >
183+ ) ;
184+ }
185+
186+ /** Editor for a notebook cell in a model notebook.
170187 */
171- export function ModelCellEditor ( props : FormalCellEditorProps < ModelJudgment > ) {
188+ function ModelCellEditor ( props : FormalCellEditorProps < ModelJudgment > ) {
172189 return (
173190 < Switch >
174191 < Match when = { props . content . tag === "object" } >
0 commit comments