swaf/assets/views/macros.njk
Alice Gaudon 6aa37eb9e4 Add two step pre-compile/compile asset processing
Reorganize views into new "assets" folder structure
Turn locals into a store so locals don't have to be passed through files that don't need them
Some fixes to previous commit (esm) 82ab0b963c
Remove afs in favor of fs.promises (renamed afs.exists to Utils.doesFileExist
Rename Utils.readdirRecursively to Utils.listFilesRecursively
2021-05-04 17:14:32 +02:00

186 lines
7.8 KiB
Plaintext

{% macro message(type, content, raw=false, discreet=false) %}
<div class="message{{ ' message-discreet' if discreet }}" data-type="{{ type }}">
<i class="icon"></i>
<span class="content">
{{ content|safe if raw else content }}
</span>
</div>
{% endmacro %}
{% macro messages(flash) %}
{% set flashed = flash() %}
{% set display = 0 %}
{% for type, bag in flashed %}
{% if bag|length %}
{% set display = 1 %}
{% endif %}
{% endfor %}
{% if display %}
<div class="messages">
{% for type, bag in flashed %}
{% for content in bag %}
{{ message(type, content) }}
{% endfor %}
{% endfor %}
</div>
{% endif %}
{% endmacro %}
{% macro csrf(getCsrfToken) %}
<input type="hidden" name="csrf" value="{{ getCsrfToken() }}">
{% endmacro %}
{% macro field(_locals, type, name, value, placeholder, hint, validation_attributes='', extraData='', icon=null) %}
{% set validation = _locals.validation() %}
{% set validation = validation[name] if validation[name] or null %}
{% set previousFormData = _locals.previousFormData() %}
{% set value = previousFormData[name] or value or validation.value or '' %}
{% set prefix = _locals.getFormPrefix() | default('') %}
{% if type == 'hidden' %}
{% if validation %}
{{ message('error', validation.message) }}
{% endif %}
<input type="hidden" name="{{ name }}" value="{{ value }}">
{% else %}
<div class="form-field{{ ' inline' if type == 'checkbox' }}">
<div class="control">
{% if icon != null %}
{% if icon.startsWith('fa') %}
<i class="{{ icon }} feather icon"></i>
{% else %}
<i data-feather="{{ icon }}" class="icon"></i>
{% endif %}
{% endif %}
{% if type == 'duration' %}
<div class="input-group">
{% for f in extraData %}
<div class="time-input">
{% if previousFormData[name] %}
{% set v = value[f] %}
{% else %}
{% set v = (value % 60) if f == 's' else (((value - value % 60) / 60 % 60) if f == 'm' else ((value - value % 3600) / 3600 if f == 'h')) %}
{% endif %}
<input type="number" name="{{ name }}[{{ f }}]" id="field-{{ prefix }}{{ name }}-{{ f }}"
value="{{ v }}"
min="0" {{ 'max=60' if (f == 's' or f == 'm') }}
{{ validation_attributes }}>
<label for="field-{{ prefix }}{{ name }}-{{ f }}">{{ f }}</label>
</div>
{% endfor %}
</div>
{% elseif type == 'select' %}
<select name="{{ name }}" id="field-{{ prefix }}{{ name }}" {{ validation_attributes|safe }}>
{% for option in extraData %}
<option value="{% if option.display === undefined or option.value !== undefined %}{{ option.value | default(option) }}{% endif %}"
{{ 'selected' if value == (option.value | default(option)) }}>{{ option.display | default(option) }}</option>
{% endfor %}
</select>
<i data-feather="chevron-down"></i>
{% elseif type == 'textarea' %}
<textarea name="{{ name }}" id="field-{{ prefix }}{{ name }}"
{{ validation_attributes|safe }} value="{{ value }}">{{ value }}</textarea>
{% else %}
<input type="{{ type }}" name="{{ name }}" id="field-{{ prefix }}{{ name }}"
{% if type != 'checkbox' %} value="{{ value }}" {% endif %}
{{ 'checked' if (type == 'checkbox' and value == 'on') }}
{{ validation_attributes|safe }}>
{% endif %}
<label for="field-{{ prefix }}{{ name }}{{ '-' + extraData[0] if type == 'duration' }}">{{ placeholder }}</label>
</div>
{{ fieldError(_locals, name) }}
{% if hint %}
<div class="hint"><i data-feather="info"></i> {{ hint }}</div>
{% endif %}
</div>
{% endif %}
{% endmacro %}
{% macro fieldError(_locals, name) %}
{% set validation = _locals.validation() %}
{% set validation = validation[name] if validation[name] or null %}
{% if validation %}
<div class="error"><i data-feather="x-circle"></i> {{ validation.message }}</div>
{% endif %}
{% endmacro %}
{% macro websocket(websocketUrl, listener, reconnectOnClose = 1, checkFunction = 0) %}
<script>
document.addEventListener('DOMContentLoaded', () => {
{% if checkFunction %}
if (!{{ checkFunction }}()) return;
{% endif %}
const run = () => {
const websocket = new WebSocket('{{ websocketUrl }}');
websocket.onopen = (e) => {
console.debug('Websocket connected');
};
websocket.onmessage = (e) => {
{{ listener }}(websocket, e);
};
websocket.onerror = (e) => {
console.error('Websocket error', e);
};
websocket.onclose = (e) => {
console.debug('Websocket closed', e.code, e.reason);
{% if reconnectOnClose %}
setTimeout(run, 1000);
{% endif %}
};
};
run();
});
</script>
{% endmacro %}
{% macro paginate(pagination, routeName, contextSize) %}
{% if pagination.hasPrevious() or pagination.hasNext() %}
<nav class="pagination">
<ul>
{% if pagination.hasPrevious() %}
<li><a href="{{ route(routeName, {page: pagination.page - 1}) }}"><i data-feather="chevron-left"></i> Previous</a></li>
{% for i in pagination.previousPages(contextSize) %}
{% if i == -1 %}
<li class="ellipsis">...</li>
{% else %}
<li><a href="{{ route(routeName, {page: i}) }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
{% endif %}
<li class="active"><span>{{ pagination.page }}</span></li>
{% if pagination.hasNext() %}
{% for i in pagination.nextPages(contextSize) %}
{% if i == -1 %}
<li class="ellipsis">...</li>
{% else %}
<li><a href="{{ route(routeName, {page: i}) }}">{{ i }}</a></li>
{% endif %}
{% endfor %}
<li><a href="{{ route(routeName, {page: pagination.page + 1}) }}">Next <i data-feather="chevron-right"></i></a></li>
{% endif %}
</ul>
</nav>
{% endif %}
{% endmacro %}
{% macro breadcrumb(currentPageTitle, pages=[]) %}
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
{% for page in pages %}
<li><a href="{{ page.link }}">{{ page.title }}</a></li>
{% endfor %}
<li class="active" aria-current="page">{{ currentPageTitle }}</li>
</ol>
</nav>
{% endmacro %}