1
0
mirror of https://gitlab.nic.cz/turris/reforis/foris-js.git synced 2025-06-15 13:36:35 +02:00

Compare commits

...

24 Commits

Author SHA1 Message Date
1e6278abdf Merge branch 'dev' into 'master'
Release 3.0.0

See merge request turris/reforis/foris-js!68
2020-01-07 16:10:16 +01:00
6769e84e62 Merge branch 'version-3.0.0' into 'dev'
Version 3.0.0

See merge request turris/reforis/foris-js!69
2020-01-07 15:57:28 +01:00
71b0a9a5fa Version 3.0.0 [skip ci] 2020-01-07 15:37:07 +01:00
418e38de31 Merge branch 'form-widgets-size' into 'dev'
Form widgets size

See merge request turris/reforis/foris-js!66
2020-01-07 13:27:50 +01:00
56a4c47948 Form widgets size 2020-01-07 13:27:49 +01:00
c67ad164ce Merge branch 'pack-without-src' into 'dev'
Make packing without src.

See merge request turris/reforis/foris-js!67
2020-01-07 13:07:44 +01:00
6374fd5adf Make packing without src. 2020-01-07 13:03:55 +01:00
cc13e9c164 Merge branch 'no-babel' into 'dev'
No babel

See merge request turris/reforis/foris-js!64
2020-01-07 11:12:17 +01:00
bb90800945 Merge branch 'dev' into 'master'
Release 2.1.1

See merge request turris/reforis/foris-js!65
2020-01-06 09:56:29 +01:00
6d4bff2b4f Merge branch 'datepicker' into 'dev'
Display datepicker above input

Closes reforis#153

See merge request turris/reforis/foris-js!63
2020-01-06 09:45:16 +01:00
92f560b69f Display datepicker above input 2020-01-06 09:45:16 +01:00
32e3a57bd7 Fix source files path. 2019-12-27 12:10:19 +01:00
dd27802056 Fix relative imports. 2019-12-27 12:10:19 +01:00
bd4e1953e3 Don't use babel. 2019-12-27 12:10:19 +01:00
68e4368ae3 npm audit fix. 2019-12-27 12:10:19 +01:00
51ba380cf0 Merge branch 'dev' into 'master'
Release 2.1.0

See merge request turris/reforis/foris-js!62
2019-12-19 12:10:18 +01:00
4eae1ed8d2 Merge branch 'ws-logging' into 'dev'
Changed levels of WS logs

Closes reforis#162

See merge request turris/reforis/foris-js!61
2019-12-19 11:58:59 +01:00
3d290114fa Changed levels of WS logs 2019-12-17 17:45:55 +01:00
3f87e9e4b4 Merge branch 'export-radio' into 'dev'
Export <Radio />.

See merge request turris/reforis/foris-js!60
2019-12-17 14:07:14 +01:00
6d5cb6a951 Export <Radio />. 2019-12-17 14:04:06 +01:00
8d3be8df67 Merge branch 'click-outside-hook' into 'dev'
Detect clicks outside element with a hook

See merge request turris/reforis/foris-js!59
2019-12-16 16:21:18 +01:00
90509f2a23 Detect clicks outside element with a hook 2019-12-16 13:44:58 +01:00
73f84a2d81 Merge branch '8-fix-git-link' into 'dev'
Fixed link to git repository

Closes #8

See merge request turris/reforis/foris-js!58
2019-12-09 12:45:01 +01:00
cea7325427 Fixed link to git repository 2019-12-09 11:51:50 +01:00
34 changed files with 1021 additions and 675 deletions

View File

@ -35,11 +35,6 @@ $(VENV_NAME)/bin/activate:
install-js: package.json
npm install --save-dev
watch-js:
npm run build:watch
build-js:
npm run build
collect-files:
sh scripts/collect_files.sh
pack: collect-files

View File

