This is an automated email from the ASF dual-hosted git repository.

chenyulin0719 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/yunikorn-web.git


The following commit(s) were added to refs/heads/master by this push:
     new 21ebe5d  [YUNIKORN-2606] Modular sidebar with remote components (#198)
21ebe5d is described below

commit 21ebe5d9b1bbfc2e1eea8bbb8440d2a8bd38af4e
Author: Denis Coric <[email protected]>
AuthorDate: Tue Sep 24 15:02:07 2024 +0000

    [YUNIKORN-2606] Modular sidebar with remote components (#198)
    
    Implemented Module Federation for the Applications Drawer component
    
    Closes: #198
    
    Signed-off-by: Yu-Lin Chen <[email protected]>
---
 Makefile                                           |   4 +-
 angular.json                                       |  47 +++-
 package.json                                       |   7 +-
 pnpm-lock.yaml                                     | 310 +++++++++++++--------
 src/app/app.module.ts                              |   4 +
 .../allocations-drawer.component.html              |  94 +++++++
 .../allocations-drawer.component.scss}             | 130 ++-------
 .../allocations-drawer.component.spec.ts           | 113 ++++++++
 .../allocations-drawer.component.ts                | 133 +++++++++
 .../components/apps-view/apps-view.component.html  | 122 ++------
 .../components/apps-view/apps-view.component.scss  |  28 +-
 .../apps-view/apps-view.component.spec.ts          |  59 +++-
 .../components/apps-view/apps-view.component.ts    | 111 +++++---
 src/app/models/envconfig.model.ts                  |   2 +
 src/app/services/envconfig/envconfig.service.ts    |  15 +-
 src/app/testing/mocks.ts                           |   2 +
 src/assets/config/envconfig.json                   |   4 +-
 src/{main.ts => bootstrap.ts}                      |   0
 src/main.ts                                        |  14 +-
 tsconfig.app.json                                  |   3 +-
 tsconfig.json                                      |   3 +-
 webpack.config.js                                  |  37 +++
 webpack.prod.config.js                             |  19 ++
 23 files changed, 846 insertions(+), 415 deletions(-)

diff --git a/Makefile b/Makefile
index 8dbc072..dc84d88 100644
--- a/Makefile
+++ b/Makefile
@@ -195,9 +195,9 @@ OS := $(shell uname -s | tr '[:upper:]' '[:lower:]')
 license-check:
        @echo "checking license headers:"
 ifeq (darwin,$(OS))
-       $(shell mkdir -p "$(OUTPUT)" && find -E . -not \( -path './.git*' 
-prune \) -not \( -path ./coverage -prune \) -not \( -path ./node_modules 
-prune \) -not \( -path ./build -prune \) -not \( -path ./tools -prune \) -not 
-path ./pnpm-lock.yaml -regex ".*\.(go|sh|md|conf|yaml|yml|html|mod)" -exec 
grep -L "Licensed to the Apache Software Foundation" {} \; > 
"$(OUTPUT)/license-check.txt")
+       $(shell mkdir -p "$(OUTPUT)" && find -E . -not \( -path './.git*' 
-prune \) -not \( -path ./coverage -prune \) -not \( -path ./node_modules 
-prune \) -not \( -path ./build -prune \) -not \( -path ./tools -prune \) -not 
-path ./pnpm-lock.yaml  -not \( -path ./dist -prune \) -regex 
".*\.(go|sh|md|conf|yaml|yml|html|mod|js)" -exec grep -L "Licensed to the 
Apache Software Foundation" {} \; > "$(OUTPUT)/license-check.txt")
 else
-       $(shell mkdir -p "$(OUTPUT)" && find . -not \( -path './.git*' -prune 
\) -not \( -path ./coverage -prune \) -not \( -path ./node_modules -prune \) 
-not \( -path ./build -prune \) -not \( -path ./tools -prune \) -not -path 
./pnpm-lock.yaml -regex ".*\.\(go\|sh\|md\|conf\|yaml\|yml\|html\|mod\)" -exec 
grep -L "Licensed to the Apache Software Foundation" {} \; > 
"$(OUTPUT)/license-check.txt")
+       $(shell mkdir -p "$(OUTPUT)" && find . -not \( -path './.git*' -prune 
\) -not \( -path ./coverage -prune \) -not \( -path ./node_modules -prune \) 
-not \( -path ./build -prune \) -not \( -path ./tools -prune \) -not -path 
./pnpm-lock.yaml -not \( -path ./node_modules -prune \) -regex 
".*\.\(go\|sh\|md\|conf\|yaml\|yml\|html\|mod\|js\)" -exec grep -L "Licensed to 
the Apache Software Foundation" {} \; > "$(OUTPUT)/license-check.txt")
 endif
        @if [ -s "$(OUTPUT)/license-check.txt" ]; then \
                echo "following files are missing license header:" ; \
diff --git a/angular.json b/angular.json
index c3b4d83..cb77e20 100644
--- a/angular.json
+++ b/angular.json
@@ -22,7 +22,7 @@
       "prefix": "app",
       "architect": {
         "build": {
-          "builder": "@angular-devkit/build-angular:browser",
+          "builder": "ngx-build-plus:browser",
           "options": {
             "outputPath": "dist/yunikorn-web",
             "index": "src/index.html",
@@ -30,13 +30,23 @@
             "polyfills": "src/polyfills.ts",
             "tsConfig": "tsconfig.app.json",
             "inlineStyleLanguage": "scss",
-            "assets": ["src/favicon.ico", "src/assets", {"glob": "LICENSE", 
"input": "./", "output": "./"}],
+            "assets": [
+              "src/favicon.ico",
+              "src/assets",
+              {
+                "glob": "LICENSE",
+                "input": "./",
+                "output": "./"
+              }
+            ],
             "styles": [
               "src/styles.scss",
               "node_modules/@fontsource/roboto/index.css",
               "node_modules/@fortawesome/fontawesome-free/css/all.css"
             ],
-            "scripts": []
+            "scripts": [],
+            "extraWebpackConfig": "webpack.config.js",
+            "commonChunk": false
           },
           "configurations": {
             "production": {
@@ -58,7 +68,8 @@
                   "with": "src/environments/environment.prod.ts"
                 }
               ],
-              "outputHashing": "all"
+              "outputHashing": "all",
+              "extraWebpackConfig": "webpack.prod.config.js"
             },
             "development": {
               "buildOptimizer": false,
@@ -72,21 +83,28 @@
           "defaultConfiguration": "production"
         },
         "serve": {
-          "builder": "@angular-devkit/build-angular:dev-server",
+          "builder": "ngx-build-plus:dev-server",
           "configurations": {
             "production": {
-              "browserTarget": "yunikorn-web:build:production"
+              "browserTarget": "yunikorn-web:build:production",
+              "extraWebpackConfig": "webpack.prod.config.js"
             },
             "development": {
               "browserTarget": "yunikorn-web:build:development"
             }
           },
-          "defaultConfiguration": "development"
+          "defaultConfiguration": "development",
+          "options": {
+            "port": 4200,
+            "publicHost": "http://localhost:4200";,
+            "extraWebpackConfig": "webpack.config.js"
+          }
         },
         "extract-i18n": {
-          "builder": "@angular-devkit/build-angular:extract-i18n",
+          "builder": "ngx-build-plus:extract-i18n",
           "options": {
-            "browserTarget": "yunikorn-web:build"
+            "browserTarget": "yunikorn-web:build",
+            "extraWebpackConfig": "webpack.config.js"
           }
         },
         "test": {
@@ -97,12 +115,17 @@
             "tsConfig": "tsconfig.spec.json",
             "karmaConfig": "karma.conf.js",
             "inlineStyleLanguage": "scss",
-            "assets": ["src/favicon.ico", "src/assets"],
-            "styles": ["src/styles.scss"],
+            "assets": [
+              "src/favicon.ico",
+              "src/assets"
+            ],
+            "styles": [
+              "src/styles.scss"
+            ],
             "scripts": []
           }
         }
       }
     }
   }
-}
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index f2685ed..a77b7c0 100644
--- a/package.json
+++ b/package.json
@@ -13,7 +13,8 @@
     "build:prod": "ng build --configuration production",
     "start:srv": "json-server --watch json-db.json",
     "test:coverage": "ng test --code-coverage 
--karma-config=./karma.conf.ci.js",
-    "prettify": "prettier --config ./.prettierrc --write 
'src/**/*.{js,ts,json,css,scss,md,html}'"
+    "prettify": "prettier --config ./.prettierrc --write 
'src/**/*.{js,ts,json,css,scss,md,html}'",
+    "run:all": "node 
node_modules/@angular-architects/module-federation/src/server/mf-dev-server.js"
   },
   "private": true,
   "husky": {
@@ -28,6 +29,7 @@
     ]
   },
   "dependencies": {
+    "@angular-architects/module-federation": "^16.0.4",
     "@angular/animations": "^16.2.10",
     "@angular/cdk": "^16.2.9",
     "@angular/common": "^16.2.10",
@@ -81,6 +83,7 @@
     "karma-super-dots-reporter": "^0.2.0",
     "lint-staged": "^15.0.2",
     "ng-mocks": "^14.11.0",
+    "ngx-build-plus": "^16.0.0",
     "prettier": "^3.0.3",
     "puppeteer": "^22.2.0",
     "typescript": "5.1.6"
@@ -90,4 +93,4 @@
     "pnpm": "9"
   },
   "packageManager": "pnpm@9"
-}
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 9184524..360360f 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -8,36 +8,39 @@ importers:
 
   .:
     dependencies:
+      '@angular-architects/module-federation':
+        specifier: ^16.0.4
+        version: 
16.0.4(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular
 [...]
       '@angular/animations':
         specifier: ^16.2.10
-        version: 16.2.10(@angular/[email protected])
+        version: 16.2.10(@angular/[email protected]([email protected])([email protected]))
       '@angular/cdk':
         specifier: ^16.2.9
-        version: 
16.2.9(@angular/[email protected])(@angular/[email protected])([email protected])
+        version: 
16.2.9(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/common':
         specifier: ^16.2.10
-        version: 16.2.10(@angular/[email protected])([email protected])
+        version: 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/compiler':
         specifier: ^16.2.10
-        version: 16.2.10(@angular/[email protected])
+        version: 16.2.10(@angular/[email protected]([email protected])([email protected]))
       '@angular/core':
         specifier: ^16.2.10
         version: 16.2.10([email protected])([email protected])
       '@angular/forms':
         specifier: ^16.2.10
-        version: 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])
+        version: 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])))([email protected])
       '@angular/material':
         specifier: ^16.2.9
-        version: 
16.2.9(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])
+        version: 16.2.9(kqpsfetbzlelvbukbleaduojjq)
       '@angular/platform-browser':
         specifier: ^16.2.10
-        version: 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+        version: 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))
       '@angular/platform-browser-dynamic':
         specifier: ^16.2.10
-        version: 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+        version: 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])))
       '@angular/router':
         specifier: ^16.2.10
-        version: 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])
+        version: 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])))([email protected])
       '@fontsource/roboto':
         specifier: ^5.0.12
         version: 5.0.12
@@ -97,7 +100,7 @@ importers:
         version: 2.29.4
       ngx-spinner:
         specifier: ^16.0.2
-        version: 
16.0.2(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+        version: 
16.0.2(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))
       rxjs:
         specifier: ~7.8.1
         version: 7.8.1
