You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@archiva.apache.org by ma...@apache.org on 2020/11/07 12:38:39 UTC

[archiva] branch master updated (20f3b50 -> 88b27de)

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

martin_s pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git.


    from 20f3b50  Adding tooltip
     new d89b03d  Adding todos
     new 88b27de  Improving user view in ng

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 .../security/ArchivaConfigurableUsersManager.java  |   4 +
 .../src/main/archiva-web/package-lock.json         | 217 +++++++++++++++++++++
 .../src/main/archiva-web/package.json              |   4 +-
 .../src/main/archiva-web/src/app/app.module.ts     |   4 +-
 .../archiva-web/src/app/model/paged-result.spec.ts |   7 +
 .../main/archiva-web/src/app/model/paged-result.ts |   6 +
 .../src/app/model/pagination-info.spec.ts          |   7 +
 .../archiva-web/src/app/model/pagination-info.ts   |   5 +
 .../manage-users-list.component.html               |  21 +-
 .../manage-users-list.component.ts                 |  52 ++++-
 .../archiva-web/src/app/services/user.service.ts   |   5 +
 .../src/main/archiva-web/src/assets/i18n/en.json   |   5 +-
 .../src/main/archiva-web/src/polyfills.ts          |   3 +-
 13 files changed, 329 insertions(+), 11 deletions(-)
 create mode 100644 archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.spec.ts
 create mode 100644 archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.ts
 create mode 100644 archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.spec.ts
 create mode 100644 archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.ts


[archiva] 01/02: Adding todos

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit d89b03d0581b3887d4046bf5f07c831074f4ef52
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sat Nov 7 13:38:12 2020 +0100

    Adding todos
---
 .../apache/archiva/web/security/ArchivaConfigurableUsersManager.java  | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaConfigurableUsersManager.java b/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaConfigurableUsersManager.java
index 969f0ea..866083a 100644
--- a/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaConfigurableUsersManager.java
+++ b/archiva-modules/archiva-web/archiva-web-common/src/main/java/org/apache/archiva/web/security/ArchivaConfigurableUsersManager.java
@@ -149,6 +149,10 @@ public class ArchivaConfigurableUsersManager
         return user;
     }
 
+    /*
+     * TODO: This must be refactored. This does not work for multiple user managers.
+     *  We need a combined user query that merges results
+     */
     @Override
     public UserQuery createUserQuery()
     {


[archiva] 02/02: Improving user view in ng

Posted by ma...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

martin_s pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/archiva.git

commit 88b27de5e28c724b18d63d2ca342c1aaf1fea589
Author: Martin Stockhammer <ma...@apache.org>
AuthorDate: Sat Nov 7 13:38:32 2020 +0100

    Improving user view in ng
---
 .../src/main/archiva-web/package-lock.json         | 217 +++++++++++++++++++++
 .../src/main/archiva-web/package.json              |   4 +-
 .../src/main/archiva-web/src/app/app.module.ts     |   4 +-
 .../archiva-web/src/app/model/paged-result.spec.ts |   7 +
 .../main/archiva-web/src/app/model/paged-result.ts |   6 +
 .../src/app/model/pagination-info.spec.ts          |   7 +
 .../archiva-web/src/app/model/pagination-info.ts   |   5 +
 .../manage-users-list.component.html               |  21 +-
 .../manage-users-list.component.ts                 |  52 ++++-
 .../archiva-web/src/app/services/user.service.ts   |   5 +
 .../src/main/archiva-web/src/assets/i18n/en.json   |   5 +-
 .../src/main/archiva-web/src/polyfills.ts          |   3 +-
 12 files changed, 325 insertions(+), 11 deletions(-)

diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json
index 5ca161b..e3aaebc 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package-lock.json
@@ -535,6 +535,215 @@
         "tslib": "^2.0.0"
       }
     },
