def serviceDisplay(serviceObject, instance=None, objType=None, queryArgs=None): cells.ensureSubscribedSchema(schema) cells.ensureSubscribedSchema(ContentSchema.schema) cells.ensureSubscribedSchema(EvaluationSchema.schema) ss = cells.sessionState() assert ss ss.setdefault('showNavTree', True) ss.setdefault('showEditor', True) ss.setdefault('showEvaluation', True) return ( cells.CollapsiblePanel( ResearchFrontend.navDisplay().background_color("#FAFAFA").height("100%"), cells.SubscribedSequence( lambda: [x for x in ["showEditor", "showEvaluation"] if cells.sessionState().get(x)], lambda which: ResearchFrontend.editorDisplay() if which == "showEditor" else ResearchFrontend.evaluationDisplay() if which == "showEvaluation" else None , asColumns=True ).height("100%"), lambda: cells.sessionState().showNavTree ).height("100%") .withContext() + cells.Subscribed(lambda: cells.Text("Modal") + cells.sessionState().modalOverlay if cells.sessionState().modalOverlay else None) )
def renamer(): cells.sessionState().modalOverlay = ModalEditBox( f"Rename module '{module.project.name}.{module.name}'", module.name, onOK=lambda newName: ( setattr(module, 'name', newName), setattr(cells.sessionState(), "modalOverlay", None) ), onCancel=lambda: setattr(cells.sessionState(), 'modalOverlay', None) ).tagged("RFE_RenameModuleModal")
def renamer(): cells.sessionState().modalOverlay = ModalEditBox( f"Rename project '{project.name}'", project.name, onOK=lambda newName: ( setattr(project, 'name', newName), setattr(cells.sessionState(), "modalOverlay", None) ), onCancel=lambda: setattr(cells.sessionState(), 'modalOverlay', None) ).tagged("RFE_RenameProjectModal")
def deleter(): def reallyDelete(): project.deleteSelf() setattr(cells.sessionState(), "modalOverlay", None) cells.sessionState().modalOverlay = cells.Modal( f"Really delete project '{project.name}'?", "Because you can't undo this yet.", Cancel=lambda: setattr(cells.sessionState(), "modalOverlay", None), OK=reallyDelete ).tagged("RFE_DeleteProjectModal")
def serviceHeaderToggles(serviceObject, instance=None): ss = cells.sessionState() ss.setdefault('showNavTree', True) ss.setdefault('showEditor', True) ss.setdefault('showEvaluation', True) return [ cells.Subscribed(lambda: cells.ButtonGroup([ cells.Button( cells.Octicon("list-unordered"), lambda: ss.toggle('showNavTree'), active=ss.showNavTree), cells.Button( cells.Octicon("terminal"), lambda: ss.toggle('showEditor'), active=ss.showEditor), cells.Button( cells.Octicon("graph"), lambda: ss.toggle('showEvaluation'), active=ss.showEvaluation) ]) ) ]
def evaluationDisplay(): evaluation = EvaluationSchema.EvaluationContext.lookupOrCreate() # force us to redraw if anything changes in terms of the horizontal width # because right now the plotly charts aren't smart enough to do this. cells.sessionState().showNavTree cells.sessionState().showEditor cells.sessionState().showEvaluation if not evaluation: return None return cells.Subscribed( lambda: cells.Card("Waiting for backend...") if evaluation.state == "Dirty" else cells.Card("Backend computing...") if evaluation.state == "Calculating" else cells.Traceback(evaluation.error) if evaluation.error is not None else cells.Tabs( Displays=cells.Card( cells.Subscribed( lambda: ResearchFrontend.displaysDisplay(evaluation).tagged("RFE_Displays") ) ), Variables=cells.Card( cells.Subscribed( lambda: DisplayForVariables.variablesDisplay(evaluation).tagged("RFE_Variables") ) ) ).tagged("DisplayTabCell") ).overflow("auto").width("100%")
def editorDisplay(): module = cells.sessionState().selected_module if module is None or not module.exists(): return cells.Card("Please select a module") def onEnter(buffer, selection): module.update(buffer) module.mark() evaluation = EvaluationSchema.EvaluationContext.lookupOrCreate() evaluation.request(module, None) def onExecuteSelected(buffer, selection): module.update(buffer) evaluation = EvaluationSchema.EvaluationContext.lookupOrCreate() if isinstance(selection,dict): selection = CodeSelection.fromAceEditorJson(selection) selectedText = selection.slice(buffer) else: selectedText = None evaluation.request(module, selectedText) def onTextChange(buffer, selection): module.update(buffer) ed = cells.CodeEditor( keybindings={'Enter': onEnter, 'Space': onExecuteSelected}, fontSize=14, minLines=50, onTextChange=onTextChange ).height('calc(100vh - 110px)') def onCodeChange(): """Executing this code in a 'subscribed' forces us to check whether the editor is out of sync with the current buffer. If so, we set the buffer. Any time the buffer changes because a user changes it, we should be forcing 'current_buffer' to reflect that change immediately. Otherwise this code will execute and force it to be the same again. """ if ed.getContents() != module.current_buffer: ed.setContents(module.current_buffer) return ed.width(1200) + cells.Subscribed(onCodeChange)
def createNewModule(project, base_name = None): all_names = [w.name for w in Module.lookupAll(project=project)] now_stamp = time.time() if base_name is None: base_name = "module" name = base_name count = 1 while name in all_names: name = base_name+"_%s"%count count += 1 newModule = Module( name=name, created_timestamp=now_stamp, project=project, last_modified_timestamp=now_stamp ) cells.sessionState().selected_module = newModule
def isSelected(): if cells.sessionState().selected_module is not None and cells.sessionState().selected_module.exists(): return cells.sessionState().selected_module == module return False
def reallyDelete(): module.deleteSelf() setattr(cells.sessionState(), "modalOverlay", None)
def selectModule(): cells.sessionState().selected_module = module
def onProjectSelectChanged(): if (cells.sessionState().selected_module and cells.sessionState().selected_module.exists() and cells.sessionState().selected_module.project == project and not expander.isExpanded): expander.isExpanded = True expander.markDirty()