Spaces:
Sleeping
Sleeping
MansoorSarookh
commited on
Update app.py
Browse files
app.py
CHANGED
@@ -7,10 +7,18 @@ import smtplib
|
|
7 |
from email.mime.text import MIMEText
|
8 |
import base64
|
9 |
|
|
|
|
|
10 |
from docx import Document
|
|
|
|
|
11 |
from email.mime.multipart import MIMEMultipart
|
|
|
12 |
from email import encoders
|
13 |
import os
|
|
|
|
|
|
|
14 |
from email.mime.multipart import MIMEMultipart
|
15 |
|
16 |
# File to store project data
|
@@ -58,13 +66,15 @@ def save_team(df):
|
|
58 |
|
59 |
|
60 |
|
|
|
61 |
import streamlit as st
|
62 |
|
63 |
def home():
|
64 |
st.title("Welcome to the Project Management Tool")
|
65 |
st.markdown("""
|
66 |
## About the Tool
|
67 |
-
The **Project Management Tool** is a comprehensive solution built specifically for **Admins** and **Project Managers** in small
|
|
|
68 |
|
69 |
### Key Features:
|
70 |
- **Add, Edit, and Delete Projects:** Easily create, modify, or remove projects.
|
@@ -84,7 +94,7 @@ def home():
|
|
84 |
|
85 |
### Why Choose This Tool?
|
86 |
- Specifically designed for **Admins** and **Project Managers**.
|
87 |
-
- Tailored for small
|
88 |
- Focused on streamlining project workflows and improving efficiency.
|
89 |
""")
|
90 |
|
@@ -160,8 +170,6 @@ def add_project():
|
|
160 |
else:
|
161 |
st.error("Please fill in all fields")
|
162 |
|
163 |
-
|
164 |
-
|
165 |
# Edit project with suggestions and technology update
|
166 |
def edit_project():
|
167 |
st.header("Edit Project")
|
@@ -238,29 +246,36 @@ def delete_project():
|
|
238 |
save_projects(df)
|
239 |
st.success(f"Project '{project}' has been deleted.")
|
240 |
|
241 |
-
|
242 |
-
# for notifications purpose
|
243 |
-
|
244 |
-
|
245 |
|
246 |
# Function to send email
|
247 |
-
def send_email(to_email, subject, body):
|
248 |
from_email = "[email protected]" # Replace with your email
|
249 |
password = "your_password" # Replace with your email app password
|
250 |
try:
|
251 |
server = smtplib.SMTP('smtp.gmail.com', 587)
|
252 |
server.starttls()
|
253 |
server.login(from_email, password)
|
254 |
-
msg =
|
255 |
msg['Subject'] = subject
|
256 |
msg['From'] = from_email
|
257 |
msg['To'] = to_email
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
258 |
server.sendmail(from_email, to_email, msg.as_string())
|
259 |
server.quit()
|
260 |
except Exception as e:
|
261 |
print(f"Failed to send email: {e}")
|
262 |
|
263 |
-
|
264 |
# Task management within each project
|
265 |
def manage_tasks():
|
266 |
st.header("Task Management")
|
@@ -298,49 +313,66 @@ def manage_tasks():
|
|
298 |
tags = st.multiselect("Tags/Labels", ["Design", "Development", "Testing", "Research", "Bug Fixing"])
|
299 |
team_leader = st.selectbox("Team Leader", team_members.get(project, []))
|
300 |
assigned_to = st.multiselect("Assigned Team Members", team_members.get(project, []))
|
|
|
301 |
deadline = st.date_input("Deadline")
|
302 |
|
303 |
-
#
|
304 |
-
|
305 |
-
|
306 |
-
|
307 |
-
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
314 |
|
315 |
# Add task button
|
316 |
if st.button("Add Task"):
|
317 |
-
if project and title and team_leader and assigned_to:
|
318 |
-
new_task = pd.DataFrame({
|
319 |
-
"Project Name": [project],
|
320 |
-
"Task Title": [title],
|
321 |
-
"Description": [description],
|
322 |
-
"Priority": [priority if priority != "Custom" else custom_priority],
|
323 |
-
"Tags": [", ".join(tags)],
|
324 |
-
"Team Leader": [team_leader],
|
325 |
-
"Assigned To": [", ".join(assigned_to)],
|
326 |
-
"Deadline": [deadline],
|
327 |
-
"Status": ["Uncompleted"]
|
328 |
-
})
|
329 |
tasks_df = pd.concat([tasks_df, new_task], ignore_index=True)
|
330 |
save_tasks(tasks_df)
|
331 |
st.success(f"Task '{title}' has been added to project '{project}'.")
|
332 |
-
|
333 |
-
# Send email notification to each assigned member after adding the task
|
334 |
-
for member in assigned_to:
|
335 |
-
member_email = f"{member}@gmail.com" # Assuming team members use gmail
|
336 |
-
subject = f"New Task Assigned: {title}"
|
337 |
-
body = f"You have been assigned a new task '{title}' in project '{project}'."
|
338 |
-
send_email(member_email, subject, body)
|
339 |
-
|
340 |
else:
|
341 |
st.error("Please fill in all required fields.")
|
342 |
|
343 |
|
|
|
|
|
344 |
# View project deadlines and high-priority projects
|
345 |
def view_high_priority():
|
346 |
st.header("Upcoming Deadlines & High Priority Projects")
|
@@ -390,8 +422,6 @@ def manage_team():
|
|
390 |
|
391 |
|
392 |
|
393 |
-
# MODIFIED PROJECT PROGRESS
|
394 |
-
|
395 |
# Predefined Data
|
396 |
project_suggestions = [
|
397 |
"Machine Learning Model",
|
@@ -509,29 +539,28 @@ def project_progress():
|
|
509 |
st.success(f"Report saved as {report_file}")
|
510 |
st.markdown(create_download_link(report_file), unsafe_allow_html=True)
|
511 |
|
512 |
-
# Send the report via email
|
513 |
-
st.subheader("Send Report via Email")
|
514 |
-
recipient_emails = st.text_area("Enter recipient emails (comma-separated)")
|
515 |
-
if st.button("Send Report"):
|
516 |
-
|
517 |
-
|
518 |
-
|
519 |
-
|
520 |
-
|
521 |
-
|
522 |
-
|
523 |
-
|
524 |
-
|
525 |
-
|
526 |
-
|
527 |
-
|
528 |
-
|
|
|
529 |
# project_progress()
|
530 |
|
531 |
|
532 |
|
533 |
-
|
534 |
-
|
535 |
# Set milestones for each project
|
536 |
def set_milestones():
|
537 |
st.header("Set Milestones")
|
@@ -731,31 +760,82 @@ def project_templates():
|
|
731 |
df = pd.concat([df, new_project], ignore_index=True)
|
732 |
save_projects(df)
|
733 |
st.success(f"Project created from template: {selected_template}")
|
734 |
-
|
|
|
735 |
def budget_tracking():
|
736 |
st.header("Budget Tracking")
|
737 |
-
df = load_projects()
|
|
|
738 |
if df.empty:
|
739 |
st.info("No projects available.")
|
740 |
return
|
741 |
|
742 |
project = st.selectbox("Select Project for Budget Tracking", df["Project Name"])
|
743 |
-
budget = st.number_input("Set Budget (in
|
744 |
-
expenses = st.number_input("Enter Expenses (in
|
745 |
|
746 |
if st.button("Update Budget"):
|
|
|
747 |
df.loc[df["Project Name"] == project, "Budget"] = budget
|
748 |
df.loc[df["Project Name"] == project, "Expenses"] = expenses
|
749 |
save_projects(df)
|
750 |
st.success(f"Budget and expenses updated for project '{project}'.")
|
751 |
|
752 |
-
# Display budget status
|
753 |
st.subheader("Project Budgets")
|
754 |
for _, row in df.iterrows():
|
755 |
budget = row.get("Budget", 0)
|
756 |
expenses = row.get("Expenses", 0)
|
757 |
remaining_budget = budget - expenses
|
758 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
759 |
|
760 |
# Comments and Notes
|
761 |
def comments_and_notes():
|
@@ -945,27 +1025,10 @@ def project_templates():
|
|
945 |
df = pd.concat([df, new_project], ignore_index=True)
|
946 |
save_projects(df)
|
947 |
st.success(f"Project '{template_name} Project' created from template.")
|
948 |
-
# Budget Tracking: Set and track budgets for projects
|
949 |
-
def budget_tracking():
|
950 |
-
st.header("Budget Tracking")
|
951 |
-
df = load_projects()
|
952 |
-
if df.empty:
|
953 |
-
st.info("No projects available.")
|
954 |
-
return
|
955 |
|
956 |
-
project = st.selectbox("Select Project", df["Project Name"])
|
957 |
-
budget = st.number_input("Set Project Budget", min_value=0.0, step=100.0)
|
958 |
-
expenses = st.number_input("Record Project Expenses", min_value=0.0, step=100.0)
|
959 |
|
960 |
-
if st.button("Update Budget and Expenses"):
|
961 |
-
df.loc[df["Project Name"] == project, "Budget"] = budget
|
962 |
-
df.loc[df["Project Name"] == project, "Expenses"] = expenses
|
963 |
-
save_projects(df)
|
964 |
-
st.success(f"Budget and expenses for '{project}' updated successfully.")
|
965 |
|
966 |
-
|
967 |
-
for i, row in df.iterrows():
|
968 |
-
st.write(f"**{row['Project Name']}** - Budget: ${row.get('Budget', 'N/A')}, Expenses: ${row.get('Expenses', 'N/A')}")
|
969 |
|
970 |
# Comments and Notes for team collaboration
|
971 |
def comments_and_notes():
|
@@ -1253,6 +1316,16 @@ def integration_with_third_party_tools():
|
|
1253 |
if st.button("Integrate"):
|
1254 |
st.success(f"{tool} has been integrated successfully! (Simulated)")
|
1255 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1256 |
# Add your other function definitions here, like add_project(), edit_project(), etc.
|
1257 |
|
1258 |
# Sidebar menu using radio buttons
|
|
|
7 |
from email.mime.text import MIMEText
|
8 |
import base64
|
9 |
|
10 |
+
# import streamlit as st
|
11 |
+
# import pandas as pd
|
12 |
from docx import Document
|
13 |
+
# import smtplib
|
14 |
+
# from email.mime.text import MIMEText
|
15 |
from email.mime.multipart import MIMEMultipart
|
16 |
+
# from email.mime.base import MIMEBase
|
17 |
from email import encoders
|
18 |
import os
|
19 |
+
|
20 |
+
# import smtplib
|
21 |
+
# from email.mime.text import MIMEText
|
22 |
from email.mime.multipart import MIMEMultipart
|
23 |
|
24 |
# File to store project data
|
|
|
66 |
|
67 |
|
68 |
|
69 |
+
|
70 |
import streamlit as st
|
71 |
|
72 |
def home():
|
73 |
st.title("Welcome to the Project Management Tool")
|
74 |
st.markdown("""
|
75 |
## About the Tool
|
76 |
+
The **Project Management Tool** is a comprehensive solution built specifically for **Admins** and **Project Managers** in small software houses.
|
77 |
+
- It **streamlines workflows, enhances productivity, and ensures smooth project execution.**
|
78 |
|
79 |
### Key Features:
|
80 |
- **Add, Edit, and Delete Projects:** Easily create, modify, or remove projects.
|
|
|
94 |
|
95 |
### Why Choose This Tool?
|
96 |
- Specifically designed for **Admins** and **Project Managers**.
|
97 |
+
- Tailored for small software houses.
|
98 |
- Focused on streamlining project workflows and improving efficiency.
|
99 |
""")
|
100 |
|
|
|
170 |
else:
|
171 |
st.error("Please fill in all fields")
|
172 |
|
|
|
|
|
173 |
# Edit project with suggestions and technology update
|
174 |
def edit_project():
|
175 |
st.header("Edit Project")
|
|
|
246 |
save_projects(df)
|
247 |
st.success(f"Project '{project}' has been deleted.")
|
248 |
|
249 |
+
# THIS IS THE EXACT DESIRE ONE EXCEPT OF THE EMAIL FIELD ALTHOGUH WE CAN SEDN EMAIL SMOOTHLY
|
|
|
|
|
|
|
250 |
|
251 |
# Function to send email
|
252 |
+
def send_email(to_email, subject, body, attachment=None):
|
253 |
from_email = "[email protected]" # Replace with your email
|
254 |
password = "your_password" # Replace with your email app password
|
255 |
try:
|
256 |
server = smtplib.SMTP('smtp.gmail.com', 587)
|
257 |
server.starttls()
|
258 |
server.login(from_email, password)
|
259 |
+
msg = MIMEMultipart()
|
260 |
msg['Subject'] = subject
|
261 |
msg['From'] = from_email
|
262 |
msg['To'] = to_email
|
263 |
+
msg.attach(MIMEText(body, 'plain'))
|
264 |
+
|
265 |
+
# Attach a file if provided
|
266 |
+
if attachment:
|
267 |
+
with open(attachment, "rb") as file:
|
268 |
+
part = MIMEBase("application", "octet-stream")
|
269 |
+
part.set_payload(file.read())
|
270 |
+
encoders.encode_base64(part)
|
271 |
+
part.add_header("Content-Disposition", f"attachment; filename={attachment}")
|
272 |
+
msg.attach(part)
|
273 |
+
|
274 |
server.sendmail(from_email, to_email, msg.as_string())
|
275 |
server.quit()
|
276 |
except Exception as e:
|
277 |
print(f"Failed to send email: {e}")
|
278 |
|
|
|
279 |
# Task management within each project
|
280 |
def manage_tasks():
|
281 |
st.header("Task Management")
|
|
|
313 |
tags = st.multiselect("Tags/Labels", ["Design", "Development", "Testing", "Research", "Bug Fixing"])
|
314 |
team_leader = st.selectbox("Team Leader", team_members.get(project, []))
|
315 |
assigned_to = st.multiselect("Assigned Team Members", team_members.get(project, []))
|
316 |
+
start_date = st.date_input("Start Date") # Start Date feature
|
317 |
deadline = st.date_input("Deadline")
|
318 |
|
319 |
+
# Prepare new task as a DataFrame (temporary)
|
320 |
+
new_task = pd.DataFrame({
|
321 |
+
"Project Name": [project],
|
322 |
+
"Task Title": [title],
|
323 |
+
"Description": [description],
|
324 |
+
"Priority": [priority if priority != "Custom" else custom_priority],
|
325 |
+
"Tags": [", ".join(tags)],
|
326 |
+
"Team Leader": [team_leader],
|
327 |
+
"Assigned To": [", ".join(assigned_to)],
|
328 |
+
"Start Date": [start_date], # Include Start Date
|
329 |
+
"Deadline": [deadline],
|
330 |
+
"Status": ["Uncompleted"]
|
331 |
+
})
|
332 |
+
|
333 |
+
# Show options before adding the task
|
334 |
+
if title and team_leader and assigned_to:
|
335 |
+
st.subheader("Preview Current Task")
|
336 |
+
st.write(new_task)
|
337 |
+
|
338 |
+
# Download Current Task
|
339 |
+
st.subheader("Download Current Task")
|
340 |
+
current_task_file = "current_task.csv"
|
341 |
+
new_task.to_csv(current_task_file, index=False)
|
342 |
+
st.download_button(
|
343 |
+
label="Download Current Task as CSV",
|
344 |
+
data=open(current_task_file, "rb").read(),
|
345 |
+
file_name="current_task.csv",
|
346 |
+
mime="text/csv"
|
347 |
+
)
|
348 |
+
|
349 |
+
# Send Current Task File via Email
|
350 |
+
st.subheader("Send Email to Team Member")
|
351 |
+
email_recipient = st.text_input("Email Recipient for Current Task File")
|
352 |
+
if st.button("Send Current Task File"):
|
353 |
+
if email_recipient:
|
354 |
+
send_email(
|
355 |
+
to_email=email_recipient,
|
356 |
+
subject=f"Task Assigned: {title}",
|
357 |
+
body=f"Task '{title}' has been assigned to you. Please find the details attached.",
|
358 |
+
attachment=current_task_file
|
359 |
+
)
|
360 |
+
st.success(f"Current task file sent to {email_recipient}!")
|
361 |
+
else:
|
362 |
+
st.error("Please provide an email recipient.")
|
363 |
|
364 |
# Add task button
|
365 |
if st.button("Add Task"):
|
366 |
+
if project and title and team_leader and assigned_to and start_date:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
367 |
tasks_df = pd.concat([tasks_df, new_task], ignore_index=True)
|
368 |
save_tasks(tasks_df)
|
369 |
st.success(f"Task '{title}' has been added to project '{project}'.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
else:
|
371 |
st.error("Please fill in all required fields.")
|
372 |
|
373 |
|
374 |
+
|
375 |
+
|
376 |
# View project deadlines and high-priority projects
|
377 |
def view_high_priority():
|
378 |
st.header("Upcoming Deadlines & High Priority Projects")
|
|
|
422 |
|
423 |
|
424 |
|
|
|
|
|
425 |
# Predefined Data
|
426 |
project_suggestions = [
|
427 |
"Machine Learning Model",
|
|
|
539 |
st.success(f"Report saved as {report_file}")
|
540 |
st.markdown(create_download_link(report_file), unsafe_allow_html=True)
|
541 |
|
542 |
+
# # Send the report via email
|
543 |
+
# st.subheader("Send Report via Email")
|
544 |
+
# recipient_emails = st.text_area("Enter recipient emails (comma-separated)")
|
545 |
+
# if st.button("Send Report"):
|
546 |
+
# if report_file:
|
547 |
+
# for email in recipient_emails.split(","):
|
548 |
+
# email_status = send_email_with_report(
|
549 |
+
# email.strip(),
|
550 |
+
# f"Project Report: {project}",
|
551 |
+
# f"Dear Team,\n\nPlease find attached the latest project report for {project}.\n\nBest regards,\nProject Management Team",
|
552 |
+
# report_file,
|
553 |
+
# )
|
554 |
+
# st.write(email_status)
|
555 |
+
# else:
|
556 |
+
# st.error("Please generate the report first!")
|
557 |
+
|
558 |
+
|
559 |
+
# Call the function to display in menu
|
560 |
# project_progress()
|
561 |
|
562 |
|
563 |
|
|
|
|
|
564 |
# Set milestones for each project
|
565 |
def set_milestones():
|
566 |
st.header("Set Milestones")
|
|
|
760 |
df = pd.concat([df, new_project], ignore_index=True)
|
761 |
save_projects(df)
|
762 |
st.success(f"Project created from template: {selected_template}")
|
763 |
+
|
764 |
+
#Budget Tracking
|
765 |
def budget_tracking():
|
766 |
st.header("Budget Tracking")
|
767 |
+
df = load_projects() # Assume this fetches your existing projects data.
|
768 |
+
|
769 |
if df.empty:
|
770 |
st.info("No projects available.")
|
771 |
return
|
772 |
|
773 |
project = st.selectbox("Select Project for Budget Tracking", df["Project Name"])
|
774 |
+
budget = st.number_input("Set Budget (in PKR)", min_value=0)
|
775 |
+
expenses = st.number_input("Enter Expenses (in PKR)", min_value=0)
|
776 |
|
777 |
if st.button("Update Budget"):
|
778 |
+
# Update the budget and expenses for the selected project.
|
779 |
df.loc[df["Project Name"] == project, "Budget"] = budget
|
780 |
df.loc[df["Project Name"] == project, "Expenses"] = expenses
|
781 |
save_projects(df)
|
782 |
st.success(f"Budget and expenses updated for project '{project}'.")
|
783 |
|
784 |
+
# Display budget status with Profit or Loss Calculation
|
785 |
st.subheader("Project Budgets")
|
786 |
for _, row in df.iterrows():
|
787 |
budget = row.get("Budget", 0)
|
788 |
expenses = row.get("Expenses", 0)
|
789 |
remaining_budget = budget - expenses
|
790 |
+
# Calculate profit or loss
|
791 |
+
if remaining_budget > 0:
|
792 |
+
status = "Profit"
|
793 |
+
amount = remaining_budget
|
794 |
+
else:
|
795 |
+
status = "Loss"
|
796 |
+
amount = -remaining_budget # Convert to positive value for loss
|
797 |
+
|
798 |
+
st.write(
|
799 |
+
f"{row['Project Name']} - Budget: {budget}, Expenses: {expenses}, "
|
800 |
+
f"Remaining: {remaining_budget} ({status}: {amount})"
|
801 |
+
)
|
802 |
+
|
803 |
+
# Download options
|
804 |
+
st.subheader("Download Budget Reports")
|
805 |
+
|
806 |
+
# Current project budget
|
807 |
+
current_project_data = df[df["Project Name"] == project]
|
808 |
+
if not current_project_data.empty:
|
809 |
+
current_csv = current_project_data.to_csv(index=False)
|
810 |
+
st.download_button(
|
811 |
+
label=f"Download Current Budget ({project})",
|
812 |
+
data=current_csv,
|
813 |
+
file_name=f"{project}_budget.csv",
|
814 |
+
mime="text/csv",
|
815 |
+
)
|
816 |
+
|
817 |
+
# Overall budgets of the selected project
|
818 |
+
overall_project_data = df[df["Project Name"] == project][["Project Name", "Budget", "Expenses"]]
|
819 |
+
if not overall_project_data.empty:
|
820 |
+
overall_csv = overall_project_data.to_csv(index=False)
|
821 |
+
st.download_button(
|
822 |
+
label=f"Download Overall Budget for {project}",
|
823 |
+
data=overall_csv,
|
824 |
+
file_name=f"{project}_overall_budget.csv",
|
825 |
+
mime="text/csv",
|
826 |
+
)
|
827 |
+
|
828 |
+
# All projects' budgets
|
829 |
+
all_csv = df.to_csv(index=False)
|
830 |
+
st.download_button(
|
831 |
+
label="Download All Projects Budget",
|
832 |
+
data=all_csv,
|
833 |
+
file_name="all_projects_budget.csv",
|
834 |
+
mime="text/csv",
|
835 |
+
)
|
836 |
+
|
837 |
+
|
838 |
+
|
839 |
|
840 |
# Comments and Notes
|
841 |
def comments_and_notes():
|
|
|
1025 |
df = pd.concat([df, new_project], ignore_index=True)
|
1026 |
save_projects(df)
|
1027 |
st.success(f"Project '{template_name} Project' created from template.")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1028 |
|
|
|
|
|
|
|
1029 |
|
|
|
|
|
|
|
|
|
|
|
1030 |
|
1031 |
+
|
|
|
|
|
1032 |
|
1033 |
# Comments and Notes for team collaboration
|
1034 |
def comments_and_notes():
|
|
|
1316 |
if st.button("Integrate"):
|
1317 |
st.success(f"{tool} has been integrated successfully! (Simulated)")
|
1318 |
|
1319 |
+
|
1320 |
+
|
1321 |
+
|
1322 |
+
# #project tags and categories , "Third-Party Integrations", "Automated Notifications", "Backup & Restore",
|
1323 |
+
|
1324 |
+
|
1325 |
+
# for notifications:
|
1326 |
+
|
1327 |
+
import streamlit as st
|
1328 |
+
|
1329 |
# Add your other function definitions here, like add_project(), edit_project(), etc.
|
1330 |
|
1331 |
# Sidebar menu using radio buttons
|