@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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sedoo/unidoo",
3
- "version": "0.0.60",
3
+ "version": "0.0.64",
4
4
  "private": false,
5
5
  "scripts": {
6
6
  "build": "vue-cli-service build --target lib --name unidoo src/plugin.js",
@@ -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 instanceof Date) ? d : (new 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 !== this.year) {
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 && params.key === 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 style="margin-right: 5px;" @click="switchDate(-1)">
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 style="margin-left: 5px;" @click="switchDate(1)">
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
- export default {
15
- name: 'date-switcher',
20
+ import Plugin from '../../plugin.js'
16
21
 
22
+ export default {
17
23
  props: {
18
- date : {
19
- type : [String, Date],
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
- computed:{
25
- cleanedDate(){
26
- if(this.date){
27
- if(typeof this.date === 'date'){
28
- return date;
29
- } else if(typeof this.date === 'string'){
30
- return new Date(this.date);
31
- }
32
- }
33
- return null;
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
- switchDate(n){
39
- if(this.cleanedDate && n){
40
- let newDate = new Date(this.cleanedDate);
41
- newDate.setDate(this.cleanedDate.getDate() + n);
42
- this.$unidooHeatmap.setDate(newDate);
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