From 2b5cf93ece1fca6a1525ad8eb0d80c4b97d0a557 Mon Sep 17 00:00:00 2001 From: tanshu Date: Tue, 19 Jan 2021 07:10:14 +0530 Subject: [PATCH] Hearing Date is not not null and unique for the court case. Data import also needs to reflect this. Cause List made. --- docker/app/Dockerfile | 8 -- .../versions/74058d75b7a0_initial_commit.py | 3 +- luthor/luthor/main.py | 2 + luthor/luthor/routers/cause_list.py | 110 +++++++++++++++ luthor/luthor/schemas/cause_list.py | 30 ++++ luthor/luthor/schemas/hearing.py | 4 +- otis/src/app/app-routing.module.ts | 4 + .../case-detail/case-detail.component.ts | 1 + .../app/cause-list/cause-list-datasource.ts | 43 ++++++ .../cause-list-resolver.service.spec.ts | 15 ++ .../cause-list/cause-list-resolver.service.ts | 19 +++ .../cause-list-routing.module.spec.ts | 13 ++ .../cause-list/cause-list-routing.module.ts | 29 ++++ .../app/cause-list/cause-list.component.css | 0 .../app/cause-list/cause-list.component.html | 128 ++++++++++++++++++ .../cause-list/cause-list.component.spec.ts | 22 +++ .../app/cause-list/cause-list.component.ts | 112 +++++++++++++++ .../app/cause-list/cause-list.module.spec.ts | 13 ++ otis/src/app/cause-list/cause-list.module.ts | 63 +++++++++ .../app/cause-list/cause-list.service.spec.ts | 15 ++ otis/src/app/cause-list/cause-list.service.ts | 31 +++++ otis/src/app/cause-list/cause-list.ts | 14 ++ otis/src/app/nav-bar/nav-bar.component.html | 2 +- 23 files changed, 668 insertions(+), 13 deletions(-) create mode 100644 luthor/luthor/routers/cause_list.py create mode 100644 luthor/luthor/schemas/cause_list.py create mode 100644 otis/src/app/cause-list/cause-list-datasource.ts create mode 100644 otis/src/app/cause-list/cause-list-resolver.service.spec.ts create mode 100644 otis/src/app/cause-list/cause-list-resolver.service.ts create mode 100644 otis/src/app/cause-list/cause-list-routing.module.spec.ts create mode 100644 otis/src/app/cause-list/cause-list-routing.module.ts create mode 100644 otis/src/app/cause-list/cause-list.component.css create mode 100644 otis/src/app/cause-list/cause-list.component.html create mode 100644 otis/src/app/cause-list/cause-list.component.spec.ts create mode 100644 otis/src/app/cause-list/cause-list.component.ts create mode 100644 otis/src/app/cause-list/cause-list.module.spec.ts create mode 100644 otis/src/app/cause-list/cause-list.module.ts create mode 100644 otis/src/app/cause-list/cause-list.service.spec.ts create mode 100644 otis/src/app/cause-list/cause-list.service.ts create mode 100644 otis/src/app/cause-list/cause-list.ts diff --git a/docker/app/Dockerfile b/docker/app/Dockerfile index 76c24a8..6c132c9 100644 --- a/docker/app/Dockerfile +++ b/docker/app/Dockerfile @@ -11,14 +11,6 @@ LABEL maintainer="Amritanshu " COPY --from=builder /app/luthor /app COPY --from=builder /app/frontend /app/frontend -RUN apt-get update && \ - apt-get install -y locales && \ - sed --in-place --expression='s/# en_IN UTF-8/en_IN UTF-8/' /etc/locale.gen && \ - dpkg-reconfigure --frontend=noninteractive locales - -ENV LANG en_IN -ENV LC_ALL en_IN - WORKDIR /app # Install Poetry diff --git a/luthor/alembic/versions/74058d75b7a0_initial_commit.py b/luthor/alembic/versions/74058d75b7a0_initial_commit.py index ae035bb..9dbed22 100644 --- a/luthor/alembic/versions/74058d75b7a0_initial_commit.py +++ b/luthor/alembic/versions/74058d75b7a0_initial_commit.py @@ -256,7 +256,7 @@ def upgrade(): sa.Column("bench", sa.Unicode(length=255), nullable=True), sa.Column("proceedings", sa.Unicode(length=2000), nullable=True), sa.Column("compliance_date", sa.DateTime(), nullable=True), - sa.Column("next_hearing_date", sa.DateTime(), nullable=True), + sa.Column("next_hearing_date", sa.DateTime(), nullable=False), sa.Column("court_status_id", postgresql.UUID(as_uuid=True), nullable=True), sa.Column("old_court_status_id", sa.Integer(), nullable=True), sa.ForeignKeyConstraint(["case_id"], ["cases.id"], name=op.f("fk_hearings_case_id_cases")), @@ -264,6 +264,7 @@ def upgrade(): ["court_status_id"], ["court_statuses.id"], name=op.f("fk_hearings_court_status_id_court_statuses") ), sa.PrimaryKeyConstraint("id", name=op.f("pk_hearings")), + sa.UniqueConstraint("next_hearing_date", "case_id", name=op.f("uq_hearings_next_hearing_date")), ) op.create_index(op.f("ix_hearings_case_id"), "hearings", ["case_id"], unique=False) op.create_index(op.f("ix_hearings_next_hearing_date"), "hearings", ["next_hearing_date"], unique=False) diff --git a/luthor/luthor/main.py b/luthor/luthor/main.py index 05cb892..7732372 100644 --- a/luthor/luthor/main.py +++ b/luthor/luthor/main.py @@ -12,6 +12,7 @@ from .routers import ( case, case_source, case_type, + cause_list, contact, court, court_status, @@ -38,6 +39,7 @@ app.include_router(user.router, prefix="/api/users", tags=["users"]) app.include_router(act.router, prefix="/api/acts", tags=["acts"]) app.include_router(advocate.router, prefix="/api/advocates", tags=["advocates"]) +app.include_router(cause_list.router, prefix="/api/cause-list", tags=["cases"]) app.include_router(case.router, prefix="/api/cases", tags=["cases"]) app.include_router(case_source.router, prefix="/api/case-sources", tags=["case-sources"]) app.include_router(case_type.router, prefix="/api/case-types", tags=["case-types"]) diff --git a/luthor/luthor/routers/cause_list.py b/luthor/luthor/routers/cause_list.py new file mode 100644 index 0000000..2fe7748 --- /dev/null +++ b/luthor/luthor/routers/cause_list.py @@ -0,0 +1,110 @@ +from datetime import date, datetime + +import luthor.schemas.case as schemas +import luthor.schemas.cause_list as cl_schemas + +from fastapi import APIRouter, Depends, Request, Security +from luthor.models.hearing import Hearing +from sqlalchemy.orm import Session + +from ..core.security import get_current_active_user as get_user +from ..db.session import SessionLocal +from ..models.case import Case +from ..schemas.user_token import UserToken + + +router = APIRouter() + + +# Dependency +def get_db(): + try: + db = SessionLocal() + yield db + finally: + db.close() + + +@router.get("", response_model=cl_schemas.CauseList) +def report_blank( + request: Request, + s: str = None, + f: str = None, + db: Session = Depends(get_db), + user: UserToken = Security(get_user, scopes=["cases"]), +) -> cl_schemas.CauseList: + s = date.today() if s is None else datetime.strptime(s, "%d-%b-%Y").date() + f = date.today() if f is None else datetime.strptime(f, "%d-%b-%Y").date() + return cl_schemas.CauseList( + startDate=s, + finishDate=f, + cases=[ + case_info(item) + for item in db.query(Case) + .join(Case.hearings) + .filter(Hearing.next_hearing_date >= s, Hearing.next_hearing_date <= f) + .order_by(Hearing.next_hearing_date) + .all() + ], + ) + + +def case_info(item: Case) -> schemas.Case: + return schemas.Case( + id=item.id, + caseSource=schemas.CaseSourceLink( + id=item.case_source.id, name=item.case_source.name, prefix=item.case_source.prefix + ), + officeFileNumber=item.office_file_number if item.office_file_number is not None else "", + courtCaseNumber=item.court_case_number if item.court_case_number is not None else "", + year=item.year, + title=item.title if item.title is not None else "", + docketNumber=item.docket_number if item.docket_number is not None else "", + receiptDate=item.receipt_date, + limitation_date=item.limitation_date, + filingDate=item.filing_date, + appearOnBehalfOf=item.appear_on_behalf_of if item.appear_on_behalf_of is not None else "", + questionOfLaw=item.question_of_law if item.question_of_law is not None else "", + aorName=item.aor_name if item.aor_name is not None else "", + opposingCouncilAor=item.opposing_council_aor if item.opposing_council_aor is not None else "", + opposingCouncilDetail=item.opposing_council_detail if item.opposing_council_detail is not None else "", + lowerCourtCaseNumber=item.lower_court_case_number if item.lower_court_case_number is not None else "", + dateOfImpugnedJudgement=item.date_of_impugned_judgement, + briefDescription=item.brief_description if item.brief_description is not None else "", + remarks=item.remarks if item.remarks is not None else "", + slpCounter=item.slp_counter if item.slp_counter is not None else "", + contactDetail=item.contact_detail if item.contact_detail is not None else "", + caseConnectedWith=item.case_connected_with if item.case_connected_with is not None else "", + bunchCases=item.bunch_cases if item.bunch_cases is not None else "", + court=schemas.CourtLink(id=item.court.id, name=item.court.name) if item.court is not None else None, + department=schemas.DepartmentLink(id=item.department.id, name=item.department.name) + if item.department is not None + else None, + office=schemas.OfficeLink(id=item.office.id, name=item.office.name) if item.office is not None else None, + caseType=schemas.CaseTypeLink(id=item.case_type.id, name=item.case_type.name) + if item.case_type is not None + else None, + act=schemas.ActLink(id=item.act.id, name=item.act.name) if item.act is not None else None, + nature=schemas.NatureLink(id=item.nature.id, name=item.nature.name) if item.nature is not None else None, + officeStatus=schemas.OfficeStatusLink(id=item.office_status.id, name=item.office_status.name) + if item.office_status is not None + else None, + courtStatus=schemas.CourtStatusLink(id=item.court_status.id, name=item.court_status.name) + if item.court_status is not None + else None, + hearings=[ + schemas.Hearing( + id=h.id, + courtNumber=h.court_number if h.court_number is not None else "", + itemNumber=h.item_number if h.item_number is not None else "", + bench=h.bench if h.bench is not None else "", + proceedings=h.proceedings if h.proceedings is not None else "", + complianceDate=h.compliance_date, + nextHearingDate=h.next_hearing_date, + courtStatus=schemas.CourtStatusLink(id=h.court_status.id, name=h.court_status.name) + if h.court_status is not None + else None, + ) + for h in item.hearings + ], + ) diff --git a/luthor/luthor/schemas/cause_list.py b/luthor/luthor/schemas/cause_list.py new file mode 100644 index 0000000..7e4387f --- /dev/null +++ b/luthor/luthor/schemas/cause_list.py @@ -0,0 +1,30 @@ +from datetime import date, datetime +from typing import List + +from luthor.schemas.case import Case +from pydantic import BaseModel, validator + +from . import to_camel + + +class CauseList(BaseModel): + start_date: date + finish_date: date + cases: List[Case] + + class Config: + anystr_strip_whitespace = True + alias_generator = to_camel + json_encoders = {date: lambda v: v.strftime("%d-%b-%Y")} + + @validator("start_date", pre=True) + def parse_start_date(cls, value): + if isinstance(value, date): + return value + return datetime.strptime(value, "%d-%b-%Y").date() + + @validator("finish_date", pre=True) + def parse_finish_date(cls, value): + if isinstance(value, date): + return value + return datetime.strptime(value, "%d-%b-%Y").date() diff --git a/luthor/luthor/schemas/hearing.py b/luthor/luthor/schemas/hearing.py index 3d2cba6..2b1333a 100644 --- a/luthor/luthor/schemas/hearing.py +++ b/luthor/luthor/schemas/hearing.py @@ -15,7 +15,7 @@ class HearingIn(BaseModel): bench: str proceedings: str compliance_date: Optional[date] - next_hearing_date: Optional[date] + next_hearing_date: date court_status: Optional[CourtStatusLink] class Config: @@ -35,8 +35,6 @@ class HearingIn(BaseModel): def parse_next_hearing_date(cls, value): if isinstance(value, date): return value - if value is None: - return None return datetime.strptime(value, "%d-%b-%Y").date() diff --git a/otis/src/app/app-routing.module.ts b/otis/src/app/app-routing.module.ts index f5878e4..ce83e4c 100644 --- a/otis/src/app/app-routing.module.ts +++ b/otis/src/app/app-routing.module.ts @@ -13,6 +13,10 @@ const routes: Routes = [ path: 'advocates', loadChildren: () => import('./advocates/advocates.module').then((mod) => mod.AdvocatesModule), }, + { + path: 'cause-list', + loadChildren: () => import('./cause-list/cause-list.module').then((mod) => mod.CauseListModule), + }, { path: 'case-sources', loadChildren: () => diff --git a/otis/src/app/cases/case-detail/case-detail.component.ts b/otis/src/app/cases/case-detail/case-detail.component.ts index cbce120..d9bc44d 100644 --- a/otis/src/app/cases/case-detail/case-detail.component.ts +++ b/otis/src/app/cases/case-detail/case-detail.component.ts @@ -238,6 +238,7 @@ export class CaseDetailComponent implements OnInit, AfterViewInit { getItem(): Case { const formModel = this.form.value; + this.item.caseSource.id = formModel.caseSource; this.item.officeFileNumber = formModel.officeFileNumber; this.item.courtCaseNumber = formModel.courtCaseNumber; this.item.year = formModel.year; diff --git a/otis/src/app/cause-list/cause-list-datasource.ts b/otis/src/app/cause-list/cause-list-datasource.ts new file mode 100644 index 0000000..3659adf --- /dev/null +++ b/otis/src/app/cause-list/cause-list-datasource.ts @@ -0,0 +1,43 @@ +import { DataSource } from '@angular/cdk/collections'; +import { EventEmitter } from '@angular/core'; +import { MatPaginator, PageEvent } from '@angular/material/paginator'; +import { merge, Observable } from 'rxjs'; +import { map, tap } from 'rxjs/operators'; + +import { Case } from '../core/case'; + +export class CauseListDatasource extends DataSource { + private dataValues: Case[] = []; + private data: Observable = new Observable(); + constructor(public d: Observable, private paginator?: MatPaginator) { + super(); + this.data = d.pipe(tap((x) => (this.dataValues = x))); + } + + connect(): Observable { + const dataMutations: (Observable | EventEmitter)[] = [this.data]; + if (this.paginator) { + dataMutations.push((this.paginator as MatPaginator).page); + } + + return merge(...dataMutations) + .pipe( + tap((x: Case[]) => { + if (this.paginator) { + this.paginator.length = x.length; + } + }), + ) + .pipe(map((x: Case[]) => this.getPagedData(this.dataValues))); + } + + disconnect() {} + + private getPagedData(data: Case[]) { + if (this.paginator === undefined) { + return data; + } + const startIndex = this.paginator.pageIndex * this.paginator.pageSize; + return data.slice(startIndex, startIndex + this.paginator.pageSize); + } +} diff --git a/otis/src/app/cause-list/cause-list-resolver.service.spec.ts b/otis/src/app/cause-list/cause-list-resolver.service.spec.ts new file mode 100644 index 0000000..d514393 --- /dev/null +++ b/otis/src/app/cause-list/cause-list-resolver.service.spec.ts @@ -0,0 +1,15 @@ +import { inject, TestBed } from '@angular/core/testing'; + +import { CauseListResolver } from './cause-list-resolver.service'; + +describe('CauseListResolverService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [CauseListResolver], + }); + }); + + it('should be created', inject([CauseListResolver], (service: CauseListResolver) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/otis/src/app/cause-list/cause-list-resolver.service.ts b/otis/src/app/cause-list/cause-list-resolver.service.ts new file mode 100644 index 0000000..b6a8d7a --- /dev/null +++ b/otis/src/app/cause-list/cause-list-resolver.service.ts @@ -0,0 +1,19 @@ +import { Injectable } from '@angular/core'; +import { ActivatedRouteSnapshot, Resolve } from '@angular/router'; +import { Observable } from 'rxjs/internal/Observable'; + +import { CauseList } from './cause-list'; +import { CauseListService } from './cause-list.service'; + +@Injectable({ + providedIn: 'root', +}) +export class CauseListResolver implements Resolve { + constructor(private ser: CauseListService) {} + + resolve(route: ActivatedRouteSnapshot): Observable { + const startDate = route.queryParamMap.get('startDate') || null; + const finishDate = route.queryParamMap.get('finishDate') || null; + return this.ser.list(startDate, finishDate); + } +} diff --git a/otis/src/app/cause-list/cause-list-routing.module.spec.ts b/otis/src/app/cause-list/cause-list-routing.module.spec.ts new file mode 100644 index 0000000..d8cff88 --- /dev/null +++ b/otis/src/app/cause-list/cause-list-routing.module.spec.ts @@ -0,0 +1,13 @@ +import { CauseListRoutingModule } from './cause-list-routing.module'; + +describe('CauseListRoutingModule', () => { + let causeListRoutingModule: CauseListRoutingModule; + + beforeEach(() => { + causeListRoutingModule = new CauseListRoutingModule(); + }); + + it('should create an instance', () => { + expect(causeListRoutingModule).toBeTruthy(); + }); +}); diff --git a/otis/src/app/cause-list/cause-list-routing.module.ts b/otis/src/app/cause-list/cause-list-routing.module.ts new file mode 100644 index 0000000..c3b6cc1 --- /dev/null +++ b/otis/src/app/cause-list/cause-list-routing.module.ts @@ -0,0 +1,29 @@ +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { RouterModule, Routes } from '@angular/router'; + +import { AuthGuard } from '../auth/auth-guard.service'; + +import { CauseListResolver } from './cause-list-resolver.service'; +import { CauseListComponent } from './cause-list.component'; +const advocatesRoutes: Routes = [ + { + path: '', + component: CauseListComponent, + canActivate: [AuthGuard], + data: { + permission: 'Cases', + }, + resolve: { + info: CauseListResolver, + }, + runGuardsAndResolvers: 'always', + }, +]; + +@NgModule({ + imports: [CommonModule, RouterModule.forChild(advocatesRoutes)], + exports: [RouterModule], + providers: [CauseListResolver], +}) +export class CauseListRoutingModule {} diff --git a/otis/src/app/cause-list/cause-list.component.css b/otis/src/app/cause-list/cause-list.component.css new file mode 100644 index 0000000..e69de29 diff --git a/otis/src/app/cause-list/cause-list.component.html b/otis/src/app/cause-list/cause-list.component.html new file mode 100644 index 0000000..40307cc --- /dev/null +++ b/otis/src/app/cause-list/cause-list.component.html @@ -0,0 +1,128 @@ + + + Cases + + add_box + Add + + + +
+
+ + + + + + + + + + + +
+
+ + + + File No. + {{ row.caseSource.prefix }}-{{ row.officeFileNumber }} + + + + + Title + {{ row.title }} + + + + + Case No. + {{ row.courtCaseNumber }} + + + + + Forum + {{ row.court?.name }} + + + + + Court / Item Number + {{ courtNumber(row) }} / {{ itemNumber(row) }} + + + + + Bench + {{ bench(row) }} + + + + + Proceedings + {{ proceedings(row) }} + + + + + Next Hearing Date + {{ nextHearingDate(row) }} + + + + + On Behalf of + {{ row.appearOnBehalfOf }} + + + + + Other Hearing Dates + {{ otherHearingDates(row) }} + + + + + Remarks + {{ row.remarks }} + + + + + + + +
+
diff --git a/otis/src/app/cause-list/cause-list.component.spec.ts b/otis/src/app/cause-list/cause-list.component.spec.ts new file mode 100644 index 0000000..633d873 --- /dev/null +++ b/otis/src/app/cause-list/cause-list.component.spec.ts @@ -0,0 +1,22 @@ +import { ComponentFixture, fakeAsync, TestBed } from '@angular/core/testing'; + +import { CauseListComponent } from './cause-list.component'; + +describe('CauseListComponent', () => { + let component: CauseListComponent; + let fixture: ComponentFixture; + + beforeEach(fakeAsync(() => { + TestBed.configureTestingModule({ + declarations: [CauseListComponent], + }).compileComponents(); + + fixture = TestBed.createComponent(CauseListComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should compile', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/otis/src/app/cause-list/cause-list.component.ts b/otis/src/app/cause-list/cause-list.component.ts new file mode 100644 index 0000000..fe99048 --- /dev/null +++ b/otis/src/app/cause-list/cause-list.component.ts @@ -0,0 +1,112 @@ +import { Component, OnInit, ViewChild } from '@angular/core'; +import { FormBuilder, FormGroup } from '@angular/forms'; +import { MatPaginator } from '@angular/material/paginator'; +import { ActivatedRoute, Router } from '@angular/router'; +import * as moment from 'moment'; +import { Observable, of } from 'rxjs'; + +import { Case } from '../core/case'; + +import { CauseList } from './cause-list'; +import { CauseListDatasource } from './cause-list-datasource'; + +@Component({ + selector: 'app-cause-list', + templateUrl: './cause-list.component.html', + styleUrls: ['./cause-list.component.css'], +}) +export class CauseListComponent implements OnInit { + @ViewChild(MatPaginator, { static: true }) paginator?: MatPaginator; + form: FormGroup; + info: CauseList = new CauseList(); + list: Observable = new Observable(); + dataSource: CauseListDatasource = new CauseListDatasource(this.list); + /** Columns displayed in the table. Columns IDs can be added, removed, or reordered. */ + displayedColumns = [ + 'officeFileNumber', + 'title', + 'courtCaseNumber', + 'forum', + 'courtAndItemNumber', + 'bench', + 'proceedings', + 'nextHearingDate', + 'appearOnBehalfOf', + 'otherHearingDates', + 'remarks', + ]; + + constructor(private route: ActivatedRoute, private router: Router, private fb: FormBuilder) { + // Create form + this.form = this.fb.group({ + startDate: '', + finishDate: '', + }); + } + + ngOnInit() { + this.route.data.subscribe((value) => { + const data = value as { info: CauseList }; + + this.info = data.info; + console.log(this.info.cases); + this.form.setValue({ + startDate: moment(this.info.startDate, 'DD-MMM-YYYY').toDate(), + finishDate: moment(this.info.finishDate, 'DD-MMM-YYYY').toDate(), + }); + this.list = of(this.info.cases); + this.dataSource = new CauseListDatasource(this.list, this.paginator); + }); + } + + courtNumber(row: Case): string { + const [hearing] = row.hearings; + return hearing.courtNumber; + } + + itemNumber(row: Case): string { + const [hearing] = row.hearings; + return hearing.itemNumber; + } + + bench(row: Case): string { + const [hearing] = row.hearings; + return hearing.bench; + } + + proceedings(row: Case): string { + const [hearing] = row.hearings; + return hearing.proceedings; + } + + nextHearingDate(row: Case): string { + const [hearing] = row.hearings; + return hearing.nextHearingDate || ''; + } + + otherHearingDates(row: Case): string { + return row.hearings + .map((x) => x.nextHearingDate) + .filter((x) => !!x) + .join(', '); + } + + show() { + const info = this.getInfo(); + this.router.navigate(['cause-list'], { + queryParams: { + startDate: info.startDate, + finishDate: info.finishDate, + }, + }); + } + + getInfo(): CauseList { + const formModel = this.form.value; + + return new CauseList({ + startDate: moment(formModel.startDate).format('DD-MMM-YYYY'), + finishDate: moment(formModel.finishDate).format('DD-MMM-YYYY'), + }); + } +} diff --git a/otis/src/app/cause-list/cause-list.module.spec.ts b/otis/src/app/cause-list/cause-list.module.spec.ts new file mode 100644 index 0000000..a4c5dee --- /dev/null +++ b/otis/src/app/cause-list/cause-list.module.spec.ts @@ -0,0 +1,13 @@ +import { CauseListModule } from './cause-list.module'; + +describe('CauseListModule', () => { + let causeListModule: CauseListModule; + + beforeEach(() => { + causeListModule = new CauseListModule(); + }); + + it('should create an instance', () => { + expect(causeListModule).toBeTruthy(); + }); +}); diff --git a/otis/src/app/cause-list/cause-list.module.ts b/otis/src/app/cause-list/cause-list.module.ts new file mode 100644 index 0000000..34ce7e6 --- /dev/null +++ b/otis/src/app/cause-list/cause-list.module.ts @@ -0,0 +1,63 @@ +import { CdkTableModule } from '@angular/cdk/table'; +import { CommonModule } from '@angular/common'; +import { NgModule } from '@angular/core'; +import { FlexLayoutModule } from '@angular/flex-layout'; +import { ReactiveFormsModule } from '@angular/forms'; +import { MomentDateAdapter } from '@angular/material-moment-adapter'; +import { MatButtonModule } from '@angular/material/button'; +import { MatCardModule } from '@angular/material/card'; +import { + DateAdapter, + MAT_DATE_FORMATS, + MAT_DATE_LOCALE, + MatNativeDateModule, +} from '@angular/material/core'; +import { MatDatepickerModule } from '@angular/material/datepicker'; +import { MatDialogModule } from '@angular/material/dialog'; +import { MatIconModule } from '@angular/material/icon'; +import { MatInputModule } from '@angular/material/input'; +import { MatPaginatorModule } from '@angular/material/paginator'; +import { MatProgressSpinnerModule } from '@angular/material/progress-spinner'; +import { MatSelectModule } from '@angular/material/select'; +import { MatTableModule } from '@angular/material/table'; + +import { CauseListRoutingModule } from './cause-list-routing.module'; +import { CauseListComponent } from './cause-list.component'; + +export const MY_FORMATS = { + parse: { + dateInput: 'DD-MMM-YYYY', + }, + display: { + dateInput: 'DD-MMM-YYYY', + monthYearLabel: 'MMM YYYY', + dateA11yLabel: 'DD-MMM-YYYY', + monthYearA11yLabel: 'MMM YYYY', + }, +}; + +@NgModule({ + imports: [ + CommonModule, + CdkTableModule, + FlexLayoutModule, + MatButtonModule, + MatCardModule, + MatIconModule, + MatInputModule, + MatProgressSpinnerModule, + MatTableModule, + ReactiveFormsModule, + CauseListRoutingModule, + MatSelectModule, + MatPaginatorModule, + MatDatepickerModule, + MatDialogModule, + ], + declarations: [CauseListComponent], + providers: [ + { provide: DateAdapter, useClass: MomentDateAdapter, deps: [MAT_DATE_LOCALE] }, + { provide: MAT_DATE_FORMATS, useValue: MY_FORMATS }, + ], +}) +export class CauseListModule {} diff --git a/otis/src/app/cause-list/cause-list.service.spec.ts b/otis/src/app/cause-list/cause-list.service.spec.ts new file mode 100644 index 0000000..6004f63 --- /dev/null +++ b/otis/src/app/cause-list/cause-list.service.spec.ts @@ -0,0 +1,15 @@ +import { inject, TestBed } from '@angular/core/testing'; + +import { CauseListService } from './cause-list.service'; + +describe('CauseListService', () => { + beforeEach(() => { + TestBed.configureTestingModule({ + providers: [CauseListService], + }); + }); + + it('should be created', inject([CauseListService], (service: CauseListService) => { + expect(service).toBeTruthy(); + })); +}); diff --git a/otis/src/app/cause-list/cause-list.service.ts b/otis/src/app/cause-list/cause-list.service.ts new file mode 100644 index 0000000..53a3efb --- /dev/null +++ b/otis/src/app/cause-list/cause-list.service.ts @@ -0,0 +1,31 @@ +import { HttpClient, HttpParams } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { Observable } from 'rxjs/internal/Observable'; +import { catchError } from 'rxjs/operators'; + +import { ErrorLoggerService } from '../core/error-logger.service'; + +import { CauseList } from './cause-list'; + +const url = '/api/cause-list'; +const serviceName = 'CauseListService'; + +@Injectable({ + providedIn: 'root', +}) +export class CauseListService { + constructor(private http: HttpClient, private log: ErrorLoggerService) {} + + list(startDate: string | null, finishDate: string | null): Observable { + const options = { params: new HttpParams() }; + if (startDate !== null) { + options.params = options.params.set('s', startDate); + } + if (finishDate !== null) { + options.params = options.params.set('f', finishDate); + } + return this.http + .get(url, options) + .pipe(catchError(this.log.handleError(serviceName, 'list'))) as Observable; + } +} diff --git a/otis/src/app/cause-list/cause-list.ts b/otis/src/app/cause-list/cause-list.ts new file mode 100644 index 0000000..ead4346 --- /dev/null +++ b/otis/src/app/cause-list/cause-list.ts @@ -0,0 +1,14 @@ +import { Case } from '../core/case'; + +export class CauseList { + startDate: string; + finishDate: string; + cases: Case[]; + + public constructor(init?: Partial) { + this.startDate = ''; + this.finishDate = ''; + this.cases = []; + Object.assign(this, init); + } +} diff --git a/otis/src/app/nav-bar/nav-bar.component.html b/otis/src/app/nav-bar/nav-bar.component.html index abba0f9..99a457a 100644 --- a/otis/src/app/nav-bar/nav-bar.component.html +++ b/otis/src/app/nav-bar/nav-bar.component.html @@ -3,7 +3,7 @@ home Home - Cases + Cause List Acts Advocates