nova-trame 0.19.0.dev5__py3-none-any.whl → 0.19.0.dev7__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,7 +8,7 @@ from trame.widgets import vuetify3 as vuetify
8
8
 
9
9
  from nova.mvvm.trame_binding import TrameBinding
10
10
  from nova.trame.model.data_selector import DataSelectorModel
11
- from nova.trame.view.layouts import GridLayout
11
+ from nova.trame.view.layouts import GridLayout, VBoxLayout
12
12
  from nova.trame.view_model.data_selector import DataSelectorViewModel
13
13
 
14
14
  from .input_field import InputField
@@ -78,7 +78,7 @@ class DataSelector(vuetify.VDataTable):
78
78
  self.create_ui(facility, instrument, **kwargs)
79
79
 
80
80
  def create_ui(self, facility: str, instrument: str, **kwargs: Any) -> None:
81
- with html.Div(classes="nova-data-selector"):
81
+ with VBoxLayout(classes="nova-data-selector", height="100%"):
82
82
  with GridLayout(columns=3):
83
83
  columns = 3
84
84
  if facility == "":
@@ -98,24 +98,24 @@ class DataSelector(vuetify.VDataTable):
98
98
  type="autocomplete",
99
99
  )
100
100
 
101
- with GridLayout(columns=2, valign="start"):
101
+ with GridLayout(columns=2, classes="flex-1-0", valign="start"):
102
102
  if not self._prefix:
103
- with html.Div():
104
- vuetify.VListSubheader("Available Directories", classes="justify-center px-0")
103
+ with html.Div(classes="d-flex flex-column h-100 overflow-hidden"):
104
+ vuetify.VListSubheader("Available Directories", classes="flex-0-1 justify-center px-0")
105
105
  vuetify.VTreeview(
106
106
  v_if=(f"{self._directories_name}.length > 0",),
107
107
  activatable=True,
108
108
  active_strategy="single-independent",
109
- classes="overflow-y-auto",
109
+ classes="flex-1-0 h-0 overflow-y-auto",
110
110
  item_value="path",
111
111
  items=(self._directories_name,),
112
- style="max-height: 500px",
113
112
  update_activated=(self._vm.set_directory, "$event"),
114
113
  )
115
- vuetify.VListItem("No directories found", classes="text-center", v_else=True)
114
+ vuetify.VListItem("No directories found", classes="flex-0-1 text-center", v_else=True)
116
115
 
117
116
  super().__init__(
118
117
  v_model=self._v_model,
118
+ classes="overflow-y-auto",
119
119
  headers=("[{ align: 'left', key: 'title', title: 'Available Datafiles' }]",),
120
120
  item_title="title",
121
121
  item_value="path",
@@ -123,6 +123,8 @@ class DataSelector(vuetify.VDataTable):
123
123
  show_select=True,
124
124
  **kwargs,
125
125
  )
126
+ if self._label:
127
+ self.label = self._label
126
128
  self.items = (self._datafiles_name,)
127
129
  if "update_modelValue" not in kwargs:
128
130
  self.update_modelValue = f"flushState('{self._v_model.split('.')[0]}')"
