Merge remote-tracking branch 'origin/master' into instructions

This commit is contained in:
2025-01-24 19:40:30 +01:00
198 changed files with 3436 additions and 1888 deletions
+2 -6
View File
@@ -4,7 +4,7 @@
{% block main %}
<div class="container">
{% if not config['HIDE_ADD_BULK_SET'].value %}
{% if not config['HIDE_ADD_BULK_SET'] %}
<div class="alert alert-primary" role="alert">
<h4 class="alert-heading">Too many to add?</h4>
<p class="mb-0">You can import multiple sets at once with <a href="{{ url_for('add.bulk') }}" class="btn btn-primary"><i class="ri-function-add-line"></i> Bulk add</a>.</p>
@@ -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>
@@ -70,7 +70,3 @@
</div>
{% include 'set/socket.html' %}
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='scripts/socket.js') }}"></script>
{% endblock %}
+8 -3
View File
@@ -12,20 +12,25 @@
<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' %}
{% elif import_database %}
{% include 'admin/database/import.html' %}
{% elif upgrade_database %}
{% include 'admin/database/upgrade.html' %}
{% else %}
{% include 'admin/logout.html' %}
{% include 'admin/instructions.html' %}
{% if not config['USE_REMOTE_IMAGES'].value %}
{% if not config['USE_REMOTE_IMAGES'] %}
{% include 'admin/image.html' %}
{% endif %}
{% include 'admin/theme.html' %}
{% include 'admin/retired.html' %}
{% include 'admin/checkbox.html' %}
{% include 'admin/database.html' %}
{% include 'admin/configuration.html' %}
{% endif %}
@@ -36,4 +41,4 @@
</div>
</div>
</div>
{% endblock %}
{% endblock %}
+62
View File
@@ -0,0 +1,62 @@
{% 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() }}
+25
View File
@@ -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() }}
+4 -6
View File
@@ -18,12 +18,10 @@
<code>{{ entry.value }}</code>
{% endif %}
{% endif %}
{% if not entry.not_from_env %}
<span class="badge rounded-pill text-bg-light border">Env: {{ entry.env_name }}</span>
{% if entry.extra_name %}<span class="badge rounded-pill text-bg-light border">Env: {{ entry.extra_name }}</span>{% endif %}
{% if entry.is_changed() %}
<span class="badge rounded-pill text-bg-warning">Changed</span>
{% endif %}
<span class="badge rounded-pill text-bg-light border">Env: {{ entry.env_name }}</span>
{% if entry.extra_name %}<span class="badge rounded-pill text-bg-light border">Env: {{ entry.extra_name }}</span>{% endif %}
{% if entry.is_changed() %}
<span class="badge rounded-pill text-bg-warning">Changed</span>
{% endif %}
</li>
{% endfor %}
+26 -43
View File
@@ -2,48 +2,34 @@
{{ accordion.header('Database', 'database', 'admin', expanded=open_database, icon='database-2-line') }}
<h5 class="border-bottom">Status</h5>
{% if exception %}<div class="alert alert-danger" role="alert">An exception occured while loading this page: {{ exception }}</div>{% endif %}
{% if error %}<div class="alert alert-danger" role="alert"><strong>Error:</strong> {{ error }}.</div>{% endif %}
{% if not is_init %}
{% if database_exception %}<div class="alert alert-danger" role="alert">An exception occured while loading this page: {{ database_exception }}</div>{% endif %}
{% if database_error %}<div class="alert alert-danger" role="alert"><strong>Error:</strong> {{ database_error }}.</div>{% endif %}
{% if database_upgrade_needed %}
<div class="alert alert-warning" role="alert">
<p>The database file is: <code>{{ config['DATABASE_PATH'].value }}</code>. The database is not initialized.</p>
<p>Your database needs to be upgraded.</p>
<hr>
<form action="{{ url_for('admin.init_database') }}" method="post" class="text-end">
<button type="submit" class="btn btn-warning"><i class="ri-reset-right-fill"></i> Initialize the database</button>
</form>
</div>
{% else %}
{% if count_none %}
<div class="alert alert-warning" role="alert">
<p>
Your <code>missing</code> table contains <code>"None"</code> entries (instead of <code>NULL</code>). <br>
This can lead to "phantom" missing parts appearing in your sets if you are coming from the original version of BrickTracker.
</p>
<hr>
<form action="{{ url_for('admin.init_database') }}" method="post" class="text-end">
<button type="submit" class="btn btn-warning"><i class="ri-capsule-line"></i> Apply the fix</button>
</form>
<div class="text-end">
<a href="{{ url_for('admin_database.upgrade') }}" class="btn btn-warning" role="button"><i class="ri-arrow-up-double-line"></i> Upgrade the database</a>
</div>
{% endif %}
<p>The database file is: <code>{{ config['DATABASE_PATH'].value }}</code>. <i class="ri-checkbox-circle-line"></i> The database is initialized.</p>
<p>
<a href="{{ url_for('admin.download_database') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Download the database file</a>
</p>
</div>
{% endif %}
<p>The database file is: <code>{{ config['DATABASE_PATH'] }}</code> at version <span class="badge rounded-pill text-bg-light border fw-normal"><i class="ri-hashtag"></i>{{ database_version }}</span></p>
<p>
<a href="{{ url_for('admin_database.download') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Download the database file</a>
</p>
{% if database_counters %}
<h5 class="border-bottom">Records</h5>
<div class="d-flex justify-content-start">
<ul class="list-group">
<li class="list-group-item d-flex justify-content-between align-items-start">
<span><i class="ri-hashtag"></i> Sets</span> <span class="badge text-bg-primary rounded-pill ms-2">{{ counters['sets'] }}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<span><i class="ri-group-line"></i> Minifigures</span> <span class="badge text-bg-primary rounded-pill ms-2">{{ counters['minifigures'] }}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<span><i class="ri-shapes-line"></i> Parts</span> <span class="badge text-bg-primary rounded-pill ms-2">{{ counters['inventory'] }}</span>
</li>
<li class="list-group-item d-flex justify-content-between align-items-start">
<span><i class="ri-error-warning-line"></i> Missing</span> <span class="badge text-bg-primary rounded-pill ms-2">{{ counters['missing'] }}</span>
</li>
<ul class="list-group me-2">
{% for counter in database_counters %}
<li class="list-group-item d-flex justify-content-between align-items-start">
<span><i class="ri-{{ counter.icon }}"></i> {{ counter.name }}</span> <span class="badge text-bg-primary rounded-pill ms-2">{{ counter.count }}</span>
</li>
{% if not (loop.index % 5) %}
</ul>
<ul class="list-group me-2">
{% endif %}
{% endfor %}
</ul>
</div>
{% endif %}
@@ -51,10 +37,7 @@
{{ accordion.header('Database danger zone', 'database-danger', 'admin', danger=true, class='text-end') }}
{% if error %}<div class="alert alert-danger text-start" role="alert"><strong>Error:</strong> {{ error }}.</div>{% endif %}
<a href="{{ url_for('admin.import_database') }}" class="btn btn-warning" role="button"><i class="ri-upload-line"></i> Import a database file</a>
<form action="{{ url_for('admin.init_database') }}" method="post" class="d-inline">
<button type="submit" class="btn btn-warning"><i class="ri-reset-right-fill"></i> Initialize the database (only missing tables)</button>
</form>
<a href="{{ url_for('admin.drop_database') }}" class="btn btn-danger" role="button"><i class="ri-close-line"></i> Drop the database</a>
<a href="{{ url_for('admin.delete_database') }}" class="btn btn-danger" role="button"><i class="ri-delete-bin-2-line"></i> Delete the database file</a>
<a href="{{ url_for('admin_database.upload') }}" class="btn btn-warning" role="button"><i class="ri-upload-line"></i> Import a database file</a>
<a href="{{ url_for('admin_database.drop') }}" class="btn btn-danger" role="button"><i class="ri-close-line"></i> Drop the database</a>
<a href="{{ url_for('admin_database.delete') }}" class="btn btn-danger" role="button"><i class="ri-delete-bin-2-line"></i> Delete the database file</a>
{{ accordion.footer() }}
+1 -1
View File
@@ -1,7 +1,7 @@
{% import 'macro/accordion.html' as accordion %}
{{ accordion.header('Database danger zone', 'database-danger', 'admin', expanded=true, danger=true, class='text-end') }}
<form action="{{ url_for('admin.do_delete_database') }}" method="post">
<form action="{{ url_for('admin_database.do_delete') }}" 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 the database file</strong>. This action is irreversible.</div>
<a class="btn btn-danger" href="{{ url_for('admin.admin') }}" role="button"><i class="ri-arrow-left-long-line"></i> Back to the admin</a>
+1 -1
View File
@@ -1,7 +1,7 @@
{% import 'macro/accordion.html' as accordion %}
{{ accordion.header('Database danger zone', 'database-danger', 'admin', expanded=true, danger=true, class='text-end') }}
<form action="{{ url_for('admin.do_drop_database') }}" method="post">
<form action="{{ url_for('admin_database.do_drop') }}" 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>drop all the tables from the database</strong>. This action is irreversible.</div>
<a class="btn btn-danger" href="{{ url_for('admin.admin') }}" role="button"><i class="ri-arrow-left-long-line"></i> Back to the admin</a>
+1 -1
View File
@@ -1,7 +1,7 @@
{% import 'macro/accordion.html' as accordion %}
{{ accordion.header('Database danger zone', 'database-danger', 'admin', expanded=true, danger=true) }}
<form action="{{ url_for('admin.do_import_database') }}" method="post" enctype="multipart/form-data">
<form action="{{ url_for('admin_database.do_upload') }}" method="post" enctype="multipart/form-data">
{% if error %}<div class="alert alert-danger text-start" role="alert"><strong>Error:</strong> {{ error }}.</div>{% endif %}
<div class="alert alert-warning text-center" role="alert">You are about to <strong>import a database file</strong>. This will replace the <strong>whole content</strong> of the database. This action is irreversible.</div>
<div class="mb-3">
+29
View File
@@ -0,0 +1,29 @@
{% import 'macro/accordion.html' as accordion %}
{{ accordion.header('Database', 'database', 'admin', expanded=true, icon='database-2-line') }}
<form action="{{ url_for('admin_database.do_upgrade') }}" method="post">
{% if error %}<div class="alert alert-danger text-start" role="alert"><strong>Error:</strong> {{ error }}.</div>{% endif %}
<div class="alert alert-warning text-center" role="alert">
You are about to <strong>upgrade your database file</strong>. This action is irreversible.<br>
The process shold be lossless, but just to be sure, grab a copy of your database before proceeding.<br>
</div>
<h5 class="border-bottom">Upgrades</h5>
<ul>
{% for migration in migrations %}
<li>
<span class="badge rounded-pill text-bg-light border fw-normal me-2"><i class="ri-hashtag"></i>{{ migration.version }}</span>
{% if migration.get_description() %}
<code>{{ migration.get_description() }}</code>
{% else %}
<span class="badge rounded-pill text-bg-secondary fst-italic">No description</span>
{% endif %}
</li>
{% endfor %}
</ul>
<div class="text-end">
<a class="btn btn-danger" href="{{ url_for('admin.admin') }}" role="button"><i class="ri-arrow-left-long-line"></i> Back to the admin</a>
<a href="{{ url_for('admin_database.download') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Download the database file</a>
<button type="submit" class="btn btn-warning"><i class="ri-arrow-up-double-line"></i> Upgrade the database</button>
</div>
</form>
{{ accordion.footer() }}
+1 -1
View File
@@ -9,6 +9,6 @@
<img class="table-img border mx-1" src="{{ nil_part_url }}" alt="{{ nil_part_name }}">
</div>
<p>
<a href="{{ url_for('admin.update_image') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Update the images</a>
<a href="{{ url_for('admin_image.update') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Update the images</a>
</p>
{{ accordion.footer() }}
+3 -3
View File
@@ -3,8 +3,8 @@
{{ accordion.header('Instructions', 'instructions', 'admin', expanded=open_instructions, icon='file-line') }}
<h5 class="border-bottom">Folder</h5>
<p>
The instructions files folder is: <code>{{ config['INSTRUCTIONS_FOLDER'].value }}</code>. <br>
Allowed file formats for instructions are the following: <code>{{ ', '.join(config['INSTRUCTIONS_ALLOWED_EXTENSIONS'].value) }}</code>.
The instructions files folder is: <code>{{ config['INSTRUCTIONS_FOLDER'] }}</code>. <br>
Allowed file formats for instructions are the following: <code>{{ ', '.join(config['INSTRUCTIONS_ALLOWED_EXTENSIONS']) }}</code>.
</p>
<h5 class="border-bottom">Counters</h5>
<p>
@@ -27,6 +27,6 @@
</p>
<h5 class="border-bottom">Refresh</h5>
<p>
<a href="{{ url_for('admin.refresh_instructions') }}" class="btn btn-primary" role="button"><i class="ri-refresh-line"></i> Refresh the instructions cache</a>
<a href="{{ url_for('admin_instructions.refresh') }}" class="btn btn-primary" role="button"><i class="ri-refresh-line"></i> Refresh the instructions cache</a>
</p>
{{ accordion.footer() }}
+3 -3
View File
@@ -4,7 +4,7 @@
<h5 class="border-bottom">File</h5>
{% if retired.exception %}<div class="alert alert-danger" role="alert">An exception occured while loading processing the retired sets: {{ retired.exception }}</div>{% endif %}
<p>
The retired sets file is: <code>{{ config['RETIRED_SETS_PATH'].value }}</code>.
The retired sets file is: <code>{{ config['RETIRED_SETS_PATH'] }}</code>.
{% if retired.size %}<span class="badge rounded-pill text-bg-info fw-normal"><i class="ri-hard-drive-line"></i> {{ retired.human_size() }}</span>{% endif %}
{% if retired.mtime %}<span class="badge rounded-pill text-bg-light border fw-normal"><i class="ri-calendar-line"></i> {{ retired.human_time() }}</span>{% endif %}
</p>
@@ -20,7 +20,7 @@
</p>
<h5 class="border-bottom">Refresh</h5>
<p>
<a href="{{ url_for('admin.refresh_retired') }}" class="btn btn-primary" role="button"><i class="ri-refresh-line"></i> Refresh the retired sets cache</a>
<a href="{{ url_for('admin.update_retired') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Update the retired sets file</a>
<a href="{{ url_for('admin_retired.refresh') }}" class="btn btn-primary" role="button"><i class="ri-refresh-line"></i> Refresh the retired sets cache</a>
<a href="{{ url_for('admin_retired.update') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Update the retired sets file</a>
</p>
{{ accordion.footer() }}
+3 -3
View File
@@ -4,7 +4,7 @@
<h5 class="border-bottom">File</h5>
{% if theme.exception %}<div class="alert alert-danger" role="alert">An exception occured while loading processing the themes: {{ theme.exception }}</div>{% endif %}
<p>
The themes file is: <code>{{ config['THEMES_PATH'].value }}</code>.
The themes file is: <code>{{ config['THEMES_PATH'] }}</code>.
{% if theme.size %}<span class="badge rounded-pill text-bg-info fw-normal"><i class="ri-hard-drive-line"></i> {{ theme.human_size() }}</span>{% endif %}
{% if theme.mtime %}<span class="badge rounded-pill text-bg-light border fw-normal"><i class="ri-calendar-line"></i> {{ theme.human_time() }}</span>{% endif %}
</p>
@@ -20,7 +20,7 @@
</p>
<h5 class="border-bottom">Refresh</h5>
<p>
<a href="{{ url_for('admin.refresh_themes') }}" class="btn btn-primary" role="button"><i class="ri-refresh-line"></i> Refresh the themes cache</a>
<a href="{{ url_for('admin.update_themes') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Update the themes file</a>
<a href="{{ url_for('admin_theme.refresh') }}" class="btn btn-primary" role="button"><i class="ri-refresh-line"></i> Refresh the themes cache</a>
<a href="{{ url_for('admin_theme.update') }}" class="btn btn-primary" role="button"><i class="ri-download-line"></i> Update the themes file</a>
</p>
{{ accordion.footer() }}
+17 -3
View File
@@ -25,7 +25,7 @@
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav me-auto mb-2 mb-lg-0">
{% for item in config['_NAVBAR'] %}
{% if item.flag and not config[item.flag].value %}
{% if item.flag and not config[item.flag] %}
<li class="nav-item px-1">
<a {% if request.url_rule.endpoint == item.endpoint %}class="nav-link active" aria-current="page"{% else %}class="nav-link"{% endif %} href="{{ url_for(item.endpoint) }}">
{% if item.icon %}
@@ -61,7 +61,7 @@
<div class="col-md-6 d-flex justify-content-center">
<small>
<i class="ri-timer-2-line"></i> {{ g.request_time() }}
{%if config['DEBUG'].value and g.database_stats %}
{%if config['DEBUG'] and g.database_stats %}
| <i class="ri-database-2-line"></i> {{g.database_stats.print() }}
{% endif %}
</small>
@@ -78,11 +78,25 @@
<script src="https://cdnjs.cloudflare.com/ajax/libs/baguettebox.js/1.12.0/baguetteBox.min.js" integrity="sha512-HzIuiABxntLbBS8ClRa7drXZI3cqvkAZ5DD0JCAkmRwUtykSGqzA9uItHivDhRUYnW3MMyY5xqk7qVUHOEMbMA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.8.1/socket.io.min.js" integrity="sha512-8ExARjWWkIllMlNzVg7JKq9RKWPlJABQUNq6YvAjE/HobctjH/NA+bSiDMDvouBVjp4Wwnf1VP1OEv7Zgjtuxw==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.jsdelivr.net/npm/simple-datatables@9.2.1/dist/umd/simple-datatables.min.js"></script>
<!-- BrickTracker scripts -->
<script src="{{ url_for('static', filename='scripts/changer.js') }}"></script>
<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/socket.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/table.js') }}"></script>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
setup_grids();
setup_changers();
setup_tables({{ config['DEFAULT_TABLE_PER_PAGE'] }});
baguetteBox.run('[data-lightbox]');
});
</script>
<!-- Bootstrap tooltips -->
<script type="text/javascript">
const tooltipTriggerList = document.querySelectorAll('[data-bs-toggle="tooltip"]')
const tooltipList = [...tooltipTriggerList].map(tooltipTriggerEl => new bootstrap.Tooltip(tooltipTriggerEl))
</script>
{% block scripts %}{% endblock %}
</body>
</html>
-4
View File
@@ -62,7 +62,3 @@
{% include 'set/socket.html' %}
{% endwith %}
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='scripts/socket.js') }}"></script>
{% endblock %}
+1 -10
View File
@@ -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">
@@ -12,13 +12,4 @@
</div>
</div>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
baguetteBox.run('[data-lightbox]');
});
</script>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='scripts/set.js') }}"></script>
{% endblock %}
+4 -4
View File
@@ -3,8 +3,8 @@
{% block main %}
<div class="container-fluid">
<h2 class="border-bottom lh-base pb-1">
<i class="ri-hashtag"></i> {% if config['RANDOM'].value %}Random selection of{% else %}Latest added{% endif %} sets
{% if not config['HIDE_ALL_SETS'].value %}
<i class="ri-hashtag"></i> {% if config['RANDOM'] %}Random selection of{% else %}Latest added{% endif %} sets
{% if not config['HIDE_ALL_SETS'] %}
<a href="{{ url_for('set.list') }}" class="btn btn-sm btn-primary ms-1">All sets</a>
{% endif %}
</h2>
@@ -23,8 +23,8 @@
{% endif %}
{% if minifigure_collection | length %}
<h2 class="border-bottom lh-base pb-1">
<i class="ri-group-line"></i> {% if config['RANDOM'].value %}Random selection of{% else %}Latest added{% endif %} minifigures
{% if not config['HIDE_ALL_MINIFIGURES'].value %}
<i class="ri-group-line"></i> {% if config['RANDOM'] %}Random selection of{% else %}Latest added{% endif %} minifigures
{% if not config['HIDE_ALL_MINIFIGURES'] %}
<a href="{{ url_for('minifigure.list') }}" class="btn btn-sm btn-primary ms-1">All minifigures</a>
{% endif %}
</h2>
+1 -1
View File
@@ -25,4 +25,4 @@
{% endwith %}
</div>
{% endif %}
{% endblock %}
{% endblock %}
+2 -7
View File
@@ -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>
@@ -28,8 +28,3 @@
<div class="card-footer"></div>
</div>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
baguetteBox.run('[data-lightbox]');
});
</script>
+2 -7
View File
@@ -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>
@@ -34,8 +34,3 @@
<div class="card-footer"></div>
</div>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
baguetteBox.run('[data-lightbox]');
});
</script>
+9 -12
View File
@@ -1,14 +1,14 @@
{% import 'macro/table.html' as table %}
<div class="table-responsive-sm">
<table class="table table-striped align-middle" id="instructions">
<table data-table="{% if all %}true{% endif %}" class="table table-striped align-middle" id="instructions">
<thead>
<tr>
<th scope="col"><i class="ri-file-line fw-normal"></i> Filename</th>
<th scope="col"><i class="ri-hashtag fw-normal"></i> Set</th>
<th class="no-sort" scope="col"><i class="ri-image-line fw-normal"></i> Image</th>
<th data-table-no-sort="true" class="no-sort" scope="col"><i class="ri-image-line fw-normal"></i> Image</th>
{% if g.login.is_authenticated() %}
<th class="no-sort" scope="col"><i class="ri-settings-4-line fw-normal"></i> Actions</th>
<th data-table-no-sort="true" class="no-sort" scope="col"><i class="ri-settings-4-line fw-normal"></i> Actions</th>
{% endif %}
</tr>
</thead>
@@ -23,15 +23,15 @@
{%- if item.allowed -%}
</a>
{% endif %}
<span class="badge rounded-pill text-bg-info fw-normal"><i class="ri-hard-drive-line"></i> {{ item.human_size() }}</span>
<span class="badge rounded-pill text-bg-light border fw-normal"><i class="ri-calendar-line"></i> {{ item.human_time() }}</span>
<span data-search="exclude" class="badge rounded-pill text-bg-info fw-normal"><i class="ri-hard-drive-line"></i> {{ item.human_size() }}</span>
<span data-search="exclude" 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 %}
@@ -46,6 +46,3 @@
</tbody>
</table>
</div>
{% if all %}
{{ table.dynamic('instructions', no_sort='2,3')}}
{% endif %}
+2 -2
View File
@@ -26,8 +26,8 @@
<div class="mb-3">
<label for="file" class="form-label">Instructions file</label>
<div class="input-group">
<input type="file" class="form-control" id="file" name="file" accept="{{ ','.join(config['INSTRUCTIONS_ALLOWED_EXTENSIONS'].value) }}">
<span class="input-group-text">{{ ', '.join(config['INSTRUCTIONS_ALLOWED_EXTENSIONS'].value) }}</span>
<input type="file" class="form-control" id="file" name="file" accept="{{ ','.join(config['INSTRUCTIONS_ALLOWED_EXTENSIONS']) }}">
<span class="input-group-text">{{ ', '.join(config['INSTRUCTIONS_ALLOWED_EXTENSIONS']) }}</span>
</div>
</div>
<div class="text-end">
+1 -1
View File
@@ -16,7 +16,7 @@
{% endif %}
</button>
</h2>
<div id="{{ id }}" class="accordion-collapse collapse {% if expanded %}show{% endif %}" {% if not config['INDEPENDENT_ACCORDIONS'].value %}data-bs-parent="#{{ parent }}"{% endif %}>
<div id="{{ id }}" class="accordion-collapse collapse {% if expanded %}show{% endif %}" {% if not config['INDEPENDENT_ACCORDIONS'] %}data-bs-parent="#{{ parent }}"{% endif %}>
<div class="accordion-body {% if class %}{{ class }}{% endif %}">
{% endmacro %}
+9 -5
View File
@@ -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>
+8 -32
View File
@@ -1,25 +1,25 @@
{% macro header(color=false, quantity=false, missing=false, missing_parts=false, sets=false, minifigures=false) %}
<thead>
<tr>
<th class="no-sort" scope="col"><i class="ri-image-line fw-normal"></i> Image</th>
<th data-table-no-sort="true" class="no-sort" scope="col"><i class="ri-image-line fw-normal"></i> Image</th>
<th scope="col"><i class="ri-pencil-line fw-normal"></i> Name</th>
{% if color %}
<th scope="col"><i class="ri-palette-line fw-normal"></i> Color</th>
{% endif %}
{% if quantity %}
<th scope="col"><i class="ri-functions fw-normal"></i> Quantity</th>
<th data-table-number="true" scope="col"><i class="ri-functions fw-normal"></i> Quantity</th>
{% endif %}
{% if missing %}
<th scope="col"><i class="ri-error-warning-line fw-normal"></i> Missing</th>
<th data-table-number="true" scope="col"><i class="ri-error-warning-line fw-normal"></i> Missing</th>
{% endif %}
{% if missing_parts %}
<th scope="col"><i class="ri-error-warning-line fw-normal"></i> Missing parts</th>
<th data-table-number="true" scope="col"><i class="ri-error-warning-line fw-normal"></i> Missing parts</th>
{% endif %}
{% if sets %}
<th scope="col"><i class="ri-hashtag fw-normal"></i> Sets</th>
<th data-table-number="true" scope="col"><i class="ri-hashtag fw-normal"></i> Sets</th>
{% endif %}
{% if minifigures %}
<th scope="col"><i class="ri-group-line fw-normal"></i> Minifigures</th>
<th data-table-number="true" scope="col"><i class="ri-group-line fw-normal"></i> Minifigures</th>
{% endif %}
</tr>
</thead>
@@ -28,7 +28,7 @@
{% macro bricklink(item) %}
{% set url=item.url_for_bricklink() %}
{% if url %}
<a href="{{ url }}" target="_blank" class="badge rounded-pill text-bg-light border fw-normal">
<a data-search="exclude" href="{{ url }}" target="_blank" class="badge rounded-pill text-bg-light border fw-normal">
<i class="ri-external-link-line"></i> Bricklink
</a>
{% endif %}
@@ -45,32 +45,8 @@
{% macro rebrickable(item) %}
{% set url=item.url_for_rebrickable() %}
{% if url %}
<a href="{{ url }}" target="_blank" class="badge rounded-pill text-bg-light border fw-normal">
<a data-search="exclude" href="{{ url }}" target="_blank" class="badge rounded-pill text-bg-light border fw-normal">
<i class="ri-external-link-line"></i> Rebrickable
</a>
{% endif %}
{% endmacro %}
{% macro dynamic(id, no_sort=none, number=none) %}
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
new simpleDatatables.DataTable("#{{ id }}", {
columns: [
{% if no_sort %}{ select: [{{ no_sort }}], sortable: false, searchable: false },{% endif %}
{% if number %}{ select: [{{ number }}], type: "number", searchable: false },{% endif %}
],
pagerDelta: 1,
perPage: {{ config['DEFAULT_TABLE_PER_PAGE'].value }},
perPageSelect: [10, 25, 50, 100, 500, 1000],
searchable: true,
searchQuerySeparator: "",
tableRender: () => {
baguetteBox.run('[data-lightbox]')
},
pagerRender: () => {
baguetteBox.run('[data-lightbox]')
}
});
});
</script>
{% endmacro %}
-5
View File
@@ -12,9 +12,4 @@
</div>
</div>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
baguetteBox.run('[data-lightbox]');
});
</script>
{% endblock %}
+1 -4
View File
@@ -1,7 +1,7 @@
{% import 'macro/table.html' as table %}
<div class="table-responsive-sm">
<table class="table table-striped align-middle" id="minifigures">
<table data-table="{% if all %}true{% endif %}" class="table table-striped align-middle" id="minifigures">
{{ table.header(quantity=true, missing_parts=true, sets=true) }}
<tbody>
{% for item in table_collection %}
@@ -21,6 +21,3 @@
</tbody>
</table>
</div>
{% if all %}
{{ table.dynamic('minifigures', no_sort='0', number='2, 3, 4')}}
{% endif %}
+1 -1
View File
@@ -8,4 +8,4 @@
{% include 'minifigure/table.html' %}
{% endwith %}
</div>
{% endblock %}
{% endblock %}
+1 -1
View File
@@ -8,4 +8,4 @@
{% include 'part/table.html' %}
{% endwith %}
</div>
{% endblock %}
{% endblock %}
-5
View File
@@ -12,9 +12,4 @@
</div>
</div>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
baguetteBox.run('[data-lightbox]');
});
</script>
{% endblock %}
+1 -4
View File
@@ -1,7 +1,7 @@
{% import 'macro/table.html' as table %}
<div class="table-responsive-sm">
<table class="table table-striped align-middle {% if not all %}sortable mb-0{% endif %}" {% if all %}id="parts"{% endif %}>
<table data-table="{% if all %}true{% endif %}" class="table table-striped align-middle {% if not all %}sortable mb-0{% endif %}" {% if all %}id="parts"{% endif %}>
{{ table.header(color=true, quantity=not no_quantity, missing=not no_missing, sets=all, minifigures=all) }}
<tbody>
{% for item in table_collection %}
@@ -51,6 +51,3 @@
</tbody>
</table>
</div>
{% if all %}
{{ table.dynamic('parts', no_sort='0', number='3, 4, 5, 6')}}
{% endif %}
+1 -1
View File
@@ -8,4 +8,4 @@
{% include 'part/table.html' %}
{% endwith %}
</div>
{% endblock %}
{% endblock %}
+1 -10
View File
@@ -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">
@@ -12,13 +12,4 @@
</div>
</div>
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
baguetteBox.run('[data-lightbox]');
});
</script>
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='scripts/set.js') }}"></script>
{% endblock %}
+20 -22
View File
@@ -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 border-bottom-0 {% if not solo %}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,21 +26,17 @@
{{ 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-bottom-0">
{% 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 %}
<div class="accordion accordion-flush" id="set-details">
<div class="accordion accordion-flush border-top" id="set-details">
{% if not delete %}
{{ accordion.header('Instructions', 'instructions', 'set-details', expanded=open_instructions, quantity=item.instructions | length, icon='file-line', class='p-0') }}
<div class="list-group list-group-flush">
+4 -4
View File
@@ -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>
+5 -14
View File
@@ -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>
@@ -57,7 +58,7 @@
</div>
</div>
<div class="row" id="grid">
<div class="row" data-grid="true" id="grid">
{% for item in collection %}
<div class="col-md-6 col-xl-3 d-flex align-items-stretch">
{% with index=loop.index0 %}
@@ -66,18 +67,8 @@
</div>
{% endfor %}
</div>
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", () => {
new BrickGrid("grid");
});
</script>
</div>
{% else %}
{% include 'set/empty.html' %}
{% endif %}
{% endblock %}
{% block scripts %}
<script src="{{ url_for('static', filename='scripts/grid.js') }}"></script>
<script src="{{ url_for('static', filename='scripts/set.js') }}"></script>
{% endblock %}
+8 -11
View File
@@ -2,10 +2,10 @@
{% import 'macro/badge.html' as badge %}
<div class="table-responsive-sm">
<table class="table table-striped align-middle" id="wish">
<table data-table="{% if all %}true{% endif %}" class="table table-striped align-middle" id="wish">
<thead>
<tr>
<th class="no-sort" scope="col"><i class="ri-image-line fw-normal"></i> Image</th>
<th data-table-no-sort="true" class="no-sort" scope="col"><i class="ri-image-line fw-normal"></i> Image</th>
<th scope="col"><i class="ri-hashtag fw-normal"></i> Set</th>
<th scope="col"><i class="ri-pencil-line fw-normal"></i> Name</th>
<th scope="col"><i class="price-tag-3-line fw-normal"></i> Theme</th>
@@ -13,20 +13,20 @@
<th scope="col"><i class="ri-shapes-line fw-normal"></i> Parts</th>
<th scope="col"><i class="ri-calendar-close-line fw-normal"></i> Retirement</th>
{% if g.login.is_authenticated() %}
<th class="no-sort" scope="col"><i class="ri-settings-4-line fw-normal"></i> Actions</th>
<th data-table-no-sort="true" class="no-sort" scope="col"><i class="ri-settings-4-line fw-normal"></i> Actions</th>
{% endif %}
</tr>
</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 }}<br>{{ badge.rebrickable(item) }}</td>
{{ table.image(item.url_for_image(), caption=item.fields.name, alt=item.fields.set) }}
<td>{{ item.fields.set }} {{ table.rebrickable(item) }}</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>
@@ -40,6 +40,3 @@
</tbody>
</table>
</div>
{% if all %}
{{ table.dynamic('wish', no_sort='0,7')}}
{% endif %}
+1 -1
View File
@@ -28,4 +28,4 @@
{% include 'wish/table.html' %}
{% endwith %}
</div>
{% endblock %}
{% endblock %}