@retalia/sidebar-navigation 21.1.13 → 21.1.14
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/README.md +42 -42
- package/karma.conf.js +44 -0
- package/ng-package.json +8 -0
- package/package.json +14 -26
- package/{lib → src}/assets/fonts/Effra_Std_It.svg +5123 -5123
- package/{lib → src}/assets/fonts/Effra_Std_Md.svg +4128 -4128
- package/{lib → src}/assets/fonts/Effra_Std_Rg.svg +4690 -4690
- package/{lib → src}/assets/icons/sidebar-burger.svg +3 -3
- package/{lib → src}/assets/icons/sidebar-cross.svg +3 -3
- package/{lib → src}/assets/icons/subItem-arrow.svg +3 -3
- package/{lib → src}/assets/icons/topbar-info.svg +3 -3
- package/{lib → src}/assets/icons/topbar-logout.svg +4 -4
- package/{lib → src}/assets/icons/topbar-menu-burger.svg +5 -5
- package/{lib → src}/assets/icons/topbar-menu-close.svg +3 -3
- package/{lib → src}/assets/icons/topbar-notification.svg +3 -3
- package/{lib → src}/assets/icons/topbar-profile.svg +4 -4
- package/{lib → src}/assets/icons/topbar-settings.svg +3 -3
- package/{lib → src}/assets/icons/topmenu-arrow.svg +3 -3
- package/{lib → src}/assets/logo/_K3_imagine_White.svg +14 -14
- package/src/lib/data/support-routes.ts +56 -0
- package/src/lib/data/test-data.ts +628 -0
- package/src/lib/data/test-data2.ts +1742 -0
- package/src/lib/models/cookie-names.ts +12 -0
- package/src/lib/models/environment.ts +4 -0
- package/src/lib/models/http-response.ts +3 -0
- package/src/lib/models/module.ts +39 -0
- package/src/lib/navigation-lib.component.html +20 -0
- package/src/lib/navigation-lib.component.scss +30 -0
- package/src/lib/navigation-lib.component.ts +26 -0
- package/src/lib/navigation-lib.module.ts +26 -0
- package/src/lib/navigation-lib.service.ts +9 -0
- package/src/lib/services/auth.service.ts +39 -0
- package/src/lib/services/cookie.service.ts +33 -0
- package/src/lib/services/http.service.ts +26 -0
- package/src/lib/services/module.service.ts +153 -0
- package/src/lib/services/sub-item.service.ts +56 -0
- package/src/lib/sidebar/shop-modal/shop-modal.component.html +17 -0
- package/src/lib/sidebar/shop-modal/shop-modal.component.scss +73 -0
- package/src/lib/sidebar/shop-modal/shop-modal.component.ts +36 -0
- package/src/lib/sidebar/sidebar.component.html +86 -0
- package/src/lib/sidebar/sidebar.component.scss +260 -0
- package/src/lib/sidebar/sidebar.component.ts +267 -0
- package/src/lib/sidebar/sub-item/sub-item.component.html +18 -0
- package/src/lib/sidebar/sub-item/sub-item.component.scss +154 -0
- package/src/lib/sidebar/sub-item/sub-item.component.ts +61 -0
- package/src/lib/topbar/topbar.component.html +29 -0
- package/src/lib/topbar/topbar.component.scss +176 -0
- package/src/lib/topbar/topbar.component.ts +76 -0
- package/src/public-api.ts +14 -0
- package/src/styles/app.scss +53 -0
- package/src/test.ts +15 -0
- package/tsconfig.lib.json +21 -0
- package/tsconfig.lib.prod.json +11 -0
- package/tsconfig.spec.json +17 -0
- package/fesm2022/retalia-sidebar-navigation.mjs +0 -1388
- package/fesm2022/retalia-sidebar-navigation.mjs.map +0 -1
- package/production-0.0.2.tgz +0 -0
- package/types/retalia-sidebar-navigation.d.ts +0 -232
- /package/{lib → src}/assets/fonts/Effra_Std_It.eot +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_It.ttf +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_It.woff +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_It.woff2 +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Md.eot +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Md.ttf +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Md.woff +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Md.woff2 +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Rg.eot +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Rg.ttf +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Rg.woff +0 -0
- /package/{lib → src}/assets/fonts/Effra_Std_Rg.woff2 +0 -0
- /package/{lib → src}/assets/fonts/Poppins-Black.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-BlackItalic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-Bold.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-BoldItalic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-ExtraBold.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-ExtraBoldItalic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-ExtraLight.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-ExtraLightItalic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-Italic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-Light.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-LightItalic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-Medium.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-MediumItalic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-Regular.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-SemiBold.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-SemiBoldItalic.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-Thin.ttf +0 -0
- /package/{lib → src}/assets/fonts/Poppins-ThinItalic.ttf +0 -0
- /package/{lib → src}/assets/icons/topbar-avatar.png +0 -0
- /package/{lib → src}/assets/logo/full-white.png +0 -0
- /package/{lib → src}/assets/logo/full.png +0 -0
- /package/{lib → src}/assets/logo/mobile-white.png +0 -0
- /package/{lib → src}/assets/logo/mobile.png +0 -0
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
<div id="sidebar-panel">
|
|
2
|
+
<div class="panel-item" (click)="toggleSidebar($event, 'isModuleOpen')" data-testid="nav-menu">
|
|
3
|
+
@if (!panelButtonStates.isModuleOpen) {
|
|
4
|
+
<svg class="panel-icon" height="14" width="21" viewBox="0 0 18 12"
|
|
5
|
+
fill="#3e3e3e" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet">
|
|
6
|
+
<path d="M0 12H18V10H0V12ZM0 7H18V5H0V7ZM0 0V2H18V0H0Z" />
|
|
7
|
+
</svg>
|
|
8
|
+
}
|
|
9
|
+
@if (panelButtonStates.isModuleOpen) {
|
|
10
|
+
<svg class="panel-icon" height="13" width="13" viewBox="0 0 14 14"
|
|
11
|
+
fill="#3e3e3e" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet">
|
|
12
|
+
<path
|
|
13
|
+
d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z" />
|
|
14
|
+
</svg>
|
|
15
|
+
}
|
|
16
|
+
</div>
|
|
17
|
+
<div class="panel-item" (click)="toggleSidebar($event, 'isSupportOpen')" data-testid="nav-support">
|
|
18
|
+
@if (!panelButtonStates.isSupportOpen) {
|
|
19
|
+
<svg class="panel-icon" width="18" height="21" viewBox="0 0 18 21"
|
|
20
|
+
fill="#3e3e3e" xmlns="http://www.w3.org/2000/svg">
|
|
21
|
+
<path
|
|
22
|
+
d="M16 0H2C0.89 0 0 0.9 0 2V16C0 17.1 0.89 18 2 18H6L9 21L12 18H16C17.1 18 18 17.1 18 16V2C18 0.9 17.1 0 16 0ZM10 16H8V14H10V16ZM12.07 8.25L11.17 9.17C10.45 9.9 10 10.5 10 12H8V11.5C8 10.4 8.45 9.4 9.17 8.67L10.41 7.41C10.78 7.05 11 6.55 11 6C11 4.9 10.1 4 9 4C7.9 4 7 4.9 7 6H5C5 3.79 6.79 2 9 2C11.21 2 13 3.79 13 6C13 6.88 12.64 7.68 12.07 8.25Z" />
|
|
23
|
+
</svg>
|
|
24
|
+
}
|
|
25
|
+
@if (panelButtonStates.isSupportOpen) {
|
|
26
|
+
<svg class="panel-icon" height="13" width="13" viewBox="0 0 14 14"
|
|
27
|
+
fill="#3e3e3e" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet">
|
|
28
|
+
<path
|
|
29
|
+
d="M14 1.41L12.59 0L7 5.59L1.41 0L0 1.41L5.59 7L0 12.59L1.41 14L7 8.41L12.59 14L14 12.59L8.41 7L14 1.41Z" />
|
|
30
|
+
</svg>
|
|
31
|
+
}
|
|
32
|
+
</div>
|
|
33
|
+
|
|
34
|
+
@if (!isSidebarOpen) {
|
|
35
|
+
<div class="collapsed-module-icons">
|
|
36
|
+
@for (module of modules; track module.authorizationId) {
|
|
37
|
+
@if (module.icon) {
|
|
38
|
+
<div class="collapsed-module-icon" [attr.title]="module.translatedName || module.name">
|
|
39
|
+
<img [src]="module.icon" [alt]="module.translatedName || module.name" />
|
|
40
|
+
</div>
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</div>
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
<div class="status-button" (mouseover)="hideStatus = false" (mouseleave)="hideStatus = true"
|
|
48
|
+
(click)="goToStatusPage()" data-testid="sidebar-status">
|
|
49
|
+
<svg class="panel-icon" width="22" height="22" viewBox="0 0 22 22" fill="#FFFFFF"
|
|
50
|
+
xmlns="http://www.w3.org/2000/svg">
|
|
51
|
+
<path
|
|
52
|
+
d="M20.625 6.5H1.375C0.615613 6.5 0 5.82842 0 5V2C0 1.17158 0.615613 0.5 1.375 0.5H20.625C21.3844 0.5 22 1.17158 22 2V5C22 5.82842 21.3844 6.5 20.625 6.5ZM18.5625 2.375C17.9929 2.375 17.5312 2.87867 17.5312 3.5C17.5312 4.12133 17.9929 4.625 18.5625 4.625C19.1321 4.625 19.5938 4.12133 19.5938 3.5C19.5938 2.87867 19.1321 2.375 18.5625 2.375ZM15.8125 2.375C15.2429 2.375 14.7812 2.87867 14.7812 3.5C14.7812 4.12133 15.2429 4.625 15.8125 4.625C16.3821 4.625 16.8438 4.12133 16.8438 3.5C16.8438 2.87867 16.3821 2.375 15.8125 2.375ZM20.625 14H1.375C0.615613 14 0 13.3284 0 12.5V9.5C0 8.67158 0.615613 8 1.375 8H20.625C21.3844 8 22 8.67158 22 9.5V12.5C22 13.3284 21.3844 14 20.625 14ZM18.5625 9.875C17.9929 9.875 17.5312 10.3787 17.5312 11C17.5312 11.6213 17.9929 12.125 18.5625 12.125C19.1321 12.125 19.5938 11.6213 19.5938 11C19.5938 10.3787 19.1321 9.875 18.5625 9.875ZM15.8125 9.875C15.2429 9.875 14.7812 10.3787 14.7812 11C14.7812 11.6213 15.2429 12.125 15.8125 12.125C16.3821 12.125 16.8438 11.6213 16.8438 11C16.8438 10.3787 16.3821 9.875 15.8125 9.875ZM20.625 21.5H1.375C0.615613 21.5 0 20.8284 0 20V17C0 16.1716 0.615613 15.5 1.375 15.5H20.625C21.3844 15.5 22 16.1716 22 17V20C22 20.8284 21.3844 21.5 20.625 21.5ZM18.5625 17.375C17.9929 17.375 17.5312 17.8787 17.5312 18.5C17.5312 19.1213 17.9929 19.625 18.5625 19.625C19.1321 19.625 19.5938 19.1213 19.5938 18.5C19.5938 17.8787 19.1321 17.375 18.5625 17.375ZM15.8125 17.375C15.2429 17.375 14.7812 17.8787 14.7812 18.5C14.7812 19.1213 15.2429 19.625 15.8125 19.625C16.3821 19.625 16.8438 19.1213 16.8438 18.5C16.8438 17.8787 16.3821 17.375 15.8125 17.375Z" />
|
|
53
|
+
</svg>
|
|
54
|
+
<iframe id="status-frame" [ngClass]="{'isOpen': !hideStatus, 'isClosed': hideStatus }"
|
|
55
|
+
src="//status.retalia.cloud/embed-status/light-sm" name="statusPage" width="230" height="61" frameBorder="0"
|
|
56
|
+
scrolling="no">
|
|
57
|
+
</iframe>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
<div id="sidebar-container" [class.open-sidebar]="isSidebarOpen">
|
|
62
|
+
<div id="sticky-header">
|
|
63
|
+
<img class="logo-full" height="40px" src="https://imagineshared.blob.core.windows.net/portal/retalia_files/logos/sidebar_logo.png" (click)="goToPortal()"
|
|
64
|
+
data-testid="nav-logo" />
|
|
65
|
+
<div class="module-divider"></div>
|
|
66
|
+
@if (panelButtonStates.isModuleOpen) {
|
|
67
|
+
<div class="moduleSearchbar">
|
|
68
|
+
<input class="moduleSearchInput" type="search" autocomplete="off" id="search" [value]="moduleSearchValue"
|
|
69
|
+
required="false" [placeholder]="moduleSearchPlaceholder" (keyup)="handleModuleSearch($event)"
|
|
70
|
+
(click)="handleModuleSearch($event)" />
|
|
71
|
+
</div>
|
|
72
|
+
}
|
|
73
|
+
</div>
|
|
74
|
+
@if (panelButtonStates.isModuleOpen) {
|
|
75
|
+
<div id="menu">
|
|
76
|
+
<sub-item [items]="modules"></sub-item>
|
|
77
|
+
</div>
|
|
78
|
+
}
|
|
79
|
+
@if (panelButtonStates.isSupportOpen) {
|
|
80
|
+
<div id="menu">
|
|
81
|
+
<sub-item [items]="supportRoutes"></sub-item>
|
|
82
|
+
</div>
|
|
83
|
+
}
|
|
84
|
+
</div>
|
|
85
|
+
|
|
86
|
+
<shop-modal [availableShops]="availableShops" (selectedShop)="selectedShop($event)"></shop-modal>
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
@import "../../styles/app.scss";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
#sidebar-panel {
|
|
6
|
+
z-index: 1;
|
|
7
|
+
position: fixed;
|
|
8
|
+
float: left;
|
|
9
|
+
width: 60px;
|
|
10
|
+
height: 100vh;
|
|
11
|
+
color: black;
|
|
12
|
+
text-align: center;
|
|
13
|
+
transition: 0.2s linear;
|
|
14
|
+
background-color: rgba(#ffffff, 1);
|
|
15
|
+
-webkit-box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2);
|
|
16
|
+
-moz-box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2);
|
|
17
|
+
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2);
|
|
18
|
+
@include responsive(mobileonly) {
|
|
19
|
+
height: 100%;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.panel-item {
|
|
24
|
+
cursor: pointer;
|
|
25
|
+
position: relative;
|
|
26
|
+
height: 40px;
|
|
27
|
+
margin: 10px;
|
|
28
|
+
transition: 0.2s linear;
|
|
29
|
+
border-radius: 50%;
|
|
30
|
+
|
|
31
|
+
&:hover {
|
|
32
|
+
background-color: imagine-color(nav-inactive-text-color);
|
|
33
|
+
|
|
34
|
+
.panel-icon {
|
|
35
|
+
fill: white;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&:active,
|
|
40
|
+
&:focus {
|
|
41
|
+
background: rgba(imagine-color(nav-active-text-color), 0.2);
|
|
42
|
+
|
|
43
|
+
.panel-icon {
|
|
44
|
+
fill: imagine-color(nav-active-text-color);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.panel-icon {
|
|
49
|
+
margin: 0;
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: 50%;
|
|
52
|
+
left: 50%;
|
|
53
|
+
-ms-transform: translate(-50%, -50%);
|
|
54
|
+
transform: translate(-50%, -50%);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.collapsed-module-icons {
|
|
59
|
+
margin-top: 8px;
|
|
60
|
+
max-height: calc(100vh - 170px);
|
|
61
|
+
overflow-y: auto;
|
|
62
|
+
overflow-x: hidden;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.collapsed-module-icon {
|
|
66
|
+
width: 40px;
|
|
67
|
+
height: 40px;
|
|
68
|
+
margin: 10px;
|
|
69
|
+
display: flex;
|
|
70
|
+
align-items: center;
|
|
71
|
+
justify-content: center;
|
|
72
|
+
border-radius: 50%;
|
|
73
|
+
|
|
74
|
+
img {
|
|
75
|
+
width: 20px;
|
|
76
|
+
height: 20px;
|
|
77
|
+
object-fit: contain;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
#sidebar-container {
|
|
82
|
+
position: sticky;
|
|
83
|
+
top: 0; /* Sticky requires top/left */
|
|
84
|
+
height: 100vh; /* Set height by vh not % to fill viewport, handles sticky better */
|
|
85
|
+
overflow: hidden;
|
|
86
|
+
font-size: 12px;
|
|
87
|
+
font-family: "Chakra Petch", Arial, sans-serif;
|
|
88
|
+
width: 0px;
|
|
89
|
+
background: rgba(#ffffff, 1);
|
|
90
|
+
padding-left: 60px;
|
|
91
|
+
transition: 0.3s;
|
|
92
|
+
transition-timing-function: cubic-bezier(0.11, 0.95, 0.91, 0.93);
|
|
93
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
94
|
+
scrollbar-width: none; /* Firefox */
|
|
95
|
+
|
|
96
|
+
-webkit-box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2);
|
|
97
|
+
-moz-box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2);
|
|
98
|
+
box-shadow: 0px 0px 4px 0px rgba(0, 0, 0, 0.2);
|
|
99
|
+
@include responsive(mobileonly) {
|
|
100
|
+
top: auto;
|
|
101
|
+
position: relative;
|
|
102
|
+
border-right: 0px;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
.open-sidebar {
|
|
107
|
+
width: 260px !important;
|
|
108
|
+
@include responsive(mobileonly) {
|
|
109
|
+
width: 160px !important;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
@media print {
|
|
114
|
+
#container {
|
|
115
|
+
display: none;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.module-divider {
|
|
120
|
+
width: 240px;
|
|
121
|
+
margin: 10px;
|
|
122
|
+
border-top: 0.2px solid rgba(grey, 0.2);
|
|
123
|
+
-webkit-background-clip: padding-box; /* for Safari */
|
|
124
|
+
background-clip: padding-box; /* for IE9+, Firefox 4+, Opera, Chrome */
|
|
125
|
+
@include responsive(mobileonly) {
|
|
126
|
+
width: 240px !important;
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
div#menu {
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-flow: column;
|
|
133
|
+
background-color: transparent;
|
|
134
|
+
z-index: 10;
|
|
135
|
+
direction: ltr;
|
|
136
|
+
float: left;
|
|
137
|
+
width: 258px;
|
|
138
|
+
height: 85%;
|
|
139
|
+
overflow-y: overlay;
|
|
140
|
+
overflow-x: hidden;
|
|
141
|
+
transition: 0.2s linear;
|
|
142
|
+
@include responsive(mobileonly) {
|
|
143
|
+
width: 160px !important;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.moduleSearchbar {
|
|
148
|
+
z-index: 20;
|
|
149
|
+
position: inherit;
|
|
150
|
+
cursor: pointer;
|
|
151
|
+
width: 240px;
|
|
152
|
+
height: 28px;
|
|
153
|
+
border-radius: 4px;
|
|
154
|
+
margin: 10px;
|
|
155
|
+
background: rgba(#e2e2e2, 1);
|
|
156
|
+
@include responsive(mobileonly) {
|
|
157
|
+
width: 140px !important;
|
|
158
|
+
height: 40px;
|
|
159
|
+
}
|
|
160
|
+
.moduleSearchInput {
|
|
161
|
+
direction: ltr;
|
|
162
|
+
width: inherit;
|
|
163
|
+
height: inherit;
|
|
164
|
+
padding-left: 10px;
|
|
165
|
+
color: imagine-color(nav-active-text-color);
|
|
166
|
+
font-family: "Chakra Petch", Arial, sans-serif;
|
|
167
|
+
|
|
168
|
+
background-color: transparent;
|
|
169
|
+
border-style: none;
|
|
170
|
+
outline: none;
|
|
171
|
+
appearance: none;
|
|
172
|
+
-webkit-appearance: none; /* safari */
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
input:invalid {
|
|
176
|
+
box-shadow: none; /* prevent Mozilla Firefox from creating a red border */
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
::placeholder {
|
|
180
|
+
color: imagine-color(nav-inactive-text-color);
|
|
181
|
+
/* text-transform: uppercase; */
|
|
182
|
+
font-size: 11px;
|
|
183
|
+
opacity: 1;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
#sticky-header {
|
|
188
|
+
margin-top: 10px;
|
|
189
|
+
width: 100%;
|
|
190
|
+
text-align: center;
|
|
191
|
+
position: sticky;
|
|
192
|
+
transition: 1s ease;
|
|
193
|
+
|
|
194
|
+
.logo-full {
|
|
195
|
+
cursor: pointer;
|
|
196
|
+
padding: 5px 21px 0px 21px;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
.status-button {
|
|
201
|
+
cursor: pointer;
|
|
202
|
+
position: inherit;
|
|
203
|
+
bottom: 0;
|
|
204
|
+
margin-left: 8px;
|
|
205
|
+
margin-bottom: 15px;
|
|
206
|
+
width: 40px;
|
|
207
|
+
height: 32px;
|
|
208
|
+
padding-top: 8px;
|
|
209
|
+
border-radius: 50%;
|
|
210
|
+
transition: 0.2s linear;
|
|
211
|
+
.panel-icon {
|
|
212
|
+
fill: #0c1830;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
&:hover {
|
|
216
|
+
background-color: imagine-color(nav-active-text-color);
|
|
217
|
+
|
|
218
|
+
.panel-icon {
|
|
219
|
+
fill: #ffffff;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
#status-frame {
|
|
225
|
+
position: inherit;
|
|
226
|
+
bottom: -8px;
|
|
227
|
+
padding-left: 25px;
|
|
228
|
+
transition: 0.2s linear;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
.isOpen {
|
|
232
|
+
opacity: 1;
|
|
233
|
+
visibility: visible;
|
|
234
|
+
}
|
|
235
|
+
.isClosed {
|
|
236
|
+
opacity: 0;
|
|
237
|
+
visibility: hidden;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
::-webkit-scrollbar {
|
|
241
|
+
width: 5px; /* remove scrollbar space */
|
|
242
|
+
background: transparent;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
::-webkit-scrollbar-thumb {
|
|
246
|
+
background-color: rgba(imagine-color(nav-active-text-color), 0.3);
|
|
247
|
+
border-radius: 10px;
|
|
248
|
+
transition: 0.2s linear;
|
|
249
|
+
|
|
250
|
+
&:hover {
|
|
251
|
+
background-color: rgba(imagine-color(nav-active-text-color), 0.9);
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
input[type="search"]::-webkit-search-decoration,
|
|
256
|
+
input[type="search"]::-webkit-search-cancel-button,
|
|
257
|
+
input[type="search"]::-webkit-search-results-button,
|
|
258
|
+
input[type="search"]::-webkit-search-results-decoration {
|
|
259
|
+
-webkit-appearance: none;
|
|
260
|
+
}
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ChangeDetectorRef,
|
|
3
|
+
Component,
|
|
4
|
+
EventEmitter,
|
|
5
|
+
Input,
|
|
6
|
+
OnChanges,
|
|
7
|
+
OnDestroy,
|
|
8
|
+
Output,
|
|
9
|
+
SimpleChanges,
|
|
10
|
+
} from '@angular/core';
|
|
11
|
+
import { ModuleItem, Shop, SidebarEntry } from '../models/module';
|
|
12
|
+
import { SubItemService } from '../services/sub-item.service';
|
|
13
|
+
import { NgxSmartModalService } from 'ngx-smart-modal';
|
|
14
|
+
import { ModuleService } from '../services/module.service';
|
|
15
|
+
import { Environment } from '../models/environment';
|
|
16
|
+
import { supportRoutes } from '../data/support-routes';
|
|
17
|
+
import { CookieNames } from '../models/cookie-names';
|
|
18
|
+
import { CookieService } from '../services/cookie.service';
|
|
19
|
+
|
|
20
|
+
@Component({
|
|
21
|
+
selector: 'sidebar',
|
|
22
|
+
templateUrl: './sidebar.component.html',
|
|
23
|
+
styleUrls: ['./sidebar.component.scss'],
|
|
24
|
+
standalone: false
|
|
25
|
+
})
|
|
26
|
+
export class SidebarComponent implements OnChanges, OnDestroy {
|
|
27
|
+
private moduleRetryInterval: any;
|
|
28
|
+
private moduleFetchInProgress = false;
|
|
29
|
+
|
|
30
|
+
ngOnInit(): void {
|
|
31
|
+
this.tryFetchModulesUntilReady();
|
|
32
|
+
}
|
|
33
|
+
@Output() selectedRoute: EventEmitter<SidebarEntry> = new EventEmitter();
|
|
34
|
+
@Input() environment: Environment;
|
|
35
|
+
@Input() moduleSearchValue: any = '';
|
|
36
|
+
modules: ModuleItem[] = [];
|
|
37
|
+
modulesCopy: ModuleItem[] = [];
|
|
38
|
+
supportRoutes: ModuleItem[] = supportRoutes;
|
|
39
|
+
selectedModule: ModuleItem;
|
|
40
|
+
selectedItem;
|
|
41
|
+
availableShops: Shop[] = [];
|
|
42
|
+
availableShopsCopy: Shop[] = [];
|
|
43
|
+
moduleSearchPlaceholder = 'Search Modules ...';
|
|
44
|
+
isSidebarOpen: boolean = this.getSidebarState();
|
|
45
|
+
hideStatus: boolean = true;
|
|
46
|
+
panelButtonStates = {
|
|
47
|
+
isModuleOpen: this.isSidebarOpen,
|
|
48
|
+
isSupportOpen: false,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
constructor(
|
|
52
|
+
private cdr: ChangeDetectorRef,
|
|
53
|
+
private moduleService: ModuleService,
|
|
54
|
+
private subItemService: SubItemService,
|
|
55
|
+
private cookieService: CookieService,
|
|
56
|
+
public ngxSmartModalService: NgxSmartModalService
|
|
57
|
+
) {
|
|
58
|
+
this.subItemService.subItemClickEvent.subscribe((item) => {
|
|
59
|
+
this.subItemClicked(item);
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
ngOnChanges(changes: SimpleChanges): void {
|
|
64
|
+
if (changes['environment'] && changes['environment'].currentValue.apiRequestUrl) {
|
|
65
|
+
this.panelButtonStates.isModuleOpen = this.isSidebarOpen;
|
|
66
|
+
this.tryFetchModulesUntilReady();
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
ngOnDestroy(): void {
|
|
71
|
+
if (this.moduleRetryInterval) {
|
|
72
|
+
clearInterval(this.moduleRetryInterval);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
private tryFetchModulesUntilReady(): void {
|
|
77
|
+
if (this.moduleRetryInterval) {
|
|
78
|
+
clearInterval(this.moduleRetryInterval);
|
|
79
|
+
}
|
|
80
|
+
const tryFetch = () => {
|
|
81
|
+
if (
|
|
82
|
+
this.environment &&
|
|
83
|
+
this.environment.apiRequestUrl &&
|
|
84
|
+
this.modules.length === 0 &&
|
|
85
|
+
!this.moduleFetchInProgress
|
|
86
|
+
) {
|
|
87
|
+
this.getModules(true);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
tryFetch();
|
|
91
|
+
this.moduleRetryInterval = setInterval(tryFetch, 500);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
public toggleSidebar(e: Event, option: string): void {
|
|
95
|
+
e.stopPropagation();
|
|
96
|
+
// Allows us to expand the panel items in future without needing to change the toggle logic
|
|
97
|
+
for (let item in Object(this.panelButtonStates)) {
|
|
98
|
+
item === option
|
|
99
|
+
? (this.panelButtonStates[item] = !this.panelButtonStates[item])
|
|
100
|
+
: (this.panelButtonStates[item] = false);
|
|
101
|
+
}
|
|
102
|
+
this.isSidebarOpen = this.panelButtonStates[option];
|
|
103
|
+
this.setSidebarState();
|
|
104
|
+
|
|
105
|
+
if (this.modules.length === 0) {
|
|
106
|
+
this.tryFetchModulesUntilReady();
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
public setSidebarState(): void {
|
|
111
|
+
this.cookieService.setCookie(CookieNames.isSidebarOpen, this.isSidebarOpen);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
public getSidebarState(): boolean {
|
|
115
|
+
const cookieValue = this.cookieService.getCookie(
|
|
116
|
+
CookieNames.isSidebarOpen
|
|
117
|
+
);
|
|
118
|
+
//If the cookie doesn't exist, default to "open" so modules load immediately.
|
|
119
|
+
if (typeof cookieValue === 'undefined' || cookieValue === null) return true;
|
|
120
|
+
return cookieValue === 'true';
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
public goToPortal(): void {
|
|
124
|
+
window.location.href = this.environment.portalUrl;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
public handleModuleSearch(e): void {
|
|
128
|
+
if (this.modulesCopy.length < 1) {
|
|
129
|
+
this.modulesCopy = [...this.modules];
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
this.moduleSearchValue = e && e.target ? e.target.value : '';
|
|
133
|
+
const searchString = this.moduleSearchValue.toLowerCase();
|
|
134
|
+
|
|
135
|
+
const moduleCopy = JSON.parse(JSON.stringify(this.modulesCopy));
|
|
136
|
+
this.modules = this.filterModules(moduleCopy, searchString);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public filterModules(
|
|
140
|
+
moduleItems: ModuleItem[] | SidebarEntry[],
|
|
141
|
+
searchTerm: string
|
|
142
|
+
): any[] {
|
|
143
|
+
const matches = [];
|
|
144
|
+
if (!Array.isArray(this.modules)) return matches;
|
|
145
|
+
|
|
146
|
+
moduleItems.forEach((i) => {
|
|
147
|
+
if (i.name.toLowerCase().includes(searchTerm)) {
|
|
148
|
+
i.visible = true;
|
|
149
|
+
matches.push(i);
|
|
150
|
+
} else {
|
|
151
|
+
const childResults: SidebarEntry[] = this.filterModules(
|
|
152
|
+
i.children,
|
|
153
|
+
searchTerm
|
|
154
|
+
);
|
|
155
|
+
if (childResults.length) {
|
|
156
|
+
matches.push(Object.assign({}, i, { children: childResults }));
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
return matches;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
public subItemClicked(item): void {
|
|
165
|
+
this.selectedModule = this.modules.find(
|
|
166
|
+
(m) =>
|
|
167
|
+
m.authorizationId ===
|
|
168
|
+
(item.authorizationId || item.moduleAuthorizationId)
|
|
169
|
+
);
|
|
170
|
+
|
|
171
|
+
if (this.selectedItem) this.selectedItem.active = false;
|
|
172
|
+
this.selectedItem = item;
|
|
173
|
+
this.selectedItem.active = true;
|
|
174
|
+
|
|
175
|
+
if (this.selectedItem.relationName === 'Documentation') {
|
|
176
|
+
window.open(this.selectedItem.url, '_blank', 'noopener noreferrer');
|
|
177
|
+
} else if (
|
|
178
|
+
(this.selectedModule && !this.selectedModule.entityAccess) ||
|
|
179
|
+
!this.selectedModule.entityAccess.length
|
|
180
|
+
) {
|
|
181
|
+
this.routeToUrl();
|
|
182
|
+
} else if (
|
|
183
|
+
this.selectedModule &&
|
|
184
|
+
this.selectedModule.entityAccess.length === 1
|
|
185
|
+
) {
|
|
186
|
+
const soleShop = this.selectedModule.entityAccess[0];
|
|
187
|
+
this.subItemService.saveItemInfo(this.selectedModule, soleShop);
|
|
188
|
+
this.routeToUrl();
|
|
189
|
+
} else {
|
|
190
|
+
this.mapShopModal();
|
|
191
|
+
this.ngxSmartModalService.getModal('shopModal').open();
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
public selectedShop(selectedShop: Shop): void {
|
|
196
|
+
this.subItemService.saveItemInfo(this.selectedModule, selectedShop.id);
|
|
197
|
+
this.routeToUrl();
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
public mapShopModal(): void {
|
|
201
|
+
if (this.availableShopsCopy.length < 1) {
|
|
202
|
+
this.availableShopsCopy = [...this.availableShops];
|
|
203
|
+
}
|
|
204
|
+
this.availableShops = this.availableShopsCopy.filter((shop) =>
|
|
205
|
+
this.selectedModule.entityAccess.includes(shop.id)
|
|
206
|
+
);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
public goToStatusPage(): void {
|
|
210
|
+
window.open(
|
|
211
|
+
'https://status.retalia.cloud',
|
|
212
|
+
'_blank',
|
|
213
|
+
'noopener noreferrer'
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
public routeToUrl(): void {
|
|
218
|
+
let currentModule = this.moduleService.getCurrentModule(this.selectedItem);
|
|
219
|
+
if (
|
|
220
|
+
currentModule &&
|
|
221
|
+
this.selectedItem &&
|
|
222
|
+
(currentModule.authorizationId === this.selectedItem.authorizationId ||
|
|
223
|
+
currentModule.authorizationId === this.selectedItem.moduleAuthorizationId)
|
|
224
|
+
) {
|
|
225
|
+
let currentItem = JSON.parse(JSON.stringify(this.selectedItem));
|
|
226
|
+
const pathArray = this.selectedItem.url.split('/');
|
|
227
|
+
pathArray.splice(0, 2);
|
|
228
|
+
currentItem.url = pathArray.join('/');
|
|
229
|
+
this.selectedRoute.emit(currentItem);
|
|
230
|
+
} else {
|
|
231
|
+
const itemUrl = this.selectedItem.url;
|
|
232
|
+
window.location.href = itemUrl;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
private getModules(isFirstCall: boolean): void {
|
|
237
|
+
this.moduleFetchInProgress = true;
|
|
238
|
+
let apiUrl = this.environment.apiRequestUrl;
|
|
239
|
+
if (apiUrl.endsWith("/"))
|
|
240
|
+
apiUrl = apiUrl.slice(0, -1);
|
|
241
|
+
|
|
242
|
+
this.moduleService.getUserModules(apiUrl, '').then((moduleObject) => {
|
|
243
|
+
if (!moduleObject || !moduleObject.modulesDetails) {
|
|
244
|
+
if (!isFirstCall) {
|
|
245
|
+
console.log(`No modules were found using: ${apiUrl}`);
|
|
246
|
+
}
|
|
247
|
+
this.moduleFetchInProgress = false;
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
this.availableShops = moduleObject.shops;
|
|
252
|
+
this.modules = this.moduleService.mapModuleItems(
|
|
253
|
+
moduleObject.modulesDetails
|
|
254
|
+
);
|
|
255
|
+
this.selectedItem = this.moduleService.findNestedUrlMatch(this.modules,window.location.pathname);
|
|
256
|
+
this.panelButtonStates.isModuleOpen = this.isSidebarOpen;
|
|
257
|
+
this.moduleFetchInProgress = false;
|
|
258
|
+
if (this.moduleRetryInterval) {
|
|
259
|
+
clearInterval(this.moduleRetryInterval);
|
|
260
|
+
this.moduleRetryInterval = null;
|
|
261
|
+
}
|
|
262
|
+
this.cdr.detectChanges();
|
|
263
|
+
}).catch(() => {
|
|
264
|
+
this.moduleFetchInProgress = false;
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@for (item of items; track item; let i = $index) {
|
|
2
|
+
<div
|
|
3
|
+
[attr.data-testid]="'nav-' + (item.authorizationId || item.name)"
|
|
4
|
+
[class]="this.getClass(item, items)" (click)="subItemClicked($event, item)">
|
|
5
|
+
@if (item.visible) {
|
|
6
|
+
<div class="item-label">
|
|
7
|
+
@if (item.icon && item.authorizationId) {
|
|
8
|
+
<img [src]="item.icon" class="item-icon" alt="" />
|
|
9
|
+
}
|
|
10
|
+
{{ item.translatedName || item.name }}
|
|
11
|
+
</div>
|
|
12
|
+
}
|
|
13
|
+
@if (item.children) {
|
|
14
|
+
<sub-item [items]="item.children">
|
|
15
|
+
</sub-item>
|
|
16
|
+
}
|
|
17
|
+
</div>
|
|
18
|
+
}
|