Disable worklogs when work complete.
This commit is contained in:
parent
96d34ebf55
commit
76b6882d71
2 changed files with 118 additions and 141 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
{% import "fragments/_icon_fragment.html" as icons %}
|
{% import "fragments/_icon_fragment.html" as icons %}
|
||||||
|
|
||||||
{% macro render_editor(id, title, mode='edit', content=None) %}
|
{% macro render_editor(id, title, mode='edit', content=None, enabled=True) %}
|
||||||
<!-- Editor Fragment -->
|
<!-- Editor Fragment -->
|
||||||
<div class="row mb-3">
|
<div class="row mb-3">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
|
|
@ -8,17 +8,19 @@
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link text-black">{{ title }}</a>
|
<a class="nav-link text-black">{{ title }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% if enabled %}
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link{% if mode == 'view' %} active{% endif %}" data-bs-toggle="tab" data-bs-target="#viewer{{ id }}">{{ icons.render_icon('file-earmark-richtext', 16) }}</a>
|
<a class="nav-link{% if mode == 'view' %} active{% endif %}" data-bs-toggle="tab" data-bs-target="#viewer{{ id }}">{{ icons.render_icon('file-earmark-richtext', 16) }}</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item">
|
||||||
<a class="nav-link{% if mode == 'edit' %} active{% endif %}" data-bs-toggle="tab" data-bs-target="#editor{{ id }}" id="editTab{{ id }}">{{ icons.render_icon('pencil', 16) }}</a>
|
<a class="nav-link{% if mode == 'edit' %} active{% endif %}" data-bs-toggle="tab" data-bs-target="#editor{{ id }}" id="editTab{{ id }}">{{ icons.render_icon('pencil', 16) }}</a>
|
||||||
</li>
|
</li>
|
||||||
|
{% endif %}
|
||||||
</ul>
|
</ul>
|
||||||
<div class="tab-content" id="tabContent{{ id }}">
|
<div class="tab-content" id="tabContent{{ id }}">
|
||||||
<div class="tab-pane fade{% if mode == 'view' %} show active border border-top-0{% endif %} p-2 markdown-body" id="viewer{{ id }}"></div>
|
<div class="tab-pane fade{% if mode == 'view' %} show active border border-top-0{% endif %} p-2 markdown-body" id="viewer{{ id }}"></div>
|
||||||
<div class="tab-pane fade{% if mode == 'edit' %} show active border border-top-0{% endif %}" id="editor{{ id }}">
|
<div class="tab-pane fade{% if mode == 'edit' %} show active border border-top-0{% endif %}" id="editor{{ id }}">
|
||||||
<textarea id="textEditor{{ id }}" name="editor{{ id }}" class="form-control border-top-0 rounded-top-0" data-note-id="{{ id }}">{{ content if content }}</textarea>
|
<textarea id="textEditor{{ id }}" name="editor{{ id }}" class="form-control border-top-0 rounded-top-0{% if not enabled %} disabled{% endif %}" data-note-id="{{ id }}">{{ content if content }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
|
|
@ -4,115 +4,123 @@
|
||||||
{% block title %}{{ title }}{% endblock %}
|
{% block title %}{{ title }}{% endblock %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<nav>
|
<nav>
|
||||||
{{ breadcrumbs.breadcrumb_header(
|
{{ breadcrumbs.breadcrumb_header(
|
||||||
breadcrumbs=[
|
breadcrumbs=[
|
||||||
{'label': 'Work Log', 'url': url_for('main.list_worklog')}
|
{'label': 'Work Log', 'url': url_for('main.list_worklog')}
|
||||||
],
|
],
|
||||||
title=title,
|
title=title,
|
||||||
save_button=True,
|
save_button=True,
|
||||||
delete_button=log.id != None
|
delete_button=log.id != None
|
||||||
) }}
|
) }}
|
||||||
|
</nav>
|
||||||
|
{% if log.complete %}
|
||||||
|
<div class="alert alert-success">
|
||||||
|
This work item is complete. You cannot make any further changes.
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<input type="hidden" id="logId" value="{{ log.id }}">
|
<input type="hidden" id="logId" value="{{ log.id }}">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<label for="start" class="form-label">Start Timestamp</label>
|
<label for="start" class="form-label">Start Timestamp</label>
|
||||||
<input type="date" class="form-control" name="start" placeholder="-"
|
<input type="date" class="form-control" name="start" placeholder="-"
|
||||||
value="{{ log.start_time.date().isoformat() if log.start_time }}">
|
value="{{ log.start_time.date().isoformat() if log.start_time }}"{% if log.complete %} disabled{% endif %}>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-6">
|
<div class="col-6">
|
||||||
<label for="end" class="form-label">End Timestamp</label>
|
<label for="end" class="form-label">End Timestamp</label>
|
||||||
<input type="date" class="form-control" name="end" placeholder="-"
|
<input type="date" class="form-control" name="end" placeholder="-"
|
||||||
value="{{ log.end_time.date().isoformat() if log.end_time }}">
|
value="{{ log.end_time.date().isoformat() if log.end_time }}"{% if log.complete %} disabled{% endif %}>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-4">
|
<div class="col-4">
|
||||||
<label for="contact" class="form-label">
|
<label for="contact" class="form-label">
|
||||||
Contact
|
Contact
|
||||||
{% if log.contact_id %}
|
{% if log.contact_id %}
|
||||||
{{ links.entry_link('user', log.contact_id) }}
|
{{ links.entry_link('user', log.contact_id) }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</label>
|
</label>
|
||||||
<select class="form-select" name="contact" id="contact">
|
<select class="form-select" name="contact" id="contact"{% if log.complete %} disabled{% endif %}>
|
||||||
<option value="">-</option>
|
<option value="">-</option>
|
||||||
{% for contact in users %}
|
{% for contact in users %}
|
||||||
<option value="{{ contact.id }}"{% if contact.id == log.contact_id %} selected{% endif %}>{{ contact.full_name }}
|
<option value="{{ contact.id }}" {% if contact.id==log.contact_id %} selected{% endif %}>{{
|
||||||
</option>
|
contact.full_name }}
|
||||||
{% endfor %}
|
</option>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-4">
|
|
||||||
<label for="item" class="form-label">
|
|
||||||
Work Item
|
|
||||||
{% if log.work_item_id %}
|
|
||||||
{{ links.entry_link('inventory_item', log.work_item_id) }}
|
|
||||||
{% endif %}
|
|
||||||
</label>
|
|
||||||
<select id="item" name="item" class="form-select">
|
|
||||||
<option value="">-</option>
|
|
||||||
{% for item in items %}
|
|
||||||
<option value="{{ item.id }}"{% if item.id == log.work_item_id %} selected{% endif %}>{{ item.identifier }}</option>
|
|
||||||
{% endfor %}
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
<div class="col-4">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<input type="checkbox" id="complete" class="form-check-input" name="complete"{% if log.complete %} checked{%
|
|
||||||
endif %}>
|
|
||||||
<label for="complete" class="form-check-label">
|
|
||||||
Complete?
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<input type="checkbox" id="followup" class="form-check-input" name="followup"{% if log.followup %} checked{%
|
|
||||||
endif %}>
|
|
||||||
<label for="followup" class="form-check-label">
|
|
||||||
Follow Up?
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col">
|
|
||||||
<input type="checkbox" id="analysis" class="form-check-input" name="analysis"{% if log.analysis %} checked{%
|
|
||||||
endif %}>
|
|
||||||
<label for="analysis" class="form-check-label">
|
|
||||||
Quick Analysis?
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="container" id="updates-container">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-11">
|
|
||||||
<label class="form-label">Updates</label>
|
|
||||||
</div>
|
|
||||||
<div class="col">
|
|
||||||
<button class="btn btn-primary mb-3" id="addUpdateButton">
|
|
||||||
{{ icons.render_icon('plus-lg', 16) }}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% for update in log.updates %}
|
|
||||||
{{ editor.render_editor(
|
|
||||||
id = update.id,
|
|
||||||
title = update.timestamp.strftime('%Y-%m-%d %H:%M:%S'),
|
|
||||||
mode = 'view',
|
|
||||||
content = update.content
|
|
||||||
) }}
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
<template id="editor-template">
|
</select>
|
||||||
{{ editor.render_editor('__ID__', '__TIMESTAMP__', 'edit', '') }}
|
</div>
|
||||||
</template>
|
<div class="col-4">
|
||||||
|
<label for="item" class="form-label">
|
||||||
|
Work Item
|
||||||
|
{% if log.work_item_id %}
|
||||||
|
{{ links.entry_link('inventory_item', log.work_item_id) }}
|
||||||
|
{% endif %}
|
||||||
|
</label>
|
||||||
|
<select id="item" name="item" class="form-select"{% if log.complete %} disabled{% endif %}>
|
||||||
|
<option value="">-</option>
|
||||||
|
{% for item in items %}
|
||||||
|
<option value="{{ item.id }}" {% if item.id==log.work_item_id %} selected{% endif %}>{{ item.identifier
|
||||||
|
}}</option>
|
||||||
|
{% endfor %}
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-4">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<input type="checkbox" id="complete" class="form-check-input" name="complete" {% if log.complete %}
|
||||||
|
checked{% endif %}>
|
||||||
|
<label for="complete" class="form-check-label">
|
||||||
|
Complete?
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<input type="checkbox" id="followup" class="form-check-input" name="followup" {% if log.followup %}
|
||||||
|
checked{% endif %}{% if log.complete %} disabled{% endif %}>
|
||||||
|
<label for="followup" class="form-check-label">
|
||||||
|
Follow Up?
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<input type="checkbox" id="analysis" class="form-check-input" name="analysis" {% if log.analysis %}
|
||||||
|
checked{% endif %}{% if log.complete %} disabled{% endif %}>
|
||||||
|
<label for="analysis" class="form-check-label">
|
||||||
|
Quick Analysis?
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</nav>
|
</div>
|
||||||
|
<div class="container" id="updates-container">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-11">
|
||||||
|
<label class="form-label">Updates</label>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<button class="btn btn-primary mb-3" id="addUpdateButton"{% if log.complete %} disabled{% endif %}>
|
||||||
|
{{ icons.render_icon('plus-lg', 16) }}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% for update in log.updates %}
|
||||||
|
{{ editor.render_editor(
|
||||||
|
id = update.id,
|
||||||
|
title = update.timestamp.strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
|
mode = 'view',
|
||||||
|
content = update.content,
|
||||||
|
enabled = not log.complete
|
||||||
|
) }}
|
||||||
|
{% endfor %}
|
||||||
|
<template id="editor-template">
|
||||||
|
{{ editor.render_editor('__ID__', '__TIMESTAMP__', 'edit', '') }}
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block script %}
|
{% block script %}
|
||||||
|
|
@ -123,44 +131,11 @@
|
||||||
function formatDate(date) {
|
function formatDate(date) {
|
||||||
const pad = (n) => String(n).padStart(2, '0');
|
const pad = (n) => String(n).padStart(2, '0');
|
||||||
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} `
|
return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} `
|
||||||
+ `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
+ `${pad(date.getHours())}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addUpdateButton) {
|
if (addUpdateButton) {
|
||||||
addUpdateButton.addEventListener("click", (e) => {
|
addUpdateButton.addEventListener("click", (e) => {
|
||||||
{#
|
|
||||||
const row = document.createElement("div");
|
|
||||||
row.classList.add("row");
|
|
||||||
|
|
||||||
const col = document.createElement("div");
|
|
||||||
col.classList.add("col");
|
|
||||||
|
|
||||||
const igroup = document.createElement("div");
|
|
||||||
igroup.classList.add("input-group", "mb-3");
|
|
||||||
|
|
||||||
// Timestamp span (just display the current time)
|
|
||||||
const ts = document.createElement("span");
|
|
||||||
ts.classList.add("input-group-text");
|
|
||||||
const now = formatDate(new Date());
|
|
||||||
ts.textContent = now;
|
|
||||||
|
|
||||||
// Textarea for update content
|
|
||||||
const updateContent = document.createElement("textarea");
|
|
||||||
updateContent.classList.add("form-control");
|
|
||||||
updateContent.placeholder = "Enter update...";
|
|
||||||
updateContent.dataset.noteId = "";
|
|
||||||
updateContent.name = "updateNew";
|
|
||||||
|
|
||||||
// Hook in auto-resize
|
|
||||||
updateContent.addEventListener("input", () => autoResizeTextarea(updateContent));
|
|
||||||
autoResizeTextarea(updateContent);
|
|
||||||
|
|
||||||
// Stitch it all together
|
|
||||||
igroup.appendChild(ts);
|
|
||||||
igroup.appendChild(updateContent);
|
|
||||||
col.appendChild(igroup);
|
|
||||||
row.appendChild(col);
|
|
||||||
#}
|
|
||||||
const template = document.getElementById("editor-template");
|
const template = document.getElementById("editor-template");
|
||||||
const newEditor = EditorWidget.createEditorWidget(template, EditorWidget.createTempId("new"), formatDate(new Date()));
|
const newEditor = EditorWidget.createEditorWidget(template, EditorWidget.createTempId("new"), formatDate(new Date()));
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue