@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.
Files changed (40) hide show
  1. package/dist/akinon-favicon.png +0 -0
  2. package/dist/akinon-logo.png +0 -0
  3. package/dist/akinon-logo.svg +10 -0
  4. package/dist/assets/index-BFs1gfY5.css +1 -0
  5. package/dist/assets/index-Dk6Gr15i.js +408 -0
  6. package/dist/assets/jost-cyrillic-wght-normal-B0_vFdaS.woff2 +0 -0
  7. package/dist/assets/jost-latin-ext-wght-normal-B4kqP43q.woff2 +0 -0
  8. package/dist/assets/jost-latin-wght-normal-CfFW3YMY.woff2 +0 -0
  9. package/dist/index.html +2 -2
  10. package/dist/logo.png +0 -0
  11. package/dist/symbol.png +0 -0
  12. package/package.json +7 -3
  13. package/public/akinon-favicon.png +0 -0
  14. package/public/akinon-logo.png +0 -0
  15. package/public/akinon-logo.svg +10 -0
  16. package/public/logo.png +0 -0
  17. package/public/symbol.png +0 -0
  18. package/src/components/AppLayout.tsx +8 -26
  19. package/src/components/Header.tsx +20 -11
  20. package/src/components/Navigation.tsx +37 -64
  21. package/src/components/PageContent.tsx +9 -0
  22. package/src/components/PageHeading.tsx +61 -0
  23. package/src/components/PluginTestPage.scss +26 -0
  24. package/src/components/PluginTestPage.tsx +89 -207
  25. package/src/components/WelcomePage.tsx +72 -69
  26. package/src/components/layout.scss +26 -24
  27. package/src/global.scss +33 -0
  28. package/src/main.tsx +8 -2
  29. package/src/pages/Dashboard.tsx +25 -0
  30. package/src/pages/External.tsx +15 -0
  31. package/src/pages/PluginTest.tsx +7 -0
  32. package/src/pages/pages.scss +9 -0
  33. package/src/providers.tsx +108 -0
  34. package/src/routes.tsx +44 -0
  35. package/src/server/dev-server.mjs +18 -15
  36. package/src/shell-app.tsx +12 -3
  37. package/src/utils/navigation.tsx +65 -0
  38. package/dist/assets/index-cI-pE1VB.js +0 -387
  39. package/dist/assets/index-tRJwBFdH.css +0 -1
  40. package/src/components/AppRouter.tsx +0 -41
package/dist/index.html CHANGED
@@ -24,8 +24,8 @@
24
24
  box-sizing: border-box;
25
25
  }
26
26
  </style>
27
- <script type="module" crossorigin src="/assets/index-cI-pE1VB.js"></script>
28
- <link rel="stylesheet" crossorigin href="/assets/index-tRJwBFdH.css">
27
+ <script type="module" crossorigin src="/assets/index-Dk6Gr15i.js"></script>
28
+ <link rel="stylesheet" crossorigin href="/assets/index-BFs1gfY5.css">
29
29
  </head>
30
30
  <body>
31
31
  <div id="root"></div>
package/dist/logo.png ADDED
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akinon/ui-shell-dev",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "description": "Development shell application for Akinon UI Protocol plugins",
6
6
  "type": "module",
@@ -8,17 +8,21 @@
8
8
  "files": [
9
9
  "dist",
10
10
  "src",
11
+ "public",
11
12
  "index.html",
12
13
  "index.mjs",
13
14
  "vite.config.ts",
14
15
  "tsconfig.json"
15
16
  ],
