@celljs/shell 3.0.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 (135) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -0
  3. package/cell-locale.yml +13 -0
  4. package/cell.yml +18 -0
  5. package/lib/browser/annotation/index.d.ts +3 -0
  6. package/lib/browser/annotation/index.d.ts.map +1 -0
  7. package/lib/browser/annotation/index.js +19 -0
  8. package/lib/browser/annotation/index.js.map +1 -0
  9. package/lib/browser/annotation/left-area.d.ts +2 -0
  10. package/lib/browser/annotation/left-area.d.ts.map +1 -0
  11. package/lib/browser/annotation/left-area.js +12 -0
  12. package/lib/browser/annotation/left-area.js.map +1 -0
  13. package/lib/browser/annotation/top-area.d.ts +2 -0
  14. package/lib/browser/annotation/top-area.d.ts.map +1 -0
  15. package/lib/browser/annotation/top-area.js +12 -0
  16. package/lib/browser/annotation/top-area.js.map +1 -0
  17. package/lib/browser/apps/app-service.d.ts +11 -0
  18. package/lib/browser/apps/app-service.d.ts.map +1 -0
  19. package/lib/browser/apps/app-service.js +55 -0
  20. package/lib/browser/apps/app-service.js.map +1 -0
  21. package/lib/browser/apps/apps.d.ts +13 -0
  22. package/lib/browser/apps/apps.d.ts.map +1 -0
  23. package/lib/browser/apps/apps.js +44 -0
  24. package/lib/browser/apps/apps.js.map +1 -0
  25. package/lib/browser/apps/index.d.ts +3 -0
  26. package/lib/browser/apps/index.d.ts.map +1 -0
  27. package/lib/browser/apps/index.js +19 -0
  28. package/lib/browser/apps/index.js.map +1 -0
  29. package/lib/browser/area/area-protocol.d.ts +18 -0
  30. package/lib/browser/area/area-protocol.d.ts.map +1 -0
  31. package/lib/browser/area/area-protocol.js +22 -0
  32. package/lib/browser/area/area-protocol.js.map +1 -0
  33. package/lib/browser/area/index.d.ts +4 -0
  34. package/lib/browser/area/index.d.ts.map +1 -0
  35. package/lib/browser/area/index.js +20 -0
  36. package/lib/browser/area/index.js.map +1 -0
  37. package/lib/browser/area/left/index.d.ts +2 -0
  38. package/lib/browser/area/left/index.d.ts.map +1 -0
  39. package/lib/browser/area/left/index.js +18 -0
  40. package/lib/browser/area/left/index.js.map +1 -0
  41. package/lib/browser/area/left/left.d.ts +5 -0
  42. package/lib/browser/area/left/left.d.ts.map +1 -0
  43. package/lib/browser/area/left/left.js +31 -0
  44. package/lib/browser/area/left/left.js.map +1 -0
  45. package/lib/browser/area/top/index.d.ts +2 -0
  46. package/lib/browser/area/top/index.d.ts.map +1 -0
  47. package/lib/browser/area/top/index.js +18 -0
  48. package/lib/browser/area/top/index.js.map +1 -0
  49. package/lib/browser/area/top/top.d.ts +5 -0
  50. package/lib/browser/area/top/top.d.ts.map +1 -0
  51. package/lib/browser/area/top/top.js +31 -0
  52. package/lib/browser/area/top/top.js.map +1 -0
  53. package/lib/browser/index.d.ts +5 -0
  54. package/lib/browser/index.d.ts.map +1 -0
  55. package/lib/browser/index.js +21 -0
  56. package/lib/browser/index.js.map +1 -0
  57. package/lib/browser/layout/index.d.ts +2 -0
  58. package/lib/browser/layout/index.d.ts.map +1 -0
  59. package/lib/browser/layout/index.js +18 -0
  60. package/lib/browser/layout/index.js.map +1 -0
  61. package/lib/browser/layout/layout.d.ts +6 -0
  62. package/lib/browser/layout/layout.d.ts.map +1 -0
  63. package/lib/browser/layout/layout.js +65 -0
  64. package/lib/browser/layout/layout.js.map +1 -0
  65. package/lib/browser/module.d.ts +4 -0
  66. package/lib/browser/module.d.ts.map +1 -0
  67. package/lib/browser/module.js +6 -0
  68. package/lib/browser/module.js.map +1 -0
  69. package/lib/browser/tool/account.d.ts +5 -0
  70. package/lib/browser/tool/account.d.ts.map +1 -0
  71. package/lib/browser/tool/account.js +66 -0
  72. package/lib/browser/tool/account.js.map +1 -0
  73. package/lib/browser/tool/app-set.d.ts +5 -0
  74. package/lib/browser/tool/app-set.d.ts.map +1 -0
  75. package/lib/browser/tool/app-set.js +55 -0
  76. package/lib/browser/tool/app-set.js.map +1 -0
  77. package/lib/browser/tool/index.d.ts +5 -0
  78. package/lib/browser/tool/index.d.ts.map +1 -0
  79. package/lib/browser/tool/index.js +21 -0
  80. package/lib/browser/tool/index.js.map +1 -0
  81. package/lib/browser/tool/logo.d.ts +5 -0
  82. package/lib/browser/tool/logo.d.ts.map +1 -0
  83. package/lib/browser/tool/logo.js +38 -0
  84. package/lib/browser/tool/logo.js.map +1 -0
  85. package/lib/browser/tool/settings.d.ts +5 -0
  86. package/lib/browser/tool/settings.d.ts.map +1 -0
  87. package/lib/browser/tool/settings.js +66 -0
  88. package/lib/browser/tool/settings.js.map +1 -0
  89. package/lib/common/index.d.ts +2 -0
  90. package/lib/common/index.d.ts.map +1 -0
  91. package/lib/common/index.js +18 -0
  92. package/lib/common/index.js.map +1 -0
  93. package/lib/common/shell-protocol.d.ts +19 -0
  94. package/lib/common/shell-protocol.d.ts.map +1 -0
  95. package/lib/common/shell-protocol.js +5 -0
  96. package/lib/common/shell-protocol.js.map +1 -0
  97. package/lib/node/index.d.ts +1 -0
  98. package/lib/node/index.d.ts.map +1 -0
  99. package/lib/node/index.js +1 -0
  100. package/lib/node/index.js.map +1 -0
  101. package/lib/node/module.d.ts +3 -0
  102. package/lib/node/module.d.ts.map +1 -0
  103. package/lib/node/module.js +5 -0
  104. package/lib/node/module.js.map +1 -0
  105. package/lib/package.spec.d.ts +1 -0
  106. package/lib/package.spec.d.ts.map +1 -0
  107. package/lib/package.spec.js +4 -0
  108. package/lib/package.spec.js.map +1 -0
  109. package/package.json +50 -0
  110. package/src/browser/annotation/index.ts +2 -0
  111. package/src/browser/annotation/left-area.ts +9 -0
  112. package/src/browser/annotation/top-area.ts +9 -0
  113. package/src/browser/apps/app-service.ts +40 -0
  114. package/src/browser/apps/apps.tsx +67 -0
  115. package/src/browser/apps/index.ts +2 -0
  116. package/src/browser/area/area-protocol.ts +18 -0
  117. package/src/browser/area/index.ts +3 -0
  118. package/src/browser/area/left/index.ts +1 -0
  119. package/src/browser/area/left/left.tsx +26 -0
  120. package/src/browser/area/top/index.ts +1 -0
  121. package/src/browser/area/top/top.tsx +24 -0
  122. package/src/browser/index.ts +4 -0
  123. package/src/browser/layout/index.ts +1 -0
  124. package/src/browser/layout/layout.tsx +63 -0
  125. package/src/browser/module.ts +5 -0
  126. package/src/browser/tool/account.tsx +61 -0
  127. package/src/browser/tool/app-set.tsx +47 -0
  128. package/src/browser/tool/index.ts +4 -0
  129. package/src/browser/tool/logo.tsx +14 -0
  130. package/src/browser/tool/settings.tsx +56 -0
  131. package/src/common/index.ts +1 -0
  132. package/src/common/shell-protocol.ts +21 -0
  133. package/src/node/index.ts +0 -0
  134. package/src/node/module.ts +4 -0
  135. package/src/package.spec.ts +4 -0
