change(ui): add api client response check; add types for some immut collections
This commit is contained in:
parent
f1d852abb4
commit
d5fc6d7a1b
14 changed files with 129 additions and 132 deletions
|
|
@ -95,7 +95,16 @@ export default class APIClient {
|
|||
) {
|
||||
edp = `${ edp }/${ this.siteId }`
|
||||
}
|
||||
return fetch(edp + path, this.init);
|
||||
return fetch(edp + path, this.init)
|
||||
.then(response => {
|
||||
if (response.ok) {
|
||||
return response
|
||||
} else {
|
||||
throw new Error(
|
||||
`! ${this.init.method} error on ${path}; ${response.status}`
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get(path, params, options) {
|
||||
|
|
|
|||
|
|
@ -145,17 +145,17 @@ function FilterAutoComplete(props: Props) {
|
|||
new APIClient()
|
||||
[method?.toLocaleLowerCase()](endpoint, { ...params, q: inputValue })
|
||||
.then((response: any) => {
|
||||
if (response.ok) {
|
||||
return response.json();
|
||||
}
|
||||
throw new Error(response.statusText);
|
||||
})
|
||||
.then(({ data }: any) => {
|
||||
const _options = data.map((i: any) => ({ value: i.value, label: i.value })) || [];
|
||||
setOptions(_options);
|
||||
callback(_options);
|
||||
setLoading(false);
|
||||
});
|
||||
})
|
||||
.catch((e) => {
|
||||
throw new Error(e);
|
||||
})
|
||||
};
|
||||
|
||||
const debouncedLoadOptions = React.useCallback(debounce(loadOptions, 1000), [params]);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ import { combineReducers } from 'redux-immutable';
|
|||
import jwt from './jwt';
|
||||
import user from './user';
|
||||
import sessions from './sessions';
|
||||
import issues from './issues';
|
||||
import assignments from './assignments';
|
||||
import target from './target';
|
||||
import targetCustom from './targetCustom';
|
||||
|
|
@ -34,11 +33,10 @@ import customMetrics from './customMetrics';
|
|||
import search from './search';
|
||||
import liveSearch from './liveSearch';
|
||||
|
||||
export default combineReducers({
|
||||
const rootReducer = combineReducers({
|
||||
jwt,
|
||||
user,
|
||||
sessions,
|
||||
issues,
|
||||
assignments,
|
||||
target,
|
||||
targetCustom,
|
||||
|
|
@ -70,3 +68,7 @@ export default combineReducers({
|
|||
...integrations,
|
||||
...sources,
|
||||
});
|
||||
|
||||
export type RootStore = ReturnType<typeof rootReducer>
|
||||
|
||||
export default rootReducer
|
||||
|
|
@ -21,7 +21,6 @@ const PUSH_NEW_SITE = 'user/PUSH_NEW_SITE';
|
|||
const SET_ONBOARDING = 'user/SET_ONBOARDING';
|
||||
|
||||
const initialState = Map({
|
||||
// client: Client(),
|
||||
account: Account(),
|
||||
siteId: null,
|
||||
passwordRequestError: false,
|
||||
|
|
|
|||
|
|
@ -1,16 +1,17 @@
|
|||
import BaseService from './BaseService';
|
||||
import { fetchErrorCheck } from 'App/utils'
|
||||
|
||||
export default class ErrorService extends BaseService {
|
||||
all(params: any = {}): Promise<any[]> {
|
||||
return this.client.post('/errors/search', params)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response: { data: any; }) => response.data || []);
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || [])
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
one(id: string): Promise<any> {
|
||||
return this.client.get(`/errors/${id}`)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response: { data: any; }) => response.data || {});
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || {})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,5 @@
|
|||
import Widget from "App/mstore/types/widget";
|
||||
import APIClient from 'App/api_client';
|
||||
import { fetchErrorCheck } from "App/utils";
|
||||
|
||||
export default class MetricService {
|
||||
private client: APIClient;
|
||||
|
|
@ -30,8 +29,9 @@ export default class MetricService {
|
|||
*/
|
||||
getMetric(metricId: string): Promise<any> {
|
||||
return this.client.get('/metrics/' + metricId)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response: { data: any; }) => response.data || {});
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || {})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -45,8 +45,9 @@ export default class MetricService {
|
|||
const method = isCreating ? 'post' : 'put';
|
||||
const url = isCreating ? '/metrics' : '/metrics/' + data[Widget.ID_KEY];
|
||||
return this.client[method](url, data)
|
||||
.then(fetchErrorCheck)
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || {})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -74,8 +75,9 @@ export default class MetricService {
|
|||
getMetricChartData(metric: Widget, data: any, isWidget: boolean = false): Promise<any> {
|
||||
const path = isWidget ? `/metrics/${metric.metricId}/chart` : `/metrics/try`;
|
||||
return this.client.post(path, data)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response: { data: any; }) => response.data || {});
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || {})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -45,89 +45,61 @@ export interface NotesFilter {
|
|||
}
|
||||
|
||||
export default class NotesService {
|
||||
private client: APIClient;
|
||||
private client: APIClient;
|
||||
|
||||
constructor(client?: APIClient) {
|
||||
this.client = client ? client : new APIClient();
|
||||
}
|
||||
constructor(client?: APIClient) {
|
||||
this.client = client ? client : new APIClient();
|
||||
}
|
||||
|
||||
initClient(client?: APIClient) {
|
||||
this.client = client || new APIClient();
|
||||
}
|
||||
initClient(client?: APIClient) {
|
||||
this.client = client || new APIClient();
|
||||
}
|
||||
|
||||
fetchNotes(filter: NotesFilter): Promise<Note[]> {
|
||||
return this.client.post('/notes', filter).then(r => {
|
||||
if (r.ok) {
|
||||
return r.json().then(r => r.data)
|
||||
} else {
|
||||
throw new Error('Error getting notes: ' + r.status)
|
||||
}
|
||||
})
|
||||
}
|
||||
fetchNotes(filter: NotesFilter): Promise<Note[]> {
|
||||
return this.client.post('/notes', filter).then(r => {
|
||||
return r.json().then(r => r.data)
|
||||
})
|
||||
}
|
||||
|
||||
getNotesBySessionId(sessionID: string): Promise<Note[]> {
|
||||
return this.client.get(`/sessions/${sessionID}/notes`)
|
||||
getNotesBySessionId(sessionID: string): Promise<Note[]> {
|
||||
return this.client.get(`/sessions/${sessionID}/notes`)
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
return r.json().then(r => r.data)
|
||||
} else {
|
||||
throw new Error('Error getting notes for ' +sessionID + ' cuz: ' + r.status)
|
||||
}
|
||||
return r.json().then(r => r.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
addNote(sessionID: string, note: WriteNote): Promise<Note> {
|
||||
return this.client.post(`/sessions/${sessionID}/notes`, note)
|
||||
addNote(sessionID: string, note: WriteNote): Promise<Note> {
|
||||
return this.client.post(`/sessions/${sessionID}/notes`, note)
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
return r.json().then(r => r.data)
|
||||
} else {
|
||||
throw new Error('Error adding note: ' + r.status)
|
||||
}
|
||||
return r.json().then(r => r.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
updateNote(noteID: string, note: WriteNote): Promise<Note> {
|
||||
return this.client.post(`/notes/${noteID}`, note)
|
||||
updateNote(noteID: string, note: WriteNote): Promise<Note> {
|
||||
return this.client.post(`/notes/${noteID}`, note)
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
return r.json().then(r => r.data)
|
||||
} else {
|
||||
throw new Error('Error updating note: ' + r.status)
|
||||
}
|
||||
return r.json().then(r => r.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
deleteNote(noteID: number) {
|
||||
return this.client.delete(`/notes/${noteID}`)
|
||||
deleteNote(noteID: number) {
|
||||
return this.client.delete(`/notes/${noteID}`)
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
return r.json().then(r => r.data)
|
||||
} else {
|
||||
throw new Error('Error deleting note: ' + r.status)
|
||||
}
|
||||
return r.json().then(r => r.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sendSlackNotification(noteId: string, webhook: string) {
|
||||
return this.client.get(`/notes/${noteId}/slack/${webhook}`)
|
||||
sendSlackNotification(noteId: string, webhook: string) {
|
||||
return this.client.get(`/notes/${noteId}/slack/${webhook}`)
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
return r.json().then(r => r.data)
|
||||
} else {
|
||||
throw new Error('Error sending slack notif: ' + r.status)
|
||||
}
|
||||
return r.json().then(r => r.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
sendMsTeamsNotification(noteId: string, webhook: string) {
|
||||
return this.client.get(`/notes/${noteId}/msteams/${webhook}`)
|
||||
sendMsTeamsNotification(noteId: string, webhook: string) {
|
||||
return this.client.get(`/notes/${noteId}/msteams/${webhook}`)
|
||||
.then(r => {
|
||||
if (r.ok) {
|
||||
return r.json().then(r => r.data)
|
||||
} else {
|
||||
throw new Error('Error sending slack notif: ' + r.status)
|
||||
}
|
||||
return r.json().then(r => r.data)
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,11 +37,7 @@ export default class RecordingsService {
|
|||
|
||||
reserveUrl(siteId: string, recordingData: RecordingData): Promise<{ URL: string; key: string }> {
|
||||
return this.client.put(`/${siteId}/assist/save`, recordingData).then((r) => {
|
||||
if (r.ok) {
|
||||
return r.json().then((j) => j.data);
|
||||
} else {
|
||||
throw new Error("Can't reserve space for recording: " + r.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
|
@ -51,61 +47,37 @@ export default class RecordingsService {
|
|||
headers: { 'Content-Type': 'video/webm' },
|
||||
body: file,
|
||||
}).then((r) => {
|
||||
if (r.ok) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error("Can't upload file: " + r.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
confirmFile(siteId: string, recordingData: RecordingData, key: string): Promise<any> {
|
||||
return this.client.put(`/${siteId}/assist/save/done`, { ...recordingData, key }).then((r) => {
|
||||
if (r.ok) {
|
||||
return r.json().then((j) => j.data);
|
||||
} else {
|
||||
throw new Error("Can't confirm file saving: " + r.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fetchRecordings(filters: FetchFilter): Promise<IRecord[]> {
|
||||
return this.client.post(`/assist/records`, filters).then((r) => {
|
||||
if (r.ok) {
|
||||
return r.json().then((j) => j.data);
|
||||
} else {
|
||||
throw new Error("Can't get recordings: " + r.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
fetchRecording(id: number): Promise<IRecord> {
|
||||
return this.client.get(`/assist/records/${id}`).then((r) => {
|
||||
if (r.ok) {
|
||||
return r.json().then((j) => j.data);
|
||||
} else {
|
||||
throw new Error("Can't get recordings: " + r.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateRecordingName(id: number, name: string): Promise<IRecord> {
|
||||
return this.client.post(`/assist/records/${id}`, { name }).then((r) => {
|
||||
if (r.ok) {
|
||||
return r.json().then((j) => j.data);
|
||||
} else {
|
||||
throw new Error("Can't get recordings: " + r.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
deleteRecording(id: number): Promise<any> {
|
||||
return this.client.delete(`/assist/records/${id}`).then((r) => {
|
||||
if (r.ok) {
|
||||
return r.json().then((j) => j.data);
|
||||
} else {
|
||||
throw new Error("Can't get recordings: " + r.status);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
import APIClient from 'App/api_client';
|
||||
import { fetchErrorCheck } from 'App/utils';
|
||||
|
||||
export default class SettingsService {
|
||||
private client: APIClient;
|
||||
|
|
@ -26,8 +25,9 @@ export default class SettingsService {
|
|||
getSessions(filter: any) {
|
||||
return this.client
|
||||
.post('/sessions/search', filter)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response) => response.data || []);
|
||||
.then(r => r.json())
|
||||
.then((response) => response.data || [])
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
getSessionInfo(sessionId: string, isLive?: boolean): Promise<Record<string, any>> {
|
||||
|
|
@ -41,7 +41,8 @@ export default class SettingsService {
|
|||
getLiveSessions(filter: any) {
|
||||
return this.client
|
||||
.post('/assist/sessions', filter)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response) => response.data || []);
|
||||
.then(r => r.json())
|
||||
.then((response) => response.data || [])
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
import APIClient from 'App/api_client';
|
||||
import { IUser } from 'App/mstore/types/user'
|
||||
import { fetchErrorCheck } from 'App/utils'
|
||||
|
||||
export default class UserService {
|
||||
private client: APIClient;
|
||||
|
|
@ -29,12 +28,14 @@ export default class UserService {
|
|||
const data = user.toSave();
|
||||
if (user.userId) {
|
||||
return this.client.put('/client/members/' + user.userId, data)
|
||||
.then(fetchErrorCheck)
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || {})
|
||||
.catch(e => Promise.reject(e))
|
||||
} else {
|
||||
return this.client.post('/client/members', data)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response: { data: any; }) => response.data || {});
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || {})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -46,8 +47,9 @@ export default class UserService {
|
|||
|
||||
delete(userId: string) {
|
||||
return this.client.delete('/client/members/' + userId)
|
||||
.then(fetchErrorCheck)
|
||||
.then((response: { data: any; }) => response.data || {});
|
||||
.then(r => r.json())
|
||||
.then((response: { data: any; }) => response.data || {})
|
||||
.catch(e => Promise.reject(e))
|
||||
}
|
||||
|
||||
getRoles() {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,27 @@
|
|||
import Member from 'Types/member';
|
||||
import Limit from './limit';
|
||||
import Member, { IMember } from 'Types/member';
|
||||
import Limit, { ILimits } from './limit';
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
// TODO types for mobx and all
|
||||
export interface IAccount extends IMember {
|
||||
changePassword?: any
|
||||
limits: ILimits
|
||||
banner: string
|
||||
email: string
|
||||
verifiedEmail: string
|
||||
id: string
|
||||
smtp: boolean
|
||||
license: string
|
||||
expirationDate?: DateTime
|
||||
permissions: string[]
|
||||
iceServers: string
|
||||
hasPassword: boolean
|
||||
apiKey: string
|
||||
tenantKey: string
|
||||
edition: string
|
||||
optOut: string
|
||||
}
|
||||
|
||||
export default Member.extend({
|
||||
changePassword: undefined,
|
||||
limits: Limit(),
|
||||
|
|
@ -1,6 +1,16 @@
|
|||
import Record from 'Types/Record';
|
||||
import { Map } from 'immutable';
|
||||
|
||||
interface ILimitValue {
|
||||
limit: number
|
||||
remaining: number
|
||||
}
|
||||
|
||||
export interface ILimits {
|
||||
teamMember: ILimitValue
|
||||
sites: ILimitValue
|
||||
}
|
||||
|
||||
const defaultValues = Map({ limit: 0, remaining: 0 });
|
||||
const Limit = Record({
|
||||
teamMember: defaultValues,
|
||||
|
|
@ -2,6 +2,20 @@ import Record from 'Types/Record';
|
|||
import { DateTime } from 'luxon';
|
||||
import { validateEmail, validateName } from 'App/validate';
|
||||
|
||||
export interface IMember {
|
||||
id: string
|
||||
name: string
|
||||
email: string
|
||||
createdAt: DateTime
|
||||
admin: boolean
|
||||
superAdmin: boolean
|
||||
joined: boolean
|
||||
expiredInvitation: boolean
|
||||
roleId: string
|
||||
roleName: string
|
||||
invitationLink: string
|
||||
}
|
||||
|
||||
export default Record({
|
||||
id: undefined,
|
||||
name: '',
|
||||
|
|
@ -346,13 +346,6 @@ export const exportCSVFile = (headers, items, fileTitle) => {
|
|||
}
|
||||
};
|
||||
|
||||
export const fetchErrorCheck = async (response: any) => {
|
||||
if (!response.ok) {
|
||||
return Promise.reject(response);
|
||||
}
|
||||
return response.json();
|
||||
};
|
||||
|
||||
export const cleanSessionFilters = (data: any) => {
|
||||
const { filters, ...rest } = data;
|
||||
const _fitlers = filters.filter((f: any) => {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue