Skip to content

Commit

Permalink
Implement color list page
Browse files Browse the repository at this point in the history
  • Loading branch information
Yamaguchi committed Mar 18, 2024
1 parent 0d52d1c commit d3c72c7
Show file tree
Hide file tree
Showing 12 changed files with 289 additions and 0 deletions.
27 changes: 27 additions & 0 deletions backend/actions/color_list.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
const app = require('../app.js');
const rest = require('../libs/rest');
const logger = require('../libs/logger');

app.use((req, res, next) => {
res.header('Access-Control-Allow-Origin', '*');
res.header(
'Access-Control-Allow-Headers',
'Origin, X-Requested-With, Content-Type, Accept'
);
next();
});

app.get('/api/colors', async (req, res) => {
const lastSeenColorId = req.query.lastSeenColorId;

try {
const colors = await rest.color.list(lastSeenColorId);
console.log(colors);
res.json({ colors: colors });
} catch (err) {
logger.error(
`Error retrieving colors. Error Message - ${err.message}`
);
res.status(500).send(`Error Retrieving Blocks`);
}
});
14 changes: 14 additions & 0 deletions backend/libs/rest.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,20 @@ const block = {
};

const color = {
list: async lastSeenColorId => {
let url;
if (lastSeenColorId) {
url = `${baseUrl}/colors/${lastSeenColorId}`;
} else {
url = `${baseUrl}/colors`;
}
const response = await fetch(url, { agent: agentSelector });
if (response.ok) {
return response.json();
} else {
throw new Error(`failed to fetch API ${url}`);
}
},
get: async colorId => {
const url = `${baseUrl}/color/${colorId}`;
const response = await fetch(url, { agent: agentSelector });
Expand Down
1 change: 1 addition & 0 deletions backend/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ const app = require('./app.js');
require('./actions/block_detail.js');
require('./actions/block_list.js');
require('./actions/color_detail.js');
require('./actions/color_list.js');
require('./actions/transaction_detail.js');
require('./actions/transaction_list.js');
require('./actions/address_detail.js');
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/app/app-routing.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,11 @@ const routes: Routes = [
m => m.BlockRawdataPageModule
)
},
{
path: 'colors',
loadChildren: () =>
import('./colors/colors.module').then(m => m.ColorsPageModule)
},
{
path: 'color/:colorId',
loadChildren: () =>
Expand Down
4 changes: 4 additions & 0 deletions frontend/src/app/app.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export class AppComponent implements OnInit {
title: 'Txns',
url: '/tx/recent'
},
{
title: 'Colors',
url: '/colors'
},
{
title: 'Tracking Validation',
url: '/material_tracking_validation'
Expand Down
10 changes: 10 additions & 0 deletions frontend/src/app/backend.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,16 @@ export class BackendService {
return this.http.get(`${this.backendUrl}/api/tx/${query}/get`);
}

getColors(lastSeenColorId?: string): Observable<any> {
return this.http.get(`${this.backendUrl}/api/colors`, {
params: new HttpParams({
fromObject: {
lastSeenColorId: (lastSeenColorId || '').toString()
}
})
});
}

getColor(colorId: string, lastSeenTxid?: string): Observable<any> {
return this.http.get(`${this.backendUrl}/api/color/${colorId}`, {
params: new HttpParams({
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/app/colors/colors-routing.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { NgModule } from '@angular/core';
import { Routes, RouterModule } from '@angular/router';

import { ColorsPage } from './colors.page';

const routes: Routes = [
{
path: '',
component: ColorsPage
}
];

@NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ColorsPageRoutingModule {}
23 changes: 23 additions & 0 deletions frontend/src/app/colors/colors.module.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';

import { IonicModule } from '@ionic/angular';

import { ColorsPageRoutingModule } from './colors-routing.module';

import { ColorsPage } from './colors.page';
import { SharedPipeModule } from '../modules/sharePipe.module';
import { NgxPaginationModule } from 'ngx-pagination';
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ColorsPageRoutingModule,
NgxPaginationModule,
SharedPipeModule
],
declarations: [ColorsPage]
})
export class ColorsPageModule {}
51 changes: 51 additions & 0 deletions frontend/src/app/colors/colors.page.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<ion-content class="pb-footer">
<div class="ion-padding" *ngIf="!hasError">
<div class="bg-white ion-padding ion-margin-top">
<ion-row>
<ion-col size="12">
<h3 id="color-header-text">Colors</h3>
</ion-col>
</ion-row>
<ion-row class="table-header">
<ion-col size="8" class="pt-10">COLOR ID</ion-col>
<ion-col size="4" class="pt-10">LATEST USED BLOCK</ion-col>
</ion-row>
<ion-row class="text-color table-border-bottom" *ngFor="let color of colors">
<ion-col
size="8"
(click)="goToColorPage(color[0])"
class="link-color cursor-pointer ellipsis"
>{{ color[0] }}</ion-col
>
<ion-col
size="4"
(click)="goToBlock(color[1])"
class="link-color cursor-pointer ellipsis"
>{{ color[1] }}</ion-col
>
</ion-row>
</div>
</div>
<ion-grid *ngIf="!hasError">
<ion-row>
<ion-col class="ion-text-center">
<ion-button
color="primary"
id="next"
class="cursor-pointer"
(click)="onNextPage()"
>Load More</ion-button
>
</ion-col>
</ion-row>
</ion-grid>
<div class="ion-padding" *ngIf="hasError">
<h1 class="error text-primary">
<div class="code">{{ statusCode }}</div>
<div class="message">{{ statusMsg }}</div>
</h1>
<div>
<p class="detail">{{ detailMsg }}</p>
</div>
</div>
</ion-content>
37 changes: 37 additions & 0 deletions frontend/src/app/colors/colors.page.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
ion-content {
--background: var(
--ion-item-background,
var(--ion-background-color, #e5e5e5)
) !important;
}

#color-header-text {
@media (max-width: 539px) {
font-size: 16px;
margin: 17px 10px 10px;
}

@media (min-width: 540px) {
font-size: 36px;
margin: 0px 10px 20px;
}

font-weight: 500;
}

.table-header {
background-color: #f6f6f6;
font-size: 14px;
color: #aaaaaa;
}

.table-border-bottom {
border-bottom: 1px solid #f6f6f6;
padding: 10px 10px;
}

.ellipsis {
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
}
30 changes: 30 additions & 0 deletions frontend/src/app/colors/colors.page.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
import { IonicModule } from '@ionic/angular';

import { ColorsPage } from './colors.page';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';

describe('ColorsPage', () => {
let component: ColorsPage;
let fixture: ComponentFixture<ColorsPage>;

beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ColorsPage],
imports: [
IonicModule.forRoot(),
RouterTestingModule,
HttpClientTestingModule
]
}).compileComponents();

fixture = TestBed.createComponent(ColorsPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));

it('should create', () => {
expect(component).toBeTruthy();
});
});
70 changes: 70 additions & 0 deletions frontend/src/app/colors/colors.page.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { ModalController, NavController } from '@ionic/angular';
import { BackendService } from '../backend.service';
import { AppConst } from '../app.const';

@Component({
selector: 'app-color',
templateUrl: './colors.page.html',
styleUrls: ['./colors.page.scss'],
providers: [BackendService]
})
export class ColorsPage implements OnInit {
lastSeenColorId?: string;
colors = [];
hasError: boolean;
statusCode: string;
statusMsg: string;
detailMsg: string;

constructor(
private activatedRoute: ActivatedRoute,
private httpClient: HttpClient,
private modalCtrl: ModalController,
private navCtrl: NavController,
private backendService: BackendService
) {}

ngOnInit() {
this.lastSeenColorId = this.activatedRoute.snapshot.paramMap.get('lastSeenColorId') || '';
this.getColorsInfo();
}

getColorsInfo() {
this.resetError();
this.backendService.getColors(this.lastSeenColorId).subscribe(
data => {
this.colors = this.colors.concat(data["colors"]);
this.lastSeenColorId = data["colors"][data["colors"].length - 1][0];
},
err => {
console.log(err);
this.hasError = true;
this.statusCode = err.status;
this.statusMsg = err.statusText;
this.detailMsg = err.error;
}
);
}

goToColorPage(colorId) {
this.navCtrl.navigateForward(`/color/${colorId}`);
}

goToBlock(block_height) {
this.navCtrl.navigateForward(`/block/height/${block_height}`);
}

onNextPage() {
this.getColorsInfo();
}

resetError() {
this.hasError = false;
this.statusCode = null;
this.statusMsg = null;
this.detailMsg = null;
}
}

0 comments on commit d3c72c7

Please sign in to comment.