@@ -110,13 +113,13 @@ importers:
     devDependencies:
       '@angular-devkit/build-angular':
         specifier: ^16.2.7
-        version: 
16.2.7(@angular/[email protected])(@types/[email protected])([email protected])([email protected])
+        version: 
16.2.7(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected]))(@types/[email protected])([email protected])([email protected])
       '@angular/cli':
         specifier: ^16.2.7
-        version: 16.2.7
+        version: 16.2.7([email protected])
       '@angular/compiler-cli':
         specifier: ^16.2.10
-        version: 16.2.10(@angular/[email protected])([email protected])
+        version: 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected])
       '@types/jasmine':
         specifier: ~5.1.1
         version: 5.1.1
@@ -149,7 +152,7 @@ importers:
         version: 5.1.0([email protected])
       karma-jasmine-html-reporter:
         specifier: ~2.1.0
-        version: 2.1.0([email protected])([email protected])([email protected])
+        version: 
2.1.0([email protected])([email protected]([email protected]))([email protected])
       karma-spec-reporter:
         specifier: ^0.0.36
         version: 0.0.36([email protected])
@@ -161,13 +164,16 @@ importers:
         version: 15.0.2
       ng-mocks:
         specifier: ^14.11.0
-        version: 
14.11.0(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+        version: 
14.11.0(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected](rxjs@7
 [...]
+      ngx-build-plus:
+        specifier: ^16.0.0
+        version: 
16.0.0(@angular-devkit/[email protected](@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected]))(@types/[email protected])([email protected])([email protected]))([email protected])([email protected])
       prettier:
         specifier: ^3.0.3
         version: 3.0.3
       puppeteer:
         specifier: ^22.2.0
-        version: 22.2.0([email protected])
+        version: 22.2.0([email protected])([email protected])
       typescript:
         specifier: 5.1.6
         version: 5.1.6
@@ -178,6 +184,21 @@ packages:
     resolution: {integrity: 
sha512-lFMjJTrFL3j7L9yBxwYfCq2k6qqwHyzuUl/XBnif78PWTJYyL/dfowQHWE3sp6U6ZzqWiiIZnpTMO96zhkjwtg==}
     engines: {node: '>=6.0.0'}
 
+  '@angular-architects/[email protected]':
+    resolution: {integrity: 
sha512-1qbS109+6Rq41wt0jp8w/to/zn3xY4IhvWlqhaMphZSD6bOZ0s/+MXdVo7p0iljA/lpNFAMVbYvarEpl6bSsjQ==}
+    peerDependencies:
+      '@angular/common': '>=16.0.0'
+      '@angular/core': '>=16.0.0'
+      '@angular/platform-browser-dynamic': '>=16.0.0'
+
+  '@angular-architects/[email protected]':
+    resolution: {integrity: 
sha512-RQmHe7JqkPE4OAmNOxSKgFlGBoxi7Cy9THsbo5Leas8XQ3M2W3q2lBQF0woRNjMj575NaSQ84S7Tq8WvH+KGhw==}
+    peerDependencies:
+      '@angular/common': '>=16.0.0'
+      '@angular/core': '>=16.0.0'
+      '@angular/platform-browser-dynamic': '>=16.0.0'
+      rxjs: '>=6.6.3'
+
   '@angular-devkit/[email protected]':
     resolution: {integrity: 
sha512-r6+z4jRE+e9VNeTmJCGz5VI5azRagOqE4SIDqaywz75eHOJ9UPSo9MHy8zFw1eLt1WcvCDqk+Pk9+krh2E+B8Q==}
     engines: {node: ^16.14.0 || >=18.10.0, npm: ^6.11.0 || ^7.5.6 || >=8.0.0, 
yarn: '>= 1.13.0'}
@@ -1986,6 +2007,9 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-0vdNRFXn5q+dtOqjfFtmtlI9N2eVZ7LMyEV2iKC5mEEFvSg/69Ml6b/WU2qF8W1nLRa0wiSrDT3Y5jOHZCwKPQ==}
+
   [email protected]:
     resolution: {integrity: 
sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==}
     engines: {node: '>=6'}
@@ -3570,6 +3594,12 @@ packages:
       '@angular/forms': 5.0.0-alpha - 5 || 6.0.0-alpha - 6 || 7.0.0-alpha - 7 
|| 8.0.0-alpha - 8 || 9.0.0-alpha - 9 || 10.0.0-alpha - 10 || 11.0.0-alpha - 11 
|| 12.0.0-alpha - 12 || 13.0.0-alpha - 13 || 14.0.0-alpha - 14 || 15.0.0-alpha 
- 15 || 16.0.0-alpha - 16
       '@angular/platform-browser': 5.0.0-alpha - 5 || 6.0.0-alpha - 6 || 
7.0.0-alpha - 7 || 8.0.0-alpha - 8 || 9.0.0-alpha - 9 || 10.0.0-alpha - 10 || 
11.0.0-alpha - 11 || 12.0.0-alpha - 12 || 13.0.0-alpha - 13 || 14.0.0-alpha - 
14 || 15.0.0-alpha - 15 || 16.0.0-alpha - 16
 
+  [email protected]:
+    resolution: {integrity: 
sha512-AXqBJoQGyptbHTK09yfuxS2Gm2+YnVCBnPWyORq79wbC2gdbkYLR34eLA5wi8HZbqWNXdaYdGc75MFAZmkho4Q==}
+    peerDependencies:
+      '@angular-devkit/build-angular': ^16.0.0
+      rxjs: '>= 6.0.0'
+
   [email protected]:
     resolution: {integrity: 
sha512-MZpOHb3dvSqD6xiEdR+EtOfPY2r1kfA7t5Hv5IVwi7gkbTwVgnqxDWdOYJ/HW1pSZ5iEGhqlJqWg6CysLmNfHQ==}
     peerDependencies:
@@ -4811,6 +4841,10 @@ packages:
   [email protected]:
     resolution: {integrity: 
sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==}
 
+  [email protected]:
+    resolution: {integrity: 
sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==}
+    engines: {node: '>=0.10.0'}
+
   [email protected]:
     resolution: {integrity: 
sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
     engines: {node: '>=10'}
@@ -4911,6 +4945,27 @@ snapshots:
       '@jridgewell/gen-mapping': 0.3.3
       '@jridgewell/trace-mapping': 0.3.18
 
+  
'@angular-architects/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@ang
 [...]
+    dependencies:
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
+      '@angular/core': 16.2.10([email protected])([email protected])
+      '@angular/platform-browser-dynamic': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](
 [...]
+      tslib: 2.6.2
+
+  
'@angular-architects/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/ani
 [...]
+    dependencies:
+      '@angular-architects/module-federation-runtime': 
16.0.4(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected]
 [...]
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
+      '@angular/core': 16.2.10([email protected])([email protected])
+      '@angular/platform-browser-dynamic': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](
 [...]
+      callsite: 1.0.0
+      node-fetch: 2.7.0([email protected])
+      rxjs: 7.8.1
+      semver: 7.6.0
+      word-wrap: 1.2.5
+    transitivePeerDependencies:
+      - encoding
+
   '@angular-devkit/[email protected]([email protected])':
     dependencies:
       '@angular-devkit/core': 16.2.7([email protected])
@@ -4918,13 +4973,13 @@ snapshots:
     transitivePeerDependencies:
       - chokidar
 
-  
'@angular-devkit/[email protected](@angular/[email protected])(@types/[email protected])([email protected])([email protected])':
+  
'@angular-devkit/[email protected](@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected]))(@types/[email protected])([email protected])([email protected])':
     dependencies:
       '@ampproject/remapping': 2.2.1
       '@angular-devkit/architect': 0.1602.7([email protected])
-      '@angular-devkit/build-webpack': 
0.1602.7([email protected])([email protected])([email protected])
+      '@angular-devkit/build-webpack': 
0.1602.7([email protected])([email protected]([email protected]([email protected])))([email protected]([email protected]))
       '@angular-devkit/core': 16.2.7([email protected])
-      '@angular/compiler-cli': 
16.2.10(@angular/[email protected])([email protected])
+      '@angular/compiler-cli': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected])
       '@babel/core': 7.22.9
       '@babel/generator': 7.22.9
       '@babel/helper-annotate-as-pure': 7.22.5
@@ -4936,31 +4991,30 @@ snapshots:
       '@babel/runtime': 7.22.6
       '@babel/template': 7.22.5
       '@discoveryjs/json-ext': 0.5.7
-      '@ngtools/webpack': 
16.2.7(@angular/[email protected])([email protected])([email protected])
-      '@vitejs/plugin-basic-ssl': 1.0.1([email protected])
+      '@ngtools/webpack': 
16.2.7(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected]))([email protected])([email protected]([email protected]))
+      '@vitejs/plugin-basic-ssl': 
1.0.1([email protected](@types/[email protected])([email protected])([email protected])([email protected]))
       ansi-colors: 4.1.3
       autoprefixer: 10.4.14([email protected])
-      babel-loader: 9.1.3(@babel/[email protected])([email protected])
+      babel-loader: 9.1.3(@babel/[email protected])([email protected]([email protected]))
       babel-plugin-istanbul: 6.1.1
       browserslist: 4.22.1
       chokidar: 3.5.3
-      copy-webpack-plugin: 11.0.0([email protected])
+      copy-webpack-plugin: 11.0.0([email protected]([email protected]))
       critters: 0.0.20
-      css-loader: 6.8.1([email protected])
+      css-loader: 6.8.1([email protected]([email protected]))
       esbuild-wasm: 0.18.17
       fast-glob: 3.3.1
       guess-parser: 0.4.22([email protected])
       https-proxy-agent: 5.0.1
       inquirer: 8.2.4
       jsonc-parser: 3.2.0
-      karma: 6.4.2
       karma-source-map-support: 1.4.0
       less: 4.1.3
-      less-loader: 11.1.0([email protected])([email protected])
-      license-webpack-plugin: 4.0.2([email protected])
+      less-loader: 11.1.0([email protected])([email protected]([email protected]))
+      license-webpack-plugin: 4.0.2([email protected]([email protected]))
       loader-utils: 3.2.1
       magic-string: 0.30.1
-      mini-css-extract-plugin: 2.7.6([email protected])
+      mini-css-extract-plugin: 2.7.6([email protected]([email protected]))
       mrmime: 1.0.1
       open: 8.4.2
       ora: 5.4.1
@@ -4968,13 +5022,13 @@ snapshots:
       picomatch: 2.3.1
       piscina: 4.0.0
       postcss: 8.4.31
-      postcss-loader: 7.3.3([email protected])([email protected])([email protected])
+      postcss-loader: 
7.3.3([email protected])([email protected])([email protected]([email protected]))
       resolve-url-loader: 5.0.0
       rxjs: 7.8.1
       sass: 1.64.1
-      sass-loader: 13.3.2([email protected])([email protected])
+      sass-loader: 13.3.2([email protected])([email protected]([email protected]))
       semver: 7.5.4
-      source-map-loader: 4.0.1([email protected])
+      source-map-loader: 4.0.1([email protected]([email protected]))
       source-map-support: 0.5.21
       terser: 5.19.2
       text-table: 0.2.0
@@ -4983,12 +5037,13 @@ snapshots:
       typescript: 5.1.6
       vite: 4.4.7(@types/[email protected])([email protected])([email protected])([email protected])
       webpack: 5.88.2([email protected])
