Merge remote-tracking branch 'rd/all-python'
This commit is contained in:
commit
fdc2503fcf
198 changed files with 13289 additions and 2977 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -4,3 +4,4 @@ _build/
|
|||
.DS_Store
|
||||
dev.db
|
||||
.coverage
|
||||
staticfiles
|
||||
|
|
54
LICENSE
54
LICENSE
|
@ -1,3 +1,30 @@
|
|||
registrasion-demo
|
||||
-----------------
|
||||
|
||||
# Copyright (c) 2016-2017 Christopher Neugebauer and contributors
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
|
||||
pinaxcon
|
||||
--------
|
||||
|
||||
# Copyright (c) 2009-2015 James Tauber and contributors
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
|
@ -17,3 +44,30 @@
|
|||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
# THE SOFTWARE.
|
||||
|
||||
|
||||
bootstrap-sass
|
||||
--------------
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2011-2016 Twitter, Inc
|
||||
Copyright (c) 2011-2016 The Bootstrap Authors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
"description": "",
|
||||
"insitetree": true,
|
||||
"hint": "",
|
||||
"url": "pages_page \"about/\"",
|
||||
"url": "page_about",
|
||||
"inbreadcrumbs": true,
|
||||
"title": "About",
|
||||
"tree": 1,
|
||||
|
@ -40,7 +40,7 @@
|
|||
"description": "",
|
||||
"insitetree": true,
|
||||
"hint": "",
|
||||
"url": "pages_page \"venue/\"",
|
||||
"url": "page_venue",
|
||||
"inbreadcrumbs": true,
|
||||
"title": "Venue",
|
||||
"tree": 1,
|
||||
|
@ -109,9 +109,9 @@
|
|||
"description": "",
|
||||
"insitetree": true,
|
||||
"hint": "",
|
||||
"url": "sponsor_apply",
|
||||
"url": "page_sponsor_info",
|
||||
"inbreadcrumbs": true,
|
||||
"title": "Apply to be a Sponsor",
|
||||
"title": "Prospectus",
|
||||
"tree": 1,
|
||||
"access_perm_type": 1,
|
||||
"alias": null,
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
buildpack: https://buildpack.gondor.io/python
|
||||
site: eldarion-conferences/pinaxcon
|
||||
deploy:
|
||||
services:
|
||||
- web
|
||||
branches:
|
||||
master: primary
|
116
gulpfile.js
116
gulpfile.js
|
@ -1,116 +0,0 @@
|
|||
/**
|
||||
* Setup
|
||||
*/
|
||||
process.title = process.title || 'gulp';
|
||||
|
||||
/**
|
||||
* Dependencies
|
||||
*/
|
||||
const path = require('path');
|
||||
const gulp = require('gulp');
|
||||
|
||||
/**
|
||||
* Setup
|
||||
*/
|
||||
const tasks = require(path.resolve(__dirname, 'gulp/tasks'));
|
||||
const config = require(path.resolve(__dirname, 'gulp/config'));
|
||||
|
||||
/**
|
||||
* Tasks
|
||||
*/
|
||||
gulp.task('build:clean', function buildClean() {
|
||||
tasks.clean(config.paths.build);
|
||||
return tasks.clean(config.paths.dist);
|
||||
});
|
||||
|
||||
gulp.task('build:styles', function buildStyles() {
|
||||
return tasks.css(config.styles.source, {less: {paths: config.styles.npmPaths}})
|
||||
.pipe(gulp.dest(config.styles.dist));
|
||||
});
|
||||
|
||||
gulp.task('build:js', function buildJS() {
|
||||
return tasks.browserify(config.scripts.main)
|
||||
.pipe(gulp.dest(config.scripts.dist));
|
||||
});
|
||||
|
||||
gulp.task('manifest', function manifest() {
|
||||
return tasks.rev(config.manifest.source)
|
||||
.pipe(gulp.dest(config.paths.dist))
|
||||
.pipe(tasks.manifest())
|
||||
.pipe(gulp.dest(config.paths.build));
|
||||
});
|
||||
|
||||
gulp.task('build:copy-icons', function() {
|
||||
return tasks.copy(config.fonts.sources)
|
||||
.pipe(gulp.dest(config.fonts.dist));
|
||||
});
|
||||
gulp.task('build:copy-images', function() {
|
||||
return tasks.copy(config.images.sources).pipe(gulp.dest(config.images.dist));
|
||||
});
|
||||
|
||||
gulp.task('build:script-include', function () {
|
||||
return tasks.handlebars(config.templates.manifestPath, config.templates.scriptsTemplate, config.staticUrlRoot)
|
||||
.pipe(gulp.dest(config.templates.destination));
|
||||
});
|
||||
|
||||
gulp.task('build:style-include', function () {
|
||||
return tasks.handlebars(config.templates.manifestPath, config.templates.stylesTemplate, config.staticUrlRoot)
|
||||
.pipe(gulp.dest(config.templates.destination));
|
||||
});
|
||||
|
||||
gulp.task('test', function test() {
|
||||
return tasks.test(config.test.all);
|
||||
});
|
||||
|
||||
gulp.task('test:req', function testReq() {
|
||||
return tasks.test(config.test.req);
|
||||
});
|
||||
|
||||
gulp.task('test:components', function testComponents() {
|
||||
return tasks.test(config.test.components);
|
||||
});
|
||||
|
||||
gulp.task('xo', function xo() {
|
||||
return tasks.xo(config.xo.source);
|
||||
});
|
||||
|
||||
gulp.task('optimize:js', function () {
|
||||
return tasks.optimizejs(config.optimize.js.source, config.optimize.js.options, config.optimize.js.dist);
|
||||
});
|
||||
|
||||
gulp.task('optimize:css', function () {
|
||||
return tasks.optimizecss(config.optimize.css.source, config.optimize.css.options, config.optimize.css.dist);
|
||||
});
|
||||
|
||||
/**
|
||||
* Compound Tasks
|
||||
*/
|
||||
gulp.task('watch', function watch() {
|
||||
gulp.watch(config.watch.styles, gulp.series(['build:styles', 'manifest', 'build:style-include']));
|
||||
gulp.watch(config.watch.scripts, gulp.series(['build:js', 'manifest', 'build:script-include']));
|
||||
});
|
||||
|
||||
gulp.task('build', gulp.series([
|
||||
'xo',
|
||||
'build:clean',
|
||||
gulp.parallel([
|
||||
'build:styles',
|
||||
'build:js',
|
||||
'build:copy-icons',
|
||||
'build:copy-images'
|
||||
]),
|
||||
'manifest',
|
||||
'build:script-include',
|
||||
'build:style-include'
|
||||
]));
|
||||
|
||||
gulp.task('default', gulp.series([
|
||||
'build',
|
||||
'watch'
|
||||
]));
|
||||
|
||||
gulp.task('release', gulp.series([
|
||||
'build',
|
||||
'optimize:js',
|
||||
'optimize:css'
|
||||
]));
|
|
@ -56,22 +56,23 @@ MEDIA_URL = "/site_media/media/"
|
|||
# Don"t put anything in this directory yourself; store your static files
|
||||
# in apps" "static/" subdirectories and in STATICFILES_DIRS.
|
||||
# Example: "/home/media/media.lawrence.com/static/"
|
||||
STATIC_ROOT = os.path.join(PACKAGE_ROOT, "site_media", "static")
|
||||
STATIC_ROOT = os.path.join(PROJECT_ROOT, 'staticfiles')
|
||||
|
||||
# URL prefix for static files.
|
||||
# Example: "http://media.lawrence.com/static/"
|
||||
STATIC_URL = "/site_media/static/"
|
||||
STATIC_URL = '/static/'
|
||||
|
||||
# Additional locations of static files
|
||||
STATICFILES_DIRS = [
|
||||
os.path.join(PROJECT_ROOT, "static", "dist"),
|
||||
]
|
||||
STATICFILES_DIRS = (
|
||||
os.path.join(PROJECT_ROOT, 'static'),
|
||||
)
|
||||
|
||||
# List of finder classes that know how to find static files in
|
||||
# various locations.
|
||||
STATICFILES_FINDERS = [
|
||||
"django.contrib.staticfiles.finders.FileSystemFinder",
|
||||
"django.contrib.staticfiles.finders.AppDirectoriesFinder",
|
||||
"compressor.finders.CompressorFinder",
|
||||
]
|
||||
|
||||
# Make this unique, and don't share it with anybody.
|
||||
|
@ -155,6 +156,7 @@ INSTALLED_APPS = [
|
|||
|
||||
# Registrasion
|
||||
"registrasion",
|
||||
"symposion_templates",
|
||||
|
||||
# Registrasion-stipe
|
||||
"pinax.stripe",
|
||||
|
@ -171,6 +173,9 @@ INSTALLED_APPS = [
|
|||
|
||||
#testing
|
||||
"django_nose",
|
||||
|
||||
# stylesheets and js
|
||||
'compressor',
|
||||
]
|
||||
|
||||
# A sample logging configuration. The only tangible logging
|
||||
|
@ -202,6 +207,10 @@ LOGGING = {
|
|||
}
|
||||
}
|
||||
|
||||
COMPRESS_PRECOMPILERS = (
|
||||
('text/x-scss', 'django_libsass.SassCompiler'),
|
||||
)
|
||||
|
||||
FIXTURE_DIRS = [
|
||||
os.path.join(PROJECT_ROOT, "fixtures"),
|
||||
]
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<div class="pull-left">
|
||||
©2016
|
||||
© 2017
|
||||
</div>
|
||||
|
||||
<div class="pull-right">
|
||||
Site powered by <a href="http://eldarion.com/symposion/"><b>Symposion</b></a>.
|
||||
Site powered by <a href="http://eldarion.com/symposion/"><b>Symposion</b></a>
|
||||
and <a href="http://github.com/chrisjrn/registrasion/"><b>Registrasion</b></a>.
|
||||
</div>
|
||||
|
|
|
@ -1 +1,10 @@
|
|||
<script src='/site_media/static/js/site-92ae8d0d6c.js'></script>
|
||||
{% load compress %}
|
||||
{% load staticfiles %}
|
||||
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.js"></script>
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js"></script>
|
||||
|
||||
{% compress js %}
|
||||
<script src='{% static "bootstrap/javascripts/bootstrap.min.js" %}'></script>
|
||||
<script src='{% static "js/site.js" %}'></script>
|
||||
{% endcompress %}
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
<link href='/site_media/static/css/site-0a247b924d.css' rel='stylesheet' />
|
||||
{% load compress %}
|
||||
{% load staticfiles %}
|
||||
|
||||
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
|
||||
{% compress css %}
|
||||
<link rel="stylesheet" type="text/x-scss" href="{% static "scss/site.scss" %}" />
|
||||
{% endcompress %}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load pinax_boxes_tags %}
|
||||
|
||||
{% block head_title %}{% trans "Welcome" %}{% endblock %}
|
||||
|
||||
{% block body_class %}home{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% box "homepage" %}
|
||||
<h1>{{ SITE_NAME }}</h1>
|
||||
<p class="lead">Welcome to the demo site.</p>
|
||||
{% endblock %}
|
||||
|
|
18
pinaxcon/templates/page_with_title_and_lede.html
Normal file
18
pinaxcon/templates/page_with_title_and_lede.html
Normal file
|
@ -0,0 +1,18 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% block head_title %}{% block title %}{% endblock %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% block heading_base %}
|
||||
<h1>{% block heading %}{% endblock %}</h1>
|
||||
{% endblock %}
|
||||
|
||||
{% block lede_base %}
|
||||
<p class="lead">{% block lede %}{% endblock %}</p>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
{% endblock %}
|
||||
|
||||
{% endblock %}
|
9
pinaxcon/templates/pages/about.html
Normal file
9
pinaxcon/templates/pages/about.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "page_with_title_and_lede.html" %}
|
||||
|
||||
{% block title %}About {{ SITE_NAME }}{% endblock %}
|
||||
{% block heading %}About {{ SITE_NAME }}{% endblock %}
|
||||
{% block lede %}{{ SITE_NAME }} is the premier demo conference site for Symposion and Registrasion{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>I am the body content</p>
|
||||
{% endblock %}
|
9
pinaxcon/templates/pages/sponsors/info.html
Normal file
9
pinaxcon/templates/pages/sponsors/info.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "page_with_title_and_lede.html" %}
|
||||
|
||||
{% block title %}Sponsorship Prospectus{% endblock %}
|
||||
{% block heading %}Sponsorship Prospectus{% endblock %}
|
||||
{% block lede %}{{ SITE_NAME }} wants sponsors.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>I am the body content</p>
|
||||
{% endblock %}
|
9
pinaxcon/templates/pages/venue.html
Normal file
9
pinaxcon/templates/pages/venue.html
Normal file
|
@ -0,0 +1,9 @@
|
|||
{% extends "page_with_title_and_lede.html" %}
|
||||
|
||||
{% block title %}Venue{% endblock %}
|
||||
{% block heading %}Venue{% endblock %}
|
||||
{% block lede %}{{ SITE_NAME }} is being held on a Django Hosting facility, somewhere.{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<p>I am the body content</p>
|
||||
{% endblock %}
|
|
@ -5,12 +5,10 @@
|
|||
{% load i18n %}
|
||||
{% load sitetree %}
|
||||
|
||||
|
||||
{% block styles %}
|
||||
{% include "_styles.html" %}
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block extra_head_base %}
|
||||
{% block extra_head %}{% endblock %}
|
||||
{% endblock %}
|
||||
|
@ -46,7 +44,6 @@
|
|||
|
||||
{% block scripts %}
|
||||
{% include "_scripts.html" %}
|
||||
<script src="//cdnjs.cloudflare.com/ajax/libs/ace/1.2.0/ace.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_body_base %}
|
||||
|
|
|
@ -1,95 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load sitetree %}
|
||||
|
||||
{% block head_title %}User List{% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
div.dataTables_length label {
|
||||
float: left;
|
||||
text-align: left;
|
||||
}
|
||||
div.dataTables_length select {
|
||||
width: 75px;
|
||||
}
|
||||
div.dataTables_filter label {
|
||||
float: right;
|
||||
}
|
||||
div.dataTables_info {
|
||||
padding-top: 8px;
|
||||
}
|
||||
div.dataTables_paginate {
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
table.table {
|
||||
clear: both;
|
||||
margin-bottom: 6px !important;
|
||||
background-color: white;
|
||||
}
|
||||
table.table thead .sorting,
|
||||
table.table thead .sorting_asc,
|
||||
table.table thead .sorting_desc,
|
||||
table.table thead .sorting_asc_disabled,
|
||||
table.table thead .sorting_desc_disabled {
|
||||
cursor: pointer;
|
||||
*cursor: hand;
|
||||
}
|
||||
table.dataTable th:active {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body_outer %}
|
||||
<h1>User List</h1>
|
||||
<table class="table table-striped table-bordered table-reviews">
|
||||
<thead>
|
||||
<th>{% trans "Email" %}</th>
|
||||
<th>{% trans "Name" %}</th>
|
||||
<th>{% trans "Speaker Profile?" %}</th>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for user in users %}
|
||||
<tr>
|
||||
<td>{{ user.email }}</td>
|
||||
<td>{{ user.get_full_name }}</td>
|
||||
<td>
|
||||
{% if user.speaker_profile %}
|
||||
<a href="{% url "speaker_profile" user.speaker_profile.pk %}">{{ user.speaker_profile }}</a>
|
||||
{% else %}
|
||||
<a href="{% url "speaker_create_staff" user.pk %}" class="btn btn-xs">create</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script src="{{ STATIC_URL }}datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
|
||||
<script src="{{ STATIC_URL }}tabletools/js/TableTools.min.js" type="text/javascript"></script>
|
||||
<script src="{{ STATIC_URL }}datatables/js/dataTables.bootstrap.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$(".tip").tooltip();
|
||||
$("table.table-reviews").dataTable({
|
||||
"sDom": "<'row'<'col-md-3'l><'col-md-3'T><'col-md-4'f>r>t<'row'<'col-md-3'i><'col-md-5'p>>",
|
||||
"sPaginationType": "bootstrap",
|
||||
"bStateSave": true,
|
||||
"oTableTools": {
|
||||
"aButtons": [
|
||||
"copy",
|
||||
"csv",
|
||||
"print"
|
||||
],
|
||||
"sSwfPath": "{{ STATIC_URL }}tabletools/swf/copy_csv_xls.swf"
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,13 +0,0 @@
|
|||
{% load account_tags %}
|
||||
{% load i18n %}
|
||||
{% user_display message.user as user %}
|
||||
<p>
|
||||
{% blocktrans with title=proposal.title %}<b>{{ user }}</b> has added a message on <b>{{ title }}</b>.{% endblocktrans %}
|
||||
</p>
|
||||
<blockquote>
|
||||
{{ message.message|safe }}
|
||||
</blockquote>
|
||||
<p>
|
||||
{% if reviewer %}{% url 'review_detail' proposal.pk as detail_url %}{% else %}{% url 'proposal_detail' proposal.pk as detail_url %}{% endif %}
|
||||
{% blocktrans %} Respond online at <a href="http://{{ current_site }}{{ detail_url }}#proposal-feedback">http://{{ current_site }}{{ detail_url }}#proposal-feedback</a>{% endblocktrans %}
|
||||
</p>
|
|
@ -1 +0,0 @@
|
|||
{% load account_tags i18n %}{% user_display message.user as user %}{% blocktrans with title=proposal.title %}New message on "{{ title }}" from {{ user }}{% endblocktrans %}
|
|
@ -1,10 +0,0 @@
|
|||
{% load account_tags %}
|
||||
{% load i18n %}
|
||||
{% user_display user as username %}
|
||||
<p>
|
||||
{% blocktrans with title=proposal.title %}<b>{{ username }}</b> has made changes to <b>{{ title }}</b> which you have previously reviewed or commented on.{% endblocktrans %}
|
||||
</p>
|
||||
<p>
|
||||
{% url 'review_detail' proposal.pk as detail_url %}
|
||||
{% blocktrans %}View the latest version of the proposal online at <a href="http://{{ current_site }}{{ detail_url }}">http://{{ current_site }}{{ detail_url }}</a>{% endblocktrans %}
|
||||
</p>
|
|
@ -1 +0,0 @@
|
|||
{% load account_tags i18n %}{% user_display user as username %}{% blocktrans with title=proposal.title %}"{{ title }}" has been updated by {{ username }}{% endblocktrans %}
|
|
@ -1,10 +0,0 @@
|
|||
{% load i18n %}
|
||||
{% url 'dashboard' as dashboard_url %}
|
||||
{% blocktrans with username=proposal.speaker.name site_name=current_site.name title=proposal.title %}
|
||||
<p>{{ username }} attached you as an additional speaker to a
|
||||
talk proposal for {{ site_name }} entitled "{{ title }}".</p>
|
||||
|
||||
<p>For more details, visit the {{ site_name }} speaker dashboard:
|
||||
<a href="http://{{ current_site }}{{ dashboard_url }}">http://{{ current_site }}{{ dashboard_url ]}</a>
|
||||
</p>
|
||||
{% endblocktrans %}
|
|
@ -1 +0,0 @@
|
|||
{% load i18n %}{% blocktrans with name=proposal.speaker.name title=proposal.title %}{{ name }} has invited you to join as a speaker on {{ title }}{% endblocktrans %}
|
|
@ -1,14 +0,0 @@
|
|||
{% load i18n %}
|
||||
{% url 'speaker_create_token' token as token_url %}
|
||||
{% blocktrans with invitator=proposal.speaker.name title=proposal.title site_name=current_site.name %}
|
||||
<p>{{ invitator }} attached you as an additional speaker to a
|
||||
talk proposal for {{ site_name }} entitled "{{ title }}".</p>
|
||||
|
||||
<p>Go to</p>
|
||||
|
||||
<p><a href="http://{{ current_site }}{{ token_url }}">http://{{ current_site }}{{ token_url }}</a></p>
|
||||
|
||||
<p>to confirm.</p>
|
||||
|
||||
<p>If you don't have account on the website, you will be asked to create one.</p>
|
||||
{% endblocktrans %}
|
|
@ -1 +0,0 @@
|
|||
{% load i18n %}{% blocktrans with name=proposal.speaker.name title=proposal.title %}{{ name }} has invited you to join as a speaker on {{ title }}{% endblocktrans %}
|
|
@ -1,12 +0,0 @@
|
|||
{% load i18n %}
|
||||
{% url 'speaker_create_token' token as token_url %}
|
||||
{% blocktrans with username=proposal.speaker.name site_name=current_site.name title=proposal.title %}
|
||||
<p>{{ username }} attached you as an additional speaker to a
|
||||
talk proposal for {{ site_name }} entitled "{{ title }}".</p>
|
||||
|
||||
<p>Go to</p>
|
||||
|
||||
<p><a href="http://{{ current_site }}{{ token_url }}">http://{{ current_site }}{{ token_url }}</a></p>
|
||||
|
||||
<p>to confirm and fill out your speaker profile.</p>
|
||||
{% endblocktrans %}
|
|
@ -1 +0,0 @@
|
|||
{% load i18n %}{% blocktrans with name=proposal.speaker.name title=proposal.title %}{{ name }} has invited you to join as a speaker on {{ title }}{% endblocktrans %}
|
|
@ -1,12 +0,0 @@
|
|||
{% load i18n %}
|
||||
{% blocktrans with sponsor_name=sponsor.name applicant=sponsor.applicant contact=sponsor.contact_name email=sponsor.contact_email level=sponsor.level %}
|
||||
<p>{{ sponsor_name }} has applied to be a sponsor.</p>
|
||||
|
||||
<ul>
|
||||
<li><b>Applicant</b>: {{ applicant }}</li>
|
||||
<li><b>Sponsor Name</b>: {{ sponsor_name }}</li>
|
||||
<li><b>Sponsor Contact</b>: {{ contact }}</li>
|
||||
<li><b>Sponsor Contact Email</b>: {{ email }}</li>
|
||||
<li><b>Sponsorship Level</b>: {{ level }}</li>
|
||||
</ul>
|
||||
{% endblocktrans %}
|
|
@ -1 +0,0 @@
|
|||
{% load i18n %}{% trans "New Sponsor Application" %}
|
|
@ -1,12 +0,0 @@
|
|||
{% load i18n account_tags %}
|
||||
{% user_display user as username %}
|
||||
{% blocktrans with team_name=team team_url=team.get_absolute_url site_name=current_site.name site_url=current_site %}
|
||||
<p>
|
||||
User "{{ username }}" has applied to join <b>{{ team_name }}</b> on {{ site_name }}.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To accept this application and see any other pending applications, visit the following url:
|
||||
<a href="http://{{ site_url }}{{ team_url }}">http://{{ site_url }}{{ team_url }}</a>
|
||||
</p>
|
||||
{% endblocktrans %}
|
|
@ -1 +0,0 @@
|
|||
{% load i18n account_tags %}{% user_display user as username %}{% blocktrans %}{{ username}} has applied to to join "{{ team }}"{% endblocktrans %}
|
|
@ -1,12 +0,0 @@
|
|||
{% load i18n account_tags %}
|
||||
|
||||
{% blocktrans with team_name=team team_url=team.get_absolute_url site_name=current_site.name site_url=current_site %}
|
||||
<p>
|
||||
You have been invited to join <b>{{ team_name }}</b> on {{ site_name }}.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
To accept this invitation, visit the following url:
|
||||
<a href="http://{{ site_url }}{{ team_url }}">http://{{ site_url }}{{ team_url }}</a>
|
||||
</p>
|
||||
{% endblocktrans %}
|
|
@ -1 +0,0 @@
|
|||
{% load i18n %}{% blocktrans %}You have been invited to join "{{ team }}"{% endblocktrans %}
|
|
@ -1,42 +0,0 @@
|
|||
{% load i18n %}
|
||||
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url "proposal_detail" proposal.pk %}">{{ proposal.title }}</a>
|
||||
</td>
|
||||
|
||||
<td>{{ proposal.kind.name }}</td>
|
||||
|
||||
<td>
|
||||
{% if proposal.cancelled %}
|
||||
<span class="label label-danger">{% trans 'Cancelled' %}</span>
|
||||
{% else %}
|
||||
{% if request.user == proposal.speaker.user %}
|
||||
{% if proposal.result.status == "accepted" %}
|
||||
<span class="label label-success">{% trans 'Accepted' %}</span>
|
||||
{% else %}
|
||||
<span class="label label-default">{% trans 'Submitted' %}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="label label-default">{% trans 'Invited' %}</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if not proposal.cancelled %}
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-xs dropdown-toggle" data-toggle="dropdown" href="#">
|
||||
{% trans 'Choose Response' %}
|
||||
<span class="caret"></span>
|
||||
</a>
|
||||
<ul class="dropdown-menu">
|
||||
<li><a href="{% url "proposal_pending_join" proposal.id %}">
|
||||
{% trans 'Accept invitation' %}</a></li>
|
||||
<li><a href="{% url "proposal_pending_decline" proposal.id
|
||||
%}">{% trans 'Decline invitation' %}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
|
@ -1,60 +0,0 @@
|
|||
{% load i18n %}
|
||||
|
||||
<dl class="dl-horizontal">
|
||||
<dt>{% trans "Submitted by" %}</dt>
|
||||
<dd>{{ proposal.speaker }}</dd>
|
||||
|
||||
<dt>{% trans "Track" %}</dt>
|
||||
<dd>{{ proposal.track }} </dd>
|
||||
|
||||
<dt>{% trans "Audience Level" %}</dt>
|
||||
<dd>{{ proposal.get_audience_level_display }} </dd>
|
||||
|
||||
{% if proposal.additional_speakers.all %}
|
||||
<dt>{% trans "Additional Speakers" %}</dt>
|
||||
<dd>
|
||||
{% for speaker in proposal.additional_speakers.all %}
|
||||
<li>
|
||||
{% if speaker.user %}
|
||||
<strong>{{ speaker.name }}</strong> <{{ speaker.email }}>
|
||||
{% else %}
|
||||
{{ speaker.email }} ({% trans "Invitation Sent" %})
|
||||
{% endif %}
|
||||
</li>
|
||||
{% endfor %}
|
||||
</dd>
|
||||
{% endif %}
|
||||
|
||||
<dt>{% trans "Description" %}</dt>
|
||||
<dd>{{ proposal.description }} </dd>
|
||||
|
||||
<dt>{% trans "Abstract" %}</dt>
|
||||
<dd>{{ proposal.abstract_html|safe }} </dd>
|
||||
|
||||
<dt>{% trans "Notes" %}</dt>
|
||||
<dd>{{ proposal.additional_notes_html|safe }} </dd>
|
||||
|
||||
<dt>{% trans "Speaker Bio" %}</dt>
|
||||
<dd>{{ proposal.speaker.biography|safe }} </dd>
|
||||
|
||||
<dt>{% trans "Documents" %}</dt>
|
||||
<dd>
|
||||
{% if proposal.supporting_documents.exists %}
|
||||
<table class="table table-striped">
|
||||
{% for document in proposal.supporting_documents.all %}
|
||||
<tr>
|
||||
<td><a href="{{ document.download_url }}">{{ document.description }}</a></td>
|
||||
<td>
|
||||
<form style="margin: 0;" method="post" action="{% url "proposal_document_delete" document.pk %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-xs">delete</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
No supporting documents attached to this proposal.
|
||||
{% endif %}
|
||||
</dd>
|
||||
</dl>
|
|
@ -1,32 +0,0 @@
|
|||
<tr>
|
||||
<td>
|
||||
<a href="{% url "proposal_detail" proposal.pk %}">{{ proposal.title }}</a>
|
||||
</td>
|
||||
|
||||
<td>{{ proposal.kind.name }}</td>
|
||||
|
||||
<td>
|
||||
{% if proposal.cancelled %}
|
||||
<span class="label label-danger">Cancelled</span>
|
||||
{% else %}
|
||||
{% if request.user == proposal.speaker.user %}
|
||||
{% if proposal.result.status == "accepted" %}
|
||||
<span class="label label-success">Accepted</span>
|
||||
{% else %}
|
||||
<span class="label label-default">Submitted</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
<span class="label label-default">Associated</span>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
|
||||
<td>
|
||||
{% if not proposal.cancelled %}
|
||||
{% if request.user == proposal.speaker.user and proposal.can_edit %}
|
||||
<a href="{% url "proposal_edit" proposal.pk %}" class="btn btn-xs"><i class="fa fa-pencil"></i> Edit</a>
|
||||
<a href="{% url "proposal_speaker_manage" proposal.id %}" class="btn btn-xs"><i class="fa fa-user"></i> Manage Additional Speakers</a>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
</tr>
|
|
@ -1,5 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% block body_outer %}
|
||||
{% block body %}{% endblock %}
|
||||
{% endblock %}
|
|
@ -1,17 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
|
||||
{% block page_title %}Upload Document to '{{ proposal.title }}'{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form method="POST" action="" enctype="multipart/form-data" class="form form-horizontal">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{{ form|bootstrap_horizontal }}
|
||||
</fieldset>
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Upload" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,16 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block head_title %}{% trans 'Cancel Proposal' %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Cancel: {{ proposal.title }}</h1>
|
||||
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<p>Are you sure you want to cancel <b>{{ proposal.title }}</b>?</p>
|
||||
<input class="btn btn-danger" type="submit" value="I am sure" />
|
||||
<a class="btn btn-default" href="{% url "proposal_detail" proposal.pk %}">{% trans 'No, keep it for now' %}</a>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,119 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load account_tags %}
|
||||
{% load bootstrap %}
|
||||
|
||||
{% block head_title %}{{ proposal.title }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="pull-right">
|
||||
{% if not proposal.cancelled %}
|
||||
{% if request.user == proposal.speaker.user %}
|
||||
<a href="{% url "proposal_edit" proposal.pk %}" class="btn btn-default">
|
||||
{% trans "Edit this proposal" %}
|
||||
</a>
|
||||
<a href="{% url "proposal_cancel" proposal.pk %}" class="btn btn-default">
|
||||
{% trans "Cancel this proposal" %}
|
||||
</a>
|
||||
{% else %}
|
||||
<a href="{% url "proposal_leave" proposal.pk %}" class="btn btn-default">
|
||||
{% trans "Remove me from this proposal" %}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% trans 'Cancelled' }
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<h3>#{{ proposal.number }}: {{ proposal.title }} ({{ proposal.speaker }}, Track: {{ proposal.track }})</h3>
|
||||
|
||||
<div class="tabbable">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#proposal-detail" data-toggle="tab">{% trans "Proposal Details" %}</a></li>
|
||||
{% if request.user == proposal.speaker.user %}
|
||||
<li><a href="#proposal-documents" data-toggle="tab">{% trans "Supporting Documents" %}</a></li>
|
||||
{% endif %}
|
||||
{% if message_form %}
|
||||
<li><a href="#proposal-feedback" data-toggle="tab">{% trans "Reviewer Feedback" %} <span class="badge">{{ proposal.messages.all|length }}</span></a></li>
|
||||
{% endif %}
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="proposal-detail">
|
||||
{% include "symposion/proposals/_proposal_fields.html" %}
|
||||
</div>
|
||||
{% if request.user == proposal.speaker.user %}
|
||||
<div class="tab-pane" id="proposal-documents">
|
||||
<h3>{% trans 'Supporting Documents' %}</h3>
|
||||
|
||||
{% if proposal.supporting_documents.exists %}
|
||||
<table class="table table-striped">
|
||||
{% for document in proposal.supporting_documents.all %}
|
||||
<tr>
|
||||
<td><a href="{{ document.download_url }}">{{ document.description }}</a></td>
|
||||
<td>
|
||||
<form style="margin: 0;" method="post" action="{% url "proposal_document_delete" document.pk %}">
|
||||
{% csrf_token %}
|
||||
<button type="submit" class="btn btn-xs">{% trans 'delete' %}</button>
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p>{% trans 'No supporting documents attached to this proposal.' %}</p>
|
||||
{% endif %}
|
||||
<a class="btn btn-default btn-sm{% if proposal.cancelled %} btn-disabled{% endif %}" href="{% url "proposal_document_create" proposal.pk %}"><i class="fa fa-upload"></i> {% trans 'Add Document' %}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if message_form %}
|
||||
<div class="tab-pane" id="proposal-feedback">
|
||||
|
||||
<h3>{% trans 'Conversation with Reviewers' %}</h3>
|
||||
|
||||
{% for message in proposal.messages.all %}
|
||||
<div class="review-box">
|
||||
<div class="comment">{{ message.message|safe }}</div>
|
||||
<div class="dateline"><b>{% user_display message.user %}</b> {{ message.submitted_at|timesince }} ago</div>
|
||||
</div>
|
||||
<div class="clear"></div>
|
||||
{% endfor %}
|
||||
|
||||
<h3>{% trans 'Leave a Message' %}</h3>
|
||||
|
||||
<p>{% trans 'You can leave a message for the reviewers here.' %}</p>
|
||||
|
||||
<form action="" method="POST" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{{ message_form|bootstrap }}
|
||||
</fieldset>
|
||||
<div class="actions">
|
||||
<button type="submit" name="message_submit" class="btn btn-primary">{% trans 'Submit' %}</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script src="{{ STATIC_URL }}symposion/js/jquery.history.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var History = window.History;
|
||||
|
||||
$(window).bind("anchorchange", function() {
|
||||
$(".nav-tabs a[href='" + location.hash + "']").click();
|
||||
});
|
||||
|
||||
$('#.nav-tabs a[data-toggle="tab"]').on('shown', function (e) {
|
||||
if (History.enabled) {
|
||||
History.pushState(null, null, $(e.target).attr("href"));
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock extra_script %}
|
|
@ -1,22 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
|
||||
{% block head_title %}Editing {{ proposal.title }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Edit: {{ proposal.title }}</h1>
|
||||
|
||||
<p><a href="{% url "proposal_speaker_manage" proposal.pk %}">Manage speakers</a></p>
|
||||
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{{ form|bootstrap }}
|
||||
</fieldset>
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Save" />
|
||||
<a class="btn btn-default" href="{% url "proposal_detail" proposal.pk %}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,11 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<h3>Leaving {{ proposal.title }}</h3>
|
||||
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<p>Are you sure you wish to leave as a speaker on <b>{{ proposal.title }}</b>?</p>
|
||||
<input type="submit" class="btn btn-primary" value="I am sure" />
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,41 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load bootstrap %}
|
||||
|
||||
{% block body %}
|
||||
<h1>{% trans 'Proposal:' %} {{ proposal.title }}</h1>
|
||||
|
||||
<p>
|
||||
<a href="{% url "proposal_edit" proposal.pk %}">{% trans 'Edit proposal' %}
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<h2>{% trans 'Current Speakers' %}</h2>
|
||||
|
||||
{% for speaker in speakers %}
|
||||
{% if speaker.user %}
|
||||
<p><b>{{ speaker.name }}</b> — {{ speaker.email }}</p>
|
||||
{% else %}
|
||||
<p>{{ speaker.email }} — {% trans 'pending invitation' %}</p>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
|
||||
<h2>{% trans 'Add another speaker' %}</h2>
|
||||
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
{{ add_speaker_form|bootstrap }}
|
||||
<div class="form-action">
|
||||
<input type="submit" value="Add speaker" class="btn btn-primary" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_body %}
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#id_email").focus();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,20 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% load pinax_boxes_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}{% trans "Submit A Proposal" %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% box "proposal_submit" %}
|
||||
|
||||
{% if kinds %}
|
||||
<p>Select what kind of proposal you'd like to submit:</p>
|
||||
|
||||
{% for kind in kinds %}
|
||||
<a href="{% url "proposal_submit_kind" kind.slug %}" class="btn btn-default">{{ kind }}</a>
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
<p>Proposals are not currently open for submission.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,26 +0,0 @@
|
|||
{% extends "symposion/proposals/base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
{% load pinax_boxes_tags %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block page_title %}Submit a Proposal for a {{ kind.name }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% box "example_proposal" %}
|
||||
|
||||
<form method="POST" action="" enctype="multipart/form-data" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{{ proposal_form|bootstrap_horizontal }}
|
||||
</fieldset>
|
||||
<div class="form-actions">
|
||||
<p>
|
||||
You will be able to edit your proposal after it has been submitted. The program committee may ask questions, provide feedback, and even suggest changes to your proposal as part of the review processes.
|
||||
</p>
|
||||
<input class="btn btn-primary" type="submit" name="finish" value="Save" />
|
||||
<!-- <span style="float: right; padding: 4px 6px">or</span> -->
|
||||
<input class="btn btn-default" type="submit" name="add-speakers" value="Save and Add Additional Speakers" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,7 +0,0 @@
|
|||
<b>Body</b> may include the following variables which will be substituted in the email with a value
|
||||
specific to each proposal:
|
||||
<ul>
|
||||
<li><code>{% templatetag openvariable %} proposal.title {% templatetag closevariable %}</code> e.g. {{ proposals.0.title }}
|
||||
<li><code>{% templatetag openvariable %} proposal.kind {% templatetag closevariable %}</code> e.g. {{ proposals.0.kind }}
|
||||
<li><code>{% templatetag openvariable %} proposal.speaker {% templatetag closevariable %}</code> e.g. {{ proposals.0.speaker }}
|
||||
</ul>
|
|
@ -1,37 +0,0 @@
|
|||
{% load i18n %}
|
||||
|
||||
<table class="table table-striped table-bordered table-reviews">
|
||||
<thead>
|
||||
<th>#</th>
|
||||
<th>{% trans "Speaker / Title" %}</th>
|
||||
<th>{% trans "Category" %}</th>
|
||||
<th><i class="fa fa-comment-alt"></i></th>
|
||||
<th>{% trans "+1" %}</th>
|
||||
<th>{% trans "+0" %}</th>
|
||||
<th>{% trans "-0" %}</th>
|
||||
<th>{% trans "-1" %}</th>
|
||||
<th><a href="#" class="tip" title="{% trans "Your Rating" %}"><i class="fa fa-user"></i></a></th>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for proposal in proposals %}
|
||||
<tr class="{{ proposal.user_vote_css }}">
|
||||
<td>{{ proposal.number }}</td>
|
||||
<td>
|
||||
<a href="{% url "review_detail" proposal.pk %}">
|
||||
<small><strong>{{ proposal.speaker }}</strong></small>
|
||||
<br />
|
||||
{{ proposal.title }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ proposal.track }}</td>
|
||||
<td>{{ proposal.comment_count }}</td>
|
||||
<td>{{ proposal.plus_one }}</td>
|
||||
<td>{{ proposal.plus_zero }}</td>
|
||||
<td>{{ proposal.minus_zero }}</td>
|
||||
<td>{{ proposal.minus_one }}</td>
|
||||
<td>{{ proposal.user_vote|default:"" }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,10 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Access Not Permitted</h1>
|
||||
|
||||
<p>
|
||||
Sorry, you do not have permission to access this page. If you
|
||||
believe this is a bug, please contact us immediately.
|
||||
</p>
|
||||
{% endblock %}
|
|
@ -1,112 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load sitetree %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
div.dataTables_length label {
|
||||
float: left;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
div.dataTables_length select {
|
||||
width: 75px;
|
||||
}
|
||||
|
||||
div.dataTables_filter label {
|
||||
float: right;
|
||||
}
|
||||
|
||||
div.dataTables_info {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
div.dataTables_paginate {
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
table.table {
|
||||
clear: both;
|
||||
margin-bottom: 6px !important;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
table.table thead .sorting,
|
||||
table.table thead .sorting_asc,
|
||||
table.table thead .sorting_desc,
|
||||
table.table thead .sorting_asc_disabled,
|
||||
table.table thead .sorting_desc_disabled {
|
||||
cursor: pointer;
|
||||
*cursor: hand;
|
||||
}
|
||||
|
||||
table.dataTable th:active {
|
||||
outline: none;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body_class %}reviews{% endblock %}
|
||||
|
||||
{% block body_outer %}
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
{% block sidebar %}
|
||||
{% for section in review_sections %}
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h3 class="panel-title">{{ section }}</h3>
|
||||
</div>
|
||||
<div class="list-group">
|
||||
<a class="list-group-item review-list" href="{% url "review_section" section.section.slug %}">
|
||||
{% trans "All Reviews" %}
|
||||
</a>
|
||||
{% comment %}
|
||||
<li>
|
||||
<a href="{% url "review_section_assignments" section.section.slug %}">
|
||||
{% trans "Your Assignments" %}
|
||||
</a>
|
||||
</li>
|
||||
{% endcomment %}
|
||||
<a class="list-group-item voting-status" href="{% url "review_status" section.section.slug %}">
|
||||
{% trans "Voting Status" %}
|
||||
</a>
|
||||
{% if request.user.is_staff %}
|
||||
<a class="list-group-item review-results" href="{% url "result_notification" section.section.slug 'accepted' %}">Result Notification</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
{% block body %}
|
||||
{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script src="{{ STATIC_URL }}datatables/js/jquery.dataTables.min.js" type="text/javascript"></script>
|
||||
<script src="{{ STATIC_URL }}tabletools/js/TableTools.min.js" type="text/javascript"></script>
|
||||
<script src="{{ STATIC_URL }}datatables/js/dataTables.bootstrap.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$(".tip").tooltip();
|
||||
$("table.table-reviews").dataTable({
|
||||
"sDom": "<'row'<'col-md-3'l><'col-md-3'T><'col-md-4'f>r>t<'row'<'col-md-3'i><'col-md-5'p>>",
|
||||
"sPaginationType": "bootstrap",
|
||||
"bStateSave": true,
|
||||
"oTableTools": {
|
||||
"aButtons": [
|
||||
"copy",
|
||||
"csv",
|
||||
"print"
|
||||
],
|
||||
"sSwfPath": "{{ STATIC_URL }}tabletools/swf/copy_csv_xls.swf"
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,156 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
|
||||
{% block body_class %}{{ block.super }} review-results{% endblock %}
|
||||
|
||||
{% block extra_style %}
|
||||
<style type="text/css">
|
||||
.table-striped tbody tr.selected td {
|
||||
background-color: #F7F4E6;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<ul class="nav nav-pills">
|
||||
<li{% if status == 'accepted' %} class="active"{% endif %}><a href="{% url "result_notification" section_slug 'accepted' %}">accepted</a>
|
||||
<li{% if status == 'rejected' %} class="active"{% endif %}><a href="{% url "result_notification" section_slug 'rejected' %}">rejected</a>
|
||||
<li{% if status == 'standby' %} class="active"{% endif %}><a href="{% url "result_notification" section_slug 'standby' %}">standby</a>
|
||||
</ul>
|
||||
|
||||
<h1>Result Notification</h1>
|
||||
|
||||
<form method="post" action="{% url "result_notification_prepare" section_slug status %}">
|
||||
|
||||
{% csrf_token %}
|
||||
|
||||
<p>
|
||||
Select one or more proposals (<span class="action-counter">0</span> currently selected)
|
||||
<br/>
|
||||
then pick an email template
|
||||
<select name="notification_template">
|
||||
<option value="">[blank]</option>
|
||||
{% for template in notification_templates %}
|
||||
<option value="{{ template.pk }}">{{ template.label }}</option>
|
||||
{% endfor %}
|
||||
</select>
|
||||
<br/>
|
||||
<button id="next-button" type="submit" class="btn btn-primary" disabled>Next <i class="fa fa-chevron-right"></i></button>
|
||||
</p>
|
||||
|
||||
<table class="table table-striped table-bordered">
|
||||
<thead>
|
||||
<th><input type="checkbox" id="action-toggle"></th>
|
||||
<th>#</th>
|
||||
<th>{% trans "Speaker / Title" %}</th>
|
||||
<th>{% trans "Category" %}</th>
|
||||
<th>{% trans "Status" %}</th>
|
||||
<th>{% trans "Notified?" %}</th>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
{% for proposal in proposals %}
|
||||
<tr>
|
||||
<td><input class="action-select" type="checkbox" name="_selected_action" value="{{ proposal.pk }}"></td>
|
||||
<td>{{ proposal.number }}</td>
|
||||
<td>
|
||||
<a href="{% url "review_detail" proposal.pk %}">
|
||||
<small><strong>{{ proposal.speaker }}</strong></small>
|
||||
<br />
|
||||
{{ proposal.title }}
|
||||
</a>
|
||||
</td>
|
||||
<td>{{ proposal.track }}</td>
|
||||
<td>
|
||||
{% with proposal.result.status as status %}
|
||||
<div class="{{ status }}">
|
||||
{% if status != "undecided" %}
|
||||
<span>{{ status }}</span>
|
||||
{% endif %}
|
||||
</div>
|
||||
{% endwith %}
|
||||
</td>
|
||||
<td>
|
||||
{% if proposal.notifications.exists %}yes{% endif %}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</form>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script type="text/javascript">
|
||||
(function($) {
|
||||
$.fn.actions = function(opts) {
|
||||
var options = $.extend({}, $.fn.actions.defaults, opts);
|
||||
var actionCheckboxes = $(this);
|
||||
checker = function(checked) {
|
||||
$(actionCheckboxes).prop("checked", checked)
|
||||
.parent().parent().toggleClass(options.selectedClass, checked);
|
||||
}
|
||||
updateCounter = function() {
|
||||
var sel = $(actionCheckboxes).filter(":checked").length;
|
||||
$(options.counterContainer).html(sel);
|
||||
$(options.allToggle).prop("checked", function() {
|
||||
if (sel == actionCheckboxes.length) {
|
||||
value = true;
|
||||
} else {
|
||||
value = false;
|
||||
}
|
||||
return value;
|
||||
});
|
||||
if (sel == 0) {
|
||||
$("#next-button").prop("disabled", true);
|
||||
} else {
|
||||
$("#next-button").prop("disabled", false);
|
||||
}
|
||||
}
|
||||
// Check state of checkboxes and reinit state if needed
|
||||
$(this).filter(":checked").each(function(i) {
|
||||
$(this).parent().parent().toggleClass(options.selectedClass);
|
||||
updateCounter();
|
||||
});
|
||||
$(options.allToggle).click(function() {
|
||||
checker($(this).prop("checked"));
|
||||
updateCounter();
|
||||
});
|
||||
lastChecked = null;
|
||||
$(actionCheckboxes).click(function(event) {
|
||||
if (!event) { var event = window.event; }
|
||||
var target = event.target ? event.target : event.srcElement;
|
||||
if (lastChecked && $.data(lastChecked) != $.data(target) && event.shiftKey == true) {
|
||||
var inrange = false;
|
||||
$(lastChecked).prop("checked", target.checked)
|
||||
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||
$(actionCheckboxes).each(function() {
|
||||
if ($.data(this) == $.data(lastChecked) || $.data(this) == $.data(target)) {
|
||||
inrange = (inrange) ? false : true;
|
||||
}
|
||||
if (inrange) {
|
||||
$(this).prop("checked", target.checked)
|
||||
.parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||
}
|
||||
});
|
||||
}
|
||||
$(target).parent().parent().toggleClass(options.selectedClass, target.checked);
|
||||
lastChecked = target;
|
||||
updateCounter();
|
||||
});
|
||||
}
|
||||
/* Setup plugin defaults */
|
||||
$.fn.actions.defaults = {
|
||||
counterContainer: "span.action-counter",
|
||||
allToggle: "#action-toggle",
|
||||
selectedClass: "selected"
|
||||
}
|
||||
})($);
|
||||
$(function() {
|
||||
$("tr input.action-select").actions();
|
||||
});
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,49 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Result Notification Prepare</h1>
|
||||
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<h2>Proposals</h2>
|
||||
<table class="table table-striped table-compact">
|
||||
{% for proposal in proposals %}
|
||||
<tr>
|
||||
<td>
|
||||
<strong>{{ proposal.speaker }}</strong> ({{ proposal.speaker.email }})
|
||||
<br />
|
||||
{{ proposal.title }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
<h2>Email</h2>
|
||||
|
||||
<form method="post" action="{% url "result_notification_send" section_slug status %}">
|
||||
|
||||
{% csrf_token %}
|
||||
|
||||
<label>From Address</label>
|
||||
<input type="text" name="from_address" class="span5" value="{{ notification_template.from_address }}" />
|
||||
<br/>
|
||||
<label>Subject</label>
|
||||
<input type="text" name="subject" class="span5" value="{{ notification_template.subject }}" />
|
||||
<br/>
|
||||
<label>Body</label>
|
||||
<textarea class="span5" rows="10" name="body">{{ notification_template.body }}</textarea>
|
||||
<br/>
|
||||
<input type="hidden" name="notification_template" value="{{ notification_template.pk }}" />
|
||||
<input type="hidden" name="proposal_pks" value="{{ proposal_pks }}" />
|
||||
|
||||
{% include "symposion/reviews/_result_notification_prepare_help.html" %}
|
||||
|
||||
<button type="submit" class="btn btn-primary">Send {{ proposals|length }} Email{{ proposals|length|pluralize }}</button>
|
||||
<a class="btn" href="{% url "result_notification" section_slug status %}">Cancel</a>
|
||||
</form>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,56 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Reviewers</h1>
|
||||
|
||||
<table class="table table-striped">
|
||||
<tr>
|
||||
<th>
|
||||
Reviewer
|
||||
</th>
|
||||
<th>
|
||||
Proposals<br/>Reviewed
|
||||
</td>
|
||||
<th>
|
||||
Comments
|
||||
</th>
|
||||
<th>
|
||||
+1
|
||||
</th>
|
||||
<th>
|
||||
+0
|
||||
</th>
|
||||
<th>
|
||||
−0
|
||||
</th>
|
||||
<th>
|
||||
−1
|
||||
</th>
|
||||
</tr>
|
||||
{% for reviewer in reviewers %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url "review_list_user" section_slug reviewer.pk %}">{{ reviewer.get_full_name }}</a>
|
||||
</td>
|
||||
<td>
|
||||
{{ reviewer.total_votes }}
|
||||
</td>
|
||||
<td>
|
||||
{{ reviewer.comment_count }}
|
||||
</td>
|
||||
<td>
|
||||
{{ reviewer.plus_one }}
|
||||
</td>
|
||||
<td>
|
||||
{{ reviewer.plus_zero }}
|
||||
</td>
|
||||
<td>
|
||||
{{ reviewer.minus_zero }}
|
||||
</td>
|
||||
<td>
|
||||
{{ reviewer.minus_one }}
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endblock %}
|
|
@ -1,32 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Review Assignments</h1>
|
||||
|
||||
{% if assignments %}
|
||||
<table>
|
||||
<tr>
|
||||
<th>Proposal</th>
|
||||
<th>Opted out</th>
|
||||
<th>Opt out</th>
|
||||
</tr>
|
||||
{% for assignment in assignments %}
|
||||
<tr>
|
||||
<td>
|
||||
<a href="{% url review_detail assignment.proposal.pk %}">
|
||||
{{ assignment.proposal.title }}
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<form method="post" action="{% url "review_assignment_opt_out" assignment.pk %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" value="Opt-out" />
|
||||
</form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% else %}
|
||||
<p>You do not have any assignments.</p>
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -1,15 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
<h1>Bulk Accept</h1>
|
||||
<form action="" method="POST" class="uniForm" accept-charset="utf-8">
|
||||
{% csrf_token %}
|
||||
{{ form|bootstrap }}
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" name="submit" value="submit" />
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,2 +0,0 @@
|
|||
{{ proposal }}: proposal obj
|
||||
{{ form }}: comment form obj
|
|
@ -1,186 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load bootstrap %}
|
||||
{% load account_tags %}
|
||||
|
||||
|
||||
{% block body %}
|
||||
{% if request.user.is_staff %}
|
||||
<div class="pull-right">
|
||||
<form class="result-form form-inline" method="POST" action="">
|
||||
{% csrf_token %}
|
||||
<div class="btn-group">
|
||||
{% if proposal.result.status == "accepted" %}
|
||||
<a class="btn dropdown-toggle btn-success" data-toggle="dropdown" href="#">Accepted <span class="caret"></span></a>
|
||||
<div class="dropdown-menu pull-right" style="width: 200px; padding-left: 10px;">
|
||||
<div class="btn-group">
|
||||
<input type="submit" name="result_submit" value="reject" class="btn btn-xs btn-danger" />
|
||||
<input type="submit" name="result_submit" value="standby" class="btn btn-xs" />
|
||||
<input type="submit" name="result_submit" value="undecide" class="btn btn-default btn-xs" />
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if proposal.result.status == "rejected" %}
|
||||
<a class="btn dropdown-toggle btn-danger" data-toggle="dropdown" href="#">Rejected <span class="caret"></span></a>
|
||||
<div class="dropdown-menu pull-right" style="width: 200px; padding-left: 10px;">
|
||||
<div class="btn-group">
|
||||
<input type="submit" name="result_submit" value="accept" class="btn btn-xs btn-success" />
|
||||
<input type="submit" name="result_submit" value="standby" class="btn btn-xs" />
|
||||
<input type="submit" name="result_submit" value="undecide" class="btn btn-default btn-xs" />
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% if proposal.result.status == "standby" %}
|
||||
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Standby <span class="caret"></span></a>
|
||||
<div class="dropdown-menu pull-right" style="width: 200px; padding-left: 10px;">
|
||||
<div class="btn-group">
|
||||
<input type="submit" name="result_submit" value="accept" class="btn btn-xs btn-success" />
|
||||
<input type="submit" name="result_submit" value="reject" class="btn btn-xs btn-danger" />
|
||||
<input type="submit" name="result_submit" value="undecide" class="btn btn-default btn-xs" />
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
<a class="btn dropdown-toggle" data-toggle="dropdown" href="#">Undecided <span class="caret"></span></a>
|
||||
<div class="dropdown-menu pull-right" style="width: 200px; padding-left: 10px;">
|
||||
<div class="btn-group">
|
||||
<input type="submit" name="result_submit" value="accept" class="btn btn-xs btn-success" />
|
||||
<input type="submit" name="result_submit" value="reject" class="btn btn-xs btn-danger" />
|
||||
<input type="submit" name="result_submit" value="standby" class="btn btn-default btn-xs" />
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<h3>#{{ proposal.number }}: {{ proposal.title }} ({{ proposal.speaker }})</h3>
|
||||
|
||||
<div class="tabbable">
|
||||
<ul class="nav nav-tabs">
|
||||
<li class="active"><a href="#proposal-detail" data-toggle="tab">{% trans "Proposal Details" %}</a></li>
|
||||
<li><a href="#proposal-reviews" data-toggle="tab">{% trans "Reviews" %} <span class="badge">{{ reviews|length }}</span></a></li>
|
||||
<li><a href="#proposal-feedback" data-toggle="tab">{% trans "Speaker Feedback" %} <span class="badge">{{ proposal.messages.all|length }}</span></a></li>
|
||||
</ul>
|
||||
<div class="tab-content">
|
||||
<div class="tab-pane active" id="proposal-detail">
|
||||
{% include "symposion/proposals/_proposal_fields.html" %}
|
||||
</div>
|
||||
<div class="tab-pane" id="proposal-reviews">
|
||||
|
||||
<h4>{% trans "Current Results" %}</h4>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<th>+1 votes</th>
|
||||
<th>+0 votes</th>
|
||||
<th>-0 votes</th>
|
||||
<th>-1 votes</th>
|
||||
<th>{% trans "Total Responses" %}
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ proposal.plus_one }}</td>
|
||||
<td>{{ proposal.plus_zero }}</td>
|
||||
<td>{{ proposal.minus_zero }}</td>
|
||||
<td>{{ proposal.minus_one }}</td>
|
||||
<td>{{ proposal.total_votes }}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<hr />
|
||||
|
||||
{% if review_form %}
|
||||
<form method="POST" action="" class="review-form">
|
||||
<legend>{% trans "Submit Review" %}</legend>
|
||||
<p>Enter your vote and any comment to go along with it. You can revise your vote or comment multiple times with an existing vote (your previously recorded score will be replaced during calculations). <b>Your vote and comments are not public and will only be viewable by other reviewers.</b></p>
|
||||
{% csrf_token %}
|
||||
{{ review_form|bootstrap }}
|
||||
<div class="form-action">
|
||||
<input type="submit" class="btn btn-primary" name="vote_submit" value="Submit Review" />
|
||||
</div>
|
||||
</form>
|
||||
{% else %}
|
||||
<p>You do not have permission to vote on this proposal.</p>
|
||||
{% endif %}
|
||||
|
||||
{% if reviews %}
|
||||
<h5>Review Comments</h5>
|
||||
{% for review in reviews %}
|
||||
<div class="review-box">
|
||||
<div class="vote pull-left">
|
||||
<span>{{ review.vote }}</span>
|
||||
</div>
|
||||
{% if is_manager %}
|
||||
<div class="pull-right">
|
||||
<form class="form-inline" action="{% url "review_delete" review.id %}" method="POST">
|
||||
{% csrf_token %}
|
||||
<button class="btn btn-xs btn-danger" type="submit">Delete</button>
|
||||
</form>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="review-content">
|
||||
<b>{% user_display review.user %}</b>
|
||||
{{ review.submitted_at|timesince }} ago <br />
|
||||
{{ review.comment|safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="tab-pane" id="proposal-feedback">
|
||||
{% if review_messages %}
|
||||
<h3>{% trans "Conversation with the submitter" %}</h3>
|
||||
{% for message in review_messages %}
|
||||
<div class="comment-box">
|
||||
<div class="commment-content">
|
||||
<b>{% user_display message.user %}</b>
|
||||
{{ message.submitted_at|timesince }} ago <br />
|
||||
{{ message.message|safe }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
<hr />
|
||||
{% endif %}
|
||||
|
||||
<form action="" method="POST"accept-charset="utf-8">
|
||||
<legend>{% trans "Send a message" %}</legend>
|
||||
<p>
|
||||
{% blocktrans %}
|
||||
If you'd like to communicate with the submitter, use the following form and he or she will be
|
||||
notified and given the opportunity to respond.
|
||||
{% endblocktrans %}
|
||||
</p>
|
||||
{% csrf_token %}
|
||||
{{ message_form|bootstrap }}
|
||||
<div class="form-actions">
|
||||
<input type="submit" class="btn btn-primary" name="message_submit" value="Send Message" />
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script src="{{ STATIC_URL }}symposion/js/jquery.history.js"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
var History = window.History;
|
||||
|
||||
$(window).bind("anchorchange", function() {
|
||||
$(".nav-tabs a[href='" + location.hash + "']").click();
|
||||
});
|
||||
|
||||
$('#.nav-tabs a[data-toggle="tab"]').on('shown', function (e) {
|
||||
if (History.enabled) {
|
||||
History.pushState(null, null, $(e.target).attr("href"));
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
|
@ -1,17 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
|
||||
{% block body_class %}{{ block.super }} review-list{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h3>{{ section }}</h3>
|
||||
{% if reviewed == 'all_reviews' %}
|
||||
<h4>All proposals</h4>
|
||||
{% elif reviewed == 'user_reviewed' %}
|
||||
<h4>Proposals you have reviewed</h4>
|
||||
{% else %}
|
||||
<h4>Proposals you have not yet reviewed</h4>
|
||||
{% endif %}
|
||||
|
||||
{% include "symposion/reviews/_review_table.html" %}
|
||||
{% endblock %}
|
|
@ -1,77 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
|
||||
{% block body_class %}review{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Proposal Review</h1>
|
||||
|
||||
<div class="proposal">
|
||||
<h2>{{ proposal.title }}</h2>
|
||||
|
||||
<p>
|
||||
{% if proposal.cancelled %}
|
||||
Cancelled
|
||||
{% endif %}
|
||||
</p>
|
||||
|
||||
<div>
|
||||
{{ proposal.description }}
|
||||
</div>
|
||||
|
||||
<p><b>Type</b>: {{ proposal.get_session_type_display }}</p>
|
||||
|
||||
<h3>Abstract</h3>
|
||||
<div class="abstract">
|
||||
{{ proposal.abstract_html|safe }}
|
||||
</div>
|
||||
|
||||
<p><b>Audience level</b>: {{ proposal.get_audience_level_display }}</p>
|
||||
|
||||
<p><b>Submitting speaker</b>: {{ proposal.speaker }}</p> {# @@@ bio? #}
|
||||
|
||||
{% if proposal.additional_speakers.all %}
|
||||
<p><b>Additional speakers</b>:</p>
|
||||
<ul>
|
||||
{% for speaker in proposal.additional_speakers.all %}
|
||||
{% if speaker.user %}
|
||||
<li><b>{{ speaker.name }}</b> — {{ speaker.email }}</li>
|
||||
{% else %}
|
||||
<li>{{ speaker.email }} — pending invitation</li>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
<h3>Additional Notes (private from submitter)</h3>
|
||||
<div class="additional_notes">
|
||||
{{ proposal.additional_notes }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2>Review</h2>
|
||||
|
||||
<form method="POST" action="{% url "review_review" proposal.pk %}" class="form">
|
||||
{% csrf_token %}
|
||||
<fieldset class="inlineLabels">
|
||||
{{ review_form|bootstrap }}
|
||||
<div class="form_block">
|
||||
<input type="submit" value="Submit" />
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
<h2>Comment</h2>
|
||||
|
||||
<form method="POST" action="{% url "review_comment" proposal.pk %}" class="form">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{{ comment_form|bootstrap }}
|
||||
<div class="form_block">
|
||||
<input type="submit" value="Submit" />
|
||||
</div>
|
||||
</fieldset>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
|
@ -1,85 +0,0 @@
|
|||
{% extends "symposion/reviews/base.html" %}
|
||||
|
||||
{% block body_class %}{{ block.super }} voting-status {{ key }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h1>Voting Status ({{ section_slug }})</h1>
|
||||
|
||||
{% if key %}
|
||||
<br />
|
||||
<div class="btn-group">
|
||||
<a class="btn btn-default positive" href="{% url "review_status" section_slug "positive" %}">Positive</a>
|
||||
<a class="btn btn-default negative" href="{% url "review_status" section_slug "negative" %}">Negative</a>
|
||||
<a class="btn btn-default indifferent" href="{% url "review_status" section_slug "indifferent" %}">Indifferent</a>
|
||||
<a class="btn btn-default controversial" href="{% url "review_status" section_slug "controversial" %}">Controversial</a>
|
||||
<a class="btn btn-default too_few" href="{% url "review_status" section_slug "too_few" %}">Too Few</a>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
{% if key == "positive" %}
|
||||
<h3>Positive
|
||||
<small>proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one +1 and no −1s</small></h3>
|
||||
{% endif %}
|
||||
{% if key == "negative" %}
|
||||
<h3>Negative
|
||||
<small>proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one −1 and no +1s</small></h3>
|
||||
{% endif %}
|
||||
{% if key == "indifferent" %}
|
||||
<h3>Indifferent
|
||||
<small>proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and neither a +1 or a −1</small></h3>
|
||||
{% endif %}
|
||||
{% if key == "controversial" %}
|
||||
<h3>Controversial
|
||||
<small>proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and both a +1 and −1</small></h3>
|
||||
{% endif %}
|
||||
{% if key == "too_few" %}
|
||||
<h3>Too Few Reviews
|
||||
<small>proposals with fewer than {{ vote_threshold }} vote{{ vote_threshold|pluralize }}</small></h3>
|
||||
{% endif %}
|
||||
|
||||
{% include "symposion/reviews/_review_table.html" %}
|
||||
|
||||
</div>
|
||||
{% else %}
|
||||
<p>Reviews are placed into one of five buckets depending on the state of their votes:</p>
|
||||
|
||||
<dl>
|
||||
<dt>
|
||||
<a href="{% url "review_status" section_slug "positive" %}">Positive</a>
|
||||
<span class="badge">{{ proposals.positive|length }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one +1 and no −1s
|
||||
</dd>
|
||||
<dt>
|
||||
<a href="{% url "review_status" section_slug "negative" %}">Negative</a>
|
||||
<span class="badge">{{ proposals.negative|length }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and at least one −1 and no +1s
|
||||
</dd>
|
||||
<dt>
|
||||
<a href="{% url "review_status" section_slug "indifferent" %}">Indifferent</a>
|
||||
<span class="badge">{{ proposals.indifferent|length }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and neither a +1 or a −1
|
||||
</dd>
|
||||
<dt>
|
||||
<a href="{% url "review_status" section_slug "controversial" %}">Controversial</a>
|
||||
<span class="badge">{{ proposals.controversial|length }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
proposals with at least {{ vote_threshold }} vote{{ vote_threshold|pluralize }} and both a +1 and −1
|
||||
</dd>
|
||||
<dt>
|
||||
<a href="{% url "review_status" section_slug "too_few" %}">Too Few Reviews</a>
|
||||
<span class="badge">{{ proposals.too_few|length }}</span>
|
||||
</dt>
|
||||
<dd>
|
||||
proposals with fewer than {{ vote_threshold }} vote{{ vote_threshold|pluralize }}
|
||||
</dd>
|
||||
</dl>
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
|
@ -1,39 +0,0 @@
|
|||
<table class="calendar table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="time"> </th>
|
||||
{% for room in timetable.rooms %}
|
||||
<th>{{ room.name }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in timetable %}
|
||||
<tr>
|
||||
<td class="time">{{ row.time|date:"h:iA" }}</td>
|
||||
{% for slot in row.slots %}
|
||||
<td class="slot slot-{{ slot.kind.label }}" colspan="{{ slot.colspan }}" rowspan="{{ slot.rowspan }}">
|
||||
{% if slot.kind.label == "talk" or slot.kind.label == "tutorial" %}
|
||||
{% if not slot.content %}
|
||||
<a class="btn btn-xs edit-slot" data-action="{% url "schedule_slot_edit" schedule.section.slug slot.pk %}" href="#">+</a>
|
||||
{% else %}
|
||||
<span class="title"><a class="edit-slot" data-action="{% url "schedule_slot_edit" schedule.section.slug slot.pk %}" href="#">{{ slot.content.title }}</a></span>
|
||||
<span class="speaker">{{ slot.content.speaker }}</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if slot.content_override.raw %}
|
||||
{{ slot.content_override.rendered|safe }}
|
||||
{% else %}
|
||||
{{ slot.kind.label }}
|
||||
{% endif %}
|
||||
— <a class="edit-slot" data-action="{% url "schedule_slot_edit" schedule.section.slug slot.pk %}" href="#">edit</a>
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% if forloop.last %}
|
||||
<td colspan="{{ timetable.rooms|length }}"></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,41 +0,0 @@
|
|||
<table class="calendar table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="time"> </th>
|
||||
{% for room in timetable.rooms %}
|
||||
<th>{{ room.name }}</th>
|
||||
{% endfor %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for row in timetable %}
|
||||
<tr>
|
||||
<td class="time">{{ row.time|date:"h:iA" }}</td>
|
||||
{% for slot in row.slots %}
|
||||
<td class="slot slot-{{ slot.kind.label }}" colspan="{{ slot.colspan }}" rowspan="{{ slot.rowspan }}">
|
||||
{% if slot.kind.label == "talk" or slot.kind.label == "tutorial" %}
|
||||
{% if not slot.content %}
|
||||
{% else %}
|
||||
<span class="title">
|
||||
<a href="{% url "schedule_presentation_detail" slot.content.pk %}">{{ slot.content.title }}</a>
|
||||
</span>
|
||||
<span class="speaker">
|
||||
{{ slot.content.speakers|join:", " }}
|
||||
</span>
|
||||
{% endif %}
|
||||
{% else %}
|
||||
{% if slot.content_override.raw %}
|
||||
{{ slot.content_override.rendered|safe }}
|
||||
{% else %}
|
||||
{{ slot.kind.label }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endfor %}
|
||||
{% if forloop.last %}
|
||||
<td colspan="{{ timetable.rooms|length }}"></td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
|
@ -1,14 +0,0 @@
|
|||
{% load i18n bootstrap %}
|
||||
<form id="slotEditForm" class="modal-form" method="POST" action="{% url "schedule_slot_edit" slug slot.pk %}">
|
||||
<div class="modal-header">
|
||||
<a class="close" data-dismiss="modal">×</a>
|
||||
<h3>{% trans "Edit Slot" %}</h3>
|
||||
</div>
|
||||
<div class="modal-body" style="height:350px">
|
||||
{% csrf_token %}
|
||||
{{ form|bootstrap }}
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
</div>
|
||||
</form>
|
|
@ -1,35 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load sitetree %}
|
||||
|
||||
{% block head_title %}Presentation: {{ presentation.title }}{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{% sitetree_breadcrumbs from "main" %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% if presentation.slot %}
|
||||
<h4>
|
||||
{{ presentation.slot.day.date|date:"l" }}
|
||||
{{ presentation.slot.start}}–{{ presentation.slot.end }}
|
||||
</h4>
|
||||
{% endif %}
|
||||
<h2>{{ presentation.title }}</h2>
|
||||
|
||||
<h4>
|
||||
{% for speaker in presentation.speakers %}
|
||||
<a href="{% url "speaker_profile" speaker.pk %}">{{ speaker }}</a>{% if not forloop.last %}, {% endif %}{% endfor %}
|
||||
</h4>
|
||||
|
||||
<dl class="dl-horizontal">
|
||||
<dt>Audience level:</dt>
|
||||
<dd style="margin-bottom: 0;">{{ presentation.proposal.get_audience_level_display }}</dd>
|
||||
</dl>
|
||||
|
||||
<h3>Description</h3>
|
||||
|
||||
<div class="description">{{ presentation.description }}</div>
|
||||
|
||||
<h3>Abstract</h3>
|
||||
|
||||
<div class="abstract">{{ presentation.abstract|safe }}</div>
|
||||
{% endblock %}
|
|
@ -1,31 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load pinax_boxes_tags %}
|
||||
{% load cache %}
|
||||
|
||||
{% block head_title %}Conference Schedule{% endblock %}
|
||||
|
||||
{% block body_class %}full{% endblock %}
|
||||
|
||||
{% block right %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body_outer %}
|
||||
<div class="page-head">
|
||||
<h1>Conference Schedule</h1>
|
||||
{% block breadcrumbs %}{% endblock %}
|
||||
</div>
|
||||
{% box "schedule_top" %}
|
||||
|
||||
{% for section in sections %}
|
||||
{% cache 600 "schedule-table" section.schedule.section %}
|
||||
{% for timetable in section.days %}
|
||||
<h3>{{ section.schedule.section.name }} — {{ timetable.day.date }}</h3>
|
||||
{% include "symposion/schedule/_grid.html" %}
|
||||
{% endfor %}
|
||||
{% endcache %}
|
||||
{% endfor %}
|
||||
|
||||
{% box "schedule_bottom" %}
|
||||
{% endblock %}
|
|
@ -1,30 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load pinax_boxes_tags %}
|
||||
{% load cache %}
|
||||
{% load sitetree %}
|
||||
|
||||
{% block head_title %}Conference Schedule{% endblock %}
|
||||
|
||||
{% block body_class %}full{% endblock %}
|
||||
|
||||
{% block right %}
|
||||
{% endblock %}
|
||||
|
||||
{% block body_outer %}
|
||||
<div class="page-head">
|
||||
<h1>{{ schedule.section }} Schedule</h1>
|
||||
{% block breadcrumbs %}{% sitetree_breadcrumbs from "main" %}{% endblock %}
|
||||
</div>
|
||||
{% box "schedule_top_"|add:schedule.section.name|slugify %}
|
||||
|
||||
{% cache 600 "schedule-table" schedule.section %}
|
||||
{% for timetable in days %}
|
||||
<h3>{{ timetable.day.date }}</h3>
|
||||
{% include "symposion/schedule/_grid.html" %}
|
||||
{% endfor %}
|
||||
{% endcache %}
|
||||
|
||||
{% box "schedule_bottom" %}
|
||||
{% endblock %}
|
|
@ -1,58 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
|
||||
{% block head_title %}Conference Schedule Edit{% endblock %}
|
||||
|
||||
{% block body_class %}full{% endblock %}
|
||||
|
||||
{% block right %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_head %}
|
||||
<link rel="stylesheet" href="{{ STATIC_URL }}chosen/chosen.css" />
|
||||
{% endblock %}
|
||||
|
||||
{% block body_outer %}
|
||||
<h1>Schedule Edit</h1>
|
||||
|
||||
{% for timetable in days %}
|
||||
<h2>{{ timetable.day.date }}</h2>
|
||||
{% include "symposion/schedule/_edit_grid.html" %}
|
||||
{% endfor %}
|
||||
<form id="schedule-builder" action="." method="post" enctype="multipart/form-data">{% csrf_token %}
|
||||
{{ form.as_p }}
|
||||
<input type="submit" name="submit" value="Submit" />
|
||||
<input type="submit" id="delete" name="delete" value="Delete Schedule" />
|
||||
</form>
|
||||
<div class="modal fade hide in" id="slotEditModal"></div>
|
||||
{% endblock %}
|
||||
|
||||
{% block extra_script %}
|
||||
<script src="{{ STATIC_URL }}chosen/chosen.jquery.min.js" type="text/javascript"></script>
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("a.edit-slot").click(function(e) {
|
||||
$("#slotEditModal").load($(this).data("action"), function() {
|
||||
$("#id_presentation").chosen();
|
||||
$("#slotEditModal").modal("show");
|
||||
});
|
||||
e.preventDefault();
|
||||
});
|
||||
});
|
||||
$(function() {
|
||||
//submit event handler
|
||||
$("form#schedule-builder :submit").click(function(e) {
|
||||
var name = this.name;
|
||||
if(name == 'delete') {
|
||||
if (!confirm("Are you sure you want to delete the schedule?"))
|
||||
{
|
||||
e.preventDefault();
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock %}
|
|
@ -1,51 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load cache %}
|
||||
{% load sitetree %}
|
||||
|
||||
{% block head_title %}Presentation Listing{% endblock %}
|
||||
|
||||
{% block extra_head %}
|
||||
<style>
|
||||
.presentation {
|
||||
|
||||
}
|
||||
.presentation h3 {
|
||||
line-height: 1.1em;
|
||||
font-weight: bold;
|
||||
}
|
||||
.presentation h4 {
|
||||
|
||||
}
|
||||
.presentation p {
|
||||
margin-bottom: 0.5em;
|
||||
line-height: 1.2em;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block breadcrumbs %}{% sitetree_breadcrumbs from "main" %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h2>Accepted {{ schedule.section.name }}</h2>
|
||||
{% cache 600 "schedule-list" schedule.section.name %}
|
||||
{% for presentation in presentations %}
|
||||
<div class="row">
|
||||
<div class="col-md-8 presentation well">
|
||||
<h3><a href="{% url "schedule_presentation_detail" presentation.pk %}">{{ presentation.title }}</a></h3>
|
||||
<h4>{{ presentation.speakers|join:", " }}</h4>
|
||||
{{ presentation.description }}
|
||||
{% if presentation.slot %}
|
||||
<h4>
|
||||
{{ presentation.slot.day.date|date:"l" }}
|
||||
{{ presentation.slot.start}}–{{ presentation.slot.end }}
|
||||
in
|
||||
{{ presentation.slot.rooms|join:", " }}
|
||||
</h4>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endcache %}
|
||||
{% endblock %}
|
|
@ -1 +0,0 @@
|
|||
{% extends "site_base_onecolumn.html" %}
|
|
@ -1,23 +0,0 @@
|
|||
{% extends "symposion/speakers/base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
{% load pinax_boxes_tags %}
|
||||
|
||||
{% block page_title %}{% trans "Create Speaker Profile" %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% box "speaker-profile" %}
|
||||
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<legend>{% trans "Create Speaker Profile" %}</legend>
|
||||
<fieldset>
|
||||
{{ speaker_form|bootstrap }}
|
||||
</fieldset>
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Save" />
|
||||
<a class="btn btn-default" href="{% url "dashboard" %}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,23 +0,0 @@
|
|||
{% extends "symposion/speakers/base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
{% load pinax_boxes_tags %}
|
||||
|
||||
{% block page_title %}{% trans "Edit Speaker Profile" %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
{% box "speaker-profile" %}
|
||||
|
||||
<form method="POST" action="" enctype="multipart/form-data">
|
||||
{% csrf_token %}
|
||||
<legend>{% trans "Edit Speaker Profile" %}</legend>
|
||||
<fieldset>
|
||||
{{ speaker_form|bootstrap }}
|
||||
</fieldset>
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Save" />
|
||||
<a class="btn btn-default" href="{% url "dashboard" %}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,41 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load i18n %}
|
||||
{% load thumbnail %}
|
||||
|
||||
|
||||
{% block head_title %}{{ speaker.name }}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
{% if speaker.photo %}
|
||||
<img src="{% thumbnail speaker.photo '128x128' %}" alt="{{ speaker.name }}" />
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="col-md-6">
|
||||
{% if speaker.user == request.user or request.user.is_staff %}
|
||||
<a class="btn btn-default pull-right" href="{% url "speaker_edit" speaker.pk %}">Edit</a>
|
||||
{% endif %}
|
||||
<h1>{{ speaker.name }}</h1>
|
||||
<div class="bio">{{ speaker.biography|safe }}</div>
|
||||
|
||||
<h2>Presentations</h2>
|
||||
{% for presentation in presentations %}
|
||||
<h3><a href="{% url "schedule_presentation_detail" presentation.pk %}">{{ presentation.title }}</a></h3>
|
||||
{% if presentation.slot %}
|
||||
<p>
|
||||
{{ presentation.slot.day.date|date:"l" }}
|
||||
{{ presentation.slot.start}}–{{ presentation.slot.end }}
|
||||
in
|
||||
{{ presentation.slot.rooms|join:", " }}
|
||||
</p>
|
||||
{% endif %}
|
||||
{% empty %}
|
||||
<p>No presentations. This page is only visible to staff until there is a presentation.<p>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,12 +0,0 @@
|
|||
{% load sponsorship_tags %}
|
||||
|
||||
{% sponsor_levels as levels %}
|
||||
|
||||
<div class="sponsor-list">
|
||||
{% for level in levels %}
|
||||
<h3>{{ level.name }}</h3>
|
||||
{% for sponsor in level.sponsors %}
|
||||
{% include "symposion/sponsorship/_sponsor_link.html" with sponsor=sponsor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
|
@ -1,11 +0,0 @@
|
|||
{% load thumbnail %}
|
||||
|
||||
{% spaceless %}
|
||||
<a href="{{ sponsor.external_url }}">
|
||||
{% if dimensions %}
|
||||
<img id="sponsor_{{ sponsor.pk }}" src="{% thumbnail sponsor.logo dimensions %}" alt="{{ sponsor.name }}" />
|
||||
{% else %}
|
||||
<img id="sponsor_{{ sponsor.pk }}" src="{% thumbnail sponsor.logo '150x150' %}" alt="{{ sponsor.name }}" />
|
||||
{% endif %}
|
||||
</a>
|
||||
{% endspaceless %}
|
|
@ -1,14 +0,0 @@
|
|||
{% load sponsorship_tags %}
|
||||
|
||||
{% sponsor_levels as levels %}
|
||||
|
||||
<div class="sponsor-list">
|
||||
{% for level in levels %}
|
||||
<h3>{{ level.name }}</h3>
|
||||
{% for sponsor in level.sponsors %}
|
||||
<div>
|
||||
{% include "symposion/sponsorship/_sponsor_link.html" with sponsor=sponsor %}
|
||||
</div>
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
</div>
|
|
@ -1,9 +0,0 @@
|
|||
{% load sponsorship_tags %}
|
||||
|
||||
{% sponsors as sponsors %}
|
||||
|
||||
<div class="sponsor-wall">
|
||||
{% for sponsor in sponsors %}
|
||||
{% include "symposion/sponsorship/_sponsor_link.html" with sponsor=sponsor %}
|
||||
{% endfor %}
|
||||
</div>
|
|
@ -1,22 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
{% load pinax_boxes_tags %}
|
||||
|
||||
{% block head_title %}{% trans "Add a Sponsor" %}{% endblock %}
|
||||
|
||||
{% block body_class %}sponsorships{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<form method="POST" action="{% url "sponsor_add" %}" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<legend>{% trans "Add a Sponsor" %}</legend>
|
||||
{{ form|bootstrap_horizontal }}
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Add" />
|
||||
<a class="btn btn-default" href="{% url "dashboard" %}">Cancel</a>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
|
@ -1,28 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
{% load pinax_boxes_tags %}
|
||||
|
||||
{% block head_title %}{% trans "Apply to be a Sponsor" %}{% endblock %}
|
||||
|
||||
{% block body_class %}sponsorships{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
|
||||
{% box "sponsorship-apply" %}
|
||||
|
||||
<form method="POST" action="" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<legend>{% trans "Apply to Be a Sponsor" %}</legend>
|
||||
{{ form|bootstrap_horizontal }}
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Apply" />
|
||||
<a class="btn btn-default" href="{% url "dashboard" %}">Cancel</a>
|
||||
<p class="help-block">
|
||||
<small>By submitting this sponsor application you are agreeing to the <a href="{% url "pages_page" "sponsor/terms/" %}" target="_blank">terms and conditions</a>.</small>
|
||||
</p>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
{% endblock %}
|
|
@ -1,40 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block head_title %}{{ sponsor }}{% endblock %}
|
||||
|
||||
{% block page_title %}{% trans "Sponsorship" %}{% endblock %}
|
||||
|
||||
{% block body %}
|
||||
<h2>{{ sponsor.name }} ({{ sponsor.level }})</h2>
|
||||
|
||||
<form enctype="multipart/form-data" method="POST" action="" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<fieldset>
|
||||
{{ form|bootstrap_horizontal }}
|
||||
</fieldset>
|
||||
|
||||
<h3>{{ sponsor.level }} Sponsor Benefits</h3>
|
||||
|
||||
{{ formset.management_form }}
|
||||
{{ formset.non_form_errors }}
|
||||
|
||||
{% for form in formset.forms %}
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{ form.instance.benefit }}</label>
|
||||
<div class="controls">
|
||||
{{ form }}
|
||||
<p class="help-block">{{ form.instance.benefit.description }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Save" />
|
||||
<a class="btn btn-default" href="{% url "dashboard" %}">Cancel</a>
|
||||
</div>
|
||||
|
||||
</form>
|
||||
{% endblock %}
|
|
@ -1,40 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load sponsorship_tags %}
|
||||
{% load thumbnail %}
|
||||
{% load i18n %}
|
||||
|
||||
{% block head_title %}{% trans "About Our Sponsors" %}{% endblock %}
|
||||
|
||||
{% block body_class %}sponsorships{% endblock %}
|
||||
|
||||
{% block body_outer %}
|
||||
<h1>{% trans "About Our Sponsors" %}</h1>
|
||||
<a href="{% url "pages_page" "sponsors/prospectus/" %}" class="btn">Learn how to become a sponsor <span class="arrow"></span></a>
|
||||
|
||||
{% sponsor_levels as levels %}
|
||||
{% for level in levels %}
|
||||
{% if level.sponsors %}
|
||||
<h3>{{ level.name }}</h3>
|
||||
|
||||
{% for sponsor in level.sponsors %}
|
||||
{% if sponsor.website_logo %}
|
||||
<div class="row">
|
||||
<div class="col-md-2">
|
||||
<h2>
|
||||
<a href="{{ sponsor.external_url }}">
|
||||
<img src="{% thumbnail sponsor.website_logo '150x80' %}" alt="{{ sponsor.name }}" />
|
||||
</a>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="col-md-10">
|
||||
<h5>{{ sponsor.name }}</h5>
|
||||
<p><a href="{{ sponsor.external_url }}">{{ sponsor.external_url }}</a></p>
|
||||
<p>{{ sponsor.listing_text|urlize|linebreaks }}</p>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endblock %}
|
|
@ -1,99 +0,0 @@
|
|||
{% extends "site_base.html" %}
|
||||
|
||||
{% load bootstrap %}
|
||||
|
||||
{% block head_title %}{{ team.name }}{% endblock %}
|
||||
|
||||
{% block body_outer %}
|
||||
<div class="pull-right">
|
||||
{% if can_join %}
|
||||
<form method="post" action="{% url "team_join" team.slug %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn btn-primary" value="join">
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% if can_leave %}
|
||||
<form method="post" action="{% url "team_leave" team.slug %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn btn-default" value="leave">
|
||||
</form>
|
||||
{% endif %}
|
||||
|
||||
{% if can_apply %}
|
||||
<form method="post" action="{% url "team_apply" team.slug %}">
|
||||
{% csrf_token %}
|
||||
<input type="submit" class="btn btn-primary" value="apply">
|
||||
</form>
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
<h1>{{ team.name }}{% if state %} <span class="label">{{ state }}</span>{% endif %}</h1>
|
||||
|
||||
{% if team.description %}<p>{{ team.description }}</p>{% endif %}
|
||||
|
||||
{% if state == "invited" %}<p>You have been invited to join this team. Click <b>join</b> to the right to accept.</p>{% endif %}
|
||||
|
||||
{% if user.is_staff or state == "manager" %}
|
||||
{% if team.managers %}
|
||||
<h2>Managers</h2>
|
||||
<table class="table table-striped">
|
||||
{% for membership in team.managers %}
|
||||
<tr>
|
||||
<td>{{ membership.user.email }}{% if user == membership.user %} <span class="label label-info">you</span>{% endif %}</td>
|
||||
<td>
|
||||
<form style="margin: 0;" method="post" action="{% url "team_demote" membership.pk %}">{% csrf_token %}<button type="submit" class="btn btn-xs">demote</button></form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if team.members %}
|
||||
<h2>Team Members</h2>
|
||||
<table class="table table-striped">
|
||||
{% for membership in team.members %}
|
||||
<tr>
|
||||
<td>{{ membership.user.email }}{% if user == membership.user %} <span class="label label-info">you</span>{% endif %}</td>
|
||||
<td>
|
||||
<form style="margin: 0;" method="post" action="{% url "team_promote" membership.pk %}">{% csrf_token %}<button type="submit" class="btn btn-xs">promote</button></form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if team.applicants and team.access == "application" %}
|
||||
<h2>Applicants</h2>
|
||||
<table class="table table-striped">
|
||||
{% for membership in team.applicants %}
|
||||
<tr>
|
||||
<td>{{ membership.user.email }}</td>
|
||||
<td>
|
||||
<form style="margin: 0; float: left;" method="post" action="{% url "team_accept" membership.pk %}">{% csrf_token %}<button type="submit" class="btn btn-xs">accept</button></form>
|
||||
<form style="margin: 0; float: left;" method="post" action="{% url "team_reject" membership.pk %}">{% csrf_token %}<button type="submit" class="btn btn-xs">reject</button></form>
|
||||
</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if team.invitees %}
|
||||
<h2>Invitees</h2>
|
||||
<table class="table table-striped">
|
||||
{% for membership in team.invitees %}
|
||||
<tr>
|
||||
<td>{{ membership.user.email }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</table>
|
||||
{% endif %}
|
||||
{% if invite_form %}
|
||||
<form method="POST" action="" class="form-horizontal">
|
||||
{% csrf_token %}
|
||||
<legend>Invite User to Team</legend>
|
||||
{{ invite_form|bootstrap_horizontal }}
|
||||
<div class="form-actions">
|
||||
<input class="btn btn-primary" type="submit" value="Invite" />
|
||||
</div>
|
||||
</form>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
|
@ -10,6 +10,15 @@ import symposion.views
|
|||
|
||||
urlpatterns = [
|
||||
url(r"^$", TemplateView.as_view(template_name="homepage.html"), name="home"),
|
||||
|
||||
url(r"^about$", TemplateView.as_view(template_name="pages/about.html"), name="page_about"),
|
||||
url(r"^venue$", TemplateView.as_view(template_name="pages/venue.html"), name="page_venue"),
|
||||
url(
|
||||
r"^sponsors/info$",
|
||||
TemplateView.as_view(template_name="pages/sponsors/info.html"),
|
||||
name="page_sponsor_info",
|
||||
),
|
||||
|
||||
url(r"^admin/", include(admin.site.urls)),
|
||||
|
||||
url(r"^account/", include("account.urls")),
|
||||
|
|
|
@ -7,6 +7,7 @@ dj-static==0.0.6
|
|||
dj-database-url==0.4.0
|
||||
pinax-pages==0.4.2
|
||||
pinax-boxes==2.1.2
|
||||
django-libsass==0.7
|
||||
|
||||
# For testing
|
||||
django-nose==1.4.3
|
||||
|
@ -16,3 +17,4 @@ coverage==4.0.3
|
|||
https://github.com/chrisjrn/registrasion/tarball/master#egg=registrasion
|
||||
https://github.com/pinax/symposion/tarball/ad81810#egg=symposion
|
||||
https://github.com/chrisjrn/registrasion-stripe/tarball/master#egg=registrasion-stripe
|
||||
https://github.com/chrisjrn/symposion-bootstrap-templates/tarball/master#egg=symposion-bootstrap-templates
|
||||
|
|
|
@ -1,10 +0,0 @@
|
|||
# Static Media
|
||||
|
||||
We are using `gulp` and `npm` for our static build process.
|
||||
|
||||
Do NOT edit anything in the `dist/` directory.
|
||||
|
||||
Local development uses media from `dist/` and we are firm believers in building
|
||||
static assets and committing them to the repo before deployments. This way we
|
||||
always are testing and exercise exactly what will be served in production. It
|
||||
also makes our deployment simpler.
|
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
0
static/bootstrap/images/.keep
Normal file
0
static/bootstrap/images/.keep
Normal file
12
static/bootstrap/javascripts/bootstrap-sprockets.js
vendored
Normal file
12
static/bootstrap/javascripts/bootstrap-sprockets.js
vendored
Normal file
|
@ -0,0 +1,12 @@
|
|||
//= require ./bootstrap/transition
|
||||
//= require ./bootstrap/alert
|
||||
//= require ./bootstrap/button
|
||||
//= require ./bootstrap/carousel
|
||||
//= require ./bootstrap/collapse
|
||||
//= require ./bootstrap/dropdown
|
||||
//= require ./bootstrap/modal
|
||||
//= require ./bootstrap/tab
|
||||
//= require ./bootstrap/affix
|
||||
//= require ./bootstrap/scrollspy
|
||||
//= require ./bootstrap/tooltip
|
||||
//= require ./bootstrap/popover
|
2377
static/bootstrap/javascripts/bootstrap.js
vendored
Normal file
2377
static/bootstrap/javascripts/bootstrap.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
7
static/bootstrap/javascripts/bootstrap.min.js
vendored
Normal file
7
static/bootstrap/javascripts/bootstrap.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
162
static/bootstrap/javascripts/bootstrap/affix.js
Normal file
162
static/bootstrap/javascripts/bootstrap/affix.js
Normal file
|
@ -0,0 +1,162 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: affix.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#affix
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// AFFIX CLASS DEFINITION
|
||||
// ======================
|
||||
|
||||
var Affix = function (element, options) {
|
||||
this.options = $.extend({}, Affix.DEFAULTS, options)
|
||||
|
||||
this.$target = $(this.options.target)
|
||||
.on('scroll.bs.affix.data-api', $.proxy(this.checkPosition, this))
|
||||
.on('click.bs.affix.data-api', $.proxy(this.checkPositionWithEventLoop, this))
|
||||
|
||||
this.$element = $(element)
|
||||
this.affixed = null
|
||||
this.unpin = null
|
||||
this.pinnedOffset = null
|
||||
|
||||
this.checkPosition()
|
||||
}
|
||||
|
||||
Affix.VERSION = '3.3.7'
|
||||
|
||||
Affix.RESET = 'affix affix-top affix-bottom'
|
||||
|
||||
Affix.DEFAULTS = {
|
||||
offset: 0,
|
||||
target: window
|
||||
}
|
||||
|
||||
Affix.prototype.getState = function (scrollHeight, height, offsetTop, offsetBottom) {
|
||||
var scrollTop = this.$target.scrollTop()
|
||||
var position = this.$element.offset()
|
||||
var targetHeight = this.$target.height()
|
||||
|
||||
if (offsetTop != null && this.affixed == 'top') return scrollTop < offsetTop ? 'top' : false
|
||||
|
||||
if (this.affixed == 'bottom') {
|
||||
if (offsetTop != null) return (scrollTop + this.unpin <= position.top) ? false : 'bottom'
|
||||
return (scrollTop + targetHeight <= scrollHeight - offsetBottom) ? false : 'bottom'
|
||||
}
|
||||
|
||||
var initializing = this.affixed == null
|
||||
var colliderTop = initializing ? scrollTop : position.top
|
||||
var colliderHeight = initializing ? targetHeight : height
|
||||
|
||||
if (offsetTop != null && scrollTop <= offsetTop) return 'top'
|
||||
if (offsetBottom != null && (colliderTop + colliderHeight >= scrollHeight - offsetBottom)) return 'bottom'
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Affix.prototype.getPinnedOffset = function () {
|
||||
if (this.pinnedOffset) return this.pinnedOffset
|
||||
this.$element.removeClass(Affix.RESET).addClass('affix')
|
||||
var scrollTop = this.$target.scrollTop()
|
||||
var position = this.$element.offset()
|
||||
return (this.pinnedOffset = position.top - scrollTop)
|
||||
}
|
||||
|
||||
Affix.prototype.checkPositionWithEventLoop = function () {
|
||||
setTimeout($.proxy(this.checkPosition, this), 1)
|
||||
}
|
||||
|
||||
Affix.prototype.checkPosition = function () {
|
||||
if (!this.$element.is(':visible')) return
|
||||
|
||||
var height = this.$element.height()
|
||||
var offset = this.options.offset
|
||||
var offsetTop = offset.top
|
||||
var offsetBottom = offset.bottom
|
||||
var scrollHeight = Math.max($(document).height(), $(document.body).height())
|
||||
|
||||
if (typeof offset != 'object') offsetBottom = offsetTop = offset
|
||||
if (typeof offsetTop == 'function') offsetTop = offset.top(this.$element)
|
||||
if (typeof offsetBottom == 'function') offsetBottom = offset.bottom(this.$element)
|
||||
|
||||
var affix = this.getState(scrollHeight, height, offsetTop, offsetBottom)
|
||||
|
||||
if (this.affixed != affix) {
|
||||
if (this.unpin != null) this.$element.css('top', '')
|
||||
|
||||
var affixType = 'affix' + (affix ? '-' + affix : '')
|
||||
var e = $.Event(affixType + '.bs.affix')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
this.affixed = affix
|
||||
this.unpin = affix == 'bottom' ? this.getPinnedOffset() : null
|
||||
|
||||
this.$element
|
||||
.removeClass(Affix.RESET)
|
||||
.addClass(affixType)
|
||||
.trigger(affixType.replace('affix', 'affixed') + '.bs.affix')
|
||||
}
|
||||
|
||||
if (affix == 'bottom') {
|
||||
this.$element.offset({
|
||||
top: scrollHeight - height - offsetBottom
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// AFFIX PLUGIN DEFINITION
|
||||
// =======================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.affix')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.affix', (data = new Affix(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.affix
|
||||
|
||||
$.fn.affix = Plugin
|
||||
$.fn.affix.Constructor = Affix
|
||||
|
||||
|
||||
// AFFIX NO CONFLICT
|
||||
// =================
|
||||
|
||||
$.fn.affix.noConflict = function () {
|
||||
$.fn.affix = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// AFFIX DATA-API
|
||||
// ==============
|
||||
|
||||
$(window).on('load', function () {
|
||||
$('[data-spy="affix"]').each(function () {
|
||||
var $spy = $(this)
|
||||
var data = $spy.data()
|
||||
|
||||
data.offset = data.offset || {}
|
||||
|
||||
if (data.offsetBottom != null) data.offset.bottom = data.offsetBottom
|
||||
if (data.offsetTop != null) data.offset.top = data.offsetTop
|
||||
|
||||
Plugin.call($spy, data)
|
||||
})
|
||||
})
|
||||
|
||||
}(jQuery);
|
94
static/bootstrap/javascripts/bootstrap/alert.js
Normal file
94
static/bootstrap/javascripts/bootstrap/alert.js
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: alert.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#alerts
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// ALERT CLASS DEFINITION
|
||||
// ======================
|
||||
|
||||
var dismiss = '[data-dismiss="alert"]'
|
||||
var Alert = function (el) {
|
||||
$(el).on('click', dismiss, this.close)
|
||||
}
|
||||
|
||||
Alert.VERSION = '3.3.7'
|
||||
|
||||
Alert.TRANSITION_DURATION = 150
|
||||
|
||||
Alert.prototype.close = function (e) {
|
||||
var $this = $(this)
|
||||
var selector = $this.attr('data-target')
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||||
}
|
||||
|
||||
var $parent = $(selector === '#' ? [] : selector)
|
||||
|
||||
if (e) e.preventDefault()
|
||||
|
||||
if (!$parent.length) {
|
||||
$parent = $this.closest('.alert')
|
||||
}
|
||||
|
||||
$parent.trigger(e = $.Event('close.bs.alert'))
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$parent.removeClass('in')
|
||||
|
||||
function removeElement() {
|
||||
// detach from parent, fire event then clean up data
|
||||
$parent.detach().trigger('closed.bs.alert').remove()
|
||||
}
|
||||
|
||||
$.support.transition && $parent.hasClass('fade') ?
|
||||
$parent
|
||||
.one('bsTransitionEnd', removeElement)
|
||||
.emulateTransitionEnd(Alert.TRANSITION_DURATION) :
|
||||
removeElement()
|
||||
}
|
||||
|
||||
|
||||
// ALERT PLUGIN DEFINITION
|
||||
// =======================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.alert')
|
||||
|
||||
if (!data) $this.data('bs.alert', (data = new Alert(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.alert
|
||||
|
||||
$.fn.alert = Plugin
|
||||
$.fn.alert.Constructor = Alert
|
||||
|
||||
|
||||
// ALERT NO CONFLICT
|
||||
// =================
|
||||
|
||||
$.fn.alert.noConflict = function () {
|
||||
$.fn.alert = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// ALERT DATA-API
|
||||
// ==============
|
||||
|
||||
$(document).on('click.bs.alert.data-api', dismiss, Alert.prototype.close)
|
||||
|
||||
}(jQuery);
|
125
static/bootstrap/javascripts/bootstrap/button.js
Normal file
125
static/bootstrap/javascripts/bootstrap/button.js
Normal file
|
@ -0,0 +1,125 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: button.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#buttons
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// BUTTON PUBLIC CLASS DEFINITION
|
||||
// ==============================
|
||||
|
||||
var Button = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, Button.DEFAULTS, options)
|
||||
this.isLoading = false
|
||||
}
|
||||
|
||||
Button.VERSION = '3.3.7'
|
||||
|
||||
Button.DEFAULTS = {
|
||||
loadingText: 'loading...'
|
||||
}
|
||||
|
||||
Button.prototype.setState = function (state) {
|
||||
var d = 'disabled'
|
||||
var $el = this.$element
|
||||
var val = $el.is('input') ? 'val' : 'html'
|
||||
var data = $el.data()
|
||||
|
||||
state += 'Text'
|
||||
|
||||
if (data.resetText == null) $el.data('resetText', $el[val]())
|
||||
|
||||
// push to event loop to allow forms to submit
|
||||
setTimeout($.proxy(function () {
|
||||
$el[val](data[state] == null ? this.options[state] : data[state])
|
||||
|
||||
if (state == 'loadingText') {
|
||||
this.isLoading = true
|
||||
$el.addClass(d).attr(d, d).prop(d, true)
|
||||
} else if (this.isLoading) {
|
||||
this.isLoading = false
|
||||
$el.removeClass(d).removeAttr(d).prop(d, false)
|
||||
}
|
||||
}, this), 0)
|
||||
}
|
||||
|
||||
Button.prototype.toggle = function () {
|
||||
var changed = true
|
||||
var $parent = this.$element.closest('[data-toggle="buttons"]')
|
||||
|
||||
if ($parent.length) {
|
||||
var $input = this.$element.find('input')
|
||||
if ($input.prop('type') == 'radio') {
|
||||
if ($input.prop('checked')) changed = false
|
||||
$parent.find('.active').removeClass('active')
|
||||
this.$element.addClass('active')
|
||||
} else if ($input.prop('type') == 'checkbox') {
|
||||
if (($input.prop('checked')) !== this.$element.hasClass('active')) changed = false
|
||||
this.$element.toggleClass('active')
|
||||
}
|
||||
$input.prop('checked', this.$element.hasClass('active'))
|
||||
if (changed) $input.trigger('change')
|
||||
} else {
|
||||
this.$element.attr('aria-pressed', !this.$element.hasClass('active'))
|
||||
this.$element.toggleClass('active')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// BUTTON PLUGIN DEFINITION
|
||||
// ========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.button')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.button', (data = new Button(this, options)))
|
||||
|
||||
if (option == 'toggle') data.toggle()
|
||||
else if (option) data.setState(option)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.button
|
||||
|
||||
$.fn.button = Plugin
|
||||
$.fn.button.Constructor = Button
|
||||
|
||||
|
||||
// BUTTON NO CONFLICT
|
||||
// ==================
|
||||
|
||||
$.fn.button.noConflict = function () {
|
||||
$.fn.button = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// BUTTON DATA-API
|
||||
// ===============
|
||||
|
||||
$(document)
|
||||
.on('click.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||||
var $btn = $(e.target).closest('.btn')
|
||||
Plugin.call($btn, 'toggle')
|
||||
if (!($(e.target).is('input[type="radio"], input[type="checkbox"]'))) {
|
||||
// Prevent double click on radios, and the double selections (so cancellation) on checkboxes
|
||||
e.preventDefault()
|
||||
// The target component still receive the focus
|
||||
if ($btn.is('input,button')) $btn.trigger('focus')
|
||||
else $btn.find('input:visible,button:visible').first().trigger('focus')
|
||||
}
|
||||
})
|
||||
.on('focus.bs.button.data-api blur.bs.button.data-api', '[data-toggle^="button"]', function (e) {
|
||||
$(e.target).closest('.btn').toggleClass('focus', /^focus(in)?$/.test(e.type))
|
||||
})
|
||||
|
||||
}(jQuery);
|
237
static/bootstrap/javascripts/bootstrap/carousel.js
Normal file
237
static/bootstrap/javascripts/bootstrap/carousel.js
Normal file
|
@ -0,0 +1,237 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: carousel.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#carousel
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// CAROUSEL CLASS DEFINITION
|
||||
// =========================
|
||||
|
||||
var Carousel = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.$indicators = this.$element.find('.carousel-indicators')
|
||||
this.options = options
|
||||
this.paused = null
|
||||
this.sliding = null
|
||||
this.interval = null
|
||||
this.$active = null
|
||||
this.$items = null
|
||||
|
||||
this.options.keyboard && this.$element.on('keydown.bs.carousel', $.proxy(this.keydown, this))
|
||||
|
||||
this.options.pause == 'hover' && !('ontouchstart' in document.documentElement) && this.$element
|
||||
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
|
||||
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
|
||||
}
|
||||
|
||||
Carousel.VERSION = '3.3.7'
|
||||
|
||||
Carousel.TRANSITION_DURATION = 600
|
||||
|
||||
Carousel.DEFAULTS = {
|
||||
interval: 5000,
|
||||
pause: 'hover',
|
||||
wrap: true,
|
||||
keyboard: true
|
||||
}
|
||||
|
||||
Carousel.prototype.keydown = function (e) {
|
||||
if (/input|textarea/i.test(e.target.tagName)) return
|
||||
switch (e.which) {
|
||||
case 37: this.prev(); break
|
||||
case 39: this.next(); break
|
||||
default: return
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
Carousel.prototype.cycle = function (e) {
|
||||
e || (this.paused = false)
|
||||
|
||||
this.interval && clearInterval(this.interval)
|
||||
|
||||
this.options.interval
|
||||
&& !this.paused
|
||||
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Carousel.prototype.getItemIndex = function (item) {
|
||||
this.$items = item.parent().children('.item')
|
||||
return this.$items.index(item || this.$active)
|
||||
}
|
||||
|
||||
Carousel.prototype.getItemForDirection = function (direction, active) {
|
||||
var activeIndex = this.getItemIndex(active)
|
||||
var willWrap = (direction == 'prev' && activeIndex === 0)
|
||||
|| (direction == 'next' && activeIndex == (this.$items.length - 1))
|
||||
if (willWrap && !this.options.wrap) return active
|
||||
var delta = direction == 'prev' ? -1 : 1
|
||||
var itemIndex = (activeIndex + delta) % this.$items.length
|
||||
return this.$items.eq(itemIndex)
|
||||
}
|
||||
|
||||
Carousel.prototype.to = function (pos) {
|
||||
var that = this
|
||||
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
|
||||
|
||||
if (pos > (this.$items.length - 1) || pos < 0) return
|
||||
|
||||
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
|
||||
if (activeIndex == pos) return this.pause().cycle()
|
||||
|
||||
return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
|
||||
}
|
||||
|
||||
Carousel.prototype.pause = function (e) {
|
||||
e || (this.paused = true)
|
||||
|
||||
if (this.$element.find('.next, .prev').length && $.support.transition) {
|
||||
this.$element.trigger($.support.transition.end)
|
||||
this.cycle(true)
|
||||
}
|
||||
|
||||
this.interval = clearInterval(this.interval)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
Carousel.prototype.next = function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('next')
|
||||
}
|
||||
|
||||
Carousel.prototype.prev = function () {
|
||||
if (this.sliding) return
|
||||
return this.slide('prev')
|
||||
}
|
||||
|
||||
Carousel.prototype.slide = function (type, next) {
|
||||
var $active = this.$element.find('.item.active')
|
||||
var $next = next || this.getItemForDirection(type, $active)
|
||||
var isCycling = this.interval
|
||||
var direction = type == 'next' ? 'left' : 'right'
|
||||
var that = this
|
||||
|
||||
if ($next.hasClass('active')) return (this.sliding = false)
|
||||
|
||||
var relatedTarget = $next[0]
|
||||
var slideEvent = $.Event('slide.bs.carousel', {
|
||||
relatedTarget: relatedTarget,
|
||||
direction: direction
|
||||
})
|
||||
this.$element.trigger(slideEvent)
|
||||
if (slideEvent.isDefaultPrevented()) return
|
||||
|
||||
this.sliding = true
|
||||
|
||||
isCycling && this.pause()
|
||||
|
||||
if (this.$indicators.length) {
|
||||
this.$indicators.find('.active').removeClass('active')
|
||||
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
|
||||
$nextIndicator && $nextIndicator.addClass('active')
|
||||
}
|
||||
|
||||
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
|
||||
if ($.support.transition && this.$element.hasClass('slide')) {
|
||||
$next.addClass(type)
|
||||
$next[0].offsetWidth // force reflow
|
||||
$active.addClass(direction)
|
||||
$next.addClass(direction)
|
||||
$active
|
||||
.one('bsTransitionEnd', function () {
|
||||
$next.removeClass([type, direction].join(' ')).addClass('active')
|
||||
$active.removeClass(['active', direction].join(' '))
|
||||
that.sliding = false
|
||||
setTimeout(function () {
|
||||
that.$element.trigger(slidEvent)
|
||||
}, 0)
|
||||
})
|
||||
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
|
||||
} else {
|
||||
$active.removeClass('active')
|
||||
$next.addClass('active')
|
||||
this.sliding = false
|
||||
this.$element.trigger(slidEvent)
|
||||
}
|
||||
|
||||
isCycling && this.cycle()
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// CAROUSEL PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.carousel')
|
||||
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
var action = typeof option == 'string' ? option : options.slide
|
||||
|
||||
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
|
||||
if (typeof option == 'number') data.to(option)
|
||||
else if (action) data[action]()
|
||||
else if (options.interval) data.pause().cycle()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.carousel
|
||||
|
||||
$.fn.carousel = Plugin
|
||||
$.fn.carousel.Constructor = Carousel
|
||||
|
||||
|
||||
// CAROUSEL NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.carousel.noConflict = function () {
|
||||
$.fn.carousel = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// CAROUSEL DATA-API
|
||||
// =================
|
||||
|
||||
var clickHandler = function (e) {
|
||||
var href
|
||||
var $this = $(this)
|
||||
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
|
||||
if (!$target.hasClass('carousel')) return
|
||||
var options = $.extend({}, $target.data(), $this.data())
|
||||
var slideIndex = $this.attr('data-slide-to')
|
||||
if (slideIndex) options.interval = false
|
||||
|
||||
Plugin.call($target, options)
|
||||
|
||||
if (slideIndex) {
|
||||
$target.data('bs.carousel').to(slideIndex)
|
||||
}
|
||||
|
||||
e.preventDefault()
|
||||
}
|
||||
|
||||
$(document)
|
||||
.on('click.bs.carousel.data-api', '[data-slide]', clickHandler)
|
||||
.on('click.bs.carousel.data-api', '[data-slide-to]', clickHandler)
|
||||
|
||||
$(window).on('load', function () {
|
||||
$('[data-ride="carousel"]').each(function () {
|
||||
var $carousel = $(this)
|
||||
Plugin.call($carousel, $carousel.data())
|
||||
})
|
||||
})
|
||||
|
||||
}(jQuery);
|
212
static/bootstrap/javascripts/bootstrap/collapse.js
Normal file
212
static/bootstrap/javascripts/bootstrap/collapse.js
Normal file
|
@ -0,0 +1,212 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: collapse.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#collapse
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
/* jshint latedef: false */
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// COLLAPSE PUBLIC CLASS DEFINITION
|
||||
// ================================
|
||||
|
||||
var Collapse = function (element, options) {
|
||||
this.$element = $(element)
|
||||
this.options = $.extend({}, Collapse.DEFAULTS, options)
|
||||
this.$trigger = $('[data-toggle="collapse"][href="#' + element.id + '"],' +
|
||||
'[data-toggle="collapse"][data-target="#' + element.id + '"]')
|
||||
this.transitioning = null
|
||||
|
||||
if (this.options.parent) {
|
||||
this.$parent = this.getParent()
|
||||
} else {
|
||||
this.addAriaAndCollapsedClass(this.$element, this.$trigger)
|
||||
}
|
||||
|
||||
if (this.options.toggle) this.toggle()
|
||||
}
|
||||
|
||||
Collapse.VERSION = '3.3.7'
|
||||
|
||||
Collapse.TRANSITION_DURATION = 350
|
||||
|
||||
Collapse.DEFAULTS = {
|
||||
toggle: true
|
||||
}
|
||||
|
||||
Collapse.prototype.dimension = function () {
|
||||
var hasWidth = this.$element.hasClass('width')
|
||||
return hasWidth ? 'width' : 'height'
|
||||
}
|
||||
|
||||
Collapse.prototype.show = function () {
|
||||
if (this.transitioning || this.$element.hasClass('in')) return
|
||||
|
||||
var activesData
|
||||
var actives = this.$parent && this.$parent.children('.panel').children('.in, .collapsing')
|
||||
|
||||
if (actives && actives.length) {
|
||||
activesData = actives.data('bs.collapse')
|
||||
if (activesData && activesData.transitioning) return
|
||||
}
|
||||
|
||||
var startEvent = $.Event('show.bs.collapse')
|
||||
this.$element.trigger(startEvent)
|
||||
if (startEvent.isDefaultPrevented()) return
|
||||
|
||||
if (actives && actives.length) {
|
||||
Plugin.call(actives, 'hide')
|
||||
activesData || actives.data('bs.collapse', null)
|
||||
}
|
||||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element
|
||||
.removeClass('collapse')
|
||||
.addClass('collapsing')[dimension](0)
|
||||
.attr('aria-expanded', true)
|
||||
|
||||
this.$trigger
|
||||
.removeClass('collapsed')
|
||||
.attr('aria-expanded', true)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
var complete = function () {
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse in')[dimension]('')
|
||||
this.transitioning = 0
|
||||
this.$element
|
||||
.trigger('shown.bs.collapse')
|
||||
}
|
||||
|
||||
if (!$.support.transition) return complete.call(this)
|
||||
|
||||
var scrollSize = $.camelCase(['scroll', dimension].join('-'))
|
||||
|
||||
this.$element
|
||||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)[dimension](this.$element[0][scrollSize])
|
||||
}
|
||||
|
||||
Collapse.prototype.hide = function () {
|
||||
if (this.transitioning || !this.$element.hasClass('in')) return
|
||||
|
||||
var startEvent = $.Event('hide.bs.collapse')
|
||||
this.$element.trigger(startEvent)
|
||||
if (startEvent.isDefaultPrevented()) return
|
||||
|
||||
var dimension = this.dimension()
|
||||
|
||||
this.$element[dimension](this.$element[dimension]())[0].offsetHeight
|
||||
|
||||
this.$element
|
||||
.addClass('collapsing')
|
||||
.removeClass('collapse in')
|
||||
.attr('aria-expanded', false)
|
||||
|
||||
this.$trigger
|
||||
.addClass('collapsed')
|
||||
.attr('aria-expanded', false)
|
||||
|
||||
this.transitioning = 1
|
||||
|
||||
var complete = function () {
|
||||
this.transitioning = 0
|
||||
this.$element
|
||||
.removeClass('collapsing')
|
||||
.addClass('collapse')
|
||||
.trigger('hidden.bs.collapse')
|
||||
}
|
||||
|
||||
if (!$.support.transition) return complete.call(this)
|
||||
|
||||
this.$element
|
||||
[dimension](0)
|
||||
.one('bsTransitionEnd', $.proxy(complete, this))
|
||||
.emulateTransitionEnd(Collapse.TRANSITION_DURATION)
|
||||
}
|
||||
|
||||
Collapse.prototype.toggle = function () {
|
||||
this[this.$element.hasClass('in') ? 'hide' : 'show']()
|
||||
}
|
||||
|
||||
Collapse.prototype.getParent = function () {
|
||||
return $(this.options.parent)
|
||||
.find('[data-toggle="collapse"][data-parent="' + this.options.parent + '"]')
|
||||
.each($.proxy(function (i, element) {
|
||||
var $element = $(element)
|
||||
this.addAriaAndCollapsedClass(getTargetFromTrigger($element), $element)
|
||||
}, this))
|
||||
.end()
|
||||
}
|
||||
|
||||
Collapse.prototype.addAriaAndCollapsedClass = function ($element, $trigger) {
|
||||
var isOpen = $element.hasClass('in')
|
||||
|
||||
$element.attr('aria-expanded', isOpen)
|
||||
$trigger
|
||||
.toggleClass('collapsed', !isOpen)
|
||||
.attr('aria-expanded', isOpen)
|
||||
}
|
||||
|
||||
function getTargetFromTrigger($trigger) {
|
||||
var href
|
||||
var target = $trigger.attr('data-target')
|
||||
|| (href = $trigger.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') // strip for ie7
|
||||
|
||||
return $(target)
|
||||
}
|
||||
|
||||
|
||||
// COLLAPSE PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.collapse')
|
||||
var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
|
||||
if (!data && options.toggle && /show|hide/.test(option)) options.toggle = false
|
||||
if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.collapse
|
||||
|
||||
$.fn.collapse = Plugin
|
||||
$.fn.collapse.Constructor = Collapse
|
||||
|
||||
|
||||
// COLLAPSE NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.collapse.noConflict = function () {
|
||||
$.fn.collapse = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// COLLAPSE DATA-API
|
||||
// =================
|
||||
|
||||
$(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
|
||||
var $this = $(this)
|
||||
|
||||
if (!$this.attr('data-target')) e.preventDefault()
|
||||
|
||||
var $target = getTargetFromTrigger($this)
|
||||
var data = $target.data('bs.collapse')
|
||||
var option = data ? 'toggle' : $this.data()
|
||||
|
||||
Plugin.call($target, option)
|
||||
})
|
||||
|
||||
}(jQuery);
|
165
static/bootstrap/javascripts/bootstrap/dropdown.js
Normal file
165
static/bootstrap/javascripts/bootstrap/dropdown.js
Normal file
|
@ -0,0 +1,165 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: dropdown.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#dropdowns
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// DROPDOWN CLASS DEFINITION
|
||||
// =========================
|
||||
|
||||
var backdrop = '.dropdown-backdrop'
|
||||
var toggle = '[data-toggle="dropdown"]'
|
||||
var Dropdown = function (element) {
|
||||
$(element).on('click.bs.dropdown', this.toggle)
|
||||
}
|
||||
|
||||
Dropdown.VERSION = '3.3.7'
|
||||
|
||||
function getParent($this) {
|
||||
var selector = $this.attr('data-target')
|
||||
|
||||
if (!selector) {
|
||||
selector = $this.attr('href')
|
||||
selector = selector && /#[A-Za-z]/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') // strip for ie7
|
||||
}
|
||||
|
||||
var $parent = selector && $(selector)
|
||||
|
||||
return $parent && $parent.length ? $parent : $this.parent()
|
||||
}
|
||||
|
||||
function clearMenus(e) {
|
||||
if (e && e.which === 3) return
|
||||
$(backdrop).remove()
|
||||
$(toggle).each(function () {
|
||||
var $this = $(this)
|
||||
var $parent = getParent($this)
|
||||
var relatedTarget = { relatedTarget: this }
|
||||
|
||||
if (!$parent.hasClass('open')) return
|
||||
|
||||
if (e && e.type == 'click' && /input|textarea/i.test(e.target.tagName) && $.contains($parent[0], e.target)) return
|
||||
|
||||
$parent.trigger(e = $.Event('hide.bs.dropdown', relatedTarget))
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$this.attr('aria-expanded', 'false')
|
||||
$parent.removeClass('open').trigger($.Event('hidden.bs.dropdown', relatedTarget))
|
||||
})
|
||||
}
|
||||
|
||||
Dropdown.prototype.toggle = function (e) {
|
||||
var $this = $(this)
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
var $parent = getParent($this)
|
||||
var isActive = $parent.hasClass('open')
|
||||
|
||||
clearMenus()
|
||||
|
||||
if (!isActive) {
|
||||
if ('ontouchstart' in document.documentElement && !$parent.closest('.navbar-nav').length) {
|
||||
// if mobile we use a backdrop because click events don't delegate
|
||||
$(document.createElement('div'))
|
||||
.addClass('dropdown-backdrop')
|
||||
.insertAfter($(this))
|
||||
.on('click', clearMenus)
|
||||
}
|
||||
|
||||
var relatedTarget = { relatedTarget: this }
|
||||
$parent.trigger(e = $.Event('show.bs.dropdown', relatedTarget))
|
||||
|
||||
if (e.isDefaultPrevented()) return
|
||||
|
||||
$this
|
||||
.trigger('focus')
|
||||
.attr('aria-expanded', 'true')
|
||||
|
||||
$parent
|
||||
.toggleClass('open')
|
||||
.trigger($.Event('shown.bs.dropdown', relatedTarget))
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
Dropdown.prototype.keydown = function (e) {
|
||||
if (!/(38|40|27|32)/.test(e.which) || /input|textarea/i.test(e.target.tagName)) return
|
||||
|
||||
var $this = $(this)
|
||||
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
|
||||
if ($this.is('.disabled, :disabled')) return
|
||||
|
||||
var $parent = getParent($this)
|
||||
var isActive = $parent.hasClass('open')
|
||||
|
||||
if (!isActive && e.which != 27 || isActive && e.which == 27) {
|
||||
if (e.which == 27) $parent.find(toggle).trigger('focus')
|
||||
return $this.trigger('click')
|
||||
}
|
||||
|
||||
var desc = ' li:not(.disabled):visible a'
|
||||
var $items = $parent.find('.dropdown-menu' + desc)
|
||||
|
||||
if (!$items.length) return
|
||||
|
||||
var index = $items.index(e.target)
|
||||
|
||||
if (e.which == 38 && index > 0) index-- // up
|
||||
if (e.which == 40 && index < $items.length - 1) index++ // down
|
||||
if (!~index) index = 0
|
||||
|
||||
$items.eq(index).trigger('focus')
|
||||
}
|
||||
|
||||
|
||||
// DROPDOWN PLUGIN DEFINITION
|
||||
// ==========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.dropdown')
|
||||
|
||||
if (!data) $this.data('bs.dropdown', (data = new Dropdown(this)))
|
||||
if (typeof option == 'string') data[option].call($this)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.dropdown
|
||||
|
||||
$.fn.dropdown = Plugin
|
||||
$.fn.dropdown.Constructor = Dropdown
|
||||
|
||||
|
||||
// DROPDOWN NO CONFLICT
|
||||
// ====================
|
||||
|
||||
$.fn.dropdown.noConflict = function () {
|
||||
$.fn.dropdown = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// APPLY TO STANDARD DROPDOWN ELEMENTS
|
||||
// ===================================
|
||||
|
||||
$(document)
|
||||
.on('click.bs.dropdown.data-api', clearMenus)
|
||||
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
|
||||
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
|
||||
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
|
||||
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
|
||||
|
||||
}(jQuery);
|
339
static/bootstrap/javascripts/bootstrap/modal.js
Normal file
339
static/bootstrap/javascripts/bootstrap/modal.js
Normal file
|
@ -0,0 +1,339 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: modal.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#modals
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// MODAL CLASS DEFINITION
|
||||
// ======================
|
||||
|
||||
var Modal = function (element, options) {
|
||||
this.options = options
|
||||
this.$body = $(document.body)
|
||||
this.$element = $(element)
|
||||
this.$dialog = this.$element.find('.modal-dialog')
|
||||
this.$backdrop = null
|
||||
this.isShown = null
|
||||
this.originalBodyPad = null
|
||||
this.scrollbarWidth = 0
|
||||
this.ignoreBackdropClick = false
|
||||
|
||||
if (this.options.remote) {
|
||||
this.$element
|
||||
.find('.modal-content')
|
||||
.load(this.options.remote, $.proxy(function () {
|
||||
this.$element.trigger('loaded.bs.modal')
|
||||
}, this))
|
||||
}
|
||||
}
|
||||
|
||||
Modal.VERSION = '3.3.7'
|
||||
|
||||
Modal.TRANSITION_DURATION = 300
|
||||
Modal.BACKDROP_TRANSITION_DURATION = 150
|
||||
|
||||
Modal.DEFAULTS = {
|
||||
backdrop: true,
|
||||
keyboard: true,
|
||||
show: true
|
||||
}
|
||||
|
||||
Modal.prototype.toggle = function (_relatedTarget) {
|
||||
return this.isShown ? this.hide() : this.show(_relatedTarget)
|
||||
}
|
||||
|
||||
Modal.prototype.show = function (_relatedTarget) {
|
||||
var that = this
|
||||
var e = $.Event('show.bs.modal', { relatedTarget: _relatedTarget })
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
this.isShown = true
|
||||
|
||||
this.checkScrollbar()
|
||||
this.setScrollbar()
|
||||
this.$body.addClass('modal-open')
|
||||
|
||||
this.escape()
|
||||
this.resize()
|
||||
|
||||
this.$element.on('click.dismiss.bs.modal', '[data-dismiss="modal"]', $.proxy(this.hide, this))
|
||||
|
||||
this.$dialog.on('mousedown.dismiss.bs.modal', function () {
|
||||
that.$element.one('mouseup.dismiss.bs.modal', function (e) {
|
||||
if ($(e.target).is(that.$element)) that.ignoreBackdropClick = true
|
||||
})
|
||||
})
|
||||
|
||||
this.backdrop(function () {
|
||||
var transition = $.support.transition && that.$element.hasClass('fade')
|
||||
|
||||
if (!that.$element.parent().length) {
|
||||
that.$element.appendTo(that.$body) // don't move modals dom position
|
||||
}
|
||||
|
||||
that.$element
|
||||
.show()
|
||||
.scrollTop(0)
|
||||
|
||||
that.adjustDialog()
|
||||
|
||||
if (transition) {
|
||||
that.$element[0].offsetWidth // force reflow
|
||||
}
|
||||
|
||||
that.$element.addClass('in')
|
||||
|
||||
that.enforceFocus()
|
||||
|
||||
var e = $.Event('shown.bs.modal', { relatedTarget: _relatedTarget })
|
||||
|
||||
transition ?
|
||||
that.$dialog // wait for modal to slide in
|
||||
.one('bsTransitionEnd', function () {
|
||||
that.$element.trigger('focus').trigger(e)
|
||||
})
|
||||
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
|
||||
that.$element.trigger('focus').trigger(e)
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.hide = function (e) {
|
||||
if (e) e.preventDefault()
|
||||
|
||||
e = $.Event('hide.bs.modal')
|
||||
|
||||
this.$element.trigger(e)
|
||||
|
||||
if (!this.isShown || e.isDefaultPrevented()) return
|
||||
|
||||
this.isShown = false
|
||||
|
||||
this.escape()
|
||||
this.resize()
|
||||
|
||||
$(document).off('focusin.bs.modal')
|
||||
|
||||
this.$element
|
||||
.removeClass('in')
|
||||
.off('click.dismiss.bs.modal')
|
||||
.off('mouseup.dismiss.bs.modal')
|
||||
|
||||
this.$dialog.off('mousedown.dismiss.bs.modal')
|
||||
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
this.$element
|
||||
.one('bsTransitionEnd', $.proxy(this.hideModal, this))
|
||||
.emulateTransitionEnd(Modal.TRANSITION_DURATION) :
|
||||
this.hideModal()
|
||||
}
|
||||
|
||||
Modal.prototype.enforceFocus = function () {
|
||||
$(document)
|
||||
.off('focusin.bs.modal') // guard against infinite focus loop
|
||||
.on('focusin.bs.modal', $.proxy(function (e) {
|
||||
if (document !== e.target &&
|
||||
this.$element[0] !== e.target &&
|
||||
!this.$element.has(e.target).length) {
|
||||
this.$element.trigger('focus')
|
||||
}
|
||||
}, this))
|
||||
}
|
||||
|
||||
Modal.prototype.escape = function () {
|
||||
if (this.isShown && this.options.keyboard) {
|
||||
this.$element.on('keydown.dismiss.bs.modal', $.proxy(function (e) {
|
||||
e.which == 27 && this.hide()
|
||||
}, this))
|
||||
} else if (!this.isShown) {
|
||||
this.$element.off('keydown.dismiss.bs.modal')
|
||||
}
|
||||
}
|
||||
|
||||
Modal.prototype.resize = function () {
|
||||
if (this.isShown) {
|
||||
$(window).on('resize.bs.modal', $.proxy(this.handleUpdate, this))
|
||||
} else {
|
||||
$(window).off('resize.bs.modal')
|
||||
}
|
||||
}
|
||||
|
||||
Modal.prototype.hideModal = function () {
|
||||
var that = this
|
||||
this.$element.hide()
|
||||
this.backdrop(function () {
|
||||
that.$body.removeClass('modal-open')
|
||||
that.resetAdjustments()
|
||||
that.resetScrollbar()
|
||||
that.$element.trigger('hidden.bs.modal')
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.removeBackdrop = function () {
|
||||
this.$backdrop && this.$backdrop.remove()
|
||||
this.$backdrop = null
|
||||
}
|
||||
|
||||
Modal.prototype.backdrop = function (callback) {
|
||||
var that = this
|
||||
var animate = this.$element.hasClass('fade') ? 'fade' : ''
|
||||
|
||||
if (this.isShown && this.options.backdrop) {
|
||||
var doAnimate = $.support.transition && animate
|
||||
|
||||
this.$backdrop = $(document.createElement('div'))
|
||||
.addClass('modal-backdrop ' + animate)
|
||||
.appendTo(this.$body)
|
||||
|
||||
this.$element.on('click.dismiss.bs.modal', $.proxy(function (e) {
|
||||
if (this.ignoreBackdropClick) {
|
||||
this.ignoreBackdropClick = false
|
||||
return
|
||||
}
|
||||
if (e.target !== e.currentTarget) return
|
||||
this.options.backdrop == 'static'
|
||||
? this.$element[0].focus()
|
||||
: this.hide()
|
||||
}, this))
|
||||
|
||||
if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
|
||||
|
||||
this.$backdrop.addClass('in')
|
||||
|
||||
if (!callback) return
|
||||
|
||||
doAnimate ?
|
||||
this.$backdrop
|
||||
.one('bsTransitionEnd', callback)
|
||||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||||
callback()
|
||||
|
||||
} else if (!this.isShown && this.$backdrop) {
|
||||
this.$backdrop.removeClass('in')
|
||||
|
||||
var callbackRemove = function () {
|
||||
that.removeBackdrop()
|
||||
callback && callback()
|
||||
}
|
||||
$.support.transition && this.$element.hasClass('fade') ?
|
||||
this.$backdrop
|
||||
.one('bsTransitionEnd', callbackRemove)
|
||||
.emulateTransitionEnd(Modal.BACKDROP_TRANSITION_DURATION) :
|
||||
callbackRemove()
|
||||
|
||||
} else if (callback) {
|
||||
callback()
|
||||
}
|
||||
}
|
||||
|
||||
// these following methods are used to handle overflowing modals
|
||||
|
||||
Modal.prototype.handleUpdate = function () {
|
||||
this.adjustDialog()
|
||||
}
|
||||
|
||||
Modal.prototype.adjustDialog = function () {
|
||||
var modalIsOverflowing = this.$element[0].scrollHeight > document.documentElement.clientHeight
|
||||
|
||||
this.$element.css({
|
||||
paddingLeft: !this.bodyIsOverflowing && modalIsOverflowing ? this.scrollbarWidth : '',
|
||||
paddingRight: this.bodyIsOverflowing && !modalIsOverflowing ? this.scrollbarWidth : ''
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.resetAdjustments = function () {
|
||||
this.$element.css({
|
||||
paddingLeft: '',
|
||||
paddingRight: ''
|
||||
})
|
||||
}
|
||||
|
||||
Modal.prototype.checkScrollbar = function () {
|
||||
var fullWindowWidth = window.innerWidth
|
||||
if (!fullWindowWidth) { // workaround for missing window.innerWidth in IE8
|
||||
var documentElementRect = document.documentElement.getBoundingClientRect()
|
||||
fullWindowWidth = documentElementRect.right - Math.abs(documentElementRect.left)
|
||||
}
|
||||
this.bodyIsOverflowing = document.body.clientWidth < fullWindowWidth
|
||||
this.scrollbarWidth = this.measureScrollbar()
|
||||
}
|
||||
|
||||
Modal.prototype.setScrollbar = function () {
|
||||
var bodyPad = parseInt((this.$body.css('padding-right') || 0), 10)
|
||||
this.originalBodyPad = document.body.style.paddingRight || ''
|
||||
if (this.bodyIsOverflowing) this.$body.css('padding-right', bodyPad + this.scrollbarWidth)
|
||||
}
|
||||
|
||||
Modal.prototype.resetScrollbar = function () {
|
||||
this.$body.css('padding-right', this.originalBodyPad)
|
||||
}
|
||||
|
||||
Modal.prototype.measureScrollbar = function () { // thx walsh
|
||||
var scrollDiv = document.createElement('div')
|
||||
scrollDiv.className = 'modal-scrollbar-measure'
|
||||
this.$body.append(scrollDiv)
|
||||
var scrollbarWidth = scrollDiv.offsetWidth - scrollDiv.clientWidth
|
||||
this.$body[0].removeChild(scrollDiv)
|
||||
return scrollbarWidth
|
||||
}
|
||||
|
||||
|
||||
// MODAL PLUGIN DEFINITION
|
||||
// =======================
|
||||
|
||||
function Plugin(option, _relatedTarget) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.modal')
|
||||
var options = $.extend({}, Modal.DEFAULTS, $this.data(), typeof option == 'object' && option)
|
||||
|
||||
if (!data) $this.data('bs.modal', (data = new Modal(this, options)))
|
||||
if (typeof option == 'string') data[option](_relatedTarget)
|
||||
else if (options.show) data.show(_relatedTarget)
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.modal
|
||||
|
||||
$.fn.modal = Plugin
|
||||
$.fn.modal.Constructor = Modal
|
||||
|
||||
|
||||
// MODAL NO CONFLICT
|
||||
// =================
|
||||
|
||||
$.fn.modal.noConflict = function () {
|
||||
$.fn.modal = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// MODAL DATA-API
|
||||
// ==============
|
||||
|
||||
$(document).on('click.bs.modal.data-api', '[data-toggle="modal"]', function (e) {
|
||||
var $this = $(this)
|
||||
var href = $this.attr('href')
|
||||
var $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) // strip for ie7
|
||||
var option = $target.data('bs.modal') ? 'toggle' : $.extend({ remote: !/#/.test(href) && href }, $target.data(), $this.data())
|
||||
|
||||
if ($this.is('a')) e.preventDefault()
|
||||
|
||||
$target.one('show.bs.modal', function (showEvent) {
|
||||
if (showEvent.isDefaultPrevented()) return // only register focus restorer if modal will actually get shown
|
||||
$target.one('hidden.bs.modal', function () {
|
||||
$this.is(':visible') && $this.trigger('focus')
|
||||
})
|
||||
})
|
||||
Plugin.call($target, option, this)
|
||||
})
|
||||
|
||||
}(jQuery);
|
108
static/bootstrap/javascripts/bootstrap/popover.js
Normal file
108
static/bootstrap/javascripts/bootstrap/popover.js
Normal file
|
@ -0,0 +1,108 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: popover.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#popovers
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// POPOVER PUBLIC CLASS DEFINITION
|
||||
// ===============================
|
||||
|
||||
var Popover = function (element, options) {
|
||||
this.init('popover', element, options)
|
||||
}
|
||||
|
||||
if (!$.fn.tooltip) throw new Error('Popover requires tooltip.js')
|
||||
|
||||
Popover.VERSION = '3.3.7'
|
||||
|
||||
Popover.DEFAULTS = $.extend({}, $.fn.tooltip.Constructor.DEFAULTS, {
|
||||
placement: 'right',
|
||||
trigger: 'click',
|
||||
content: '',
|
||||
template: '<div class="popover" role="tooltip"><div class="arrow"></div><h3 class="popover-title"></h3><div class="popover-content"></div></div>'
|
||||
})
|
||||
|
||||
|
||||
// NOTE: POPOVER EXTENDS tooltip.js
|
||||
// ================================
|
||||
|
||||
Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype)
|
||||
|
||||
Popover.prototype.constructor = Popover
|
||||
|
||||
Popover.prototype.getDefaults = function () {
|
||||
return Popover.DEFAULTS
|
||||
}
|
||||
|
||||
Popover.prototype.setContent = function () {
|
||||
var $tip = this.tip()
|
||||
var title = this.getTitle()
|
||||
var content = this.getContent()
|
||||
|
||||
$tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
|
||||
$tip.find('.popover-content').children().detach().end()[ // we use append for html objects to maintain js events
|
||||
this.options.html ? (typeof content == 'string' ? 'html' : 'append') : 'text'
|
||||
](content)
|
||||
|
||||
$tip.removeClass('fade top bottom left right in')
|
||||
|
||||
// IE8 doesn't accept hiding via the `:empty` pseudo selector, we have to do
|
||||
// this manually by checking the contents.
|
||||
if (!$tip.find('.popover-title').html()) $tip.find('.popover-title').hide()
|
||||
}
|
||||
|
||||
Popover.prototype.hasContent = function () {
|
||||
return this.getTitle() || this.getContent()
|
||||
}
|
||||
|
||||
Popover.prototype.getContent = function () {
|
||||
var $e = this.$element
|
||||
var o = this.options
|
||||
|
||||
return $e.attr('data-content')
|
||||
|| (typeof o.content == 'function' ?
|
||||
o.content.call($e[0]) :
|
||||
o.content)
|
||||
}
|
||||
|
||||
Popover.prototype.arrow = function () {
|
||||
return (this.$arrow = this.$arrow || this.tip().find('.arrow'))
|
||||
}
|
||||
|
||||
|
||||
// POPOVER PLUGIN DEFINITION
|
||||
// =========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.popover')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data && /destroy|hide/.test(option)) return
|
||||
if (!data) $this.data('bs.popover', (data = new Popover(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.popover
|
||||
|
||||
$.fn.popover = Plugin
|
||||
$.fn.popover.Constructor = Popover
|
||||
|
||||
|
||||
// POPOVER NO CONFLICT
|
||||
// ===================
|
||||
|
||||
$.fn.popover.noConflict = function () {
|
||||
$.fn.popover = old
|
||||
return this
|
||||
}
|
||||
|
||||
}(jQuery);
|
172
static/bootstrap/javascripts/bootstrap/scrollspy.js
Normal file
172
static/bootstrap/javascripts/bootstrap/scrollspy.js
Normal file
|
@ -0,0 +1,172 @@
|
|||
/* ========================================================================
|
||||
* Bootstrap: scrollspy.js v3.3.7
|
||||
* http://getbootstrap.com/javascript/#scrollspy
|
||||
* ========================================================================
|
||||
* Copyright 2011-2016 Twitter, Inc.
|
||||
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
|
||||
* ======================================================================== */
|
||||
|
||||
|
||||
+function ($) {
|
||||
'use strict';
|
||||
|
||||
// SCROLLSPY CLASS DEFINITION
|
||||
// ==========================
|
||||
|
||||
function ScrollSpy(element, options) {
|
||||
this.$body = $(document.body)
|
||||
this.$scrollElement = $(element).is(document.body) ? $(window) : $(element)
|
||||
this.options = $.extend({}, ScrollSpy.DEFAULTS, options)
|
||||
this.selector = (this.options.target || '') + ' .nav li > a'
|
||||
this.offsets = []
|
||||
this.targets = []
|
||||
this.activeTarget = null
|
||||
this.scrollHeight = 0
|
||||
|
||||
this.$scrollElement.on('scroll.bs.scrollspy', $.proxy(this.process, this))
|
||||
this.refresh()
|
||||
this.process()
|
||||
}
|
||||
|
||||
ScrollSpy.VERSION = '3.3.7'
|
||||
|
||||
ScrollSpy.DEFAULTS = {
|
||||
offset: 10
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.getScrollHeight = function () {
|
||||
return this.$scrollElement[0].scrollHeight || Math.max(this.$body[0].scrollHeight, document.documentElement.scrollHeight)
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.refresh = function () {
|
||||
var that = this
|
||||
var offsetMethod = 'offset'
|
||||
var offsetBase = 0
|
||||
|
||||
this.offsets = []
|
||||
this.targets = []
|
||||
this.scrollHeight = this.getScrollHeight()
|
||||
|
||||
if (!$.isWindow(this.$scrollElement[0])) {
|
||||
offsetMethod = 'position'
|
||||
offsetBase = this.$scrollElement.scrollTop()
|
||||
}
|
||||
|
||||
this.$body
|
||||
.find(this.selector)
|
||||
.map(function () {
|
||||
var $el = $(this)
|
||||
var href = $el.data('target') || $el.attr('href')
|
||||
var $href = /^#./.test(href) && $(href)
|
||||
|
||||
return ($href
|
||||
&& $href.length
|
||||
&& $href.is(':visible')
|
||||
&& [[$href[offsetMethod]().top + offsetBase, href]]) || null
|
||||
})
|
||||
.sort(function (a, b) { return a[0] - b[0] })
|
||||
.each(function () {
|
||||
that.offsets.push(this[0])
|
||||
that.targets.push(this[1])
|
||||
})
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.process = function () {
|
||||
var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
|
||||
var scrollHeight = this.getScrollHeight()
|
||||
var maxScroll = this.options.offset + scrollHeight - this.$scrollElement.height()
|
||||
var offsets = this.offsets
|
||||
var targets = this.targets
|
||||
var activeTarget = this.activeTarget
|
||||
var i
|
||||
|
||||
if (this.scrollHeight != scrollHeight) {
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
if (scrollTop >= maxScroll) {
|
||||
return activeTarget != (i = targets[targets.length - 1]) && this.activate(i)
|
||||
}
|
||||
|
||||
if (activeTarget && scrollTop < offsets[0]) {
|
||||
this.activeTarget = null
|
||||
return this.clear()
|
||||
}
|
||||
|
||||
for (i = offsets.length; i--;) {
|
||||
activeTarget != targets[i]
|
||||
&& scrollTop >= offsets[i]
|
||||
&& (offsets[i + 1] === undefined || scrollTop < offsets[i + 1])
|
||||
&& this.activate(targets[i])
|
||||
}
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.activate = function (target) {
|
||||
this.activeTarget = target
|
||||
|
||||
this.clear()
|
||||
|
||||
var selector = this.selector +
|
||||
'[data-target="' + target + '"],' +
|
||||
this.selector + '[href="' + target + '"]'
|
||||
|
||||
var active = $(selector)
|
||||
.parents('li')
|
||||
.addClass('active')
|
||||
|
||||
if (active.parent('.dropdown-menu').length) {
|
||||
active = active
|
||||
.closest('li.dropdown')
|
||||
.addClass('active')
|
||||
}
|
||||
|
||||
active.trigger('activate.bs.scrollspy')
|
||||
}
|
||||
|
||||
ScrollSpy.prototype.clear = function () {
|
||||
$(this.selector)
|
||||
.parentsUntil(this.options.target, '.active')
|
||||
.removeClass('active')
|
||||
}
|
||||
|
||||
|
||||
// SCROLLSPY PLUGIN DEFINITION
|
||||
// ===========================
|
||||
|
||||
function Plugin(option) {
|
||||
return this.each(function () {
|
||||
var $this = $(this)
|
||||
var data = $this.data('bs.scrollspy')
|
||||
var options = typeof option == 'object' && option
|
||||
|
||||
if (!data) $this.data('bs.scrollspy', (data = new ScrollSpy(this, options)))
|
||||
if (typeof option == 'string') data[option]()
|
||||
})
|
||||
}
|
||||
|
||||
var old = $.fn.scrollspy
|
||||
|
||||
$.fn.scrollspy = Plugin
|
||||
$.fn.scrollspy.Constructor = ScrollSpy
|
||||
|
||||
|
||||
// SCROLLSPY NO CONFLICT
|
||||
// =====================
|
||||
|
||||
$.fn.scrollspy.noConflict = function () {
|
||||
$.fn.scrollspy = old
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
// SCROLLSPY DATA-API
|
||||
// ==================
|
||||
|
||||
$(window).on('load.bs.scrollspy.data-api', function () {
|
||||
$('[data-spy="scroll"]').each(function () {
|
||||
var $spy = $(this)
|
||||
Plugin.call($spy, $spy.data())
|
||||
})
|
||||
})
|
||||
|
||||
}(jQuery);
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue