@firedesktop/react-base 2.1.25 → 3.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +162 -0
- package/README.md +174 -94
- package/dist/components/AppIcon.d.ts +20 -20
- package/dist/components/AppIcon.js +53 -64
- package/dist/components/AppIcon.js.map +1 -1
- package/dist/components/AppInput.d.ts +20 -20
- package/dist/components/AppInput.js +7 -18
- package/dist/components/AppInput.js.map +1 -1
- package/dist/components/AppPagination.d.ts +11 -11
- package/dist/components/AppPagination.js +63 -74
- package/dist/components/AppPagination.js.map +1 -1
- package/dist/components/Spin.d.ts +6 -6
- package/dist/components/Spin.js +21 -17
- package/dist/components/Spin.js.map +1 -1
- package/dist/components/Toaster/Toaster.d.ts +7 -7
- package/dist/components/Toaster/Toaster.js +41 -29
- package/dist/components/Toaster/Toaster.js.map +1 -1
- package/dist/components/Toaster/Types.d.ts +6 -6
- package/dist/components/Toaster/Types.js +1 -1
- package/dist/components/index.d.ts +7 -7
- package/dist/components/index.js +7 -7
- package/dist/index.d.ts +8 -7
- package/dist/index.js +8 -7
- package/dist/index.js.map +1 -1
- package/dist/utils/CurrencyUtiles.d.ts +4 -4
- package/dist/utils/CurrencyUtiles.js +35 -30
- package/dist/utils/CurrencyUtiles.js.map +1 -1
- package/dist/utils/DateUtils.d.ts +7 -7
- package/dist/utils/DateUtils.js +111 -100
- package/dist/utils/DateUtils.js.map +1 -1
- package/dist/utils/FileUtils.d.ts +5 -5
- package/dist/utils/FileUtils.js +73 -73
- package/dist/utils/FileUtils.js.map +1 -1
- package/dist/utils/Logger.d.ts +13 -0
- package/dist/utils/Logger.js +44 -0
- package/dist/utils/Logger.js.map +1 -0
- package/dist/utils/RegExValidation.d.ts +4 -4
- package/dist/utils/RegExValidation.js +19 -19
- package/dist/utils/UrlUtils.d.ts +4 -4
- package/dist/utils/UrlUtils.js +15 -15
- package/dist/utils/UrlUtils.js.map +1 -1
- package/dist/utils/configuration/ConfigurationLoader.d.ts +6 -6
- package/dist/utils/configuration/ConfigurationLoader.js +76 -75
- package/dist/utils/configuration/ConfigurationLoader.js.map +1 -1
- package/dist/utils/configuration/ConfigurationManager.d.ts +5 -5
- package/dist/utils/configuration/ConfigurationManager.js +96 -89
- package/dist/utils/configuration/ConfigurationManager.js.map +1 -1
- package/dist/utils/configuration/ConfigurationReturner.d.ts +9 -9
- package/dist/utils/configuration/ConfigurationReturner.js +70 -69
- package/dist/utils/configuration/ConfigurationReturner.js.map +1 -1
- package/dist/utils/configuration/index.d.ts +4 -4
- package/dist/utils/configuration/index.js +4 -4
- package/dist/utils/fetch/Types.d.ts +10 -10
- package/dist/utils/fetch/Types.js +1 -1
- package/dist/utils/fetch/fetchWrapper.d.ts +14 -14
- package/dist/utils/fetch/fetchWrapper.js +268 -233
- package/dist/utils/fetch/fetchWrapper.js.map +1 -1
- package/dist/utils/fetch/index.d.ts +3 -3
- package/dist/utils/fetch/index.js +3 -3
- package/dist/utils/index.d.ts +10 -9
- package/dist/utils/index.js +10 -9
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/labels/LanguageLoader.d.ts +7 -7
- package/dist/utils/labels/LanguageLoader.js +130 -100
- package/dist/utils/labels/LanguageLoader.js.map +1 -1
- package/dist/utils/labels/LanguageManager.d.ts +6 -6
- package/dist/utils/labels/LanguageManager.js +118 -110
- package/dist/utils/labels/LanguageManager.js.map +1 -1
- package/dist/utils/labels/LanguageReturner.d.ts +10 -10
- package/dist/utils/labels/LanguageReturner.js +70 -69
- package/dist/utils/labels/LanguageReturner.js.map +1 -1
- package/dist/utils/labels/index.d.ts +4 -4
- package/dist/utils/labels/index.js +4 -4
- package/docs/APP_ICON.md +82 -0
- package/docs/APP_INPUT.md +81 -0
- package/docs/APP_PAGINATION.md +61 -0
- package/docs/CONFIGURATION.md +105 -0
- package/docs/FETCH_WRAPPER.md +163 -0
- package/docs/LABELS.md +148 -0
- package/docs/LOGGER.md +112 -0
- package/docs/SECURITY_AUDIT_2026-02-05.md +468 -0
- package/docs/SPIN.md +45 -0
- package/docs/TOASTER.md +75 -0
- package/docs/UTILITIES.md +177 -0
- package/package.json +28 -38
- package/src/App.css +0 -12
- package/src/lib/components/AppIcon.tsx +0 -784
- package/src/lib/components/AppInput.tsx +0 -66
- package/src/lib/components/AppPagination.tsx +0 -124
- package/src/lib/components/Spin.tsx +0 -31
- package/src/lib/components/Toaster/Toaster.tsx +0 -50
- package/src/lib/components/Toaster/Types.ts +0 -11
- package/src/lib/components/index.ts +0 -8
- package/src/lib/index.ts +0 -15
- package/src/lib/styles/base.css +0 -392
- package/src/lib/styles/syncfusion_bootstrap4.css +0 -10
- package/src/lib/styles/toaster.css +0 -50
- package/src/lib/utils/CurrencyUtiles.ts +0 -48
- package/src/lib/utils/DateUtils.ts +0 -135
- package/src/lib/utils/FileUtils.ts +0 -40
- package/src/lib/utils/RegExValidation.ts +0 -49
- package/src/lib/utils/UrlUtils.ts +0 -17
- package/src/lib/utils/configuration/ConfigurationLoader.tsx +0 -43
- package/src/lib/utils/configuration/ConfigurationManager.ts +0 -38
- package/src/lib/utils/configuration/ConfigurationReturner.tsx +0 -39
- package/src/lib/utils/configuration/index.ts +0 -9
- package/src/lib/utils/fetch/Types.ts +0 -11
- package/src/lib/utils/fetch/fetchWrapper.ts +0 -174
- package/src/lib/utils/fetch/index.ts +0 -4
- package/src/lib/utils/index.ts +0 -11
- package/src/lib/utils/labels/LanguageLoader.tsx +0 -69
- package/src/lib/utils/labels/LanguageManager.ts +0 -61
- package/src/lib/utils/labels/LanguageReturner.tsx +0 -41
- package/src/lib/utils/labels/index.ts +0 -9
|
@@ -1,70 +1,71 @@
|
|
|
1
|
-
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
-
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
-
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
-
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
-
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
-
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
-
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
-
});
|
|
9
|
-
};
|
|
10
|
-
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
-
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
12
|
-
return g =
|
|
13
|
-
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
-
function step(op) {
|
|
15
|
-
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
-
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
-
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
-
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
-
switch (op[0]) {
|
|
20
|
-
case 0: case 1: t = op; break;
|
|
21
|
-
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
-
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
-
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
-
default:
|
|
25
|
-
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
-
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
-
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
-
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
-
if (t[2]) _.ops.pop();
|
|
30
|
-
_.trys.pop(); continue;
|
|
31
|
-
}
|
|
32
|
-
op = body.call(thisArg, _);
|
|
33
|
-
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
-
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
-
}
|
|
36
|
-
};
|
|
37
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
38
|
-
import React, { useEffect } from 'react';
|
|
39
|
-
import
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
_a.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
}
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
11
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
|
|
12
|
+
return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
13
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
14
|
+
function step(op) {
|
|
15
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
16
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
17
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
18
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
19
|
+
switch (op[0]) {
|
|
20
|
+
case 0: case 1: t = op; break;
|
|
21
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
22
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
23
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
24
|
+
default:
|
|
25
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
26
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
27
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
28
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
29
|
+
if (t[2]) _.ops.pop();
|
|
30
|
+
_.trys.pop(); continue;
|
|
31
|
+
}
|
|
32
|
+
op = body.call(thisArg, _);
|
|
33
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
34
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
38
|
+
import React, { useEffect } from 'react';
|
|
39
|
+
import Logger from '../Logger';
|
|
40
|
+
import LanguageManager from './LanguageManager';
|
|
41
|
+
export default function LanguageReturner(_a) {
|
|
42
|
+
var labels = _a.labels, language = _a.language, onLanguageLoad = _a.onLanguageLoad, path = _a.path;
|
|
43
|
+
var loadLabels = LanguageManager().loadLabels;
|
|
44
|
+
var fullPath = "".concat(path, "/").concat(language, ".json");
|
|
45
|
+
useEffect(function () {
|
|
46
|
+
function justAsync() {
|
|
47
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
48
|
+
return __generator(this, function (_a) {
|
|
49
|
+
switch (_a.label) {
|
|
50
|
+
case 0:
|
|
51
|
+
if (!(!labels || !labels.language || labels.language !== language)) return [3, 2];
|
|
52
|
+
Logger.debug("Loading Language Labels for this Path: ".concat(path, " in this fullpath: ").concat(fullPath));
|
|
53
|
+
return [4, loadLabels(fullPath).then(function (response) {
|
|
54
|
+
Logger.debug("Loaded Language Labels for this Path: ".concat(path, " in this fullpath: ").concat(fullPath), response);
|
|
55
|
+
onLanguageLoad(response);
|
|
56
|
+
}).catch(function (err) {
|
|
57
|
+
Logger.error("Problem loading the Path: ".concat(path, " Language Labels in this fullpath: ").concat(fullPath));
|
|
58
|
+
})];
|
|
59
|
+
case 1:
|
|
60
|
+
_a.sent();
|
|
61
|
+
_a.label = 2;
|
|
62
|
+
case 2: return [2];
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
justAsync();
|
|
68
|
+
}, [language]);
|
|
69
|
+
return (_jsx(React.Fragment, {}));
|
|
70
|
+
}
|
|
70
71
|
//# sourceMappingURL=LanguageReturner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LanguageReturner.js","sourceRoot":"","sources":["../../../src/lib/utils/labels/LanguageReturner.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAYhD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAoE;QAAlE,MAAM,YAAA,EAAE,QAAQ,cAAA,EAAE,cAAc,oBAAA,EAAE,IAAI,UAAA;IACrE,IAAA,UAAU,GAAK,eAAe,EAAE,WAAtB,CAAuB;IAEzC,IAAM,QAAQ,GAAG,UAAG,IAAI,cAAI,QAAQ,UAAO,CAAC;IAG5C,SAAS,CAAC;QACN,SAAe,SAAS;;;;;iCAChB,CAAA,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAA,EAA3D,cAA2D;4BAC3D,
|
|
1
|
+
{"version":3,"file":"LanguageReturner.js","sourceRoot":"","sources":["../../../src/lib/utils/labels/LanguageReturner.tsx"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzC,OAAO,MAAM,MAAM,WAAW,CAAC;AAC/B,OAAO,eAAe,MAAM,mBAAmB,CAAC;AAYhD,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,EAAoE;QAAlE,MAAM,YAAA,EAAE,QAAQ,cAAA,EAAE,cAAc,oBAAA,EAAE,IAAI,UAAA;IACrE,IAAA,UAAU,GAAK,eAAe,EAAE,WAAtB,CAAuB;IAEzC,IAAM,QAAQ,GAAG,UAAG,IAAI,cAAI,QAAQ,UAAO,CAAC;IAG5C,SAAS,CAAC;QACN,SAAe,SAAS;;;;;iCAChB,CAAA,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,CAAA,EAA3D,cAA2D;4BAC3D,MAAM,CAAC,KAAK,CAAC,iDAA0C,IAAI,gCAAsB,QAAQ,CAAE,CAAC,CAAC;4BAC7F,WAAM,UAAU,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,UAAC,QAAa;oCAC1C,MAAM,CAAC,KAAK,CAAC,gDAAyC,IAAI,gCAAsB,QAAQ,CAAE,EAAE,QAAQ,CAAC,CAAC;oCACtG,cAAc,CAAC,QAAQ,CAAC,CAAC;gCAC7B,CAAC,CAAC,CAAC,KAAK,CAAC,UAAC,GAAQ;oCACd,MAAM,CAAC,KAAK,CAAC,oCAA6B,IAAI,gDAAsC,QAAQ,CAAE,CAAC,CAAC;gCACpG,CAAC,CAAC,EAAA;;4BALF,SAKE,CAAC;;;;;;SAEV;QACD,SAAS,EAAE,CAAC;IAEhB,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC;IAEf,OAAO,CACH,KAAC,KAAK,CAAC,QAAQ,KACE,CACpB,CAAC;AACN,CAAC"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import LanguageLoader from './LanguageLoader';
|
|
2
|
-
import LanguageManager from './LanguageManager';
|
|
3
|
-
import LanguageReturner from './LanguageReturner';
|
|
4
|
-
export { LanguageLoader, LanguageManager, LanguageReturner };
|
|
1
|
+
import LanguageLoader from './LanguageLoader';
|
|
2
|
+
import LanguageManager from './LanguageManager';
|
|
3
|
+
import LanguageReturner from './LanguageReturner';
|
|
4
|
+
export { LanguageLoader, LanguageManager, LanguageReturner };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import LanguageLoader from './LanguageLoader';
|
|
2
|
-
import LanguageManager from './LanguageManager';
|
|
3
|
-
import LanguageReturner from './LanguageReturner';
|
|
4
|
-
export { LanguageLoader, LanguageManager, LanguageReturner };
|
|
1
|
+
import LanguageLoader from './LanguageLoader';
|
|
2
|
+
import LanguageManager from './LanguageManager';
|
|
3
|
+
import LanguageReturner from './LanguageReturner';
|
|
4
|
+
export { LanguageLoader, LanguageManager, LanguageReturner };
|
|
5
5
|
//# sourceMappingURL=index.js.map
|
package/docs/APP_ICON.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# AppIcon
|
|
2
|
+
|
|
3
|
+
SVG icon component with 40+ built-in icon variants.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import { Components } from '@firedesktop/react-base';
|
|
9
|
+
const { AppIcon } = Components;
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Required | Default | Description |
|
|
15
|
+
|------|------|----------|---------|-------------|
|
|
16
|
+
| `name` | `string` (union) | Yes | -- | Icon identifier (see list below) |
|
|
17
|
+
| `className` | `string` | Yes | -- | CSS class applied to the SVG `<path>` elements |
|
|
18
|
+
| `iconClassName` | `string` | Yes | -- | CSS class applied to the `<svg>` element |
|
|
19
|
+
| `iconHeight` | `number` | No | varies | SVG height in pixels |
|
|
20
|
+
| `iconWidth` | `number` | No | varies | SVG width in pixels |
|
|
21
|
+
| `fill` | `string` | No | `'none'` | SVG fill color |
|
|
22
|
+
| `stroke` | `string` | No | -- | SVG stroke color |
|
|
23
|
+
| `onClick` | `(event: React.MouseEvent<SVGSVGElement>) => void` | No | -- | Click handler |
|
|
24
|
+
| `ref` | `React.LegacyRef<SVGSVGElement>` | No | -- | Ref to the SVG element |
|
|
25
|
+
|
|
26
|
+
## Available Icons
|
|
27
|
+
|
|
28
|
+
### Actions
|
|
29
|
+
`add`, `edit`, `delete`, `list`, `link`, `unlink`, `shrink`, `upload`, `download`, `share`
|
|
30
|
+
|
|
31
|
+
### Navigation
|
|
32
|
+
`arrow-first`, `arrow-prev`, `arrow-next`, `arrow-last`, `expand`, `backicon`, `home`
|
|
33
|
+
|
|
34
|
+
### Form / Auth
|
|
35
|
+
`user`, `password`
|
|
36
|
+
|
|
37
|
+
### Status
|
|
38
|
+
`tickTrue`, `tickFalse`, `tickStep`, `circle`
|
|
39
|
+
|
|
40
|
+
### Domain
|
|
41
|
+
`document`, `company`, `plantMonitor`, `plantMissing`, `contact`, `userManagement`, `configurations`, `documentTemplate`, `registry`, `material`, `supply`, `delivery`, `table`
|
|
42
|
+
|
|
43
|
+
### UI
|
|
44
|
+
`eye`, `search`, `logo-main`, `unPin`, `Pin`, `pin-tilted`
|
|
45
|
+
|
|
46
|
+
## Usage
|
|
47
|
+
|
|
48
|
+
```jsx
|
|
49
|
+
<AppIcon
|
|
50
|
+
name="edit"
|
|
51
|
+
className="primary-svg"
|
|
52
|
+
iconClassName="my-icon"
|
|
53
|
+
iconWidth={24}
|
|
54
|
+
iconHeight={24}
|
|
55
|
+
fill="none"
|
|
56
|
+
stroke="#0057ff"
|
|
57
|
+
/>
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### With click handler
|
|
61
|
+
|
|
62
|
+
```jsx
|
|
63
|
+
<AppIcon
|
|
64
|
+
name="delete"
|
|
65
|
+
className="danger-svg"
|
|
66
|
+
iconClassName="action-icon"
|
|
67
|
+
onClick={() => handleDelete(item.id)}
|
|
68
|
+
/>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Styling with CSS utility classes
|
|
72
|
+
|
|
73
|
+
The library provides utility classes in `base.css` for coloring icons:
|
|
74
|
+
|
|
75
|
+
```jsx
|
|
76
|
+
{/* Fill-based coloring */}
|
|
77
|
+
<AppIcon name="tickTrue" className="success-svg" iconClassName="" />
|
|
78
|
+
<AppIcon name="tickFalse" className="danger-svg" iconClassName="" />
|
|
79
|
+
|
|
80
|
+
{/* Stroke-based coloring */}
|
|
81
|
+
<AppIcon name="edit" className="primary-svg-stroke" iconClassName="" />
|
|
82
|
+
```
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# AppInput
|
|
2
|
+
|
|
3
|
+
Input wrapper component with icon support, built on Bootstrap form classes.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import { Components } from '@firedesktop/react-base';
|
|
9
|
+
const { AppIcon, AppInput } = Components;
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Required | Default | Description |
|
|
15
|
+
|------|------|----------|---------|-------------|
|
|
16
|
+
| `appIcon` | `React.ReactNode` | Yes | -- | Icon element rendered alongside the input |
|
|
17
|
+
| `type` | `AppInputType_Type` | No | `'text'` | HTML input type |
|
|
18
|
+
| `value` | `string \| number` | No | -- | Controlled input value |
|
|
19
|
+
| `placeholder` | `string` | No | -- | Placeholder text |
|
|
20
|
+
| `onChange` | `(event: React.ChangeEvent<HTMLInputElement>) => void` | No | -- | Change handler |
|
|
21
|
+
| `onKeyUp` | `(event: React.KeyboardEvent<HTMLInputElement>) => void` | No | -- | Key up handler |
|
|
22
|
+
| `className` | `string` | No | -- | CSS class for the `<input>` element |
|
|
23
|
+
| `classNameWrapper` | `string` | No | -- | CSS class appended to the wrapper `<div>` |
|
|
24
|
+
| `id` | `string` | No | -- | Input ID attribute |
|
|
25
|
+
| `name` | `string` | No | -- | Input name attribute |
|
|
26
|
+
| `autoFocus` | `boolean` | No | `false` | Auto focus on mount |
|
|
27
|
+
| `autoComplete` | `boolean` | No | `true` | Browser autocomplete (`on`/`off`) |
|
|
28
|
+
| `ariadescribedby` | `string` | No | -- | ARIA described-by attribute |
|
|
29
|
+
| `ref` | `React.LegacyRef<HTMLInputElement>` | No | -- | Ref to the input element |
|
|
30
|
+
|
|
31
|
+
### Supported input types
|
|
32
|
+
|
|
33
|
+
`button`, `checkbox`, `color`, `date`, `datetime-local`, `email`, `file`, `hidden`, `image`, `month`, `number`, `password`, `radio`, `range`, `reset`, `search`, `submit`, `tel`, `text`, `url`, `week`
|
|
34
|
+
|
|
35
|
+
## Usage
|
|
36
|
+
|
|
37
|
+
```jsx
|
|
38
|
+
<AppInput
|
|
39
|
+
appIcon={<AppIcon name="search" className="primary-svg" iconClassName="" />}
|
|
40
|
+
placeholder="Search..."
|
|
41
|
+
value={query}
|
|
42
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
43
|
+
/>
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Password input
|
|
47
|
+
|
|
48
|
+
```jsx
|
|
49
|
+
<AppInput
|
|
50
|
+
appIcon={<AppIcon name="password" className="primary-svg" iconClassName="" />}
|
|
51
|
+
type="password"
|
|
52
|
+
placeholder="Enter password"
|
|
53
|
+
autoComplete={false}
|
|
54
|
+
/>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### With key handler
|
|
58
|
+
|
|
59
|
+
```jsx
|
|
60
|
+
<AppInput
|
|
61
|
+
appIcon={<AppIcon name="search" className="primary-svg" iconClassName="" />}
|
|
62
|
+
type="text"
|
|
63
|
+
placeholder="Search and press Enter"
|
|
64
|
+
value={query}
|
|
65
|
+
onChange={(e) => setQuery(e.target.value)}
|
|
66
|
+
onKeyUp={(e) => {
|
|
67
|
+
if (e.key === 'Enter') handleSearch();
|
|
68
|
+
}}
|
|
69
|
+
/>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## HTML Output
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<div class="form-group AppInput_form {classNameWrapper}">
|
|
76
|
+
<input class="form-control {className}" type="text" ... />
|
|
77
|
+
<!-- appIcon rendered here -->
|
|
78
|
+
</div>
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Requires Bootstrap `form-group` and `form-control` classes (peer dependency).
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# AppPagination
|
|
2
|
+
|
|
3
|
+
Bootstrap-based pagination component with smart page range calculation.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import { Components } from '@firedesktop/react-base';
|
|
9
|
+
const { AppPagination } = Components;
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
## Props
|
|
13
|
+
|
|
14
|
+
| Prop | Type | Required | Default | Description |
|
|
15
|
+
|------|------|----------|---------|-------------|
|
|
16
|
+
| `activePage` | `number` | Yes | -- | Current active page (1-based) |
|
|
17
|
+
| `totalItems` | `number` | Yes | -- | Total number of items across all pages |
|
|
18
|
+
| `itemsPerPage` | `number` | Yes | -- | Number of items displayed per page |
|
|
19
|
+
| `onPageChange` | `(page: number) => void` | Yes | -- | Callback when page changes |
|
|
20
|
+
| `maxSize` | `number` | No | `5` | Maximum number of page buttons visible |
|
|
21
|
+
| `pageFontSize` | `number` | No | `14` | Font size for page numbers in pixels |
|
|
22
|
+
| `className` | `string` | No | -- | CSS class for the `<nav>` element |
|
|
23
|
+
|
|
24
|
+
## Usage
|
|
25
|
+
|
|
26
|
+
```jsx
|
|
27
|
+
const [page, setPage] = useState(1);
|
|
28
|
+
const itemsPerPage = 10;
|
|
29
|
+
const totalItems = 87;
|
|
30
|
+
|
|
31
|
+
<AppPagination
|
|
32
|
+
activePage={page}
|
|
33
|
+
totalItems={totalItems}
|
|
34
|
+
itemsPerPage={itemsPerPage}
|
|
35
|
+
onPageChange={(newPage) => setPage(newPage)}
|
|
36
|
+
/>
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Custom page window size
|
|
40
|
+
|
|
41
|
+
```jsx
|
|
42
|
+
<AppPagination
|
|
43
|
+
activePage={page}
|
|
44
|
+
totalItems={200}
|
|
45
|
+
itemsPerPage={25}
|
|
46
|
+
maxSize={3}
|
|
47
|
+
onPageChange={setPage}
|
|
48
|
+
/>
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Behavior
|
|
52
|
+
|
|
53
|
+
- Shows first, previous, next, and last navigation arrows (using `AppIcon`)
|
|
54
|
+
- Displays a centered window of page numbers around the active page
|
|
55
|
+
- Automatically adjusts the window when near the first or last page
|
|
56
|
+
- Active page is highlighted with Bootstrap's `.active` class
|
|
57
|
+
- Navigation arrows are disabled when at boundaries (first/last page)
|
|
58
|
+
|
|
59
|
+
## Dependencies
|
|
60
|
+
|
|
61
|
+
Requires Bootstrap `pagination` CSS classes (peer dependency).
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Configuration
|
|
2
|
+
|
|
3
|
+
Runtime configuration loader that fetches a JSON file and stores it in Redux state or returns it via callback.
|
|
4
|
+
|
|
5
|
+
## Components
|
|
6
|
+
|
|
7
|
+
### ConfigurationLoader (Redux)
|
|
8
|
+
|
|
9
|
+
Headless component that loads configuration on mount and dispatches to Redux.
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
import { ConfigurationLoader } from '@firedesktop/react-base';
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
#### Props
|
|
16
|
+
|
|
17
|
+
| Prop | Type | Required | Default | Description |
|
|
18
|
+
|------|------|----------|---------|-------------|
|
|
19
|
+
| `updateAppState` | `(name: string, value: object) => any` | Yes | -- | Redux action creator |
|
|
20
|
+
| `path` | `string` | No | `'/configuration/config.json'` | Path to the JSON config file |
|
|
21
|
+
|
|
22
|
+
#### Usage
|
|
23
|
+
|
|
24
|
+
```jsx
|
|
25
|
+
import { ConfigurationLoader } from '@firedesktop/react-base';
|
|
26
|
+
import { Provider } from 'react-redux';
|
|
27
|
+
|
|
28
|
+
<Provider store={store}>
|
|
29
|
+
<ConfigurationLoader updateAppState={updateAppState} />
|
|
30
|
+
<App />
|
|
31
|
+
</Provider>
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
With a custom path:
|
|
35
|
+
|
|
36
|
+
```jsx
|
|
37
|
+
<ConfigurationLoader updateAppState={updateAppState} path="/settings/app.json" />
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### ConfigurationReturner (Callback)
|
|
41
|
+
|
|
42
|
+
For applications not using Redux. Loads configuration and calls a callback.
|
|
43
|
+
|
|
44
|
+
```javascript
|
|
45
|
+
import { ConfigurationReturner } from '@firedesktop/react-base';
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
#### Props
|
|
49
|
+
|
|
50
|
+
| Prop | Type | Required | Description |
|
|
51
|
+
|------|------|----------|-------------|
|
|
52
|
+
| `configuration` | `{ loaded: boolean }` | No | Current config state (prevents re-loading) |
|
|
53
|
+
| `onConfigurationLoad` | `(config?) => void` | Yes | Callback receiving the loaded config |
|
|
54
|
+
| `path` | `string` | Yes | Path to the JSON config file |
|
|
55
|
+
|
|
56
|
+
#### Usage
|
|
57
|
+
|
|
58
|
+
```jsx
|
|
59
|
+
<ConfigurationReturner
|
|
60
|
+
configuration={config}
|
|
61
|
+
onConfigurationLoad={(cfg) => setConfig({ ...cfg, loaded: true })}
|
|
62
|
+
path="/configuration/config.json"
|
|
63
|
+
/>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Configuration File Format
|
|
67
|
+
|
|
68
|
+
Place a JSON file in `public/configuration/config.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"apiBaseUrl": "https://api.example.com",
|
|
73
|
+
"appTitle": "My Application",
|
|
74
|
+
"features": {
|
|
75
|
+
"darkMode": true,
|
|
76
|
+
"notifications": false
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
The response must be a plain JSON object (not an array or primitive).
|
|
82
|
+
|
|
83
|
+
## Behavior
|
|
84
|
+
|
|
85
|
+
- Fetches with cache-busting timestamp query parameter
|
|
86
|
+
- Sets `Cache-Control`, `pragma`, `Expires`, and `X-Content-Type-Options` headers
|
|
87
|
+
- Validates HTTP status (`res.ok`) before parsing
|
|
88
|
+
- Validates the response is a plain object
|
|
89
|
+
- Dispatches as `updateAppState('configuration', response)` (Redux variant)
|
|
90
|
+
- Loads only once -- skips if `configuration.loaded` is already truthy
|
|
91
|
+
- Errors are logged via [Logger](LOGGER.md) (silent by default)
|
|
92
|
+
|
|
93
|
+
## Accessing Configuration
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
import { useSelector } from 'react-redux';
|
|
97
|
+
|
|
98
|
+
function MyComponent() {
|
|
99
|
+
const { configuration } = useSelector(state => state);
|
|
100
|
+
|
|
101
|
+
if (!configuration) return <Spin spinning={true} />;
|
|
102
|
+
|
|
103
|
+
return <div>{configuration.appTitle}</div>;
|
|
104
|
+
}
|
|
105
|
+
```
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
# FetchWrapper
|
|
2
|
+
|
|
3
|
+
HTTP client class with session-token authentication, configurable error handling, timeout support, and file upload capability.
|
|
4
|
+
|
|
5
|
+
## Import
|
|
6
|
+
|
|
7
|
+
```javascript
|
|
8
|
+
import { Utils } from '@firedesktop/react-base';
|
|
9
|
+
const FetchWrapper = Utils.Fetch;
|
|
10
|
+
|
|
11
|
+
const api = new FetchWrapper('v1', customLabels, handle401, handle403);
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Constructor
|
|
15
|
+
|
|
16
|
+
```typescript
|
|
17
|
+
new FetchWrapper(
|
|
18
|
+
apiVersion?: string,
|
|
19
|
+
labels?: ILabels,
|
|
20
|
+
status_401?: () => Promise<void>,
|
|
21
|
+
status_403?: () => Promise<void>
|
|
22
|
+
)
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
| Parameter | Type | Description |
|
|
26
|
+
|-----------|------|-------------|
|
|
27
|
+
| `apiVersion` | `string` | Sent as the `api-version` header on every request |
|
|
28
|
+
| `labels` | `ILabels` | Custom error messages (falls back to defaults if incomplete) |
|
|
29
|
+
| `status_401` | `() => Promise<void>` | Callback for 401 Unauthorized responses |
|
|
30
|
+
| `status_403` | `() => Promise<void>` | Callback for 403 Forbidden responses |
|
|
31
|
+
|
|
32
|
+
### ILabels
|
|
33
|
+
|
|
34
|
+
```typescript
|
|
35
|
+
interface ILabels {
|
|
36
|
+
errorBadRequest: string;
|
|
37
|
+
errorGeneric: string;
|
|
38
|
+
errorServerNotAvailable: string;
|
|
39
|
+
errorSessionExpired: string;
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Default labels are used if not provided:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
errorBadRequest: "Request is not in a valid format"
|
|
47
|
+
errorGeneric: "Sorry we have errors on the remote server"
|
|
48
|
+
errorServerNotAvailable: "Server not available"
|
|
49
|
+
errorSessionExpired: "Your session has expired, please login."
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Methods
|
|
53
|
+
|
|
54
|
+
All methods share the same signature and return `Promise<any>`.
|
|
55
|
+
|
|
56
|
+
### `get`, `post`, `put`, `delete`
|
|
57
|
+
|
|
58
|
+
```typescript
|
|
59
|
+
api.get(url, applicationName?, token?, onGenericServerError?, params?,
|
|
60
|
+
isFile?, isBlobInReturn?, additionalParams?, timeoutInMilli?)
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
| Parameter | Type | Default | Description |
|
|
64
|
+
|-----------|------|---------|-------------|
|
|
65
|
+
| `url` | `string` | -- | Request URL |
|
|
66
|
+
| `applicationName` | `string` | -- | Sent as `ApplicationName` header |
|
|
67
|
+
| `token` | `string` | -- | Sent as `SessionToken` header |
|
|
68
|
+
| `onGenericServerError` | `(status: number, error?: any) => void` | -- | Error callback for non-401/403 errors |
|
|
69
|
+
| `params` | `Blob \| any` | -- | Request body (JSON-serialized, or Blob for files) |
|
|
70
|
+
| `isFile` | `boolean` | `false` | Send as `FormData` with `file` field |
|
|
71
|
+
| `isBlobInReturn` | `boolean` | `false` | Parse response as `Blob` instead of JSON |
|
|
72
|
+
| `additionalParams` | `AdditionalParamsType[]` | `[]` | Extra form fields when uploading files |
|
|
73
|
+
| `timeoutInMilli` | `number` | `60000` | Request timeout in milliseconds |
|
|
74
|
+
|
|
75
|
+
### AdditionalParamsType
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
type AdditionalParamsType = {
|
|
79
|
+
name: string;
|
|
80
|
+
value: string | number;
|
|
81
|
+
};
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
## Usage
|
|
85
|
+
|
|
86
|
+
### Basic GET
|
|
87
|
+
|
|
88
|
+
```javascript
|
|
89
|
+
const api = new FetchWrapper('v1');
|
|
90
|
+
const data = await api.get('/api/users', 'MyApp', sessionToken);
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### POST with JSON body
|
|
94
|
+
|
|
95
|
+
```javascript
|
|
96
|
+
const newUser = { name: 'Alice', email: 'alice@example.com' };
|
|
97
|
+
const result = await api.post('/api/users', 'MyApp', sessionToken, null, newUser);
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### File upload
|
|
101
|
+
|
|
102
|
+
```javascript
|
|
103
|
+
const file = inputElement.files[0];
|
|
104
|
+
const result = await api.post(
|
|
105
|
+
'/api/upload', 'MyApp', sessionToken, null,
|
|
106
|
+
file, true, false,
|
|
107
|
+
[{ name: 'category', value: 'documents' }]
|
|
108
|
+
);
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Download as Blob
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
const blob = await api.get(
|
|
115
|
+
'/api/reports/export', 'MyApp', sessionToken,
|
|
116
|
+
null, null, false, true
|
|
117
|
+
);
|
|
118
|
+
const url = URL.createObjectURL(blob);
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### With error handling
|
|
122
|
+
|
|
123
|
+
```javascript
|
|
124
|
+
const api = new FetchWrapper(
|
|
125
|
+
'v1',
|
|
126
|
+
{ errorBadRequest: 'Bad request', errorGeneric: 'Error', errorServerNotAvailable: 'Offline', errorSessionExpired: 'Session expired' },
|
|
127
|
+
async () => { window.location.href = '/login'; }, // 401
|
|
128
|
+
async () => { alert('Access denied'); } // 403
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
try {
|
|
132
|
+
const data = await api.get('/api/data', 'MyApp', token, (status, error) => {
|
|
133
|
+
console.error(`Server error ${status}`, error);
|
|
134
|
+
});
|
|
135
|
+
} catch (err) {
|
|
136
|
+
// err is the error message string from labels
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Request Headers
|
|
141
|
+
|
|
142
|
+
Every request includes:
|
|
143
|
+
|
|
144
|
+
| Header | Value |
|
|
145
|
+
|--------|-------|
|
|
146
|
+
| `Cache-Control` | `no-cache, no-store, must-revalidate` |
|
|
147
|
+
| `pragma` | `no-cache` |
|
|
148
|
+
| `Expires` | `0` |
|
|
149
|
+
| `X-Content-Type-Options` | `nosniff` |
|
|
150
|
+
| `Content-Type` | `application/json` (for non-file requests with body) |
|
|
151
|
+
| `api-version` | Constructor `apiVersion` (if provided) |
|
|
152
|
+
| `ApplicationName` | Method `applicationName` (if provided) |
|
|
153
|
+
| `SessionToken` | Method `token` (if provided) |
|
|
154
|
+
|
|
155
|
+
## Behavior
|
|
156
|
+
|
|
157
|
+
- CORS mode with `credentials: 'include'` (cookies sent on every request)
|
|
158
|
+
- Request timeout via `AbortController` (default 60s)
|
|
159
|
+
- Validates `Content-Type: application/json` before parsing JSON responses
|
|
160
|
+
- Validates HTTP status 2xx before processing the response
|
|
161
|
+
- 401/403 responses routed to constructor callbacks if provided
|
|
162
|
+
- Other errors routed to `onGenericServerError` callback if provided
|
|
163
|
+
- Falls back to throwing error label strings if no callback handles the error
|