Loading src/nova/trame/view/components/data_selector.py +15 −1 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ class DataSelector(datagrid.VGrid): self._select_strategy = select_strategy self._show_user_directories = show_user_directories self._revogrid_id = f"nova__dataselector_{self._next_id}_rv" self._state_name = f"nova__dataselector_{self._next_id}_state" self._facilities_name = f"nova__dataselector_{self._next_id}_facilities" self._instruments_name = f"nova__dataselector_{self._next_id}_instruments" Loading @@ -87,6 +88,9 @@ class DataSelector(datagrid.VGrid): self._datafiles_name = f"nova__dataselector_{self._next_id}_datafiles" self._flush_state = f"flushState('{self._v_model_name_in_state}');" self._reset_rv_grid = client.JSEval( exec=f"window.rvUpdateCheckboxes('{self._v_model}', '{self._datafiles_name}')" ).exec self._reset_state = client.JSEval(exec=f"{self._v_model} = []; {self._flush_state}").exec self.create_model(facility, instrument) Loading Loading @@ -145,10 +149,13 @@ class DataSelector(datagrid.VGrid): f" datafiles_key: '{self._datafiles_name}'," f" model_key: '{self._v_model}'," " name: 'Available Datafiles'," " prop: 'title'" " prop: 'title'," f" state_key: '{self._v_model_name_in_state}'," "}]", ), frame_size=10, hide_attribution=True, id=self._revogrid_id, readonly=True, stretch=True, source=(self._datafiles_name,), Loading @@ -160,6 +167,12 @@ class DataSelector(datagrid.VGrid): if "update_modelValue" not in kwargs: self.update_modelValue = self._flush_state # Sets up some JavaScript event handlers when the component is mounted. with self: client.ClientTriggers( mounted=f"window.rvOnMount('{self._revogrid_id}', '{self._v_model}', '{self._datafiles_name}');" ) with cast( vuetify.VSelect, InputField( Loading Loading @@ -199,6 +212,7 @@ class DataSelector(datagrid.VGrid): def reset(self, _: Any = None) -> None: self._reset_state() self._reset_rv_grid() def set_state( self, facility: Optional[str] = None, instrument: Optional[str] = None, experiment: Optional[str] = None Loading src/nova/trame/view/theme/assets/js/revo_grid.js +52 −10 Original line number Diff line number Diff line window.rvOnMount = function(id, modelKey, dataKey) { const grid = document.querySelector(`#${id}`) grid.addEventListener('viewportscroll', () => { window.rvUpdateCheckboxes(modelKey, dataKey) }) } window.rvUpdateCheckboxes = function(modelKey, dataKey) { const trameState = window.trame.state.state const modelValue = _.get(trameState, modelKey) const availableData = _.get(trameState, dataKey) const selectAllCheckbox = document.querySelector(".header-content input") const rowCheckboxes = document.querySelectorAll(".rgCell") if (selectAllCheckbox === null) { return } if (modelValue.length === 0) { selectAllCheckbox.checked = false selectAllCheckbox.indeterminate = false } else if (modelValue.length === availableData.length) { selectAllCheckbox.checked = true selectAllCheckbox.indeterminate = false } else { selectAllCheckbox.checked = false selectAllCheckbox.indeterminate = true } rowCheckboxes.forEach((element) => { input = element.querySelector('input') rowIndex = element.dataset.rgrow input.checked = modelValue.includes(availableData[rowIndex].path) }) } window.rvCellTemplate = function(createElement, props) { const inputVNode = createElement('input', { type: 'checkbox', onChange: (e) => { const state = window.trame.state.state const modelKey = props.column.model_key const trameState = window.trame.state.state const modelValue = _.get(trameState, props.column.model_key) const path = props.data[props.rowIndex].path const index = _.get(window.trame.state.state, modelKey).indexOf(path) const index = modelValue.indexOf(path) // We need to assign instead of modifying in place in order for the Trame watcher to pick up changes. if (e.target.checked && index < 0) { _.get(state, modelKey).push(path) _.set(trameState, props.column.model_key, _.concat(modelValue, path)) } else if (index >= 0) { _.get(state, modelKey).splice(index, 1) _.set(trameState, props.column.model_key, modelValue.toSpliced(index, 1)) } window.trame.state.dirty('config') // Update the UI window.rvUpdateCheckboxes(props.column.model_key, props.column.datafiles_key) window.trame.state.dirty(props.column.state_key) }, }) Loading @@ -24,15 +63,18 @@ window.rvColumnTemplate = function (createElement, props) { const inputVNode = createElement('input', { type: 'checkbox', onChange: (e) => { const state = window.trame.state.state const trameState = window.trame.state.state const availableData = _.get(trameState, props.datafiles_key) if (e.target.checked) { _.set(state, 'config.selected_files', _.get(state, props.datafiles_key).map((item) => item.path)) _.set(trameState, 'config.selected_files', availableData.map((item) => item.path)) } else { _.set(state, 'config.selected_files', []) _.set(trameState, 'config.selected_files', []) } window.trame.state.dirty('config') // Update the UI window.rvUpdateCheckboxes(props.model_key, props.datafiles_key) window.trame.state.dirty(props.state_key) }, }) Loading Loading
src/nova/trame/view/components/data_selector.py +15 −1 Original line number Diff line number Diff line Loading @@ -79,6 +79,7 @@ class DataSelector(datagrid.VGrid): self._select_strategy = select_strategy self._show_user_directories = show_user_directories self._revogrid_id = f"nova__dataselector_{self._next_id}_rv" self._state_name = f"nova__dataselector_{self._next_id}_state" self._facilities_name = f"nova__dataselector_{self._next_id}_facilities" self._instruments_name = f"nova__dataselector_{self._next_id}_instruments" Loading @@ -87,6 +88,9 @@ class DataSelector(datagrid.VGrid): self._datafiles_name = f"nova__dataselector_{self._next_id}_datafiles" self._flush_state = f"flushState('{self._v_model_name_in_state}');" self._reset_rv_grid = client.JSEval( exec=f"window.rvUpdateCheckboxes('{self._v_model}', '{self._datafiles_name}')" ).exec self._reset_state = client.JSEval(exec=f"{self._v_model} = []; {self._flush_state}").exec self.create_model(facility, instrument) Loading Loading @@ -145,10 +149,13 @@ class DataSelector(datagrid.VGrid): f" datafiles_key: '{self._datafiles_name}'," f" model_key: '{self._v_model}'," " name: 'Available Datafiles'," " prop: 'title'" " prop: 'title'," f" state_key: '{self._v_model_name_in_state}'," "}]", ), frame_size=10, hide_attribution=True, id=self._revogrid_id, readonly=True, stretch=True, source=(self._datafiles_name,), Loading @@ -160,6 +167,12 @@ class DataSelector(datagrid.VGrid): if "update_modelValue" not in kwargs: self.update_modelValue = self._flush_state # Sets up some JavaScript event handlers when the component is mounted. with self: client.ClientTriggers( mounted=f"window.rvOnMount('{self._revogrid_id}', '{self._v_model}', '{self._datafiles_name}');" ) with cast( vuetify.VSelect, InputField( Loading Loading @@ -199,6 +212,7 @@ class DataSelector(datagrid.VGrid): def reset(self, _: Any = None) -> None: self._reset_state() self._reset_rv_grid() def set_state( self, facility: Optional[str] = None, instrument: Optional[str] = None, experiment: Optional[str] = None Loading
src/nova/trame/view/theme/assets/js/revo_grid.js +52 −10 Original line number Diff line number Diff line window.rvOnMount = function(id, modelKey, dataKey) { const grid = document.querySelector(`#${id}`) grid.addEventListener('viewportscroll', () => { window.rvUpdateCheckboxes(modelKey, dataKey) }) } window.rvUpdateCheckboxes = function(modelKey, dataKey) { const trameState = window.trame.state.state const modelValue = _.get(trameState, modelKey) const availableData = _.get(trameState, dataKey) const selectAllCheckbox = document.querySelector(".header-content input") const rowCheckboxes = document.querySelectorAll(".rgCell") if (selectAllCheckbox === null) { return } if (modelValue.length === 0) { selectAllCheckbox.checked = false selectAllCheckbox.indeterminate = false } else if (modelValue.length === availableData.length) { selectAllCheckbox.checked = true selectAllCheckbox.indeterminate = false } else { selectAllCheckbox.checked = false selectAllCheckbox.indeterminate = true } rowCheckboxes.forEach((element) => { input = element.querySelector('input') rowIndex = element.dataset.rgrow input.checked = modelValue.includes(availableData[rowIndex].path) }) } window.rvCellTemplate = function(createElement, props) { const inputVNode = createElement('input', { type: 'checkbox', onChange: (e) => { const state = window.trame.state.state const modelKey = props.column.model_key const trameState = window.trame.state.state const modelValue = _.get(trameState, props.column.model_key) const path = props.data[props.rowIndex].path const index = _.get(window.trame.state.state, modelKey).indexOf(path) const index = modelValue.indexOf(path) // We need to assign instead of modifying in place in order for the Trame watcher to pick up changes. if (e.target.checked && index < 0) { _.get(state, modelKey).push(path) _.set(trameState, props.column.model_key, _.concat(modelValue, path)) } else if (index >= 0) { _.get(state, modelKey).splice(index, 1) _.set(trameState, props.column.model_key, modelValue.toSpliced(index, 1)) } window.trame.state.dirty('config') // Update the UI window.rvUpdateCheckboxes(props.column.model_key, props.column.datafiles_key) window.trame.state.dirty(props.column.state_key) }, }) Loading @@ -24,15 +63,18 @@ window.rvColumnTemplate = function (createElement, props) { const inputVNode = createElement('input', { type: 'checkbox', onChange: (e) => { const state = window.trame.state.state const trameState = window.trame.state.state const availableData = _.get(trameState, props.datafiles_key) if (e.target.checked) { _.set(state, 'config.selected_files', _.get(state, props.datafiles_key).map((item) => item.path)) _.set(trameState, 'config.selected_files', availableData.map((item) => item.path)) } else { _.set(state, 'config.selected_files', []) _.set(trameState, 'config.selected_files', []) } window.trame.state.dirty('config') // Update the UI window.rvUpdateCheckboxes(props.model_key, props.datafiles_key) window.trame.state.dirty(props.state_key) }, }) Loading