-      webpack-dev-middleware: 6.1.1([email protected])
-      webpack-dev-server: 4.15.1([email protected])
+      webpack-dev-middleware: 6.1.1([email protected]([email protected]))
+      webpack-dev-server: 4.15.1([email protected]([email protected]))
       webpack-merge: 5.9.0
-      webpack-subresource-integrity: 5.1.0([email protected])
+      webpack-subresource-integrity: 5.1.0([email protected]([email protected]))
     optionalDependencies:
       esbuild: 0.18.17
+      karma: 6.4.2
     transitivePeerDependencies:
       - '@swc/core'
       - '@types/node'
@@ -5007,12 +5062,12 @@ snapshots:
       - utf-8-validate
       - webpack-cli
 
-  
'@angular-devkit/[email protected]([email protected])([email protected])([email protected])':
+  
'@angular-devkit/[email protected]([email protected])([email protected]([email protected]([email protected])))([email protected]([email protected]))':
     dependencies:
       '@angular-devkit/architect': 0.1602.7([email protected])
       rxjs: 7.8.1
       webpack: 5.88.2([email protected])
-      webpack-dev-server: 4.15.1([email protected])
+      webpack-dev-server: 4.15.1([email protected]([email protected]))
     transitivePeerDependencies:
       - chokidar
 
@@ -5020,13 +5075,14 @@ snapshots:
     dependencies:
       ajv: 8.12.0
       ajv-formats: 2.1.1([email protected])
-      chokidar: 3.5.3
       jsonc-parser: 3.2.0
       picomatch: 2.3.1
       rxjs: 7.8.1
       source-map: 0.7.4
+    optionalDependencies:
+      chokidar: 3.5.3
 
-  '@angular-devkit/[email protected]':
+  '@angular-devkit/[email protected]([email protected])':
     dependencies:
       '@angular-devkit/core': 16.2.7([email protected])
       jsonc-parser: 3.2.0
@@ -5036,26 +5092,26 @@ snapshots:
     transitivePeerDependencies:
       - chokidar
 
-  '@angular/[email protected](@angular/[email protected])':
+  
'@angular/[email protected](@angular/[email protected]([email protected])([email protected]))':
     dependencies:
       '@angular/core': 16.2.10([email protected])([email protected])
       tslib: 2.6.2
 
-  
'@angular/[email protected](@angular/[email protected])(@angular/[email protected])([email protected])':
+  
'@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))([email protected])':
     dependencies:
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/core': 16.2.10([email protected])([email protected])
       rxjs: 7.8.1
       tslib: 2.6.2
     optionalDependencies:
       parse5: 7.1.2
 
-  '@angular/[email protected]':
+  '@angular/[email protected]([email protected])':
     dependencies:
       '@angular-devkit/architect': 0.1602.7([email protected])
       '@angular-devkit/core': 16.2.7([email protected])
-      '@angular-devkit/schematics': 16.2.7
-      '@schematics/angular': 16.2.7
+      '@angular-devkit/schematics': 16.2.7([email protected])
+      '@schematics/angular': 16.2.7([email protected])
       '@yarnpkg/lockfile': 1.1.0
       ansi-colors: 4.1.3
       ini: 4.1.1
@@ -5075,15 +5131,15 @@ snapshots:
       - chokidar
       - supports-color
 
-  '@angular/[email protected](@angular/[email protected])([email protected])':
+  
'@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected])':
     dependencies:
       '@angular/core': 16.2.10([email protected])([email protected])
       rxjs: 7.8.1
       tslib: 2.6.2
 
-  '@angular/[email protected](@angular/[email protected])([email protected])':
+  
'@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected])':
     dependencies:
-      '@angular/compiler': 16.2.10(@angular/[email protected])
+      '@angular/compiler': 
16.2.10(@angular/[email protected]([email protected])([email protected]))
       '@babel/core': 7.23.2
       '@jridgewell/sourcemap-codec': 1.4.15
       chokidar: 3.5.3
@@ -5096,10 +5152,11 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  '@angular/[email protected](@angular/[email protected])':
+  
'@angular/[email protected](@angular/[email protected]([email protected])([email protected]))':
     dependencies:
-      '@angular/core': 16.2.10([email protected])([email protected])
       tslib: 2.6.2
+    optionalDependencies:
+      '@angular/core': 16.2.10([email protected])([email protected])
 
   '@angular/[email protected]([email protected])([email protected])':
     dependencies:
@@ -5107,22 +5164,22 @@ snapshots:
       tslib: 2.6.2
       zone.js: 0.13.0
 
-  
'@angular/[email protected](@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])':
+  
'@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])))([email protected])':
     dependencies:
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/core': 16.2.10([email protected])([email protected])
-      '@angular/platform-browser': 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+      '@angular/platform-browser': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))
       rxjs: 7.8.1
       tslib: 2.6.2
 
-  
'@angular/[email protected](@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])':
+  '@angular/[email protected](kqpsfetbzlelvbukbleaduojjq)':
     dependencies:
-      '@angular/animations': 16.2.10(@angular/[email protected])
-      '@angular/cdk': 
16.2.9(@angular/[email protected])(@angular/[email protected])([email protected])
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
+      '@angular/animations': 
16.2.10(@angular/[email protected]([email protected])([email protected]))
+      '@angular/cdk': 
16.2.9(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))([email protected])
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/core': 16.2.10([email protected])([email protected])
-      '@angular/forms': 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])
-      '@angular/platform-browser': 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+      '@angular/forms': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])))([email protected])
+      '@angular/platform-browser': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))
       '@material/animation': 15.0.0-canary.bc9ae6c9c.0
       '@material/auto-init': 15.0.0-canary.bc9ae6c9c.0
       '@material/banner': 15.0.0-canary.bc9ae6c9c.0
@@ -5173,26 +5230,27 @@ snapshots:
       rxjs: 7.8.1
       tslib: 2.6.2
 
-  
'@angular/[email protected](@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])':
+  
'@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected](rxjs@7
 [...]
     dependencies:
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
-      '@angular/compiler': 16.2.10(@angular/[email protected])
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
+      '@angular/compiler': 
16.2.10(@angular/[email protected]([email protected])([email protected]))
       '@angular/core': 16.2.10([email protected])([email protected])
-      '@angular/platform-browser': 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+      '@angular/platform-browser': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))
       tslib: 2.6.2
 
-  
'@angular/[email protected](@angular/[email protected])(@angular/[email protected])(@angular/[email protected])':
+  
'@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))':
     dependencies:
-      '@angular/animations': 16.2.10(@angular/[email protected])
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/core': 16.2.10([email protected])([email protected])
       tslib: 2.6.2
+    optionalDependencies:
+      '@angular/animations': 
16.2.10(@angular/[email protected]([email protected])([email protected]))
 
-  
'@angular/[email protected](@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])':
+  
'@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])))([email protected])':
     dependencies:
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/core': 16.2.10([email protected])([email protected])
-      '@angular/platform-browser': 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+      '@angular/platform-browser': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))
       rxjs: 7.8.1
       tslib: 2.6.2
 
@@ -6709,9 +6767,9 @@ snapshots:
       '@material/theme': 15.0.0-canary.bc9ae6c9c.0
       tslib: 2.6.2
 
-  
'@ngtools/[email protected](@angular/[email protected])([email protected])([email protected])':
+  
'@ngtools/[email protected](@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected]))([email protected])([email protected]([email protected]))':
     dependencies:
-      '@angular/compiler-cli': 
16.2.10(@angular/[email protected])([email protected])
+      '@angular/compiler-cli': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected])
       typescript: 5.1.6
       webpack: 5.88.2([email protected])
 
@@ -6792,10 +6850,10 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  '@schematics/[email protected]':
+  '@schematics/[email protected]([email protected])':
     dependencies:
       '@angular-devkit/core': 16.2.7([email protected])
-      '@angular-devkit/schematics': 16.2.7
+      '@angular-devkit/schematics': 16.2.7([email protected])
       jsonc-parser: 3.2.0
     transitivePeerDependencies:
       - chokidar
@@ -6945,7 +7003,7 @@ snapshots:
       '@types/node': 20.8.7
     optional: true
 
-  '@vitejs/[email protected]([email protected])':
+  
'@vitejs/[email protected]([email protected](@types/[email protected])([email protected])([email protected])([email protected]))':
     dependencies:
       vite: 4.4.7(@types/[email protected])([email protected])([email protected])([email protected])
 
@@ -7099,7 +7157,7 @@ snapshots:
       indent-string: 4.0.0
 
   [email protected]([email protected]):
-    dependencies:
+    optionalDependencies:
       ajv: 8.12.0
 
   [email protected]([email protected]):
@@ -7201,7 +7259,7 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected](@babel/[email protected])([email protected]):
+  [email protected](@babel/[email protected])([email protected]([email protected])):
     dependencies:
       '@babel/core': 7.22.9
       find-cache-dir: 4.0.0
@@ -7410,6 +7468,8 @@ snapshots:
       function-bind: 1.1.1
       get-intrinsic: 1.2.1
 
+  [email protected]: {}
+
   [email protected]: {}
 
   [email protected]: {}
@@ -7604,7 +7664,7 @@ snapshots:
     dependencies:
       is-what: 3.14.1
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       fast-glob: 3.3.1
       glob-parent: 6.0.2
@@ -7631,6 +7691,7 @@ snapshots:
       js-yaml: 4.1.0
       parse-json: 5.2.0
       path-type: 4.0.0
+    optionalDependencies:
       typescript: 5.1.6
 
   [email protected]([email protected]):
@@ -7639,6 +7700,7 @@ snapshots:
       import-fresh: 3.3.0
       js-yaml: 4.1.0
       parse-json: 5.2.0
+    optionalDependencies:
       typescript: 5.1.6
 
   [email protected]:
@@ -7651,9 +7713,9 @@ snapshots:
       postcss: 8.4.31
       pretty-bytes: 5.6.0
 
-  [email protected]:
+  [email protected]([email protected]):
     dependencies:
-      node-fetch: 2.7.0
+      node-fetch: 2.7.0([email protected])
     transitivePeerDependencies:
       - encoding
 
@@ -7663,7 +7725,7 @@ snapshots:
       shebang-command: 2.0.0
       which: 2.0.2
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       icss-utils: 5.1.0([email protected])
       postcss: 8.4.31
@@ -7944,6 +8006,7 @@ snapshots:
       '@esbuild/win32-arm64': 0.18.17
       '@esbuild/win32-ia32': 0.18.17
       '@esbuild/win32-x64': 0.18.17
+    optional: true
 
   [email protected]:
     optionalDependencies:
@@ -8421,12 +8484,13 @@ snapshots:
 
   [email protected](@types/[email protected]):
     dependencies:
-      '@types/express': 4.17.17
       '@types/http-proxy': 1.17.8
       http-proxy: 1.18.1
       is-glob: 4.0.3
       is-plain-obj: 3.0.0
       micromatch: 4.0.5
+    optionalDependencies:
+      '@types/express': 4.17.17
     transitivePeerDependencies:
       - debug
 
@@ -8784,7 +8848,7 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  
[email protected]([email protected])([email protected])([email protected]):
+  
[email protected]([email protected])([email protected]([email protected]))([email protected]):
     dependencies:
       jasmine-core: 5.1.1
       karma: 6.4.2
