Skip to content

Commit

Permalink
Add partials tab, closes #11
Browse files Browse the repository at this point in the history
  • Loading branch information
felixbrucker committed Feb 19, 2024
1 parent 0758263 commit 9faabcc
Show file tree
Hide file tree
Showing 11 changed files with 364 additions and 4 deletions.
16 changes: 15 additions & 1 deletion src/app/account.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ import {AccountWonBlock} from './api/types/account/account-won-block'
import {makeAccountIdentifierName} from './util'
import {HistoricalStatsDuration} from './api/types/historical-stats-duration'
import {HistoricalStatsDurationProvider} from './historical-stats-duration-provider'
import {AccountPartialList} from './api/types/account/account-partial'
import {Harvester} from './api/types/harvester/harvester'

@Injectable({
providedIn: 'root'
Expand Down Expand Up @@ -269,7 +271,7 @@ export class AccountService {

async getAccountHarvesters({ bustCache = false }) {
this.isLoading = true
let accountHarvesters = []
let accountHarvesters: Harvester[] = []
try {
accountHarvesters = await this.statsService.getAccountHarvesters({ accountIdentifier: this.accountIdentifier, bustCache })
} finally {
Expand All @@ -279,6 +281,18 @@ export class AccountService {
return accountHarvesters
}

public async getAccountPartials({ page, limit }) {
this.isLoading = true
let accountPartials: AccountPartialList
try {
accountPartials = await this.statsService.getAccountPartials({ accountIdentifier: this.accountIdentifier, page, limit })
} finally {
this.isLoading = false
}

return accountPartials
}

async getAccountHistoricalStats({ accountIdentifier, duration }: { accountIdentifier: string, duration: HistoricalStatsDuration }): Promise<AccountHistoricalStat[]> {
this.isLoading = true
let accountHistoricalStats = []
Expand Down
7 changes: 7 additions & 0 deletions src/app/api/abstract-api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {LoginTokenResult} from './types/auth/login-token-result'
import {BaseTopAccount} from './types/account/top-account'
import {ApiResponse} from './types/api-response'
import {HistoricalStatsDuration} from './types/historical-stats-duration'
import {AccountPartialList} from './types/account/account-partial'

export abstract class AbstractApi<
AccountType extends Account,
Expand Down Expand Up @@ -101,6 +102,12 @@ export abstract class AbstractApi<
return data
}

public async getAccountPartials({ accountIdentifier, page, limit }: { accountIdentifier: string, page: number, limit: number }): Promise<AccountPartialList> {
const { data } = await this.client.get<AccountPartialList>(`account/${accountIdentifier}/partials`, { params: { page, limit } })

return data
}

public async getHarvesterStats({ harvesterId, duration }: { harvesterId: string, duration: HistoricalStatsDuration }): Promise<HarvesterStats> {
const { data } = await this.client.get<HarvesterStats>(`harvester/${harvesterId}/stats`, { params: { duration } })

Expand Down
18 changes: 18 additions & 0 deletions src/app/api/types/account/account-partial.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
export enum PartialState {
valid = 'VALID',
stale = 'STALE',
invalid = 'INVALID',
}

export interface AccountPartial {
shares: number
harvester: string
receivedAt: string
proofTimeInSeconds: number
type: PartialState
}

export interface AccountPartialList {
partials: AccountPartial[]
total: number
}
2 changes: 2 additions & 0 deletions src/app/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ import { IntegrationSettingsComponent } from './integration-settings/integration
import {NgxSliderModule} from 'ngx-slider-v2'
import { UpdateBlockSettingsComponent } from './update-block-settings/update-block-settings.component'
import { ConfirmationModalComponent } from './confirmation-modal/confirmation-modal.component'
import {FarmerPartialsComponent} from './farmer-partials/farmer-partials.component'

@NgModule({
declarations: [
Expand Down Expand Up @@ -96,6 +97,7 @@ import { ConfirmationModalComponent } from './confirmation-modal/confirmation-mo
IntegrationSettingsComponent,
UpdateBlockSettingsComponent,
ConfirmationModalComponent,
FarmerPartialsComponent,
],
imports: [
BrowserModule,
Expand Down
17 changes: 17 additions & 0 deletions src/app/config.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export class ConfigService implements OnDestroy {
private static readonly payoutDateFormattingStorageKey = 'config:dateFormatting:payout'
private static readonly rewardTimeIntervalStorageKey = 'config:rewardTimeInterval'
private static readonly hideNewAccountInfoAlertStorageKey = 'config:hideNewAccountInfoAlert'
private static readonly partialDateFormattingStorageKey = 'config:dateFormatting:partial'

public selectedCurrencySubject = new BehaviorSubject<string>(
this.localStorageService.getItem(ConfigService.selectedCurrencyStorageKey) || 'usd'
Expand All @@ -29,6 +30,9 @@ export class ConfigService implements OnDestroy {
private readonly hideNewAccountInfoAlertSubject: BehaviorSubject<boolean> = new BehaviorSubject<boolean>(
JSON.parse(this.localStorageService.getItem(ConfigService.hideNewAccountInfoAlertStorageKey) ?? 'false')
)
public readonly partialDateFormattingSubject = new BehaviorSubject<DateFormatting>(
DateFormatting[this.localStorageService.getItem(ConfigService.partialDateFormattingStorageKey) || DateFormatting.fixed]
)

private readonly subscriptions: Subscription[] = [
this.selectedCurrencySubject
Expand Down Expand Up @@ -56,6 +60,11 @@ export class ConfigService implements OnDestroy {
.subscribe(hideNewAccountInfoAlert =>
this.localStorageService.setItem(ConfigService.hideNewAccountInfoAlertStorageKey, JSON.stringify(hideNewAccountInfoAlert))
),
this.partialDateFormattingSubject
.pipe(skip(1), distinctUntilChanged())
.subscribe(partialDateFormatting =>
this.localStorageService.setItem(ConfigService.partialDateFormattingStorageKey, partialDateFormatting)
),
]

constructor(private readonly localStorageService: LocalStorageService) {}
Expand Down Expand Up @@ -100,6 +109,14 @@ export class ConfigService implements OnDestroy {
this.hideNewAccountInfoAlertSubject.next(hideNewAccountInfoAlert)
}

public get partialDateFormatting(): DateFormatting {
return this.partialDateFormattingSubject.getValue()
}

public set partialDateFormatting(dateFormatting: DateFormatting) {
this.partialDateFormattingSubject.next(dateFormatting)
}

public ngOnDestroy(): void {
this.subscriptions.map(subscription => subscription.unsubscribe())
}
Expand Down
72 changes: 72 additions & 0 deletions src/app/farmer-partials/farmer-partials.component.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
<div class="table-responsive-lg">
<table class="table">
<thead>
<tr>
<th scope="col">
<div class="date-header-container">
<span>Date</span>
<fa-icon [icon]="faExchangeAlt" class="toggle-date-formatting-icon" (click)="toggleDateFormatting()"></fa-icon>
</div>
</th>
<th scope="col">State</th>
<th scope="col">Shares</th>
<th scope="col">Harvester</th>
<th scope="col">Proof time</th>
</tr>
</thead>
<tbody>
<tr *ngIf="isLoadingInitial | async">
<td colspan="5" style="text-align: center">
<app-loading-state></app-loading-state>
</td>
</tr>
<tr *ngIf="(isLoadingInitial | async) === false && (partials | async)?.length === 0">
<td colspan="5" style="text-align: center; padding-top: 1rem">
<app-empty-state text="No partials received yet" [icon]="faBarsStaggered"></app-empty-state>
</td>
</tr>
<tr *ngFor="let partial of partials | async; trackBy: trackBy">
<td>{{getPartialDate(partial)}}</td>
<td>
<span *ngIf="partial.type === 'VALID'" class="badge state-pill background-color-light-green">Valid</span>
<span *ngIf="partial.type === 'INVALID'" class="badge state-pill background-color-red">Invalid</span>
<span *ngIf="partial.type === 'STALE'" class="badge state-pill background-color-orange">Stale</span>
</td>
<td>{{partial.shares}}</td>
<td>{{getPartialHarvesterName(partial)}}</td>
<td><span [ngStyle]="{color: getProofTimeColor(partial.proofTimeInSeconds)}">{{partial.proofTimeInSeconds}} sec</span></td>
</tr>
</tbody>
</table>
</div>
<div class="d-grid footer-grid">
<div class="pagination-grid-item">
<ngb-pagination
*ngIf="total > pageSize"
class="d-flex justify-content-center"
[(page)]="page"
[pageSize]="pageSize"
[collectionSize]="total"
[maxSize]="5"
[rotate]="true"
[boundaryLinks]="true"
(pageChange)="onPageChange()">
<ng-template ngbPaginationNumber let-p>
<div class="d-flex flex-nowrap gap-1">
{{ p }}
<app-loading-state *ngIf="p === page && (isLoading | async)" width="1" height="1" colorClass="text-light"></app-loading-state>
</div>
</ng-template>
</ngb-pagination>
</div>
<div style="margin-left: auto" *ngIf="showItemsPerPageSelection | async">
<div class="input-group" style="flex-wrap: nowrap">
<label class="input-group-text page-size-select-label">
Items per page
</label>
<select class="form-select page-size-select" [(ngModel)]="pageSize">
<option *ngFor="let currPageSize of pageSizes" [ngValue]="currPageSize" class="page-size-select-option">{{currPageSize}}</option>
</select>
</div>
</div>
</div>
58 changes: 58 additions & 0 deletions src/app/farmer-partials/farmer-partials.component.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
::ng-deep .page-link {
background-color: var(--page-link-background-color);
border-color: var(--page-link-border-color);
-webkit-transition: color 0.3s;
transition: color 0.3s;
color: var(--highlight-color);
}
::ng-deep .page-link:hover {
color: var(--highlight-color-hover);
border-color: var(--page-link-border-color);
text-decoration: none;
}
::ng-deep .page-item:not(.active) .page-link:hover {
background-color: var(--page-link-background-color);
}
::ng-deep .page-item.disabled .page-link {
background-color: var(--page-link-background-color);
border-color: var(--page-link-border-color);
}
.page-size-select {
width: 4.2em;
background-color: var(--input-field-background-color);
color: var(--text-color);
border-color: var(--input-field-border-color);
}
.page-size-select-option {
background-color: var(--select-item-background-color);
}
.page-size-select-label {
font-size: small;
background-color: var(--input-field-background-color);
color: var(--text-color);
border-color: var(--input-field-border-color);
}
.footer-grid {
grid-template-columns: repeat(3, 1fr);
grid-column-gap: 5px;
grid-auto-flow: row;
justify-items: center;
}
.pagination-grid-item {
grid-column-start: 2;
}
@media (max-width: 606px) {
.footer-grid {
grid-template-columns: repeat(1, 1fr);
grid-column-gap: 5px;
grid-auto-flow: row;
justify-items: center;
}
.pagination-grid-item {
grid-column-start: 1;
}
}
.state-pill {
color: #18191c;
font-weight: 600;
}
Loading

0 comments on commit 9faabcc

Please sign in to comment.