+    "@angular/localize": {
+      "version": "10.2.0",
+      "resolved": "https://registry.npmjs.org/@angular/localize/-/localize-10.2.0.tgz",
+      "integrity": "sha512-hAtmjdPs8BLQfHPtYUSFFDSn1mv/OoMxDO2iXdnvPQ5HBVIHuHb9qrpY3twX8LutJf2O175cJR7OB66DljuBmA==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "7.8.3",
+        "glob": "7.1.2",
+        "yargs": "15.3.0"
+      },
+      "dependencies": {
+        "@babel/core": {
+          "version": "7.8.3",
+          "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz",
+          "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.8.3",
+            "@babel/generator": "^7.8.3",
+            "@babel/helpers": "^7.8.3",
+            "@babel/parser": "^7.8.3",
+            "@babel/template": "^7.8.3",
+            "@babel/traverse": "^7.8.3",
+            "@babel/types": "^7.8.3",
+            "convert-source-map": "^1.7.0",
+            "debug": "^4.1.0",
+            "gensync": "^1.0.0-beta.1",
+            "json5": "^2.1.0",
+            "lodash": "^4.17.13",
+            "resolve": "^1.3.2",
+            "semver": "^5.4.1",
+            "source-map": "^0.5.0"
+          }
+        },
+        "ansi-regex": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz",
+          "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "cliui": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz",
+          "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==",
+          "dev": true,
+          "requires": {
+            "string-width": "^4.2.0",
+            "strip-ansi": "^6.0.0",
+            "wrap-ansi": "^6.2.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true
+        },
+        "emoji-regex": {
+          "version": "8.0.0",
+          "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+          "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+          "dev": true
+        },
+        "find-up": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz",
+          "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^5.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+          "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+          "dev": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+          "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+          "dev": true
+        },
+        "locate-path": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
+          "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^4.1.0"
+          }
+        },
+        "p-locate": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz",
+          "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.2.0"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
+        "semver": {
+          "version": "5.7.1",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz",
+          "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "4.2.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz",
+          "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^8.0.0",
+            "is-fullwidth-code-point": "^3.0.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz",
+          "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^5.0.0"
+          }
+        },
+        "wrap-ansi": {
+          "version": "6.2.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
+          "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^4.0.0",
+            "string-width": "^4.1.0",
+            "strip-ansi": "^6.0.0"
+          }
+        },
+        "yargs": {
+          "version": "15.3.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.0.tgz",
+          "integrity": "sha512-g/QCnmjgOl1YJjGsnUg2SatC7NUYEiLXJqxNOQU9qSpjzGtGXda9b+OKccr1kLTy8BN9yqEyqfq5lxlwdc13TA==",
+          "dev": true,
+          "requires": {
+            "cliui": "^6.0.0",
+            "decamelize": "^1.2.0",
+            "find-up": "^4.1.0",
+            "get-caller-file": "^2.0.1",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^2.0.0",
+            "set-blocking": "^2.0.0",
+            "string-width": "^4.2.0",
+            "which-module": "^2.0.0",
+            "y18n": "^4.0.0",
+            "yargs-parser": "^18.1.0"
+          }
+        },
+        "yargs-parser": {
+          "version": "18.1.3",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz",
+          "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
+      }
+    },
     "@angular/platform-browser": {
       "version": "10.2.0",
       "resolved": "https://registry.npmjs.org/@angular/platform-browser/-/platform-browser-10.2.0.tgz",
@@ -1733,6 +1942,14 @@
         "schema-utils": "^2.7.0"
       }
     },
