Skip to content
Open
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
4 changes: 4 additions & 0 deletions main/global_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ typedef struct SystemModule
bool use_fallback_stratum;
bool is_using_fallback;
float response_time;
float response_time_min;
float response_time_max;
float last_response_time_min;
float last_response_time_max;
uint16_t response_share_batch;
float process_time;
float cpu_usage;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<div class="relative w-full" [id]="inputId">
<div
(click)="toggle($event)"
[attr.tabindex]="disabled ? -1 : 0"
[class.border-primary]="isOpen"
[class.opacity-50]="disabled"
[class.pointer-events-none]="disabled"
[ngClass]="triggerClass || 'input-text'"
class="flex items-center justify-between cursor-pointer select-none bg-bg-card border border-surface rounded outline-none transition duration-150 focus:border-primary"
>
<span class="truncate">{{ selectedOptionName }}</span>
<i class="pi pi-chevron-down text-xs transition-transform duration-200" [class.rotate-180]="isOpen"></i>
</div>
@if (isOpen) {
<ul
[class.bottom-full]="openUpward"
[class.mb-1]="openUpward"
[class.top-full]="!openUpward"
[class.mt-1]="!openUpward"
class="absolute z-50 left-0 w-full max-h-60 overflow-y-auto bg-bg-card border border-surface rounded shadow-lg list-none p-0 m-0"
>
@for (option of options; track option.value ?? $index; let i = $index) {
<li
(mouseenter)="focusedIndex = i"
(mousedown)="$event.preventDefault()"
(click)="select(option, $event)"
class="px-3 py-2 cursor-pointer select-none"
[class.bg-primary]="i === focusedIndex"
[class.text-white]="i === focusedIndex"
[class.bg-bg-hover]="i !== focusedIndex && option.value === value"
[class.text-primary]="i !== focusedIndex && option.value === value"
>
{{ option.name || option.label }}
</li>
}
</ul>
}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,7 @@ import { SelectOption } from '../../models/select-option.model';

