[DEV-108] Change component to select date ranges (#1216)

Update console for better API request/response logs

Add some logs

Remove dateRange and make period select work

Fix package files

Fix stats path

WIP

Fix stats for single staff members

Remove logger
This commit is contained in:
Maximiliano Redigonda 2022-06-01 07:08:36 -03:00 committed by GitHub
parent 8c732f5dda
commit 82fd54ffd9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 149 additions and 110 deletions

View File

@ -14765,10 +14765,10 @@
"integrity": "sha1-zcvAgYgmWtEZtqWnyKtw7s+10n0=",
"optional": true,
"requires": {
"chalk": "1.1.3",
"commander": "2.9.0",
"is-my-json-valid": "2.15.0",
"pinkie-promise": "2.0.1"
"chalk": "^1.1.1",
"commander": "^2.9.0",
"is-my-json-valid": "^2.12.4",
"pinkie-promise": "^2.0.0"
}
},
"has-ansi": {
@ -15116,26 +15116,26 @@
"integrity": "sha1-Tf5b9r6LjNw3/Pk+BLZVd3InEN4=",
"optional": true,
"requires": {
"aws-sign2": "0.6.0",
"aws4": "1.6.0",
"caseless": "0.11.0",
"combined-stream": "1.0.5",
"extend": "3.0.0",
"forever-agent": "0.6.1",
"form-data": "2.1.2",
"har-validator": "2.0.6",
"hawk": "3.1.3",
"http-signature": "1.1.1",
"is-typedarray": "1.0.0",
"isstream": "0.1.2",
"json-stringify-safe": "5.0.1",
"mime-types": "2.1.14",
"oauth-sign": "0.8.2",
"qs": "6.3.1",
"stringstream": "0.0.5",
"tough-cookie": "2.3.2",
"tunnel-agent": "0.4.3",
"uuid": "3.0.1"
"aws-sign2": "~0.6.0",
"aws4": "^1.2.1",
"caseless": "~0.11.0",
"combined-stream": "~1.0.5",
"extend": "~3.0.0",
"forever-agent": "~0.6.1",
"form-data": "~2.1.1",
"har-validator": "~2.0.6",
"hawk": "~3.1.3",
"http-signature": "~1.1.0",
"is-typedarray": "~1.0.0",
"isstream": "~0.1.2",
"json-stringify-safe": "~5.0.1",
"mime-types": "~2.1.7",
"oauth-sign": "~0.8.1",
"qs": "~6.3.0",
"stringstream": "~0.0.4",
"tough-cookie": "~2.3.0",
"tunnel-agent": "~0.4.1",
"uuid": "^3.0.0"
}
},
"rimraf": {

View File

@ -29,7 +29,7 @@ export default {
}
},
changeFilters(listConfig) {
const filtersForAPI = searchTicketsUtils.prepareFiltersForAPI(listConfig.filters);
const filtersForAPI = searchTicketsUtils.getFiltersForAPI(listConfig.filters);
return {
type: 'SEARCH_FILTERS_CHANGE_FILTERS',
@ -49,7 +49,7 @@ export default {
}
},
changePage(filtersWithPage) {
const filtersForAPI = searchTicketsUtils.prepareFiltersForAPI(filtersWithPage);
const filtersForAPI = searchTicketsUtils.getFiltersForAPI(filtersWithPage);
const currentPath = window.location.pathname;
const urlQuery = searchTicketsUtils.getFiltersForURL({
filters: filtersForAPI,
@ -64,7 +64,7 @@ export default {
}
},
changeOrderBy(filtersWithOrderBy) {
const filtersForAPI = searchTicketsUtils.prepareFiltersForAPI(filtersWithOrderBy);
const filtersForAPI = searchTicketsUtils.getFiltersForAPI(filtersWithOrderBy);
const currentPath = window.location.pathname;
const urlQuery = searchTicketsUtils.getFiltersForURL({
filters: filtersForAPI,

View File

@ -49,22 +49,15 @@ class TicketQueryFilters extends React.Component {
<div className="ticket-query-filters__search-box">
<FormField name="query" field="search-box" fieldProps={{onSearch: this.onSubmitListConfig.bind(this)}} />
</div>
<div className="ticket-query-filters__first-row">
<div className="ticket-query-filters__second-row">
<FormField
label={i18n('DATE')}
name="dateRange"
field="date-range"
fieldProps={{defaultValue: formState.dateRange}} />
<FormField
label={i18n('STATUS')}
name="closed"
label={i18n('PERIOD')}
name="period"
field="select"
fieldProps={{
items: this.getStatusItems(),
className: 'ticket-query-filters__status-drop-down'
items: [{content: i18n('LAST_7_DAYS')}, {content: i18n('LAST_30_DAYS')}, {content: i18n('LAST_90_DAYS')}, {content: i18n('LAST_365_DAYS')}],
className: 'ticket-query-filters__drop-down'
}} />
</div>
<div className="ticket-query-filters__second-row">
<FormField
label={i18n('DEPARTMENTS')}
name="departments"
@ -77,6 +70,14 @@ class TicketQueryFilters extends React.Component {
fieldProps={{items: ticketUtils.getStaffList({staffList}, 'toAutocomplete')}} />
</div>
<div className="ticket-query-filters__third-row">
<FormField
label={i18n('STATUS')}
name="closed"
field="select"
fieldProps={{
items: this.getStatusItems(),
className: 'ticket-query-filters__drop-down'
}} />
<FormField
label={i18n('TAGS')}
name="tags"
@ -266,8 +267,8 @@ class TicketQueryFilters extends React.Component {
true
);
if(formEdited && formState.dateRange.valid) {
const filtersForAPI = searchTicketsUtils.prepareFiltersForAPI(listConfigWithCompleteAuthorsList.filters);
if(formEdited) {
const filtersForAPI = searchTicketsUtils.getFiltersForAPI(listConfigWithCompleteAuthorsList.filters);
const currentPath = window.location.pathname;
const urlQuery = searchTicketsUtils.getFiltersForURL({
filters: filtersForAPI,
@ -297,8 +298,6 @@ class TicketQueryFilters extends React.Component {
}
onChangeForm(data) {
const newStartDate = data.dateRange.startDate ? data.dateRange.startDate : searchTicketsUtils.getDefaultLocalStartDate();
const newEndDate = data.dateRange.endDate ? data.dateRange.endDate : searchTicketsUtils.getDefaultlocalEndDate();
const departmentsId = data.departments.map(department => department.id);
const staffsId = data.owners.map(staff => staff.id);
const tagsName = this.tagsNametoTagsId(data.tags);
@ -310,11 +309,6 @@ class TicketQueryFilters extends React.Component {
owners: staffsId,
departments: departmentsId,
authors: authors,
dateRange: {
...data.dateRange,
startDate: newStartDate,
endDate: newEndDate
}
});
}

View File

@ -58,7 +58,7 @@
align-items: flex-start;
}
&__status-drop-down > .drop-down__current-item {
&__drop-down > .drop-down__current-item {
background-color: $very-light-grey;
&:focus {

View File

@ -4,6 +4,7 @@ import { connect } from 'react-redux';
import API from 'lib-app/api-call';
import i18n from 'lib-app/i18n';
import statsUtils from 'lib-app/stats-utils';
import date from 'lib-app/date';
import Header from 'core-components/header';
import Form from 'core-components/form';
@ -18,7 +19,7 @@ class AdminPanelStats extends React.Component {
state = {
loading: true,
rawForm: {
dateRange: statsUtils.getInitialDateRange(),
period: 0,
departments: [],
owners: [],
tags: []
@ -28,7 +29,7 @@ class AdminPanelStats extends React.Component {
componentDidMount() {
statsUtils.retrieveStats({
rawForm: this.state.rawForm,
rawForm: this.getFormWithDateRange(this.state.rawForm),
tags: this.props.tags
}).then(({data}) => {
this.setState({ticketData: data, loading: false});
@ -47,7 +48,7 @@ class AdminPanelStats extends React.Component {
<div className="admin-panel-stats__form__container">
<div className="admin-panel-stats__form__container__row">
<div className="admin-panel-stats__form__container__col">
<FormField name="dateRange" label={i18n('DATE')} field="date-range" fieldProps={{defaultValue: rawForm.dateRange}} />
<FormField name="period" label={i18n('DATE')} field="select" fieldProps={{size: 'large', items: [{content: i18n('LAST_7_DAYS')}, {content: i18n('LAST_30_DAYS')}, {content: i18n('LAST_90_DAYS')}, {content: i18n('LAST_365_DAYS')}]}} />
<FormField name="tags" label={i18n('TAGS')} field="tag-selector" fieldProps={{items: this.getTagItems()}} />
</div>
<div className="admin-panel-stats__form__container__col">
@ -90,7 +91,7 @@ class AdminPanelStats extends React.Component {
event.preventDefault();
this.setState({
rawForm: {
dateRange: statsUtils.getInitialDateRange(),
period: 0,
departments: [],
owners: [],
tags: []
@ -163,7 +164,7 @@ class AdminPanelStats extends React.Component {
onFormSubmit() {
statsUtils.retrieveStats({
rawForm: this.state.rawForm,
rawForm: this.getFormWithDateRange(this.state.rawForm),
tags: this.props.tags
}).then(({data}) => {
this.setState({ticketData: data, loading: false});
@ -171,6 +172,18 @@ class AdminPanelStats extends React.Component {
if (showLogs) console.error('ERROR: ', error);
});
}
getFormWithDateRange(form) {
const {startDate, endDate} = statsUtils.getDateRangeFromPeriod(form.period);
return {
...form,
dateRange: {
startDate,
endDate
}
};
}
}
export default connect((store) => {

View File

@ -59,9 +59,8 @@ class StaffEditor extends React.Component {
showMessage: true,
showReInviteStaffMessage: true,
rawForm: {
dateRange: statsUtils.getInitialDateRange(),
departments: [],
owners: [],
owners: [{id: this.props.staffId}],
tags: []
},
ticketData: {},
@ -84,6 +83,8 @@ class StaffEditor extends React.Component {
}
render() {
console.log('State: ', this.state.rawForm);
const { name, level, profilePic, myAccount, staffId, staffList, userId } = this.props;
const { message, tickets, loadingPicture, email } = this.state;
const myData = _.filter(staffList, {id: `${staffId}`})[0];

View File

@ -30,7 +30,7 @@ export function updateSearchTicketsFromURL() {
const currentSearchParams = queryString.parse(currentSearch);
const showFilters = (currentSearch !== SEARCH_TICKETS_INITIAL_QUERY) && currentSearchParams.custom;
if((showFilters !== undefined) && currentSearchParams.useInitialValues) store.dispatch(searchFiltersActions.changeShowFilters(!showFilters));
if(showFilters !== undefined && currentSearchParams.useInitialValues) store.dispatch(searchFiltersActions.changeShowFilters(!showFilters));
store.dispatch(searchFiltersActions.changeFilters(listConfig));
store.dispatch(searchFiltersActions.retrieveSearchTickets(
@ -38,7 +38,7 @@ export function updateSearchTicketsFromURL() {
...store.getState().searchFilters.ticketQueryListState,
page: (currentSearchParams.page || INITIAL_PAGE)*1
},
searchTicketsUtils.prepareFiltersForAPI(listConfig.filters),
searchTicketsUtils.getFiltersForAPI(listConfig.filters),
currentSearchParams.pageSize
));
});

View File

@ -135,7 +135,7 @@ export default {
'LEVEL_3': 'Nível 3 (Chamados + Artigos + Equipe)',
'LEVEL_1_DESCRIPTION': 'Só pode responder aos chamados e gerenciar os usuários',
'LEVEL_2_DESCRIPTION': 'Pode fazer o que o nível 1 faz e pode criar ou editar artigos e pode criar respostas customizadas.',
'LEVEL_3_DESCRIPTION': 'Pode fazero que o nível 2 faz e pode criar ou editar membros da equipe e pode gerenciar todo o sistema.',
'LEVEL_3_DESCRIPTION': 'Pode fazer o que o nível 2 faz e pode criar ou editar membros da equipe e pode gerenciar todo o sistema.',
'UPDATE_EMAIL': 'Atualizar e-mail',
'UPDATE_PASSWORD': 'Atualizar senha',
'UPDATE_CUSTOM_FIELDS': 'Atualize campos personalizados',

View File

@ -78,6 +78,7 @@ export default {
'OWNER': 'Owner',
'OWNED': 'Owned',
'STATUS': 'Status',
'PERIOD': 'Period',
'NONE': 'None',
'ANY': 'Any',
'OPENED': 'Opened',

View File

@ -24,13 +24,30 @@ function processData (data, dataAsForm = false) {
return newData;
}
const randomString = (length) => {
var result = "";
var characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
var charactersLength = characters.length;
for (var i = 0; i < length; i++) {
result += characters.charAt(Math.floor(Math.random() * charactersLength));
}
return result;
};
module.exports = {
call: function ({path, data, plain, dataAsForm}) {
if(showLogs) console.log('request ' + path, data);
const callId = randomString(3);
const boldStyle = 'font-weight: bold;';
const normalStyle = 'font-weight: normal;';
if (showLogs) {
console.log(`▶ Request %c${path}%c [${callId}]: `, boldStyle, normalStyle, data);
}
return new Promise(function (resolve, reject) {
APIUtils.post(apiRoot + path, processData(data, dataAsForm), dataAsForm)
.then(function (result) {
if(showLogs) console.log(result);
if (showLogs) {
console.log(`▶ Result %c${path}%c [${callId}]: `, boldStyle, normalStyle, result);
}
if (plain || result.status === 'success') {
resolve(result);

View File

@ -4,6 +4,7 @@ import _ from 'lodash';
import DateTransformer from 'lib-core/date-transformer';
import date from 'lib-app/date';
import API from 'lib-app/api-call';
import statsUtils from 'lib-app/stats-utils';
const DEFAULT_UTC_START_DATE = 201701010000;
@ -19,6 +20,15 @@ const CLOSED_DROPDOWN_INDEXES = {
CLOSED: 2
}
const getAuthorsForAPI = (authors) => {
if (authors === undefined) return undefined;
const authorsListFilters = JSON.parse(authors);
if (!authorsListFilters || authorsListFilters.length === 0 || !authorsListFilters[0].name) return undefined;
return JSON.stringify(
authorsListFilters.map(author => ({id: author.id*1, isStaff: author.isStaff}))
);
};
export default {
getAuthorsFromAPI(authors = '') {
return API.call({
@ -72,33 +82,21 @@ export default {
}
}
},
prepareFiltersForAPI(filters){
const authorsListFilters = (filters && filters.authors) ? JSON.parse(filters.authors) : undefined;
let filtersForAPI = (
(authorsListFilters && authorsListFilters.length && authorsListFilters[0].name) ?
{
...filters,
authors: JSON.stringify(
authorsListFilters.map(author => ({id: author.id*1, isStaff: author.isStaff}))
)
} :
filters
);
const dateRange = filtersForAPI.dateRange;
if(filtersForAPI && filtersForAPI.closed !== undefined) {
filtersForAPI = {
...filtersForAPI,
closed: filtersForAPI.closed*1
}
}
filtersForAPI = {
...filtersForAPI,
dateRange: dateRange ? dateRange : this.getDefaultUTCRange()
}
return filtersForAPI ? filtersForAPI : {};
getDateRangeForAPI(period) {
const {startDate, endDate} = statsUtils.getDateRangeFromPeriod(period);
const dateRangeJSON = JSON.stringify([startDate, endDate]);
return dateRangeJSON;
},
getFiltersForAPI(filters) {
if (!filters) filters = {};
const authorsList = getAuthorsForAPI(filters.authors);
const filtersForAPI = {
...filters,
...(filters.closed !== undefined && {closed: filters.closed*1}),
...(authorsList !== undefined && {authors: authorsList}),
...{dateRange: this.getDateRangeForAPI(Number(filters.period) || 0)}
};
return filtersForAPI;
},
getFiltersForURL(filtersWithShouldRemoveParams) {
const shouldRemoveCustomParam = filtersWithShouldRemoveParams.shouldRemoveCustomParam ? filtersWithShouldRemoveParams.shouldRemoveCustomParam : false;
@ -136,7 +134,7 @@ export default {
return `?${query}`;
}
},
getClosedDropdowIndex(status) {
getClosedDropdownIndex(status) {
let closedDropdownIndex;
switch(status) {
@ -153,21 +151,14 @@ export default {
return closedDropdownIndex;
},
transformToFormValue(filters) {
const localDateRange = DateTransformer.rangeTransformer(JSON.parse(filters.dateRange), "UTCToLocal");
const newDateRange = {
valid: true,
startDate: localDateRange[0],
endDate: localDateRange[1],
};
return {
...filters,
query: filters.query ? filters.query : '',
closed: this.getClosedDropdowIndex(filters.closed*1),
closed: this.getClosedDropdownIndex(filters.closed*1),
period: filters.period ? filters.period*1 : 0,
departments: JSON.parse(filters.departments),
owners: JSON.parse(filters.owners),
tags: JSON.parse(filters.tags),
dateRange: newDateRange,
authors: filters.authors ? JSON.parse(filters.authors) : [],
};
},
@ -189,17 +180,16 @@ export default {
},
formValueToListConfig(form, hasAllAuthorsInfo = false) {
const authors = form.authors ? form.authors.map(author => ({id: author.id*1, isStaff: author.isStaff})) : [];
const localRange = [form.dateRange.startDate, form.dateRange.endDate];
return {
filters: {
...form,
query: form.query !== '' ? form.query : undefined,
closed: this.getTicketStatusByDropdownIndex(form.closed),
period: form.period ? form.period*1 : 0,
departments: form.departments !== undefined ? JSON.stringify(form.departments) : '[]',
owners: JSON.stringify(form.owners),
tags: JSON.stringify(form.tags),
dateRange: JSON.stringify(DateTransformer.rangeTransformer(localRange, "localToUTC")),
authors: JSON.stringify(authors),
},
hasAllAuthorsInfo

View File

@ -77,7 +77,7 @@ export default {
startDate: date.getFullDate(firstDayOfMonth),
endDate: date.getFullDate(todayAtNight)
};
} ,
},
getStatsOptions(axis) {
return {
@ -109,13 +109,41 @@ export default {
);
},
retrieveStats({ rawForm, tags, departments}) {
const { startDate, endDate } = rawForm.dateRange;
getDateRangeFromPeriod(periodIndex) {
let daysInPeriod = 0;
switch (periodIndex) {
case 0:
daysInPeriod = 7;
break;
case 1:
daysInPeriod = 30;
break;
case 2:
daysInPeriod = 90;
break;
case 3:
daysInPeriod = 365;
break;
}
const d = new Date();
d.setDate(d.getDate() - daysInPeriod);
const startDate = date.getFullDate(d);
const endDate = date.getCurrentFullDate();
return {
startDate,
endDate
};
},
retrieveStats({ rawForm, tags, departments}) {
const { dateRange } = rawForm;
const dateRangeProp = dateRange && {dateRange: "[" + dateRange.startDate.toString() + "," + dateRange.endDate.toString() + "]"};
return API.call({
path: '/system/get-stats',
data: {
dateRange: "[" + startDate.toString() + "," + endDate.toString() + "]",
...dateRangeProp,
departments: departments ? JSON.stringify(departments) : "[" + rawForm.departments.map(department => department.id) + "]",
owners: "[" + rawForm.owners.map(owner => owner.id) + "]",
tags: tags ? "[" + this.getSelectedTagIds(rawForm, tags) + "]" : "[]"

View File

@ -11,7 +11,6 @@ const DEFAULT_FILTERS = {
departments: '[]',
owners: '[]',
tags: '[]',
dateRange: searchTicketsUtils.getDefaultUTCRange(),
orderBy: undefined,
authors: '[]',
};
@ -30,11 +29,7 @@ class searchFiltersReducer extends Reducer {
owners: [],
tags: [],
authors: [],
dateRange: {
valid: true,
startDate: searchTicketsUtils.getDefaultLocalStartDate(),
endDate: searchTicketsUtils.getDefaultlocalEndDate()
}
period: 0
},
ticketQueryListState : {
tickets: [],