|
import streamlit as st |
|
import pandas as pd |
|
from datetime import date, datetime |
|
import os |
|
import altair as alt |
|
import smtplib |
|
from email.mime.text import MIMEText |
|
import base64 |
|
|
|
|
|
|
|
from docx import Document |
|
|
|
|
|
from email.mime.multipart import MIMEMultipart |
|
|
|
from email import encoders |
|
import os |
|
|
|
|
|
|
|
from email.mime.multipart import MIMEMultipart |
|
|
|
|
|
PROJECT_DATA_FILE = 'projects.csv' |
|
TASK_DATA_FILE = 'tasks.csv' |
|
TEAM_DATA_FILE = 'team_members.csv' |
|
|
|
st.title("Projects Management Tool") |
|
|
|
|
|
|
|
def load_projects(): |
|
try: |
|
return pd.read_csv(PROJECT_DATA_FILE) |
|
except FileNotFoundError: |
|
return pd.DataFrame(columns=["Project Name", "Description", "Start Date", "End Date", "Priority", "Status", "Progress", "Budget", "Tags"]) |
|
|
|
|
|
def save_projects(df): |
|
df.to_csv(PROJECT_DATA_FILE, index=False) |
|
|
|
|
|
def load_tasks(): |
|
try: |
|
return pd.read_csv(TASK_DATA_FILE) |
|
except FileNotFoundError: |
|
return pd.DataFrame(columns=["Project Name", "Task Name", "Deadline", "Status", "Assigned To"]) |
|
|
|
|
|
def save_tasks(df): |
|
df.to_csv(TASK_DATA_FILE, index=False) |
|
|
|
|
|
def load_team(): |
|
try: |
|
return pd.read_csv(TEAM_DATA_FILE) |
|
except FileNotFoundError: |
|
return pd.DataFrame(columns=["Project Name", "Member Name", "Role"]) |
|
|
|
|
|
def save_team(df): |
|
df.to_csv(TEAM_DATA_FILE, index=False) |
|
|
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
|
|
def home(): |
|
st.title("Welcome to the Project Management Tool") |
|
st.markdown(""" |
|
## About the Tool |
|
The **Project Management Tool** is a comprehensive solution built specifically for **Admins** and **Project Managers** in small software houses. |
|
- It **streamlines workflows, enhances productivity, and ensures smooth project execution.** |
|
|
|
### Key Features: |
|
- **Add, Edit, and Delete Projects:** Easily create, modify, or remove projects. |
|
- **Task Management:** Assign and organize tasks efficiently. |
|
- **High Priority & Deadlines:** Focus on critical tasks to meet deadlines. |
|
- **Project Progress Tracking:** Monitor project progress in real-time. |
|
- **Team Collaboration:** Facilitate communication and teamwork. |
|
- **Analytics & Reports:** Generate performance and resource utilization reports. |
|
- **Calendar View:** Plan schedules with an intuitive calendar format. |
|
- **Search and Filter Projects:** Quickly find projects using advanced search tools. |
|
- **Budget Tracking:** Manage budgets effectively to avoid overspending. |
|
- **Comments and Notes:** Document critical details and discussions. |
|
- **Prioritization Metrics:** Focus on the most impactful tasks. |
|
- **Gantt Chart Visualization:** Gain a clear view of timelines with Gantt charts. |
|
- **Resource Management:** Allocate resources optimally across projects. |
|
- **Risk Management:** Identify and mitigate potential risks proactively. |
|
|
|
### Why Choose This Tool? |
|
- Specifically designed for **Admins** and **Project Managers**. |
|
- Tailored for small software houses. |
|
- Focused on streamlining project workflows and improving efficiency. |
|
""") |
|
|
|
|
|
|
|
|
|
def add_project(): |
|
st.header("Add New Project") |
|
|
|
|
|
project_suggestions = [ |
|
"Machine Learning Model", |
|
"Web Development App", |
|
"Mobile App Development", |
|
"Data Science Pipeline", |
|
"API Development", |
|
"Game Development", |
|
] |
|
project_name = st.selectbox("Select or type a project name:", project_suggestions) |
|
|
|
|
|
description_placeholder = { |
|
"Machine Learning Model": "Enter a brief description of your machine learning model project.", |
|
"Web Development App": "Enter a brief description of your web development app project.", |
|
"Mobile App Development": "Enter a brief description of your mobile app development project.", |
|
"Data Science Pipeline": "Enter a brief description of your data science pipeline project.", |
|
"API Development": "Enter a brief description of your API development project.", |
|
"Game Development": "Enter a brief description of your game development project." |
|
} |
|
description = st.text_area("Project Description", placeholder=description_placeholder.get(project_name, "")) |
|
|
|
|
|
technologies = { |
|
"Machine Learning Model": ["Python", "TensorFlow", "PyTorch", "Scikit-learn"], |
|
"Web Development App": ["HTML", "CSS", "JavaScript", "Django", "Flask"], |
|
"Mobile App Development": ["Flutter", "React Native", "Swift", "Kotlin"], |
|
"Data Science Pipeline": ["Python", "Pandas", "NumPy", "Matplotlib"], |
|
"API Development": ["FastAPI", "Flask", "Express.js", "Django Rest Framework"], |
|
"Game Development": ["Unity", "Unreal Engine", "C#", "Godot"], |
|
} |
|
|
|
if project_name in technologies: |
|
tech_options = technologies[project_name] |
|
else: |
|
tech_options = [] |
|
|
|
technology_used = st.multiselect("Select technologies used in the project:", tech_options) |
|
|
|
|
|
start_date = st.date_input("Start Date", date.today()) |
|
end_date = st.date_input("End Date") |
|
priority = st.selectbox("Priority", ["Low", "Medium", "High"]) |
|
budget = st.number_input("Budget", min_value=0.0) |
|
|
|
|
|
if st.button("Create Project"): |
|
if project_name and description: |
|
new_project = pd.DataFrame({ |
|
"Project Name": [project_name], |
|
"Description": [description], |
|
"Start Date": [start_date], |
|
"End Date": [end_date], |
|
"Priority": [priority], |
|
"Status": ["Uncompleted"], |
|
"Progress": [0], |
|
"Budget": [budget], |
|
"Technologies": [", ".join(technology_used)] |
|
}) |
|
df = load_projects() |
|
df = pd.concat([df, new_project], ignore_index=True) |
|
save_projects(df) |
|
st.success(f"Project '{project_name}' has been added!") |
|
else: |
|
st.error("Please fill in all fields") |
|
|
|
|
|
def edit_project(): |
|
st.header("Edit Project") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects to edit.") |
|
return |
|
|
|
project_names = df["Project Name"].tolist() |
|
project = st.selectbox("Select Project", project_names) |
|
|
|
if project: |
|
row = df[df["Project Name"] == project].iloc[0] |
|
|
|
|
|
project_suggestions = [ |
|
"Machine Learning Model", |
|
"Web Development App", |
|
"Mobile App Development", |
|
"Data Science Pipeline", |
|
"API Development", |
|
"Game Development", |
|
] |
|
new_name = st.selectbox("Select or type a project name:", project_suggestions, index=project_suggestions.index(row["Project Name"]) if row["Project Name"] in project_suggestions else 0) |
|
|
|
|
|
description_placeholder = { |
|
"Machine Learning Model": "Enter a brief description of your machine learning model project.", |
|
"Web Development App": "Enter a brief description of your web development app project.", |
|
"Mobile App Development": "Enter a brief description of your mobile app development project.", |
|
"Data Science Pipeline": "Enter a brief description of your data science pipeline project.", |
|
"API Development": "Enter a brief description of your API development project.", |
|
"Game Development": "Enter a brief description of your game development project." |
|
} |
|
description = st.text_area("Project Description", placeholder=description_placeholder.get(new_name, ""), value=row["Description"]) |
|
|
|
|
|
technologies = { |
|
"Machine Learning Model": ["Python", "TensorFlow", "PyTorch", "Scikit-learn"], |
|
"Web Development App": ["HTML", "CSS", "JavaScript", "Django", "Flask"], |
|
"Mobile App Development": ["Flutter", "React Native", "Swift", "Kotlin"], |
|
"Data Science Pipeline": ["Python", "Pandas", "NumPy", "Matplotlib"], |
|
"API Development": ["FastAPI", "Flask", "Express.js", "Django Rest Framework"], |
|
"Game Development": ["Unity", "Unreal Engine", "C#", "Godot"], |
|
} |
|
|
|
tech_options = technologies.get(new_name, []) |
|
technology_used = st.multiselect("Select technologies used in the project:", tech_options, default=row["Technologies"].split(", ")) |
|
|
|
|
|
start_date = st.date_input("Start Date", row["Start Date"]) |
|
end_date = st.date_input("End Date", row["End Date"]) |
|
priority = st.selectbox("Priority", ["Low", "Medium", "High"], index=["Low", "Medium", "High"].index(row["Priority"])) |
|
budget = st.number_input("Budget", min_value=0.0, value=row["Budget"]) |
|
|
|
|
|
if st.button("Update Project"): |
|
|
|
df.loc[df["Project Name"] == project, ["Project Name", "Description", "Start Date", "End Date", "Priority", "Budget", "Technologies"]] = new_name, description, start_date, end_date, priority, budget, ", ".join(technology_used) |
|
save_projects(df) |
|
st.success(f"Project '{new_name}' has been updated.") |
|
|
|
|
|
def delete_project(): |
|
st.header("Delete Project") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects to delete.") |
|
return |
|
|
|
project = st.selectbox("Select Project to Delete", df["Project Name"]) |
|
if st.button("Delete Project"): |
|
df = df[df["Project Name"] != project] |
|
save_projects(df) |
|
st.success(f"Project '{project}' has been deleted.") |
|
|
|
|
|
|
|
|
|
def send_email(to_email, subject, body, attachment=None): |
|
from_email = "[email protected]" |
|
password = "your_password" |
|
try: |
|
server = smtplib.SMTP('smtp.gmail.com', 587) |
|
server.starttls() |
|
server.login(from_email, password) |
|
msg = MIMEMultipart() |
|
msg['Subject'] = subject |
|
msg['From'] = from_email |
|
msg['To'] = to_email |
|
msg.attach(MIMEText(body, 'plain')) |
|
|
|
|
|
if attachment: |
|
with open(attachment, "rb") as file: |
|
part = MIMEBase("application", "octet-stream") |
|
part.set_payload(file.read()) |
|
encoders.encode_base64(part) |
|
part.add_header("Content-Disposition", f"attachment; filename={attachment}") |
|
msg.attach(part) |
|
|
|
server.sendmail(from_email, to_email, msg.as_string()) |
|
server.quit() |
|
except Exception as e: |
|
print(f"Failed to send email: {e}") |
|
|
|
|
|
def manage_tasks(): |
|
st.header("Task Management") |
|
|
|
|
|
projects = load_projects() |
|
tasks_df = load_tasks() |
|
|
|
if projects.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
|
|
project = st.selectbox("Select Project", projects["Project Name"]) |
|
|
|
|
|
team_members = { |
|
"Machine Learning Model": ["Ahmed", "Omar", "Faisal"], |
|
"Web Development App": ["Zaid", "Salman", "Yusuf"], |
|
"Mobile App Development": ["Hassan", "Bilal", "Ibrahim"], |
|
"Data Science Pipeline": ["Suleiman", "Imran", "Farhan"], |
|
"API Development": ["Adeel", "Hamza", "Mustafa"], |
|
"Game Development": ["Ali", "Khalid", "Tariq"] |
|
} |
|
|
|
|
|
st.subheader("Add a New Task") |
|
title = st.text_input("Task Title") |
|
description = st.text_area("Task Description") |
|
priority = st.selectbox("Priority", ["Low", "Medium", "High", "Custom"]) |
|
custom_priority = None |
|
if priority == "Custom": |
|
custom_priority = st.text_input("Enter Custom Priority") |
|
|
|
tags = st.multiselect("Tags/Labels", ["Design", "Development", "Testing", "Research", "Bug Fixing"]) |
|
team_leader = st.selectbox("Team Leader", team_members.get(project, [])) |
|
assigned_to = st.multiselect("Assigned Team Members", team_members.get(project, [])) |
|
start_date = st.date_input("Start Date") |
|
deadline = st.date_input("Deadline") |
|
|
|
|
|
new_task = pd.DataFrame({ |
|
"Project Name": [project], |
|
"Task Title": [title], |
|
"Description": [description], |
|
"Priority": [priority if priority != "Custom" else custom_priority], |
|
"Tags": [", ".join(tags)], |
|
"Team Leader": [team_leader], |
|
"Assigned To": [", ".join(assigned_to)], |
|
"Start Date": [start_date], |
|
"Deadline": [deadline], |
|
"Status": ["Uncompleted"] |
|
}) |
|
|
|
|
|
if title and team_leader and assigned_to: |
|
st.subheader("Preview Current Task") |
|
st.write(new_task) |
|
|
|
|
|
st.subheader("Download Current Task") |
|
current_task_file = "current_task.csv" |
|
new_task.to_csv(current_task_file, index=False) |
|
st.download_button( |
|
label="Download Current Task as CSV", |
|
data=open(current_task_file, "rb").read(), |
|
file_name="current_task.csv", |
|
mime="text/csv" |
|
) |
|
|
|
|
|
st.subheader("Send Email to Team Member") |
|
email_recipient = st.text_input("Email Recipient for Current Task File") |
|
if st.button("Send Current Task File"): |
|
if email_recipient: |
|
send_email( |
|
to_email=email_recipient, |
|
subject=f"Task Assigned: {title}", |
|
body=f"Task '{title}' has been assigned to you. Please find the details attached.", |
|
attachment=current_task_file |
|
) |
|
st.success(f"Current task file sent to {email_recipient}!") |
|
else: |
|
st.error("Please provide an email recipient.") |
|
|
|
|
|
if st.button("Add Task"): |
|
if project and title and team_leader and assigned_to and start_date: |
|
tasks_df = pd.concat([tasks_df, new_task], ignore_index=True) |
|
save_tasks(tasks_df) |
|
st.success(f"Task '{title}' has been added to project '{project}'.") |
|
else: |
|
st.error("Please fill in all required fields.") |
|
|
|
|
|
|
|
|
|
|
|
def view_high_priority(): |
|
st.header("Upcoming Deadlines & High Priority Projects") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
today = date.today() |
|
upcoming_deadlines = df[df["End Date"] >= str(today)].sort_values("End Date") |
|
high_priority = upcoming_deadlines[upcoming_deadlines["Priority"] == "High"] |
|
|
|
if not high_priority.empty: |
|
st.subheader("High Priority Projects") |
|
for i, row in high_priority.iterrows(): |
|
st.text(f"{row['Project Name']} - Deadline: {row['End Date']}") |
|
|
|
st.subheader("Upcoming Deadlines") |
|
for i, row in upcoming_deadlines.iterrows(): |
|
st.text(f"{row['Project Name']} - Deadline: {row['End Date']}") |
|
|
|
|
|
def manage_team(): |
|
st.header("Team Management") |
|
df = load_team() |
|
project = st.selectbox("Assign Team Member to Project", load_projects()["Project Name"]) |
|
member_name = st.text_input("Team Member Name") |
|
role = st.selectbox("Role", ["Project Manager", "Developer", "Designer", "Quality Assurance Specialist QA"]) |
|
|
|
if st.button("Add Member"): |
|
if project and member_name: |
|
new_member = pd.DataFrame({ |
|
"Project Name": [project], |
|
"Member Name": [member_name], |
|
"Role": [role] |
|
}) |
|
df = pd.concat([df, new_member], ignore_index=True) |
|
save_team(df) |
|
st.success(f"Team member '{member_name}' assigned to project '{project}'.") |
|
|
|
if not df.empty: |
|
st.subheader("Team Members") |
|
for i, member in df.iterrows(): |
|
st.text(f"Member: {member['Member Name']} | Role: {member['Role']} | Project: {member['Project Name']}") |
|
|
|
|
|
|
|
|
|
|
|
|
|
project_suggestions = [ |
|
"Machine Learning Model", |
|
"Web Development App", |
|
"Mobile App Development", |
|
"Data Science Pipeline", |
|
"API Development", |
|
"Game Development", |
|
] |
|
|
|
technologies = { |
|
"Machine Learning Model": ["Python", "TensorFlow", "PyTorch", "Scikit-learn"], |
|
"Web Development App": ["HTML", "CSS", "JavaScript", "Django", "Flask"], |
|
"Mobile App Development": ["Flutter", "React Native", "Swift", "Kotlin"], |
|
"Data Science Pipeline": ["Python", "Pandas", "NumPy", "Matplotlib"], |
|
"API Development": ["FastAPI", "Flask", "Express.js", "Django Rest Framework"], |
|
"Game Development": ["Unity", "Unreal Engine", "C#", "Godot"], |
|
} |
|
|
|
|
|
def generate_report(project_name, deadline, progress_data, overall_progress): |
|
doc = Document() |
|
doc.add_heading("Project Report", level=1) |
|
|
|
|
|
doc.add_heading("Project Details", level=2) |
|
doc.add_paragraph(f"Project Name: {project_name}") |
|
doc.add_paragraph(f"Deadline: {deadline}") |
|
doc.add_paragraph(f"Overall Progress: {overall_progress:.2f}%") |
|
|
|
|
|
doc.add_heading("Team Progress", level=2) |
|
table = doc.add_table(rows=1, cols=2) |
|
table.style = "Table Grid" |
|
hdr_cells = table.rows[0].cells |
|
hdr_cells[0].text = "Team Member" |
|
hdr_cells[1].text = "Progress (%)" |
|
for progress in progress_data: |
|
row_cells = table.add_row().cells |
|
row_cells[0].text = progress["Member"] |
|
row_cells[1].text = f"{progress['Progress (%)']}%" |
|
|
|
|
|
file_name = f"{project_name.replace(' ', '_')}_Report.docx" |
|
doc.save(file_name) |
|
return file_name |
|
|
|
|
|
def create_download_link(file_path): |
|
with open(file_path, "rb") as file: |
|
file_bytes = file.read() |
|
b64 = base64.b64encode(file_bytes).decode() |
|
href = f'<a href="data:application/octet-stream;base64,{b64}" download="{os.path.basename(file_path)}">Download Report</a>' |
|
return href |
|
|
|
|
|
def send_email_with_report(receiver_email, subject, body, file_path): |
|
sender_email = "[email protected]" |
|
msg = MIMEMultipart() |
|
msg["From"] = sender_email |
|
msg["To"] = receiver_email |
|
msg["Subject"] = subject |
|
|
|
|
|
msg.attach(MIMEText(body, "plain")) |
|
|
|
|
|
with open(file_path, "rb") as attachment: |
|
part = MIMEBase("application", "octet-stream") |
|
part.set_payload(attachment.read()) |
|
encoders.encode_base64(part) |
|
part.add_header( |
|
"Content-Disposition", |
|
f"attachment; filename= {os.path.basename(file_path)}", |
|
) |
|
msg.attach(part) |
|
|
|
|
|
try: |
|
with smtplib.SMTP("smtp.gmail.com", 587) as server: |
|
server.starttls() |
|
server.sendmail(sender_email, receiver_email, msg.as_string()) |
|
return f"Email sent successfully to {receiver_email}!" |
|
except Exception as e: |
|
return f"Failed to send email: {e}" |
|
|
|
|
|
def project_progress(): |
|
st.title("Project Progress Tracking") |
|
|
|
|
|
project = st.selectbox("Select a Project", project_suggestions) |
|
technologies_used = ", ".join(technologies[project]) |
|
st.write(f"Technologies: {technologies_used}") |
|
|
|
|
|
deadline = st.date_input(f"Set a deadline for {project}") |
|
progress_data = [] |
|
team_size = st.number_input(f"Enter number of team members for {project}", min_value=1, step=1) |
|
for i in range(team_size): |
|
member = st.text_input(f"Enter team member {i+1} name") |
|
progress = st.slider(f"Progress by {member} (%)", 0, 100, 0) |
|
email = st.text_input(f"Email for {member}") |
|
progress_data.append({"Member": member, "Progress (%)": progress, "Email": email}) |
|
|
|
|
|
progress_df = pd.DataFrame(progress_data) |
|
overall_progress = progress_df["Progress (%)"].mean() |
|
st.progress(overall_progress / 100) |
|
st.write(f"Overall Progress: {overall_progress:.2f}%") |
|
|
|
|
|
if st.button("Generate Report"): |
|
report_file = generate_report(project, deadline, progress_data, overall_progress) |
|
st.success(f"Report saved as {report_file}") |
|
st.markdown(create_download_link(report_file), unsafe_allow_html=True) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def set_milestones(): |
|
st.header("Set Milestones") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Milestone", df["Project Name"]) |
|
milestone = st.text_input("Milestone Name") |
|
milestone_date = st.date_input("Milestone Date") |
|
|
|
if st.button("Add Milestone"): |
|
if project and milestone: |
|
st.success(f"Milestone '{milestone}' added to project '{project}' for {milestone_date}.") |
|
else: |
|
st.error("Please complete the milestone details.") |
|
|
|
|
|
def time_tracking(): |
|
st.header("Time Tracking") |
|
project = st.selectbox("Select Project", load_projects()["Project Name"]) |
|
hours_logged = st.number_input("Hours Worked", min_value=0) |
|
|
|
if st.button("Log Time"): |
|
if project: |
|
st.success(f"{hours_logged} hours logged for project '{project}'.") |
|
|
|
|
|
def document_upload(): |
|
st.header("Document Upload") |
|
project = st.selectbox("Select Project for Document Upload", load_projects()["Project Name"]) |
|
uploaded_file = st.file_uploader("Upload Document", type=["pdf", "docx", "txt"]) |
|
|
|
if uploaded_file is not None: |
|
st.success(f"Document uploaded to project '{project}'.") |
|
|
|
|
|
def project_tags(): |
|
st.header("Project Tags & Categories") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Tagging", df["Project Name"]) |
|
tags = st.text_input("Tags (comma-separated)") |
|
|
|
if st.button("Add Tags"): |
|
if tags: |
|
df.loc[df["Project Name"] == project, "Tags"] = tags |
|
save_projects(df) |
|
st.success(f"Tags updated for project '{project}'.") |
|
|
|
|
|
def analytics(): |
|
st.header("Project Analytics and Reports") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No data available.") |
|
return |
|
|
|
st.subheader("Projects by Priority") |
|
priority_counts = df["Priority"].value_counts() |
|
st.bar_chart(priority_counts) |
|
|
|
st.subheader("Project Progress Overview") |
|
st.line_chart(df["Progress"]) |
|
|
|
|
|
def calendar_view(): |
|
st.header("Project Calendar View") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects to display on the calendar.") |
|
return |
|
|
|
st.subheader("Upcoming Deadlines") |
|
for i, row in df.iterrows(): |
|
st.text(f"{row['Project Name']} - End Date: {row['End Date']}") |
|
|
|
def automated_notifications(): |
|
st.header("Automated Notifications") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
today = date.today() |
|
notification_list = [] |
|
|
|
|
|
for _, row in df.iterrows(): |
|
days_left = (pd.to_datetime(row['End Date']) - pd.to_datetime(today)).days |
|
if days_left <= 7 or row['Priority'] == 'High': |
|
notification_list.append(f"{row['Project Name']} - {days_left} days remaining") |
|
|
|
if notification_list: |
|
st.subheader("Notifications") |
|
for notification in notification_list: |
|
st.warning(notification) |
|
else: |
|
st.info("No upcoming deadlines or high-priority tasks.") |
|
|
|
|
|
|
|
def search_and_filter_projects(): |
|
st.header("Search and Filter Projects") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
|
|
search_query = st.text_input("Search by Project Name or Description") |
|
|
|
|
|
filter_priority = st.selectbox("Filter by Priority", ["All", "Low", "Medium", "High"]) |
|
filter_status = st.selectbox("Filter by Status", ["All", "Completed", "Uncompleted"]) |
|
|
|
|
|
if search_query: |
|
df = df[df["Project Name"].str.contains(search_query, case=False) | df["Description"].str.contains(search_query, case=False)] |
|
if filter_priority != "All": |
|
df = df[df["Priority"] == filter_priority] |
|
if filter_status != "All": |
|
df = df[df["Status"] == filter_status] |
|
|
|
if df.empty: |
|
st.info("No projects matched the search criteria.") |
|
else: |
|
st.write(df) |
|
|
|
|
|
def backup_and_restore(): |
|
st.header("Backup and Restore") |
|
|
|
|
|
if st.button("Backup Data"): |
|
df = load_projects() |
|
if not df.empty: |
|
df.to_csv('project_backup.csv', index=False) |
|
st.success("Project data backed up successfully.") |
|
else: |
|
st.info("No data to back up.") |
|
|
|
|
|
uploaded_file = st.file_uploader("Upload Backup File", type=["csv"]) |
|
if uploaded_file is not None: |
|
restored_df = pd.read_csv(uploaded_file) |
|
save_projects(restored_df) |
|
st.success("Project data restored successfully.") |
|
|
|
|
|
def customize_status(): |
|
st.header("Customizable Project Status Options") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project to Change Status", df["Project Name"]) |
|
new_status = st.text_input("Enter New Status (e.g., In Progress, Pending, On Hold)") |
|
|
|
if st.button("Update Status"): |
|
if project and new_status: |
|
df.loc[df["Project Name"] == project, "Status"] = new_status |
|
save_projects(df) |
|
st.success(f"Status updated for project '{project}' to '{new_status}'.") |
|
|
|
|
|
def project_templates(): |
|
st.header("Project Templates") |
|
templates = { |
|
"Software Development": { |
|
"Description": "Developing a software application.", |
|
"Start Date": date.today(), |
|
"End Date": date.today(), |
|
"Priority": "High", |
|
"Status": "Uncompleted" |
|
}, |
|
"Marketing Campaign": { |
|
"Description": "Executing a marketing strategy.", |
|
"Start Date": date.today(), |
|
"End Date": date.today(), |
|
"Priority": "Medium", |
|
"Status": "Uncompleted" |
|
} |
|
} |
|
|
|
selected_template = st.selectbox("Choose a Template", list(templates.keys())) |
|
template_data = templates[selected_template] |
|
|
|
if st.button("Create Project from Template"): |
|
df = load_projects() |
|
new_project = pd.DataFrame(template_data, index=[0]) |
|
df = pd.concat([df, new_project], ignore_index=True) |
|
save_projects(df) |
|
st.success(f"Project created from template: {selected_template}") |
|
|
|
|
|
def budget_tracking(): |
|
st.header("Budget Tracking") |
|
df = load_projects() |
|
|
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Budget Tracking", df["Project Name"]) |
|
budget = st.number_input("Set Budget (in PKR)", min_value=0) |
|
expenses = st.number_input("Enter Expenses (in PKR)", min_value=0) |
|
|
|
if st.button("Update Budget"): |
|
|
|
df.loc[df["Project Name"] == project, "Budget"] = budget |
|
df.loc[df["Project Name"] == project, "Expenses"] = expenses |
|
save_projects(df) |
|
st.success(f"Budget and expenses updated for project '{project}'.") |
|
|
|
|
|
st.subheader("Project Budgets") |
|
for _, row in df.iterrows(): |
|
budget = row.get("Budget", 0) |
|
expenses = row.get("Expenses", 0) |
|
remaining_budget = budget - expenses |
|
|
|
if remaining_budget > 0: |
|
status = "Profit" |
|
amount = remaining_budget |
|
else: |
|
status = "Loss" |
|
amount = -remaining_budget |
|
|
|
st.write( |
|
f"{row['Project Name']} - Budget: {budget}, Expenses: {expenses}, " |
|
f"Remaining: {remaining_budget} ({status}: {amount})" |
|
) |
|
|
|
|
|
st.subheader("Download Budget Reports") |
|
|
|
|
|
current_project_data = df[df["Project Name"] == project] |
|
if not current_project_data.empty: |
|
current_csv = current_project_data.to_csv(index=False) |
|
st.download_button( |
|
label=f"Download Current Budget ({project})", |
|
data=current_csv, |
|
file_name=f"{project}_budget.csv", |
|
mime="text/csv", |
|
) |
|
|
|
|
|
overall_project_data = df[df["Project Name"] == project][["Project Name", "Budget", "Expenses"]] |
|
if not overall_project_data.empty: |
|
overall_csv = overall_project_data.to_csv(index=False) |
|
st.download_button( |
|
label=f"Download Overall Budget for {project}", |
|
data=overall_csv, |
|
file_name=f"{project}_overall_budget.csv", |
|
mime="text/csv", |
|
) |
|
|
|
|
|
all_csv = df.to_csv(index=False) |
|
st.download_button( |
|
label="Download All Projects Budget", |
|
data=all_csv, |
|
file_name="all_projects_budget.csv", |
|
mime="text/csv", |
|
) |
|
|
|
|
|
|
|
|
|
|
|
def comments_and_notes(): |
|
st.header("Comments and Notes") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project to Comment On", df["Project Name"]) |
|
comment = st.text_area("Add Comment/Note") |
|
|
|
if st.button("Add Comment"): |
|
df.loc[df["Project Name"] == project, "Comments"] = df.loc[df["Project Name"] == project, "Comments"].fillna("") + comment + "\n" |
|
save_projects(df) |
|
st.success(f"Comment added to project '{project}'.") |
|
|
|
|
|
st.subheader("Project Comments") |
|
for _, row in df.iterrows(): |
|
comments = row.get("Comments", "No comments yet.") |
|
st.write(f"{row['Project Name']} - Comments:\n{comments}") |
|
|
|
|
|
def prioritization_metrics(): |
|
st.header("Prioritization Metrics") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Prioritization", df["Project Name"]) |
|
impact = st.slider("Impact", min_value=1, max_value=10) |
|
cost = st.slider("Cost", min_value=1, max_value=10) |
|
urgency = st.slider("Urgency", min_value=1, max_value=10) |
|
overall_priority = (impact * 0.5) + (urgency * 0.3) + (10 - cost) * 0.2 |
|
|
|
if st.button("Set Prioritization Metrics"): |
|
df.loc[df["Project Name"] == project, "Impact"] = impact |
|
df.loc[df["Project Name"] == project, "Cost"] = cost |
|
df.loc[df["Project Name"] == project, "Urgency"] = urgency |
|
df.loc[df["Project Name"] == project, "Priority Score"] = overall_priority |
|
save_projects(df) |
|
st.success(f"Prioritization metrics set for project '{project}'.") |
|
|
|
|
|
st.subheader("Project Prioritization Scores") |
|
for _, row in df.iterrows(): |
|
priority_score = row.get("Priority Score", "Not set") |
|
st.write(f"{row['Project Name']} - Priority Score: {priority_score}") |
|
|
|
|
|
def calendar_view(): |
|
st.header("Calendar View") |
|
import plotly.express as px |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
|
|
df["Start Date"] = pd.to_datetime(df["Start Date"]) |
|
df["End Date"] = pd.to_datetime(df["End Date"]) |
|
|
|
|
|
fig = px.timeline(df, x_start="Start Date", x_end="End Date", y="Project Name", color="Priority", |
|
title="Project Calendar View", labels={"Priority": "Priority Level"}) |
|
fig.update_yaxes(categoryorder="total ascending") |
|
st.plotly_chart(fig) |
|
|
|
def automated_notifications(): |
|
st.header("Automated Notifications") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
today = date.today() |
|
notifications = [] |
|
|
|
|
|
for _, row in df.iterrows(): |
|
end_date = pd.to_datetime(row["End Date"]) |
|
days_to_deadline = (end_date - today).days |
|
if days_to_deadline == 7: |
|
notifications.append(f"Project '{row['Project Name']}' is due in 7 days!") |
|
elif days_to_deadline == 1: |
|
notifications.append(f"Project '{row['Project Name']}' is due tomorrow!") |
|
elif days_to_deadline == 0: |
|
notifications.append(f"Project '{row['Project Name']}' is due today!") |
|
|
|
|
|
if notifications: |
|
st.subheader("Notifications") |
|
for notification in notifications: |
|
st.warning(notification) |
|
else: |
|
st.info("No notifications for upcoming deadlines.") |
|
|
|
|
|
def search_and_filter_projects(): |
|
st.header("Search and Filter Projects") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
search_term = st.text_input("Search by Project Name or Description") |
|
priority_filter = st.selectbox("Filter by Priority", ["All", "Low", "Medium", "High"]) |
|
status_filter = st.selectbox("Filter by Status", ["All", "Completed", "Uncompleted"]) |
|
|
|
if search_term: |
|
df = df[df["Project Name"].str.contains(search_term, case=False) | df["Description"].str.contains(search_term, case=False)] |
|
|
|
if priority_filter != "All": |
|
df = df[df["Priority"] == priority_filter] |
|
|
|
if status_filter != "All": |
|
df = df[df["Status"] == status_filter] |
|
|
|
if df.empty: |
|
st.info("No projects match the search criteria.") |
|
else: |
|
st.subheader("Search Results") |
|
for _, row in df.iterrows(): |
|
st.write(f"**{row['Project Name']}** - Priority: {row['Priority']}, Status: {row['Status']}") |
|
|
|
|
|
def backup_and_restore(): |
|
st.header("Backup and Restore") |
|
df = load_projects() |
|
|
|
if st.button("Backup Project Data"): |
|
backup_file = PROJECT_DATA_FILE.replace(".csv", "_backup.csv") |
|
df.to_csv(backup_file, index=False) |
|
st.success(f"Backup created as {backup_file}") |
|
|
|
uploaded_file = st.file_uploader("Restore from Backup", type=["csv"]) |
|
if uploaded_file: |
|
df_backup = pd.read_csv(uploaded_file) |
|
save_projects(df_backup) |
|
st.success("Project data restored from backup.") |
|
|
|
|
|
def customize_status(): |
|
st.header("Customize Project Status Options") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project to Update Status", df["Project Name"]) |
|
status_options = ["In Progress", "Pending", "On Hold", "Completed", "Uncompleted"] |
|
custom_status = st.selectbox("Set Custom Status", status_options) |
|
|
|
if st.button("Update Status"): |
|
df.loc[df["Project Name"] == project, "Status"] = custom_status |
|
save_projects(df) |
|
st.success(f"Status of '{project}' updated to '{custom_status}'") |
|
|
|
|
|
def project_templates(): |
|
st.header("Project Templates") |
|
template_name = st.selectbox("Select Template", ["Software Development", "Marketing Campaign", "Research Project", "Event Planning", "Custom"]) |
|
|
|
if template_name != "Custom": |
|
template_description = { |
|
"Software Development": "Developing a software application with multiple phases, from requirements gathering to deployment.", |
|
"Marketing Campaign": "Organizing and launching a marketing campaign, including content creation and social media promotion.", |
|
"Research Project": "Conducting research, including literature review, data collection, analysis, and reporting.", |
|
"Event Planning": "Planning and organizing an event, including venue booking, logistics, and promotions." |
|
}.get(template_name, "A general project template.") |
|
else: |
|
template_description = st.text_area("Custom Project Description") |
|
|
|
if st.button("Create Project from Template"): |
|
new_project = pd.DataFrame({ |
|
"Project Name": [template_name + " Project"], |
|
"Description": [template_description], |
|
"Start Date": [date.today()], |
|
"End Date": [date.today()], |
|
"Priority": ["Medium"], |
|
"Status": ["Uncompleted"] |
|
}) |
|
|
|
df = load_projects() |
|
df = pd.concat([df, new_project], ignore_index=True) |
|
save_projects(df) |
|
st.success(f"Project '{template_name} Project' created from template.") |
|
|
|
|
|
|
|
|
|
|
|
|
|
def comments_and_notes(): |
|
st.header("Project Comments & Notes") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project", df["Project Name"]) |
|
note = st.text_area("Add a Comment or Note") |
|
|
|
if st.button("Add Note"): |
|
df.loc[df["Project Name"] == project, "Notes"] = df.loc[df["Project Name"] == project].get("Notes", "") + "\n" + note |
|
save_projects(df) |
|
st.success(f"Note added to '{project}'") |
|
|
|
st.subheader("Project Notes") |
|
for i, row in df.iterrows(): |
|
if "Notes" in row and row["Notes"]: |
|
st.write(f"**{row['Project Name']}** Notes:\n{row['Notes']}") |
|
|
|
|
|
def calendar_view(): |
|
st.header("Project Calendar View") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
st.write("**Project Deadlines and Timelines**") |
|
for i, row in df.iterrows(): |
|
st.write(f"{row['Project Name']} - **Start:** {row['Start Date']} **End:** {row['End Date']}") |
|
|
|
|
|
|
|
def prioritization_metrics(): |
|
st.header("Prioritization Metrics") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
priority_metric = st.selectbox("Set Prioritization Criteria", ["Impact", "Cost", "Deadline"]) |
|
st.write(f"Projects prioritized by {priority_metric}") |
|
|
|
|
|
if priority_metric == "Impact": |
|
df = df.sort_values("Priority", ascending=False) |
|
elif priority_metric == "Cost": |
|
df = df.sort_values("Budget", ascending=True) |
|
elif priority_metric == "Deadline": |
|
df = df.sort_values("End Date") |
|
|
|
for i, row in df.iterrows(): |
|
st.write(f"{row['Project Name']} - Priority: {row['Priority']} - Deadline: {row['End Date']}") |
|
|
|
def customizable_status_options(): |
|
st.header("Customizable Status Options") |
|
df = load_projects() |
|
|
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
|
|
project = st.selectbox("Select Project", df["Project Name"].unique()) |
|
custom_status = st.text_input("Enter New Status (e.g., In Progress, On Hold)") |
|
|
|
if st.button("Update Status"): |
|
if custom_status: |
|
df.loc[df["Project Name"] == project, "Status"] = custom_status |
|
save_projects(df) |
|
st.success(f"Status for '{project}' updated to '{custom_status}'.") |
|
else: |
|
st.warning("Please enter a valid status.") |
|
|
|
|
|
def comments_and_notes(): |
|
st.header("Comments and Notes") |
|
df = load_projects() |
|
|
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Comments", df["Project Name"].unique()) |
|
comment = st.text_area("Add Comment or Note") |
|
|
|
if st.button("Submit Comment"): |
|
if comment: |
|
comments_file = f"{project}_comments.txt" |
|
with open(comments_file, "a") as file: |
|
file.write(f"{comment}\n") |
|
st.success("Comment added successfully!") |
|
else: |
|
st.warning("Please enter a comment.") |
|
|
|
|
|
if os.path.exists(f"{project}_comments.txt"): |
|
st.subheader("Existing Comments") |
|
with open(f"{project}_comments.txt", "r") as file: |
|
comments = file.readlines() |
|
for c in comments: |
|
st.text(c.strip()) |
|
|
|
|
|
def automated_notifications(): |
|
st.header("Automated Notifications") |
|
df = load_projects() |
|
|
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
today = date.today() |
|
upcoming_deadlines = df[(pd.to_datetime(df['End Date']) >= today) & (pd.to_datetime(df['End Date']) <= today + pd.Timedelta(days=7))] |
|
|
|
if not upcoming_deadlines.empty: |
|
st.warning("Upcoming Deadlines:") |
|
for i, row in upcoming_deadlines.iterrows(): |
|
st.text(f"{row['Project Name']} - Due on {row['End Date']}") |
|
|
|
st.success("Notifications are enabled for approaching deadlines and updates.") |
|
|
|
|
|
def team_collaboration(): |
|
st.header("Team Collaboration") |
|
df = load_projects() |
|
|
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Team Collaboration", df["Project Name"].unique()) |
|
member_name = st.text_input("Team Member Name") |
|
role = st.selectbox("Role", ["Team Member", "Project Manager", "Viewer"]) |
|
|
|
if st.button("Add Team Member"): |
|
if member_name: |
|
team_file = f"{project}_team.csv" |
|
if os.path.exists(team_file): |
|
team_df = pd.read_csv(team_file) |
|
else: |
|
team_df = pd.DataFrame(columns=["Member Name", "Role"]) |
|
|
|
new_member = pd.DataFrame({"Member Name": [member_name], "Role": [role]}) |
|
team_df = pd.concat([team_df, new_member], ignore_index=True) |
|
team_df.to_csv(team_file, index=False) |
|
st.success(f"{member_name} added to the project as {role}!") |
|
else: |
|
st.warning("Please enter a team member's name.") |
|
|
|
|
|
if os.path.exists(f"{project}_team.csv"): |
|
st.subheader("Current Team Members") |
|
team_df = pd.read_csv(f"{project}_team.csv") |
|
st.dataframe(team_df) |
|
|
|
def gantt_chart_visualization(): |
|
st.header("Gantt Chart Visualization") |
|
df = load_projects() |
|
|
|
if df.empty: |
|
st.info("No projects available to display in Gantt chart.") |
|
return |
|
|
|
|
|
df['Start Date'] = pd.to_datetime(df['Start Date']) |
|
df['End Date'] = pd.to_datetime(df['End Date']) |
|
df['Duration'] = (df['End Date'] - df['Start Date']).dt.days |
|
|
|
chart = alt.Chart(df).mark_bar().encode( |
|
x='Start Date:T', |
|
x2='End Date:T', |
|
y=alt.Y('Project Name', sort=alt.SortField("Start Date", order="ascending")), |
|
color='Priority' |
|
).properties(width=600, height=400) |
|
|
|
st.altair_chart(chart) |
|
|
|
|
|
def manage_task_dependencies(): |
|
st.header("Manage Task Dependencies") |
|
project_name = st.selectbox("Select Project", load_projects()["Project Name"].unique()) |
|
task_name = st.text_input("Task Name") |
|
dependency_task = st.selectbox("Select Prerequisite Task", load_projects()["Project Name"].unique()) |
|
|
|
if st.button("Set Dependency"): |
|
if task_name and dependency_task: |
|
dependencies_file = f"{project_name}_dependencies.csv" |
|
if os.path.exists(dependencies_file): |
|
dependencies_df = pd.read_csv(dependencies_file) |
|
else: |
|
dependencies_df = pd.DataFrame(columns=["Task", "Dependency"]) |
|
|
|
new_dependency = pd.DataFrame({"Task": [task_name], "Dependency": [dependency_task]}) |
|
dependencies_df = pd.concat([dependencies_df, new_dependency], ignore_index=True) |
|
dependencies_df.to_csv(dependencies_file, index=False) |
|
st.success("Dependency added successfully!") |
|
else: |
|
st.warning("Please enter both the task name and prerequisite task.") |
|
|
|
if os.path.exists(f"{project_name}_dependencies.csv"): |
|
st.subheader("Existing Dependencies") |
|
dependencies_df = pd.read_csv(f"{project_name}_dependencies.csv") |
|
st.dataframe(dependencies_df) |
|
|
|
|
|
def resource_management(): |
|
st.header("Resource Management") |
|
df = load_projects() |
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Resource Allocation", df["Project Name"].unique()) |
|
resource_name = st.text_input("Resource Name") |
|
allocation_percentage = st.slider("Resource Allocation Percentage", 0, 100, 50) |
|
|
|
if st.button("Allocate Resource"): |
|
if resource_name: |
|
resource_file = f"{project}_resources.csv" |
|
if os.path.exists(resource_file): |
|
resource_df = pd.read_csv(resource_file) |
|
else: |
|
resource_df = pd.DataFrame(columns=["Resource Name", "Allocation (%)"]) |
|
|
|
new_resource = pd.DataFrame({"Resource Name": [resource_name], "Allocation (%)": [allocation_percentage]}) |
|
resource_df = pd.concat([resource_df, new_resource], ignore_index=True) |
|
resource_df.to_csv(resource_file, index=False) |
|
st.success(f"{resource_name} allocated to '{project}'!") |
|
else: |
|
st.warning("Please enter the resource name.") |
|
|
|
if os.path.exists(f"{project}_resources.csv"): |
|
st.subheader("Allocated Resources") |
|
resource_df = pd.read_csv(f"{project}_resources.csv") |
|
st.dataframe(resource_df) |
|
|
|
|
|
def risk_management(): |
|
st.header("Risk Management and Mitigation Tracking") |
|
df = load_projects() |
|
|
|
if df.empty: |
|
st.info("No projects available.") |
|
return |
|
|
|
project = st.selectbox("Select Project for Risk Management", df["Project Name"].unique()) |
|
risk_description = st.text_input("Risk Description") |
|
risk_level = st.selectbox("Risk Level", ["Low", "Medium", "High"]) |
|
mitigation_strategy = st.text_area("Mitigation Strategy") |
|
|
|
if st.button("Log Risk"): |
|
if risk_description and mitigation_strategy: |
|
risk_file = f"{project}_risks.csv" |
|
if os.path.exists(risk_file): |
|
risk_df = pd.read_csv(risk_file) |
|
else: |
|
risk_df = pd.DataFrame(columns=["Risk Description", "Risk Level", "Mitigation Strategy"]) |
|
|
|
new_risk = pd.DataFrame({ |
|
"Risk Description": [risk_description], |
|
"Risk Level": [risk_level], |
|
"Mitigation Strategy": [mitigation_strategy] |
|
}) |
|
risk_df = pd.concat([risk_df, new_risk], ignore_index=True) |
|
risk_df.to_csv(risk_file, index=False) |
|
st.success(f"Risk added to '{project}'!") |
|
else: |
|
st.warning("Please complete all fields to log a risk.") |
|
|
|
if os.path.exists(f"{project}_risks.csv"): |
|
st.subheader("Logged Risks") |
|
risk_df = pd.read_csv(f"{project}_risks.csv") |
|
st.dataframe(risk_df) |
|
|
|
|
|
def integration_with_third_party_tools(): |
|
st.header("Integration with Third-Party Tools") |
|
st.info("Here, you can integrate with various third-party tools like Slack, Trello, or Google Workspace.") |
|
|
|
tool = st.selectbox("Select Tool to Integrate", ["Slack", "GitHub", "Trello", "Google Workspace"]) |
|
if st.button("Integrate"): |
|
st.success(f"{tool} has been integrated successfully! (Simulated)") |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import streamlit as st |
|
|
|
|
|
|
|
|
|
menu = st.sidebar.radio( |
|
"Menu", [ |
|
"Home", "Add Project", "Edit Project", "Delete Project", |
|
"Task Management", "High Priority & Deadlines", |
|
"Project Progress Tracking", |
|
|
|
"Analytics & Reports", "Calendar View", |
|
"Search and Filter", "Budget Tracking", |
|
"Comments and Notes", "Prioritization Metrics", |
|
"Gantt Chart Visualization", |
|
"Resource Management", "Risk Management" |
|
] |
|
) |
|
|
|
|
|
if menu == "Home": |
|
home() |
|
elif menu == "Add Project": |
|
add_project() |
|
elif menu == "Edit Project": |
|
edit_project() |
|
elif menu == "Delete Project": |
|
delete_project() |
|
elif menu == "Task Management": |
|
manage_tasks() |
|
elif menu == "High Priority & Deadlines": |
|
view_high_priority() |
|
|
|
|
|
elif menu == "Project Progress Tracking": |
|
project_progress() |
|
|
|
|
|
|
|
|
|
|
|
|
|
elif menu == "Analytics & Reports": |
|
analytics() |
|
elif menu == "Calendar View": |
|
calendar_view() |
|
elif menu == "Search and Filter": |
|
search_and_filter_projects() |
|
|
|
|
|
|
|
|
|
elif menu == "Budget Tracking": |
|
budget_tracking() |
|
elif menu == "Comments and Notes": |
|
comments_and_notes() |
|
elif menu == "Prioritization Metrics": |
|
prioritization_metrics() |
|
elif menu == "Gantt Chart Visualization": |
|
gantt_chart_visualization() |
|
|
|
|
|
elif menu == "Resource Management": |
|
resource_management() |
|
elif menu == "Risk Management": |
|
risk_management() |
|
|
|
|
|
|
|
|
|
|