@@ -8851,7 +8915,7 @@ snapshots:
       picocolors: 1.0.0
       shell-quote: 1.8.1
 
-  [email protected]([email protected])([email protected]):
+  [email protected]([email protected])([email protected]([email protected])):
     dependencies:
       klona: 2.0.6
       less: 4.1.3
@@ -8873,10 +8937,11 @@ snapshots:
     transitivePeerDependencies:
       - supports-color
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
-      webpack: 5.88.2([email protected])
       webpack-sources: 3.2.3
+    optionalDependencies:
+      webpack: 5.88.2([email protected])
 
   [email protected]: {}
 
@@ -9076,7 +9141,7 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       schema-utils: 4.0.0
       webpack: 5.88.2([email protected])
@@ -9199,17 +9264,26 @@ snapshots:
 
   [email protected]: {}
 
-  
[email protected](@angular/[email protected])(@angular/[email protected])(@angular/[email protected])(@angular/[email protected]):
+  
[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])(
 [...]
     dependencies:
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/core': 16.2.10([email protected])([email protected])
-      '@angular/forms': 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])([email protected])
-      '@angular/platform-browser': 
16.2.10(@angular/[email protected])(@angular/[email protected])(@angular/[email protected])
+      '@angular/forms': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])))([email protected])
+      '@angular/platform-browser': 
16.2.10(@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected]))
 
-  
[email protected](@angular/[email protected])(@angular/[email protected])(@angular/[email protected]):
+  
[email protected](@angular-devkit/[email protected](@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected]))(@types/[email protected])([email protected])([email protected]))([email protected])([email protected]):
     dependencies:
-      '@angular/animations': 16.2.10(@angular/[email protected])
-      '@angular/common': 16.2.10(@angular/[email protected])([email protected])
+      '@angular-devkit/build-angular': 
16.2.7(@angular/[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))([email protected]))(@types/[email protected])([email protected])([email protected])
+      '@schematics/angular': 16.2.7([email protected])
+      rxjs: 7.8.1
+      webpack-merge: 5.9.0
+    transitivePeerDependencies:
+      - chokidar
+
+  
[email protected](@angular/[email protected](@angular/[email protected]([email protected])([email protected])))(@angular/[email protected](@angular/[email protected]([email protected])([email protected]))([email protected]))(@angular/[email protected]([email protected])([email protected])):
+    dependencies:
+      '@angular/animations': 
16.2.10(@angular/[email protected]([email protected])([email protected]))
+      '@angular/common': 
16.2.10(@angular/[email protected]([email protected])([email protected]))([email protected])
       '@angular/core': 16.2.10([email protected])([email protected])
       tslib: 2.6.2
 
@@ -9222,9 +9296,11 @@ snapshots:
   [email protected]:
     optional: true
 
-  [email protected]:
+  [email protected]([email protected]):
     dependencies:
       whatwg-url: 5.0.0
+    optionalDependencies:
+      encoding: 0.1.13
 
   [email protected]: {}
 
@@ -9533,7 +9609,7 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected]([email protected])([email protected])([email protected]):
+  
[email protected]([email protected])([email protected])([email protected]([email protected])):
     dependencies:
       cosmiconfig: 8.3.6([email protected])
       jiti: 1.20.0
@@ -9626,11 +9702,11 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected]:
+  [email protected]([email protected]):
     dependencies:
       '@puppeteer/browsers': 2.1.0
       chromium-bidi: 0.5.9([email protected])
-      cross-fetch: 4.0.0
+      cross-fetch: 4.0.0([email protected])
       debug: 4.3.4
       devtools-protocol: 0.0.1249869
       ws: 8.16.0
@@ -9640,11 +9716,11 @@ snapshots:
       - supports-color
       - utf-8-validate
 
-  [email protected]([email protected]):
+  [email protected]([email protected])([email protected]):
     dependencies:
       '@puppeteer/browsers': 2.1.0
       cosmiconfig: 9.0.0([email protected])
-      puppeteer-core: 22.2.0
+      puppeteer-core: 22.2.0([email protected])
     transitivePeerDependencies:
       - bufferutil
       - encoding
@@ -9819,11 +9895,12 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected]([email protected])([email protected]):
+  [email protected]([email protected])([email protected]([email protected])):
     dependencies:
       neo-async: 2.6.2
-      sass: 1.64.1
       webpack: 5.88.2([email protected])
+    optionalDependencies:
+      sass: 1.64.1
 
   [email protected]:
     dependencies:
@@ -10013,7 +10090,7 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       abab: 2.0.6
       iconv-lite: 0.6.3
@@ -10186,15 +10263,16 @@ snapshots:
       mkdirp: 1.0.4
       yallist: 4.0.0
 
-  [email protected]([email protected])([email protected]):
+  
[email protected]([email protected])([email protected]([email protected])):
     dependencies:
       '@jridgewell/trace-mapping': 0.3.18
-      esbuild: 0.18.17
       jest-worker: 27.5.1
       schema-utils: 3.3.0
       serialize-javascript: 6.0.1
       terser: 5.19.2
       webpack: 5.88.2([email protected])
+    optionalDependencies:
+      esbuild: 0.18.17
 
   [email protected]:
     dependencies:
@@ -10351,15 +10429,15 @@ snapshots:
 
   [email protected](@types/[email protected])([email protected])([email protected])([email protected]):
     dependencies:
-      '@types/node': 20.8.7
       esbuild: 0.18.20
-      less: 4.1.3
       postcss: 8.4.31
       rollup: 3.29.4
-      sass: 1.64.1
-      terser: 5.19.2
     optionalDependencies:
+      '@types/node': 20.8.7
       fsevents: 2.3.2
+      less: 4.1.3
+      sass: 1.64.1
+      terser: 5.19.2
 
   [email protected]: {}
 
@@ -10390,7 +10468,7 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       colorette: 2.0.20
       memfs: 3.5.1
@@ -10399,16 +10477,17 @@ snapshots:
       schema-utils: 4.0.0
       webpack: 5.88.2([email protected])
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       colorette: 2.0.20
       memfs: 3.5.1
       mime-types: 2.1.35
       range-parser: 1.2.1
       schema-utils: 4.0.0
+    optionalDependencies:
       webpack: 5.88.2([email protected])
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       '@types/bonjour': 3.5.10
       '@types/connect-history-api-fallback': 1.3.5
@@ -10438,9 +10517,10 @@ snapshots:
       serve-index: 1.9.1
       sockjs: 0.3.24
       spdy: 4.0.2
-      webpack: 5.88.2([email protected])
-      webpack-dev-middleware: 5.3.4([email protected])
+      webpack-dev-middleware: 5.3.4([email protected]([email protected]))
       ws: 8.16.0
+    optionalDependencies:
+      webpack: 5.88.2([email protected])
     transitivePeerDependencies:
       - bufferutil
       - debug
@@ -10454,7 +10534,7 @@ snapshots:
 
   [email protected]: {}
 
-  [email protected]([email protected]):
+  [email protected]([email protected]([email protected])):
     dependencies:
       typed-assert: 1.0.9
       webpack: 5.88.2([email protected])
@@ -10482,7 +10562,7 @@ snapshots:
       neo-async: 2.6.2
       schema-utils: 3.3.0
       tapable: 2.2.1
-      terser-webpack-plugin: 5.3.8([email protected])([email protected])
+      terser-webpack-plugin: 
5.3.8([email protected])([email protected]([email protected]))
       watchpack: 2.4.0
       webpack-sources: 3.2.3
     transitivePeerDependencies:
@@ -10533,6 +10613,8 @@ snapshots:
 
   [email protected]: {}
 
+  [email protected]: {}
+
   [email protected]:
     dependencies:
       ansi-styles: 4.3.0
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index 413394b..8fcac29 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -63,6 +63,8 @@ import { HealthchecksComponent } from 
'@app/components/healthchecks/healthchecks
 import { AppNodeUtilizationsComponent } from 
'@app/components/app-node-utilizations/app-node-utilizations.component';
 import { VerticalBarChartComponent } from 
'@app/components/vertical-bar-chart/vertical-bar-chart.component';
 import { LicensesModalComponent } from 
