Jelajahi Sumber

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

Andrei 2 tahun lalu
induk
melakukan
2f65e8a0dc

+ 4 - 4
forms/task.py

@@ -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('Сохранить')

+ 46 - 17
main.py

@@ -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:

+ 37 - 0
static/css/answer.css

@@ -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%;

+ 1 - 0
static/css/base.css

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

+ 30 - 0
static/css/edit_project.css

@@ -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 - 0
static/css/edit_task.css

@@ -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;
+}

+ 1 - 0
static/css/new_task.css

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

+ 45 - 9
static/css/project.css

@@ -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;

+ 1 - 1
static/css/projects.css

@@ -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;
 }

+ 13 - 17
templates/answer.html

@@ -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">

+ 3 - 3
templates/base.html

@@ -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>

+ 5 - 0
templates/edit_project.html

@@ -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 - 0
templates/edit_task.html

@@ -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 %}

+ 7 - 5
templates/project.html

@@ -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>