@@ -19,13 +19,15 @@ import { css, html, LitElement } from 'lit';
1919import { customElement , property , state } from 'lit/decorators.js' ;
2020import { Router , RouterLocation } from '@vaadin/router' ;
2121import { getRootPath } from '../common/util' ;
22+ import { IS_EMBEDDED } from '../common/constants' ;
2223
2324/**
2425 * Represents a part of the breadcrumb navigation
2526 */
2627interface BreadcrumbPart {
2728 path : string ;
2829 name : string ;
30+ icon ?: string ;
2931}
3032
3133/**
@@ -42,7 +44,31 @@ export class BreadcrumbNav extends LitElement {
4244 align-items: center;
4345 gap: 8px;
4446 margin-bottom: 16px;
45- width: fit-content;
47+ width: 100%;
48+ justify-content: space-between;
49+ }
50+
51+ .breadcrumb-container {
52+ display: flex;
53+ align-items: center;
54+ gap: 8px;
55+ }
56+
57+ .realm-badge {
58+ background-color: var(--or-app-color4);
59+ color: white;
60+ padding: 4px 12px;
61+ border-radius: 16px;
62+ font-size: 12px;
63+ font-weight: 500;
64+ text-transform: uppercase;
65+ letter-spacing: 0.5px;
66+ margin-left: auto;
67+ min-width: 60px;
68+ text-align: center;
69+ display: flex;
70+ align-items: center;
71+ justify-content: center;
4672 }
4773
4874 a {
@@ -53,7 +79,7 @@ export class BreadcrumbNav extends LitElement {
5379 gap: 4px;
5480 --or-icon-width: 16px;
5581 --or-icon-height: 16px;
56- max-width: 200px ;
82+ max-width: 300px ;
5783 }
5884
5985 a:hover {
@@ -63,7 +89,7 @@ export class BreadcrumbNav extends LitElement {
6389 span[aria-current='page'] {
6490 color: rgba(0, 0, 0, 0.87);
6591 font-weight: 500;
66- max-width: 200px ;
92+ max-width: 300px ;
6793 overflow: hidden;
6894 text-overflow: ellipsis;
6995 white-space: nowrap;
@@ -86,26 +112,17 @@ export class BreadcrumbNav extends LitElement {
86112
87113 protected readonly rootPath = getRootPath ( ) ;
88114
89- protected get HOME_LINK ( ) : BreadcrumbPart {
90- return {
91- path : `${ this . rootPath } /${ this . realm } /configs` ,
92- name : 'ML Forecast Service'
93- } ;
94- }
95-
96- protected readonly MAX_TEXT_LENGTH = 20 ;
115+ protected readonly MAX_TEXT_LENGTH = 40 ;
97116
98117 willUpdate ( changedProperties : Map < string , any > ) {
99118 if ( changedProperties . has ( 'realm' ) && this . realm ) {
100- // Trigger location change event
101119 const location : Partial < RouterLocation > = {
102120 pathname : `${ this . rootPath } /${ this . realm } /configs` ,
103121 params : {
104122 realm : this . realm
105123 }
106124 } ;
107125
108- // Update the breadcrumbs and title
109126 this . updateBreadcrumbs ( location as RouterLocation ) ;
110127 }
111128 }
@@ -115,7 +132,6 @@ export class BreadcrumbNav extends LitElement {
115132 */
116133 protected readonly handleLocationChange = ( event : CustomEvent < { location : RouterLocation } > ) => {
117134 const location = event . detail . location ;
118- // Update the breadcrumbs and title
119135 this . updateBreadcrumbs ( location ) ;
120136 } ;
121137
@@ -136,28 +152,45 @@ export class BreadcrumbNav extends LitElement {
136152 const parts : BreadcrumbPart [ ] = [ ] ;
137153 const { pathname, params } = location ;
138154
139- // Add Smartcity part (realm)
140- if ( this . realm ) {
141- parts . push ( {
142- path : `${ this . rootPath } /${ this . realm } /configs` ,
143- name : this . realm . charAt ( 0 ) . toUpperCase ( ) + this . realm . slice ( 1 )
144- } ) ;
155+
156+ const homePart = {
157+ path : `${ this . rootPath } /${ this . realm } /configs` ,
158+ name : 'ML Forecast Service' ,
159+ icon : 'puzzle'
160+ } ;
161+
162+ // If we are not embedded, add the home part
163+ if ( ! IS_EMBEDDED ) {
164+ parts . push ( homePart ) ;
145165 }
146166
167+ const configsPart = {
168+ path : `${ this . rootPath } /${ this . realm } /configs` ,
169+ name : 'Configurations'
170+ } ;
171+
147172 // Add Configs part
148173 if ( pathname . includes ( '/configs' ) ) {
149- parts . push ( {
150- path : `${ this . rootPath } /${ this . realm } /configs` ,
151- name : 'Configs'
152- } ) ;
174+ parts . push ( configsPart ) ;
153175
154- // Add specific config part if we're on a config page
155- if ( params . id ) {
176+ // Handle config editor page
177+ const isExistingConfig = params . id && ! pathname . includes ( '/new' ) ;
178+ if ( isExistingConfig ) {
156179 parts . push ( {
157180 path : `${ this . rootPath } /${ this . realm } /configs/${ params . id } ` ,
158- name : params . id === 'new' ? 'New Config' : `${ params . id } `
181+ name : `${ params . id } `
159182 } ) ;
160183 }
184+
185+ const isNewConfig = pathname . includes ( '/new' ) ;
186+ if ( isNewConfig ) {
187+ parts . push ( {
188+ path : `${ this . rootPath } /${ this . realm } /configs/new` ,
189+ name : 'New'
190+ } ) ;
191+ }
192+
193+
161194 }
162195
163196 this . parts = parts ;
@@ -173,15 +206,18 @@ export class BreadcrumbNav extends LitElement {
173206 /**
174207 * Renders a single breadcrumb item
175208 */
176- protected renderBreadcrumbItem ( part : BreadcrumbPart , readonly : boolean ) {
209+ protected renderBreadcrumbItem ( part : BreadcrumbPart , readonly : boolean , isFirst : boolean ) {
177210 const truncatedName = this . truncateText ( part . name ) ;
178211
212+ const icon = part . icon ? html `< or-icon icon =${ part . icon } > </ or-icon > ` : html `` ;
213+
179214 return html `
180- < span aria-hidden ="true "> ></ span >
215+ ${ ! isFirst ? html ` < span aria-hidden ="true "> ></ span > ` : html `` }
181216 ${ readonly
182217 ? html `< span aria-current ="page "> ${ truncatedName } </ span > `
183218 : html `
184219 < a href ="${ part . path } " @click =${ ( e : MouseEvent ) => this . handleNavigation ( e , part . path ) } >
220+ ${ icon }
185221 < span class ="truncate "> ${ truncatedName } </ span >
186222 </ a >
187223 ` }
@@ -197,15 +233,20 @@ export class BreadcrumbNav extends LitElement {
197233 }
198234
199235 render ( ) {
200- const truncatedHomeName = this . truncateText ( this . HOME_LINK . name ) ;
236+ // Hide breadcrumbs if there's only one part
237+ const shouldShowBreadcrumbs = this . parts . length > 1 ;
238+ if ( ! shouldShowBreadcrumbs ) {
239+ return html `` ;
240+ }
241+
242+ const realmBadge = IS_EMBEDDED ? html `` : html `< div class ="realm-badge "> ${ this . realm } </ div > ` ;
201243
202244 return html `
203245 < nav aria-label ="breadcrumb ">
204- < a href ="${ this . HOME_LINK . path } " @click =${ ( e : MouseEvent ) => this . handleNavigation ( e , this . HOME_LINK . path ) } >
205- < or-icon icon ="puzzle "> </ or-icon >
206- < span class ="truncate "> ${ truncatedHomeName } </ span >
207- </ a >
208- ${ this . parts . map ( ( part , index ) => this . renderBreadcrumbItem ( part , index === this . parts . length - 1 ) ) }
246+ < div class ="breadcrumb-container ">
247+ ${ this . parts . map ( ( part , index ) => this . renderBreadcrumbItem ( part , index === this . parts . length - 1 , index === 0 ) ) }
248+ </ div >
249+ ${ realmBadge }
209250 </ nav >
210251 ` ;
211252 }
0 commit comments