Browse Source
Merge pull request #65 from flipped-aurora/gin-vue-admin_v2_dev
Merge pull request #65 from flipped-aurora/gin-vue-admin_v2_dev
Gin vue admin v2 devmain
rainyan
5 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 1084 additions and 84 deletions
-
119.dockerignore
-
41Dockerfile
-
2README-zh_CN.md
-
4docker/docker-start.sh
-
56docker/etc/nginx/nginx.conf.tpl
-
24server/Dockerfile
-
19server/api/v1/sys_authority.go
-
8server/config.yaml
-
80server/config/config.go
-
BINserver/db.db
-
152server/docs/docs.go
-
148server/docs/swagger.json
-
93server/docs/swagger.yaml
-
1server/initialize/router.go
-
7server/main.go
-
5server/model/response/sys_authority.go
-
4server/model/response/sys_casbin.go
-
1server/router/sys_authority.go
-
1server/service/exa_file_upload_download.go
-
29server/service/sys_authority.go
-
8server/service/sys_casbin.go
-
1server/service/sys_user.go
-
320web/src/view/dashboard/component/todoList/index.scss
-
9web/src/view/dashboard/component/todoList/index.vue
-
24web/src/view/dashboard/index.vue
-
2web/src/view/login/login.vue
-
10web/src/view/systemTools/system/system.vue
@ -0,0 +1,119 @@ |
|||||
|
# Created by .ignore support plugin (hsz.mobi) |
||||
|
### Node template |
||||
|
# Logs |
||||
|
logs |
||||
|
*.log |
||||
|
npm-debug.log* |
||||
|
yarn-debug.log* |
||||
|
yarn-error.log* |
||||
|
lerna-debug.log* |
||||
|
|
||||
|
# Diagnostic reports (https://nodejs.org/api/report.html) |
||||
|
report.[0-9]*.[0-9]*.[0-9]*.[0-9]*.json |
||||
|
|
||||
|
# Runtime data |
||||
|
pids |
||||
|
*.pid |
||||
|
*.seed |
||||
|
*.pid.lock |
||||
|
|
||||
|
# Directory for instrumented libs generated by jscoverage/JSCover |
||||
|
lib-cov |
||||
|
|
||||
|
# Coverage directory used by tools like istanbul |
||||
|
coverage |
||||
|
*.lcov |
||||
|
|
||||
|
# nyc test coverage |
||||
|
.nyc_output |
||||
|
|
||||
|
# Grunt intermediate storage (https://gruntjs.com/creating-plugins#storing-task-files) |
||||
|
.grunt |
||||
|
|
||||
|
# Bower dependency directory (https://bower.io/) |
||||
|
bower_components |
||||
|
|
||||
|
# node-waf configuration |
||||
|
.lock-wscript |
||||
|
|
||||
|
# Compiled binary addons (https://nodejs.org/api/addons.html) |
||||
|
build/Release |
||||
|
|
||||
|
# Dependency directories |
||||
|
node_modules/ |
||||
|
jspm_packages/ |
||||
|
|
||||
|
# Snowpack dependency directory (https://snowpack.dev/) |
||||
|
web_modules/ |
||||
|
|
||||
|
# TypeScript cache |
||||
|
*.tsbuildinfo |
||||
|
|
||||
|
# Optional npm cache directory |
||||
|
.npm |
||||
|
|
||||
|
# Optional eslint cache |
||||
|
.eslintcache |
||||
|
|
||||
|
# Microbundle cache |
||||
|
.rpt2_cache/ |
||||
|
.rts2_cache_cjs/ |
||||
|
.rts2_cache_es/ |
||||
|
.rts2_cache_umd/ |
||||
|
|
||||
|
# Optional REPL history |
||||
|
.node_repl_history |
||||
|
|
||||
|
# Output of 'npm pack' |
||||
|
*.tgz |
||||
|
|
||||
|
# Yarn Integrity file |
||||
|
.yarn-integrity |
||||
|
|
||||
|
# dotenv environment variables file |
||||
|
.env |
||||
|
.env.test |
||||
|
|
||||
|
# parcel-bundler cache (https://parceljs.org/) |
||||
|
.cache |
||||
|
.parcel-cache |
||||
|
|
||||
|
# Next.js build output |
||||
|
.next |
||||
|
|
||||
|
# Nuxt.js build / generate output |
||||
|
.nuxt |
||||
|
dist |
||||
|
|
||||
|
# Gatsby files |
||||
|
.cache/ |
||||
|
# Comment in the public line in if your project uses Gatsby and not Next.js |
||||
|
# https://nextjs.org/blog/next-9-1#public-directory-support |
||||
|
# public |
||||
|
|
||||
|
# vuepress build output |
||||
|
.vuepress/dist |
||||
|
|
||||
|
# Serverless directories |
||||
|
.serverless/ |
||||
|
|
||||
|
# FuseBox cache |
||||
|
.fusebox/ |
||||
|
|
||||
|
# DynamoDB Local files |
||||
|
.dynamodb/ |
||||
|
|
||||
|
# TernJS port file |
||||
|
.tern-port |
||||
|
|
||||
|
# Stores VSCode versions used for testing VSCode extensions |
||||
|
.vscode-test |
||||
|
|
||||
|
# yarn v2 |
||||
|
|
||||
|
.yarn/cache |
||||
|
.yarn/unplugged |
||||
|
.yarn/build-state.yml |
||||
|
.pnp.* |
||||
|
|
||||
|
**/node_modules |
@ -0,0 +1,41 @@ |
|||||
|
FROM golang:alpine as builder |
||||
|
RUN apk add --update --no-cache yarn make g++ |
||||
|
RUN yarn global add cross-env node-sass |
||||
|
|
||||
|
ENV GOPROXY=https://goproxy.cn,https://goproxy.io,direct \ |
||||
|
GO111MODULE=on \ |
||||
|
CGO_ENABLED=1 |
||||
|
WORKDIR /go/src/gin-vue-admin |
||||
|
RUN go env -w GOPROXY=https://goproxy.cn,https://goproxy.io,direct |
||||
|
COPY server/ ./ |
||||
|
RUN go env && go list && go build -v -a -ldflags "-extldflags \"-static\" " -o gvadmin . |
||||
|
|
||||
|
WORKDIR /web |
||||
|
COPY web/ ./ |
||||
|
RUN yarn install && yarn run build |
||||
|
|
||||
|
|
||||
|
FROM nginx:alpine |
||||
|
LABEL MAINTAINER="rikugun" |
||||
|
|
||||
|
RUN apk add --no-cache gettext tzdata && \ |
||||
|
cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \ |
||||
|
echo "Asia/Shanghai" > /etc/timezone && \ |
||||
|
date && \ |
||||
|
apk del tzdata |
||||
|
|
||||
|
COPY docker/etc/nginx/nginx.conf.tpl /etc/nginx/nginx.conf.tpl |
||||
|
WORKDIR /app |
||||
|
#copy web |
||||
|
COPY --from=builder /web/dist/ /var/www/ |
||||
|
#copy go app |
||||
|
COPY --from=builder /go/src/gin-vue-admin/gvadmin ./ |
||||
|
COPY --from=builder /go/src/gin-vue-admin/db.db ./ |
||||
|
COPY --from=builder /go/src/gin-vue-admin/config.yaml ./ |
||||
|
COPY --from=builder /go/src/gin-vue-admin/resource ./resource |
||||
|
COPY docker/docker-start.sh ./ |
||||
|
|
||||
|
ENV API_SERVER="http://localhost:8888/" |
||||
|
EXPOSE 80 |
||||
|
|
||||
|
ENTRYPOINT ["./docker-start.sh"] |
@ -0,0 +1,4 @@ |
|||||
|
#!/bin/sh |
||||
|
envsubst '$API_SERVER' < /etc/nginx/nginx.conf.tpl > /etc/nginx/nginx.conf |
||||
|
env nginx |
||||
|
./gvadmin |
@ -0,0 +1,56 @@ |
|||||
|
daemon on; |
||||
|
worker_processes 50; |
||||
|
#error_log /dev/stdout warn; |
||||
|
error_log /var/log/nginx/error.log error; |
||||
|
|
||||
|
|
||||
|
events { |
||||
|
worker_connections 1024; |
||||
|
} |
||||
|
|
||||
|
|
||||
|
http { |
||||
|
include mime.types; |
||||
|
default_type application/octet-stream; |
||||
|
# See http://licson.net/post/optimizing-nginx-for-large-file-delivery/ for more detail |
||||
|
# This optimizes the server for HLS fragment delivery |
||||
|
sendfile off; |
||||
|
#tcp_nopush on; |
||||
|
keepalive_timeout 65; |
||||
|
log_format main '$remote_addr - $remote_user [$time_local] "$request" ' |
||||
|
'$status $body_bytes_sent "$http_referer" ' |
||||
|
'"$http_user_agent" "$http_x_forwarded_for"'; |
||||
|
#access_log /dev/stdout combined; |
||||
|
|
||||
|
# ssl_ciphers HIGH:!aNULL:!MD5; |
||||
|
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2; |
||||
|
# ssl_session_cache shared:SSL:10m; |
||||
|
# ssl_session_timeout 10m; |
||||
|
|
||||
|
server { |
||||
|
listen 80; |
||||
|
|
||||
|
# Uncomment these lines to enable SSL. |
||||
|
# Update the ssl paths with your own certificate and private key. |
||||
|
# listen 443 ssl; |
||||
|
# ssl_certificate /opt/certs/example.com.crt; |
||||
|
# ssl_certificate_key /opt/certs/example.com.key; |
||||
|
location / { |
||||
|
root /var/www; |
||||
|
try_files $uri $uri/ /index.html; |
||||
|
index index.html; |
||||
|
} |
||||
|
|
||||
|
location /v1/ { |
||||
|
proxy_set_header X-Forwarded-Proto $scheme; |
||||
|
proxy_set_header X-Forwarded-Port $server_port; |
||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; |
||||
|
proxy_set_header Upgrade $http_upgrade; |
||||
|
proxy_set_header Connection "upgrade"; |
||||
|
proxy_set_header Host $host; |
||||
|
proxy_pass ${API_SERVER} ; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
FROM centos:7.6.1810 |
||||
|
|
||||
|
# 设置go mod proxy 国内代理 |
||||
|
# 设置golang path |
||||
|
ENV GOPROXY=https://goproxy.io GOPATH=/gopath PATH="${PATH}:/usr/local/go/bin" |
||||
|
# 定义使用的Golang 版本 |
||||
|
ARG GO_VERSION=1.13.3 |
||||
|
|
||||
|
# 安装 golang 1.13.3 |
||||
|
RUN wget "https://dl.google.com/go/go$GO_VERSION.linux-amd64.tar.gz" && \ |
||||
|
rm -rf /usr/local/go && \ |
||||
|
tar -C /usr/local -xzf "go$GO_VERSION.linux-amd64.tar.gz" && \ |
||||
|
rm -rf *.tar.gz && \ |
||||
|
go version && go env; |
||||
|
|
||||
|
|
||||
|
WORKDIR $GOPATH |
||||
|
COPY . gin-vue |
||||
|
|
||||
|
RUN cd server && go build -o app; |
||||
|
|
||||
|
EXPOSE 8888 |
||||
|
|
||||
|
CMD ["gin-vue/app"] |
@ -1,70 +1,70 @@ |
|||||
package config |
package config |
||||
|
|
||||
type Server struct { |
type Server struct { |
||||
Mysql Mysql `mapstructure:"mysql" json:"mysql"` |
|
||||
Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite"` |
|
||||
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu"` |
|
||||
Casbin Casbin `mapstructure:"casbin" json:"casbin"` |
|
||||
Redis Redis `mapstructure:"redis" json:"redis"` |
|
||||
System System `mapstructure:"system" json:"system"` |
|
||||
JWT JWT `mapstructure:"jwt" json:"jwt"` |
|
||||
Captcha Captcha `mapstructure:"captcha" json:"captcha"` |
|
||||
Log Log `mapstructure:"log" json:"log"` |
|
||||
|
Mysql Mysql `mapstructure:"mysql" json:"mysql" yaml:"mysql"` |
||||
|
Sqlite Sqlite `mapstructure:"sqlite" json:"sqlite" yaml:"sqlite"` |
||||
|
Qiniu Qiniu `mapstructure:"qiniu" json:"qiniu" yaml:"qiniu"` |
||||
|
Casbin Casbin `mapstructure:"casbin" json:"casbin" yaml:"casbin"` |
||||
|
Redis Redis `mapstructure:"redis" json:"redis" yaml:"redis"` |
||||
|
System System `mapstructure:"system" json:"system" yaml:"system"` |
||||
|
JWT JWT `mapstructure:"jwt" json:"jwt" yaml:"jwt"` |
||||
|
Captcha Captcha `mapstructure:"captcha" json:"captcha" yaml:"captcha"` |
||||
|
Log Log `mapstructure:"log" json:"log" yaml:"log"` |
||||
} |
} |
||||
|
|
||||
type System struct { |
type System struct { |
||||
UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint"` |
|
||||
Env string `mapstructure:"env" json:"env"` |
|
||||
Addr int `mapstructure:"addr" json:"addr"` |
|
||||
DbType string `mapstructure:"db-type" json:"dbType"` |
|
||||
|
UseMultipoint bool `mapstructure:"use-multipoint" json:"useMultipoint" yaml:"use-multipoint"` |
||||
|
Env string `mapstructure:"env" json:"env" yaml:"env"` |
||||
|
Addr int `mapstructure:"addr" json:"addr" yaml:"addr"` |
||||
|
DbType string `mapstructure:"db-type" json:"dbType" yaml:"db-type"` |
||||
} |
} |
||||
|
|
||||
type JWT struct { |
type JWT struct { |
||||
SigningKey string `mapstructure:"signing-key" json:"signingKey"` |
|
||||
|
SigningKey string `mapstructure:"signing-key" json:"signingKey" yaml:"signing-key"` |
||||
} |
} |
||||
|
|
||||
type Casbin struct { |
type Casbin struct { |
||||
ModelPath string `mapstructure:"model-path" json:"modelPath"` |
|
||||
|
ModelPath string `mapstructure:"model-path" json:"modelPath" yaml:"model-path"` |
||||
} |
} |
||||
|
|
||||
type Mysql struct { |
type Mysql struct { |
||||
Username string `mapstructure:"username" json:"username"` |
|
||||
Password string `mapstructure:"password" json:"password"` |
|
||||
Path string `mapstructure:"path" json:"path"` |
|
||||
Dbname string `mapstructure:"db-name" json:"dbname"` |
|
||||
Config string `mapstructure:"config" json:"config"` |
|
||||
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns"` |
|
||||
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns"` |
|
||||
LogMode bool `mapstructure:"log-mode" json:"logMode"` |
|
||||
|
Username string `mapstructure:"username" json:"username" yaml:"username"` |
||||
|
Password string `mapstructure:"password" json:"password" yaml:"password"` |
||||
|
Path string `mapstructure:"path" json:"path" yaml:"path"` |
||||
|
Dbname string `mapstructure:"db-name" json:"dbname" yaml:"db-name"` |
||||
|
Config string `mapstructure:"config" json:"config" yaml:"config"` |
||||
|
MaxIdleConns int `mapstructure:"max-idle-conns" json:"maxIdleConns" yaml:"max-idle-conns"` |
||||
|
MaxOpenConns int `mapstructure:"max-open-conns" json:"maxOpenConns" yaml:"max-open-conns"` |
||||
|
LogMode bool `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` |
||||
} |
} |
||||
|
|
||||
type Redis struct { |
type Redis struct { |
||||
Addr string `mapstructure:"addr" json:"addr"` |
|
||||
Password string `mapstructure:"password" json:"password"` |
|
||||
DB int `mapstructure:"db" json:"db"` |
|
||||
|
Addr string `mapstructure:"addr" json:"addr" yaml:"addr"` |
||||
|
Password string `mapstructure:"password" json:"password" yaml:"password"` |
||||
|
DB int `mapstructure:"db" json:"db" yaml:"db"` |
||||
} |
} |
||||
type Qiniu struct { |
type Qiniu struct { |
||||
AccessKey string `mapstructure:"access-key" json:"accessKey"` |
|
||||
SecretKey string `mapstructure:"secret-key" json:"secretKey"` |
|
||||
|
AccessKey string `mapstructure:"access-key" json:"accessKey" yaml:"access-key"` |
||||
|
SecretKey string `mapstructure:"secret-key" json:"secretKey" yaml:"secret-key"` |
||||
} |
} |
||||
|
|
||||
type Captcha struct { |
type Captcha struct { |
||||
KeyLong int `mapstructure:"key-long" json:"keyLong"` |
|
||||
ImgWidth int `mapstructure:"img-width" json:"imgWidth"` |
|
||||
ImgHeight int `mapstructure:"img-height" json:"imgHeight"` |
|
||||
|
KeyLong int `mapstructure:"key-long" json:"keyLong" yaml:"key-long"` |
||||
|
ImgWidth int `mapstructure:"img-width" json:"imgWidth" yaml:"img-width"` |
||||
|
ImgHeight int `mapstructure:"img-height" json:"imgHeight" yaml:"img-height"` |
||||
} |
} |
||||
|
|
||||
type Log struct { |
type Log struct { |
||||
Prefix string `mapstructure:"prefix" json:"prefix"` |
|
||||
LogFile bool `mapstructure:"log-file" json:"logFile"` |
|
||||
Stdout string `mapstructure:"stdout" json:"stdout"` |
|
||||
File string `mapstructure:"file" json:"file"` |
|
||||
|
Prefix string `mapstructure:"prefix" json:"prefix" yaml:"prefix"` |
||||
|
LogFile bool `mapstructure:"log-file" json:"logFile" yaml:"log-file"` |
||||
|
Stdout string `mapstructure:"stdout" json:"stdout" yaml:"stdout"` |
||||
|
File string `mapstructure:"file" json:"file" yaml:"file"` |
||||
} |
} |
||||
|
|
||||
type Sqlite struct { |
type Sqlite struct { |
||||
Username string `mapstructure:"username" json:"username"` |
|
||||
Password string `mapstructure:"password" json:"password"` |
|
||||
Path string `mapstructure:"path" json:"path"` |
|
||||
Config string `mapstructure:"config" json:"config"` |
|
||||
LogMode bool `mapstructure:"log-mode" json:"logMode"` |
|
||||
|
Username string `mapstructure:"username" json:"username" yaml:"username"` |
||||
|
Password string `mapstructure:"password" json:"password" yaml:"password"` |
||||
|
Path string `mapstructure:"path" json:"path" yaml:"path"` |
||||
|
Config string `mapstructure:"config" json:"config" yaml:"config"` |
||||
|
LogMode bool `mapstructure:"log-mode" json:"logMode" yaml:"log-mode"` |
||||
} |
} |
@ -1,5 +1,7 @@ |
|||||
package response |
package response |
||||
|
|
||||
|
import "gin-vue-admin/model/request" |
||||
|
|
||||
type PolicyPathResponse struct { |
type PolicyPathResponse struct { |
||||
Paths []map[string]string `json:"paths"` |
|
||||
|
Paths []request.CasbinInfo `json:"paths"` |
||||
} |
} |
@ -0,0 +1,320 @@ |
|||||
|
.todoapp { |
||||
|
font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif; |
||||
|
line-height: 1.4em; |
||||
|
color: #4d4d4d; |
||||
|
min-width: 230px; |
||||
|
max-width: 666px; |
||||
|
margin: 0 auto ; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
font-weight: 300; |
||||
|
background: #fff; |
||||
|
z-index: 1; |
||||
|
position: relative; |
||||
|
button { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
border: 0; |
||||
|
background: none; |
||||
|
font-size: 100%; |
||||
|
vertical-align: baseline; |
||||
|
font-family: inherit; |
||||
|
font-weight: inherit; |
||||
|
color: inherit; |
||||
|
-webkit-appearance: none; |
||||
|
appearance: none; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
:focus { |
||||
|
outline: 0; |
||||
|
} |
||||
|
.hidden { |
||||
|
display: none; |
||||
|
} |
||||
|
.todoapp { |
||||
|
background: #fff; |
||||
|
margin: 130px 0 40px 0; |
||||
|
position: relative; |
||||
|
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2), 0 25px 50px 0 rgba(0, 0, 0, 0.1); |
||||
|
} |
||||
|
.todoapp input::-webkit-input-placeholder { |
||||
|
font-style: italic; |
||||
|
font-weight: 300; |
||||
|
color: #e6e6e6; |
||||
|
} |
||||
|
.todoapp input::-moz-placeholder { |
||||
|
font-style: italic; |
||||
|
font-weight: 300; |
||||
|
color: #e6e6e6; |
||||
|
} |
||||
|
.todoapp input::input-placeholder { |
||||
|
font-style: italic; |
||||
|
font-weight: 300; |
||||
|
color: #e6e6e6; |
||||
|
} |
||||
|
.todoapp h1 { |
||||
|
position: absolute; |
||||
|
top: -155px; |
||||
|
width: 100%; |
||||
|
font-size: 100px; |
||||
|
font-weight: 100; |
||||
|
text-align: center; |
||||
|
color: rgba(175, 47, 47, 0.15); |
||||
|
-webkit-text-rendering: optimizeLegibility; |
||||
|
-moz-text-rendering: optimizeLegibility; |
||||
|
text-rendering: optimizeLegibility; |
||||
|
} |
||||
|
.new-todo, |
||||
|
.edit { |
||||
|
position: relative; |
||||
|
margin: 0; |
||||
|
width: 100%; |
||||
|
font-size: 18px; |
||||
|
font-family: inherit; |
||||
|
font-weight: inherit; |
||||
|
line-height: 1.4em; |
||||
|
border: 0; |
||||
|
color: inherit; |
||||
|
padding: 6px; |
||||
|
border: 1px solid #999; |
||||
|
box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2); |
||||
|
box-sizing: border-box; |
||||
|
-webkit-font-smoothing: antialiased; |
||||
|
-moz-osx-font-smoothing: grayscale; |
||||
|
} |
||||
|
.new-todo { |
||||
|
padding: 10px 16px 16px 60px; |
||||
|
border: none; |
||||
|
background: rgba(0, 0, 0, 0.003); |
||||
|
box-shadow: inset 0 -2px 1px rgba(0, 0, 0, 0.03); |
||||
|
} |
||||
|
.main { |
||||
|
position: relative; |
||||
|
z-index: 2; |
||||
|
border-top: 1px solid #e6e6e6; |
||||
|
} |
||||
|
.toggle-all { |
||||
|
text-align: center; |
||||
|
border: none; |
||||
|
/* Mobile Safari */ |
||||
|
opacity: 0; |
||||
|
position: absolute; |
||||
|
} |
||||
|
.toggle-all+label { |
||||
|
width: 60px; |
||||
|
height: 34px; |
||||
|
font-size: 0; |
||||
|
position: absolute; |
||||
|
top: -52px; |
||||
|
left: -13px; |
||||
|
-webkit-transform: rotate(90deg); |
||||
|
transform: rotate(90deg); |
||||
|
} |
||||
|
.toggle-all+label:before { |
||||
|
content: '❯'; |
||||
|
font-size: 22px; |
||||
|
color: #e6e6e6; |
||||
|
padding: 10px 27px 10px 27px; |
||||
|
} |
||||
|
.toggle-all:checked+label:before { |
||||
|
color: #737373; |
||||
|
} |
||||
|
.todo-list { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
list-style: none; |
||||
|
} |
||||
|
.todo-list li { |
||||
|
position: relative; |
||||
|
font-size: 24px; |
||||
|
border-bottom: 1px solid #ededed; |
||||
|
} |
||||
|
.todo-list li:last-child { |
||||
|
border-bottom: none; |
||||
|
} |
||||
|
.todo-list li.editing { |
||||
|
border-bottom: none; |
||||
|
padding: 0; |
||||
|
} |
||||
|
.todo-list li.editing .edit { |
||||
|
display: block; |
||||
|
width: 506px; |
||||
|
padding: 12px 16px; |
||||
|
margin: 0 0 0 43px; |
||||
|
} |
||||
|
.todo-list li.editing .view { |
||||
|
display: none; |
||||
|
} |
||||
|
.todo-list li .toggle { |
||||
|
text-align: center; |
||||
|
width: 40px; |
||||
|
/* auto, since non-WebKit browsers doesn't support input styling */ |
||||
|
height: auto; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
bottom: 0; |
||||
|
margin: auto 0; |
||||
|
border: none; |
||||
|
/* Mobile Safari */ |
||||
|
-webkit-appearance: none; |
||||
|
appearance: none; |
||||
|
} |
||||
|
.todo-list li .toggle { |
||||
|
opacity: 0; |
||||
|
} |
||||
|
.todo-list li .toggle+label { |
||||
|
/* |
||||
|
Firefox requires `#` to be escaped - https://bugzilla.mozilla.org/show_bug.cgi?id=922433 |
||||
|
IE and Edge requires *everything* to be escaped to render, so we do that instead of just the `#` - https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/7157459/ |
||||
|
*/ |
||||
|
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23ededed%22%20stroke-width%3D%223%22/%3E%3C/svg%3E'); |
||||
|
background-repeat: no-repeat; |
||||
|
background-position: center left; |
||||
|
background-size: 36px; |
||||
|
} |
||||
|
.todo-list li .toggle:checked+label { |
||||
|
background-size: 36px; |
||||
|
background-image: url('data:image/svg+xml;utf8,%3Csvg%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%20width%3D%2240%22%20height%3D%2240%22%20viewBox%3D%22-10%20-18%20100%20135%22%3E%3Ccircle%20cx%3D%2250%22%20cy%3D%2250%22%20r%3D%2250%22%20fill%3D%22none%22%20stroke%3D%22%23bddad5%22%20stroke-width%3D%223%22/%3E%3Cpath%20fill%3D%22%235dc2af%22%20d%3D%22M72%2025L42%2071%2027%2056l-4%204%2020%2020%2034-52z%22/%3E%3C/svg%3E'); |
||||
|
} |
||||
|
.todo-list li label { |
||||
|
word-break: break-all; |
||||
|
padding: 15px 15px 15px 50px; |
||||
|
display: block; |
||||
|
line-height: 1.0; |
||||
|
font-size: 14px; |
||||
|
transition: color 0.4s; |
||||
|
} |
||||
|
.todo-list li.completed label { |
||||
|
color: #d9d9d9; |
||||
|
text-decoration: line-through; |
||||
|
} |
||||
|
.todo-list li .destroy { |
||||
|
display: none; |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
right: 10px; |
||||
|
bottom: 0; |
||||
|
width: 40px; |
||||
|
height: 40px; |
||||
|
margin: auto 0; |
||||
|
font-size: 30px; |
||||
|
color: #cc9a9a; |
||||
|
transition: color 0.2s ease-out; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.todo-list li .destroy:hover { |
||||
|
color: #af5b5e; |
||||
|
} |
||||
|
.todo-list li .destroy:after { |
||||
|
content: '×'; |
||||
|
} |
||||
|
.todo-list li:hover .destroy { |
||||
|
display: block; |
||||
|
} |
||||
|
.todo-list li .edit { |
||||
|
display: none; |
||||
|
} |
||||
|
.todo-list li.editing:last-child { |
||||
|
margin-bottom: -1px; |
||||
|
} |
||||
|
.footer { |
||||
|
color: #777; |
||||
|
position: relative; |
||||
|
padding: 10px 15px; |
||||
|
height: 40px; |
||||
|
text-align: center; |
||||
|
border-top: 1px solid #e6e6e6; |
||||
|
} |
||||
|
.footer:before { |
||||
|
content: ''; |
||||
|
position: absolute; |
||||
|
right: 0; |
||||
|
bottom: 0; |
||||
|
left: 0; |
||||
|
height: 40px; |
||||
|
overflow: hidden; |
||||
|
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2), 0 8px 0 -3px #f6f6f6, 0 9px 1px -3px rgba(0, 0, 0, 0.2), 0 16px 0 -6px #f6f6f6, 0 17px 2px -6px rgba(0, 0, 0, 0.2); |
||||
|
} |
||||
|
.todo-count { |
||||
|
float: left; |
||||
|
text-align: left; |
||||
|
} |
||||
|
.todo-count strong { |
||||
|
font-weight: 300; |
||||
|
} |
||||
|
.filters { |
||||
|
margin: 0; |
||||
|
padding: 0; |
||||
|
position: relative; |
||||
|
z-index: 1; |
||||
|
list-style: none; |
||||
|
} |
||||
|
.filters li { |
||||
|
display: inline; |
||||
|
} |
||||
|
.filters li a { |
||||
|
color: inherit; |
||||
|
font-size: 12px; |
||||
|
padding: 3px 7px; |
||||
|
text-decoration: none; |
||||
|
border: 1px solid transparent; |
||||
|
border-radius: 3px; |
||||
|
} |
||||
|
.filters li a:hover { |
||||
|
border-color: rgba(175, 47, 47, 0.1); |
||||
|
} |
||||
|
.filters li a.selected { |
||||
|
border-color: rgba(175, 47, 47, 0.2); |
||||
|
} |
||||
|
.clear-completed, |
||||
|
html .clear-completed:active { |
||||
|
float: right; |
||||
|
position: relative; |
||||
|
line-height: 20px; |
||||
|
text-decoration: none; |
||||
|
cursor: pointer; |
||||
|
} |
||||
|
.clear-completed:hover { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
.info { |
||||
|
margin: 65px auto 0; |
||||
|
color: #bfbfbf; |
||||
|
font-size: 10px; |
||||
|
text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5); |
||||
|
text-align: center; |
||||
|
} |
||||
|
.info p { |
||||
|
line-height: 1; |
||||
|
} |
||||
|
.info a { |
||||
|
color: inherit; |
||||
|
text-decoration: none; |
||||
|
font-weight: 400; |
||||
|
} |
||||
|
.info a:hover { |
||||
|
text-decoration: underline; |
||||
|
} |
||||
|
/* |
||||
|
Hack to remove background from Mobile Safari. |
||||
|
Can't use it globally since it destroys checkboxes in Firefox |
||||
|
*/ |
||||
|
@media screen and (-webkit-min-device-pixel-ratio:0) { |
||||
|
.toggle-all, |
||||
|
.todo-list li .toggle { |
||||
|
background: none; |
||||
|
} |
||||
|
.todo-list li .toggle { |
||||
|
height: 40px; |
||||
|
} |
||||
|
} |
||||
|
@media (max-width: 430px) { |
||||
|
.footer { |
||||
|
height: 50px; |
||||
|
} |
||||
|
.filters { |
||||
|
bottom: 10px; |
||||
|
} |
||||
|
} |
||||
|
} |
Write
Preview
Loading…
Cancel
Save
Reference in new issue