mirror of
https://codeberg.org/Mo8it/AdvLabDB.git
synced 2024-12-30 18:23:56 +00:00
Added admin templates
This commit is contained in:
parent
718d7744d3
commit
45c3d55470
28 changed files with 1421 additions and 10 deletions
|
@ -9,25 +9,19 @@ from advlabdb.utils import userActiveSemester
|
|||
def adminViewIsAccessible():
|
||||
return current_user.has_role("admin")
|
||||
|
||||
def handleAdminView():
|
||||
flash("User active semester: " + userActiveSemester(flashWarning=True).label)
|
||||
|
||||
class SecureAdminIndexView(AdminIndexView):
|
||||
def is_accessible(self):
|
||||
return adminViewIsAccessible()
|
||||
|
||||
def _handle_view(self, *args, **kwargs):
|
||||
handleAdminView()
|
||||
return super()._handle_view(*args, **kwargs)
|
||||
|
||||
|
||||
class SecureModelView(ModelView):
|
||||
can_export = True
|
||||
can_set_page_size = True
|
||||
|
||||
list_template = "admin_list.html"
|
||||
create_template = "admin_create.html"
|
||||
edit_template = "admin_edit.html"
|
||||
|
||||
def is_accessible(self):
|
||||
return adminViewIsAccessible()
|
||||
|
||||
def _handle_view(self, *args, **kwargs):
|
||||
handleAdminView()
|
||||
return super()._handle_view(*args, **kwargs)
|
||||
|
|
34
advlabdb/templates/admin/actions.html
Normal file
34
advlabdb/templates/admin/actions.html
Normal file
|
@ -0,0 +1,34 @@
|
|||
{% import 'admin/static.html' as admin_static with context %}
|
||||
|
||||
{% macro dropdown(actions, btn_class='btn dropdown-toggle') -%}
|
||||
<a class="{{ btn_class }}" data-toggle="dropdown" href="javascript:void(0)">{{ _gettext('With selected') }}<b class="caret"></b></a>
|
||||
<ul class="dropdown-menu">
|
||||
{% for p in actions %}
|
||||
<li>
|
||||
<a href="javascript:void(0)" onclick="return modelActions.execute('{{ p[0] }}');">{{ _gettext(p[1]) }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro form(actions, url) %}
|
||||
{% if actions %}
|
||||
<form id="action_form" action="{{ url }}" method="POST" style="display: none">
|
||||
{% if action_form.csrf_token %}
|
||||
{{ action_form.csrf_token }}
|
||||
{% elif csrf_token %}
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
{% endif %}
|
||||
{{ action_form.url(value=return_url) }}
|
||||
{{ action_form.action() }}
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro script(message, actions, actions_confirmation) %}
|
||||
{% if actions %}
|
||||
<div id="actions-confirmation-data" style="display:none;">{{ actions_confirmation|tojson|safe }}</div>
|
||||
<div id="message-data" style="display:none;">{{ message|tojson|safe }}</div>
|
||||
<script src="{{ admin_static.url(filename='admin/js/actions.js', v='1.0.0') }}"></script>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
98
advlabdb/templates/admin/base.html
Normal file
98
advlabdb/templates/admin/base.html
Normal file
|
@ -0,0 +1,98 @@
|
|||
{% import 'admin/layout.html' as layout with context -%}
|
||||
{% import 'admin/static.html' as admin_static with context %}
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block title %}{% if admin_view.category %}{{ admin_view.category }} - {% endif %}{{ admin_view.name }} - {{ admin_view.admin.name }}{% endblock %}</title>
|
||||
{% block head_meta %}
|
||||
<meta charset="UTF-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="description" content="">
|
||||
<meta name="author" content="">
|
||||
{% endblock %}
|
||||
{% block head_css %}
|
||||
<link href="{{ admin_static.url(filename='bootstrap/bootstrap3/swatch/{swatch}/bootstrap.min.css'.format(swatch=config.get('FLASK_ADMIN_SWATCH', 'default')), v='3.3.5') }}" rel="stylesheet">
|
||||
{%if config.get('FLASK_ADMIN_SWATCH', 'default') == 'default' %}
|
||||
<link href="{{ admin_static.url(filename='bootstrap/bootstrap3/css/bootstrap-theme.min.css', v='3.3.5') }}" rel="stylesheet">
|
||||
{%endif%}
|
||||
<link href="{{ admin_static.url(filename='admin/css/bootstrap3/admin.css', v='1.1.1') }}" rel="stylesheet">
|
||||
<link href="{{ admin_static.url(filename='admin/css/bootstrap3/submenu.css') }}" rel="stylesheet">
|
||||
{% if admin_view.extra_css %}
|
||||
{% for css_url in admin_view.extra_css %}
|
||||
<link href="{{ css_url }}" rel="stylesheet">
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
<style>
|
||||
body {
|
||||
padding-top: 4px;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block head %}
|
||||
{% endblock %}
|
||||
{% block head_tail %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
{% block page_body %}
|
||||
<div class="container{%if config.get('FLASK_ADMIN_FLUID_LAYOUT', False) %}-fluid{% endif %}">
|
||||
<nav class="navbar navbar-default" role="navigation">
|
||||
<!-- Brand and toggle get grouped for better mobile display -->
|
||||
<div class="navbar-header">
|
||||
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#admin-navbar-collapse">
|
||||
<span class="sr-only">Toggle navigation</span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
{% block brand %}
|
||||
<a class="navbar-brand" href="{{ admin_view.admin.url }}">{{ admin_view.admin.name }}</a>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<!-- navbar content -->
|
||||
<div class="collapse navbar-collapse" id="admin-navbar-collapse">
|
||||
{% block main_menu %}
|
||||
<ul class="nav navbar-nav">
|
||||
{{ layout.menu() }}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block menu_links %}
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
{{ layout.menu_links() }}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
{% block access_control %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
{% block messages %}
|
||||
{{ layout.messages() }}
|
||||
{% endblock %}
|
||||
|
||||
{# store the jinja2 context for form_rules rendering logic #}
|
||||
{% set render_ctx = h.resolve_ctx() %}
|
||||
|
||||
{% block body %}{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block tail_js %}
|
||||
<script src="{{ admin_static.url(filename='vendor/jquery.min.js', v='3.3.1') }}" type="text/javascript"></script>
|
||||
<script src="{{ admin_static.url(filename='bootstrap/bootstrap3/js/bootstrap.min.js', v='3.3.5') }}" type="text/javascript"></script>
|
||||
<script src="{{ admin_static.url(filename='vendor/moment.min.js', v='2.22.2') }}" type="text/javascript"></script>
|
||||
<script src="{{ admin_static.url(filename='vendor/select2/select2.min.js', v='3.5.2') }}" type="text/javascript"></script>
|
||||
<script src="{{ admin_static.url(filename='admin/js/helpers.js', v='1.0.0') }}" type="text/javascript"></script>
|
||||
{% if admin_view.extra_js %}
|
||||
{% for js_url in admin_view.extra_js %}
|
||||
<script src="{{ js_url }}" type="text/javascript"></script>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
9
advlabdb/templates/admin/file/form.html
Normal file
9
advlabdb/templates/admin/file/form.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
|
||||
{% block body %}
|
||||
{% block header %}<h3>{{ header_text }}</h3>{% endblock %}
|
||||
{% block fa_form %}
|
||||
{{ lib.render_form(form, dir_url) }}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
196
advlabdb/templates/admin/file/list.html
Normal file
196
advlabdb/templates/admin/file/list.html
Normal file
|
@ -0,0 +1,196 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
{% import 'admin/actions.html' as actionslib with context %}
|
||||
|
||||
{% block body %}
|
||||
{% block breadcrums %}
|
||||
<ul class="breadcrumb">
|
||||
<li>
|
||||
<a href="{{ get_dir_url('.index_view', path=None) }}">{{ _gettext('Root') }}</a>
|
||||
</li>
|
||||
{% for name, path in breadcrumbs[:-1] %}
|
||||
<li>
|
||||
<a href="{{ get_dir_url('.index_view', path=path) }}">{{ name }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
{% if breadcrumbs %}
|
||||
<li>
|
||||
<a href="{{ get_dir_url('.index_view', path=breadcrumbs[-1][1]) }}">{{ breadcrumbs[-1][0] }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block file_list_table %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-bordered model-list">
|
||||
<thead>
|
||||
<tr>
|
||||
{% block list_header scoped %}
|
||||
{% if actions %}
|
||||
<th class="list-checkbox-column">
|
||||
<input type="checkbox" name="rowtoggle" class="action-rowtoggle" />
|
||||
</th>
|
||||
{% endif %}
|
||||
<th class="col-md-1"> </th>
|
||||
{% for column in admin_view.column_list %}
|
||||
<th>
|
||||
{% if admin_view.is_column_sortable(column) %}
|
||||
{% if sort_column == column %}
|
||||
<a href="{{ sort_url(column, dir_path, True) }}" title="{{ _gettext('Sort by %(name)s', name=column) }}">
|
||||
{{ admin_view.column_label(column) }}
|
||||
{% if sort_desc %}
|
||||
<span class="fa fa-chevron-up glyphicon glyphicon-chevron-up"></span>
|
||||
{% else %}
|
||||
<span class="fa fa-chevron-down glyphicon glyphicon-chevron-down"></span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ sort_url(column, dir_path) }}" title="{{ _gettext('Sort by %(name)s', name=column) }}">{{ admin_view.column_label(column) }}</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ _gettext(admin_view.column_label(column)) }}
|
||||
{% endif %}
|
||||
</th>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</tr>
|
||||
</thead>
|
||||
{% for name, path, is_dir, size, date in items %}
|
||||
<tr>
|
||||
{% block list_row scoped %}
|
||||
{% if actions %}
|
||||
<td>
|
||||
{% if not is_dir %}
|
||||
<input type="checkbox" name="rowid" class="action-checkbox" value="{{ path }}" />
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
<td>
|
||||
{% block list_row_actions scoped %}
|
||||
{% if admin_view.can_rename and path and name != '..' %}
|
||||
{%- if admin_view.rename_modal -%}
|
||||
{{ lib.add_modal_button(url=get_url('.rename', path=path, modal=True),
|
||||
title=_gettext('Rename File'),
|
||||
content='<i class="fa fa-pencil glyphicon glyphicon-pencil"></i>') }}
|
||||
{% else %}
|
||||
<a class="icon" href="{{ get_url('.rename', path=path) }}" title="{{ _gettext('Rename File') }}">
|
||||
<i class="fa fa-pencil glyphicon glyphicon-pencil"></i>
|
||||
</a>
|
||||
{%- endif -%}
|
||||
{% endif %}
|
||||
{%- if admin_view.can_delete and path -%}
|
||||
{% if is_dir %}
|
||||
{% if name != '..' and admin_view.can_delete_dirs %}
|
||||
<form class="icon" method="POST" action="{{ get_url('.delete') }}">
|
||||
{{ delete_form.path(value=path) }}
|
||||
{% if delete_form.csrf_token %}
|
||||
{{ delete_form.csrf_token }}
|
||||
{% elif csrf_token %}
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
{% endif %}
|
||||
<button onclick="return confirm('{{ _gettext('Are you sure you want to delete \\\'%(name)s\\\' recursively?', name=name) }}')">
|
||||
<i class="fa fa-times glyphicon glyphicon-remove"></i>
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<form class="icon" method="POST" action="{{ get_url('.delete') }}">
|
||||
{{ delete_form.path(value=path) }}
|
||||
{% if delete_form.csrf_token %}
|
||||
{{ delete_form.csrf_token }}
|
||||
{% elif csrf_token %}
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
{% endif %}
|
||||
<button onclick="return confirm('{{ _gettext('Are you sure you want to delete \\\'%(name)s\\\'?', name=name) }}')">
|
||||
<i class="fa fa-trash glyphicon glyphicon-trash"></i>
|
||||
</button>
|
||||
</form>
|
||||
{% endif %}
|
||||
{%- endif -%}
|
||||
{% endblock %}
|
||||
</td>
|
||||
{% if is_dir %}
|
||||
<td colspan="2">
|
||||
<a href="{{ get_dir_url('.index_view', path)|safe }}">
|
||||
<i class="fa fa-folder-o glyphicon glyphicon-folder-close"></i> <span>{{ name }}</span>
|
||||
</a>
|
||||
</td>
|
||||
{% else %}
|
||||
<td>
|
||||
{% if admin_view.can_download %}
|
||||
{%- if admin_view.edit_modal and admin_view.is_file_editable(path) -%}
|
||||
{{ lib.add_modal_button(url=get_file_url(path, modal=True)|safe,
|
||||
btn_class='', content=name) }}
|
||||
{% else %}
|
||||
<a href="{{ get_file_url(path)|safe }}">{{ name }}</a>
|
||||
{%- endif -%}
|
||||
{% else %}
|
||||
{{ name }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% if admin_view.is_column_visible('size') %}
|
||||
<td>
|
||||
{{ size|filesizeformat }}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if admin_view.is_column_visible('date') %}
|
||||
<td>
|
||||
{{ timestamp_format(date) }}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block toolbar %}
|
||||
<div class="btn-toolbar">
|
||||
{% if admin_view.can_upload %}
|
||||
<div class="btn-group">
|
||||
{%- if admin_view.upload_modal -%}
|
||||
{{ lib.add_modal_button(url=get_dir_url('.upload', path=dir_path, modal=True),
|
||||
btn_class="btn btn-default btn-large",
|
||||
content=_gettext('Upload File')) }}
|
||||
{% else %}
|
||||
<a class="btn btn-default btn-large" href="{{ get_dir_url('.upload', path=dir_path) }}">{{ _gettext('Upload File') }}</a>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if admin_view.can_mkdir %}
|
||||
<div class="btn-group">
|
||||
{%- if admin_view.mkdir_modal -%}
|
||||
{{ lib.add_modal_button(url=get_dir_url('.mkdir', path=dir_path, modal=True),
|
||||
btn_class="btn btn-default btn-large",
|
||||
content=_gettext('Create Directory')) }}
|
||||
{% else %}
|
||||
<a class="btn btn-default btn-large" href="{{ get_dir_url('.mkdir', path=dir_path) }}">{{ _gettext('Create Directory') }}</a>
|
||||
{%- endif -%}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if actions %}
|
||||
<div class="btn-group">
|
||||
{{ actionslib.dropdown(actions, 'dropdown-toggle btn btn-default btn-large') }}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block actions %}
|
||||
{{ actionslib.form(actions, get_url('.action_view')) }}
|
||||
{% endblock %}
|
||||
|
||||
{%- if admin_view.rename_modal or admin_view.mkdir_modal
|
||||
or admin_view.upload_modal or admin_view.edit_modal -%}
|
||||
{{ lib.add_modal_window() }}
|
||||
{%- endif -%}
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
{{ super() }}
|
||||
{{ actionslib.script(_gettext('Please select at least one file.'),
|
||||
actions,
|
||||
actions_confirmation) }}
|
||||
{% endblock %}
|
19
advlabdb/templates/admin/file/modals/form.html
Normal file
19
advlabdb/templates/admin/file/modals/form.html
Normal file
|
@ -0,0 +1,19 @@
|
|||
{% import 'admin/static.html' as admin_static with context %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
|
||||
{% block body %}
|
||||
{# content added to modal-content #}
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{% block header %}<h3>{{ header_text }}</h3>{% endblock %}
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{% block fa_form %}
|
||||
{{ lib.render_form(form, dir_url, action=request.url, is_modal=True) }}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
<script src="{{ admin_static.url(filename='admin/js/bs3_modal.js', v='1.0.0') }}"></script>
|
||||
{% endblock %}
|
4
advlabdb/templates/admin/index.html
Normal file
4
advlabdb/templates/admin/index.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
|
||||
{% block body %}
|
||||
{% endblock %}
|
102
advlabdb/templates/admin/layout.html
Normal file
102
advlabdb/templates/admin/layout.html
Normal file
|
@ -0,0 +1,102 @@
|
|||
{% macro menu_icon(item) -%}
|
||||
{% set icon_type = item.get_icon_type() %}
|
||||
{%- if icon_type %}
|
||||
{% set icon_value = item.get_icon_value() %}
|
||||
{% if icon_type == 'glyph' %}
|
||||
<i class="glyphicon {{ icon_value }}"></i>
|
||||
{% elif icon_type == 'fa' %}
|
||||
<i class="fa {{ icon_value }}"></i>
|
||||
{% elif icon_type == 'image' %}
|
||||
<img src="{{ url_for('static', filename=icon_value) }}" alt="menu image">
|
||||
{% elif icon_type == 'image-url' %}
|
||||
<img src="{{ icon_value }}" alt="menu image">
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro menu(menu_root=None) %}
|
||||
{% if menu_root is none %}{% set menu_root = admin_view.admin.menu() %}{% endif %}
|
||||
{%- for item in menu_root %}
|
||||
{%- if item.is_category() -%}
|
||||
{% set children = item.get_children() %}
|
||||
{%- if children %}
|
||||
{% set class_name = item.get_class_name() or '' %}
|
||||
{%- if item.is_active(admin_view) %}
|
||||
<li class="active dropdown{% if class_name %} {{class_name}}{% endif %}">
|
||||
{% else -%}
|
||||
<li class="dropdown{% if class_name %} {{class_name}}{% endif %}">
|
||||
{%- endif %}
|
||||
<a class="dropdown-toggle" data-toggle="dropdown" href="javascript:void(0)">
|
||||
{% if item.class_name %}<span class="{{ item.class_name }}"></span> {% endif %}
|
||||
{{ menu_icon(item) }}{{ item.name }}
|
||||
{%- if 'dropdown-submenu' in class_name -%}
|
||||
<i class="glyphicon glyphicon-chevron-right small"></i>
|
||||
{%- else -%}
|
||||
<i class="glyphicon glyphicon-chevron-down small"></i>
|
||||
{%- endif -%}
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
{%- for child in children -%}
|
||||
{%- if child.is_category() -%}
|
||||
{{ menu(menu_root=[child]) }}
|
||||
{% else %}
|
||||
{% set class_name = child.get_class_name() %}
|
||||
{%- if child.is_active(admin_view) %}
|
||||
<li class="active{% if class_name %} {{class_name}}{% endif %}">
|
||||
{% else %}
|
||||
<li{% if class_name %} class="{{class_name}}"{% endif %}>
|
||||
{%- endif %}
|
||||
<a href="{{ child.get_url() }}"{% if child.target %}
|
||||
target="{{ child.target }}"{% endif %}>
|
||||
{{ menu_icon(child) }}{{ child.name }}</a>
|
||||
</li>
|
||||
{%- endif %}
|
||||
{%- endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endif %}
|
||||
{%- else %}
|
||||
{%- if item.is_accessible() and item.is_visible() -%}
|
||||
{% set class_name = item.get_class_name() %}
|
||||
{%- if item.is_active(admin_view) %}
|
||||
<li class="active{% if class_name %} {{class_name}}{% endif %}">
|
||||
{%- else %}
|
||||
<li{% if class_name %} class="{{class_name}}"{% endif %}>
|
||||
{%- endif %}
|
||||
<a href="{{ item.get_url() }}"{% if item.target %} target="{{ item.target }}"{% endif %}>{{ menu_icon(item) }}{{ item.name }}</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{% endif -%}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro menu_links(links=None) %}
|
||||
{% if links is none %}{% set links = admin_view.admin.menu_links() %}{% endif %}
|
||||
{% for item in links %}
|
||||
{% set class_name = item.get_class_name() %}
|
||||
{% if item.is_accessible() and item.is_visible() %}
|
||||
<li{% if class_name %} class="{{ class_name }}"{% endif %}>
|
||||
<a href="{{ item.get_url() }}">{{ menu_icon(item) }}{{ item.name }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro messages() %}
|
||||
{% with messages = get_flashed_messages(with_categories=True) %}
|
||||
{% if messages %}
|
||||
{% for category, m in messages %}
|
||||
{% if category %}
|
||||
{# alert-error changed to alert-danger in bootstrap 3, mapping is for backwards compatibility #}
|
||||
{% set mapping = {'message': 'info', 'error': 'danger'} %}
|
||||
<div class="alert alert-{{ mapping.get(category, category) }} alert-dismissable">
|
||||
{% else %}
|
||||
<div class="alert alert-dismissable">
|
||||
{% endif %}
|
||||
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">×</button>
|
||||
{{ m }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endmacro %}
|
256
advlabdb/templates/admin/lib.html
Normal file
256
advlabdb/templates/admin/lib.html
Normal file
|
@ -0,0 +1,256 @@
|
|||
{% import 'admin/static.html' as admin_static with context %}
|
||||
|
||||
{# ---------------------- Pager -------------------------- #}
|
||||
{% macro pager(page, pages, generator) -%}
|
||||
{% if pages > 1 %}
|
||||
<ul class="pagination">
|
||||
{% set min = page - 3 %}
|
||||
{% set max = page + 3 + 1 %}
|
||||
|
||||
{% if min < 0 %}
|
||||
{% set max = max - min %}
|
||||
{% endif %}
|
||||
{% if max >= pages %}
|
||||
{% set min = min - max + pages %}
|
||||
{% endif %}
|
||||
|
||||
{% if min < 0 %}
|
||||
{% set min = 0 %}
|
||||
{% endif %}
|
||||
{% if max >= pages %}
|
||||
{% set max = pages %}
|
||||
{% endif %}
|
||||
|
||||
{% if min > 0 %}
|
||||
<li>
|
||||
<a href="{{ generator(0) }}">«</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="disabled">
|
||||
<a href="javascript:void(0)">«</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if page > 0 %}
|
||||
<li>
|
||||
<a href="{{ generator(page-1) }}"><</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="disabled">
|
||||
<a href="javascript:void(0)"><</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% for p in range(min, max) %}
|
||||
{% if page == p %}
|
||||
<li class="active">
|
||||
<a href="javascript:void(0)">{{ p + 1 }}</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a href="{{ generator(p) }}">{{ p + 1 }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
{% if page + 1 < pages %}
|
||||
<li>
|
||||
<a href="{{ generator(page + 1) }}">></a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="disabled">
|
||||
<a href="javascript:void(0)">></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if max < pages %}
|
||||
<li>
|
||||
<a href="{{ generator(pages - 1) }}">»</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="disabled">
|
||||
<a href="javascript:void(0)">»</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{%- endmacro %}
|
||||
|
||||
{% macro simple_pager(page, have_next, generator) -%}
|
||||
<ul class="pagination">
|
||||
{% if page > 0 %}
|
||||
<li>
|
||||
<a href="{{ generator(page - 1) }}"><</a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="disabled">
|
||||
<a href="{{ generator(0) }}"><</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% if have_next %}
|
||||
<li>
|
||||
<a href="{{ generator(page + 1) }}">></a>
|
||||
</li>
|
||||
{% else %}
|
||||
<li class="disabled">
|
||||
<a href="{{ generator(page) }}">></a>
|
||||
</li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
{%- endmacro %}
|
||||
|
||||
{# ---------------------- Modal Window ------------------- #}
|
||||
{% macro add_modal_window(modal_window_id='fa_modal_window', modal_label_id='fa_modal_label') %}
|
||||
<div class="modal fade" id="{{ modal_window_id }}" tabindex="-1" role="dialog" aria-labelledby="{{ modal_label_id }}">
|
||||
<div class="modal-dialog" role="document">
|
||||
{# bootstrap version > 3.1.0 required for this to work #}
|
||||
<div class="modal-content">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro add_modal_button(url='', title='', content='', modal_window_id='fa_modal_window', btn_class='icon') %}
|
||||
<a class="{{ btn_class }}" data-target="#{{ modal_window_id }}" title="{{ title }}" href="{{ url }}" data-toggle="modal">
|
||||
{{ content|safe }}
|
||||
</a>
|
||||
{% endmacro %}
|
||||
|
||||
{# ---------------------- Forms -------------------------- #}
|
||||
{% macro render_field(form, field, kwargs={}, caller=None) %}
|
||||
{% set direct_error = h.is_field_error(field.errors) %}
|
||||
<div class="form-group{{ ' has-error' if direct_error else '' }}">
|
||||
<label for="{{ field.id }}" class="col-md-2 control-label">{{ field.label.text }}
|
||||
{% if h.is_required_form_field(field) %}
|
||||
<strong style="color: red">*</strong>
|
||||
{%- else -%}
|
||||
|
||||
{%- endif %}
|
||||
</label>
|
||||
<div class="{{ kwargs.get('column_class', 'col-md-10') }}">
|
||||
{% set _dummy = kwargs.setdefault('class', 'form-control') %}
|
||||
{{ field(**kwargs)|safe }}
|
||||
{% if field.description %}
|
||||
<p class="help-block">{{ field.description|safe }}</p>
|
||||
{% endif %}
|
||||
{% if direct_error %}
|
||||
<ul class="help-block input-errors">
|
||||
{% for e in field.errors if e is string %}
|
||||
<li>{{ e }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% if caller %}
|
||||
{{ caller(form, field, direct_error, kwargs) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_header(form, text) %}
|
||||
<h3>{{ text }}</h3>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_form_fields(form, form_opts=None) %}
|
||||
{% if form.hidden_tag is defined %}
|
||||
{{ form.hidden_tag() }}
|
||||
{% else %}
|
||||
{% if csrf_token %}
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
{% endif %}
|
||||
{% for f in form if f.widget.input_type == 'hidden' %}
|
||||
{{ f }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
|
||||
{% if form_opts and form_opts.form_rules %}
|
||||
{% for r in form_opts.form_rules %}
|
||||
{{ r(form, form_opts=form_opts) }}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{% for f in form if f.widget.input_type != 'hidden' %}
|
||||
{% if form_opts %}
|
||||
{% set kwargs = form_opts.widget_args.get(f.short_name, {}) %}
|
||||
{% else %}
|
||||
{% set kwargs = {} %}
|
||||
{% endif %}
|
||||
{{ render_field(form, f, kwargs) }}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro form_tag(form=None, action=None) %}
|
||||
<form action="{{ action or '' }}" method="POST" role="form" class="admin-form form-horizontal" enctype="multipart/form-data">
|
||||
{{ caller() }}
|
||||
</form>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_form_buttons(cancel_url, extra=None, is_modal=False) %}
|
||||
<hr>
|
||||
<div class="form-group">
|
||||
<div class="col-md-offset-2 col-md-10 submit-row">
|
||||
<input type="submit" class="btn btn-primary" value="{{ _gettext('Save') }}" />
|
||||
{% if extra %}
|
||||
{{ extra }}
|
||||
{% endif %}
|
||||
{% if cancel_url %}
|
||||
<a href="{{ cancel_url }}" class="btn btn-danger" role="button" {% if is_modal %}data-dismiss="modal"{% endif %}>{{ _gettext('Cancel') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro render_form(form, cancel_url, extra=None, form_opts=None, action=None, is_modal=False) -%}
|
||||
{% call form_tag(action=action) %}
|
||||
{{ render_form_fields(form, form_opts=form_opts) }}
|
||||
{{ render_form_buttons(cancel_url, extra, is_modal) }}
|
||||
{% endcall %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro form_css() %}
|
||||
<link href="{{ admin_static.url(filename='vendor/select2/select2.css', v='3.5.2') }}" rel="stylesheet">
|
||||
<link href="{{ admin_static.url(filename='vendor/select2/select2-bootstrap3.css', v='1.4.6') }}" rel="stylesheet">
|
||||
<link href="{{ admin_static.url(filename='vendor/bootstrap-daterangepicker/daterangepicker-bs3.css', v='1.3.22') }}" rel="stylesheet">
|
||||
{% if config.MAPBOX_MAP_ID %}
|
||||
<link href="{{ admin_static.url(filename='vendor/leaflet/leaflet.css', v='1.0.2') }}" rel="stylesheet">
|
||||
<link href="{{ admin_static.url(filename='vendor/leaflet/leaflet.draw.css', v='0.4.6') }}" rel="stylesheet">
|
||||
{% endif %}
|
||||
{% if editable_columns %}
|
||||
<link href="{{ admin_static.url(filename='vendor/x-editable/css/bootstrap3-editable.css', v='1.5.1.1') }}" rel="stylesheet">
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro form_js() %}
|
||||
{% if config.MAPBOX_MAP_ID %}
|
||||
<script>
|
||||
window.MAPBOX_MAP_ID = "{{ config.MAPBOX_MAP_ID }}";
|
||||
{% if config.MAPBOX_ACCESS_TOKEN %}
|
||||
window.MAPBOX_ACCESS_TOKEN = "{{ config.MAPBOX_ACCESS_TOKEN }}";
|
||||
{% endif %}
|
||||
{% if config.DEFAULT_CENTER_LAT and config.DEFAULT_CENTER_LONG %}
|
||||
window.DEFAULT_CENTER_LAT = "{{ config.DEFAULT_CENTER_LAT }}";
|
||||
window.DEFAULT_CENTER_LONG = "{{ config.DEFAULT_CENTER_LONG }}";
|
||||
{% endif %}
|
||||
</script>
|
||||
<script src="{{ admin_static.url(filename='vendor/leaflet/leaflet.js', v='1.0.2') }}"></script>
|
||||
<script src="{{ admin_static.url(filename='vendor/leaflet/leaflet.draw.js', v='0.4.6') }}"></script>
|
||||
{% if config.MAPBOX_SEARCH %}
|
||||
<script>
|
||||
window.MAPBOX_SEARCH = "{{ config.MAPBOX_SEARCH }}";
|
||||
</script>
|
||||
<script src="https://maps.googleapis.com/maps/api/js?v=3&libraries=places&key={{ config.get('GOOGLE_MAPS_API_KEY') }}"></script>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
<script src="{{ admin_static.url(filename='vendor/bootstrap-daterangepicker/daterangepicker.js', v='1.3.22') }}"></script>
|
||||
{% if editable_columns %}
|
||||
<script src="{{ admin_static.url(filename='vendor/x-editable/js/bootstrap3-editable.min.js', v='1.5.1.1') }}"></script>
|
||||
{% endif %}
|
||||
<script src="{{ admin_static.url(filename='admin/js/form.js', v='1.0.1') }}"></script>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro extra() %}
|
||||
{% if admin_view.can_create %}
|
||||
<input name="_add_another" type="submit" class="btn btn-default" value="{{ _gettext('Save and Add Another') }}" />
|
||||
{% endif %}
|
||||
{% if admin_view.can_edit %}
|
||||
<input name="_continue_editing" type="submit" class="btn btn-default" value="{{ _gettext('Save and Continue Editing') }}" />
|
||||
{% endif %}
|
||||
{% endmacro %}
|
1
advlabdb/templates/admin/master.html
Normal file
1
advlabdb/templates/admin/master.html
Normal file
|
@ -0,0 +1 @@
|
|||
{% extends admin_base_template %}
|
30
advlabdb/templates/admin/model/create.html
Normal file
30
advlabdb/templates/admin/model/create.html
Normal file
|
@ -0,0 +1,30 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
{% from 'admin/lib.html' import extra with context %} {# backward compatible #}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
{{ lib.form_css() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% block navlinks %}
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{{ return_url }}">{{ _gettext('List') }}</a>
|
||||
</li>
|
||||
<li class="active">
|
||||
<a href="javascript:void(0)">{{ _gettext('Create') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block create_form %}
|
||||
{{ lib.render_form(form, return_url, extra(), form_opts) }}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
{{ super() }}
|
||||
{{ lib.form_js() }}
|
||||
{% endblock %}
|
52
advlabdb/templates/admin/model/details.html
Normal file
52
advlabdb/templates/admin/model/details.html
Normal file
|
@ -0,0 +1,52 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
|
||||
{% block body %}
|
||||
{% block navlinks %}
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{{ return_url }}">{{ _gettext('List') }}</a>
|
||||
</li>
|
||||
{%- if admin_view.can_create -%}
|
||||
<li>
|
||||
<a href="{{ get_url('.create_view', url=return_url) }}">{{ _gettext('Create') }}</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
{%- if admin_view.can_edit -%}
|
||||
<li>
|
||||
<a href="{{ get_url('.edit_view', id=request.args.get('id'), url=return_url) }}">{{ _gettext('Edit') }}</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
<li class="active">
|
||||
<a href="javascript:void(0)">{{ _gettext('Details') }}</a>
|
||||
</li>
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block details_search %}
|
||||
<div class="input-group fa_filter_container col-lg-6">
|
||||
<span class="input-group-addon">{{ _gettext('Filter') }}</span>
|
||||
<input id="fa_filter" type="text" class="form-control">
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block details_table %}
|
||||
<table class="table table-hover table-bordered searchable">
|
||||
{% for c, name in details_columns %}
|
||||
<tr>
|
||||
<td>
|
||||
<b>{{ name }}</b>
|
||||
</td>
|
||||
<td>
|
||||
{{ get_value(model, c) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
{{ super() }}
|
||||
<script src="{{ admin_static.url(filename='admin/js/details_filter.js', v='1.0.0') }}"></script>
|
||||
{% endblock %}
|
40
advlabdb/templates/admin/model/edit.html
Normal file
40
advlabdb/templates/admin/model/edit.html
Normal file
|
@ -0,0 +1,40 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
{% from 'admin/lib.html' import extra with context %} {# backward compatible #}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
{{ lib.form_css() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% block navlinks %}
|
||||
<ul class="nav nav-tabs">
|
||||
<li>
|
||||
<a href="{{ return_url }}">{{ _gettext('List') }}</a>
|
||||
</li>
|
||||
{%- if admin_view.can_create -%}
|
||||
<li>
|
||||
<a href="{{ get_url('.create_view', url=return_url) }}">{{ _gettext('Create') }}</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
<li class="active">
|
||||
<a href="javascript:void(0)">{{ _gettext('Edit') }}</a>
|
||||
</li>
|
||||
{%- if admin_view.can_view_details -%}
|
||||
<li>
|
||||
<a href="{{ get_url('.details_view', id=request.args.get('id'), url=return_url) }}">{{ _gettext('Details') }}</a>
|
||||
</li>
|
||||
{%- endif -%}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% block edit_form %}
|
||||
{{ lib.render_form(form, return_url, extra(), form_opts) }}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
{{ super() }}
|
||||
{{ lib.form_js() }}
|
||||
{% endblock %}
|
15
advlabdb/templates/admin/model/inline_field_list.html
Normal file
15
advlabdb/templates/admin/model/inline_field_list.html
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% import 'admin/model/inline_list_base.html' as base with context %}
|
||||
|
||||
{% macro render_field(field) %}
|
||||
{{ field }}
|
||||
|
||||
{% if h.is_field_error(field.errors) %}
|
||||
<ul class="help-block input-errors">
|
||||
{% for e in field.errors if e is string %}
|
||||
<li>{{ e }}</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{{ base.render_inline_fields(field, template, render_field, check) }}
|
4
advlabdb/templates/admin/model/inline_form.html
Normal file
4
advlabdb/templates/admin/model/inline_form.html
Normal file
|
@ -0,0 +1,4 @@
|
|||
{% import 'admin/lib.html' as lib with context %}
|
||||
<div class="inline-form-field">
|
||||
{{ lib.render_form_fields(field.form, form_opts=form_opts) }}
|
||||
</div>
|
45
advlabdb/templates/admin/model/inline_list_base.html
Normal file
45
advlabdb/templates/admin/model/inline_list_base.html
Normal file
|
@ -0,0 +1,45 @@
|
|||
{% macro render_inline_fields(field, template, render, check=None) %}
|
||||
<div class="inline-field" id="{{ field.id }}">
|
||||
{# existing inline form fields #}
|
||||
<div class="inline-field-list">
|
||||
{% for subfield in field %}
|
||||
<div id="{{ subfield.id }}" class="inline-field well well-sm">
|
||||
{%- if not check or check(subfield) %}
|
||||
<legend>
|
||||
<small>
|
||||
{{ field.label.text }} #{{ loop.index }}
|
||||
<div class="pull-right">
|
||||
{% if subfield.get_pk and subfield.get_pk() %}
|
||||
<input type="checkbox" name="del-{{ subfield.id }}" id="del-{{ subfield.id }}" />
|
||||
<label for="del-{{ subfield.id }}" style="display: inline">{{ _gettext('Delete?') }}</label>
|
||||
{% else %}
|
||||
<a href="javascript:void(0)" value="{{ _gettext('Are you sure you want to delete this record?') }}" class="inline-remove-field"><i class="fa fa-times glyphicon glyphicon-remove"></i></a>
|
||||
{% endif %}
|
||||
</div>
|
||||
</small>
|
||||
</legend>
|
||||
<div class='clearfix'></div>
|
||||
{%- endif -%}
|
||||
{{ render(subfield) }}
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
|
||||
{# template for new inline form fields #}
|
||||
<div class="inline-field-template hide">
|
||||
{% filter forceescape %}
|
||||
<div class="inline-field well well-sm">
|
||||
<legend>
|
||||
<small>{{ _gettext('New') }} {{ field.label.text }}</small>
|
||||
<div class="pull-right">
|
||||
<a href="javascript:void(0)" value="{{ _gettext('Are you sure you want to delete this record?') }}" class="inline-remove-field"><span class="fa fa-times glyphicon glyphicon-remove"></span></a>
|
||||
</div>
|
||||
</legend>
|
||||
<div class='clearfix'></div>
|
||||
{{ render(template) }}
|
||||
</div>
|
||||
{% endfilter %}
|
||||
</div>
|
||||
<a id="{{ field.id }}-button" href="javascript:void(0)" class="btn btn-default" onclick="faForm.addInlineField(this, '{{ field.id }}');">{{ _gettext('Add') }} {{ field.label.text }}</a>
|
||||
</div>
|
||||
{% endmacro %}
|
107
advlabdb/templates/admin/model/layout.html
Normal file
107
advlabdb/templates/admin/model/layout.html
Normal file
|
@ -0,0 +1,107 @@
|
|||
{% macro filter_options(btn_class='dropdown-toggle') %}
|
||||
<a class="{{ btn_class }}" data-toggle="dropdown" href="javascript:void(0)">
|
||||
{{ _gettext('Add Filter') }}<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu field-filters">
|
||||
{% for k in filter_groups %}
|
||||
<li>
|
||||
<a href="javascript:void(0)" class="filter" onclick="return false;">{{ k }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro export_options(btn_class='dropdown-toggle') %}
|
||||
{% if admin_view.export_types|length > 1 %}
|
||||
<li class="dropdown">
|
||||
<a class="{{ btn_class }}" data-toggle="dropdown" href="javascript:void(0)">
|
||||
{{ _gettext('Export') }}<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu field-filters">
|
||||
{% for export_type in admin_view.export_types %}
|
||||
<li>
|
||||
<a href="{{ get_url('.export', export_type=export_type, **request.args) }}" title="{{ _gettext('Export') }}">{{ _gettext('Export') + ' ' + export_type|upper }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% else %}
|
||||
<li>
|
||||
<a href="{{ get_url('.export', export_type=admin_view.export_types[0], **request.args) }}" title="{{ _gettext('Export') }}">{{ _gettext('Export') }}</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro filter_form() %}
|
||||
<form id="filter_form" method="GET" action="{{ return_url }}">
|
||||
{% for arg_name, arg_value in extra_args.items() %}
|
||||
<input type="hidden" name="{{ arg_name }}" value="{{ arg_value }}">
|
||||
{% endfor %}
|
||||
{% if sort_column is not none %}
|
||||
<input type="hidden" name="sort" value="{{ sort_column }}">
|
||||
{% endif %}
|
||||
{% if sort_desc %}
|
||||
<input type="hidden" name="desc" value="{{ sort_desc }}">
|
||||
{% endif %}
|
||||
{% if search %}
|
||||
<input type="hidden" name="search" value="{{ search }}">
|
||||
{% endif %}
|
||||
{% if page_size != default_page_size %}
|
||||
<input type="hidden" name="page_size" value="{{ page_size }}">
|
||||
{% endif %}
|
||||
<div class="pull-right">
|
||||
<button type="submit" class="btn btn-primary" style="display: none">{{ _gettext('Apply') }}</button>
|
||||
{% if active_filters %}
|
||||
<a href="{{ clear_search_url }}" class="btn btn-default">{{ _gettext('Reset Filters') }}</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<table class="filters"></table>
|
||||
</form>
|
||||
<div class="clearfix"></div>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro search_form(input_class=None) %}
|
||||
<form method="GET" action="{{ return_url }}" class="navbar-form navbar-left" role="search">
|
||||
{% for flt_name, flt_value in filter_args.items() %}
|
||||
<input type="hidden" name="{{ flt_name }}" value="{{ flt_value }}">
|
||||
{% endfor %}
|
||||
{% for arg_name, arg_value in extra_args.items() %}
|
||||
<input type="hidden" name="{{ arg_name }}" value="{{ arg_value }}">
|
||||
{% endfor %}
|
||||
{% if page_size != default_page_size %}
|
||||
<input type="hidden" name="page_size" value="{{ page_size }}">
|
||||
{% endif %}
|
||||
{% if sort_column is not none %}
|
||||
<input type="hidden" name="sort" value="{{ sort_column }}">
|
||||
{% endif %}
|
||||
{% if sort_desc %}
|
||||
<input type="hidden" name="desc" value="{{ sort_desc }}">
|
||||
{% endif %}
|
||||
{%- set full_search_placeholder = _gettext('Search') %}
|
||||
{%- set max_size = config.get('FLASK_ADMIN_SEARCH_SIZE_MAX', 100) %}
|
||||
{%- if search_placeholder %}{% set full_search_placeholder = [full_search_placeholder, search_placeholder] | join(": ") %}{% endif %}
|
||||
{%- set input_size = [[full_search_placeholder | length, 30] | max, max_size] | min %}
|
||||
{% if search %}
|
||||
<div class="input-group">
|
||||
<input type="search" name="search" value="{{ search }}" class="form-control{% if input_class %} {{ input_class }}{% endif %}" size="{{ input_size }}" placeholder="{{ full_search_placeholder }}">
|
||||
<a href="{{ clear_search_url }}" class="input-group-addon clear"><span class="fa fa-times glyphicon glyphicon-remove"></span></a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="form-group">
|
||||
<input type="search" name="search" value="" class="form-control{% if input_class %} {{ input_class }}{% endif %}" size="{{ input_size }}" placeholder="{{ full_search_placeholder }}">
|
||||
</div>
|
||||
{% endif %}
|
||||
</form>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro page_size_form(generator, btn_class='dropdown-toggle') %}
|
||||
<a class="{{ btn_class }}" data-toggle="dropdown" href="javascript:void(0)">
|
||||
{{ page_size }} {{ _gettext('items') }}<b class="caret"></b>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{{ generator(20) }}">20 {{ _gettext('items') }}</a></li>
|
||||
<li><a href="{{ generator(50) }}">50 {{ _gettext('items') }}</a></li>
|
||||
<li><a href="{{ generator(100) }}">100 {{ _gettext('items') }}</a></li>
|
||||
</ul>
|
||||
{% endmacro %}
|
197
advlabdb/templates/admin/model/list.html
Executable file
197
advlabdb/templates/admin/model/list.html
Executable file
|
@ -0,0 +1,197 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
{% import 'admin/static.html' as admin_static with context%}
|
||||
{% import 'admin/model/layout.html' as model_layout with context %}
|
||||
{% import 'admin/actions.html' as actionlib with context %}
|
||||
{% import 'admin/model/row_actions.html' as row_actions with context %}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
{{ lib.form_css() }}
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% block model_menu_bar %}
|
||||
<ul class="nav nav-tabs actions-nav">
|
||||
<li class="active">
|
||||
<a href="javascript:void(0)">{{ _gettext('List') }}{% if count %} ({{ count }}){% endif %}</a>
|
||||
</li>
|
||||
|
||||
{% if admin_view.can_create %}
|
||||
<li>
|
||||
{%- if admin_view.create_modal -%}
|
||||
{{ lib.add_modal_button(url=get_url('.create_view', url=return_url, modal=True), title=_gettext('Create New Record'), content=_gettext('Create')) }}
|
||||
{% else %}
|
||||
<a href="{{ get_url('.create_view', url=return_url) }}" title="{{ _gettext('Create New Record') }}">{{ _gettext('Create') }}</a>
|
||||
{%- endif -%}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if admin_view.can_export %}
|
||||
{{ model_layout.export_options() }}
|
||||
{% endif %}
|
||||
|
||||
{% block model_menu_bar_before_filters %}{% endblock %}
|
||||
|
||||
{% if filters %}
|
||||
<li class="dropdown">
|
||||
{{ model_layout.filter_options() }}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if can_set_page_size %}
|
||||
<li class="dropdown">
|
||||
{{ model_layout.page_size_form(page_size_url) }}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if actions %}
|
||||
<li class="dropdown">
|
||||
{{ actionlib.dropdown(actions) }}
|
||||
</li>
|
||||
{% endif %}
|
||||
|
||||
{% if search_supported %}
|
||||
<li>
|
||||
{{ model_layout.search_form() }}
|
||||
</li>
|
||||
{% endif %}
|
||||
{% block model_menu_bar_after_filters %}{% endblock %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
|
||||
{% if filters %}
|
||||
{{ model_layout.filter_form() }}
|
||||
<div class="clearfix"></div>
|
||||
{% endif %}
|
||||
|
||||
{% block model_list_table %}
|
||||
<div class="table-responsive">
|
||||
<table class="table table-striped table-bordered table-hover model-list">
|
||||
<thead>
|
||||
<tr>
|
||||
{% block list_header scoped %}
|
||||
{% if actions %}
|
||||
<th class="list-checkbox-column">
|
||||
<input type="checkbox" name="rowtoggle" class="action-rowtoggle" title="{{ _gettext('Select all records') }}" />
|
||||
</th>
|
||||
{% endif %}
|
||||
{% block list_row_actions_header %}
|
||||
{% if admin_view.column_display_actions %}
|
||||
<th class="col-md-1"> </th>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% for c, name in list_columns %}
|
||||
{% set column = loop.index0 %}
|
||||
<th class="column-header col-{{c}}">
|
||||
{% if admin_view.is_sortable(c) %}
|
||||
{% if sort_column == column %}
|
||||
<a href="{{ sort_url(column, True) }}" title="{{ _gettext('Sort by %(name)s', name=name) }}">
|
||||
{{ name }}
|
||||
{% if sort_desc %}
|
||||
<span class="fa fa-chevron-up glyphicon glyphicon-chevron-up"></span>
|
||||
{% else %}
|
||||
<span class="fa fa-chevron-down glyphicon glyphicon-chevron-down"></span>
|
||||
{% endif %}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{{ sort_url(column) }}" title="{{ _gettext('Sort by %(name)s', name=name) }}">{{ name }}</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ name }}
|
||||
{% endif %}
|
||||
{% if admin_view.column_descriptions.get(c) %}
|
||||
<a class="fa fa-question-circle glyphicon glyphicon-question-sign"
|
||||
title="{{ admin_view.column_descriptions[c] }}"
|
||||
href="javascript:void(0)" data-role="tooltip"
|
||||
></a>
|
||||
{% endif %}
|
||||
</th>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</tr>
|
||||
</thead>
|
||||
{% for row in data %}
|
||||
<tr>
|
||||
{% block list_row scoped %}
|
||||
{% if actions %}
|
||||
<td>
|
||||
<input type="checkbox" name="rowid" class="action-checkbox" value="{{ get_pk_value(row) }}" title="{{ _gettext('Select record') }}" />
|
||||
</td>
|
||||
{% endif %}
|
||||
{% block list_row_actions_column scoped %}
|
||||
{% if admin_view.column_display_actions %}
|
||||
<td class="list-buttons-column">
|
||||
{% block list_row_actions scoped %}
|
||||
{% for action in list_row_actions %}
|
||||
{{ action.render_ctx(get_pk_value(row), row) }}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</td>
|
||||
{%- endif -%}
|
||||
{% endblock %}
|
||||
|
||||
{% for c, name in list_columns %}
|
||||
<td class="col-{{c}}">
|
||||
{% if admin_view.is_editable(c) %}
|
||||
{% set form = list_forms[get_pk_value(row)] %}
|
||||
{% if form.csrf_token %}
|
||||
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c), csrf=form.csrf_token._value()) }}
|
||||
{% elif csrf_token %}
|
||||
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c), csrf=csrf_token()) }}
|
||||
{% else %}
|
||||
{{ form[c](pk=get_pk_value(row), display_value=get_value(row, c)) }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ get_value(row, c) }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</tr>
|
||||
{% else %}
|
||||
<tr>
|
||||
<td colspan="999">
|
||||
{% block empty_list_message %}
|
||||
<div class="text-center">
|
||||
{{ admin_view.get_empty_list_message() }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
{% block list_pager %}
|
||||
{% if num_pages is not none %}
|
||||
{{ lib.pager(page, num_pages, pager_url) }}
|
||||
{% else %}
|
||||
{{ lib.simple_pager(page, data|length == page_size, pager_url) }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block actions %}
|
||||
{{ actionlib.form(actions, get_url('.action_view')) }}
|
||||
{% endblock %}
|
||||
|
||||
{%- if admin_view.edit_modal or admin_view.create_modal or admin_view.details_modal -%}
|
||||
{{ lib.add_modal_window() }}
|
||||
{%- endif -%}
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
{{ super() }}
|
||||
|
||||
{% if filter_groups %}
|
||||
<div id="filter-groups-data" style="display:none;">{{ filter_groups|tojson|safe }}</div>
|
||||
<div id="active-filters-data" style="display:none;">{{ active_filters|tojson|safe }}</div>
|
||||
{% endif %}
|
||||
|
||||
{{ lib.form_js() }}
|
||||
<script src="{{ admin_static.url(filename='admin/js/filters.js', v='1.0.0') }}"></script>
|
||||
|
||||
{{ actionlib.script(_gettext('Please select at least one record.'),
|
||||
actions,
|
||||
actions_confirmation) }}
|
||||
{% endblock %}
|
24
advlabdb/templates/admin/model/modals/create.html
Normal file
24
advlabdb/templates/admin/model/modals/create.html
Normal file
|
@ -0,0 +1,24 @@
|
|||
{% import 'admin/static.html' as admin_static with context%}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
|
||||
{# store the jinja2 context for form_rules rendering logic #}
|
||||
{% set render_ctx = h.resolve_ctx() %}
|
||||
|
||||
{% block body %}
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{% block header_text %}<h3>{{ _gettext('Create New Record') }}</h3>{% endblock %}
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{# "save and add" button is removed from modal (it won't function properly) #}
|
||||
{% block create_form %}
|
||||
{{ lib.render_form(form, return_url, extra=None, form_opts=form_opts,
|
||||
action=url_for('.create_view', url=return_url),
|
||||
is_modal=True) }}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
<script src="{{ admin_static.url(filename='admin/js/bs3_modal.js', v='1.0.0') }}"></script>
|
||||
{% endblock %}
|
40
advlabdb/templates/admin/model/modals/details.html
Executable file
40
advlabdb/templates/admin/model/modals/details.html
Executable file
|
@ -0,0 +1,40 @@
|
|||
{% import 'admin/static.html' as admin_static with context%}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
|
||||
{% block body %}
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{% block header_text %}
|
||||
<h3>{{ _gettext('View Record') + ' #' + request.args.get('id') }}</h3>
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<div class="modal-body">
|
||||
{% block details_search %}
|
||||
<div class="input-group fa_filter_container col-lg-6">
|
||||
<span class="input-group-addon">{{ _gettext('Filter') }}</span>
|
||||
<input id="fa_filter" type="text" class="form-control">
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block details_table %}
|
||||
<table class="table table-hover table-bordered searchable">
|
||||
{% for c, name in details_columns %}
|
||||
<tr>
|
||||
<td>
|
||||
<b>{{ name }}</b>
|
||||
</td>
|
||||
<td>
|
||||
{{ get_value(model, c) }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
<script src="{{ admin_static.url(filename='admin/js/details_filter.js', v='1.0.0') }}"></script>
|
||||
<script src="{{ admin_static.url(filename='admin/js/bs3_modal.js', v='1.0.0') }}"></script>
|
||||
{% endblock %}
|
26
advlabdb/templates/admin/model/modals/edit.html
Normal file
26
advlabdb/templates/admin/model/modals/edit.html
Normal file
|
@ -0,0 +1,26 @@
|
|||
{% import 'admin/static.html' as admin_static with context%}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
|
||||
{# store the jinja2 context for form_rules rendering logic #}
|
||||
{% set render_ctx = h.resolve_ctx() %}
|
||||
|
||||
{% block body %}
|
||||
<div class="modal-header">
|
||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
|
||||
{% block header_text %}
|
||||
<h3>{{ _gettext('Edit Record') + ' #' + request.args.get('id') }}</h3>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div class="modal-body">
|
||||
{# "save and continue" button is removed from modal (it won't function properly) #}
|
||||
{% block edit_form %}
|
||||
{{ lib.render_form(form, return_url, extra=None, form_opts=form_opts,
|
||||
action=url_for('.edit_view', id=request.args.get('id'), url=return_url),
|
||||
is_modal=True) }}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
<script src="{{ admin_static.url(filename='admin/js/bs3_modal.js', v='1.0.0') }}"></script>
|
||||
{% endblock %}
|
38
advlabdb/templates/admin/model/row_actions.html
Normal file
38
advlabdb/templates/admin/model/row_actions.html
Normal file
|
@ -0,0 +1,38 @@
|
|||
{% import 'admin/lib.html' as lib with context %}
|
||||
|
||||
{% macro link(action, url, icon_class=None) %}
|
||||
<a class="icon" href="{{ url }}" title="{{ action.title or '' }}">
|
||||
<span class="{{ icon_class or action.icon_class }}"></span>
|
||||
</a>
|
||||
{% endmacro %}
|
||||
|
||||
{% macro view_row(action, row_id, row) %}
|
||||
{{ link(action, get_url('.details_view', id=row_id, url=return_url), 'fa fa-eye glyphicon glyphicon-eye-open') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro view_row_popup(action, row_id, row) %}
|
||||
{{ lib.add_modal_button(url=get_url('.details_view', id=row_id, url=return_url, modal=True), title=action.title, content='<span class="fa fa-eye glyphicon glyphicon-eye-open"></span>') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro edit_row(action, row_id, row) %}
|
||||
{{ link(action, get_url('.edit_view', id=row_id, url=return_url), 'fa fa-pencil glyphicon glyphicon-pencil') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro edit_row_popup(action, row_id, row) %}
|
||||
{{ lib.add_modal_button(url=get_url('.edit_view', id=row_id, url=return_url, modal=True), title=action.title, content='<span class="fa fa-pencil glyphicon glyphicon-pencil"></span>') }}
|
||||
{% endmacro %}
|
||||
|
||||
{% macro delete_row(action, row_id, row) %}
|
||||
<form class="icon" method="POST" action="{{ get_url('.delete_view') }}">
|
||||
{{ delete_form.id(value=get_pk_value(row)) }}
|
||||
{{ delete_form.url(value=return_url) }}
|
||||
{% if delete_form.csrf_token %}
|
||||
{{ delete_form.csrf_token }}
|
||||
{% elif csrf_token %}
|
||||
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}"/>
|
||||
{% endif %}
|
||||
<button onclick="return faHelpers.safeConfirm('{{ _gettext('Are you sure you want to delete this record?') }}');" title="{{ _gettext('Delete record') }}">
|
||||
<span class="fa fa-trash glyphicon glyphicon-trash"></span>
|
||||
</button>
|
||||
</form>
|
||||
{% endmacro %}
|
27
advlabdb/templates/admin/rediscli/console.html
Normal file
27
advlabdb/templates/admin/rediscli/console.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
{% extends 'admin/master.html' %}
|
||||
{% import 'admin/lib.html' as lib with context %}
|
||||
{% import 'admin/static.html' as admin_static with context%}
|
||||
|
||||
{% block head %}
|
||||
{{ super() }}
|
||||
<link href="{{ admin_static.url(filename='admin/css/bootstrap3/rediscli.css', v='1.0.0') }}" rel="stylesheet">
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="console">
|
||||
<div class="console-container">
|
||||
</div>
|
||||
<div class="console-line">
|
||||
<form action="#">
|
||||
<input type="text"></input>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block tail %}
|
||||
{{ super() }}
|
||||
|
||||
<div id="execute-view-data" style="display:none;">{{ admin_view.get_url('.execute_view')|tojson|safe }}</div>
|
||||
<script src="{{ admin_static.url(filename='admin/js/rediscli.js', v='1.0.0') }}"></script>
|
||||
{% endblock %}
|
32
advlabdb/templates/admin/rediscli/response.html
Normal file
32
advlabdb/templates/admin/rediscli/response.html
Normal file
|
@ -0,0 +1,32 @@
|
|||
{% macro render(item, depth=0) %}
|
||||
{% set type = type_name(item) %}
|
||||
|
||||
{% if type == 'tuple' or type == 'list' %}
|
||||
{% if not item %}
|
||||
Empty {{ type }}.
|
||||
{% else %}
|
||||
{% for n in item %}
|
||||
{{ loop.index }}) {{ render(n, depth + 1) }}<br/>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% elif type == 'bool' %}
|
||||
{% if depth == 0 and item %}
|
||||
OK
|
||||
{% else %}
|
||||
<span class="type-bool">{{ item }}</span>
|
||||
{% endif %}
|
||||
{% elif type == 'str' or type == 'unicode' %}
|
||||
"{{ item }}"
|
||||
{% elif type == 'bytes' %}
|
||||
"{{ item.decode('utf-8') }}"
|
||||
{% elif type == 'TextWrapper' %}
|
||||
<pre>{{ item }}</pre>
|
||||
{% elif type == 'dict' %}
|
||||
{% for k, v in item.items() %}
|
||||
{{ loop.index }}) {{ k }} - {{ render(v, depth + 1) }}<br/>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{{ item }}
|
||||
{% endif %}
|
||||
{% endmacro %}
|
||||
{{ render(result) }}
|
3
advlabdb/templates/admin/static.html
Normal file
3
advlabdb/templates/admin/static.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
{% macro url() -%}
|
||||
{{ get_url('{admin_endpoint}.static'.format(admin_endpoint=admin_view.admin.endpoint), *varargs, **kwargs) }}
|
||||
{%- endmacro %}
|
6
advlabdb/templates/admin_create.html
Normal file
6
advlabdb/templates/admin_create.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
{% extends "admin/model/create.html" %}
|
||||
|
||||
{% block body %}
|
||||
User's active semester: {{userActiveSemester().label}}
|
||||
{{super()}}
|
||||
{% endblock %}
|
6
advlabdb/templates/admin_edit.html
Normal file
6
advlabdb/templates/admin_edit.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
{% extends "admin/model/edit.html" %}
|
||||
|
||||
{% block body %}
|
||||
User's active semester: {{userActiveSemester().label}}
|
||||
{{super()}}
|
||||
{% endblock %}
|
6
advlabdb/templates/admin_list.html
Normal file
6
advlabdb/templates/admin_list.html
Normal file
|
@ -0,0 +1,6 @@
|
|||
{% extends "admin/model/list.html" %}
|
||||
|
||||
{% block body %}
|
||||
User's active semester: {{userActiveSemester(flashWarning=True).label}}
|
||||
{{super()}}
|
||||
{% endblock %}
|
Loading…
Reference in a new issue