Skip to content

Commit 24ba57c

Browse files
committed
Add dashboard
1 parent de0518d commit 24ba57c

File tree

19 files changed

+591
-87
lines changed

19 files changed

+591
-87
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "timer",
3-
"version": "0.0.1",
3+
"version": "0.0.2",
44
"description": "Web timer",
55
"main": "index.js",
66
"scripts": {

public/dashboard.html

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8" />
5+
</head>
6+
<body>
7+
<div id="app"></div>
8+
</body>
9+
<script src="../dashboard.js"></script>
10+
</html>

src/background.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,11 @@ chrome.tabs.onActivated.addListener((tabInfo: chrome.tabs.TabActiveInfo) => {
3939
!!lastFocusTabId && chrome.tabs.sendMessage(lastFocusTabId, { code: UNFOCUS })
4040
lastFocusTabId = tabId
4141
})
42+
43+
chrome.windows.onFocusChanged.addListener((windowId) => {
44+
if (windowId === chrome.windows.WINDOW_ID_NONE) {
45+
// All windows lost focus
46+
!!lastFocusTabId && chrome.tabs.sendMessage(lastFocusTabId, { code: UNFOCUS })
47+
lastFocusTabId = undefined
48+
}
49+
})

src/content-script.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import database, { WastePerDay } from "./database"
22
import { FOCUS, HOST_END, SAVE_FOCUS, UNFOCUS } from "./util/constant"
3-
import { formatSpec } from "./util/time"
3+
import { formatPeriod } from "./util/time"
44

55
const host = document.location.host
66
chrome.runtime.sendMessage({ code: 'hostStart', host })
@@ -14,9 +14,14 @@ database.refresh(() => {
1414
.replace('{host}', host)
1515
.replace('{time}', waste.time.toString())
1616
console.log(info0)
17+
18+
const hourMsg = chrome.i18n.getMessage('message_timeWithHour')
19+
const minuteMsg = chrome.i18n.getMessage('message_timeWithMinute')
20+
const secondMsg = chrome.i18n.getMessage('message_timeWithSecond')
21+
1722
const info1 = chrome.i18n.getMessage('message_usedTimeInConsoleLog')
18-
.replace('{focus}', formatSpec(waste.focus))
19-
.replace('{total}', formatSpec(waste.total))
23+
.replace('{focus}', formatPeriod(waste.focus, hourMsg, minuteMsg, secondMsg))
24+
.replace('{total}', formatPeriod(waste.total, hourMsg, minuteMsg, secondMsg))
2025
console.log(info1)
2126
})
2227

src/dashboard/AppMain.vue

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
<template>
2+
<div class="app-container">
3+
<div class="filter-container">
4+
<el-input class="filter-item"
5+
v-model="host"
6+
:placeholder="$t('dashboard.hostPlaceholder')"
7+
clearable
8+
@keyup.enter.native="queryData">
9+
</el-input>
10+
<span class="filter-item">
11+
<el-date-picker v-model="dateRange"
12+
type="daterange"
13+
format="yyyy/MM/dd"
14+
range-separator="-"
15+
:picker-options="pickerOptions"
16+
:start-placeholder="$t('dashboard.startDate')"
17+
:end-placeholder="$t('dashboard.endDate')">
18+
</el-date-picker>
19+
</span>
20+
<a class="filter-name">{{ $t('dashboard.mergeDate') }}</a>
21+
<el-switch class="filter-item"
22+
v-model="mergeDate" />
23+
<a class="filter-name">{{ $t('dashboard.mergeDomain') }}</a>
24+
<el-switch class="filter-item"
25+
v-model="mergeDomain" />
26+
<a class="filter-name">{{ $t('dashboard.displayBySecond') }}</a>
27+
<el-switch class="filter-item"
28+
v-model="displayBySecond" />
29+
</div>
30+
<!-- table -->
31+
<el-table :data="tableData"
32+
border
33+
:default-sort="sort"
34+
@sort-change="sortChangeHandler"
35+
style="width: 100%">
36+
<el-table-column prop="date"
37+
:label="$t('item.date')"
38+
min-width="100px"
39+
align="center"
40+
:formatter="dateFormatter"
41+
sortable="custom"
42+
v-if="!mergeDate" />
43+
<el-table-column prop="host"
44+
:label="$t('item.host')"
45+
min-width="170px"
46+
sortable="custom"
47+
align="center" />
48+
<el-table-column prop="focus"
49+
:label="$t('item.focus')"
50+
min-width="130px"
51+
sortable="custom"
52+
align="center"
53+
:formatter="row => periodFormatter(row.focus)" />
54+
<el-table-column prop="total"
55+
:label="$t('item.total')"
56+
min-width="130px"
57+
sortable="custom"
58+
align="center"
59+
:formatter="row => periodFormatter(row.total)" />
60+
<el-table-column prop="time"
61+
:label="$t('item.time')"
62+
min-width="80px"
63+
sortable="custom"
64+
align="center" />
65+
</el-table>
66+
<div class="pagination-container">
67+
<el-pagination @size-change="queryData"
68+
@current-change="queryData"
69+
:current-page.sync="page.num"
70+
:page-sizes="[10, 20, 50]"
71+
:page-size.sync="page.size"
72+
layout="total, sizes, prev, pager, next, jumper"
73+
:total="page.total">
74+
</el-pagination>
75+
</div>
76+
</div>
77+
</template>
78+
<script>
79+
import database, { QueryParam } from '../database'
80+
import { formatPeriodCommon } from '../util/time'
81+
const ELEMENT_SORT_2_DB = {
82+
descending: QueryParam.DESC,
83+
ascending: QueryParam.ASC
84+
}
85+
export default {
86+
name: 'Dashboard',
87+
data () {
88+
return {
89+
host: '',
90+
mergeDate: false,
91+
mergeDomain: true,
92+
displayBySecond: false,
93+
dateRange: [],
94+
sort: {
95+
prop: 'focus',
96+
order: 'descending'
97+
},
98+
page: {
99+
size: 10,
100+
num: 1,
101+
total: 0
102+
},
103+
tableData: [],
104+
pickerOptions: {
105+
disabledDate: date => date > new Date(),
106+
shortcuts: [
107+
{
108+
text: this.$t('dashboard.latestWeek'),
109+
onClick (picker) {
110+
const end = new Date()
111+
const start = new Date()
112+
start.setTime(end.getTime() - 3600 * 1000 * 24 * 7)
113+
picker.$emit('pick', [start, end])
114+
}
115+
}, {
116+
text: this.$t('dashboard.latest30Days'),
117+
onClick (picker) {
118+
const end = new Date()
119+
const start = new Date()
120+
start.setTime(end.getTime() - 3600 * 1000 * 24 * 30)
121+
picker.$emit('pick', [start, end])
122+
}
123+
}
124+
]
125+
}
126+
}
127+
},
128+
watch: {
129+
mergeDate () {
130+
this.queryData()
131+
},
132+
mergeDomain () {
133+
this.queryData()
134+
},
135+
dateRange () {
136+
this.queryData()
137+
}
138+
},
139+
created () {
140+
document.title = this.$t('dashboard.title')
141+
database.refresh(() => this.queryData())
142+
},
143+
methods: {
144+
queryData () {
145+
const param = {
146+
host: this.host,
147+
date: this.dateRange,
148+
mergeDomain: this.mergeDomain,
149+
mergeDate: this.mergeDate,
150+
sort: this.sort.prop,
151+
sortOrder: ELEMENT_SORT_2_DB[this.sort.order]
152+
}
153+
const page = {
154+
pageSize: this.page.size,
155+
pageNum: this.page.num
156+
}
157+
const { list, total } = database.selectByPage(param, page)
158+
this.tableData = list
159+
this.page.total = total
160+
},
161+
dateFormatter ({ date }) {
162+
if (!date) return '-'
163+
return date.substring(0, 4) + '/' + date.substring(4, 6) + '/' + date.substring(6, 8)
164+
},
165+
periodFormatter (val) {
166+
return val === undefined ? '-' : this.displayBySecond ? (Math.floor(val / 1000) + ' s') : formatPeriodCommon(val)
167+
},
168+
sortChangeHandler ({ prop, order }) {
169+
this.sort.prop = prop
170+
this.sort.order = order
171+
this.queryData()
172+
}
173+
}
174+
}
175+
</script>
176+
<style scoped>
177+
.app-container {
178+
width: 70%;
179+
height: 100%;
180+
margin: auto;
181+
padding-top: 35px;
182+
}
183+
184+
.filter-container {
185+
padding-bottom: 10px;
186+
}
187+
188+
.filter-item {
189+
display: inline-block;
190+
vertical-align: middle;
191+
margin-bottom: 10px;
192+
padding-right: 20px;
193+
}
194+
.filter-name {
195+
color: #909399;
196+
font-weight: bold;
197+
font-size: 14px;
198+
}
199+
.filter-item.el-input {
200+
width: 175px;
201+
}
202+
.pagination-container {
203+
width: 100%;
204+
text-align: center;
205+
margin-top: 23px;
206+
}
207+
</style>
208+
<style>
209+
.el-input__suffix {
210+
right: 30px !important;
211+
}
212+
</style>

src/dashboard/element.js

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import Vue from 'vue'
2+
import {
3+
DatePicker,
4+
Icon, Input,
5+
Option,
6+
Pagination,
7+
Switch,
8+
Table, TableColumn
9+
} from 'element-ui'
10+
11+
Vue.use(DatePicker)
12+
import 'element-ui/lib/theme-chalk/date-picker.css'
13+
14+
Vue.use(Icon)
15+
import 'element-ui/lib/theme-chalk/icon.css'
16+
17+
Vue.use(Input)
18+
import 'element-ui/lib/theme-chalk/input.css'
19+
20+
Vue.use(Option)
21+
import 'element-ui/lib/theme-chalk/option.css'
22+
23+
Vue.use(Pagination)
24+
import 'element-ui/lib/theme-chalk/pagination.css'
25+
26+
Vue.use(Switch)
27+
import 'element-ui/lib/theme-chalk/switch.css'
28+
29+
Vue.use(Table)
30+
import 'element-ui/lib/theme-chalk/table.css'
31+
Vue.use(TableColumn)
32+
import 'element-ui/lib/theme-chalk/table-column.css'

src/dashboard/main.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import Vue from 'vue'
2+
import AppMain from './AppMain'
3+
import './element'
4+
import i18n from '../common/vue-i18n'
5+
6+
new Vue({
7+
el: '#app',
8+
i18n,
9+
render: (h) => h(AppMain),
10+
})

0 commit comments

Comments
 (0)