diff --git a/src/api/call-forward.js b/src/api/call-forward.js index 2d98b479..282fa718 100644 --- a/src/api/call-forward.js +++ b/src/api/call-forward.js @@ -4,7 +4,7 @@ import Vue from 'vue' import { i18n } from 'src/boot/i18n' import { getJsonBody } from './utils' import { normalizeDestination } from '../filters/number-format' -import { LIST_ALL_ROWS, patchReplaceFull, get, getList } from './common' +import { LIST_ALL_ROWS, patchReplaceFull, get, getList, del } from './common' export function getMappings (id) { return new Promise((resolve, reject) => { @@ -613,36 +613,157 @@ export function convertTimesetToWeekdays (options) { } } -export function loadTimesetTimes (options) { - return new Promise((resolve, reject) => { - Promise.resolve().then(() => { - return getTimesets(options.subscriberId) - }).then((timesets) => { - const times = convertTimesetToWeekdays({ timesets: timesets, timesetName: options.timeset }) - return times - }).then((times) => { - resolve(times) - }).catch((err) => { - reject(err) - }) - }) +function convertToTimes (times) { + return times.reduce((timesConverted, time) => { + const hourParts = time.hour.split('-') + let minuteParts = null + if (time.minute !== null && time.minute !== '') { + minuteParts = time.minute.split('-') + } + if (hourParts.length === 1 && minuteParts === null) { + timesConverted.push({ + from: normalizeTimePart(hourParts[0]) + ':00', + to: normalizeTimePart(hourParts[0]) + ':00', + weekday: parseInt(time.wday) + }) + } else if (hourParts.length === 1 && minuteParts !== null && minuteParts.length === 1) { + timesConverted.push({ + from: normalizeTimePart(hourParts[0]) + ':' + normalizeTimePart(minuteParts[0]), + to: normalizeTimePart(hourParts[0]) + ':' + normalizeTimePart(minuteParts[0]), + weekday: parseInt(time.wday) + }) + } else if (hourParts.length === 1 && minuteParts !== null && minuteParts.length === 2) { + timesConverted.push({ + from: normalizeTimePart(hourParts[0]) + ':' + normalizeTimePart(minuteParts[0]), + to: normalizeTimePart(hourParts[0]) + ':' + normalizeTimePart(minuteParts[1]), + weekday: parseInt(time.wday) + }) + } else if (hourParts.length === 2 && minuteParts === null) { + timesConverted.push({ + from: normalizeTimePart(hourParts[0]) + ':00', + to: normalizeTimePart(hourParts[1]) + ':00', + weekday: parseInt(time.wday) + }) + } else if (hourParts.length === 2 && minuteParts !== null && minuteParts.length === 1) { + timesConverted.push({ + from: normalizeTimePart(hourParts[0]) + ':' + normalizeTimePart(minuteParts[0]), + to: normalizeTimePart(hourParts[1]) + ':' + normalizeTimePart(minuteParts[0]), + weekday: parseInt(time.wday) + }) + } else if (hourParts.length === 2 && minuteParts !== null && minuteParts.length === 2) { + timesConverted.push({ + from: normalizeTimePart(hourParts[0]) + ':' + normalizeTimePart(minuteParts[0]), + to: normalizeTimePart(hourParts[1]) + ':' + normalizeTimePart(minuteParts[1]), + weekday: parseInt(time.wday) + }) + } else if (hourParts.length === 2 && minuteParts !== null && minuteParts.length === 2) { + timesConverted.push({ + from: normalizeTimePart(hourParts[0]) + ':' + normalizeTimePart(minuteParts[0]), + to: normalizeTimePart(hourParts[1]) + ':' + normalizeTimePart(minuteParts[1]), + weekday: parseInt(time.wday) + }) + } + return timesConverted + }, []) } -export function deleteTimeFromTimeset (options) { - const headers = { - 'Content-Type': 'application/json-patch+json' +function normalizeTimePart (part) { + if (part.length === 1) { + return '0' + part + } else { + return part } - return new Promise((resolve, reject) => { - Vue.http.patch('api/cftimesets/' + options.timesetId, [{ - op: 'replace', - path: '/times', - value: options.times - }], { headers: headers }).then((result) => { - resolve(result) - }).catch((err) => { - reject(err) - }) +} + +export async function loadTimesetTimes (options) { + const timesets = await getTimesets(options.subscriberId) + const filteredTimesets = timesets.filter(timeset => timeset.name === options.timeset) + if (filteredTimesets.length === 1) { + return { + times: convertToTimes(filteredTimesets[0].times), + timesetIsCompatible: true, + timesetExists: filteredTimesets.length === 1, + timesetHasReverse: false, + timesetHasDuplicate: filteredTimesets.length > 1, + timesetId: filteredTimesets[0].id + } + } else { + return { + times: [], + timesetIsCompatible: true, + timesetExists: false, + timesetHasReverse: false, + timesetHasDuplicate: false, + timesetId: null + } + } +} + +export async function appendTimeToTimeset (options) { + const timeset = await get({ + resource: 'cftimesets', + resourceId: options.timesetId + }) + const times = _.cloneDeep(timeset.times) + times.push(options.time) + const updatedTimeset = await patchReplaceFull({ + resource: 'cftimesets', + resourceId: options.timesetId, + fieldPath: 'times', + value: times }) + return { + times: convertToTimes(updatedTimeset.times), + timesetIsCompatible: true, + timesetExists: true, + timesetHasReverse: false, + timesetHasDuplicate: false, + timesetId: updatedTimeset.id + } +} + +/** + * Removes a specific time from a given timeset + * @param options + * @param options.timesetId + * @param options.timeId + * @returns {Promise} + */ +export async function deleteTimeFromTimeset (options) { + const timeset = await get({ + resource: 'cftimesets', + resourceId: options.timesetId + }) + const updatedTimes = timeset.times.filter((time, index) => index !== options.timeId) + if (updatedTimes.length === 0) { + await del({ + resource: 'cftimesets', + resourceId: options.timesetId + }) + return { + times: null, + timesetIsCompatible: true, + timesetExists: false, + timesetHasReverse: false, + timesetHasDuplicate: false, + timesetId: null + } + } else { + const updatedTimeset = await patchReplaceFull({ + resource: 'cftimesets', + resourceId: options.timesetId, + fieldPath: 'times', + value: updatedTimes + }) + return { + times: convertToTimes(updatedTimeset.times), + timesetIsCompatible: true, + timesetExists: true, + timesetHasReverse: false, + timesetHasDuplicate: false, + timesetId: updatedTimeset.id + } + } } export function deleteTimesetById (id) { @@ -767,22 +888,6 @@ export function getTimesByTimesetId (id) { }) } -export function appendTimeToTimeset (options) { - return new Promise((resolve, reject) => { - const convertedTime = convertAddTime({ time: options.time[0], weekday: options.weekday }) - Promise.resolve().then(() => { - return getTimesByTimesetId(options.id) - }).then((times) => { - const concatTimes = times.concat(convertedTime) - return addTimeToTimeset({ id: options.id, times: concatTimes }) - }).then(() => { - resolve() - }).catch((err) => { - reject(err) - }) - }) -} - export function getSourcesetById (id) { return new Promise((resolve, reject) => { Vue.http.get('api/cfsourcesets/' + id).then((res) => { diff --git a/src/api/common.js b/src/api/common.js index 966b64a5..40e80795 100644 --- a/src/api/common.js +++ b/src/api/common.js @@ -27,121 +27,126 @@ export class ApiResponseError extends Error { } } -export function getList (options) { - return new Promise((resolve, reject) => { - options = options || {} - options = _.merge({ - all: false, - params: { - page: LIST_DEFAULT_PAGE, - rows: LIST_DEFAULT_ROWS - }, - headers: GET_HEADERS - }, options) - Promise.resolve().then(() => { - if (options.all === true) { - options.params.rows = LIST_ALL_ROWS - } - return Vue.http.get(options.path, { - params: options.params, - headers: options.headers - }) - }).then((res) => { - const body = getJsonBody(res.body) - if (options.all === true && body.total_count > LIST_ALL_ROWS) { - return Vue.http.get(options.path, { - params: _.merge(options.params, { - rows: body.total_count - }), - headers: options.headers - }) - } else { - return Promise.resolve(res) - } - }).then((res) => { - const body = getJsonBody(res.body) - const totalCount = _.get(body, 'total_count', 0) - let lastPage = Math.ceil(totalCount / options.params.rows) - if (options.all === true) { - lastPage = 1 - } - if (lastPage === 0) { - lastPage = null - } - const items = _.get(body, options.root, []) - for (let i = 0; i < items.length; i++) { - items[i] = normalizeEntity(items[i]) - } - resolve({ - items: items, - lastPage: lastPage - }) - }).catch((err) => { - reject(err) - }) +export async function getList (options) { + options = options || {} + options = _.merge({ + all: false, + params: { + page: LIST_DEFAULT_PAGE, + rows: LIST_DEFAULT_ROWS + }, + headers: GET_HEADERS + }, options) + if (options.all === true) { + options.params.rows = LIST_ALL_ROWS + } + if (options.resource !== undefined) { + options.path = 'api/' + options.resource + options.root = '_embedded.ngcp:' + options.resource + } + const firstRes = await Vue.http.get(options.path, { + params: options.params, + headers: options.headers }) + let secondRes = null + const firstResBody = getJsonBody(firstRes.body) + if (options.all === true && firstResBody.total_count > LIST_ALL_ROWS) { + secondRes = await Vue.http.get(options.path, { + params: _.merge(options.params, { + rows: firstResBody.total_count + }), + headers: options.headers + }) + } + let res = firstRes + let body = firstResBody + if (secondRes !== null) { + res = secondRes + body = getJsonBody(res.body) + } + const totalCount = _.get(body, 'total_count', 0) + let lastPage = Math.ceil(totalCount / options.params.rows) + if (options.all === true) { + lastPage = 1 + } + if (lastPage === 0) { + lastPage = null + } + const items = _.get(body, options.root, []) + for (let i = 0; i < items.length; i++) { + items[i] = normalizeEntity(items[i]) + } + return { + items: items, + lastPage: lastPage + } } -export function get (options) { - return new Promise((resolve, reject) => { - options = options || {} - options = _.merge({ - headers: GET_HEADERS - }, options) - const requestOptions = { - headers: options.headers, - params: options.params - } +export async function get (options) { + options = options || {} + options = _.merge({ + headers: GET_HEADERS + }, options) + const requestOptions = { + headers: options.headers, + params: options.params + } + if (options.blob === true) { + requestOptions.responseType = 'blob' + } + let path = options.path + if (options.resource !== undefined && options.resourceId !== undefined) { + path = 'api/' + options.resource + '/' + options.resourceId + } + try { + const res = await Vue.http.get(path, requestOptions) + let body = null if (options.blob === true) { - requestOptions.responseType = 'blob' + body = URL.createObjectURL(res.body) + } else { + body = normalizeEntity(getJsonBody(res.body)) } - return Vue.http.get(options.path, requestOptions).then((result) => { - let body = null - if (options.blob === true) { - body = URL.createObjectURL(result.body) - } else { - body = normalizeEntity(getJsonBody(result.body)) - } - resolve(body) - }).catch((err) => { - const code = _.get(err, 'body.code', null) - const message = _.get(err, 'body.message', null) - if (code !== null && message !== null) { - reject(new ApiResponseError(err.body.code, err.body.message)) - } else { - reject(err) - } - }) - }) + return body + } catch (err) { + const code = _.get(err, 'body.code', null) + const message = _.get(err, 'body.message', null) + if (code !== null && message !== null) { + throw new ApiResponseError(err.body.code, err.body.message) + } else { + throw err + } + } } -export function patch (operation, options) { - return new Promise((resolve, reject) => { - options = options || {} - options = _.merge({ - headers: PATCH_HEADERS - }, options) - const body = { - op: operation, - path: '/' + options.fieldPath - } - if (options.value !== undefined) { - body.value = options.value - } - Vue.http.patch(options.path, [body], { +export async function patch (operation, options) { + options = options || {} + options = _.merge({ + headers: PATCH_HEADERS + }, options) + const body = { + op: operation, + path: '/' + options.fieldPath + } + if (options.value !== undefined) { + body.value = options.value + } + let path = options.path + if (options.resource !== undefined && options.resourceId !== undefined) { + path = 'api/' + options.resource + '/' + options.resourceId + } + try { + return await Vue.http.patch(path, [body], { headers: options.headers - }).then((result) => { - resolve(result) - }).catch((err) => { - const code = _.get(err, 'body.code', null) - const message = _.get(err, 'body.message', null) - if (code !== null && message !== null) { - reject(new ApiResponseError(err.body.code, err.body.message)) - } else { - reject(err) - } }) - }) + } catch (err) { + const code = _.get(err, 'body.code', null) + const message = _.get(err, 'body.message', null) + if (code !== null && message !== null) { + throw new ApiResponseError(err.body.code, err.body.message) + } else { + throw err + } + } } export function patchReplace (options) { @@ -156,20 +161,15 @@ export function patchRemove (options) { return patch('remove', options) } -export function patchFull (operation, options) { - return new Promise((resolve, reject) => { - options = options || {} - options = _.merge(options, { - headers: { - Prefer: 'return=representation' - } - }) - patch(operation, options).then((result) => { - resolve(getJsonBody(result.body)) - }).catch((err) => { - reject(err) - }) +export async function patchFull (operation, options) { + options = options || {} + options = _.merge(options, { + headers: { + Prefer: 'return=representation' + } }) + const res = await patch(operation, options) + return normalizeEntity(getJsonBody(res.body)) } export function patchReplaceFull (options) { @@ -184,6 +184,32 @@ export function patchRemoveFull (options) { return patchFull('remove', options) } +export async function del (options) { + options = options || {} + options = _.merge({ + headers: GET_HEADERS + }, options) + const requestOptions = { + headers: options.headers, + params: options.params + } + let path = options.path + if (options.resource !== undefined && options.resourceId !== undefined) { + path = 'api/' + options.resource + '/' + options.resourceId + } + try { + await Vue.http.delete(path, requestOptions) + } catch (err) { + const code = _.get(err, 'body.code', null) + const message = _.get(err, 'body.message', null) + if (code !== null && message !== null) { + throw new ApiResponseError(err.body.code, err.body.message) + } else { + throw err + } + } +} + export function getFieldList (options) { return new Promise((resolve, reject) => { options = options || {} diff --git a/src/boot/filters.js b/src/boot/filters.js index d46a5f72..2361801f 100644 --- a/src/boot/filters.js +++ b/src/boot/filters.js @@ -6,7 +6,8 @@ import NumberFormatFilter, { } from 'src/filters/number-format' import DateFilter, { smartTime, - time + time, + weekday } from 'src/filters/date' import { startCase @@ -28,4 +29,5 @@ export default () => { Vue.filter('groupName', displayName) Vue.filter('displayName', displayName) Vue.filter('time', time) + Vue.filter('weekday', weekday) } diff --git a/src/components/pages/CallForward/CscAddTimeForm.vue b/src/components/pages/CallForward/CscAddTimeForm.vue index aa0a61b0..5c9950fa 100644 --- a/src/components/pages/CallForward/CscAddTimeForm.vue +++ b/src/components/pages/CallForward/CscAddTimeForm.vue @@ -11,6 +11,7 @@ options-dense emit-value map-options + dense :options="selectOptions" /> @@ -19,6 +20,7 @@ >
diff --git a/src/components/pages/CallForward/CscCallForwardTime.vue b/src/components/pages/CallForward/CscCallForwardTime.vue index ad9de039..0bd33dfb 100644 --- a/src/components/pages/CallForward/CscCallForwardTime.vue +++ b/src/components/pages/CallForward/CscCallForwardTime.vue @@ -1,7 +1,7 @@