Coder Social home page Coder Social logo

im-perativa / streamlit-calendar Goto Github PK

View Code? Open in Web Editor NEW
104.0 4.0 11.0 6.02 MB

A Streamlit component to show calendar view using FullCalendar

Home Page: https://calendar-component.streamlit.app/

License: Apache License 2.0

Python 60.47% HTML 4.03% TypeScript 34.17% CSS 1.33%
calendar fullcalendar streamlit streamlit-component

streamlit-calendar's Introduction

streamlit-calendar 📆

PyPI Supported Python versions PyPI downloads License GitHub Workflow Status Code style: Black

A Streamlit component to show calendar view using FullCalendar with support for Streamlit light/dark theme, callbacks, and custom CSS

Buy Me A Coffee

🌏Demo Streamlit App

⚙️Installation

pip install streamlit-calendar

💻Usage

from streamlit_calendar import calendar

calendar_options = {
    "editable": "true",
    "selectable": "true",
    "headerToolbar": {
        "left": "today prev,next",
        "center": "title",
        "right": "resourceTimelineDay,resourceTimelineWeek,resourceTimelineMonth",
    },
    "slotMinTime": "06:00:00",
    "slotMaxTime": "18:00:00",
    "initialView": "resourceTimelineDay",
    "resourceGroupField": "building",
    "resources": [
        {"id": "a", "building": "Building A", "title": "Building A"},
        {"id": "b", "building": "Building A", "title": "Building B"},
        {"id": "c", "building": "Building B", "title": "Building C"},
        {"id": "d", "building": "Building B", "title": "Building D"},
        {"id": "e", "building": "Building C", "title": "Building E"},
        {"id": "f", "building": "Building C", "title": "Building F"},
    ],
}
calendar_events = [
    {
        "title": "Event 1",
        "start": "2023-07-31T08:30:00",
        "end": "2023-07-31T10:30:00",
        "resourceId": "a",
    },
    {
        "title": "Event 2",
        "start": "2023-07-31T07:30:00",
        "end": "2023-07-31T10:30:00",
        "resourceId": "b",
    },
    {
        "title": "Event 3",
        "start": "2023-07-31T10:40:00",
        "end": "2023-07-31T12:30:00",
        "resourceId": "a",
    }
]
custom_css="""
    .fc-event-past {
        opacity: 0.8;
    }
    .fc-event-time {
        font-style: italic;
    }
    .fc-event-title {
        font-weight: 700;
    }
    .fc-toolbar-title {
        font-size: 2rem;
    }
"""

calendar = calendar(events=calendar_events, options=calendar_options, custom_css=custom_css)
st.write(calendar)

📝API References

Initialization Args

For complete event object properties, check out: https://fullcalendar.io/docs/event-object
For complete options object properties, check out: https://fullcalendar.io/docs
For complete custom_css options, check out: https://fullcalendar.io/docs/css-customization

Component Values

The component value, i.e. the return value of the calendar(...) instance, is a dict which properties depends on the current called callback.

For example, when the user clicked on an event, the component value would be:

st.write(calendar)
# {
#   "callback": "eventClick",
#   "eventClick": {
#     "event": {
#       "allDay": true,
#       "title": "Event 1",
#       "start": "2023-07-03",
#       "end": "2023-07-05",
#       "backgroundColor": "#FF6C6C",
#       "borderColor": "#FF6C6C"
#     },
#     "view": {
#       "type": "dayGridMonth",
#       "title": "July 2023",
#       "activeStart": "2023-06-24T17:00:00.000Z",
#       "activeEnd": "2023-08-05T17:00:00.000Z",
#       "currentStart": "2023-06-30T17:00:00.000Z",
#       "currentEnd": "2023-07-31T17:00:00.000Z"
#     }
#   },
# }

The properties of each callback is explained as follows:

dateClick

Triggered when the user clicks on a date or a time.

Source: https://fullcalendar.io/docs/dateClick

Property Type Description
allDay boolean true or false whether the click happened on an all-day cell.
date string a date for the clicked day/time in ISO8601 string format.
view View The current view.
resource Resource If the current view is a resource-view, the resource that owns this date.

