trkmdemo / app.py
Ninjasharp's picture
Upload 2 files
8506867 verified
import streamlit as st
import pandas as pd
from datetime import datetime
import matplotlib.pyplot as plt
import seaborn as sns
import matplotlib.dates as mdates
from matplotlib.patches import Patch
# Set page configuration without the 'theme' argument
st.set_page_config(
page_title="Task Manager",
page_icon="✅",
layout="wide",
initial_sidebar_state="expanded"
)
st.text(" ")
st.write("#")
st.image("st.PNG", width=280)
# Initialize session state to store tasks
if 'tasks' not in st.session_state:
st.session_state.tasks = []
# Function to add a new task
def add_task(game_name, company, start_date, end_date, status, notes):
st.session_state.tasks.append({
'Game Name': game_name,
'Company': company,
'Start': start_date,
'Finish': end_date,
'Status': status,
'Notes': notes
})
# Function to remove a task
def remove_task(task_index):
if 0 <= task_index < len(st.session_state.tasks):
if st.sidebar.button(f"Confirm Delete Task {task_index}"):
st.session_state.tasks.pop(task_index)
st.success(f"Task {task_index} deleted permanently!")
# Function to update a task
def update_task(index, game_name, company, start_date, end_date, status, notes):
if 0 <= index < len(st.session_state.tasks):
st.session_state.tasks[index] = {
'Game Name': game_name,
'Company': company,
'Start': start_date,
'Finish': end_date,
'Status': status,
'Notes': notes
}
# Function to load tasks from a CSV file
def load_tasks_from_csv(uploaded_file):
df = pd.read_csv(uploaded_file)
for _, row in df.iterrows():
add_task(
row['Game Name'],
row['Company'],
pd.to_datetime(row['Start']),
pd.to_datetime(row['Finish']),
row['Status'],
row['Notes']
)
# Function to clear tasks from session state
def clear_tasks():
if st.sidebar.button("Confirm Clear All Tasks"):
st.session_state.tasks = []
st.success("All tasks cleared permanently!")
# Sidebar for adding new tasks
with st.sidebar:
st.header("Add New Task")
game_name = st.text_input("Game Name", key="add_game_name")
company = st.text_input("Company", key="add_company")
start_date = st.date_input("Start Date", min_value=datetime.now(), key="add_start_date")
end_date = st.date_input("End Date", min_value=start_date, key="add_end_date")
status = st.selectbox(
"Status",
["Not Started", "In Progress", "Completed", "Hold", "Delayed"],
key="add_status"
)
notes = st.text_area("Notes", key="add_notes")
if st.button("Add Task", key="add_task_button"):
add_task(game_name, company, start_date, end_date, status, notes)
st.success("Task added successfully!")
# Sidebar for uploading tasks from a file
with st.sidebar:
st.header("Upload Tasks from File")
uploaded_file = st.file_uploader("Upload a CSV file", type=["csv"], key="file_uploader")
if uploaded_file is not None:
load_tasks_from_csv(uploaded_file)
st.success("Tasks loaded successfully!")
# Sidebar for managing tasks
with st.sidebar:
st.header("Manage Tasks")
task_action = st.radio("Choose Action", ("None", "Edit Task", "Delete Task"), key="task_action")
if task_action != "None" and st.session_state.tasks:
task_names = [
f"{task['Game Name']} - {task['Start'].strftime('%b %Y')} to {task['Finish'].strftime('%b %Y')}"
for task in st.session_state.tasks
]
selected_task_index = st.selectbox(
"Select Task",
range(len(task_names)),
format_func=lambda x: task_names[x],
key="select_task"
)
if task_action == "Edit Task":
st.write("Editing Task:", task_names[selected_task_index])
edit_game_name = st.text_input(
"Game Name",
value=st.session_state.tasks[selected_task_index]['Game Name'],
key="edit_game_name"
)
edit_company = st.text_input(
"Company",
value=st.session_state.tasks[selected_task_index]['Company'],
key="edit_company"
)
edit_start_date = st.date_input(
"Start Date",
value=st.session_state.tasks[selected_task_index]['Start'],
key="edit_start_date"
)
edit_end_date = st.date_input(
"End Date",
value=st.session_state.tasks[selected_task_index]['Finish'],
key="edit_end_date"
)
edit_status = st.selectbox(
"Status",
["Not Started", "In Progress", "Completed", "Hold", "Delayed"],
index=["Not Started", "In Progress", "Completed", "Hold", "Delayed"].index(
st.session_state.tasks[selected_task_index]['Status']
),
key="edit_status"
)
edit_notes = st.text_area(
"Notes",
value=st.session_state.tasks[selected_task_index]['Notes'],
key="edit_notes"
)
if st.button("Update Task", key="update_task_button"):
update_task(
selected_task_index,
edit_game_name,
edit_company,
edit_start_date,
edit_end_date,
edit_status,
edit_notes
)
st.success("Task updated successfully!")
elif task_action == "Delete Task":
st.write("Deleting Task:", task_names[selected_task_index])
remove_task(selected_task_index)
# Clear the selection
selected_task_index = None
elif not st.session_state.tasks:
st.write("No tasks available to edit or delete.")
# Button to clear tasks from memory
with st.sidebar:
if st.button("Clear All Tasks"):
clear_tasks()
# Create DataFrame for the Gantt chart
if st.session_state.tasks:
df = pd.DataFrame(st.session_state.tasks)
df['Start'] = pd.to_datetime(df['Start'])
df['Finish'] = pd.to_datetime(df['Finish'])
# Custom color map for task statuses
color_discrete_map = {
"Not Started": "lightblue",
"In Progress": "blue",
"Completed": "green",
"Hold": "tan",
"Delayed": "red"
}
# Create Gantt chart with Matplotlib
fig, ax = plt.subplots(figsize=(12, 6), facecolor='black') # Set figure background to dark
# Set axes background to dark
ax.set_facecolor('black')
# Plot each task as a horizontal bar
for i, task in df.iterrows():
ax.barh(
task['Game Name'],
(task['Finish'] - task['Start']).days,
left=task['Start'].to_pydatetime(),
color=color_discrete_map.get(task['Status'], 'gray'),
edgecolor='white' # Optional: add edge color for better separation
)
# Set labels and title with white color and clear font
ax.set_xlabel('Time', color='white', fontsize=14, fontweight='bold')
ax.set_ylabel('Game Name', color='white', fontsize=14, fontweight='bold')
ax.set_title('Project Timelines', color='white', fontsize=18, fontweight='bold')
# Format the x-axis to show month and year
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1)) # Set the interval of the ticks
# Rotate x-axis labels for better readability and set color to white
plt.xticks(rotation=45, color='white')
# Set y-axis tick labels to white
plt.yticks(color='white', fontsize=12)
# Set x-axis tick labels to white
ax.tick_params(axis='x', colors='white', labelsize=12)
ax.tick_params(axis='y', colors='white', labelsize=12)
# Set the spine colors to white
for spine in ax.spines.values():
spine.set_color('white')
# Add gridlines (optional: customize as needed)
ax.grid(True, which='both', axis='x', color='gray', linestyle='--', linewidth=0.5)
# Add a legend with white font
legend_elements = [Patch(facecolor=color_discrete_map[status], edgecolor='white', label=status) for status in color_discrete_map]
ax.legend(handles=legend_elements, title="Status", title_fontsize='13', fontsize='12', loc='upper right', facecolor='black', edgecolor='white', labelcolor='white')
# Adjust layout for better spacing
plt.tight_layout()
# Display the Gantt chart
st.write("Progress Updates")
st.pyplot(fig)
# Convert DataFrame to CSV
csv = df.to_csv(index=False)
st.sidebar.download_button(
label="Download CSV",
data=csv,
file_name='tasks.csv',
mime='text/csv',
key="download_csv_button"
)
else:
st.write("No tasks to display in the timeline chart.")
# Bar chart of task statuses using Seaborn
if st.session_state.tasks:
status_counts = df['Status'].value_counts().reset_index()
status_counts.columns = ['Status', 'Count']
fig, ax = plt.subplots(figsize=(10, 5), facecolor='black') # Set figure background to dark
ax.set_facecolor('black')
sns.barplot(
x='Status',
y='Count',
data=status_counts,
palette=[color_discrete_map.get(status, 'gray') for status in status_counts['Status']],
ax=ax
)
# Set labels and title with white color and clear font
ax.set_title('Task Status Distribution', color='white', fontsize=16, fontweight='bold')
ax.set_ylabel('Game Count', color='white', fontsize=14, fontweight='bold')
ax.set_xlabel('Status', color='white', fontsize=14, fontweight='bold')
# Set tick parameters for better readability
ax.tick_params(axis='x', colors='white', labelsize=12)
ax.tick_params(axis='y', colors='white', labelsize=12)
# Set the spine colors to white
for spine in ax.spines.values():
spine.set_color('white')
# Add a legend with white font
legend_elements = [Patch(facecolor=color_discrete_map[status], edgecolor='white', label=status) for status in color_discrete_map]
ax.legend(handles=legend_elements, title="Status", title_fontsize='13', fontsize='12', loc='upper right', facecolor='black', edgecolor='white', labelcolor='white')
# Adjust layout for better spacing
plt.tight_layout()
# Display the bar chart
st.pyplot(fig)
# Final save and load buttons
st.write("Save files, edit and load from sidebar")
st.info("Built by dw 8-27-24")