Skip to content

Commit 1f33e3b

Browse files
authored
Create reusable inventory tab component (#13)
reusable inventory tab component
1 parent e93a659 commit 1f33e3b

20 files changed

+81
-99
lines changed

src/@seed/components/page/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
export * from './page.component'
22
export * from './table/table-container.component'
3+
export * from './inventory-tab'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './inventory-tab.component'
2+
export * from './inventory-tab.types'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<div class="flex space-x-1" *transloco="let t">
2+
@for (tab of config.tabs; track tab) {
3+
<div
4+
class="bg-default relative flex cursor-pointer self-start overflow-hidden rounded-t border border-b-0 pb-1 pl-5 pr-4 pt-2"
5+
[ngClass]="type === tab ? ['z-2', 'text-primary'] : ['bg-slate-50', 'dark:bg-slate-700']"
6+
(click)="config.action(tab)"
7+
matRipple
8+
>
9+
<div class="overflow-hidden">
10+
<div class="truncate font-medium leading-6">{{ t(tab) }}</div>
11+
</div>
12+
</div>
13+
}
14+
</div>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { NgClass } from '@angular/common'
2+
import type { OnDestroy, OnInit } from '@angular/core'
3+
import { Component, inject, Input } from '@angular/core'
4+
import { ActivatedRoute } from '@angular/router'
5+
import { Subject } from 'rxjs'
6+
import { SharedImports } from '@seed/directives'
7+
import type { InventoryType } from 'app/modules/inventory/inventory.types'
8+
import type { Config } from './inventory-tab.types'
9+
10+
@Component({
11+
selector: 'seed-page-inventory-tab',
12+
templateUrl: './inventory-tab.component.html',
13+
imports: [NgClass, SharedImports],
14+
})
15+
export class InventoryTabComponent implements OnDestroy, OnInit {
16+
private _route = inject(ActivatedRoute)
17+
@Input() config: Config
18+
type: InventoryType
19+
private readonly _unsubscribeAll$ = new Subject<void>()
20+
21+
ngOnInit(): void {
22+
this._route.paramMap.subscribe((params) => {
23+
this.type = params.get('type') as InventoryType
24+
})
25+
}
26+
27+
ngOnDestroy(): void {
28+
this._unsubscribeAll$.next()
29+
this._unsubscribeAll$.complete()
30+
}
31+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
export type Config = {
2+
action: (tab: string) => void;
3+
tabs: string[];
4+
}

src/@seed/components/page/table/table-container.component.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { Component } from '@angular/core'
22

33
@Component({
4-
selector: 'seed-page-table-container',
4+
selector: 'seed-page-inventory-table-container',
55
templateUrl: './table-container.component.html',
66
imports: [],
77
})

src/app/modules/inventory/inventory.component.html

+1-13
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,7 @@
1111
</div>
1212

1313
<!-- Tabs -->
14-
<div class="flex space-x-1">
15-
@for (tab of tabs; track tab) {
16-
<div
17-
class="bg-default relative flex cursor-pointer self-start overflow-hidden rounded-t-xl border border-b-0 pb-1 pl-5 pr-4 pt-2"
18-
[ngClass]="type === tab ? 'z-2' : ['bg-slate-50', 'dark:bg-slate-700']"
19-
(click)="toggleInventoryType(tab)"
20-
>
21-
<div class="overflow-hidden">
22-
<div class="truncate font-medium leading-6">{{ t(tab) }}</div>
23-
</div>
24-
</div>
25-
}
26-
</div>
14+
<seed-page-inventory-tab [config]="{ tabs, action: toggleInventoryType.bind(this) }"></seed-page-inventory-tab>
2715
</div>
2816
</div>
2917

src/app/modules/inventory/inventory.component.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
1-
import { NgClass } from '@angular/common'
21
import { Component, inject, ViewEncapsulation } from '@angular/core'
32
import { MatButtonModule } from '@angular/material/button'
43
import { MatIconModule } from '@angular/material/icon'
54
import { MatTabsModule } from '@angular/material/tabs'
65
import { ActivatedRoute, Router } from '@angular/router'
6+
import { InventoryTabComponent } from '@seed/components'
77
import { SharedImports } from '@seed/directives'
88
import type { InventoryType } from './inventory.types'
99

1010
@Component({
1111
selector: 'seed-inventory',
1212
templateUrl: './inventory.component.html',
1313
encapsulation: ViewEncapsulation.None,
14-
imports: [MatButtonModule, MatIconModule, MatTabsModule, NgClass, SharedImports],
14+
imports: [MatButtonModule, MatIconModule, MatTabsModule, SharedImports, InventoryTabComponent],
1515
})
1616
export class InventoryComponent {
1717
private _activatedRoute = inject(ActivatedRoute)
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export type InventoryType = 'properties' | 'taxlots'
1+
export type InventoryType = 'properties' | 'taxlots' | 'goal'

src/app/modules/organizations/column-mappings/column-mappings.component.html

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
<seed-page [config]="{ title: 'Column Mappings' }" *transloco="let t">
2-
<div class="flex space-x-1">
3-
@for (tab of tabs; track tab) {
4-
<div
5-
class="bg-default relative flex cursor-pointer self-start overflow-hidden rounded-t-xl border border-b-0 pb-1 pl-5 pr-4 pt-2"
6-
[ngClass]="type === tab ? 'z-2' : ['bg-slate-50', 'dark:bg-slate-700']"
7-
(click)="toggleInventoryType(tab)"
8-
matRipple
9-
>
10-
<div class="overflow-hidden">
11-
<div class="truncate font-medium leading-6">{{ t(tab) }}</div>
12-
</div>
13-
</div>
14-
}
15-
</div>
2+
<seed-page-inventory-tab [config]="{ tabs, action: toggleInventoryType.bind(this) }"></seed-page-inventory-tab>
163

174
<div class="z-1 -mt-px flex-auto border-t pt-4 sm:pt-6">
185
<div class="mx-auto w-full max-w-screen-xl">{{ t(type) }} column mappings table</div>

src/app/modules/organizations/column-mappings/column-mappings.component.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
1-
import { NgClass } from '@angular/common'
21
import type { OnInit } from '@angular/core'
32
import { Component, inject, ViewEncapsulation } from '@angular/core'
43
import { ActivatedRoute, Router } from '@angular/router'
5-
import { PageComponent } from '@seed/components'
4+
import { InventoryTabComponent, PageComponent } from '@seed/components'
65
import { SharedImports } from '@seed/directives'
7-
import type { OrganizationTab } from '../organizations.types'
6+
import type { InventoryType } from 'app/modules/inventory/inventory.types'
87

98
@Component({
109
selector: 'seed-organizations-column-mappings',
1110
templateUrl: './column-mappings.component.html',
1211
encapsulation: ViewEncapsulation.None,
13-
imports: [NgClass, PageComponent, SharedImports],
12+
imports: [InventoryTabComponent, PageComponent, SharedImports],
1413
})
1514
export class ColumnMappingsComponent implements OnInit {
1615
private _route = inject(ActivatedRoute)
1716
private _router = inject(Router)
1817

19-
readonly tabs: OrganizationTab[] = ['properties', 'taxlots']
20-
type = this._route.snapshot.paramMap.get('type') as OrganizationTab
18+
readonly tabs: InventoryType[] = ['properties', 'taxlots']
19+
type = this._route.snapshot.paramMap.get('type') as InventoryType
2120
readonly urlSegment = 'column-mappings'
2221
readonly table_type = 'Column Mappings'
2322

2423
ngOnInit(): void {
2524
console.log('organizations column mappings')
2625
}
2726

28-
async toggleInventoryType(type: OrganizationTab) {
27+
async toggleInventoryType(type: InventoryType) {
2928
if (type !== this.type) {
3029
const newRoute = `/organizations/column-mappings/${type}`
3130
await this._router.navigateByUrl(newRoute, { skipLocationChange: false })

src/app/modules/organizations/column-settings/column-settings.component.html

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
<seed-page [config]="{ title: 'Column Settings' }" *transloco="let t">
2-
<div class="flex space-x-1">
3-
@for (tab of tabs; track tab) {
4-
<div
5-
class="bg-default relative flex cursor-pointer self-start overflow-hidden rounded-t-xl border border-b-0 pb-1 pl-5 pr-4 pt-2"
6-
[ngClass]="type === tab ? 'z-2' : ['bg-slate-50', 'dark:bg-slate-700']"
7-
(click)="toggleInventoryType(tab)"
8-
matRipple
9-
>
10-
<div class="overflow-hidden">
11-
<div class="truncate font-medium leading-6">{{ t(tab) }}</div>
12-
</div>
13-
</div>
14-
}
15-
</div>
2+
<seed-page-inventory-tab [config]="{ tabs, action: toggleInventoryType.bind(this) }"></seed-page-inventory-tab>
163

174
<div class="z-1 -mt-px flex-auto border-t pt-4 sm:pt-6">
185
<div class="mx-auto w-full max-w-screen-xl">{{ t(type) }} column settings table</div>

src/app/modules/organizations/column-settings/column-settings.component.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
import { NgClass } from '@angular/common'
21
import type { OnInit } from '@angular/core'
32
import { Component, inject, ViewEncapsulation } from '@angular/core'
43
import { ActivatedRoute, Router } from '@angular/router'
5-
import { PageComponent } from '@seed/components'
4+
import { InventoryTabComponent, PageComponent } from '@seed/components'
65
import { SharedImports } from '@seed/directives'
76
import type { InventoryType } from '../../inventory/inventory.types'
87

98
@Component({
109
selector: 'seed-organizations-column-settings',
1110
templateUrl: './column-settings.component.html',
1211
encapsulation: ViewEncapsulation.None,
13-
imports: [NgClass, PageComponent, SharedImports],
12+
imports: [InventoryTabComponent, PageComponent, SharedImports],
1413
})
1514
export class ColumnSettingsComponent implements OnInit {
1615
private _route = inject(ActivatedRoute)

src/app/modules/organizations/cycles/cycles.component.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<seed-page [config]="{ title: 'Cycles', action: createCycle, actionIcon: 'fa-solid:plus', actionText: 'Create Cycle' }" title="Cycles">
22
<!-- Cycles Table -->
3-
<seed-page-table-container>
3+
<seed-page-inventory-table-container>
44
<table class="mat-elevation-z8 w-full bg-transparent" mat-table matSort [dataSource]="cyclesDataSource" [trackBy]="trackByFn">
55
<ng-container matColumnDef="id">
66
<th mat-header-cell *matHeaderCellDef>ID</th>
@@ -40,5 +40,5 @@
4040
<tr mat-row *matRowDef="let row; columns: cyclesColumns"></tr>
4141
</tbody>
4242
</table>
43-
</seed-page-table-container>
43+
</seed-page-inventory-table-container>
4444
</seed-page>

src/app/modules/organizations/data-quality/data-quality.component.html

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
<seed-page [config]="{ title: 'Data Quality' }" *transloco="let t">
2-
<div class="flex space-x-1">
3-
@for (tab of tabs; track tab) {
4-
<div
5-
class="bg-default relative flex cursor-pointer self-start overflow-hidden rounded-t-xl border border-b-0 pb-1 pl-5 pr-4 pt-2"
6-
[ngClass]="type === tab ? 'z-2' : ['bg-slate-50', 'dark:bg-slate-700']"
7-
(click)="toggleInventoryType(tab)"
8-
matRipple
9-
>
10-
<div class="overflow-hidden">
11-
<div class="truncate font-medium leading-6">{{ t(tab) }}</div>
12-
</div>
13-
</div>
14-
}
15-
</div>
2+
<seed-page-inventory-tab [config]="{ tabs, action: toggleInventoryType.bind(this) }"></seed-page-inventory-tab>
163

174
<div class="z-1 -mt-px flex-auto border-t pt-4 sm:pt-6">
185
<div class="mx-auto w-full max-w-screen-xl">{{ t(type) }} table</div>

src/app/modules/organizations/data-quality/data-quality.component.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,30 @@
1-
import { NgClass } from '@angular/common'
21
import type { OnInit } from '@angular/core'
32
import { Component, inject, ViewEncapsulation } from '@angular/core'
43
import { ActivatedRoute, Router } from '@angular/router'
5-
import { PageComponent } from '@seed/components'
4+
import { InventoryTabComponent, PageComponent } from '@seed/components'
65
import { SharedImports } from '@seed/directives'
7-
import type { OrganizationTab } from '../organizations.types'
6+
import type { InventoryType } from 'app/modules/inventory/inventory.types'
87

98
@Component({
109
selector: 'seed-organizations-data-quality',
1110
templateUrl: './data-quality.component.html',
1211
encapsulation: ViewEncapsulation.None,
13-
imports: [NgClass, PageComponent, SharedImports],
12+
imports: [InventoryTabComponent, PageComponent, SharedImports],
1413
})
1514
export class DataQualityComponent implements OnInit {
1615
private _route = inject(ActivatedRoute)
1716
private _router = inject(Router)
1817

19-
readonly tabs: OrganizationTab[] = ['properties', 'taxlots', 'goal']
20-
type = this._route.snapshot.paramMap.get('type') as OrganizationTab
18+
readonly tabs: InventoryType[] = ['properties', 'taxlots', 'goal']
19+
type = this._route.snapshot.paramMap.get('type') as InventoryType
2120
readonly table_type = 'Data Quality'
2221
readonly urlSegment = 'data-quality'
2322

2423
ngOnInit(): void {
2524
console.log('organizations data quality')
2625
}
2726

28-
async toggleInventoryType(type: OrganizationTab) {
27+
async toggleInventoryType(type: InventoryType) {
2928
if (type !== this.type) {
3029
const newRoute = `/organizations/data-quality/${type}`
3130
await this._router.navigateByUrl(newRoute, { skipLocationChange: false })

src/app/modules/organizations/derived-columns/derived-columns.component.html

+1-14
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,5 @@
11
<seed-page [config]="{ title: 'Derived Columns' }" *transloco="let t">
2-
<div class="flex space-x-1">
3-
@for (tab of tabs; track tab) {
4-
<div
5-
class="bg-default relative flex cursor-pointer self-start overflow-hidden rounded-t-xl border border-b-0 pb-1 pl-5 pr-4 pt-2"
6-
[ngClass]="type === tab ? 'z-2' : ['bg-slate-50', 'dark:bg-slate-700']"
7-
(click)="toggleInventoryType(tab)"
8-
matRipple
9-
>
10-
<div class="overflow-hidden">
11-
<div class="truncate font-medium leading-6">{{ t(tab) }}</div>
12-
</div>
13-
</div>
14-
}
15-
</div>
2+
<seed-page-inventory-tab [config]="{ tabs, action: toggleInventoryType.bind(this) }"></seed-page-inventory-tab>
163

174
<div class="z-1 -mt-px flex-auto border-t pt-4 sm:pt-6">
185
<div class="mx-auto w-full max-w-screen-xl">{{ t(type) }} derived columns table</div>

src/app/modules/organizations/derived-columns/derived-columns.component.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
1-
import { NgClass } from '@angular/common'
21
import type { OnInit } from '@angular/core'
32
import { Component, inject, ViewEncapsulation } from '@angular/core'
43
import { ActivatedRoute, Router } from '@angular/router'
5-
import { PageComponent } from '@seed/components'
4+
import { InventoryTabComponent, PageComponent } from '@seed/components'
65
import { SharedImports } from '@seed/directives'
76
import type { InventoryType } from '../../inventory/inventory.types'
87

98
@Component({
109
selector: 'seed-organizations-derived-columns',
1110
templateUrl: './derived-columns.component.html',
1211
encapsulation: ViewEncapsulation.None,
13-
imports: [NgClass, PageComponent, SharedImports],
12+
imports: [InventoryTabComponent, PageComponent, SharedImports],
1413
})
1514
export class DerivedColumnsComponent implements OnInit {
1615
private _route = inject(ActivatedRoute)

src/app/modules/organizations/members/members.component.html

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<seed-page [config]="{ title: 'Members' }">
22
<!-- Members table -->
3-
<seed-page-table-container>
3+
<seed-page-inventory-table-container>
44
<table class="mat-elevation-z8 w-full bg-transparent" mat-table matSort [dataSource]="membersDataSource" [trackBy]="trackByFn">
55
<ng-container matColumnDef="name">
66
<th mat-header-cell *matHeaderCellDef>Member Name</th>
@@ -46,5 +46,5 @@
4646
<tr mat-row *matRowDef="let row; columns: membersColumns"></tr>
4747
</tbody>
4848
</table>
49-
</seed-page-table-container>
49+
</seed-page-inventory-table-container>
5050
</seed-page>

src/app/modules/organizations/organizations.types.ts

-2
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,3 @@ export type Organization = {
1212
export type OrganizationsList = Organization[]
1313

1414
export type OrganizationGenericTypeMatcher = { segments: UrlSegment[]; validTypes: string[]; validPage: string }
15-
16-
export type OrganizationTab = 'goal' | 'properties' | 'taxlots'

0 commit comments

Comments
 (0)