'@app/components/licenses-modal/licenses-modal.component';
+import { AllocationsDrawerComponent } from 
'@app/components/allocations-drawer/allocations-drawer.component';
+import { MatChipsModule } from '@angular/material/chips';
 
 @NgModule({
   declarations: [
@@ -85,6 +87,7 @@ import { LicensesModalComponent } from 
'@app/components/licenses-modal/licenses-
     AppNodeUtilizationsComponent,
     VerticalBarChartComponent,
     LicensesModalComponent,
+    AllocationsDrawerComponent,
   ],
   imports: [
     BrowserModule,
@@ -111,6 +114,7 @@ import { LicensesModalComponent } from 
'@app/components/licenses-modal/licenses-
     MatExpansionModule,
     MatIconModule,
     MatDialogModule,
+    MatChipsModule,
   ],
   providers: [
     {
diff --git 
a/src/app/components/allocations-drawer/allocations-drawer.component.html 
b/src/app/components/allocations-drawer/allocations-drawer.component.html
new file mode 100644
index 0000000..b0b6629
--- /dev/null
+++ b/src/app/components/allocations-drawer/allocations-drawer.component.html
@@ -0,0 +1,94 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ -->
+
+<mat-drawer-container class="flex-primary" [hasBackdrop]="false">
+  <mat-drawer #matDrawer mode="over" position="end">
+    <mat-drawer-content>
+      <div class="header">
+        <span>{{ selectedRow?.applicationId }} ({{ 
selectedRow?.allocations?.length }} allocations)</span>
+        <span class="far fa-clipboard copy-btn" (click)="copyLinkToClipboard()"
+          matTooltip="Click to copy the URL to this view" 
matTooltipShowDelay="500"></span>
+        <span class="far fa-solid fa-xmark close-btn" 
(click)="closeDrawer()"></span>
+      </div>
+      <div class="content">
+
+        <mat-table [dataSource]="allocDataSource" matSort #allocSort="matSort">
+          <ng-container [matColumnDef]="columnDef.colId" *ngFor="let columnDef 
of allocColumnDef">
+            <mat-header-cell *matHeaderCellDef mat-sort-header 
[style.flex]="columnDef?.colWidth || 1">{{
+              columnDef.colName }}</mat-header-cell>
+
+            <ng-container *ngIf="columnDef.colId === 'priority'; else 
renderNext_3">
+              <mat-cell class="small" *matCellDef="let element" 
[style.flex]="columnDef?.colWidth || 1"
+                [title]="element[columnDef.colId]">{{
+                element['priority'] }} </mat-cell>
+            </ng-container>
+
+            <ng-container *ngIf="columnDef.colId === 'resource'; else 
renderNext_3">
+              <mat-cell *matCellDef="let element" class="allocations-data" 
[style.flex]="columnDef?.colWidth || 1"
+                matTooltip="
+                          {{element[columnDef.colId]}}" 
matTooltipShowDelay="500">
+                <ng-container *ngIf="columnDef.colFormatter; else 
showAllocRowData;">
+                  <ng-container 
*ngIf="columnDef.colFormatter(element[columnDef.colId]) as colValue">
+                    <ul class="mat-res-ul">
+                      <ng-container *ngFor="let resource of 
formatResources(colValue); let i = index">
+                        <li class="mat-res-li" *ngIf="i<1">
+                          {{ resource }}
+                        </li>
+                        <li class="mat-res-li" *ngIf="i>=1 && 
element['expanded']">
+                          {{ resource }}
+                        </li>
+                      </ng-container>
+                    </ul>
+                  </ng-container>
+                </ng-container>
+                <ng-template #showAllocRowData>
+                  <span>{{ element[columnDef.colId] }}</span>
+                </ng-template>
+              </mat-cell>
+            </ng-container>
+
+            <ng-template #renderNext_3>
+              <mat-cell *matCellDef="let element" [class]="element['expanded'] 
? '' : 'ellipsis'"
+                [style.flex]="columnDef?.colWidth || 1" 
matTooltip="{{element[columnDef.colId]}}"
+                matTooltipShowDelay="500">{{ element[columnDef.colId] || 'n/a'
+                }}</mat-cell>
+            </ng-template>
+          </ng-container>
+
+          <ng-container matColumnDef="noRecord">
+            <mat-footer-cell *matFooterCellDef>
+              <div class="no-record">No records found</div>
+            </mat-footer-cell>
+          </ng-container>
+
+          <mat-header-row *matHeaderRowDef="allocColumnIds"></mat-header-row>
+
+          <mat-row *matRowDef="let row; columns: allocColumnIds; let i = 
index" (click)="allocationsDetailToggle(i)"
+            [ngClass]="{'even-row': i % 2 === 0, 'row': true}"></mat-row>
+
+          <mat-footer-row *matFooterRowDef="['noRecord']"
+            [ngStyle]="{ display: isAllocDataSourceEmpty() ? '' : 'none' 
}"></mat-footer-row>
+        </mat-table>
+
+        <mat-paginator #allocationMatPaginator [pageSizeOptions]="[10, 20, 50, 
100]" [pageSize]="50"
+          [ngStyle]="{ display: isAllocDataSourceEmpty() ? 'none' : '' }" 
showFirstLastButtons></mat-paginator>
+
+      </div>
+    </mat-drawer-content>
+  </mat-drawer>
+</mat-drawer-container>
\ No newline at end of file
diff --git a/src/app/components/apps-view/apps-view.component.scss 
b/src/app/components/allocations-drawer/allocations-drawer.component.scss
similarity index 61%
copy from src/app/components/apps-view/apps-view.component.scss
copy to src/app/components/allocations-drawer/allocations-drawer.component.scss
index f88e974..604b73b 100644
--- a/src/app/components/apps-view/apps-view.component.scss
+++ b/src/app/components/allocations-drawer/allocations-drawer.component.scss
@@ -15,89 +15,28 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-@import '~material-design-icons/iconfont/material-icons.css';
-
- .top-section {
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: row;
-  justify-content: space-between;
-  align-items: center;
-  .left-side{
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    .dropdown-wrapper {
-      padding-right: 40px;
-      .dropdown-label {
-        color: #333;
-        font-size: 1.2em;
-        margin-right: 10px;
-      }
-    }
-  }
-  .right-side{
-    display: flex;
-    flex-direction: row;
-    align-items: center;
-    .btn-wrapper {
-      filter: drop-shadow(0px 2px 1px rgba(90, 90, 90, 0.5));
-      &:hover{
-        filter: drop-shadow(0px 3px 3px rgba(90, 90, 90, 0.5));
-      }
-      :hover{
-        cursor: pointer;
-      }
-      .btn{
-        display: block;
-        border: none;
-        padding: 13px 24px;
-        border-radius: 5px;
-        font-size: 24px;
-        transform: translateY(-13px);
-      }
-      .material-icons{
-        transform: translateY(2px);
-      }
-    }
-    .search-wrapper {
-      width: 300px;
-      right: 20px;
-      padding-right: 20px;
-      input {
-        width: calc(100% - 22px);
-        color: #333;
-      }
-      .clear-btn {
-        outline: none;
-        border: none;
-        padding: 0 0 0 4px;
-        cursor: pointer;
-        background: transparent;
-        i {
-          font-size: 18px;
-          &:hover {
-            color: #f44336;
-          }
-        }
-      }
-      .search-icon {
-        margin-left: 4px;
-        font-size: 17px;
-      }
+ 
+.mat-drawer-container {
+  min-width: 430px;
+  width: 55%;
+  height: calc(100vh - 60px);
+  background: transparent;
+  pointer-events: none;
+  position: absolute;
+  right: 0;
+  bottom: 0;
+  .mat-drawer {
+    pointer-events: auto;
+    width: 100%;
+    .content {
+      padding: 0 10px;
     }
   }
-}
 
-.mdc-button .mdc-button__label{
-  display: flex;
-  align-items: center;
-}
+  .full-row-height {
+    border: 1px solid red;
+  }
 
-.apps-view {
-  width: 100%;
-  height: 100%;
   .mat-mdc-header-cell {
     font-size: 15px;
     font-weight: bold;
@@ -148,38 +87,7 @@
     font-size: 18px;
     margin-left: 10px;
   }
-  .app-allocations {
-    margin-top: 40px;
-    .mat-mdc-table {
-      margin-top: 20px;
-    }
-  }
-  .no-record {
-    font-size: 14px;
-    font-weight: bold;
-    color: #666;
-    width: 100%;
-    text-align: center;
-  }
-}
-
 
-.mat-drawer-container {
-  min-width: 430px;
-  width: 55%;
-  height: calc(100vh - 60px);
-  background: transparent;
-  pointer-events: none;
-  position: absolute;
-  right: 0;
-  bottom: 0;
-  .mat-drawer {
-    pointer-events: auto;
-    width: 100%;
-    .content {
-      padding: 0 10px;
-    }
-  }
   .close-btn {
     float: right;
     font-size: 1.2em;
@@ -243,4 +151,4 @@
   .row {
     min-height: unset;
   }
-}
+}
\ No newline at end of file
diff --git 
a/src/app/components/allocations-drawer/allocations-drawer.component.spec.ts 
b/src/app/components/allocations-drawer/allocations-drawer.component.spec.ts
new file mode 100644
index 0000000..c79b406
--- /dev/null
+++ b/src/app/components/allocations-drawer/allocations-drawer.component.spec.ts
@@ -0,0 +1,113 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { DebugElement } from '@angular/core';
+import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { MatDividerModule } from '@angular/material/divider';
+import { MatInputModule } from '@angular/material/input';
+import { MatPaginatorModule } from '@angular/material/paginator';
+import { MatSelectModule } from '@angular/material/select';
+import { MatDrawer, MatSidenavModule } from '@angular/material/sidenav';
+import { MatSortModule } from '@angular/material/sort';
+import { MatTableDataSource, MatTableModule } from '@angular/material/table';
+import { By } from '@angular/platform-browser';
+import { NoopAnimationsModule } from '@angular/platform-browser/animations';
+import { NgxSpinnerService } from 'ngx-spinner';
+
+import { MockNgxSpinnerService } from '@app/testing/mocks';
+import { AllocationInfo } from '@app/models/alloc-info.model';
+
+import { AllocationsDrawerComponent } from './allocations-drawer.component';
+
+describe('AllocationsDrawerComponent', () => {
+  let component: AllocationsDrawerComponent;
+  let fixture: ComponentFixture<AllocationsDrawerComponent>;
+
+  beforeEach(() => {
+    TestBed.configureTestingModule({
+      declarations: [AllocationsDrawerComponent, MatDrawer],
+      imports: [
+        NoopAnimationsModule,
+        MatSidenavModule,
+        MatPaginatorModule,
+        MatDividerModule,
+        MatSortModule,
+        MatInputModule,
+        MatTableModule,
+        MatSelectModule,
+      ],
+      providers: [{ provide: NgxSpinnerService, useValue: 
MockNgxSpinnerService }],
+    }).compileComponents();
+    fixture = TestBed.createComponent(AllocationsDrawerComponent);
+    component = fixture.componentInstance;
+    fixture.detectChanges();
+  });
+
+  it('should create', () => {
+    expect(component).toBeTruthy();
+  });
+
+  it('should open drawer', () => {
+    spyOn(component.matDrawer, 'open');
+    component.openDrawer();
+    expect(component.matDrawer.open).toHaveBeenCalled();
+  });
+
+  it('should close drawer', () => {
+    spyOn(component.matDrawer, 'close');
+    component.closeDrawer();
+    expect(component.matDrawer.close).toHaveBeenCalled();
+  });
+
+  it('should copy the allocations URL to clipboard', () => {
+    const debugEl: DebugElement = fixture.debugElement;
+    const copyButton = debugEl.query(By.css('.copy-btn'));
+    const copyButtonSpy = spyOn(component, 'copyLinkToClipboard');
+    copyButton.triggerEventHandler('click', null);
+    expect(copyButtonSpy).toHaveBeenCalled();
+  });
+
+  it('should toggle allocations detail with nothing previously selected', () 
=> {
+    const row = 0;
+    const allocDataSource = new MatTableDataSource([{ expanded: false }]);
+    component.allocDataSource = allocDataSource as unknown as 
MatTableDataSource<
+      AllocationInfo & { expanded: boolean }
+    >;
+
+    component.allocationsDetailToggle(row);
+    expect(component.allocDataSource.data[row].expanded).toBe(true);
+
+    component.allocationsDetailToggle(row);
+    expect(component.allocDataSource.data[row].expanded).toBe(false);
+  });
+
+  it('should toggle allocations detail with previous selection active', () => {
+    const row = 0;
+    const allocDataSource = new MatTableDataSource([{ expanded: false }, { 
expanded: true }]);
+    component.selectedAllocationsRow = 1;
+    component.allocDataSource = allocDataSource as unknown as 
MatTableDataSource<
+      AllocationInfo & { expanded: boolean }
+    >;
+
+    component.allocationsDetailToggle(row);
+    expect(component.allocDataSource.data[row].expanded).toBe(true);
+
+    component.allocationsDetailToggle(row);
+    expect(component.allocDataSource.data[row].expanded).toBe(false);
+  });
+});
diff --git 
a/src/app/components/allocations-drawer/allocations-drawer.component.ts 
b/src/app/components/allocations-drawer/allocations-drawer.component.ts
new file mode 100644
index 0000000..7b69753
--- /dev/null
+++ b/src/app/components/allocations-drawer/allocations-drawer.component.ts
@@ -0,0 +1,133 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import { Component, EventEmitter, Input, OnInit, Output, ViewChild } from 
'@angular/core';
+import { MatPaginator } from '@angular/material/paginator';
+import { MatDrawer } from '@angular/material/sidenav';
+import { MatSort } from '@angular/material/sort';
+import { MatTableDataSource } from '@angular/material/table';
+import { AllocationInfo } from '@app/models/alloc-info.model';
+import { AppInfo } from '@app/models/app-info.model';
+import { ColumnDef } from '@app/models/column-def.model';
+import { CommonUtil } from '@app/utils/common.util';
+
+@Component({
+  selector: 'app-allocations-drawer',
+  templateUrl: './allocations-drawer.component.html',
+  styleUrls: ['./allocations-drawer.component.scss'],
+})
+export class AllocationsDrawerComponent implements OnInit {
+  @ViewChild('matDrawer', { static: false }) matDrawer!: MatDrawer;
+  @ViewChild('allocationMatPaginator', { static: true }) allocPaginator!: 
MatPaginator;
+  @ViewChild('allocSort', { static: true }) allocSort!: MatSort;
+  @Input() allocDataSource!: MatTableDataSource<AllocationInfo & { expanded: 
boolean }>;
+  @Input() selectedRow!: AppInfo | null;
+  @Input() partitionSelected!: string;
+  @Input() leafQueueSelected!: string;
+
+  @Output() removeRowSelection = new EventEmitter<void>();
+
+  allocColumnDef: ColumnDef[] = [];
+  allocColumnIds: string[] = [];
+  selectedAllocationsRow: number = -1;
+
+  ngOnChanges(): void {
+    if (this.allocDataSource) {
+      this.allocDataSource.paginator = this.allocPaginator;
+      this.allocDataSource.sort = this.allocSort;
+    }
+  }
+
+  ngOnInit(): void {
+    this.allocColumnDef = [
+      { colId: 'displayName', colName: 'Display Name', colWidth: 1 },
+      { colId: 'allocationKey', colName: 'Allocation Key', colWidth: 1 },
+      { colId: 'nodeId', colName: 'Node ID', colWidth: 1 },
+      {
+        colId: 'resource',
+        colName: 'Resource',
+        colFormatter: CommonUtil.resourceColumnFormatter,
+        colWidth: 1,
+      },
+      { colId: 'priority', colName: 'Priority', colWidth: 0.5 },
+    ];
+    this.allocColumnIds = this.allocColumnDef.map((col) => col.colId);
+  }
+
+  formatResources(colValue: string): string[] {
+    const arr: string[] = colValue.split('<br/>');
+    // Check if there are "cpu" or "Memory" elements in the array
+    const hasCpu = arr.some((item) => item.toLowerCase().includes('cpu'));
+    const hasMemory = arr.some((item) => 
item.toLowerCase().includes('memory'));
+    if (!hasCpu) {
+      arr.unshift('CPU: n/a');
+    }
+    if (!hasMemory) {
+      arr.unshift('Memory: n/a');
+    }
+
+    // Concatenate the two arrays, with "cpu" and "Memory" elements first
+    const cpuAndMemoryElements = arr.filter(
+      (item) => item.toLowerCase().includes('CPU') || 
item.toLowerCase().includes('Memory')
+    );
+    const otherElements = arr.filter(
+      (item) => !item.toLowerCase().includes('CPU') && 
!item.toLowerCase().includes('Memory')
+    );
+    const result = cpuAndMemoryElements.concat(otherElements);
+
+    return result;
+  }
+
+  isAllocDataSourceEmpty() {
+    return this.allocDataSource?.data && this.allocDataSource.data.length === 
0;
+  }
+
+  allocationsDetailToggle(row: number) {
+    if (this.selectedAllocationsRow !== -1) {
+      if (this.selectedAllocationsRow !== row) {
+        this.allocDataSource.data[this.selectedAllocationsRow].expanded = 
false;
+        this.selectedAllocationsRow = row;
+        this.allocDataSource.data[row].expanded = true;
+      } else {
+        this.allocDataSource.data[this.selectedAllocationsRow].expanded = 
false;
+        this.selectedAllocationsRow = -1;
+      }
+    } else {
+      this.selectedAllocationsRow = row;
+      this.allocDataSource.data[row].expanded = true;
+    }
+  }
+
+  closeDrawer() {
+    this.selectedAllocationsRow = -1;
+    this.matDrawer.close();
+    this.removeRowSelection.emit();
+  }
+
+  openDrawer() {
+    this.matDrawer.open();
+  }
+
+  copyLinkToClipboard() {
+    const url = window.location.href.split('?')[0];
+    const copyString = 
`${url}?partition=${this.partitionSelected}&queue=${this.leafQueueSelected}&applicationId=${this?.selectedRow?.applicationId}`;
+    navigator.clipboard
+      .writeText(copyString)
+      .catch((error) => console.error('Writing to the clipboard is not 
allowed. ', error));
+  }
+}
diff --git a/src/app/components/apps-view/apps-view.component.html 
b/src/app/components/apps-view/apps-view.component.html
index 5e44df0..5c85aca 100644
--- a/src/app/components/apps-view/apps-view.component.html
+++ b/src/app/components/apps-view/apps-view.component.html
@@ -43,7 +43,7 @@
     <mat-form-field class="search-wrapper white-mat-form-field">
       <input matInput type="text" [(ngModel)]="searchText" placeholder="Search 
By Application ID" #searchInput />
       <button class="clear-btn" *ngIf="searchText" (click)="onClearSearch()" 
matTooltip="Clear Search"
-              matTooltipShowDelay="500">
+        matTooltipShowDelay="500">
         <i class="far fa-times-circle"></i>
       </button>
       <i *ngIf="!searchText" class="fas fa-search search-icon"></i>
@@ -59,32 +59,35 @@
   <div class="mat-elevation-z8">
     <mat-table [dataSource]="appDataSource" matSort #appSort="matSort">
       <ng-container [matColumnDef]="columnDef.colId" *ngFor="let columnDef of 
appColumnDef">
-        <mat-header-cell *matHeaderCellDef mat-sort-header>{{ 
columnDef.colName }}</mat-header-cell>
+        <mat-header-cell *matHeaderCellDef mat-sort-header 
[style.flex]="columnDef.colWidth || 1">{{ columnDef.colName
+          }}</mat-header-cell>
 
         <ng-container *ngIf="columnDef.colId === 'submissionTime'; else 
renderNext_1">
-          <mat-cell *matCellDef="let element">{{ 
element['formattedSubmissionTime'] }}</mat-cell>
+          <mat-cell *matCellDef="let element" [style.flex]="columnDef.colWidth 
|| 1">{{
+            element['formattedSubmissionTime'] }}</mat-cell>
         </ng-container>
 
         <ng-container *ngIf="columnDef.colId === 'lastStateChangeTime'; else 
renderNext_1">
-          <mat-cell *matCellDef="let element">{{ 
element['formattedlastStateChangeTime'] }}</mat-cell>
+          <mat-cell *matCellDef="let element" [style.flex]="columnDef.colWidth 
|| 1">{{
+            element['formattedlastStateChangeTime'] }}</mat-cell>
         </ng-container>
 
         <ng-template #renderNext_1>
           <ng-container
             *ngIf="columnDef.colId === 'usedResource' || columnDef.colId === 
'pendingResource'; else renderNext_1">
-            <mat-cell *matCellDef="let element">
+            <mat-cell *matCellDef="let element" 
[style.flex]="columnDef.colWidth || 1">
               <ng-container *ngIf="columnDef.colFormatter; else 
showAppRawData">
                 <ng-container 
*ngIf="columnDef.colFormatter(element[columnDef.colId]) as colValue">
-                  <ul class="mat-res-ul">
+                  <mat-chip-set aria-label="Resources" 
[attr.data-test]="formatResources(colValue)">
                     <ng-container *ngFor="let resource of 
formatResources(colValue); let i = index">
-                      <li class="mat-res-li" *ngIf="i<2">
+                      <mat-chip class="mat-chip" *ngIf="i<2">
                         {{ resource }}
-                      </li>
-                      <li class="mat-res-li" *ngIf="i>=2 && detailToggle">
+                      </mat-chip>
+                      <mat-chip class="mat-chip" *ngIf="i>=2 && detailToggle">
                         {{ resource }}
-                      </li>
+                      </mat-chip>
                     </ng-container>
-                  </ul>
+                  </mat-chip-set>
                 </ng-container>
               </ng-container>
               <ng-template #showAppRawData>
@@ -125,98 +128,19 @@
 
       <mat-header-row *matHeaderRowDef="appColumnIds"></mat-header-row>
 
-      <mat-row *matRowDef="let row; columns: appColumnIds" 
[class.selected-row]="selectedRow === row"
-               (click)="toggleRowSelection(row)"></mat-row>
+      <mat-row *matRowDef="let row; columns: appColumnIds; let i = index" 
[class.selected-row]="selectedRow === row"
+        (click)="toggleRowSelection(row)" [ngClass]="{'even-row': i % 2 === 0, 
'row': true}"></mat-row>
 
       <mat-footer-row *matFooterRowDef="['noRecord']"
-                      [ngStyle]="{ display: isAppDataSourceEmpty() ? '' : 
'none' }"></mat-footer-row>
+        [ngStyle]="{ display: isAppDataSourceEmpty() ? '' : 'none' 
}"></mat-footer-row>
     </mat-table>
 
