From fe91d794c31baee54451db6e4083920b3237ecaf Mon Sep 17 00:00:00 2001
From: Daniel Crazzolara <crazzolaradaniel@gmail.com>
Date: Thu, 1 Jul 2021 19:27:31 +0200
Subject: [PATCH] Implemented gitlab groups selector

---
 .../gitlab-path-selector.component.html       | 53 +++++++++++++++++++
 .../gitlab-path-selector.component.scss       |  0
 .../gitlab-path-selector.component.ts         | 49 +++++++++++++++++
 .../webapp/app/shared/gitlab/gitlab.module.ts | 10 ++++
 .../app/shared/gitlab/gitlab.service.ts       | 30 +++++++++++
 .../app/shared/model/gitlab-group.model.ts    | 21 ++++++++
 src/main/webapp/i18n/de/gitlabModal.json      | 12 +++++
 src/main/webapp/i18n/en/gitlabModal.json      | 12 +++++
 8 files changed, 187 insertions(+)
 create mode 100644 src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html
 create mode 100644 src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.scss
 create mode 100644 src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.ts
 create mode 100644 src/main/webapp/app/shared/gitlab/gitlab.module.ts
 create mode 100644 src/main/webapp/app/shared/gitlab/gitlab.service.ts
 create mode 100644 src/main/webapp/app/shared/model/gitlab-group.model.ts
 create mode 100644 src/main/webapp/i18n/de/gitlabModal.json
 create mode 100644 src/main/webapp/i18n/en/gitlabModal.json

