Skip to content
Merged
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
13 changes: 10 additions & 3 deletions src/@seed/components/page/inventory-tab/inventory-tab.component.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { CommonModule } from '@angular/common'
import type { OnDestroy, OnInit } from '@angular/core'
import type { OnChanges, OnDestroy, OnInit, SimpleChanges } from '@angular/core'
import { Component, inject, Input } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { Subject } from 'rxjs'
Expand All @@ -12,18 +12,25 @@ import type { Config } from './inventory-tab.types'
templateUrl: './inventory-tab.component.html',
imports: [CommonModule, SharedImports],
})
export class InventoryTabComponent implements OnDestroy, OnInit {
export class InventoryTabComponent implements OnChanges, OnDestroy, OnInit {
private _route = inject(ActivatedRoute)
@Input() config: Config
@Input() inputType?: InventoryType // special case for organization columns
type: InventoryType
private readonly _unsubscribeAll$ = new Subject<void>()

ngOnInit(): void {
this._route.paramMap.subscribe((params) => {
this.type = params.get('type') as InventoryType
this.type = params.get('type') as InventoryType || this.inputType
})
}

ngOnChanges(changes: SimpleChanges) {
if (changes.inputType && this.inputType) {
this.type = this.inputType
}
}

ngOnDestroy(): void {
this._unsubscribeAll$.next()
this._unsubscribeAll$.complete()
Expand Down
10 changes: 5 additions & 5 deletions src/app/modules/organizations/columns/columns.component.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ <h3 class="text-sm font-semibold uppercase tracking-wider text-primary-400">Colu
}"
>
@if (useTabs) {
<nav [tabPanel]="tabPanel" mat-tab-nav-bar>
@for (tab of tabs; track tab.label) {
<a [active]="tab.route === currentType()" (click)="navigateTo(tab.route)" mat-tab-link>{{ tab.label }}</a>
}
</nav>
<seed-page-inventory-tab
[config]="{ tabs: ['properties', 'taxlots'], action: navigateTo.bind(this) }"
[inputType]="currentType()"
></seed-page-inventory-tab>
}

<mat-tab-nav-panel class="p-4" #tabPanel>
<router-outlet></router-outlet>
</mat-tab-nav-panel>
Expand Down
25 changes: 18 additions & 7 deletions src/app/modules/organizations/columns/columns.component.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ import { MatSidenavModule } from '@angular/material/sidenav'
import { MatTabsModule } from '@angular/material/tabs'
import { Title } from '@angular/platform-browser'
import { Router, RouterOutlet } from '@angular/router'
import { DrawerService, type NavigationItem, VerticalNavigationComponent } from '@seed/components'
import { DrawerService, InventoryTabComponent, type NavigationItem, VerticalNavigationComponent } from '@seed/components'
import { PageComponent } from '@seed/components'
import { SharedImports } from '@seed/directives'
import type { InventoryType } from 'app/modules/inventory'
import { ColumnDataTypesHelpComponent } from './data-types/help.component'
import { ColumnGeocodingHelpComponent } from './geocoding/help.component'
import { ColumnImportSettingsHelpComponent } from './import-settings/help.component'
import { ColumnListHelpComponent } from './list/help.component'
import { ColumnMappingHelpComponent } from './mappings/help.component'
import { ColumnMatchingCriteriaHelpComponent } from './matching-criteria/help.component'

type ColumnNavigationItem = NavigationItem & { useTabs: boolean; helpComponent: Type<Component> | null }
@Component({
Expand All @@ -24,6 +26,7 @@ type ColumnNavigationItem = NavigationItem & { useTabs: boolean; helpComponent:
imports: [
CommonModule,
SharedImports,
InventoryTabComponent,
MatButtonModule,
MatIconModule,
MatSidenavModule,
Expand Down Expand Up @@ -92,6 +95,15 @@ export class ColumnsComponent implements AfterViewInit, OnInit {
fn: (n: ColumnNavigationItem) => { this.setPageInfo(n) },
helpComponent: ColumnImportSettingsHelpComponent,
},
{
id: 'organizations/columns/matching-criteria',
link: '/organizations/columns/matching-criteria',
title: 'Matching Criteria',
type: 'basic',
useTabs: true,
fn: (n: ColumnNavigationItem) => { this.setPageInfo(n) },
helpComponent: ColumnMatchingCriteriaHelpComponent,
},
{
id: 'organizations/columns/mappings',
link: '/organizations/columns/mappings',
Expand All @@ -111,15 +123,14 @@ export class ColumnsComponent implements AfterViewInit, OnInit {
this._drawerService.setDrawer(this.drawer)
}

currentType(): string {
return this._location.path().split('/').pop()
currentType() {
return this._location.path().split('/').pop() as InventoryType
}

async navigateTo(type: string) {
async navigateTo(type: InventoryType) {
const loc = this._location.path()
if (loc.includes(type)) {
return
}
if (loc.includes(type)) return

const newPath = loc.replace(this.inverseType(type), type)
await this._router.navigateByUrl(newPath).then(() => {
this.setTitle()
Expand Down
17 changes: 17 additions & 0 deletions src/app/modules/organizations/columns/columns.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { ImportSettingsTaxLotsComponent } from './import-settings/import-setting
import { ListPropertiesComponent } from './list/list-properties.component'
import { ListTaxLotComponent } from './list/list-taxlots.component'
import { MappingsComponent } from './mappings/mappings.component'
import { MatchingCriteriaPropertiesComponent } from './matching-criteria/matching-criteria-properties.component'
import { MatchingCriteriaTaxlotsComponent } from './matching-criteria/matching-criteria-taxlots.component'

export default [
{
Expand Down Expand Up @@ -71,6 +73,21 @@ export default [
title: 'Import Settings',
component: ImportSettingsTaxLotsComponent,
},
{
path: 'matching-criteria',
pathMatch: 'full',
redirectTo: 'matching-criteria/properties',
},
{
path: 'matching-criteria/properties',
title: 'Matching Criteria',
component: MatchingCriteriaPropertiesComponent,
},
{
path: 'matching-criteria/taxlots',
title: 'Matching Criteria',
component: MatchingCriteriaTaxlotsComponent,
},
{
path: 'mappings',
title: 'Column Mappings',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<div class="" (cdkDropListDropped)="drop($event)" cdkDropList>
@for (column of columns; track column.id) {
<div
class="w-75 my-2 flex flex-row items-center justify-between space-x-2 rounded-md border border-solid border-slate-600 p-2 drop-shadow-md"
class="w-75 dark:color-white my-2 flex flex-row items-center justify-between space-x-2 rounded-md border border-solid border-slate-600 bg-slate-100 p-2 drop-shadow-md dark:bg-gray-700"
cdkDrag
>
<div class="leading-40 flex flex-row space-x-4 text-lg">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<div class="my-4 flex flex-row border-b-2 border-solid border-gray-700 py-4 dark:border-gray-200">
<div class="flex w-2/3 text-lg">Column Name</div>
<div class="flex w-1/3 text-lg">Remove</div>
</div>
@for (column of columns; track column.id) {
<div class="my-2 flex flex-row">
<div class="flex w-2/3 text-lg">{{ column.display_name }}</div>
<div class="flex w-1/3">
@if (canRemove(column)) {
<a class="flex" (click)="removeColumn(column)" mat-stroked-button matTooltip="Remove Column From Matching Criteria">
<mat-icon class="fill-red-700 icon-size-4" svgIcon="fa-solid:x"></mat-icon>
</a>
} @else {
Locked
}
</div>
</div>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Component, EventEmitter, Input, Output, ViewEncapsulation } from '@angular/core'
import { MatButtonModule } from '@angular/material/button'
import { MatIcon } from '@angular/material/icon'
import { type Column } from '@seed/api/column'
import { SharedImports } from '@seed/directives'

@Component({
selector: 'seed-matching-criteria-list',
templateUrl: './criteria-list.component.html',
encapsulation: ViewEncapsulation.None,
imports: [SharedImports, MatButtonModule, MatIcon],
})

export class CriteriaListComponent {
@Input() columns: Column[]
@Output() removeColumnEvent = new EventEmitter<Column>()

removeColumn(column: Column) {
this.removeColumnEvent.emit(column)
}

canRemove(column: Column) {
return !column.is_matching_criteria
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<div class="prose px-4" *transloco="let t">
<h2 class="mt-6 flex items-center border-b-2 font-extrabold tracking-tight">
{{ t('Help') }}<mat-icon class="mx-2 text-current icon-size-3" svgIcon="fa-solid:chevron-right"></mat-icon
>{{ t('MODIFYING_COLUMN_SETTINGS') }}
</h2>
<p>{{ t('COL_MATCHING_CRITERIA_TOGGLE') }}</p>
<p>{{ t('MATCHING_CRITERIA_PREVIEW_WARNING') }}</p>
</div>
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Component, ViewEncapsulation } from '@angular/core'
import { MatIcon } from '@angular/material/icon'
import { SharedImports } from '@seed/directives'

@Component({
selector: 'seed-organizations-column-matching-criteria-help',
templateUrl: './help.component.html',
encapsulation: ViewEncapsulation.None,
imports: [SharedImports, MatIcon],
})

export class ColumnMatchingCriteriaHelpComponent {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { CommonModule } from '@angular/common'
import { Component, type OnInit, ViewEncapsulation } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { MatButtonModule } from '@angular/material/button'
import { MatDividerModule } from '@angular/material/divider'
import { MatFormFieldModule } from '@angular/material/form-field'
import { MatIconModule } from '@angular/material/icon'
import { MatInputModule } from '@angular/material/input'
import { MatSelectModule } from '@angular/material/select'
import { MatTooltipModule } from '@angular/material/tooltip'
import { AgGridAngular, AgGridModule } from 'ag-grid-angular'
import { combineLatest, takeUntil } from 'rxjs'
import { SharedImports } from '@seed/directives'
import { CriteriaListComponent } from './criteria-list.component'
import { MatchingCriteriaComponent } from './matching-criteria.component'

@Component({
selector: 'seed-organizations-column-matching-criteria',
templateUrl: './matching-criteria.component.html',
encapsulation: ViewEncapsulation.None,
imports: [
AgGridAngular,
AgGridModule,
CommonModule,
CriteriaListComponent,
FormsModule,
MatButtonModule,
MatDividerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
SharedImports,
MatSelectModule,
MatTooltipModule,
ReactiveFormsModule,
],
})
export class MatchingCriteriaPropertiesComponent extends MatchingCriteriaComponent implements OnInit {
ngOnInit(): void {
combineLatest([
this._columnService.propertyColumns$,
this._organizationService.currentOrganization$,
])
.pipe(takeUntil(this._unsubscribeAll$))
.subscribe(([columns, organization]) => {
this.organization = organization
this.populateMatchingColumns(columns)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { CommonModule } from '@angular/common'
import { Component, type OnInit, ViewEncapsulation } from '@angular/core'
import { FormsModule, ReactiveFormsModule } from '@angular/forms'
import { MatButtonModule } from '@angular/material/button'
import { MatDividerModule } from '@angular/material/divider'
import { MatFormFieldModule } from '@angular/material/form-field'
import { MatIconModule } from '@angular/material/icon'
import { MatInputModule } from '@angular/material/input'
import { MatSelectModule } from '@angular/material/select'
import { MatTooltipModule } from '@angular/material/tooltip'
import { AgGridAngular, AgGridModule } from 'ag-grid-angular'
import { combineLatest, takeUntil } from 'rxjs'
import { SharedImports } from '@seed/directives'
import { CriteriaListComponent } from './criteria-list.component'
import { MatchingCriteriaComponent } from './matching-criteria.component'

@Component({
selector: 'seed-organizations-column-matching-criteria-taxlots',
templateUrl: './matching-criteria.component.html',
encapsulation: ViewEncapsulation.None,
imports: [
AgGridAngular,
AgGridModule,
CommonModule,
CriteriaListComponent,
FormsModule,
MatButtonModule,
MatDividerModule,
MatFormFieldModule,
MatIconModule,
MatInputModule,
SharedImports,
ReactiveFormsModule,
MatSelectModule,
MatTooltipModule,
],
})
export class MatchingCriteriaTaxlotsComponent extends MatchingCriteriaComponent implements OnInit {
ngOnInit(): void {
combineLatest([
this._columnService.taxLotColumns$,
this._organizationService.currentOrganization$,
])
.pipe(takeUntil(this._unsubscribeAll$))
.subscribe(([columns, organization]) => {
this.organization = organization
this.populateMatchingColumns(columns)
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<!-- Current -->
<div class="mb-4 ml-4 flex items-center text-lg font-medium">
<mat-icon svgIcon="fa-solid:layer-group"></mat-icon>
<span class="ml-4">Current Criteria</span>
</div>

<div class="mb-10">
@if (rowDataCurrent.length) {
<ag-grid-angular
[columnDefs]="columnDefsCurrent"
[defaultColDef]="defaultColDef"
[rowData]="rowDataCurrent"
[style.height.px]="gridHeightCurrent"
[theme]="gridTheme$ | async"
(gridReady)="onCurrentReady($event)"
></ag-grid-angular>
}
</div>

<mat-divider></mat-divider>

<!-- Pending -->
@if (rowDataPending.length) {
<div class="mt-2 flex justify-between">
<div class="my-4 ml-4 flex items-center text-lg font-medium">
<mat-icon svgIcon="fa-solid:pen-to-square"></mat-icon>
<span class="ml-4">Pending Changes</span>
</div>

<button class="my-2" (click)="save()" color="primary" mat-raised-button>Save Changes</button>
</div>

<div class="mb-10">
<ag-grid-angular
[columnDefs]="columnDefsPending"
[defaultColDef]="defaultColDef"
[rowData]="rowDataPending"
[style.height.px]="gridHeightPending"
[theme]="gridTheme$ | async"
(gridReady)="onPendingReady($event)"
></ag-grid-angular>
</div>

<mat-divider></mat-divider>
}

<form class="mt-4 flex w-1/2 flex-col" [formGroup]="addForm" (ngSubmit)="addColumn()">
<div class="flex gap-4">
<mat-form-field class="w-full" hideRequiredMarker>
<mat-label>Add Column</mat-label>
<mat-select formControlName="columnToAdd">
@for (c of availableColumns; track c.id) {
<mat-option [value]="c.id">{{ c.display_name }}</mat-option>
}
</mat-select>
</mat-form-field>

<button class="my-auto flex" [disabled]="!addForm.get('columnToAdd').value" mat-stroked-button>Add</button>
</div>
</form>
Loading