diff --git a/solr/webapp/web/solrUi/.gitignore b/solr/webapp/web/solrUi/.gitignore
new file mode 100644
index 00000000000..0711527ef9d
--- /dev/null
+++ b/solr/webapp/web/solrUi/.gitignore
@@ -0,0 +1,42 @@
+# See http://help.github.com/ignore-files/ for more about ignoring files.
+
+# Compiled output
+/dist
+/tmp
+/out-tsc
+/bazel-out
+
+# Node
+/node_modules
+npm-debug.log
+yarn-error.log
+
+# IDEs and editors
+.idea/
+.project
+.classpath
+.c9/
+*.launch
+.settings/
+*.sublime-workspace
+
+# Visual Studio Code
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+.history/*
+
+# Miscellaneous
+/.angular/cache
+.sass-cache/
+/connect.lock
+/coverage
+/libpeerconnection.log
+testem.log
+/typings
+
+# System files
+.DS_Store
+Thumbs.db
diff --git a/solr/webapp/web/solrUi/README.md b/solr/webapp/web/solrUi/README.md
new file mode 100644
index 00000000000..225c1853e10
--- /dev/null
+++ b/solr/webapp/web/solrUi/README.md
@@ -0,0 +1,27 @@
+# SolrUi
+
+This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 18.x .
+
+## Development server
+
+Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The application will automatically reload if you change any of the source files.
+
+## Code scaffolding
+
+Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
+
+## Build
+
+Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory.
+
+## Running unit tests
+
+Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
+
+## Running end-to-end tests
+
+Run `ng e2e` to execute the end-to-end tests via a platform of your choice. To use this command, you need to first add a package that implements end-to-end testing capabilities.
+
+## Further help
+
+To get more help on the Angular CLI use `ng help` or go check out the [Angular CLI Overview and Command Reference](https://angular.io/cli) page.
diff --git a/solr/webapp/web/solrUi/angular.json b/solr/webapp/web/solrUi/angular.json
new file mode 100644
index 00000000000..fa97d6d255d
--- /dev/null
+++ b/solr/webapp/web/solrUi/angular.json
@@ -0,0 +1,108 @@
+{
+ "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+ "version": 1,
+ "newProjectRoot": "projects",
+ "projects": {
+ "solrUi": {
+ "projectType": "application",
+ "schematics": {
+ "@schematics/angular:component": {
+ "style": "scss"
+ }
+ },
+ "root": "",
+ "sourceRoot": "src",
+ "prefix": "app",
+ "architect": {
+ "build": {
+ "builder": "@angular-devkit/build-angular:application",
+ "options": {
+ "outputPath": "dist/solr-ui",
+ "index": "src/index.html",
+ "browser": "src/main.ts",
+ "polyfills": [
+ "zone.js"
+ ],
+ "tsConfig": "tsconfig.app.json",
+ "inlineStyleLanguage": "scss",
+ "assets": [
+ "src/favicon.ico",
+ "src/assets"
+ ],
+ "styles": [
+ "src/styles.scss"
+ ],
+ "scripts": []
+ },
+ "configurations": {
+ "production": {
+ "budgets": [
+ {
+ "type": "initial",
+ "maximumWarning": "500kb",
+ "maximumError": "1mb"
+ },
+ {
+ "type": "anyComponentStyle",
+ "maximumWarning": "10kb",
+ "maximumError": "10kb"
+ }
+ ],
+ "outputHashing": "all"
+ },
+ "development": {
+ "optimization": false,
+ "extractLicenses": false,
+ "sourceMap": true,
+ "fileReplacements": [
+ {
+ "replace": "src/environments/environment.ts",
+ "with": "src/environments/environment.development.ts"
+ }
+ ]
+ }
+ },
+ "defaultConfiguration": "production"
+ },
+ "serve": {
+ "builder": "@angular-devkit/build-angular:dev-server",
+ "configurations": {
+ "production": {
+ "buildTarget": "solrUi:build:production"
+ },
+ "development": {
+ "buildTarget": "solrUi:build:development",
+ "proxyConfig": "src/proxy.conf.json"
+ }
+ },
+ "defaultConfiguration": "development"
+ },
+ "extract-i18n": {
+ "builder": "@angular-devkit/build-angular:extract-i18n",
+ "options": {
+ "buildTarget": "solrUi:build"
+ }
+ },
+ "test": {
+ "builder": "@angular-devkit/build-angular:karma",
+ "options": {
+ "polyfills": [
+ "zone.js",
+ "zone.js/testing"
+ ],
+ "tsConfig": "tsconfig.spec.json",
+ "inlineStyleLanguage": "scss",
+ "assets": [
+ "src/favicon.ico",
+ "src/assets"
+ ],
+ "styles": [
+ "src/styles.scss"
+ ],
+ "scripts": []
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/solr/webapp/web/solrUi/package.json b/solr/webapp/web/solrUi/package.json
new file mode 100644
index 00000000000..6af2b13150d
--- /dev/null
+++ b/solr/webapp/web/solrUi/package.json
@@ -0,0 +1,45 @@
+{
+ "name": "solr-ui",
+ "version": "2.0.0",
+ "scripts": {
+ "ng": "ng",
+ "start": "ng serve",
+ "build": "ng build",
+ "watch": "ng build --watch --configuration development",
+ "test": "ng test"
+ },
+ "private": true,
+ "dependencies": {
+ "@angular/animations": "18.2.8",
+ "@angular/common": "18.2.8",
+ "@angular/compiler": "18.2.8",
+ "@angular/core": "18.2.8",
+ "@angular/forms": "18.2.8",
+ "@angular/platform-browser": "18.2.8",
+ "@angular/platform-browser-dynamic": "18.2.8",
+ "@angular/router": "18.2.8",
+ "@ngx-resource/core": "n15.0.0",
+ "@ngx-resource/handler-ngx-http": "15.0.0",
+ "rxjs": "7.8.1",
+ "tslib": "2.7.0",
+ "zone.js": "0.14.10"
+ },
+ "devDependencies": {
+ "@angular-devkit/build-angular": "18.2.8",
+ "@angular/cli": "18.2.8",
+ "@angular/compiler-cli": "18.2.8",
+ "@types/jasmine": "5.1.4",
+ "autoprefixer": "10.4.20",
+ "cssnano": "7.0.5",
+ "jasmine-core": "5.3.0",
+ "karma": "6.4.4",
+ "karma-chrome-launcher": "3.2.0",
+ "karma-coverage": "2.2.1",
+ "karma-jasmine": "5.1.0",
+ "karma-jasmine-html-reporter": "2.1.0",
+ "postcss": "8.4.47",
+ "postcss-cli": "11.0.0",
+ "tslombok": "^1.2.6",
+ "typescript": "5.5.4"
+ }
+}
diff --git a/solr/webapp/web/solrUi/postcss.config.js b/solr/webapp/web/solrUi/postcss.config.js
new file mode 100644
index 00000000000..456f24ceb15
--- /dev/null
+++ b/solr/webapp/web/solrUi/postcss.config.js
@@ -0,0 +1,26 @@
+/*
+ * 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 = {
+ plugins: [
+ require('autoprefixer'),
+ require('cssnano')({
+ preset: 'default',
+ }),
+ ],
+};
diff --git a/solr/webapp/web/solrUi/src/app/app.component.html b/solr/webapp/web/solrUi/src/app/app.component.html
new file mode 100644
index 00000000000..c3175bb7f8a
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/app.component.html
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/solr/webapp/web/solrUi/src/app/app.component.scss b/solr/webapp/web/solrUi/src/app/app.component.scss
new file mode 100644
index 00000000000..171e9c7846f
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/app.component.scss
@@ -0,0 +1,209 @@
+/*!
+ * 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.
+ *
+ */
+
+$color_1: #c0c0c0;
+$color_2: #fff;
+$color_3: #4D4D4D;
+$color_4: #00f;
+$color_5: aqua;
+$color_6: #333;
+$background-color_1: #fafafa;
+$background-color_2: #f00;
+$background-color_3: #f0f0f0;
+$border-color_1: #c0c0c0;
+
+#content-wrapper {
+ margin-left: 150px;
+ border: 1px solid #c0c0c0;
+ min-height: 500px;
+}
+#content {
+ padding: 10px;
+ >.loader {
+ background-position: 0 50%;
+ padding-left: 21px;
+ }
+ iframe {
+ border: 0;
+ display: block;
+ min-height: 400px;
+ width: 100%;
+ }
+ .block {
+ margin-bottom: 10px;
+ h2 {
+ background-color: $background-color_1;
+ background-position: 5px 50%;
+ border-bottom: 1px solid #f0f0f0;
+ font-weight: bold;
+ padding: 5px;
+ padding-left: 26px;
+ }
+ .message {
+ padding: 5px;
+ }
+ .content {
+ padding: 5px;
+ }
+ }
+ .block.disabled {
+ color: $color_1;
+ h2 {
+ color: $color_1;
+ }
+ }
+ .tree {
+ li.jstree-last {
+ background: transparent;
+ }
+ .jstree-open {
+ >ins {
+ background-position: -36px 0;
+ }
+ }
+ .jstree-closed {
+ >ins {
+ background-position: -18px 0;
+ }
+ }
+ .jstree-leaf {
+ >ins {
+ background-position: 0 0;
+ }
+ a {
+ .jstree-icon {
+ background-image: url(../../../img/ico/document-text.png );
+ background-position: unset;
+ }
+ }
+ }
+ a.active {
+ background-color: $background-color_3;
+ color: $color_4;
+ }
+ a {
+ .jstree-icon {
+ background-image: url(../../../img/ico/folder.png );
+ background-position: unset;
+ }
+ }
+ .jstree-search {
+ font-style: italic;
+ }
+ a.jstree-search {
+ color: $color_5;
+ }
+ }
+ .address-bar {
+ margin-bottom: 10px;
+ margin-top: 10px;
+ background-image: url(../../../img/ico/ui-address-bar.png );
+ background-position: 5px 50%;
+ border: 1px solid #f0f0f0;
+ box-shadow: 1px 1px 0 #f0f0f0;
+ -moz-box-shadow: 1px 1px 0 #f0f0f0;
+ -webkit-box-shadow: 1px 1px 0 #f0f0f0;
+ color: $color_3;
+ display: block;
+ overflow: hidden;
+ padding: 5px;
+ padding-left: 26px;
+ white-space: nowrap;
+ &:focus {
+ border-color: $border-color_1;
+ box-shadow: 1px 1px 0 #d8d8d8;
+ -moz-box-shadow: 1px 1px 0 #d8d8d8;
+ -webkit-box-shadow: 1px 1px 0 #d8d8d8;
+ color: $color_6;
+ }
+ &:hover {
+ border-color: $border-color_1;
+ box-shadow: 1px 1px 0 #d8d8d8;
+ -moz-box-shadow: 1px 1px 0 #d8d8d8;
+ -webkit-box-shadow: 1px 1px 0 #d8d8d8;
+ color: $color_6;
+ }
+ }
+}
+.header-message {
+ border: 1px solid #f00;
+ margin-left: 150px;
+ margin-bottom: 20px;
+ h2 {
+ padding: 10px;
+ background-color: $background-color_2;
+ color: $color_2;
+ font-weight: bold;
+ }
+ ul {
+ padding: 10px;
+ }
+ p {
+ padding: 10px;
+ color: $color_3;
+ padding-top: 0;
+ }
+}
+#loading {
+ #http-exception {
+ display: none;
+ }
+}
+.clearfix {
+ &:after {
+ clear: both;
+ content: ".";
+ display: block;
+ font-size: 0;
+ height: 0;
+ visibility: hidden;
+ }
+ display: block;
+}
+#wrapper {
+ position: relative;
+ margin: 0 auto;
+ margin-bottom: 30px;
+ text-align: left;
+}
+#main {
+ min-width: 750px;
+ position: relative;
+}
+#main.error {
+ border: 0;
+ min-height: 0;
+ padding-top: 20px;
+ .message {
+ background-color: $background-color_2;
+ background-image: url(../../../img/ico/construction.png );
+ background-position: 10px 50%;
+ color: $color_2;
+ font-weight: bold;
+ margin-left: 150px;
+ margin-bottom: 20px;
+ padding: 10px;
+ padding-left: 35px;
+ }
+ .code {
+ border: 1px solid #c0c0c0;
+ padding: 5px;
+ }
+}
+
+@import "modules/dashboard/components/main/main.component";
diff --git a/solr/webapp/web/solrUi/src/app/app.component.ts b/solr/webapp/web/solrUi/src/app/app.component.ts
new file mode 100644
index 00000000000..967b33b2506
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/app.component.ts
@@ -0,0 +1,32 @@
+/*
+ * 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} from '@angular/core';
+import {RouterOutlet} from '@angular/router';
+import {DashboardModule} from "./modules/dashboard/dashboard.module";
+
+@Component({
+ selector: 'app-root',
+ standalone: true,
+ imports: [RouterOutlet, DashboardModule],
+ templateUrl: './app.component.html',
+ styleUrl: './app.component.scss'
+})
+export class AppComponent {
+ title = 'solrUi';
+}
diff --git a/solr/webapp/web/solrUi/src/app/app.config.ts b/solr/webapp/web/solrUi/src/app/app.config.ts
new file mode 100644
index 00000000000..78c764a065f
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/app.config.ts
@@ -0,0 +1,34 @@
+/*
+ * 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 {ApplicationConfig, InjectionToken} from '@angular/core';
+import {provideRouter} from '@angular/router';
+
+import {routes} from './app.routes';
+import {HttpClient, provideHttpClient, withFetch} from "@angular/common/http";
+import {ResourceHandlerHttpClient} from "@ngx-resource/handler-ngx-http";
+import {ResourceHandler} from "@ngx-resource/core";
+
+export const RES_HANDLER = new InjectionToken("RES_HANDLER");
+
+export function createResourceHandler(httpClient:HttpClient): ResourceHandler {
+ return new ResourceHandlerHttpClient(httpClient);
+}
+
+export const appConfig: ApplicationConfig = {
+ providers: [provideRouter(routes), provideHttpClient(withFetch()), { provide: RES_HANDLER, useFactory: createResourceHandler, deps:[HttpClient]}]
+};
diff --git a/solr/webapp/web/solrUi/src/app/app.routes.ts b/solr/webapp/web/solrUi/src/app/app.routes.ts
new file mode 100644
index 00000000000..ba599bba415
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/app.routes.ts
@@ -0,0 +1,20 @@
+/*
+ * 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 {Routes} from '@angular/router';
+
+export const routes: Routes = [];
diff --git a/solr/webapp/web/solrUi/src/app/modules/common/models/IResponseHeader.ts b/solr/webapp/web/solrUi/src/app/modules/common/models/IResponseHeader.ts
new file mode 100644
index 00000000000..ce6364b69bb
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/modules/common/models/IResponseHeader.ts
@@ -0,0 +1,21 @@
+/*
+ * 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.
+ */
+
+export interface IResponseHeader {
+ status: number | undefined;
+ qTime: number | undefined;
+}
diff --git a/solr/webapp/web/solrUi/src/app/modules/common/pipes/sizeconverter/size-unit-converter-pipe.pipe.ts b/solr/webapp/web/solrUi/src/app/modules/common/pipes/sizeconverter/size-unit-converter-pipe.pipe.ts
new file mode 100644
index 00000000000..89e45735652
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/modules/common/pipes/sizeconverter/size-unit-converter-pipe.pipe.ts
@@ -0,0 +1,50 @@
+/*
+ * 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 {Pipe, PipeTransform} from '@angular/core';
+
+
+@Pipe({
+ name: 'sizeUnitConverter'
+})
+export class SizeUnitConverterPipe implements PipeTransform {
+ private readonly unitNames: {short:string, long:string}[]= [
+ {short: "B", long: "Byte/s"},
+ {short: "KB", long: "Kilobyte/s"},
+ {short: "MB", long: "Megabyte/s"},
+ {short: "GB", long: "Gigabyte/s"},
+ {short: "TB", long: "Terabyte/s"},
+ {short: "PB", long: "Petabyte/s"},
+ {short: "EB", long: "Exabyte/s"},
+ {short: "ZB", long: "Zettabyte/s"},
+ {short: "YB", long: "Yottabyte/s"}
+ ];
+
+ private readonly decimalBase = 100;
+ private readonly base = 1024;
+
+ transform(sizeValue: number, isLong: boolean = false): string {
+
+ ;
+ let power = Math.round(Math.log(sizeValue) / Math.log(this.base));
+ let unit = isLong ? this.unitNames[power].short : this.unitNames[power].long;
+ let size = Math.round((sizeValue / Math.pow(this.base, power) ) * this.decimalBase) / this.decimalBase;
+
+ return `${size} ${unit}`;
+ }
+
+}
diff --git a/solr/webapp/web/solrUi/src/app/modules/common/pipes/timeconverter/time-ago.pipe.ts b/solr/webapp/web/solrUi/src/app/modules/common/pipes/timeconverter/time-ago.pipe.ts
new file mode 100644
index 00000000000..139b62e7a40
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/modules/common/pipes/timeconverter/time-ago.pipe.ts
@@ -0,0 +1,51 @@
+/*
+ * 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 {Pipe, PipeTransform} from '@angular/core';
+
+@Pipe({
+ name: 'timeAgo'
+})
+export class TimeAgoPipe implements PipeTransform {
+ private static YEAR_MS: number = 1000 * 60 * 60 * 24 * 7 * 4 * 12;
+ private static MAPPER: {single:string, many:string, div: number}[] = [
+ { single: 'a year ago', many: 'years', div: 1 },
+ { single: 'a month ago', many: 'months', div: 12 },
+ { single: 'a week ago', many: 'weeks', div: 4 },
+ { single: 'a day ago', many: 'days', div: 7 },
+ { single: 'an hour ago', many: 'hours', div: 24 },
+ { single: 'a minute ago', many: 'minutes', div: 60 },
+ ]
+ transform(value: number): string {
+ if (!value) {
+ return 'Invalid start time';
+ }
+
+ for (let i: number = 0, l = TimeAgoPipe.MAPPER.length, div: number = TimeAgoPipe.YEAR_MS; i < l; ++i) {
+ let elm = TimeAgoPipe.MAPPER[i];
+ let unit: number = Math.floor(value / (div /= elm.div));
+
+ if (unit >= 1) {
+ return unit === 1 ? elm.single : `${unit} ${elm.many} ago`;
+ }
+ }
+
+ return 'less than a minute';
+ }
+
+}
diff --git a/solr/webapp/web/solrUi/src/app/modules/common/shared.module.ts b/solr/webapp/web/solrUi/src/app/modules/common/shared.module.ts
new file mode 100644
index 00000000000..8d8f6cca7ab
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/modules/common/shared.module.ts
@@ -0,0 +1,50 @@
+/*
+ * 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 {NgModule} from '@angular/core';
+import {SizeUnitConverterPipe} from "./pipes/sizeconverter/size-unit-converter-pipe.pipe";
+import {TimeAgoPipe} from "./pipes/timeconverter/time-ago.pipe";
+import {CommonModule, NgClass, NgFor, NgIf} from "@angular/common";
+import {IResourceParams} from "@ngx-resource/core";
+import {environment} from "../../../environments/environment";
+
+
+@NgModule({
+ declarations: [SizeUnitConverterPipe, TimeAgoPipe],
+ imports: [CommonModule, NgClass, NgFor, NgIf],
+ exports: [SizeUnitConverterPipe, TimeAgoPipe, NgClass, NgFor, NgIf],
+})
+export class SharedModule {
+
+ static isOdd(id: number):boolean {
+ return (id & 1) !== 0
+ }
+
+ static getResourceSettings(path: string): IResourceParams{
+ if(environment.production){
+ return {
+ url: environment.apiUrl,
+ pathPrefix: path
+ }
+ }
+ return {
+ url: environment.apiUrl,
+ pathPrefix: path
+ }
+ }
+}
diff --git a/solr/webapp/web/solrUi/src/app/modules/common/utils/DateConverter.ts b/solr/webapp/web/solrUi/src/app/modules/common/utils/DateConverter.ts
new file mode 100644
index 00000000000..393bc89a6e3
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/modules/common/utils/DateConverter.ts
@@ -0,0 +1,28 @@
+/*
+ * 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.
+ */
+
+export class DateConverter {
+ private static pattern: string = '/.* (?\d{4}-\d{2}-\d{2}) .*/';
+
+ public static convertDateFromServerVersion(versionInfo: string): Date {
+ let found: RegExpMatchArray | null = versionInfo.match(this.pattern);
+
+
+ return (found && found.groups) ? new Date(found.groups['date']) : new Date();
+ }
+}
+
diff --git a/solr/webapp/web/solrUi/src/app/modules/dashboard/components/main/main.component.html b/solr/webapp/web/solrUi/src/app/modules/dashboard/components/main/main.component.html
new file mode 100644
index 00000000000..4dbf5c3dc09
--- /dev/null
+++ b/solr/webapp/web/solrUi/src/app/modules/dashboard/components/main/main.component.html
@@ -0,0 +1,164 @@
+
+
+
+
+
+
+
Instance
+
+
+
+
Start
+
{{startTime() | timeAgo}}
+
+
+
+
+
+
Versions
+
+
+
+
solr-spec
+
{{solrSpecificationVersion()}}
+
+
+
solr-impl
+
{{solrImplementationVersion()}}
+
+
+
lucene-spec
+
{{luceneSpecificationVersion()}}
+
+
+
lucene-impl
+
{{luceneImplementationVersion()}}
+
+
+
+
+
WARNING: This Solr release is more than a year old. Consider upgrading.