@servicetitan/navigation 3.3.0 → 4.1.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/components/header-navigation/header-navigation-content.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation-content.js +3 -3
- package/dist/components/header-navigation/header-navigation-content.js.map +1 -1
- package/dist/components/header-navigation/header-navigation-extra.stories.d.ts +3 -3
- package/dist/components/header-navigation/header-navigation-extra.stories.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation-extra.stories.js +8 -22
- package/dist/components/header-navigation/header-navigation-extra.stories.js.map +1 -1
- package/dist/components/header-navigation/header-navigation-links.d.ts +3 -30
- package/dist/components/header-navigation/header-navigation-links.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation-links.js +8 -5
- package/dist/components/header-navigation/header-navigation-links.js.map +1 -1
- package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts +1 -0
- package/dist/components/header-navigation/header-navigation-stacked.stories.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation-stacked.stories.js +8 -26
- package/dist/components/header-navigation/header-navigation-stacked.stories.js.map +1 -1
- package/dist/components/header-navigation/header-navigation.d.ts +1 -28
- package/dist/components/header-navigation/header-navigation.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation.js +5 -8
- package/dist/components/header-navigation/header-navigation.js.map +1 -1
- package/dist/components/header-navigation/header-navigation.module.less +13 -70
- package/dist/components/header-navigation/header-navigation.stories.d.ts +1 -0
- package/dist/components/header-navigation/header-navigation.stories.d.ts.map +1 -1
- package/dist/components/header-navigation/header-navigation.stories.js +9 -27
- package/dist/components/header-navigation/header-navigation.stories.js.map +1 -1
- package/dist/components/header-navigation/index.d.ts +0 -1
- package/dist/components/header-navigation/index.d.ts.map +1 -1
- package/dist/components/header-navigation/index.js +0 -1
- package/dist/components/header-navigation/index.js.map +1 -1
- package/dist/components/layout.stories.d.ts +1 -0
- package/dist/components/layout.stories.d.ts.map +1 -1
- package/dist/components/layout.stories.js +4 -2
- package/dist/components/layout.stories.js.map +1 -1
- package/dist/components/left-navigation/header-navigation-tiny-links.d.ts +16 -0
- package/dist/components/left-navigation/header-navigation-tiny-links.d.ts.map +1 -0
- package/dist/components/left-navigation/header-navigation-tiny-links.js +43 -0
- package/dist/components/left-navigation/header-navigation-tiny-links.js.map +1 -0
- package/dist/components/left-navigation/header-navigation-tiny.d.ts +23 -0
- package/dist/components/left-navigation/header-navigation-tiny.d.ts.map +1 -0
- package/dist/components/left-navigation/header-navigation-tiny.js +7 -0
- package/dist/components/left-navigation/header-navigation-tiny.js.map +1 -0
- package/dist/components/left-navigation/header-navigation-tiny.module.less +109 -0
- package/dist/components/{header-navigation → left-navigation}/header-navigation-tiny.stories.d.ts +2 -2
- package/dist/components/left-navigation/header-navigation-tiny.stories.d.ts.map +1 -0
- package/dist/components/left-navigation/header-navigation-tiny.stories.js +30 -0
- package/dist/components/left-navigation/header-navigation-tiny.stories.js.map +1 -0
- package/dist/components/left-navigation/index.d.ts +3 -0
- package/dist/components/left-navigation/index.d.ts.map +1 -0
- package/dist/components/left-navigation/index.js +3 -0
- package/dist/components/left-navigation/index.js.map +1 -0
- package/dist/components/{side-navigation → left-navigation}/side-navigation.d.ts +1 -12
- package/dist/components/left-navigation/side-navigation.d.ts.map +1 -0
- package/dist/components/left-navigation/side-navigation.js +23 -0
- package/dist/components/left-navigation/side-navigation.js.map +1 -0
- package/dist/components/{side-navigation → left-navigation}/side-navigation.module.less +28 -22
- package/dist/components/left-navigation/side-navigation.stories.d.ts +10 -0
- package/dist/components/left-navigation/side-navigation.stories.d.ts.map +1 -0
- package/dist/components/left-navigation/side-navigation.stories.js +31 -0
- package/dist/components/left-navigation/side-navigation.stories.js.map +1 -0
- package/dist/components/links.d.ts +5 -0
- package/dist/components/links.d.ts.map +1 -0
- package/dist/components/links.js +14 -0
- package/dist/components/links.js.map +1 -0
- package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts +2 -8
- package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js +5 -43
- package/dist/components/profile-dropdown/profile-dropdown-stacked.stories.js.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts +9 -0
- package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.d.ts.map +1 -0
- package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js +13 -0
- package/dist/components/profile-dropdown/profile-dropdown-tiny.stories.js.map +1 -0
- package/dist/components/profile-dropdown/profile-dropdown.d.ts +2 -1
- package/dist/components/profile-dropdown/profile-dropdown.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.js +16 -7
- package/dist/components/profile-dropdown/profile-dropdown.js.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.module.less +7 -1
- package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts +9 -8
- package/dist/components/profile-dropdown/profile-dropdown.stories.d.ts.map +1 -1
- package/dist/components/profile-dropdown/profile-dropdown.stories.js +39 -39
- package/dist/components/profile-dropdown/profile-dropdown.stories.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/test/data-stories.module.less +8 -0
- package/dist/test/data.stories.d.ts +26 -0
- package/dist/test/data.stories.d.ts.map +1 -0
- package/dist/test/data.stories.js +151 -0
- package/dist/test/data.stories.js.map +1 -0
- package/dist/utils/navigation-context.d.ts +2 -2
- package/dist/utils/navigation-context.d.ts.map +1 -1
- package/dist/utils/navigation-context.js +18 -5
- package/dist/utils/navigation-context.js.map +1 -1
- package/dist/utils/navigation.d.ts +47 -0
- package/dist/utils/navigation.d.ts.map +1 -1
- package/package.json +11 -11
- package/src/components/header-navigation/header-navigation-content.tsx +3 -3
- package/src/components/header-navigation/header-navigation-extra.stories.tsx +29 -38
- package/src/components/header-navigation/header-navigation-links.tsx +19 -41
- package/src/components/header-navigation/header-navigation-stacked.stories.tsx +18 -70
- package/src/components/header-navigation/header-navigation.module.less +13 -70
- package/src/components/header-navigation/header-navigation.module.less.d.ts +0 -1
- package/src/components/header-navigation/header-navigation.stories.tsx +20 -71
- package/src/components/header-navigation/header-navigation.tsx +6 -82
- package/src/components/header-navigation/index.ts +0 -1
- package/src/components/layout.stories.tsx +4 -2
- package/src/components/left-navigation/header-navigation-tiny-links.tsx +110 -0
- package/src/components/left-navigation/header-navigation-tiny.module.less +109 -0
- package/src/components/left-navigation/header-navigation-tiny.module.less.d.ts +14 -0
- package/src/components/{header-navigation → left-navigation}/header-navigation-tiny.stories.tsx +39 -46
- package/src/components/left-navigation/header-navigation-tiny.tsx +65 -0
- package/src/components/left-navigation/index.ts +2 -0
- package/src/components/{side-navigation → left-navigation}/side-navigation.module.less +28 -22
- package/src/components/{side-navigation → left-navigation}/side-navigation.module.less.d.ts +3 -3
- package/src/components/left-navigation/side-navigation.stories.tsx +46 -0
- package/src/components/left-navigation/side-navigation.tsx +171 -0
- package/src/components/links.tsx +31 -0
- package/src/components/profile-dropdown/profile-dropdown-stacked.stories.tsx +5 -170
- package/src/components/profile-dropdown/profile-dropdown-tiny.stories.tsx +15 -0
- package/src/components/profile-dropdown/profile-dropdown.module.less +7 -1
- package/src/components/profile-dropdown/profile-dropdown.module.less.d.ts +1 -0
- package/src/components/profile-dropdown/profile-dropdown.stories.tsx +106 -129
- package/src/components/profile-dropdown/profile-dropdown.tsx +35 -8
- package/src/index.ts +2 -1
- package/src/test/data-stories.module.less +8 -0
- package/src/test/data-stories.module.less.d.ts +3 -0
- package/src/test/data.stories.tsx +223 -0
- package/src/utils/navigation-context.tsx +10 -10
- package/src/utils/navigation.ts +54 -0
- package/dist/components/header-navigation/header-navigation-tiny.stories.d.ts.map +0 -1
- package/dist/components/header-navigation/header-navigation-tiny.stories.js +0 -25
- package/dist/components/header-navigation/header-navigation-tiny.stories.js.map +0 -1
- package/dist/components/side-navigation/icons.d.ts +0 -7
- package/dist/components/side-navigation/icons.d.ts.map +0 -1
- package/dist/components/side-navigation/icons.js +0 -5
- package/dist/components/side-navigation/icons.js.map +0 -1
- package/dist/components/side-navigation/index.d.ts +0 -2
- package/dist/components/side-navigation/index.d.ts.map +0 -1
- package/dist/components/side-navigation/index.js +0 -2
- package/dist/components/side-navigation/index.js.map +0 -1
- package/dist/components/side-navigation/side-navigation.d.ts.map +0 -1
- package/dist/components/side-navigation/side-navigation.js +0 -37
- package/dist/components/side-navigation/side-navigation.js.map +0 -1
- package/dist/components/side-navigation/side-navigation.stories.d.ts +0 -10
- package/dist/components/side-navigation/side-navigation.stories.d.ts.map +0 -1
- package/dist/components/side-navigation/side-navigation.stories.js +0 -52
- package/dist/components/side-navigation/side-navigation.stories.js.map +0 -1
- package/src/components/side-navigation/icons.tsx +0 -74
- package/src/components/side-navigation/index.ts +0 -1
- package/src/components/side-navigation/side-navigation.stories.tsx +0 -95
- package/src/components/side-navigation/side-navigation.tsx +0 -224
|
@@ -1,157 +1,134 @@
|
|
|
1
1
|
import { Button } from '@servicetitan/design-system';
|
|
2
|
-
import {
|
|
3
|
-
import { NavLinkComponentProps } from '../../utils/navigation';
|
|
2
|
+
import { withAnvil, withMemoryRouter } from '../../test/data.stories';
|
|
4
3
|
import { HeaderNavigation } from '../header-navigation';
|
|
5
4
|
import { ProfileDropdown } from './profile-dropdown';
|
|
6
5
|
|
|
6
|
+
const withHeaderNavigation = (Story: any) => (
|
|
7
|
+
<HeaderNavigation>
|
|
8
|
+
<Story />
|
|
9
|
+
</HeaderNavigation>
|
|
10
|
+
);
|
|
11
|
+
|
|
7
12
|
export default {
|
|
8
13
|
title: 'Navigation/ProfileDropdown',
|
|
9
14
|
component: ProfileDropdown,
|
|
10
15
|
parameters: {},
|
|
16
|
+
decorators: [withMemoryRouter, withAnvil, withHeaderNavigation],
|
|
11
17
|
};
|
|
12
18
|
|
|
13
|
-
const
|
|
14
|
-
<
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
</ProfileDropdown.Link>
|
|
32
|
-
<ProfileDropdown.Link id="second" onClick={() => alert('second click')}>
|
|
33
|
-
second link
|
|
34
|
-
</ProfileDropdown.Link>
|
|
35
|
-
<ProfileDropdown.Divider />
|
|
36
|
-
<ProfileDropdown.Section id="content">some content</ProfileDropdown.Section>
|
|
37
|
-
<ProfileDropdown.Divider />
|
|
38
|
-
<ProfileDropdown.Divider />
|
|
39
|
-
<ProfileDropdown.Divider />
|
|
40
|
-
<ProfileDropdown.Link id="third" to="https://google.com">
|
|
41
|
-
third link
|
|
42
|
-
</ProfileDropdown.Link>
|
|
43
|
-
<ProfileDropdown.Divider />
|
|
44
|
-
</ProfileDropdown>
|
|
45
|
-
</HeaderNavigation>
|
|
19
|
+
export const ProfileDropdownDefault = () => (
|
|
20
|
+
<ProfileDropdown>
|
|
21
|
+
<ProfileDropdown.Link id="first" to="https://google.com">
|
|
22
|
+
first link
|
|
23
|
+
</ProfileDropdown.Link>
|
|
24
|
+
<ProfileDropdown.Link id="second" onClick={() => alert('second click')}>
|
|
25
|
+
second link
|
|
26
|
+
</ProfileDropdown.Link>
|
|
27
|
+
<ProfileDropdown.Divider />
|
|
28
|
+
<ProfileDropdown.Section id="content">some content</ProfileDropdown.Section>
|
|
29
|
+
<ProfileDropdown.Divider />
|
|
30
|
+
<ProfileDropdown.Divider />
|
|
31
|
+
<ProfileDropdown.Divider />
|
|
32
|
+
<ProfileDropdown.Link id="third" to="third">
|
|
33
|
+
third link
|
|
34
|
+
</ProfileDropdown.Link>
|
|
35
|
+
<ProfileDropdown.Divider />
|
|
36
|
+
</ProfileDropdown>
|
|
46
37
|
);
|
|
47
38
|
|
|
48
|
-
export const
|
|
49
|
-
<
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
>
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
</ProfileDropdown>
|
|
62
|
-
</HeaderNavigation>
|
|
39
|
+
export const ProfileDropdownWithLogo = () => (
|
|
40
|
+
<ProfileDropdown
|
|
41
|
+
trigger={{
|
|
42
|
+
imageSrc: 'https://upload.wikimedia.org/wikipedia/en/1/11/Milhouse_Van_Houten.png',
|
|
43
|
+
}}
|
|
44
|
+
>
|
|
45
|
+
<ProfileDropdown.Link id="first" to="https://google.com">
|
|
46
|
+
first link
|
|
47
|
+
</ProfileDropdown.Link>
|
|
48
|
+
<ProfileDropdown.Link id="second" onClick={() => alert('second click')}>
|
|
49
|
+
second link
|
|
50
|
+
</ProfileDropdown.Link>
|
|
51
|
+
</ProfileDropdown>
|
|
63
52
|
);
|
|
64
53
|
|
|
65
|
-
export const
|
|
66
|
-
<
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
/>
|
|
72
|
-
</HeaderNavigation>
|
|
54
|
+
export const ProfileDropdownWithErrorLogo = () => (
|
|
55
|
+
<ProfileDropdown
|
|
56
|
+
trigger={{
|
|
57
|
+
imageSrc: 'https://some.incorrect.url/logo.png',
|
|
58
|
+
}}
|
|
59
|
+
/>
|
|
73
60
|
);
|
|
74
61
|
|
|
75
|
-
export const
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
/>
|
|
83
|
-
</HeaderNavigation>
|
|
62
|
+
export const ProfileDropdownWithInfo = () => (
|
|
63
|
+
<ProfileDropdown
|
|
64
|
+
trigger={{
|
|
65
|
+
info: { text: 'first', title: 'tenant user' },
|
|
66
|
+
avatarBadge: true,
|
|
67
|
+
}}
|
|
68
|
+
/>
|
|
84
69
|
);
|
|
85
70
|
|
|
86
|
-
export const
|
|
87
|
-
<
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
/>
|
|
95
|
-
</HeaderNavigation>
|
|
71
|
+
export const ProfileDropdownWithCounter = () => (
|
|
72
|
+
<ProfileDropdown
|
|
73
|
+
trigger={{
|
|
74
|
+
info: { text: 'first', title: 'tenant user' },
|
|
75
|
+
avatarBadge: true,
|
|
76
|
+
badge: { content: 3, className: 'bg-red-500' },
|
|
77
|
+
}}
|
|
78
|
+
/>
|
|
96
79
|
);
|
|
97
80
|
|
|
98
|
-
export const
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
/>
|
|
106
|
-
</HeaderNavigation>
|
|
81
|
+
export const ProfileDropdownWithBothBadges = () => (
|
|
82
|
+
<ProfileDropdown
|
|
83
|
+
trigger={{
|
|
84
|
+
avatarBadge: 'yellow-500',
|
|
85
|
+
badge: { className: 'bg-red-400' },
|
|
86
|
+
}}
|
|
87
|
+
/>
|
|
107
88
|
);
|
|
108
89
|
|
|
109
90
|
// eslint-disable-next-line no-console
|
|
110
91
|
const log = (text: string) => console.log(text);
|
|
111
92
|
|
|
112
|
-
export const
|
|
113
|
-
<
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
>
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
</ProfileDropdown>
|
|
141
|
-
</HeaderNavigation>
|
|
93
|
+
export const ProfileDropdownWithHintPopup = () => (
|
|
94
|
+
<ProfileDropdown
|
|
95
|
+
trigger={{
|
|
96
|
+
avatarBadge: 'yellow-500',
|
|
97
|
+
badge: { className: 'bg-red-400' },
|
|
98
|
+
}}
|
|
99
|
+
hintPopup={{
|
|
100
|
+
className: 'bg-blue-500-i c-white',
|
|
101
|
+
content: ({ openProfile }) => (
|
|
102
|
+
<div>
|
|
103
|
+
hello{' '}
|
|
104
|
+
<Button onClick={openProfile} size="xsmall">
|
|
105
|
+
show me
|
|
106
|
+
</Button>
|
|
107
|
+
</div>
|
|
108
|
+
),
|
|
109
|
+
width: 's',
|
|
110
|
+
onClose: () => log('close profile dropdown hint'),
|
|
111
|
+
}}
|
|
112
|
+
onOpen={() => log('open profile dropdown')}
|
|
113
|
+
onClose={() => log('close profile dropdown')}
|
|
114
|
+
>
|
|
115
|
+
<ProfileDropdown.Link id="first" to="https://google.com">
|
|
116
|
+
first item
|
|
117
|
+
</ProfileDropdown.Link>
|
|
118
|
+
<ProfileDropdown.Divider />
|
|
119
|
+
<ProfileDropdown.Section id="second">second item</ProfileDropdown.Section>
|
|
120
|
+
</ProfileDropdown>
|
|
142
121
|
);
|
|
143
122
|
|
|
144
|
-
export const
|
|
145
|
-
<
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
/>
|
|
156
|
-
</HeaderNavigation>
|
|
123
|
+
export const ProfileDropdownWithHintAndInfoPopup = () => (
|
|
124
|
+
<ProfileDropdown
|
|
125
|
+
trigger={{
|
|
126
|
+
avatarBadge: 'yellow-500',
|
|
127
|
+
badge: { className: 'bg-red-400' },
|
|
128
|
+
info: { title: 'some text', text: 'qq' },
|
|
129
|
+
}}
|
|
130
|
+
hintPopup={{
|
|
131
|
+
content: () => <div>hello</div>,
|
|
132
|
+
}}
|
|
133
|
+
/>
|
|
157
134
|
);
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Icon } from '@servicetitan/anvil2';
|
|
2
|
+
import SvgExpandLess from '@servicetitan/anvil2/assets/icons/material/round/expand_less.svg';
|
|
3
|
+
import SvgExpandMore from '@servicetitan/anvil2/assets/icons/material/round/expand_more.svg';
|
|
4
|
+
import SvgAccountActive from '@servicetitan/anvil2/assets/icons/st/gnav_account_active.svg';
|
|
5
|
+
import SvgAccountInactive from '@servicetitan/anvil2/assets/icons/st/gnav_account_inactive.svg';
|
|
6
|
+
import { BodyText, Popover, PopoverPropsStrict } from '@servicetitan/design-system';
|
|
2
7
|
import classNames from 'classnames';
|
|
3
8
|
import {
|
|
4
9
|
FC,
|
|
@@ -7,12 +12,16 @@ import {
|
|
|
7
12
|
MouseEventHandler,
|
|
8
13
|
ReactNode,
|
|
9
14
|
useCallback,
|
|
15
|
+
useContext,
|
|
10
16
|
useEffect,
|
|
11
17
|
useMemo,
|
|
12
18
|
useState,
|
|
13
19
|
} from 'react';
|
|
14
20
|
|
|
15
|
-
import {
|
|
21
|
+
import {
|
|
22
|
+
NavigationComponentContext,
|
|
23
|
+
NavigationLegacyContext,
|
|
24
|
+
} from '../../utils/navigation-context';
|
|
16
25
|
import { CounterTag, CounterTagPropsType } from '../counter-tag';
|
|
17
26
|
import * as Styles from './profile-dropdown.module.less';
|
|
18
27
|
import { ProfileLogo } from './profile-icon';
|
|
@@ -24,6 +33,7 @@ export interface ProfileDropdownTriggerProps {
|
|
|
24
33
|
avatarBadge?: boolean | string;
|
|
25
34
|
badge?: { content?: number | string; className: string };
|
|
26
35
|
hintArrow?: boolean;
|
|
36
|
+
open: boolean;
|
|
27
37
|
onClick?(e: MouseEvent): void;
|
|
28
38
|
}
|
|
29
39
|
|
|
@@ -35,9 +45,11 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
|
|
|
35
45
|
imageSrc,
|
|
36
46
|
info,
|
|
37
47
|
onClick,
|
|
48
|
+
open,
|
|
38
49
|
}) => {
|
|
39
50
|
const [avatarSource, setAvatarSource] = useState(imageSrc ?? '');
|
|
40
51
|
const [avatarSourceError, setAvatarSourceError] = useState(false);
|
|
52
|
+
const isLegacy = useContext(NavigationLegacyContext);
|
|
41
53
|
|
|
42
54
|
useEffect(() => {
|
|
43
55
|
const src = imageSrc ?? '';
|
|
@@ -60,7 +72,10 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
|
|
|
60
72
|
'd-f align-items-center cursor-pointer position-relative p-x-1 p-y-half',
|
|
61
73
|
'profile-dropdown-trigger',
|
|
62
74
|
Styles.triggerContainer,
|
|
63
|
-
{
|
|
75
|
+
{
|
|
76
|
+
[Styles.triggerContainerHintArrow]: hintArrow,
|
|
77
|
+
[Styles.triggerContainerLegacy]: isLegacy,
|
|
78
|
+
},
|
|
64
79
|
className
|
|
65
80
|
)}
|
|
66
81
|
onClick={onClick}
|
|
@@ -74,13 +89,20 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
|
|
|
74
89
|
onError={onAvatarError}
|
|
75
90
|
alt="user dropdown menu"
|
|
76
91
|
/>
|
|
77
|
-
) : (
|
|
92
|
+
) : isLegacy ? (
|
|
78
93
|
<ProfileLogo />
|
|
94
|
+
) : (
|
|
95
|
+
<Icon size="large" svg={open ? SvgAccountActive : SvgAccountInactive} />
|
|
79
96
|
)}
|
|
80
97
|
|
|
81
98
|
{!!info && (
|
|
82
99
|
<div className={Styles.info}>
|
|
83
|
-
<BodyText
|
|
100
|
+
<BodyText
|
|
101
|
+
bold
|
|
102
|
+
title={info.title}
|
|
103
|
+
className="t-truncate c-inherit"
|
|
104
|
+
size="xsmall"
|
|
105
|
+
>
|
|
84
106
|
{info.title}
|
|
85
107
|
</BodyText>
|
|
86
108
|
<BodyText
|
|
@@ -93,7 +115,11 @@ const ProfileDropdownTrigger: FC<ProfileDropdownTriggerProps> = ({
|
|
|
93
115
|
</div>
|
|
94
116
|
)}
|
|
95
117
|
|
|
96
|
-
<Icon
|
|
118
|
+
<Icon
|
|
119
|
+
svg={open ? SvgExpandLess : SvgExpandMore}
|
|
120
|
+
className={classNames('d-f align-items-center c-inherit', { 'm-l-half': isLegacy })}
|
|
121
|
+
size="small"
|
|
122
|
+
/>
|
|
97
123
|
|
|
98
124
|
{!!avatarBadge && (
|
|
99
125
|
<div
|
|
@@ -185,7 +211,7 @@ export const ProfileDropdownLink: FC<ProfileDropdownLinkProps> = ({
|
|
|
185
211
|
onClick,
|
|
186
212
|
...rest
|
|
187
213
|
}: ProfileDropdownLinkProps) => {
|
|
188
|
-
const NavigationComponent =
|
|
214
|
+
const NavigationComponent = useContext(NavigationComponentContext);
|
|
189
215
|
|
|
190
216
|
const clickHandler = (e: MouseEvent<any>) => {
|
|
191
217
|
e.preventDefault();
|
|
@@ -241,7 +267,7 @@ export interface ProfileDropdownPropsStrict {
|
|
|
241
267
|
children?: ReactNode;
|
|
242
268
|
className?: string;
|
|
243
269
|
direction?: PopoverPropsStrict['direction'];
|
|
244
|
-
trigger?: Omit<ProfileDropdownTriggerProps, 'onClick' | 'hintArrow'>;
|
|
270
|
+
trigger?: Omit<ProfileDropdownTriggerProps, 'onClick' | 'open' | 'hintArrow'>;
|
|
245
271
|
hintPopup?: {
|
|
246
272
|
className?: string;
|
|
247
273
|
content: FC<{ openProfile(): void }>;
|
|
@@ -305,6 +331,7 @@ export const ProfileDropdown: ProfileDropdownType = (({
|
|
|
305
331
|
{...trigger}
|
|
306
332
|
onClick={children ? onTriggerClick : undefined}
|
|
307
333
|
hintArrow={hintShown}
|
|
334
|
+
open={open}
|
|
308
335
|
/>
|
|
309
336
|
);
|
|
310
337
|
|
package/src/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ export * from './components/logo/logo-company-title';
|
|
|
4
4
|
export * from './components/logo/logo-titan';
|
|
5
5
|
export * from './components/logo/logo-titan-text';
|
|
6
6
|
export * from './components/counter-tag';
|
|
7
|
-
export * from './components/
|
|
7
|
+
export * from './components/left-navigation';
|
|
8
|
+
export * from './components/links';
|
|
8
9
|
export * from './utils/navigation';
|
|
9
10
|
export * from './utils/with-tooltip';
|
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import { AnvilProvider } from '@servicetitan/anvil2';
|
|
2
|
+
import SvgPhone from '@servicetitan/anvil2/assets/icons/material/round/phone_disabled.svg';
|
|
3
|
+
import SvgPhoneActive from '@servicetitan/anvil2/assets/icons/material/round/phone_enabled.svg';
|
|
4
|
+
import SvgAccountingActive from '@servicetitan/anvil2/assets/icons/st/gnav_accounting_active.svg';
|
|
5
|
+
import SvgAccounting from '@servicetitan/anvil2/assets/icons/st/gnav_accounting_inactive.svg';
|
|
6
|
+
import SvgCallsActive from '@servicetitan/anvil2/assets/icons/st/gnav_calls_active.svg';
|
|
7
|
+
import SvgCalls from '@servicetitan/anvil2/assets/icons/st/gnav_calls_inactive.svg';
|
|
8
|
+
import SvgDashboardActive from '@servicetitan/anvil2/assets/icons/st/gnav_dashboard_active.svg';
|
|
9
|
+
import SvgDashboard from '@servicetitan/anvil2/assets/icons/st/gnav_dashboard_inactive.svg';
|
|
10
|
+
import SvgDispatchActive from '@servicetitan/anvil2/assets/icons/st/gnav_dispatch_active.svg';
|
|
11
|
+
import SvgDispatch from '@servicetitan/anvil2/assets/icons/st/gnav_dispatch_inactive.svg';
|
|
12
|
+
import SvgFleetProActive from '@servicetitan/anvil2/assets/icons/st/gnav_fleet_pro_active.svg';
|
|
13
|
+
import SvgFleetPro from '@servicetitan/anvil2/assets/icons/st/gnav_fleet_pro_inactive.svg';
|
|
14
|
+
import SvgFollowUpActive from '@servicetitan/anvil2/assets/icons/st/gnav_follow_up_active.svg';
|
|
15
|
+
import SvgFollowUp from '@servicetitan/anvil2/assets/icons/st/gnav_follow_up_inactive.svg';
|
|
16
|
+
import SvgInventoryActive from '@servicetitan/anvil2/assets/icons/st/gnav_inventory_active.svg';
|
|
17
|
+
import SvgInventory from '@servicetitan/anvil2/assets/icons/st/gnav_inventory_inactive.svg';
|
|
18
|
+
import SvgMarketingActive from '@servicetitan/anvil2/assets/icons/st/gnav_marketing_active.svg';
|
|
19
|
+
import SvgMarketing from '@servicetitan/anvil2/assets/icons/st/gnav_marketing_inactive.svg';
|
|
20
|
+
import SvgPosActive from '@servicetitan/anvil2/assets/icons/st/gnav_pos_active.svg';
|
|
21
|
+
import SvgPos from '@servicetitan/anvil2/assets/icons/st/gnav_pos_inactive.svg';
|
|
22
|
+
import SvgPriceBookActive from '@servicetitan/anvil2/assets/icons/st/gnav_pricebook_active.svg';
|
|
23
|
+
import SvgPriceBook from '@servicetitan/anvil2/assets/icons/st/gnav_pricebook_inactive.svg';
|
|
24
|
+
import SvgProjectsActive from '@servicetitan/anvil2/assets/icons/st/gnav_projects_active.svg';
|
|
25
|
+
import SvgProjects from '@servicetitan/anvil2/assets/icons/st/gnav_projects_inactive.svg';
|
|
26
|
+
import SvgReportsActive from '@servicetitan/anvil2/assets/icons/st/gnav_reports_active.svg';
|
|
27
|
+
import SvgReports from '@servicetitan/anvil2/assets/icons/st/gnav_reports_inactive.svg';
|
|
28
|
+
import SvgScheduleActive from '@servicetitan/anvil2/assets/icons/st/gnav_schedule_active.svg';
|
|
29
|
+
import SvgSchedule from '@servicetitan/anvil2/assets/icons/st/gnav_schedule_inactive.svg';
|
|
30
|
+
import SvgTasksActive from '@servicetitan/anvil2/assets/icons/st/gnav_tasks_active.svg';
|
|
31
|
+
import SvgTasks from '@servicetitan/anvil2/assets/icons/st/gnav_tasks_inactive.svg';
|
|
32
|
+
|
|
33
|
+
import { Popover } from '@servicetitan/design-system';
|
|
34
|
+
|
|
35
|
+
import classNames from 'classnames';
|
|
36
|
+
import { forwardRef, useState } from 'react';
|
|
37
|
+
// needed only for storybook and added in root dependencies
|
|
38
|
+
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
39
|
+
import { MemoryRouter, useHistory, useLocation } from 'react-router-dom';
|
|
40
|
+
import { HeaderNavigationTrigger } from '../components/links';
|
|
41
|
+
import { HeaderNavigationItemData, NavLinkComponentProps } from '../utils/navigation';
|
|
42
|
+
import { NavigationComponentContext } from '../utils/navigation-context';
|
|
43
|
+
import * as Styles from './data-stories.module.less';
|
|
44
|
+
|
|
45
|
+
export const NavLinkMock = forwardRef<any, NavLinkComponentProps>(
|
|
46
|
+
({ to, children, activeClassName, className, isActive, ...rest }, ref) => {
|
|
47
|
+
const history = useHistory();
|
|
48
|
+
const location = useLocation();
|
|
49
|
+
const linkActive = location.pathname.replace('/', '') === to;
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<a
|
|
53
|
+
{...rest}
|
|
54
|
+
className={classNames(className, linkActive ? activeClassName : '')}
|
|
55
|
+
href={to}
|
|
56
|
+
onClick={e => {
|
|
57
|
+
e.preventDefault();
|
|
58
|
+
|
|
59
|
+
if (!to.startsWith('http')) {
|
|
60
|
+
history.push(to);
|
|
61
|
+
}
|
|
62
|
+
}}
|
|
63
|
+
ref={ref}
|
|
64
|
+
>
|
|
65
|
+
{children}
|
|
66
|
+
</a>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
export const withMemoryRouter = (Story: any) => (
|
|
72
|
+
<MemoryRouter>
|
|
73
|
+
<NavigationComponentContext.Provider value={NavLinkMock}>
|
|
74
|
+
<Story />
|
|
75
|
+
</NavigationComponentContext.Provider>
|
|
76
|
+
</MemoryRouter>
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
export const withAnvil = (Story: any) => (
|
|
80
|
+
<AnvilProvider className={Styles.fixIcons}>
|
|
81
|
+
<Story />
|
|
82
|
+
</AnvilProvider>
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
export const InventoryIcon = () => (
|
|
86
|
+
<svg width="20" xmlns="http://www.w3.org/2000/svg" viewBox="-293 385 24 24" fill="currentColor">
|
|
87
|
+
<polyline points="-288,400.9 -282,404.3 -282,397.6 -288,394.2 -288,400.9 " />
|
|
88
|
+
<path d="M-272,401.5c0,0.4-0.2,0.7-0.5,0.9l-7.9,4.4c-0.2,0.1-0.4,0.2-0.6,0.2s-0.4-0.1-0.6-0.2l-7.9-4.4c-0.3-0.2-0.5-0.5-0.5-0.9v-9c0-0.4,0.2-0.7,0.5-0.9l7.9-4.4c0.2-0.1,0.4-0.2,0.6-0.2s0.4,0.1,0.6,0.2l7.9,4.4c0.3,0.2,0.5,0.5,0.5,0.9V401.5 M-287,392.5 l6,3.4l5.9-3.3l-5.9-3.4L-287,392.5 M-274,400.9v-6.7l-6,3.4v6.7L-274,400.9z" />
|
|
89
|
+
</svg>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
export const SearchIcon = () => (
|
|
93
|
+
<svg
|
|
94
|
+
width="1em"
|
|
95
|
+
height="1em"
|
|
96
|
+
viewBox="0 0 24 24"
|
|
97
|
+
fill="none"
|
|
98
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
99
|
+
>
|
|
100
|
+
<g transform="translate(0,4)">
|
|
101
|
+
<path
|
|
102
|
+
d="M0 15.7992V13.9992H12V15.7992H0ZM0 9.49922V7.69922H6V9.49922H0ZM0 3.19922V1.39922H6V3.19922H0ZM22.74 15.7992L17.94 10.9992C17.42 11.3992 16.86 11.6992 16.26 11.8992C15.66 12.0992 15.04 12.1992 14.4 12.1992C12.74 12.1992 11.325 11.6142 10.155 10.4442C8.985 9.27422 8.4 7.85922 8.4 6.19922C8.4 4.53922 8.985 3.12422 10.155 1.95422C11.325 0.784219 12.74 0.199219 14.4 0.199219C16.06 0.199219 17.475 0.784219 18.645 1.95422C19.815 3.12422 20.4 4.53922 20.4 6.19922C20.4 6.83922 20.3 7.45922 20.1 8.05922C19.9 8.65922 19.6 9.21922 19.2 9.73922L24 14.5392L22.74 15.7992ZM14.393 10.3992C15.5577 10.3992 16.55 9.99157 17.37 9.17627C18.19 8.36099 18.6 7.37099 18.6 6.20627C18.6 5.04157 18.1923 4.04922 17.377 3.22922C16.5618 2.40922 15.5718 1.99922 14.407 1.99922C13.2423 1.99922 12.25 2.40687 11.43 3.22217C10.61 4.03745 10.2 5.02745 10.2 6.19217C10.2 7.35687 10.6077 8.34922 11.423 9.16922C12.2382 9.98922 13.2282 10.3992 14.393 10.3992Z"
|
|
103
|
+
fill="white"
|
|
104
|
+
/>
|
|
105
|
+
</g>
|
|
106
|
+
</svg>
|
|
107
|
+
);
|
|
108
|
+
|
|
109
|
+
const getItem = (
|
|
110
|
+
id: string,
|
|
111
|
+
data: Partial<HeaderNavigationItemData>
|
|
112
|
+
): HeaderNavigationItemData => ({
|
|
113
|
+
id,
|
|
114
|
+
to: id,
|
|
115
|
+
title: id[0].toUpperCase() + id.substring(1),
|
|
116
|
+
hint: id,
|
|
117
|
+
icon: undefined,
|
|
118
|
+
iconActive: undefined,
|
|
119
|
+
...(data ?? {}),
|
|
120
|
+
});
|
|
121
|
+
|
|
122
|
+
export const items = {
|
|
123
|
+
calendar: getItem('calendar', {
|
|
124
|
+
iconName: 'event',
|
|
125
|
+
icon: SvgSchedule,
|
|
126
|
+
iconActive: SvgScheduleActive,
|
|
127
|
+
}),
|
|
128
|
+
calls: getItem('calls', {
|
|
129
|
+
iconName: 'local_phone',
|
|
130
|
+
icon: SvgCalls,
|
|
131
|
+
iconActive: SvgCallsActive,
|
|
132
|
+
counter: 12,
|
|
133
|
+
}),
|
|
134
|
+
dashboard: getItem('dashboard', {
|
|
135
|
+
iconName: 'odometer',
|
|
136
|
+
icon: SvgDashboard,
|
|
137
|
+
iconActive: SvgDashboardActive,
|
|
138
|
+
}),
|
|
139
|
+
dispatch: getItem('dispatch', {
|
|
140
|
+
iconName: 'location_disabled',
|
|
141
|
+
icon: SvgDispatch,
|
|
142
|
+
iconActive: SvgDispatchActive,
|
|
143
|
+
counter: 1,
|
|
144
|
+
}),
|
|
145
|
+
fleet: getItem('fleet', {
|
|
146
|
+
iconName: 'fleet-pro',
|
|
147
|
+
icon: SvgFleetPro,
|
|
148
|
+
iconActive: SvgFleetProActive,
|
|
149
|
+
title: 'Fleet Pro',
|
|
150
|
+
}),
|
|
151
|
+
followUps: getItem('followUps', {
|
|
152
|
+
iconName: 'flag',
|
|
153
|
+
icon: SvgFollowUp,
|
|
154
|
+
iconActive: SvgFollowUpActive,
|
|
155
|
+
title: 'Follow Ups',
|
|
156
|
+
}),
|
|
157
|
+
inventory: getItem('inventory', {
|
|
158
|
+
iconName: 'toys',
|
|
159
|
+
icon: SvgInventory,
|
|
160
|
+
iconActive: SvgInventoryActive,
|
|
161
|
+
}),
|
|
162
|
+
purchasing: getItem('purchasing', { iconComponent: InventoryIcon }),
|
|
163
|
+
accounting: getItem('accounting', {
|
|
164
|
+
iconName: 'assignment',
|
|
165
|
+
icon: SvgAccounting,
|
|
166
|
+
iconActive: SvgAccountingActive,
|
|
167
|
+
}),
|
|
168
|
+
marketing: getItem('marketing', {
|
|
169
|
+
iconName: 'bullhorn',
|
|
170
|
+
icon: SvgMarketing,
|
|
171
|
+
iconActive: SvgMarketingActive,
|
|
172
|
+
}),
|
|
173
|
+
priceBook: getItem('priceBook', {
|
|
174
|
+
iconName: 'book',
|
|
175
|
+
icon: SvgPriceBook,
|
|
176
|
+
iconActive: SvgPriceBookActive,
|
|
177
|
+
}),
|
|
178
|
+
pointOfSale: getItem('pointOfSale', {
|
|
179
|
+
iconName: 'cash-register',
|
|
180
|
+
icon: SvgPos,
|
|
181
|
+
iconActive: SvgPosActive,
|
|
182
|
+
}),
|
|
183
|
+
projects: getItem('projects', {
|
|
184
|
+
iconName: 'folder_special',
|
|
185
|
+
icon: SvgProjects,
|
|
186
|
+
iconActive: SvgProjectsActive,
|
|
187
|
+
}),
|
|
188
|
+
reports: getItem('reports', {
|
|
189
|
+
iconName: 'folder_special',
|
|
190
|
+
icon: SvgReports,
|
|
191
|
+
iconActive: SvgReportsActive,
|
|
192
|
+
}),
|
|
193
|
+
tasks: getItem('tasks', {
|
|
194
|
+
iconName: 'format_list_bulleted',
|
|
195
|
+
icon: SvgTasks,
|
|
196
|
+
iconActive: SvgTasksActive,
|
|
197
|
+
}),
|
|
198
|
+
};
|
|
199
|
+
|
|
200
|
+
export const CallsNavigationTrigger = () => {
|
|
201
|
+
const [open, setOpen] = useState(false);
|
|
202
|
+
|
|
203
|
+
return (
|
|
204
|
+
<Popover
|
|
205
|
+
open={open}
|
|
206
|
+
onClickOutside={() => setOpen(false)}
|
|
207
|
+
direction="bl"
|
|
208
|
+
trigger={
|
|
209
|
+
<HeaderNavigationTrigger
|
|
210
|
+
id="dialpad"
|
|
211
|
+
iconName="phone"
|
|
212
|
+
counter={2}
|
|
213
|
+
icon={SvgPhone}
|
|
214
|
+
iconActive={SvgPhoneActive}
|
|
215
|
+
onClick={() => setOpen(!open)}
|
|
216
|
+
isActive={open}
|
|
217
|
+
/>
|
|
218
|
+
}
|
|
219
|
+
>
|
|
220
|
+
calls content
|
|
221
|
+
</Popover>
|
|
222
|
+
);
|
|
223
|
+
};
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { FC, createContext
|
|
2
|
-
import { NavLink } from 'react-router-dom';
|
|
1
|
+
import { FC, createContext } from 'react';
|
|
3
2
|
import { NavLinkComponentProps } from './navigation';
|
|
4
3
|
|
|
5
|
-
export const DefaultNavLinkComponent: FC<NavLinkComponentProps> =
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
)
|
|
4
|
+
export const DefaultNavLinkComponent: FC<NavLinkComponentProps> = ({
|
|
5
|
+
children,
|
|
6
|
+
activeClassName,
|
|
7
|
+
isActive,
|
|
8
|
+
...props
|
|
9
|
+
}) => <a {...props}>{children}</a>;
|
|
11
10
|
|
|
12
|
-
export const
|
|
13
|
-
|
|
11
|
+
export const NavigationComponentContext =
|
|
12
|
+
createContext<FC<NavLinkComponentProps>>(DefaultNavLinkComponent);
|
|
13
|
+
export const NavigationLegacyContext = createContext(false);
|