-    <mat-paginator #appsViewMatPaginator [pageSizeOptions]="[10, 20, 50, 100]"
-                   [ngStyle]="{ display: isAppDataSourceEmpty() ? 'none' : '' 
}" (page)="onPaginatorChanged()"
-                   showFirstLastButtons></mat-paginator>
+    <mat-paginator #appsViewMatPaginator [pageSizeOptions]="[10, 20, 50, 100]" 
pageSize="50"
+      [ngStyle]="{ display: isAppDataSourceEmpty() ? 'none' : '' }" 
(page)="onPaginatorChanged()"
+      showFirstLastButtons></mat-paginator>
   </div>
+  <ng-container #drawerContainer></ng-container>
+  <ng-container #mfeContainer></ng-container>
 
-  <mat-drawer-container
-    class="flex-primary"
-    [hasBackdrop]="false"
-  >
-    <mat-drawer #matDrawer mode="over" position="end">
-      <mat-drawer-content>
-        <div class="header">
-          <span>{{ selectedRow?.applicationId }} ({{ 
selectedRow?.allocations?.length }} allocations)</span>
-          <span class="far fa-clipboard copy-btn" 
(click)="copyLinkToClipboard()" matTooltip="Click to copy the URL to this view" 
matTooltipShowDelay="500"></span>
-          <span class="far fa-solid fa-xmark close-btn" 
(click)="closeDrawer()"></span>
-        </div>
-        <div class="content">
 
