Separate bricktracker sets from rebrickable sets (dedup), introduce custom checkboxes
This commit is contained in:
+1
-1
@@ -47,7 +47,7 @@
|
||||
<div class="card mb-3 col-6">
|
||||
<div class="card-header">
|
||||
<h5 class="mb-0">
|
||||
<span class="badge text-bg-secondary fw-normal"><i class="ri-hashtag"></i> <span id="add-card-number"></span></span>
|
||||
<span class="badge text-bg-secondary fw-normal"><i class="ri-hashtag"></i> <span id="add-card-set"></span></span>
|
||||
<span id="add-card-name"></span>
|
||||
</h5>
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,9 @@
|
||||
<h5 class="mb-0"><i class="ri-settings-4-line"></i> Administration</h5>
|
||||
</div>
|
||||
<div class="accordion accordion-flush" id="admin">
|
||||
{% if delete_database %}
|
||||
{% if delete_checkbox %}
|
||||
{% include 'admin/checkbox/delete.html' %}
|
||||
{% elif delete_database %}
|
||||
{% include 'admin/database/delete.html' %}
|
||||
{% elif drop_database %}
|
||||
{% include 'admin/database/drop.html' %}
|
||||
@@ -28,6 +30,7 @@
|
||||
{% endif %}
|
||||
{% include 'admin/theme.html' %}
|
||||
{% include 'admin/retired.html' %}
|
||||
{% include 'admin/checkbox.html' %}
|
||||
{% include 'admin/database.html' %}
|
||||
{% include 'admin/configuration.html' %}
|
||||
{% endif %}
|
||||
@@ -38,4 +41,8 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static', filename='scripts/changer.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -0,0 +1,67 @@
|
||||
{% import 'macro/accordion.html' as accordion %}
|
||||
|
||||
{{ accordion.header('Checkboxes', 'checkbox', 'admin', expanded=open_checkbox, icon='checkbox-line', class='p-0') }}
|
||||
{% if error %}<div class="alert alert-danger m-2" role="alert"><strong>Error:</strong> {{ error }}.</div>{% endif %}
|
||||
{% if database_error %}<div class="alert alert-danger m-2" role="alert"><strong>Error:</strong> {{ database_error }}.</div>{% endif %}
|
||||
<ul class="list-group list-group-flush">
|
||||
{% if brickset_checkboxes | length %}
|
||||
{% for checkbox in brickset_checkboxes %}
|
||||
<li class="list-group-item">
|
||||
<form action="{{ url_for('admin_checkbox.rename', id=checkbox.fields.id) }}" method="post" class="row row-cols-lg-auto g-3 align-items-center">
|
||||
<div class="col-12 flex-grow-1">
|
||||
<label class="visually-hidden" for="name-{{ checkbox.fields.id }}">Name</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">Name</div>
|
||||
<input type="text" class="form-control" id="name-{{ checkbox.fields.id }}" name="name" value="{{ checkbox.fields.name }}">
|
||||
<button type="submit" class="btn btn-primary"><i class="ri-edit-line"></i> Rename</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="grid-{{ checkbox.fields.id }}"
|
||||
data-changer-id="{{ checkbox.fields.id }}" data-changer-prefix="grid" data-changer-url="{{ url_for('admin_checkbox.update_status', id=checkbox.fields.id, name='displayed_on_grid')}}"
|
||||
{% if checkbox.fields.displayed_on_grid %}checked{% endif %} autocomplete="off">
|
||||
<label class="form-check-label" for="grid-{{ checkbox.fields.id }}">
|
||||
Displayed on the Set Grid
|
||||
<i id="status-grid-{{ checkbox.fields.id }}" class="mb-1"></i>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<a href="{{ url_for('admin_checkbox.delete', id=checkbox.fields.id) }}" class="btn btn-danger" role="button"><i class="ri-delete-bin-2-line"></i> Delete</a>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<li class="list-group-item"><i class="ri-error-warning-line"></i> No checkbox found.</li>
|
||||
{% endif %}
|
||||
<li class="list-group-item">
|
||||
<form action="{{ url_for('admin_checkbox.add') }}" method="post" class="row row-cols-lg-auto g-3 align-items-center">
|
||||
<div class="col-12 flex-grow-1">
|
||||
<label class="visually-hidden" for="name">Name</label>
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">Name</div>
|
||||
<input type="text" class="form-control" id="name" name="name" value="">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" id="grid" name="grid" checked>
|
||||
<label class="form-check-label" for="grid-">
|
||||
Displayed on the Set Grid
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<button type="submit" class="btn btn-primary"><i class="ri-add-circle-line"></i> Add</button>
|
||||
</div>
|
||||
</form>
|
||||
</li>
|
||||
</ul>
|
||||
{{ accordion.footer() }}
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
setup_changers();
|
||||
});
|
||||
</script>
|
||||
@@ -0,0 +1,25 @@
|
||||
{% import 'macro/accordion.html' as accordion %}
|
||||
|
||||
{{ accordion.header('Checkbox danger zone', 'checkbox-danger', 'admin', expanded=true, danger=true, class='text-end') }}
|
||||
<form action="{{ url_for('admin_checkbox.do_delete', id=checkbox.fields.id) }}" method="post">
|
||||
{% if error %}<div class="alert alert-danger text-start" role="alert"><strong>Error:</strong> {{ error }}.</div>{% endif %}
|
||||
<div class="alert alert-danger text-center" role="alert">You are about to <strong>delete a checkbox</strong>. This action is irreversible.</div>
|
||||
<div class="row row-cols-lg-auto g-3 align-items-center">
|
||||
<div class="col-12 flex-grow-1">
|
||||
<div class="input-group">
|
||||
<div class="input-group-text">Name</div>
|
||||
<input type="text" class="form-control" value="{{ checkbox.fields.name }}" disabled>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" {% if checkbox.fields.displayed_on_grid %}checked{% endif %} disabled>
|
||||
<span class="form-check-label">Displayed on the Set Grid</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr class="border-bottom">
|
||||
<a class="btn btn-danger" href="{{ url_for('admin.admin', open_checkbox=true) }}" role="button"><i class="ri-arrow-left-long-line"></i> Back to the admin</a>
|
||||
<button type="submit" class="btn btn-danger"><i class="ri-delete-bin-2-line"></i> Delete <strong>the checkbox</strong></button>
|
||||
</form>
|
||||
{{ accordion.footer() }}
|
||||
@@ -1,6 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %} - Delete a set {{ item.fields.set_num }} ({{ item.fields.u_id }}){% endblock %}
|
||||
{% block title %} - Delete a set {{ item.fields.set }} ({{ item.fields.id }}){% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="container">
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
</div>
|
||||
<div class="accordion accordion-flush" id="instructions">
|
||||
{{ accordion.header('Instructions danger zone', 'instructions-delete', 'instructions', expanded=true, danger=true) }}
|
||||
{% if item.brickset %}
|
||||
{% if item.rebrickable %}
|
||||
<div class="d-flex justify-content-center">
|
||||
{% with item=item.brickset %}
|
||||
{% with item=item.rebrickable %}
|
||||
{% include 'set/mini.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
</div>
|
||||
<div class="accordion accordion-flush" id="instructions">
|
||||
{{ accordion.header('Management', 'instructions-rename', 'instructions', expanded=true) }}
|
||||
{% if item.brickset %}
|
||||
{% if item.rebrickable %}
|
||||
<div class="d-flex justify-content-center">
|
||||
{% with item=item.brickset %}
|
||||
{% with item=item.rebrickable %}
|
||||
{% include 'set/mini.html' %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
|
||||
@@ -27,11 +27,11 @@
|
||||
<span class="badge rounded-pill text-bg-light border fw-normal"><i class="ri-calendar-line"></i> {{ item.human_time() }}</span>
|
||||
</td>
|
||||
<td>
|
||||
{% if item.number %}<span class="badge text-bg-secondary fw-normal"><i class="ri-hashtag"></i> {{ item.number }}</span>{% endif %}
|
||||
{% if item.brickset %}{{ item.brickset.fields.name }}{% endif %}
|
||||
{% if item.set %}<span class="badge text-bg-secondary fw-normal"><i class="ri-hashtag"></i> {{ item.set }}</span>{% endif %}
|
||||
{% if item.rebrickable %}{{ item.rebrickable.fields.name }}{% endif %}
|
||||
</td>
|
||||
{% if item.brickset %}
|
||||
{{ table.image(item.brickset.url_for_image(), caption=item.brickset.fields.name, alt=item.brickset.fields.set_num) }}
|
||||
{% if item.rebrickable %}
|
||||
{{ table.image(item.rebrickable.url_for_image(), caption=item.rebrickable.fields.name, alt=item.rebrickable.fields.set) }}
|
||||
{% else %}
|
||||
<td><i class="ri-file-warning-line"></i></td>
|
||||
{% endif %}
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
{% macro checkbox(kind, id, text, url, checked, delete=false) %}
|
||||
{% macro checkbox(prefix, id, text, url, checked, delete=false) %}
|
||||
{% if g.login.is_authenticated() %}
|
||||
<input class="form-check-input" type="checkbox" id="{{ kind }}-{{ id }}" {% if checked %}checked{% endif %}
|
||||
{% if not delete %}onchange="change_set_checkbox_status(this, '{{ kind }}', '{{ id }}', '{{ url }}')"{% else %}disabled{% endif %}
|
||||
<input class="form-check-input" type="checkbox" id="{{ prefix }}-{{ id }}" {% if checked %}checked{% endif %}
|
||||
{% if not delete %}
|
||||
data-changer-id="{{ id }}" data-changer-prefix="{{ prefix }}" data-changer-url="{{ url }}" data-changer-parent="set"
|
||||
{% else %}
|
||||
disabled
|
||||
{% endif %}
|
||||
autocomplete="off">
|
||||
<label class="form-check-label" for="{{ kind }}-{{ id }}">
|
||||
{{ text }} <i id="status-{{ kind }}-{{ id }}" class="mb-1"></i>
|
||||
<label class="form-check-label" for="{{ prefix }}-{{ id }}">
|
||||
{{ text }} <i id="status-{{ prefix }}-{{ id }}" class="mb-1"></i>
|
||||
</label>
|
||||
{% else %}
|
||||
<input class="form-check-input text-reset" type="checkbox" {% if checked %}checked{% endif %} disabled>
|
||||
|
||||
+3
-1
@@ -1,6 +1,6 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block title %} - Set {{ item.fields.name}} ({{ item.fields.set_num }}){% endblock %}
|
||||
{% block title %} - Set {{ item.fields.name}} ({{ item.fields.set }}){% endblock %}
|
||||
|
||||
{% block main %}
|
||||
<div class="container">
|
||||
@@ -15,10 +15,12 @@
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
baguetteBox.run('[data-lightbox]');
|
||||
setup_changers();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static', filename='scripts/changer.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='scripts/set.js') }}"></script>
|
||||
{% endblock %}
|
||||
+19
-21
@@ -3,18 +3,20 @@
|
||||
{% import 'macro/card.html' as card %}
|
||||
{% import 'macro/form.html' as form %}
|
||||
|
||||
<div {% if not solo %}id="set-{{ item.fields.u_id }}"{% endif %} class="card mb-3 flex-fill {% if solo %}card-solo{% endif %}"
|
||||
{% if not solo %}data-index="{{ index }}" data-number="{{ item.fields.set_number }}" data-name="{{ item.fields.name | lower }}" data-parts="{{ item.fields.num_parts }}"
|
||||
data-year="{{ item.fields.year }}" data-theme="{{ item.theme_name | lower }}" data-minifigures-collected="{{ item.fields.mini_col }}" data-set-collected="{{ item.fields.set_col }}"
|
||||
data-set-checked="{{ item.fields.set_check }}" data-has-missing="{{ (item.fields.total_missing > 0) | int }}" data-has-minifigures="{{ (item.fields.total_minifigures > 0) | int }}"
|
||||
data-has-missing-instructions="{{ (not (item.instructions | length)) | int }}" data-minifigures="{{ item.fields.total_minifigures }}" data-missing="{{ item.fields.total_missing }}"{% endif %}
|
||||
<div {% if not solo %}id="set-{{ item.fields.id }}"{% endif %} class="card mb-3 flex-fill {% if solo %}card-solo{% endif %}"
|
||||
{% if not solo %}
|
||||
data-index="{{ index }}" data-number="{{ item.fields.set }}" data-name="{{ item.fields.name | lower }}" data-parts="{{ item.fields.number_of_parts }}"
|
||||
data-year="{{ item.fields.year }}" data-theme="{{ item.theme.name | lower }}" data-minifigures="{{ item.fields.total_minifigures }}" data-has-minifigures="{{ (item.fields.total_minifigures > 0) | int }}"
|
||||
data-has-missing="{{ (item.fields.total_missing > 0) | int }}" data-has-missing-instructions="{{ (not (item.instructions | length)) | int }}" data-missing="{{ item.fields.total_missing }}"
|
||||
{% for checkbox in brickset_checkboxes %}data-{{ checkbox.as_dataset() }}="{{ item.fields[checkbox.as_column()] }}" {% endfor %}
|
||||
{% endif %}
|
||||
>
|
||||
{{ card.header(item, item.fields.name, solo=solo, number=item.fields.set_num) }}
|
||||
{{ card.image(item, solo=solo, last=last, caption=item.fields.name, alt=item.fields.set_num) }}
|
||||
<div class="card-body {% if not solo %}p-1{% endif %}">
|
||||
{{ badge.theme(item.theme_name, solo=solo, last=last) }}
|
||||
{{ card.header(item, item.fields.name, solo=solo, number=item.fields.number) }}
|
||||
{{ card.image(item, solo=solo, last=last, caption=item.fields.name, alt=item.fields.number) }}
|
||||
<div class="card-body {% if solo %}border-bottom{% else %}p-1{% endif %}">
|
||||
{{ badge.theme(item.theme.name, solo=solo, last=last) }}
|
||||
{{ badge.year(item.fields.year, solo=solo, last=last) }}
|
||||
{{ badge.parts(item.fields.num_parts, solo=solo, last=last) }}
|
||||
{{ badge.parts(item.fields.number_of_parts, solo=solo, last=last) }}
|
||||
{{ badge.total_minifigures(item.fields.total_minifigures, solo=solo, last=last) }}
|
||||
{{ badge.total_missing(item.fields.total_missing, solo=solo, last=last) }}
|
||||
{% if not last %}
|
||||
@@ -24,17 +26,13 @@
|
||||
{{ badge.rebrickable(item, solo=solo, last=last) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if not tiny %}
|
||||
<ul class="list-group list-group-flush card-check">
|
||||
<li class="list-group-item {% if not solo %}p-1{% endif %}">
|
||||
{{ form.checkbox('minifigures-collected', item.fields.u_id, 'Minifigures are collected', item.url_for_minifigures_collected(), item.fields.mini_col, delete=delete) }}
|
||||
</li>
|
||||
<li class="list-group-item {% if not solo %}p-1{% endif %}">
|
||||
{{ form.checkbox('set-checked', item.fields.u_id, 'Set is checked', item.url_for_set_checked(), item.fields.set_check, delete=delete) }}
|
||||
</li>
|
||||
<li class="list-group-item {% if not solo %}p-1{% endif %}">
|
||||
{{ form.checkbox('set-collected', item.fields.u_id, 'Set is collected and boxed', item.url_for_set_collected(), item.fields.set_col, delete=delete) }}
|
||||
</li>
|
||||
{% if not tiny and brickset_checkboxes | length %}
|
||||
<ul class="list-group list-group-flush card-check border-top-0 {% if not solo %}border-bottom-0{% endif %}">
|
||||
{% for checkbox in brickset_checkboxes %}
|
||||
<li class="list-group-item {% if not solo %}p-1{% endif %}">
|
||||
{{ form.checkbox(checkbox.as_dataset(), item.fields.id, checkbox.fields.name, checkbox.status_url(item.fields.id), item.fields[checkbox.as_column()], delete=delete) }}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% if solo %}
|
||||
|
||||
@@ -2,11 +2,11 @@
|
||||
{% import 'macro/card.html' as card %}
|
||||
|
||||
<div class="card mb-3">
|
||||
{{ card.header(item, item.fields.name, solo=true, number=item.fields.set_num) }}
|
||||
{{ card.image(item, solo=true, last=false, caption=item.fields.name, alt=item.fields.set_num) }}
|
||||
{{ card.header(item, item.fields.name, solo=true, number=item.fields.set) }}
|
||||
{{ card.image(item, solo=true, last=false, caption=item.fields.name, alt=item.fields.set) }}
|
||||
<div class="card-body p-1">
|
||||
{{ badge.theme(item.theme_name) }}
|
||||
{{ badge.theme(item.theme.name) }}
|
||||
{{ badge.year(item.fields.year) }}
|
||||
{{ badge.parts(item.fields.num_parts) }}
|
||||
{{ badge.parts(item.fields.number_of_parts) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+6
-4
@@ -19,12 +19,13 @@
|
||||
<span class="input-group-text">Filter</span>
|
||||
<select id="grid-filter" class="form-select form-select-sm" autocomplete="off">
|
||||
<option value="" selected>All sets</option>
|
||||
<option value="minifigures-collected">Minifigures are collected</option>
|
||||
<option value="set-collected">Set is collected and boxed</option>
|
||||
<option value="set-checked">Set is checked</option>
|
||||
<option value="-has-missing">Set is complete</option>
|
||||
<option value="has-missing">Set has missing pieces</option>
|
||||
<option value="has-missing-instructions">Set has missing instructions</option>
|
||||
{% for checkbox in brickset_checkboxes %}
|
||||
<option value="{{ checkbox.as_dataset() }}">{{ checkbox.fields.name }}</option>
|
||||
<option value="-{{ checkbox.as_dataset() }}">NOT: {{ checkbox.fields.name }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<select id="grid-theme" class="form-select form-select-sm" autocomplete="off">
|
||||
<option value="" selected>All themes</option>
|
||||
@@ -69,6 +70,7 @@
|
||||
<script type="text/javascript">
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
new BrickGrid("grid");
|
||||
setup_changers();
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
@@ -79,5 +81,5 @@
|
||||
|
||||
{% block scripts %}
|
||||
<script src="{{ url_for('static', filename='scripts/grid.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='scripts/set.js') }}"></script>
|
||||
<script src="{{ url_for('static', filename='scripts/changer.js') }}"></script>
|
||||
{% endblock %}
|
||||
@@ -18,14 +18,14 @@
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for item in table_collection %}
|
||||
{% set retirement_date = retired.get(item.fields.set_num) %}
|
||||
{% set retirement_date = retired.get(item.fields.set) %}
|
||||
<tr>
|
||||
{{ table.image(item.url_for_image(), caption=item.fields.name, alt=item.fields.set_num) }}
|
||||
<td>{{ item.fields.set_num }}</td>
|
||||
{{ table.image(item.url_for_image(), caption=item.fields.name, alt=item.fields.set) }}
|
||||
<td>{{ item.fields.set }}</td>
|
||||
<td>{{ item.fields.name }}</td>
|
||||
<td>{{ item.theme_name }}</td>
|
||||
<td>{{ item.theme.name }}</td>
|
||||
<td>{{ item.fields.year }}</td>
|
||||
<td>{{ item.fields.num_parts }}</td>
|
||||
<td>{{ item.fields.number_of_parts }}</td>
|
||||
<td>{% if retirement_date %}{{ retirement_date }}{% else %}<span class="badge rounded-pill text-bg-light border">Not found</span>{% endif %}</td>
|
||||
{% if g.login.is_authenticated() %}
|
||||
<td>
|
||||
|
||||
Reference in New Issue
Block a user