Добавил возможность редактировать и удалять задачи

This commit is contained in:
Andrei 2023-02-28 22:39:11 +05:00
parent 913871fc47
commit 2f65e8a0dc
14 changed files with 347 additions and 56 deletions

View File

@ -4,18 +4,18 @@ from wtforms import StringField, SubmitField, TextAreaField, DateField, TimeFiel
from wtforms.validators import DataRequired
class NewTask(FlaskForm):
class Task(FlaskForm):
name = StringField('Название', validators=[DataRequired()])
description = TextAreaField('Описание', validators=[DataRequired()])
deadline_date = DateField('Дедлайн', validators=[DataRequired()])
deadline_time = TimeField('', validators=[DataRequired()])
submit = SubmitField('Создать')
save = SubmitField('Сохранить')
delete = SubmitField('Удалить')
class AnswerTask(FlaskForm):
text = TextAreaField('Письменный ответ')
file = MultipleFileField('Файловый ответ')
file = MultipleFileField('Добавить файлы')
realized = BooleanField('Задача решена')
deadline_date = DateField('Дедлайн', validators=[DataRequired()])
deadline_time = TimeField('', validators=[DataRequired()])
submit = SubmitField('Сохранить')

63
main.py
View File

@ -14,7 +14,7 @@ from sqlalchemy import or_
from json import loads
from functions import check_password, mail, init_db_default, get_projects_data, get_user_data, save_project_logo, \
overdue_quest_project, save_proof_quest, find_files_answer, file_tree, delete_project_data
overdue_quest_project, save_proof_quest, find_files_answer, file_tree, delete_project_data, delete_quest_data
from forms.edit_profile import EditProfileForm
from forms.login import LoginForm
from forms.find_project import FindProjectForm
@ -22,7 +22,7 @@ from forms.register import RegisterForm
from forms.project import ProjectForm, AddFileProject
from forms.recovery import RecoveryForm, NewPasswordForm
from forms.conf_delete_project import DeleteProjectForm
from forms.task import NewTask, AnswerTask
from forms.task import Task, AnswerTask
from data.users import User
from data.quests import Quests
@ -56,6 +56,43 @@ def base():
return redirect('/projects')
@app.route('/project/<int:id_project>/quest/<int:id_task>/edit', methods=['GET', 'POST'])
def edit_quest(id_project, id_task):
if current_user.is_authenticated:
data_session = db_session.create_session()
current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
current_task = data_session.query(Quests).filter(Quests.id == id_task).first()
if current_project and current_task and current_task.project == current_project.id and (
current_task.creator == current_user.id or current_project.creator == current_user.id):
form = Task()
if request.method == 'GET':
form.name.data = current_task.name
form.description.data = current_task.description
form.deadline_time.data = current_task.deadline.time()
form.deadline_date.data = current_task.deadline.date()
if form.delete.data:
delete_quest_data(current_task, data_session)
data_session.delete(current_task)
data_session.commit()
return redirect(f'/project/{str(current_project.id)}')
if form.validate_on_submit():
if form.deadline_date.data and form.deadline_time.data:
deadline = datetime.datetime.combine(form.deadline_date.data, form.deadline_time.data)
else:
deadline = None
current_task.name = form.name.data if form.name.data else None
current_task.description = form.description.data if form.description.data else None
current_task.deadline = deadline
data_session.commit()
return redirect(f'/project/{str(current_project.id)}')
return render_template('edit_task.html', title='Редактирование задачи', form=form, porject=current_project,
task=current_task)
else:
abort(403)
else:
return redirect('/login')
@app.route('/project/<int:id_project>/file/<int:id_file>/delete')
def delete_file(id_project, id_file):
if current_user.is_authenticated:
@ -98,11 +135,6 @@ def task_project(id_project, id_task):
current_answer = data_session.query(Answer).filter(Answer.quest == current_task.id).first()
list_files = None
if form.submit.data and request.method == 'POST':
if form.deadline_date.data and form.deadline_time.data:
deadline = datetime.datetime.combine(form.deadline_date.data, form.deadline_time.data)
else:
deadline = current_task.deadline
current_task.deadline = deadline
if current_answer:
current_answer.text = form.text.data
current_answer.date_edit = datetime.datetime.now()
@ -152,9 +184,6 @@ def task_project(id_project, id_task):
files = data_session.query(FileProof).filter(FileProof.answer == current_answer.id).all()
if files:
list_files = list(map(lambda x: find_files_answer(x.file), files))
if current_task.deadline and current_task.deadline and request.method == 'GET':
form.deadline_date.data = current_task.deadline.date()
form.deadline_time.data = current_task.deadline.time()
return render_template('answer.html', title='Решение', project=current_project, task=current_task,
form=form, list_files=list_files)
else:
@ -169,7 +198,7 @@ def new_task_project(id_project):
data_session = db_session.create_session()
current_project = data_session.query(Projects).filter(Projects.id == id_project).first()
if current_project:
form = NewTask()
form = Task()
if form.validate_on_submit():
if form.deadline_date.data and form.deadline_time.data:
deadline = datetime.datetime.combine(form.deadline_date.data, form.deadline_time.data)
@ -386,28 +415,28 @@ def new_project():
list_users = list(
map(lambda x: get_user_data(x), data_session.query(User).filter(User.id != current_user.id).all()))
if form.validate_on_submit():
currnet_project = Projects(
current_project = Projects(
name=form.name.data,
description=form.description.data,
date_create=datetime.datetime.now(),
creator=current_user.id
)
currnet_project.photo = save_project_logo(
current_project.photo = save_project_logo(
form.logo.data) if form.logo.data else 'static/images/none_project.png'
data_session.add(currnet_project)
data_session.add(current_project)
data_session.flush()
data_session.refresh(currnet_project)
data_session.refresh(current_project)
for i in list_users:
if request.form.getlist(f"choose_{i['login']}") and i['id'] != current_user.id:
new_staffer = StaffProjects(
user=i['id'],
project=currnet_project.id,
project=current_project.id,
role='user',
permission=3
)
data_session.add(new_staffer)
data_session.commit()
os.mkdir(f'static/app_files/all_projects/{str(currnet_project.id)}')
os.mkdir(f'static/app_files/all_projects/{str(current_project.id)}')
return redirect('/projects')
return render_template('new_project.html', title='Новый проект', form=form, list_users=list_users)
else:

View File

@ -15,12 +15,46 @@ body {
margin-bottom: 20vw;
}
.link_back_block {
margin-right: 0.5vw;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
flex-wrap: nowrap;
}
.head_buttons_block {
display: flex;
flex-direction: row;
}
.link_edit_block {
margin-left: 0.5vw;
background-color: #9E795A;
border: #9E795A;
width: 13vw;
height: 4.5vw;
color: #ffffff;
border-radius: 5vw;
vertical-align: middle;
font-size: 1.5vw;
}
.link_edit {
width: 13vw;
height: 4.5vw;
}
.link_edit:hover {
text-decoration: none;
color: #000000;
}
.link_edit_text {
width: 13vw;
height: 4.5vw;
text-align: center;
font-size: 1.5vw;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
.link_back {
background-color: #ffffff;
color: #000000;
@ -60,6 +94,9 @@ body {
text-align: center;
color: #000000;
font-size: 4vw;
max-width: 80%;
overflow-x: auto;
overflow-y: hidden;
}
.description_task {
width: 80%;

View File

@ -12,6 +12,7 @@ body {
height: 8vw;
}
#navbar {
margin-top: -80px;
position: fixed;
width: 100%;
transition: top 0.3s;

View File

@ -146,4 +146,34 @@
align-items: center;
justify-content: center;
margin-top: 10px;
}
.link_back_block {
margin-right: 0.5vw;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
flex-wrap: nowrap;
}
.link_back {
background-color: #ffffff;
color: #000000;
width: 15vw;
height: 4.5vw;
vertical-align: middle;
border-radius: 5vw;
display: flex;
align-items: center;
justify-content: center;
}
.link_back:hover {
text-decoration: none;
color: #000000;
}
.link_back_text {
font-size: 1.5vw;
margin-top: 15px;
display: flex;
align-items: center;
justify-content: center;
}

106
static/css/edit_task.css Normal file
View File

@ -0,0 +1,106 @@
.new_task_page {
height: 50vw;
background-color: #dcb495;
}
.form_data {
display: flex;
flex-direction: column;
margin-left: 2%;
}
.form_block {
display: flex;
align-items: center;
justify-content: center;
}
.form_data_button {
margin-top: 2.5vw;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.input_data {
color: #000000;
border: 0.1vw solid #595008;
height: 4.5vw;
min-height: 4.5vw;
width: 50vw;
background-color: #dbc3af;
border-radius: 4.5vw;
font-size: 1.3vw;
display: inline-flex;
align-items: center;
}
.form_label {
margin-top: 10px;
font-size: 1.3vw;
color: #ffffff;
font-weight: bold;
}
.description {
border-radius: 2vw !important;
width: 50vw;
max-height: 10vw !important;
}
.name_form_block {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
}
.deadline {
width: 20vw;
}
.quest_button {
margin-top: 1vw;
margin-left: 5vw;
width: 20vw;
height: 5vw;
background-color: #000000;
color: #ffffff;
border-radius: 5vw;
vertical-align: middle;
font-size: 1.5vw;
}
.data_form_block {
display: flex;
flex-direction: row;
align-items: center;
justify-content: center;
}
.deadline {
margin: 5px;
}
.link_back_block {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
flex-wrap: nowrap;
}
.link_back {
background-color: #ffffff;
color: #000000;
width: 15vw;
height: 4.5vw;
vertical-align: middle;
border-radius: 5vw;
display: flex;
align-items: center;
justify-content: center;
}
.link_back:hover {
text-decoration: none;
color: #000000;
}
.link_back_text {
font-size: 1.5vw;
margin-top: 15px;
display: flex;
align-items: center;
justify-content: center;
}
.delete_project_link {
background-color: #ff3f3f;
border: #ff3f3f;
}

View File

@ -39,6 +39,7 @@
.description {
border-radius: 2vw !important;
width: 50vw;
max-height: 10vw;
}
.name_form_block {
width: 100%;

View File

@ -22,6 +22,7 @@
}
.brand_block {
height: 25vw;
margin-left: -8vw;
display: flex;
flex-direction: column;
align-items: center;
@ -38,15 +39,30 @@
justify-content: center;
}
.edit_button {
width: 4.5vw;
height: 4.5vw;
background-color: #9E795A;
border: #9E795A;
width: 12vw;
height: 5vw;
color: #ffffff;
border-radius: 5vw;
vertical-align: middle;
font-size: 1.5vw;
}
.edit_button_text {
color: #ffffff;
height: 5vw;
margin-top: 32%;
}
.edit_button_link {
width: 12vw;
height: 5vw;
display: flex;
align-items: center;
justify-content: center;
}
.edit_button_image {
height: 3vw;
width: 3vw;
.edit_button_link:hover {
text-decoration: none;
color: #ffffff;
}
.collaborator_block {
width: 95%;
@ -140,12 +156,32 @@
flex-direction: row;
}
.new_task_block {
width: 4.5vw;
height: 4.5vw;
width: 13vw;
height: 5vw;
background-color: #000000;
border: 2px solid #ffffff;
border-radius: 3vw;
margin-left: 2vw;
margin-bottom: 0.5vw;
}
.new_task_link {
width: 4.5vw;
height: 4.5vw;
color: #ffffff;
width: 13vw;
height: 5vw;
}
.new_task_link:hover {
text-decoration: none;
color: #ffffff;
}
.new_task_text {
width: 13vw;
height: 5vw;
text-align: center;
font-size: 1.5vw;
color: #ffffff;
display: flex;
align-items: center;
justify-content: center;
}
.new_task_image {
width: 4.5vw;

View File

@ -252,7 +252,7 @@
align-items: center;
justify-content: center;
}
.new_project_button_lin, find_project_button_linkk {
.new_project_button_link, find_project_button_linkk {
width: 13vw;
height: 5vw;
}

View File

@ -1,10 +1,19 @@
<link rel="stylesheet" href="../../../static/css/answer.css"/>
{% extends "base.html" %} {% block content %}
<div class="decision_page">
<div class="link_back_block">
<a class="link_back" href="../../../project/{{ project.id }}">
<p class="link_back_text">К проекту</p>
</a>
<div class="head_buttons_block">
<div class="link_back_block">
<a class="link_back" href="../../../project/{{ project.id }}">
<p class="link_back_text">К проекту</p>
</a>
</div>
{% if task.creator == current_user.id or project.creator == current_user.id %}
<div class="link_edit_block">
<a class="link_edit" href="{{ task.id }}/edit">
<p class="link_edit_text">Редактировать</p>
</a>
</div>
{% endif %}
</div>
<div class="name_block">
<div class="title_block">
@ -68,19 +77,6 @@
{% endfor %}
</div>
</div>
{% if current_user.id == project.creator %}
<div class="form_data">
<label class="form_label">{{ form.deadline_date.label }}</label>
{{ form.deadline_date(class="input_data deadline padding_data", type="date") }}
{% for error in form.deadline_date.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
{{ form.deadline_time(class="input_data deadline padding_data", type="time") }}
{% for error in form.deadline_time.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
{% endif %}
<div class="form_data_button">
{{ form.submit(type="submit", class="quest_button") }}
<div class="box">

View File

@ -2,7 +2,7 @@
<html lang="ru">
<head>
<meta charset="UTF-8"/>
<link rel="stylesheet" href="../../../static/css/base.css"/>
<link rel="stylesheet" href="../../../../static/css/base.css"/>
<link
rel="stylesheet"
href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
@ -41,7 +41,7 @@
<nav class="navbar" id="navbar">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<img src="../../../static/images/logo_b.png" class="nav_logo"/>
<img src="../../../../static/images/logo_b.png" class="nav_logo"/>
</a>
<a class="auth_button" href="/login">Авторизация</a>
</div>
@ -52,7 +52,7 @@
<footer class="footer">
<div class="footer_block">
<a href="/#header_block"
><img class="footer_logo" src="../../../static/images/logo_w.png"
><img class="footer_logo" src="../../../../static/images/logo_w.png"
/></a>
<strong class="footer_rights">© All rights reserved</strong>
</div>

View File

@ -1,6 +1,11 @@
<link rel="stylesheet" href="../../static/css/edit_project.css"/>
{% extends "base.html" %} {% block content %}
<div class="edit_project_page">
<div class="link_back_block">
<a class="link_back" href="../../../project/{{ project.id }}">
<p class="link_back_text">К проекту</p>
</a>
</div>
<div class="form_block">
<form action="" method="post" class="register_form" enctype="multipart/form-data">
{{ form.hidden_tag() }}

48
templates/edit_task.html Normal file
View File

@ -0,0 +1,48 @@
<link rel="stylesheet" href="../../../../static/css/edit_task.css"/>
{% extends "base.html" %} {% block content %}
<div class="new_task_page">
<div class="link_back_block">
<a class="link_back" href="../{{ task.id }}">
<p class="link_back_text">К задаче</p>
</a>
</div>
<div class="form_block">
<form action="" method="post" class="new_task_form" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<div class="name_form_block">
<div class="form_data">
<label class="form_label">{{ form.name.label }}</label>
{{ form.name(class="input_data label_data", type="name", placeholder='your project name') }}
{% for error in form.name.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
<div class="form_data">
<label class="form_label">{{ form.description.label }}</label>
{{ form.description(class="input_data description padding_data", type="description", placeholder='your project description') }}
{% for error in form.description.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
</div>
<div class="data_form_block">
<div class="form_data">
<label class="form_label">{{ form.deadline_date.label }}</label>
{{ form.deadline_date(class="input_data deadline padding_data", type="date") }}
{% for error in form.deadline_date.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
{{ form.deadline_time(class="input_data deadline padding_data", type="time") }}
{% for error in form.deadline_time.errors %}
<div class="alert alert-danger" role="alert">{{ error }}</div>
{% endfor %}
</div>
<div class="form_data_button">
{{ form.save(type="submit", class="quest_button") }}
{{ form.delete(type="submit", class="quest_button delete_project_link") }}
</div>
</div>
</form>
</div>
</div>
{% endblock %}

View File

@ -9,11 +9,13 @@
<div class="project_header">
<div class="edit_block">
{% if current_user.id == project.creator %}
<a id="edit_button" class="edit_button" href="">
<img class="edit_button_image" src="../static/images/pen_b.png">
</a>
<div class="edit_button">
<a id="edit_button" class="edit_button_link" href="">
<p class="edit_button_text">Редактировать</p>
</a>
</div>
{% else %}
<p class="edit_button"> </p>
<p style="width: 12vw;"> </p>
{% endif %}
</div>
<div class="brand_block">
@ -45,7 +47,7 @@
<h3 class="header_title_2">Задачи</h3>
<div class="new_task_block">
<a class="new_task_link" id="new_task_link" href="/">
<img class="new_task_image" src="../static/images/plus_b.png">
<p class="new_task_text">Добавить</p>
</a>
</div>
</div>