@ -0,0 +1,373 @@ | |||
# ForumSystem | |||
# 滑动师范大学论坛 | |||
### 环境配置 | |||
一、更新系统软件包 | |||
yum update -y | |||
二、安装软件管理包和可能使用的依赖 | |||
yum -y groupinstall "Development tools" | |||
yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel | |||
三、下载Pyhton3到/usr/local 目录 | |||
cd /usr/local | |||
wget https://www.python.org/ftp/python/3.6.6/Python-3.6.6.tgz | |||
解压 | |||
tar -zxvf Python-3.6.6.tgz | |||
进入 Python-3.6.6路径 | |||
cd Python-3.6.6 | |||
编译安装到指定路径 | |||
./configure --prefix=/usr/local/python3 | |||
安装python3 | |||
make | |||
make install | |||
python3建立软连接:ln -s /usr/local/python3/bin/python3.6 /usr/bin/python3 | |||
同样给pip3建立软链接:ln -s /usr/local/python3/bin/pip3.6 /usr/bin/pip3 | |||
四、安装virtualenv | |||
pip3 install virtualenv | |||
建立软链接 | |||
ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv | |||
五、下载并安装MySQL | |||
wget -i -c http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm | |||
yum -y install mysql57-community-release-el7-10.noarch.rpm | |||
yum -y install mysql-community-server | |||
MySQL数据库设置: systemctl start mysqld.service | |||
grep "password" /var/log/mysqld.log | |||
登录mysql:mysql -uroot -p | |||
修改密码:ALTER USER 'root'@'localhost' IDENTIFIED BY 'new password'; | |||
创建数据库create database forum,并使用use forum; | |||
创建/www/wwwroot/目录,并将项目解压至该目录 | |||
在master目录下创建虚拟环境virtualenv --python=/usr/bin/python3 master_venv | |||
执行source ./master_venv/bin/activate | |||
修改/master/ForumSystem下settings.py中数据库密码 | |||
回到master目录,在虚拟环境下安装pip3 install django pip3 install pgsql | |||
pip3 install uwsgi pip3 install -r requirements.txt | |||
安装requirements.txt出错 | |||
centos安装psycopg2时出错:Error: pg_config executable not found.解决方案 | |||
yum install postgresql-devel* | |||
使用 pip install psycopg2-binary 安装即可 | |||
再执行pip3 install -r requirements.txt | |||
六、配置uwsgi配置文件(master同目录下,已创建,可以修改端口) | |||
[uwsgi] | |||
master = true | |||
processes = 1 | |||
threads = 2 | |||
chdir = /www/wwwroot/master | |||
#wsgi-file= /www/wwwroot/master/ | |||
wsgi-file = /www/wwwroot/master/ForumSystem/wsgi.py | |||
http = 0.0.0.0:8080 | |||
logto = /www/wwwroot/master/logs/error.log | |||
chmod-socket = 660 | |||
vacuum = true | |||
master = true | |||
max-requests = 1000 | |||
static-map = /static=/www/wwwroot/master/static | |||
在master目录下运行,进行数据库迁移: | |||
python manage.py makemigrations | |||
python manage.py migrate | |||
在master目录下启动uwsgi | |||
uwsgi --ini uwsgi.ini | |||
浏览器输入网址http://ip地址:8080/login 安装成功 | |||
## 展示 | |||
### 用户端 | |||
登录 | |||
![image](http://ww1.sinaimg.cn/large/006tNc79ly1g4z46rpj9cj31k10u0drs.jpg) | |||
主页 | |||
![](http://ww4.sinaimg.cn/large/006tNc79ly1g520s6ijl0j31kl0u0e81.jpg) | |||
全部帖子 | |||
![](http://ww2.sinaimg.cn/large/006tNc79ly1g520t8nsslj31k10u0qv5.jpg) | |||
发帖 | |||
![](http://ww1.sinaimg.cn/large/006tNc79ly1g520u2tfwfj31k90u0drc.jpg) | |||
### 管理员端 | |||
帖子管理 | |||
![image](http://ww1.sinaimg.cn/large/006tNc79ly1g4z43fiddwj31jm0u0gy1.jpg) | |||
公告管理 | |||
![image](http://ww2.sinaimg.cn/large/006tNc79ly1g4z43pup25j31k10u0136.jpg) | |||
板块(分类)管理 | |||
![image](http://ww3.sinaimg.cn/large/006tNc79ly1g4z44l23y8j31jv0u0131.jpg) | |||
## 功能 | |||
### 用户端功能 | |||
- 注册:用户在注册界面可以提交注册,暂不支持手机短信验证,直接注册。 | |||
- 登录:已注册的用户可以通过正确的用户名和密码登录。 | |||
- 欢迎:主页的导航栏会显示用户名并且欢迎。 | |||
- 查看公告:查看管理员发出的公告。 | |||
- 查看指南:显示在主页的指南。 | |||
- 推荐帖子:每个帖子可以选择推荐在首页显示。 | |||
- 查看类别:可以看到论坛里帖子所有的类别,点击可以查看对应下的帖子。 | |||
- 查看全部帖子:按照时间顺序,查看所有帖子。 | |||
- 帖子筛选:可以根据帖子分类、回复量、发布时间进行组合筛选。 | |||
- 帖子搜索:根据输入关键字查询相关帖子。 | |||
- 发帖:普通用户可以发帖。 | |||
- 查看帖子详细:可以看到帖子的发布时间,作者,类别,标题,简介,详细内容,所有留言信息。 | |||
- 留言:可以在帖子下面发表文字或者图片留言(评论),暂不支持回复评论。 | |||
## 系统说明 | |||
### 数据库 | |||
项目采用mysql进行存储,我使用的是mysql 8.0.16。表之间不采用任何外键关联,逻辑的管理都在控制层完成。每个表的id都由Django自动创建,也同时作为主键。 | |||
#### 表与字段 | |||
##### 用户表:User | |||
字段名称 | 字段类型 | 字段说明 | |||
---|---|--- | |||
id | int | 编号,自增,主键 | |||
uid | vchar(16) | 用户名,唯一 | |||
password | vchar(16) | 密码 | |||
create_time | Date | 创建日期 | |||
##### 帖子表:Topic | |||
字段名称 | 字段类型 | 字段说明 | |||
---|---|--- | |||
id | int | 编号,自增,主键 | |||
t_uid | vchar(16) | 帖子作者 | |||
t_kind | vchar(32) | 帖子类型 | |||
create_time | Date | 帖子发布日期 | |||
t_photo | vchar(128) | 帖子主页图,允许为空 | |||
t_content | vchar(3000) | 帖子内容 | |||
t_title | vchar(64) | 帖子标题 | |||
t_introduce | vchar(256) | 帖子介绍 | |||
recommend | boolean | 是否推荐到主页,默认false | |||
##### 回复表:Reply | |||
字段名称 | 字段类型 | 字段说明 | |||
---|---|--- | |||
id | int | 编号,自增,主键 | |||
r_tid | vchar(16) | 回复的帖子 | |||
r_uid | vchar(16) | 发表回复的人 | |||
r_time | Date | 回复时间 | |||
r_photo | vchar(128) | 回复图片,允许为空 | |||
r_content | vchar(256) | 回复内容 | |||
##### 分类表:Kind | |||
字段名称 | 字段类型 | 字段说明 | |||
---|---|--- | |||
id | int | 编号,自增,主键 | |||
k_name | vchar(16) | 分类名称 | |||
##### 公告表:Announcement | |||
字段名称 | 字段类型 | 字段说明 | |||
---|---|--- | |||
id | int | 编号,自增,主键 | |||
a_title | vchar(64) | 公告名称 | |||
a_content | vchar(3000) | 公告内容,允许为空 | |||
#### 数据库代码 | |||
数据库代码在模型(models)层:参见/ForumSystem/app01/models.py | |||
### 用户端 | |||
#### 用户端前端 | |||
- 主页: | |||
- 显示公告:模板和数据渲染生成 | |||
- 显示指南:html固定内容 | |||
- 显示导航栏 | |||
- 登陆后显示:主页、发帖、看帖、欢迎、退出 | |||
- 未登录显示:主页、发帖(点击会跳转到登录)、看帖、登录。 | |||
- 显示推荐帖子:模板和数据渲染生成 | |||
- 显示全部帖子按钮:页面固定 | |||
- 底部栏:显示名称和导航栏 | |||
- 登录&注册页面: | |||
- 一个输入框:分为用户名和密码 | |||
- 两个按钮(登录/注册) | |||
- 通过ajax发送登录或者注册请求 | |||
- 全部帖子页面: | |||
- 论坛名称(左上角):固定显示 | |||
- 搜索框:固定,form表单post提交 | |||
- 导航栏:同上 | |||
- 组合筛选栏 | |||
- 分类筛选:模板和数据渲染得到所有分类显示 | |||
- 回复数量筛选:固定 | |||
- 发布时间筛选:固定 | |||
- 显示全部帖子:模板和数据渲染获取 | |||
- 帖子详情页面:模板和数据渲染获取 | |||
- 论坛名称:同上 | |||
- 导航栏:同上 | |||
- 帖子主图 | |||
- 帖子标题和详细内容 | |||
- 帖子作者、发布时间、分类 | |||
- 发表留言栏:form表单,post提交 | |||
- 显示所有留言:模板和数据渲染获取 | |||
- 公告详情页面: | |||
- 公告标题 | |||
- 公告内容 | |||
- 发布帖子页面: | |||
- 一个大form表单,包括帖子的标题、简介、内容、封面图、类别(下拉选择)。 | |||
- 修改密码页面: | |||
- 用户名框(只显示,不可改) | |||
- 原密码框 | |||
- 新密码框 | |||
- 确认新密码框 | |||
- 提交(成功后返回主页)、取消(返回主页)按钮 | |||
#### 用户端接口 | |||
##### 主页 | |||
- url:http://127.0.0.1:8000/home/ | |||
- GET请求 | |||
- 参数:无 | |||
- 返回值:10个最新公告列表,所有推荐贴列表,渲染好的**页面**。 | |||
##### 所有帖子 | |||
- url:http://127.0.0.1:8000/all-0-0-0 | |||
- GET请求 | |||
- url说明:后3个0指组合筛选不进行筛选 | |||
- 参数:无,也可以说是all后面的3个数字(kid, reply_limit, time_limit) | |||
- 返回值:根据3个参数选择后的**帖子列表** | |||
- POST请求: | |||
- 参数 | |||
- keys:搜索关键字 | |||
- 返回值:根据关键字搜索到的**帖子列表** | |||
##### 登录、注册 | |||
- url:http://127.0.0.1:8000/login/ | |||
- GET请求: | |||
- 参数:无 | |||
- 返回值:登录页面 | |||
- POST请求: | |||
- 参数: | |||
- type:login 或者 register | |||
- uid:用户名 | |||
- pwd:密码 | |||
- 返回值: | |||
- msg:信息 | |||
- status:状态,成功与否 | |||
##### 发布帖子 | |||
- url:http://127.0.0.1:8000/publish/ | |||
- GET请求: | |||
- 参数:无 | |||
- 返回值:发布帖子页面 | |||
- POST请求: | |||
- 参数: | |||
- t_title:标题 | |||
- t_introduce:介绍 | |||
- t_content:内容 | |||
- t_kind:类别 | |||
- t_photo:主图 | |||
- 返回值: | |||
- 成功后重定向到单个帖子页面 | |||
##### 单个帖子 | |||
- url:http://127.0.0.1:8000/single/1/ | |||
- GET请求: | |||
- url说明:1就是tid | |||
- 参数:tid | |||
- 返回值:帖子相关所有信息,渲染成单个帖子详情页面 | |||
- POST请求:主要用于评论的发表和删除 | |||
- 参数: | |||
- type:类型,删除评论还是发表评论 | |||
- r_content:评论内容 | |||
- r_photo:评论图片 | |||
- r_id:回复id,删除已有回复才用到 | |||
- 返回值: | |||
- msg:信息 | |||
- status:状态,成功与否 | |||
##### 修改密码 | |||
- url:http://127.0.0.1:8000/edit-pwd/ | |||
- GET请求: | |||
- 参数:无 | |||
- 返回值:修改密码页面 | |||
- POST请求: | |||
- 参数: | |||
- old_pwd:旧密码 | |||
- new_pwd1:新密码 | |||
- new_pwd2:确认新密码 | |||
- 返回值: | |||
- 成功后重定向到主页 | |||
### 管理员端 | |||
#### 管理员前端 | |||
- 管理员登录: | |||
- 一个输入框:分为用户名和密码 | |||
- 两个按钮(登录/取消) | |||
- 一个form表单,提交数据 | |||
- 帖子管理: | |||
- 导航栏:帖子管理、公告管理、分类管理 | |||
- 欢迎头部 | |||
- 帖子列表:序号、名称、简介、推荐、操作 | |||
- 推荐操作:绑定ajax,刷新页面 | |||
- 取消推荐操作:ajax,刷新 | |||
- 查看操作:跳转帖子详情页面 | |||
- 删除操作:ajax,同时刷新 | |||
- 公告管理: | |||
- 导航栏:帖子管理、公告管理、分类管理 | |||
- 欢迎头部 | |||
- 公告列表:序号、标题、操作 | |||
- 查看操作:跳转公告详情页面 | |||
- 删除操作:ajax,同时刷新 | |||
- 分类(板块)管理: | |||
- 导航栏:帖子管理、公告管理、分类管理 | |||
- 欢迎头部 | |||
- 分类列表:序号、分类名称、操作 | |||
- 查看该分类下所有帖子操作:跳转到全部帖子下组合搜索出分类里的帖子 | |||
- 删除操作:ajax,同时刷新 | |||
#### 管理员接口 | |||
##### 登录 | |||
- url:http://127.0.0.1:8000/my-admin/ | |||
- GET请求: | |||
- 参数:无 | |||
- 返回值:管理员登录页面 | |||
- POST请求: | |||
- 参数: | |||
- admin_id:管理员用户名 | |||
- admin_pwd:管理员密码 | |||
- 返回值: | |||
- 成功后重定向到帖子管理页面 | |||
- 注意:管理员我没有做表去存放管理员账号密码,所以在程序里写死了管理员账号为guanliyuan,密码为123456 | |||
##### 帖子管理 | |||
- url:http://127.0.0.1:8000/admin-home/ | |||
- GET请求: | |||
- 参数:无 | |||
- 返回值:所有帖子信息,渲染后的帖子管理页面,需要验证管理员是否登录(使用session) | |||
- POST请求: | |||
- 参数: | |||
- type:post请求类型(以下为type可用的值) | |||
- zhiding:置顶(推荐) | |||
- qzhiding:取消置顶 | |||
- delete:删除 | |||
- t_id:帖子id,根据帖子id进行type操作 | |||
- 返回值: | |||
- msg:信息 | |||
- status:成功与否状态 | |||
##### 公告管理 | |||
- url:http://127.0.0.1:8000/announcement/ | |||
- GET请求: | |||
- 参数:无 | |||
- 返回值:所有公告信息,渲染后的公告管理页面,需要验证管理员是否登录(使用session) | |||
- POST请求: | |||
- 参数: | |||
- type:post请求类型 | |||
- create:创建公告 | |||
- delete:删除公告 | |||
- a_id:公告id,如果type=delete需要公告id | |||
- a_title:公告标题,如果type=create,需要公告标题 | |||
- a_content:公告内容,如果type=create,需要公告标题 | |||
- 返回值: | |||
- msg:信息 | |||
- status:成功与否状态 | |||
##### 分类管理 | |||
- url:http://127.0.0.1:8000/kind-manage/ | |||
- GET请求: | |||
- 参数:无 | |||
- 返回值:所有分类信息,渲染后的类别管理页面,需要验证管理员是否登录(使用session) | |||
- POST请求: | |||
- 参数: | |||
- type:post请求类型(删除or创建) | |||
- create:创建类别 | |||
- delete:删除类别 | |||
- k_id:类别id,如果type=delete需要类别id | |||
- k_name:类别名称,如果type=create,需要类别名称 | |||
- 返回值: | |||
- msg:信息 | |||
- status:成功与否状态 | |||
@ -0,0 +1,8 @@ | |||
# Default ignored files | |||
/shelf/ | |||
/workspace.xml | |||
# Datasource local storage ignored files | |||
/dataSources/ | |||
/dataSources.local.xml | |||
# Editor-based HTTP Client requests | |||
/httpRequests/ |
@ -0,0 +1,34 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<module type="PYTHON_MODULE" version="4"> | |||
<component name="FacetManager"> | |||
<facet type="django" name="Django"> | |||
<configuration> | |||
<option name="rootFolder" value="$MODULE_DIR$" /> | |||
<option name="settingsModule" value="ForumSystem/settings.py" /> | |||
<option name="manageScript" value="$MODULE_DIR$/manage.py" /> | |||
<option name="environment" value="<map/>" /> | |||
<option name="doNotUseTestRunner" value="false" /> | |||
<option name="trackFilePattern" value="migrations" /> | |||
</configuration> | |||
</facet> | |||
</component> | |||
<component name="NewModuleRootManager"> | |||
<content url="file://$MODULE_DIR$" /> | |||
<orderEntry type="jdk" jdkName="Python 3.7 (visualization)" jdkType="Python SDK" /> | |||
<orderEntry type="sourceFolder" forTests="false" /> | |||
<orderEntry type="library" name="R User Library" level="project" /> | |||
<orderEntry type="library" name="R Skeletons" level="application" /> | |||
</component> | |||
<component name="TemplatesService"> | |||
<option name="TEMPLATE_CONFIGURATION" value="Django" /> | |||
<option name="TEMPLATE_FOLDERS"> | |||
<list> | |||
<option value="$MODULE_DIR$/templates" /> | |||
</list> | |||
</option> | |||
</component> | |||
<component name="TestRunnerService"> | |||
<option name="projectConfiguration" value="Twisted Trial" /> | |||
<option name="PROJECT_TEST_RUNNER" value="Twisted Trial" /> | |||
</component> | |||
</module> |
@ -0,0 +1,19 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="DataSourceManagerImpl" format="xml" multifile-model="true"> | |||
<data-source source="LOCAL" name="MySQL - forum_system@localhost" uuid="47ae3cb6-5721-4752-aabd-d732b72e3838"> | |||
<driver-ref>mysql.8</driver-ref> | |||
<synchronize>true</synchronize> | |||
<jdbc-driver>com.mysql.cj.jdbc.Driver</jdbc-driver> | |||
<jdbc-url>jdbc:mysql://localhost:3306/forum_system</jdbc-url> | |||
<driver-properties> | |||
<property name="autoReconnect" value="true" /> | |||
<property name="zeroDateTimeBehavior" value="CONVERT_TO_NULL" /> | |||
<property name="tinyInt1isBit" value="false" /> | |||
<property name="characterEncoding" value="utf8" /> | |||
<property name="characterSetResults" value="utf8" /> | |||
<property name="yearIsDateType" value="false" /> | |||
</driver-properties> | |||
</data-source> | |||
</component> | |||
</project> |
@ -0,0 +1,3 @@ | |||
<component name="ProjectDictionaryState"> | |||
<dictionary name="likunhong" /> | |||
</component> |
@ -0,0 +1,20 @@ | |||
<component name="InspectionProjectProfileManager"> | |||
<profile version="1.0"> | |||
<option name="myName" value="Project Default" /> | |||
<inspection_tool class="PyPep8NamingInspection" enabled="true" level="WEAK WARNING" enabled_by_default="true"> | |||
<option name="ignoredErrors"> | |||
<list> | |||
<option value="N806" /> | |||
<option value="N802" /> | |||
</list> | |||
</option> | |||
</inspection_tool> | |||
<inspection_tool class="PyUnresolvedReferencesInspection" enabled="true" level="WARNING" enabled_by_default="true"> | |||
<option name="ignoredIdentifiers"> | |||
<list> | |||
<option value="float.__getitem__" /> | |||
</list> | |||
</option> | |||
</inspection_tool> | |||
</profile> | |||
</component> |
@ -0,0 +1,6 @@ | |||
<component name="libraryTable"> | |||
<library name="R User Library"> | |||
<CLASSES /> | |||
<SOURCES /> | |||
</library> | |||
</component> |
@ -0,0 +1,30 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="JavaScriptSettings"> | |||
<option name="languageLevel" value="ES6" /> | |||
</component> | |||
<component name="ProjectInspectionProfilesVisibleTreeState"> | |||
<entry key="Project Default"> | |||
<profile-state> | |||
<expanded-state> | |||
<State /> | |||
<State> | |||
<id>CSS</id> | |||
</State> | |||
<State> | |||
<id>Probable bugsCSS</id> | |||
</State> | |||
<State> | |||
<id>RELAX NG</id> | |||
</State> | |||
</expanded-state> | |||
<selected-state> | |||
<State> | |||
<id>Angular</id> | |||
</State> | |||
</selected-state> | |||
</profile-state> | |||
</entry> | |||
</component> | |||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (visualization)" project-jdk-type="Python SDK" /> | |||
</project> |
@ -0,0 +1,8 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="ProjectModuleManager"> | |||
<modules> | |||
<module fileurl="file://$PROJECT_DIR$/.idea/ForumSystem.iml" filepath="$PROJECT_DIR$/.idea/ForumSystem.iml" /> | |||
</modules> | |||
</component> | |||
</project> |
@ -0,0 +1,6 @@ | |||
<?xml version="1.0" encoding="UTF-8"?> | |||
<project version="4"> | |||
<component name="VcsDirectoryMappings"> | |||
<mapping directory="$PROJECT_DIR$" vcs="Git" /> | |||
</component> | |||
</project> |
@ -0,0 +1,5 @@ | |||
import pymysql | |||
pymysql.version_info = (1, 4, 13, "final", 0) | |||
pymysql.install_as_MySQLdb() |
@ -0,0 +1,145 @@ | |||
""" | |||
Django settings for ForumSystem project. | |||
Generated by 'django-admin startproject' using Django 2.1.4. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/2.1/topics/settings/ | |||
For the full list of settings and their values, see | |||
https://docs.djangoproject.com/en/2.1/ref/settings/ | |||
""" | |||
import os | |||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...) | |||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |||
# Quick-start development settings - unsuitable for production | |||
# See https://docs.djangoproject.com/en/2.1/howto/deployment/checklist/ | |||
# SECURITY WARNING: keep the secret key used in production secret! | |||
SECRET_KEY = 'e(!)-kb_kqw5p@%u!6ak6u2$db5-4h@c#u)dwrcw^xp5m-q(q$' | |||
# SECURITY WARNING: don't run with debug turned on in production! | |||
DEBUG = True | |||
ALLOWED_HOSTS = [ | |||
'*' | |||
] | |||
# Application definition | |||
INSTALLED_APPS = [ | |||
'django.contrib.admin', | |||
'django.contrib.auth', | |||
'django.contrib.contenttypes', | |||
'django.contrib.sessions', | |||
'django.contrib.messages', | |||
'django.contrib.staticfiles', | |||
'app01.apps.App01Config', | |||
] | |||
MIDDLEWARE = [ | |||
'django.middleware.security.SecurityMiddleware', | |||
'django.contrib.sessions.middleware.SessionMiddleware', | |||
'django.middleware.common.CommonMiddleware', | |||
'django.middleware.csrf.CsrfViewMiddleware', | |||
'django.contrib.auth.middleware.AuthenticationMiddleware', | |||
'django.contrib.messages.middleware.MessageMiddleware', | |||
'django.middleware.clickjacking.XFrameOptionsMiddleware', | |||
] | |||
ROOT_URLCONF = 'ForumSystem.urls' | |||
TEMPLATES = [ | |||
{ | |||
'BACKEND': 'django.template.backends.django.DjangoTemplates', | |||
'DIRS': [os.path.join(BASE_DIR, 'templates')] | |||
, | |||
'APP_DIRS': True, | |||
'OPTIONS': { | |||
'context_processors': [ | |||
'django.template.context_processors.debug', | |||
'django.template.context_processors.request', | |||
'django.contrib.auth.context_processors.auth', | |||
'django.contrib.messages.context_processors.messages', | |||
], | |||
}, | |||
}, | |||
] | |||
WSGI_APPLICATION = 'ForumSystem.wsgi.application' | |||
# Database | |||
# https://docs.djangoproject.com/en/2.1/ref/settings/#databases | |||
# DATABASES = { | |||
# 'default': { | |||
# 'ENGINE': 'django.db.backends.sqlite3', | |||
# 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'), | |||
# } | |||
# } | |||
DATABASES = { | |||
'default': { | |||
'ENGINE': 'django.db.backends.mysql', | |||
'HOST': '', | |||
'NAME': 'forum', #你的数据库名称 | |||
'USER': 'root', #你的数据库用户名 | |||
'PASSWORD': 'xsh_123_XSH', | |||
'PORT': '3306', | |||
} | |||
} | |||
# Password validation | |||
# https://docs.djangoproject.com/en/2.1/ref/settings/#auth-password-validators | |||
AUTH_PASSWORD_VALIDATORS = [ | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', | |||
}, | |||
{ | |||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', | |||
}, | |||
] | |||
# Internationalization | |||
# https://docs.djangoproject.com/en/2.1/topics/i18n/ | |||
# LANGUAGE_CODE = 'en-us' | |||
# TIME_ZONE = 'UTC' | |||
LANGUAGE_CODE = 'zh-hans' | |||
TIME_ZONE = 'Asia/Shanghai' | |||
USE_I18N = True | |||
USE_L10N = True | |||
USE_TZ = True | |||
# Static files (CSS, JavaScript, Images) | |||
# https://docs.djangoproject.com/en/2.1/howto/static-files/ | |||
STATIC_URL = '/static/' | |||
# STATIC_ROOT = os.path.join(BASE_DIR,'static') | |||
# STATIC_URL = '/static/' | |||
STATIC_ROOT = os.path.join(BASE_DIR, "static") | |||
STATICFILES_DIRS = ( | |||
os.path.join(BASE_DIR, 'static'), | |||
) |
@ -0,0 +1,36 @@ | |||
"""ForumSystem URL Configuration | |||
The `urlpatterns` list routes URLs to views. For more information please see: | |||
https://docs.djangoproject.com/en/2.1/topics/http/urls/ | |||
Examples: | |||
Function views | |||
1. Add an import: from my_app import views | |||
2. Add a URL to urlpatterns: path('', views.home, name='home') | |||
Class-based views | |||
1. Add an import: from other_app.views import Home | |||
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home') | |||
Including another URLconf | |||
1. Import the include() function: from django.urls import include, path | |||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) | |||
""" | |||
from django.contrib import admin | |||
from django.urls import path | |||
from app01 import views | |||
from django.conf.urls import url | |||
urlpatterns = [ | |||
path('admin/', admin.site.urls), | |||
# url(r'^all/', views.all_tie), # 全部帖子 | |||
url(r'^ownpublish-(?P<kid>\d+)-(?P<reply_limit>\d+)-(?P<time_limit>\d+)', views.ownpublish), # 按条件搜索自己帖子 | |||
url(r'^all-(?P<kid>\d+)-(?P<reply_limit>\d+)-(?P<time_limit>\d+)', views.all_tie), # 按条件搜索帖子 | |||
url(r'^home/', views.home), # 主页 | |||
url(r'^login/', views.login), # 登录注册 | |||
url(r'^publish/', views.publish), # 发布帖子 | |||
url(r'^single/(?P<tid>\d+)/', views.single), # 单个帖子 | |||
url(r'^edit-pwd/', views.edit_pwd), # 修改密码 | |||
url(r'^my-admin/', views.admin), # 修改密码 | |||
url(r'^announcement/', views.announcement), # 公告管理 | |||
url(r'^admin-home/', views.topic_manage), # 帖子管理,也是主页面 | |||
url(r'^kind-manage/', views.kind_manage), # 板块管理 | |||
url(r'^single-an-(?P<aid>\d+)/', views.single_an), # 单个公告显示 | |||
] |
@ -0,0 +1,15 @@ | |||
""" | |||
WSGI config for ForumSystem project. | |||
It exposes the WSGI callable as a module-level variable named ``application``. | |||
For more information on this file, see | |||
https://docs.djangoproject.com/en/2.1/howto/deployment/wsgi/ | |||
""" | |||
import os | |||
from django.core.wsgi import get_wsgi_application | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ForumSystem.settings') | |||
application = get_wsgi_application() |
@ -0,0 +1,5 @@ | |||
import pymysql | |||
pymysql.version_info = (1, 4, 13, "final", 0) | |||
pymysql.install_as_MySQLdb() |
@ -0,0 +1,3 @@ | |||
from django.contrib import admin | |||
# Register your models here. |
@ -0,0 +1,5 @@ | |||
from django.apps import AppConfig | |||
class App01Config(AppConfig): | |||
name = 'app01' |
@ -0,0 +1,65 @@ | |||
# Generated by Django 2.1.4 on 2019-07-02 04:07 | |||
from django.db import migrations, models | |||
class Migration(migrations.Migration): | |||
initial = True | |||
dependencies = [ | |||
] | |||
operations = [ | |||
migrations.CreateModel( | |||
name='Announcement', | |||
fields=[ | |||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||
('a_id', models.CharField(max_length=16, verbose_name='公告id')), | |||
('a_title', models.CharField(max_length=16, verbose_name='公告标题')), | |||
('a_content', models.CharField(max_length=16, null=True, verbose_name='公告内容')), | |||
], | |||
), | |||
migrations.CreateModel( | |||
name='Kind', | |||
fields=[ | |||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||
('k_id', models.CharField(max_length=16, verbose_name='分类id')), | |||
('k_name', models.CharField(max_length=16, verbose_name='分类名称')), | |||
], | |||
), | |||
migrations.CreateModel( | |||
name='Reply', | |||
fields=[ | |||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||
('r_tid', models.CharField(max_length=16, verbose_name='帖子id')), | |||
('r_uid', models.CharField(max_length=16, verbose_name='发表者id')), | |||
('r_photo', models.CharField(max_length=128, null=True, verbose_name='回复的图片')), | |||
('r_time', models.DateField(auto_now_add=True, verbose_name='留言时间')), | |||
('r_content', models.CharField(max_length=256, verbose_name='回复内容')), | |||
], | |||
), | |||
migrations.CreateModel( | |||
name='Topic', | |||
fields=[ | |||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||
('t_id', models.CharField(max_length=16, verbose_name='帖子id')), | |||
('t_uid', models.CharField(max_length=16, verbose_name='帖子所属用户id')), | |||
('t_kind', models.CharField(max_length=32, verbose_name='类别')), | |||
('create_time', models.DateField(auto_now_add=True, verbose_name='创建时间')), | |||
('t_photo', models.CharField(max_length=128, null=True, verbose_name='帖子图片')), | |||
('t_content', models.CharField(max_length=3000, verbose_name='帖子正文')), | |||
('t_title', models.CharField(max_length=64, verbose_name='帖子标题')), | |||
('t_introduce', models.CharField(max_length=256, verbose_name='帖子简介')), | |||
], | |||
), | |||
migrations.CreateModel( | |||
name='User', | |||
fields=[ | |||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), | |||
('uid', models.CharField(max_length=16, unique=True, verbose_name='电话/用户号')), | |||
('password', models.CharField(max_length=16, verbose_name='密码')), | |||
('create_time', models.DateField(auto_now_add=True, verbose_name='创建时间')), | |||
], | |||
), | |||
] |
@ -0,0 +1,28 @@ | |||
# Generated by Django 2.1.4 on 2019-07-03 01:51 | |||
from django.db import migrations, models | |||
class Migration(migrations.Migration): | |||
dependencies = [ | |||
('app01', '0001_initial'), | |||
] | |||
operations = [ | |||
migrations.AddField( | |||
model_name='topic', | |||
name='recommend', | |||
field=models.BooleanField(default=False, verbose_name='是否推荐'), | |||
), | |||
migrations.AlterField( | |||
model_name='announcement', | |||
name='a_content', | |||
field=models.CharField(max_length=3000, null=True, verbose_name='公告内容'), | |||
), | |||
migrations.AlterField( | |||
model_name='announcement', | |||
name='a_title', | |||
field=models.CharField(max_length=64, verbose_name='公告标题'), | |||
), | |||
] |
@ -0,0 +1,25 @@ | |||
# Generated by Django 2.1.4 on 2019-07-03 02:59 | |||
from django.db import migrations | |||
class Migration(migrations.Migration): | |||
dependencies = [ | |||
('app01', '0002_auto_20190703_0151'), | |||
] | |||
operations = [ | |||
migrations.RemoveField( | |||
model_name='announcement', | |||
name='a_id', | |||
), | |||
migrations.RemoveField( | |||
model_name='kind', | |||
name='k_id', | |||
), | |||
migrations.RemoveField( | |||
model_name='topic', | |||
name='t_id', | |||
), | |||
] |
@ -0,0 +1,18 @@ | |||
# Generated by Django 3.1.5 on 2021-01-13 09:16 | |||
from django.db import migrations, models | |||
class Migration(migrations.Migration): | |||
dependencies = [ | |||
('app01', '0003_auto_20190703_0259'), | |||
] | |||
operations = [ | |||
migrations.AddField( | |||
model_name='topic', | |||
name='t_like', | |||
field=models.IntegerField(default=0, verbose_name='点赞数量'), | |||
), | |||
] |
@ -0,0 +1,46 @@ | |||
from django.db import models | |||
# Create your models here. | |||
# 用户表 | |||
class User(models.Model): | |||
uid = models.CharField(verbose_name='电话/用户号', max_length=16, unique=True) | |||
password = models.CharField(verbose_name='密码', max_length=16) | |||
create_time = models.DateField(verbose_name='创建时间', auto_now_add=True) | |||
# 帖子表 | |||
class Topic(models.Model): | |||
#t_id = models.CharField(verbose_name='帖子id', max_length=16) | |||
t_uid = models.CharField(verbose_name='帖子所属用户id', max_length=16) | |||
t_kind = models.CharField(verbose_name='类别', max_length=32) | |||
create_time = models.DateField(verbose_name='创建时间', auto_now_add=True) | |||
t_photo = models.CharField(verbose_name='帖子图片', max_length=128, null=True) | |||
t_content = models.CharField(verbose_name='帖子正文', max_length=3000) | |||
t_title = models.CharField(verbose_name='帖子标题', max_length=64) | |||
t_introduce = models.CharField(verbose_name='帖子简介', max_length=256) | |||
recommend = models.BooleanField(verbose_name='是否推荐', default=False) | |||
t_like = models.IntegerField(verbose_name='点赞数量',default=0) | |||
# 回复表 | |||
class Reply(models.Model): | |||
r_tid = models.CharField(verbose_name='帖子id', max_length=16) | |||
r_uid = models.CharField(verbose_name='发表者id', max_length=16) | |||
r_photo = models.CharField(verbose_name='回复的图片', max_length=128, null=True) | |||
r_time = models.DateField(verbose_name='留言时间', auto_now_add=True) | |||
r_content = models.CharField(verbose_name='回复内容', max_length=256) | |||
# 分类表 | |||
class Kind(models.Model): | |||
# k_id = models.CharField(verbose_name='分类id', max_length=16) | |||
k_name = models.CharField(verbose_name='分类名称', max_length=16) | |||
# 公告表 | |||
class Announcement(models.Model): | |||
# a_id = models.CharField(verbose_name='公告id', max_length=16) | |||
a_title = models.CharField(verbose_name='公告标题', max_length=64) | |||
a_content = models.CharField(verbose_name='公告内容', max_length=3000, null=True) |
@ -0,0 +1,3 @@ | |||
from django.test import TestCase | |||
# Create your tests here. |
@ -0,0 +1,565 @@ | |||
from django.http import HttpResponse | |||
from django.shortcuts import render, redirect | |||
from app01 import models | |||
import json | |||
# Create your views here. | |||
# 主页 | |||
def home(request): | |||
if request.method == 'GET': | |||
response = {} | |||
# top 10(公告)的处理,筛选10个也要改 | |||
announcements = models.Announcement.objects.filter() | |||
# 把这10个公告封装成字典 | |||
a_list = [] | |||
for a in announcements: | |||
dic = {'a_id': a.id, 'a_title': a.a_title} | |||
a_list.append(dic) | |||
# 把列表装进回复字典里 | |||
n = 10 if len(a_list) < 10 else len(a_list) | |||
response['a_list'] = a_list[::-1][0:n-1] | |||
# 帖子推荐列表,推荐8个帖子,推荐8个要改 | |||
recommends = models.Topic.objects.filter(recommend=True) | |||
# 推荐列表 | |||
r_list = [] | |||
for t in recommends: | |||
dic = {'t_id': t.id, 't_title': t.t_title, 't_introduce': t.t_introduce, 't_photo': t.t_photo} | |||
r_list.append(dic) | |||
# 把列表装进response | |||
response['r_list'] = r_list | |||
# 把uid装进返回字典里 | |||
response['uid'] = request.session['uid'] | |||
# 把所有类别装入返回字典里 | |||
kinds = models.Kind.objects.filter() | |||
response['kinds'] = kinds | |||
return render(request, 'home.html', response) | |||
# 所有帖子 | |||
def all_tie(request, kid, reply_limit, time_limit): | |||
uid = request.session.get('uid') | |||
if request.method == 'GET': | |||
kinds = models.Kind.objects.filter() | |||
if kid == '0' and reply_limit == '0' and time_limit == '0': | |||
# 默认时间排序把帖子传过去 | |||
topics = models.Topic.objects.filter() | |||
else: | |||
# request.path_info # 获取当前url | |||
# from django.urls import reverse | |||
# reverse('all_tie', kwargs={'kid': '0', 'reply_limit': '0', 'time_limit': '0'}) | |||
topics = models.Topic.objects.filter() | |||
# 筛选分类 | |||
if kid != '0': | |||
topics = models.Topic.objects.filter(t_kind=kid) | |||
# 筛选回复数量 | |||
tmp = [] | |||
for topic in topics: | |||
# 查看每个帖子的回复数量 | |||
count = len(models.Reply.objects.filter(r_tid=topic.id)) | |||
# print(count) | |||
print(reply_limit) | |||
if reply_limit == '0': | |||
pass | |||
elif reply_limit == '1': # 1是大于100 | |||
print('到1了') | |||
if count < 100: | |||
print('到了') | |||
continue | |||
elif reply_limit == '2': # 2是30-100 | |||
if count < 30 or count > 100: | |||
continue | |||
elif reply_limit == '3': # 3是小于30 | |||
if count > 30: | |||
continue | |||
tmp.append(topic) | |||
topics = tmp | |||
print(topics) | |||
# 筛选发布时间 | |||
tmp = [] | |||
for topic in topics: | |||
if time_limit == '0': # 0是全部时间 | |||
pass | |||
elif time_limit == '1': # 1是1个月内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
elif time_limit == '2': # 2是3个月内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
elif time_limit == '3': # 3是6个月内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
elif time_limit == '4': # 4是1年内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
tmp.append(topic) | |||
topics = tmp | |||
response = { | |||
'topics': topics, | |||
'kinds': kinds, | |||
'kid': kid, | |||
'time_limit': time_limit, | |||
'reply_limit': reply_limit, | |||
'uid': uid, | |||
} | |||
return render(request, 'all.html', response) | |||
elif request.method == 'POST': | |||
# 搜索接收一个字段,查询标题或者简介里有关键字的帖子 | |||
keys = request.POST.get('keys') | |||
# 按关键字查询标题里含有关键字的 | |||
topics = models.Topic.objects.filter(t_title__icontains=keys) | |||
kinds = models.Kind.objects.filter() | |||
return render(request, 'all.html', {'topics': topics, 'kinds': kinds, 'uid': uid}) | |||
def ownpublish(request, kid, reply_limit, time_limit): | |||
uid = request.session.get('uid') | |||
if request.method == 'GET': | |||
kinds = models.Kind.objects.filter() | |||
if kid == '0' and reply_limit == '0' and time_limit == '0': | |||
# 默认时间排序把帖子传过去 | |||
topics = models.Topic.objects.filter(t_uid = uid) | |||
else: | |||
# request.path_info # 获取当前url | |||
# from django.urls import reverse | |||
# reverse('all_tie', kwargs={'kid': '0', 'reply_limit': '0', 'time_limit': '0'}) | |||
topics = models.Topic.objects.filter(t_uid = uid) | |||
# 筛选分类 | |||
if kid != '0': | |||
topics = models.Topic.objects.filter(t_kind=kid,t_uid = uid) | |||
# 筛选回复数量 | |||
tmp = [] | |||
for topic in topics: | |||
# 查看每个帖子的回复数量 | |||
count = len(models.Reply.objects.filter(r_tid=topic.id)) | |||
# print(count) | |||
print(reply_limit) | |||
if reply_limit == '0': | |||
pass | |||
elif reply_limit == '1': # 1是大于100 | |||
print('到1了') | |||
if count < 100: | |||
print('到了') | |||
continue | |||
elif reply_limit == '2': # 2是30-100 | |||
if count < 30 or count > 100: | |||
continue | |||
elif reply_limit == '3': # 3是小于30 | |||
if count > 30: | |||
continue | |||
tmp.append(topic) | |||
topics = tmp | |||
print(topics) | |||
# 筛选发布时间 | |||
tmp = [] | |||
for topic in topics: | |||
if time_limit == '0': # 0是全部时间 | |||
pass | |||
elif time_limit == '1': # 1是1个月内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
elif time_limit == '2': # 2是3个月内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
elif time_limit == '3': # 3是6个月内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
elif time_limit == '4': # 4是1年内 | |||
# 如果在限制之前,就筛掉 | |||
pass | |||
tmp.append(topic) | |||
topics = tmp | |||
response = { | |||
'topics': topics, | |||
'kinds': kinds, | |||
'kid': kid, | |||
'time_limit': time_limit, | |||
'reply_limit': reply_limit, | |||
'uid': uid, | |||
} | |||
return render(request, 'ownpublish.html', response) | |||
elif request.method == 'POST': | |||
type1 = request.POST.get('type1') | |||
if type1 == 'owndelete': | |||
tid = request.POST.get('tid') | |||
# 刪除帖子 | |||
response = {'msg': '', 'status': False} | |||
r_id = request.POST.get('r_id') | |||
models.Topic.objects.filter(id=tid).delete() | |||
response['status'] = True | |||
return HttpResponse(json.dumps(response)) | |||
else: | |||
# 搜索接收一个字段,查询标题或者简介里有关键字的帖子 | |||
keys = request.POST.get('keys') | |||
# 按关键字查询标题里含有关键字的 | |||
topics = models.Topic.objects.filter(t_title__icontains=keys,t_uid = uid) | |||
kinds = models.Kind.objects.filter() | |||
return render(request, 'ownpublish.html', {'topics': topics, 'kinds': kinds, 'uid': uid}) | |||
# 登录 | |||
def login(request): | |||
if request.method == 'GET': | |||
return render(request, 'login.html') | |||
elif request.method == 'POST': | |||
# 验证用户名密码是否正确,然后登陆存入session | |||
type = request.POST.get('type') | |||
response = {'msg': '', 'status': False} | |||
uid = request.POST.get('uid') | |||
pwd = request.POST.get('pwd') | |||
if type == 'login': | |||
if len(models.User.objects.filter(uid=uid, password=pwd)) != 0: | |||
# 登录成功 | |||
response['status'] = True | |||
request.session['uid'] = uid | |||
return HttpResponse(json.dumps(response)) | |||
pass | |||
else: | |||
# 登录失败 | |||
response['msg'] = '用户名或者密码错误' | |||
return HttpResponse(json.dumps(response)) | |||
pass | |||
elif type == 'register': | |||
models.User.objects.create(uid=uid, password=pwd) | |||
response['status'] = True | |||
request.session['uid'] = uid | |||
return HttpResponse(json.dumps(response)) | |||
# 注册 | |||
def register(request): | |||
if request.method == 'POST': | |||
# 判断是否已有 | |||
uid = request.POST.get('uid') | |||
pwd = request.POST.get('pwd') | |||
if len(models.User.objects.filter(uid=uid)) != 0: | |||
# 已被创建,返回错误 | |||
return render(request, 'login.html', {'message': '用户名已被创建'}) | |||
else: | |||
# 插入数据 | |||
user = { | |||
'uid': uid, | |||
'password': pwd, | |||
} | |||
models.User.objects.create(**user) | |||
return redirect('/home') | |||
# 发布页 | |||
def publish(request): | |||
if request.method == 'GET': | |||
kinds = models.Kind.objects.filter() | |||
response = { | |||
'kinds': kinds | |||
} | |||
return render(request, 'publish.html', response) | |||
elif request.method == 'POST': | |||
# session获取uid | |||
uid = request.session['uid'] | |||
# 提交发布的文章 | |||
t_title = request.POST.get('t_title') | |||
t_introduce = request.POST.get('t_introduce') | |||
t_content = request.POST.get('t_content') | |||
t_kind = request.POST.get('t_kind') | |||
print(t_title, t_introduce) | |||
obj = models.Topic.objects.create(t_title=t_title, t_introduce=t_introduce, | |||
t_content=t_content, t_kind=t_kind, t_uid=uid) | |||
t_id = obj.id | |||
# 存帖子图片 | |||
t_photo = request.FILES.get('t_photo', None) | |||
#t_photo_path = 'static/img/t_photo/' + str(t_id) + '_' + t_photo.name | |||
if t_photo: | |||
t_photo_path = 'static/img/t_photo/' + str(t_id) + '_' + t_photo.name | |||
# 保存文件 | |||
import os | |||
f = open(os.path.join(t_photo_path), 'wb') | |||
for line in t_photo.chunks(): | |||
f.write(line) | |||
f.close() | |||
else: | |||
t_photo_path = 'static/img/t_photo/' + 'wrong.jpg' | |||
# 吧图片路径存入数据库 | |||
models.Topic.objects.filter(id=t_id).update(t_photo='/'+t_photo_path) | |||
return redirect('/single/' + str(t_id)) | |||
# 单个帖子页面 | |||
def single(request, tid): | |||
if request.method == 'GET': | |||
# 帖子内容 | |||
# 时间类别作者,标题,正文,图片path | |||
try: | |||
topic = models.Topic.objects.get(id = tid) | |||
except Exception as e: | |||
return redirect('/home') | |||
t_time = topic.create_time | |||
t_kind = topic.t_kind | |||
# 根据类别 id 获得类别名称 | |||
kind = models.Kind.objects.get(id = t_kind) | |||
t_kind = kind.k_name | |||
t_title = topic.t_title | |||
t_content = topic.t_content | |||
t_photo = topic.t_photo | |||
t_uid = topic.t_uid | |||
t_introduce = topic.t_introduce | |||
t_like = topic.t_like | |||
uid = request.session['uid'] | |||
admin_uid = request.session.get('admin_uid') | |||
response = { | |||
'tid': tid, | |||
't_uid': t_uid, | |||
't_time': t_time, | |||
't_kind': t_kind, | |||
't_title': t_title, | |||
't_content': t_content, | |||
't_photo': t_photo, | |||
't_introduce': t_introduce, | |||
'uid': uid, | |||
'admin_uid': admin_uid, | |||
't_like':t_like | |||
} | |||
# 留言内容 | |||
# 留言者,留言时间,留言内容 | |||
replys = models.Reply.objects.filter(r_tid=tid) | |||
reply_list = [] | |||
for reply in replys: | |||
single_reply = { | |||
'r_uid': reply.r_uid, | |||
'r_time': reply.r_time, | |||
'r_content': reply.r_content, | |||
'r_id': reply.id, | |||
'r_photo': reply.r_photo, | |||
} | |||
reply_list.append(single_reply) | |||
response['reply_list'] = reply_list | |||
return render(request, 'single.html', response) | |||
elif request.method == 'POST': | |||
type1 = request.POST.get('type1') | |||
if type1 == 'like': | |||
print("here") | |||
tid = request.POST.get('tid') | |||
response = {'msg': '', 'status': False} | |||
# 点赞数量增加 1 | |||
orignal_like = models.Topic.objects.get(id=tid).t_like | |||
models.Topic.objects.filter(id=tid).update(t_like=orignal_like + 1) | |||
response['status'] = True | |||
return HttpResponse(json.dumps(response)) | |||
# 判断是否登录 | |||
uid = request.session.get('uid') | |||
# 删除回复,管理员才可以删除 | |||
p_type = request.POST.get('type2') | |||
if p_type == 'delete': | |||
response = {'msg': '', 'status': False} | |||
r_id = request.POST.get('r_id') | |||
uid = request.POST.get('uid') | |||
r_uid = models.Reply.objects.get(id=r_id).r_uid | |||
if uid == r_uid: | |||
models.Reply.objects.filter(id=r_id).delete() | |||
response['status'] = True | |||
return HttpResponse(json.dumps(response)) | |||
if not uid: | |||
return redirect('/login') | |||
# 进行回复 | |||
r_content = request.POST.get('r_content') | |||
# 提交数据库 | |||
obj = models.Reply.objects.create(r_tid=tid,r_uid=uid,r_content=r_content) | |||
r_id = str(obj.id) | |||
r_photo = request.FILES.get('r_photo') | |||
if r_photo: | |||
# 保存文件 | |||
r_photo_path = 'static/img/r_photo/' + r_id + '_' + r_photo.name | |||
import os | |||
f = open(os.path.join(r_photo_path), 'wb') | |||
for line in r_photo.chunks(): | |||
f.write(line) | |||
f.close() | |||
models.Reply.objects.filter(id=r_id).update(r_photo='/'+r_photo_path) | |||
#else: | |||
#r_photo_path = 'static/img/t_photo/' + 'hungry.png' | |||
# 吧图片路径存入数据库 | |||
#models.Reply.objects.filter(id=r_id).update(r_photo='/'+r_photo_path) | |||
return redirect('/single/' + tid) | |||
# 修改密码页面 | |||
def edit_pwd(request): | |||
if request.method == 'GET': | |||
uid = request.session.get('uid') | |||
return render(request, 'edit-pwd.html', {'uid': uid}) | |||
if request.method == 'POST': | |||
uid = request.session.get('uid') | |||
old = request.POST.get('old_pwd') | |||
new1 = request.POST.get('new_pwd1') | |||
new2 = request.POST.get('new_pwd2') | |||
if new1 == new2 and len(models.User.objects.filter(uid=uid, password=old)) != 0: | |||
# 核对成功,修改密码 | |||
models.User.objects.filter(uid=uid).update(password=new1) | |||
return redirect('/home') | |||
# 管理员登录 | |||
def admin(request): | |||
if request.method == 'GET': | |||
return render(request, 'admin.html') | |||
elif request.method == 'POST': | |||
admin_uid = request.POST.get('admin_id') | |||
admin_pwd = request.POST.get('admin_pwd') | |||
response = {'msg': '', 'status': False} | |||
if admin_uid == 'guanliyuan' and admin_pwd == '123456': | |||
# 管理员登录成功 | |||
response['status'] = True | |||
request.session['admin_uid'] = 'guanliyuan' | |||
return HttpResponse(json.dumps(response)) | |||
else: | |||
response['msg'] = '用户名或者密码错误' | |||
return HttpResponse(json.dumps(response)) | |||
# 公告管理 | |||
def announcement(request): | |||
if not request.session.get('admin_uid'): | |||
return redirect('/my-admin') | |||
# 查询所有公告 | |||
if request.method == 'GET': | |||
announcements = models.Announcement.objects.filter() | |||
response = {'announcements': announcements} | |||
return render(request, 'announcement.html', response) | |||
# 发公告,删公告 | |||
elif request.method == 'POST': | |||
p_type = request.POST.get('type') | |||
response = {'msg': '', 'status': False} | |||
if p_type == 'delete': | |||
a_id = request.POST.get('a_id') | |||
models.Announcement.objects.filter(id=a_id).delete() | |||
response['status'] = True | |||
elif p_type == 'create': | |||
# 添加一条公告 | |||
a_title = request.POST.get('a_title') | |||
a_content = request.POST.get('a_content') | |||
models.Announcement.objects.create(a_title=a_title, a_content=a_content) | |||
response['status'] = True | |||
return HttpResponse(json.dumps(response)) | |||
# 帖子管理:标题,简介,时间, | |||
def topic_manage(request): | |||
if not request.session.get('admin_uid'): | |||
return redirect('/my-admin') | |||
if request.method == 'GET': | |||
topics = models.Topic.objects.filter() | |||
response = { | |||
'topics': topics, | |||
} | |||
return render(request, 'admin-home.html', response) | |||
elif request.method == 'POST': | |||
p_type = request.POST.get('type') | |||
response = {'msg': '', 'status': False} | |||
print(p_type) | |||
# 删除帖子 | |||
if p_type == 'delete': | |||
t_id = request.POST.get('t_id') | |||
models.Topic.objects.filter(id=t_id).delete() | |||
response['status'] = True | |||
# 置顶(推荐) | |||
if p_type == 'zhiding': | |||
print('置顶') | |||
t_id = request.POST.get('t_id') | |||
models.Topic.objects.filter(id=t_id).update(recommend=True) | |||
response['status'] = True | |||
# 取消置顶(推荐) | |||
if p_type == 'qzhiding': | |||
t_id = request.POST.get('t_id') | |||
models.Topic.objects.filter(id=t_id).update(recommend=False) | |||
response['status'] = True | |||
return HttpResponse(json.dumps(response)) | |||
# 类别管理(板块管理) | |||
def kind_manage(request): | |||
# 验证登录 | |||
if not request.session.get('admin_uid'): | |||
return redirect('/my-admin') | |||
if request.method == 'GET': | |||
# get返回所有类别(板块) | |||
kinds = models.Kind.objects.filter() | |||
response = { | |||
'kinds': kinds, | |||
} | |||
return render(request, 'kind-manage.html', response) | |||
if request.method == 'POST': | |||
p_type = request.POST.get('type') | |||
response = {'msg': '', 'status': False} | |||
# 删除类别 | |||
if p_type == 'delete': | |||
k_id = request.POST.get('k_id') | |||
models.Kind.objects.filter(id=k_id).delete() | |||
response['status'] = True | |||
# 添加类别 | |||
if p_type == 'create': | |||
k_name = request.POST.get('k_name') | |||
models.Kind.objects.create(k_name=k_name) | |||
response['status'] = True | |||
return HttpResponse(json.dumps(response)) | |||
# 公告页面 | |||
def single_an(request, aid): | |||
if request.method == 'GET': | |||
try: | |||
an = models.Announcement.objects.get(id=aid) | |||
except Exception as e: | |||
return '/home' | |||
a_title = an.a_title | |||
a_content = an.a_content | |||
response = { | |||
'a_title': a_title, | |||
'a_content': a_content, | |||
} | |||
return render(request, 'single-an.html', response) |
@ -0,0 +1,15 @@ | |||
#!/usr/bin/env python | |||
import os | |||
import sys | |||
if __name__ == '__main__': | |||
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'ForumSystem.settings') | |||
try: | |||
from django.core.management import execute_from_command_line | |||
except ImportError as exc: | |||
raise ImportError( | |||
"Couldn't import Django. Are you sure it's installed and " | |||
"available on your PYTHONPATH environment variable? Did you " | |||
"forget to activate a virtual environment?" | |||
) from exc | |||
execute_from_command_line(sys.argv) |
@ -0,0 +1,59 @@ | |||
appdirs==1.4.4 | |||
asgiref==3.3.1 | |||
atomicwrites==1.4.0 | |||
attrs==20.3.0 | |||
Automat==20.2.0 | |||
certifi==2020.12.5 | |||
cffi==1.14.4 | |||
cfgv==3.2.0 | |||
chardet==4.0.0 | |||
click==7.1.2 | |||
codecov==2.1.11 | |||
colorama==0.4.4 | |||
constantly==15.1.0 | |||
coverage==5.3.1 | |||
cryptography==3.3.1 | |||
cssselect==1.1.0 | |||
distlib==0.3.1 | |||
Django==3.1.5 | |||
filelock==3.0.12 | |||
Flask==1.1.2 | |||
hyperlink==20.0.1 | |||
identify==1.5.10 | |||
idna==2.10 | |||
incremental==17.5.0 | |||
iniconfig==1.1.1 | |||
itemadapter==0.2.0 | |||
itsdangerous==1.1.0 | |||
Jinja2==2.11.2 | |||
jmespath==0.10.0 | |||
lxml==4.6.2 | |||
MarkupSafe==1.1.1 | |||
nodeenv==1.5.0 | |||
packaging==20.8 | |||
parsel==1.6.0 | |||
pluggy==0.13.1 | |||
pre-commit==2.9.3 | |||
psycopg2==2.8.6 | |||
py==1.10.0 | |||
pyasn1==0.4.8 | |||
pyasn1-modules==0.2.8 | |||
pycparser==2.20 | |||
PyHamcrest==2.0.2 | |||
PyJWT==2.0.0 | |||
PyMySQL==0.10.1 | |||
pyparsing==2.4.7 | |||
pytest==6.2.1 | |||
pytz==2020.5 | |||
PyYAML==5.3.1 | |||
requests==2.25.1 | |||
simplejson==3.17.2 | |||
six==1.15.0 | |||
SQLAlchemy==1.3.22 | |||
sqlparse==0.4.1 | |||
toml==0.10.2 | |||
urllib3==1.26.2 | |||
virtualenv==20.2.2 | |||
w3lib==1.22.0 | |||
Werkzeug==1.0.1 | |||
zope.interface==5.2.0 |
@ -0,0 +1,260 @@ | |||
select.admin-autocomplete { | |||
width: 20em; | |||
} | |||
.select2-container--admin-autocomplete.select2-container { | |||
min-height: 30px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--single, | |||
.select2-container--admin-autocomplete .select2-selection--multiple { | |||
min-height: 30px; | |||
padding: 0; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--focus .select2-selection, | |||
.select2-container--admin-autocomplete.select2-container--open .select2-selection { | |||
border-color: #999; | |||
min-height: 30px; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--single, | |||
.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--single { | |||
padding: 0; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--focus .select2-selection.select2-selection--multiple, | |||
.select2-container--admin-autocomplete.select2-container--open .select2-selection.select2-selection--multiple { | |||
padding: 0; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--single { | |||
background-color: #fff; | |||
border: 1px solid #ccc; | |||
border-radius: 4px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered { | |||
color: #444; | |||
line-height: 30px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear { | |||
cursor: pointer; | |||
float: right; | |||
font-weight: bold; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__placeholder { | |||
color: #999; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow { | |||
height: 26px; | |||
position: absolute; | |||
top: 1px; | |||
right: 1px; | |||
width: 20px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b { | |||
border-color: #888 transparent transparent transparent; | |||
border-style: solid; | |||
border-width: 5px 4px 0 4px; | |||
height: 0; | |||
left: 50%; | |||
margin-left: -4px; | |||
margin-top: -2px; | |||
position: absolute; | |||
top: 50%; | |||
width: 0; | |||
} | |||
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__clear { | |||
float: left; | |||
} | |||
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--single .select2-selection__arrow { | |||
left: 1px; | |||
right: auto; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single { | |||
background-color: #eee; | |||
cursor: default; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--single .select2-selection__clear { | |||
display: none; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--open .select2-selection--single .select2-selection__arrow b { | |||
border-color: transparent transparent #888 transparent; | |||
border-width: 0 4px 5px 4px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple { | |||
background-color: white; | |||
border: 1px solid #ccc; | |||
border-radius: 4px; | |||
cursor: text; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered { | |||
box-sizing: border-box; | |||
list-style: none; | |||
margin: 0; | |||
padding: 0 5px; | |||
width: 100%; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered li { | |||
list-style: none; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__placeholder { | |||
color: #999; | |||
margin-top: 5px; | |||
float: left; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear { | |||
cursor: pointer; | |||
float: right; | |||
font-weight: bold; | |||
margin: 5px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice { | |||
background-color: #e4e4e4; | |||
border: 1px solid #ccc; | |||
border-radius: 4px; | |||
cursor: default; | |||
float: left; | |||
margin-right: 5px; | |||
margin-top: 5px; | |||
padding: 0 5px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove { | |||
color: #999; | |||
cursor: pointer; | |||
display: inline-block; | |||
font-weight: bold; | |||
margin-right: 2px; | |||
} | |||
.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__choice__remove:hover { | |||
color: #333; | |||
} | |||
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-search--inline { | |||
float: right; | |||
} | |||
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice { | |||
margin-left: 5px; | |||
margin-right: auto; | |||
} | |||
.select2-container--admin-autocomplete[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { | |||
margin-left: 2px; | |||
margin-right: auto; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--focus .select2-selection--multiple { | |||
border: solid #999 1px; | |||
outline: 0; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection--multiple { | |||
background-color: #eee; | |||
cursor: default; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--disabled .select2-selection__choice__remove { | |||
display: none; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--above .select2-selection--multiple { | |||
border-top-left-radius: 0; | |||
border-top-right-radius: 0; | |||
} | |||
.select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--single, .select2-container--admin-autocomplete.select2-container--open.select2-container--below .select2-selection--multiple { | |||
border-bottom-left-radius: 0; | |||
border-bottom-right-radius: 0; | |||
} | |||
.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field { | |||
border: 1px solid #ccc; | |||
} | |||
.select2-container--admin-autocomplete .select2-search--inline .select2-search__field { | |||
background: transparent; | |||
border: none; | |||
outline: 0; | |||
box-shadow: none; | |||
-webkit-appearance: textfield; | |||
} | |||
.select2-container--admin-autocomplete .select2-results > .select2-results__options { | |||
max-height: 200px; | |||
overflow-y: auto; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option[role=group] { | |||
padding: 0; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option[aria-disabled=true] { | |||
color: #999; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option[aria-selected=true] { | |||
background-color: #ddd; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option { | |||
padding-left: 1em; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__group { | |||
padding-left: 0; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -1em; | |||
padding-left: 2em; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -2em; | |||
padding-left: 3em; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -3em; | |||
padding-left: 4em; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -4em; | |||
padding-left: 5em; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -5em; | |||
padding-left: 6em; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] { | |||
background-color: #79aec8; | |||
color: white; | |||
} | |||
.select2-container--admin-autocomplete .select2-results__group { | |||
cursor: default; | |||
display: block; | |||
padding: 6px; | |||
} |
@ -0,0 +1,966 @@ | |||
/* | |||
DJANGO Admin styles | |||
*/ | |||
@import url(fonts.css); | |||
html, body { | |||
height: 100%; | |||
} | |||
body { | |||
margin: 0; | |||
padding: 0; | |||
font-size: 14px; | |||
font-family: "Roboto","Lucida Grande","DejaVu Sans","Bitstream Vera Sans",Verdana,Arial,sans-serif; | |||
color: #333; | |||
background: #fff; | |||
} | |||
/* LINKS */ | |||
a:link, a:visited { | |||
color: #447e9b; | |||
text-decoration: none; | |||
} | |||
a:focus, a:hover { | |||
color: #036; | |||
} | |||
a:focus { | |||
text-decoration: underline; | |||
} | |||
a img { | |||
border: none; | |||
} | |||
a.section:link, a.section:visited { | |||
color: #fff; | |||
text-decoration: none; | |||
} | |||
a.section:focus, a.section:hover { | |||
text-decoration: underline; | |||
} | |||
/* GLOBAL DEFAULTS */ | |||
p, ol, ul, dl { | |||
margin: .2em 0 .8em 0; | |||
} | |||
p { | |||
padding: 0; | |||
line-height: 140%; | |||
} | |||
h1,h2,h3,h4,h5 { | |||
font-weight: bold; | |||
} | |||
h1 { | |||
margin: 0 0 20px; | |||
font-weight: 300; | |||
font-size: 20px; | |||
color: #666; | |||
} | |||
h2 { | |||
font-size: 16px; | |||
margin: 1em 0 .5em 0; | |||
} | |||
h2.subhead { | |||
font-weight: normal; | |||
margin-top: 0; | |||
} | |||
h3 { | |||
font-size: 14px; | |||
margin: .8em 0 .3em 0; | |||
color: #666; | |||
font-weight: bold; | |||
} | |||
h4 { | |||
font-size: 12px; | |||
margin: 1em 0 .8em 0; | |||
padding-bottom: 3px; | |||
} | |||
h5 { | |||
font-size: 10px; | |||
margin: 1.5em 0 .5em 0; | |||
color: #666; | |||
text-transform: uppercase; | |||
letter-spacing: 1px; | |||
} | |||
ul > li { | |||
list-style-type: square; | |||
padding: 1px 0; | |||
} | |||
li ul { | |||
margin-bottom: 0; | |||
} | |||
li, dt, dd { | |||
font-size: 13px; | |||
line-height: 20px; | |||
} | |||
dt { | |||
font-weight: bold; | |||
margin-top: 4px; | |||
} | |||
dd { | |||
margin-left: 0; | |||
} | |||
form { | |||
margin: 0; | |||
padding: 0; | |||
} | |||
fieldset { | |||
margin: 0; | |||
min-width: 0; | |||
padding: 0; | |||
border: none; | |||
border-top: 1px solid #eee; | |||
} | |||
blockquote { | |||
font-size: 11px; | |||
color: #777; | |||
margin-left: 2px; | |||
padding-left: 10px; | |||
border-left: 5px solid #ddd; | |||
} | |||
code, pre { | |||
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; | |||
color: #666; | |||
font-size: 12px; | |||
overflow-x: auto; | |||
} | |||
pre.literal-block { | |||
margin: 10px; | |||
background: #eee; | |||
padding: 6px 8px; | |||
} | |||
code strong { | |||
color: #930; | |||
} | |||
hr { | |||
clear: both; | |||
color: #eee; | |||
background-color: #eee; | |||
height: 1px; | |||
border: none; | |||
margin: 0; | |||
padding: 0; | |||
font-size: 1px; | |||
line-height: 1px; | |||
} | |||
/* TEXT STYLES & MODIFIERS */ | |||
.small { | |||
font-size: 11px; | |||
} | |||
.mini { | |||
font-size: 10px; | |||
} | |||
.help, p.help, form p.help, div.help, form div.help, div.help li { | |||
font-size: 11px; | |||
color: #999; | |||
} | |||
div.help ul { | |||
margin-bottom: 0; | |||
} | |||
.help-tooltip { | |||
cursor: help; | |||
} | |||
p img, h1 img, h2 img, h3 img, h4 img, td img { | |||
vertical-align: middle; | |||
} | |||
.quiet, a.quiet:link, a.quiet:visited { | |||
color: #999; | |||
font-weight: normal; | |||
} | |||
.clear { | |||
clear: both; | |||
} | |||
.nowrap { | |||
white-space: nowrap; | |||
} | |||
/* TABLES */ | |||
table { | |||
border-collapse: collapse; | |||
border-color: #ccc; | |||
} | |||
td, th { | |||
font-size: 13px; | |||
line-height: 16px; | |||
border-bottom: 1px solid #eee; | |||
vertical-align: top; | |||
padding: 8px; | |||
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif; | |||
} | |||
th { | |||
font-weight: 600; | |||
text-align: left; | |||
} | |||
thead th, | |||
tfoot td { | |||
color: #666; | |||
padding: 5px 10px; | |||
font-size: 11px; | |||
background: #fff; | |||
border: none; | |||
border-top: 1px solid #eee; | |||
border-bottom: 1px solid #eee; | |||
} | |||
tfoot td { | |||
border-bottom: none; | |||
border-top: 1px solid #eee; | |||
} | |||
thead th.required { | |||
color: #000; | |||
} | |||
tr.alt { | |||
background: #f6f6f6; | |||
} | |||
tr:nth-child(odd), .row-form-errors { | |||
background: #fff; | |||
} | |||
tr:nth-child(even), | |||
tr:nth-child(even) .errorlist, | |||
tr:nth-child(odd) + .row-form-errors, | |||
tr:nth-child(odd) + .row-form-errors .errorlist { | |||
background: #f9f9f9; | |||
} | |||
/* SORTABLE TABLES */ | |||
thead th { | |||
padding: 5px 10px; | |||
line-height: normal; | |||
text-transform: uppercase; | |||
background: #f6f6f6; | |||
} | |||
thead th a:link, thead th a:visited { | |||
color: #666; | |||
} | |||
thead th.sorted { | |||
background: #eee; | |||
} | |||
thead th.sorted .text { | |||
padding-right: 42px; | |||
} | |||
table thead th .text span { | |||
padding: 8px 10px; | |||
display: block; | |||
} | |||
table thead th .text a { | |||
display: block; | |||
cursor: pointer; | |||
padding: 8px 10px; | |||
} | |||
table thead th .text a:focus, table thead th .text a:hover { | |||
background: #eee; | |||
} | |||
thead th.sorted a.sortremove { | |||
visibility: hidden; | |||
} | |||
table thead th.sorted:hover a.sortremove { | |||
visibility: visible; | |||
} | |||
table thead th.sorted .sortoptions { | |||
display: block; | |||
padding: 9px 5px 0 5px; | |||
float: right; | |||
text-align: right; | |||
} | |||
table thead th.sorted .sortpriority { | |||
font-size: .8em; | |||
min-width: 12px; | |||
text-align: center; | |||
vertical-align: 3px; | |||
margin-left: 2px; | |||
margin-right: 2px; | |||
} | |||
table thead th.sorted .sortoptions a { | |||
position: relative; | |||
width: 14px; | |||
height: 14px; | |||
display: inline-block; | |||
background: url(../img/sorting-icons.svg) 0 0 no-repeat; | |||
background-size: 14px auto; | |||
} | |||
table thead th.sorted .sortoptions a.sortremove { | |||
background-position: 0 0; | |||
} | |||
table thead th.sorted .sortoptions a.sortremove:after { | |||
content: '\\'; | |||
position: absolute; | |||
top: -6px; | |||
left: 3px; | |||
font-weight: 200; | |||
font-size: 18px; | |||
color: #999; | |||
} | |||
table thead th.sorted .sortoptions a.sortremove:focus:after, | |||
table thead th.sorted .sortoptions a.sortremove:hover:after { | |||
color: #447e9b; | |||
} | |||
table thead th.sorted .sortoptions a.sortremove:focus, | |||
table thead th.sorted .sortoptions a.sortremove:hover { | |||
background-position: 0 -14px; | |||
} | |||
table thead th.sorted .sortoptions a.ascending { | |||
background-position: 0 -28px; | |||
} | |||
table thead th.sorted .sortoptions a.ascending:focus, | |||
table thead th.sorted .sortoptions a.ascending:hover { | |||
background-position: 0 -42px; | |||
} | |||
table thead th.sorted .sortoptions a.descending { | |||
top: 1px; | |||
background-position: 0 -56px; | |||
} | |||
table thead th.sorted .sortoptions a.descending:focus, | |||
table thead th.sorted .sortoptions a.descending:hover { | |||
background-position: 0 -70px; | |||
} | |||
/* FORM DEFAULTS */ | |||
input, textarea, select, .form-row p, form .button { | |||
margin: 2px 0; | |||
padding: 2px 3px; | |||
vertical-align: middle; | |||
font-family: "Roboto", "Lucida Grande", Verdana, Arial, sans-serif; | |||
font-weight: normal; | |||
font-size: 13px; | |||
} | |||
.form-row div.help { | |||
padding: 2px 3px; | |||
} | |||
textarea { | |||
vertical-align: top; | |||
} | |||
input[type=text], input[type=password], input[type=email], input[type=url], | |||
input[type=number], input[type=tel], textarea, select, .vTextField { | |||
border: 1px solid #ccc; | |||
border-radius: 4px; | |||
padding: 5px 6px; | |||
margin-top: 0; | |||
} | |||
input[type=text]:focus, input[type=password]:focus, input[type=email]:focus, | |||
input[type=url]:focus, input[type=number]:focus, input[type=tel]:focus, | |||
textarea:focus, select:focus, .vTextField:focus { | |||
border-color: #999; | |||
} | |||
select { | |||
height: 30px; | |||
} | |||
select[multiple] { | |||
/* Allow HTML size attribute to override the height in the rule above. */ | |||
height: auto; | |||
min-height: 150px; | |||
} | |||
/* FORM BUTTONS */ | |||
.button, input[type=submit], input[type=button], .submit-row input, a.button { | |||
background: #79aec8; | |||
padding: 10px 15px; | |||
border: none; | |||
border-radius: 4px; | |||
color: #fff; | |||
cursor: pointer; | |||
} | |||
a.button { | |||
padding: 4px 5px; | |||
} | |||
.button:active, input[type=submit]:active, input[type=button]:active, | |||
.button:focus, input[type=submit]:focus, input[type=button]:focus, | |||
.button:hover, input[type=submit]:hover, input[type=button]:hover { | |||
background: #609ab6; | |||
} | |||
.button[disabled], input[type=submit][disabled], input[type=button][disabled] { | |||
opacity: 0.4; | |||
} | |||
.button.default, input[type=submit].default, .submit-row input.default { | |||
float: right; | |||
border: none; | |||
font-weight: 400; | |||
background: #417690; | |||
} | |||
.button.default:active, input[type=submit].default:active, | |||
.button.default:focus, input[type=submit].default:focus, | |||
.button.default:hover, input[type=submit].default:hover { | |||
background: #205067; | |||
} | |||
.button[disabled].default, | |||
input[type=submit][disabled].default, | |||
input[type=button][disabled].default { | |||
opacity: 0.4; | |||
} | |||
/* MODULES */ | |||
.module { | |||
border: none; | |||
margin-bottom: 30px; | |||
background: #fff; | |||
} | |||
.module p, .module ul, .module h3, .module h4, .module dl, .module pre { | |||
padding-left: 10px; | |||
padding-right: 10px; | |||
} | |||
.module blockquote { | |||
margin-left: 12px; | |||
} | |||
.module ul, .module ol { | |||
margin-left: 1.5em; | |||
} | |||
.module h3 { | |||
margin-top: .6em; | |||
} | |||
.module h2, .module caption, .inline-group h2 { | |||
margin: 0; | |||
padding: 8px; | |||
font-weight: 400; | |||
font-size: 13px; | |||
text-align: left; | |||
background: #79aec8; | |||
color: #fff; | |||
} | |||
.module caption, | |||
.inline-group h2 { | |||
font-size: 12px; | |||
letter-spacing: 0.5px; | |||
text-transform: uppercase; | |||
} | |||
.module table { | |||
border-collapse: collapse; | |||
} | |||
/* MESSAGES & ERRORS */ | |||
ul.messagelist { | |||
padding: 0; | |||
margin: 0; | |||
} | |||
ul.messagelist li { | |||
display: block; | |||
font-weight: 400; | |||
font-size: 13px; | |||
padding: 10px 10px 10px 65px; | |||
margin: 0 0 10px 0; | |||
background: #dfd url(../img/icon-yes.svg) 40px 12px no-repeat; | |||
background-size: 16px auto; | |||
color: #333; | |||
} | |||
ul.messagelist li.warning { | |||
background: #ffc url(../img/icon-alert.svg) 40px 14px no-repeat; | |||
background-size: 14px auto; | |||
} | |||
ul.messagelist li.error { | |||
background: #ffefef url(../img/icon-no.svg) 40px 12px no-repeat; | |||
background-size: 16px auto; | |||
} | |||
.errornote { | |||
font-size: 14px; | |||
font-weight: 700; | |||
display: block; | |||
padding: 10px 12px; | |||
margin: 0 0 10px 0; | |||
color: #ba2121; | |||
border: 1px solid #ba2121; | |||
border-radius: 4px; | |||
background-color: #fff; | |||
background-position: 5px 12px; | |||
} | |||
ul.errorlist { | |||
margin: 0 0 4px; | |||
padding: 0; | |||
color: #ba2121; | |||
background: #fff; | |||
} | |||
ul.errorlist li { | |||
font-size: 13px; | |||
display: block; | |||
margin-bottom: 4px; | |||
} | |||
ul.errorlist li:first-child { | |||
margin-top: 0; | |||
} | |||
ul.errorlist li a { | |||
color: inherit; | |||
text-decoration: underline; | |||
} | |||
td ul.errorlist { | |||
margin: 0; | |||
padding: 0; | |||
} | |||
td ul.errorlist li { | |||
margin: 0; | |||
} | |||
.form-row.errors { | |||
margin: 0; | |||
border: none; | |||
border-bottom: 1px solid #eee; | |||
background: none; | |||
} | |||
.form-row.errors ul.errorlist li { | |||
padding-left: 0; | |||
} | |||
.errors input, .errors select, .errors textarea, | |||
td ul.errorlist + input, td ul.errorlist + select, td ul.errorlist + textarea { | |||
border: 1px solid #ba2121; | |||
} | |||
.description { | |||
font-size: 12px; | |||
padding: 5px 0 0 12px; | |||
} | |||
/* BREADCRUMBS */ | |||
div.breadcrumbs { | |||
background: #79aec8; | |||
padding: 10px 40px; | |||
border: none; | |||
font-size: 14px; | |||
color: #c4dce8; | |||
text-align: left; | |||
} | |||
div.breadcrumbs a { | |||
color: #fff; | |||
} | |||
div.breadcrumbs a:focus, div.breadcrumbs a:hover { | |||
color: #c4dce8; | |||
} | |||
/* ACTION ICONS */ | |||
.viewlink, .inlineviewlink { | |||
padding-left: 16px; | |||
background: url(../img/icon-viewlink.svg) 0 1px no-repeat; | |||
} | |||
.addlink { | |||
padding-left: 16px; | |||
background: url(../img/icon-addlink.svg) 0 1px no-repeat; | |||
} | |||
.changelink, .inlinechangelink { | |||
padding-left: 16px; | |||
background: url(../img/icon-changelink.svg) 0 1px no-repeat; | |||
} | |||
.deletelink { | |||
padding-left: 16px; | |||
background: url(../img/icon-deletelink.svg) 0 1px no-repeat; | |||
} | |||
a.deletelink:link, a.deletelink:visited { | |||
color: #CC3434; | |||
} | |||
a.deletelink:focus, a.deletelink:hover { | |||
color: #993333; | |||
text-decoration: none; | |||
} | |||
/* OBJECT TOOLS */ | |||
.object-tools { | |||
font-size: 10px; | |||
font-weight: bold; | |||
padding-left: 0; | |||
float: right; | |||
position: relative; | |||
margin-top: -48px; | |||
} | |||
.form-row .object-tools { | |||
margin-top: 5px; | |||
margin-bottom: 5px; | |||
float: none; | |||
height: 2em; | |||
padding-left: 3.5em; | |||
} | |||
.object-tools li { | |||
display: block; | |||
float: left; | |||
margin-left: 5px; | |||
height: 16px; | |||
} | |||
.object-tools a { | |||
border-radius: 15px; | |||
} | |||
.object-tools a:link, .object-tools a:visited { | |||
display: block; | |||
float: left; | |||
padding: 3px 12px; | |||
background: #999; | |||
font-weight: 400; | |||
font-size: 11px; | |||
text-transform: uppercase; | |||
letter-spacing: 0.5px; | |||
color: #fff; | |||
} | |||
.object-tools a:focus, .object-tools a:hover { | |||
background-color: #417690; | |||
} | |||
.object-tools a:focus{ | |||
text-decoration: none; | |||
} | |||
.object-tools a.viewsitelink, .object-tools a.golink,.object-tools a.addlink { | |||
background-repeat: no-repeat; | |||
background-position: right 7px center; | |||
padding-right: 26px; | |||
} | |||
.object-tools a.viewsitelink, .object-tools a.golink { | |||
background-image: url(../img/tooltag-arrowright.svg); | |||
} | |||
.object-tools a.addlink { | |||
background-image: url(../img/tooltag-add.svg); | |||
} | |||
/* OBJECT HISTORY */ | |||
table#change-history { | |||
width: 100%; | |||
} | |||
table#change-history tbody th { | |||
width: 16em; | |||
} | |||
/* PAGE STRUCTURE */ | |||
#container { | |||
position: relative; | |||
width: 100%; | |||
min-width: 980px; | |||
padding: 0; | |||
display: flex; | |||
flex-direction: column; | |||
height: 100%; | |||
} | |||
#container > div { | |||
flex-shrink: 0; | |||
} | |||
#container > .main { | |||
display: flex; | |||
flex: 1 0 auto; | |||
} | |||
.main > .content { | |||
flex: 1 0; | |||
max-width: 100%; | |||
} | |||
#content { | |||
padding: 20px 40px; | |||
} | |||
.dashboard #content { | |||
width: 600px; | |||
} | |||
#content-main { | |||
float: left; | |||
width: 100%; | |||
} | |||
#content-related { | |||
float: right; | |||
width: 260px; | |||
position: relative; | |||
margin-right: -300px; | |||
} | |||
#footer { | |||
clear: both; | |||
padding: 10px; | |||
} | |||
/* COLUMN TYPES */ | |||
.colMS { | |||
margin-right: 300px; | |||
} | |||
.colSM { | |||
margin-left: 300px; | |||
} | |||
.colSM #content-related { | |||
float: left; | |||
margin-right: 0; | |||
margin-left: -300px; | |||
} | |||
.colSM #content-main { | |||
float: right; | |||
} | |||
.popup .colM { | |||
width: auto; | |||
} | |||
/* HEADER */ | |||
#header { | |||
width: auto; | |||
height: auto; | |||
display: flex; | |||
justify-content: space-between; | |||
align-items: center; | |||
padding: 10px 40px; | |||
background: #417690; | |||
color: #ffc; | |||
overflow: hidden; | |||
} | |||
#header a:link, #header a:visited { | |||
color: #fff; | |||
} | |||
#header a:focus , #header a:hover { | |||
text-decoration: underline; | |||
} | |||
#branding { | |||
float: left; | |||
} | |||
#branding h1 { | |||
padding: 0; | |||
margin: 0 20px 0 0; | |||
font-weight: 300; | |||
font-size: 24px; | |||
color: #f5dd5d; | |||
} | |||
#branding h1, #branding h1 a:link, #branding h1 a:visited { | |||
color: #f5dd5d; | |||
} | |||
#branding h2 { | |||
padding: 0 10px; | |||
font-size: 14px; | |||
margin: -8px 0 8px 0; | |||
font-weight: normal; | |||
color: #ffc; | |||
} | |||
#branding a:hover { | |||
text-decoration: none; | |||
} | |||
#user-tools { | |||
float: right; | |||
padding: 0; | |||
margin: 0 0 0 20px; | |||
font-weight: 300; | |||
font-size: 11px; | |||
letter-spacing: 0.5px; | |||
text-transform: uppercase; | |||
text-align: right; | |||
} | |||
#user-tools a { | |||
border-bottom: 1px solid rgba(255, 255, 255, 0.25); | |||
} | |||
#user-tools a:focus, #user-tools a:hover { | |||
text-decoration: none; | |||
border-bottom-color: #79aec8; | |||
color: #79aec8; | |||
} | |||
/* SIDEBAR */ | |||
#content-related { | |||
background: #f8f8f8; | |||
} | |||
#content-related .module { | |||
background: none; | |||
} | |||
#content-related h3 { | |||
font-size: 14px; | |||
color: #666; | |||
padding: 0 16px; | |||
margin: 0 0 16px; | |||
} | |||
#content-related h4 { | |||
font-size: 13px; | |||
} | |||
#content-related p { | |||
padding-left: 16px; | |||
padding-right: 16px; | |||
} | |||
#content-related .actionlist { | |||
padding: 0; | |||
margin: 16px; | |||
} | |||
#content-related .actionlist li { | |||
line-height: 1.2; | |||
margin-bottom: 10px; | |||
padding-left: 18px; | |||
} | |||
#content-related .module h2 { | |||
background: none; | |||
padding: 16px; | |||
margin-bottom: 16px; | |||
border-bottom: 1px solid #eaeaea; | |||
font-size: 18px; | |||
color: #333; | |||
} | |||
.delete-confirmation form input[type="submit"] { | |||
background: #ba2121; | |||
border-radius: 4px; | |||
padding: 10px 15px; | |||
color: #fff; | |||
} | |||
.delete-confirmation form input[type="submit"]:active, | |||
.delete-confirmation form input[type="submit"]:focus, | |||
.delete-confirmation form input[type="submit"]:hover { | |||
background: #a41515; | |||
} | |||
.delete-confirmation form .cancel-link { | |||
display: inline-block; | |||
vertical-align: middle; | |||
height: 15px; | |||
line-height: 15px; | |||
background: #ddd; | |||
border-radius: 4px; | |||
padding: 10px 15px; | |||
color: #333; | |||
margin: 0 0 0 10px; | |||
} | |||
.delete-confirmation form .cancel-link:active, | |||
.delete-confirmation form .cancel-link:focus, | |||
.delete-confirmation form .cancel-link:hover { | |||
background: #ccc; | |||
} | |||
/* POPUP */ | |||
.popup #content { | |||
padding: 20px; | |||
} | |||
.popup #container { | |||
min-width: 0; | |||
} | |||
.popup #header { | |||
padding: 10px 20px; | |||
} |
@ -0,0 +1,354 @@ | |||
/* CHANGELISTS */ | |||
#changelist { | |||
display: flex; | |||
align-items: flex-start; | |||
justify-content: space-between; | |||
} | |||
#changelist .changelist-form-container { | |||
flex: 1 1 auto; | |||
min-width: 0; | |||
} | |||
#changelist table { | |||
width: 100%; | |||
} | |||
.change-list .hiddenfields { display:none; } | |||
.change-list .filtered table { | |||
border-right: none; | |||
} | |||
.change-list .filtered { | |||
min-height: 400px; | |||
} | |||
.change-list .filtered .results, .change-list .filtered .paginator, | |||
.filtered #toolbar, .filtered div.xfull { | |||
width: auto; | |||
} | |||
.change-list .filtered table tbody th { | |||
padding-right: 1em; | |||
} | |||
#changelist-form .results { | |||
overflow-x: auto; | |||
width: 100%; | |||
} | |||
#changelist .toplinks { | |||
border-bottom: 1px solid #ddd; | |||
} | |||
#changelist .paginator { | |||
color: #666; | |||
border-bottom: 1px solid #eee; | |||
background: #fff; | |||
overflow: hidden; | |||
} | |||
/* CHANGELIST TABLES */ | |||
#changelist table thead th { | |||
padding: 0; | |||
white-space: nowrap; | |||
vertical-align: middle; | |||
} | |||
#changelist table thead th.action-checkbox-column { | |||
width: 1.5em; | |||
text-align: center; | |||
} | |||
#changelist table tbody td.action-checkbox { | |||
text-align: center; | |||
} | |||
#changelist table tfoot { | |||
color: #666; | |||
} | |||
/* TOOLBAR */ | |||
#toolbar { | |||
padding: 8px 10px; | |||
margin-bottom: 15px; | |||
border-top: 1px solid #eee; | |||
border-bottom: 1px solid #eee; | |||
background: #f8f8f8; | |||
color: #666; | |||
} | |||
#toolbar form input { | |||
border-radius: 4px; | |||
font-size: 14px; | |||
padding: 5px; | |||
color: #333; | |||
} | |||
#toolbar #searchbar { | |||
height: 19px; | |||
border: 1px solid #ccc; | |||
padding: 2px 5px; | |||
margin: 0; | |||
vertical-align: top; | |||
font-size: 13px; | |||
max-width: 100%; | |||
} | |||
#toolbar #searchbar:focus { | |||
border-color: #999; | |||
} | |||
#toolbar form input[type="submit"] { | |||
border: 1px solid #ccc; | |||
font-size: 13px; | |||
padding: 4px 8px; | |||
margin: 0; | |||
vertical-align: middle; | |||
background: #fff; | |||
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; | |||
cursor: pointer; | |||
color: #333; | |||
} | |||
#toolbar form input[type="submit"]:focus, | |||
#toolbar form input[type="submit"]:hover { | |||
border-color: #999; | |||
} | |||
#changelist-search img { | |||
vertical-align: middle; | |||
margin-right: 4px; | |||
} | |||
/* FILTER COLUMN */ | |||
#changelist-filter { | |||
order: 1; | |||
width: 240px; | |||
background: #f8f8f8; | |||
border-left: none; | |||
margin: 0 0 0 30px; | |||
} | |||
#changelist-filter h2 { | |||
font-size: 14px; | |||
text-transform: uppercase; | |||
letter-spacing: 0.5px; | |||
padding: 5px 15px; | |||
margin-bottom: 12px; | |||
border-bottom: none; | |||
} | |||
#changelist-filter h3 { | |||
font-weight: 400; | |||
font-size: 14px; | |||
padding: 0 15px; | |||
margin-bottom: 10px; | |||
} | |||
#changelist-filter ul { | |||
margin: 5px 0; | |||
padding: 0 15px 15px; | |||
border-bottom: 1px solid #eaeaea; | |||
} | |||
#changelist-filter ul:last-child { | |||
border-bottom: none; | |||
} | |||
#changelist-filter li { | |||
list-style-type: none; | |||
margin-left: 0; | |||
padding-left: 0; | |||
} | |||
#changelist-filter a { | |||
display: block; | |||
color: #999; | |||
text-overflow: ellipsis; | |||
overflow-x: hidden; | |||
} | |||
#changelist-filter li.selected { | |||
border-left: 5px solid #eaeaea; | |||
padding-left: 10px; | |||
margin-left: -15px; | |||
} | |||
#changelist-filter li.selected a { | |||
color: #5b80b2; | |||
} | |||
#changelist-filter a:focus, #changelist-filter a:hover, | |||
#changelist-filter li.selected a:focus, | |||
#changelist-filter li.selected a:hover { | |||
color: #036; | |||
} | |||
#changelist-filter #changelist-filter-clear a { | |||
font-size: 13px; | |||
padding-bottom: 10px; | |||
border-bottom: 1px solid #eaeaea; | |||
} | |||
/* DATE DRILLDOWN */ | |||
.change-list ul.toplinks { | |||
display: block; | |||
float: left; | |||
padding: 0; | |||
margin: 0; | |||
width: 100%; | |||
} | |||
.change-list ul.toplinks li { | |||
padding: 3px 6px; | |||
font-weight: bold; | |||
list-style-type: none; | |||
display: inline-block; | |||
} | |||
.change-list ul.toplinks .date-back a { | |||
color: #999; | |||
} | |||
.change-list ul.toplinks .date-back a:focus, | |||
.change-list ul.toplinks .date-back a:hover { | |||
color: #036; | |||
} | |||
/* PAGINATOR */ | |||
.paginator { | |||
font-size: 13px; | |||
padding-top: 10px; | |||
padding-bottom: 10px; | |||
line-height: 22px; | |||
margin: 0; | |||
border-top: 1px solid #ddd; | |||
width: 100%; | |||
} | |||
.paginator a:link, .paginator a:visited { | |||
padding: 2px 6px; | |||
background: #79aec8; | |||
text-decoration: none; | |||
color: #fff; | |||
} | |||
.paginator a.showall { | |||
border: none; | |||
background: none; | |||
color: #5b80b2; | |||
} | |||
.paginator a.showall:focus, .paginator a.showall:hover { | |||
background: none; | |||
color: #036; | |||
} | |||
.paginator .end { | |||
margin-right: 6px; | |||
} | |||
.paginator .this-page { | |||
padding: 2px 6px; | |||
font-weight: bold; | |||
font-size: 13px; | |||
vertical-align: top; | |||
} | |||
.paginator a:focus, .paginator a:hover { | |||
color: white; | |||
background: #036; | |||
} | |||
/* ACTIONS */ | |||
.filtered .actions { | |||
border-right: none; | |||
} | |||
#changelist table input { | |||
margin: 0; | |||
vertical-align: baseline; | |||
} | |||
#changelist table tbody tr.selected { | |||
background-color: #FFFFCC; | |||
} | |||
#changelist .actions { | |||
padding: 10px; | |||
background: #fff; | |||
border-top: none; | |||
border-bottom: none; | |||
line-height: 24px; | |||
color: #999; | |||
width: 100%; | |||
} | |||
#changelist .actions.selected { | |||
background: #fffccf; | |||
border-top: 1px solid #fffee8; | |||
border-bottom: 1px solid #edecd6; | |||
} | |||
#changelist .actions span.all, | |||
#changelist .actions span.action-counter, | |||
#changelist .actions span.clear, | |||
#changelist .actions span.question { | |||
font-size: 13px; | |||
margin: 0 0.5em; | |||
display: none; | |||
} | |||
#changelist .actions:last-child { | |||
border-bottom: none; | |||
} | |||
#changelist .actions select { | |||
vertical-align: top; | |||
height: 24px; | |||
background: none; | |||
color: #000; | |||
border: 1px solid #ccc; | |||
border-radius: 4px; | |||
font-size: 14px; | |||
padding: 0 0 0 4px; | |||
margin: 0; | |||
margin-left: 10px; | |||
} | |||
#changelist .actions select:focus { | |||
border-color: #999; | |||
} | |||
#changelist .actions label { | |||
display: inline-block; | |||
vertical-align: middle; | |||
font-size: 13px; | |||
} | |||
#changelist .actions .button { | |||
font-size: 13px; | |||
border: 1px solid #ccc; | |||
border-radius: 4px; | |||
background: #fff; | |||
box-shadow: 0 -15px 20px -10px rgba(0, 0, 0, 0.15) inset; | |||
cursor: pointer; | |||
height: 24px; | |||
line-height: 1; | |||
padding: 4px 8px; | |||
margin: 0; | |||
color: #333; | |||
} | |||
#changelist .actions .button:focus, #changelist .actions .button:hover { | |||
border-color: #999; | |||
} |
@ -0,0 +1,26 @@ | |||
/* DASHBOARD */ | |||
.dashboard .module table th { | |||
width: 100%; | |||
} | |||
.dashboard .module table td { | |||
white-space: nowrap; | |||
} | |||
.dashboard .module table td a { | |||
display: block; | |||
padding-right: .6em; | |||
} | |||
/* RECENT ACTIONS MODULE */ | |||
.module ul.actionlist { | |||
margin-left: 0; | |||
} | |||
ul.actionlist li { | |||
list-style-type: none; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
} |
@ -0,0 +1,20 @@ | |||
@font-face { | |||
font-family: 'Roboto'; | |||
src: url('../fonts/Roboto-Bold-webfont.woff'); | |||
font-weight: 700; | |||
font-style: normal; | |||
} | |||
@font-face { | |||
font-family: 'Roboto'; | |||
src: url('../fonts/Roboto-Regular-webfont.woff'); | |||
font-weight: 400; | |||
font-style: normal; | |||
} | |||
@font-face { | |||
font-family: 'Roboto'; | |||
src: url('../fonts/Roboto-Light-webfont.woff'); | |||
font-weight: 300; | |||
font-style: normal; | |||
} |
@ -0,0 +1,527 @@ | |||
@import url('widgets.css'); | |||
/* FORM ROWS */ | |||
.form-row { | |||
overflow: hidden; | |||
padding: 10px; | |||
font-size: 13px; | |||
border-bottom: 1px solid #eee; | |||
} | |||
.form-row img, .form-row input { | |||
vertical-align: middle; | |||
} | |||
.form-row label input[type="checkbox"] { | |||
margin-top: 0; | |||
vertical-align: 0; | |||
} | |||
form .form-row p { | |||
padding-left: 0; | |||
} | |||
.hidden { | |||
display: none; | |||
} | |||
/* FORM LABELS */ | |||
label { | |||
font-weight: normal; | |||
color: #666; | |||
font-size: 13px; | |||
} | |||
.required label, label.required { | |||
font-weight: bold; | |||
color: #333; | |||
} | |||
/* RADIO BUTTONS */ | |||
form ul.radiolist li { | |||
list-style-type: none; | |||
} | |||
form ul.radiolist label { | |||
float: none; | |||
display: inline; | |||
} | |||
form ul.radiolist input[type="radio"] { | |||
margin: -2px 4px 0 0; | |||
padding: 0; | |||
} | |||
form ul.inline { | |||
margin-left: 0; | |||
padding: 0; | |||
} | |||
form ul.inline li { | |||
float: left; | |||
padding-right: 7px; | |||
} | |||
/* ALIGNED FIELDSETS */ | |||
.aligned label { | |||
display: block; | |||
padding: 4px 10px 0 0; | |||
float: left; | |||
width: 160px; | |||
word-wrap: break-word; | |||
line-height: 1; | |||
} | |||
.aligned label:not(.vCheckboxLabel):after { | |||
content: ''; | |||
display: inline-block; | |||
vertical-align: middle; | |||
height: 26px; | |||
} | |||
.aligned label + p, .aligned label + div.help, .aligned label + div.readonly { | |||
padding: 6px 0; | |||
margin-top: 0; | |||
margin-bottom: 0; | |||
margin-left: 170px; | |||
} | |||
.aligned ul label { | |||
display: inline; | |||
float: none; | |||
width: auto; | |||
} | |||
.aligned .form-row input { | |||
margin-bottom: 0; | |||
} | |||
.colMS .aligned .vLargeTextField, .colMS .aligned .vXMLLargeTextField { | |||
width: 350px; | |||
} | |||
form .aligned ul { | |||
margin-left: 160px; | |||
padding-left: 10px; | |||
} | |||
form .aligned ul.radiolist { | |||
display: inline-block; | |||
margin: 0; | |||
padding: 0; | |||
} | |||
form .aligned p.help, | |||
form .aligned div.help { | |||
clear: left; | |||
margin-top: 0; | |||
margin-left: 160px; | |||
padding-left: 10px; | |||
} | |||
form .aligned label + p.help, | |||
form .aligned label + div.help { | |||
margin-left: 0; | |||
padding-left: 0; | |||
} | |||
form .aligned p.help:last-child, | |||
form .aligned div.help:last-child { | |||
margin-bottom: 0; | |||
padding-bottom: 0; | |||
} | |||
form .aligned input + p.help, | |||
form .aligned textarea + p.help, | |||
form .aligned select + p.help, | |||
form .aligned input + div.help, | |||
form .aligned textarea + div.help, | |||
form .aligned select + div.help { | |||
margin-left: 160px; | |||
padding-left: 10px; | |||
} | |||
form .aligned ul li { | |||
list-style: none; | |||
} | |||
form .aligned table p { | |||
margin-left: 0; | |||
padding-left: 0; | |||
} | |||
.aligned .vCheckboxLabel { | |||
float: none; | |||
width: auto; | |||
display: inline-block; | |||
vertical-align: -3px; | |||
padding: 0 0 5px 5px; | |||
} | |||
.aligned .vCheckboxLabel + p.help, | |||
.aligned .vCheckboxLabel + div.help { | |||
margin-top: -4px; | |||
} | |||
.colM .aligned .vLargeTextField, .colM .aligned .vXMLLargeTextField { | |||
width: 610px; | |||
} | |||
.checkbox-row p.help, | |||
.checkbox-row div.help { | |||
margin-left: 0; | |||
padding-left: 0; | |||
} | |||
fieldset .fieldBox { | |||
float: left; | |||
margin-right: 20px; | |||
} | |||
/* WIDE FIELDSETS */ | |||
.wide label { | |||
width: 200px; | |||
} | |||
form .wide p, | |||
form .wide input + p.help, | |||
form .wide input + div.help { | |||
margin-left: 200px; | |||
} | |||
form .wide p.help, | |||
form .wide div.help { | |||
padding-left: 38px; | |||
} | |||
form div.help ul { | |||
padding-left: 0; | |||
margin-left: 0; | |||
} | |||
.colM fieldset.wide .vLargeTextField, .colM fieldset.wide .vXMLLargeTextField { | |||
width: 450px; | |||
} | |||
/* COLLAPSED FIELDSETS */ | |||
fieldset.collapsed * { | |||
display: none; | |||
} | |||
fieldset.collapsed h2, fieldset.collapsed { | |||
display: block; | |||
} | |||
fieldset.collapsed { | |||
border: 1px solid #eee; | |||
border-radius: 4px; | |||
overflow: hidden; | |||
} | |||
fieldset.collapsed h2 { | |||
background: #f8f8f8; | |||
color: #666; | |||
} | |||
fieldset .collapse-toggle { | |||
color: #fff; | |||
} | |||
fieldset.collapsed .collapse-toggle { | |||
background: transparent; | |||
display: inline; | |||
color: #447e9b; | |||
} | |||
/* MONOSPACE TEXTAREAS */ | |||
fieldset.monospace textarea { | |||
font-family: "Bitstream Vera Sans Mono", Monaco, "Courier New", Courier, monospace; | |||
} | |||
/* SUBMIT ROW */ | |||
.submit-row { | |||
padding: 12px 14px; | |||
margin: 0 0 20px; | |||
background: #f8f8f8; | |||
border: 1px solid #eee; | |||
border-radius: 4px; | |||
text-align: right; | |||
overflow: hidden; | |||
} | |||
body.popup .submit-row { | |||
overflow: auto; | |||
} | |||
.submit-row input { | |||
height: 35px; | |||
line-height: 15px; | |||
margin: 0 0 0 5px; | |||
} | |||
.submit-row input.default { | |||
margin: 0 0 0 8px; | |||
text-transform: uppercase; | |||
} | |||
.submit-row p { | |||
margin: 0.3em; | |||
} | |||
.submit-row p.deletelink-box { | |||
float: left; | |||
margin: 0; | |||
} | |||
.submit-row a.deletelink { | |||
display: block; | |||
background: #ba2121; | |||
border-radius: 4px; | |||
padding: 10px 15px; | |||
height: 15px; | |||
line-height: 15px; | |||
color: #fff; | |||
} | |||
.submit-row a.closelink { | |||
display: inline-block; | |||
background: #bbbbbb; | |||
border-radius: 4px; | |||
padding: 10px 15px; | |||
height: 15px; | |||
line-height: 15px; | |||
margin: 0 0 0 5px; | |||
color: #fff; | |||
} | |||
.submit-row a.deletelink:focus, | |||
.submit-row a.deletelink:hover, | |||
.submit-row a.deletelink:active { | |||
background: #a41515; | |||
} | |||
.submit-row a.closelink:focus, | |||
.submit-row a.closelink:hover, | |||
.submit-row a.closelink:active { | |||
background: #aaaaaa; | |||
} | |||
/* CUSTOM FORM FIELDS */ | |||
.vSelectMultipleField { | |||
vertical-align: top; | |||
} | |||
.vCheckboxField { | |||
border: none; | |||
} | |||
.vDateField, .vTimeField { | |||
margin-right: 2px; | |||
margin-bottom: 4px; | |||
} | |||
.vDateField { | |||
min-width: 6.85em; | |||
} | |||
.vTimeField { | |||
min-width: 4.7em; | |||
} | |||
.vURLField { | |||
width: 30em; | |||
} | |||
.vLargeTextField, .vXMLLargeTextField { | |||
width: 48em; | |||
} | |||
.flatpages-flatpage #id_content { | |||
height: 40.2em; | |||
} | |||
.module table .vPositiveSmallIntegerField { | |||
width: 2.2em; | |||
} | |||
.vTextField, .vUUIDField { | |||
width: 20em; | |||
} | |||
.vIntegerField { | |||
width: 5em; | |||
} | |||
.vBigIntegerField { | |||
width: 10em; | |||
} | |||
.vForeignKeyRawIdAdminField { | |||
width: 5em; | |||
} | |||
/* INLINES */ | |||
.inline-group { | |||
padding: 0; | |||
margin: 0 0 30px; | |||
} | |||
.inline-group thead th { | |||
padding: 8px 10px; | |||
} | |||
.inline-group .aligned label { | |||
width: 160px; | |||
} | |||
.inline-related { | |||
position: relative; | |||
} | |||
.inline-related h3 { | |||
margin: 0; | |||
color: #666; | |||
padding: 5px; | |||
font-size: 13px; | |||
background: #f8f8f8; | |||
border-top: 1px solid #eee; | |||
border-bottom: 1px solid #eee; | |||
} | |||
.inline-related h3 span.delete { | |||
float: right; | |||
} | |||
.inline-related h3 span.delete label { | |||
margin-left: 2px; | |||
font-size: 11px; | |||
} | |||
.inline-related fieldset { | |||
margin: 0; | |||
background: #fff; | |||
border: none; | |||
width: 100%; | |||
} | |||
.inline-related fieldset.module h3 { | |||
margin: 0; | |||
padding: 2px 5px 3px 5px; | |||
font-size: 11px; | |||
text-align: left; | |||
font-weight: bold; | |||
background: #bcd; | |||
color: #fff; | |||
} | |||
.inline-group .tabular fieldset.module { | |||
border: none; | |||
} | |||
.inline-related.tabular fieldset.module table { | |||
width: 100%; | |||
overflow-x: scroll; | |||
} | |||
.last-related fieldset { | |||
border: none; | |||
} | |||
.inline-group .tabular tr.has_original td { | |||
padding-top: 2em; | |||
} | |||
.inline-group .tabular tr td.original { | |||
padding: 2px 0 0 0; | |||
width: 0; | |||
_position: relative; | |||
} | |||
.inline-group .tabular th.original { | |||
width: 0px; | |||
padding: 0; | |||
} | |||
.inline-group .tabular td.original p { | |||
position: absolute; | |||
left: 0; | |||
height: 1.1em; | |||
padding: 2px 9px; | |||
overflow: hidden; | |||
font-size: 9px; | |||
font-weight: bold; | |||
color: #666; | |||
_width: 700px; | |||
} | |||
.inline-group ul.tools { | |||
padding: 0; | |||
margin: 0; | |||
list-style: none; | |||
} | |||
.inline-group ul.tools li { | |||
display: inline; | |||
padding: 0 5px; | |||
} | |||
.inline-group div.add-row, | |||
.inline-group .tabular tr.add-row td { | |||
color: #666; | |||
background: #f8f8f8; | |||
padding: 8px 10px; | |||
border-bottom: 1px solid #eee; | |||
} | |||
.inline-group .tabular tr.add-row td { | |||
padding: 8px 10px; | |||
border-bottom: 1px solid #eee; | |||
} | |||
.inline-group ul.tools a.add, | |||
.inline-group div.add-row a, | |||
.inline-group .tabular tr.add-row td a { | |||
background: url(../img/icon-addlink.svg) 0 1px no-repeat; | |||
padding-left: 16px; | |||
font-size: 12px; | |||
} | |||
.empty-form { | |||
display: none; | |||
} | |||
/* RELATED FIELD ADD ONE / LOOKUP */ | |||
.related-lookup { | |||
margin-left: 5px; | |||
display: inline-block; | |||
vertical-align: middle; | |||
background-repeat: no-repeat; | |||
background-size: 14px; | |||
} | |||
.related-lookup { | |||
width: 16px; | |||
height: 16px; | |||
background-image: url(../img/search.svg); | |||
} | |||
form .related-widget-wrapper ul { | |||
display: inline-block; | |||
margin-left: 0; | |||
padding-left: 0; | |||
} | |||
.clearable-file-input input { | |||
margin-top: 0; | |||
} |
@ -0,0 +1,79 @@ | |||
/* LOGIN FORM */ | |||
.login { | |||
background: #f8f8f8; | |||
height: auto; | |||
} | |||
.login #header { | |||
height: auto; | |||
padding: 15px 16px; | |||
justify-content: center; | |||
} | |||
.login #header h1 { | |||
font-size: 18px; | |||
} | |||
.login #header h1 a { | |||
color: #fff; | |||
} | |||
.login #content { | |||
padding: 20px 20px 0; | |||
} | |||
.login #container { | |||
background: #fff; | |||
border: 1px solid #eaeaea; | |||
border-radius: 4px; | |||
overflow: hidden; | |||
width: 28em; | |||
min-width: 300px; | |||
margin: 100px auto; | |||
height: auto; | |||
} | |||
.login #content-main { | |||
width: 100%; | |||
} | |||
.login .form-row { | |||
padding: 4px 0; | |||
float: left; | |||
width: 100%; | |||
border-bottom: none; | |||
} | |||
.login .form-row label { | |||
padding-right: 0.5em; | |||
line-height: 2em; | |||
font-size: 1em; | |||
clear: both; | |||
color: #333; | |||
} | |||
.login .form-row #id_username, .login .form-row #id_password { | |||
clear: both; | |||
padding: 8px; | |||
width: 100%; | |||
box-sizing: border-box; | |||
} | |||
.login span.help { | |||
font-size: 10px; | |||
display: block; | |||
} | |||
.login .submit-row { | |||
clear: both; | |||
padding: 1em 0 0 9.4em; | |||
margin: 0; | |||
border: none; | |||
background: none; | |||
text-align: left; | |||
} | |||
.login .password-reset-link { | |||
text-align: center; | |||
} |
@ -0,0 +1,119 @@ | |||
.sticky { | |||
position: sticky; | |||
top: 0; | |||
max-height: 100vh; | |||
} | |||
.toggle-nav-sidebar { | |||
z-index: 20; | |||
left: 0; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
flex: 0 0 23px; | |||
width: 23px; | |||
border-right: 1px solid #eaeaea; | |||
background-color: #ffffff; | |||
cursor: pointer; | |||
font-size: 20px; | |||
color: #447e9b; | |||
padding: 0; | |||
} | |||
[dir="rtl"] .toggle-nav-sidebar { | |||
border-left: 1px solid #eaeaea; | |||
border-right: 0; | |||
} | |||
.toggle-nav-sidebar:hover, | |||
.toggle-nav-sidebar:focus { | |||
background-color: #f6f6f6; | |||
} | |||
#nav-sidebar { | |||
z-index: 15; | |||
flex: 0 0 275px; | |||
left: -276px; | |||
margin-left: -276px; | |||
border-top: 1px solid transparent; | |||
border-right: 1px solid #eaeaea; | |||
background-color: #ffffff; | |||
overflow: auto; | |||
} | |||
[dir="rtl"] #nav-sidebar { | |||
border-left: 1px solid #eaeaea; | |||
border-right: 0; | |||
left: 0; | |||
margin-left: 0; | |||
right: -276px; | |||
margin-right: -276px; | |||
} | |||
.toggle-nav-sidebar::before { | |||
content: '\00BB'; | |||
} | |||
.main.shifted .toggle-nav-sidebar::before { | |||
content: '\00AB'; | |||
} | |||
.main.shifted > #nav-sidebar { | |||
left: 24px; | |||
margin-left: 0; | |||
} | |||
[dir="rtl"] .main.shifted > #nav-sidebar { | |||
left: 0; | |||
right: 24px; | |||
margin-right: 0; | |||
} | |||
#nav-sidebar .module th { | |||
width: 100%; | |||
overflow-wrap: anywhere; | |||
} | |||
#nav-sidebar .module th, | |||
#nav-sidebar .module caption { | |||
padding-left: 16px; | |||
} | |||
#nav-sidebar .module td { | |||
white-space: nowrap; | |||
} | |||
[dir="rtl"] #nav-sidebar .module th, | |||
[dir="rtl"] #nav-sidebar .module caption { | |||
padding-left: 8px; | |||
padding-right: 16px; | |||
} | |||
#nav-sidebar .current-app .section:link, | |||
#nav-sidebar .current-app .section:visited { | |||
color: #ffc; | |||
font-weight: bold; | |||
} | |||
#nav-sidebar .current-model { | |||
background: #ffc; | |||
} | |||
.main > #nav-sidebar + .content { | |||
max-width: calc(100% - 23px); | |||
} | |||
.main.shifted > #nav-sidebar + .content { | |||
max-width: calc(100% - 299px); | |||
} | |||
@media (max-width: 767px) { | |||
#nav-sidebar, #toggle-nav-sidebar { | |||
display: none; | |||
} | |||
.main > #nav-sidebar + .content, | |||
.main.shifted > #nav-sidebar + .content { | |||
max-width: 100%; | |||
} | |||
} |
@ -0,0 +1,80 @@ | |||
/* TABLETS */ | |||
@media (max-width: 1024px) { | |||
[dir="rtl"] .colMS { | |||
margin-right: 0; | |||
} | |||
[dir="rtl"] #user-tools { | |||
text-align: right; | |||
} | |||
[dir="rtl"] #changelist .actions label { | |||
padding-left: 10px; | |||
padding-right: 0; | |||
} | |||
[dir="rtl"] #changelist .actions select { | |||
margin-left: 0; | |||
margin-right: 15px; | |||
} | |||
[dir="rtl"] .change-list .filtered .results, | |||
[dir="rtl"] .change-list .filtered .paginator, | |||
[dir="rtl"] .filtered #toolbar, | |||
[dir="rtl"] .filtered div.xfull, | |||
[dir="rtl"] .filtered .actions, | |||
[dir="rtl"] #changelist-filter { | |||
margin-left: 0; | |||
} | |||
[dir="rtl"] .inline-group ul.tools a.add, | |||
[dir="rtl"] .inline-group div.add-row a, | |||
[dir="rtl"] .inline-group .tabular tr.add-row td a { | |||
padding: 8px 26px 8px 10px; | |||
background-position: calc(100% - 8px) 9px; | |||
} | |||
[dir="rtl"] .related-widget-wrapper-link + .selector { | |||
margin-right: 0; | |||
margin-left: 15px; | |||
} | |||
[dir="rtl"] .selector .selector-filter label { | |||
margin-right: 0; | |||
margin-left: 8px; | |||
} | |||
[dir="rtl"] .object-tools li { | |||
float: right; | |||
} | |||
[dir="rtl"] .object-tools li + li { | |||
margin-left: 0; | |||
margin-right: 15px; | |||
} | |||
[dir="rtl"] .dashboard .module table td a { | |||
padding-left: 0; | |||
padding-right: 16px; | |||
} | |||
} | |||
/* MOBILE */ | |||
@media (max-width: 767px) { | |||
[dir="rtl"] .aligned .related-lookup, | |||
[dir="rtl"] .aligned .datetimeshortcuts { | |||
margin-left: 0; | |||
margin-right: 15px; | |||
} | |||
[dir="rtl"] .aligned ul { | |||
margin-right: 0; | |||
} | |||
[dir="rtl"] #changelist-filter { | |||
margin-left: 0; | |||
margin-right: 0; | |||
} | |||
} |
@ -0,0 +1,249 @@ | |||
body { | |||
direction: rtl; | |||
} | |||
/* LOGIN */ | |||
.login .form-row { | |||
float: right; | |||
} | |||
.login .form-row label { | |||
float: right; | |||
padding-left: 0.5em; | |||
padding-right: 0; | |||
text-align: left; | |||
} | |||
.login .submit-row { | |||
clear: both; | |||
padding: 1em 9.4em 0 0; | |||
} | |||
/* GLOBAL */ | |||
th { | |||
text-align: right; | |||
} | |||
.module h2, .module caption { | |||
text-align: right; | |||
} | |||
.module ul, .module ol { | |||
margin-left: 0; | |||
margin-right: 1.5em; | |||
} | |||
.viewlink, .addlink, .changelink { | |||
padding-left: 0; | |||
padding-right: 16px; | |||
background-position: 100% 1px; | |||
} | |||
.deletelink { | |||
padding-left: 0; | |||
padding-right: 16px; | |||
background-position: 100% 1px; | |||
} | |||
.object-tools { | |||
float: left; | |||
} | |||
thead th:first-child, | |||
tfoot td:first-child { | |||
border-left: none; | |||
} | |||
/* LAYOUT */ | |||
#user-tools { | |||
right: auto; | |||
left: 0; | |||
text-align: left; | |||
} | |||
div.breadcrumbs { | |||
text-align: right; | |||
} | |||
#content-main { | |||
float: right; | |||
} | |||
#content-related { | |||
float: left; | |||
margin-left: -300px; | |||
margin-right: auto; | |||
} | |||
.colMS { | |||
margin-left: 300px; | |||
margin-right: 0; | |||
} | |||
/* SORTABLE TABLES */ | |||
table thead th.sorted .sortoptions { | |||
float: left; | |||
} | |||
thead th.sorted .text { | |||
padding-right: 0; | |||
padding-left: 42px; | |||
} | |||
/* dashboard styles */ | |||
.dashboard .module table td a { | |||
padding-left: .6em; | |||
padding-right: 16px; | |||
} | |||
/* changelists styles */ | |||
.change-list .filtered table { | |||
border-left: none; | |||
border-right: 0px none; | |||
} | |||
#changelist-filter { | |||
border-left: none; | |||
border-right: none; | |||
margin-left: 0; | |||
margin-right: 30px; | |||
} | |||
#changelist-filter li.selected { | |||
border-left: none; | |||
padding-left: 10px; | |||
margin-left: 0; | |||
border-right: 5px solid #eaeaea; | |||
padding-right: 10px; | |||
margin-right: -15px; | |||
} | |||
#changelist table tbody td:first-child, #changelist table tbody th:first-child { | |||
border-right: none; | |||
border-left: none; | |||
} | |||
/* FORMS */ | |||
.aligned label { | |||
padding: 0 0 3px 1em; | |||
float: right; | |||
} | |||
.submit-row { | |||
text-align: left | |||
} | |||
.submit-row p.deletelink-box { | |||
float: right; | |||
} | |||
.submit-row input.default { | |||
margin-left: 0; | |||
} | |||
.vDateField, .vTimeField { | |||
margin-left: 2px; | |||
} | |||
.aligned .form-row input { | |||
margin-left: 5px; | |||
} | |||
form .aligned p.help, form .aligned div.help { | |||
clear: right; | |||
} | |||
form .aligned ul { | |||
margin-right: 163px; | |||
margin-left: 0; | |||
} | |||
form ul.inline li { | |||
float: right; | |||
padding-right: 0; | |||
padding-left: 7px; | |||
} | |||
input[type=submit].default, .submit-row input.default { | |||
float: left; | |||
} | |||
fieldset .fieldBox { | |||
float: right; | |||
margin-left: 20px; | |||
margin-right: 0; | |||
} | |||
.errorlist li { | |||
background-position: 100% 12px; | |||
padding: 0; | |||
} | |||
.errornote { | |||
background-position: 100% 12px; | |||
padding: 10px 12px; | |||
} | |||
/* WIDGETS */ | |||
.calendarnav-previous { | |||
top: 0; | |||
left: auto; | |||
right: 10px; | |||
} | |||
.calendarnav-next { | |||
top: 0; | |||
right: auto; | |||
left: 10px; | |||
} | |||
.calendar caption, .calendarbox h2 { | |||
text-align: center; | |||
} | |||
.selector { | |||
float: right; | |||
} | |||
.selector .selector-filter { | |||
text-align: right; | |||
} | |||
.inline-deletelink { | |||
float: left; | |||
} | |||
form .form-row p.datetime { | |||
overflow: hidden; | |||
} | |||
.related-widget-wrapper { | |||
float: right; | |||
} | |||
/* MISC */ | |||
.inline-related h2, .inline-group h2 { | |||
text-align: right | |||
} | |||
.inline-related h3 span.delete { | |||
padding-right: 20px; | |||
padding-left: inherit; | |||
left: 10px; | |||
right: inherit; | |||
float:left; | |||
} | |||
.inline-related h3 span.delete label { | |||
margin-left: inherit; | |||
margin-right: 2px; | |||
} |
@ -0,0 +1,21 @@ | |||
The MIT License (MIT) | |||
Copyright (c) 2012-2017 Kevin Brown, Igor Vaynberg, and Select2 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. |
@ -0,0 +1,481 @@ | |||
.select2-container { | |||
box-sizing: border-box; | |||
display: inline-block; | |||
margin: 0; | |||
position: relative; | |||
vertical-align: middle; } | |||
.select2-container .select2-selection--single { | |||
box-sizing: border-box; | |||
cursor: pointer; | |||
display: block; | |||
height: 28px; | |||
user-select: none; | |||
-webkit-user-select: none; } | |||
.select2-container .select2-selection--single .select2-selection__rendered { | |||
display: block; | |||
padding-left: 8px; | |||
padding-right: 20px; | |||
overflow: hidden; | |||
text-overflow: ellipsis; | |||
white-space: nowrap; } | |||
.select2-container .select2-selection--single .select2-selection__clear { | |||
position: relative; } | |||
.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { | |||
padding-right: 8px; | |||
padding-left: 20px; } | |||
.select2-container .select2-selection--multiple { | |||
box-sizing: border-box; | |||
cursor: pointer; | |||
display: block; | |||
min-height: 32px; | |||
user-select: none; | |||
-webkit-user-select: none; } | |||
.select2-container .select2-selection--multiple .select2-selection__rendered { | |||
display: inline-block; | |||
overflow: hidden; | |||
padding-left: 8px; | |||
text-overflow: ellipsis; | |||
white-space: nowrap; } | |||
.select2-container .select2-search--inline { | |||
float: left; } | |||
.select2-container .select2-search--inline .select2-search__field { | |||
box-sizing: border-box; | |||
border: none; | |||
font-size: 100%; | |||
margin-top: 5px; | |||
padding: 0; } | |||
.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { | |||
-webkit-appearance: none; } | |||
.select2-dropdown { | |||
background-color: white; | |||
border: 1px solid #aaa; | |||
border-radius: 4px; | |||
box-sizing: border-box; | |||
display: block; | |||
position: absolute; | |||
left: -100000px; | |||
width: 100%; | |||
z-index: 1051; } | |||
.select2-results { | |||
display: block; } | |||
.select2-results__options { | |||
list-style: none; | |||
margin: 0; | |||
padding: 0; } | |||
.select2-results__option { | |||
padding: 6px; | |||
user-select: none; | |||
-webkit-user-select: none; } | |||
.select2-results__option[aria-selected] { | |||
cursor: pointer; } | |||
.select2-container--open .select2-dropdown { | |||
left: 0; } | |||
.select2-container--open .select2-dropdown--above { | |||
border-bottom: none; | |||
border-bottom-left-radius: 0; | |||
border-bottom-right-radius: 0; } | |||
.select2-container--open .select2-dropdown--below { | |||
border-top: none; | |||
border-top-left-radius: 0; | |||
border-top-right-radius: 0; } | |||
.select2-search--dropdown { | |||
display: block; | |||
padding: 4px; } | |||
.select2-search--dropdown .select2-search__field { | |||
padding: 4px; | |||
width: 100%; | |||
box-sizing: border-box; } | |||
.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { | |||
-webkit-appearance: none; } | |||
.select2-search--dropdown.select2-search--hide { | |||
display: none; } | |||
.select2-close-mask { | |||
border: 0; | |||
margin: 0; | |||
padding: 0; | |||
display: block; | |||
position: fixed; | |||
left: 0; | |||
top: 0; | |||
min-height: 100%; | |||
min-width: 100%; | |||
height: auto; | |||
width: auto; | |||
opacity: 0; | |||
z-index: 99; | |||
background-color: #fff; | |||
filter: alpha(opacity=0); } | |||
.select2-hidden-accessible { | |||
border: 0 !important; | |||
clip: rect(0 0 0 0) !important; | |||
-webkit-clip-path: inset(50%) !important; | |||
clip-path: inset(50%) !important; | |||
height: 1px !important; | |||
overflow: hidden !important; | |||
padding: 0 !important; | |||
position: absolute !important; | |||
width: 1px !important; | |||
white-space: nowrap !important; } | |||
.select2-container--default .select2-selection--single { | |||
background-color: #fff; | |||
border: 1px solid #aaa; | |||
border-radius: 4px; } | |||
.select2-container--default .select2-selection--single .select2-selection__rendered { | |||
color: #444; | |||
line-height: 28px; } | |||
.select2-container--default .select2-selection--single .select2-selection__clear { | |||
cursor: pointer; | |||
float: right; | |||
font-weight: bold; } | |||
.select2-container--default .select2-selection--single .select2-selection__placeholder { | |||
color: #999; } | |||
.select2-container--default .select2-selection--single .select2-selection__arrow { | |||
height: 26px; | |||
position: absolute; | |||
top: 1px; | |||
right: 1px; | |||
width: 20px; } | |||
.select2-container--default .select2-selection--single .select2-selection__arrow b { | |||
border-color: #888 transparent transparent transparent; | |||
border-style: solid; | |||
border-width: 5px 4px 0 4px; | |||
height: 0; | |||
left: 50%; | |||
margin-left: -4px; | |||
margin-top: -2px; | |||
position: absolute; | |||
top: 50%; | |||
width: 0; } | |||
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { | |||
float: left; } | |||
.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { | |||
left: 1px; | |||
right: auto; } | |||
.select2-container--default.select2-container--disabled .select2-selection--single { | |||
background-color: #eee; | |||
cursor: default; } | |||
.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { | |||
display: none; } | |||
.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { | |||
border-color: transparent transparent #888 transparent; | |||
border-width: 0 4px 5px 4px; } | |||
.select2-container--default .select2-selection--multiple { | |||
background-color: white; | |||
border: 1px solid #aaa; | |||
border-radius: 4px; | |||
cursor: text; } | |||
.select2-container--default .select2-selection--multiple .select2-selection__rendered { | |||
box-sizing: border-box; | |||
list-style: none; | |||
margin: 0; | |||
padding: 0 5px; | |||
width: 100%; } | |||
.select2-container--default .select2-selection--multiple .select2-selection__rendered li { | |||
list-style: none; } | |||
.select2-container--default .select2-selection--multiple .select2-selection__clear { | |||
cursor: pointer; | |||
float: right; | |||
font-weight: bold; | |||
margin-top: 5px; | |||
margin-right: 10px; | |||
padding: 1px; } | |||
.select2-container--default .select2-selection--multiple .select2-selection__choice { | |||
background-color: #e4e4e4; | |||
border: 1px solid #aaa; | |||
border-radius: 4px; | |||
cursor: default; | |||
float: left; | |||
margin-right: 5px; | |||
margin-top: 5px; | |||
padding: 0 5px; } | |||
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove { | |||
color: #999; | |||
cursor: pointer; | |||
display: inline-block; | |||
font-weight: bold; | |||
margin-right: 2px; } | |||
.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { | |||
color: #333; } | |||
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { | |||
float: right; } | |||
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { | |||
margin-left: 5px; | |||
margin-right: auto; } | |||
.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { | |||
margin-left: 2px; | |||
margin-right: auto; } | |||
.select2-container--default.select2-container--focus .select2-selection--multiple { | |||
border: solid black 1px; | |||
outline: 0; } | |||
.select2-container--default.select2-container--disabled .select2-selection--multiple { | |||
background-color: #eee; | |||
cursor: default; } | |||
.select2-container--default.select2-container--disabled .select2-selection__choice__remove { | |||
display: none; } | |||
.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { | |||
border-top-left-radius: 0; | |||
border-top-right-radius: 0; } | |||
.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { | |||
border-bottom-left-radius: 0; | |||
border-bottom-right-radius: 0; } | |||
.select2-container--default .select2-search--dropdown .select2-search__field { | |||
border: 1px solid #aaa; } | |||
.select2-container--default .select2-search--inline .select2-search__field { | |||
background: transparent; | |||
border: none; | |||
outline: 0; | |||
box-shadow: none; | |||
-webkit-appearance: textfield; } | |||
.select2-container--default .select2-results > .select2-results__options { | |||
max-height: 200px; | |||
overflow-y: auto; } | |||
.select2-container--default .select2-results__option[role=group] { | |||
padding: 0; } | |||
.select2-container--default .select2-results__option[aria-disabled=true] { | |||
color: #999; } | |||
.select2-container--default .select2-results__option[aria-selected=true] { | |||
background-color: #ddd; } | |||
.select2-container--default .select2-results__option .select2-results__option { | |||
padding-left: 1em; } | |||
.select2-container--default .select2-results__option .select2-results__option .select2-results__group { | |||
padding-left: 0; } | |||
.select2-container--default .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -1em; | |||
padding-left: 2em; } | |||
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -2em; | |||
padding-left: 3em; } | |||
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -3em; | |||
padding-left: 4em; } | |||
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -4em; | |||
padding-left: 5em; } | |||
.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { | |||
margin-left: -5em; | |||
padding-left: 6em; } | |||
.select2-container--default .select2-results__option--highlighted[aria-selected] { | |||
background-color: #5897fb; | |||
color: white; } | |||
.select2-container--default .select2-results__group { | |||
cursor: default; | |||
display: block; | |||
padding: 6px; } | |||
.select2-container--classic .select2-selection--single { | |||
background-color: #f7f7f7; | |||
border: 1px solid #aaa; | |||
border-radius: 4px; | |||
outline: 0; | |||
background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); | |||
background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); | |||
background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); | |||
background-repeat: repeat-x; | |||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } | |||
.select2-container--classic .select2-selection--single:focus { | |||
border: 1px solid #5897fb; } | |||
.select2-container--classic .select2-selection--single .select2-selection__rendered { | |||
color: #444; | |||
line-height: 28px; } | |||
.select2-container--classic .select2-selection--single .select2-selection__clear { | |||
cursor: pointer; | |||
float: right; | |||
font-weight: bold; | |||
margin-right: 10px; } | |||
.select2-container--classic .select2-selection--single .select2-selection__placeholder { | |||
color: #999; } | |||
.select2-container--classic .select2-selection--single .select2-selection__arrow { | |||
background-color: #ddd; | |||
border: none; | |||
border-left: 1px solid #aaa; | |||
border-top-right-radius: 4px; | |||
border-bottom-right-radius: 4px; | |||
height: 26px; | |||
position: absolute; | |||
top: 1px; | |||
right: 1px; | |||
width: 20px; | |||
background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); | |||
background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); | |||
background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); | |||
background-repeat: repeat-x; | |||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } | |||
.select2-container--classic .select2-selection--single .select2-selection__arrow b { | |||
border-color: #888 transparent transparent transparent; | |||
border-style: solid; | |||
border-width: 5px 4px 0 4px; | |||
height: 0; | |||
left: 50%; | |||
margin-left: -4px; | |||
margin-top: -2px; | |||
position: absolute; | |||
top: 50%; | |||
width: 0; } | |||
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { | |||
float: left; } | |||
.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { | |||
border: none; | |||
border-right: 1px solid #aaa; | |||
border-radius: 0; | |||
border-top-left-radius: 4px; | |||
border-bottom-left-radius: 4px; | |||
left: 1px; | |||
right: auto; } | |||
.select2-container--classic.select2-container--open .select2-selection--single { | |||
border: 1px solid #5897fb; } | |||
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { | |||
background: transparent; | |||
border: none; } | |||
.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { | |||
border-color: transparent transparent #888 transparent; | |||
border-width: 0 4px 5px 4px; } | |||
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { | |||
border-top: none; | |||
border-top-left-radius: 0; | |||
border-top-right-radius: 0; | |||
background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); | |||
background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); | |||
background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); | |||
background-repeat: repeat-x; | |||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } | |||
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { | |||
border-bottom: none; | |||
border-bottom-left-radius: 0; | |||
border-bottom-right-radius: 0; | |||
background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); | |||
background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); | |||
background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); | |||
background-repeat: repeat-x; | |||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } | |||
.select2-container--classic .select2-selection--multiple { | |||
background-color: white; | |||
border: 1px solid #aaa; | |||
border-radius: 4px; | |||
cursor: text; | |||
outline: 0; } | |||
.select2-container--classic .select2-selection--multiple:focus { | |||
border: 1px solid #5897fb; } | |||
.select2-container--classic .select2-selection--multiple .select2-selection__rendered { | |||
list-style: none; | |||
margin: 0; | |||
padding: 0 5px; } | |||
.select2-container--classic .select2-selection--multiple .select2-selection__clear { | |||
display: none; } | |||
.select2-container--classic .select2-selection--multiple .select2-selection__choice { | |||
background-color: #e4e4e4; | |||
border: 1px solid #aaa; | |||
border-radius: 4px; | |||
cursor: default; | |||
float: left; | |||
margin-right: 5px; | |||
margin-top: 5px; | |||
padding: 0 5px; } | |||
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { | |||
color: #888; | |||
cursor: pointer; | |||
display: inline-block; | |||
font-weight: bold; | |||
margin-right: 2px; } | |||
.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { | |||
color: #555; } | |||
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { | |||
float: right; | |||
margin-left: 5px; | |||
margin-right: auto; } | |||
.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { | |||
margin-left: 2px; | |||
margin-right: auto; } | |||
.select2-container--classic.select2-container--open .select2-selection--multiple { | |||
border: 1px solid #5897fb; } | |||
.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { | |||
border-top: none; | |||
border-top-left-radius: 0; | |||
border-top-right-radius: 0; } | |||
.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { | |||
border-bottom: none; | |||
border-bottom-left-radius: 0; | |||
border-bottom-right-radius: 0; } | |||
.select2-container--classic .select2-search--dropdown .select2-search__field { | |||
border: 1px solid #aaa; | |||
outline: 0; } | |||
.select2-container--classic .select2-search--inline .select2-search__field { | |||
outline: 0; | |||
box-shadow: none; } | |||
.select2-container--classic .select2-dropdown { | |||
background-color: white; | |||
border: 1px solid transparent; } | |||
.select2-container--classic .select2-dropdown--above { | |||
border-bottom: none; } | |||
.select2-container--classic .select2-dropdown--below { | |||
border-top: none; } | |||
.select2-container--classic .select2-results > .select2-results__options { | |||
max-height: 200px; | |||
overflow-y: auto; } | |||
.select2-container--classic .select2-results__option[role=group] { | |||
padding: 0; } | |||
.select2-container--classic .select2-results__option[aria-disabled=true] { | |||
color: grey; } | |||
.select2-container--classic .select2-results__option--highlighted[aria-selected] { | |||
background-color: #3875d7; | |||
color: white; } | |||
.select2-container--classic .select2-results__group { | |||
cursor: default; | |||
display: block; | |||
padding: 6px; } | |||
.select2-container--classic.select2-container--open .select2-dropdown { | |||
border-color: #5897fb; } |
@ -0,0 +1,574 @@ | |||
/* SELECTOR (FILTER INTERFACE) */ | |||
.selector { | |||
width: 800px; | |||
float: left; | |||
} | |||
.selector select { | |||
width: 380px; | |||
height: 17.2em; | |||
} | |||
.selector-available, .selector-chosen { | |||
float: left; | |||
width: 380px; | |||
text-align: center; | |||
margin-bottom: 5px; | |||
} | |||
.selector-chosen select { | |||
border-top: none; | |||
} | |||
.selector-available h2, .selector-chosen h2 { | |||
border: 1px solid #ccc; | |||
border-radius: 4px 4px 0 0; | |||
} | |||
.selector-chosen h2 { | |||
background: #79aec8; | |||
color: #fff; | |||
} | |||
.selector .selector-available h2 { | |||
background: #f8f8f8; | |||
color: #666; | |||
} | |||
.selector .selector-filter { | |||
background: white; | |||
border: 1px solid #ccc; | |||
border-width: 0 1px; | |||
padding: 8px; | |||
color: #999; | |||
font-size: 10px; | |||
margin: 0; | |||
text-align: left; | |||
} | |||
.selector .selector-filter label, | |||
.inline-group .aligned .selector .selector-filter label { | |||
float: left; | |||
margin: 7px 0 0; | |||
width: 18px; | |||
height: 18px; | |||
padding: 0; | |||
overflow: hidden; | |||
line-height: 1; | |||
} | |||
.selector .selector-available input { | |||
width: 320px; | |||
margin-left: 8px; | |||
} | |||
.selector ul.selector-chooser { | |||
float: left; | |||
width: 22px; | |||
background-color: #eee; | |||
border-radius: 10px; | |||
margin: 10em 5px 0 5px; | |||
padding: 0; | |||
} | |||
.selector-chooser li { | |||
margin: 0; | |||
padding: 3px; | |||
list-style-type: none; | |||
} | |||
.selector select { | |||
padding: 0 10px; | |||
margin: 0 0 10px; | |||
border-radius: 0 0 4px 4px; | |||
} | |||
.selector-add, .selector-remove { | |||
width: 16px; | |||
height: 16px; | |||
display: block; | |||
text-indent: -3000px; | |||
overflow: hidden; | |||
cursor: default; | |||
opacity: 0.3; | |||
} | |||
.active.selector-add, .active.selector-remove { | |||
opacity: 1; | |||
} | |||
.active.selector-add:hover, .active.selector-remove:hover { | |||
cursor: pointer; | |||
} | |||
.selector-add { | |||
background: url(../img/selector-icons.svg) 0 -96px no-repeat; | |||
} | |||
.active.selector-add:focus, .active.selector-add:hover { | |||
background-position: 0 -112px; | |||
} | |||
.selector-remove { | |||
background: url(../img/selector-icons.svg) 0 -64px no-repeat; | |||
} | |||
.active.selector-remove:focus, .active.selector-remove:hover { | |||
background-position: 0 -80px; | |||
} | |||
a.selector-chooseall, a.selector-clearall { | |||
display: inline-block; | |||
height: 16px; | |||
text-align: left; | |||
margin: 1px auto 3px; | |||
overflow: hidden; | |||
font-weight: bold; | |||
line-height: 16px; | |||
color: #666; | |||
text-decoration: none; | |||
opacity: 0.3; | |||
} | |||
a.active.selector-chooseall:focus, a.active.selector-clearall:focus, | |||
a.active.selector-chooseall:hover, a.active.selector-clearall:hover { | |||
color: #447e9b; | |||
} | |||
a.active.selector-chooseall, a.active.selector-clearall { | |||
opacity: 1; | |||
} | |||
a.active.selector-chooseall:hover, a.active.selector-clearall:hover { | |||
cursor: pointer; | |||
} | |||
a.selector-chooseall { | |||
padding: 0 18px 0 0; | |||
background: url(../img/selector-icons.svg) right -160px no-repeat; | |||
cursor: default; | |||
} | |||
a.active.selector-chooseall:focus, a.active.selector-chooseall:hover { | |||
background-position: 100% -176px; | |||
} | |||
a.selector-clearall { | |||
padding: 0 0 0 18px; | |||
background: url(../img/selector-icons.svg) 0 -128px no-repeat; | |||
cursor: default; | |||
} | |||
a.active.selector-clearall:focus, a.active.selector-clearall:hover { | |||
background-position: 0 -144px; | |||
} | |||
/* STACKED SELECTORS */ | |||
.stacked { | |||
float: left; | |||
width: 490px; | |||
} | |||
.stacked select { | |||
width: 480px; | |||
height: 10.1em; | |||
} | |||
.stacked .selector-available, .stacked .selector-chosen { | |||
width: 480px; | |||
} | |||
.stacked .selector-available { | |||
margin-bottom: 0; | |||
} | |||
.stacked .selector-available input { | |||
width: 422px; | |||
} | |||
.stacked ul.selector-chooser { | |||
height: 22px; | |||
width: 50px; | |||
margin: 0 0 10px 40%; | |||
background-color: #eee; | |||
border-radius: 10px; | |||
} | |||
.stacked .selector-chooser li { | |||
float: left; | |||
padding: 3px 3px 3px 5px; | |||
} | |||
.stacked .selector-chooseall, .stacked .selector-clearall { | |||
display: none; | |||
} | |||
.stacked .selector-add { | |||
background: url(../img/selector-icons.svg) 0 -32px no-repeat; | |||
cursor: default; | |||
} | |||
.stacked .active.selector-add { | |||
background-position: 0 -32px; | |||
cursor: pointer; | |||
} | |||
.stacked .active.selector-add:focus, .stacked .active.selector-add:hover { | |||
background-position: 0 -48px; | |||
cursor: pointer; | |||
} | |||
.stacked .selector-remove { | |||
background: url(../img/selector-icons.svg) 0 0 no-repeat; | |||
cursor: default; | |||
} | |||
.stacked .active.selector-remove { | |||
background-position: 0 0px; | |||
cursor: pointer; | |||
} | |||
.stacked .active.selector-remove:focus, .stacked .active.selector-remove:hover { | |||
background-position: 0 -16px; | |||
cursor: pointer; | |||
} | |||
.selector .help-icon { | |||
background: url(../img/icon-unknown.svg) 0 0 no-repeat; | |||
display: inline-block; | |||
vertical-align: middle; | |||
margin: -2px 0 0 2px; | |||
width: 13px; | |||
height: 13px; | |||
} | |||
.selector .selector-chosen .help-icon { | |||
background: url(../img/icon-unknown-alt.svg) 0 0 no-repeat; | |||
} | |||
.selector .search-label-icon { | |||
background: url(../img/search.svg) 0 0 no-repeat; | |||
display: inline-block; | |||
height: 18px; | |||
width: 18px; | |||
} | |||
/* DATE AND TIME */ | |||
p.datetime { | |||
line-height: 20px; | |||
margin: 0; | |||
padding: 0; | |||
color: #666; | |||
font-weight: bold; | |||
} | |||
.datetime span { | |||
white-space: nowrap; | |||
font-weight: normal; | |||
font-size: 11px; | |||
color: #ccc; | |||
} | |||
.datetime input, .form-row .datetime input.vDateField, .form-row .datetime input.vTimeField { | |||
margin-left: 5px; | |||
margin-bottom: 4px; | |||
} | |||
table p.datetime { | |||
font-size: 11px; | |||
margin-left: 0; | |||
padding-left: 0; | |||
} | |||
.datetimeshortcuts .clock-icon, .datetimeshortcuts .date-icon { | |||
position: relative; | |||
display: inline-block; | |||
vertical-align: middle; | |||
height: 16px; | |||
width: 16px; | |||
overflow: hidden; | |||
} | |||
.datetimeshortcuts .clock-icon { | |||
background: url(../img/icon-clock.svg) 0 0 no-repeat; | |||
} | |||
.datetimeshortcuts a:focus .clock-icon, | |||
.datetimeshortcuts a:hover .clock-icon { | |||
background-position: 0 -16px; | |||
} | |||
.datetimeshortcuts .date-icon { | |||
background: url(../img/icon-calendar.svg) 0 0 no-repeat; | |||
top: -1px; | |||
} | |||
.datetimeshortcuts a:focus .date-icon, | |||
.datetimeshortcuts a:hover .date-icon { | |||
background-position: 0 -16px; | |||
} | |||
.timezonewarning { | |||
font-size: 11px; | |||
color: #999; | |||
} | |||
/* URL */ | |||
p.url { | |||
line-height: 20px; | |||
margin: 0; | |||
padding: 0; | |||
color: #666; | |||
font-size: 11px; | |||
font-weight: bold; | |||
} | |||
.url a { | |||
font-weight: normal; | |||
} | |||
/* FILE UPLOADS */ | |||
p.file-upload { | |||
line-height: 20px; | |||
margin: 0; | |||
padding: 0; | |||
color: #666; | |||
font-size: 11px; | |||
font-weight: bold; | |||
} | |||
.aligned p.file-upload { | |||
margin-left: 170px; | |||
} | |||
.file-upload a { | |||
font-weight: normal; | |||
} | |||
.file-upload .deletelink { | |||
margin-left: 5px; | |||
} | |||
span.clearable-file-input label { | |||
color: #333; | |||
font-size: 11px; | |||
display: inline; | |||
float: none; | |||
} | |||
/* CALENDARS & CLOCKS */ | |||
.calendarbox, .clockbox { | |||
margin: 5px auto; | |||
font-size: 12px; | |||
width: 19em; | |||
text-align: center; | |||
background: white; | |||
border: 1px solid #ddd; | |||
border-radius: 4px; | |||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); | |||
overflow: hidden; | |||
position: relative; | |||
} | |||
.clockbox { | |||
width: auto; | |||
} | |||
.calendar { | |||
margin: 0; | |||
padding: 0; | |||
} | |||
.calendar table { | |||
margin: 0; | |||
padding: 0; | |||
border-collapse: collapse; | |||
background: white; | |||
width: 100%; | |||
} | |||
.calendar caption, .calendarbox h2 { | |||
margin: 0; | |||
text-align: center; | |||
border-top: none; | |||
background: #f5dd5d; | |||
font-weight: 700; | |||
font-size: 12px; | |||
color: #333; | |||
} | |||
.calendar th { | |||
padding: 8px 5px; | |||
background: #f8f8f8; | |||
border-bottom: 1px solid #ddd; | |||
font-weight: 400; | |||
font-size: 12px; | |||
text-align: center; | |||
color: #666; | |||
} | |||
.calendar td { | |||
font-weight: 400; | |||
font-size: 12px; | |||
text-align: center; | |||
padding: 0; | |||
border-top: 1px solid #eee; | |||
border-bottom: none; | |||
} | |||
.calendar td.selected a { | |||
background: #79aec8; | |||
color: #fff; | |||
} | |||
.calendar td.nonday { | |||
background: #f8f8f8; | |||
} | |||
.calendar td.today a { | |||
font-weight: 700; | |||
} | |||
.calendar td a, .timelist a { | |||
display: block; | |||
font-weight: 400; | |||
padding: 6px; | |||
text-decoration: none; | |||
color: #444; | |||
} | |||
.calendar td a:focus, .timelist a:focus, | |||
.calendar td a:hover, .timelist a:hover { | |||
background: #79aec8; | |||
color: white; | |||
} | |||
.calendar td a:active, .timelist a:active { | |||
background: #417690; | |||
color: white; | |||
} | |||
.calendarnav { | |||
font-size: 10px; | |||
text-align: center; | |||
color: #ccc; | |||
margin: 0; | |||
padding: 1px 3px; | |||
} | |||
.calendarnav a:link, #calendarnav a:visited, | |||
#calendarnav a:focus, #calendarnav a:hover { | |||
color: #999; | |||
} | |||
.calendar-shortcuts { | |||
background: white; | |||
font-size: 11px; | |||
line-height: 11px; | |||
border-top: 1px solid #eee; | |||
padding: 8px 0; | |||
color: #ccc; | |||
} | |||
.calendarbox .calendarnav-previous, .calendarbox .calendarnav-next { | |||
display: block; | |||
position: absolute; | |||
top: 8px; | |||
width: 15px; | |||
height: 15px; | |||
text-indent: -9999px; | |||
padding: 0; | |||
} | |||
.calendarnav-previous { | |||
left: 10px; | |||
background: url(../img/calendar-icons.svg) 0 0 no-repeat; | |||
} | |||
.calendarbox .calendarnav-previous:focus, | |||
.calendarbox .calendarnav-previous:hover { | |||
background-position: 0 -15px; | |||
} | |||
.calendarnav-next { | |||
right: 10px; | |||
background: url(../img/calendar-icons.svg) 0 -30px no-repeat; | |||
} | |||
.calendarbox .calendarnav-next:focus, | |||
.calendarbox .calendarnav-next:hover { | |||
background-position: 0 -45px; | |||
} | |||
.calendar-cancel { | |||
margin: 0; | |||
padding: 4px 0; | |||
font-size: 12px; | |||
background: #eee; | |||
border-top: 1px solid #ddd; | |||
color: #333; | |||
} | |||
.calendar-cancel:focus, .calendar-cancel:hover { | |||
background: #ddd; | |||
} | |||
.calendar-cancel a { | |||
color: black; | |||
display: block; | |||
} | |||
ul.timelist, .timelist li { | |||
list-style-type: none; | |||
margin: 0; | |||
padding: 0; | |||
} | |||
.timelist a { | |||
padding: 2px; | |||
} | |||
/* EDIT INLINE */ | |||
.inline-deletelink { | |||
float: right; | |||
text-indent: -9999px; | |||
background: url(../img/inline-delete.svg) 0 0 no-repeat; | |||
width: 16px; | |||
height: 16px; | |||
border: 0px none; | |||
} | |||
.inline-deletelink:focus, .inline-deletelink:hover { | |||
cursor: pointer; | |||
} | |||
/* RELATED WIDGET WRAPPER */ | |||
.related-widget-wrapper { | |||
float: left; /* display properly in form rows with multiple fields */ | |||
overflow: hidden; /* clear floated contents */ | |||
} | |||
.related-widget-wrapper-link { | |||
opacity: 0.3; | |||
} | |||
.related-widget-wrapper-link:link { | |||
opacity: .8; | |||
} | |||
.related-widget-wrapper-link:link:focus, | |||
.related-widget-wrapper-link:link:hover { | |||
opacity: 1; | |||
} | |||
select + .related-widget-wrapper-link, | |||
.related-widget-wrapper-link + .related-widget-wrapper-link { | |||
margin-left: 7px; | |||
} |
@ -0,0 +1,202 @@ | |||
Apache License | |||
Version 2.0, January 2004 | |||
http://www.apache.org/licenses/ | |||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |||
1. Definitions. | |||
"License" shall mean the terms and conditions for use, reproduction, | |||
and distribution as defined by Sections 1 through 9 of this document. | |||
"Licensor" shall mean the copyright owner or entity authorized by | |||
the copyright owner that is granting the License. | |||
"Legal Entity" shall mean the union of the acting entity and all | |||
other entities that control, are controlled by, or are under common | |||
control with that entity. For the purposes of this definition, | |||
"control" means (i) the power, direct or indirect, to cause the | |||
direction or management of such entity, whether by contract or | |||
otherwise, or (ii) ownership of fifty percent (50%) or more of the | |||
outstanding shares, or (iii) beneficial ownership of such entity. | |||
"You" (or "Your") shall mean an individual or Legal Entity | |||
exercising permissions granted by this License. | |||
"Source" form shall mean the preferred form for making modifications, | |||
including but not limited to software source code, documentation | |||
source, and configuration files. | |||
"Object" form shall mean any form resulting from mechanical | |||
transformation or translation of a Source form, including but | |||
not limited to compiled object code, generated documentation, | |||
and conversions to other media types. | |||
"Work" shall mean the work of authorship, whether in Source or | |||
Object form, made available under the License, as indicated by a | |||
copyright notice that is included in or attached to the work | |||
(an example is provided in the Appendix below). | |||
"Derivative Works" shall mean any work, whether in Source or Object | |||
form, that is based on (or derived from) the Work and for which the | |||
editorial revisions, annotations, elaborations, or other modifications | |||
represent, as a whole, an original work of authorship. For the purposes | |||
of this License, Derivative Works shall not include works that remain | |||
separable from, or merely link (or bind by name) to the interfaces of, | |||
the Work and Derivative Works thereof. | |||
"Contribution" shall mean any work of authorship, including | |||
the original version of the Work and any modifications or additions | |||
to that Work or Derivative Works thereof, that is intentionally | |||
submitted to Licensor for inclusion in the Work by the copyright owner | |||
or by an individual or Legal Entity authorized to submit on behalf of | |||
the copyright owner. For the purposes of this definition, "submitted" | |||
means any form of electronic, verbal, or written communication sent | |||
to the Licensor or its representatives, including but not limited to | |||
communication on electronic mailing lists, source code control systems, | |||
and issue tracking systems that are managed by, or on behalf of, the | |||
Licensor for the purpose of discussing and improving the Work, but | |||
excluding communication that is conspicuously marked or otherwise | |||
designated in writing by the copyright owner as "Not a Contribution." | |||
"Contributor" shall mean Licensor and any individual or Legal Entity | |||
on behalf of whom a Contribution has been received by Licensor and | |||
subsequently incorporated within the Work. | |||
2. Grant of Copyright License. Subject to the terms and conditions of | |||
this License, each Contributor hereby grants to You a perpetual, | |||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
copyright license to reproduce, prepare Derivative Works of, | |||
publicly display, publicly perform, sublicense, and distribute the | |||
Work and such Derivative Works in Source or Object form. | |||
3. Grant of Patent License. Subject to the terms and conditions of | |||
this License, each Contributor hereby grants to You a perpetual, | |||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |||
(except as stated in this section) patent license to make, have made, | |||
use, offer to sell, sell, import, and otherwise transfer the Work, | |||
where such license applies only to those patent claims licensable | |||
by such Contributor that are necessarily infringed by their | |||
Contribution(s) alone or by combination of their Contribution(s) | |||
with the Work to which such Contribution(s) was submitted. If You | |||
institute patent litigation against any entity (including a | |||
cross-claim or counterclaim in a lawsuit) alleging that the Work | |||
or a Contribution incorporated within the Work constitutes direct | |||
or contributory patent infringement, then any patent licenses | |||
granted to You under this License for that Work shall terminate | |||
as of the date such litigation is filed. | |||
4. Redistribution. You may reproduce and distribute copies of the | |||
Work or Derivative Works thereof in any medium, with or without | |||
modifications, and in Source or Object form, provided that You | |||
meet the following conditions: | |||
(a) You must give any other recipients of the Work or | |||
Derivative Works a copy of this License; and | |||
(b) You must cause any modified files to carry prominent notices | |||
stating that You changed the files; and | |||
(c) You must retain, in the Source form of any Derivative Works | |||
that You distribute, all copyright, patent, trademark, and | |||
attribution notices from the Source form of the Work, | |||
excluding those notices that do not pertain to any part of | |||
the Derivative Works; and | |||
(d) If the Work includes a "NOTICE" text file as part of its | |||
distribution, then any Derivative Works that You distribute must | |||
include a readable copy of the attribution notices contained | |||
within such NOTICE file, excluding those notices that do not | |||
pertain to any part of the Derivative Works, in at least one | |||
of the following places: within a NOTICE text file distributed | |||
as part of the Derivative Works; within the Source form or | |||
documentation, if provided along with the Derivative Works; or, | |||
within a display generated by the Derivative Works, if and | |||
wherever such third-party notices normally appear. The contents | |||
of the NOTICE file are for informational purposes only and | |||
do not modify the License. You may add Your own attribution | |||
notices within Derivative Works that You distribute, alongside | |||
or as an addendum to the NOTICE text from the Work, provided | |||
that such additional attribution notices cannot be construed | |||
as modifying the License. | |||
You may add Your own copyright statement to Your modifications and | |||
may provide additional or different license terms and conditions | |||
for use, reproduction, or distribution of Your modifications, or | |||
for any such Derivative Works as a whole, provided Your use, | |||
reproduction, and distribution of the Work otherwise complies with | |||
the conditions stated in this License. | |||
5. Submission of Contributions. Unless You explicitly state otherwise, | |||
any Contribution intentionally submitted for inclusion in the Work | |||
by You to the Licensor shall be under the terms and conditions of | |||
this License, without any additional terms or conditions. | |||
Notwithstanding the above, nothing herein shall supersede or modify | |||
the terms of any separate license agreement you may have executed | |||
with Licensor regarding such Contributions. | |||
6. Trademarks. This License does not grant permission to use the trade | |||
names, trademarks, service marks, or product names of the Licensor, | |||
except as required for reasonable and customary use in describing the | |||
origin of the Work and reproducing the content of the NOTICE file. | |||
7. Disclaimer of Warranty. Unless required by applicable law or | |||
agreed to in writing, Licensor provides the Work (and each | |||
Contributor provides its Contributions) on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |||
implied, including, without limitation, any warranties or conditions | |||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |||
PARTICULAR PURPOSE. You are solely responsible for determining the | |||
appropriateness of using or redistributing the Work and assume any | |||
risks associated with Your exercise of permissions under this License. | |||
8. Limitation of Liability. In no event and under no legal theory, | |||
whether in tort (including negligence), contract, or otherwise, | |||
unless required by applicable law (such as deliberate and grossly | |||
negligent acts) or agreed to in writing, shall any Contributor be | |||
liable to You for damages, including any direct, indirect, special, | |||
incidental, or consequential damages of any character arising as a | |||
result of this License or out of the use or inability to use the | |||
Work (including but not limited to damages for loss of goodwill, | |||
work stoppage, computer failure or malfunction, or any and all | |||
other commercial damages or losses), even if such Contributor | |||
has been advised of the possibility of such damages. | |||
9. Accepting Warranty or Additional Liability. While redistributing | |||
the Work or Derivative Works thereof, You may choose to offer, | |||
and charge a fee for, acceptance of support, warranty, indemnity, | |||
or other liability obligations and/or rights consistent with this | |||
License. However, in accepting such obligations, You may act only | |||
on Your own behalf and on Your sole responsibility, not on behalf | |||
of any other Contributor, and only if You agree to indemnify, | |||
defend, and hold each Contributor harmless for any liability | |||
incurred by, or claims asserted against, such Contributor by reason | |||
of your accepting any such warranty or additional liability. | |||
END OF TERMS AND CONDITIONS | |||
APPENDIX: How to apply the Apache License to your work. | |||
To apply the Apache License to your work, attach the following | |||
boilerplate notice, with the fields enclosed by brackets "[]" | |||
replaced with your own identifying information. (Don't include | |||
the brackets!) The text should be enclosed in the appropriate | |||
comment syntax for the file format. We also recommend that a | |||
file or class name and description of purpose be included on the | |||
same "printed page" as the copyright notice for easier | |||
identification within third-party archives. | |||
Copyright [yyyy] [name of copyright owner] | |||
Licensed under the Apache License, Version 2.0 (the "License"); | |||
you may not use this file except in compliance with the License. | |||
You may obtain a copy of the License at | |||
http://www.apache.org/licenses/LICENSE-2.0 | |||
Unless required by applicable law or agreed to in writing, software | |||
distributed under the License is distributed on an "AS IS" BASIS, | |||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||
See the License for the specific language governing permissions and | |||
limitations under the License. |
@ -0,0 +1,3 @@ | |||
Roboto webfont source: https://www.google.com/fonts/specimen/Roboto | |||
WOFF files extracted using https://github.com/majodev/google-webfonts-helper | |||
Weights used in this project: Light (300), Regular (400), Bold (700) |
@ -0,0 +1,20 @@ | |||
The MIT License (MIT) | |||
Copyright (c) 2014 Code Charm Ltd | |||
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. |
@ -0,0 +1,7 @@ | |||
All icons are taken from Font Awesome (http://fontawesome.io/) project. | |||
The Font Awesome font is licensed under the SIL OFL 1.1: | |||
- https://scripts.sil.org/OFL | |||
SVG icons source: https://github.com/encharm/Font-Awesome-SVG-PNG | |||
Font-Awesome-SVG-PNG is licensed under the MIT license (see file license | |||
in current folder). |
@ -0,0 +1,14 @@ | |||
<svg width="15" height="60" viewBox="0 0 1792 7168" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
<defs> | |||
<g id="previous"> | |||
<path d="M1037 1395l102-102q19-19 19-45t-19-45l-307-307 307-307q19-19 19-45t-19-45l-102-102q-19-19-45-19t-45 19l-454 454q-19 19-19 45t19 45l454 454q19 19 45 19t45-19zm627-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
<g id="next"> | |||
<path d="M845 1395l454-454q19-19 19-45t-19-45l-454-454q-19-19-45-19t-45 19l-102 102q-19 19-19 45t19 45l307 307-307 307q-19 19-19 45t19 45l102 102q19 19 45 19t45-19zm819-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
</defs> | |||
<use xlink:href="#previous" x="0" y="0" fill="#333333" /> | |||
<use xlink:href="#previous" x="0" y="1792" fill="#000000" /> | |||
<use xlink:href="#next" x="0" y="3584" fill="#333333" /> | |||
<use xlink:href="#next" x="0" y="5376" fill="#000000" /> | |||
</svg> |
@ -0,0 +1 @@ | |||
<svg width="24" height="22" viewBox="0 0 847 779" xmlns="http://www.w3.org/2000/svg"><g><path fill="#EBECE6" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120z"/><path fill="#9E9E93" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120zm607 25h-607c-26 0-50 11-67 28-17 18-28 41-28 67v536c0 27 11 50 28 68 17 17 41 27 67 27h607c26 0 49-10 67-27 17-18 28-41 28-68v-536c0-26-11-49-28-67-18-17-41-28-67-28z"/><path stroke="#A9A8A4" stroke-width="20" d="M706 295l-68 281"/><path stroke="#E47474" stroke-width="20" d="M316 648l390-353M141 435l175 213"/><path stroke="#C9C9C9" stroke-width="20" d="M319 151l-178 284M706 295l-387-144"/><g fill="#040405"><path d="M319 111c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40zM141 395c22 0 40 18 40 40s-18 40-40 40c-23 0-41-18-41-40s18-40 41-40zM316 608c22 0 40 18 40 40 0 23-18 41-40 41s-40-18-40-41c0-22 18-40 40-40zM706 254c22 0 40 18 40 41 0 22-18 40-40 40s-40-18-40-40c0-23 18-41 40-41zM638 536c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40z"/></g></g></svg> |
@ -0,0 +1 @@ | |||
<svg width="24" height="22" viewBox="0 0 847 779" xmlns="http://www.w3.org/2000/svg"><g><path fill="#F1C02A" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120z"/><path fill="#9E9E93" d="M120 1h607c66 0 120 54 120 120v536c0 66-54 120-120 120h-607c-66 0-120-54-120-120v-536c0-66 54-120 120-120zm607 25h-607c-26 0-50 11-67 28-17 18-28 41-28 67v536c0 27 11 50 28 68 17 17 41 27 67 27h607c26 0 49-10 67-27 17-18 28-41 28-68v-536c0-26-11-49-28-67-18-17-41-28-67-28z"/><path stroke="#A9A8A4" stroke-width="20" d="M706 295l-68 281"/><path stroke="#E47474" stroke-width="20" d="M316 648l390-353M141 435l175 213"/><path stroke="#C9A741" stroke-width="20" d="M319 151l-178 284M706 295l-387-144"/><g fill="#040405"><path d="M319 111c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40zM141 395c22 0 40 18 40 40s-18 40-40 40c-23 0-41-18-41-40s18-40 41-40zM316 608c22 0 40 18 40 40 0 23-18 41-40 41s-40-18-40-41c0-22 18-40 40-40zM706 254c22 0 40 18 40 41 0 22-18 40-40 40s-40-18-40-40c0-23 18-41 40-41zM638 536c22 0 40 18 40 40s-18 40-40 40-40-18-40-40 18-40 40-40z"/></g></g></svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#70bf2b" d="M1600 796v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="14" height="14" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#efb80b" d="M1024 1375v-190q0-14-9.5-23.5t-22.5-9.5h-192q-13 0-22.5 9.5t-9.5 23.5v190q0 14 9.5 23.5t22.5 9.5h192q13 0 22.5-9.5t9.5-23.5zm-2-374l18-459q0-12-10-19-13-11-24-11h-220q-11 0-24 11-10 7-10 21l17 457q0 10 10 16.5t24 6.5h185q14 0 23.5-6.5t10.5-16.5zm-14-934l768 1408q35 63-2 126-17 29-46.5 46t-63.5 17h-1536q-34 0-63.5-17t-46.5-46q-37-63-2-126l768-1408q17-31 47-49t65-18 65 18 47 49z"/> | |||
</svg> |
@ -0,0 +1,9 @@ | |||
<svg width="16" height="32" viewBox="0 0 1792 3584" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
<defs> | |||
<g id="icon"> | |||
<path d="M192 1664h288v-288h-288v288zm352 0h320v-288h-320v288zm-352-352h288v-320h-288v320zm352 0h320v-320h-320v320zm-352-384h288v-288h-288v288zm736 736h320v-288h-320v288zm-384-736h320v-288h-320v288zm768 736h288v-288h-288v288zm-384-352h320v-320h-320v320zm-352-864v-288q0-13-9.5-22.5t-22.5-9.5h-64q-13 0-22.5 9.5t-9.5 22.5v288q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5-9.5t9.5-22.5zm736 864h288v-320h-288v320zm-384-384h320v-288h-320v288zm384 0h288v-288h-288v288zm32-480v-288q0-13-9.5-22.5t-22.5-9.5h-64q-13 0-22.5 9.5t-9.5 22.5v288q0 13 9.5 22.5t22.5 9.5h64q13 0 22.5-9.5t9.5-22.5zm384-64v1280q0 52-38 90t-90 38h-1408q-52 0-90-38t-38-90v-1280q0-52 38-90t90-38h128v-96q0-66 47-113t113-47h64q66 0 113 47t47 113v96h384v-96q0-66 47-113t113-47h64q66 0 113 47t47 113v96h128q52 0 90 38t38 90z"/> | |||
</g> | |||
</defs> | |||
<use xlink:href="#icon" x="0" y="0" fill="#447e9b" /> | |||
<use xlink:href="#icon" x="0" y="1792" fill="#003366" /> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#efb80b" d="M491 1536l91-91-235-235-91 91v107h128v128h107zm523-928q0-22-22-22-10 0-17 7l-542 542q-7 7-7 17 0 22 22 22 10 0 17-7l542-542q7-7 7-17zm-54-192l416 416-832 832h-416v-416zm683 96q0 53-37 90l-166 166-416-416 166-165q36-38 90-38 53 0 91 38l235 234q37 39 37 91z"/> | |||
</svg> |
@ -0,0 +1,9 @@ | |||
<svg width="16" height="32" viewBox="0 0 1792 3584" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
<defs> | |||
<g id="icon"> | |||
<path d="M1024 544v448q0 14-9 23t-23 9h-320q-14 0-23-9t-9-23v-64q0-14 9-23t23-9h224v-352q0-14 9-23t23-9h64q14 0 23 9t9 23zm416 352q0-148-73-273t-198-198-273-73-273 73-198 198-73 273 73 273 198 198 273 73 273-73 198-198 73-273zm224 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
</defs> | |||
<use xlink:href="#icon" x="0" y="0" fill="#447e9b" /> | |||
<use xlink:href="#icon" x="0" y="1792" fill="#003366" /> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="14" height="14" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#dd4646" d="M1490 1322q0 40-28 68l-136 136q-28 28-68 28t-68-28l-294-294-294 294q-28 28-68 28t-68-28l-136-136q-28-28-28-68t28-68l294-294-294-294q-28-28-28-68t28-68l136-136q28-28 68-28t68 28l294 294 294-294q28-28 68-28t68 28l136 136q28 28 28 68t-28 68l-294 294 294 294q28 28 28 68z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#dd4646" d="M1277 1122q0-26-19-45l-181-181 181-181q19-19 19-45 0-27-19-46l-90-90q-19-19-46-19-26 0-45 19l-181 181-181-181q-19-19-45-19-27 0-46 19l-90 90q-19 19-19 46 0 26 19 45l181 181-181 181q-19 19-19 45 0 27 19 46l90 90q19 19 46 19 26 0 45-19l181-181 181 181q19 19 45 19 27 0 46-19l90-90q19-19 19-46zm387-226q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#ffffff" d="M1024 1376v-192q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23-9t9-23zm256-672q0-88-55.5-163t-138.5-116-170-41q-243 0-371 213-15 24 8 42l132 100q7 6 19 6 16 0 25-12 53-68 86-92 34-24 86-24 48 0 85.5 26t37.5 59q0 38-20 61t-68 45q-63 28-115.5 86.5t-52.5 125.5v36q0 14 9 23t23 9h192q14 0 23-9t9-23q0-19 21.5-49.5t54.5-49.5q32-18 49-28.5t46-35 44.5-48 28-60.5 12.5-81zm384 192q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#666666" d="M1024 1376v-192q0-14-9-23t-23-9h-192q-14 0-23 9t-9 23v192q0 14 9 23t23 9h192q14 0 23-9t9-23zm256-672q0-88-55.5-163t-138.5-116-170-41q-243 0-371 213-15 24 8 42l132 100q7 6 19 6 16 0 25-12 53-68 86-92 34-24 86-24 48 0 85.5 26t37.5 59q0 38-20 61t-68 45q-63 28-115.5 86.5t-52.5 125.5v36q0 14 9 23t23 9h192q14 0 23-9t9-23q0-19 21.5-49.5t54.5-49.5q32-18 49-28.5t46-35 44.5-48 28-60.5 12.5-81zm384 192q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#2b70bf" d="M1664 960q-152-236-381-353 61 104 61 225 0 185-131.5 316.5t-316.5 131.5-316.5-131.5-131.5-316.5q0-121 61-225-229 117-381 353 133 205 333.5 326.5t434.5 121.5 434.5-121.5 333.5-326.5zm-720-384q0-20-14-34t-34-14q-125 0-214.5 89.5t-89.5 214.5q0 20 14 34t34 14 34-14 14-34q0-86 61-147t147-61q20 0 34-14t14-34zm848 384q0 34-20 69-140 230-376.5 368.5t-499.5 138.5-499.5-139-376.5-368q-20-35-20-69t20-69q140-229 376.5-368t499.5-139 499.5 139 376.5 368q20 35 20 69z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#70bf2b" d="M1412 734q0-28-18-46l-91-90q-19-19-45-19t-45 19l-408 407-226-226q-19-19-45-19t-45 19l-91 90q-18 18-18 46 0 27 18 45l362 362q19 19 45 19 27 0 46-19l543-543q18-18 18-45zm252 162q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="16" height="16" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#999999" d="M1277 1122q0-26-19-45l-181-181 181-181q19-19 19-45 0-27-19-46l-90-90q-19-19-46-19-26 0-45 19l-181 181-181-181q-19-19-45-19-27 0-46 19l-90 90q-19 19-19 46 0 26 19 45l181 181-181 181q-19 19-19 45 0 27 19 46l90 90q19 19 46 19 26 0 45-19l181-181 181 181q19 19 45 19 27 0 46-19l90-90q19-19 19-46zm387-226q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="15" height="15" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#555555" d="M1216 832q0-185-131.5-316.5t-316.5-131.5-316.5 131.5-131.5 316.5 131.5 316.5 316.5 131.5 316.5-131.5 131.5-316.5zm512 832q0 52-38 90t-90 38q-54 0-90-38l-343-342q-179 124-399 124-143 0-273.5-55.5t-225-150-150-225-55.5-273.5 55.5-273.5 150-225 225-150 273.5-55.5 273.5 55.5 225 150 150 225 55.5 273.5q0 220-124 399l343 343q37 37 37 90z"/> | |||
</svg> |
@ -0,0 +1,34 @@ | |||
<svg width="16" height="192" viewBox="0 0 1792 21504" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
<defs> | |||
<g id="up"> | |||
<path d="M1412 895q0-27-18-45l-362-362-91-91q-18-18-45-18t-45 18l-91 91-362 362q-18 18-18 45t18 45l91 91q18 18 45 18t45-18l189-189v502q0 26 19 45t45 19h128q26 0 45-19t19-45v-502l189 189q19 19 45 19t45-19l91-91q18-18 18-45zm252 1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
<g id="down"> | |||
<path d="M1412 897q0-27-18-45l-91-91q-18-18-45-18t-45 18l-189 189v-502q0-26-19-45t-45-19h-128q-26 0-45 19t-19 45v502l-189-189q-19-19-45-19t-45 19l-91 91q-18 18-18 45t18 45l362 362 91 91q18 18 45 18t45-18l91-91 362-362q18-18 18-45zm252-1q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
<g id="left"> | |||
<path d="M1408 960v-128q0-26-19-45t-45-19h-502l189-189q19-19 19-45t-19-45l-91-91q-18-18-45-18t-45 18l-362 362-91 91q-18 18-18 45t18 45l91 91 362 362q18 18 45 18t45-18l91-91q18-18 18-45t-18-45l-189-189h502q26 0 45-19t19-45zm256-64q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
<g id="right"> | |||
<path d="M1413 896q0-27-18-45l-91-91-362-362q-18-18-45-18t-45 18l-91 91q-18 18-18 45t18 45l189 189h-502q-26 0-45 19t-19 45v128q0 26 19 45t45 19h502l-189 189q-19 19-19 45t19 45l91 91q18 18 45 18t45-18l362-362 91-91q18-18 18-45zm251 0q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
<g id="clearall"> | |||
<path transform="translate(336, 336) scale(0.75)" d="M1037 1395l102-102q19-19 19-45t-19-45l-307-307 307-307q19-19 19-45t-19-45l-102-102q-19-19-45-19t-45 19l-454 454q-19 19-19 45t19 45l454 454q19 19 45 19t45-19zm627-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
<g id="chooseall"> | |||
<path transform="translate(336, 336) scale(0.75)" d="M845 1395l454-454q19-19 19-45t-19-45l-454-454q-19-19-45-19t-45 19l-102 102q-19 19-19 45t19 45l307 307-307 307q-19 19-19 45t19 45l102 102q19 19 45 19t45-19zm819-499q0 209-103 385.5t-279.5 279.5-385.5 103-385.5-103-279.5-279.5-103-385.5 103-385.5 279.5-279.5 385.5-103 385.5 103 279.5 279.5 103 385.5z"/> | |||
</g> | |||
</defs> | |||
<use xlink:href="#up" x="0" y="0" fill="#666666" /> | |||
<use xlink:href="#up" x="0" y="1792" fill="#447e9b" /> | |||
<use xlink:href="#down" x="0" y="3584" fill="#666666" /> | |||
<use xlink:href="#down" x="0" y="5376" fill="#447e9b" /> | |||
<use xlink:href="#left" x="0" y="7168" fill="#666666" /> | |||
<use xlink:href="#left" x="0" y="8960" fill="#447e9b" /> | |||
<use xlink:href="#right" x="0" y="10752" fill="#666666" /> | |||
<use xlink:href="#right" x="0" y="12544" fill="#447e9b" /> | |||
<use xlink:href="#clearall" x="0" y="14336" fill="#666666" /> | |||
<use xlink:href="#clearall" x="0" y="16128" fill="#447e9b" /> | |||
<use xlink:href="#chooseall" x="0" y="17920" fill="#666666" /> | |||
<use xlink:href="#chooseall" x="0" y="19712" fill="#447e9b" /> | |||
</svg> |
@ -0,0 +1,19 @@ | |||
<svg width="14" height="84" viewBox="0 0 1792 10752" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||
<defs> | |||
<g id="sort"> | |||
<path d="M1408 1088q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45zm0-384q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/> | |||
</g> | |||
<g id="ascending"> | |||
<path d="M1408 1216q0 26-19 45t-45 19h-896q-26 0-45-19t-19-45 19-45l448-448q19-19 45-19t45 19l448 448q19 19 19 45z"/> | |||
</g> | |||
<g id="descending"> | |||
<path d="M1408 704q0 26-19 45l-448 448q-19 19-45 19t-45-19l-448-448q-19-19-19-45t19-45 45-19h896q26 0 45 19t19 45z"/> | |||
</g> | |||
</defs> | |||
<use xlink:href="#sort" x="0" y="0" fill="#999999" /> | |||
<use xlink:href="#sort" x="0" y="1792" fill="#447e9b" /> | |||
<use xlink:href="#ascending" x="0" y="3584" fill="#999999" /> | |||
<use xlink:href="#ascending" x="0" y="5376" fill="#447e9b" /> | |||
<use xlink:href="#descending" x="0" y="7168" fill="#999999" /> | |||
<use xlink:href="#descending" x="0" y="8960" fill="#447e9b" /> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#ffffff" d="M1600 736v192q0 40-28 68t-68 28h-416v416q0 40-28 68t-68 28h-192q-40 0-68-28t-28-68v-416h-416q-40 0-68-28t-28-68v-192q0-40 28-68t68-28h416v-416q0-40 28-68t68-28h192q40 0 68 28t28 68v416h416q40 0 68 28t28 68z"/> | |||
</svg> |
@ -0,0 +1,3 @@ | |||
<svg width="13" height="13" viewBox="0 0 1792 1792" xmlns="http://www.w3.org/2000/svg"> | |||
<path fill="#ffffff" d="M1363 877l-742 742q-19 19-45 19t-45-19l-166-166q-19-19-19-45t19-45l531-531-531-531q-19-19-19-45t19-45l166-166q19-19 45-19t45 19l742 742q19 19 19 45t-19 45z"/> | |||
</svg> |