Adds start year input to report charts #483
This commit is contained in:
parent
52dd5b6485
commit
c565f0a0cb
|
@ -34,7 +34,8 @@
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
flex-wrap: wrap; }
|
flex-wrap: wrap; }
|
||||||
#tainacan-reports-app .postbox .box-header .box-header__item {
|
#tainacan-reports-app .postbox .box-header .box-header__item {
|
||||||
margin-bottom: 10px; }
|
margin-bottom: 10px;
|
||||||
|
line-height: 2rem; }
|
||||||
#tainacan-reports-app .graph-mode-switch {
|
#tainacan-reports-app .graph-mode-switch {
|
||||||
display: inline-block; }
|
display: inline-block; }
|
||||||
#tainacan-reports-app .graph-mode-switch button {
|
#tainacan-reports-app .graph-mode-switch button {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"version": 3,
|
"version": 3,
|
||||||
"mappings": "AAAA,qBAAsB;EAClB,OAAO,EAAE,iBAAiB;EAC1B,MAAM,EAAE,CAAC;EAGT,4CAAuB;IACnB,OAAO,EAAE,GAAG;EAGhB,6BAAQ;IACJ,MAAM,EAAE,OAAO;EAGnB,wCAAmB;IACf,aAAa,EAAE,IAAI;EAGvB,8BAAS;IACL,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,MAAM;IAEvB,sCAAQ;MACJ,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,CAAC;MAEV,+CAAS;QACL,MAAM,EAAE,OAAO;EAK3B,8BAAS;IACL,OAAO,EAAE,gBAAgB;IACzB,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,oCAAoC;IAEtD,oCAAM;MACF,WAAW,EAAE,IAAI;MACjB,SAAS,EAAE,QAAQ;IAEvB,wDAA4B;MACxB,MAAM,EAAE,iCAAiC;MACzC,UAAU,EAAE,IAAI;IAGpB,0CAAY;MACR,OAAO,EAAE,IAAI;MACb,WAAW,EAAE,QAAQ;MACrB,eAAe,EAAE,aAAa;MAC9B,SAAS,EAAE,IAAI;MAEf,4DAAkB;QACd,aAAa,EAAE,IAAI;EAI/B,wCAAmB;IACf,OAAO,EAAE,YAAY;IACrB,+CAAO;MACH,MAAM,EAAE,eAAe;MACvB,UAAU,EAAE,eAAe;MAC3B,UAAU,EAAE,eAAe;MAC3B,OAAO,EAAE,CAAC;MACV,MAAM,EAAE,OAAO;MAEf,uDAAU;QACN,KAAK,EAAE,oCAAoC",
|
"mappings": "AAAA,qBAAsB;EAClB,OAAO,EAAE,iBAAiB;EAC1B,MAAM,EAAE,CAAC;EAGT,4CAAuB;IACnB,OAAO,EAAE,GAAG;EAGhB,6BAAQ;IACJ,MAAM,EAAE,OAAO;EAGnB,wCAAmB;IACf,aAAa,EAAE,IAAI;EAGvB,8BAAS;IACL,SAAS,EAAE,IAAI;IACf,WAAW,EAAE,UAAU;IACvB,eAAe,EAAE,MAAM;IAEvB,sCAAQ;MACJ,SAAS,EAAE,IAAI;MACf,OAAO,EAAE,CAAC;MAEV,+CAAS;QACL,MAAM,EAAE,OAAO;EAK3B,8BAAS;IACL,OAAO,EAAE,gBAAgB;IACzB,aAAa,EAAE,CAAC;IAChB,MAAM,EAAE,IAAI;IACZ,UAAU,EAAE,KAAK;IACjB,gBAAgB,EAAE,oCAAoC;IAEtD,oCAAM;MACF,WAAW,EAAE,IAAI;MACjB,SAAS,EAAE,QAAQ;IAEvB,wDAA4B;MACxB,MAAM,EAAE,iCAAiC;MACzC,UAAU,EAAE,IAAI;IAGpB,0CAAY;MACR,OAAO,EAAE,IAAI;MACb,WAAW,EAAE,QAAQ;MACrB,eAAe,EAAE,aAAa;MAC9B,SAAS,EAAE,IAAI;MAEf,4DAAkB;QACd,aAAa,EAAE,IAAI;QACnB,WAAW,EAAE,IAAI;EAI7B,wCAAmB;IACf,OAAO,EAAE,YAAY;IACrB,+CAAO;MACH,MAAM,EAAE,eAAe;MACvB,UAAU,EAAE,eAAe;MAC3B,UAAU,EAAE,eAAe;MAC3B,OAAO,EAAE,CAAC;MACV,MAAM,EAAE,OAAO;MAEf,uDAAU;QACN,KAAK,EAAE,oCAAoC",
|
||||||
"sources": ["../../views/reports/tainacan-reports.scss"],
|
"sources": ["../../views/reports/tainacan-reports.scss"],
|
||||||
"names": [],
|
"names": [],
|
||||||
"file": "tainacan-reports.css"
|
"file": "tainacan-reports.css"
|
||||||
|
|
|
@ -111,14 +111,20 @@ export const fetchTaxonomyTerms = ({ commit }, taxonomyId) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
export const fetchActivities = ({ commit }, { collectionId } ) => {
|
export const fetchActivities = ({ commit }, { collectionId, startDate, force } ) => {
|
||||||
|
|
||||||
let endpoint = '/reports';
|
let endpoint = '/reports';
|
||||||
|
|
||||||
if (collectionId && collectionId != 'default')
|
if (collectionId && collectionId != 'default')
|
||||||
endpoint += '/collection/' + collectionId + '/activities';
|
endpoint += '/collection/' + collectionId + '/activities?';
|
||||||
else
|
else
|
||||||
endpoint += '/activities';
|
endpoint += '/activities?';
|
||||||
|
|
||||||
|
if (startDate)
|
||||||
|
endpoint += '&start=' + startDate;
|
||||||
|
|
||||||
|
if (startDate || force)
|
||||||
|
endpoint += '&force=yes';
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
axios.tainacan.get(endpoint)
|
axios.tainacan.get(endpoint)
|
||||||
|
|
|
@ -1,48 +1,87 @@
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<div
|
<div
|
||||||
v-if="!isFetchingData && chartData && !isBuildingChart && !isFetchingUsers"
|
:class="{ 'skeleton': isFetchingData || !chartData || isBuildingChart || isFetchingUsers }"
|
||||||
class="postbox">
|
class="postbox">
|
||||||
<div class="users-charts columns is-multiline">
|
<div class="box-header">
|
||||||
<div
|
<div
|
||||||
class="users-charts__card column is-one-third is-half-desktop"
|
v-if="currentStart && currentEnd"
|
||||||
v-for="(chartSeries, index) of chartSeriesByUser"
|
class="box-header__item tablenav-pages">
|
||||||
:key="index">
|
<label>
|
||||||
<div
|
{{ $i18n.get('label_activities_last_year') }}
|
||||||
v-if="chartSeries[0].userId == 0"
|
</label>
|
||||||
class="users-charts__card--header">
|
<span class="pagination-links">
|
||||||
<div class="anonymous-user-avatar" />
|
<span
|
||||||
<div class="users-charts__card--header-text">
|
@click="(!isBuildingChart && currentStart.getFullYear() > minYear) ? decreaseYear() : null"
|
||||||
<p>{{ $i18n.get('label_anonymous_user') }}</p>
|
:class="{'tablenav-pages-navspan disabled' : isBuildingChart || currentStart.getFullYear() <= minYear}"
|
||||||
<span>{{ chartSeries[0].total }}</span>
|
class="prev-page button"
|
||||||
</div>
|
aria-hidden="true">
|
||||||
</div>
|
‹
|
||||||
<div
|
</span>
|
||||||
v-if="chartSeries[0].userId != 0 && users[chartSeries[0].userId]"
|
<input
|
||||||
class="users-charts__card--header">
|
type="number"
|
||||||
<img :src="users[chartSeries[0].userId].avatar_urls['48']">
|
step="1"
|
||||||
<div class="users-charts__card--header-text">
|
:min="minYear"
|
||||||
<p>{{ users[chartSeries[0].userId].name }}</p>
|
:max="maxYear"
|
||||||
<span>{{ chartSeries[0].total }}</span>
|
class="screen-per-page"
|
||||||
</div>
|
name="start_year"
|
||||||
</div>
|
id="start_year"
|
||||||
<apexchart
|
maxlength="6"
|
||||||
type="area"
|
:disabled="isBuildingChart"
|
||||||
height="160"
|
:value="currentStart.getFullYear()"
|
||||||
:series="chartSeries"
|
@input="($event) => setStartYear($event.target.value)">
|
||||||
:options="chartOptionsByUser[index]" />
|
<span
|
||||||
|
@click="(!isBuildingChart && currentStart.getFullYear() <= maxYear) ? increaseYear() : null"
|
||||||
|
:class="{ 'tablenav-pages-navspan disabled': isBuildingChart || currentStart.getFullYear() > maxYear}"
|
||||||
|
aria-hidden="true"
|
||||||
|
class="next-page button">
|
||||||
|
›
|
||||||
|
</span>
|
||||||
|
<span class="paging-input">
|
||||||
|
{{ currentStart.toDateString() }} - {{ currentEnd.toDateString() }}
|
||||||
|
</span>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<apexchart
|
<template v-if="!isFetchingData && chartData && !isBuildingChart && !isFetchingUsers">
|
||||||
type="area"
|
<div class="users-charts columns is-multiline">
|
||||||
height="200"
|
<div
|
||||||
:series="chartSeries"
|
class="users-charts__card column is-one-third is-half-desktop"
|
||||||
:options="chartOptions" />
|
v-for="(chartSeries, index) of chartSeriesByUser"
|
||||||
|
:key="index">
|
||||||
|
<div
|
||||||
|
v-if="chartSeries[0].userId == 0"
|
||||||
|
class="users-charts__card--header">
|
||||||
|
<div class="anonymous-user-avatar" />
|
||||||
|
<div class="users-charts__card--header-text">
|
||||||
|
<p>{{ $i18n.get('label_anonymous_user') }}</p>
|
||||||
|
<span>{{ chartSeries[0].total }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-if="chartSeries[0].userId != 0 && users[chartSeries[0].userId]"
|
||||||
|
class="users-charts__card--header">
|
||||||
|
<img :src="users[chartSeries[0].userId].avatar_urls['48']">
|
||||||
|
<div class="users-charts__card--header-text">
|
||||||
|
<p>{{ users[chartSeries[0].userId].name }}</p>
|
||||||
|
<span>{{ chartSeries[0].total }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<apexchart
|
||||||
|
type="area"
|
||||||
|
height="160"
|
||||||
|
:series="chartSeries"
|
||||||
|
:options="chartOptionsByUser[index]" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<apexchart
|
||||||
|
type="area"
|
||||||
|
height="200"
|
||||||
|
:series="chartSeries"
|
||||||
|
:options="chartOptions" />
|
||||||
|
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
style="min-height=740px"
|
|
||||||
class="skeleton postbox" />
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -57,7 +96,11 @@ export default {
|
||||||
isFetchingUsers: false,
|
isFetchingUsers: false,
|
||||||
users: {},
|
users: {},
|
||||||
chartSeriesByUser: [],
|
chartSeriesByUser: [],
|
||||||
chartOptionsByUser: []
|
chartOptionsByUser: [],
|
||||||
|
maxYear: new Date().getFullYear() + 1,
|
||||||
|
minYear: 2018,
|
||||||
|
currentStart: '',
|
||||||
|
currentEnd: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -72,7 +115,7 @@ export default {
|
||||||
this.buildActivitiesChart();
|
this.buildActivitiesChart();
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.isFetchingUsers = true;
|
this.isFetchingUsers = true;
|
||||||
|
@ -91,16 +134,33 @@ export default {
|
||||||
...mapActions('activity', {
|
...mapActions('activity', {
|
||||||
fetchUsers: 'fetchUsers',
|
fetchUsers: 'fetchUsers',
|
||||||
}),
|
}),
|
||||||
|
increaseYear() {
|
||||||
|
this.setStartYear(this.currentEnd.getFullYear());
|
||||||
|
},
|
||||||
|
decreaseYear() {
|
||||||
|
let currentStartDate = new Date(this.currentStart.getTime());
|
||||||
|
this.setStartYear(new Date(currentStartDate.setFullYear(currentStartDate.getFullYear() - 1)).getFullYear());
|
||||||
|
},
|
||||||
|
setStartYear(newStartYear) {
|
||||||
|
let currentStartDate = new Date(this.currentStart.getTime());
|
||||||
|
const newStart = new Date(currentStartDate.setFullYear(newStartYear));
|
||||||
|
|
||||||
|
this.$emit('time-range-update', newStart.toISOString());
|
||||||
|
},
|
||||||
buildActivitiesChart() {
|
buildActivitiesChart() {
|
||||||
this.isBuildingChart = true;
|
this.isBuildingChart = true;
|
||||||
|
|
||||||
const daysWithActivities = (this.chartData.totals.by_interval && this.chartData.totals.by_interval.general) ? this.chartData.totals.by_interval.general : [];
|
const daysWithActivities = (this.chartData.totals.by_interval && this.chartData.totals.by_interval.general) ? this.chartData.totals.by_interval.general : [];
|
||||||
const startDate = new Date(this.chartData.totals.by_interval.start).getTime();
|
this.currentStart = new Date(this.chartData.totals.by_interval.start);
|
||||||
const endDate = new Date(this.chartData.totals.by_interval.end).getTime();
|
this.currentEnd = new Date(this.chartData.totals.by_interval.end);
|
||||||
|
|
||||||
this.chartSeries = [{
|
if (daysWithActivities.length)
|
||||||
data: []
|
this.chartSeries = [{
|
||||||
}];
|
name: this.$i18n.get('activities'),
|
||||||
|
data: []
|
||||||
|
}];
|
||||||
|
else
|
||||||
|
this.chartSeries = [];
|
||||||
|
|
||||||
let maximumOfActivitiesInADay = 0;
|
let maximumOfActivitiesInADay = 0;
|
||||||
daysWithActivities.forEach((activity) => {
|
daysWithActivities.forEach((activity) => {
|
||||||
|
@ -115,7 +175,10 @@ export default {
|
||||||
this.chartOptions = {
|
this.chartOptions = {
|
||||||
...this.areaChartOptions,
|
...this.areaChartOptions,
|
||||||
title: {
|
title: {
|
||||||
text: this.$i18n.get('label_activities_last_year')
|
text: ''
|
||||||
|
},
|
||||||
|
noData: {
|
||||||
|
text: daysWithActivities.length ? this.$i18n.get('label_loading_report') : this.$i18n.get('info_no_activities')
|
||||||
},
|
},
|
||||||
chart: {
|
chart: {
|
||||||
id: 'generalchart',
|
id: 'generalchart',
|
||||||
|
@ -136,10 +199,11 @@ export default {
|
||||||
},
|
},
|
||||||
xaxis: {
|
xaxis: {
|
||||||
type: 'datetime',
|
type: 'datetime',
|
||||||
min: startDate,
|
min: this.currentStart.getTime(),
|
||||||
max: endDate
|
max: this.currentEnd.getTime()
|
||||||
},
|
},
|
||||||
yaxis: {
|
yaxis: {
|
||||||
|
show: daysWithActivities.length,
|
||||||
max: maximumOfActivitiesInADay,
|
max: maximumOfActivitiesInADay,
|
||||||
tickAmount: 4,
|
tickAmount: 4,
|
||||||
labels: {
|
labels: {
|
||||||
|
@ -148,9 +212,11 @@ export default {
|
||||||
},
|
},
|
||||||
colors: ['#01295c'],
|
colors: ['#01295c'],
|
||||||
};
|
};
|
||||||
|
console.log(this.chartSeries, this.chartOptions, this.currentStart, this.currentEnd);
|
||||||
const daysWithActivitiesByUser = JSON.parse(JSON.stringify(this.chartData.totals.by_interval.by_user)).sort((a, b) => parseInt(b.total) - parseInt(a.total));
|
const daysWithActivitiesByUser = JSON.parse(JSON.stringify(this.chartData.totals.by_interval.by_user)).sort((a, b) => parseInt(b.total) - parseInt(a.total));
|
||||||
|
|
||||||
|
this.chartSeriesByUser = [];
|
||||||
|
this.chartOptionsByUser = []
|
||||||
daysWithActivitiesByUser.forEach((daysWithActivityByUser) => {
|
daysWithActivitiesByUser.forEach((daysWithActivityByUser) => {
|
||||||
this.chartSeriesByUser.push([{
|
this.chartSeriesByUser.push([{
|
||||||
total: daysWithActivityByUser.total,
|
total: daysWithActivityByUser.total,
|
||||||
|
@ -186,8 +252,8 @@ export default {
|
||||||
},
|
},
|
||||||
xaxis: {
|
xaxis: {
|
||||||
type: 'datetime',
|
type: 'datetime',
|
||||||
min: startDate,
|
min: this.currentStart.getTime(),
|
||||||
max: endDate
|
max: this.currentEnd.getTime()
|
||||||
},
|
},
|
||||||
yaxis: {
|
yaxis: {
|
||||||
max: maximumOfActivitiesInADay,
|
max: maximumOfActivitiesInADay,
|
||||||
|
@ -208,9 +274,16 @@ export default {
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.postbox {
|
.postbox {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column-reverse;
|
flex-direction: column;
|
||||||
|
justify-content: flex-start;
|
||||||
|
min-height: 280px !important;
|
||||||
|
|
||||||
|
.screen-per-page {
|
||||||
|
width: 6em;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.users-charts {
|
.users-charts {
|
||||||
|
order: 3;
|
||||||
padding: 12px;
|
padding: 12px;
|
||||||
|
|
||||||
.users-charts__card {
|
.users-charts__card {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<div v-if="taxonomiesList != undefined">
|
<div v-if="taxonomiesList != undefined">
|
||||||
<div class="postbox">
|
<div
|
||||||
|
:class="{ 'skeleton': isFetchingData || isBuildingChart || isFetchingTaxonomyTerms || !selectedTaxonomy || !selectedTaxonomy.id }"
|
||||||
|
class="postbox">
|
||||||
<div class="box-header">
|
<div class="box-header">
|
||||||
<div class="box-header__item">
|
<div class="box-header__item">
|
||||||
<label
|
<label
|
||||||
|
@ -99,10 +101,6 @@
|
||||||
height="380px"
|
height="380px"
|
||||||
:series="chartSeries"
|
:series="chartSeries"
|
||||||
:options="chartOptions" />
|
:options="chartOptions" />
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
style="min-height=380px"
|
|
||||||
class="skeleton postbox" />
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -85,17 +85,11 @@
|
||||||
:chart-data="metadata"
|
:chart-data="metadata"
|
||||||
:is-fetching-data="isFetchingMetadata"
|
:is-fetching-data="isFetchingMetadata"
|
||||||
v-if="!isRepositoryLevel"/>
|
v-if="!isRepositoryLevel"/>
|
||||||
</div>
|
|
||||||
<div class="columns">
|
|
||||||
<metadata-list-block
|
|
||||||
class="column is-full"
|
|
||||||
:chart-data="metadataList"
|
|
||||||
v-if="!isRepositoryLevel" />
|
|
||||||
<activities-block
|
<activities-block
|
||||||
class="column is-full"
|
class="column is-full"
|
||||||
:chart-data="activities"
|
:chart-data="activities"
|
||||||
:is-fetching-data="isFetchingActivities"
|
:is-fetching-data="isFetchingActivities"
|
||||||
v-if="isRepositoryLevel" />
|
@time-range-update="loadActivities" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -141,10 +135,10 @@ export default {
|
||||||
this.loadMetadata();
|
this.loadMetadata();
|
||||||
this.loadActivities();
|
this.loadActivities();
|
||||||
|
|
||||||
if (this.isRepositoryLevel)
|
if (this.isRepositoryLevel) {
|
||||||
this.loadCollectionsList();
|
this.loadCollectionsList();
|
||||||
this.loadTaxonomiesList();
|
this.loadTaxonomiesList();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
immediate: true
|
immediate: true
|
||||||
}
|
}
|
||||||
|
@ -197,9 +191,9 @@ export default {
|
||||||
.then(() => this.isFetchingTaxonomiesList = false)
|
.then(() => this.isFetchingTaxonomiesList = false)
|
||||||
.catch(() => this.isFetchingTaxonomiesList = false);
|
.catch(() => this.isFetchingTaxonomiesList = false);
|
||||||
},
|
},
|
||||||
loadActivities() {
|
loadActivities(startDate) {
|
||||||
this.isFetchingActivities = true;
|
this.isFetchingActivities = true;
|
||||||
this.fetchActivities({ collectionId: this.selectedCollection })
|
this.fetchActivities({ collectionId: this.selectedCollection, startDate: startDate })
|
||||||
.then(() => this.isFetchingActivities = false)
|
.then(() => this.isFetchingActivities = false)
|
||||||
.catch(() => this.isFetchingActivities = false);
|
.catch(() => this.isFetchingActivities = false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
|
|
||||||
.box-header__item {
|
.box-header__item {
|
||||||
margin-bottom: 10px;
|
margin-bottom: 10px;
|
||||||
|
line-height: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue