diff --git a/backend/src/controllers/setup.controller.ts b/backend/src/controllers/setup.controller.ts index 83e139e..b520a43 100644 --- a/backend/src/controllers/setup.controller.ts +++ b/backend/src/controllers/setup.controller.ts @@ -1,5 +1,6 @@ import { Request, Response } from 'express'; import app from '../index.js'; +import StatusService from '../services/status.service.js'; class SetupController { async registrationComplete(req: Request, res: Response) { @@ -77,6 +78,16 @@ class SetupController { } } + async getStatus(req: Request, res: Response) { + try { + const statusService = new StatusService(); + const status = await statusService.getStatus(); + return res.json(status); + } catch (error) { + res.status(500).json(error); + } + } + async getInstall(req: Request, res: Response) { try { const { installation } = await app.github.getInstallation(req.body.id || req.body.owner) diff --git a/backend/src/database.ts b/backend/src/database.ts index 4e26b38..dc7f7cc 100644 --- a/backend/src/database.ts +++ b/backend/src/database.ts @@ -45,13 +45,18 @@ class Database { sequelize = typeof this.input === 'string' ? new Sequelize(this.input, { pool: { - max: 10, + max: 5, acquire: 30000, idle: 10000 }, ...this.options }) : new Sequelize({ + pool: { + max: 10, + acquire: 30000, + idle: 10000 + }, ...this.input, ...this.options }); diff --git a/backend/src/services/copilot.seats.service.ts b/backend/src/services/copilot.seats.service.ts index 32e3b1a..9347671 100644 --- a/backend/src/services/copilot.seats.service.ts +++ b/backend/src/services/copilot.seats.service.ts @@ -1,6 +1,6 @@ import { Endpoints } from '@octokit/types'; import { Seat } from "../models/copilot.seats.model.js"; -import { Sequelize } from 'sequelize'; +import { QueryTypes, Sequelize } from 'sequelize'; import { components } from "@octokit/openapi-types"; import { Member, Team } from '../models/teams.model.js'; import app from '../index.js'; @@ -231,6 +231,16 @@ class SeatsService { } async getMembersActivityTotals(org?: string) { + const assignees2 = await app.database.sequelize?.query(` + SELECT \`Member\`.\`login\`, \`Member\`.\`id\`, \`activity\`.\`id\` AS \`activity.id\`, \`activity\`.\`last_activity_at\` AS \`activity.last_activity_at\` + FROM \`Members\` AS \`Member\` + INNER JOIN \`Seats\` AS \`activity\` ON \`Member\`.\`id\` = \`activity\`.\`assignee_id\` + `, { + replacements: { org }, + type: QueryTypes.SELECT + }); + console.log(assignees2); + const assignees = await Member.findAll({ attributes: ['login', 'id'], include: [{ diff --git a/backend/src/services/status.service.ts b/backend/src/services/status.service.ts new file mode 100644 index 0000000..e65a1bc --- /dev/null +++ b/backend/src/services/status.service.ts @@ -0,0 +1,65 @@ +import { Seat } from "../models/copilot.seats.model.js"; +import { Survey } from "../models/survey.model.js"; +import { Member } from "../models/teams.model.js"; + +export interface StatusType { + github?: { + isGood: boolean + }; + pollingHistory?: { + isGood: boolean; + message: string; + value?: any; + progress?: string; + }; + repos?: { + value: number; + }; + surveys?: StatusType; +} + +class StatusService { + constructor() { + + } + + async getStatus(): Promise { + const status = {} as StatusType; + + const assignee = await Member.findOne(); + if (assignee) { + const seats = await Seat.findAll({ + include: [{ + model: Member, + as: 'assignee' + }], + where: { + assignee_id: assignee.id + }, + order: [['createdAt', 'DESC']], + }); + const oldestSeat = seats.find(seat => seat.createdAt); + const daysSince = oldestSeat ? Math.floor((new Date().getTime() - oldestSeat.createdAt.getTime()) / (1000 * 3600 * 24)) : undefined; + status.pollingHistory = { + isGood: true, + message: `${oldestSeat?.createdAt}`, + value: daysSince + } + } + + const surveys = await Survey.findAll({ + order: [['updatedAt', 'DESC']] + }); + + if (surveys) { + // status.surveys = { + // message: `${surveys.length} surveys created`, + // value: surveys.length + // } + } + + return status; + } +} + +export default StatusService; \ No newline at end of file diff --git a/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.html b/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.html index 4452eee..f23919f 100644 --- a/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.html +++ b/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.html @@ -5,14 +5,14 @@

Dashboard

-->
- + [change]="totalSurveysThisWeek" changeSuffix="" changeDescription=" this week"> @@ -39,11 +39,11 @@

Dashboard

- - - + - +
diff --git a/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.scss b/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.scss index 7c74e48..9561b9f 100644 --- a/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.scss +++ b/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.scss @@ -27,6 +27,10 @@ width: 100%; overflow: hidden; } + + #status { + grid-column: span 3; + } } /* Add media query for smaller screens */ diff --git a/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.ts b/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.ts index 71f251a..aac35d1 100644 --- a/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.ts +++ b/frontend/src/app/main/copilot/copilot-dashboard/dashboard.component.ts @@ -88,7 +88,25 @@ export class CopilotDashboardComponent implements OnInit { } activityTotals?: Record; - + statusChecks = [ + // First column: Telemetry + { title: 'API Connectivity', statusMessage: 'Unknown' }, + { title: 'Form Hits', statusMessage: 'Unknown' }, + { title: 'Settings Configured', statusMessage: 'Unknown' }, + // Second column: Developer Estimates + { title: 'Polling History', statusMessage: 'Unknown' }, + { title: 'Repositories Configured', statusMessage: 'Unknown' }, + { title: 'Targets Selected', statusMessage: 'Unknown' }, + // Third column: Predictive Modeling + { title: 'Average Usage Level', statusMessage: 'Unknown' }, + { title: 'Estimates Collected', statusMessage: 'Unknown' }, + { title: 'Targets Last Updated', statusMessage: 'Unknown' }, + // Additional Checks + { title: 'Usage Level Trend', statusMessage: 'Unknown' }, + { title: 'Estimates/Daily-User Ratio', statusMessage: 'Unknown' }, + { title: 'Target Levels Acquired', statusMessage: '0 Levels Acquired' } + ]; + constructor( private metricsService: MetricsService, private membersService: MembersService, diff --git a/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.html b/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.html index e69de29..5661b3e 100644 --- a/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.html +++ b/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.html @@ -0,0 +1,14 @@ +@for (s of status; track $index) { +
+
+ {{s.title}} + {{s.statusMessage}} +
+ +
+ +
+
+} \ No newline at end of file diff --git a/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.scss b/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.scss index 5d4e87f..9091767 100644 --- a/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.scss +++ b/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.scss @@ -1,3 +1,27 @@ :host { - display: block; + display: grid; + grid-template-columns: 1fr 1fr 1fr; } + +.status { + display: flex; + padding: 17.6px 20px 16px 20px; + border: var(--mdc-outlined-card-outline-width) solid var(--mdc-outlined-card-outline-color, var(--mat-app-outline-variant)); + .status-icon { + display: flex; + justify-content: center; + align-items: center; + } +} + +.error { + background-color: var(--error) !important; +} + +.success { + background-color: var(--success) !important; +} + +.warning { + background-color: var(--warning) !important; +} \ No newline at end of file diff --git a/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.ts b/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.ts index 81c2f90..964033e 100644 --- a/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.ts +++ b/frontend/src/app/main/copilot/copilot-dashboard/status/status.component.ts @@ -1,11 +1,27 @@ -import { ChangeDetectionStrategy, Component } from '@angular/core'; +import { ChangeDetectionStrategy, Component, Input } from '@angular/core'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { MatIconModule } from '@angular/material/icon'; @Component({ selector: 'app-status', standalone: true, - imports: [], + imports: [ + MatCardModule, + MatIconModule, + MatButtonModule + ], templateUrl: './status.component.html', styleUrl: './status.component.scss', changeDetection: ChangeDetectionStrategy.OnPush, }) -export class StatusComponent { } +export class StatusComponent { + @Input() status?: any[]; + + constructor() { + } + + ngOnInit() { + console.log(this.status); + } +} diff --git a/frontend/src/styles.scss b/frontend/src/styles.scss index 6046cb8..9cc8f96 100644 --- a/frontend/src/styles.scss +++ b/frontend/src/styles.scss @@ -91,4 +91,10 @@ highcharts-chart { display: block; width: 100% !important; height: 100% !important; +} + +:root { + --error: #93000a; /* Error */ + --success: #28a745; /* Green */ + --warning: #FFAB00; /* Orange/Yellow */ } \ No newline at end of file