diff --git a/work-form-management/README.md b/work-form-management/README.md new file mode 100644 index 0000000000..5cc7506d7e --- /dev/null +++ b/work-form-management/README.md @@ -0,0 +1,15 @@ +Work Form Management System + +A minimal Flask + SQLite app to maintain workflow, due list, priorities and stages. + +Quick start (Windows): +1. Create a virtualenv: python -m venv .venv +2. Activate: .\.venv\Scripts\activate +3. Install: pip install -r requirements.txt +4. Run: set FLASK_APP=app.py && flask run + +Use the web UI at http://127.0.0.1:5000 to add tasks, edit, mark complete, and view due dates. + +Notes: +- Database is stored at work-form-management/instance/tasks.db +- Fields: title, description, status, workflow_stage, due_date, priority diff --git a/work-form-management/__pycache__/app.cpython-314.pyc b/work-form-management/__pycache__/app.cpython-314.pyc new file mode 100644 index 0000000000..b88d25fa2d Binary files /dev/null and b/work-form-management/__pycache__/app.cpython-314.pyc differ diff --git a/work-form-management/app.py b/work-form-management/app.py new file mode 100644 index 0000000000..972d50b4f2 --- /dev/null +++ b/work-form-management/app.py @@ -0,0 +1,102 @@ +from flask import Flask, g, render_template, request, redirect, url_for +import sqlite3 +import os +import datetime + +BASE_DIR = os.path.dirname(__file__) +DB_PATH = os.path.join(BASE_DIR, 'instance', 'tasks.db') +os.makedirs(os.path.dirname(DB_PATH), exist_ok=True) + +app = Flask(__name__) + +def get_db(): + db = getattr(g, '_database', None) + if db is None: + db = g._database = sqlite3.connect(DB_PATH) + db.row_factory = sqlite3.Row + return db + +def init_db(): + db = get_db() + db.execute('''CREATE TABLE IF NOT EXISTS tasks ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + title TEXT NOT NULL, + description TEXT, + status TEXT NOT NULL DEFAULT 'pending', + workflow_stage TEXT, + due_date TEXT, + priority INTEGER DEFAULT 3, + created_at TEXT, + updated_at TEXT + )''') + db.commit() + +@app.teardown_appcontext +def close_connection(exception): + db = getattr(g, '_database', None) + if db is not None: + db.close() + +@app.before_request +def before_request(): + init_db() + +@app.route('/') +def index(): + db = get_db() + rows = db.execute('SELECT * FROM tasks ORDER BY due_date IS NULL, due_date, priority').fetchall() + tasks = [dict(r) for r in rows] + return render_template('index.html', tasks=tasks, today=str(datetime.date.today())) + +@app.route('/add', methods=['GET','POST']) +def add(): + if request.method == 'POST': + title = request.form['title'].strip() + description = request.form.get('description','').strip() + due_date = request.form.get('due_date') or None + workflow_stage = request.form.get('workflow_stage','Backlog') + priority = int(request.form.get('priority',3)) + created = datetime.datetime.utcnow().isoformat() + db = get_db() + db.execute('INSERT INTO tasks (title, description, due_date, workflow_stage, priority, created_at, updated_at) VALUES (?,?,?,?,?,?,?)', + (title, description, due_date, workflow_stage, priority, created, created)) + db.commit() + return redirect(url_for('index')) + return render_template('edit.html', task=None) + +@app.route('/edit/', methods=['GET','POST']) +def edit(task_id): + db = get_db() + if request.method == 'POST': + title = request.form['title'].strip() + description = request.form.get('description','').strip() + due_date = request.form.get('due_date') or None + workflow_stage = request.form.get('workflow_stage','Backlog') + priority = int(request.form.get('priority',3)) + updated = datetime.datetime.utcnow().isoformat() + db.execute('UPDATE tasks SET title=?, description=?, due_date=?, workflow_stage=?, priority=?, updated_at=? WHERE id=?', + (title, description, due_date, workflow_stage, priority, updated, task_id)) + db.commit() + return redirect(url_for('index')) + row = db.execute('SELECT * FROM tasks WHERE id=?', (task_id,)).fetchone() + if not row: + return redirect(url_for('index')) + task = dict(row) + return render_template('edit.html', task=task) + +@app.route('/complete/') +def complete(task_id): + db = get_db() + db.execute("UPDATE tasks SET status='done', updated_at=? WHERE id=?", (datetime.datetime.utcnow().isoformat(), task_id)) + db.commit() + return redirect(url_for('index')) + +@app.route('/delete/') +def delete(task_id): + db = get_db() + db.execute('DELETE FROM tasks WHERE id=?', (task_id,)) + db.commit() + return redirect(url_for('index')) + +if __name__ == '__main__': + app.run(debug=True) diff --git a/work-form-management/requirements.txt b/work-form-management/requirements.txt new file mode 100644 index 0000000000..047e9501aa --- /dev/null +++ b/work-form-management/requirements.txt @@ -0,0 +1 @@ +Flask==3.0.0 diff --git a/work-form-management/static/style.css b/work-form-management/static/style.css new file mode 100644 index 0000000000..c0fe52a502 --- /dev/null +++ b/work-form-management/static/style.css @@ -0,0 +1,12 @@ +body{font-family:Segoe UI, Arial, sans-serif;background:#f7f7f7;color:#222} +.container{max-width:900px;margin:24px auto;padding:16px;background:#fff;border-radius:6px;box-shadow:0 2px 8px rgba(0,0,0,.06)} +header h1{margin:0} +nav{margin-top:6px} +table{width:100%;border-collapse:collapse;margin-top:12px} +th,td{padding:8px;border-bottom:1px solid #eee;text-align:left} +tr.overdue{background:#fff0f0} +tr.done{color:#888;text-decoration:line-through} +footer{margin-top:18px;color:#666} +label{display:block;margin:8px 0} +input[type=text], textarea, input[type=number]{width:100%;padding:6px;border:1px solid #ddd;border-radius:4px} +button{background:#0069d9;color:white;padding:8px 12px;border:none;border-radius:4px} diff --git a/work-form-management/templates/base.html b/work-form-management/templates/base.html new file mode 100644 index 0000000000..23af6cef0d --- /dev/null +++ b/work-form-management/templates/base.html @@ -0,0 +1,22 @@ + + + + + Work Form Management + + + +
+
+