eventClick

Triggered when the user clicks an event.

Source: https://fullcalendar.io/docs/eventClick

Property Type Description
event Event The associated event.
view View The current view.

eventChange

Called after an event has been modified in some way.

Source: https://fullcalendar.io/docs/eventChange

Property Type Description
oldEvent Event An event with data prior to the change.
event Event An Event Object with the updated changed data.
relatedEvents Event[] An array of other related events that were also affected. An event might have other recurring event instances or might be linked to other events with the same groupId.

eventsSet

Called after event data is initialized OR changed in any way.

Source: https://fullcalendar.io/docs/eventsSet

Property Type Description
events Event[] An array of events. It contains every event in memory.

select

Triggered when a date/time selection is made.

Source: https://fullcalendar.io/docs/select-callback

Property Type Description
allDay boolean true or false whether the selection happened on all-day cells.
start string a date indicating the beginning of the selection in ISO8601 string format.
end. string a date indicating the end of the selection in ISO8601 string format.
view View The current view.
resource Resource If the current view is a resource-view, the resource that owns this selection.

Types

Event

Source: https://fullcalendar.io/docs/event-object

Property Type Description
id string A unique identifier of an event.
groupId string Events that share a groupId will be dragged and resized together automatically.
allDay boolean Determines if the event is shown in the “all-day” section of relevant views. In addition, if true the time text is not displayed with the event.
start string An ISO8601 string representation of the start date. If the event is all-day, there will not be a time part.
end string An ISO8601 string representation of the end date. If the event is all-day, there will not be a time part.
title string The text that will appear on an event.
url string A URL that will be visited when this event is clicked by the user.
classNames string[] An array of strings like [ 'myclass1', myclass2' ]. Determines which HTML classNames will be attached to the rendered event.
display string The rendering type of this event. Can be 'auto', 'block', 'list-item', 'background', 'inverse-background', or 'none'.
backgroundColor string The eventBackgroundColor override for this specific event.
borderColor string The eventBorderColor override for this specific event.
textColor string The eventTextColor override for this specific event.
extendedProps Dictionary A plain object holding miscellaneous other properties specified during parsing. Receives properties in the explicitly given extendedProps hash as well as other non-standard properties.
resourceId string The unique string identifier for the resource of the event (if any).

Resource

Source: https://fullcalendar.io/docs/resource-object

Property Type Description
id string The unique string identifier for this resource.
title string The title of this resource.
eventBackgroundColor string Same as Event.backgroundColor.
eventBorderColor string Same as Event.borderColor.
eventTextColor string Same as Event.textColor.
eventClassNames string[] Same as Event.ClassNames.
extendedProps Dictionary A hash of non-standard props that were specified during parsing

View

Source: https://fullcalendar.io/docs/view-object

Property Type Description
type string Name of one of the available views.
title string Title text that is displayed at the top of the headerToolbar.
activeStart string An ISO8601 string that is the first visible day.
activeEnd string An ISO8601 string that is the last visible day.
currentStart string An ISO8601 string that is the start of the interval the view is trying to represent.
currentEnd string An ISO8601 string that is the end of the interval the view is trying to represent.

🛠️Development

Note: you only need to run these steps if you want to change this component or contribute to its development!

Setup

First, clone the repository:

git clone https://github.com/im-perativa/streamlit-calendar.git
cd streamlit-calendar

Install the Python dependencies:

poetry install

And install the frontend dependencies:

cd streamlit_calendar/frontend
npm install

Making changes

To make changes, first go to streamlit_calendar/__init__.py and make sure the variable _RELEASE is set to False. This will make the component use the local version of the frontend code, and not the built project.

Then, start one terminal and run:

cd streamlit_calendar/frontend
npm start

This starts the frontend code on port 3001.

Open another terminal and run:

cd streamlit_calendar
poetry shell
streamlit run __init__.py

This runs the development version on local Streamlit server. Now you can make changes to the Python or Javascript code in streamlit_calendar and the demo app should update automatically!

If nothing updates, make sure the variable _RELEASE in streamlit_calendar/__init__.py is set to False.

streamlit-calendar's People

Contributors

im-perativa avatar jingy2000 avatar maxvandenboom avatar rahadi23 avatar renovate[bot] avatar semantic-release-bot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

streamlit-calendar's Issues

Interacting with calendar makes streamlit re-run

Thanks for developing this component.

I have an issue where if I click on the calendar (anywhere, even on blank area), it causes Streamlit to re-run the entire page.

I want the calendar to be completely read-only with no click events allowed.

I have "selectable": False in the config dict. Any suggestions?

My code:

        ...

        resources = []

        for _, event in events.iterrows():
            resource = {
                "id": event["event_service_id"],
                "address": event["formatted_address"],
                "title": event["customer_name"]
            }
            resources.append(resource)

        calendar_options = {
            "initialDate": events["event_start_date"].min(),
            "initialView": "dayGridMonth",
            "headerToolbar": {
                "left": "prev,next",
                "center": "title",
                "right": "dayGridWeek,dayGridDay"
            },
            "resources": resources,
            "resourceGroupField": "address",
            "slotDuration": "00:30:00",
            "slotMinTime": "00:00:00",
            "slotMaxTime": "23:59:99",
            "selectable": False
        }

        calendar_events = []

        for _, event in events.iterrows():
            title = "\n".join([event["provider"], event["event_type"], event["event_description"], event["event_status"]])
            calendar_event = {
                "title": title,
                "start": event["event_start_timestamp"],
                "end": event["event_end_timestamp"],
                "resourceId": event["event_service_id"]
            }
            calendar_events.append(calendar_event)

        custom_css="""
            .fc-event-past {
                opacity: 0.8;
            }
            .fc-event-time {
                font-style: italic;
            }
            .fc-event-title {
                font-weight: 700;
            }
            .fc-toolbar-title {
                font-size: 1.5rem;
            }
        """

        cont1 = self.container.container()
        cont2 = self.container.container()

        cal = calendar(events=calendar_events, options=calendar_options, custom_css=custom_css)
        with cont1:
            cal

        cont2.expander("Show events data").dataframe(
            events,
            hide_index=True
        )

        ....

Display bug when inside a tab that is not the first tab

I'm having an issue when using the calendar inside a tab where only a little part of the calendar is displayed. The calendar gets back to normal after interaction with it by clicking on the calendar buttons.

image

This only happens when the calendar is in a tab that is not the first tab. Example code below:

  • Good, works:
tab1, tab2 = st.tabs("tab1", "tab2")

with tab1:
    show_calendar()
with tab2:
    pass
  • Bad, don't works:
tab1, tab2 = st.tabs("tab1", "tab2")

with tab1:
    pass   
with tab2:
    show_calendar()

list model bug when click "list" button

When I used ”list“ model and clicked the event,then error happened.
No matter in the online demo or in my local environment.

The error like this:
Component Error
Converting circular structure to JSON --> starting at object with constructor 'HTMLDivElement' | property '__reactInternalInstance$i4o8rs9dx7q' -> object with constructor 'Hl' --- property 'stateNode' closes the circle****

Adding eventClick functionality

Hi,
I am trying to add eventClick functionality such as:
https://fullcalendar.io/docs/eventClick-demo

to the streamlit-calender component using the following calender_options:

calendar_options = { "headerToolbar": { "left": "today prev,next", "center": "title", "right": "resourceTimelineDay,resourceTimelineWeek,resourceTimelineMonth", }, "slotMinTime": "06:00:00", "slotMaxTime": "18:00:00", "initialView": "resourceTimelineDay", "eventClick": { "event": { "title": 'my event', }, "view": { "type": 'my event view', } }, }

however, this does not produce the resulting effect of viewing the calender event/ information upon eventClick.

I'm looking for your support on this matter. Thank you.

Adjust table height in resource-timeline

The size of the table in resource-timeline is too long and adds a lot of whitespace below the last row. Also, it doesn't draw the horizontal rule for the last row. How can this be adjusted (perhaps, via custom css or another way)?

Add event to a Timeline

Hey @im-perativa, thanks for the very clean component !
I really enjoyed the demo you deployed with all the different modes.

However, one thing is puzzling me, and I can't find it either in FullCalender.io: how can I add an event from the calendar view, with either (i) a streamlit button to add an event or (ii) automatic event creation for one of the callbacks (for example with dateClick)

It seems this would be a common enough use case but I can't find anything about it 🤔
With resource-timeline for example, I could create a streamlit button to add an event on the Calendar to be placed on the right Room/Building, but the callback for eventChange does not contain the new (or old) id of the event:
image

Do you have a hack/workaround for this ?
Thanks !

Thanks & resource-timeline

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?

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Rate-Limited

These updates are currently rate-limited. Click on a checkbox below to force their creation now.

  • chore(deps): update dependency bandit to v1.7.9
  • fix(deps): update dependency streamlit to v1.37.0
  • chore(deps): update abatilo/actions-poetry action to v3
  • chore(deps): update dependency black to v24
  • chore(deps): update dependency watchdog to v4
  • chore(deps): update react monorepo to v18 (major) (@types/react, @types/react-dom, react, react-dom)
  • 🔐 Create all rate-limited PRs at once 🔐

Open

These updates have all been created already. Click a checkbox below to force a retry/rebase of any.

Detected dependencies

github-actions
.github/workflows/ci.yml
  • actions/checkout v3
  • actions/setup-python v3
  • abatilo/actions-poetry v2.1.0
  • actions/setup-python v3
  • actions/checkout v3
  • abatilo/actions-poetry v2.1.0
  • bjoluc/semantic-release-config-poetry v2
npm
streamlit_calendar/frontend/package.json
  • @fullcalendar/adaptive ^6.1.9
  • @fullcalendar/core ^6.1.9
  • @fullcalendar/daygrid ^6.1.9
  • @fullcalendar/interaction ^6.1.9
  • @fullcalendar/list ^6.1.9
  • @fullcalendar/multimonth ^6.1.9
  • @fullcalendar/react ^6.1.9
  • @fullcalendar/resource ^6.1.9
  • @fullcalendar/resource-daygrid ^6.1.9
  • @fullcalendar/resource-timegrid ^6.1.9
  • @fullcalendar/resource-timeline ^6.1.9
  • @fullcalendar/rrule ^6.1.9
  • @fullcalendar/scrollgrid ^6.1.9
  • @fullcalendar/timegrid ^6.1.9
  • @fullcalendar/timeline ^6.1.9
  • react ^16.13.1
  • react-dom ^16.13.1
  • streamlit-component-lib ^2.0.0
  • styled-components ^6.0.8
  • @types/node ^12.0.0
  • @types/react ^16.9.0
  • @types/react-dom ^16.9.0
  • react-scripts ^5.0.1
  • typescript ^4.2.0
pep621
pyproject.toml
  • poetry-core >=1.0.0
poetry
pyproject.toml
  • python ^3.8
  • streamlit ^1.12.0
  • watchdog ^2.1.9
  • black ^22.6.0
  • isort ^5.10.1
  • bandit ^1.7.5

  • Check this box to trigger a request for Renovate to run again on this repository

Lazy load events upon date view change

Is it possible to lazy load events upon date view change? I am trying to implement lazy loading of events. The goal is to fetch and display events only for the current visible date range of the calendar. Pre-fetching all events is not feasible for my application. I only want to fetch and show events for the day(s) shown to the end user.

Disabling Drag-and-Drop in Streamlit-Calendar: Need Assistance with Event Modification Settings

I would like the user to not be able to modify the position of the slots via drag-and-drop.

I thought it was enough to set the "editable" variable in "options" to "false" to disable drag-and-drop... but it is not the case. It is still possible to move events by drag-and-drop. I also removed "eventChange" from the callbacks passed when calling calendar. It is still possible to manually move the slots...

What else should I do to make the streamlit-calendar respond only to user clicks without it being possible to interactively modify the events?

Thank you again for your help and this excellent component.

Streamlit-calender not getting rendered in streamlit tabs

When streamlit-calender is being placed in second or third tab it is not being rendered. Upon shifting the same calender to first tab, it works as expected.

image
image

It is something to do with iframe height not being set correcty. The calender is present but squashed.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.