forked from rc/aircox
cfr #121 Co-authored-by: Christophe Siraut <d@tobald.eu.org> Co-authored-by: bkfox <thomas bkfox net> Co-authored-by: Thomas Kairos <thomas@bkfox.net> Reviewed-on: rc/aircox#131 Co-authored-by: Chris Tactic <ctactic@noreply.git.radiocampus.be> Co-committed-by: Chris Tactic <ctactic@noreply.git.radiocampus.be>
This commit is contained in:
@ -1,44 +0,0 @@
|
||||
{% extends "admin/change_form.html" %}
|
||||
{% comment %}Admin edit template to edit pages.{% endcomment %}
|
||||
{% load admin_urls i18n static %}
|
||||
|
||||
{% if not is_popup %}
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=opts.app_label %}">{{ opts.app_config.verbose_name }}</a>
|
||||
› {% if has_view_permission %}<a href="{% url opts|admin_urlname:'changelist' %}">{{ opts.verbose_name_plural|capfirst }}</a>{% else %}{{ opts.verbose_name_plural|capfirst }}{% endif %}
|
||||
|
||||
{% if parent %}
|
||||
› <a href="{% url opts|admin_urlname:"changelist" %}?parent={{parent.id}}">{{ parent.title }}</a>
|
||||
{% endif %}
|
||||
|
||||
› {% if add %}{% blocktranslate with name=opts.verbose_name %}Add {{ name }}{% endblocktranslate %}{% else %}{{ original|truncatewords:"18" }}{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% block submit_buttons_bottom %}
|
||||
{% if has_change_permission %}
|
||||
<div class="columns is-size-5">
|
||||
<div class="column has-text-left">
|
||||
{% if original and not original.is_trash %}
|
||||
<button type="submit" name="status" value="32" class="button is-danger is-size-6">{% translate "Move to trash" %}</button>
|
||||
{% endif %}
|
||||
{% if original and not original.is_draft %}
|
||||
<button type="submit" name="status" value="0" class="button is-warning is-size-6">{% translate "Mark as draft" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="column has-text-right">
|
||||
<button type="submit" class="button is-secondary is-size-6">{% translate "Save" %}</button>
|
||||
<button type="submit" name="_continue" class="button is-secondary is-size-6">{% translate "Save and continue" %}</button>
|
||||
{% if not original.is_published %}
|
||||
<button type="submit" name="status" value="16" class="button is-primary is-size-6">{% translate "Publish" %}</button>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,19 +0,0 @@
|
||||
{% extends "admin/change_list.html" %}
|
||||
{% load admin_urls i18n %}
|
||||
|
||||
{% if not is_popup %}
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=cl.opts.app_label %}">{{ cl.opts.app_config.verbose_name }}</a>
|
||||
{% if parent %}
|
||||
› <a href="{% url cl.opts|admin_urlname:'changelist' %}">{{ cl.opts.verbose_name_plural|capfirst }}</a>
|
||||
<b>› {{ parent.title }}</b>
|
||||
{% else %}
|
||||
› {{ cl.opts.verbose_name_plural|capfirst }}
|
||||
{% endif %}
|
||||
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endif %}
|
@ -1,85 +0,0 @@
|
||||
{% comment %}Inline block to edit playlists{% endcomment %}
|
||||
{% load aircox aircox_admin static i18n %}
|
||||
|
||||
{% with inline_admin_formset as admin_formset %}
|
||||
{% with admin_formset.formset as formset %}
|
||||
|
||||
<div id="inline-tracks" class="box mb-5">
|
||||
{{ admin_formset.non_form_errors }}
|
||||
|
||||
<a-playlist-editor
|
||||
:labels="{% track_inline_labels %}"
|
||||
:init-data="{% track_inline_data formset=formset %}"
|
||||
settings-url="{% url "api:user-settings" %}"
|
||||
data-prefix="{{ formset.prefix }}-">
|
||||
<template #title>
|
||||
<h5 class="title is-4">{% trans "Playlist" %}</h5>
|
||||
</template>
|
||||
<template v-slot:top="{items}">
|
||||
<input type="hidden" name="{{ formset.prefix }}-TOTAL_FORMS"
|
||||
:value="items.length || 0"/>
|
||||
<input type="hidden" name="{{ formset.prefix }}-INITIAL_FORMS"
|
||||
value="{{ formset.initial_form_count }}"/>
|
||||
<input type="hidden" name="{{ formset.prefix }}-MIN_NUM_FORMS"
|
||||
value="{{ formset.min_num }}"/>
|
||||
<input type="hidden" name="{{ formset.prefix }}-MAX_NUM_FORMS"
|
||||
value="{{ formset.max_num }}"/>
|
||||
</template>
|
||||
<template #rows-header-head>
|
||||
<th style="max-width:2em" title="{% trans "Track Position" %}"
|
||||
aria-description="{% trans "Track Position" %}">
|
||||
<span class="icon">
|
||||
<i class="fa fa-arrow-down-1-9"></i>
|
||||
</span>
|
||||
</th>
|
||||
</template>
|
||||
<template v-slot:row-head="{item,row}">
|
||||
<td>
|
||||
[[ row+1 ]]
|
||||
<input type="hidden"
|
||||
:name="'{{ formset.prefix }}-' + row + '-position'"
|
||||
:value="row"/>
|
||||
<input t-if="item.data.id" type="hidden"
|
||||
:name="'{{ formset.prefix }}-' + row + '-id'"
|
||||
:value="item.data.id || item.id"/>
|
||||
|
||||
{% for field in admin_formset.fields %}
|
||||
{% if field.name != 'position' and field.widget.is_hidden %}
|
||||
<input type="hidden"
|
||||
:name="'{{ formset.prefix }}-' + row + '-{{ field.name }}'"
|
||||
v-model="item.data[attr]"/>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
</template>
|
||||
{% for field in admin_formset.fields %}
|
||||
{% if not field.widget.is_hidden and not field.is_readonly %}
|
||||
<template v-slot:row-{{ field.name }}="{item,cell,value,attr,emit}">
|
||||
<div class="field">
|
||||
{% if field.name in 'artist,title,album' %}
|
||||
<a-autocomplete
|
||||
:input-class="['input', item.error(attr) ? 'is-danger' : 'half-field']"
|
||||
url="{% url 'api:track-autocomplete' %}?{{ field.name }}=${query}&field={{ field.name }}"
|
||||
{% else %}
|
||||
<div class="control">
|
||||
<input type="{{ widget.type }}"
|
||||
:class="['input', item.error(attr) ? 'is-danger' : 'half-field']"
|
||||
{% endif %}
|
||||
:name="'{{ formset.prefix }}-' + cell.row + '-{{ field.name }}'"
|
||||
v-model="item.data[attr]"
|
||||
title="{{ field.help }}"
|
||||
@change="emit('change', col)"/>
|
||||
{% if field.name not in 'artist,title,album' %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<p v-for="error in item.error(attr)" class="help is-danger">
|
||||
[[ error ]] !
|
||||
</p>
|
||||
</div>
|
||||
</template>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</a-playlist-editor>
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endwith %}
|
@ -1,82 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% comment %}Admin tool displaying logs statistics{% endcomment %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
|
||||
{% block content %}{{ block.super }}
|
||||
<div id="app">
|
||||
|
||||
{# TODO: date subtitle #}
|
||||
<nav class="navbar" role="menu">
|
||||
{% with "admin:tools-stats" as url_name %}
|
||||
{% include "aircox/widgets/dates_menu.html" %}
|
||||
{% endwith %}
|
||||
</nav>
|
||||
|
||||
<a-statistics class="column">
|
||||
<template v-slot="{counts}">
|
||||
<table class="table is-hoverable is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% translate "Time" %}</th>
|
||||
<th>{% translate "Episode" %}</th>
|
||||
<th>{% translate "Track" %}</th>
|
||||
<th>{% translate "Tags" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for object in object_list %}
|
||||
{% with object|get_tracks as tracks %}
|
||||
{% for track in tracks %}
|
||||
<tr>
|
||||
{% if forloop.first %}
|
||||
<td rowspan="{{ tracks|length }}">{{ object.start|time:"H:i" }} {% if object|is_diffusion %} - {{ object.end|time:"H:i" }}{% endif %}</td>
|
||||
<td rowspan="{{ tracks|length }}">{{ object.episode|default:"" }}</td>
|
||||
{% endif %}
|
||||
|
||||
{% with track as object %}
|
||||
<td>{% include "aircox/widgets/track_item.html" %}</td>
|
||||
{% endwith %}
|
||||
{% with track.tags.all|join:', ' as tags %}
|
||||
<td>
|
||||
{% if tags %}
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" checked value="{{ tags|escape }}" name="data">
|
||||
{{ tags }}
|
||||
</label>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endwith %}
|
||||
</tr>
|
||||
{% empty %}
|
||||
{% if object|is_diffusion %}
|
||||
<tr>
|
||||
<td>{{ object.start|time:"H:i" }} - {{ object.end|time:"H:i" }}</td>
|
||||
<td>{{ object.episode|default:"" }}</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td class="is-size-6">{% translate "Total" %}</td>
|
||||
<td colspan="100">
|
||||
<div class="columns is-size-6">
|
||||
<span v-for="(count, tag) in counts" class="column">
|
||||
<b>[[ tag ]]</b>
|
||||
[[ count ]]
|
||||
</span>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</template>
|
||||
</a-statistics>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,224 +0,0 @@
|
||||
{% load i18n static aircox_admin %}<!DOCTYPE html>
|
||||
{% get_current_language as LANGUAGE_CODE %}{% get_current_language_bidi as LANGUAGE_BIDI %}
|
||||
<html lang="{{ LANGUAGE_CODE|default:"en-us" }}" {% if LANGUAGE_BIDI %}dir="rtl"{% endif %}>
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %}</title>
|
||||
|
||||
<!-- <link rel="stylesheet" type="text/css" href="{% static "aircox/vendor.css" %}"> -->
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/base.css" %}">
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/css/chunk-common.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/css/chunk-vendors.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/css/admin.css" %}"/>
|
||||
<script src="{% static "aircox/js/chunk-common.js" %}"></script>
|
||||
<script src="{% static "aircox/js/chunk-vendors.js" %}"></script>
|
||||
<script src="{% static "aircox/js/admin.js" %}"></script>
|
||||
|
||||
{% block extrastyle %}{% endblock %}
|
||||
|
||||
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% block stylesheet_rtl %}{% static "admin/css/rtl.css" %}{% endblock %}">{% endif %}
|
||||
|
||||
{% block extrahead %}{% endblock %}
|
||||
{% block responsive %}
|
||||
<meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0">
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/responsive.css" %}">
|
||||
{% if LANGUAGE_BIDI %}<link rel="stylesheet" type="text/css" href="{% static "admin/css/responsive_rtl.css" %}">{% endif %}
|
||||
{% endblock %}
|
||||
{% block blockbots %}<meta name="robots" content="NONE,NOARCHIVE">{% endblock %}
|
||||
</head>
|
||||
{% load i18n %}
|
||||
|
||||
<body class="{% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}"
|
||||
data-admin-utc-offset="{% now "Z" %}">
|
||||
<script id="init-script">
|
||||
function vuePre(selector) {
|
||||
const elms = document.querySelectorAll(selector)
|
||||
for(const elm of elms) {
|
||||
elm.setAttribute('v-pre', true)
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('load', function() {
|
||||
{% block init-scripts %}
|
||||
aircox.init(null, {
|
||||
hotReload: false,
|
||||
{% if not init_app %}
|
||||
initBuilder: false,
|
||||
{% endif %}
|
||||
{% if init_el %}
|
||||
el: "{{ init_el }}",
|
||||
{% endif %}
|
||||
})
|
||||
{% endblock %}
|
||||
})
|
||||
</script>
|
||||
|
||||
<!-- Container -->
|
||||
<div class="admin">
|
||||
{% if not is_popup %}
|
||||
<!-- Header -->
|
||||
<nav class="navbar is-dark has-shadow">
|
||||
<div class="navbar-brand">
|
||||
{% block branding %}{% endblock %}
|
||||
</div>
|
||||
<div class="navbar-menu">
|
||||
{% block usertools %}
|
||||
<div class="navbar-start">
|
||||
{# Today's diffusions #}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<span class="icon-text navbar-link">
|
||||
<span class="icon"><i class="fa-regular fa-calendar-days"></i></span>
|
||||
<span>{% translate "Today" %}</span>
|
||||
</span>
|
||||
<div class="navbar-dropdown is-boxed">
|
||||
{% for diffusion in diffusions %}
|
||||
<a class="navbar-item {% if diffusion.is_now %}has-background-primary{% endif %}" href="{% url "admin:aircox_episode_change" diffusion.episode.pk %}">
|
||||
{{ diffusion.start|time }} |
|
||||
{{ diffusion.episode.title }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Articles #}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="icon-text navbar-link" href="{% url "admin:aircox_article_changelist" %}">
|
||||
<span class="icon"><i class="fa fa-newspaper"></i></span>
|
||||
<span>{% translate "Articles" %}</span>
|
||||
</a>
|
||||
<div class="navbar-dropdown is-boxed">
|
||||
<input type="text" onkeyup="aircox.filter_menu(event)"
|
||||
placeholder="{% translate "Search" %}" class="navbar-item input" />
|
||||
<hr class="navbar-divider"/>
|
||||
{% for program in programs %}
|
||||
<a class="navbar-item" href="{% url "admin:aircox_article_changelist" %}?parent={{ program.pk }}">
|
||||
{{ program.title }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Programs #}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="icon-text navbar-link" href="{% url "admin:aircox_program_changelist" %}">
|
||||
<span class="icon"><i class="fa fa-folder"></i></span>
|
||||
<span>{% translate "Programs" %}</span>
|
||||
</a>
|
||||
<div class="navbar-dropdown is-boxed">
|
||||
<input type="text" onkeyup="aircox.filter_menu(event)"
|
||||
placeholder="{% translate "Search" %}" class="navbar-item input" />
|
||||
<hr class="navbar-divider"/>
|
||||
{% for program in programs %}
|
||||
<a class="navbar-item" href="{% url "admin:aircox_program_change" program.pk %}">
|
||||
{{ program.title }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{# Episodes #}
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a class="icon-text navbar-link" href="{% url "admin:aircox_episode_changelist" %}">
|
||||
<span class="icon"><i class="fa fa-calendar-check"></i></span>
|
||||
<span>{% translate "Episodes" %}</span>
|
||||
</a>
|
||||
<div class="navbar-dropdown is-boxed">
|
||||
<input type="text" onkeyup="aircox.filter_menu(event)"
|
||||
placeholder="{% translate "Search" %}" class="navbar-item input" />
|
||||
<hr class="navbar-divider"/>
|
||||
{% for program in programs %}
|
||||
<a class="navbar-item" href="{% url "admin:aircox_episode_changelist" %}?parent={{ program.pk }}">
|
||||
{{ program.title }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="navbar-end">
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a href="#" class="icon-text navbar-link">
|
||||
<span class="icon"><i class="fa-solid fa-screwdriver-wrench"></i></span>
|
||||
<span>{% translate "Tools" %}</span>
|
||||
</a>
|
||||
<div class="navbar-dropdown is-boxed is-right">
|
||||
{% get_admin_tools as admin_tools %}
|
||||
{% for label, url in admin_tools %}
|
||||
<a href="{{ url }}" class="navbar-item">{{ label }}</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="navbar-item has-dropdown is-hoverable">
|
||||
<a href="{% url "admin:auth_user_change" user.pk %}" class="icon-text navbar-link">
|
||||
<span class="icon"><i class="fa fa-user"></i></span>
|
||||
<span>{% firstof user.get_short_name user.get_username %}</span>
|
||||
</a>
|
||||
<div class="navbar-dropdown is-boxed is-right">
|
||||
{% block userlinks %}
|
||||
{% if site_url %}
|
||||
<a href="{{ site_url }}" class="navbar-item">{% translate 'View site' %}</a>
|
||||
{% endif %}
|
||||
{% if user.is_active and user.is_staff %}
|
||||
{% url 'django-admindocs-docroot' as docsroot %}
|
||||
{% if docsroot %}
|
||||
<a href="{{ docsroot }}" class="navbar-item">{% translate 'Documentation' %}</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% if user.has_usable_password %}
|
||||
<a href="{% url 'admin:password_change' %}" class="navbar-item">{% translate 'Change password' %}</a>
|
||||
{% endif %}
|
||||
<hr class="navbar-divider" />
|
||||
<a href="{% url 'admin:logout' %}" class="navbar-item">{% translate 'Log out' %}</a>
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% block nav-global %}{% endblock %}
|
||||
</nav>
|
||||
<!-- END Header -->
|
||||
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
{% if title %} › {{ title }}{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% block messages %}
|
||||
{% if messages %}
|
||||
<ul class="messagelist">{% for message in messages %}
|
||||
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message|capfirst }}</li>
|
||||
{% endfor %}</ul>
|
||||
{% endif %}
|
||||
{% endblock messages %}
|
||||
|
||||
<!-- Content -->
|
||||
<div id="app">
|
||||
{% block app %}
|
||||
<div id="content" class="{% block coltype %}colM{% endblock %}">
|
||||
{% block pretitle %}{% endblock %}
|
||||
{% block content_title %}{% if title %}<h1 class="title is-3">{{ title }}</h1>{% endif %}{% endblock %}
|
||||
{% block content %}
|
||||
{% block object-tools %}{% endblock %}
|
||||
{{ content }}
|
||||
{% endblock %}
|
||||
{% block sidebar %}{% endblock %}
|
||||
<br class="clear">
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<!-- END Content -->
|
||||
|
||||
{% block footer %}<div id="footer"></div>{% endblock %}
|
||||
</div>
|
||||
<!-- END Container -->
|
||||
|
||||
{% block player %}
|
||||
{% if request.station %}
|
||||
<div id="player">{% include "aircox/widgets/player.html" %}</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
</body>
|
||||
</html>
|
@ -1,8 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load static %}
|
||||
|
||||
{% block branding %}
|
||||
<a href="{% url 'admin:index' %}">
|
||||
<img src="{% static "aircox/logo.png" %}"/>
|
||||
</a>
|
||||
{% endblock %}
|
@ -1,5 +0,0 @@
|
||||
{% extends "admin/change_form.html" %}
|
||||
|
||||
{% block content %}
|
||||
<div v-pre>{{ block.super }}</div>
|
||||
{% endblock %}
|
@ -1,89 +0,0 @@
|
||||
{% extends "admin/base_site.html" %}
|
||||
{% load i18n admin_urls static admin_list %}
|
||||
|
||||
{% block extrastyle %}
|
||||
{{ block.super }}
|
||||
{% if cl.formset %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">
|
||||
{% endif %}
|
||||
{% if cl.formset or action_form %}
|
||||
<script type="text/javascript" src="{% url 'admin:jsi18n' %}"></script>
|
||||
{% endif %}
|
||||
{{ media.css }}
|
||||
{% if not actions_on_top and not actions_on_bottom %}
|
||||
<style>
|
||||
#changelist table thead th:first-child {width: inherit}
|
||||
</style>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ block.super }}
|
||||
{{ media.js }}
|
||||
{% endblock %}
|
||||
|
||||
{% block bodyclass %}{{ block.super }} app-{{ opts.app_label }} model-{{ opts.model_name }} change-list{% endblock %}
|
||||
|
||||
{% if not is_popup %}
|
||||
{% block breadcrumbs %}
|
||||
<div class="breadcrumbs">
|
||||
<a href="{% url 'admin:index' %}">{% translate 'Home' %}</a>
|
||||
› <a href="{% url 'admin:app_list' app_label=cl.opts.app_label %}">{{ cl.opts.app_config.verbose_name }}</a>
|
||||
› {{ cl.opts.verbose_name_plural|capfirst }}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% block coltype %}flex{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="content-main">
|
||||
{% block object-tools %}
|
||||
<ul class="object-tools">
|
||||
{% block object-tools-items %}
|
||||
{% change_list_object_tools %}
|
||||
{% endblock %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
{% if cl.formset and cl.formset.errors %}
|
||||
<p class="errornote">
|
||||
{% if cl.formset.total_error_count == 1 %}{% translate "Please correct the error below." %}{% else %}{% trans "Please correct the errors below." %}{% endif %}
|
||||
</p>
|
||||
{{ cl.formset.non_form_errors }}
|
||||
{% endif %}
|
||||
|
||||
<div class="columns is-fullwidth module {% if cl.has_filters %} filtered{% endif %}" id="changelist">
|
||||
<div class="column">
|
||||
<form id="changelist-form" method="post"{% if cl.formset and cl.formset.is_multipart %} enctype="multipart/form-data"{% endif %} novalidate>{% csrf_token %}
|
||||
{% if cl.formset %}
|
||||
<div>{{ cl.formset.management_form }}</div>
|
||||
{% endif %}
|
||||
|
||||
{% block result_list %}
|
||||
{% if action_form and actions_on_top and cl.show_admin_actions %}{% admin_actions %}{% endif %}
|
||||
{% result_list cl %}
|
||||
{% if action_form and actions_on_bottom and cl.show_admin_actions %}{% admin_actions %}{% endif %}
|
||||
{% endblock %}
|
||||
{% block pagination %}{% pagination cl %}{% endblock %}
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<div class="column is-one-quarter">
|
||||
{% block search %}{% search_form cl %}{% endblock %}
|
||||
<hr>
|
||||
{% block date_hierarchy %}{% if cl.date_hierarchy %}{% date_hierarchy cl %}{% endif %}{% endblock %}
|
||||
|
||||
{% block filters %}
|
||||
{% if cl.has_filters %}
|
||||
<div id="changelist-filter">
|
||||
<h2>{% translate 'Filter' %}</h2>
|
||||
{% for spec in cl.filter_specs %}{% admin_list_filter cl spec %}{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,94 +0,0 @@
|
||||
{% extends "admin/index.html" %}
|
||||
{% load i18n thumbnail %}
|
||||
|
||||
|
||||
{% block app %}
|
||||
<div class="section">
|
||||
<div class="columns">
|
||||
<div class="column">
|
||||
<div class="box">
|
||||
<h1 class="title icon-text is-4">
|
||||
<span class="icon"><i class="fa-regular fa-calendar-days"></i></span>
|
||||
<span>{% translate "Today" %}</span>
|
||||
</h1>
|
||||
{% if diffusions %}
|
||||
<table class="table is-fullwidth is-striped">
|
||||
<tbody>
|
||||
{% for diffusion in diffusions %}
|
||||
{% with episode=diffusion.episode %}
|
||||
<tr {% if diffusion.is_now %}class="is-selected"{% endif %}>
|
||||
<td>{{ diffusion.start|time }} - {{ diffusion.end|time }}</td>
|
||||
<td><img src="{% thumbnail episode.cover 64x64 crop %}"/></td>
|
||||
<td>
|
||||
<a href="{% url "admin:aircox_episode_change" episode.pk %}">{{ episode.title }}</a>
|
||||
|
||||
{% if diffusion.type == diffusion.TYPE_ON_AIR %}
|
||||
<span class="tag is-info">
|
||||
<span class="icon is-small">
|
||||
{% if diffusion.is_live %}
|
||||
<i class="fa fa-microphone"
|
||||
title="{% translate "Live diffusion" %}"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-music"
|
||||
title="{% translate "Differed diffusion" %}"></i>
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
{{ diffusion.get_type_display }}
|
||||
</span>
|
||||
{% elif diffusion.type == diffusion.TYPE_CANCEL %}
|
||||
<span class="tag is-danger">
|
||||
{{ diffusion.get_type_display }}</span>
|
||||
{% elif diffusion.type == diffusion.TYPE_UNCONFIRMED %}
|
||||
<span class="tag is-warning">
|
||||
{{ diffusion.get_type_display }}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% else %}
|
||||
<div class="block has-text-centered">
|
||||
{% trans "No diffusion is scheduled for today." %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<div class="box">
|
||||
<h1 class="title is-4 icon-text">
|
||||
<span class="icon"><i class="fa-regular fa-comments"></i></span>
|
||||
<span>{% translate "Latest comments" %}</span>
|
||||
</h1>
|
||||
{% if comments %}
|
||||
{% include "aircox/widgets/page_list.html" with object_list=comments with_title=True %}
|
||||
<div class="has-text-centered">
|
||||
<a href="{% url "admin:aircox_comment_changelist" %}" class="float-center">{% translate "All comments" %}</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<p class="block has-text-centered">{% trans "No comment posted yet" %}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="column">
|
||||
<div class="box">
|
||||
<h1 class="title is-4 icon-text">
|
||||
<span class="icon"><i class="fa-regular fa-newspaper"></i></span>
|
||||
<span>{% translate "Latest publications" %}</span>
|
||||
</h1>
|
||||
{% if latests %}
|
||||
{% include "aircox/widgets/page_list.html" with object_list=latests no_actions=True %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="box">
|
||||
<h1 class="title is-4 icon-text">
|
||||
<span class="icon"><i class="fa fa-screwdriver-wrench"></i></span>
|
||||
<span>{% translate "Administration" %}</span>
|
||||
</h1>
|
||||
{% include "admin/app_list.html" with app_list=app_list show_changelinks=True %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
@ -1,30 +1,2 @@
|
||||
{% extends "aircox/page_detail.html" %}
|
||||
{% comment %}Detail page for regular articles{% endcomment %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block sidebar %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if sidebar_object_list %}
|
||||
<section>
|
||||
{% comment %}Translators: in page detail sidebar{% endcomment %}
|
||||
<h4 class="title is-4">{% translate "Latest news" %}</h4>
|
||||
|
||||
{% for object in sidebar_object_list %}
|
||||
{% include "aircox/widgets/page_item.html" %}
|
||||
{% endfor %}
|
||||
|
||||
<br>
|
||||
<nav class="pagination is-centered">
|
||||
<ul class="pagination-list">
|
||||
<li>
|
||||
<a href="{% url "article-list" %}" class="pagination-link"
|
||||
aria-label="{% translate "Show all news" %}">
|
||||
{% translate "More news" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
@ -1,3 +1,4 @@
|
||||
{% load static i18n thumbnail aircox %}<!doctype html>
|
||||
{% comment %}
|
||||
Base website template. It displays various elements depending on context
|
||||
variables.
|
||||
@ -6,14 +7,10 @@ Usefull context:
|
||||
- cover: image cover
|
||||
- site: current website
|
||||
- model: view model or displayed `object`'s
|
||||
- sidebar_object_list: item to display in sidebar
|
||||
- sidebar_url_name: url name sidebar item complete list
|
||||
- sidebar_url_parent: parent page for sidebar items complete list
|
||||
{% endcomment %}
|
||||
{% load static i18n thumbnail aircox %}
|
||||
|
||||
<html>
|
||||
<head>
|
||||
{% block head %}
|
||||
<meta charset="utf-8" />
|
||||
<meta name="application-name" content="aircox" />
|
||||
<meta name="description" content="{{ site.description }}" />
|
||||
@ -22,24 +19,36 @@ Usefull context:
|
||||
<link rel="icon" href="{% thumbnail site.favicon 32x32 crop %}" />
|
||||
|
||||
{% block assets %}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/css/chunk-common.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/css/chunk-vendors.css" %}"/>
|
||||
<script src="{% static "aircox/js/chunk-common.js" %}"></script>
|
||||
<script src="{% static "aircox/js/chunk-vendors.js" %}"></script>
|
||||
<script src="{% static "aircox/js/core.js" %}"></script>
|
||||
{% static "vue/vue.esm-browser.js" as vue_url %}
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"vue": "{{vue_url}}"
|
||||
{% block assets-import-map %}{% endblock %}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<script type="module" src="{{vue_url}}"></script>
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="{% static "fontawesome-free/css/all.min.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/index.css" %}"/>
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/public.css" %}"/>
|
||||
|
||||
<script type="module" src="{% if app_js_url %}{{ app_js_url }}{% else %}{% static "aircox/public.js" %}{% endif %}"></script>
|
||||
{% endblock %}
|
||||
|
||||
<title>
|
||||
{% block head_title %}
|
||||
{% if page and page.title %}{{ page.title }} — {{ station.name }}
|
||||
{% else %}{{ station.name }}
|
||||
{% block head-title %}
|
||||
{% if page and page.title %}{{ page.title }} —
|
||||
{% endif %}
|
||||
{{ station.name }}
|
||||
{% endblock %}
|
||||
</title>
|
||||
|
||||
{% block head_extra %}{% endblock %}
|
||||
{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<body {% if request.is_mobile %}class="mobile"{% endif %}>
|
||||
{% block body %}
|
||||
<script id="init-script">
|
||||
window.addEventListener('load', function() {
|
||||
{% block init-scripts %}
|
||||
@ -48,123 +57,119 @@ Usefull context:
|
||||
})
|
||||
</script>
|
||||
<div id="app">
|
||||
{% block top-nav-container %}
|
||||
<nav class="navbar has-shadow" role="navigation" aria-label="main navigation">
|
||||
<div class="container">
|
||||
<div class="navbar-brand">
|
||||
<a href="/" title="{% translate "Home" %}" class="navbar-item">
|
||||
<img src="{{ station.logo.url }}" class="logo"/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="navbar-menu">
|
||||
<div class="navbar-start">
|
||||
{% block top-nav %}
|
||||
{% nav_items "top" css_class="navbar-item" active_class="is-active" as items %}
|
||||
{% for item, render in items %}
|
||||
{{ render }}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div class="navbar-end">
|
||||
{% block top-nav-tools %}
|
||||
{% endblock %}
|
||||
{% block top-nav-end %}
|
||||
<div class="navbar-item">
|
||||
<form action="{% url 'page-list' %}" method="GET">
|
||||
<div class="control has-icons-left">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fa fa-search"></i>
|
||||
</span>
|
||||
<input type="text" name="q" class="input"
|
||||
placeholder="{% translate "Search" %}" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
<div class="container">
|
||||
<div class="columns is-desktop">
|
||||
<main class="column page">
|
||||
<header class="header">
|
||||
{% block header %}
|
||||
<h1 class="title is-1">
|
||||
{% block title %}
|
||||
{% if page and page.title %}
|
||||
{{ page.title }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</h1>
|
||||
|
||||
<h3 class="subtitle is-3">
|
||||
{% block subtitle %}{% endblock %}
|
||||
</h3>
|
||||
|
||||
<div class="columns is-size-4">
|
||||
{% block header_nav %}
|
||||
<span class="column">
|
||||
{% block header_crumbs %}
|
||||
{% if parent %}
|
||||
<a href="{{ parent.get_absolute_url }}">
|
||||
{{ parent.title }}</a></li>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</header>
|
||||
|
||||
{% block main %}
|
||||
{% block content %}
|
||||
{% if page and page.content %}
|
||||
<section class="page-content mb-2">{{ page.content|safe }}</section>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock main %}
|
||||
</main>
|
||||
|
||||
{% if has_sidebar %}
|
||||
{% comment %}Translators: main sidebar {% endcomment %}
|
||||
<aside class="column is-one-third-desktop">
|
||||
{# FIXME: block cover into sidebar one #}
|
||||
{% block cover %}
|
||||
{% if page and page.cover %}
|
||||
<img class="cover mb-4" src="{{ page.cover.url }}" class="cover"/>
|
||||
{% endif %}
|
||||
{% block app %}
|
||||
<div class="navs">
|
||||
{% block nav %}
|
||||
<nav class="nav primary" role="navigation" aria-label="main navigation">
|
||||
{% block primary-nav %}
|
||||
<a class="nav-brand" href="{% url "home" %}">
|
||||
<img src="{{ station.logo.url }}">
|
||||
</a>
|
||||
<a-switch class="button burger"
|
||||
el=".nav.primary .nav-menu" group="nav"
|
||||
aria-label="{% translate "Main menu" %}">
|
||||
</a-switch>
|
||||
<div class="nav-menu">
|
||||
{% block primary-nav-menu %}
|
||||
{% nav_items "top" css_class="nav-item" active_class="active" as items %}
|
||||
{% for item, render in items %}
|
||||
{{ render }}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
|
||||
{% with is_thin=True %}
|
||||
{% block sidebar %}
|
||||
{% if sidebar_object_list %}
|
||||
{% with object_list=sidebar_object_list %}
|
||||
{% with list_url=sidebar_list_url %}
|
||||
{% with has_headline=False %}
|
||||
<section>
|
||||
<h4 class="title is-4">
|
||||
{% block sidebar_title %}{% translate "Recently" %}{% endblock %}
|
||||
</h4>
|
||||
{% include "aircox/widgets/page_list.html" %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% if user.is_authenticated %}
|
||||
{% include "./widgets/nav.html" %}
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endblock %}
|
||||
{% endwith %}
|
||||
</aside>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</nav>
|
||||
|
||||
{% block secondary-nav %}{% endblock %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
{% block main-container %}
|
||||
<main class="page">
|
||||
{% block main %}
|
||||
{% spaceless %}
|
||||
{% block breadcrumbs-container %}
|
||||
<div class="breadcrumbs container">
|
||||
{% block breadcrumbs %}{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endspaceless %}
|
||||
|
||||
{% block header-container %}
|
||||
<header class="container header preview preview-header {% if cover %}has-cover{% endif %}">
|
||||
{% block header %}
|
||||
{% spaceless %}
|
||||
<figure class="header-cover">
|
||||
{% block header-cover %}
|
||||
{% if cover %}
|
||||
<img src="{{ cover }}" ref="cover" class="cover">
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</figure>
|
||||
{% endspaceless %}
|
||||
<div class="headings preview-card-headings">
|
||||
{% block headings %}
|
||||
<div>
|
||||
{% block title-container %}
|
||||
<h1 class="title is-1 {% block title-class %}{% endblock %}">{% block title %}{{ title|default:"" }}{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div>
|
||||
{% spaceless %}
|
||||
<span class="subtitle is-2">
|
||||
{% block subtitle %}
|
||||
{% if subtitle %}
|
||||
{{ subtitle }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</span>
|
||||
{% endspaceless %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
{% block content-container %}
|
||||
{% if page and page.content %}
|
||||
<section class="container content page-content">
|
||||
{% block content %}
|
||||
{{ page.display_content|safe }}
|
||||
{% endblock %}
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
</main>
|
||||
{% endblock %}
|
||||
|
||||
{% block footer-container %}
|
||||
<footer class="page-footer">
|
||||
{% block footer %}
|
||||
{% comment %}
|
||||
{% nav_items "footer" css_class="nav-item" active_class="active" as items %}
|
||||
{% for item, render in items %}
|
||||
{{ render }}
|
||||
{% endfor %}
|
||||
{% endcomment %}
|
||||
{% endblock %}
|
||||
|
||||
{% if request.station and request.station.legal_label %}
|
||||
{{ request.station.legal_label }} —
|
||||
{% endif %}
|
||||
</footer>
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
{% block player-container %}
|
||||
<div id="player">{% include "aircox/widgets/player.html" %}</div>
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
</body>
|
||||
</html>
|
||||
|
@ -1,8 +0,0 @@
|
||||
{% extends "aircox/base.html" %}
|
||||
{% comment %}Display detail of a BasePage{% endcomment %}
|
||||
|
||||
{% block head_title %}
|
||||
{% block title %}{{ page.title }}{% endblock %}
|
||||
—
|
||||
{{ station.name }}
|
||||
{% endblock %}
|
@ -1,86 +1,31 @@
|
||||
{% extends "aircox/base.html" %}
|
||||
{% extends "./public.html" %}
|
||||
|
||||
{% comment %}Display a list of BasePages{% endcomment %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block head_title %}
|
||||
{% block title %}
|
||||
{% if not page or not page.title %}
|
||||
{% if not parent %}{{ view.model|verbose_name:True|title }}
|
||||
{% else %}
|
||||
{% with parent.title as title %}
|
||||
{% with model|default:"Publications"|verbose_name:True|capfirst as model %}
|
||||
{% comment %}Translators: title when pages are filtered for a specific parent page, e.g.: Articles of My Incredible Show{% endcomment %}
|
||||
{% blocktranslate %}{{ model }} of {{ title }}{% endblocktranslate %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% else %}{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
—
|
||||
{{ station.name }}
|
||||
{% endblock %}
|
||||
{% block main %}
|
||||
{{ block.super }}
|
||||
|
||||
{% block main %}{{ block.super }}
|
||||
|
||||
{% block before_list %}{% endblock %}
|
||||
|
||||
<section role="list">
|
||||
{% block pages_list %}
|
||||
{% block list-container %}
|
||||
<section class="container clear-both list grid {{ list_class|default:"" }}" role="list">
|
||||
{% block list %}
|
||||
{% with has_headline=True %}
|
||||
{% for object in object_list %}
|
||||
{% block list_object %}
|
||||
{% include object.item_template_name|default:item_template_name %}
|
||||
{% endblock %}
|
||||
{% empty %}
|
||||
{% blocktranslate %}There is nothing published here...{% endblocktranslate %}
|
||||
{% endfor %}
|
||||
{% for object in object_list %}
|
||||
{% block list_object %}
|
||||
{% page_widget item_widget|default:"item" object %}
|
||||
{% endblock %}
|
||||
{% empty %}
|
||||
{% blocktranslate %}There is nothing published here...{% endblocktranslate %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
</section>
|
||||
|
||||
{% if is_paginated %}
|
||||
<hr/>
|
||||
{% update_query request.GET.copy page=None as GET %}
|
||||
{% with GET.urlencode as GET %}
|
||||
<nav class="pagination is-centered" role="pagination" aria-label="{% translate "pagination" %}">
|
||||
{% block pagination %}
|
||||
{% if page_obj.has_previous %}
|
||||
<a href="?{{ GET }}&page={{ page_obj.previous_page_number }}" class="pagination-previous">
|
||||
{% else %}
|
||||
<a class="pagination-previous" disabled>
|
||||
{% endif %}
|
||||
{% comment %}Translators: Bottom of the list, "previous page"{% endcomment %}
|
||||
{% translate "Previous" %}</a>
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
<a href="?{{ GET }}&page={{ page_obj.next_page_number }}" class="pagination-next">
|
||||
{% else %}
|
||||
<a class="pagination-next" disabled>
|
||||
{% endif %}
|
||||
{% comment %}Translators: Bottom of the list, "Nextpage"{% endcomment %}
|
||||
{% translate "Next" %}</a>
|
||||
|
||||
<ul class="pagination-list">
|
||||
{% for i in paginator.page_range %}
|
||||
<li>
|
||||
{% comment %}
|
||||
<form action="?{{ GET }}">
|
||||
{% for get in GET %}
|
||||
<input type="hidden" name="{{ get.0 }}" value="{{ get.1 }}" />
|
||||
{% endfor %}
|
||||
<input type="number" name="page" value="{{ page_obj.number }}" />
|
||||
</form>
|
||||
{% endcomment %}
|
||||
<a class="pagination-link {% if page_obj.number == i %}is-current{% endif %}"
|
||||
href="?{{ GET }}&page={{ i }}">{{ i }}</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endblock %}
|
||||
</nav>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% block list-pagination %}
|
||||
{% include "./widgets/list_pagination.html" %}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
16
aircox/templates/aircox/dashboard/base.html
Normal file
16
aircox/templates/aircox/dashboard/base.html
Normal file
@ -0,0 +1,16 @@
|
||||
{% extends "../base.html" %}
|
||||
{% load static i18n %}
|
||||
|
||||
{% block assets %}
|
||||
{% static "aircox/admin.js" as app_js_url %}
|
||||
{{ block.super }}
|
||||
<link rel="stylesheet" type="text/css" href="{% static "aircox/admin.css" %}"/>
|
||||
{% endblock %}
|
||||
|
||||
{% block head-title %}
|
||||
{% block title %}
|
||||
{% if page and page.title %}{{ page.title }}{% endif %}
|
||||
{% endblock %}
|
||||
{% if page and page.title %}—{% endif %}
|
||||
{{ station.name }}
|
||||
{% endblock %}
|
51
aircox/templates/aircox/dashboard/dashboard.html
Normal file
51
aircox/templates/aircox/dashboard/dashboard.html
Normal file
@ -0,0 +1,51 @@
|
||||
{% extends "./base.html" %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block subtitle %}
|
||||
<span class="icon">
|
||||
<i class="fa fa-user"></i>
|
||||
</span>
|
||||
{{ block.super }}
|
||||
{% if user.is_superuser %}
|
||||
— {% translate "administrator" %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content-container %}
|
||||
<section class="container grid-2 gap-4">
|
||||
<div>
|
||||
<h2 class="title is-2 mb-3">{% translate "Next diffusions" %}</h2>
|
||||
<div class="box box-shadow p-3" style="max-height: 35rem; overflow-y:auto;">
|
||||
{% for object in next_diffs|slice:"0:25" %}
|
||||
{% page_widget "item" object.episode diffusion=object timetable=True admin=True is_tiny=True %}
|
||||
{% empty %}
|
||||
<div>{% translate "No diffusion to display" %}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h2 class="title is-2 mb-3">{% translate "Programs" %}</h2>
|
||||
<div class="box box-shadow p-3" style="max-height: 35rem; overflow-y:auto;">
|
||||
{% for object in programs %}
|
||||
{% page_widget "item" object admin=True is_tiny=True %}
|
||||
{% empty %}
|
||||
<div>{% translate "No program to display" %}</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% if comments %}
|
||||
<div>
|
||||
<h2 class="title is-2 mb-3">{% translate "Last Comments" %}</h2>
|
||||
<div class="box box-shadow p-3" style="max-height: 35rem; overflow-y:auto;">
|
||||
{% for object in comments|slice:"0:25" %}
|
||||
{% page_widget "item" object admin=True is_tiny=True %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
</section>
|
||||
{% endblock %}
|
104
aircox/templates/aircox/dashboard/statistics.html
Normal file
104
aircox/templates/aircox/dashboard/statistics.html
Normal file
@ -0,0 +1,104 @@
|
||||
{% extends "./base.html" %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block title %}{% translate "Statistics" %}{% endblock %}
|
||||
|
||||
{% block content-container %}
|
||||
<div class="">
|
||||
|
||||
<form method="GET" class="box mt-3 mb-3">
|
||||
<h3 class="title is-3">{% translate "Filter by date" %}</h3>
|
||||
<div class="flex-row gap-3" style="align-items: flex-end">
|
||||
<div class="field mb-0">
|
||||
<label class="label">{% translate "from" %}</label>
|
||||
<input type="date" class="input" name="min_date" value="{{ min_date|date:"Y-m-d" }}"/>
|
||||
</div>
|
||||
<div class="field mb-0">
|
||||
<label class="label">{% translate "... to" %}</label>
|
||||
<input type="date" class="input" name="max_date" value="{{ max_date|date:"Y-m-d" }}"/>
|
||||
</div>
|
||||
<button class="button">{% translate "Apply" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
<a-statistics class="column">
|
||||
<template v-slot="{counts}">
|
||||
<table class="table is-hoverable is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{% translate "Time" %}</th>
|
||||
<th>{% translate "Episode" %} / {% translate "Track" %}</th>
|
||||
<th>{% translate "Tags" %}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% regroup object_list by date.date as by_date %}
|
||||
{% for date, objects in by_date %}
|
||||
<tr>
|
||||
<th colspan="3">
|
||||
{{ date|date:"l - d F Y" }}
|
||||
</th>
|
||||
</tr>
|
||||
{% for object in objects %}
|
||||
{% with object|is_diffusion as is_diff %}
|
||||
{% if is_diff %}
|
||||
<tr class="bg-main">
|
||||
<td>{{ object.start|time:"H:i" }} - {{ object.end|time:"H:i" }}</td>
|
||||
<td colspan="2">
|
||||
<a href="{% url "episode-detail" slug=object.episode.slug %}" target="new">{{ object.episode|default:"" }}</a>
|
||||
</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
|
||||
{% with object|get_tracks as tracks %}
|
||||
{% for track in tracks %}
|
||||
<tr {% if is_diff %}class="bg-main-light"{% endif %}>
|
||||
{% if forloop.first %}
|
||||
<td rowspan="{{ tracks|length }}">{{ object.start|time:"H:i" }} {% if object|is_diffusion %} - {{ object.end|time:"H:i" }}{% endif %}</td>
|
||||
{% endif %}
|
||||
|
||||
<td>
|
||||
{% if object.source %}{{ object.source }} / {% endif %}
|
||||
{% include "aircox/widgets/track_item.html" with object=track %}
|
||||
</td>
|
||||
{% with track.tags.all|join:', ' as tags %}
|
||||
<td>
|
||||
{% if tags and tags.strip %}
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" checked value="{{ tags|escape }}" name="data">
|
||||
{{ tags }}
|
||||
</label>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endwith %}
|
||||
</tr>
|
||||
{% empty %}
|
||||
{% if is_diff %}
|
||||
<tr class="bg-main-light">
|
||||
<td colspan="3">{% translate "No tracks" %}</td>
|
||||
</tr>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td class="is-size-6">{% translate "Totals" %}</td>
|
||||
<td colspan="2">
|
||||
<span v-for="(count, tag) in counts" class="mr-4">
|
||||
<b>[[ tag ]]</b>
|
||||
[[ count ]]
|
||||
</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
</template>
|
||||
</a-statistics>
|
||||
|
||||
</div>
|
||||
{% endblock %}
|
77
aircox/templates/aircox/dashboard/user_list.html
Normal file
77
aircox/templates/aircox/dashboard/user_list.html
Normal file
@ -0,0 +1,77 @@
|
||||
{% extends "./base.html" %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block title %}{% translate "Users" %}{% endblock %}
|
||||
|
||||
|
||||
{% block content-container %}
|
||||
<div class="container">
|
||||
{% if user.is_superuser %}
|
||||
<div class="message is-info mt-3">
|
||||
<div class="message-body">
|
||||
{% translate "Group and editors' changes will be visible only after page reload." %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<table class="table is-stripped is-fullwidth">
|
||||
<thead>
|
||||
<td>{% trans "User" %}</td>
|
||||
<td>{% trans "Infos" %}</td>
|
||||
<td>{% trans "Programs" %}</td>
|
||||
<td></td>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for obj in object_list %}
|
||||
<tr>
|
||||
<td>
|
||||
<div>
|
||||
{% if obj.first_name or obj.last_name %}
|
||||
<b>{{ obj.first_name }} {{ obj.last_name }}</b>
|
||||
—
|
||||
{% endif %}
|
||||
{{ obj.username }}
|
||||
</div>
|
||||
{% if obj.email %}
|
||||
<div class="text-light smaller">{{ obj.email }}</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% if not obj.is_active %}
|
||||
<span class="tag is-danger">{% trans "Inactive" %}</span>
|
||||
{% endif %}
|
||||
{% if obj.is_superuser %}
|
||||
<span class="tag is-warning">{% trans "Admin" %}</span>
|
||||
{% elif obj.is_staff %}
|
||||
<span class="tag is-info">{% trans "Staff" %}</span>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>
|
||||
{% for p in obj.programs %}
|
||||
<a href="{{ p.get_absolute_url }}">{{ p.title }}</a>
|
||||
{% if not forloop.last %}
|
||||
<br/>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</td>
|
||||
<td>
|
||||
{% if user.is_superuser %}
|
||||
<button type="button" class="button secondary"
|
||||
@click="$refs['user-groups-modal'].open({id: {{ obj.id }}, username: '{{ obj.username }}' })">
|
||||
{% trans "Groups" %}
|
||||
</button>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
{% include "aircox/widgets/list_pagination.html" %}
|
||||
|
||||
{% if user.is_superuser %}
|
||||
{% include "./widgets/user_groups.html" %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
25
aircox/templates/aircox/dashboard/widgets/form_field.html
Normal file
25
aircox/templates/aircox/dashboard/widgets/form_field.html
Normal file
@ -0,0 +1,25 @@
|
||||
{% comment %}
|
||||
Render a form field instance as field (to be used when no model instance is provided). Value is binded as vue, class to Bulma
|
||||
|
||||
Context:
|
||||
- name: field name
|
||||
- field: form field
|
||||
- value: input ":value" attribute
|
||||
- vbind: if True, use ":value" instead of "value"
|
||||
- hidden: if True, hidden field
|
||||
{% endcomment %}
|
||||
{% load aircox %}
|
||||
|
||||
{% if field.widget.is_hidden or hidden %}
|
||||
<input type="hidden" name="{{ name }}" value="{{ value|default:"" }}">
|
||||
{% elif field|is_checkbox %}
|
||||
<input type="checkbox" class="checkbox" name="{{ name }}" {% if value %}checked{% endif %}>
|
||||
{% elif field|is_select %}
|
||||
<select name="{{ name }}" class="select" value="{{ value|default:"" }}">
|
||||
{% for value, label in field.widget.choices %}
|
||||
<option value="{{ value }}">{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="text" class="input" name="{{ name }}" value="{{ value|default:"" }}">
|
||||
{% endif %}
|
34
aircox/templates/aircox/dashboard/widgets/group_users.html
Normal file
34
aircox/templates/aircox/dashboard/widgets/group_users.html
Normal file
@ -0,0 +1,34 @@
|
||||
{% load i18n %}
|
||||
|
||||
<a-modal ref="group-users-modal">
|
||||
<template #title="{item}">[[ item?.name ]]</template>
|
||||
<template #default="{item}">
|
||||
<a-many-to-many-edit v-if="item" ref="group-users"
|
||||
:url="'{% url 'api:usergroup-list' %}?group=' + item.id"
|
||||
commit-url="{% url 'api:usergroup-commit' %}"
|
||||
|
||||
:source_id="item.id" source_field="group"
|
||||
target_field="user"
|
||||
:autocomplete="{url:'{% url 'api:user-autocomplete' %}?search=${query}&not_in_group=' + item.id, 'label-field':'username', 'value-field':'id'}"
|
||||
>
|
||||
<template #items-title>{% translate "Members" %}</template>
|
||||
|
||||
<template #item="{item}">
|
||||
<b class="mr-3">[[ item.data.user.username ]]</b>
|
||||
<span>[[ item.data.user.first_name ]] [[ item.data.user.last_name ]]</span>
|
||||
</template>
|
||||
|
||||
<template #autocomplete-item="{item}">
|
||||
<b class="mr-3">[[ item.username ]]</b>
|
||||
<span class="text-light">[[ item.first_name ]] [[ item.last_name ]]</span>
|
||||
—
|
||||
<i>[[ item.email ]]</i>
|
||||
</template>
|
||||
</a-many-to-many-edit>
|
||||
</template>
|
||||
<template #footer="{item, close}">
|
||||
<button type="button" class="button" @click="$refs['group-users'].save(); close()">
|
||||
Save
|
||||
</button>
|
||||
</template>
|
||||
</a-modal>
|
54
aircox/templates/aircox/dashboard/widgets/list_editor.html
Normal file
54
aircox/templates/aircox/dashboard/widgets/list_editor.html
Normal file
@ -0,0 +1,54 @@
|
||||
{% comment %}
|
||||
Base template for list editor based on formsets (tracklist_editor, playlist_editor).
|
||||
|
||||
Context:
|
||||
- tag_id: id of parent component
|
||||
- tag: vue component tag (a-playlist-editor, etc.)
|
||||
- related_field: field name that target object
|
||||
- object: related object
|
||||
- formset: formset used to render the list editor
|
||||
- formset_data: formset data
|
||||
{% endcomment %}
|
||||
|
||||
{% load aircox aircox_admin static i18n %}
|
||||
|
||||
{% with formset.form.base_fields as fields %}
|
||||
{% block outer %}
|
||||
<div id="{{ tag_id }}">
|
||||
{{ formset.non_form_errors }}
|
||||
<!-- formset.management_form -->
|
||||
|
||||
<{{ tag }}
|
||||
{% block tag-attrs %}
|
||||
:form-data="{{ formset_data|json }}"
|
||||
:labels="window.aircox.labels"
|
||||
:init-data="{% formset_inline_data formset=formset %}"
|
||||
:columns="[{% for n, f in fields.items %}{% if not f.widget.is_hidden %}'{{ n }}',{% endif %}{% endfor %} ]"
|
||||
settings-url="{% url "api:user-settings" %}"
|
||||
data-prefix="{{ formset.prefix }}-"
|
||||
{% endblock %}>
|
||||
{% block inner %}
|
||||
<template #rows-header-head>
|
||||
{% block rows-header-head %}
|
||||
<th style="max-width:2em" title="{{ fields.position.help_text }}"
|
||||
aria-description="{{ fields.position.help_text }}">
|
||||
<span class="icon">
|
||||
<i class="fa fa-arrow-down-1-9"></i>
|
||||
</span>
|
||||
</th>
|
||||
{% endblock %}
|
||||
</template>
|
||||
{% for name, field in fields.items %}
|
||||
{% if not field.widget.is_hidden and not field.is_readonly %}
|
||||
<template v-slot:control-{{ name }}="{item,cell,value,attr,emit,inputName}">
|
||||
{% block row-control %}
|
||||
{% include "./v_form_field.html" with value="item.data."|add:name name="inputName" %}
|
||||
{% endblock %}
|
||||
</template>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</{{ tag }}>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endwith %}
|
@ -0,0 +1,46 @@
|
||||
{% extends "./list_editor.html" %}
|
||||
{% comment %}
|
||||
Context:
|
||||
- object: episode
|
||||
{% endcomment %}
|
||||
|
||||
{% block outer %}
|
||||
{% with tag_id="inline-sounds" %}
|
||||
{% with tag="a-sound-list-editor" %}
|
||||
{% with related_field="episode" %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block tag-attrs %}
|
||||
{{ block.super }}
|
||||
sound-list-url="{% url "api:sound-list" %}?program={{ object.parent_id }}"
|
||||
sound-upload-url="{% url "api:sound-list" %}"
|
||||
sound-delete-url="{% url "api:sound-detail" pk=123 %}"
|
||||
{% endblock %}
|
||||
|
||||
{% block inner %}
|
||||
{{ block.super }}
|
||||
|
||||
<template #upload-form>
|
||||
{% for field in sound_form %}
|
||||
{% with field.name as name %}
|
||||
{% if name in "program" %}
|
||||
{% include "aircox/forms/form_field.html" with value=field.initial field=field.field hidden=True %}
|
||||
{% elif name != "file" %}
|
||||
<div class="field is-horizontal">
|
||||
<label class="label mr-3">{{ field.label }}</label>
|
||||
{% include "aircox/forms/form_field.html" with value=field.initial field=field.field %}
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
</template>
|
||||
<template #row-delete="{cell}">
|
||||
<input type="checkbox" :name="'{{ formset.prefix }}-' + cell.row + '-DELETE'">
|
||||
</template>
|
||||
|
||||
{% endblock %}
|
@ -0,0 +1,34 @@
|
||||
{% extends "./list_editor.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block outer %}
|
||||
{% with tag_id="inline-tracks" %}
|
||||
{% with tag="a-track-list-editor" %}
|
||||
{% with related_field="episode" %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
{% block inner %}
|
||||
<template #title><h3 class="title">{% translate "Track list" %}</h3></template>
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block row-control %}
|
||||
{% if name == "tags" %}
|
||||
<input type="text" class="input"
|
||||
:name="inputName"
|
||||
v-model="item.data[attr]"
|
||||
@change="emit('change', cell.col)"
|
||||
>
|
||||
{% else %}
|
||||
<a-autocomplete
|
||||
:input-class="['input', item.error(attr) ? 'is-danger' : 'half-field']"
|
||||
url="{% url 'api:track-autocomplete' %}?{{ name }}=${query}&field={{ name }}"
|
||||
:name="inputName"
|
||||
v-model="item.data[attr]"
|
||||
@change="emit('change', cell.col)"/>
|
||||
{% endif %}
|
||||
{% endblock %}
|
30
aircox/templates/aircox/dashboard/widgets/user_groups.html
Normal file
30
aircox/templates/aircox/dashboard/widgets/user_groups.html
Normal file
@ -0,0 +1,30 @@
|
||||
{% load i18n %}
|
||||
|
||||
<a-modal ref="user-groups-modal">
|
||||
<template #title="{item}">[[ item?.username ]]</template>
|
||||
<template #default="{item}">
|
||||
<a-many-to-many-edit v-if="item" ref="user-groups"
|
||||
:url="'{% url 'api:usergroup-list' %}?user=' + item.id"
|
||||
commit-url="{% url 'api:usergroup-commit' %}"
|
||||
|
||||
:source_id="item.id" source_field="user"
|
||||
target_field="group"
|
||||
:autocomplete="{url:'{% url 'api:group-autocomplete' %}?search=${query}&no_user=' + item.id, 'label-field':'name', 'value-field':'id'}"
|
||||
>
|
||||
<template #items-title>{% translate "Groups" %}</template>
|
||||
|
||||
<template #item="{item}">
|
||||
[[ item.data.group.name ]]
|
||||
</template>
|
||||
|
||||
<template #autocomplete-item="{item}">
|
||||
[[ item.name ]]
|
||||
</template>
|
||||
</a-many-to-many-edit>
|
||||
</template>
|
||||
<template #footer="{item, close}">
|
||||
<button type="button" class="button" @click="$refs['user-groups'].save(); close()">
|
||||
Save
|
||||
</button>
|
||||
</template>
|
||||
</a-modal>
|
24
aircox/templates/aircox/dashboard/widgets/v_form_field.html
Normal file
24
aircox/templates/aircox/dashboard/widgets/v_form_field.html
Normal file
@ -0,0 +1,24 @@
|
||||
{% comment %}
|
||||
Render a form field instance as field (to be used when no model instance is provided). Value is binded as vue, class to Bulma
|
||||
|
||||
Context:
|
||||
- name: field name
|
||||
- field: form field
|
||||
- value: input ":v-model" attribute
|
||||
- hidden: if True, hidden field
|
||||
{% endcomment %}
|
||||
{% load aircox %}
|
||||
|
||||
{% if field.widget.is_hidden or hidden %}
|
||||
<input type="hidden" :name="{{ name }}" :value="{{ value|default:"" }}">
|
||||
{% elif field|is_checkbox %}
|
||||
<input type="checkbox" class="checkbox" :name="{{ name }}" v-model="{{ value }}">
|
||||
{% elif field|is_select %}
|
||||
<select :name="{{ name }}" class="select" v-model="{{ value|default:"" }}">
|
||||
{% for value, label in field.widget.choices %}
|
||||
<option value="{{ value }}">{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="text" class="input" :name="{{ name }}" v-model="{{ value|default:"" }}">
|
||||
{% endif %}
|
@ -14,16 +14,18 @@
|
||||
|
||||
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
|
||||
|
||||
{% block before_list %}
|
||||
{% with "diffusion-list" as url_name %}
|
||||
{% include "aircox/widgets/dates_menu.html" %}
|
||||
{% endwith %}
|
||||
{% block secondary-nav %}
|
||||
<nav class="nav secondary">
|
||||
{% include "./widgets/dates_menu.html" with url_name="diffusion-list" %}
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
{% block pages_list %}
|
||||
{% with hide_schedule=True %}
|
||||
<section role="list">
|
||||
{% include 'aircox/widgets/diffusion_list.html' %}
|
||||
<section role="list" class="list">
|
||||
{% for object in object_list %}
|
||||
{% page_widget "item" object.episode diffusion=object timetable=True %}
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
@ -2,79 +2,51 @@
|
||||
{% comment %}List of a show's episodes for a specific{% endcomment %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% include "aircox/program_sidebar.html" %}
|
||||
|
||||
{% block content-container %}
|
||||
|
||||
{% block content %}
|
||||
<a-episode :page="{title: "{{ page.title }}", podcasts: {{ object.podcasts|json }}}">
|
||||
<template v-slot="{podcasts,page}">
|
||||
{{ block.super }}
|
||||
{{ block.super }}
|
||||
|
||||
{% if object.podcasts %}
|
||||
<section>
|
||||
<a-playlist v-if="page" :set="podcasts"
|
||||
name="{{ page.title }}"
|
||||
list-class="menu-list" item-class="menu-item"
|
||||
:player="player" :actions="['play']"
|
||||
@select="player.playItems('queue', $event.item)">
|
||||
<template v-slot:header>
|
||||
<h4 class="title is-4">{% translate "Podcasts" %}</h4>
|
||||
</template>
|
||||
</a-playlist>
|
||||
{% comment %}
|
||||
{% for object in podcasts %}
|
||||
{% include "aircox/widgets/podcast_item.html" %}
|
||||
{% endfor %}
|
||||
{% endcomment %}
|
||||
</section>
|
||||
{% endif %}
|
||||
{% if object.podcasts %}
|
||||
{% spaceless %}
|
||||
<section class="container no-border">
|
||||
<h2 class="title is-2">{% translate "Podcasts" %}</h2>
|
||||
<a-playlist v-if="page" :set="podcasts"
|
||||
name="{{ page.title }}"
|
||||
list-class="menu-list" item-class="menu-item"
|
||||
:player="player" :actions="['play', 'pin']"
|
||||
@select="player.playItems('queue', $event.item)">
|
||||
</a-playlist>
|
||||
</section>
|
||||
{% endspaceless %}
|
||||
{% endif %}
|
||||
|
||||
{% if tracks %}
|
||||
<section>
|
||||
<h4 class="title is-4">{% translate "Playlist" %}</h4>
|
||||
<ol>
|
||||
{% for track in tracks %}
|
||||
<li><span>{{ track.title }}</span>
|
||||
<span class="has-text-grey-dark has-text-weight-light">
|
||||
— {{ track.artist }}
|
||||
{% if track.info %}(<i>{{ track.info }}</i>){% endif %}
|
||||
</span>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ol>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
</template></a-episode>
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<section>
|
||||
<h4 class="title is-4">{% translate "Diffusions" %}</h4>
|
||||
<ul>
|
||||
{% for diffusion in object.diffusion_set.all %}
|
||||
<li>
|
||||
{% with diffusion.start as start %}
|
||||
{% with diffusion.end as end %}
|
||||
<time datetime="{{ start }}">{{ start|date:"D. d F Y, H:i" }}</time>
|
||||
—
|
||||
<time datetime="{{ end }}">{{ end|date:"H:i" }}</time>
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
|
||||
<small>
|
||||
{% if diffusion.initial %}
|
||||
{% with diffusion.initial.date as date %}
|
||||
<span title="{% blocktranslate %}Rerun of {{ date }}{% endblocktranslate %}">
|
||||
({% translate "rerun" %})
|
||||
</span>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</small>
|
||||
<br>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</section>
|
||||
{{ block.super }}
|
||||
{% if tracks %}
|
||||
<section class="container">
|
||||
<h2 class="title is-2">{% translate "Playlist" %}</h2>
|
||||
<table class="table is-hoverable is-fullwidth">
|
||||
<thead>
|
||||
<tr>
|
||||
<th></th>
|
||||
<th>{% translate "Artist" %}</th>
|
||||
<th>{% translate "Title" %}</th>
|
||||
<th></th>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for track in tracks %}
|
||||
<tr>
|
||||
<td>{{ forloop.counter }}</td>
|
||||
<td>{{ track.artist }}</td>
|
||||
<td>{{ track.title }}</td>
|
||||
<td>{{ track.info|default:"" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</section>
|
||||
{% endif %}
|
||||
</template>
|
||||
</a-episode>
|
||||
{% endblock %}
|
||||
|
15
aircox/templates/aircox/episode_form.html
Normal file
15
aircox/templates/aircox/episode_form.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% extends "./page_form.html" %}
|
||||
{% load static i18n humanize honeypot aircox %}
|
||||
|
||||
{% block page-form %}
|
||||
<a-episode :page="{title: "{{ object.title }}", podcasts: {{ object.sounds|json }}}">
|
||||
<template v-slot="{podcasts,page}">
|
||||
{{ block.super }}
|
||||
<hr/>
|
||||
{% include "./dashboard/widgets/tracklist_editor.html" with formset=tracklist_formset formset_data=tracklist_formset_data %}
|
||||
<hr/>
|
||||
<h2 class="title is-2">{% translate "Podcasts" %}</h2>
|
||||
{% include "./dashboard/widgets/soundlist_editor.html" with formset=soundlist_formset formset_data=soundlist_formset_data %}
|
||||
</template>
|
||||
</a-episode>
|
||||
{% endblock %}
|
25
aircox/templates/aircox/forms/form_field.html
Normal file
25
aircox/templates/aircox/forms/form_field.html
Normal file
@ -0,0 +1,25 @@
|
||||
{% comment %}
|
||||
Render a form field instance as field (to be used when no model instance is provided). Value is binded as vue, class to Bulma
|
||||
|
||||
Context:
|
||||
- name: field name
|
||||
- field: form field
|
||||
- value: input ":value" attribute
|
||||
- vbind: if True, use ":value" instead of "value"
|
||||
- hidden: if True, hidden field
|
||||
{% endcomment %}
|
||||
{% load aircox %}
|
||||
|
||||
{% if field.widget.is_hidden or hidden %}
|
||||
<input type="hidden" name="{{ name }}" value="{{ value|default:"" }}">
|
||||
{% elif field|is_checkbox %}
|
||||
<input type="checkbox" class="checkbox" name="{{ name }}" {% if value %}checked{% endif %}>
|
||||
{% elif field|is_select %}
|
||||
<select name="{{ name }}" class="select" value="{{ value|default:"" }}">
|
||||
{% for value, label in field.widget.choices %}
|
||||
<option value="{{ value }}">{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="text" class="input" name="{{ name }}" value="{{ value|default:"" }}">
|
||||
{% endif %}
|
53
aircox/templates/aircox/forms/formset.html
Normal file
53
aircox/templates/aircox/forms/formset.html
Normal file
@ -0,0 +1,53 @@
|
||||
{% comment %}
|
||||
Base template for list editor based on formsets (tracklist_editor, playlist_editor).
|
||||
|
||||
Context:
|
||||
- tag_id: id of parent component
|
||||
- tag: vue component tag (a-playlist-editor, etc.)
|
||||
- related_field: field name that target object
|
||||
- object: related object
|
||||
- formset: formset used to render the list editor
|
||||
- formset_data: formset data
|
||||
{% endcomment %}
|
||||
|
||||
{% load aircox aircox_admin static i18n %}
|
||||
|
||||
{% with formset.form.base_fields as fields %}
|
||||
{% block outer %}
|
||||
<div id="{{ tag_id }}">
|
||||
{{ formset.non_form_errors }}
|
||||
<!-- formset.management_form -->
|
||||
|
||||
<{{ tag|default:"a-form-set" }} ref="formset"
|
||||
{% block tag-attrs %}
|
||||
:form-data="{{ formset_data|json }}"
|
||||
:labels="window.aircox.labels"
|
||||
:columns="[{% for n, f in fields.items %}{% if not f.widget.is_hidden %}'{{ n }}',{% endif %}{% endfor %} ]"
|
||||
settings-url="{% url "api:user-settings" %}"
|
||||
data-prefix="{{ formset.prefix }}-"
|
||||
{% endblock %}>
|
||||
{% block inner %}
|
||||
<template #rows-header-head>
|
||||
{% block rows-header-head %}
|
||||
<th style="max-width:2em" title="{{ fields.position.help_text }}"
|
||||
aria-description="{{ fields.position.help_text }}">
|
||||
<span class="icon">
|
||||
<i class="fa fa-arrow-down-1-9"></i>
|
||||
</span>
|
||||
</th>
|
||||
{% endblock %}
|
||||
</template>
|
||||
{% for name, field in fields.items %}
|
||||
{% if not field.widget.is_hidden and not field.is_readonly %}
|
||||
<template v-slot:control-{{ name }}="{context,item,cell,value,attr,emit,inputName}">
|
||||
{% block row-control %}
|
||||
{% include "./v_form_field.html" with value="item.data."|add:name name="inputName" %}
|
||||
{% endblock %}
|
||||
</template>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</{{ tag }}>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endwith %}
|
24
aircox/templates/aircox/forms/v_form_field.html
Normal file
24
aircox/templates/aircox/forms/v_form_field.html
Normal file
@ -0,0 +1,24 @@
|
||||
{% comment %}
|
||||
Render a form field instance as field (to be used when no model instance is provided). Value is binded as vue, class to Bulma
|
||||
|
||||
Context:
|
||||
- name: field name
|
||||
- field: form field
|
||||
- value: input ":v-model" attribute
|
||||
- hidden: if True, hidden field
|
||||
{% endcomment %}
|
||||
{% load aircox %}
|
||||
|
||||
{% if field.widget.is_hidden or hidden %}
|
||||
<input type="hidden" :name="{{ name }}" :value="{{ value|default:"" }}">
|
||||
{% elif field|is_checkbox %}
|
||||
<input type="checkbox" class="checkbox" :name="{{ name }}" v-model="{{ value }}">
|
||||
{% elif field|is_select %}
|
||||
<select :name="{{ name }}" class="select" v-model="{{ value|default:"" }}">
|
||||
{% for value, label in field.widget.choices %}
|
||||
<option value="{{ value }}">{{ label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
{% else %}
|
||||
<input type="text" class="input" :name="{{ name }}" v-model="{{ value|default:"" }}">
|
||||
{% endif %}
|
@ -1,85 +1,74 @@
|
||||
{% extends "aircox/page_list.html" %}
|
||||
{% comment %}Home page{% endcomment %}
|
||||
{% load i18n %}
|
||||
{% extends "./public.html" %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
|
||||
{% block head_title %}{{ station.name }}{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{% if not page or not page.title %}{{ station.name }}
|
||||
{% else %}{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block title %}{% if page %}{{ block.super }}{% endif %}{% endblock %}
|
||||
|
||||
{% block before_list %}{% endblock %}
|
||||
|
||||
{% block pages_list %}
|
||||
{% if page and page.content %}<hr/>{% endif %}
|
||||
{% block breadcrumbs-container %}{% endblock %}
|
||||
|
||||
{% block content-container %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if next_diffs %}
|
||||
<div class="columns">
|
||||
{% with render_card=True %}
|
||||
{% for object in next_diffs %}
|
||||
{% with is_primary=object.is_now %}
|
||||
<div class="column is-relative">
|
||||
<h4 class="card-super-title" title="{{ object.start }}">
|
||||
{% if is_primary %}
|
||||
<span class="fas fa-play"></span>
|
||||
<time datetime="{{ object.start }}">
|
||||
{% translate "Currently" %}
|
||||
</time>
|
||||
{% else %}
|
||||
{{ object.start|date:"H:i" }}
|
||||
{% endif %}
|
||||
<section class="container">
|
||||
<h2 class="title">
|
||||
{% with station.name as station %}
|
||||
{% blocktrans %}Today on {{ station }}{% endblocktrans %}
|
||||
{% endwith %}
|
||||
</h2>
|
||||
|
||||
{% if object.episode.category %}
|
||||
// {{ object.episode.category.title }}
|
||||
{% endif %}
|
||||
</h4>
|
||||
{% include object.item_template_name %}
|
||||
<div class="mb-3">
|
||||
{% with next_diffs.0 as obj %}
|
||||
{% page_widget "wide" obj.episode diffusion=obj timetable=True %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% endwith %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if object_list %}
|
||||
<h4 class="title is-4">{% translate "Today" %}</h4>
|
||||
<section role="list">
|
||||
{% include 'aircox/widgets/diffusion_list.html' %}
|
||||
<hr/>
|
||||
|
||||
<a-carousel section-class="card-grid">
|
||||
{% for obj in next_diffs|slice:"1:" %}
|
||||
{% if object != diffusion %}
|
||||
{% page_widget "card" obj.episode diffusion=obj timetable=True %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</a-carousel>
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block pagination %}
|
||||
<ul class="pagination-list">
|
||||
<li>
|
||||
<a href="{% url "page-list" %}" class="pagination-link"
|
||||
aria-label="{% translate "Show all publication" %}">
|
||||
{% translate "More publications..." %}
|
||||
{% if logs %}
|
||||
<section class="container">
|
||||
<h2 class="title">{% translate "It just happened" %}</h2>
|
||||
|
||||
<div class="grid" role="list">
|
||||
{% include "./widgets/logs.html" with object_list=logs %}
|
||||
</div>
|
||||
|
||||
<nav class="nav-urls">
|
||||
<a href="{% url "timetable-list" %}"
|
||||
aria-label="{% translate "Show all program's for today" %}">
|
||||
{% translate "Today" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if podcasts %}
|
||||
<section class="container">
|
||||
<h2 class="title is-3 p-2">{% translate "Last podcasts" %}</h2>
|
||||
{% include "./widgets/carousel.html" with objects=podcasts url_name="podcast-list" url_label=_("All podcasts") %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if publications %}
|
||||
<section class="container">
|
||||
<h2 class="title">{% translate "Last publications" %}</h2>
|
||||
{% include "./widgets/carousel.html" with objects=publications url_name="page-list" url_label=_("All publications") %}
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block sidebar %}
|
||||
<section>
|
||||
<h4 class="title is-4">{% translate "Previously on air" %}</h4>
|
||||
{% with has_cover=False %}
|
||||
{% with logs as object_list %}
|
||||
{% include "aircox/widgets/log_list.html" %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h4 class="title is-4">{% translate "Last publications" %}</h4>
|
||||
{% with hide_schedule=True %}
|
||||
{% with has_headline=False %}
|
||||
{% for object in last_publications %}
|
||||
{% include object.item_template_name|default:'aircox/widgets/page_item.html' %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
</section>
|
||||
{% endblock %}
|
||||
{% block pages_list %}{% endblock %}
|
||||
|
@ -1,29 +0,0 @@
|
||||
{% extends "aircox/page_list.html" %}
|
||||
{% comment %}List of logs for a specific date{% endcomment %}
|
||||
{% load i18n humanize aircox %}
|
||||
|
||||
{% block title %}
|
||||
{% if not page or not page.title %}
|
||||
{% with station.name as station %}
|
||||
{% blocktranslate %}That happened on {{ station }}{% endblocktranslate %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
|
||||
|
||||
{% block before_list %}
|
||||
{% with "log-list" as url_name %}
|
||||
{% include "aircox/widgets/dates_menu.html" %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
{% block pages_list %}
|
||||
<section>
|
||||
{# <h4 class="subtitle size-4">{{ date }}</h4> #}
|
||||
{% include "aircox/widgets/log_list.html" %}
|
||||
</section>
|
||||
{% endblock %}
|
@ -1,4 +1,4 @@
|
||||
{% extends "aircox/basepage_detail.html" %}
|
||||
{% extends "aircox/public.html" %}
|
||||
{% load static i18n humanize honeypot aircox %}
|
||||
{% comment %}
|
||||
Base template used to display a Page
|
||||
@ -6,83 +6,88 @@ Base template used to display a Page
|
||||
Context:
|
||||
- page: page
|
||||
- parent: parent page
|
||||
- related_objects: list of object to display as related publications
|
||||
- related_url: url to the full list of related_objects
|
||||
{% endcomment %}
|
||||
|
||||
{% block header_crumbs %}
|
||||
{{ block.super }}
|
||||
{% if page.category %}
|
||||
{% if parent %} / {% endif %} {{ page.category.title }}
|
||||
{% block breadcrumbs %}
|
||||
{% if parent %}
|
||||
{% include "./widgets/breadcrumbs.html" with page=parent %}
|
||||
{% if page %}
|
||||
<a href="{% url page.list_url_name parent_slug=parent.slug %}">
|
||||
{{ page|verbose_name:True }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% elif page %}
|
||||
{% include "./widgets/breadcrumbs.html" with page=page no_title=True %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block top-nav-tools %}
|
||||
{% has_perm page "change" as can_edit %}
|
||||
{% if can_edit %}
|
||||
<a class="navbar-item" href="{{ page|admin_url:'change' }}"
|
||||
target="new">
|
||||
<span class="icon is-small">
|
||||
<i class="fa fa-pen"></i>
|
||||
</span>
|
||||
<span>{% translate "Edit" %}</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% block title-container %}
|
||||
{{ block.super }}
|
||||
{% block page-actions %}
|
||||
{% include "aircox/widgets/page_actions.html" %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ block.super }}
|
||||
|
||||
{% block related %}
|
||||
{% if related_objects %}
|
||||
<section class="container">
|
||||
{% with models=object|verbose_name:True %}
|
||||
<h2 class="title is-2">{% blocktranslate %}Related {{models}}{% endblocktranslate %}</h2>
|
||||
|
||||
{% include "./widgets/carousel.html" with objects=related_objects url_name=object.list_url_name url_category=object.category %}
|
||||
{% endwith %}
|
||||
</section>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block comments %}
|
||||
{% if comments or comment_form %}
|
||||
<section class="mt-6">
|
||||
<h4 class="title is-4">{% translate "Comments" %}</h4>
|
||||
{% if comments %}
|
||||
<section class="container">
|
||||
<h2 class="title is-2">{% translate "Comments" %}</h2>
|
||||
|
||||
{% for comment in comments %}
|
||||
<div class="media box">
|
||||
<div class="media-content">
|
||||
<p>
|
||||
<strong class="mr-2">{{ comment.nickname }}</strong>
|
||||
<time datetime="{{ comment.date }}" title="{{ comment.date }}">
|
||||
<small>{{ comment.date|naturaltime }}</small>
|
||||
</time>
|
||||
<br>
|
||||
{{ comment.content }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
{% for object in comments %}
|
||||
{% page_widget "item" object %}
|
||||
{% endfor %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if comment_form %}
|
||||
{% if comment_form %}
|
||||
<section class="container">
|
||||
<h2 class="title is-2">{% translate "Post a comment" %}</h2>
|
||||
<form method="POST">
|
||||
<h5 class="title is-5">{% translate "Post a comment" %}</h5>
|
||||
{% csrf_token %}
|
||||
{% render_honeypot_field "website" %}
|
||||
|
||||
{% for field in comment_form %}
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label is-normal">
|
||||
<label class="label">
|
||||
{{ field.label_tag }}
|
||||
</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<p class="control is-expanded">{{ field }}</p>
|
||||
{% if field.errors %}
|
||||
<p class="help is-danger">{{ field.errors }}</p>
|
||||
{% endif %}
|
||||
{% if field.help_text %}
|
||||
<p class="help">{{ field.help_text|safe }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="field">
|
||||
<div class="control">
|
||||
{{ comment_form.content }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% for field in comment_form %}
|
||||
{% if field.name != "content" %}
|
||||
<div class="field is-horizontal">
|
||||
<label class="label">{{ field.label }}</label>
|
||||
<div class="control">{{ field }}</div>
|
||||
</div>
|
||||
{% if field.errors %}
|
||||
<p class="help is-danger">{{ field.errors }}</p>
|
||||
{% endif %}
|
||||
{% if field.help_text %}
|
||||
<p class="help">{{ field.help_text|safe }}</p>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<div class="has-text-right">
|
||||
<button type="reset" class="button is-danger">{% translate "Reset" %}</button>
|
||||
<button type="submit" class="button is-success">{% translate "Post comment" %}</button>
|
||||
<button type="submit" class="button">{% translate "Post comment" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
|
129
aircox/templates/aircox/page_form.html
Normal file
129
aircox/templates/aircox/page_form.html
Normal file
@ -0,0 +1,129 @@
|
||||
{% extends "./dashboard/base.html" %}
|
||||
{% load static aircox aircox_admin i18n %}
|
||||
|
||||
{% block init-scripts %}
|
||||
aircox.labels = {% inline_labels %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
|
||||
{% block header-cover %}{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{% if not object %}
|
||||
{% with view.model|verbose_name as model %}
|
||||
{% blocktranslate %}Create a {{model}}{% endblocktranslate %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content-container %}
|
||||
<a-select-file ref="cover-select"
|
||||
:labels="window.aircox.labels"
|
||||
list-url="{% url "api:image-list" %}"
|
||||
upload-url="{% url "api:image-list" %}"
|
||||
delete-url="{% url "api:image-detail" pk=123 %}"
|
||||
title="{% translate "Select an image" %}" list-class="grid-4"
|
||||
@select="(event) => fileSelected('cover-select', 'cover-input', $refs.cover)"
|
||||
>
|
||||
<template #upload-preview="{upload}">
|
||||
<img :src="upload.fileURL" class="upload-preview blink"/>
|
||||
</template>
|
||||
<template #default="{item, load, lastUrl}">
|
||||
<div class="flex-column is-fullheight" v-if="item">
|
||||
<figure class="flex-grow-1">
|
||||
<img :src="item.file"/>
|
||||
</figure>
|
||||
<div>
|
||||
<label class="label small">[[ item.name || item.original_filename ]]</label>
|
||||
<a-action-button
|
||||
class="has-text-danger small float-right"
|
||||
icon="fa fa-trash"
|
||||
confirm="{% translate "Are you sure you want to remove this item from server?" %}"
|
||||
method="DELETE"
|
||||
:url="'{% url "api:image-detail" pk="123" %}'.replace('123', item.id)"
|
||||
@done="load(lastUrl)">
|
||||
</a-action-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</a-select-file>
|
||||
|
||||
<section class="container">
|
||||
<form method="post" enctype="multipart/form-data">
|
||||
{% block page-form %}
|
||||
{% csrf_token %}
|
||||
<div class="flex-row">
|
||||
<div class="flex-grow-3">
|
||||
{% for field in form %}
|
||||
{% if field.name not in "cover,content" %}
|
||||
<div class="field {% if field.name != "content" %}is-horizontal{% endif %}">
|
||||
<label class="label">{{ field.label }}</label>
|
||||
<div class="control clear-unset">
|
||||
{% if field.name == "pub_date" %}
|
||||
<input type="datetime-local" class="input" name="{{ field.name }}"
|
||||
value="{{ field.value|date:"Y-m-d" }}T{{ field.value|date:"H:i" }}"/>
|
||||
{% else %}
|
||||
{% include "aircox/forms/form_field.html" with field=field.field name=field.name value=field.initial %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<p class="help">{{ field.help_text }}</p>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if field.errors %}
|
||||
<p class="help is-danger">{{ field.errors }}</p>
|
||||
{% endif %}
|
||||
{% if field.help_text %}
|
||||
<p class="help">{{ field.help_text|safe }}</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
{% with form.cover as field %}
|
||||
{% block page-form-cover %}
|
||||
<input type="hidden" name="{{ field.name }}" value="{{ field.value }}" ref="cover-input"/>
|
||||
{% spaceless %}
|
||||
<figure class="header-cover">
|
||||
<img src="{{ cover }}" ref="cover" class="cover">
|
||||
<button type="button" class="button" @click="$refs['cover-select'].open()">
|
||||
{% translate "Change cover" %}
|
||||
</button>
|
||||
</figure>
|
||||
{% endspaceless %}
|
||||
{% endblock %}
|
||||
{% endwith %}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% with form.content as field %}
|
||||
{% block page-form-content %}
|
||||
<div>
|
||||
<div class="field {% if field.name != "content" %}is-horizontal{% endif %}">
|
||||
<label class="label">{{ field.label }}</label>
|
||||
<div class="control clear-unset">
|
||||
<textarea name="{{ field.name }}" class="is-fullwidth height-25">{{ field.value|default:""|striptags|safe }}</textarea>
|
||||
</div>
|
||||
<p class="help">{{ field.help_text }}</p>
|
||||
</div>
|
||||
{% if field.errors %}
|
||||
<p class="help is-danger">{{ field.errors }}</p>
|
||||
{% endif %}
|
||||
{% if field.help_text %}
|
||||
<p class="help">{{ field.help_text|safe }}</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% endwith %}
|
||||
|
||||
{% endblock %}
|
||||
<hr/>
|
||||
<div class="flex-row">
|
||||
<div class="flex-grow-1">{% block page-form-actions %}{% endblock %}</div>
|
||||
<div class="has-text-right">
|
||||
<button type="submit" class="button">{% translate "Update" %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</section>
|
||||
{% endblock %}
|
@ -2,61 +2,60 @@
|
||||
{% comment %}Display a list of Pages{% endcomment %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block before_list %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if view.has_filters and object_list %}
|
||||
<form method="GET" action="" class="media">
|
||||
<div class="media-content">
|
||||
{% block filters %}
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">{% translate "Search" %}</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field">
|
||||
<div class="control has-icons-left">
|
||||
<span class="icon is-small is-left">
|
||||
<i class="fa fa-search"></i>
|
||||
</span>
|
||||
<input class="input" type="text" name="q"
|
||||
value="{{ filterset_data.q }}"
|
||||
placeholder="{% translate "Search content" %}">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="field is-horizontal">
|
||||
<div class="field-label">
|
||||
<label class="label">{% translate "Categories" %}</label>
|
||||
</div>
|
||||
<div class="field-body">
|
||||
<div class="field is-narrow">
|
||||
<div class="control">
|
||||
{% for label, value in categories %}
|
||||
<label class="checkbox">
|
||||
<input type="checkbox" class="checkbox" name="category__id__in"
|
||||
value="{{ value }}"
|
||||
{% if value in filterset_data.category__id__in %}checked{% endif %} />
|
||||
{{ label }}
|
||||
</label>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
{% block secondary-nav %}
|
||||
{% if not parent and categories %}
|
||||
<nav class="nav secondary">
|
||||
<div class="nav-menu nav-categories">
|
||||
{% for cat in categories %}
|
||||
<a class="nav-item{% if cat == category %} active{% endif %}"
|
||||
href="{% url request.resolver_match.url_name category_slug=cat.slug %}">
|
||||
{{ cat.title }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div class="media-right">
|
||||
<div class="field is-grouped is-grouped-right">
|
||||
<div class="control">
|
||||
<button class="button is-primary"/>{% translate "Apply" %}</button>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a href="?" class="button is-secondary">{% translate "Reset" %}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<a-switch class="button burger"
|
||||
el=".nav-categories" group="nav" icon="fas fa-tags"
|
||||
aria-label="{% translate "Categories" %}">
|
||||
</a-switch>
|
||||
</nav>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block title %}
|
||||
{% if parent %}{{ parent.title }}
|
||||
{% else %}{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}
|
||||
{% if page and not object %}
|
||||
{% with page as object %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{% if parent and model.list_url_name %}
|
||||
{% include "./widgets/breadcrumbs.html" with page=parent %}
|
||||
<a href="{% url model.list_url_name %}">{{ model|verbose_name:True }}</a>
|
||||
{% elif page and model.list_url_name %}
|
||||
<a href="{% url model.list_url_name %}">{{ page.title }}</a>
|
||||
{% if category %}
|
||||
<a href="{% url request.resolver_match.url_name category_slug=category.slug %}">
|
||||
{{ category.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<a href="{% url request.resolver_match.url_name %}">{{ model|verbose_name:True }}</a>
|
||||
{% if category %}
|
||||
<a href="{% url request.resolver_match.url_name category_slug=category.slug %}">
|
||||
{{ category.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block content-container %}{% endblock %}
|
||||
|
@ -1,67 +1,53 @@
|
||||
{% extends "aircox/page_detail.html" %}
|
||||
{% comment %}Detail page of a show{% endcomment %}
|
||||
{% load i18n %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% include "aircox/program_sidebar.html" %}
|
||||
|
||||
|
||||
{% block header_nav %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
{{ block.super }}
|
||||
<br>
|
||||
{% with has_headline=False %}
|
||||
{% if articles %}
|
||||
<section>
|
||||
<h4 class="title is-4">{% translate "Articles" %}</h4>
|
||||
|
||||
{% for object in articles %}
|
||||
{% include "aircox/widgets/page_item.html" %}
|
||||
{% block content-container %}
|
||||
{% with schedules=object.schedule_set.all %}
|
||||
{% if schedules %}
|
||||
<header class="container schedules">
|
||||
{% for schedule in schedules %}
|
||||
<div class="schedule">
|
||||
<div class="heading">
|
||||
<span class="day">{{ schedule.get_frequency_display }}</span>
|
||||
{% with schedule.start|date:"H:i" as start %}
|
||||
{% with schedule.end|date:"H:i" as end %}
|
||||
<time datetime="{{ start }}">{{ start }}</time>
|
||||
—
|
||||
<time datetime="{{ end }}">{{ end }}</time>
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
<small>
|
||||
{% if schedule.is_rerun %}
|
||||
{% with schedule.initial.date as date %}
|
||||
<span title="{% blocktranslate %}Rerun of {{ date }}{% endblocktranslate %}">
|
||||
({% translate "Rerun" %})
|
||||
</span>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</small>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<br>
|
||||
<nav class="pagination is-centered">
|
||||
<ul class="pagination-list">
|
||||
<li>
|
||||
<a href="{% url "article-list" parent_slug=program.slug %}"
|
||||
class="pagination-link"
|
||||
aria-label="{% translate "Show all program's articles" %}">
|
||||
{% translate "More articles" %}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</section>
|
||||
</header>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
|
||||
{% endblock %}
|
||||
|
||||
{% block sidebar %}
|
||||
<section>
|
||||
<h4 class="title is-4">{% translate "Diffusions" %}</h4>
|
||||
{% for schedule in program.schedule_set.all %}
|
||||
{{ schedule.get_frequency_display }}
|
||||
{% with schedule.start|date:"H:i" as start %}
|
||||
{% with schedule.end|date:"H:i" as end %}
|
||||
<time datetime="{{ start }}">{{ start }}</time>
|
||||
—
|
||||
<time datetime="{{ end }}">{{ end }}</time>
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
<small>
|
||||
{% if schedule.initial %}
|
||||
{% with schedule.initial.date as date %}
|
||||
<span title="{% blocktranslate %}Rerun of {{ date }}{% endblocktranslate %}">
|
||||
({% translate "Rerun" %})
|
||||
</span>
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
</small>
|
||||
<br>
|
||||
{% endfor %}
|
||||
</section>
|
||||
{{ block.super }}
|
||||
|
||||
{% if episodes %}
|
||||
<section class="container">
|
||||
<h2 class="title is-2">{% translate "Last Episodes" %}</h2>
|
||||
{% include "./widgets/carousel.html" with objects=episodes url_name="episode-list" url_parent=object url_label=_("All episodes") %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
|
||||
{% if articles %}
|
||||
<section class="container">
|
||||
<h2 class="title is-2">{% translate "Last Articles" %}</h2>
|
||||
{% include "./widgets/carousel.html" with objects=articles url_name="article-list" url_parent=object url_label=_("All articles") %}
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
26
aircox/templates/aircox/program_form.html
Normal file
26
aircox/templates/aircox/program_form.html
Normal file
@ -0,0 +1,26 @@
|
||||
{% extends "./page_form.html" %}
|
||||
{% load static i18n humanize honeypot aircox %}
|
||||
|
||||
|
||||
{% block head_extra %}
|
||||
{{ form.media }}
|
||||
{% endblock %}
|
||||
|
||||
{% block page-form-actions %}
|
||||
{% if object and object.pk and request.user.is_superuser %}
|
||||
<button type="button"
|
||||
class="button secondary"
|
||||
@click="$refs['group-users-modal'].open({id: {{ object.editors_group_id }}, name: '{{ object.editors_group.name }}' })">{% translate "Editors" %}</button>
|
||||
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block main %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if object and object.pk and request.user.is_superuser %}
|
||||
{% include "./dashboard/widgets/group_users.html" %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -1,6 +0,0 @@
|
||||
|
||||
{% block sidebar_title %}
|
||||
{% with program.title as program %}
|
||||
{% blocktranslate %}Recently on {{ program }}{% endblocktranslate %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
18
aircox/templates/aircox/public.html
Normal file
18
aircox/templates/aircox/public.html
Normal file
@ -0,0 +1,18 @@
|
||||
{% extends "./base.html" %}
|
||||
|
||||
|
||||
{% comment %}
|
||||
Override is a trick here: it allows to change title at two different different
|
||||
places inside the page: inside `<title>` tag, and inside the page
|
||||
content.
|
||||
{% endcomment %}
|
||||
|
||||
{% block head-title %}
|
||||
{% block title %}
|
||||
{% if page and page.title %}{{ page.title }}{% endif %}
|
||||
{% endblock %}
|
||||
{% if page and page.title %}—{% endif %}
|
||||
{{ station.name }}
|
||||
{% endblock %}
|
||||
|
||||
{% block header %}{% if page %}{{ block.super }}{% endif %}{% endblock %}
|
28
aircox/templates/aircox/timetable_list.html
Normal file
28
aircox/templates/aircox/timetable_list.html
Normal file
@ -0,0 +1,28 @@
|
||||
{% extends "aircox/page_list.html" %}
|
||||
{% comment %}List of diffusions as a timetable{% endcomment %}
|
||||
{% load i18n aircox humanize %}
|
||||
|
||||
{% block subtitle %}{{ date|date:"l d F Y" }}{% endblock %}
|
||||
|
||||
{% block secondary-nav %}
|
||||
<nav class="nav secondary">
|
||||
{% include "./widgets/dates_menu.html" with url_name=view.redirect_date_url %}
|
||||
</nav>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block breadcrumbs %}
|
||||
{{ block.super }}
|
||||
<a href="{% url "timetable-list" date=date %}">{{ date|date:"l d F Y" }}</a>
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block list-container %}
|
||||
{% with list_class="grid" %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
{% block list %}
|
||||
{% include "./widgets/logs.html" with object_list=object_list timetable=True %}
|
||||
{% endblock %}
|
4
aircox/templates/aircox/widgets/article.html
Normal file
4
aircox/templates/aircox/widgets/article.html
Normal file
@ -0,0 +1,4 @@
|
||||
{% extends "./page.html" %}
|
||||
{% load humanize %}
|
||||
|
||||
{% block subtitle %}{{ object.pub_date.date }}{% endblock %}
|
4
aircox/templates/aircox/widgets/autocomplete.html
Normal file
4
aircox/templates/aircox/widgets/autocomplete.html
Normal file
@ -0,0 +1,4 @@
|
||||
<a-autocomplete
|
||||
url="{{url}}"
|
||||
{% if ":name" not in widget.attrs %}name="{{ name|default:widget.name }}"{% endif %}{% if widget.value != None %} model-value="{{ widget.value|stringformat:'s' }}"{% endif %}
|
||||
{% include "django/forms/widgets/attrs.html" %} {{ extra|default:"" }}/>
|
@ -11,63 +11,48 @@ Context variables:
|
||||
- is_thin (=False): if True, smaller cover and display less info
|
||||
{% endcomment %}
|
||||
|
||||
{% if render_card %}
|
||||
<article class="card {% if is_primary %}is-primary{% endif %}">
|
||||
<header class="card-image">
|
||||
<a href="{{ object.get_absolute_url }}">
|
||||
<figure class="image is-4by3">
|
||||
<img src="{% thumbnail object.cover|default:station.default_cover 480x480 %}">
|
||||
</figure>
|
||||
</a>
|
||||
{% block outer %}
|
||||
<article class="preview preview-item{% if is_primary %}is-primary{% endif %}{% block card_class %}{% endblock %}">
|
||||
{% block inner %}
|
||||
<header class="headings"
|
||||
style="background-image: url({{ object.cover.url }})">
|
||||
{% block headings %}
|
||||
<div>
|
||||
<span class="heading subtitle">{% block subtitle %}{% endblock %}</span>
|
||||
</div>
|
||||
{% endblock %}
|
||||
</header>
|
||||
<div class="card-header">
|
||||
<h4 class="title">
|
||||
<a href="{{ object.get_absolute_url }}">
|
||||
{% block card_title %}{{ object.title }}{% endblock %}
|
||||
</a>
|
||||
</h4>
|
||||
</div>
|
||||
</article>
|
||||
|
||||
<div class="">
|
||||
<div>
|
||||
<h2 class="heading title">{% block title %}{% endblock %}</h2>
|
||||
</div>
|
||||
|
||||
{% else %}
|
||||
<article class="media item {% block css %}{% endblock%}">
|
||||
{% if has_cover|default_if_none:True %}
|
||||
<div class="media-left">
|
||||
{% if is_thin %}
|
||||
<img src="{% thumbnail object.cover|default:station.default_cover 64x64 crop=scale %}"
|
||||
class="cover is-tiny">
|
||||
{% else %}
|
||||
<img src="{% thumbnail object.cover|default:station.default_cover 128x128 crop=scale %}"
|
||||
class="cover is-small">
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="media-content">
|
||||
<h5 class="title is-5 has-text-weight-normal">
|
||||
{% block title %}
|
||||
{% if object.is_published %}
|
||||
<a href="{{ object.get_absolute_url }}">{{ object.title }}</a>
|
||||
{% else %}
|
||||
{{ object.title }}
|
||||
<summary class="heading-container">
|
||||
{% block content %}
|
||||
{% if content and with_content %}
|
||||
{% autoescape off %}
|
||||
{{ content|striptags|truncatewords:64|linebreaks }}
|
||||
{% endautoescape %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</h5>
|
||||
<div class="subtitle is-6 has-text-weight-light">
|
||||
{% block subtitle %}
|
||||
{% if object.category %}{{ object.category.title }}{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</summary>
|
||||
|
||||
{% if has_headline|default_if_none:True %}
|
||||
<div class="headline">
|
||||
{% block headline %}{{ object.headline }}{% endblock %}
|
||||
<div class="actions">
|
||||
{% block actions %}
|
||||
<a class="button float-right" href="{{ object.get_absolute_url|escape }}">
|
||||
<span class="icon">
|
||||
<i class="fas fa-external-link"></i>
|
||||
</span>
|
||||
<label>{% translate "More infos" %}</label>
|
||||
</a>
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% if not no_actions %}
|
||||
{% block actions %}{% endblock %}
|
||||
{% if with_container %}
|
||||
</div>
|
||||
{% endif %}
|
||||
</article>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
15
aircox/templates/aircox/widgets/breadcrumbs.html
Normal file
15
aircox/templates/aircox/widgets/breadcrumbs.html
Normal file
@ -0,0 +1,15 @@
|
||||
{% load aircox %}
|
||||
|
||||
<a href="{% url page.list_url_name %}">
|
||||
{{ page|verbose_name:True }}
|
||||
</a>
|
||||
{% if page.category and not no_cat %}
|
||||
<a href="{% url page.list_url_name category_slug=page.category.slug %}">
|
||||
{{ page.category.title }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if not no_title %}
|
||||
<a href="{{ page.get_absolute_url }}">
|
||||
{{ page.title|truncatechars:24 }}
|
||||
</a>
|
||||
{% endif %}
|
23
aircox/templates/aircox/widgets/card.html
Normal file
23
aircox/templates/aircox/widgets/card.html
Normal file
@ -0,0 +1,23 @@
|
||||
{% extends "./preview.html" %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block tag-class %}{{ block.super }} preview-card{% endblock %}
|
||||
|
||||
{% block inner %}
|
||||
<div class="card-content">
|
||||
{% if cover %}
|
||||
{% if url %}<a href="{{ url }}">{% endif %}
|
||||
<figure style="background-image: url({{ cover }});" class="preview-cover">
|
||||
<img src="{{ cover }}" class="hide">
|
||||
</figure>
|
||||
{% if url %}</a>{% endif %}
|
||||
{% endif %}
|
||||
|
||||
<footer class="actions">
|
||||
{% block actions %}{{ block.super }}{% endblock %}
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
{% block headings-container %}{{ block.super }}{% endblock %}
|
||||
|
||||
{% endblock %}
|
28
aircox/templates/aircox/widgets/carousel.html
Normal file
28
aircox/templates/aircox/widgets/carousel.html
Normal file
@ -0,0 +1,28 @@
|
||||
{% load aircox %}
|
||||
{% comment %}
|
||||
Context:
|
||||
- objects: list of objects to display
|
||||
- url_name: url name to show the full list
|
||||
- url_parent: parent page for the full list
|
||||
- url_label: label of url button
|
||||
{% endcomment %}
|
||||
|
||||
<a-carousel>
|
||||
{% for object in objects %}
|
||||
{% page_widget "card" object %}
|
||||
{% endfor %}
|
||||
</a-carousel>
|
||||
|
||||
{% if url_name %}
|
||||
<nav class="nav-urls">
|
||||
{% if url_parent %}
|
||||
<a href="{% url url_name parent_slug=url_parent.slug %}">
|
||||
{% elif url_category %}
|
||||
<a href="{% url url_name category_slug=url_category.slug %}">
|
||||
{% else %}
|
||||
<a href="{% url url_name %}">
|
||||
{% endif %}
|
||||
{{ url_label|default:_("Show all") }}
|
||||
</a>
|
||||
</nav>
|
||||
{% endif %}
|
55
aircox/templates/aircox/widgets/comment.html
Normal file
55
aircox/templates/aircox/widgets/comment.html
Normal file
@ -0,0 +1,55 @@
|
||||
{% extends "./page.html" %}
|
||||
{% load i18n humanize aircox %}
|
||||
|
||||
{% block tag-class %}{{ block.super }} comment{% endblock %}
|
||||
|
||||
{% block outer %}
|
||||
{% with url=object.get_absolute_url %}
|
||||
{% if with_title %}
|
||||
{{ block.super }}
|
||||
{{ block.super }}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block title %}
|
||||
{{ object.nickname }} — {{ object.date }}
|
||||
{% endblock %}
|
||||
|
||||
{% block subtitle %}
|
||||
{% if with_title %}
|
||||
{{ object.parent.title }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}{{ object.content }}{% endblock %}
|
||||
|
||||
{% block actions %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if admin %}
|
||||
{% if user.is_staff %}
|
||||
<a href="{% url "admin:aircox_comment_change" object.pk %}" class="button"
|
||||
title="{% trans "Edit comment" %}"
|
||||
aria-label="{% trans "Edit comment" %}">
|
||||
<span class="fa fa-edit"></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
<a-action-button class="button is-danger"
|
||||
title="{% trans "Delete comment" %}"
|
||||
aria-label="{% trans "Delete comment" %}"
|
||||
url="{% url "api:comment-detail" object.pk %}"
|
||||
icon="fa fa-trash-alt"
|
||||
method="delete"
|
||||
confirm="{% translate "Delete comment?" %}"
|
||||
@done="deleteElements('#{{ object|object_id }}')"
|
||||
/>
|
||||
|
||||
{# <a href="mailto:{{ object.email }}">{{ object.nickname }}</a> #}
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -11,36 +11,33 @@ An empty date results to a title or a separator
|
||||
{% endcomment %}
|
||||
{% load i18n %}
|
||||
|
||||
<div class="media" role="menu"
|
||||
aria-label="{% translate "pick a date" %}">
|
||||
<div class="media-content">
|
||||
<div class="tabs is-toggle">
|
||||
<ul>
|
||||
{% for day in dates %}
|
||||
<li class="{% if day == date %}is-active{% endif %}">
|
||||
<a href="{% url url_name date=day %}">
|
||||
{{ day|date:"D. d" }}
|
||||
</a>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<a-switch class="button burger"
|
||||
el=".nav-dates" icon="far fa-calendar" group="nav"
|
||||
aria-label="{% translate "Dates" %}">
|
||||
</a-switch>
|
||||
|
||||
<div class="media-right">
|
||||
<form action="{% url url_name %}" method="GET" class="navbar-body"
|
||||
aria-label="{% translate "Jump to date" %}">
|
||||
<div class="field has-addons">
|
||||
<div class="control has-icons-left">
|
||||
<span class="icon is-small is-left"><span class="far fa-calendar"></span></span>
|
||||
<input type="{{ date_input|default:"date" }}" class="input date"
|
||||
name="date" value="{{ date|date:"Y-m-d" }}">
|
||||
</div>
|
||||
<div class="control">
|
||||
{% comment %}Translators: form button to select a date{% endcomment %}
|
||||
<button class="button is-primary">{% translate "Go" %}</button>
|
||||
<div class="nav-menu nav-dates">
|
||||
{% for day in dates %}
|
||||
<a href="{% url url_name date=day %}" class="nav-item {% if day == date %}active{% endif %}">
|
||||
{{ day|date:"l d" }}
|
||||
</a>
|
||||
{% endfor %}
|
||||
|
||||
<a-dropdown class="nav-item align-right flex-grow-0 dropdown is-right"
|
||||
content-class="dropdown-menu"
|
||||
button-tag="span" button-class="dropdown-trigger"
|
||||
button-icon-open="fa-solid fa-plus" button-icon-close="fa-solid fa-minus">
|
||||
<template #default>
|
||||
<div class="dropdown-content">
|
||||
<div class="dropdown-item">
|
||||
<h4>{% translate "Pick a date" %}</h4>
|
||||
<v-calendar mode="date" borderless
|
||||
:initial-page="{month: {{date.month}}, year: {{date.year}}}"
|
||||
@dayclick="(event) => window.aircox.pickDate({% url url_name %}, event)"
|
||||
color="yellow"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</div>
|
||||
|
@ -3,19 +3,4 @@ Context:
|
||||
- object_list: object list
|
||||
- date: date for list
|
||||
{% endcomment %}
|
||||
<table id="timetable{% if date %}-{{ date|date:"Y-m-d" }}{% endif %}" class="timetable">
|
||||
{% for diffusion in object_list %}
|
||||
<tr class="{% if diffusion.is_now %}has-background-primary{% endif %}">
|
||||
<td class="pr-2 pb-2">
|
||||
<time datetime="{{ diffusion.start|date:"c" }}">
|
||||
{{ diffusion.start|date:"H:i" }} - {{ diffusion.end|date:"H:i" }}
|
||||
</time>
|
||||
</td>
|
||||
<td class="pb-2">
|
||||
{% with diffusion.episode as object %}
|
||||
{% include "aircox/widgets/episode_item.html" %}
|
||||
{% endwith %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% load aircox %}
|
||||
|
26
aircox/templates/aircox/widgets/diffusion_tags.html
Normal file
26
aircox/templates/aircox/widgets/diffusion_tags.html
Normal file
@ -0,0 +1,26 @@
|
||||
{% comment %}
|
||||
Context:
|
||||
- object: diffusion
|
||||
{% endcomment %}
|
||||
{% load i18n %}
|
||||
{% if object.type == object.TYPE_ON_AIR %}
|
||||
<span class="tag is-info">
|
||||
<span class="icon is-small">
|
||||
{% if object.is_live %}
|
||||
<i class="fa fa-microphone"
|
||||
title="{% translate "Live diffusion" %}"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-music"
|
||||
title="{% translate "Differed diffusion" %}"></i>
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
{{ object.get_type_display }}
|
||||
</span>
|
||||
{% elif object.type == object.TYPE_CANCEL %}
|
||||
<span class="tag is-danger">
|
||||
{{ object.get_type_display }}</span>
|
||||
{% elif object.type == object.TYPE_UNCONFIRMED %}
|
||||
<span class="tag is-warning">
|
||||
{{ object.get_type_display }}</span>
|
||||
{% endif %}
|
71
aircox/templates/aircox/widgets/episode.html
Normal file
71
aircox/templates/aircox/widgets/episode.html
Normal file
@ -0,0 +1,71 @@
|
||||
{% extends "./page.html" %}
|
||||
{% load i18n humanize aircox %}
|
||||
|
||||
{% block outer %}
|
||||
{% with diffusion.is_now as is_active %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
{% block subtitle %}
|
||||
{% if diffusion %}
|
||||
{% if timetable %}
|
||||
{{ diffusion.start|date:"H:i" }}
|
||||
—
|
||||
{{ diffusion.end|date:"H:i" }}
|
||||
{% else %}
|
||||
{{ diffusion.start|naturalday }},
|
||||
{{ diffusion.start|date:"H:i" }}
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block actions-container %}
|
||||
{% if admin and diffusion %}
|
||||
<div class="flex-row">
|
||||
<div class="flex-grow-1">
|
||||
{% if diffusion.type == diffusion.TYPE_ON_AIR %}
|
||||
<span class="tag is-info">
|
||||
<span class="icon is-small">
|
||||
{% if diffusion.is_live %}
|
||||
<i class="fa fa-microphone"
|
||||
title="{% translate "Live diffusion" %}"></i>
|
||||
{% else %}
|
||||
<i class="fa fa-music"
|
||||
title="{% translate "Differed diffusion" %}"></i>
|
||||
{% endif %}
|
||||
</span>
|
||||
|
||||
{{ diffusion.get_type_display }}
|
||||
</span>
|
||||
{% elif diffusion.type == diffusion.TYPE_CANCEL %}
|
||||
<span class="tag is-danger">
|
||||
{{ diffusion.get_type_display }}</span>
|
||||
{% elif diffusion.type == diffusion.TYPE_UNCONFIRMED %}
|
||||
<span class="tag is-warning">
|
||||
{{ diffusion.get_type_display }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{{ block.super }}
|
||||
</div>
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block actions %}
|
||||
{{ block.super }}
|
||||
{% if object.sound_set.count %}
|
||||
<button class="button action" @click="player.playButtonClick($event)"
|
||||
data-sounds="{{ object.podcasts|json }}">
|
||||
<span class="icon is-small">
|
||||
<span class="fas fa-play"></span>
|
||||
</span>
|
||||
<label>{% translate "Listen" %}</label>
|
||||
</button>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
@ -1,58 +1,36 @@
|
||||
{% extends "aircox/widgets/page_item.html" %}
|
||||
{% comment %}
|
||||
List item for an episode.
|
||||
|
||||
Context variables:
|
||||
- object: episode
|
||||
- diffusion: episode's diffusion
|
||||
- hide_schedule: if True, do not display start time
|
||||
{% endcomment %}
|
||||
|
||||
{% load i18n easy_thumbnails_tags aircox %}
|
||||
{% extends "./basepage_item.html" %}
|
||||
{% load i18n humanize %}
|
||||
|
||||
{% block title %}
|
||||
{% if not object.is_published and object.program.is_published %}
|
||||
<a href="{{ object.program.get_absolute_url }}">
|
||||
{{ object.program.title }}
|
||||
{% if diffusion %}
|
||||
—
|
||||
{{ diffusion.start|date:"d F" }}
|
||||
{% endif %}
|
||||
</a>
|
||||
<a href="{{ object.program.get_absolute_url }}">
|
||||
{{ object.program.title }}
|
||||
</a>
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block class %}
|
||||
{% if object.is_now %}is-active{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block subtitle %}
|
||||
{{ block.super }}
|
||||
|
||||
{% if diffusion %}
|
||||
{% if not hide_schedule %}
|
||||
{% if object.category %}—{% endif %}
|
||||
<time datetime="{{ diffusion.start|date:"c" }}" title="{{ diffusion.start }}">
|
||||
{{ diffusion.start|date:"d M, H:i" }}
|
||||
</time>
|
||||
{% endif %}
|
||||
{{ diffusion.start|naturalday }},
|
||||
{{ diffusion.start|date:"g:i" }}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% if diffusion.initial %}
|
||||
{% with diffusion.initial.date as date %}
|
||||
<span title="{% blocktranslate %}Rerun of {{ date }}{% endblocktranslate %}">
|
||||
{% translate "(rerun)" %}
|
||||
</span>
|
||||
|
||||
{% block content %}
|
||||
{% if not object.content %}
|
||||
{% with object.parent.content as content %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block actions %}
|
||||
{% if object.sound_set.public.count %}
|
||||
<button class="button" @click="player.playButtonClick($event)"
|
||||
data-sounds="{{ object.podcasts|json }}">
|
||||
<span class="icon is-small">
|
||||
<span class="fas fa-play"></span>
|
||||
</span>
|
||||
</button>
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
34
aircox/templates/aircox/widgets/item.html
Normal file
34
aircox/templates/aircox/widgets/item.html
Normal file
@ -0,0 +1,34 @@
|
||||
{% extends "./preview.html" %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block tag-class %}{{ block.super }} list-item is-fullwidth{% endblock %}
|
||||
|
||||
{% block headings %}
|
||||
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}">
|
||||
{% block title %}{{ title|default:"" }}{% endblock %}
|
||||
</a>
|
||||
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">
|
||||
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block inner %}
|
||||
{% block headings-container %}{{ block.super }}{% endblock %}
|
||||
{% block content-container %}
|
||||
<div class="media">
|
||||
{% if object.cover and not no_cover %}
|
||||
<a href="{{ object.get_absolute_url }}"
|
||||
class="media-left preview-cover small"
|
||||
style="background-image: url({{ object.cover.url }})">
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="media-content flex-column">
|
||||
<section class="content flex-grow-1">
|
||||
{% block content %}{{ block.super }}{% endblock %}
|
||||
</section>
|
||||
{% block actions-container %}{{ block.super }}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
39
aircox/templates/aircox/widgets/list_pagination.html
Normal file
39
aircox/templates/aircox/widgets/list_pagination.html
Normal file
@ -0,0 +1,39 @@
|
||||
{% comment %}
|
||||
Context:
|
||||
- is_paginated: if True, page is paginated
|
||||
- page_obj: page object from list view;
|
||||
{% endcomment %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% if is_paginated %}
|
||||
<hr/>
|
||||
{% update_query request.GET.copy page=None as GET %}
|
||||
{% with GET.urlencode as GET %}
|
||||
<nav class="nav-urls is-centered" role="pagination" aria-label="{% translate "pagination" %}">
|
||||
<ul class="urls">
|
||||
{% if page_obj.has_previous %}
|
||||
{% comment %}Translators: Bottom of the list, "previous page"{% endcomment %}
|
||||
<a href="?{{ GET }}&page={{ page_obj.previous_page_number }}" class="left"
|
||||
title="{% translate "Previous" %}"
|
||||
aria-label="{% translate "Previous" %}">
|
||||
<span class="icon"><i class="fa fa-chevron-left"></i></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
|
||||
<span>
|
||||
{{ page_obj.number }} / {{ page_obj.paginator.num_pages }}
|
||||
</span>
|
||||
|
||||
{% if page_obj.has_next %}
|
||||
{% comment %}Translators: Bottom of the list, "Nextpage"{% endcomment %}
|
||||
<a href="?{{ GET }}&page={{ page_obj.next_page_number }}" class="right"
|
||||
title="{% translate "Next" %}"
|
||||
aria-label="{% translate "Next" %}">
|
||||
<span class="icon"><i class="fa fa-chevron-right"></i></span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</ul>
|
||||
|
||||
</nav>
|
||||
{% endwith %}
|
||||
{% endif %}
|
23
aircox/templates/aircox/widgets/log.html
Normal file
23
aircox/templates/aircox/widgets/log.html
Normal file
@ -0,0 +1,23 @@
|
||||
{% load i18n aircox %}
|
||||
{% comment %}
|
||||
List item for a log, either for a logged track or diffusion (as diffusion).
|
||||
|
||||
Context objects:
|
||||
- object: object to render
|
||||
- hide_schedule: if true, hide the schedule
|
||||
|
||||
In case of modification, you might want to check on `assets/vue/player.vue`
|
||||
for design review.
|
||||
{% endcomment %}
|
||||
|
||||
{% block outer %}
|
||||
{% if object|is_diffusion %}
|
||||
{% page_widget widget object.episode diffusion=object timetable=timetable|default:False %}
|
||||
{% elif object|is_log %}
|
||||
{% include "./track_item.html" with object=object.track log=object timetable=timetable|default:False %}
|
||||
{% else %}
|
||||
{% for obj in object %}
|
||||
{% include "./track_item.html" with object=obj.track log=obj timetable=timetable|default:False %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -1,22 +0,0 @@
|
||||
{% load i18n aircox %}
|
||||
{% comment %}
|
||||
List item for a log, either for a logged track or diffusion (as diffusion).
|
||||
|
||||
Context objects:
|
||||
- object: object to render
|
||||
- hide_schedule: if true, hide the schedule
|
||||
|
||||
In case of modification, you might want to check on `assets/vue/player.vue`
|
||||
for design review.
|
||||
|
||||
{% endcomment %}
|
||||
|
||||
{% if object|is_diffusion %}
|
||||
{% with object as diffusion %}
|
||||
{% include "aircox/widgets/diffusion_item.html" %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{% with object.track as object %}
|
||||
{% include "aircox/widgets/track_item.html" %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
@ -1,30 +0,0 @@
|
||||
{% comment %}
|
||||
Render list of logs (as widget).
|
||||
|
||||
Context:
|
||||
- object_list: list of logs to display
|
||||
- is_thin: if True, hide some information in order to fit in a thin container
|
||||
{% endcomment %}
|
||||
{% load aircox %}
|
||||
|
||||
{% with True as hide_schedule %}
|
||||
<table class="table is-striped is-hoverable is-fullwidth" role="list">
|
||||
{% for object in object_list %}
|
||||
<tr {% if object|is_diffusion and object.is_now %}class="is-selected"{% endif %}>
|
||||
<td>
|
||||
{% if object|is_diffusion %}
|
||||
<time datetime="{{ object.start }}" title="{{ object.start }}">
|
||||
{{ object.start|date:"H:i" }}
|
||||
{% if not is_thin %} - {{ object.end|date:"H:i" }}{% endif %}
|
||||
</time>
|
||||
{% else %}
|
||||
<time datetime="{{ object.date }}" title="{{ object.date }}">
|
||||
{{ object.date|date:"H:i" }}
|
||||
</time>
|
||||
{% endif %}
|
||||
</td>
|
||||
<td>{% include "aircox/widgets/log_item.html" %}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endwith %}
|
35
aircox/templates/aircox/widgets/logs.html
Normal file
35
aircox/templates/aircox/widgets/logs.html
Normal file
@ -0,0 +1,35 @@
|
||||
{% comment %}
|
||||
Context:
|
||||
- object_list: list of logs
|
||||
- timetable: defaults to False
|
||||
- widget: defaults to "item"
|
||||
{% endcomment %}
|
||||
{% load aircox %}
|
||||
|
||||
{% with timetable|default:False as timetable %}
|
||||
{% with widget|default:"item" as widget %}
|
||||
{% for object in object_list %}
|
||||
{% if object.episode %}
|
||||
{% page_widget widget object.episode diffusion=object timetable=True %}
|
||||
{% elif object|is_log %}
|
||||
{% include "./track_item.html" with object=object.track log=object timetable=True %}
|
||||
{% else %}
|
||||
<div class="preview list-item logs">
|
||||
<header class="headings">
|
||||
<span class="heading title">
|
||||
<span class="icon pr-2">
|
||||
<i class="fas fa-music"></i>
|
||||
</span>
|
||||
{{ station.music_stream_title }}
|
||||
</span>
|
||||
</header>
|
||||
<div class="media d-block content">
|
||||
{% for obj in object %}
|
||||
{% include "./track_item.html" with object=obj.track log=obj timetable=True %}
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
50
aircox/templates/aircox/widgets/nav.html
Normal file
50
aircox/templates/aircox/widgets/nav.html
Normal file
@ -0,0 +1,50 @@
|
||||
{% load aircox i18n %}
|
||||
<div class="dropdown is-hoverable is-right">
|
||||
<div class="dropdown-trigger">
|
||||
<button class="button square" aria-haspopup="true" aria-controls="dropdown-menu" type="button">
|
||||
<span class="icon">
|
||||
<i class="fa fa-user" aria-hidden="true"></i>
|
||||
</span>
|
||||
</button>
|
||||
</div>
|
||||
<div class="dropdown-menu" id="dropdown-menu" role="menu" style="z-index:200">
|
||||
<div class="dropdown-content">
|
||||
{% block user-menu %}
|
||||
<a class="dropdown-item" href="{% url "dashboard" %}" data-force-reload="1">
|
||||
{% translate "Dashboard" %}
|
||||
</a>
|
||||
{% if user|has_perm:"list_user" %}
|
||||
<a class="dropdown-item" href="{% url "user-list" %}" data-force-reload="1">
|
||||
{% translate "Users" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% comment %}
|
||||
{% block edit-menu %}
|
||||
{% if request.user|has_perm:"aircox.create_program" %}
|
||||
<a class="dropdown-item" href="{% url "program-create" %}">
|
||||
{% translate "Create Program" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% endcomment %}
|
||||
{% if user.is_superuser %}
|
||||
<hr class="dropdown-divider" />
|
||||
{% block admin-menu %}
|
||||
<a class="dropdown-item" href="{% url "admin:index" %}" target="new">
|
||||
{% translate "Admin" %}
|
||||
</a>
|
||||
<a class="dropdown-item" href="{% url "dashboard-statistics" %}">
|
||||
{% translate "Statistics" %}
|
||||
</a>
|
||||
{% endblock %}
|
||||
<hr class="dropdown-divider" />
|
||||
{% endif %}
|
||||
<a class="dropdown-item" href="{% url "logout" %}" data-force-reload="1">
|
||||
{% translate "Disconnect" %}
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
38
aircox/templates/aircox/widgets/page.html
Normal file
38
aircox/templates/aircox/widgets/page.html
Normal file
@ -0,0 +1,38 @@
|
||||
{% extends widget_template %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
|
||||
{% block outer %}
|
||||
{% with cover|default:object.cover_url as cover %}
|
||||
{% with url|default:object.get_absolute_url as url %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block title %}
|
||||
{% if title %}
|
||||
{{ block.super }}
|
||||
{% elif object %}
|
||||
{{ object.display_title }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block content %}
|
||||
{% if not content and object %}
|
||||
{% with object.display_headline as content %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block actions %}
|
||||
{% if url and "card" not in widget_template %}
|
||||
<a href="{{ url }}">{% translate "Show" %}</a>
|
||||
{% endif %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
33
aircox/templates/aircox/widgets/page_actions.html
Normal file
33
aircox/templates/aircox/widgets/page_actions.html
Normal file
@ -0,0 +1,33 @@
|
||||
{% load aircox i18n %}
|
||||
|
||||
{% block user-actions-container %}
|
||||
{% if user.is_authenticated %}
|
||||
{{ object.get_status_display }}
|
||||
|
||||
{% if object.pub_date %}
|
||||
({{ object.pub_date|date:"d/m/Y H:i" }})
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% if user.is_authenticated and can_edit %}
|
||||
{% with request.resolver_match.view_name as view_name %}
|
||||
|
||||
{% if "-edit" in view_name %}
|
||||
<a href="{% url view_name|detail_view page.slug %}" target="_self" title="{% translate 'View' %} {{ page }}">
|
||||
<span class="icon">
|
||||
<i class="fa-regular fa-eye"></i>
|
||||
</span>
|
||||
<span>{% translate 'View' %} </span>
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url view_name|edit_view page.pk %}" target="_self" title="{% translate 'Edit' %} {{ page }}">
|
||||
<span class="icon">
|
||||
<i class="fa-solid fa-pencil"></i>
|
||||
</span>
|
||||
<span>{% translate 'Edit' %} </span>
|
||||
</a>
|
||||
{% endif %}
|
||||
{% endwith %}
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
13
aircox/templates/aircox/widgets/page_card.html
Normal file
13
aircox/templates/aircox/widgets/page_card.html
Normal file
@ -0,0 +1,13 @@
|
||||
{% extends widget|default:"./card.html" %}
|
||||
|
||||
{% block outer %}
|
||||
{% if object %}
|
||||
{% with content=object.get_display_excerpt() %}
|
||||
{% with title=object.get_display_title() %}
|
||||
{{ block.super }}
|
||||
{% endwith %}
|
||||
{% endwith %}
|
||||
{% else %}
|
||||
{{ block.super }}
|
||||
{% endif %}
|
||||
{% endblock %}
|
@ -3,3 +3,11 @@
|
||||
{% block card_title %}
|
||||
{% block title %}{{ block.super }}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block card_subtitle %}
|
||||
{% block subtitle %}{{ block.super }}{% endblock %}
|
||||
{% endblock %}
|
||||
|
||||
{% block card_class %}
|
||||
{% block class %}{{ block.super }}{% endblock %}
|
||||
{% endblock %}
|
||||
|
@ -5,10 +5,10 @@ Context:
|
||||
- object_list: object list
|
||||
- list_url: url to complete list page
|
||||
{% endcomment %}
|
||||
{% load i18n %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% for object in object_list %}
|
||||
{% include object.item_template_name %}
|
||||
{% page_widget "item" object %}
|
||||
{% endfor %}
|
||||
|
||||
{% if list_url %}
|
||||
|
@ -5,7 +5,7 @@ The audio player
|
||||
|
||||
<br>
|
||||
|
||||
<div class="box is-fullwidth is-fixed-bottom is-paddingless player"
|
||||
<div class="is-fullwidth is-fixed-bottom is-paddingless player-container"
|
||||
role="{% translate "player" %}"
|
||||
aria-description="{% translate "Audio player used to listen to the radio and podcasts" %}">
|
||||
<noscript>
|
||||
@ -20,26 +20,32 @@ The audio player
|
||||
|
||||
<a-player ref="player"
|
||||
:live-args="{% player_live_attr %}"
|
||||
:playlists="{pin: ['{% translate "Bookmarks" %}', 'fa fa-star'], queue: ['{% translate 'Playlist' %}', 'fa fa-list']}"
|
||||
button-title="{% translate "Play or pause audio" %}">
|
||||
<template v-slot:content="{ loaded, live, current }">
|
||||
<h4 v-if="loaded" class="title is-4">
|
||||
[[ loaded.name ]]
|
||||
<h4 v-if="loaded" class="title">
|
||||
<a v-if="current?.data?.page_url" :href="current.data.page_url">
|
||||
[[ loaded.name ]]
|
||||
</a>
|
||||
<template v-else>[[ loaded.name ]]</template>
|
||||
</h4>
|
||||
<h4 v-else-if="current && current.data.type == 'track'"
|
||||
class="title is-4" aria-description="{% translate "Track currently on air" %}">
|
||||
<span class="has-text-info is-size-3">♬</span>
|
||||
class="title" aria-description="{% translate "Track currently on air" %}">
|
||||
<span class="icon secondary-color mr-3">
|
||||
<i class="fas fa-music"></i>
|
||||
</span>
|
||||
<span>[[ current.data.title ]]</span>
|
||||
<span class="has-text-grey-dark has-text-weight-light">
|
||||
— [[ current.data.artist ]]
|
||||
<i v-if="current.data.info">([[ current.data.info ]])</i>
|
||||
</span>
|
||||
</h4>
|
||||
<div v-else-if="live && current && current.data.type == 'diffusion'">
|
||||
<h4 class="title is-4" aria-description="{% translate "Diffusion currently on air" %}">
|
||||
<a :href="current.data.url">[[ current.data.title ]]</a>
|
||||
<h4 v-else-if="live && current && current.data.type == 'diffusion'"
|
||||
class="title"
|
||||
aria-description="{% translate "Diffusion currently on air" %}">
|
||||
<a :href="current.data.url" v-if="current.data.url">[[ current.data.title ]]</a>
|
||||
<template v-else>[[ current.data.title ]]</template>
|
||||
</h4>
|
||||
<div class="">[[ current.data.info ]]</div>
|
||||
</div>
|
||||
<h4 v-else class="title is-4" aria-description="{% translate "Currently playing" %}">
|
||||
{{ request.station.name }}
|
||||
</h4>
|
||||
|
70
aircox/templates/aircox/widgets/preview.html
Normal file
70
aircox/templates/aircox/widgets/preview.html
Normal file
@ -0,0 +1,70 @@
|
||||
{% load i18n %}
|
||||
{% comment %}
|
||||
Content related context:
|
||||
- object: object to display
|
||||
- cover: cover
|
||||
- title: title
|
||||
- subtitle: subtitle
|
||||
- content: content to display
|
||||
|
||||
Components:
|
||||
- no_cover: don't show cover
|
||||
- no_content: don't show content
|
||||
|
||||
Styling related context:
|
||||
- is_active: add "active" css class
|
||||
- is_small: add "small" css class
|
||||
- is_tiny: add "tiny" css class
|
||||
- tag
|
||||
- tag_class: css class to set to main tag
|
||||
- tag_extra: extra tag attributes
|
||||
|
||||
{% endcomment %}
|
||||
{% load aircox %}
|
||||
|
||||
{% block outer %}
|
||||
<{{ tag|default:"article" }} id="{{ object|object_id }}" class="preview {% if not cover %}no-cover {% endif %}{% if is_active %}active {% endif %}{% if is_tiny %}tiny{% elif is_small %}small{% endif %}{% block tag-class %}{{ tag_class|default:"" }} {% endblock %}" {% block tag-extra %}{% endblock %}>
|
||||
{% block inner %}
|
||||
{% block headings-container %}
|
||||
<header class="headings{% block headings-class %}{% endblock %}"{% block headings-tag-extra %}{% endblock %}>
|
||||
{% block headings %}
|
||||
{% block title-container %}
|
||||
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}"{% if title %} title="{{ title|escape }}"{% endif %}>
|
||||
{% block title %}{{ title|default:"" }}{% endblock %}
|
||||
</a>
|
||||
{% endblock %}
|
||||
{% block subtitle-container %}
|
||||
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">
|
||||
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
</header>
|
||||
{% endblock %}
|
||||
|
||||
{% block content-container %}
|
||||
<section class="content headings-container">
|
||||
{% block content %}
|
||||
{% if content and not no_content %}
|
||||
{% autoescape off %}
|
||||
{{ content|striptags|linebreaks }}
|
||||
{% endautoescape %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</section>
|
||||
{% endblock %}
|
||||
|
||||
{% block actions-container %}
|
||||
{% spaceless %}
|
||||
<div class="actions">
|
||||
{% block actions %}
|
||||
{% if admin and object.edit_url_name %}
|
||||
<a href="{% url object.edit_url_name pk=object.pk %}">{% translate "Edit" %}</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endspaceless %}
|
||||
{% endblock %}
|
||||
{% endblock %}
|
||||
</{{ tag|default:"article" }}>
|
||||
{% endblock %}
|
@ -5,9 +5,20 @@ Context:
|
||||
- object: track to render
|
||||
{% endcomment %}
|
||||
|
||||
<span class="has-text-info is-size-5">♬</span>
|
||||
<span>{{ object.title }}</span>
|
||||
<span class="has-text-grey-dark has-text-weight-light">
|
||||
— {{ object.artist }}
|
||||
{% if object.info %}(<i>{{ object.info }}</i>){% endif %}
|
||||
<span class="track">
|
||||
<span class="icon secondary-color">
|
||||
<i class="fas fa-music"></i>
|
||||
</span>
|
||||
<label>
|
||||
{% if log %}
|
||||
<span>{{ log.date|date:"H:i" }} — </span>
|
||||
{% endif %}
|
||||
<span class="has-text-weight-boldk">{{ object.title }}</span>
|
||||
{% if object.artist and object.artist != object.title %}
|
||||
<span>
|
||||
— {{ object.artist }}
|
||||
{% if object.info %}(<i>{{ object.info }}</i>){% endif %}
|
||||
</span>
|
||||
{% endif %}
|
||||
</label>
|
||||
</span>
|
||||
|
43
aircox/templates/aircox/widgets/wide.html
Normal file
43
aircox/templates/aircox/widgets/wide.html
Normal file
@ -0,0 +1,43 @@
|
||||
{% extends "./preview.html" %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block tag-class %}{{ block.super }} list-item wide is-fullwidth{% endblock %}
|
||||
|
||||
{% block headings %}
|
||||
<a href="{{ url|escape }}" class="heading title {% block title-class %}{% endblock %}">
|
||||
{% block title %}{{ title|default:"" }}{% endblock %}
|
||||
</a>
|
||||
<span class="heading subtitle {% block subtitle-class %}{% endblock %}">
|
||||
{% block subtitle %}{{ subtitle|default:"" }}{% endblock %}
|
||||
</span>
|
||||
{% endblock %}
|
||||
|
||||
{% block inner %}
|
||||
{% block content-container %}
|
||||
<div class="media">
|
||||
{% if object.cover %}
|
||||
<a href="{{ object.get_absolute_url }}"
|
||||
class="media-left preview-cover"
|
||||
style="background-image: url({{ object.cover.url }})">
|
||||
</a>
|
||||
{% endif %}
|
||||
<div class="media-content">
|
||||
{% block headings-container %}{{ block.super }}{% endblock %}
|
||||
|
||||
<section class="content">
|
||||
{% block content %}
|
||||
{% if content and with_content %}
|
||||
{% autoescape off %}
|
||||
{{ content|striptags|linebreaks }}
|
||||
{% endautoescape %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
</section>
|
||||
|
||||
{% block actions-container %}
|
||||
{{ block.super }}
|
||||
{% endblock %}
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
18
aircox/templates/registration/login.html
Normal file
18
aircox/templates/registration/login.html
Normal file
@ -0,0 +1,18 @@
|
||||
{% extends "aircox/base.html" %}
|
||||
{% load i18n aircox %}
|
||||
|
||||
{% block content-container %}
|
||||
<div class="container content page-content">
|
||||
<h2>{% trans "Log in" %}</h2>
|
||||
<br/>
|
||||
<form method="post" action="{% url 'login' %}">
|
||||
{% csrf_token %}
|
||||
<table>
|
||||
{{ form.as_table }}
|
||||
</table>
|
||||
<br/>
|
||||
<button class="button" type="submit">{% trans "Log in" %}</button>
|
||||
<input type="hidden" name="next" value="{{ next }}">
|
||||
</form>
|
||||
</div>
|
||||
{% endblock %}
|
Reference in New Issue
Block a user