diff --git a/client/package-lock.json b/client/package-lock.json index a7ff0597..496b589b 100644 --- a/client/package-lock.json +++ b/client/package-lock.json @@ -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": { diff --git a/client/src/actions/search-filters-actions.js b/client/src/actions/search-filters-actions.js index 4c4d01bb..7a0a98ff 100644 --- a/client/src/actions/search-filters-actions.js +++ b/client/src/actions/search-filters-actions.js @@ -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, diff --git a/client/src/app-components/ticket-query-filters.js b/client/src/app-components/ticket-query-filters.js index 63fabb93..139634d2 100644 --- a/client/src/app-components/ticket-query-filters.js +++ b/client/src/app-components/ticket-query-filters.js @@ -49,22 +49,15 @@ class TicketQueryFilters extends React.Component {
-
+
- -
-
+ 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 - } }); } diff --git a/client/src/app-components/ticket-query-filters.scss b/client/src/app-components/ticket-query-filters.scss index a30e226e..9e0fd497 100644 --- a/client/src/app-components/ticket-query-filters.scss +++ b/client/src/app-components/ticket-query-filters.scss @@ -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 { diff --git a/client/src/app/admin/panel/dashboard/admin-panel-stats.js b/client/src/app/admin/panel/dashboard/admin-panel-stats.js index c4450c81..35b2d414 100644 --- a/client/src/app/admin/panel/dashboard/admin-panel-stats.js +++ b/client/src/app/admin/panel/dashboard/admin-panel-stats.js @@ -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 {
- +
@@ -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) => { diff --git a/client/src/app/admin/panel/staff/staff-editor.js b/client/src/app/admin/panel/staff/staff-editor.js index 20286c0d..0d6d30cf 100644 --- a/client/src/app/admin/panel/staff/staff-editor.js +++ b/client/src/app/admin/panel/staff/staff-editor.js @@ -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]; diff --git a/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js b/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js index c6700633..34ef83c8 100644 --- a/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js +++ b/client/src/app/admin/panel/tickets/admin-panel-search-tickets.js @@ -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 )); }); diff --git a/client/src/data/languages/br.js b/client/src/data/languages/br.js index ba0cb35e..cb81a127 100644 --- a/client/src/data/languages/br.js +++ b/client/src/data/languages/br.js @@ -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', diff --git a/client/src/data/languages/en.js b/client/src/data/languages/en.js index 560010cb..65195a0f 100644 --- a/client/src/data/languages/en.js +++ b/client/src/data/languages/en.js @@ -78,6 +78,7 @@ export default { 'OWNER': 'Owner', 'OWNED': 'Owned', 'STATUS': 'Status', + 'PERIOD': 'Period', 'NONE': 'None', 'ANY': 'Any', 'OPENED': 'Opened', diff --git a/client/src/lib-app/api-call.js b/client/src/lib-app/api-call.js index 2bd7b65c..c440b5f2 100644 --- a/client/src/lib-app/api-call.js +++ b/client/src/lib-app/api-call.js @@ -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); diff --git a/client/src/lib-app/search-tickets-utils.js b/client/src/lib-app/search-tickets-utils.js index ba654769..af49efc3 100644 --- a/client/src/lib-app/search-tickets-utils.js +++ b/client/src/lib-app/search-tickets-utils.js @@ -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 diff --git a/client/src/lib-app/stats-utils.js b/client/src/lib-app/stats-utils.js index b4cbc4fb..e9e35edf 100644 --- a/client/src/lib-app/stats-utils.js +++ b/client/src/lib-app/stats-utils.js @@ -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) + "]" : "[]" diff --git a/client/src/reducers/search-filters-reducer.js b/client/src/reducers/search-filters-reducer.js index d3b943f3..778b5860 100644 --- a/client/src/reducers/search-filters-reducer.js +++ b/client/src/reducers/search-filters-reducer.js @@ -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: [],