Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 20 additions & 0 deletions src/app/components/admin-navbar/admin-navbar.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,26 @@ export class AdminNavbarComponent {
},
],
},
{
title: "Github bot",
links: [
{
title: "Запрошенные профили",
url: "/admin/github/profiles",
isExternal: false,
},
{
title: "Чаты",
url: "/admin/github/chats",
isExternal: false,
},
{
title: "Джобы",
url: "/admin/github/processing-jobs",
isExternal: false,
},
],
},
{
title: "Инструменты",
links: [
Expand Down
24 changes: 24 additions & 0 deletions src/app/models/github.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
export interface GitHubProfile {
username: string;
version: number;
requestsCount: number;
dataSyncedAt: Date;
createdAt: Date;
updatedAt: Date;
}

export interface GitHubChat {
id: string;
chatId: number;
username: string;
isAdmin: boolean;
messagesCount: number;
createdAt: Date;
updatedAt: Date;
}

export interface GitHubProcessingJob {
username: string;
createdAt: Date;
updatedAt: Date;
}
7 changes: 7 additions & 0 deletions src/app/modules/admin/admin-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ import { CompaniesAdminPageComponent } from "./components/companies/companies-ad
import { CompanyAdminPageComponent } from "./components/companies/company-admin-page/company-admin-page.component";
import { ReviewsToApprovePageComponent } from "./components/companies/reviews-to-approve/reviews-to-approve-page.component";
import { InlineRepliesStatsComponent } from "./components/telegram/inline-replies-stats/inline-replies-stats.component";
import { GitHubProfilesPageComponent } from "./components/github/github-profiles-page/github-profiles-page.component";
import { GitHubChatsPageComponent } from "./components/github/github-chats-page/github-chats-page.component";
import { GitHubJobsPageComponent } from "./components/github/github-jobs-page/github-jobs-page.component";

const routes: Routes = [
{ path: "", component: AdminStartPageComponent },
Expand Down Expand Up @@ -61,6 +64,10 @@ const routes: Routes = [
component: ReviewsToApprovePageComponent,
},
{ path: "companies/:id", component: CompanyAdminPageComponent },

{ path: "github/profiles", component: GitHubProfilesPageComponent },
{ path: "github/chats", component: GitHubChatsPageComponent },
{ path: "github/processing-jobs", component: GitHubJobsPageComponent },
];

@NgModule({
Expand Down
9 changes: 8 additions & 1 deletion src/app/modules/admin/admin.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ import { StatDataCacheRecordsComponent } from "./components/telegram/stat-data-c
import { GenerateQrPageComponent } from "./components/generate-qr-code-page/generate-qr-page.component";
import { CurrenciesPageComponent } from "./components/currencies-page/currencies-page.component";
import { AdminDashboardService } from "./services/admin-dashboard.service";
import { GitHubAdminService } from "@services/github-admin.service";
import { CompaniesAdminPageComponent } from "./components/companies/companies-admin-page/companies-admin-page.component";
import { CompanyAdminPageComponent } from "./components/companies/company-admin-page/company-admin-page.component";
import { ReviewsToApprovePageComponent } from "./components/companies/reviews-to-approve/reviews-to-approve-page.component";
import { InlineRepliesStatsComponent } from "./components/telegram/inline-replies-stats/inline-replies-stats.component";
import { GitHubProfilesPageComponent } from "./components/github/github-profiles-page/github-profiles-page.component";
import { GitHubChatsPageComponent } from "./components/github/github-chats-page/github-chats-page.component";
import { GitHubJobsPageComponent } from "./components/github/github-jobs-page/github-jobs-page.component";

const adminServices = [AdminDashboardService];
const adminServices = [AdminDashboardService, GitHubAdminService];

@NgModule({
declarations: [
Expand All @@ -54,6 +58,9 @@ const adminServices = [AdminDashboardService];
CompanyAdminPageComponent,
ReviewsToApprovePageComponent,
InlineRepliesStatsComponent,
GitHubProfilesPageComponent,
GitHubChatsPageComponent,
GitHubJobsPageComponent,
],
imports: [
CommonModule,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -199,18 +199,18 @@
<div class="mb-2">
<span class="text-muted">Среднее: </span>
<span class="fw-bold ms-2">{{
reviewToShow?.totalRating | number: "1.2-2"
reviewToShow.totalRating | number: "1.2-2"
}}</span>
</div>

<div class="mb-2">
<div class="fw-bold text-success">Плюсы</div>
<div [innerHTML]="reviewToShow?.pros"></div>
<div [innerHTML]="reviewToShow.pros"></div>
</div>

<div class="mb-2">
<div class="fw-bold text-danger">Минусы</div>
<div [innerHTML]="reviewToShow?.cons"></div>
<div [innerHTML]="reviewToShow.cons"></div>
</div>

<div class="mb-2">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<app-page-header>Чаты с Github Bot</app-page-header>

<div class="container my-5" *ngIf="chats; else dataLoading">
<div class="card">
<div class="card-body">
<!-- Search Field -->
<div class="row mb-3">
<div class="col-md-4">
<label for="search" class="form-label">Поиск по названию чата</label>
<input
type="text"
class="form-control form-control-sm"
id="search"
name="search"
[(ngModel)]="searchQuery"
placeholder="Введите название чата..."
/>
</div>
<div class="col-md-2 d-flex align-items-end">
<button
type="button"
class="btn btn-sm btn-outline-primary"
(click)="onSearch()"
>
Поиск
</button>
<button
type="button"
class="btn btn-sm btn-outline-dark ms-2"
(click)="clearSearch()"
>
Сброс
</button>
</div>
</div>

<div
class="table-responsive mb-3"
*ngIf="chats && chats.length > 0; else nothingToShow"
>
<table class="table table-hover table-sm">
<thead class="small">
<th>Chat ID</th>
<th>Username</th>
<th>Обращений</th>
<th>Admin?</th>
<th>Создано</th>
<th>Обновлено</th>
</thead>
<tbody>
<tr class="small" *ngFor="let chat of chats; let i = index">
<td>{{ chat.chatId }}</td>
<td>{{ chat.username }}</td>
<td>{{ chat.messagesCount | formatAsMoney }}</td>
<td>{{ chat.isAdmin }}</td>
<td>{{ chat.createdAt | date: "yyyy-MM-dd HH:mm" }}</td>
<td>{{ chat.updatedAt | date: "yyyy-MM-dd HH:mm" }}</td>
</tr>
</tbody>
</table>
</div>

<div class="" *ngIf="source && source.results.length > 0">
<app-pagination-buttons
[source]="source"
(pageChange)="loadData($event)"
></app-pagination-buttons>
</div>
</div>
</div>
</div>

<ng-template #nothingToShow>
<div class="card">
<div class="card-body">
<div class="text-center">Нет данных.</div>
</div>
</div>
</ng-template>

<ng-template #dataLoading>
<div class="container mt-5">
<app-data-loader></app-data-loader>
</div>
</ng-template>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import {
mostUsedImports,
testUtilStubs,
mostUsedServices,
} from "@shared/test-utils";
import { GitHubChatsPageComponent } from "./github-chats-page.component";
import { GitHubAdminService } from "@services/github-admin.service";

describe("GitHubChatsPageComponent", () => {
let component: GitHubChatsPageComponent;
let fixture: ComponentFixture<GitHubChatsPageComponent>;

beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [GitHubChatsPageComponent],
imports: [...mostUsedImports],
providers: [...testUtilStubs, ...mostUsedServices, GitHubAdminService],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
}).compileComponents();
});

beforeEach(() => {
fixture = TestBed.createComponent(GitHubChatsPageComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});

it("should create", () => {
expect(component).toBeTruthy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { Component, OnDestroy, OnInit } from "@angular/core";
import { defaultPageParams } from "@models/page-params";
import { PaginatedList } from "@models/paginated-list";
import { TitleService } from "@services/title.service";
import { untilDestroyed } from "@shared/subscriptions/until-destroyed";
import { GitHubAdminService } from "@services/github-admin.service";
import { GitHubChat } from "@models/github";
import { ConfirmMsg } from "@shared/components/dialogs/models/confirm-msg";
import { DialogMessage } from "@shared/components/dialogs/models/dialog-message";

@Component({
templateUrl: "./github-chats-page.component.html",
standalone: false,
})
export class GitHubChatsPageComponent implements OnInit, OnDestroy {
chats: Array<GitHubChat> | null = null;
source: PaginatedList<GitHubChat> | null = null;
currentPage: number = 1;
searchQuery: string = "";

constructor(
private readonly service: GitHubAdminService,
titleService: TitleService,
) {
titleService.setTitle("GitHub Telegram Bot Chats");
}

ngOnInit(): void {
this.chats = null;
this.source = null;
this.loadData(this.currentPage);
}

loadData(pageToRequest: number): void {
this.chats = null;
this.source = null;
this.currentPage = pageToRequest;

this.service
.getChats({
page: this.currentPage,
pageSize: defaultPageParams.pageSize,
search: this.searchQuery || null,
})
.pipe(untilDestroyed(this))
.subscribe((x) => {
this.chats = x.results;
this.source = x;
});
}

onSearch(): void {
this.loadData(1);
}

clearSearch(): void {
this.searchQuery = "";
this.loadData(1);
}

ngOnDestroy(): void {
// ignored
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<app-page-header>GitHub джобы</app-page-header>

<div class="container my-5" *ngIf="jobs; else dataLoading">
<div class="card">
<div class="card-body">
<div class="mb-3">
<button
type="button"
class="btn btn-outline-primary"
(click)="loadData()"
>
Refresh
</button>
</div>

<div
class="table-responsive mb-3"
*ngIf="jobs && jobs.length > 0; else nothingToShow"
>
<table class="table table-hover table-sm">
<thead class="small">
<th>Username</th>
<th>Создано</th>
<th>Обновлено</th>
</thead>
<tbody>
<tr class="small" *ngFor="let job of jobs; let i = index">
<td class="font-monospace">{{ job.username }}</td>
<td>{{ job.createdAt | date: "yyyy-MM-dd HH:mm" }}</td>
<td>{{ job.updatedAt | date: "yyyy-MM-dd HH:mm" }}</td>
<td>
<button
type="button"
class="btn btn-sm btn-outline-danger"
(click)="openDeleteDialog(job)"
>
Delete
</button>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>

<ng-template #nothingToShow>
<div class="card">
<div class="card-body">
<div class="text-center">Нет джобов.</div>
</div>
</div>
</ng-template>

<ng-template #dataLoading>
<div class="container mt-5">
<app-data-loader></app-data-loader>
</div>
</ng-template>

<app-confirm-dialog
*ngIf="confirmDeletionMessage"
[message]="confirmDeletionMessage"
></app-confirm-dialog>
Loading