9003. Online Judge - Frontend with AngularAngular
Setup frontend UI for Online Judge app with Angular.
1. Project Structure
1.1 Client Files
All source files for client is under ‘./src’ folder.
1.2 Angular Project
This app is created by ‘ng new’ command with Angular CLI.
2. Main Components
Separate app functions to different components as follows.
Component | Path | Description |
---|---|---|
component | ’./src/app/component’ | UI components |
interceptor | ’./src/app/interceptor’ | HTTP interceptor |
model | ’./src/app/models’ | Model class |
service | ’./src/app/services’ | HTTP services to communicate with backend RESTful services |
util | ’./src/app/util’ | Helper class |
2.1 UI Components
The app page contains 5 components. In ‘./src/app/components/pages/app.component.html’, setup the app page as follows.
<div class="mainpage">
<app-widget-progress-bar></app-widget-progress-bar>
<app-header></app-header>
<app-alert></app-alert>
<router-outlet></router-outlet>
<app-footer></app-footer>
</div>
Details are explained in the table.
selector | Description |
---|---|
app-widget-progress-bar | Progress bar displays whenever Http request happens |
app-header | Top menus |
app-alert | Common alert dialog, eg. Save, Submit |
router-outlet | Angular Routing, navigate to sub component |
app-footer | Footage of the app |
2.2 Http Interceptor
Use HttpInterceptor to intercept and modify HTTP requests globally.
File Name | Class Name | Description |
---|---|---|
cookie.interceptor.ts | CookieHttpInterceptor | Manipulate Cookies settings on request |
error.interceptor.ts | ErrorHttpInterceptor | Handle http request error globally |
jwt.interceptor.ts | JwtHttpInterceptor | Add token to each http request |
timeout.interceptor.ts | TimeoutHttpInterceptor | Set timeout before sending http request |
2.3 Model
Model class for user, question, submission, etc.
2.4 Service
Services are collections of common methods. Most of the services are used to send HTTP requests to call RESTful API.
File Name | Class Name | Description |
---|---|---|
alert.service.ts | AlertService | Display Alert message from anywhere. The Alert will be shown at the top of the page. |
auth-guard.service.ts | AuthGuardService | Guard access right. If user hasn’t logged in, he/she will be navigated to login page if he/she tries to access some pages only available for registered users. |
authentication.service.ts | AuthenticationService | Http requests for register, login, etc. |
database.service.ts | DatabaseService | Http requests for data import and export. |
question.service.ts | QuestionService | Http requests for question management. |
submission.service.ts | SubmissionService | Http requests for solution submission. |
user.service.ts | UserService | Http requests for user management. |
2.5 Util
Some helper methods, string manipulation, cookie manipulation, etc.
3. Angular Routing
Define all the routings in file ‘src/app/app.route.ts’. Notice, some components are guarded by ‘AuthGuardService’. These components are accessible only when user has logged in.
import { RouterModule, Routes } from "@angular/router";
// components
import {
AlertComponent,
AppComponent,
HeaderComponent,
FooterComponent,
HomepageComponent,
SignupComponent,
LoginComponent,
ResetpwdComponent,
ProfileComponent,
DatabaseComponent,
QuestionsComponent,
QuestionComponent,
EditorComponent,
UsersComponent,
UserComponent,
WysiwygComponent,
AlgorithmQuestionComponent,
AlgorithmQuestionsComponent,
SubmissionComponent
} from "./components/";
// services
import { AuthGuardService } from "./services/";
export const appRoutes: Routes = [
{ path: "", component: HomepageComponent },
{ path: "homepage", component: HomepageComponent },
{ path: "questions", component: AlgorithmQuestionsComponent },
{ path: "question/:uniquename", component: AlgorithmQuestionComponent },
{ path: "submission/:id", component: SubmissionComponent },
{
path: "admin/database",
component: DatabaseComponent,
canActivate: [AuthGuardService]
},
{
path: "admin/users",
component: UsersComponent,
canActivate: [AuthGuardService]
},
{
path: "admin/user",
component: UserComponent,
canActivate: [AuthGuardService]
},
{
path: "admin/user/:_id",
component: UserComponent,
canActivate: [AuthGuardService]
},
{
path: "admin/questions",
component: QuestionsComponent,
canActivate: [AuthGuardService]
},
{
path: "admin/question",
component: QuestionComponent,
canActivate: [AuthGuardService]
},
{
path: "admin/question/:_id",
component: QuestionComponent,
canActivate: [AuthGuardService]
},
{
path: "editor",
component: EditorComponent
},
{
path: "wysiwyg",
component: WysiwygComponent
},
{ path: "signup", component: SignupComponent },
{ path: "login", component: LoginComponent },
{
path: "resetpwd",
component: ResetpwdComponent,
canActivate: [AuthGuardService]
},
{
path: "profile",
component: ProfileComponent,
canActivate: [AuthGuardService]
},
// otherwise redirect to home
{ path: "**", redirectTo: "" }
];