Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a98eb8c
detail side nav fxnal
perryr16 May 30, 2025
6804581
inv list icons and notes grid
perryr16 Jun 2, 2025
1890f35
notes dev
perryr16 Jun 3, 2025
492600c
modal base
perryr16 Jun 3, 2025
f2685f1
Merge branch 'main' into feat/detail-side-nav
perryr16 Jun 3, 2025
e39378c
notes modal, displayfield, side scroll
perryr16 Jun 3, 2025
1ec3817
column profiles shared btw list and detail
perryr16 Jun 4, 2025
54969eb
meters sans actions
perryr16 Jun 4, 2025
d293b91
meter modals
perryr16 Jun 5, 2025
e6786dc
error cleanup
perryr16 Jun 6, 2025
6d9c1e0
greenbutton dev and base for other detail sub pages
perryr16 Jun 6, 2025
f28c187
ubid map
perryr16 Jun 9, 2025
9afeb4f
ubid fxnal
perryr16 Jun 10, 2025
b0a0db2
sensor and readings grid displays
perryr16 Jun 11, 2025
78875d8
directory refactor
perryr16 Jun 11, 2025
f8b9dc7
sensor & dl modals, interval
perryr16 Jun 11, 2025
b0f46a0
list calls from parent
perryr16 Jun 11, 2025
cfe9c94
sensor upload
perryr16 Jun 12, 2025
2cc5008
prettier
perryr16 Jun 12, 2025
a7fbcf5
lint
perryr16 Jun 12, 2025
4a98ce6
lint
perryr16 Jun 13, 2025
2ccb663
root services are never destoryed
perryr16 Jun 13, 2025
73cae0e
progress bar component
perryr16 Jun 13, 2025
5e171b5
pulse load and refactor progress
perryr16 Jun 13, 2025
659cbc6
sensor upload
perryr16 Jun 13, 2025
1d1ae64
loading
perryr16 Jun 13, 2025
138cc45
prettier
perryr16 Jun 13, 2025
cc5be11
sensor/readings upload validation
perryr16 Jun 13, 2025
a828a92
lint
perryr16 Jun 13, 2025
92733cb
upload cleanup
perryr16 Jun 16, 2025
7500209
refactor
perryr16 Jun 16, 2025
60d206e
prettier
perryr16 Jun 16, 2025
b70e7de
bugs
perryr16 Jun 16, 2025
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
16 changes: 15 additions & 1 deletion cspell.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,19 @@
"/.spelling.dic",
"/pnpm-lock.yaml"
],
"useGitignore": true
"useGitignore": true,
"words": [
"eeej",
"EPSG",
"FEMP",
"falsey",
"greenbutton",
"movened",
"overlaycontainer",
"SRID",
"ubids",
"unpair",
"Unpair",
"unpairing",
]
}
5 changes: 2 additions & 3 deletions src/@seed/api/audit-template/audit-template.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HttpErrorResponse } from '@angular/common/http'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import type { Observable } from 'rxjs'
import { catchError, map, ReplaySubject, Subject, takeUntil } from 'rxjs'
import { catchError, map, ReplaySubject } from 'rxjs'
import { ErrorService } from '@seed/services/error/error.service'
import { UserService } from '../user'
import type {
Expand All @@ -17,7 +17,6 @@ export class AuditTemplateService {
private _httpClient = inject(HttpClient)
private _userService = inject(UserService)
private _errorService = inject(ErrorService)
private readonly _unsubscribeAll$ = new Subject<void>()
private _reportTypes = new ReplaySubject<AuditTemplateReportType[]>(1)
private _auditTemplateConfig = new ReplaySubject<AuditTemplateConfig>(1)
reportTypes$ = this._reportTypes.asObservable()
Expand Down Expand Up @@ -48,7 +47,7 @@ export class AuditTemplateService {
{ name: 'WA Commerce Clean Buildings - Form D Report' },
{ name: 'WA Commerce Grants Report' },
])
this._userService.currentOrganizationId$.pipe(takeUntil(this._unsubscribeAll$)).subscribe((organizationId) => {
this._userService.currentOrganizationId$.subscribe((organizationId) => {
this.getConfigs(organizationId).subscribe()
})
}
Expand Down
5 changes: 2 additions & 3 deletions src/@seed/api/column/column.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HttpErrorResponse } from '@angular/common/http'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import type { Observable } from 'rxjs'
import { catchError, map, ReplaySubject, Subject, takeUntil } from 'rxjs'
import { catchError, map, ReplaySubject } from 'rxjs'
import type { ProgressResponse } from '@seed/api/progress'
import { ErrorService } from '@seed/services/error/error.service'
import { UserService } from '../user'
Expand All @@ -16,14 +16,13 @@ export class ColumnService {

private _propertyColumns = new ReplaySubject<Column[]>(1)
private _taxLotColumns = new ReplaySubject<Column[]>(1)
private readonly _unsubscribeAll$ = new Subject<void>()

propertyColumns$ = this._propertyColumns.asObservable()
taxLotColumns$ = this._taxLotColumns.asObservable()

constructor() {
// Fetch current org data whenever user org id changes
this._userService.currentOrganizationId$.pipe(takeUntil(this._unsubscribeAll$)).subscribe((organizationId) => {
this._userService.currentOrganizationId$.subscribe((organizationId) => {
this.getPropertyColumns(organizationId).subscribe()
this.getTaxLotColumns(organizationId).subscribe()
})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HttpErrorResponse } from '@angular/common/http'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import type { Observable } from 'rxjs'
import { catchError, map, ReplaySubject, Subject, takeUntil } from 'rxjs'
import { catchError, map, ReplaySubject } from 'rxjs'
import { ErrorService } from '@seed/services'
import { UserService } from '../user'
import type { ColumnMapping, ColumnMappingProfile, ColumnMappingProfileDeleteResponse, ColumnMappingProfilesRequest, ColumnMappingProfileUpdateResponse, ColumnMappingSuggestionResponse } from './column_mapping_profile.types'
Expand All @@ -13,13 +13,12 @@ export class ColumnMappingProfileService {
private _userService = inject(UserService)
private _profiles = new ReplaySubject<ColumnMappingProfile[]>(1)
private _errorService = inject(ErrorService)
private readonly _unsubscribeAll$ = new Subject<void>()

profiles$ = this._profiles.asObservable()

constructor() {
// Fetch current org data whenever user org id changes
this._userService.currentOrganizationId$.pipe(takeUntil(this._unsubscribeAll$)).subscribe((organizationId) => {
this._userService.currentOrganizationId$.subscribe((organizationId) => {
this.getProfiles(organizationId).subscribe()
})
}
Expand Down
26 changes: 12 additions & 14 deletions src/@seed/api/cycle/cycle.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HttpErrorResponse } from '@angular/common/http'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import type { Observable } from 'rxjs'
import { BehaviorSubject, catchError, map, Subject, switchMap, takeUntil, tap } from 'rxjs'
import { BehaviorSubject, catchError, map, take, tap } from 'rxjs'
import { OrganizationService } from '@seed/api/organization'
import { ErrorService } from '@seed/services'
import { SnackBarService } from 'app/core/snack-bar/snack-bar.service'
Expand All @@ -15,38 +15,34 @@ export class CycleService {
private _snackBar = inject(SnackBarService)
private _errorService = inject(ErrorService)
private _cycles = new BehaviorSubject<Cycle[]>([])
private readonly _unsubscribeAll$ = new Subject<void>()
orgId: number

cycles$ = this._cycles.asObservable()

constructor() {
this._organizationService.currentOrganization$
.pipe(
takeUntil(this._unsubscribeAll$),
switchMap(({ org_id }) => this.get(org_id)),
)
.subscribe()
this._organizationService.currentOrganization$.pipe(
tap(({ org_id }) => { this.get(org_id) }),
).subscribe()
}

get(orgId: number): Observable<Cycle[]> {
get(orgId: number) {
const url = `/api/v3/cycles/?organization_id=${orgId}`
return this._httpClient.get<CyclesResponse>(url).pipe(
this._httpClient.get<CyclesResponse>(url).pipe(
take(1),
map(({ cycles }) => cycles),
tap((cycles) => {
this._cycles.next(cycles)
}),
tap((cycles) => { this._cycles.next(cycles) }),
catchError((error: HttpErrorResponse) => {
return this._errorService.handleError(error, 'Error fetching cycles')
}),
)
).subscribe()
}

post({ data, orgId }): Observable<CycleResponse | null> {
const url = `/api/v3/cycles/?organization_id=${orgId}`
return this._httpClient.post<CycleResponse>(url, data).pipe(
tap((response) => {
this._snackBar.success(`Created Cycle ${response.cycles.name}`)
this.get(orgId as number)
}),
catchError((error: HttpErrorResponse) => {
return this._errorService.handleError(error, 'Error creating cycle')
Expand All @@ -59,6 +55,7 @@ export class CycleService {
return this._httpClient.put<CycleResponse>(url, data).pipe(
tap((response) => {
this._snackBar.success(`Updated Cycle ${response.cycles.name}`)
this.get(orgId as number)
}),
catchError((error: HttpErrorResponse) => {
return this._errorService.handleError(error, 'Error updating cycle')
Expand All @@ -69,6 +66,7 @@ export class CycleService {
delete(id: number, orgId: number) {
const url = `/api/v3/cycles/${id}/?organization_id=${orgId}`
return this._httpClient.delete(url).pipe(
tap(() => { this.get(orgId) }),
catchError((error: HttpErrorResponse) => {
return this._errorService.handleError(error, 'Error deleting cycle')
}),
Expand Down
12 changes: 4 additions & 8 deletions src/@seed/api/data-quality/data-quality.service.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { HttpClient, type HttpErrorResponse } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import { catchError, type Observable, ReplaySubject, Subject, switchMap, takeUntil, tap } from 'rxjs'
import { catchError, type Observable, ReplaySubject, switchMap, tap } from 'rxjs'
import { OrganizationService } from '@seed/api/organization'
import { ErrorService } from '@seed/services'
import { SnackBarService } from 'app/core/snack-bar/snack-bar.service'
Expand All @@ -13,17 +13,13 @@ export class DataQualityService {
private _snackBar = inject(SnackBarService)
private _errorService = inject(ErrorService)
private _rules = new ReplaySubject<Rule[]>()
private readonly _unsubscribeAll$ = new Subject<void>()
orgId: number
rules$ = this._rules.asObservable()

constructor() {
this._organizationService.currentOrganization$
.pipe(
takeUntil(this._unsubscribeAll$),
switchMap(({ org_id }) => this.getRules(org_id)),
)
.subscribe()
this._organizationService.currentOrganization$.pipe(
switchMap(({ org_id }) => this.getRules(org_id)),
).subscribe()
}

getRules(orgId: number): Observable<Rule[]> {
Expand Down
5 changes: 2 additions & 3 deletions src/@seed/api/dataset/dataset.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type { HttpErrorResponse } from '@angular/common/http'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import type { Observable } from 'rxjs'
import { catchError, map, of, ReplaySubject, Subject, takeUntil } from 'rxjs'
import { catchError, map, of, ReplaySubject } from 'rxjs'
import { UserService } from '../user'
import type { CountDatasetsResponse, Dataset, ListDatasetsResponse } from './dataset.types'

Expand All @@ -11,13 +11,12 @@ export class DatasetService {
private _httpClient = inject(HttpClient)
private _userService = inject(UserService)

private readonly _unsubscribeAll$ = new Subject<void>()
private _datasetCount = new ReplaySubject<number>(1)
datasetCount$ = this._datasetCount.asObservable()

constructor() {
// Refresh dataset count only when the organization ID changes
this._userService.currentOrganizationId$.pipe(takeUntil(this._unsubscribeAll$)).subscribe((organizationId) => {
this._userService.currentOrganizationId$.subscribe((organizationId) => {
this.countDatasets(organizationId).subscribe()
})
}
Expand Down
10 changes: 2 additions & 8 deletions src/@seed/api/derived-column/derived-column.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { HttpErrorResponse } from '@angular/common/http'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import { catchError, map, type Observable, ReplaySubject, Subject, switchMap, takeUntil, tap } from 'rxjs'
import { catchError, map, type Observable, ReplaySubject, switchMap, tap } from 'rxjs'
import { ErrorService } from '@seed/services/error/error.service'
import { SnackBarService } from 'app/core/snack-bar/snack-bar.service'
import { OrganizationService } from '../organization'
Expand All @@ -14,19 +14,13 @@ export class DerivedColumnService {
private _snackBar = inject(SnackBarService)
private _errorService = inject(ErrorService)
private _derivedColumns = new ReplaySubject<DerivedColumn[]>()
private readonly _unsubscribeAll$ = new Subject<void>()

orgId: number

derivedColumns$ = this._derivedColumns.asObservable()

constructor() {
this._organizationService.currentOrganization$
.pipe(
takeUntil(this._unsubscribeAll$),
switchMap(({ org_id }) => this.get(org_id)),
)
.subscribe()
this._organizationService.currentOrganization$.pipe(switchMap(({ org_id }) => this.get(org_id))).subscribe()
}

get(orgId: number): Observable<DerivedColumn[]> {
Expand Down
41 changes: 27 additions & 14 deletions src/@seed/api/groups/groups.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { HttpErrorResponse } from '@angular/common/http'
import { HttpClient } from '@angular/common/http'
import { inject, Injectable } from '@angular/core'
import { BehaviorSubject, catchError, map, type Observable, Subject, takeUntil, tap } from 'rxjs'
import { BehaviorSubject, catchError, map, type Observable, take, tap } from 'rxjs'
import { ErrorService } from '@seed/services'
import { SnackBarService } from 'app/core/snack-bar/snack-bar.service'
import { OrganizationService } from '../organization'
Expand All @@ -10,39 +10,48 @@ import type { InventoryGroup, InventoryGroupResponse, InventoryGroupsResponse }
@Injectable({ providedIn: 'root' })
export class GroupsService {
private _errorService = inject(ErrorService)
private _groups = new BehaviorSubject<unknown>([])
private _groups = new BehaviorSubject<InventoryGroup[]>([])
private _httpClient = inject(HttpClient)
private _organizationService = inject(OrganizationService)
private _snackBar = inject(SnackBarService)
private readonly _unsubscribeAll$ = new Subject<void>()

groups$ = this._groups.asObservable()
orgId: number

constructor() {
this._organizationService.currentOrganization$
.pipe(takeUntil(this._unsubscribeAll$))
.subscribe(({ org_id }) => this.orgId = org_id)
}

list(orgId: number): Observable<InventoryGroup[]> {
list(orgId: number) {
const url = `/api/v3/inventory_groups/?organization_id=${orgId}`
return this._httpClient.get<InventoryGroupsResponse>(url).pipe(
this._httpClient.get<InventoryGroupsResponse>(url).pipe(
take(1),
map(({ data }) => {
this._groups.next(data)
return data
}),
catchError((error: HttpErrorResponse) => {
return this._errorService.handleError(error, 'Error fetching groups')
}),
)
).subscribe()
}

listForInventory(orgId: number, inventoryIds: number[]) {
const url = `/api/v3/inventory_groups/filter/?organization_id=${orgId}&inventory_type=properties`
const body = { selected: inventoryIds }
this._httpClient.post<InventoryGroupsResponse>(url, body).pipe(
take(1),
map(({ data }) => {
this._groups.next(data)
return data
}),
catchError((error: HttpErrorResponse) => {
return this._errorService.handleError(error, 'Error fetching groups for inventory')
}),
).subscribe()
}

create(orgId: number, data: InventoryGroup): Observable<InventoryGroup> {
const url = `/api/v3/inventory_groups/?organization_id=${orgId}`
return this._httpClient.post<InventoryGroupResponse>(url, data).pipe(
map(({ data }) => {
this._snackBar.success('Group created successfully')
this.list(orgId)
return data
}),
catchError((error: HttpErrorResponse) => {
Expand All @@ -56,6 +65,7 @@ export class GroupsService {
return this._httpClient.put<InventoryGroupResponse>(url, data).pipe(
map(({ data }) => {
this._snackBar.success('Group updated successfully')
this.list(orgId)
return data
}),
catchError((error: HttpErrorResponse) => {
Expand All @@ -67,7 +77,10 @@ export class GroupsService {
delete(orgId: number, id: number): Observable<unknown> {
const url = `/api/v3/inventory_groups/${id}/?organization_id=${orgId}`
return this._httpClient.delete(url).pipe(
tap(() => { this._snackBar.success('Group deleted successfully') }),
tap(() => {
this._snackBar.success('Group deleted successfully')
this.list(orgId)
}),
catchError((error: HttpErrorResponse) => {
return this._errorService.handleError(error, 'Error deleting group')
}),
Expand Down
22 changes: 21 additions & 1 deletion src/@seed/api/groups/groups.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,26 @@ export type InventoryGroup = {
inventory_type: InventoryDisplayType;
name: string;
organization: number;
systems: Record<string, unknown>[];
systems: GroupSystem[];
views_list: number[];
}

export type GroupSystem = {
cooling_capacity: number | null;
count: number;
des_type: string;
group_id: number;
heating_capacity: number | null;
id: number;
mode: string;
name: string;
services: GroupService[];
type: string;
}

export type GroupService = {
emission_factor: number;
id: number;
name: string;
properties: number[];
}
Loading