diff --git a/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html b/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html
new file mode 100644
index 000000000..a941deda8
--- /dev/null
+++ b/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.html
@@ -0,0 +1,53 @@
+<div>
+    <div class="modal-header">
+        <h4 class="modal-title" jhiTranslate="gitlab.pathSelector.title">Gitlab Path</h4>
+        <button type="button" class="close" data-dismiss="modal" aria-hidden="true" (click)="closeModal(undefined)">&times;</button>
+    </div>
+    <div class="modal-body">
+        <div class="justify-content-center p-1">
+            <jhi-alert></jhi-alert>
+            <jhi-alert-error></jhi-alert-error>
+            <div class="table-responsive p-1">
+                <table class="table table-striped">
+                    <thead>
+                    <tr>
+                        <th></th>
+                        <th><span jhiTranslate="gitlab.pathSelector.name">Name</span></th>
+                        <th><span jhiTranslate="gitlab.pathSelector.description">Description</span></th>
+                        <th><span jhiTranslate="gitlab.pathSelector.visibility">Visibility</span></th>
+                        <th><span jhiTranslate="gitlab.pathSelector.url">URL</span></th>
+                    </tr>
+                    </thead>
+                    <tbody>
+                    <tr *ngFor="let group of groups">
+                        <td>
+                            <img
+                                [height]="48"
+                                src="{{ group.avatarUrl ? group.avatarUrl : '' }}"/>
+                                <!--onerror="this.src='/content/images/image-placeholder.png'"
+                            />-->
+                        </td>
+                        <td>
+                            <strong>{{group.name}}</strong>
+                        </td>
+                        <td>
+                            <span>{{group.description}}</span>
+                        </td>
+                        <td>
+                            <span>{{group.visibility}}</span>
+                        </td>
+                        <td>
+                            <span>{{group.webUrl}}</span>
+                        </td>
+                        <td>
+                            <button type="button" class="btn ml-2 btn-primary" (click)="closeModal(group)" jhiTranslate="gitlab.pathSelector.select">
+                                Select
+                            </button>
+                        </td>
+                    </tr>
+                    </tbody>
+                </table>
+            </div>
+        </div>
+    </div>
+</div>
diff --git a/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.scss b/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.scss
new file mode 100644
index 000000000..e69de29bb
diff --git a/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.ts b/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.ts
new file mode 100644
index 000000000..824a4bbf1
--- /dev/null
+++ b/src/main/webapp/app/shared/gitlab/gitlab-path-selector/gitlab-path-selector.component.ts
@@ -0,0 +1,49 @@
+import { Component, OnInit } from '@angular/core';
+import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
+import { JhiAlertService } from 'ng-jhipster';
+import { GitlabGroup } from 'app/shared/model/gitlab-group.model';
+import { GitlabService } from 'app/shared/gitlab/gitlab.service';
+
+@Component({
+  selector: 'jhi-gitlab-path-selector',
+  templateUrl: './gitlab-path-selector.component.html',
+  styleUrls: ['./gitlab-path-selector.component.scss'],
+})
+export class GitlabPathSelectorComponent implements OnInit {
+  groups: GitlabGroup[] | undefined;
+  subgroups: GitlabGroup[] | undefined;
+
+  constructor(private activeModal: NgbActiveModal, private jhiAlertService: JhiAlertService, private gitlabService: GitlabService) {}
+
+  ngOnInit(): void {
+    this.gitlabService.getGroups().subscribe(
+      data => {
+        this.groups = data;
+      },
+      error => {
+        this.jhiAlertService.error(error.error);
+      }
+    );
+  }
+
+  /**
+   * Utility function used to retrieve the upper groups in the
+   * hierarchy
+   */
+  getParentGroups() {
+    return this.groups?.filter(group => !group.parentId);
+  }
+
+  /**
+   * Utility function used to retrieve the subgroups of
+   * a given group
+   * @param group to search for subGroups
+   */
+  getSubGroupsOfGroup(group: GitlabGroup) {
+    return this.groups?.filter(subGroup => subGroup.parentId === group.id);
+  }
+
+  closeModal(group: GitlabGroup | undefined) {
+    this.activeModal.close(group);
+  }
+}
diff --git a/src/main/webapp/app/shared/gitlab/gitlab.module.ts b/src/main/webapp/app/shared/gitlab/gitlab.module.ts
new file mode 100644
index 000000000..76b2eaaf7
--- /dev/null
+++ b/src/main/webapp/app/shared/gitlab/gitlab.module.ts
@@ -0,0 +1,10 @@
+import { NgModule } from '@angular/core';
+import { CommonModule } from '@angular/common';
+import { GitlabPathSelectorComponent } from './gitlab-path-selector/gitlab-path-selector.component';
+import { GitSearchV2SharedModule } from 'app/shared/shared.module';
+
+@NgModule({
+  imports: [CommonModule, GitSearchV2SharedModule],
+  declarations: [GitlabPathSelectorComponent],
+})
+export class GitlabModule {}
diff --git a/src/main/webapp/app/shared/gitlab/gitlab.service.ts b/src/main/webapp/app/shared/gitlab/gitlab.service.ts
new file mode 100644
index 000000000..a4ced30e3
--- /dev/null
+++ b/src/main/webapp/app/shared/gitlab/gitlab.service.ts
@@ -0,0 +1,30 @@
+import { Injectable } from '@angular/core';
+import { HttpClient } from '@angular/common/http';
+import { SERVER_API_URL } from 'app/app.constants';
+import { GitlabGroup } from 'app/shared/model/gitlab-group.model';
+import { Observable } from 'rxjs';
+
+@Injectable({
+  providedIn: 'root',
+})
+export class GitlabService {
+  public resourceUrl = SERVER_API_URL + 'api/gitlab/';
+
+  constructor(private http: HttpClient) {}
+
+  /**
+   * Used to retrieve all groups of current user
+   * (As user: their groups, as admin: all groups)
+   */
+  public getGroups(): Observable<Array<GitlabGroup>> {
+    return this.http.get<Array<GitlabGroup>>(`${this.resourceUrl}groups`);
+  }
+
+  /**
+   * used to retrieve subgroups of a given Gitlab group
+   * @param group to retrieve its subgroups
+   */
+  public getSubGroups(group: GitlabGroup): Observable<Array<GitlabGroup>> {
+    return this.http.get<Array<GitlabGroup>>(`${this.resourceUrl}subgroups/${group.id}`);
+  }
+}
diff --git a/src/main/webapp/app/shared/model/gitlab-group.model.ts b/src/main/webapp/app/shared/model/gitlab-group.model.ts
new file mode 100644
index 000000000..a3947f3bd
--- /dev/null
+++ b/src/main/webapp/app/shared/model/gitlab-group.model.ts
@@ -0,0 +1,21 @@
+export enum IVisibility {
+  PUBLIC = 'public',
+  PRIVATE = 'private',
+  INTERNAL = 'internal',
+}
+
+/**
+ * Gitlab Group model basing on org.gitlab4j.api.models.Group
+ */
+export interface GitlabGroup {
+  id: number;
+  name: string;
+  path: string;
+  description: string;
+  visibility: IVisibility;
+  avatarUrl: string;
+  webUrl: string;
+  fullName: string;
+  fullPath: string;
+  parentId: number;
+}
diff --git a/src/main/webapp/i18n/de/gitlabModal.json b/src/main/webapp/i18n/de/gitlabModal.json
new file mode 100644
index 000000000..73e1fe334
--- /dev/null
+++ b/src/main/webapp/i18n/de/gitlabModal.json
@@ -0,0 +1,12 @@
+{
+  "gitlab": {
+    "pathSelector": {
+      "title": "Gitlab Pfad",
+      "name": "Name",
+      "description": "Beschreibung",
+      "url": "URL",
+      "visibility": "Freischaltung",
+      "select": "Auswählen"
+    }
+  }
+}
diff --git a/src/main/webapp/i18n/en/gitlabModal.json b/src/main/webapp/i18n/en/gitlabModal.json
new file mode 100644
index 000000000..14a18e97e
--- /dev/null
+++ b/src/main/webapp/i18n/en/gitlabModal.json
@@ -0,0 +1,12 @@
+{
+  "gitlab": {
+    "pathSelector": {
+      "title": "Gitlab Path",
+      "name": "Name",
+      "description": "Description",
+      "url": "URL",
+      "visibility": "Visibility",
+      "select": "Select"
+    }
+  }
+}
-- 
GitLab