@akinon/ui-shell-dev 1.1.0 → 1.2.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/dist/akinon-favicon.png +0 -0
- package/dist/akinon-logo.png +0 -0
- package/dist/akinon-logo.svg +10 -0
- package/dist/assets/index-BFs1gfY5.css +1 -0
- package/dist/assets/index-Dk6Gr15i.js +408 -0
- package/dist/assets/jost-cyrillic-wght-normal-B0_vFdaS.woff2 +0 -0
- package/dist/assets/jost-latin-ext-wght-normal-B4kqP43q.woff2 +0 -0
- package/dist/assets/jost-latin-wght-normal-CfFW3YMY.woff2 +0 -0
- package/dist/index.html +2 -2
- package/dist/logo.png +0 -0
- package/dist/symbol.png +0 -0
- package/package.json +7 -3
- package/public/akinon-favicon.png +0 -0
- package/public/akinon-logo.png +0 -0
- package/public/akinon-logo.svg +10 -0
- package/public/logo.png +0 -0
- package/public/symbol.png +0 -0
- package/src/components/AppLayout.tsx +8 -26
- package/src/components/Header.tsx +20 -11
- package/src/components/Navigation.tsx +37 -64
- package/src/components/PageContent.tsx +9 -0
- package/src/components/PageHeading.tsx +61 -0
- package/src/components/PluginTestPage.scss +26 -0
- package/src/components/PluginTestPage.tsx +89 -207
- package/src/components/WelcomePage.tsx +72 -69
- package/src/components/layout.scss +26 -24
- package/src/global.scss +33 -0
- package/src/main.tsx +8 -2
- package/src/pages/Dashboard.tsx +25 -0
- package/src/pages/External.tsx +15 -0
- package/src/pages/PluginTest.tsx +7 -0
- package/src/pages/pages.scss +9 -0
- package/src/providers.tsx +108 -0
- package/src/routes.tsx +44 -0
- package/src/server/dev-server.mjs +18 -15
- package/src/shell-app.tsx +12 -3
- package/src/utils/navigation.tsx +65 -0
- package/dist/assets/index-cI-pE1VB.js +0 -387
- package/dist/assets/index-tRJwBFdH.css +0 -1
- package/src/components/AppRouter.tsx +0 -41
|
@@ -1,223 +1,105 @@
|
|
|
1
|
-
import
|
|
2
|
-
import React, { useState } from 'react';
|
|
1
|
+
import './PluginTestPage.scss';
|
|
3
2
|
|
|
4
|
-
import type {
|
|
5
|
-
|
|
3
|
+
import type {
|
|
4
|
+
FullpageApplicationConfig,
|
|
5
|
+
PluginApplicationConfig
|
|
6
|
+
} from '@akinon/app-shell';
|
|
7
|
+
import { PluginRenderer, useAppShell } from '@akinon/app-shell';
|
|
8
|
+
import { Breadcrumb, Col, PageHeading, Row } from '@akinon/ui-react';
|
|
9
|
+
import React from 'react';
|
|
10
|
+
import { useNavigate } from 'react-router-dom';
|
|
6
11
|
|
|
7
|
-
|
|
8
|
-
config: ShellConfig;
|
|
9
|
-
onNavigate: (view: 'welcome' | 'app' | 'plugin-test') => void;
|
|
10
|
-
}
|
|
12
|
+
import { PageContent } from './PageContent';
|
|
11
13
|
|
|
12
|
-
|
|
14
|
+
export const PluginTestPage: React.FC = () => {
|
|
15
|
+
const navigate = useNavigate();
|
|
16
|
+
const { apps, configs } = useAppShell();
|
|
13
17
|
|
|
14
|
-
const
|
|
15
|
-
|
|
16
|
-
name: 'Sidebar Plugin',
|
|
17
|
-
description: 'Plugin rendered in sidebar area',
|
|
18
|
-
dimensions: '300px × 100%',
|
|
19
|
-
containerStyle: {
|
|
20
|
-
width: '300px',
|
|
21
|
-
height: '400px',
|
|
22
|
-
border: '2px dashed #1890ff',
|
|
23
|
-
borderRadius: '4px',
|
|
24
|
-
backgroundColor: '#f0f8ff'
|
|
25
|
-
}
|
|
26
|
-
},
|
|
27
|
-
header: {
|
|
28
|
-
name: 'Header Plugin',
|
|
29
|
-
description: 'Plugin rendered in header area',
|
|
30
|
-
dimensions: '100% × 60px',
|
|
31
|
-
containerStyle: {
|
|
32
|
-
width: '100%',
|
|
33
|
-
height: '60px',
|
|
34
|
-
border: '2px dashed #52c41a',
|
|
35
|
-
borderRadius: '4px',
|
|
36
|
-
backgroundColor: '#f6ffed'
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
content: {
|
|
40
|
-
name: 'Content Plugin',
|
|
41
|
-
description: 'Plugin rendered in main content area',
|
|
42
|
-
dimensions: '100% × 400px',
|
|
43
|
-
containerStyle: {
|
|
44
|
-
width: '100%',
|
|
45
|
-
height: '400px',
|
|
46
|
-
border: '2px dashed #722ed1',
|
|
47
|
-
borderRadius: '4px',
|
|
48
|
-
backgroundColor: '#f9f0ff'
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
modal: {
|
|
52
|
-
name: 'Modal Plugin',
|
|
53
|
-
description: 'Plugin rendered in modal overlay',
|
|
54
|
-
dimensions: '600px × 400px',
|
|
55
|
-
containerStyle: {
|
|
56
|
-
width: '600px',
|
|
57
|
-
height: '400px',
|
|
58
|
-
border: '2px dashed #fa541c',
|
|
59
|
-
borderRadius: '4px',
|
|
60
|
-
backgroundColor: '#fff7e6'
|
|
61
|
-
}
|
|
62
|
-
},
|
|
63
|
-
drawer: {
|
|
64
|
-
name: 'Drawer Plugin',
|
|
65
|
-
description: 'Plugin rendered in drawer panel',
|
|
66
|
-
dimensions: '400px × 100%',
|
|
67
|
-
containerStyle: {
|
|
68
|
-
width: '400px',
|
|
69
|
-
height: '300px',
|
|
70
|
-
border: '2px dashed #eb2f96',
|
|
71
|
-
borderRadius: '4px',
|
|
72
|
-
backgroundColor: '#fff0f6'
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
};
|
|
18
|
+
const getPluginUrl = (placeholderId: string) => {
|
|
19
|
+
let appId: null | number = null;
|
|
76
20
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
21
|
+
Array.from(configs.entries()).forEach(
|
|
22
|
+
([key, value]: [
|
|
23
|
+
number,
|
|
24
|
+
FullpageApplicationConfig | PluginApplicationConfig
|
|
25
|
+
]) => {
|
|
26
|
+
if ('placeholderId' in value && value.placeholderId === placeholderId) {
|
|
27
|
+
appId = key;
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
);
|
|
80
32
|
|
|
81
|
-
|
|
33
|
+
if (appId === null) return '';
|
|
34
|
+
|
|
35
|
+
const { url, subSlug } = apps.find(({ id }) => id === appId) || {};
|
|
36
|
+
return url ? `[ ${url}${subSlug ?? ''} ]` : '';
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
// Get all plugin placeholders from configs
|
|
40
|
+
const pluginPlaceholders: string[] = [];
|
|
41
|
+
Array.from(configs.entries()).forEach(([, config]) => {
|
|
42
|
+
if ('placeholderId' in config) {
|
|
43
|
+
pluginPlaceholders.push(
|
|
44
|
+
(config as PluginApplicationConfig).placeholderId
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
82
48
|
|
|
83
49
|
return (
|
|
84
|
-
<div
|
|
85
|
-
<
|
|
86
|
-
|
|
87
|
-
|
|
50
|
+
<div className="page-plugin-basic">
|
|
51
|
+
<Breadcrumb
|
|
52
|
+
items={[
|
|
53
|
+
{
|
|
54
|
+
onClick: () => navigate('/'),
|
|
55
|
+
title: 'Dashboard'
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
title: 'Plugin Test'
|
|
59
|
+
}
|
|
60
|
+
]}
|
|
61
|
+
/>
|
|
62
|
+
<div className="page-heading-container">
|
|
63
|
+
<PageHeading title="Plugin Test" />
|
|
88
64
|
</div>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
65
|
+
<div className="page-content-container">
|
|
66
|
+
<PageContent>
|
|
67
|
+
{pluginPlaceholders.length > 0 ? (
|
|
68
|
+
<Row gutter={[20, 20]}>
|
|
69
|
+
{pluginPlaceholders.map((placeholderId, index) => (
|
|
70
|
+
<Col span={12} key={placeholderId}>
|
|
71
|
+
<div
|
|
72
|
+
className="plugin-placeholder"
|
|
73
|
+
data-title={`${placeholderId} ${getPluginUrl(placeholderId)}`}
|
|
74
|
+
>
|
|
75
|
+
<PluginRenderer placeholderId={placeholderId} />
|
|
76
|
+
</div>
|
|
77
|
+
</Col>
|
|
78
|
+
))}
|
|
79
|
+
</Row>
|
|
80
|
+
) : (
|
|
81
|
+
<div
|
|
99
82
|
style={{
|
|
100
|
-
|
|
101
|
-
padding: '
|
|
102
|
-
border: '1px
|
|
103
|
-
borderRadius: '
|
|
104
|
-
|
|
105
|
-
backgroundColor: 'white'
|
|
83
|
+
textAlign: 'center',
|
|
84
|
+
padding: '48px',
|
|
85
|
+
border: '1px dashed #d9d9d9',
|
|
86
|
+
borderRadius: '8px',
|
|
87
|
+
backgroundColor: '#fafafa'
|
|
106
88
|
}}
|
|
107
89
|
>
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
<label style={{ display: 'block', marginBottom: '8px', fontWeight: '500' }}>
|
|
118
|
-
Plugin Status:
|
|
119
|
-
</label>
|
|
120
|
-
<span style={{
|
|
121
|
-
padding: '4px 8px',
|
|
122
|
-
borderRadius: '4px',
|
|
123
|
-
fontSize: '12px',
|
|
124
|
-
backgroundColor: isPluginVisible ? '#f6ffed' : '#f5f5f5',
|
|
125
|
-
color: isPluginVisible ? '#52c41a' : '#666',
|
|
126
|
-
border: `1px solid ${isPluginVisible ? '#b7eb8f' : '#d9d9d9'}`
|
|
127
|
-
}}>
|
|
128
|
-
{isPluginVisible ? 'Visible' : 'Hidden'}
|
|
129
|
-
</span>
|
|
130
|
-
</div>
|
|
131
|
-
|
|
132
|
-
<div style={{ marginBottom: '16px' }}>
|
|
133
|
-
<Button
|
|
134
|
-
type="primary"
|
|
135
|
-
block
|
|
136
|
-
onClick={() => setIsPluginVisible(!isPluginVisible)}
|
|
137
|
-
>
|
|
138
|
-
{isPluginVisible ? 'Hide Plugin' : 'Show Plugin'}
|
|
139
|
-
</Button>
|
|
140
|
-
</div>
|
|
141
|
-
|
|
142
|
-
<div style={{ fontSize: '12px', color: '#666' }}>
|
|
143
|
-
<p><strong>Dimensions:</strong> {currentConfig.dimensions}</p>
|
|
144
|
-
<p><strong>Description:</strong> {currentConfig.description}</p>
|
|
145
|
-
</div>
|
|
146
|
-
</Card>
|
|
147
|
-
|
|
148
|
-
<Card title={`${currentConfig.name} Preview`} size="small">
|
|
149
|
-
<div style={{
|
|
150
|
-
padding: '24px',
|
|
151
|
-
backgroundColor: '#fafafa',
|
|
152
|
-
borderRadius: '4px',
|
|
153
|
-
minHeight: '500px',
|
|
154
|
-
display: 'flex',
|
|
155
|
-
alignItems: 'center',
|
|
156
|
-
justifyContent: 'center'
|
|
157
|
-
}}>
|
|
158
|
-
<div style={currentConfig.containerStyle}>
|
|
159
|
-
{isPluginVisible ? (
|
|
160
|
-
<div style={{ width: '100%', height: '100%', position: 'relative' }}>
|
|
161
|
-
<div style={{
|
|
162
|
-
position: 'absolute',
|
|
163
|
-
top: '8px',
|
|
164
|
-
left: '8px',
|
|
165
|
-
right: '8px',
|
|
166
|
-
backgroundColor: 'rgba(0,0,0,0.7)',
|
|
167
|
-
color: 'white',
|
|
168
|
-
padding: '4px 8px',
|
|
169
|
-
borderRadius: '2px',
|
|
170
|
-
fontSize: '10px',
|
|
171
|
-
zIndex: 10
|
|
172
|
-
}}>
|
|
173
|
-
Plugin: {config.plugin.name} ({selectedPlaceholder})
|
|
174
|
-
</div>
|
|
175
|
-
<PluginLoader config={config} />
|
|
176
|
-
</div>
|
|
177
|
-
) : (
|
|
178
|
-
<div style={{
|
|
179
|
-
display: 'flex',
|
|
180
|
-
flexDirection: 'column',
|
|
181
|
-
alignItems: 'center',
|
|
182
|
-
justifyContent: 'center',
|
|
183
|
-
height: '100%',
|
|
184
|
-
color: '#999',
|
|
185
|
-
textAlign: 'center'
|
|
186
|
-
}}>
|
|
187
|
-
<div style={{ fontSize: '48px', marginBottom: '8px' }}>📦</div>
|
|
188
|
-
<p style={{ margin: 0, fontSize: '14px' }}>
|
|
189
|
-
{currentConfig.name} Placeholder
|
|
190
|
-
</p>
|
|
191
|
-
<p style={{ margin: '4px 0 0 0', fontSize: '12px' }}>
|
|
192
|
-
Click "Show Plugin" to load
|
|
193
|
-
</p>
|
|
194
|
-
</div>
|
|
195
|
-
)}
|
|
90
|
+
<h3>No Plugin Configurations Found</h3>
|
|
91
|
+
<p>
|
|
92
|
+
No plugin applications with placeholder configurations were
|
|
93
|
+
found.
|
|
94
|
+
</p>
|
|
95
|
+
<p>
|
|
96
|
+
Make sure your shell configuration includes plugin apps with
|
|
97
|
+
placeholder IDs.
|
|
98
|
+
</p>
|
|
196
99
|
</div>
|
|
197
|
-
|
|
198
|
-
</
|
|
100
|
+
)}
|
|
101
|
+
</PageContent>
|
|
199
102
|
</div>
|
|
200
|
-
|
|
201
|
-
<Card
|
|
202
|
-
title="Integration Notes"
|
|
203
|
-
style={{ marginTop: '24px' }}
|
|
204
|
-
size="small"
|
|
205
|
-
>
|
|
206
|
-
<div style={{ fontSize: '14px', lineHeight: '1.5' }}>
|
|
207
|
-
<p>
|
|
208
|
-
This test environment simulates how your plugin will appear in different
|
|
209
|
-
placeholder configurations within host applications. Each placeholder type
|
|
210
|
-
represents a different integration scenario:
|
|
211
|
-
</p>
|
|
212
|
-
<ul>
|
|
213
|
-
<li><strong>Sidebar:</strong> Narrow vertical space, typically for navigation or quick actions</li>
|
|
214
|
-
<li><strong>Header:</strong> Horizontal space at top, usually for search or user controls</li>
|
|
215
|
-
<li><strong>Content:</strong> Main content area with full width and flexible height</li>
|
|
216
|
-
<li><strong>Modal:</strong> Overlay dialog for focused interactions</li>
|
|
217
|
-
<li><strong>Drawer:</strong> Slide-out panel for secondary content or forms</li>
|
|
218
|
-
</ul>
|
|
219
|
-
</div>
|
|
220
|
-
</Card>
|
|
221
103
|
</div>
|
|
222
104
|
);
|
|
223
|
-
};
|
|
105
|
+
};
|
|
@@ -1,114 +1,117 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { useAppShell } from '@akinon/app-shell';
|
|
2
|
+
import { Button, Card, Divider, Tag } from '@akinon/ui-react';
|
|
2
3
|
import React from 'react';
|
|
4
|
+
import { useNavigate } from 'react-router-dom';
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
export const WelcomePage: React.FC = () => {
|
|
7
|
+
const navigate = useNavigate();
|
|
8
|
+
const { apps } = useAppShell();
|
|
9
|
+
const app = apps[0]; // Get the first (and likely only) app
|
|
5
10
|
|
|
6
|
-
interface WelcomePageProps {
|
|
7
|
-
config: ShellConfig;
|
|
8
|
-
onNavigate: (view: 'welcome' | 'app' | 'plugin-test') => void;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export const WelcomePage: React.FC<WelcomePageProps> = ({ config, onNavigate }) => {
|
|
12
11
|
return (
|
|
13
|
-
<div
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
<Card
|
|
24
|
-
title="Application Configuration"
|
|
25
|
-
style={{ marginBottom: '24px' }}
|
|
26
|
-
styles={{ header: { backgroundColor: '#fafafa' } }}
|
|
27
|
-
>
|
|
28
|
-
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '16px' }}>
|
|
12
|
+
<div>
|
|
13
|
+
<Card title="Application Configuration" style={{ marginBottom: '24px' }}>
|
|
14
|
+
<div
|
|
15
|
+
style={{
|
|
16
|
+
display: 'grid',
|
|
17
|
+
gridTemplateColumns: '1fr 1fr',
|
|
18
|
+
gap: '16px'
|
|
19
|
+
}}
|
|
20
|
+
>
|
|
29
21
|
<div>
|
|
30
22
|
<strong>Application Name:</strong>
|
|
31
|
-
<p style={{ margin: '
|
|
23
|
+
<p style={{ margin: '12px 0 4px 0' }}>
|
|
24
|
+
{app?.name || 'Development App'}
|
|
25
|
+
</p>
|
|
32
26
|
</div>
|
|
33
27
|
<div>
|
|
34
28
|
<strong>Application Type:</strong>
|
|
35
|
-
<p style={{ margin: '
|
|
36
|
-
<
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
fontSize: '12px',
|
|
40
|
-
backgroundColor: config.plugin.type === 'fullpage' ? '#e6f7ff' : '#f6ffed',
|
|
41
|
-
color: config.plugin.type === 'fullpage' ? '#1890ff' : '#52c41a',
|
|
42
|
-
border: `1px solid ${config.plugin.type === 'fullpage' ? '#91d5ff' : '#b7eb8f'}`
|
|
43
|
-
}}>
|
|
44
|
-
{config.plugin.type}
|
|
45
|
-
</span>
|
|
29
|
+
<p style={{ margin: '12px 0 4px 0' }}>
|
|
30
|
+
<Tag color={app?.type === 'full_page' ? 'blue' : 'green'}>
|
|
31
|
+
{app?.type === 'full_page' ? 'fullpage' : 'plugin'}
|
|
32
|
+
</Tag>
|
|
46
33
|
</p>
|
|
47
34
|
</div>
|
|
48
35
|
<div>
|
|
49
36
|
<strong>Development URL:</strong>
|
|
50
|
-
<p
|
|
51
|
-
{
|
|
37
|
+
<p
|
|
38
|
+
style={{
|
|
39
|
+
margin: '12px 0 4px 0',
|
|
40
|
+
color: '#999',
|
|
41
|
+
fontFamily: 'monospace',
|
|
42
|
+
fontSize: '13px'
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
{app?.url || 'http://localhost:4001'}
|
|
52
46
|
</p>
|
|
53
47
|
</div>
|
|
54
48
|
<div>
|
|
55
49
|
<strong>Shell Theme:</strong>
|
|
56
|
-
<p style={{ margin: '4px 0', color: '#
|
|
50
|
+
<p style={{ margin: '12px 0 4px 0', color: '#999' }}>omnitron</p>
|
|
57
51
|
</div>
|
|
58
52
|
</div>
|
|
59
53
|
</Card>
|
|
60
54
|
|
|
61
|
-
<Card
|
|
62
|
-
title="Quick Actions"
|
|
63
|
-
style={{ marginBottom: '24px' }}
|
|
64
|
-
styles={{ header: { backgroundColor: '#fafafa' } }}
|
|
65
|
-
>
|
|
55
|
+
<Card title="Quick Actions" style={{ marginBottom: '24px' }}>
|
|
66
56
|
<div style={{ display: 'flex', gap: '16px', flexWrap: 'wrap' }}>
|
|
67
|
-
<Button
|
|
57
|
+
<Button
|
|
58
|
+
type="primary"
|
|
59
|
+
onClick={() => navigate(`/external/${app?.slug}`)}
|
|
60
|
+
>
|
|
68
61
|
Launch Application
|
|
69
62
|
</Button>
|
|
70
|
-
{
|
|
71
|
-
<Button
|
|
63
|
+
{app?.type === 'plugin' && (
|
|
64
|
+
<Button onClick={() => navigate('/plugin-test')}>
|
|
72
65
|
Test Plugin Integration
|
|
73
66
|
</Button>
|
|
74
67
|
)}
|
|
75
|
-
<Button size="large">
|
|
76
|
-
View Documentation
|
|
77
|
-
</Button>
|
|
78
68
|
</div>
|
|
79
69
|
</Card>
|
|
80
70
|
|
|
81
|
-
<Card
|
|
82
|
-
title="Development Instructions"
|
|
83
|
-
styles={{ header: { backgroundColor: '#fafafa' } }}
|
|
84
|
-
>
|
|
71
|
+
<Card title="Development Instructions">
|
|
85
72
|
<div style={{ lineHeight: '1.6' }}>
|
|
86
73
|
<h4 style={{ margin: '0 0 8px 0' }}>Getting Started:</h4>
|
|
87
74
|
<ol style={{ paddingLeft: '20px' }}>
|
|
88
|
-
<li>
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
75
|
+
<li>
|
|
76
|
+
Make sure your application is running at{' '}
|
|
77
|
+
<code>{app?.url || 'http://localhost:4001'}</code>
|
|
78
|
+
</li>
|
|
79
|
+
<li>
|
|
80
|
+
Click "Launch Application" to load your app in the shell
|
|
81
|
+
environment
|
|
82
|
+
</li>
|
|
83
|
+
{app?.type === 'plugin' && (
|
|
84
|
+
<li>
|
|
85
|
+
Use "Test Plugin Integration" to test your plugin in
|
|
86
|
+
different placeholder configurations
|
|
87
|
+
</li>
|
|
92
88
|
)}
|
|
93
|
-
<li>
|
|
89
|
+
<li>
|
|
90
|
+
The shell provides a realistic integration environment for testing
|
|
91
|
+
</li>
|
|
94
92
|
</ol>
|
|
95
|
-
|
|
96
|
-
<
|
|
97
|
-
|
|
98
|
-
<h4 style={{ margin: '16px 0 8px 0' }}>
|
|
99
|
-
|
|
93
|
+
|
|
94
|
+
<Divider />
|
|
95
|
+
|
|
96
|
+
<h4 style={{ margin: '16px 0 8px 0' }}>
|
|
97
|
+
Application Type:{' '}
|
|
98
|
+
{app?.type === 'full_page' ? 'fullpage' : 'plugin'}
|
|
99
|
+
</h4>
|
|
100
|
+
{app?.type === 'full_page' ? (
|
|
100
101
|
<p style={{ margin: 0, color: '#666' }}>
|
|
101
|
-
Your fullpage application will render as complete pages within the
|
|
102
|
-
providing full control over the content area
|
|
102
|
+
Your fullpage application will render as complete pages within the
|
|
103
|
+
shell environment, providing full control over the content area
|
|
104
|
+
and routing.
|
|
103
105
|
</p>
|
|
104
106
|
) : (
|
|
105
107
|
<p style={{ margin: 0, color: '#666' }}>
|
|
106
|
-
Your plugin application will render within designated placeholders
|
|
107
|
-
providing component-level integration
|
|
108
|
+
Your plugin application will render within designated placeholders
|
|
109
|
+
in the host application, providing component-level integration
|
|
110
|
+
capabilities.
|
|
108
111
|
</p>
|
|
109
112
|
)}
|
|
110
113
|
</div>
|
|
111
114
|
</Card>
|
|
112
115
|
</div>
|
|
113
116
|
);
|
|
114
|
-
};
|
|
117
|
+
};
|
|
@@ -1,3 +1,29 @@
|
|
|
1
|
+
.akinon-layout {
|
|
2
|
+
height: 100vh;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
.akinon-layout-sider {
|
|
6
|
+
overflow-x: hidden;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.akinon-layout-content {
|
|
10
|
+
height: calc(100vh - 64px - 40px); // Subtract header and footer
|
|
11
|
+
overflow-y: auto;
|
|
12
|
+
overflow-x: hidden;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.akinon-menu-item.akinon-menu-item-disabled {
|
|
16
|
+
opacity: 0.6;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
.akinon-menu-item {
|
|
20
|
+
font-weight: 500 !important;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.akinon-menu-item-selected {
|
|
24
|
+
font-weight: 600 !important;
|
|
25
|
+
}
|
|
26
|
+
|
|
1
27
|
.log-messages {
|
|
2
28
|
display: flex;
|
|
3
29
|
flex-direction: column;
|
|
@@ -20,27 +46,3 @@
|
|
|
20
46
|
}
|
|
21
47
|
}
|
|
22
48
|
}
|
|
23
|
-
|
|
24
|
-
/* Utility classes for header */
|
|
25
|
-
.flex {
|
|
26
|
-
display: flex;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
.items-center {
|
|
30
|
-
align-items: center;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.mr-2 {
|
|
34
|
-
margin-right: 0.5rem;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/* Utility classes for content padding */
|
|
38
|
-
.px-8 {
|
|
39
|
-
padding-left: 2rem;
|
|
40
|
-
padding-right: 2rem;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
.py-8 {
|
|
44
|
-
padding-top: 2rem;
|
|
45
|
-
padding-bottom: 2rem;
|
|
46
|
-
}
|
package/src/global.scss
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
*,
|
|
2
|
+
*::before,
|
|
3
|
+
*::after {
|
|
4
|
+
font-family: 'Jost Variable', sans-serif;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
html,
|
|
8
|
+
body,
|
|
9
|
+
#root {
|
|
10
|
+
height: 100%;
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
main {
|
|
16
|
+
padding: 4px 0;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
::-webkit-scrollbar {
|
|
20
|
+
width: 8px;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
::-webkit-scrollbar-track {
|
|
24
|
+
background-color: var(--color-ebonyClay-400);
|
|
25
|
+
border: none;
|
|
26
|
+
padding: 1px;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
::-webkit-scrollbar-thumb {
|
|
30
|
+
background-color: var(--color-ebonyClay-700);
|
|
31
|
+
border-radius: 3px;
|
|
32
|
+
border: none;
|
|
33
|
+
}
|
package/src/main.tsx
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import '@akinon/fonts-jost-variable';
|
|
2
|
+
import '@akinon/ui-utils';
|
|
3
|
+
import './global.scss';
|
|
4
|
+
|
|
1
5
|
import React from 'react';
|
|
2
6
|
import ReactDOM from 'react-dom/client';
|
|
3
7
|
|
|
@@ -9,8 +13,10 @@ const config: ShellConfig = (
|
|
|
9
13
|
window as unknown as { __SHELL_CONFIG__?: ShellConfig }
|
|
10
14
|
).__SHELL_CONFIG__ || {
|
|
11
15
|
plugin: {
|
|
12
|
-
url: 'http://localhost:
|
|
13
|
-
path: './src'
|
|
16
|
+
url: 'http://localhost:4001',
|
|
17
|
+
path: './src',
|
|
18
|
+
name: 'Development App',
|
|
19
|
+
type: 'fullpage'
|
|
14
20
|
},
|
|
15
21
|
shell: {
|
|
16
22
|
port: 4000,
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import './pages.scss';
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
|
|
5
|
+
import { PageContent } from '../components/PageContent';
|
|
6
|
+
import { PageHeading } from '../components/PageHeading';
|
|
7
|
+
import { WelcomePage } from '../components/WelcomePage';
|
|
8
|
+
|
|
9
|
+
export const PageDashboard: React.FC = () => {
|
|
10
|
+
return (
|
|
11
|
+
<div className="page-dashboard">
|
|
12
|
+
<div className="page-heading-container">
|
|
13
|
+
<PageHeading
|
|
14
|
+
title="Welcome"
|
|
15
|
+
description="Development environment for testing and integrating your applications"
|
|
16
|
+
/>
|
|
17
|
+
</div>
|
|
18
|
+
<div className="page-content-container">
|
|
19
|
+
<PageContent>
|
|
20
|
+
<WelcomePage />
|
|
21
|
+
</PageContent>
|
|
22
|
+
</div>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import './pages.scss';
|
|
2
|
+
|
|
3
|
+
import { AppRenderer } from '@akinon/app-shell';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
export const PageExternal: React.FC<{ id: number; path?: string }> = ({
|
|
7
|
+
id,
|
|
8
|
+
path
|
|
9
|
+
}) => {
|
|
10
|
+
return (
|
|
11
|
+
<div className="page-plugin-external">
|
|
12
|
+
<AppRenderer id={id} path={path} />
|
|
13
|
+
</div>
|
|
14
|
+
);
|
|
15
|
+
};
|