@@ -7,11 +7,14 @@ class AssetBrowserV2 {
77 this . urlState = this . readUrlState ( ) ;
88 this . goBack = this . goBack . bind ( this ) ;
99 this . openSvgAssetStudioV2 = this . openSvgAssetStudioV2 . bind ( this ) ;
10+ this . addAssetEntry = this . addAssetEntry . bind ( this ) ;
11+ this . currentSessionContext = null ;
1012 this . handleNavigationState = this . handleNavigationState . bind ( this ) ;
1113 window . addEventListener ( "popstate" , this . handleNavigationState ) ;
1214 window . addEventListener ( "pageshow" , this . handleNavigationState ) ;
1315 document . getElementById ( "assetBrowserV2BackButton" ) . addEventListener ( "click" , this . goBack ) ;
1416 document . getElementById ( "assetBrowserV2OpenSvgAssetStudioV2Button" ) . addEventListener ( "click" , this . openSvgAssetStudioV2 ) ;
17+ document . getElementById ( "assetManagerV2AddButton" ) . addEventListener ( "click" , this . addAssetEntry ) ;
1518 this . renderNavigation ( ) ;
1619 this . registerSnapshotHook ( ) ;
1720 this . readSession ( ) ;
@@ -116,6 +119,97 @@ class AssetBrowserV2 {
116119 window . __v2RuntimeSnapshot = ( ) => this . buildRuntimeSnapshot ( ) ;
117120 }
118121
122+ cloneSessionValue ( value ) {
123+ return JSON . parse ( JSON . stringify ( value ) ) ;
124+ }
125+
126+ setActionStatus ( message ) {
127+ document . getElementById ( "assetManagerV2ActionStatus" ) . textContent = message ;
128+ }
129+
130+ normalizedAssetEntryFromForm ( ) {
131+ const id = typeof document . getElementById ( "assetManagerV2AddId" ) . value === "string" ? document . getElementById ( "assetManagerV2AddId" ) . value . trim ( ) : "" ;
132+ const label = typeof document . getElementById ( "assetManagerV2AddLabel" ) . value === "string" ? document . getElementById ( "assetManagerV2AddLabel" ) . value . trim ( ) : "" ;
133+ const kind = typeof document . getElementById ( "assetManagerV2AddKind" ) . value === "string" ? document . getElementById ( "assetManagerV2AddKind" ) . value . trim ( ) : "" ;
134+ const path = typeof document . getElementById ( "assetManagerV2AddPath" ) . value === "string" ? document . getElementById ( "assetManagerV2AddPath" ) . value . trim ( ) : "" ;
135+ if ( ! id || ! label || ! kind || ! path ) {
136+ return { ok : false , message : "Add blocked. id, label, kind, and path are required." , entry : null } ;
137+ }
138+ return { ok : true , message : "" , entry : { id, label, kind, path } } ;
139+ }
140+
141+ clearAddAssetForm ( ) {
142+ document . getElementById ( "assetManagerV2AddId" ) . value = "" ;
143+ document . getElementById ( "assetManagerV2AddLabel" ) . value = "" ;
144+ document . getElementById ( "assetManagerV2AddKind" ) . value = "" ;
145+ document . getElementById ( "assetManagerV2AddPath" ) . value = "" ;
146+ }
147+
148+ addAssetEntry ( ) {
149+ if ( ! this . currentSessionContext || typeof this . currentSessionContext !== "object" || Array . isArray ( this . currentSessionContext ) ) {
150+ this . setActionStatus ( "Add blocked. No valid Asset Manager V2 session is loaded." ) ;
151+ return ;
152+ }
153+ if ( ! this . currentSessionContext . payloadJson || typeof this . currentSessionContext . payloadJson !== "object" || Array . isArray ( this . currentSessionContext . payloadJson ) ) {
154+ this . setActionStatus ( "Add blocked. payloadJson is missing." ) ;
155+ return ;
156+ }
157+ if ( ! this . currentSessionContext . payloadJson . assetCatalog || typeof this . currentSessionContext . payloadJson . assetCatalog !== "object" || Array . isArray ( this . currentSessionContext . payloadJson . assetCatalog ) ) {
158+ this . setActionStatus ( "Add blocked. payloadJson.assetCatalog is missing." ) ;
159+ return ;
160+ }
161+ if ( ! Array . isArray ( this . currentSessionContext . payloadJson . assetCatalog . entries ) ) {
162+ this . setActionStatus ( "Add blocked. payloadJson.assetCatalog.entries must be an array." ) ;
163+ return ;
164+ }
165+ const newEntry = this . normalizedAssetEntryFromForm ( ) ;
166+ if ( ! newEntry . ok ) {
167+ this . setActionStatus ( newEntry . message ) ;
168+ return ;
169+ }
170+ if ( this . currentSessionContext . payloadJson . assetCatalog . entries . some ( ( entry ) => entry && typeof entry === "object" && ! Array . isArray ( entry ) && typeof entry . id === "string" && entry . id . trim ( ) === newEntry . entry . id ) ) {
171+ this . setActionStatus ( `Add blocked. Asset id '${ newEntry . entry . id } ' already exists.` ) ;
172+ return ;
173+ }
174+ const nextSessionContext = this . cloneSessionValue ( this . currentSessionContext ) ;
175+ nextSessionContext . payloadJson . assetCatalog . entries . push ( newEntry . entry ) ;
176+ this . loadContract ( nextSessionContext ) ;
177+ this . clearAddAssetForm ( ) ;
178+ this . setActionStatus ( `Asset '${ newEntry . entry . id } ' added.` ) ;
179+ }
180+
181+ removeAssetEntryById ( assetId ) {
182+ if ( ! this . currentSessionContext || typeof this . currentSessionContext !== "object" || Array . isArray ( this . currentSessionContext ) ) {
183+ this . setActionStatus ( "Remove blocked. No valid Asset Manager V2 session is loaded." ) ;
184+ return ;
185+ }
186+ if ( ! this . currentSessionContext . payloadJson || typeof this . currentSessionContext . payloadJson !== "object" || Array . isArray ( this . currentSessionContext . payloadJson ) ) {
187+ this . setActionStatus ( "Remove blocked. payloadJson is missing." ) ;
188+ return ;
189+ }
190+ if ( ! this . currentSessionContext . payloadJson . assetCatalog || typeof this . currentSessionContext . payloadJson . assetCatalog !== "object" || Array . isArray ( this . currentSessionContext . payloadJson . assetCatalog ) ) {
191+ this . setActionStatus ( "Remove blocked. payloadJson.assetCatalog is missing." ) ;
192+ return ;
193+ }
194+ if ( ! Array . isArray ( this . currentSessionContext . payloadJson . assetCatalog . entries ) ) {
195+ this . setActionStatus ( "Remove blocked. payloadJson.assetCatalog.entries must be an array." ) ;
196+ return ;
197+ }
198+ if ( typeof assetId !== "string" || ! assetId . trim ( ) ) {
199+ this . setActionStatus ( "Remove blocked. Asset id is required." ) ;
200+ return ;
201+ }
202+ const nextSessionContext = this . cloneSessionValue ( this . currentSessionContext ) ;
203+ const startLength = nextSessionContext . payloadJson . assetCatalog . entries . length ;
204+ nextSessionContext . payloadJson . assetCatalog . entries = nextSessionContext . payloadJson . assetCatalog . entries . filter ( ( entry ) => ! entry || typeof entry !== "object" || Array . isArray ( entry ) || typeof entry . id !== "string" || entry . id . trim ( ) !== assetId . trim ( ) ) ;
205+ if ( nextSessionContext . payloadJson . assetCatalog . entries . length === startLength ) {
206+ this . setActionStatus ( `Remove blocked. Asset id '${ assetId . trim ( ) } ' was not found.` ) ;
207+ return ;
208+ }
209+ this . loadContract ( nextSessionContext ) ;
210+ this . setActionStatus ( `Asset '${ assetId . trim ( ) } ' removed.` ) ;
211+ }
212+
119213 logStructuredError ( type , message , details ) {
120214 console . error ( {
121215 tool : "asset-manager-v2" ,
@@ -270,16 +364,21 @@ class AssetBrowserV2 {
270364 }
271365 document . getElementById ( "assetBrowserV2InvalidState" ) . hidden = true ;
272366 document . getElementById ( "assetBrowserV2ValidState" ) . hidden = false ;
367+ this . currentSessionContext = this . cloneSessionValue ( sessionContext ) ;
273368
274369 document . getElementById ( "assetBrowserV2List" ) . replaceChildren ( ) ;
275370 assetCatalog . entries . forEach ( ( entry ) => {
371+ const assetRow = document . createElement ( "div" ) ;
276372 const assetItem = document . createElement ( "button" ) ;
277373 const assetName = document . createElement ( "strong" ) ;
278374 const assetMeta = document . createElement ( "div" ) ;
375+ const removeButton = document . createElement ( "button" ) ;
279376 assetItem . type = "button" ;
377+ removeButton . type = "button" ;
280378 assetName . textContent = entry . label . trim ( ) ;
281379 assetMeta . textContent = `${ entry . kind . trim ( ) } | ${ entry . path . trim ( ) } ` ;
282380 assetItem . append ( assetName , assetMeta ) ;
381+ removeButton . textContent = `Remove ${ entry . id . trim ( ) } ` ;
283382 assetItem . addEventListener ( "click" , ( ) => {
284383 document . getElementById ( "assetBrowserV2Preview" ) . textContent = JSON . stringify (
285384 {
@@ -292,7 +391,11 @@ class AssetBrowserV2 {
292391 2
293392 ) ;
294393 } ) ;
295- document . getElementById ( "assetBrowserV2List" ) . appendChild ( assetItem ) ;
394+ removeButton . addEventListener ( "click" , ( ) => {
395+ this . removeAssetEntryById ( entry . id . trim ( ) ) ;
396+ } ) ;
397+ assetRow . append ( assetItem , removeButton ) ;
398+ document . getElementById ( "assetBrowserV2List" ) . appendChild ( assetRow ) ;
296399 } ) ;
297400
298401 document . getElementById ( "assetBrowserV2Preview" ) . textContent = assetCatalog . entries . length === 0
@@ -313,6 +416,8 @@ class AssetBrowserV2 {
313416 document . getElementById ( "assetBrowserV2ValidState" ) . hidden = true ;
314417 document . getElementById ( "assetBrowserV2List" ) . replaceChildren ( ) ;
315418 document . getElementById ( "assetBrowserV2Preview" ) . textContent = "" ;
419+ this . currentSessionContext = null ;
420+ this . setActionStatus ( "No asset action yet." ) ;
316421 }
317422
318423 renderError ( message ) {
@@ -328,6 +433,8 @@ class AssetBrowserV2 {
328433 document . getElementById ( "assetBrowserV2ValidState" ) . hidden = true ;
329434 document . getElementById ( "assetBrowserV2List" ) . replaceChildren ( ) ;
330435 document . getElementById ( "assetBrowserV2Preview" ) . textContent = "" ;
436+ this . currentSessionContext = null ;
437+ this . setActionStatus ( "No asset action yet." ) ;
331438 }
332439}
333440
0 commit comments