Skip to content

Commit

Permalink
several refactorings
Browse files Browse the repository at this point in the history
  • Loading branch information
Psilo committed Sep 20, 2021
1 parent 0f7837f commit 9a14fef
Show file tree
Hide file tree
Showing 5 changed files with 242 additions and 168 deletions.
127 changes: 57 additions & 70 deletions src/utils/axiosUtils.ts
Original file line number Diff line number Diff line change
@@ -1,45 +1,29 @@
import Vue from 'vue'
import store from '@/store'
import { error } from './loggingUtils'
import { getDeepProperty } from './objectUtils'
import log from './loggingUtils'
import objectUtils from '@/utils/objectUtils'

function buildBaseUrl (server) {
const config = getDeepProperty(server, store.getters['rest/config'].servers)
function buildBaseUrl (server: string): string {
const config = objectUtils.getDeepProperty(server, store.getters['rest/config'].servers)
return `${config.protocol}://${config.address}:${config.port}`
}

export async function handleErrors (wrapped) {
export async function appendErrorCatcher (wrapped: Promise<any>): Promise<any> {
return wrapped.catch(err => {
const status = err ? err.status : err
let status = err
if (err && err.response) {
status = err.response.status
}
let msg = err.message
if (err != null && err.response != null && err.response.data != null && err.response.data.message != null) {
msg = err.response.data.message
}
error(msg, 'communication', status)
log.error(msg, 'communication', status)
throw new Error('Internal Error.')
})
}

function setIndicator (workingIndicator, value) {
if (workingIndicator !== null) {
if (typeof workingIndicator === 'string') {
store.dispatch(workingIndicator, value)
} else {
workingIndicator(value)
}
}
}

function setResponse (dataSetter, response) {
if (dataSetter != null) {
if (typeof dataSetter === 'string') {
store.dispatch(dataSetter, response)
} else {
dataSetter(response)
}
}
}

function provideData (dataProvider) {
function provideData (dataProvider: () => object | string): null | string | object {
if (dataProvider !== null) {
if (typeof dataProvider === 'string') {
return store.getters[dataProvider]
Expand All @@ -50,61 +34,76 @@ function provideData (dataProvider) {
return null
}

async function internalRestCall (workingIndicator, responseSetter, restCallPromise) {
setIndicator(workingIndicator, true)
return handleErrors(restCallPromise.then(response => {
setIndicator(workingIndicator, false)
async function internalRestCall (restCallPromise: Promise<any>): Promise<any> {
return appendErrorCatcher(restCallPromise.then(response => {
// console.log(response)
setResponse(responseSetter, response)
return response
}))
}

async function internalGet (server, endpointPath) {
function getAuthorizationHeader (): object {
const token = store.getters['keycloak/token']
if (token == null || token === undefined || token === '') {
return {}
}
return { Authorization: 'Bearer ' + token }
}

async function internalGet (server: string, endpointPath: string, isList: boolean): Promise<object | null> {
// console.log(buildBaseUrl(server) + endpointPath)
return Vue.axios
.get(buildBaseUrl(server) + endpointPath, {
headers: {
}
headers: Object.assign({}, getAuthorizationHeader())
})
.then(response => {
if (response === undefined || response == null) {
throw new Error('Response was null or undefined.')
}
const entries = response.data.entries
if (isList && entries !== undefined && entries == null) {
throw new Error(`Entries of response was null on call to ${server}${endpointPath}.`)
}
return response.data
})
}

async function internalDelete (server, endpointPath) {
async function internalDelete (server: string, endpointPath: string): Promise<any> {
// console.log(buildBaseUrl(server) + endpointPath)
return Vue.axios
.delete(buildBaseUrl(server) + endpointPath, {
data: {
},
headers: {
}
headers: Object.assign({}, getAuthorizationHeader())
})
.then(response => {
return response.data
})
}

async function internalPut (server, endpointPath, dataProvider) {
async function internalPut (server: string, endpointPath: string, dataProvider): Promise<any> {
// console.log(buildBaseUrl(server) + endpointPath)
return Vue.axios
.put(buildBaseUrl(server) + endpointPath, provideData(dataProvider), {
headers: {
}
headers: Object.assign({}, getAuthorizationHeader())
})
.then(response => {
if (response === undefined || response == null) {
throw new Error('Response was null or undefined.')
}
return response.data
})
}

async function internalPost (server, endpointPath, dataProvider) {
async function internalPost (server: string, endpointPath: string, dataProvider): Promise<any> {
// console.log(buildBaseUrl(server) + endpointPath)
return Vue.axios
.post(buildBaseUrl(server) + endpointPath, provideData(dataProvider), {
headers: {
}
headers: Object.assign({}, getAuthorizationHeader())
})
.then(response => {
if (response === undefined || response == null) {
throw new Error('Response was null or undefined.')
}
return response.data
})
}
Expand All @@ -113,72 +112,60 @@ async function internalPost (server, endpointPath, dataProvider) {
* Send a GET retrieving the response from the server.
* @param server name of the rest/config/servers property to use
* @param endpointPath path to the correct endpoint-definition starting from rest/config/endpoint/
* @param workingIndicator path to an indicator-action (true/false) or function(value) that will be called with value = (true/false) accordingly
* @param responseSetter path to a vuex-action (object) or function(response) that will be called with the received response
*/
export async function getResponse (server, endpointPath, workingIndicator, responseSetter) {
return internalRestCall(workingIndicator, responseSetter, internalGet(server, getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)))
export async function getResponse (server: string, endpointPath: string): Promise<any> {
return internalRestCall(internalGet(server, objectUtils.getDeepProperty(endpointPath, store.getters['rest/config'].endpoint), false))
}

/**
* Send a GET retrieving a data-object represented by an ID from the server.
* @param server name of the rest/config/servers property to use
* @param endpointPath path to the correct endpoint-definition starting from rest/config/endpoint/
* @param workingIndicator path to an indicator-action (true/false) or function(value) that will be called with value = (true/false) accordingly
* @param responseSetter path to a vuex-action (object) or function(response) that will be called with the received response
* @param id the ID of the object to retrieve
*/
export async function getById (server, endpointPath, id, workingIndicator, responseSetter) {
return internalRestCall(workingIndicator, responseSetter, internalGet(server, `${getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}/${id}`))
export async function getById (server: string, endpointPath: string, id: string | number): Promise<any> {
return internalRestCall(internalGet(server, `${objectUtils.getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}/${id}`, false))
}

/**
* Send a GET retrieving a list of data-objects from the server.
* @param server name of the rest/config/servers property to use
* @param endpointPath path to the correct endpoint-definition starting from rest/config/endpoint/
* @param workingIndicator path to an indicator-action (true/false) or function(value) that will be called with value = (true/false) accordingly
* @param responseSetter path to a vuex-action (object) or function(response) that will be called with the received response
* @param size the size of a single page of the list
* @param offset the number of pages to omit before returning the list
* @param additionalQueryParams a string containing additional query parameters (like 'scanId=5&searchName=hallo' for example)
*/
export async function getList (server, endpointPath, size, offset, workingIndicator, responseSetter, additionalQueryParams) {
return internalRestCall(workingIndicator, responseSetter, internalGet(server, `${getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}?size=${size}&offset=${offset}${additionalQueryParams != null ? '&' + additionalQueryParams : ''}`))
export async function getList (server: string, endpointPath: string, size: number, offset: number, additionalQueryParams: string): Promise<any> {
return internalRestCall(internalGet(server, `${objectUtils.getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}?size=${size}&offset=${offset}${additionalQueryParams != null ? '&' + additionalQueryParams : ''}`, true))
}

/**
* Sends a DEL request to the server for the object with the given ID.
* @param server name of the rest/config/servers property to use
* @param endpointPath path to the correct endpoint-definition starting from rest/config/endpoint/
* @param workingIndicator path to an indicator-action (true/false) or function(value) that will be called with value = (true/false) accordingly
* @param responseSetter path to a vuex-action (object) or function(response) that will be called with the received response
* @param id the ID of the object to retrieve
*/
export async function del (server, endpointPath, id, workingIndicator, responseSetter) {
return internalRestCall(workingIndicator, responseSetter, internalDelete(server, `${getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}/${id}`))
export async function del (server: string, endpointPath: string, id: string | number): Promise<any> {
return internalRestCall(internalDelete(server, `${objectUtils.getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}/${id}`))
}

/**
* Sends a PUT request to the server for the object with the given ID.
* @param server name of the rest/config/servers property to use
* @param endpointPath path to the correct endpoint-definition starting from rest/config/endpoint/
* @param workingIndicator path to an indicator-action (true/false) or function(value) that will be called with value = (true/false) accordingly
* @param dataProvider path to a vuex-getter or function that will be called in order to get the body for the call
* @param responseSetter path to a vuex-action (object) or function(response) that will be called with the received response
* @param id the ID of the object to retrieve
* @param dataProvider path to a vuex-getter or function that will be called in order to get the body for the call
*/
export async function put (server, endpointPath, id, workingIndicator, dataProvider, responseSetter) {
return internalRestCall(workingIndicator, responseSetter, internalPut(server, `${getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}/${id}`, dataProvider))
export async function put (server: string, endpointPath: string, id: string | number, dataProvider: () => object): Promise<any> {
return internalRestCall(internalPut(server, `${objectUtils.getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}/${id}`, dataProvider))
}

/**
* Sends a POST request to the server for the object with the given ID.
* @param server name of the rest/config/servers property to use
* @param endpointPath path to the correct endpoint-definition starting from rest/config/endpoint/
* @param workingIndicator path to an indicator-action (true/false) or function(value) that will be called with value = (true/false) accordingly
* @param dataProvider path to a vuex-getter or function that will be called in order to get the body for the call
* @param responseSetter path to a vuex-action (object) or function(response) that will be called with the received response
*/
export async function post (server, endpointPath, workingIndicator, dataProvider, responseSetter) {
return internalRestCall(workingIndicator, responseSetter, internalPost(server, `${getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}`, dataProvider))
export async function post (server: string, endpointPath: string, dataProvider: () => object): Promise<any> {
return internalRestCall(internalPost(server, `${objectUtils.getDeepProperty(endpointPath, store.getters['rest/config'].endpoint)}`, dataProvider))
}
52 changes: 27 additions & 25 deletions src/utils/jsUtils.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
export function toggleItem (item, array) {
const index = array.indexOf(item)
if (index === -1) {
array.push(item)
} else {
array.splice(index, 1)
}
}
export default {
toggleItem: function (item, array) {
const index = array.indexOf(item)
if (index === -1) {
array.push(item)
} else {
array.splice(index, 1)
}
},

export function removeItem (item, array) {
const index = array.indexOf(item)
if (index !== -1) {
array.splice(index, 1)
}
}
removeItem: function (item, array) {
const index = array.indexOf(item)
if (index !== -1) {
array.splice(index, 1)
}
},

export function containsItem (item, array) {
return array.indexOf(item) !== -1
}
containsItem: function (item, array) {
return array.indexOf(item) !== -1
},

/**
* Returns the value itself, or an empty string, if the value was null or undefined.
* @param value the value to sanitize
*/
export function sanitize (value) {
if (value === null || value === undefined) {
return ''
/**
* Returns the value itself, or an empty string, if the value was null or undefined.
* @param value the value to sanitize
*/
sanitize: function (value) {
if (value === null || value === undefined) {
return ''
}
return value
}
return value
}
86 changes: 44 additions & 42 deletions src/utils/loggingUtils.ts
Original file line number Diff line number Diff line change
@@ -1,48 +1,50 @@
import store from '@/store'

/**
* Logs a message to the snackbar.
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param level the level to use ('error', 'warning')
* @param status the status-code (integer) (may be omitted)
*/
export function log (message, group, level, status) {
store.dispatch('gui/snackbar/snackbarEnqueue', {
color: `${level}`,
headingTKey: `message.${level}.heading`,
descriptionTKey: `message.${level}.${group}`,
status,
message
}, { root: true })
}
export default {
/**
* Logs a message to the snackbar.
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param level the level to use ('error', 'warning')
* @param status the status-code (integer) (may be omitted)
*/
log: function (message, group, level, status) {
store.dispatch('gui/snackbar/snackbarEnqueue', {
color: `${level}`,
headingTKey: `message.${level}.heading`,
descriptionTKey: `message.${level}.${group}`,
status,
message
}, { root: true })
},

/**
* Logs a success message to the snackbar
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param status the status-code (integer) (may be omitted)
*/
export function success (message, group, status?) {
log(message, group, 'success', status)
}
/**
* Logs a success message to the snackbar
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param status the status-code (integer) (may be omitted)
*/
success: function (message, group, status?) {
this.log(message, group, 'success', status)
},

/**
* Logs a warning to the snackbar
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param status the status-code (integer) (may be omitted)
*/
export function warning (message, group, status?) {
log(message, group, 'warning', status)
}
/**
* Logs a warning to the snackbar
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param status the status-code (integer) (may be omitted)
*/
warning: function (message, group, status?) {
this.log(message, group, 'warning', status)
},

/**
* Logs an error to the snackbar
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param status the status-code (integer) (may be omitted)
*/
export function error (message, group, status?) {
log(message, group, 'error', status)
/**
* Logs an error to the snackbar
* @param message the message to log
* @param group the group to use ('internal', 'communication', ...) which is a path in the message-object in localization.
* @param status the status-code (integer) (may be omitted)
*/
error: function (message, group, status?) {
this.log(message, group, 'error', status)
}
}
Loading

0 comments on commit 9a14fef

Please sign in to comment.