@sedoo/unidoo 0.0.60 → 0.0.64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/unidoo.common.js +554 -124
- package/dist/unidoo.common.js.map +1 -1
- package/dist/unidoo.umd.js +554 -124
- package/dist/unidoo.umd.js.map +1 -1
- package/dist/unidoo.umd.min.js +2 -2
- package/dist/unidoo.umd.min.js.map +1 -1
- package/package.json +1 -1
- package/src/components/unidoo-heatmap/Heatmap.js +96 -2
- package/src/components/unidoo-heatmap/UnidooHeatmap.vue +53 -11
- package/src/components/unidoo-heatmap/date-switcher.vue +97 -25
- package/src/plugin.js +10 -0
package/package.json
CHANGED
|
@@ -8,6 +8,8 @@ export default class CalendarHeatmap {
|
|
|
8
8
|
this.max = Math.ceil((Math.max(...values.map(day => day.count)) / 5) * 4)
|
|
9
9
|
}
|
|
10
10
|
this.values = values.map(v => { return { date: this._valuesDateFormat(v.date), count: v.count } })
|
|
11
|
+
this.times = this._getTimes(this.year.getFullYear())
|
|
12
|
+
this.times.sort()
|
|
11
13
|
}
|
|
12
14
|
|
|
13
15
|
get activities () {
|
|
@@ -44,6 +46,13 @@ export default class CalendarHeatmap {
|
|
|
44
46
|
return new Date(year, month + 1, 0).getDate()
|
|
45
47
|
}
|
|
46
48
|
|
|
49
|
+
daysInYear(year) {
|
|
50
|
+
const start = new Date(year, 0, 0)
|
|
51
|
+
const end = new Date(year, 11, 31)
|
|
52
|
+
const diff = end - start
|
|
53
|
+
return Math.floor(diff / (1000 * 60 * 60 * 24))
|
|
54
|
+
}
|
|
55
|
+
|
|
47
56
|
getColorIndex (value) {
|
|
48
57
|
if (value == null || value === undefined) {
|
|
49
58
|
return 0
|
|
@@ -72,10 +81,95 @@ export default class CalendarHeatmap {
|
|
|
72
81
|
}
|
|
73
82
|
}
|
|
74
83
|
|
|
84
|
+
getNextAvailableDate(date, countGreaterThanZero) {
|
|
85
|
+
if (date) {
|
|
86
|
+
date.setHours(0, 0, 0)
|
|
87
|
+
if (this.times && this.times.length) {
|
|
88
|
+
let index = this.times.indexOf(this._encodeDate(date, null))
|
|
89
|
+
if (index < 0) index = this.times.indexOf(this._encodeDate(date, 1))
|
|
90
|
+
if (index < 0) index = this.times.indexOf(this._encodeDate(date, 0))
|
|
91
|
+
if (index >= 0) {
|
|
92
|
+
const maxIndex = this.times.length - 1
|
|
93
|
+
let n = index + 1
|
|
94
|
+
if (countGreaterThanZero) {
|
|
95
|
+
while (n < maxIndex) {
|
|
96
|
+
const curr = this.times[n]
|
|
97
|
+
if (curr.endsWith('i')) return this._decodeDate(curr)
|
|
98
|
+
n++
|
|
99
|
+
}
|
|
100
|
+
} else {
|
|
101
|
+
while (n < maxIndex) {
|
|
102
|
+
const curr = this.times[n]
|
|
103
|
+
if (!curr.endsWith('n')) return this._decodeDate(curr)
|
|
104
|
+
n++
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
return null
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
getPreviousAvailableDate(date, countGreaterThanZero) {
|
|
114
|
+
if (date) {
|
|
115
|
+
date.setHours(0, 0, 0)
|
|
116
|
+
if (this.times && this.times.length) {
|
|
117
|
+
let index = this.times.indexOf(this._encodeDate(date, null))
|
|
118
|
+
if (index < 0) index = this.times.indexOf(this._encodeDate(date, 1))
|
|
119
|
+
if (index < 0) index = this.times.indexOf(this._encodeDate(date, 0))
|
|
120
|
+
if (index > 0) {
|
|
121
|
+
let n = index - 1
|
|
122
|
+
if (countGreaterThanZero) {
|
|
123
|
+
while (n > 0) {
|
|
124
|
+
const curr = this.times[n]
|
|
125
|
+
if (curr.endsWith('i')) return this._decodeDate(curr)
|
|
126
|
+
n--
|
|
127
|
+
}
|
|
128
|
+
} else {
|
|
129
|
+
while (n > 0) {
|
|
130
|
+
const curr = this.times[n]
|
|
131
|
+
if (!curr.endsWith('n')) return this._decodeDate(curr)
|
|
132
|
+
n--
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return null
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
_getTimes (year) {
|
|
142
|
+
const date = new Date(year, 0, 1)
|
|
143
|
+
return Array.from({ length: this.daysInYear(year) },
|
|
144
|
+
() => {
|
|
145
|
+
const dDate = new Date(date.getFullYear(), date.getMonth(), date.getDate())
|
|
146
|
+
dDate.setHours(0, 0, 0)
|
|
147
|
+
const dayValues = this.activities[this._keyDayParser(dDate)]
|
|
148
|
+
date.setDate(date.getDate() + 1)
|
|
149
|
+
return this._encodeDate(dDate, (dayValues) ? dayValues.count : null)
|
|
150
|
+
}
|
|
151
|
+
)
|
|
152
|
+
}
|
|
153
|
+
|
|
75
154
|
_valuesDateFormat (d) {
|
|
76
155
|
if (!d) return ''
|
|
77
|
-
const date = (d
|
|
78
|
-
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`
|
|
156
|
+
const date = this._parseDate(d)
|
|
157
|
+
return `${date.getFullYear()}-${this._paddNumber(date.getMonth() + 1)}-${this._paddNumber(date.getDate())}`
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
_paddNumber (n) {
|
|
161
|
+
return ('' + n).padStart(2, '0')
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
_encodeDate (d, count) {
|
|
165
|
+
const date = this._parseDate(d)
|
|
166
|
+
return this._valuesDateFormat(date) + ((Number.isFinite(count)) ? ((count > 0) ? 'i' : 'o') : 'n')
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
_decodeDate (d) {
|
|
170
|
+
if (!d) return null
|
|
171
|
+
const sdate = d.slice(0, -1)
|
|
172
|
+
return new Date(sdate)
|
|
79
173
|
}
|
|
80
174
|
|
|
81
175
|
_parseDate (entry) {
|
|
@@ -88,19 +88,21 @@ export default {
|
|
|
88
88
|
}
|
|
89
89
|
},
|
|
90
90
|
data: () => ({
|
|
91
|
-
now: new Date(new Date().setHours(23,59,59,999))
|
|
91
|
+
now: new Date(new Date().setHours(23, 59, 59, 999))
|
|
92
92
|
}),
|
|
93
93
|
watch: {
|
|
94
94
|
dateValue (val) {
|
|
95
95
|
this.focusDate(val)
|
|
96
|
+
this.updateDateSwitcher(val)
|
|
96
97
|
},
|
|
97
|
-
year (val) {
|
|
98
|
-
if (val !==
|
|
98
|
+
year (val, old) {
|
|
99
|
+
if (val !== old) {
|
|
99
100
|
const rects = document.querySelectorAll('[heatmap-calendar] [month] .monthday')
|
|
100
101
|
rects.forEach(element => {
|
|
101
102
|
element.classList.remove('day-focus')
|
|
102
103
|
});
|
|
103
104
|
this.focusDate(this.dateValue)
|
|
105
|
+
this.updateDateSwitcher(null)
|
|
104
106
|
}
|
|
105
107
|
}
|
|
106
108
|
},
|
|
@@ -121,7 +123,7 @@ export default {
|
|
|
121
123
|
return DEFAULT_LOCALE
|
|
122
124
|
},
|
|
123
125
|
dateValue() {
|
|
124
|
-
if(this.value){
|
|
126
|
+
if (this.value) {
|
|
125
127
|
return (this.value instanceof Date) ? this.value : this.value.date;
|
|
126
128
|
} else {
|
|
127
129
|
return this.value;
|
|
@@ -130,14 +132,23 @@ export default {
|
|
|
130
132
|
},
|
|
131
133
|
beforeMount () {
|
|
132
134
|
Plugin.EventBus.$on("unidoo-heatmap-set-date", params => {
|
|
133
|
-
if(this.heatmapKey
|
|
134
|
-
if(params.date){
|
|
135
|
+
if (this.heatmapKey) {
|
|
136
|
+
if (params.key === this.heatmapKey && params.date) {
|
|
135
137
|
this.setDate(params.date)
|
|
136
|
-
}
|
|
137
|
-
} else if(params.date) {
|
|
138
|
+
}
|
|
139
|
+
} else if (params.date) {
|
|
138
140
|
this.setDate(params.date)
|
|
139
141
|
}
|
|
140
142
|
})
|
|
143
|
+
Plugin.EventBus.$on("unidoo-heatmap-get-date", params => {
|
|
144
|
+
if (this.heatmapKey) {
|
|
145
|
+
if (params.key === this.heatmapKey) {
|
|
146
|
+
this.updateDateSwitcher(this.dateValue)
|
|
147
|
+
}
|
|
148
|
+
} else {
|
|
149
|
+
this.updateDateSwitcher(this.dateValue)
|
|
150
|
+
}
|
|
151
|
+
})
|
|
141
152
|
},
|
|
142
153
|
methods: {
|
|
143
154
|
computeClass (day) {
|
|
@@ -174,7 +185,7 @@ export default {
|
|
|
174
185
|
handleClick (e, day) {
|
|
175
186
|
if (day) {
|
|
176
187
|
if (day.date <= this.now && (typeof day.count === 'number' || this.missingAllowed)) {
|
|
177
|
-
if(this.returnObject){
|
|
188
|
+
if (this.returnObject) {
|
|
178
189
|
this.$emit('input', day);
|
|
179
190
|
} else {
|
|
180
191
|
this.$emit('input', day.date);
|
|
@@ -185,8 +196,30 @@ export default {
|
|
|
185
196
|
setDate (d) {
|
|
186
197
|
if (!d) return
|
|
187
198
|
const day = this.heatmap.getDayFromDate(d);
|
|
188
|
-
this.handleClick(null, day);
|
|
189
|
-
|
|
199
|
+
this.handleClick(null, day);
|
|
200
|
+
},
|
|
201
|
+
updateDateSwitcher (d) {
|
|
202
|
+
this.$unidooDateSwitcher.update({
|
|
203
|
+
hasPrevious: this.hasPreviousDate(d),
|
|
204
|
+
hasNext: this.hasNextDate(d),
|
|
205
|
+
previousAvailable: this.heatmap.getPreviousAvailableDate(d),
|
|
206
|
+
nextAvailable: this.heatmap.getNextAvailableDate(d)
|
|
207
|
+
}, this.heatmapKey);
|
|
208
|
+
},
|
|
209
|
+
hasPreviousDate (d) {
|
|
210
|
+
if (!d || !this.compairDateWithYear(d)) return false;
|
|
211
|
+
const syear = (this.year instanceof Date) ? this.year.getFullYear() : this.year;
|
|
212
|
+
const firstDay = new Date(syear, 0, 1);
|
|
213
|
+
d.setHours(0, 0, 0, 0);
|
|
214
|
+
if (d <= firstDay) return false;
|
|
215
|
+
return true;
|
|
216
|
+
},
|
|
217
|
+
hasNextDate (d) {
|
|
218
|
+
if (!d || !this.compairDateWithYear(d)) return false
|
|
219
|
+
const today = new Date();
|
|
220
|
+
today.setHours(0, 0, 0, 0);
|
|
221
|
+
if (d >= today) return false;
|
|
222
|
+
return true;
|
|
190
223
|
},
|
|
191
224
|
focusDate (d) {
|
|
192
225
|
if (!d) return
|
|
@@ -254,6 +287,15 @@ export default {
|
|
|
254
287
|
return first.getFullYear() === second.getFullYear() &&
|
|
255
288
|
first.getMonth() === second.getMonth() &&
|
|
256
289
|
first.getDate() === second.getDate()
|
|
290
|
+
},
|
|
291
|
+
compairDateWithYear (d) {
|
|
292
|
+
if (this.year && d) {
|
|
293
|
+
const sd = '' + ((d instanceof Date) ? d.getFullYear() : d);
|
|
294
|
+
const syear = '' + ((this.year instanceof Date) ? this.year.getFullYear() : this.year);
|
|
295
|
+
return syear === sd;
|
|
296
|
+
} else {
|
|
297
|
+
return false
|
|
298
|
+
}
|
|
257
299
|
}
|
|
258
300
|
}
|
|
259
301
|
}
|
|
@@ -1,46 +1,119 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div date-switch>
|
|
3
|
-
<v-btn icon x-small
|
|
3
|
+
<v-btn icon x-small :disabled="!previousAvailable" style="margin-right: 4px;" @click="goToPreviousAvailable(1)">
|
|
4
4
|
<v-icon>mdi-skip-previous</v-icon>
|
|
5
5
|
</v-btn>
|
|
6
|
+
<v-btn icon x-small :disabled="!hasPrevious" style="margin-right: 8px;" @click="switchDate(-1)">
|
|
7
|
+
<v-icon>mdi-rewind</v-icon>
|
|
8
|
+
</v-btn>
|
|
6
9
|
<v-icon>mdi-calendar-month</v-icon>
|
|
7
|
-
<v-btn icon x-small
|
|
10
|
+
<v-btn icon x-small :disabled="!hasNext" style="margin-left: 8px;" @click="switchDate(1)">
|
|
11
|
+
<v-icon>mdi-fast-forward</v-icon>
|
|
12
|
+
</v-btn>
|
|
13
|
+
<v-btn icon x-small :disabled="!nextAvailable" style="margin-left: 4px;" @click="goToNextAvailable(1)">
|
|
8
14
|
<v-icon>mdi-skip-next</v-icon>
|
|
9
15
|
</v-btn>
|
|
10
16
|
</div>
|
|
11
17
|
</template>
|
|
12
18
|
|
|
13
19
|
<script>
|
|
14
|
-
|
|
15
|
-
name: 'date-switcher',
|
|
20
|
+
import Plugin from '../../plugin.js'
|
|
16
21
|
|
|
22
|
+
export default {
|
|
17
23
|
props: {
|
|
18
|
-
date
|
|
19
|
-
type
|
|
24
|
+
date: {
|
|
25
|
+
type: [String, Date],
|
|
26
|
+
default: null
|
|
27
|
+
},
|
|
28
|
+
heatmapKey: {
|
|
29
|
+
type: String,
|
|
20
30
|
default: null
|
|
21
31
|
}
|
|
22
32
|
},
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
data () {
|
|
34
|
+
return {
|
|
35
|
+
hasNext: false,
|
|
36
|
+
hasPrevious: false,
|
|
37
|
+
nextAvailable: {
|
|
38
|
+
type: Date,
|
|
39
|
+
default: null
|
|
40
|
+
},
|
|
41
|
+
previousAvailable: {
|
|
42
|
+
type: Date,
|
|
43
|
+
default: null
|
|
44
|
+
},
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
computed: {
|
|
48
|
+
cleanedDate() {
|
|
49
|
+
return this.cleanDate(this.date);
|
|
34
50
|
}
|
|
35
51
|
},
|
|
52
|
+
beforeMount () {
|
|
53
|
+
Plugin.EventBus.$on("unidoo-dateswitcher-update", params => {
|
|
54
|
+
if (this.heatmapKey) {
|
|
55
|
+
if (params.key === this.heatmapKey && params.data) {
|
|
56
|
+
this.updateNearDates(params.data);
|
|
57
|
+
}
|
|
58
|
+
} else if (params.data) {
|
|
59
|
+
this.updateNearDates(params.data);
|
|
60
|
+
} else {
|
|
61
|
+
this.reset();
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
},
|
|
65
|
+
|
|
66
|
+
mounted () {
|
|
67
|
+
this.$unidooHeatmap.getDate(this.heatmapKey);
|
|
68
|
+
},
|
|
36
69
|
|
|
37
70
|
methods: {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
71
|
+
reset() {
|
|
72
|
+
this.hasNext = false
|
|
73
|
+
this.hasPrevious = false
|
|
74
|
+
this.nextAvailable = null
|
|
75
|
+
this.previousAvailable = null
|
|
76
|
+
},
|
|
77
|
+
goToNextAvailable() {
|
|
78
|
+
if (this.hasNext) {
|
|
79
|
+
this.$unidooHeatmap.setDate(this.cleanDate(this.nextAvailable), this.heatmapKey);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
goToPreviousAvailable() {
|
|
84
|
+
if (this.hasPrevious) {
|
|
85
|
+
this.$unidooHeatmap.setDate(this.cleanDate(this.previousAvailable), this.heatmapKey);
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
switchDate(n) {
|
|
90
|
+
if (this.cleanedDate && n) {
|
|
91
|
+
if ((n > 0 && this.hasNext) || (n < 0 && this.hasPrevious)) {
|
|
92
|
+
const newDate = new Date(this.cleanedDate);
|
|
93
|
+
newDate.setDate(this.cleanedDate.getDate() + n);
|
|
94
|
+
this.$unidooHeatmap.setDate(newDate, this.heatmapKey);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
|
|
99
|
+
updateNearDates(data) {
|
|
100
|
+
if (data) {
|
|
101
|
+
this.hasNext = data.hasNext
|
|
102
|
+
this.hasPrevious = data.hasPrevious
|
|
103
|
+
this.nextAvailable = data.nextAvailable
|
|
104
|
+
this.previousAvailable = data.previousAvailable
|
|
43
105
|
}
|
|
106
|
+
},
|
|
107
|
+
|
|
108
|
+
cleanDate(date) {
|
|
109
|
+
if (date) {
|
|
110
|
+
if (date instanceof Date) {
|
|
111
|
+
return date;
|
|
112
|
+
} else if (typeof date === 'string') {
|
|
113
|
+
return new Date(date);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return null;
|
|
44
117
|
}
|
|
45
118
|
}
|
|
46
119
|
}
|
|
@@ -51,9 +124,8 @@ export default {
|
|
|
51
124
|
display: flex;
|
|
52
125
|
align-items: center;
|
|
53
126
|
padding: 1px;
|
|
127
|
+
width: fit-content;
|
|
54
128
|
background: rgb(245,245,245);
|
|
55
129
|
border-radius: 5px;
|
|
56
130
|
}
|
|
57
|
-
</style>
|
|
58
|
-
|
|
59
|
-
|
|
131
|
+
</style>
|
package/src/plugin.js
CHANGED
|
@@ -154,6 +154,16 @@ function install(Vue) {
|
|
|
154
154
|
setDate(date, key) {
|
|
155
155
|
plugin.EventBus.$emit("unidoo-heatmap-set-date", { date: date, key: key })
|
|
156
156
|
},
|
|
157
|
+
|
|
158
|
+
getDate(key) {
|
|
159
|
+
plugin.EventBus.$emit("unidoo-heatmap-get-date", { key: key })
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
Vue.prototype.$unidooDateSwitcher = {
|
|
164
|
+
update(data, key) {
|
|
165
|
+
plugin.EventBus.$emit("unidoo-dateswitcher-update", { data: data, key: key })
|
|
166
|
+
},
|
|
157
167
|
}
|
|
158
168
|
}
|
|
159
169
|
|