mirror of
https://github.com/orangecoding/fredy.git
synced 2026-06-16 12:31:07 +00:00
UI (#15)
Adding new Admin UI. Updating Fredy to V3.0.0 as it has been a large rewrite. Thanks for all contributions and help on the way!
This commit is contained in:
committed by
GitHub
parent
8185bfe818
commit
b2847f6834
43
ui/src/services/rematch/models/jobs.js
Normal file
43
ui/src/services/rematch/models/jobs.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import { xhrGet } from '../../xhr';
|
||||
|
||||
export const jobs = {
|
||||
state: {
|
||||
jobs: [],
|
||||
insights: {},
|
||||
},
|
||||
reducers: {
|
||||
setJobs: (state, payload) => {
|
||||
return {
|
||||
...state,
|
||||
jobs: Object.freeze(payload),
|
||||
};
|
||||
},
|
||||
setJobInsights: (state, payload, jobId) => {
|
||||
return {
|
||||
...state,
|
||||
insights: {
|
||||
...state.insights,
|
||||
[jobId]: Object.freeze(payload),
|
||||
},
|
||||
};
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
async getJobs() {
|
||||
try {
|
||||
const response = await xhrGet('/api/jobs');
|
||||
this.setJobs(response.json);
|
||||
} catch (Exception) {
|
||||
console.error(`Error while trying to get resource for api/jobs. Error:`, Exception);
|
||||
}
|
||||
},
|
||||
async getInsightDataForJob(jobId) {
|
||||
try {
|
||||
const response = await xhrGet(`/api/jobs/insights/${jobId}`);
|
||||
this.setJobInsights(response.json, jobId);
|
||||
} catch (Exception) {
|
||||
console.error(`Error while trying to get resource for api/jobs/insights. Error:`, Exception);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
19
ui/src/services/rematch/models/notificationAdapter.js
Normal file
19
ui/src/services/rematch/models/notificationAdapter.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { xhrGet } from '../../xhr';
|
||||
export const notificationAdapter = {
|
||||
state: [],
|
||||
reducers: {
|
||||
setAdapter: (state, payload) => {
|
||||
return [...Object.freeze(payload)];
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
async getAdapter() {
|
||||
try {
|
||||
const response = await xhrGet('/api/jobs/notificationAdapter');
|
||||
this.setAdapter(response.json);
|
||||
} catch (Exception) {
|
||||
console.error(`Error while trying to get resource for api/jobs/notificationAdapter. Error:`, Exception);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
19
ui/src/services/rematch/models/provider.js
Normal file
19
ui/src/services/rematch/models/provider.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import { xhrGet } from '../../xhr';
|
||||
export const provider = {
|
||||
state: [],
|
||||
reducers: {
|
||||
setProvider: (state, payload) => {
|
||||
return [...Object.freeze(payload)];
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
async getProvider() {
|
||||
try {
|
||||
const response = await xhrGet('/api/jobs/provider');
|
||||
this.setProvider(response.json);
|
||||
} catch (Exception) {
|
||||
console.error(`Error while trying to get resource for api/jobs/provider. Error:`, Exception);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
41
ui/src/services/rematch/models/user.js
Normal file
41
ui/src/services/rematch/models/user.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import { xhrGet } from '../../xhr';
|
||||
|
||||
export const user = {
|
||||
state: {
|
||||
users: [],
|
||||
currentUser: null,
|
||||
},
|
||||
reducers: {
|
||||
//only admins
|
||||
setUsers: (state, payload) => {
|
||||
return {
|
||||
...state,
|
||||
users: payload,
|
||||
};
|
||||
},
|
||||
setCurrentUser: (state, payload) => {
|
||||
return {
|
||||
...state,
|
||||
currentUser: Object.freeze(payload),
|
||||
};
|
||||
},
|
||||
},
|
||||
effects: {
|
||||
async getUsers() {
|
||||
try {
|
||||
const response = await xhrGet('/api/admin/users');
|
||||
this.setUsers(response.json);
|
||||
} catch (Exception) {
|
||||
console.error('Error while trying to get resource for api/admin/users. Error:', Exception);
|
||||
}
|
||||
},
|
||||
async getCurrentUser() {
|
||||
try {
|
||||
const response = await xhrGet('/api/login/user');
|
||||
this.setCurrentUser(response.json);
|
||||
} catch (Exception) {
|
||||
console.error('Error while trying to get resource for api/login/user. Error:', Exception);
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
30
ui/src/services/rematch/store.js
Normal file
30
ui/src/services/rematch/store.js
Normal file
@@ -0,0 +1,30 @@
|
||||
import { notificationAdapter } from './models/notificationAdapter';
|
||||
import createLoadingPlugin from '@rematch/loading';
|
||||
import { provider } from './models/provider';
|
||||
import { createLogger } from 'redux-logger';
|
||||
import { jobs } from './models/jobs';
|
||||
import { user } from './models/user';
|
||||
import { init } from '@rematch/core';
|
||||
|
||||
const middleware = [];
|
||||
|
||||
if (process.env.NODE_ENV === 'development') {
|
||||
// eslint-disable-line no-redeclare
|
||||
middleware.push(createLogger({ duration: false, collapsed: (getState, action, logEntry) => !logEntry.error }));
|
||||
}
|
||||
|
||||
const store = init({
|
||||
name: 'fredy',
|
||||
models: {
|
||||
notificationAdapter,
|
||||
provider,
|
||||
jobs,
|
||||
user,
|
||||
},
|
||||
plugins: [createLoadingPlugin({})],
|
||||
redux: {
|
||||
middlewares: middleware,
|
||||
},
|
||||
});
|
||||
|
||||
export const reduxStore = store;
|
||||
12
ui/src/services/time/timeService.js
Normal file
12
ui/src/services/time/timeService.js
Normal file
@@ -0,0 +1,12 @@
|
||||
export function format(ts) {
|
||||
return new Intl.DateTimeFormat('default', {
|
||||
year: 'numeric',
|
||||
month: 'numeric',
|
||||
day: 'numeric',
|
||||
hour: 'numeric',
|
||||
minute: 'numeric',
|
||||
second: 'numeric',
|
||||
}).format(ts);
|
||||
}
|
||||
|
||||
export const roundToNext5Minute = (ts) => Math.ceil(ts / (1000 * 60 * 5)) * (1000 * 60 * 5);
|
||||
@@ -0,0 +1,13 @@
|
||||
export function transform({ id, name, fields }) {
|
||||
const fieldValues = {};
|
||||
|
||||
Object.keys(fields).map((key) => {
|
||||
fieldValues[key] = fields[key].value;
|
||||
});
|
||||
|
||||
return {
|
||||
id,
|
||||
name,
|
||||
fields: fieldValues,
|
||||
};
|
||||
}
|
||||
8
ui/src/services/transformer/providerTransformer.js
Normal file
8
ui/src/services/transformer/providerTransformer.js
Normal file
@@ -0,0 +1,8 @@
|
||||
export function transform({ name, id, enabled, url }) {
|
||||
return {
|
||||
name,
|
||||
id,
|
||||
enabled,
|
||||
url,
|
||||
};
|
||||
}
|
||||
140
ui/src/services/xhr.js
Normal file
140
ui/src/services/xhr.js
Normal file
@@ -0,0 +1,140 @@
|
||||
/**
|
||||
* post something to our backend.
|
||||
*
|
||||
* @param url
|
||||
* @param data based on the content type, you need to make sure to parse in the proper data
|
||||
* @param contentType default is json
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function xhrPost(url, data, contentType = 'application/json; charset=utf-8', isJson = true) {
|
||||
return executePostOrPutCall(url, contentType, data, isJson, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* put request to backend.
|
||||
*
|
||||
* @param url
|
||||
* @param data based on the content type, you need to make sure to parse in the proper data
|
||||
* @param contentType default is json
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function xhrPut(url, data, contentType = 'application/json; charset=utf-8', isJson = true) {
|
||||
return executePostOrPutCall(url, contentType, data, isJson, false);
|
||||
}
|
||||
|
||||
function executePostOrPutCall(url, contentType, data, isJson, isPost) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(url, {
|
||||
method: isPost ? 'POST' : 'PUT',
|
||||
cache: 'no-cache',
|
||||
credentials: 'include',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
body: data == null ? JSON.stringify({}) : JSON.stringify(data),
|
||||
})
|
||||
.then((response) => (isJson ? parseJSON(response) : response))
|
||||
.then((response) => resolve(response))
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* get request to backend
|
||||
* returns a Promise with
|
||||
* {
|
||||
* status: statusCode,
|
||||
* json: values
|
||||
* }
|
||||
*
|
||||
* if an error occurs, the promise rejects with
|
||||
* {
|
||||
* json: errors: ['error', 'error']
|
||||
* }
|
||||
* @param url
|
||||
* @param contentType
|
||||
* @param isJson
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function xhrGet(url, contentType = 'application/json; charset=utf-8', isJson = true) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(url, {
|
||||
credentials: 'include',
|
||||
mode: 'cors',
|
||||
headers: {
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
})
|
||||
.then((response) => (isJson ? parseJSON(response) : response))
|
||||
.then((response) => resolve(response))
|
||||
.catch((error) => {
|
||||
reject(error);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* delete request to backend
|
||||
* returns a Promise with
|
||||
* {
|
||||
* status: statusCode,
|
||||
* json: values
|
||||
* }
|
||||
*
|
||||
* if an error occurs, the promise rejects with
|
||||
* {
|
||||
* json: errors: ['error', 'error']
|
||||
* }
|
||||
* @param url
|
||||
* @param data
|
||||
* @returns {Promise}
|
||||
*/
|
||||
export function xhrDelete(url, data, contentType = 'application/json; charset=utf-8') {
|
||||
return new Promise((resolve, reject) => {
|
||||
fetch(url, {
|
||||
method: 'DELETE',
|
||||
credentials: 'include',
|
||||
mode: 'cors',
|
||||
body: data == null ? JSON.stringify({}) : JSON.stringify(data),
|
||||
headers: {
|
||||
'Content-Type': contentType,
|
||||
},
|
||||
})
|
||||
.then((response) => parseJSON(response))
|
||||
.then((response) => resolve(response))
|
||||
.catch((error) => {
|
||||
if (error.json != null && error.json.message != null) {
|
||||
reject(error.json.message);
|
||||
} else {
|
||||
reject({ errors: [`Unspecified Network error`] });
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function parseJSON(response) {
|
||||
return new Promise((resolve, reject) =>
|
||||
response
|
||||
.text()
|
||||
.then((text) => {
|
||||
//some responses doesn't contain a body. .json() would throw errors here...
|
||||
const json = text != null && text.length > 0 ? JSON.parse(text) : {};
|
||||
|
||||
if (response.ok) {
|
||||
resolve({
|
||||
status: response.status,
|
||||
json,
|
||||
});
|
||||
} else {
|
||||
reject({
|
||||
status: response.status,
|
||||
json,
|
||||
});
|
||||
}
|
||||
})
|
||||
.catch((error) => reject('Error while trying to parse json.', error))
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user