@j2inn/fin5-ui-utils 2.0.4 → 2.0.6-beta.0
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/README.md +5 -5
- package/dist/fin5Top/fin5FileUpload.d.ts +12 -0
- package/dist/fin5Top/fin5FileUpload.js +39 -0
- package/dist/fin5Top/fin5FileUpload.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/react/components/charts/pie/PieChart.d.ts +83 -0
- package/dist/react/components/charts/pie/PieChart.js +196 -0
- package/dist/react/components/charts/pie/PieChart.js.map +1 -0
- package/dist/react/components/charts/pie/SimplePieChart.d.ts +20 -0
- package/dist/react/components/charts/pie/SimplePieChart.js +56 -0
- package/dist/react/components/charts/pie/SimplePieChart.js.map +1 -0
- package/dist_es/fin5Top/fin5FileUpload.d.ts +12 -0
- package/dist_es/fin5Top/fin5FileUpload.js +35 -0
- package/dist_es/fin5Top/fin5FileUpload.js.map +1 -0
- package/dist_es/index.d.ts +3 -0
- package/dist_es/index.js +3 -0
- package/dist_es/index.js.map +1 -1
- package/dist_es/react/components/charts/pie/PieChart.d.ts +83 -0
- package/dist_es/react/components/charts/pie/PieChart.js +169 -0
- package/dist_es/react/components/charts/pie/PieChart.js.map +1 -0
- package/dist_es/react/components/charts/pie/SimplePieChart.d.ts +20 -0
- package/dist_es/react/components/charts/pie/SimplePieChart.js +26 -0
- package/dist_es/react/components/charts/pie/SimplePieChart.js.map +1 -0
- package/dist_es/react/components/graphics/GraphicsTabViewer.jsx +12 -3
- package/dist_es/react/components/graphics/GraphicsTabViewer.jsx.map +1 -1
- package/dist_es/react/components/navigation/Router.js +19 -0
- package/dist_es/react/components/navigation/Router.js.map +1 -0
- package/dist_es/react/components/navigation/react-router/BasicLayout.d.ts +23 -0
- package/dist_es/react/components/navigation/react-router/BasicLayout.js +82 -0
- package/dist_es/react/components/navigation/react-router/BasicLayout.js.map +1 -0
- package/dist_es/react/components/navigation/react-router/ReactRouterBasicLayout.d.ts +24 -0
- package/dist_es/react/components/navigation/react-router/ReactRouterBasicLayout.js +82 -0
- package/dist_es/react/components/navigation/react-router/ReactRouterBasicLayout.js.map +1 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
# What is fin5-ui-utils? #
|
|
2
|
-
A set of useful client-side utilities useful for creating UI applications on top of the FIN 5 framework.
|
|
3
|
-
|
|
4
|
-
### How do I get set up? ###
|
|
5
|
-
To install this package run `npm i @j2inn/fin5-ui-utils`
|
|
1
|
+
# What is fin5-ui-utils? #
|
|
2
|
+
A set of useful client-side utilities useful for creating UI applications on top of the FIN 5 framework.
|
|
3
|
+
|
|
4
|
+
### How do I get set up? ###
|
|
5
|
+
To install this package run `npm i @j2inn/fin5-ui-utils`
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { HDict } from 'haystack-core';
|
|
3
|
+
import { URLSearchParams } from 'url';
|
|
4
|
+
/**
|
|
5
|
+
* Upload a File to FIN5, using the FINStack /fileUpload API. Files can then be viewed using Folio menu.
|
|
6
|
+
* @param projectName The name of the project where the files will be uploaded
|
|
7
|
+
* @param file The File to upload
|
|
8
|
+
* @param additionalTags Any additional tag that needs to be added to the file record. The tags should be
|
|
9
|
+
* provided as URL search parameters. To add a marker tag, set the value of the param to `'true'`.
|
|
10
|
+
* @returns the file record as an HDict
|
|
11
|
+
*/
|
|
12
|
+
export declare const fin5FileUpload: (projectName: string, file: File, additionalTags?: URLSearchParams) => Promise<HDict>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fin5FileUpload = void 0;
|
|
4
|
+
const haystack_core_1 = require("haystack-core");
|
|
5
|
+
const haystack_nclient_1 = require("haystack-nclient");
|
|
6
|
+
const url_1 = require("url");
|
|
7
|
+
/**
|
|
8
|
+
* Upload a File to FIN5, using the FINStack /fileUpload API. Files can then be viewed using Folio menu.
|
|
9
|
+
* @param projectName The name of the project where the files will be uploaded
|
|
10
|
+
* @param file The File to upload
|
|
11
|
+
* @param additionalTags Any additional tag that needs to be added to the file record. The tags should be
|
|
12
|
+
* provided as URL search parameters. To add a marker tag, set the value of the param to `'true'`.
|
|
13
|
+
* @returns the file record as an HDict
|
|
14
|
+
*/
|
|
15
|
+
const fin5FileUpload = async (projectName, file, additionalTags = new url_1.URLSearchParams()) => {
|
|
16
|
+
if (!additionalTags.has('dis')) {
|
|
17
|
+
additionalTags.set('dis', file.name);
|
|
18
|
+
}
|
|
19
|
+
// URL base (http://localhost) will be ignored, it's just needed to build the URL
|
|
20
|
+
const url = new URL(`/api/${projectName}/ext/finstack/fileUpload`, 'http://localhost');
|
|
21
|
+
additionalTags.forEach((value, name) => url.searchParams.set(name, value));
|
|
22
|
+
const content = await file.arrayBuffer();
|
|
23
|
+
const response = await (0, haystack_nclient_1.finCsrfFetch)(`${url.pathname}${url.search}`, {
|
|
24
|
+
method: 'POST',
|
|
25
|
+
headers: {
|
|
26
|
+
'Content-Type': 'application/octet-stream',
|
|
27
|
+
},
|
|
28
|
+
body: new Uint8Array(content),
|
|
29
|
+
});
|
|
30
|
+
const zincReader = new haystack_core_1.ZincReader(await response.text());
|
|
31
|
+
const grid = zincReader.readValue();
|
|
32
|
+
const dict = grid.first;
|
|
33
|
+
if (!dict) {
|
|
34
|
+
throw new Error('Unexpected response, no record found');
|
|
35
|
+
}
|
|
36
|
+
return dict;
|
|
37
|
+
};
|
|
38
|
+
exports.fin5FileUpload = fin5FileUpload;
|
|
39
|
+
//# sourceMappingURL=fin5FileUpload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fin5FileUpload.js","sourceRoot":"","sources":["../../src/fin5Top/fin5FileUpload.ts"],"names":[],"mappings":";;;AAAA,iDAAwD;AACxD,uDAA+C;AAC/C,6BAAqC;AAErC;;;;;;;GAOG;AACI,MAAM,cAAc,GAAG,KAAK,EAClC,WAAmB,EACnB,IAAU,EACV,cAAc,GAAG,IAAI,qBAAe,EAAE,EACrB,EAAE;IACnB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC/B,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;KACpC;IAED,iFAAiF;IACjF,MAAM,GAAG,GAAG,IAAI,GAAG,CAClB,QAAQ,WAAW,0BAA0B,EAC7C,kBAAkB,CAClB,CAAA;IACD,cAAc,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,IAAY,EAAE,EAAE,CACtD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CACjC,CAAA;IAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;IACxC,MAAM,QAAQ,GAAG,MAAM,IAAA,+BAAY,EAAC,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE;QACnE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,0BAA0B;SAC1C;QACD,IAAI,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC;KAC7B,CAAC,CAAA;IAEF,MAAM,UAAU,GAAG,IAAI,0BAAU,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IACxD,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,EAAW,CAAA;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;IACvB,IAAI,CAAC,IAAI,EAAE;QACV,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;KACvD;IACD,OAAO,IAAI,CAAA;AACZ,CAAC,CAAA;AAlCY,QAAA,cAAc,kBAkC1B"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './fin5Top/fin5FileUpload';
|
|
1
2
|
export * from './fin5Top/fin5Top';
|
|
2
3
|
export * from './fin5Top/getFin5BinUrl';
|
|
3
4
|
export * from './fin5Top/openFin5Alarm';
|
|
@@ -18,6 +19,8 @@ export * from './react/components/resolvable/configurationForm/ConfigurationForm
|
|
|
18
19
|
export * from './react/components/resolvable/configurationForm/ConfigurationFormEntry';
|
|
19
20
|
export * from './react/components/resolvable/configurationForm/getSectionDefault';
|
|
20
21
|
export * from './react/components/RecordImage';
|
|
22
|
+
export * from './react/components/charts/pie/PieChart';
|
|
23
|
+
export * from './react/components/charts/pie/SimplePieChart';
|
|
21
24
|
export * from './react/hooks/useFin5BinUrl';
|
|
22
25
|
export * from './react/app/Fin5AppContainer';
|
|
23
26
|
export * from './react/app/Fin5AppRootStore';
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
20
20
|
//////////////////////////////////////////////////////////////////////////
|
|
21
21
|
// Fin5 APIs related modules
|
|
22
22
|
//////////////////////////////////////////////////////////////////////////
|
|
23
|
+
__exportStar(require("./fin5Top/fin5FileUpload"), exports);
|
|
23
24
|
__exportStar(require("./fin5Top/fin5Top"), exports);
|
|
24
25
|
__exportStar(require("./fin5Top/getFin5BinUrl"), exports);
|
|
25
26
|
__exportStar(require("./fin5Top/openFin5Alarm"), exports);
|
|
@@ -43,6 +44,8 @@ __exportStar(require("./react/components/resolvable/configurationForm/Configurat
|
|
|
43
44
|
__exportStar(require("./react/components/resolvable/configurationForm/ConfigurationFormEntry"), exports);
|
|
44
45
|
__exportStar(require("./react/components/resolvable/configurationForm/getSectionDefault"), exports);
|
|
45
46
|
__exportStar(require("./react/components/RecordImage"), exports);
|
|
47
|
+
__exportStar(require("./react/components/charts/pie/PieChart"), exports);
|
|
48
|
+
__exportStar(require("./react/components/charts/pie/SimplePieChart"), exports);
|
|
46
49
|
//////////////////////////////////////////////////////////////////////////
|
|
47
50
|
// React hooks
|
|
48
51
|
//////////////////////////////////////////////////////////////////////////
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,0EAA0E;AAC1E,4BAA4B;AAC5B,0EAA0E;AAE1E,oDAAiC;AACjC,0DAAuC;AACvC,0DAAuC;AACvC,8DAA2C;AAC3C,uEAAoD;AAEpD,0EAA0E;AAC1E,mBAAmB;AACnB,0EAA0E;AAE1E,mEAAgD;AAChD,oEAAiD;AACjD,4DAAyC;AACzC,oEAAiD;AACjD,4EAAyD;AACzD,gFAA6D;AAC7D,4EAAyD;AACzD,yEAAsD;AACtD,kFAA+D;AAC/D,2FAAwE;AACxE,qFAAkE;AAClE,oGAAiF;AACjF,yGAAsF;AACtF,oGAAiF;AACjF,iEAA8C;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;AAEH,0EAA0E;AAC1E,4BAA4B;AAC5B,0EAA0E;AAE1E,2DAAwC;AACxC,oDAAiC;AACjC,0DAAuC;AACvC,0DAAuC;AACvC,8DAA2C;AAC3C,uEAAoD;AAEpD,0EAA0E;AAC1E,mBAAmB;AACnB,0EAA0E;AAE1E,mEAAgD;AAChD,oEAAiD;AACjD,4DAAyC;AACzC,oEAAiD;AACjD,4EAAyD;AACzD,gFAA6D;AAC7D,4EAAyD;AACzD,yEAAsD;AACtD,kFAA+D;AAC/D,2FAAwE;AACxE,qFAAkE;AAClE,oGAAiF;AACjF,yGAAsF;AACtF,oGAAiF;AACjF,iEAA8C;AAC9C,yEAAsD;AACtD,+EAA4D;AAE5D,0EAA0E;AAC1E,cAAc;AACd,0EAA0E;AAE1E,8DAA2C;AAE3C,0EAA0E;AAC1E,6BAA6B;AAC7B,0EAA0E;AAE1E,+DAA4C;AAC5C,+DAA4C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as am5 from '@amcharts/amcharts5';
|
|
2
|
+
import * as am5percent from '@amcharts/amcharts5/percent';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export declare type PieChartInterfaceColors = {
|
|
5
|
+
[Property in keyof am5.IInterfaceColorsSettings]: string;
|
|
6
|
+
};
|
|
7
|
+
export interface PieChartColorPalette {
|
|
8
|
+
interfaceColors?: Partial<PieChartInterfaceColors>;
|
|
9
|
+
series?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface PieChartSliceData {
|
|
12
|
+
value: number;
|
|
13
|
+
category: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PieChartProps {
|
|
16
|
+
/**
|
|
17
|
+
* Data used to populate the chart
|
|
18
|
+
*/
|
|
19
|
+
data: PieChartSliceData[];
|
|
20
|
+
/**
|
|
21
|
+
* Color palette for the chart slices and interface colors @see https://www.amcharts.com/docs/v5/concepts/colors-gradients-and-patterns/#Interface_colors
|
|
22
|
+
*/
|
|
23
|
+
colorPalette?: Partial<PieChartColorPalette>;
|
|
24
|
+
/**
|
|
25
|
+
* Number formatting options @see https://www.amcharts.com/docs/v5/tutorials/formatting-date-time-and-numbers-using-intl-object/#Formatting_numbers
|
|
26
|
+
*/
|
|
27
|
+
numberFormat?: Intl.NumberFormatOptions;
|
|
28
|
+
/**
|
|
29
|
+
* amcharts5 theme classes to be used by the chart @see https://www.amcharts.com/docs/v5/concepts/themes/
|
|
30
|
+
*/
|
|
31
|
+
chartThemes?: typeof am5.Theme[];
|
|
32
|
+
/**
|
|
33
|
+
* Settings for chart customization @see https://www.amcharts.com/docs/v5/reference/piechart/#Settings
|
|
34
|
+
*/
|
|
35
|
+
chartSettings?: am5percent.IPieChartSettings;
|
|
36
|
+
/**
|
|
37
|
+
* Settings for legend customization @see https://www.amcharts.com/docs/v5/reference/legend/#Settings
|
|
38
|
+
*/
|
|
39
|
+
legendSettings?: am5.ILegendSettings;
|
|
40
|
+
/**
|
|
41
|
+
* Settings for legend value labels customization @see https://www.amcharts.com/docs/v5/reference/label/#Settings
|
|
42
|
+
*/
|
|
43
|
+
legendValueLabelsSettings?: Partial<am5.ILabelSettings>;
|
|
44
|
+
/**
|
|
45
|
+
* Settings for chart series customization @see https://www.amcharts.com/docs/v5/reference/pieseries/#Settings
|
|
46
|
+
*/
|
|
47
|
+
seriesSettings?: am5percent.IPieSeriesSettings;
|
|
48
|
+
/**
|
|
49
|
+
* Settings for series labels customization @see https://www.amcharts.com/docs/v5/reference/pieseries/#Settings
|
|
50
|
+
*/
|
|
51
|
+
seriesLabelsSettings?: Partial<am5.IRadialLabelSettings>;
|
|
52
|
+
/**
|
|
53
|
+
* Settings for central label customization, useful for donut charts, if not specified no center label will be shown @see https://www.amcharts.com/docs/v5/reference/radiallabel/#Settings
|
|
54
|
+
*/
|
|
55
|
+
centerLabelSettings?: am5.ILabelSettings;
|
|
56
|
+
/**
|
|
57
|
+
* Settings for pie slices customization @see https://www.amcharts.com/docs/v5/reference/slice/#Settings
|
|
58
|
+
*/
|
|
59
|
+
slicesSettings?: Partial<am5.ISliceSettings>;
|
|
60
|
+
/**
|
|
61
|
+
* List of adapters to be applied to the slices @see https://www.amcharts.com/docs/v5/concepts/settings/adapters
|
|
62
|
+
*/
|
|
63
|
+
sliceAdapters?: SliceAdapter[];
|
|
64
|
+
/**
|
|
65
|
+
* Optional DOM id for the chart container, if not specified it will be automatically generated
|
|
66
|
+
*/
|
|
67
|
+
DOMtargetId?: string;
|
|
68
|
+
}
|
|
69
|
+
export declare type SliceAdapter<T extends keyof am5.ISliceSettings = keyof am5.ISliceSettings> = [
|
|
70
|
+
T,
|
|
71
|
+
(context: {
|
|
72
|
+
root: am5.Root;
|
|
73
|
+
chart: am5percent.PieChart;
|
|
74
|
+
series: am5percent.PieSeries;
|
|
75
|
+
}) => (value: am5.ISliceSettings[T], target: am5.Slice, key: T) => am5.ISliceSettings[T]
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* Highly customizable pie chart component based on amcharts5
|
|
79
|
+
* @see https://www.amcharts.com/docs/v5/charts/percent-charts/pie-chart/
|
|
80
|
+
*
|
|
81
|
+
* This component wraps some of the chart configuration trying to make it more react-friendly
|
|
82
|
+
*/
|
|
83
|
+
export declare const PieChart: React.FC<PieChartProps>;
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2023, J2 Innovations. All Rights Reserved
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
+
exports.PieChart = void 0;
|
|
30
|
+
const am5 = __importStar(require("@amcharts/amcharts5"));
|
|
31
|
+
const am5percent = __importStar(require("@amcharts/amcharts5/percent"));
|
|
32
|
+
const react_1 = __importStar(require("react"));
|
|
33
|
+
const react_jss_1 = require("react-jss");
|
|
34
|
+
const useStyles = (0, react_jss_1.createUseStyles)({
|
|
35
|
+
root: {
|
|
36
|
+
width: '100%',
|
|
37
|
+
height: '100%',
|
|
38
|
+
},
|
|
39
|
+
});
|
|
40
|
+
/**
|
|
41
|
+
* Returns a color palette selecting some colors from the theme.
|
|
42
|
+
* @param theme The theme
|
|
43
|
+
* @returns An array of colors
|
|
44
|
+
*/
|
|
45
|
+
const getDefaultChartColors = (theme) => {
|
|
46
|
+
return {
|
|
47
|
+
interfaceColors: {
|
|
48
|
+
text: theme.textColor,
|
|
49
|
+
},
|
|
50
|
+
series: [
|
|
51
|
+
theme.palette.lime,
|
|
52
|
+
theme.palette.cyan,
|
|
53
|
+
theme.palette.red,
|
|
54
|
+
theme.palette.volcano,
|
|
55
|
+
theme.palette.orange,
|
|
56
|
+
theme.palette.gold,
|
|
57
|
+
theme.palette.yellow,
|
|
58
|
+
theme.palette.green,
|
|
59
|
+
theme.palette.purple,
|
|
60
|
+
theme.palette.magenta,
|
|
61
|
+
theme.palette.blue,
|
|
62
|
+
theme.palette.grey,
|
|
63
|
+
],
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Highly customizable pie chart component based on amcharts5
|
|
68
|
+
* @see https://www.amcharts.com/docs/v5/charts/percent-charts/pie-chart/
|
|
69
|
+
*
|
|
70
|
+
* This component wraps some of the chart configuration trying to make it more react-friendly
|
|
71
|
+
*/
|
|
72
|
+
const PieChart = ({ DOMtargetId, data, colorPalette, numberFormat, chartThemes, chartSettings, legendSettings, legendValueLabelsSettings, seriesSettings, seriesLabelsSettings, centerLabelSettings, slicesSettings, sliceAdapters, }) => {
|
|
73
|
+
// Colors configuration
|
|
74
|
+
const theme = (0, react_jss_1.useTheme)();
|
|
75
|
+
const colors = { ...getDefaultChartColors(theme), ...colorPalette };
|
|
76
|
+
// Chart lifecycle
|
|
77
|
+
const [id, setId] = (0, react_1.useState)(DOMtargetId ?? `amchart-${Math.random()}`);
|
|
78
|
+
const rootRef = (0, react_1.useRef)(null);
|
|
79
|
+
const chartRef = (0, react_1.useRef)(null);
|
|
80
|
+
const legendRef = (0, react_1.useRef)(null);
|
|
81
|
+
(0, react_1.useEffect)(() => {
|
|
82
|
+
if (DOMtargetId && DOMtargetId !== id) {
|
|
83
|
+
setId(DOMtargetId);
|
|
84
|
+
}
|
|
85
|
+
}, [DOMtargetId]);
|
|
86
|
+
// Chart setup
|
|
87
|
+
(0, react_1.useLayoutEffect)(() => {
|
|
88
|
+
const root = am5.Root.new(id);
|
|
89
|
+
// Setup amcharts theme
|
|
90
|
+
if (chartThemes) {
|
|
91
|
+
root.setThemes(chartThemes.map((t) => t.new(root)));
|
|
92
|
+
}
|
|
93
|
+
// Setup interface colors, see https://www.amcharts.com/docs/v5/concepts/colors-gradients-and-patterns/#Interface_colors
|
|
94
|
+
if (colors.interfaceColors) {
|
|
95
|
+
// Remap settings to use amcharts Color objects
|
|
96
|
+
for (const setting in colors.interfaceColors) {
|
|
97
|
+
const color = colors.interfaceColors[setting];
|
|
98
|
+
// Apply defined interfaceColor on the chart
|
|
99
|
+
root.interfaceColors.set(setting, am5.color(color));
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
// Setup chart settings
|
|
103
|
+
const chart = root.container.children.push(am5percent.PieChart.new(root, {
|
|
104
|
+
layout: root.verticalLayout,
|
|
105
|
+
...chartSettings,
|
|
106
|
+
}));
|
|
107
|
+
// Setup legend
|
|
108
|
+
const legend = chart.children.push(am5.Legend.new(root, {
|
|
109
|
+
layout: root.horizontalLayout,
|
|
110
|
+
...legendSettings,
|
|
111
|
+
}));
|
|
112
|
+
if (legendValueLabelsSettings) {
|
|
113
|
+
legend.valueLabels.template.setAll(legendValueLabelsSettings);
|
|
114
|
+
}
|
|
115
|
+
rootRef.current = root;
|
|
116
|
+
chartRef.current = chart;
|
|
117
|
+
legendRef.current = legend;
|
|
118
|
+
// clean up before component removal from the DOM
|
|
119
|
+
return () => {
|
|
120
|
+
legendRef.current?.dispose();
|
|
121
|
+
legendRef.current = null;
|
|
122
|
+
chartRef.current?.dispose();
|
|
123
|
+
chartRef.current = null;
|
|
124
|
+
root?.dispose();
|
|
125
|
+
rootRef.current = null;
|
|
126
|
+
};
|
|
127
|
+
}, [
|
|
128
|
+
id,
|
|
129
|
+
colors,
|
|
130
|
+
chartThemes,
|
|
131
|
+
chartSettings,
|
|
132
|
+
legendSettings,
|
|
133
|
+
legendValueLabelsSettings,
|
|
134
|
+
]);
|
|
135
|
+
// Set data
|
|
136
|
+
(0, react_1.useEffect)(() => {
|
|
137
|
+
const root = rootRef.current;
|
|
138
|
+
const chart = chartRef.current;
|
|
139
|
+
if (chart && root) {
|
|
140
|
+
chart.series.clear();
|
|
141
|
+
if (data?.length) {
|
|
142
|
+
// Setup series
|
|
143
|
+
const series = chart.series.push(am5percent.PieSeries.new(root, {
|
|
144
|
+
valueField: 'value',
|
|
145
|
+
categoryField: 'category',
|
|
146
|
+
...seriesSettings,
|
|
147
|
+
}));
|
|
148
|
+
// Setup series labels
|
|
149
|
+
if (seriesLabelsSettings) {
|
|
150
|
+
series.labels.template.setAll(seriesLabelsSettings);
|
|
151
|
+
}
|
|
152
|
+
// Setup center label
|
|
153
|
+
if (centerLabelSettings) {
|
|
154
|
+
series.children.push(am5.Label.new(root, {
|
|
155
|
+
...centerLabelSettings,
|
|
156
|
+
}));
|
|
157
|
+
}
|
|
158
|
+
// Setup series slices
|
|
159
|
+
if (slicesSettings) {
|
|
160
|
+
series.slices.template.setAll(slicesSettings);
|
|
161
|
+
}
|
|
162
|
+
// Setup slice adapters
|
|
163
|
+
if (sliceAdapters) {
|
|
164
|
+
sliceAdapters.forEach(([key, callbackMaker]) => series.slices.template.adapters.add(key, callbackMaker({
|
|
165
|
+
root: root,
|
|
166
|
+
chart: chart,
|
|
167
|
+
series,
|
|
168
|
+
})));
|
|
169
|
+
}
|
|
170
|
+
// Setup series colors
|
|
171
|
+
if (colors?.series) {
|
|
172
|
+
series.get('colors')?.set('colors', colors.series.map((c) => am5.color(c)));
|
|
173
|
+
}
|
|
174
|
+
series.data.setAll(data);
|
|
175
|
+
legendRef.current?.data.setAll(series.dataItems);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}, [
|
|
179
|
+
data,
|
|
180
|
+
chartRef.current,
|
|
181
|
+
colors?.series,
|
|
182
|
+
seriesSettings,
|
|
183
|
+
slicesSettings,
|
|
184
|
+
seriesLabelsSettings,
|
|
185
|
+
sliceAdapters,
|
|
186
|
+
]);
|
|
187
|
+
(0, react_1.useEffect)(() => {
|
|
188
|
+
if (numberFormat) {
|
|
189
|
+
rootRef.current?.numberFormatter.set('numberFormat', numberFormat);
|
|
190
|
+
}
|
|
191
|
+
}, [rootRef.current, numberFormat]);
|
|
192
|
+
const classes = useStyles();
|
|
193
|
+
return react_1.default.createElement("div", { id: id, className: classes.root });
|
|
194
|
+
};
|
|
195
|
+
exports.PieChart = PieChart;
|
|
196
|
+
//# sourceMappingURL=PieChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PieChart.js","sourceRoot":"","sources":["../../../../../src/react/components/charts/pie/PieChart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PieChartColorPalette, PieChartSliceData } from './PieChart';
|
|
3
|
+
export interface SimplePieChartProps {
|
|
4
|
+
data: PieChartSliceData[];
|
|
5
|
+
donut?: boolean;
|
|
6
|
+
animated?: boolean;
|
|
7
|
+
colorPalette?: Partial<PieChartColorPalette>;
|
|
8
|
+
tooltipFormat?: string;
|
|
9
|
+
numberFormat?: Intl.NumberFormatOptions;
|
|
10
|
+
hideLabels?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Optional DOM id for the chart container, if not specified it will be automatically generated
|
|
13
|
+
*/
|
|
14
|
+
DOMtargetId?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Simplified version of the pie chart for quick usage and easy configuration.
|
|
18
|
+
* Serves also as an example of how to use the underlying PieChart component.
|
|
19
|
+
*/
|
|
20
|
+
export declare const SimplePieChart: React.FC<SimplePieChartProps>;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* Copyright (c) 2023, J2 Innovations. All Rights Reserved
|
|
4
|
+
*/
|
|
5
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
8
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
9
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
10
|
+
}
|
|
11
|
+
Object.defineProperty(o, k2, desc);
|
|
12
|
+
}) : (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
o[k2] = m[k];
|
|
15
|
+
}));
|
|
16
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
17
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
18
|
+
}) : function(o, v) {
|
|
19
|
+
o["default"] = v;
|
|
20
|
+
});
|
|
21
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
22
|
+
if (mod && mod.__esModule) return mod;
|
|
23
|
+
var result = {};
|
|
24
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
25
|
+
__setModuleDefault(result, mod);
|
|
26
|
+
return result;
|
|
27
|
+
};
|
|
28
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
29
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
30
|
+
};
|
|
31
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
32
|
+
exports.SimplePieChart = void 0;
|
|
33
|
+
const am5 = __importStar(require("@amcharts/amcharts5"));
|
|
34
|
+
const Animated_1 = __importDefault(require("@amcharts/amcharts5/themes/Animated"));
|
|
35
|
+
const react_1 = __importDefault(require("react"));
|
|
36
|
+
const PieChart_1 = require("./PieChart");
|
|
37
|
+
/**
|
|
38
|
+
* Simplified version of the pie chart for quick usage and easy configuration.
|
|
39
|
+
* Serves also as an example of how to use the underlying PieChart component.
|
|
40
|
+
*/
|
|
41
|
+
const SimplePieChart = ({ data, donut, animated, colorPalette, tooltipFormat, numberFormat = {
|
|
42
|
+
style: 'decimal',
|
|
43
|
+
minimumFractionDigits: 0,
|
|
44
|
+
maximumFractionDigits: 1,
|
|
45
|
+
}, hideLabels, DOMtargetId, }) => {
|
|
46
|
+
return (react_1.default.createElement(PieChart_1.PieChart, { DOMtargetId: DOMtargetId, colorPalette: colorPalette, data: data, chartThemes: animated ? [Animated_1.default] : undefined, chartSettings: {
|
|
47
|
+
innerRadius: donut ? am5.percent(55) : undefined,
|
|
48
|
+
}, numberFormat: numberFormat, legendSettings: {
|
|
49
|
+
centerX: am5.percent(50),
|
|
50
|
+
x: am5.percent(50),
|
|
51
|
+
}, seriesLabelsSettings: { forceHidden: hideLabels }, seriesSettings: { alignLabels: false }, slicesSettings: {
|
|
52
|
+
tooltipText: tooltipFormat,
|
|
53
|
+
} }));
|
|
54
|
+
};
|
|
55
|
+
exports.SimplePieChart = SimplePieChart;
|
|
56
|
+
//# sourceMappingURL=SimplePieChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimplePieChart.js","sourceRoot":"","sources":["../../../../../src/react/components/charts/pie/SimplePieChart.tsx"],"names":[],"mappings":";AAAA;;GAEG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,yDAA0C;AAC1C,mFAAoE;AACpE,kDAAyB;AACzB,yCAA8E;AAgB9E;;;GAGG;AACI,MAAM,cAAc,GAAkC,CAAC,EAC7D,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,YAAY,GAAG;IACd,KAAK,EAAE,SAAS;IAChB,qBAAqB,EAAE,CAAC;IACxB,qBAAqB,EAAE,CAAC;CACxB,EACD,UAAU,EACV,WAAW,GACX,EAAe,EAAE;IACjB,OAAO,CACN,8BAAC,mBAAQ,IACR,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,SAAS,EACxD,aAAa,EAAE;YACd,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;SAChD,EACD,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE;YACf,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;SAClB,EACD,oBAAoB,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,EACjD,cAAc,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EACtC,cAAc,EAAE;YACf,WAAW,EAAE,aAAa;SAC1B,GACA,CACF,CAAA;AACF,CAAC,CAAA;AAnCY,QAAA,cAAc,kBAmC1B"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { HDict } from 'haystack-core';
|
|
3
|
+
import { URLSearchParams } from 'url';
|
|
4
|
+
/**
|
|
5
|
+
* Upload a File to FIN5, using the FINStack /fileUpload API. Files can then be viewed using Folio menu.
|
|
6
|
+
* @param projectName The name of the project where the files will be uploaded
|
|
7
|
+
* @param file The File to upload
|
|
8
|
+
* @param additionalTags Any additional tag that needs to be added to the file record. The tags should be
|
|
9
|
+
* provided as URL search parameters. To add a marker tag, set the value of the param to `'true'`.
|
|
10
|
+
* @returns the file record as an HDict
|
|
11
|
+
*/
|
|
12
|
+
export declare const fin5FileUpload: (projectName: string, file: File, additionalTags?: URLSearchParams) => Promise<HDict>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ZincReader } from 'haystack-core';
|
|
2
|
+
import { finCsrfFetch } from 'haystack-nclient';
|
|
3
|
+
import { URLSearchParams } from 'url';
|
|
4
|
+
/**
|
|
5
|
+
* Upload a File to FIN5, using the FINStack /fileUpload API. Files can then be viewed using Folio menu.
|
|
6
|
+
* @param projectName The name of the project where the files will be uploaded
|
|
7
|
+
* @param file The File to upload
|
|
8
|
+
* @param additionalTags Any additional tag that needs to be added to the file record. The tags should be
|
|
9
|
+
* provided as URL search parameters. To add a marker tag, set the value of the param to `'true'`.
|
|
10
|
+
* @returns the file record as an HDict
|
|
11
|
+
*/
|
|
12
|
+
export const fin5FileUpload = async (projectName, file, additionalTags = new URLSearchParams()) => {
|
|
13
|
+
if (!additionalTags.has('dis')) {
|
|
14
|
+
additionalTags.set('dis', file.name);
|
|
15
|
+
}
|
|
16
|
+
// URL base (http://localhost) will be ignored, it's just needed to build the URL
|
|
17
|
+
const url = new URL(`/api/${projectName}/ext/finstack/fileUpload`, 'http://localhost');
|
|
18
|
+
additionalTags.forEach((value, name) => url.searchParams.set(name, value));
|
|
19
|
+
const content = await file.arrayBuffer();
|
|
20
|
+
const response = await finCsrfFetch(`${url.pathname}${url.search}`, {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/octet-stream',
|
|
24
|
+
},
|
|
25
|
+
body: new Uint8Array(content),
|
|
26
|
+
});
|
|
27
|
+
const zincReader = new ZincReader(await response.text());
|
|
28
|
+
const grid = zincReader.readValue();
|
|
29
|
+
const dict = grid.first;
|
|
30
|
+
if (!dict) {
|
|
31
|
+
throw new Error('Unexpected response, no record found');
|
|
32
|
+
}
|
|
33
|
+
return dict;
|
|
34
|
+
};
|
|
35
|
+
//# sourceMappingURL=fin5FileUpload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fin5FileUpload.js","sourceRoot":"","sources":["../../src/fin5Top/fin5FileUpload.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,UAAU,EAAE,MAAM,eAAe,CAAA;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,KAAK,CAAA;AAErC;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,EAClC,WAAmB,EACnB,IAAU,EACV,cAAc,GAAG,IAAI,eAAe,EAAE,EACrB,EAAE;IACnB,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE;QAC/B,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,IAAI,CAAC,IAAI,CAAC,CAAA;KACpC;IAED,iFAAiF;IACjF,MAAM,GAAG,GAAG,IAAI,GAAG,CAClB,QAAQ,WAAW,0BAA0B,EAC7C,kBAAkB,CAClB,CAAA;IACD,cAAc,CAAC,OAAO,CAAC,CAAC,KAAa,EAAE,IAAY,EAAE,EAAE,CACtD,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,EAAE,KAAK,CAAC,CACjC,CAAA;IAED,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAA;IACxC,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,GAAG,GAAG,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE;QACnE,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACR,cAAc,EAAE,0BAA0B;SAC1C;QACD,IAAI,EAAE,IAAI,UAAU,CAAC,OAAO,CAAC;KAC7B,CAAC,CAAA;IAEF,MAAM,UAAU,GAAG,IAAI,UAAU,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IACxD,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,EAAW,CAAA;IAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAA;IACvB,IAAI,CAAC,IAAI,EAAE;QACV,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAA;KACvD;IACD,OAAO,IAAI,CAAA;AACZ,CAAC,CAAA"}
|
package/dist_es/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './fin5Top/fin5FileUpload';
|
|
1
2
|
export * from './fin5Top/fin5Top';
|
|
2
3
|
export * from './fin5Top/getFin5BinUrl';
|
|
3
4
|
export * from './fin5Top/openFin5Alarm';
|
|
@@ -18,6 +19,8 @@ export * from './react/components/resolvable/configurationForm/ConfigurationForm
|
|
|
18
19
|
export * from './react/components/resolvable/configurationForm/ConfigurationFormEntry';
|
|
19
20
|
export * from './react/components/resolvable/configurationForm/getSectionDefault';
|
|
20
21
|
export * from './react/components/RecordImage';
|
|
22
|
+
export * from './react/components/charts/pie/PieChart';
|
|
23
|
+
export * from './react/components/charts/pie/SimplePieChart';
|
|
21
24
|
export * from './react/hooks/useFin5BinUrl';
|
|
22
25
|
export * from './react/app/Fin5AppContainer';
|
|
23
26
|
export * from './react/app/Fin5AppRootStore';
|
package/dist_es/index.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
//////////////////////////////////////////////////////////////////////////
|
|
5
5
|
// Fin5 APIs related modules
|
|
6
6
|
//////////////////////////////////////////////////////////////////////////
|
|
7
|
+
export * from './fin5Top/fin5FileUpload';
|
|
7
8
|
export * from './fin5Top/fin5Top';
|
|
8
9
|
export * from './fin5Top/getFin5BinUrl';
|
|
9
10
|
export * from './fin5Top/openFin5Alarm';
|
|
@@ -27,6 +28,8 @@ export * from './react/components/resolvable/configurationForm/ConfigurationForm
|
|
|
27
28
|
export * from './react/components/resolvable/configurationForm/ConfigurationFormEntry';
|
|
28
29
|
export * from './react/components/resolvable/configurationForm/getSectionDefault';
|
|
29
30
|
export * from './react/components/RecordImage';
|
|
31
|
+
export * from './react/components/charts/pie/PieChart';
|
|
32
|
+
export * from './react/components/charts/pie/SimplePieChart';
|
|
30
33
|
//////////////////////////////////////////////////////////////////////////
|
|
31
34
|
// React hooks
|
|
32
35
|
//////////////////////////////////////////////////////////////////////////
|
package/dist_es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,0EAA0E;AAC1E,4BAA4B;AAC5B,0EAA0E;AAE1E,cAAc,mBAAmB,CAAA;AACjC,cAAc,yBAAyB,CAAA;AACvC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sCAAsC,CAAA;AAEpD,0EAA0E;AAC1E,mBAAmB;AACnB,0EAA0E;AAE1E,cAAc,kCAAkC,CAAA;AAChD,cAAc,mCAAmC,CAAA;AACjD,cAAc,2BAA2B,CAAA;AACzC,cAAc,mCAAmC,CAAA;AACjD,cAAc,2CAA2C,CAAA;AACzD,cAAc,+CAA+C,CAAA;AAC7D,cAAc,2CAA2C,CAAA;AACzD,cAAc,wCAAwC,CAAA;AACtD,cAAc,iDAAiD,CAAA;AAC/D,cAAc,0DAA0D,CAAA;AACxE,cAAc,oDAAoD,CAAA;AAClE,cAAc,mEAAmE,CAAA;AACjF,cAAc,wEAAwE,CAAA;AACtF,cAAc,mEAAmE,CAAA;AACjF,cAAc,gCAAgC,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,0EAA0E;AAC1E,4BAA4B;AAC5B,0EAA0E;AAE1E,cAAc,0BAA0B,CAAA;AACxC,cAAc,mBAAmB,CAAA;AACjC,cAAc,yBAAyB,CAAA;AACvC,cAAc,yBAAyB,CAAA;AACvC,cAAc,6BAA6B,CAAA;AAC3C,cAAc,sCAAsC,CAAA;AAEpD,0EAA0E;AAC1E,mBAAmB;AACnB,0EAA0E;AAE1E,cAAc,kCAAkC,CAAA;AAChD,cAAc,mCAAmC,CAAA;AACjD,cAAc,2BAA2B,CAAA;AACzC,cAAc,mCAAmC,CAAA;AACjD,cAAc,2CAA2C,CAAA;AACzD,cAAc,+CAA+C,CAAA;AAC7D,cAAc,2CAA2C,CAAA;AACzD,cAAc,wCAAwC,CAAA;AACtD,cAAc,iDAAiD,CAAA;AAC/D,cAAc,0DAA0D,CAAA;AACxE,cAAc,oDAAoD,CAAA;AAClE,cAAc,mEAAmE,CAAA;AACjF,cAAc,wEAAwE,CAAA;AACtF,cAAc,mEAAmE,CAAA;AACjF,cAAc,gCAAgC,CAAA;AAC9C,cAAc,wCAAwC,CAAA;AACtD,cAAc,8CAA8C,CAAA;AAE5D,0EAA0E;AAC1E,cAAc;AACd,0EAA0E;AAE1E,cAAc,6BAA6B,CAAA;AAE3C,0EAA0E;AAC1E,6BAA6B;AAC7B,0EAA0E;AAE1E,cAAc,8BAA8B,CAAA;AAC5C,cAAc,8BAA8B,CAAA"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import * as am5 from '@amcharts/amcharts5';
|
|
2
|
+
import * as am5percent from '@amcharts/amcharts5/percent';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
export declare type PieChartInterfaceColors = {
|
|
5
|
+
[Property in keyof am5.IInterfaceColorsSettings]: string;
|
|
6
|
+
};
|
|
7
|
+
export interface PieChartColorPalette {
|
|
8
|
+
interfaceColors?: Partial<PieChartInterfaceColors>;
|
|
9
|
+
series?: string[];
|
|
10
|
+
}
|
|
11
|
+
export interface PieChartSliceData {
|
|
12
|
+
value: number;
|
|
13
|
+
category: string;
|
|
14
|
+
}
|
|
15
|
+
export interface PieChartProps {
|
|
16
|
+
/**
|
|
17
|
+
* Data used to populate the chart
|
|
18
|
+
*/
|
|
19
|
+
data: PieChartSliceData[];
|
|
20
|
+
/**
|
|
21
|
+
* Color palette for the chart slices and interface colors @see https://www.amcharts.com/docs/v5/concepts/colors-gradients-and-patterns/#Interface_colors
|
|
22
|
+
*/
|
|
23
|
+
colorPalette?: Partial<PieChartColorPalette>;
|
|
24
|
+
/**
|
|
25
|
+
* Number formatting options @see https://www.amcharts.com/docs/v5/tutorials/formatting-date-time-and-numbers-using-intl-object/#Formatting_numbers
|
|
26
|
+
*/
|
|
27
|
+
numberFormat?: Intl.NumberFormatOptions;
|
|
28
|
+
/**
|
|
29
|
+
* amcharts5 theme classes to be used by the chart @see https://www.amcharts.com/docs/v5/concepts/themes/
|
|
30
|
+
*/
|
|
31
|
+
chartThemes?: typeof am5.Theme[];
|
|
32
|
+
/**
|
|
33
|
+
* Settings for chart customization @see https://www.amcharts.com/docs/v5/reference/piechart/#Settings
|
|
34
|
+
*/
|
|
35
|
+
chartSettings?: am5percent.IPieChartSettings;
|
|
36
|
+
/**
|
|
37
|
+
* Settings for legend customization @see https://www.amcharts.com/docs/v5/reference/legend/#Settings
|
|
38
|
+
*/
|
|
39
|
+
legendSettings?: am5.ILegendSettings;
|
|
40
|
+
/**
|
|
41
|
+
* Settings for legend value labels customization @see https://www.amcharts.com/docs/v5/reference/label/#Settings
|
|
42
|
+
*/
|
|
43
|
+
legendValueLabelsSettings?: Partial<am5.ILabelSettings>;
|
|
44
|
+
/**
|
|
45
|
+
* Settings for chart series customization @see https://www.amcharts.com/docs/v5/reference/pieseries/#Settings
|
|
46
|
+
*/
|
|
47
|
+
seriesSettings?: am5percent.IPieSeriesSettings;
|
|
48
|
+
/**
|
|
49
|
+
* Settings for series labels customization @see https://www.amcharts.com/docs/v5/reference/pieseries/#Settings
|
|
50
|
+
*/
|
|
51
|
+
seriesLabelsSettings?: Partial<am5.IRadialLabelSettings>;
|
|
52
|
+
/**
|
|
53
|
+
* Settings for central label customization, useful for donut charts, if not specified no center label will be shown @see https://www.amcharts.com/docs/v5/reference/radiallabel/#Settings
|
|
54
|
+
*/
|
|
55
|
+
centerLabelSettings?: am5.ILabelSettings;
|
|
56
|
+
/**
|
|
57
|
+
* Settings for pie slices customization @see https://www.amcharts.com/docs/v5/reference/slice/#Settings
|
|
58
|
+
*/
|
|
59
|
+
slicesSettings?: Partial<am5.ISliceSettings>;
|
|
60
|
+
/**
|
|
61
|
+
* List of adapters to be applied to the slices @see https://www.amcharts.com/docs/v5/concepts/settings/adapters
|
|
62
|
+
*/
|
|
63
|
+
sliceAdapters?: SliceAdapter[];
|
|
64
|
+
/**
|
|
65
|
+
* Optional DOM id for the chart container, if not specified it will be automatically generated
|
|
66
|
+
*/
|
|
67
|
+
DOMtargetId?: string;
|
|
68
|
+
}
|
|
69
|
+
export declare type SliceAdapter<T extends keyof am5.ISliceSettings = keyof am5.ISliceSettings> = [
|
|
70
|
+
T,
|
|
71
|
+
(context: {
|
|
72
|
+
root: am5.Root;
|
|
73
|
+
chart: am5percent.PieChart;
|
|
74
|
+
series: am5percent.PieSeries;
|
|
75
|
+
}) => (value: am5.ISliceSettings[T], target: am5.Slice, key: T) => am5.ISliceSettings[T]
|
|
76
|
+
];
|
|
77
|
+
/**
|
|
78
|
+
* Highly customizable pie chart component based on amcharts5
|
|
79
|
+
* @see https://www.amcharts.com/docs/v5/charts/percent-charts/pie-chart/
|
|
80
|
+
*
|
|
81
|
+
* This component wraps some of the chart configuration trying to make it more react-friendly
|
|
82
|
+
*/
|
|
83
|
+
export declare const PieChart: React.FC<PieChartProps>;
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023, J2 Innovations. All Rights Reserved
|
|
3
|
+
*/
|
|
4
|
+
import * as am5 from '@amcharts/amcharts5';
|
|
5
|
+
import * as am5percent from '@amcharts/amcharts5/percent';
|
|
6
|
+
import React, { useEffect, useLayoutEffect, useRef, useState } from 'react';
|
|
7
|
+
import { createUseStyles, useTheme } from 'react-jss';
|
|
8
|
+
const useStyles = createUseStyles({
|
|
9
|
+
root: {
|
|
10
|
+
width: '100%',
|
|
11
|
+
height: '100%',
|
|
12
|
+
},
|
|
13
|
+
});
|
|
14
|
+
/**
|
|
15
|
+
* Returns a color palette selecting some colors from the theme.
|
|
16
|
+
* @param theme The theme
|
|
17
|
+
* @returns An array of colors
|
|
18
|
+
*/
|
|
19
|
+
const getDefaultChartColors = (theme) => {
|
|
20
|
+
return {
|
|
21
|
+
interfaceColors: {
|
|
22
|
+
text: theme.textColor,
|
|
23
|
+
},
|
|
24
|
+
series: [
|
|
25
|
+
theme.palette.lime,
|
|
26
|
+
theme.palette.cyan,
|
|
27
|
+
theme.palette.red,
|
|
28
|
+
theme.palette.volcano,
|
|
29
|
+
theme.palette.orange,
|
|
30
|
+
theme.palette.gold,
|
|
31
|
+
theme.palette.yellow,
|
|
32
|
+
theme.palette.green,
|
|
33
|
+
theme.palette.purple,
|
|
34
|
+
theme.palette.magenta,
|
|
35
|
+
theme.palette.blue,
|
|
36
|
+
theme.palette.grey,
|
|
37
|
+
],
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Highly customizable pie chart component based on amcharts5
|
|
42
|
+
* @see https://www.amcharts.com/docs/v5/charts/percent-charts/pie-chart/
|
|
43
|
+
*
|
|
44
|
+
* This component wraps some of the chart configuration trying to make it more react-friendly
|
|
45
|
+
*/
|
|
46
|
+
export const PieChart = ({ DOMtargetId, data, colorPalette, numberFormat, chartThemes, chartSettings, legendSettings, legendValueLabelsSettings, seriesSettings, seriesLabelsSettings, centerLabelSettings, slicesSettings, sliceAdapters, }) => {
|
|
47
|
+
// Colors configuration
|
|
48
|
+
const theme = useTheme();
|
|
49
|
+
const colors = { ...getDefaultChartColors(theme), ...colorPalette };
|
|
50
|
+
// Chart lifecycle
|
|
51
|
+
const [id, setId] = useState(DOMtargetId ?? `amchart-${Math.random()}`);
|
|
52
|
+
const rootRef = useRef(null);
|
|
53
|
+
const chartRef = useRef(null);
|
|
54
|
+
const legendRef = useRef(null);
|
|
55
|
+
useEffect(() => {
|
|
56
|
+
if (DOMtargetId && DOMtargetId !== id) {
|
|
57
|
+
setId(DOMtargetId);
|
|
58
|
+
}
|
|
59
|
+
}, [DOMtargetId]);
|
|
60
|
+
// Chart setup
|
|
61
|
+
useLayoutEffect(() => {
|
|
62
|
+
const root = am5.Root.new(id);
|
|
63
|
+
// Setup amcharts theme
|
|
64
|
+
if (chartThemes) {
|
|
65
|
+
root.setThemes(chartThemes.map((t) => t.new(root)));
|
|
66
|
+
}
|
|
67
|
+
// Setup interface colors, see https://www.amcharts.com/docs/v5/concepts/colors-gradients-and-patterns/#Interface_colors
|
|
68
|
+
if (colors.interfaceColors) {
|
|
69
|
+
// Remap settings to use amcharts Color objects
|
|
70
|
+
for (const setting in colors.interfaceColors) {
|
|
71
|
+
const color = colors.interfaceColors[setting];
|
|
72
|
+
// Apply defined interfaceColor on the chart
|
|
73
|
+
root.interfaceColors.set(setting, am5.color(color));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
// Setup chart settings
|
|
77
|
+
const chart = root.container.children.push(am5percent.PieChart.new(root, {
|
|
78
|
+
layout: root.verticalLayout,
|
|
79
|
+
...chartSettings,
|
|
80
|
+
}));
|
|
81
|
+
// Setup legend
|
|
82
|
+
const legend = chart.children.push(am5.Legend.new(root, {
|
|
83
|
+
layout: root.horizontalLayout,
|
|
84
|
+
...legendSettings,
|
|
85
|
+
}));
|
|
86
|
+
if (legendValueLabelsSettings) {
|
|
87
|
+
legend.valueLabels.template.setAll(legendValueLabelsSettings);
|
|
88
|
+
}
|
|
89
|
+
rootRef.current = root;
|
|
90
|
+
chartRef.current = chart;
|
|
91
|
+
legendRef.current = legend;
|
|
92
|
+
// clean up before component removal from the DOM
|
|
93
|
+
return () => {
|
|
94
|
+
legendRef.current?.dispose();
|
|
95
|
+
legendRef.current = null;
|
|
96
|
+
chartRef.current?.dispose();
|
|
97
|
+
chartRef.current = null;
|
|
98
|
+
root?.dispose();
|
|
99
|
+
rootRef.current = null;
|
|
100
|
+
};
|
|
101
|
+
}, [
|
|
102
|
+
id,
|
|
103
|
+
colors,
|
|
104
|
+
chartThemes,
|
|
105
|
+
chartSettings,
|
|
106
|
+
legendSettings,
|
|
107
|
+
legendValueLabelsSettings,
|
|
108
|
+
]);
|
|
109
|
+
// Set data
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
const root = rootRef.current;
|
|
112
|
+
const chart = chartRef.current;
|
|
113
|
+
if (chart && root) {
|
|
114
|
+
chart.series.clear();
|
|
115
|
+
if (data?.length) {
|
|
116
|
+
// Setup series
|
|
117
|
+
const series = chart.series.push(am5percent.PieSeries.new(root, {
|
|
118
|
+
valueField: 'value',
|
|
119
|
+
categoryField: 'category',
|
|
120
|
+
...seriesSettings,
|
|
121
|
+
}));
|
|
122
|
+
// Setup series labels
|
|
123
|
+
if (seriesLabelsSettings) {
|
|
124
|
+
series.labels.template.setAll(seriesLabelsSettings);
|
|
125
|
+
}
|
|
126
|
+
// Setup center label
|
|
127
|
+
if (centerLabelSettings) {
|
|
128
|
+
series.children.push(am5.Label.new(root, {
|
|
129
|
+
...centerLabelSettings,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
// Setup series slices
|
|
133
|
+
if (slicesSettings) {
|
|
134
|
+
series.slices.template.setAll(slicesSettings);
|
|
135
|
+
}
|
|
136
|
+
// Setup slice adapters
|
|
137
|
+
if (sliceAdapters) {
|
|
138
|
+
sliceAdapters.forEach(([key, callbackMaker]) => series.slices.template.adapters.add(key, callbackMaker({
|
|
139
|
+
root: root,
|
|
140
|
+
chart: chart,
|
|
141
|
+
series,
|
|
142
|
+
})));
|
|
143
|
+
}
|
|
144
|
+
// Setup series colors
|
|
145
|
+
if (colors?.series) {
|
|
146
|
+
series.get('colors')?.set('colors', colors.series.map((c) => am5.color(c)));
|
|
147
|
+
}
|
|
148
|
+
series.data.setAll(data);
|
|
149
|
+
legendRef.current?.data.setAll(series.dataItems);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}, [
|
|
153
|
+
data,
|
|
154
|
+
chartRef.current,
|
|
155
|
+
colors?.series,
|
|
156
|
+
seriesSettings,
|
|
157
|
+
slicesSettings,
|
|
158
|
+
seriesLabelsSettings,
|
|
159
|
+
sliceAdapters,
|
|
160
|
+
]);
|
|
161
|
+
useEffect(() => {
|
|
162
|
+
if (numberFormat) {
|
|
163
|
+
rootRef.current?.numberFormatter.set('numberFormat', numberFormat);
|
|
164
|
+
}
|
|
165
|
+
}, [rootRef.current, numberFormat]);
|
|
166
|
+
const classes = useStyles();
|
|
167
|
+
return React.createElement("div", { id: id, className: classes.root });
|
|
168
|
+
};
|
|
169
|
+
//# sourceMappingURL=PieChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PieChart.js","sourceRoot":"","sources":["../../../../../src/react/components/charts/pie/PieChart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PieChartColorPalette, PieChartSliceData } from './PieChart';
|
|
3
|
+
export interface SimplePieChartProps {
|
|
4
|
+
data: PieChartSliceData[];
|
|
5
|
+
donut?: boolean;
|
|
6
|
+
animated?: boolean;
|
|
7
|
+
colorPalette?: Partial<PieChartColorPalette>;
|
|
8
|
+
tooltipFormat?: string;
|
|
9
|
+
numberFormat?: Intl.NumberFormatOptions;
|
|
10
|
+
hideLabels?: boolean;
|
|
11
|
+
/**
|
|
12
|
+
* Optional DOM id for the chart container, if not specified it will be automatically generated
|
|
13
|
+
*/
|
|
14
|
+
DOMtargetId?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Simplified version of the pie chart for quick usage and easy configuration.
|
|
18
|
+
* Serves also as an example of how to use the underlying PieChart component.
|
|
19
|
+
*/
|
|
20
|
+
export declare const SimplePieChart: React.FC<SimplePieChartProps>;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023, J2 Innovations. All Rights Reserved
|
|
3
|
+
*/
|
|
4
|
+
import * as am5 from '@amcharts/amcharts5';
|
|
5
|
+
import am5themes_Animated from '@amcharts/amcharts5/themes/Animated';
|
|
6
|
+
import React from 'react';
|
|
7
|
+
import { PieChart } from './PieChart';
|
|
8
|
+
/**
|
|
9
|
+
* Simplified version of the pie chart for quick usage and easy configuration.
|
|
10
|
+
* Serves also as an example of how to use the underlying PieChart component.
|
|
11
|
+
*/
|
|
12
|
+
export const SimplePieChart = ({ data, donut, animated, colorPalette, tooltipFormat, numberFormat = {
|
|
13
|
+
style: 'decimal',
|
|
14
|
+
minimumFractionDigits: 0,
|
|
15
|
+
maximumFractionDigits: 1,
|
|
16
|
+
}, hideLabels, DOMtargetId, }) => {
|
|
17
|
+
return (React.createElement(PieChart, { DOMtargetId: DOMtargetId, colorPalette: colorPalette, data: data, chartThemes: animated ? [am5themes_Animated] : undefined, chartSettings: {
|
|
18
|
+
innerRadius: donut ? am5.percent(55) : undefined,
|
|
19
|
+
}, numberFormat: numberFormat, legendSettings: {
|
|
20
|
+
centerX: am5.percent(50),
|
|
21
|
+
x: am5.percent(50),
|
|
22
|
+
}, seriesLabelsSettings: { forceHidden: hideLabels }, seriesSettings: { alignLabels: false }, slicesSettings: {
|
|
23
|
+
tooltipText: tooltipFormat,
|
|
24
|
+
} }));
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=SimplePieChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SimplePieChart.js","sourceRoot":"","sources":["../../../../../src/react/components/charts/pie/SimplePieChart.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,GAAG,MAAM,qBAAqB,CAAA;AAC1C,OAAO,kBAAkB,MAAM,qCAAqC,CAAA;AACpE,OAAO,KAAK,MAAM,OAAO,CAAA;AACzB,OAAO,EAAE,QAAQ,EAA2C,MAAM,YAAY,CAAA;AAgB9E;;;GAGG;AACH,MAAM,CAAC,MAAM,cAAc,GAAkC,CAAC,EAC7D,IAAI,EACJ,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,aAAa,EACb,YAAY,GAAG;IACd,KAAK,EAAE,SAAS;IAChB,qBAAqB,EAAE,CAAC;IACxB,qBAAqB,EAAE,CAAC;CACxB,EACD,UAAU,EACV,WAAW,GACX,EAAe,EAAE;IACjB,OAAO,CACN,oBAAC,QAAQ,IACR,WAAW,EAAE,WAAW,EACxB,YAAY,EAAE,YAAY,EAC1B,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,SAAS,EACxD,aAAa,EAAE;YACd,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS;SAChD,EACD,YAAY,EAAE,YAAY,EAC1B,cAAc,EAAE;YACf,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;YACxB,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;SAClB,EACD,oBAAoB,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,EACjD,cAAc,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE,EACtC,cAAc,EAAE;YACf,WAAW,EAAE,aAAa;SAC1B,GACA,CACF,CAAA;AACF,CAAC,CAAA"}
|
|
@@ -22,8 +22,15 @@ const useStyles = createUseStyles({
|
|
|
22
22
|
},
|
|
23
23
|
},
|
|
24
24
|
},
|
|
25
|
+
fallback: {
|
|
26
|
+
height: '100%',
|
|
27
|
+
display: 'flex',
|
|
28
|
+
justifyContent: 'center',
|
|
29
|
+
alignItems: 'center',
|
|
30
|
+
fontSize: '1.1em',
|
|
31
|
+
},
|
|
25
32
|
});
|
|
26
|
-
export const GraphicsTabViewer = ({ projectName = fin5Top?.finstack?.projectName, targetRef, className, }) => {
|
|
33
|
+
export const GraphicsTabViewer = ({ projectName = fin5Top?.finstack?.projectName, targetRef, className, queryRelated = false, fallbackText = 'No graphics found.', fallbackClassName, }) => {
|
|
27
34
|
const client = useClient();
|
|
28
35
|
const classes = useStyles();
|
|
29
36
|
const [loading, setLoading] = useState(true);
|
|
@@ -31,7 +38,7 @@ export const GraphicsTabViewer = ({ projectName = fin5Top?.finstack?.projectName
|
|
|
31
38
|
useEffect(() => {
|
|
32
39
|
if (targetRef) {
|
|
33
40
|
client.ext
|
|
34
|
-
.eval(`readById(${targetRef.toAxon()}).finGraphicOn(
|
|
41
|
+
.eval(`readById(${targetRef.toAxon()}).finGraphicOn(${queryRelated})`)
|
|
35
42
|
.then((grid) => {
|
|
36
43
|
setGraphicsList(grid.getRows());
|
|
37
44
|
})
|
|
@@ -49,6 +56,8 @@ export const GraphicsTabViewer = ({ projectName = fin5Top?.finstack?.projectName
|
|
|
49
56
|
};
|
|
50
57
|
});
|
|
51
58
|
}, [graphicsList]);
|
|
52
|
-
return loading ? (<LoadingSpinner />) : (<Tabs className={cn(classes.tabs, className)} items={tabs}/>)
|
|
59
|
+
return loading ? (<LoadingSpinner />) : tabs.length > 0 ? (<Tabs className={cn(classes.tabs, className)} items={tabs}/>) : (<div className={cn(classes.fallback, fallbackClassName)}>
|
|
60
|
+
{fallbackText}
|
|
61
|
+
</div>);
|
|
53
62
|
};
|
|
54
63
|
//# sourceMappingURL=GraphicsTabViewer.jsx.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GraphicsTabViewer.jsx","sourceRoot":"","sources":["../../../../src/react/components/graphics/GraphicsTabViewer.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,MAAM,SAAS,GAAG,eAAe,CAAC;IACjC,IAAI,EAAE;QACL,MAAM,EAAE,MAAM;QACd,CAAC,MAAM,UAAU,sBAAsB,CAAC,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,CAAC,MAAM,UAAU,eAAe,CAAC,EAAE;gBAClC,MAAM,EAAE,MAAM;gBACd,CAAC,MAAM,UAAU,eAAe,CAAC,EAAE;oBAClC,MAAM,EAAE,MAAM;iBACd;aACD;SACD;KACD;CACD,CAAC,CAAA;
|
|
1
|
+
{"version":3,"file":"GraphicsTabViewer.jsx","sourceRoot":"","sources":["../../../../src/react/components/graphics/GraphicsTabViewer.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAA;AAC5C,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAC1C,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAClD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAE/C,MAAM,SAAS,GAAG,eAAe,CAAC;IACjC,IAAI,EAAE;QACL,MAAM,EAAE,MAAM;QACd,CAAC,MAAM,UAAU,sBAAsB,CAAC,EAAE;YACzC,MAAM,EAAE,MAAM;YACd,CAAC,MAAM,UAAU,eAAe,CAAC,EAAE;gBAClC,MAAM,EAAE,MAAM;gBACd,CAAC,MAAM,UAAU,eAAe,CAAC,EAAE;oBAClC,MAAM,EAAE,MAAM;iBACd;aACD;SACD;KACD;IACD,QAAQ,EAAE;QACT,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,MAAM;QACf,cAAc,EAAE,QAAQ;QACxB,UAAU,EAAE,QAAQ;QACpB,QAAQ,EAAE,OAAO;KACjB;CACD,CAAC,CAAA;AAoBF,MAAM,CAAC,MAAM,iBAAiB,GAAgC,CAAC,EAC9D,WAAW,GAAG,OAAO,EAAE,QAAQ,EAAE,WAAW,EAC5C,SAAS,EACT,SAAS,EACT,YAAY,GAAG,KAAK,EACpB,YAAY,GAAG,oBAAoB,EACnC,iBAAiB,GACjB,EAAE,EAAE;IACJ,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAC1B,MAAM,OAAO,GAAG,SAAS,EAAE,CAAA;IAC3B,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAA;IAC5C,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,CAAkB,EAAE,CAAC,CAAA;IAErE,SAAS,CAAC,GAAG,EAAE;QACd,IAAI,SAAS,EAAE;YACd,MAAM,CAAC,GAAG;iBACR,IAAI,CACJ,YAAY,SAAS,CAAC,MAAM,EAAE,kBAAkB,YAAY,GAAG,CAC/D;iBACA,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;gBACd,eAAe,CAAC,IAAI,CAAC,OAAO,EAAqB,CAAC,CAAA;YACnD,CAAC,CAAC;iBACD,OAAO,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;SAClC;IACF,CAAC,EAAE,CAAC,SAAS,CAAC,CAAC,CAAA;IAEf,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE;QACzB,OAAO,YAAY;aACjB,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC;aACtD,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE;YAChB,OAAO;gBACN,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE;gBACtB,GAAG,EAAE,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE;gBACxB,QAAQ,EAAE,CACT,CAAC,aAAa,CACb,WAAW,CAAC,CAAC,WAAW,IAAI,EAAE,CAAC,CAC/B,SAAS,CAAC,CAAC,SAAS,CAAC,CACrB,SAAS,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EACrB,CACF;aACD,CAAA;QACF,CAAC,CAAC,CAAA;IACJ,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAA;IAElB,OAAO,OAAO,CAAC,CAAC,CAAC,CAChB,CAAC,cAAc,CAAC,AAAD,EAAG,CAClB,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CACrB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAG,CAC7D,CAAC,CAAC,CAAC,CACH,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CACvD;GAAA,CAAC,YAAY,CACd;EAAA,EAAE,GAAG,CAAC,CACN,CAAA;AACF,CAAC,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2022, J2 Innovations. All Rights Reserved
|
|
3
|
+
*/
|
|
4
|
+
import React, { Suspense, useEffect, useMemo, } from 'react';
|
|
5
|
+
import { LoadingSpinner } from '../LoadingSpinner';
|
|
6
|
+
import { findPageByName } from './MenuPage';
|
|
7
|
+
/**
|
|
8
|
+
* Renders the currently selected page from a tree of pages
|
|
9
|
+
*/
|
|
10
|
+
export function Router({ pages = [], currentPage, onPageChange, fallbackComponent, }) {
|
|
11
|
+
const page = useMemo(() => findPageByName(pages, currentPage), [pages, currentPage]);
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
onPageChange?.(page);
|
|
14
|
+
}, [page]);
|
|
15
|
+
return page?.component ? (React.createElement(Suspense, { fallback: React.createElement(LoadingSpinner, null) }, React.createElement(page.component, page?.props))) : (fallbackComponent ?? React.createElement("div", null,
|
|
16
|
+
currentPage,
|
|
17
|
+
" page not found"));
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=Router.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Router.js","sourceRoot":"","sources":["../../../../src/react/components/navigation/Router.tsx"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,EAGb,QAAQ,EACR,SAAS,EACT,OAAO,GACP,MAAM,OAAO,CAAA;AACd,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAA;AAClD,OAAO,EAAE,cAAc,EAAY,MAAM,YAAY,CAAA;AASrD;;GAEG;AACH,MAAM,UAAU,MAAM,CAAqB,EAC1C,KAAK,GAAG,EAAE,EACV,WAAW,EACX,YAAY,EACZ,iBAAiB,GACkB;IACnC,MAAM,IAAI,GAAG,OAAO,CACnB,GAAG,EAAE,CAAC,cAAc,CAAC,KAAK,EAAE,WAAW,CAAC,EACxC,CAAC,KAAK,EAAE,WAAW,CAAC,CACpB,CAAA;IAED,SAAS,CAAC,GAAG,EAAE;QACd,YAAY,EAAE,CAAC,IAAI,CAAC,CAAA;IACrB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAA;IAEV,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,CACxB,oBAAC,QAAQ,IAAC,QAAQ,EAAE,oBAAC,cAAc,OAAG,IACpC,KAAK,CAAC,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,KAAK,CAAC,CACvC,CACX,CAAC,CAAC,CAAC,CACH,iBAAiB,IAAI;QAAM,WAAW;0BAAsB,CAC5D,CAAA;AACF,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Location } from '@remix-run/router';
|
|
2
|
+
import { LayoutProps, MenuProps, SiderProps } from 'antd';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { MenuPage } from '../MenuPage';
|
|
5
|
+
export interface BasicLayoutProps {
|
|
6
|
+
pages?: MenuPage[];
|
|
7
|
+
compactSider?: boolean;
|
|
8
|
+
layoutProps?: LayoutProps;
|
|
9
|
+
mobileHeaderProps?: LayoutProps;
|
|
10
|
+
siderProps?: SiderProps;
|
|
11
|
+
contentProps?: LayoutProps;
|
|
12
|
+
menuProps?: Omit<MenuProps, 'items' | 'selectedKeys' | 'onSelect'>;
|
|
13
|
+
isSelectedRoute?: (page: MenuPage, location: Location) => boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* This hook can be used with react-router/BasicLayout,
|
|
17
|
+
* to ensure FIN5 URL is aligned with the internal frame URL.
|
|
18
|
+
*/
|
|
19
|
+
export declare const useLocationUpdate: () => void;
|
|
20
|
+
/**
|
|
21
|
+
* Basic layout that uses React Router.
|
|
22
|
+
*/
|
|
23
|
+
export declare const BasicLayout: React.FC<BasicLayoutProps>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023, J2 Innovations. All Rights Reserved
|
|
3
|
+
*/
|
|
4
|
+
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
|
|
5
|
+
import { Layout, Menu } from '@j2inn/ui';
|
|
6
|
+
import classNames from 'classnames';
|
|
7
|
+
import { IN_IFRAME, fin5SkipHashUpdate, getFin5HashFrameParameters, getTopLocation, } from 'fin5Top/useFin5AppURLHashParameter';
|
|
8
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
9
|
+
import { Outlet, useLocation, useNavigate } from 'react-router';
|
|
10
|
+
import { HEADER_HEIGHT, getMenuPages, useStyles } from '../BasicLayout';
|
|
11
|
+
import { pageTreeToPageList } from '../MenuPage';
|
|
12
|
+
// Workaround j2inn/ui exporting problem
|
|
13
|
+
const Header = Layout.Header;
|
|
14
|
+
const Sider = Layout.Sider;
|
|
15
|
+
const Content = Layout.Content;
|
|
16
|
+
/**
|
|
17
|
+
* This hook can be used with react-router/BasicLayout,
|
|
18
|
+
* to ensure FIN5 URL is aligned with the internal frame URL.
|
|
19
|
+
*/
|
|
20
|
+
export const useLocationUpdate = () => {
|
|
21
|
+
const location = useLocation();
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
console.debug('Location changed', location);
|
|
24
|
+
const hash = location.pathname;
|
|
25
|
+
const queryParams = location.search;
|
|
26
|
+
if (IN_IFRAME) {
|
|
27
|
+
fin5SkipHashUpdate()?.then(() => {
|
|
28
|
+
const frameParameters = getFin5HashFrameParameters();
|
|
29
|
+
frameParameters.set('url', frameParameters.get('url')?.split('#')[0] +
|
|
30
|
+
'#' +
|
|
31
|
+
hash +
|
|
32
|
+
queryParams);
|
|
33
|
+
getTopLocation().hash = `#${getTopLocation().hash.slice(1).split('?')[0]}?${frameParameters.toString()}`;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}, [location]);
|
|
37
|
+
};
|
|
38
|
+
const useSelectedRoutes = (pages, isSelectedRoute = (page, location) => location.pathname.includes(`/${page.key}`)) => {
|
|
39
|
+
const location = useLocation();
|
|
40
|
+
return useMemo(() => {
|
|
41
|
+
const flatPages = pageTreeToPageList(pages);
|
|
42
|
+
return flatPages
|
|
43
|
+
.filter((page) => isSelectedRoute(page, location))
|
|
44
|
+
.map((page) => page.key);
|
|
45
|
+
}, [location, pages]);
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Basic layout that uses React Router.
|
|
49
|
+
*/
|
|
50
|
+
export const BasicLayout = ({ pages = [], compactSider, layoutProps, mobileHeaderProps, siderProps, contentProps, menuProps, isSelectedRoute, }) => {
|
|
51
|
+
const navigate = useNavigate();
|
|
52
|
+
const selectedRoutes = useSelectedRoutes(pages, isSelectedRoute);
|
|
53
|
+
// manage mobile navigation
|
|
54
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
55
|
+
const [hiddenSider, setHiddenSider] = useState(false);
|
|
56
|
+
const siderWidth = siderProps?.width;
|
|
57
|
+
const classes = useStyles({ isMobile, compactSider, siderWidth });
|
|
58
|
+
const menuPages = useMemo(() => getMenuPages(pages), [pages]);
|
|
59
|
+
return (React.createElement(Layout, { hasSider: true, ...layoutProps },
|
|
60
|
+
isMobile && (React.createElement(Header, { ...mobileHeaderProps, className: classNames(classes.header, mobileHeaderProps?.className) }, hiddenSider ? (React.createElement(MenuUnfoldOutlined, { className: classes.menuTrigger, onClick: () => {
|
|
61
|
+
setHiddenSider(!hiddenSider);
|
|
62
|
+
} })) : (React.createElement(MenuFoldOutlined, { className: classes.menuTrigger, onClick: () => {
|
|
63
|
+
setHiddenSider(!hiddenSider);
|
|
64
|
+
} })))),
|
|
65
|
+
React.createElement(Sider, { ...siderProps, className: classNames(classes.sider, siderProps?.className), breakpoint: 'md', onBreakpoint: (broken) => {
|
|
66
|
+
setIsMobile(broken);
|
|
67
|
+
setHiddenSider(true);
|
|
68
|
+
}, collapsed: (isMobile && hiddenSider) || compactSider, collapsedWidth: isMobile && hiddenSider
|
|
69
|
+
? 0
|
|
70
|
+
: compactSider
|
|
71
|
+
? HEADER_HEIGHT
|
|
72
|
+
: 0, trigger: null },
|
|
73
|
+
React.createElement(Menu, { ...menuProps, items: menuPages, selectedKeys: selectedRoutes, onSelect: ({ key }) => {
|
|
74
|
+
if (!hiddenSider) {
|
|
75
|
+
setHiddenSider(true);
|
|
76
|
+
}
|
|
77
|
+
navigate(key);
|
|
78
|
+
} })),
|
|
79
|
+
React.createElement(Content, { ...contentProps, className: classNames(classes.content, contentProps?.className) },
|
|
80
|
+
React.createElement(Outlet, null))));
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=BasicLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BasicLayout.js","sourceRoot":"","sources":["../../../../../src/react/components/navigation/react-router/BasicLayout.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Location } from '@remix-run/router';
|
|
2
|
+
import { LayoutProps, MenuProps, SiderProps } from 'antd';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { MenuPage } from '../MenuPage';
|
|
5
|
+
export interface ReactRouterBasicLayoutProps {
|
|
6
|
+
pages?: MenuPage[];
|
|
7
|
+
defaultPage?: string;
|
|
8
|
+
compactSider?: boolean;
|
|
9
|
+
layoutProps?: LayoutProps;
|
|
10
|
+
mobileHeaderProps?: LayoutProps;
|
|
11
|
+
siderProps?: SiderProps;
|
|
12
|
+
contentProps?: LayoutProps;
|
|
13
|
+
menuProps?: Omit<MenuProps, 'items' | 'selectedKeys' | 'onSelect'>;
|
|
14
|
+
isSelectedRoute?: (page: MenuPage, location: Location) => boolean;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* This hook can be used with react-router/BasicLayout,
|
|
18
|
+
* to ensure FIN5 URL is aligned with the internal frame URL.
|
|
19
|
+
*/
|
|
20
|
+
export declare const useLocationUpdate: () => void;
|
|
21
|
+
/**
|
|
22
|
+
* Basic layout that uses React Router.
|
|
23
|
+
*/
|
|
24
|
+
export declare const ReactRouterBasicLayout: React.FC<ReactRouterBasicLayoutProps>;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2023, J2 Innovations. All Rights Reserved
|
|
3
|
+
*/
|
|
4
|
+
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons';
|
|
5
|
+
import { Layout, Menu } from '@j2inn/ui';
|
|
6
|
+
import classNames from 'classnames';
|
|
7
|
+
import React, { useEffect, useMemo, useState } from 'react';
|
|
8
|
+
import { Outlet, useLocation, useNavigate } from 'react-router';
|
|
9
|
+
import { IN_IFRAME, fin5SkipHashUpdate, getFin5HashFrameParameters, getTopLocation, } from '../../../../fin5Top/useFin5AppURLHashParameter';
|
|
10
|
+
import { HEADER_HEIGHT, getMenuPages, useStyles } from '../BasicLayout';
|
|
11
|
+
import { pageTreeToPageList } from '../MenuPage';
|
|
12
|
+
// Workaround j2inn/ui exporting problem
|
|
13
|
+
const Header = Layout.Header;
|
|
14
|
+
const Sider = Layout.Sider;
|
|
15
|
+
const Content = Layout.Content;
|
|
16
|
+
/**
|
|
17
|
+
* This hook can be used with react-router/BasicLayout,
|
|
18
|
+
* to ensure FIN5 URL is aligned with the internal frame URL.
|
|
19
|
+
*/
|
|
20
|
+
export const useLocationUpdate = () => {
|
|
21
|
+
const location = useLocation();
|
|
22
|
+
useEffect(() => {
|
|
23
|
+
console.debug('Location changed', location);
|
|
24
|
+
const hash = location.pathname;
|
|
25
|
+
const queryParams = location.search;
|
|
26
|
+
if (IN_IFRAME) {
|
|
27
|
+
fin5SkipHashUpdate()?.then(() => {
|
|
28
|
+
const frameParameters = getFin5HashFrameParameters();
|
|
29
|
+
frameParameters.set('url', frameParameters.get('url')?.split('#')[0] +
|
|
30
|
+
'#' +
|
|
31
|
+
hash +
|
|
32
|
+
queryParams);
|
|
33
|
+
getTopLocation().hash = `#${getTopLocation().hash.slice(1).split('?')[0]}?${frameParameters.toString()}`;
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}, [location]);
|
|
37
|
+
};
|
|
38
|
+
const useSelectedRoutes = (pages, isSelectedRoute = (page, location) => location.pathname.includes(`/${page.key}`)) => {
|
|
39
|
+
const location = useLocation();
|
|
40
|
+
return useMemo(() => {
|
|
41
|
+
const flatPages = pageTreeToPageList(pages);
|
|
42
|
+
return flatPages
|
|
43
|
+
.filter((page) => isSelectedRoute(page, location))
|
|
44
|
+
.map((page) => page.key);
|
|
45
|
+
}, [location, pages]);
|
|
46
|
+
};
|
|
47
|
+
/**
|
|
48
|
+
* Basic layout that uses React Router.
|
|
49
|
+
*/
|
|
50
|
+
export const ReactRouterBasicLayout = ({ pages = [], defaultPage, compactSider, layoutProps, mobileHeaderProps, siderProps, contentProps, menuProps, isSelectedRoute, }) => {
|
|
51
|
+
const navigate = useNavigate();
|
|
52
|
+
const selectedRoutes = useSelectedRoutes(pages, isSelectedRoute);
|
|
53
|
+
// manage mobile navigation
|
|
54
|
+
const [isMobile, setIsMobile] = useState(false);
|
|
55
|
+
const [hiddenSider, setHiddenSider] = useState(false);
|
|
56
|
+
const siderWidth = siderProps?.width;
|
|
57
|
+
const classes = useStyles({ isMobile, compactSider, siderWidth });
|
|
58
|
+
const menuPages = useMemo(() => getMenuPages(pages), [pages]);
|
|
59
|
+
return (React.createElement(Layout, { hasSider: true, ...layoutProps },
|
|
60
|
+
isMobile && (React.createElement(Header, { ...mobileHeaderProps, className: classNames(classes.header, mobileHeaderProps?.className) }, hiddenSider ? (React.createElement(MenuUnfoldOutlined, { className: classes.menuTrigger, onClick: () => {
|
|
61
|
+
setHiddenSider(!hiddenSider);
|
|
62
|
+
} })) : (React.createElement(MenuFoldOutlined, { className: classes.menuTrigger, onClick: () => {
|
|
63
|
+
setHiddenSider(!hiddenSider);
|
|
64
|
+
} })))),
|
|
65
|
+
React.createElement(Sider, { ...siderProps, className: classNames(classes.sider, siderProps?.className), breakpoint: 'md', onBreakpoint: (broken) => {
|
|
66
|
+
setIsMobile(broken);
|
|
67
|
+
setHiddenSider(true);
|
|
68
|
+
}, collapsed: (isMobile && hiddenSider) || compactSider, collapsedWidth: isMobile && hiddenSider
|
|
69
|
+
? 0
|
|
70
|
+
: compactSider
|
|
71
|
+
? HEADER_HEIGHT
|
|
72
|
+
: 0, trigger: null },
|
|
73
|
+
React.createElement(Menu, { ...menuProps, defaultSelectedKeys: defaultPage ? [defaultPage] : undefined, items: menuPages, selectedKeys: selectedRoutes, onSelect: ({ key }) => {
|
|
74
|
+
if (!hiddenSider) {
|
|
75
|
+
setHiddenSider(true);
|
|
76
|
+
}
|
|
77
|
+
navigate(key);
|
|
78
|
+
} })),
|
|
79
|
+
React.createElement(Content, { ...contentProps, className: classNames(classes.content, contentProps?.className) },
|
|
80
|
+
React.createElement(Outlet, null))));
|
|
81
|
+
};
|
|
82
|
+
//# sourceMappingURL=ReactRouterBasicLayout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ReactRouterBasicLayout.js","sourceRoot":"","sources":["../../../../../src/react/components/navigation/react-router/ReactRouterBasicLayout.tsx"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@j2inn/fin5-ui-utils",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.6-beta.0",
|
|
4
4
|
"description": "A set of useful client-side utilities useful for creating UI applications on top of FIN 5",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"js-yaml": "^4.1.0"
|
|
32
32
|
},
|
|
33
33
|
"peerDependencies": {
|
|
34
|
+
"@amcharts/amcharts5": "^5.4.4",
|
|
34
35
|
"@j2inn/app": "^2.0.0",
|
|
35
36
|
"@j2inn/resolvable-ui-elements": "^1.0.1",
|
|
36
37
|
"@j2inn/ui": "^6.0.22",
|
|
@@ -121,4 +122,4 @@
|
|
|
121
122
|
"eslint --fix"
|
|
122
123
|
]
|
|
123
124
|
}
|
|
124
|
-
}
|
|
125
|
+
}
|