-          <mat-table [dataSource]="allocDataSource" matSort 
#allocSort="matSort">
-            <ng-container [matColumnDef]="columnDef.colId" *ngFor="let 
columnDef of allocColumnDef">
-              <mat-header-cell *matHeaderCellDef mat-sort-header 
[style.flex]="columnDef?.colWidth || 1">{{ columnDef.colName 
}}</mat-header-cell>
-
-              <ng-container *ngIf="columnDef.colId === 'priority'; else 
renderNext_3" >
-                <mat-cell class="small" *matCellDef="let element"
-                          [style.flex]="columnDef?.colWidth || 1"
-                          [style.min-height]="allocationsToggle ? '96px' : 
'unset'"
-                          [title]="element[columnDef.colId]"
-                >{{ element['priority'] }}  </mat-cell>
-              </ng-container>
-
-              <ng-container *ngIf="columnDef.colId === 'resource'; else 
renderNext_3">
-                <mat-cell *matCellDef="let element" class="allocations-data" 
[style.flex]="columnDef?.colWidth || 1" matTooltip="
-                          {{element[columnDef.colId]}}" 
matTooltipShowDelay="500" >
-                  <ng-container *ngIf="columnDef.colFormatter; else 
showAllocRowData;">
-                    <ng-container 
*ngIf="columnDef.colFormatter(element[columnDef.colId]) as colValue">
-                      <ul class="mat-res-ul">
-                        <ng-container *ngFor="let resource of 
formatResources(colValue); let i = index">
-                          <li class="mat-res-li" *ngIf="i<1">
-                            {{ resource }}
-                          </li>
-                          <li class="mat-res-li" *ngIf="i>=1 && 
allocationsToggle">
-                            {{ resource }}
-                          </li>
-                        </ng-container>
-                      </ul>
-                    </ng-container>
-                  </ng-container>
-                  <ng-template #showAllocRowData>
-                    <span>{{ element[columnDef.colId] }}</span>
-                  </ng-template>
-                </mat-cell>
-              </ng-container>
-
-              <ng-template #renderNext_3>
-                <mat-cell *matCellDef="let element"
-                          [class]="allocationsToggle ? '' : 'ellipsis'"
-                          [style.flex]="columnDef?.colWidth || 1"
-                          [style.min-height]="allocationsToggle ? '96px' : 
'unset'"
-                          matTooltip="{{element[columnDef.colId]}}" 
matTooltipShowDelay="500"
-                >{{ element[columnDef.colId] || 'n/a' }}</mat-cell>
-              </ng-template>
-            </ng-container>
-
-            <ng-container matColumnDef="noRecord">
-              <mat-footer-cell *matFooterCellDef>
-                <div class="no-record">No records found</div>
-              </mat-footer-cell>
-            </ng-container>
-
-            <mat-header-row *matHeaderRowDef="allocColumnIds"></mat-header-row>
-
-            <mat-row *matRowDef="let row; columns: allocColumnIds; let i = 
index" (click)="allocationsDetailToggle()"
-                     [ngClass]="{'even-row': i % 2 === 0, 'row': true}"
-            ></mat-row>
-
-            <mat-footer-row *matFooterRowDef="['noRecord']"
-                            [ngStyle]="{ display: isAllocDataSourceEmpty() ? 
'' : 'none' }"></mat-footer-row>
-          </mat-table>
-
-          <mat-paginator #allocationMatPaginator [pageSizeOptions]="[10, 20, 
50, 100]"
-                         [ngStyle]="{ display: isAllocDataSourceEmpty() ? 
'none' : '' }"
-                         showFirstLastButtons></mat-paginator>
-
-        </div>
-      </mat-drawer-content>
-    </mat-drawer>
-  </mat-drawer-container>
-</div>
+</div>
\ No newline at end of file
diff --git a/src/app/components/apps-view/apps-view.component.scss 
b/src/app/components/apps-view/apps-view.component.scss
index f88e974..60625e0 100644
--- a/src/app/components/apps-view/apps-view.component.scss
+++ b/src/app/components/apps-view/apps-view.component.scss
@@ -98,6 +98,27 @@
 .apps-view {
   width: 100%;
   height: 100%;
+
+  mat-chip {
+    height: 20px;
+    line-height: 14px;
+    font-size: 12px;
+    margin: 1px;
+    // border-radius: 5px;
+    // background-color: #313D54;
+    background-color: transparent;
+
+    span {
+        font-size: 12px;
+    }
+  }
+
+  .mat-mdc-standard-chip {
+    --mdc-chip-label-text-color: #333;
+    --mdc-chip-label-text-size: 12px;
+    --mdc-chip-label-text-weight: 400;
+  }
+
   .mat-mdc-header-cell {
     font-size: 15px;
     font-weight: bold;
@@ -124,7 +145,12 @@
       }
     }
   }
+  .even-row {
+    background: #eee;
+  }
   .mat-mdc-row {
+    min-height: unset;
+    font-size: 12px;
     &:hover {
       background: #cccccc;
       cursor: pointer;
@@ -243,4 +269,4 @@
   .row {
     min-height: unset;
   }
-}
+}
\ No newline at end of file
diff --git a/src/app/components/apps-view/apps-view.component.spec.ts 
b/src/app/components/apps-view/apps-view.component.spec.ts
index 951b932..36c8969 100644
--- a/src/app/components/apps-view/apps-view.component.spec.ts
+++ b/src/app/components/apps-view/apps-view.component.spec.ts
@@ -31,8 +31,15 @@ import { By, HAMMER_LOADER } from 
'@angular/platform-browser';
 import { NoopAnimationsModule } from '@angular/platform-browser/animations';
 import { RouterTestingModule } from '@angular/router/testing';
 import { AppInfo } from '@app/models/app-info.model';
+import { EnvconfigService } from '@app/services/envconfig/envconfig.service';
 import { SchedulerService } from '@app/services/scheduler/scheduler.service';
-import { MockNgxSpinnerService, MockSchedulerService } from 
'@app/testing/mocks';
+import { MatChipsModule } from '@angular/material/chips';
+
+import {
+  MockEnvconfigService,
+  MockNgxSpinnerService,
+  MockSchedulerService,
+} from '@app/testing/mocks';
 import { NgxSpinnerService } from 'ngx-spinner';
 import { of } from 'rxjs';
 
@@ -57,15 +64,20 @@ describe('AppsViewComponent', () => {
         MatTooltipModule,
         MatSelectModule,
         MatSidenavModule,
+        MatChipsModule,
       ],
       providers: [
         { provide: SchedulerService, useValue: MockSchedulerService },
         { provide: NgxSpinnerService, useValue: MockNgxSpinnerService },
         { provide: HAMMER_LOADER, useValue: () => new Promise(() => {}) },
+        { provide: EnvconfigService, useValue: MockEnvconfigService },
       ],
     }).compileComponents();
     fixture = TestBed.createComponent(AppsViewComponent);
     component = fixture.componentInstance;
+    spyOn(component, 'initializeSidebarComponent').and.callFake(
+      (b = null) => new Promise(() => {})
+    );
     fixture.detectChanges();
   });
 
@@ -73,7 +85,7 @@ describe('AppsViewComponent', () => {
     expect(component).toBeTruthy();
   });
 