16
17
  "dependencies": {
17
- "@akinon/ui-react": "^1.1.0",
18
+ "@akinon/app-shell": "^1.2.0",
19
+ "@akinon/ui-react": "^1.2.0",
20
+ "@akinon/ui-utils": "^1.0.0",
18
21
  "@akinon/icons": "^1.0.0",
19
- "@akinon/fonts-jost-variable": "^1.0.0",
22
+ "@akinon/fonts-jost-variable": "^2.0.1",
20
23
  "react": "^18.2.0",
21
24
  "react-dom": "^18.2.0",
25
+ "react-router-dom": "^6.28.0",
22
26
  "express": "^4.18.2",
23
27
  "cors": "^2.8.5",
24
28
  "vite": "^5.2.0"
Binary file
Binary file
@@ -0,0 +1,10 @@
1
+ <svg width="180" height="40" viewBox="0 0 180 40" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_4_1297)">
3
+ <path d="M176.207 8.3551V18.2732C176.207 21.9305 176.307 25.362 176.275 25.362H176.244C176.207 25.362 173.814 22.0987 172.104 19.8406L163.315 8.35953H159.759V31.6493H163.552V21.7667C163.552 17.609 163.452 14.4786 163.483 14.4786H163.515C163.552 14.4786 165.603 17.3744 167.723 20.2037L176.444 31.6493H180V8.3551H176.207ZM134.822 20C134.822 14.9081 138.415 11.5121 143.343 11.5121C148.271 11.5121 151.858 14.9037 151.858 20C151.858 25.0963 148.23 28.4879 143.343 28.4879C138.456 28.4879 134.822 25.0255 134.822 20ZM130.929 20C130.929 27.0224 136.463 32.1098 143.343 32.1098C150.222 32.1098 155.788 27.0224 155.788 20C155.788 12.9776 150.217 7.89019 143.343 7.89019C136.468 7.89019 130.929 12.9776 130.929 20ZM123.065 8.3551V18.2732C123.065 21.9305 123.17 25.362 123.133 25.362H123.102C123.07 25.362 120.672 22.0987 118.962 19.8406L110.173 8.35953H106.621V31.6493H110.41V21.7667C110.41 17.609 110.309 14.4786 110.341 14.4786H110.373C110.405 14.4786 112.461 17.3744 114.581 20.2037L123.307 31.6493H126.858V8.3551H123.07H123.065ZM97.5859 31.6449H101.379V8.3551H97.5859V31.6449ZM93.5741 31.6449L83.1436 18.0031L93.0635 8.3551H88.4454L81.0921 15.4793C79.0406 17.4718 77.3995 19.1676 77.363 19.1676H77.3311C77.2992 19.1676 77.3995 17.5382 77.3995 13.7791V8.3551H73.6065V31.6449H77.3995V23.6263L80.6499 20.4339L89.1293 31.6493H93.5741V31.6449ZM53.9717 23.1304L57.0489 15.8379C57.5641 14.5716 58.143 12.8094 58.175 12.8094H58.2069C58.2433 12.8094 58.8223 14.5716 59.3375 15.8379L62.4147 23.1304H53.9717ZM66.007 31.6449H70.0735L59.9529 8.3551H56.4335L46.3129 31.6449H50.384L52.6041 26.3538H63.7869L66.007 31.6449ZM28.1187 13.8101L20.9021 0L0 40H41.8043L36.8808 30.5822C36.3291 31.5785 35.6453 32.4729 34.8247 33.2566C33.7215 34.3148 32.404 35.1339 30.8814 35.7095C29.3587 36.2896 27.6902 36.5818 25.8758 36.5818C24.0614 36.5818 22.3974 36.2896 20.8702 35.7095C19.3476 35.1295 18.0301 34.3104 16.9269 33.2566C15.8236 32.1984 14.9575 30.9497 14.342 29.5019C13.7266 28.054 13.4166 26.4556 13.4166 24.7067C13.4166 23.0905 13.763 21.5984 14.4469 20.2391C15.1352 18.8798 16.0561 17.7109 17.2095 16.7279C18.3629 15.7494 19.6941 14.9878 21.1985 14.4432C22.7029 13.903 24.2574 13.6285 25.8712 13.6285C26.628 13.6285 27.3756 13.6905 28.1096 13.8101M30.3526 20.7793C29.7736 20.2568 29.1034 19.8362 28.3376 19.5218C27.5717 19.2074 26.7511 19.0525 25.8712 19.0525C24.9914 19.0525 24.1754 19.2074 23.4049 19.5218C22.639 19.8362 21.9643 20.2568 21.3899 20.7793C20.811 21.3018 20.3551 21.9083 20.0132 22.5902C19.6758 23.2765 19.5071 23.9894 19.5071 24.7332C19.5071 25.6675 19.6758 26.522 20.0132 27.3013C20.3505 28.0806 20.811 28.758 21.3899 29.3292C21.9689 29.9004 22.639 30.3476 23.4049 30.6708C24.1708 30.994 24.9914 31.1579 25.8712 31.1579C26.7511 31.1579 27.5671 30.9984 28.3376 30.6708C29.1034 30.3476 29.7781 29.9004 30.3526 29.3292C30.9315 28.758 31.3874 28.085 31.7247 27.3013C32.0621 26.522 32.2308 25.6631 32.2308 24.7332C32.2308 23.9894 32.0621 23.2765 31.7247 22.5902C31.3874 21.9039 30.927 21.3018 30.3526 20.7793Z" fill="#D02C2F"/>
4
+ </g>
5
+ <defs>
6
+ <clipPath id="clip0_4_1297">
7
+ <rect width="180" height="40" fill="white"/>
8
+ </clipPath>
9
+ </defs>
10
+ </svg>
Binary file
Binary file
@@ -3,19 +3,16 @@ import './layout.scss';
3
3
  import { Layout, Space, Text } from '@akinon/ui-react';