+    "@ng-bootstrap/ng-bootstrap": {
+      "version": "8.0.0",
+      "resolved": "https://registry.npmjs.org/@ng-bootstrap/ng-bootstrap/-/ng-bootstrap-8.0.0.tgz",
+      "integrity": "sha512-v77Gfd8xHH+exq0WqIqVRlxbUEHdA/2+RUJenUP2IDTQN9E1rWl7O461/kosr+0XPuxPArHQJxhh/WsCYckcNg==",
+      "requires": {
+        "tslib": "^2.0.0"
+      }
+    },
     "@ngtools/webpack": {
       "version": "10.2.0",
       "resolved": "https://registry.npmjs.org/@ngtools/webpack/-/webpack-10.2.0.tgz",
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json
index 060bd99..113e3a1 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/package.json
@@ -21,6 +21,7 @@
     "@angular/router": "~10.2.0",
     "@fortawesome/fontawesome-free": "^5.13.1",
     "@fortawesome/fontawesome-svg-core": "^1.2.29",
+    "@ng-bootstrap/ng-bootstrap": "^8.0.0",
     "@ngx-translate/core": "^13.0.0",
     "@ngx-translate/http-loader": "^6.0.0",
     "bootstrap": "^4.5.0",
@@ -36,9 +37,10 @@
     "@angular-devkit/build-angular": "~0.1002.0",
     "@angular/cli": "~10.2.0",
     "@angular/compiler-cli": "~10.2.0",
-    "@types/node": "^12.11.1",
+    "@angular/localize": "^10.2.0",
     "@types/jasmine": "~3.5.0",
     "@types/jasminewd2": "~2.0.3",
+    "@types/node": "^12.11.1",
     "codelyzer": "^6.0.0-next.1",
     "jasmine-core": "~3.5.0",
     "jasmine-spec-reporter": "~5.0.0",
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts
index 1fe0382..3535437 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/app.module.ts
@@ -42,6 +42,7 @@ import { SecurityConfigurationComponent } from './modules/user/security-configur
 import { ManageUsersListComponent } from './modules/user/users/manage-users-list/manage-users-list.component';
 import { ManageUsersAddComponent } from './modules/user/users/manage-users-add/manage-users-add.component';
 import { EnableTooltipDirective } from './directives/enable-tooltip.directive';
+import {NgbPagination, NgbPaginationModule} from "@ng-bootstrap/ng-bootstrap";
 
 
 @NgModule({
@@ -79,7 +80,8 @@ import { EnableTooltipDirective } from './directives/enable-tooltip.directive';
         useFactory: httpTranslateLoader,
         deps: [HttpClient]
       }
-    })
+    }),
+      NgbPaginationModule
   ],
   providers: [],
   bootstrap: [AppComponent]
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.spec.ts
new file mode 100644
index 0000000..c3ca58a
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.spec.ts
@@ -0,0 +1,7 @@
+import { PagedResult } from './paged-result';
+
+describe('PagedResult', () => {
+  it('should create an instance', () => {
+    expect(new PagedResult()).toBeTruthy();
+  });
+});
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.ts
new file mode 100644
index 0000000..08c3caa
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/paged-result.ts
@@ -0,0 +1,6 @@
+import {PaginationInfo} from "./pagination-info";
+
+export class PagedResult<T> {
+    pagination : PaginationInfo;
+    data : Array<T>;
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.spec.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.spec.ts
new file mode 100644
index 0000000..64d8e03
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.spec.ts
@@ -0,0 +1,7 @@
+import { PaginationInfo } from './pagination-info';
+
+describe('PaginationInfo', () => {
+  it('should create an instance', () => {
+    expect(new PaginationInfo()).toBeTruthy();
+  });
+});
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.ts
new file mode 100644
index 0000000..d67070f
--- /dev/null
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/model/pagination-info.ts
@@ -0,0 +1,5 @@
+export class PaginationInfo {
+    totalCount : number;
+    offset: number;
+    limit: number;
+}
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.html b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.html
index 2f36763..98be856 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.html
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.html
@@ -21,8 +21,8 @@
     <div class="form-row align-items-center">
         <div class="col-lg-4 col-md-2 col-sm-1">
             <label class="sr-only" for="searchQuery">{{'users.list.search' |translate}}</label>
-            <input type="text" class="form-control" id="searchQuery" placeholder="Search" data-toggle="tooltip"
-                   data-placement="top" title="SEARCHHH">
+            <input type="text" class="form-control" id="searchQuery" placeholder="Search" #searchTerm
+            (keyup)="search(searchTerm.value)">
         </div>
         <div class="col-auto">
             <button type="submit" class="btn btn-primary">{{'search.button'|translate}}</button>
@@ -32,7 +32,7 @@
 
 </form>
 
-<table class="table" appEnableTooltip>
+<table class="table table-striped table-bordered" appEnableTooltip>
     <thead class="thead-light">
     <tr>
         <th scope="col">{{'users.list.table.head.id' | translate}}</th>
@@ -49,8 +49,23 @@
         </th>
         <th scope="col">{{'users.list.table.head.lastLogin' | translate}}</th>
         <th scope="col">{{'users.list.table.head.created' | translate}}</th>
+        <th scope="col">{{'users.list.table.head.lastPwChange' | translate}}</th>
     </tr>
     </thead>
     <tbody>
+    <tr *ngFor="let user of items$ | async"  [ngClass]="user.permanent?'table-secondary':''">
+        <td>{{user.id}}</td>
+        <td>{{user.user_id}}</td>
+        <td>{{user.fullName}}</td>
+        <td>{{user.email}}</td>
+        <td><span class="far" [attr.aria-valuetext]="user.validated" [ngClass]="user.validated?'fa-check-circle':'fa-circle'"></span></td>
+        <td><span class="far" [attr.aria-valuetext]="user.locked" [ngClass]="user.locked?'fa-check-circle':'fa-circle'"></span></td>
+        <td><span class="far" [attr.aria-valuetext]="user.passwordChangeRequired" [ngClass]="user.passwordChangeRequired?'fa-check-circle':'fa-circle'"></span></td>
+        <td>{{user.timestampLastLogin | date:'yyyy-MM-ddTHH:mm:ss'}}</td>
+        <td>{{user.timestampAccountCreation | date : 'yyyy-MM-ddTHH:mm:ss'}}</td>
+        <td>{{user.timestampLastPasswordChange| date : 'yyyy-MM-ddTHH:mm:ss'}}</td>
+    </tr>
     </tbody>
 </table>
+
+<ngb-pagination [collectionSize]="total$|async" maxSize="2" rotate="true" [(page)]="page" (pageChange)="changePage($event)" aria-label="Default pagination"></ngb-pagination>
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.ts
index 22625a7..d7629a9 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.ts
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/modules/user/users/manage-users-list/manage-users-list.component.ts
@@ -19,8 +19,11 @@
 
 import { Component, OnInit, Input } from '@angular/core';
 import {TranslateService} from "@ngx-translate/core";
-import {AppComponent} from "../../../../app.component";
 import {UserService} from "../../../../services/user.service";
+import {Observable, Subject, merge} from 'rxjs';
+import { map, pluck, debounceTime, distinctUntilChanged, startWith, mergeMap} from "rxjs/operators";
+import {UserInfo} from "../../../../model/user-info";
+
 
 @Component({
   selector: 'app-manage-users-list',
@@ -29,18 +32,61 @@ import {UserService} from "../../../../services/user.service";
 })
 export class ManageUsersListComponent implements OnInit {
   @Input() heads: any;
+  page = 1;
+  pageSize = 10;
+  total$: Observable<number>;
+  items$: Observable<UserInfo[]>;
+  searchTerm: string;
+  private pageStream: Subject<number> = new Subject<number>();
+  private searchTermStream: Subject<string> = new Subject<string>();
 
   constructor(private translator: TranslateService, private userService : UserService) { }
 
   ngOnInit(): void {
-    this.heads={};
+    this.heads = {};
     // We need to wait for the translator initialization and use the init key as step in.
-    this.translator.get('init').subscribe( () => {
+    this.translator.get('init').subscribe(() => {
       // Only table headings for small columns that use icons
       for (let suffix of ['validated', 'locked', 'pwchange']) {
         this.heads[suffix] = this.translator.instant('users.list.table.head.' + suffix);
       }
     });
+    const pageSource = this.pageStream.pipe(map(pageNumber => {
+      return {search: this.searchTerm, page: pageNumber}
+    }));
+    const searchSource = this.searchTermStream.pipe(
+        debounceTime(1000),
+        distinctUntilChanged(),
+        map(searchTerm => {
+          this.searchTerm = searchTerm;
+          console.log("Search term " + searchTerm);
+          return {search: searchTerm, page: 1}
+        }));
+    const source = merge(pageSource, searchSource).pipe(
+    startWith({search: this.searchTerm, page: this.page}),
+        mergeMap((params: { search: string, page: number }) => {
+          console.log("Executing user list " + params.search);
+          return this.userService.getUserList(params.search, params.page*this.pageSize, this.pageSize)
+        }));
+
+    this.total$ = source.pipe(pluck('pagination.total'));
+    this.items$ = source.pipe(pluck('data'));
+
+
+
+    // const pageSource = map(pageNumber => {
+    //   this.page = pageNumber
+    //   return {search: this.searchTerm, page: pageNumber}
+    // })
+  }
+  search(terms: string) {
+    console.log("Keystroke " + terms);
+    this.searchTermStream.next(terms)
+  }
+
+  changePage(pageNumber : number) {
+    console.log("Page change " +typeof(pageNumber) +":" + JSON.stringify(pageNumber));
+    this.pageStream.next(pageNumber);
   }
 
 }
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts
index a1cc652..21f9d1a 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/app/services/user.service.ts
@@ -23,6 +23,7 @@ import {HttpErrorResponse} from "@angular/common/http";
 import {ErrorResult} from "../model/error-result";
 import {Observable} from "rxjs";
 import {Permission} from '../model/permission';
+import {PagedResult} from "../model/paged-result";
 
 @Injectable({
     providedIn: 'root'
@@ -257,4 +258,8 @@ export class UserService implements OnInit, OnDestroy {
         this.authenticated = false;
     }
 
+    public getUserList(searchTerm : string, offset : number = 0, limit : number = 10) : Observable<PagedResult<UserInfo>>  {
+        return this.rest.executeRestCall<PagedResult<UserInfo>>("get", "redback", "users", {'offset':offset,'limit':limit});
+    }
+
 }
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json
index d43bd2a..3e212d7 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/assets/i18n/en.json
@@ -55,14 +55,15 @@
       "table":{
         "head": {
           "id": "ID",
-          "user_id": "User Identifier",
+          "user_id": "Login Name",
           "email": "Email",
           "fullName": "Name",
           "validated": "User Validated",
           "locked": "User Locked",
           "pwchange": "Password Change Required",
           "lastLogin": "Last Login",
-          "created": "Created"
+          "created": "Created",
+          "lastPwChange": "Last Password Change"
         }
       }
     },
diff --git a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/polyfills.ts b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/polyfills.ts
index 488506e..b704a5e 100644
--- a/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/polyfills.ts
+++ b/archiva-modules/archiva-web/archiva-webapp/src/main/archiva-web/src/polyfills.ts
@@ -19,7 +19,8 @@
 /***************************************************************************************************
  * Load `$localize` onto the global scope - used if i18n tags appear in Angular templates.
  */
-// import '@angular/localize/init';
+// We don't use it, but ng-bootstrap needs it.
+import '@angular/localize/init';
 /**
  * This file includes polyfills needed by Angular and is loaded before the app.
  * You can add your own extra polyfills to this file.