Closed CHerSun closed 1 year ago
Ok, found this out. Your demo has a side-effect bug. Any click on calendar gives:
Note, eventsSet: NULL
.
Code in demo:
if "eventsSet" in state:
st.session_state["events"] = state["eventsSet"]
it doesn't check for None
value and just saves to session_state. After that changing to any other view gives empty calendar. Can either remove that (at least I found no reason to keep that, see below). Or should be something like:
if (events_set := state.get("eventsSet", None)):
st.session_state["events"] = events_set
hmm, was trying to play with it to add creation of new event on click. Found 2 problems:
calendar
?But still, it works, I was able to create new events by clicking in resource-timeline, that's really awesome.
Btw, badly need callbacks to make returned events single-time things (if I don't force redraw by using new key - event returned on streamlit rerun is the same, forcing streamlit into endless loop of the same actions).
Just in case, the code I used to create new event on click:
# change: init events once
if "events" not in st.session_state:
st.session_state["events"] = get_events()
# change: add counter to key
state = calendar(
events=st.session_state["events"],
options=calendar_options,
key=mode+str(st.session_state.setdefault("calendar_version", 0)),
)
# added: parsing of dateClick event and increase counter to force redraw - effectively making event a single-time thing in streamlit
from random import randint
from datetime import datetime, timedelta
if (date_click := state.get("dateClick", None)):
if (resource_clicked := date_click.get("resource", None)):
date_start = datetime.fromisoformat(date_click["date"])
date_end = date_start + timedelta(days=1)
new_event_color = '#%02X%02X%02X' % (randint(0,255),randint(0,255),randint(0,255))
new_event = {
"title": f'Event {len(st.session_state["events"])+1}',
"color": new_event_color,
"start": date_start.isoformat(),
"end": date_end.isoformat(),
"resourceId": resource_clicked["id"],
}
st.session_state["events"].append(new_event)
st.session_state["calendar_version"] += 1
st.experimental_rerun()
I just wanted to tell you - thank you. I was looking for a calendar component for streamlit for ages (can't make one myself unfortunately).
Especially love the resource-timeline view. Could you maybe add a few events to the demo app for resource-timeline view?
Hi, thanks for your input. Regarding the bug in resource based view, I just realized the javascript package itself doesn't include the resource id back in events object https://github.com/fullcalendar/fullcalendar/issues/6191. The updated version should fix that.
:tada: This issue has been resolved in version 0.5.0 :tada:
The release is available on PyPI and GitHub.
@im-perativa cool. Thank you for update, resource ids are nice thing to have. Could you advise on other things? How to add data to existing component without having a full redraw via a new streamlit key? I've read about calendar sources in FullCalendar. It looks like I will be able to make it self-updating if I give it a JSON source via another service (REST API), but don't have that ready at the moment, so if there's a way to update via streamlit directly - that'd be cool.
I just wanted to tell you - thank you. I was looking for a calendar component for streamlit for ages (can't make one myself unfortunately).
Especially love the resource-timeline view. Could you maybe add a few events to the demo app for resource-timeline view?