4
4
  import React, { useState } from 'react';
5
5
 
6
- import type { ShellConfig, ViewType } from '../types';
7
- import { AppRouter } from './AppRouter';
8
6
  import { Header } from './Header';
9
7
  import { Navigation } from './Navigation';
10
8
 
11
9
  interface AppLayoutProps {
12
- config: ShellConfig;
10
+ children: React.ReactNode;
13
11
  }
14
12
 
15
- export const AppLayout: React.FC<AppLayoutProps> = ({ config }) => {
13
+ export const AppLayout: React.FC<AppLayoutProps> = ({ children }) => {
16
14
  const [leftSiderCollapsed, setLeftSiderCollapsed] = useState(false);
17
15
  const [rightSiderCollapsed, setRightSiderCollapsed] = useState(true);
18
- const [currentView, setCurrentView] = useState<ViewType>('welcome');
19
16
 
20
17
  const toggleLeftSider = () => setLeftSiderCollapsed(!leftSiderCollapsed);
21
18
  const toggleRightSider = () => setRightSiderCollapsed(!rightSiderCollapsed);
@@ -24,14 +21,10 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ config }) => {
24
21
  <Layout>
25
22
  <Layout.Sider
26
23
  collapsed={leftSiderCollapsed}
27
- brandImageUrl="/akinon-logo.svg"
28
- iconUrl="/akinon-favicon.svg"
24
+ brandImageUrl="/logo.png"
25
+ iconUrl="/symbol.png"
29
26
  >
30
- <Navigation
31
- config={config}
32
- currentView={currentView}
33
- onNavigate={setCurrentView}
34
- />
27
+ <Navigation />
35
28
  </Layout.Sider>
36
29
 
37
30
  <Layout>
@@ -42,18 +35,7 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ config }) => {
42
35
  />
43
36
  </Layout.Header>
44
37
 
45
- <Layout.Content>
46
- <AppRouter
47
- config={config}
48
- currentView={currentView}
49
- onNavigate={setCurrentView}
50
- />
51
- </Layout.Content>
52
-
53
- <Layout.Footer>
54
- {config.shell.title} &copy; {new Date().getFullYear()} Created by
55
- Akinon
56
- </Layout.Footer>
38
+ <Layout.Content>{children}</Layout.Content>
57
39
  </Layout>
58
40
 
59
41
  {/* Development logs/notifications area */}
@@ -68,8 +50,8 @@ export const AppLayout: React.FC<AppLayoutProps> = ({ config }) => {
68
50
  <Text>{new Date().toLocaleTimeString()}</Text>
69
51
  </div>
70
52
  <div className="log-messages-item">
71
- <Text>Plugin URL: {config.plugin.url}</Text>
72
- <Text>Type: {config.plugin.type}</Text>
53
+ <Text>Shell environment active</Text>
54
+ <Text>Ready for testing</Text>
73
55
  </div>
74
56
  </Space>
75
57
  </Layout.Sider>
@@ -1,17 +1,14 @@
1
- import { Button } from '@akinon/ui-react';
1
+ import { Badge, Button } from '@akinon/ui-react';
2
2
  import React from 'react';
3
3
 
4
- import { HeaderSearch } from './HeaderSearch';
5
- import { HeaderUser } from './HeaderUser';
6
-
7
4
  interface HeaderProps {
8
5
  onToggleLeftSider: () => void;
9
6
  onToggleRightSider: () => void;
10
7
  }
11
8
 
12
- export const Header: React.FC<HeaderProps> = ({
13
- onToggleLeftSider,
14
- onToggleRightSider
9
+ export const Header: React.FC<HeaderProps> = ({
10
+ onToggleLeftSider,
11
+ onToggleRightSider
15
12
  }) => {
16
13
  return (
17
14
  <>
@@ -19,24 +16,36 @@ export const Header: React.FC<HeaderProps> = ({
19
16
  <Button
20
17
  type="text"
21
18
  icon="outdent"
19
+ iconSize={16}
22
20
  onClick={onToggleLeftSider}
23
21
  className="mr-2"
24
22
  />
25
23
  </div>
26
24
 
27
25
  <div>
28
- <HeaderSearch />
26
+ <div
27
+ style={{
28
+ display: 'flex',
29
+ alignItems: 'center',
30
+ gap: '8px'
31
+ }}
32
+ >
33
+ <Badge dot status="success" />
34
+ <span style={{ fontSize: '14px', color: '#666' }}>
35
+ Development Mode
36
+ </span>
37
+ </div>
29
38
  </div>
30
39
 
31
40
  <div className="flex items-center">
32
- <HeaderUser />
33
41
  <Button
34
42
  type="text"
35
- icon="bell"
43
+ icon="siralama"
44
+ iconSize={16}
36
45
  onClick={onToggleRightSider}
37
46
  className="mr-2"
38
47
  />
39
48
  </div>
40
49
  </>
41
50
  );
42
- };
51
+ };
@@ -1,82 +1,55 @@
1
- import { Menu, IMenuProps } from '@akinon/ui-react';
1
+ import { useAppShell } from '@akinon/app-shell';
2
+ import { IMenuProps, Menu } from '@akinon/ui-react';
3
+ import { useEffect, useState } from 'react';
2
4
  import React from 'react';
5
+ import { useLocation, useNavigate } from 'react-router-dom';
6
+
7
+ import {
8
+ getFullpageNavigationItems,
9
+ getPluginNavigationItems,
10
+ getStaticNavigationItems
11
+ } from '../utils/navigation';
12
+
13
+ export const Navigation: React.FC = () => {
14
+ const { apps, configs } = useAppShell();
15
+ const location = useLocation();
16
+ const navigate = useNavigate();
17
+ const [selectedKey, setSelectedKey] = useState('/');
18
+ const [openKeys, setOpenKeys] = useState<string[]>([]);
19
+ const items = getStaticNavigationItems();
20
+ const fullpageItems = getFullpageNavigationItems(
21
+ apps,
22
+ configs as Map<number, any>
23
+ );
24
+ const pluginItems = getPluginNavigationItems();
3
25
 
4
- import type { ShellConfig, ViewType } from '../types';
5
-
6
- interface NavigationProps {
7
- config: ShellConfig;
8
- currentView: ViewType;
9
- onNavigate: (view: ViewType) => void;
10
- }
11
-
12
- export const Navigation: React.FC<NavigationProps> = ({
13
- config,
14
- currentView,
15
- onNavigate
16
- }) => {
17
- const getMenuItems = () => {
18
- const items = [
19
- {
20
- key: 'welcome',
21
- label: 'Welcome',
22
- icon: 'home'
23
- },
24
- {
25
- key: 'development',
26
- label: 'Development',
27
- icon: 'build',
28
- children: [
29
- {
30
- key: 'app',
31
- label: config.plugin.name,
32
- icon: config.plugin.type === 'fullpage' ? 'desktop' : 'appstore'
33
- }
34
- ]
35
- }
36
- ];
26
+ useEffect(() => {
27
+ setSelectedKey(location.pathname);
28
+ }, [location]);
37
29
 
38
- // Add plugin test page for plugin apps
39
- if (config.plugin.type === 'plugin') {
40
- items[1].children.push({
41
- key: 'plugin-test',
42
- label: 'Plugin Test',
43
- icon: 'experiment'
44
- });
30
+ const onClick: IMenuProps['onClick'] = (e: any) => {
31
+ if (!e.key.includes('external')) {
32
+ setOpenKeys([]);
45
33
  }
46
34
 
47
- // Add static menu items to match playground
48
- items.push(
49
- {
50
- key: 'settings',
51
- label: 'Settings',
52
- icon: 'setting'
53
- },
54
- {
55
- key: 'help',
56
- label: 'Help & Support',
57
- icon: 'question-circle'
58
- }
59
- );
60
-
61
- return items;
35
+ navigate(e.key);
62
36
  };
63
37
 
64
- const onClick: IMenuProps['onClick'] = (e: any) => {
65
- if (e.key === 'welcome' || e.key === 'app' || e.key === 'plugin-test') {
66
- onNavigate(e.key as ViewType);
67
- }
38
+ const onOpenChange = (openKeys: string[]) => {
39
+ setOpenKeys([openKeys.pop() || '']);
68
40
  };
69
41
 
70
42
  return (
71
43
  <div>
72
44
  <Menu
73
45
  mode="inline"
74
- selectedKeys={[currentView]}
75
- defaultOpenKeys={['development']}
76
- items={getMenuItems()}
46
+ selectedKeys={[selectedKey]}
47
+ items={[...items, ...fullpageItems, ...pluginItems]}
77
48
  onClick={onClick}
78
49
  theme="dark"
50
+ openKeys={openKeys}
51
+ onOpenChange={onOpenChange}
79
52
  />
80
53
  </div>
81
54
  );
82
- };
55
+ };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+
3
+ interface PageContentProps {
4
+ children: React.ReactNode;
5
+ }
6
+
7
+ export const PageContent: React.FC<PageContentProps> = ({ children }) => {
8
+ return <div className="px-8 py-8">{children}</div>;
9
+ };
@@ -0,0 +1,61 @@
1
+ import { Flex, Space, Typography } from 'antd';
2
+ import * as React from 'react';
3
+
4
+ export interface PageHeadingProps {
5
+ /**
6
+ * The title of the PageHeading.
7
+ */
8
+ title: string;
9
+
10
+ /**
11
+ * The description of the PageHeading.
12
+ */
13
+ description?: string;
14
+
15
+ /**
16
+ * The action items of the PageHeading.
17
+ */
18
+ actions?: React.ReactNode;
19
+
20
+ /**
21
+ * The additional css class
22
+ */
23
+ className?: string;
24
+ }
25
+
26
+ /**
27
+ * It is used to generate title, description and actions for a standard page.
28
+ * See the [PageContent](/docs/layout-pagecontent--docs) component for more information.
29
+ */
30
+
31
+ export const PageHeading = ({
32
+ title,
33
+ description,
34
+ actions,
35
+ className
36
+ }: PageHeadingProps) => {
37
+ return (
38
+ <Flex
39
+ justify="space-between"
40
+ align="flex-start"
41
+ className={className}
42
+ style={{
43
+ padding: '18px 30px',
44
+ borderBlockEnd: 'solid 1px var(--color-gray-900)'
45
+ }}
46
+ >
47
+ <Space direction="vertical" size={4}>
48
+ <Typography.Title level={4} style={{ margin: 0 }}>
49
+ {title}
50
+ </Typography.Title>
51
+ {description && (
52
+ <Typography.Paragraph type="secondary">
53
+ {description}
54
+ </Typography.Paragraph>
55
+ )}
56
+ </Space>
57
+
58
+ {actions && <Space>{actions}</Space>}
59
+ </Flex>
60
+ );
61
+ };
@@ -0,0 +1,26 @@
1
+ .page-plugin-basic {
2
+ .plugin-placeholder {
3
+ border: 2px dashed #fff;
4
+ border-radius: 4px;
5
+ height: 320px;
6
+ position: relative;
7
+ margin-bottom: 2rem;
8
+
9
+ &::after {
10
+ content: '#' attr(data-title);
11
+ color: var(--color-gray-400);
12
+ border-bottom-left-radius: 2px;
13
+ border-bottom-right-radius: 2px;
14
+ padding: 0.125rem 0.25rem;
15
+ font-size: 12px;
16
+ position: absolute;
17
+ top: 100%;
18
+ left: 0.5rem;
19
+ }
20
+ }
21
+
22
+ .app-shell-plugin-container,
23
+ .app-shell-plugin-container iframe {
24
+ height: 100%;
25
+ }
26
+ }