build electron app

implement new fetch api calls
use typescript
This commit is contained in:
2020-12-17 20:53:22 +00:00
parent c049aa345c
commit 7d696122fa
43 changed files with 804 additions and 500 deletions

88
src/utils/Api.ts Normal file
View File

@ -0,0 +1,88 @@
let customBackendURL: string;
/**
* get the domain of the api backend
* @return string domain of backend http://x.x.x.x/bla
*/
export function getBackendDomain(): string {
let userAgent = navigator.userAgent.toLowerCase();
if (userAgent.indexOf(' electron/') > -1) {
// Electron-specific code - force a custom backendurl
return (customBackendURL);
} else {
// use custom only if defined
if (customBackendURL) {
return (customBackendURL);
} else {
return (window.location.origin);
}
}
}
/**
* set a custom backend domain
* @param domain a url in format [http://x.x.x.x/somanode]
*/
export function setCustomBackendDomain(domain: string) {
customBackendURL = domain;
}
/**
* a helper function to get the api path
*/
function getAPIDomain(): string {
return getBackendDomain() + '/api/';
}
/**
* interface how an api request should look like
*/
interface ApiBaseRequest {
action: string,
[_: string]: string
}
/**
* helper function to build a formdata for requesting post data correctly
* @param args api request object
*/
function buildFormData(args: ApiBaseRequest): FormData {
const req = new FormData();
for (const i in args) {
req.append(i, args[i]);
}
return req;
}
/**
* A backend api call
* @param apinode which api backend handler to call
* @param fd the object to send to backend
* @param callback the callback with json reply from backend
* @param errorcallback a optional callback if an error occured
*/
export function callAPI(apinode: string, fd: ApiBaseRequest, callback: (_: object) => void, errorcallback: (_: object) => void = (_: object) => {
}): void {
fetch(getAPIDomain() + apinode, {method: 'POST', body: buildFormData(fd)})
.then((response) => response.json()
.then((result) => {
callback(result);
})).catch(reason => errorcallback(reason));
}
/**
* A backend api call
* @param apinode which api backend handler to call
* @param fd the object to send to backend
* @param callback the callback with PLAIN text reply from backend
*/
export function callAPIPlain(apinode: string, fd: ApiBaseRequest, callback: (_: any) => void): void {
fetch(getAPIDomain() + apinode, {method: 'POST', body: buildFormData(fd)})
.then((response) => response.text()
.then((result) => {
callback(result);
}));
}

54
src/utils/GlobalInfos.js Normal file
View File

@ -0,0 +1,54 @@
import darktheme from '../AppDarkTheme.module.css';
import lighttheme from '../AppLightTheme.module.css';
/**
* This class is available for all components in project
* it contains general infos about app - like theme
*/
class StaticInfos {
#darktheme = true;
#viewbinding = () => {console.warn('Viewbinding not set now!');};
/**
* check if the current theme is the dark theme
* @returns {boolean} is dark theme?
*/
isDarkTheme() {
return this.#darktheme;
};
/**
* setter to enable or disable the dark or light theme
* @param enable enable the dark theme?
*/
enableDarkTheme(enable = true) {
this.#darktheme = enable;
}
/**
* get the currently selected theme stylesheet
* @returns {*} the style object of the current active theme
*/
getThemeStyle() {
return this.isDarkTheme() ? darktheme : lighttheme;
}
/**
* set the global Viewbinding for the main Navigation
* @param cb
*/
setViewBinding(cb) {
this.#viewbinding = cb;
}
/**
* return the Viewbinding for main navigation
* @returns {StaticInfos.viewbinding}
*/
getViewBinding() {
return this.#viewbinding;
}
}
const GlobalInfos = new StaticInfos();
export default GlobalInfos;

View File

@ -0,0 +1,24 @@
import React from 'react';
import GlobalInfos from './GlobalInfos';
describe('<GlobalInfos/>', function () {
it('always same instance ', function () {
GlobalInfos.enableDarkTheme(true);
expect(GlobalInfos.isDarkTheme()).toBe(true);
GlobalInfos.enableDarkTheme(false);
expect(GlobalInfos.isDarkTheme()).toBe(false);
});
it('test default theme', function () {
expect(GlobalInfos.isDarkTheme()).toBe(false);
});
it('test receive of stylesheet', function () {
const style = GlobalInfos.getThemeStyle();
expect(style.navitem).not.toBeNull();
});
});