-  it('should have usedResource and pendingResource column', () => {
+  it('should have usedResource and pendingResource column with detailToggle 
OFF', () => {
     let service: SchedulerService;
     service = TestBed.inject(SchedulerService);
     let appInfo = new AppInfo(
@@ -90,22 +102,45 @@ describe('AppsViewComponent', () => {
     );
     spyOn(service, 'fetchAppList').and.returnValue(of([appInfo]));
     component.fetchAppListForPartitionAndQueue('default', 'root');
-    component.toggle();
     fixture.detectChanges();
     const debugEl: DebugElement = fixture.debugElement;
     expect(
-      
debugEl.query(By.css('mat-cell.mat-column-usedResource')).nativeElement.innerText
-    ).toContain('Memory: 500.0 KB\nCPU: 10\npods: 1');
+      debugEl.query(By.css('[data-test="Memory: 500.0 KB,CPU: 10,pods: 
1"]')).nativeElement
+        .innerText
+    ).toContain('Memory: 500.0 KB\nCPU: 10');
     expect(
-      
debugEl.query(By.css('mat-cell.mat-column-pendingResource')).nativeElement.innerText
-    ).toContain('Memory: 0.0 bytes\nCPU: 0\npods: n/a');
+      debugEl.query(By.css('[data-test="Memory: 0.0 bytes,CPU: 0,pods: 
n/a"]')).nativeElement
+        .innerText
+    ).toContain('Memory: 0.0 bytes\nCPU: 0');
   });
 
-  it('should copy the allocations URL to clipboard', () => {
+  it('should have usedResource and pendingResource column with detailToggle 
ON', () => {
+    let service: SchedulerService;
+    service = TestBed.inject(SchedulerService);
+    let appInfo = new AppInfo(
+      'app1',
+      'Memory: 500.0 KB, CPU: 10, pods: 1',
+      'Memory: 0.0 bytes, CPU: 0, pods: n/a',
+      '',
+      1,
+      2,
+      [],
+      2,
+      'RUNNING',
+      []
+    );
+    spyOn(service, 'fetchAppList').and.returnValue(of([appInfo]));
+    component.fetchAppListForPartitionAndQueue('default', 'root');
+    component.detailToggle = true;
+    fixture.detectChanges();
     const debugEl: DebugElement = fixture.debugElement;
-    const copyButton = debugEl.query(By.css('.copy-btn'));
-    const copyButtonSpy = spyOn(component, 'copyLinkToClipboard');
-    copyButton.triggerEventHandler('click', null);
-    expect(copyButtonSpy).toHaveBeenCalled();
+    expect(
+      debugEl.query(By.css('[data-test="Memory: 500.0 KB,CPU: 10,pods: 
1"]')).nativeElement
+        .innerText
+    ).toContain('Memory: 500.0 KB\nCPU: 10\npods: 1');
+    expect(
+      debugEl.query(By.css('[data-test="Memory: 0.0 bytes,CPU: 0,pods: 
n/a"]')).nativeElement
+        .innerText
+    ).toContain('Memory: 0.0 bytes\nCPU: 0\npods: n/a');
   });
 });
diff --git a/src/app/components/apps-view/apps-view.component.ts 
b/src/app/components/apps-view/apps-view.component.ts
index d742aac..c65d5cb 100644
--- a/src/app/components/apps-view/apps-view.component.ts
+++ b/src/app/components/apps-view/apps-view.component.ts
@@ -16,25 +16,36 @@
  * limitations under the License.
  */
 
-import { Component, OnInit, ViewChild, ElementRef } from '@angular/core';
-import { ActivatedRoute, Router } from '@angular/router';
+import {
+  Component,
+  ComponentRef,
+  ElementRef,
+  OnInit,
+  ViewChild,
+  ViewContainerRef,
+} from '@angular/core';
 import { MatPaginator } from '@angular/material/paginator';
-import { MatTableDataSource } from '@angular/material/table';
+import { MatSelect, MatSelectChange } from '@angular/material/select';
 import { MatSort } from '@angular/material/sort';
-import { MatSelectChange, MatSelect } from '@angular/material/select';
-import { finalize, debounceTime, distinctUntilChanged } from 'rxjs/operators';
-import { NgxSpinnerService } from 'ngx-spinner';
-import { fromEvent } from 'rxjs';
-
-import { SchedulerService } from '@app/services/scheduler/scheduler.service';
-import { AppInfo } from '@app/models/app-info.model';
+import { MatTableDataSource } from '@angular/material/table';
+import { ActivatedRoute, Router } from '@angular/router';
+import { AllocationsDrawerComponent } from 
'@app/components/allocations-drawer/allocations-drawer.component';
 import { AllocationInfo } from '@app/models/alloc-info.model';
+import { AppInfo } from '@app/models/app-info.model';
 import { ColumnDef } from '@app/models/column-def.model';
-import { CommonUtil } from '@app/utils/common.util';
-import { PartitionInfo } from '@app/models/partition-info.model';
 import { DropdownItem } from '@app/models/dropdown-item.model';
+import { PartitionInfo } from '@app/models/partition-info.model';
 import { QueueInfo } from '@app/models/queue-info.model';
-import { MatDrawer } from '@angular/material/sidenav';
+import { EnvconfigService } from '@app/services/envconfig/envconfig.service';
+import { SchedulerService } from '@app/services/scheduler/scheduler.service';
+import { CommonUtil } from '@app/utils/common.util';
+import { NgxSpinnerService } from 'ngx-spinner';
+import { fromEvent } from 'rxjs';
+import { debounceTime, distinctUntilChanged, finalize } from 'rxjs/operators';
+import {
+  loadRemoteModule,
+  LoadRemoteModuleEsmOptions,
+} from '@angular-architects/module-federation';
 
 @Component({
   selector: 'app-applications-view',
@@ -48,7 +59,12 @@ export class AppsViewComponent implements OnInit {
   @ViewChild('allocSort', { static: true }) allocSort!: MatSort;
   @ViewChild('searchInput', { static: true }) searchInput!: ElementRef;
   @ViewChild('queueSelect', { static: false }) queueSelect!: MatSelect;
-  @ViewChild('matDrawer', { static: false }) matDrawer!: MatDrawer;
+
+  @ViewChild('drawerContainer', { read: ViewContainerRef, static: true })
+  drawerContainer!: ViewContainerRef;
+
+  @ViewChild('mfeContainer', { read: ViewContainerRef, static: true })
+  mfeContainer!: ViewContainerRef;
 
   appDataSource = new MatTableDataSource<AppInfo>([]);
   appColumnDef: ColumnDef[] = [];
@@ -67,13 +83,14 @@ export class AppsViewComponent implements OnInit {
   leafQueueSelected = '';
 
   detailToggle: boolean = false;
-  allocationsToggle: boolean = false;
+  allocationsDrawerComponent: ComponentRef<AllocationsDrawerComponent> | 
undefined = undefined;
 
   constructor(
     private scheduler: SchedulerService,
     private spinner: NgxSpinnerService,
     private activatedRoute: ActivatedRoute,
-    private router: Router
+    private router: Router,
+    private envConfig: EnvconfigService
   ) {}
 
   ngOnInit() {
@@ -84,27 +101,31 @@ export class AppsViewComponent implements OnInit {
     this.appSort.sort({ id: 'submissionTime', start: 'desc', disableClear: 
false });
 
     this.appColumnDef = [
-      { colId: 'applicationId', colName: 'Application ID' },
-      { colId: 'applicationState', colName: 'Application State' },
+      { colId: 'applicationId', colName: 'Application ID', colWidth: 1 },
+      { colId: 'applicationState', colName: 'Application State', colWidth: 1 },
       {
         colId: 'lastStateChangeTime',
         colName: 'Last State Change Time',
         colFormatter: CommonUtil.timeColumnFormatter,
+        colWidth: 1,
       },
       {
         colId: 'usedResource',
         colName: 'Used Resource',
         colFormatter: CommonUtil.resourceColumnFormatter,
+        colWidth: 2,
       },
       {
         colId: 'pendingResource',
         colName: 'Pending Resource',
         colFormatter: CommonUtil.resourceColumnFormatter,
+        colWidth: 2,
       },
       {
         colId: 'submissionTime',
         colName: 'Submission Time',
         colFormatter: CommonUtil.timeColumnFormatter,
+        colWidth: 1,
       },
     ];
 
@@ -154,6 +175,31 @@ export class AppsViewComponent implements OnInit {
           this.clearQueueSelection();
         }
       });
+
+    this.initializeSidebarComponent(
+      this.envConfig.getAllocationsDrawerComponentRemoteConfig()
+    ).catch(console.error);
+  }
+
+  async initializeSidebarComponent(remoteComponentConfig: 
LoadRemoteModuleEsmOptions | null) {
+    let component = AllocationsDrawerComponent;
+
+    if (remoteComponentConfig !== null) {
+      const { AllocationsDrawerComponent: allocationsDrawerComponent } =
+        await loadRemoteModule(remoteComponentConfig);
+      component = allocationsDrawerComponent;
+    }
+
+    this.drawerContainer.clear();
+    this.allocationsDrawerComponent = 
this.drawerContainer.createComponent(component);
+
+    this.allocationsDrawerComponent.setInput('selectedRow', this.selectedRow);
+    this.allocationsDrawerComponent.setInput('allocDataSource', 
this.allocDataSource);
+    this.allocationsDrawerComponent.setInput('partitionSelected', 
this.partitionSelected);
+    this.allocationsDrawerComponent.setInput('leafQueueSelected', 
this.leafQueueSelected);
+    this.allocationsDrawerComponent.instance.removeRowSelection.subscribe(() 
=> {
+      this.removeRowSelection();
+    });
   }
 
   fetchQueuesForPartition(partitionName: string) {
@@ -277,10 +323,12 @@ export class AppsViewComponent implements OnInit {
     } else {
       this.selectedRow = row;
       row.isSelected = true;
-      this.matDrawer.open();
       if (row.allocations) {
         this.allocDataSource.data = row.allocations;
       }
+      this.allocationsDrawerComponent?.setInput('selectedRow', 
this.selectedRow);
+      this.allocationsDrawerComponent?.setInput('allocDataSource', 
this.allocDataSource);
+      this.allocationsDrawerComponent?.instance.openDrawer();
     }
   }
 
@@ -300,10 +348,6 @@ export class AppsViewComponent implements OnInit {
     return this.appDataSource.data && this.appDataSource.data.length === 0;
   }
 
-  isAllocDataSourceEmpty() {
-    return this.allocDataSource.data && this.allocDataSource.data.length === 0;
-  }
-
   onClearSearch() {
     this.searchText = '';
     this.removeRowSelection();
@@ -377,9 +421,7 @@ export class AppsViewComponent implements OnInit {
     const otherElements = arr.filter(
       (item) => !item.toLowerCase().includes('CPU') && 
!item.toLowerCase().includes('Memory')
     );
-    const result = cpuAndMemoryElements.concat(otherElements);
-
-    return result;
+    return cpuAndMemoryElements.concat(otherElements);
   }
 
   clearQueueSelection() {
@@ -395,21 +437,4 @@ export class AppsViewComponent implements OnInit {
   toggle() {
     this.detailToggle = !this.detailToggle;
   }
-
-  allocationsDetailToggle() {
-    this.allocationsToggle = !this.allocationsToggle;
-  }
-
-  closeDrawer() {
-    this.matDrawer.close();
-    this.removeRowSelection();
-  }
-
-  copyLinkToClipboard() {
-    const url = window.location.href.split('?')[0];
-    const copyString = 
`${url}?partition=${this.partitionSelected}&queue=${this.leafQueueSelected}&applicationId=${this?.selectedRow?.applicationId}`;
-    navigator.clipboard
-      .writeText(copyString)
-      .catch((error) => console.error('Writing to the clipboard is not 
allowed. ', error));
-  }
 }
diff --git a/src/app/models/envconfig.model.ts 
b/src/app/models/envconfig.model.ts
index 0ca4a7e..78b3a41 100644
--- a/src/app/models/envconfig.model.ts
+++ b/src/app/models/envconfig.model.ts
@@ -18,4 +18,6 @@
 
 export interface EnvConfig {
   localSchedulerWebAddress: string;
+  moduleFederationRemoteEntry?: string;
+  allocationsDrawerRemoteComponent?: string;
 }
diff --git a/src/app/services/envconfig/envconfig.service.ts 
b/src/app/services/envconfig/envconfig.service.ts
index 8118795..f351b46 100644
--- a/src/app/services/envconfig/envconfig.service.ts
+++ b/src/app/services/envconfig/envconfig.service.ts
@@ -21,7 +21,7 @@ import { HttpClient } from '@angular/common/http';
 import { environment } from '../../../environments/environment';
 
 import { EnvConfig } from '@app/models/envconfig.model';
-import { DEFAULT_PROTOCOL } from '@app/utils/constants';
+import { LoadRemoteModuleEsmOptions } from 
'@angular-architects/module-federation';
 
 const ENV_CONFIG_JSON_URL = './assets/config/envconfig.json';
 
@@ -63,4 +63,17 @@ export class EnvconfigService {
 
     return `${this.uiProtocol}//${this.uiHostname}:${this.uiPort}`;
   }
+
+  getAllocationsDrawerComponentRemoteConfig(): LoadRemoteModuleEsmOptions | 
null {
+    if (
+      this.envConfig.allocationsDrawerRemoteComponent &&
+      this.envConfig.moduleFederationRemoteEntry
+    )
+      return {
+        type: 'module',
+        remoteEntry: this.envConfig.moduleFederationRemoteEntry,
+        exposedModule: this.envConfig.allocationsDrawerRemoteComponent,
+      };
+    return null;
+  }
 }
diff --git a/src/app/testing/mocks.ts b/src/app/testing/mocks.ts
index 45efbd4..c91ffd7 100644
--- a/src/app/testing/mocks.ts
+++ b/src/app/testing/mocks.ts
@@ -21,6 +21,7 @@ import { AppInfo } from '@app/models/app-info.model';
 import { CommonUtil } from '@app/utils/common.util';
 
 export const noopFn = () => {};
+export const nullFn = () => null;
 
 export const MockSchedulerService = {
   fetchClusterByName: () => of({}),
@@ -41,6 +42,7 @@ export const MockNgxSpinnerService = {
 
 export const MockEnvconfigService = {
   getSchedulerWebAddress: noopFn,
+  getAllocationsDrawerComponentRemoteConfig: nullFn,
 };
 
 export const MockEventBusService = {
diff --git a/src/assets/config/envconfig.json b/src/assets/config/envconfig.json
index fb22397..8e21192 100644
--- a/src/assets/config/envconfig.json
+++ b/src/assets/config/envconfig.json
@@ -1,3 +1,5 @@
 {
-  "localSchedulerWebAddress": "http://localhost:9889";
+  "localSchedulerWebAddress": "http://localhost:9889";,
+  "moduleFederationRemoteEntry": "",
+  "allocationsDrawerRemoteComponent": ""
 }
diff --git a/src/main.ts b/src/bootstrap.ts
similarity index 100%
copy from src/main.ts
copy to src/bootstrap.ts
diff --git a/src/main.ts b/src/main.ts
index be5f6fc..8039bb0 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -16,16 +16,4 @@
  * limitations under the License.
  */
 
-import { enableProdMode } from '@angular/core';
-import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
-
-import { AppModule } from './app/app.module';
-import { environment } from './environments/environment';
-
-if (environment.production) {
-  enableProdMode();
-}
-
-platformBrowserDynamic()
-  .bootstrapModule(AppModule)
-  .catch((err) => console.error(err));
+import('./bootstrap').catch((err) => console.error(err));
diff --git a/tsconfig.app.json b/tsconfig.app.json
index 82d91dc..58c0f98 100644
--- a/tsconfig.app.json
+++ b/tsconfig.app.json
@@ -1,4 +1,3 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
 {
   "extends": "./tsconfig.json",
   "compilerOptions": {
@@ -12,4 +11,4 @@
   "include": [
     "src/**/*.d.ts"
   ]
-}
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
index b3eb0fd..14abf2d 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -1,4 +1,3 @@
-/* To learn more about this file see: https://angular.io/config/tsconfig. */
 {
   "compileOnSave": false,
   "compilerOptions": {
@@ -38,4 +37,4 @@
     "strictInputAccessModifiers": true,
     "strictTemplates": true
   }
-}
+}
\ No newline at end of file
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 0000000..f730193
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,37 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+
+const {
+  shareAll,
+  withModuleFederationPlugin,
+} = require('@angular-architects/module-federation/webpack');
+
+const webpackConfig = withModuleFederationPlugin({
+  shared: {
+    ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 
'auto' }),
+  },
+});
+
+module.exports = {
+  ...webpackConfig,
+  output: {
+    ...webpackConfig.output,
+    scriptType: 'text/javascript',
+  },
+};
diff --git a/webpack.prod.config.js b/webpack.prod.config.js
new file mode 100644
index 0000000..f2e70c2
--- /dev/null
+++ b/webpack.prod.config.js
@@ -0,0 +1,19 @@
+//
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+//
+module.exports = require('./webpack.config');


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to