91 lines
2.8 KiB
Python
91 lines
2.8 KiB
Python
|
import param
|
||
|
import panel as pn
|
||
|
import toml
|
||
|
from .util import get_plans, get_manifest
|
||
|
from .composition import Composition
|
||
|
|
||
|
STAGE_WELCOME = 'Welcome'
|
||
|
STAGE_CONFIG_COMPOSITION = 'Configure'
|
||
|
|
||
|
|
||
|
class Welcome(param.Parameterized):
|
||
|
composition = param.Parameter()
|
||
|
composition_picker = pn.widgets.FileInput(accept='.toml')
|
||
|
plan_picker = param.Selector()
|
||
|
ready = param.Boolean()
|
||
|
|
||
|
def __init__(self, **params):
|
||
|
super().__init__(**params)
|
||
|
self.composition_picker.param.watch(self._composition_updated, 'value')
|
||
|
self.param.watch(self._plan_selected, 'plan_picker')
|
||
|
self.param['plan_picker'].objects = ['Select a Plan'] + get_plans()
|
||
|
|
||
|
def panel(self):
|
||
|
tabs = pn.Tabs(
|
||
|
('New Compostion', self.param['plan_picker']),
|
||
|
('Existing Composition', self.composition_picker),
|
||
|
)
|
||
|
|
||
|
return pn.Column(
|
||
|
"Either choose an existing composition or select a plan to create a new composition:",
|
||
|
tabs,
|
||
|
)
|
||
|
|
||
|
def _composition_updated(self, *args):
|
||
|
print('composition updated')
|
||
|
content = self.composition_picker.value.decode('utf8')
|
||
|
comp_toml = toml.loads(content)
|
||
|
manifest = get_manifest(comp_toml['global']['plan'])
|
||
|
self.composition = Composition.from_dict(comp_toml, manifest=manifest)
|
||
|
print('existing composition: {}'.format(self.composition))
|
||
|
self.ready = True
|
||
|
|
||
|
def _plan_selected(self, evt):
|
||
|
if evt.new == 'Select a Plan':
|
||
|
return
|
||
|
print('plan selected: {}'.format(evt.new))
|
||
|
manifest = get_manifest(evt.new)
|
||
|
self.composition = Composition(manifest=manifest)
|
||
|
print('new composition: ', self.composition)
|
||
|
self.ready = True
|
||
|
|
||
|
|
||
|
class ConfigureComposition(param.Parameterized):
|
||
|
composition = param.Parameter()
|
||
|
|
||
|
@param.depends('composition')
|
||
|
def panel(self):
|
||
|
if self.composition is None:
|
||
|
return pn.Pane("no composition :(")
|
||
|
print('composition: ', self.composition)
|
||
|
return self.composition.panel()
|
||
|
|
||
|
|
||
|
class WorkflowPipeline(object):
|
||
|
def __init__(self):
|
||
|
stages = [
|
||
|
(STAGE_WELCOME, Welcome(), dict(ready_parameter='ready')),
|
||
|
(STAGE_CONFIG_COMPOSITION, ConfigureComposition())
|
||
|
]
|
||
|
|
||
|
self.pipeline = pn.pipeline.Pipeline(debug=True, stages=stages)
|
||
|
|
||
|
def panel(self):
|
||
|
return pn.Column(
|
||
|
pn.Row(
|
||
|
self.pipeline.title,
|
||
|
self.pipeline.network,
|
||
|
self.pipeline.prev_button,
|
||
|
self.pipeline.next_button,
|
||
|
),
|
||
|
self.pipeline.stage,
|
||
|
)
|
||
|
|
||
|
|
||
|
class App(object):
|
||
|
def __init__(self):
|
||
|
self.workflow = WorkflowPipeline()
|
||
|
|
||
|
def ui(self):
|
||
|
return self.workflow.panel().servable("Testground Composer")
|