datastake-daf 0.6.97 → 0.6.98
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/dist/components/index.js +130 -20
- package/package.json +107 -107
- package/rollup.config.js +41 -83
- package/src/@daf/core/components/Dashboard/DashboardLayout/DashboardLayout.stories.jsx +2 -1
- package/src/@daf/core/components/Dashboard/DashboardLayout/index.jsx +2 -1
- package/src/@daf/core/components/Footer/Footer.stories.jsx +152 -0
- package/src/@daf/core/components/Footer/hook.js +84 -0
- package/src/@daf/core/components/Footer/index.jsx +101 -0
- package/src/@daf/core/components/Footer/style.js +176 -0
- package/src/index.js +3 -0
- package/src/styles/_index.scss +1 -1
- package/src/styles/datastake.scss +4454 -1
- package/.vscode/settings.json +0 -13
- package/dist/style/datastake/_index.css +0 -5
- package/dist/style/datastake/datastake.css +0 -5081
- package/dist/style/datastake/fonts/Outfit-Black.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-Bold.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-ExtraBold.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-ExtraLight.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-Light.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-Medium.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-Regular.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-SemiBold.ttf +0 -0
- package/dist/style/datastake/fonts/Outfit-Thin.ttf +0 -0
- package/dist/style/datastake/fonts/outfit.css +0 -62
- package/dist/style/datastake/fonts/sf-ui-display-black-58646a6b80d5a.woff +0 -0
- package/dist/style/datastake/fonts/sf-ui-display-bold-58646a511e3d9.woff +0 -0
- package/dist/style/datastake/fonts/sf-ui-display-heavy-586470160b9e5.woff +0 -0
- package/dist/style/datastake/fonts/sf-ui-display-light-58646b33e0551.woff +0 -0
- package/dist/style/datastake/fonts/sf-ui-display-medium-58646be638f96.woff +0 -0
- package/dist/style/datastake/fonts/sf-ui-display-semibold-58646eddcae92.woff +0 -0
- package/dist/style/datastake/fonts/sf-ui-display-thin-58646e9b26e8b.woff +0 -0
- package/dist/style/datastake/fonts/sf-ui-display-ultralight-58646b19bf205.woff +0 -0
- package/dist/style/datastake/fonts/sfDisplay.css +0 -59
- package/dist/style/datastake/leaflet.css +0 -671
- package/dist/style/datastake/leaflet.markercluster.css +0 -60
- package/dist/style/style.css +0 -1
- package/src/styles/datastake/_index.css +0 -5
- package/src/styles/datastake/datastake.css +0 -5081
- package/src/styles/datastake/fonts/Outfit-Black.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-Bold.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-ExtraBold.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-ExtraLight.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-Light.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-Medium.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-Regular.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-SemiBold.ttf +0 -0
- package/src/styles/datastake/fonts/Outfit-Thin.ttf +0 -0
- package/src/styles/datastake/fonts/outfit.css +0 -62
- package/src/styles/datastake/fonts/sf-ui-display-black-58646a6b80d5a.woff +0 -0
- package/src/styles/datastake/fonts/sf-ui-display-bold-58646a511e3d9.woff +0 -0
- package/src/styles/datastake/fonts/sf-ui-display-heavy-586470160b9e5.woff +0 -0
- package/src/styles/datastake/fonts/sf-ui-display-light-58646b33e0551.woff +0 -0
- package/src/styles/datastake/fonts/sf-ui-display-medium-58646be638f96.woff +0 -0
- package/src/styles/datastake/fonts/sf-ui-display-semibold-58646eddcae92.woff +0 -0
- package/src/styles/datastake/fonts/sf-ui-display-thin-58646e9b26e8b.woff +0 -0
- package/src/styles/datastake/fonts/sf-ui-display-ultralight-58646b19bf205.woff +0 -0
- package/src/styles/datastake/fonts/sfDisplay.css +0 -59
- package/src/styles/datastake/leaflet.css +0 -671
- package/src/styles/datastake/leaflet.markercluster.css +0 -60
package/rollup.config.js
CHANGED
|
@@ -1,145 +1,103 @@
|
|
|
1
|
-
import babel from
|
|
2
|
-
import commonjs from
|
|
3
|
-
import resolve from
|
|
4
|
-
import peerDep from
|
|
5
|
-
import nodePolyfills from
|
|
6
|
-
import postcss from
|
|
7
|
-
|
|
1
|
+
import babel from 'rollup-plugin-babel';
|
|
2
|
+
import commonjs from 'rollup-plugin-commonjs';
|
|
3
|
+
import resolve from 'rollup-plugin-node-resolve';
|
|
4
|
+
import peerDep from 'rollup-plugin-peer-deps-external';
|
|
5
|
+
import nodePolyfills from 'rollup-plugin-node-polyfills';
|
|
6
|
+
import postcss from 'rollup-plugin-postcss'; // Add this plugin
|
|
7
|
+
|
|
8
8
|
|
|
9
9
|
// When you add a new package and you have problems publishing, you can add it here and try publishing again
|
|
10
10
|
const external = [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
"leaflet",
|
|
20
|
-
"react-is",
|
|
21
|
-
"countries-list",
|
|
22
|
-
"react/jsx-runtime",
|
|
23
|
-
"lodash",
|
|
24
|
-
"lodash.camelcase",
|
|
25
|
-
"@antv/g2",
|
|
26
|
-
"dot-object",
|
|
27
|
-
"react-collapsed",
|
|
28
|
-
"leaflet-geosearch",
|
|
29
|
-
"react-html-parser",
|
|
30
|
-
"styled-component",
|
|
31
|
-
"@ant-design/icons",
|
|
32
|
-
"deepmerge",
|
|
33
|
-
"leaflet.heat",
|
|
34
|
-
"leaflet.markercluster",
|
|
35
|
-
"react-flow-renderer",
|
|
36
|
-
"country-city-location",
|
|
37
|
-
"@antv/g2plot",
|
|
38
|
-
"@xyflow/react",
|
|
39
|
-
"leaflet-editable",
|
|
40
|
-
"@xyflow/react",
|
|
41
|
-
"zustand/shallow",
|
|
42
|
-
"@elfalem/leaflet-curve",
|
|
11
|
+
'react', 'react-dom', 'react-dom/client', 'antd', 'prop-types', 'dayjs',
|
|
12
|
+
'dayjs', 'moment', 'leaflet', 'react-is', 'countries-list',
|
|
13
|
+
'react/jsx-runtime', 'lodash', 'lodash.camelcase',
|
|
14
|
+
'@antv/g2', 'dot-object', 'react-collapsed', 'leaflet-geosearch',
|
|
15
|
+
'react-html-parser', 'styled-component', '@ant-design/icons',
|
|
16
|
+
'deepmerge', 'leaflet.heat', 'leaflet.markercluster', 'react-flow-renderer',
|
|
17
|
+
'country-city-location', '@antv/g2plot', '@xyflow/react', 'leaflet-editable',
|
|
18
|
+
'@xyflow/react', 'zustand/shallow', '@elfalem/leaflet-curve'
|
|
43
19
|
];
|
|
44
20
|
|
|
45
|
-
// Four builds, components, utils, hooks
|
|
21
|
+
// Four builds, components, utils, hooks and context
|
|
46
22
|
export default [
|
|
47
23
|
{
|
|
48
|
-
input:
|
|
24
|
+
input: 'src/index.js',
|
|
49
25
|
output: [
|
|
50
26
|
{
|
|
51
|
-
file:
|
|
52
|
-
format:
|
|
27
|
+
file: 'dist/components/index.js',
|
|
28
|
+
format: 'cjs',
|
|
53
29
|
},
|
|
54
30
|
],
|
|
55
31
|
external,
|
|
56
32
|
plugins: [
|
|
57
33
|
nodePolyfills(),
|
|
58
34
|
resolve({ browser: true }),
|
|
59
|
-
babel({ exclude:
|
|
35
|
+
babel({ exclude: 'node_modules/**', babelrc: true }),
|
|
60
36
|
peerDep(),
|
|
61
37
|
commonjs({
|
|
62
38
|
include: /node_modules/,
|
|
63
|
-
requireReturnsDefault:
|
|
39
|
+
requireReturnsDefault: 'auto',
|
|
64
40
|
}),
|
|
65
|
-
postcss({
|
|
66
|
-
extract: true,
|
|
67
|
-
minimize: true,
|
|
68
|
-
modules: true,
|
|
41
|
+
postcss({
|
|
42
|
+
extract: true,
|
|
43
|
+
minimize: true,
|
|
44
|
+
modules: true,
|
|
69
45
|
}),
|
|
70
46
|
],
|
|
71
47
|
},
|
|
72
48
|
{
|
|
73
|
-
input:
|
|
49
|
+
input: 'src/utils.js',
|
|
74
50
|
output: [
|
|
75
51
|
{
|
|
76
|
-
file:
|
|
77
|
-
format:
|
|
52
|
+
file: 'dist/utils/index.js',
|
|
53
|
+
format: 'cjs',
|
|
78
54
|
},
|
|
79
55
|
],
|
|
80
56
|
external,
|
|
81
57
|
plugins: [
|
|
82
58
|
nodePolyfills(),
|
|
83
59
|
resolve({ browser: true }),
|
|
84
|
-
babel({ exclude:
|
|
60
|
+
babel({ exclude: 'node_modules/**', babelrc: true }),
|
|
85
61
|
peerDep(),
|
|
86
62
|
commonjs({
|
|
87
63
|
include: /node_modules/,
|
|
88
|
-
requireReturnsDefault:
|
|
64
|
+
requireReturnsDefault: 'auto',
|
|
89
65
|
}),
|
|
90
66
|
],
|
|
91
67
|
},
|
|
92
68
|
{
|
|
93
|
-
input:
|
|
69
|
+
input: 'src/hooks.js',
|
|
94
70
|
output: [
|
|
95
71
|
{
|
|
96
|
-
file:
|
|
97
|
-
format:
|
|
72
|
+
file: 'dist/hooks/index.js',
|
|
73
|
+
format: 'cjs',
|
|
98
74
|
},
|
|
99
75
|
],
|
|
100
76
|
external,
|
|
101
77
|
plugins: [
|
|
102
78
|
nodePolyfills(),
|
|
103
79
|
resolve({ browser: true }),
|
|
104
|
-
babel({ exclude:
|
|
80
|
+
babel({ exclude: 'node_modules/**', babelrc: true }),
|
|
105
81
|
peerDep(),
|
|
106
82
|
commonjs({
|
|
107
83
|
include: /node_modules/,
|
|
108
|
-
requireReturnsDefault:
|
|
84
|
+
requireReturnsDefault: 'auto',
|
|
109
85
|
}),
|
|
110
86
|
],
|
|
111
87
|
},
|
|
112
88
|
{
|
|
113
|
-
input:
|
|
89
|
+
input: 'src/context.js',
|
|
114
90
|
output: [
|
|
115
91
|
{
|
|
116
|
-
file:
|
|
117
|
-
format:
|
|
92
|
+
file: 'dist/context/index.js',
|
|
93
|
+
format: 'cjs',
|
|
118
94
|
},
|
|
119
95
|
],
|
|
120
96
|
external,
|
|
121
|
-
plugins: [resolve(), babel({ exclude: "node_modules/**" }), peerDep()],
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
input: "src/styles/datastake.scss",
|
|
125
|
-
output: [
|
|
126
|
-
{
|
|
127
|
-
file: "dist/style/style.css",
|
|
128
|
-
},
|
|
129
|
-
],
|
|
130
97
|
plugins: [
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
sourceMap: false,
|
|
135
|
-
extensions: [".scss"],
|
|
136
|
-
use: [["sass", { javascriptEnabled: true }]],
|
|
137
|
-
}),
|
|
138
|
-
copy({
|
|
139
|
-
targets: [
|
|
140
|
-
{ src: "src/styles/datastake/*", dest: "dist/style/datastake" },
|
|
141
|
-
],
|
|
142
|
-
}),
|
|
98
|
+
resolve(),
|
|
99
|
+
babel({ exclude: 'node_modules/**' }),
|
|
100
|
+
peerDep(),
|
|
143
101
|
],
|
|
144
102
|
},
|
|
145
103
|
];
|
|
@@ -2,7 +2,7 @@ import DashboardLayout from "./index.jsx";
|
|
|
2
2
|
import ThemeLayout from "../../ThemeLayout";
|
|
3
3
|
import Widget from "../Widget/index.jsx";
|
|
4
4
|
import Header from "../../Header/index.jsx";
|
|
5
|
-
|
|
5
|
+
import Footer from "../../Footer/index.jsx";
|
|
6
6
|
export default {
|
|
7
7
|
title: "Dashboard/DashboardLayout",
|
|
8
8
|
component: DashboardLayout,
|
|
@@ -23,6 +23,7 @@ export const Primary = {
|
|
|
23
23
|
render: () => (
|
|
24
24
|
<DashboardLayout
|
|
25
25
|
header={<Header title="Dashboard" supportText="The Support text for the header" />}
|
|
26
|
+
footer={<Footer actionButtons={[{ label: "Next", type: "primary", onClick: () => console.log("Next clicked") }]} />}
|
|
26
27
|
>
|
|
27
28
|
<section>
|
|
28
29
|
<Widget title="Widget Title">
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Every Widget inside the component (children) must be wrapped by a section tag, because i say so and if you dont like it you can change the code in the entire codebase, included but not limited to the following projects: nashiriki, tazama, kustawi, sbg, cukura, kota, mmt, and wherever the daf library is used.
|
|
7
7
|
*/
|
|
8
|
-
export default function DashboardLayout({ children, header }) {
|
|
8
|
+
export default function DashboardLayout({ children, header, footer }) {
|
|
9
9
|
return (
|
|
10
10
|
<div
|
|
11
11
|
className="daf-analysis"
|
|
@@ -19,6 +19,7 @@ export default function DashboardLayout({ children, header }) {
|
|
|
19
19
|
<div className="sections-cont w-pt">{children}</div>
|
|
20
20
|
</div>
|
|
21
21
|
</div>
|
|
22
|
+
{footer}
|
|
22
23
|
</div>
|
|
23
24
|
);
|
|
24
25
|
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { default as Footer } from './index.jsx';
|
|
3
|
+
import { Button } from 'antd';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Components/Footer',
|
|
7
|
+
component: Footer,
|
|
8
|
+
parameters: {
|
|
9
|
+
layout: 'fullscreen',
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Template = (args) => (
|
|
14
|
+
<div style={{ height: '100vh', display: 'flex', flexDirection: 'column', background: '#2c2c2c' }}>
|
|
15
|
+
<div style={{ flex: 1, padding: '20px', background: '#2c2c2c', color: 'white' }}>
|
|
16
|
+
<h2>Main Content Area</h2>
|
|
17
|
+
<p>This is the main content area. The footer will be at the bottom.</p>
|
|
18
|
+
</div>
|
|
19
|
+
<Footer {...args} />
|
|
20
|
+
</div>
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export const Default = Template.bind({});
|
|
24
|
+
Default.args = {
|
|
25
|
+
leftContent: null,
|
|
26
|
+
centerContent: null,
|
|
27
|
+
rightContent: null,
|
|
28
|
+
actionButtons: [
|
|
29
|
+
{
|
|
30
|
+
label: 'Next',
|
|
31
|
+
type: 'primary',
|
|
32
|
+
onClick: () => console.log('Next clicked'),
|
|
33
|
+
},
|
|
34
|
+
],
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const WithLeftContent = Template.bind({});
|
|
38
|
+
WithLeftContent.args = {
|
|
39
|
+
leftContent: (
|
|
40
|
+
<div>
|
|
41
|
+
<span>© 2024 DataStake</span>
|
|
42
|
+
<br />
|
|
43
|
+
<span style={{ fontSize: '12px', color: '#666' }}>
|
|
44
|
+
All rights reserved
|
|
45
|
+
</span>
|
|
46
|
+
</div>
|
|
47
|
+
),
|
|
48
|
+
centerContent: null,
|
|
49
|
+
rightContent: null,
|
|
50
|
+
actionButtons: [],
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export const WithCenterContent = Template.bind({});
|
|
54
|
+
WithCenterContent.args = {
|
|
55
|
+
leftContent: null,
|
|
56
|
+
centerContent: (
|
|
57
|
+
<div style={{ textAlign: 'center' }}>
|
|
58
|
+
<span>Last updated: {new Date().toLocaleDateString()}</span>
|
|
59
|
+
</div>
|
|
60
|
+
),
|
|
61
|
+
rightContent: null,
|
|
62
|
+
actionButtons: [],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const WithRightContent = Template.bind({});
|
|
66
|
+
WithRightContent.args = {
|
|
67
|
+
leftContent: null,
|
|
68
|
+
centerContent: null,
|
|
69
|
+
rightContent: (
|
|
70
|
+
<div>
|
|
71
|
+
<Button type="link" size="small">
|
|
72
|
+
Help
|
|
73
|
+
</Button>
|
|
74
|
+
<Button type="link" size="small">
|
|
75
|
+
Support
|
|
76
|
+
</Button>
|
|
77
|
+
</div>
|
|
78
|
+
),
|
|
79
|
+
actionButtons: [],
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
export const FixedFooter = Template.bind({});
|
|
83
|
+
FixedFooter.args = {
|
|
84
|
+
fixed: true,
|
|
85
|
+
leftContent: <span>Fixed Footer</span>,
|
|
86
|
+
centerContent: <span>This footer is fixed to the bottom</span>,
|
|
87
|
+
rightContent: null,
|
|
88
|
+
actionButtons: [
|
|
89
|
+
{
|
|
90
|
+
label: 'Action',
|
|
91
|
+
type: 'primary',
|
|
92
|
+
onClick: () => console.log('Action clicked'),
|
|
93
|
+
},
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
|
|
97
|
+
export const FullContent = Template.bind({});
|
|
98
|
+
FullContent.args = {
|
|
99
|
+
leftContent: (
|
|
100
|
+
<div>
|
|
101
|
+
<span>© 2024 DataStake</span>
|
|
102
|
+
<br />
|
|
103
|
+
<span style={{ fontSize: '12px', color: '#666' }}>
|
|
104
|
+
All rights reserved
|
|
105
|
+
</span>
|
|
106
|
+
</div>
|
|
107
|
+
),
|
|
108
|
+
centerContent: (
|
|
109
|
+
<div style={{ textAlign: 'center' }}>
|
|
110
|
+
<span>Version 1.0.0</span>
|
|
111
|
+
<br />
|
|
112
|
+
<span style={{ fontSize: '12px', color: '#666' }}>
|
|
113
|
+
Last updated: {new Date().toLocaleDateString()}
|
|
114
|
+
</span>
|
|
115
|
+
</div>
|
|
116
|
+
),
|
|
117
|
+
rightContent: (
|
|
118
|
+
<div>
|
|
119
|
+
<Button type="link" size="small">
|
|
120
|
+
Help
|
|
121
|
+
</Button>
|
|
122
|
+
<Button type="link" size="small">
|
|
123
|
+
Support
|
|
124
|
+
</Button>
|
|
125
|
+
</div>
|
|
126
|
+
),
|
|
127
|
+
actionButtons: [
|
|
128
|
+
{
|
|
129
|
+
label: 'Save',
|
|
130
|
+
type: 'primary',
|
|
131
|
+
onClick: () => console.log('Save clicked'),
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
label: 'Cancel',
|
|
135
|
+
onClick: () => console.log('Cancel clicked'),
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
};
|
|
139
|
+
|
|
140
|
+
export const ImageStyle = Template.bind({});
|
|
141
|
+
ImageStyle.args = {
|
|
142
|
+
leftContent: null,
|
|
143
|
+
centerContent: null,
|
|
144
|
+
rightContent: null,
|
|
145
|
+
actionButtons: [
|
|
146
|
+
{
|
|
147
|
+
label: 'Next',
|
|
148
|
+
type: 'primary',
|
|
149
|
+
onClick: () => console.log('Next clicked'),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { Space } from "antd";
|
|
3
|
+
import DafButton from "../Button/index.jsx";
|
|
4
|
+
import CustomIcon from "../Icon/CustomIcon.jsx";
|
|
5
|
+
import { BTN_TYPES, BTN_SIZE } from "../../../utils/button.js";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Custom hook for managing footer state and rendering logic
|
|
9
|
+
*/
|
|
10
|
+
export const useFooter = ({
|
|
11
|
+
leftContent,
|
|
12
|
+
centerContent,
|
|
13
|
+
rightContent,
|
|
14
|
+
actionButtons,
|
|
15
|
+
app,
|
|
16
|
+
isViewMode,
|
|
17
|
+
}) => {
|
|
18
|
+
const renderFooterContent = useMemo(() => {
|
|
19
|
+
const FooterContent = () => (
|
|
20
|
+
<div className="daf-footer-content">
|
|
21
|
+
<div className="daf-footer-left">
|
|
22
|
+
{leftContent}
|
|
23
|
+
</div>
|
|
24
|
+
|
|
25
|
+
<div className="daf-footer-center">
|
|
26
|
+
{centerContent}
|
|
27
|
+
</div>
|
|
28
|
+
|
|
29
|
+
<div className="daf-footer-right">
|
|
30
|
+
{rightContent}
|
|
31
|
+
{actionButtons.length > 0 && (
|
|
32
|
+
<Space className="daf-footer-actions">
|
|
33
|
+
{actionButtons.map((button, index) => {
|
|
34
|
+
const {
|
|
35
|
+
label,
|
|
36
|
+
onClick,
|
|
37
|
+
icon,
|
|
38
|
+
type = BTN_TYPES.PRIMARY,
|
|
39
|
+
tooltip,
|
|
40
|
+
disabled = false,
|
|
41
|
+
loading = false,
|
|
42
|
+
style = {},
|
|
43
|
+
className = "",
|
|
44
|
+
...restProps
|
|
45
|
+
} = button;
|
|
46
|
+
|
|
47
|
+
return (
|
|
48
|
+
<DafButton
|
|
49
|
+
key={index}
|
|
50
|
+
content={label}
|
|
51
|
+
type={type}
|
|
52
|
+
size={BTN_SIZE.MD}
|
|
53
|
+
icon={typeof icon === "string" ? <CustomIcon name={icon} /> : icon}
|
|
54
|
+
onClick={onClick}
|
|
55
|
+
disabled={disabled || isViewMode}
|
|
56
|
+
loading={loading}
|
|
57
|
+
title={tooltip}
|
|
58
|
+
style={style}
|
|
59
|
+
className={className}
|
|
60
|
+
{...restProps}
|
|
61
|
+
/>
|
|
62
|
+
);
|
|
63
|
+
})}
|
|
64
|
+
</Space>
|
|
65
|
+
)}
|
|
66
|
+
</div>
|
|
67
|
+
</div>
|
|
68
|
+
);
|
|
69
|
+
|
|
70
|
+
FooterContent.displayName = 'FooterContent';
|
|
71
|
+
return FooterContent;
|
|
72
|
+
}, [
|
|
73
|
+
leftContent,
|
|
74
|
+
centerContent,
|
|
75
|
+
rightContent,
|
|
76
|
+
actionButtons,
|
|
77
|
+
app,
|
|
78
|
+
isViewMode,
|
|
79
|
+
]);
|
|
80
|
+
|
|
81
|
+
return {
|
|
82
|
+
renderFooterContent,
|
|
83
|
+
};
|
|
84
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import PropTypes from "prop-types";
|
|
2
|
+
import { useFooter } from "./hook.js";
|
|
3
|
+
import { FooterContainer } from "./style.js";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* DAFFooter Component
|
|
7
|
+
*
|
|
8
|
+
* A flexible footer component for the DAF dashboard layout.
|
|
9
|
+
*
|
|
10
|
+
* Props:
|
|
11
|
+
* - `leftContent` (ReactNode):
|
|
12
|
+
* Optional content to display on the left side of the footer.
|
|
13
|
+
* Default: `null`.
|
|
14
|
+
*
|
|
15
|
+
* - `centerContent` (ReactNode):
|
|
16
|
+
* Optional content to display in the center of the footer.
|
|
17
|
+
* Default: `null`.
|
|
18
|
+
*
|
|
19
|
+
* - `rightContent` (ReactNode):
|
|
20
|
+
* Optional content to display on the right side of the footer.
|
|
21
|
+
* Default: `null`.
|
|
22
|
+
*
|
|
23
|
+
* - `actionButtons` (Array):
|
|
24
|
+
* An array of action button configurations to be rendered in the footer.
|
|
25
|
+
* Each item in the array is an object with the following optional properties:
|
|
26
|
+
* - `label` (string): Text displayed on the button.
|
|
27
|
+
* - `onClick` (function): Callback when the button is clicked.
|
|
28
|
+
* - `icon` (ReactNode | string): Optional icon shown before or inside the button.
|
|
29
|
+
* - `type` (string): Visual style (e.g., `"primary"`, `"danger"`, `"ghost"`).
|
|
30
|
+
* - `tooltip` (string | ReactNode): Tooltip text or component shown on hover.
|
|
31
|
+
* - `disabled` (boolean): Whether the button is disabled.
|
|
32
|
+
* - `loading` (boolean): Whether the button is in loading state.
|
|
33
|
+
* - `style` (object): Inline styles for the button.
|
|
34
|
+
* - `className` (string): Additional class names for custom styling.
|
|
35
|
+
* Default: `[]`.
|
|
36
|
+
*
|
|
37
|
+
* - `className` (string):
|
|
38
|
+
* Additional CSS class names for the footer container.
|
|
39
|
+
* Default: `''`.
|
|
40
|
+
*
|
|
41
|
+
* - `style` (object):
|
|
42
|
+
* Inline styles for the footer container.
|
|
43
|
+
* Default: `{}`.
|
|
44
|
+
*
|
|
45
|
+
* - `fixed` (boolean):
|
|
46
|
+
* Whether the footer should be fixed to the bottom of the viewport.
|
|
47
|
+
* Default: `false`.
|
|
48
|
+
*
|
|
49
|
+
* - `app` (string):
|
|
50
|
+
* Optional app identifier for app-specific styling or logic.
|
|
51
|
+
* Default: `''`.
|
|
52
|
+
*
|
|
53
|
+
* - `isViewMode` (boolean):
|
|
54
|
+
* Indicates read-only or view-only mode, useful for disabling actions.
|
|
55
|
+
* Default: `false`.
|
|
56
|
+
*
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
export default function DAFFooter({
|
|
60
|
+
leftContent = null,
|
|
61
|
+
centerContent = null,
|
|
62
|
+
rightContent = null,
|
|
63
|
+
actionButtons = [],
|
|
64
|
+
className = "",
|
|
65
|
+
style = {},
|
|
66
|
+
fixed = false,
|
|
67
|
+
app = "",
|
|
68
|
+
isViewMode = false,
|
|
69
|
+
}) {
|
|
70
|
+
const { renderFooterContent } = useFooter({
|
|
71
|
+
leftContent,
|
|
72
|
+
centerContent,
|
|
73
|
+
rightContent,
|
|
74
|
+
actionButtons,
|
|
75
|
+
app,
|
|
76
|
+
isViewMode,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
return (
|
|
80
|
+
<FooterContainer
|
|
81
|
+
className={`${fixed ? 'daf-footer-fixed' : ''} ${className}`}
|
|
82
|
+
style={style}
|
|
83
|
+
>
|
|
84
|
+
<div className={`daf-footer ${fixed ? 'daf-footer-fixed' : ''}`}>
|
|
85
|
+
{renderFooterContent()}
|
|
86
|
+
</div>
|
|
87
|
+
</FooterContainer>
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
DAFFooter.propTypes = {
|
|
92
|
+
leftContent: PropTypes.any,
|
|
93
|
+
centerContent: PropTypes.any,
|
|
94
|
+
rightContent: PropTypes.any,
|
|
95
|
+
actionButtons: PropTypes.array,
|
|
96
|
+
className: PropTypes.string,
|
|
97
|
+
style: PropTypes.object,
|
|
98
|
+
fixed: PropTypes.bool,
|
|
99
|
+
app: PropTypes.string,
|
|
100
|
+
isViewMode: PropTypes.bool,
|
|
101
|
+
};
|