@@ -0,0 +1,2 @@
1
+ export * from './top-area';
2
+ export * from './left-area';
@@ -0,0 +1,9 @@
1
+ import { ReactComponent } from '@celljs/react';
2
+ import { LEFT_AREA } from '../area/area-protocol';
3
+
4
+ export const LeftArea =
5
+ function (component?: any, rebind: boolean = true): (target: any) => any {
6
+ return (t: any) => {
7
+ ReactComponent(LEFT_AREA, component || t, rebind)(t);
8
+ };
9
+ };
@@ -0,0 +1,9 @@
1
+ import { ReactComponent } from '@celljs/react';
2
+ import { TOP_AREA } from '../area/area-protocol';
3
+
4
+ export const TopArea =
5
+ function (component?: any, rebind: boolean = true): (target: any) => any {
6
+ return (t: any) => {
7
+ ReactComponent(TOP_AREA, component || t, rebind)(t);
8
+ };
9
+ };
@@ -0,0 +1,40 @@
1
+ import { AppService, Category, AppInfo } from '../../common';
2
+ import { Component, Prioritizeable, Value } from '@celljs/core';
3
+
4
+ @Component(AppService)
5
+ export class AppServiceImpl implements AppService {
6
+
7
+ @Value('cell.shell.apps')
8
+ protected readonly apps: { [id: string]: AppInfo };
9
+
10
+ @Value('cell.shell.categories')
11
+ protected readonly categories: { [id: string]: Category };
12
+
13
+ async load(): Promise<Category[]> {
14
+ const categoryMap = new Map<string, Category>();
15
+ const parsedCategories = Object.keys(this.categories || {}).map(key => {
16
+ const category = { ...this.categories[key] };
17
+ category.id = key;
18
+ category.priority = 500;
19
+ category.apps = category.apps || [];
20
+ categoryMap.set(key, category);
21
+ return category;
22
+ });
23
+ const parsedApps = Object.keys(this.apps || {}).map(key => {
24
+ const app = { ...this.apps[key] };
25
+ app.id = key;
26
+ app.priority = 500;
27
+ return app;
28
+ });
29
+ const sortedCategories = Prioritizeable.prioritizeAllSync(parsedCategories).map(c => c.value);
30
+ const sortedApps = Prioritizeable.prioritizeAllSync(parsedApps).map(c => c.value);
31
+ for (const app of sortedApps) {
32
+ const category = categoryMap.get(app.categoryId);
33
+ if (category) {
34
+ category.apps.push(app);
35
+ }
36
+ }
37
+ return sortedCategories;
38
+ }
39
+
40
+ }
@@ -0,0 +1,67 @@
1
+ import * as React from 'react';
2
+ import { Grid, Box, Text, ResponsiveContext } from 'grommet';
3
+ import { ContainerUtil } from '@celljs/core';
4
+ import { AppService, Category, AppInfo } from '../../common';
5
+ import { Icon } from '@celljs/grommet';
6
+ import { useIntl } from 'react-intl';
7
+ const { useState, useEffect, useContext } = React;
8
+
9
+ export function Apps({ size }: { size?: string }) {
10
+ size = size || useContext(ResponsiveContext);
11
+ const [categories, setCategories] = useState<Category[]>([]);
12
+ useEffect(() => {
13
+ const loadApps = async () => {
14
+ const appService = ContainerUtil.get<AppService>(AppService);
15
+ const data = await appService.load();
16
+ setCategories(data);
17
+ };
18
+ loadApps();
19
+ }, []);
20
+
21
+ return (
22
+ <Box direction="column" pad="small" gap="small" alignContent="start"
23
+ >
24
+ {categories.map(c => (
25
+ <AppCategory key={c.id} size={size!} category={c}></AppCategory>
26
+ ))}
27
+ </Box>
28
+ );
29
+ }
30
+
31
+ export function AppCategory({ category, size }: { category: Category, size: string }) {
32
+ const intl = useIntl();
33
+ const apps = category.apps || [];
34
+ return (
35
+ <Box>
36
+ <Text weight="bold" textAlign={ size === 'small' ? 'center' : 'start' } size={size} margin={{ bottom: size }}>{ intl.formatMessage({ id: category.name}) }</Text>
37
+ <Box border={{ side: 'top', color: 'light-2' }}></Box>
38
+ <Grid
39
+ rows={size === 'small' ? 'xsmall' : 'small'}
40
+ columns={size === 'small' ? 'xsmall' : 'small'}
41
+ >
42
+ {apps.map(app => (
43
+ <AppItem key={app.id} size={size} app={app}></AppItem>
44
+ ))}
45
+
46
+ </Grid>
47
+ </Box>
48
+ );
49
+ }
50
+
51
+ export function AppItem({ app, size }: { app: AppInfo, size: string }) {
52
+ const intl = useIntl();
53
+ const onClick = () => {
54
+ window.location.href = app.url;
55
+ };
56
+ return (
57
+ <Box
58
+ justify="center"
59
+ align="center"
60
+ hoverIndicator
61
+ onClick={onClick}
62
+ >
63
+ <Icon icon={app.icon} size={size === 'small' ? 'medium' : 'large'}/>
64
+ <Text size={size} margin={{ top: size }}>{intl.formatMessage({ id: app.name})}</Text>
65
+ </Box>
66
+ );
67
+ }
@@ -0,0 +1,2 @@
1
+ export * from './app-service';
2
+ export * from './apps';
@@ -0,0 +1,18 @@
1
+ export const TOP_AREA = Symbol('TOP_AREA');
2
+ export const LEFT_AREA = Symbol('LEFT_AREA');
3
+
4
+ export enum AreaType {
5
+ TopArea = 'Top',
6
+ SecondaryTopArea = 'SecondaryTop',
7
+ TertiaryTopArea = 'TertiaryTop',
8
+ LeftArea = 'Left',
9
+ TopLeftArea = 'TopLeft',
10
+ TopRightArea = 'TopRight',
11
+ LeftHeaderArea = 'LeftHeader',
12
+ LeftFooterArea = 'LeftFooter',
13
+ LeftBodyArea = 'LeftBody',
14
+ NavArea = 'Nav',
15
+ SettingsArea = 'Settings',
16
+ AccountArea = 'Account',
17
+ BottomArea = 'Bottom'
18
+ }
@@ -0,0 +1,3 @@
1
+ export * from './top';
2
+ export * from './left';
3
+ export * from './area-protocol';
@@ -0,0 +1 @@
1
+ export * from './left';
@@ -0,0 +1,26 @@
1
+ import * as React from 'react';
2
+ import { Nav, Sidebar, BoxProps } from 'grommet';
3
+ import { ConfigUtil } from '@celljs/core';
4
+ import { AreaType } from '../area-protocol';
5
+ import { Slot } from '@celljs/react';
6
+ import { Widget } from '@celljs/widget';
7
+
8
+ export function LeftArea(props: BoxProps) {
9
+ props = { ...(ConfigUtil.get('cell.shell.leftArea') || {}), ...props };
10
+
11
+ return (
12
+ <Sidebar animation="fadeIn" pad="medium" background="white" width="250px"
13
+ footer={<Slot area={AreaType.LeftFooterArea} />}
14
+ {...props}
15
+ >
16
+ <Slot area={AreaType.LeftHeaderArea} />
17
+ <Nav gap="none">
18
+ <Slot area={AreaType.NavArea} />
19
+ <Slot area={AreaType.LeftBodyArea} />
20
+ </Nav>
21
+ </Sidebar>
22
+ );
23
+ }
24
+
25
+ @Widget({ area: AreaType.LeftArea, component: LeftArea })
26
+ export default class {}
@@ -0,0 +1 @@
1
+ export * from './top';
@@ -0,0 +1,24 @@
1
+ import * as React from 'react';
2
+ import { Box, Nav, BoxProps } from 'grommet';
3
+ import { ConfigUtil } from '@celljs/core';
4
+ import { AreaType } from '../area-protocol';
5
+ import { Slot } from '@celljs/react';
6
+ import { Widget } from '@celljs/widget';
7
+
8
+ export function TopArea(props: BoxProps) {
9
+ props = { ...ConfigUtil.get('cell.shell.topArea'), ...props };
10
+
11
+ return (
12
+ <Nav direction="row" pad={{ vertical: 'small', horizontal: 'medium' }} elevation="xsmall" justify="between" {...props}>
13
+ <Box direction="row" gap="small">
14
+ <Slot area={AreaType.TopLeftArea} />
15
+ </Box>
16
+ <Box direction="row" gap="small">
17
+ <Slot area={AreaType.TopRightArea} />
18
+ </Box>
19
+ </Nav>
20
+ );
21
+ }
22
+
23
+ @Widget({ area: AreaType.TopArea, component: TopArea })
24
+ export default class {}
@@ -0,0 +1,4 @@
1
+ export * from './apps';
2
+ export * from './area';
3
+ export * from './tool';
4
+ export * from './layout';
@@ -0,0 +1 @@
1
+ export * from './layout';
@@ -0,0 +1,63 @@
1
+ import { DefaultLayout, Slot } from '@celljs/react';
2
+ import * as React from 'react';
3
+ import { AreaType } from '../area';
4
+ import styled from 'styled-components';
5
+ import { Box } from 'grommet';
6
+
7
+ const StyledWraper = styled.div`
8
+ left: 0;
9
+ position: absolute;
10
+ right: 0;
11
+ top: 0;
12
+ bottom: 0;
13
+ overflow: hidden;
14
+ z-index: 2;
15
+ `;
16
+
17
+ const StyledSidebar = styled.div`
18
+ left: 0;
19
+ position: absolute;
20
+ top: 76px;
21
+ bottom: 0;
22
+ z-index: 1;
23
+ `;
24
+
25
+ const StyledMain = styled.div`
26
+ left: 250px;
27
+ position: absolute;
28
+ right: 0;
29
+ top: 70px;
30
+ bottom: 0;
31
+ overflow: auto;
32
+ z-index: 0;
33
+ `;
34
+
35
+ export function TopLeftLayout({ children }: React.PropsWithChildren<any>) {
36
+ return (
37
+ <StyledWraper>
38
+ <Slot area={AreaType.TopArea}/>
39
+ <StyledSidebar>
40
+ <Slot area={AreaType.LeftArea}/>
41
+ </StyledSidebar>
42
+ <StyledMain>
43
+ {children}
44
+ <Slot area={AreaType.BottomArea}/>
45
+ </StyledMain>
46
+ </StyledWraper>
47
+ );
48
+ }
49
+
50
+ export function MultiTopLayout({ children }: React.PropsWithChildren<any>) {
51
+ return (
52
+ <Box>
53
+ <Slot area={AreaType.TopArea}/>
54
+ <Slot area={AreaType.SecondaryTopArea}/>
55
+ <Slot area={AreaType.TertiaryTopArea}/>
56
+ {children}
57
+ <Slot area={AreaType.BottomArea}/>
58
+ </Box>
59
+ );
60
+ }
61
+
62
+ @DefaultLayout(TopLeftLayout)
63
+ export default class {}
@@ -0,0 +1,5 @@
1
+
2
+ import './index';
3
+ import { autoBind } from '@celljs/core';
4
+
5
+ export default autoBind();
@@ -0,0 +1,61 @@
1
+ import * as React from 'react';
2
+ import { Avatar, AvatarProps, Drop, Box } from 'grommet';
3
+ import { ConfigUtil, ContainerUtil } from '@celljs/core';
4
+ import { Widget } from '@celljs/widget';
5
+ import { AreaType } from '../area';
6
+ import styled from 'styled-components';
7
+ import { Slot } from '@celljs/react';
8
+ import { UserManager } from '@celljs/security/lib/browser';
9
+ import { User } from '@celljs/security';
10
+ import { NavItem, Icon } from '@celljs/grommet';
11
+
12
+ const StyledAccount = styled.div`
13
+ width: 200px;
14
+ max-height: 450px;
15
+ padding-top: 12px;
16
+ overflow: auto;
17
+ right: 0;
18
+ `;
19
+
20
+ export function Account(props: AvatarProps) {
21
+ // eslint-disable-next-line no-null/no-null
22
+ const targetRef = React.useRef(null);
23
+ const loginUserManager = ContainerUtil.get<UserManager>(UserManager);
24
+ const [show, setShow] = React.useState(false);
25
+ const [user, setUser] = React.useState<User | undefined>(loginUserManager.userInfoSubject.value);
26
+ React.useEffect(() => {
27
+ const subscription = loginUserManager.userInfoSubject.subscribe(u => setUser(u));
28
+ return () => subscription.unsubscribe();
29
+ }, []);
30
+ const { icon, login, ...rest } = ConfigUtil.get('cell.shell.account');
31
+ props = { ...rest, ...props };
32
+ if (!user) {
33
+ const { label, ...loginRest } = login;
34
+ return (<NavItem label={label} size="medium" {...loginRest}/>);
35
+ }
36
+ return (
37
+ <Box ref={targetRef}>
38
+ <Avatar
39
+ hoverIndicator title={user.nickname} style={{ margin: '12px' }} size='small' onClick={() => setShow(true)} {...props} src={user.avatar || props.src}>
40
+ {<Icon icon={user.avatar || icon}/>}
41
+ </Avatar>
42
+ {targetRef.current && show && (
43
+ <Drop
44
+ target={targetRef.current!}
45
+ style={{ margin: '20px 0' }}
46
+ elevation="large"
47
+ align={{ top: 'bottom', right: 'right'}}
48
+ onEsc={() => setShow(false)}
49
+ onClickOutside={() => setShow(false)}
50
+ >
51
+ <StyledAccount>
52
+ <Slot area={AreaType.AccountArea}/>
53
+ </StyledAccount>
54
+ </Drop>
55
+ )}
56
+ </Box>
57
+ );
58
+ }
59
+
60
+ @Widget({ area: AreaType.TopRightArea, component: Account, priority: 100 })
61
+ export default class {}
@@ -0,0 +1,47 @@
1
+ import * as React from 'react';
2
+ import { Button, ButtonProps, Drop } from 'grommet';
3
+ import { ConfigUtil } from '@celljs/core';
4
+ import { Icon } from '@celljs/grommet';
5
+ import { Widget } from '@celljs/widget';
6
+ import { AreaType } from '../area';
7
+ import { Apps } from '../apps';
8
+ import styled from 'styled-components';
9
+
10
+ const { Fragment } = React;
11
+
12
+ const StyledAppSet = styled.div`
13
+ width: 320px;
14
+ max-height: 450px;
15
+ padding-top: 12px;
16
+ overflow: auto;
17
+ `;
18
+
19
+ export function AppSet(props: ButtonProps) {
20
+ // eslint-disable-next-line no-null/no-null
21
+ const targetRef = React.useRef(null);
22
+ const [show, setShow] = React.useState(false);
23
+ const { icon, ...rest } = ConfigUtil.get('cell.shell.appSet');
24
+ props = { ...rest, ...props };
25
+ return (
26
+ <Fragment>
27
+ <Button ref={targetRef} hoverIndicator onClick={() => setShow(true)} {...props} icon={<Icon icon={icon}/>}/>
28
+ {targetRef.current && show && (
29
+ <Drop
30
+ target={targetRef.current!}
31
+ style={{ marginTop: '20px' }}
32
+ elevation="large"
33
+ align={{ top: 'bottom', right: 'right'}}
34
+ onEsc={() => setShow(false)}
35
+ onClickOutside={() => setShow(false)}
36
+ >
37
+ <StyledAppSet>
38
+ <Apps size="small"/>
39
+ </StyledAppSet>
40
+ </Drop>
41
+ )}
42
+ </Fragment>
43
+ );
44
+ }
45
+
46
+ @Widget({ area: AreaType.TopRightArea, component: AppSet, priority: 200 })
47
+ export default class {}
@@ -0,0 +1,4 @@
1
+ export * from './logo';
2
+ export * from './settings';
3
+ export * from './app-set';
4
+ export * from './account';
@@ -0,0 +1,14 @@
1
+ import * as React from 'react';
2
+ import { ConfigUtil } from '@celljs/core';
3
+ import { Widget } from '@celljs/widget';
4
+ import { AreaType } from '../area';
5
+ import { NavItemProps, NavItem, Icon } from '@celljs/grommet';
6
+
7
+ export function Logo(props: NavItemProps) {
8
+ const { label, icon, ...rest } = ConfigUtil.get('cell.shell.logo');
9
+ props = { ...rest, ...props };
10
+ return (<NavItem size="medium" gap="xsmall" label={label} icon={<Icon icon={icon}/>} hoverIndicator={false} activatable={false} {...props}/>);
11
+ }
12
+
13
+ @Widget({ area: AreaType.TopLeftArea, component: Logo, priority: 1000 })
14
+ export default class {}
@@ -0,0 +1,56 @@
1
+ import * as React from 'react';
2
+ import { Button, ButtonProps, Drop, ThemeType, Box } from 'grommet';
3
+ import { ConfigUtil, ContainerUtil } from '@celljs/core';
4
+ import { Icon, ThemeBox, LocaleMenu } from '@celljs/grommet';
5
+ import { Widget, ThemeManager } from '@celljs/widget';
6
+ import { AreaType } from '../area';
7
+ import styled from 'styled-components';
8
+ import { Slot } from '@celljs/react';
9
+
10
+ const { Fragment } = React;
11
+
12
+ const StyledSettings = styled.div`
13
+ width: 300px;
14
+ max-height: 450px;
15
+ padding-top: 12px;
16
+ overflow: auto;
17
+ right: 0;
18
+ `;
19
+ // @ts-ignore
20
+ export function Settings(props: ButtonProps) {
21
+ // eslint-disable-next-line no-null/no-null
22
+ const targetRef = React.useRef(null);
23
+ const [show, setShow] = React.useState(false);
24
+ const { icon, ...rest } = ConfigUtil.get<any>('cell.shell.settings');
25
+ props = { ...rest, ...props };
26
+ React.useEffect(() => {
27
+ const themeManager = ContainerUtil.get<ThemeManager<ThemeType>>(ThemeManager);
28
+ const subscription = themeManager.currentSubject.subscribe(t => setShow(false));
29
+ return () => subscription.unsubscribe();
30
+ }, []);
31
+ // @ts-ignore
32
+ return (<Fragment>
33
+ <Button ref={targetRef} hoverIndicator onClick={() => setShow(true)} {...props} icon={<Icon icon={icon}/>}/>
34
+ {targetRef.current && show && (
35
+ <Drop
36
+ target={targetRef.current!}
37
+ style={{ marginTop: '20px' }}
38
+ elevation="large"
39
+ align={{ top: 'bottom', right: 'right'}}
40
+ onEsc={() => setShow(false)}
41
+ onClickOutside={() => setShow(false)}
42
+ >
43
+ <StyledSettings>
44
+ <Box>
45
+ <Slot area={AreaType.SettingsArea}/>
46
+ </Box>
47
+ </StyledSettings>
48
+ </Drop>
49
+ )}
50
+ </Fragment>);
51
+ }
52
+
53
+ @Widget({ area: AreaType.SettingsArea, component: LocaleMenu, priority: 200 })
54
+ @Widget({ area: AreaType.SettingsArea, component: ThemeBox, priority: 300 })
55
+ @Widget({ area: AreaType.TopRightArea, component: Settings, priority: 300 })
56
+ export default class {}
@@ -0,0 +1 @@
1
+ export * from './shell-protocol';
@@ -0,0 +1,21 @@
1
+ export const AppService = Symbol('AppService');
2
+
3
+ export interface AppInfo {
4
+ id: string;
5
+ name: string;
6
+ icon: string;
7
+ categoryId: string;
8
+ priority: number;
9
+ url: string;
10
+ }
11
+
12
+ export interface Category {
13
+ id: string;
14
+ name: string;
15
+ priority: number;
16
+ apps: AppInfo[];
17
+ }
18
+
19
+ export interface AppService {
20
+ load(): Promise<Category[]>;
21
+ }
File without changes
@@ -0,0 +1,4 @@
1
+
2
+ import { autoBind } from '@celljs/core';
3
+
4
+ export default autoBind();
@@ -0,0 +1,4 @@
1
+ describe('shell package', () => {
2
+
3
+ it('support code coverage statistics', () => {});
4
+ });