Open hamishcraze opened 2 years ago
If key is not specified, st_sortables will look at the contents of items to determine the uniqueness of the component, as same as official widgets. In this case, each time a new item is added, a new st_sortables object is created and it behaves as if it were forgotten.
We should sync session_state with st_sortables' internal state something like code below. Might be a little tricky.
import streamlit as st
from streamlit_sortables import sort_items
if not 'pipeline' in st.session_state:
st.session_state.pipeline = {
'left': ['item1', 'item2', 'item3'],
'right': ['item4', 'item5', 'item6']
}
pipeline = st.session_state.pipeline
items = [
{'header': 'Pipeline', 'items': pipeline['left']},
{'header': 'Disabled', 'items': pipeline['right']},
]
sorted_items = sort_items(items, multi_containers=True, direction='vertical')
if st.button('Add', key='BUTTON'):
n_items = len(pipeline['left']) + len(pipeline['right'])
# the item value must be unique.
new_item = f'item{n_items + 1}'
# session_state must be sorted
st.session_state.pipeline = {
'left': sorted_items[0]['items'] + [new_item],
'right': sorted_items[1]['items']
}
# should rerun to reflect the change of session_state
st.experimental_rerun()
Summary I am attempting to use streamlit-sortables to create text processing pipelines (a set of interoperable functions). What we do is allow the user to create an operation. This operation is added to the pipeline. However, perhaps a user wishes to change the order that operations run, streamlit-sortables works well for this.
However we are running into when we try to add new items to these lists (via some button press).
Reproducible Code Example
Steps To Reproduce I.E Streamlit starts up. You initialize the streamlit sortable via the following:
items = [ {'header': 'Pipeline', 'items': ["item1","item2,","item3"]}, {'header': 'Disabled', 'items': ["item4","item5,","item6"]}, ]
All is well. Items can be moved between lists and reordered as per usual. But we wish for the end-user to be able to assemble a pipeline themselves. Meaning they need to be able to add new elements to the lists.
We thought we'd implement that using session state:
As you can see, when a button element is clicked, the item "ADDED" is added to the pipeline_left list which is stored in session_state. This means that on reload, the sorted_items element should be populated with the new items. This proceeds as expected.
The issue occurs when you then try to reorder the sortable list via the frontend. Something is going wrong that is preventing the sortable list for updating correctly and it becomes unresponsive (i) forgets the added element entirely (ii) if you drag ADD from pipeline_left to pipeline_right, when a new element is added, all previously added items appear in pipeline_left. Ignoring all previous state changes.
Expected Behavior We expect to be able to add new elements to the sortable_items list during runtime without completely breaking it's functionality
Current Behavior becomes unresponsive (i) forgets the added element entirely (ii) if you drag "ADDED" from pipeline_left to pipeline_right, when a new element is added (via a second button press), all previously added items appear in pipeline_left. Ignoring all previous state changes.
Something in streamlit_sortables is not talking to the streamlit backend correctly.