@ -1 +0,0 @@
[javascript: src/**.js]

1436
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +1,18 @@
{
"name": "foris",
"version": "2.0.0",
"version": "3.0.0",
"description": "Set of components and utils for Foris and its plugins.",
"author": "CZ.NIC, z.s.p.o.",
"repository": {
"type": "git",
"url": "https://gitlab.labs.nic.cz/turris/reforis/forisjs.git"
"url": "https://gitlab.labs.nic.cz/turris/reforis/foris-js.git"
},
"keywords": [
"foris",
"reforis"
],
"license": "GPL-3.0",
"main": "index.js",
"main": "./index.js",
"dependencies": {
"axios": "^0.19.0",
"jest-transform-css": "^2.0.0",
@ -44,7 +44,7 @@
"babel-plugin-react-transform": "^3.0.0",
"babel-polyfill": "^6.26.0",
"bootstrap": "^4.3.1",
"copy-webpack-plugin": "^5.0.4",
"copy-webpack-plugin": "^5.1.1",
"css-loader": "^3.2.0",
"eslint": "^6.1.0",
"eslint-config-reforis": "^1.0.0",
@ -56,14 +56,12 @@
"moment-timezone": "^0.5.25",
"react": "16.9.0",
"react-dom": "16.9.0",
"react-styleguidist": "^9.1.16",
"react-styleguidist": "^10.3.2",
"snapshot-diff": "^0.5.1",
"style-loader": "^1.0.0",
"webpack": "^4.41.0"
},
"scripts": {
"build": "rm -rf dist; babel src --out-dir dist --source-maps inline --copy-files",
"build:watch": "babel src --verbose --watch --out-dir dist --source-maps inline --copy-files",
"lint": "eslint src",
"test": "jest",
"test:watch": "jest --watch",

View File

@ -1,8 +1,9 @@
#!/bin/sh
# Collect files
npm run build
cp package.json README.md dist
mkdir -p dist
cp -rf ./src/* dist
cp package.json package-lock.json README.md dist
cp -rf translations dist
# Remove unwanted files
rm -rf dist/**/__tests__

View File

@ -8,8 +8,8 @@
import React, { useState, useContext, useCallback } from "react";
import PropTypes from "prop-types";
import { Alert, ALERT_TYPES } from "bootstrap/Alert";
import { Portal } from "utils/Portal";
import { Alert, ALERT_TYPES } from "../bootstrap/Alert";
import { Portal } from "../utils/Portal";
AlertContextProvider.propTypes = {
children: PropTypes.oneOfType([

View File

@ -9,7 +9,7 @@ import {
useCallback, useEffect, useReducer, useState,
} from "react";
import { ForisURLs } from "forisUrls";
import { ForisURLs } from "../forisUrls";
import {
API_ACTIONS, API_METHODS, API_STATE, getErrorPayload, HEADERS, TIMEOUT,
} from "./utils";

View File

@ -8,11 +8,6 @@
import React from "react";
import PropTypes from "prop-types";
const OFFSET = 8;
const SIZE = 3;
const SIZE_CLASS = ` offset-lg-${OFFSET} col-lg-${SIZE}`;
const SIZE_CLASS_SM = " col-sm-12";
Button.propTypes = {
/** Additional class name. */
className: PropTypes.string,
@ -32,14 +27,16 @@ Button.propTypes = {
export function Button({
className, loading, forisFormSize, children, ...props
}) {
className = className ? `btn ${className}` : "btn btn-primary ";
if (forisFormSize) className += SIZE_CLASS + SIZE_CLASS_SM;
let buttonClass = className ? `btn ${className}` : "btn btn-primary ";
if (forisFormSize) {
buttonClass = `${buttonClass} col-sm-12 col-lg-3`;
}
const span = loading
? <span className="spinner-border spinner-border-sm" role="status" aria-hidden="true" /> : null;
return (
<button type="button" className={className} {...props}>
<button type="button" className={buttonClass} {...props}>
{span}
{" "}
{span ? " " : null}

View File

@ -9,30 +9,25 @@ import React from "react";
import PropTypes from "prop-types";
import { useUID } from "react-uid";
import { formFieldsSize } from "./constants";
CheckBox.propTypes = {
/** Label message */
label: PropTypes.string.isRequired,
/** Help text message */
helpText: PropTypes.string,
/** Apply default size (full-width) */
useDefaultSize: PropTypes.bool,
/** Control if checkbox is clickable */
disabled: PropTypes.bool,
};
CheckBox.defaultProps = {
useDefaultSize: true,
disabled: false,
};
export function CheckBox({
label, helpText, useDefaultSize, disabled, ...props
label, helpText, disabled, ...props
}) {
const uid = useUID();
return (
<div className={`form-group ${useDefaultSize ? formFieldsSize : ""}`.trim()}>
<div className="form-group">
<div className="custom-control custom-checkbox ">
<input
className="custom-control-input"

View File

@ -0,0 +1,4 @@
/* Override defaults from "react-datetime" - display picker above input */
.rdtPicker {
bottom: 0;
}

View File

@ -10,6 +10,7 @@ import PropTypes from "prop-types";
import Datetime from "react-datetime/DateTime";
import moment from "moment/moment";
import "react-datetime/css/react-datetime.css";
import "./DataTimeInput.css";
import { Input } from "./Input";

View File

@ -6,8 +6,8 @@
*/
import React from "react";
import PropTypes from "prop-types";
import { Input } from "./Input";
export const EmailInput = ({ ...props }) => <Input type="email" {...props} />;

View File

@ -9,8 +9,6 @@ import React from "react";
import { useUID } from "react-uid";
import PropTypes from "prop-types";
import { formFieldsSize } from "./constants";
Input.propTypes = {
type: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
@ -32,7 +30,7 @@ export function Input({
const uid = useUID();
const inputClassName = `form-control ${className || ""} ${(error ? "is-invalid" : "")}`.trim();
return (
<div className={`form-group ${formFieldsSize}`}>
<div className="form-group">
<label className={labelClassName} htmlFor={uid}>{label}</label>
<div className={`input-group ${groupClassName || ""}`.trim()}>
<input

View File

@ -5,10 +5,11 @@
* See /LICENSE for more information.
*/
import React, { useEffect, useRef } from "react";
import React, { useRef } from "react";
import PropTypes from "prop-types";
import { Portal } from "utils/Portal";
import { Portal } from "../utils/Portal";
import { useClickOutside } from "../utils/hooks";
Modal.propTypes = {
/** Is modal shown value */
@ -26,16 +27,7 @@ Modal.propTypes = {
export function Modal({ shown, setShown, children }) {
const dialogRef = useRef();
useEffect(() => {
function handleClickOutsideDialog(e) {
if (!dialogRef.current.contains(e.target)) setShown(false);
}
document.addEventListener("mousedown", handleClickOutsideDialog);
return () => {
document.removeEventListener("mousedown", handleClickOutsideDialog);
};
}, [setShown]);
useClickOutside(dialogRef, () => setShown(false));
return (
<Portal containerId="modal-container">

View File

@ -8,7 +8,7 @@
import React from "react";
import PropTypes from "prop-types";
import { useConditionalTimeout } from "utils/hooks";
import { useConditionalTimeout } from "../utils/hooks";
import { Input } from "./Input";
import "./NumberInput.css";

View File

@ -9,8 +9,6 @@ import React from "react";
import PropTypes from "prop-types";
import { useUID } from "react-uid";
import { formFieldsSize } from "./constants";
RadioSet.propTypes = {
/** Name attribute of the input HTML tag. */
name: PropTypes.string.isRequired,
@ -51,7 +49,7 @@ export function RadioSet({
});
return (
<div className={`form-group ${formFieldsSize}`}>
<div className="form-group">
{label && <label htmlFor={uid} className="d-block">{label}</label>}
{radios}
{helpText && <small className="form-text text-muted">{helpText}</small>}
@ -65,7 +63,7 @@ Radio.propTypes = {
helpText: PropTypes.string,
};
function Radio({
export function Radio({
label, id, helpText, ...props
}) {
return (

View File

@ -33,7 +33,7 @@ export function Select({
);
return (
<div className="form-group col-sm-12 offset-lg-1 col-lg-10">
<div className="form-group">
<label htmlFor={uid}>{label}</label>
<select
className="custom-select"

View File

@ -2,7 +2,7 @@
exports[`<Checkbox/> Render checkbox 1`] = `
<div
class="form-group col-sm-12 offset-lg-1 col-lg-10"
class="form-group"
>
<div
class="custom-control custom-checkbox "
@ -30,7 +30,7 @@ exports[`<Checkbox/> Render checkbox 1`] = `
exports[`<Checkbox/> Render uncheked checkbox 1`] = `
<div
class="form-group col-sm-12 offset-lg-1 col-lg-10"
class="form-group"
>
<div
class="custom-control custom-checkbox "

View File

@ -2,7 +2,7 @@
exports[`<NumberInput/> Render number input 1`] = `
<div
class="form-group col-sm-12 offset-lg-1 col-lg-10"
class="form-group"
>
<label
for="1"

View File

@ -2,7 +2,7 @@
exports[`<PasswordInput/> Render password input 1`] = `
<div
class="form-group col-sm-12 offset-lg-1 col-lg-10"
class="form-group"
>
<label
for="1"

View File

@ -2,7 +2,7 @@
exports[`<RadioSet/> Render radio set 1`] = `
<div
class="form-group col-sm-12 offset-lg-1 col-lg-10"
class="form-group"
>
<label
class="d-block"

View File

@ -3,7 +3,7 @@
exports[`<Select/> Test with snapshot. 1`] = `
<div>
<div
class="form-group col-sm-12 offset-lg-1 col-lg-10"
class="form-group"
>
<label
for="1"

View File

@ -2,7 +2,7 @@
exports[`<TextInput/> Render text input 1`] = `
<div
class="form-group col-sm-12 offset-lg-1 col-lg-10"
class="form-group"
>
<label
for="1"

View File

@ -7,4 +7,4 @@
/** Bootstrap column size for form fields */
// eslint-disable-next-line import/prefer-default-export
export const formFieldsSize = "col-sm-12 offset-lg-1 col-lg-10";
export const formFieldsSize = "col-sm-12 offset-lg-1 col-lg-10 p-0 mb-3";

View File

@ -8,15 +8,15 @@
import React, { useState, useEffect } from "react";
import PropTypes from "prop-types";
import { useAPIPost } from "api/hooks";
import { API_STATE } from "api/utils";
import { ForisURLs } from "forisUrls";
import { useAPIPost } from "../api/hooks";
import { API_STATE } from "../api/utils";
import { ForisURLs } from "../forisUrls";
import { Button } from "bootstrap/Button";
import { Button } from "../bootstrap/Button";
import {
Modal, ModalHeader, ModalBody, ModalFooter,
} from "bootstrap/Modal";
import { useAlert } from "alertContext/AlertContext";
} from "../bootstrap/Modal";
import { useAlert } from "../alertContext/AlertContext";
RebootButton.propTypes = {
forisFormSize: PropTypes.bool,

View File

@ -3,7 +3,7 @@
exports[`<SubmitButton/> Render load 1`] = `
<div>
<button
class="btn btn-primary offset-lg-8 col-lg-3 col-sm-12"
class="btn btn-primary col-sm-12 col-lg-3"
disabled=""
type="submit"
>
@ -23,7 +23,7 @@ exports[`<SubmitButton/> Render load 1`] = `
exports[`<SubmitButton/> Render ready 1`] = `
<div>
<button
class="btn btn-primary offset-lg-8 col-lg-3 col-sm-12"
class="btn btn-primary col-sm-12 col-lg-3"
type="submit"
>
@ -36,7 +36,7 @@ exports[`<SubmitButton/> Render ready 1`] = `
exports[`<SubmitButton/> Render saving 1`] = `
<div>
<button
class="btn btn-primary offset-lg-8 col-lg-3 col-sm-12"
class="btn btn-primary col-sm-12 col-lg-3"
disabled=""
type="submit"
>

View File

@ -10,6 +10,7 @@ import React from 'react';
import { act, fireEvent, render, waitForElement } from 'customTestRender';
import mockAxios from 'jest-mock-axios';
import { ForisForm } from "../components/ForisForm";
import { WebSockets } from "webSockets/WebSockets";
// It's possible to unittest each hooks via react-hooks-testing-library.
@ -30,7 +31,6 @@ describe('useForm hook.', () => {
let mockValidator;
let mockPrepData;
let mockPrepDataToSubmit;
let mockWebSockets;
let input;
let form;
const Child = jest.fn(props => <TestForm {...props}/>);
@ -41,7 +41,7 @@ describe('useForm hook.', () => {
mockValidator = jest.fn(data => data.field === 'invalidValue' ? {field: 'Error'} : {});
const {getByTestId, container} = render(
<ForisForm
ws={mockWebSockets}
ws={new WebSockets()}
// Just some module which exists...
forisConfig={{
endpoint: 'testEndpoint',
@ -59,7 +59,7 @@ describe('useForm hook.', () => {
input = await waitForElement(() =>
getByTestId('test-input')
);
form = container.firstChild
form = container.firstChild.firstChild;
});
it('Validation on changing.', () => {

View File

@ -7,15 +7,16 @@
import React, { useEffect } from "react";
import PropTypes from "prop-types";
import { Spinner } from "bootstrap/Spinner";
import { useAPIPost } from "api/hooks";
import { Prompt } from "react-router";
import { API_STATE } from "api/utils";
import { ErrorMessage } from "utils/ErrorMessage";
import { useAlert } from "alertContext/AlertContext";
import { ALERT_TYPES } from "bootstrap/Alert";
import { ALERT_TYPES } from "../../bootstrap/Alert";
import { API_STATE } from "../../api/utils";
import { ErrorMessage } from "../../utils/ErrorMessage";
import { formFieldsSize } from "../../bootstrap/constants";
import { Spinner } from "../../bootstrap/Spinner";
import { useAlert } from "../../alertContext/AlertContext";
import { useAPIPost } from "../../api/hooks";
import { useForisModule, useForm } from "../hooks";
import { STATES as SUBMIT_BUTTON_STATES, SubmitButton } from "./SubmitButton";
@ -154,15 +155,17 @@ export function ForisForm({
}
return (
<>
<div className={formFieldsSize}>
<Prompt message={getMessageOnLeavingPage} />
<form onSubmit={onSubmit}>
{childrenWithFormProps}
<SubmitButton
state={getSubmitButtonState()}
disabled={submitButtonIsDisabled}
/>
<div className="text-right">
<SubmitButton
state={getSubmitButtonState()}
disabled={submitButtonIsDisabled}
/>
</div>
</form>
</>
</div>
);
}

View File

@ -8,7 +8,7 @@
import React from "react";
import PropTypes from "prop-types";
import { Button } from "bootstrap/Button";
import { Button } from "../../bootstrap/Button";
export const STATES = {
READY: 1,

View File

@ -8,8 +8,8 @@
import { useCallback, useEffect, useReducer } from "react";
import update from "immutability-helper";
import { useAPIGet } from "api/hooks";
import { useWSForisModule } from "webSockets/hooks";
import { useAPIGet } from "../api/hooks";
import { useWSForisModule } from "../webSockets/hooks";
const FORM_ACTIONS = {
updateValue: 1,

View File

@ -13,58 +13,59 @@ export {
useAPIPut,
useAPIDelete,
useAPIPolling,
} from "api/hooks";
export { API_STATE } from "api/utils";
} from "./api/hooks";
export { API_STATE } from "./api/utils";
// Bootstrap
export { Alert, ALERT_TYPES } from "bootstrap/Alert";
export { Button } from "bootstrap/Button";
export { CheckBox } from "bootstrap/CheckBox";
export { DownloadButton } from "bootstrap/DownloadButton";
export { DataTimeInput } from "bootstrap/DataTimeInput";
export { EmailInput } from "bootstrap/EmailInput";
export { FileInput } from "bootstrap/FileInput";
export { Input } from "bootstrap/Input";
export { NumberInput } from "bootstrap/NumberInput";
export { PasswordInput } from "bootstrap/PasswordInput";
export { RadioSet } from "bootstrap/RadioSet";
export { Select } from "bootstrap/Select";
export { TextInput } from "bootstrap/TextInput";
export { formFieldsSize } from "bootstrap/constants";
export { Alert, ALERT_TYPES } from "./bootstrap/Alert";
export { Button } from "./bootstrap/Button";
export { CheckBox } from "./bootstrap/CheckBox";
export { DownloadButton } from "./bootstrap/DownloadButton";
export { DataTimeInput } from "./bootstrap/DataTimeInput";
export { EmailInput } from "./bootstrap/EmailInput";
export { FileInput } from "./bootstrap/FileInput";
export { Input } from "./bootstrap/Input";
export { NumberInput } from "./bootstrap/NumberInput";
export { PasswordInput } from "./bootstrap/PasswordInput";
export { Radio, RadioSet } from "./bootstrap/RadioSet";
export { Select } from "./bootstrap/Select";
export { TextInput } from "./bootstrap/TextInput";
export { formFieldsSize } from "./bootstrap/constants";
export {
Spinner,
SpinnerElement,
} from "bootstrap/Spinner";
} from "./bootstrap/Spinner";
export {
Modal,
ModalBody,
ModalFooter,
ModalHeader,
} from "bootstrap/Modal";
} from "./bootstrap/Modal";
// Common
export { RebootButton } from "common/RebootButton";
export { RebootButton } from "./common/RebootButton";
// Form
export { ForisForm } from "form/components/ForisForm";
export { SubmitButton, STATES as SUBMIT_BUTTON_STATES } from "form/components/SubmitButton";
export { useForisModule, useForm } from "form/hooks";
export { ForisForm } from "./form/components/ForisForm";
export { SubmitButton, STATES as SUBMIT_BUTTON_STATES } from "./form/components/SubmitButton";
export { useForisModule, useForm } from "./form/hooks";
// WebSockets
export { useWSForisModule } from "webSockets/hooks";
export { WebSockets } from "webSockets/WebSockets";
export { useWSForisModule } from "./webSockets/hooks";
export { WebSockets } from "./webSockets/WebSockets";
// Utils
export { Portal } from "utils/Portal";
export { undefinedIfEmpty, withoutUndefinedKeys, onlySpecifiedKeys } from "utils/objectHelpers";
export { Portal } from "./utils/Portal";
export { undefinedIfEmpty, withoutUndefinedKeys, onlySpecifiedKeys } from "./utils/objectHelpers";
export {
withEither, withSpinner, withSending, withSpinnerOnSending, withError, withErrorMessage,
} from "utils/conditionalHOCs";
export { ErrorMessage } from "utils/ErrorMessage";
} from "./utils/conditionalHOCs";
export { ErrorMessage } from "./utils/ErrorMessage";
export { useClickOutside } from "./utils/hooks";
// Foris URL
export { ForisURLs, REFORIS_URL_PREFIX } from "forisUrls";
export { ForisURLs, REFORIS_URL_PREFIX } from "./forisUrls";
// Validation
export {
@ -75,7 +76,7 @@ export {
validateDUID,
validateMAC,
validateMultipleEmails,
} from "validations";
} from "./validations";
// Alert context
export { AlertContextProvider, useAlert } from "alertContext/AlertContext";
export { AlertContextProvider, useAlert } from "./alertContext/AlertContext";

View File

@ -7,8 +7,8 @@
import React from "react";
import { Spinner } from "bootstrap/Spinner";
import { API_STATE } from "api/utils";
import { Spinner } from "../bootstrap/Spinner";
import { API_STATE } from "../api/utils";
import { ErrorMessage } from "./ErrorMessage";
function withEither(conditionalFn, Either) {

View File

@ -18,3 +18,19 @@ export function useConditionalTimeout({ callback, timeout = 125 }, ...callbackAr
}, [condition, callback, timeout, callbackArgs]);
return setCondition;
}
/** Execute callback when user clicks outside specified element. */
export function useClickOutside(element, callback) {
function handleClickOutside(event) {
if (element.current && !element.current.contains(event.target)) {
callback(event);
}
}
useEffect(() => {
document.addEventListener("mousedown", handleClickOutside);
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
});
}

View File

@ -7,7 +7,7 @@
/* eslint no-console: "off" */
import { ForisURLs } from "forisUrls";
import { ForisURLs } from "../forisUrls";
const PROTOCOL = window.location.protocol === "http:" ? "ws" : "wss";
@ -25,18 +25,18 @@ export class WebSockets {
console.error("WS: Error observed, you aren't logged probably.");
window.location.replace(ForisURLs.login);
}
console.log(`WS: Error: ${e}`);
console.error(`WS: Error: ${e}`);
};
this.ws.onmessage = (e) => {
console.log(`WS: Received Message: ${e.data}`);
console.debug(`WS: Received Message: ${e.data}`);
const data = JSON.parse(e.data);
this.dispatch(data);
};
this.ws.onopen = () => {
console.log("WS: Connection open.");
console.debug("WS: Connection open.");
};
this.ws.onclose = () => {
console.log("WS: Connection closed.");
console.debug("WS: Connection closed.");
};
// callbacks[module][action]
@ -111,7 +111,7 @@ export class WebSockets {
chain = this.callbacks[json.module][json.action];
} catch (error) {
if (error instanceof TypeError) {
console.log(`Callback for this message wasn't found:${error.data}`);
console.warn(`Callback for this message wasn't found:${error.data}`);
} else throw error;
}