@Component({
selector: 'app-dropdown',
template: `
<div class="relative w-full" [id]="inputId">
<div
(click)="toggle($event)"
[attr.tabindex]="disabled ? -1 : 0"
[class.border-primary]="isOpen"
[class.opacity-50]="disabled"
[class.pointer-events-none]="disabled"
[ngClass]="triggerClass || 'input-text'"
class="flex items-center justify-between cursor-pointer select-none bg-bg-card border border-surface rounded outline-none transition duration-150 focus:border-primary"
>
<span>{{ selectedOptionName }}</span>
<i class="pi pi-chevron-down text-xs transition-transform duration-200" [class.rotate-180]="isOpen"></i>
</div>
@if (isOpen) {
<ul
[class.bottom-full]="openUpward"
[class.mb-1]="openUpward"
[class.top-full]="!openUpward"
[class.mt-1]="!openUpward"
class="absolute z-50 left-0 w-full max-h-60 overflow-y-auto bg-bg-card border border-surface rounded shadow-lg list-none p-0 m-0"
>
@for (option of options; track option.value ?? $index; let i = $index) {
<li
(mouseenter)="focusedIndex = i"
(mousedown)="$event.preventDefault()"
(click)="select(option, $event)"
class="px-3 py-2 cursor-pointer select-none"
[class.bg-primary]="i === focusedIndex"
[class.text-white]="i === focusedIndex"
[class.bg-bg-hover]="i !== focusedIndex && option.value === value"
[class.text-primary]="i !== focusedIndex && option.value === value"
>
{{ option.name || option.label }}
</li>
}
</ul>
}
</div>
`,
templateUrl: './dropdown.component.html',
providers: [
{
provide: NG_VALUE_ACCESSOR,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -221,12 +221,12 @@
<app-dropdown
formControlName="chartY1Unit"
[options]="chartUnitGroups"
class="w-40 text-sm">
class="w-48 text-sm">
</app-dropdown>
<app-dropdown
formControlName="chartY2Unit"
[options]="chartUnitGroups"
class="w-40 text-sm">
class="w-48 text-sm">
</app-dropdown>
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { LocalStorageService } from 'src/app/local-storage.service';
import { DashboardEditService } from 'src/app/services/dashboard-edit.service';
import { LayoutService } from 'src/app/layout/service/app.layout.service';
import { SystemInfo as ISystemInfo, SystemStatistics as ISystemStatistics } from 'src/app/generated/models';
import { eChartLabel } from 'src/models/enum/eChartLabel';

const mockSystemInfo: ISystemInfo = {
ASICModel: 'BM1370',
Expand Down Expand Up @@ -110,6 +111,8 @@ const mockSystemInfo: ISystemInfo = {
maxPower: 20,
poolConnectionInfo: 'Connected',
responseTime: 45,
responseTimeMin: 45,
responseTimeMax: 45,
responseShareBatch: 1,
poolDifficulty: 1000,
blockHeight: 800000,
Expand Down Expand Up @@ -510,6 +513,46 @@ describe('HomeComponent', () => {
expect(component.dataLabel.length).toBe(2);
});

it('should merge response time into closest neighbor when removed point has data in limitDataPoints', () => {
component['statsLimit'] = 3;
component.dataLabel = [1000, 2000, 2050, 4000];
component.hashrateData = [100, 100, 100, 100];
component.powerData = [10, 10, 10, 10];
component.chartDatasets = {
responseTimeMin: [null, 35.5, null, null],
responseTimeMax: [null, 55.5, null, null]
};

component.limitDataPoints(0);

expect(component.dataLabel.length).toBe(3);
expect(component.dataLabel).not.toContain(2000);
expect(component.dataLabel).toContain(2050);
const idx2050 = component.dataLabel.indexOf(2050);
expect(component.chartDatasets['responseTimeMin'][idx2050]).toBe(35.5);
expect(component.chartDatasets['responseTimeMax'][idx2050]).toBe(55.5);
});

it('should merge min and max of either points when thinning in limitDataPoints', () => {
component['statsLimit'] = 3;
component.dataLabel = [1000, 2000, 2050, 4000];
component.hashrateData = [100, 100, 100, 100];
component.powerData = [10, 10, 10, 10];
component.chartDatasets = {
responseTimeMin: [null, 35.5, 25.0, null],
responseTimeMax: [null, 45.5, 60.0, null]
};

component.limitDataPoints(0);

expect(component.dataLabel.length).toBe(3);
expect(component.dataLabel).toContain(2050);
expect(component.dataLabel).not.toContain(2000);
const idx2050 = component.dataLabel.indexOf(2050);
expect(component.chartDatasets['responseTimeMin'][idx2050]).toBe(25.0);
expect(component.chartDatasets['responseTimeMax'][idx2050]).toBe(60.0);
});

it('should clear flash timeouts on destroy', () => {
component['shareAcceptedTimeout'] = setTimeout(() => {}, 10000) as any;
component['shareRejectedTimeout'] = setTimeout(() => {}, 10000) as any;
Expand All @@ -523,5 +566,13 @@ describe('HomeComponent', () => {
expect(clearTimeout).toHaveBeenCalledWith(component['shareRejectedTimeout']);
expect(clearTimeout).toHaveBeenCalledWith(component['workReceivedTimeout']);
});

it('should return 0 for response time min/max and undefined for others in getMinForLabel', () => {
expect(component.getMinForLabel(eChartLabel.responseTimeMin)).toBe(0);
expect(component.getMinForLabel(eChartLabel.responseTimeMax)).toBe(0);
expect(component.getMinForLabel(eChartLabel.hashrate)).toBeUndefined();
expect(component.getMinForLabel(eChartLabel.none)).toBeUndefined();
expect(component.getMinForLabel(undefined)).toBeUndefined();
});
});
});
Loading
Loading