@@ -130,11 +132,9 @@ class DataSelector(vuetify.VDataTable):
130
132
  with cast(
131
133
  vuetify.VSelect,
132
134
  InputField(
133
- v_show=f"{self._v_model}.length > 0",
134
135
  v_model=self._v_model,
135
- classes="nova-readonly",
136
+ classes="flex-0-1 nova-readonly",
136
137
  clearable=True,
137
- label=self._label,
138
138
  readonly=True,
139
139
  type="select",
140
140
  click_clear=f"{self._v_model} = []; flushState('{self._v_model.split('.')[0]}');",
@@ -48,7 +48,9 @@ class FileUpload(vuetify.VBtn):
48
48
  ref=self._ref_name,
49
49
  # Serialize the content in a way that will work with nova-mvvm and then push it to the server.
50
50
  update_modelValue=(
51
- f"{self._v_model}.arrayBuffer().then((contents) => {{ trigger('decode_blob', [contents]); }});"
51
+ f"{self._v_model}.arrayBuffer().then((contents) => {{"
52
+ f"trigger('decode_blob_{self._id}', [contents]); "
53
+ "});"
52
54
  ),
53
55
  )
54
56
  self.remote_file_input = RemoteFileInput(
@@ -61,7 +63,7 @@ class FileUpload(vuetify.VBtn):
61
63
  vuetify.VListItem("From Local Machine", click=f"trame.refs.{self._ref_name}.click()")
62
64
  vuetify.VListItem("From Analysis Cluster", click=self.remote_file_input.open_dialog)
63
65
 
64
- @self.server.controller.trigger("decode_blob")
66
+ @self.server.controller.trigger(f"decode_blob_{self._id}")
65
67
  def _decode_blob(contents: bytes) -> None:
66
68
  self.remote_file_input.decode_file(contents)
67
69
 
@@ -4,6 +4,7 @@ import logging
4
4
  import os
5
5
  import re
6
6
  from enum import Enum
7
+ from inspect import isclass
7
8
  from typing import Any, Dict, Optional, Union
8
9
 
9
10
  from trame.app import get_server
@@ -70,7 +71,11 @@ class InputField:
70
71
  "rules": (f"[(v) => trigger('validate_pydantic_field', ['{field}', v, index])]",),
71
72
  }
72
73
 
73
- if field_type in ["autocomplete", "combobox", "select"] and issubclass(field_info.annotation, Enum):
74
+ if (
75
+ field_type in ["autocomplete", "combobox", "select"]
76
+ and isclass(field_info.annotation)
77
+ and issubclass(field_info.annotation, Enum)
78
+ ):
74
79
  args |= {"items": str([option.value for option in field_info.annotation])}
75
80
 
76
81
  if debounce > 0 and throttle > 0:
@@ -275,7 +275,7 @@ class MatplotlibFigure(matplotlib.Figure):
275
275
  ready_%(port)d(
276
276
  function() {
277
277
  var websocket_type = mpl.get_websocket_type();
278
- var websocket = new websocket_type(`ws://${window.location.host}/mpl/%(port)d`);
278
+ var websocket = new websocket_type('mpl/%(port)d');
279
279
 
280
280
  var fig = new mpl.figure(
281
281
  // A unique numeric identifier for the figure
@@ -16,6 +16,7 @@ class GridLayout(html.Div):
16
16
  width: Optional[Union[int, str]] = None,
17
17
  halign: Optional[str] = None,
18
18
  valign: Optional[str] = None,
19
+ gap: Optional[Union[int, str]] = "0em",
19
20
  **kwargs: Any,
20
21
  ) -> None:
21
22
  """Constructor for GridLayout.
@@ -64,7 +65,7 @@ class GridLayout(html.Div):
64
65
  classes = " ".join(classes)
65
66
  classes += " d-grid"
66
67
 
67
- style = self.get_root_styles(columns, height, width, halign, valign) | kwargs.pop("style", {})
68
+ style = self.get_root_styles(columns, height, width, halign, valign, gap) | kwargs.pop("style", {})
68
69
 
69
70
  super().__init__(classes=classes, style=style, **kwargs)
70
71
 
@@ -75,9 +76,11 @@ class GridLayout(html.Div):
75
76
  width: Optional[Union[int, str]],
76
77
  halign: Optional[str],
77
78
  valign: Optional[str],
79
+ gap: Optional[Union[int, str]],
78
80
  ) -> dict[str, str]:
79
81
  height = f"{height}px" if isinstance(height, int) else height
80
82
  width = f"{width}px" if isinstance(width, int) else width
83
+ gap = f"{gap}px" if isinstance(gap, int) else gap
81
84
 
82
85
  styles = {
83
86
  "grid-template-columns": f"repeat({columns}, 1fr)",
@@ -91,6 +94,8 @@ class GridLayout(html.Div):
91
94
  styles["justify-items"] = halign
92
95
  if valign:
93
96
  styles["align-items"] = valign
97
+ if gap:
98
+ styles["gap"] = gap
94
99
 
95
100
  return styles
96
101
 
@@ -14,6 +14,8 @@ class HBoxLayout(html.Div):
14
14
  width: Optional[Union[int, str]] = None,
15
15
  halign: Optional[str] = None,
16
16
  valign: Optional[str] = None,
17
+ gap: Optional[Union[int, str]] = "0em",
18
+ vspace: Optional[Union[int, str]] = "0em",
17
19
  **kwargs: Any,
18
20
  ) -> None:
19
21
  """Constructor for HBoxLayout.
@@ -51,7 +53,7 @@ class HBoxLayout(html.Div):
51
53
  classes = " ".join(classes)
52
54
  classes += " d-flex flex-row"
53
55
 
54
- style = self.get_root_styles(height, width, halign, valign) | kwargs.pop("style", {})
56
+ style = self.get_root_styles(height, width, halign, valign, gap, vspace) | kwargs.pop("style", {})
55
57
 
56
58
  super().__init__(classes=classes, style=style, **kwargs)
57
59
 
@@ -61,9 +63,13 @@ class HBoxLayout(html.Div):
61
63
  width: Optional[Union[int, str]],
62
64
  halign: Optional[str],
63
65
  valign: Optional[str],
66
+ gap: Optional[Union[int, str]],
67
+ vspace: Optional[Union[int, str]],
64
68
  ) -> dict:
65
69
  height = f"{height}px" if isinstance(height, int) else height
66
70
  width = f"{width}px" if isinstance(width, int) else width
71
+ gap = f"{gap}px" if isinstance(gap, int) else gap
72
+ vspace = f"{vspace}px" if isinstance(vspace, int) else vspace
67
73
 
68
74
  styles = {}
69
75
 
@@ -75,5 +81,9 @@ class HBoxLayout(html.Div):
75
81
  styles["justify-content"] = halign
76
82
  if valign:
77
83
  styles["align-items"] = valign
84
+ if gap:
85
+ styles["gap"] = gap
86
+ if vspace:
87
+ styles["margin-bottom"] = vspace
78
88
 
79
89
  return styles
@@ -14,6 +14,8 @@ class VBoxLayout(html.Div):
14
14
  width: Optional[Union[int, str]] = None,
15
15
  halign: Optional[str] = None,
16
16
  valign: Optional[str] = None,
17
+ gap: Optional[Union[int, str]] = "0em",
18
+ vspace: Optional[Union[int, str]] = "0em",
17
19
  **kwargs: Any,
18
20
  ) -> None:
19
21
  """Constructor for VBoxLayout.
@@ -51,7 +53,7 @@ class VBoxLayout(html.Div):
51
53
  classes = " ".join(classes)
52
54
  classes += " d-flex flex-column"
53
55
 
54
- style = self.get_root_styles(height, width, halign, valign) | kwargs.pop("style", {})
56
+ style = self.get_root_styles(height, width, halign, valign, gap, vspace) | kwargs.pop("style", {})
55
57
 
56
58
  super().__init__(classes=classes, style=style, **kwargs)
57
59
 
@@ -61,9 +63,13 @@ class VBoxLayout(html.Div):
61
63
  width: Optional[Union[int, str]],
62
64
  halign: Optional[str],
63
65
  valign: Optional[str],
66
+ gap: Optional[Union[int, str]],
67
+ vspace: Optional[Union[int, str]],
64
68
  ) -> dict:
65
69
  height = f"{height}px" if isinstance(height, int) else height
66
70
  width = f"{width}px" if isinstance(width, int) else width
71
+ gap = f"{gap}px" if isinstance(gap, int) else gap
72
+ vspace = f"{vspace}px" if isinstance(vspace, int) else vspace
67
73
 
68
74
  styles = {}
69
75
 
@@ -75,5 +81,9 @@ class VBoxLayout(html.Div):
75
81
  styles["align-items"] = halign
76
82
  if valign:
77
83
  styles["justify-content"] = valign
84
+ if gap:
85
+ styles["gap"] = gap
86
+ if vspace:
87
+ styles["margin-bottom"] = vspace
78
88
 
79
89
  return styles
@@ -12,6 +12,16 @@ html {
12
12
  box-shadow: none !important;
13
13
  }
14
14
 
15
+ .v-tab.v-btn {
16
+ height: 30px !important;
17
+ min-width: fit-content !important;
18
+ padding: 10px !important;
19
+ }
20
+
21
+ .v-checkbox .v-selection-control {
22
+ min-height: 0px !important;
23
+ }
24
+
15
25
  .mpl-message, .ui-dialog-titlebar {
16
26
  display: none !important;
17
27
  }
@@ -26,6 +36,11 @@ html {
26
36
  }
27
37
  }
28
38
 
39
+ .v-window {
40
+ overflow-x: visible !important;
41
+ overflow-y: visible !important;
42
+ }
43
+
29
44
  @media only screen and (max-width: 959px) {
30
45
  .d-grid {
31
46
  grid-template-columns: repeat(1, 1fr) !important;
@@ -49,6 +64,10 @@ html {
49
64
  }
50
65
 
51
66
  .nova-data-selector {
67
+ .v-list-item {
68
+ padding-left: 0;
69
+ }
70
+
52
71
  .v-data-table__td {
53
72
  max-width: 100px;
54
73
  overflow: hidden;
@@ -99,7 +118,6 @@ html {
99
118
  text-transform: none;
100
119
  }
101
120
 
102
-
103
121
  .v-label {
104
122
  font-size: 0.75rem;
105
123
  }
@@ -56,7 +56,8 @@
56
56
  },
57
57
  "VFileInput": {
58
58
  "color": "primary",
59
- "prependIcon": false
59
+ "prependIcon": false,
60
+ "variant": "outlined"
60
61
  },
61
62
  "VLabel": {
62
63
  "style": {
@@ -91,7 +92,8 @@
91
92
  "color": "primary"
92
93
  },
93
94
  "VSelect": {
94
- "color": "primary"
95
+ "color": "primary",
96
+ "variant": "outlined"
95
97
  },
96
98
  "VSlider": {
97
99
  "color": "primary"
@@ -106,10 +108,12 @@
106
108
  "color": "primary"
107
109
  },
108
110
  "VTextarea": {
109
- "color": "primary"
111
+ "color": "primary",
112
+ "variant": "outlined"
110
113
  },
111
114
  "VTextField": {
112
- "color": "primary"
115
+ "color": "primary",
116
+ "variant": "outlined"
113
117
  },
114
118
  "VWindowItem": {
115
119
  "reverseTransition": "fade-transition",
@@ -178,8 +182,7 @@
178
182
  },
179
183
  "VTextField": {
180
184
  "VBtn": {
181
- "size": "default",
182
- "variant": "outlined"
185
+ "size": "default"
183
186
  },
184
187
  "variant": "outlined"
185
188
  },
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: nova-trame
3
- Version: 0.19.0.dev5
3
+ Version: 0.19.0.dev7
4
4
  Summary: A Python Package for injecting curated themes and custom components into Trame applications
5
5
  License: MIT
6
6
  Keywords: NDIP,Python,Trame,Vuetify
@@ -3,30 +3,30 @@ nova/trame/__init__.py,sha256=gFrAg1qva5PIqR5TjvPzAxLx103IKipJLqp3XXvrQL8,59
3
3
  nova/trame/model/data_selector.py,sha256=6tH5E7PmPMc6Cc7utFqe7MUpKsUP15_2jU0plygeqn0,7168
4
4
  nova/trame/model/remote_file_input.py,sha256=9KAf31ZHzpsh_aXUrNcF81Q5jvUZDWCzW1QATKls-Jk,3675
5
5
  nova/trame/view/components/__init__.py,sha256=u8yzshFp_TmuC1g9TRxKjy_BdGWMIzPQouI52hzcr2U,234
6
- nova/trame/view/components/data_selector.py,sha256=VbZtgSgb6jRXJmj31uYqVdMjpcHyioDW_1RD3yLGMDw,8159
7
- nova/trame/view/components/file_upload.py,sha256=_P-FJM2hHm7x0IcrPJhUQa1L43g7_P78Z3oJO2LqLck,3051
8
- nova/trame/view/components/input_field.py,sha256=ncVVSzdJwH_-KP24I2rCqcb6v3J2hPhNTXr8Lb1EZ_U,15931
6
+ nova/trame/view/components/data_selector.py,sha256=3-tlSFzCigMEZs-TwTZ_Ejx3Q69gxVeOJXIADuBkHN0,8270
7
+ nova/trame/view/components/file_upload.py,sha256=7VcpfA6zmiqMDLkwVPlb35Tf0IUTBN1xsHpoUFnSr1w,3111
8
+ nova/trame/view/components/input_field.py,sha256=Wf-WuYm9SmbHXYy1cvYy8zDWe5rhvLcUHmwqmBvqVxk,16074
9
9
  nova/trame/view/components/remote_file_input.py,sha256=MnsUttZaCy8vEpOmRqXMsWa6PiC-RTRb-hJnnH0rBZc,9644
10
10
  nova/trame/view/components/visualization/__init__.py,sha256=reqkkbhD5uSksHHlhVMy1qNUCwSekS5HlXk6wCREYxU,152
11
11
  nova/trame/view/components/visualization/interactive_2d_plot.py,sha256=foZCMoqbuahT5dtqIQvm8C4ZJcY9P211eJEcpQJltmM,3421
12
- nova/trame/view/components/visualization/matplotlib_figure.py,sha256=yop7Kd_MylUiCwEial2jOYESbvchrYhrpSmRowUhePY,12003
12
+ nova/trame/view/components/visualization/matplotlib_figure.py,sha256=xxgEAE2boc-sIFEIsbJxQZQ5biBMBXT0U8Il5299VNc,11974
13
13
  nova/trame/view/layouts/__init__.py,sha256=cMrlB5YMUoK8EGB83b34UU0kPTVrH8AxsYvKRtpUNEc,141
14
- nova/trame/view/layouts/grid.py,sha256=k-QHuH31XeAVDuMKUMoAMVnAM-Yavq7kdLYOC1ZrGTQ,5021
15
- nova/trame/view/layouts/hbox.py,sha256=r5irhFX6YWTWN4V4NwNQx6mheyM8p6PVcJbrbhvOAwo,2625
16
- nova/trame/view/layouts/vbox.py,sha256=Q4EvrtGJORyNF6AnCLGXToy8XU6yofiO5_kt7hK-AYs,2626
14
+ nova/trame/view/layouts/grid.py,sha256=CPutDeiJnLsKiG2mBtIDAnHJX-NJE92vhFiFyraV0R8,5220
15
+ nova/trame/view/layouts/hbox.py,sha256=NE11FV0W7QKfqIdz4MUOTIWsgCr8jrJDtUCcgw1K0HM,3060
16
+ nova/trame/view/layouts/vbox.py,sha256=HkWpU6LiqdZMwl9KRosvxX_4lAxgjiRS5q9acIBUyfE,3061
17
17
  nova/trame/view/theme/__init__.py,sha256=70_marDlTigIcPEOGiJb2JTs-8b2sGM5SlY7XBPtBDM,54
18
- nova/trame/view/theme/assets/core_style.scss,sha256=dez2vI7dPfjYQGHJSKiKCCsLTidAQsAcynidNYN4VBk,2547
18
+ nova/trame/view/theme/assets/core_style.scss,sha256=kB33fiic0OcMJedYGQeIN2QssF5q9KQCAdKYIJnRM-4,2882
19
19
  nova/trame/view/theme/assets/favicon.png,sha256=Xbp1nUmhcBDeObjsebEbEAraPDZ_M163M_ZLtm5AbQc,1927
20
20
  nova/trame/view/theme/assets/js/delay_manager.js,sha256=vmb34DZ5YCQIlRW9Tf2M_uvJW6HFCmtlKZ5e_TPR8yg,536
21
21
  nova/trame/view/theme/assets/js/lodash.debounce.min.js,sha256=GLzlQH04WDUNYN7i39ttHHejSdu-CpAvfWgDgKDn-OY,4448
22
22
  nova/trame/view/theme/assets/js/lodash.throttle.min.js,sha256=9csqjX-M-LVGJnF3z4ha1R_36O5AfkFE8rPHkxmt3tE,4677
23
- nova/trame/view/theme/assets/vuetify_config.json,sha256=HuR23Ds1dATt5fFUFMolFoLRjINLzg7AiLgQpQvuabc,5567
23
+ nova/trame/view/theme/assets/vuetify_config.json,sha256=KKS50xguCxl3RtBT7xx_Xk6qyH2RO-ePAG9UBGloIBI,5656
24
24
  nova/trame/view/theme/theme.py,sha256=OFUtq1IWriFcDu-346J67ZrSES8IOI9PTY_4Vwg7bZQ,11820
25
25
  nova/trame/view/utilities/local_storage.py,sha256=vD8f2VZIpxhIKjZwEaD7siiPCTZO4cw9AfhwdawwYLY,3218
26
26
  nova/trame/view_model/data_selector.py,sha256=Bpkfjd78ZIkexHNF_aA9PfizRBzkeOuoSE7ZsBFcSOs,1749
27
27
  nova/trame/view_model/remote_file_input.py,sha256=ojEOJ8ZPkajpbAaZi9VLj7g-uBjhb8BMrTdMmwf_J6A,3367
28
- nova_trame-0.19.0.dev5.dist-info/LICENSE,sha256=Iu5QiDbwNbREg75iYaxIJ_V-zppuv4QFuBhAW-qiAlM,1061
29
- nova_trame-0.19.0.dev5.dist-info/METADATA,sha256=jq6kH6P8wTV1xtLC_6p-WGhunujfdYwijEK_lqutRl0,1451
30
- nova_trame-0.19.0.dev5.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
31
- nova_trame-0.19.0.dev5.dist-info/entry_points.txt,sha256=J2AmeSwiTYZ4ZqHHp9HO6v4MaYQTTBPbNh6WtoqOT58,42
32
- nova_trame-0.19.0.dev5.dist-info/RECORD,,
28
+ nova_trame-0.19.0.dev7.dist-info/LICENSE,sha256=Iu5QiDbwNbREg75iYaxIJ_V-zppuv4QFuBhAW-qiAlM,1061
29
+ nova_trame-0.19.0.dev7.dist-info/METADATA,sha256=CIUfrKoM8j1mwV-zA2dJgkYFpzqy2LPYR8SG8c6oz80,1451
30
+ nova_trame-0.19.0.dev7.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
31
+ nova_trame-0.19.0.dev7.dist-info/entry_points.txt,sha256=J2AmeSwiTYZ4ZqHHp9HO6v4MaYQTTBPbNh6WtoqOT58,42
32
+ nova_trame-0.19.0.dev7.dist-info/RECORD,,