forgejo/web_src/js/components/ActivityHeatmap.vue
silverwind e88218f4be
Fix heatmap first color being unused (#22158)
Backport #22157. vue3-calendar-heatmap has the behaviour that the first
and second colors are mapped to values null and 0, meaning the second
color was not used as intended for values > 0. I think this is a
behaviour change from previous vue2 version that was missed during the
upgrade.

This change makes first and second values the same, so the heatmap can
now use one additional color for meaningful values.
2022-12-18 15:18:07 +02:00

80 lines
2.1 KiB
Vue

<template>
<div id="user-heatmap">
<div class="total-contributions">
{{ sum }} contributions in the last 12 months
</div>
<calendar-heatmap
:locale="locale"
:no-data-text="locale.no_contributions"
:tooltip-unit="locale.contributions"
:end-date="endDate"
:values="values"
:range-color="colorRange"
@day-click="handleDayClick($event)"
/>
</div>
</template>
<script>
import {CalendarHeatmap} from 'vue3-calendar-heatmap';
export default {
name: 'ActivityHeatmap',
components: {CalendarHeatmap},
props: {
values: {
type: Array,
default: () => [],
},
},
data: () => ({
colorRange: [
'var(--color-secondary-alpha-70)',
'var(--color-secondary-alpha-70)',
'var(--color-primary-light-4)',
'var(--color-primary-light-2)',
'var(--color-primary)',
'var(--color-primary-dark-2)',
'var(--color-primary-dark-4)',
],
endDate: new Date(),
locale: {
contributions: 'contributions',
no_contributions: 'No contributions',
},
}),
computed: {
sum() {
let s = 0;
for (let i = 0; i < this.values.length; i++) {
s += this.values[i].count;
}
return s;
}
},
mounted() {
// work around issue with first legend color being rendered twice and legend cut off
const legend = document.querySelector('.vch__external-legend-wrapper');
legend.setAttribute('viewBox', '12 0 80 10');
legend.style.marginRight = '-12px';
},
methods: {
handleDayClick(e) {
// Reset filter if same date is clicked
const params = new URLSearchParams(document.location.search);
const queryDate = params.get('date');
// Timezone has to be stripped because toISOString() converts to UTC
const clickedDate = new Date(e.date - (e.date.getTimezoneOffset() * 60000)).toISOString().substring(0, 10);
if (queryDate && queryDate === clickedDate) {
params.delete('date');
} else {
params.set('date', clickedDate);
}
const newSearch = params.toString();
window.location.search = newSearch.length ? `?${newSearch}` : '';
}
},
};
</script>