Work Form Management

+ +
+
+ {% block content %}{% endblock %} +
+
+ Minimal app — customize as needed. +
+
+ + \ No newline at end of file diff --git a/work-form-management/templates/edit.html b/work-form-management/templates/edit.html new file mode 100644 index 0000000000..aad81c0816 --- /dev/null +++ b/work-form-management/templates/edit.html @@ -0,0 +1,12 @@ +{% extends 'base.html' %} +{% block content %} +

{% if task %}Edit Task{% else %}Add Task{% endif %}

+
+
+
+
+
+
+ +
+{% endblock %} \ No newline at end of file diff --git a/work-form-management/templates/index.html b/work-form-management/templates/index.html new file mode 100644 index 0000000000..84135f896f --- /dev/null +++ b/work-form-management/templates/index.html @@ -0,0 +1,25 @@ +{% extends 'base.html' %} +{% block content %} +

Tasks

+ {% if tasks %} + + + {% for t in tasks %} + + + + + + + + + {% endfor %} +
TitleStageDuePriorityStatusActions
{{ t.title }}{{ t.workflow_stage or 'Backlog' }}{{ t.due_date or '-' }}{{ t.priority or 3 }}{{ t.status }} + Edit | + Complete | + Delete +
+ {% else %} +

No tasks yet. Add one.

+ {% endif %} +{% endblock %} \ No newline at end of file