Skip to content

Commit ad5d1b0

Browse files
committed
refactor(kanban): align filter workspace UI and tighten controls spacing
1 parent d74d05a commit ad5d1b0

3 files changed

Lines changed: 117 additions & 96 deletions

File tree

src/app/core/layout/component/app-menu/app-menu.component.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export class AppMenuComponent {
2525
{
2626
label: 'Workspaces',
2727
items: [
28+
{ label: 'Kanban Board', icon: 'pi pi-fw pi-th-large', routerLink: ['/projects/kanban'] },
2829
{ label: 'All Projects', icon: 'pi pi-fw pi-list', routerLink: ['/projects'] },
2930
{
3031
label: 'Project Details',
@@ -38,8 +39,7 @@ export class AppMenuComponent {
3839
icon: 'pi pi-fw pi-plus',
3940
routerLink: ['/projects/create'],
4041
visible: this.authService.hasAnyRole([...MANAGEMENT_ROLES])
41-
},
42-
{ label: 'Kanban Board', icon: 'pi pi-fw pi-th-large', routerLink: ['/projects/kanban'] }
42+
}
4343
]
4444
},
4545
{

src/app/features/projects/components/project-kanban/project-kanban.component.html

Lines changed: 87 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -34,89 +34,98 @@ <h2>Project Kanban Board</h2>
3434
</p-card>
3535

3636
<p-card class="kanban-controls-card">
37-
<div class="kanban-controls-grid">
38-
<section class="kanban-control-block">
39-
<div class="kanban-control-block__top">
40-
<span class="kanban-control-block__heading">Project Scope</span>
41-
<span class="kanban-control-block__counter">{{ selectedProjectIndex + 1 }} / {{ projects.length }}</span>
37+
<div class="kanban-controls-shell">
38+
<div class="kanban-controls-shell__header">
39+
<div class="kanban-controls-shell__title">
40+
<i class="pi pi-sliders-h"></i>
41+
<span>Filter Workspace</span>
4242
</div>
43+
</div>
4344

44-
<div class="kanban-control-block__picker">
45-
<button pButton type="button" icon="pi pi-angle-left" class="p-button-rounded p-button-text p-button-sm kanban-control-nav" [disabled]="!canSelectPreviousProject || isLoadingProjects" (click)="selectPreviousProject()"></button>
46-
47-
<p-dropdown
48-
inputId="projectPicker"
49-
[options]="projects"
50-
optionLabel="name"
51-
optionValue="id"
52-
[ngModel]="selectedProjectId"
53-
[filter]="true"
54-
filterBy="name"
55-
[showClear]="false"
56-
[appendTo]="'body'"
57-
[disabled]="isLoadingProjects || projects.length === 0"
58-
placeholder="Select project"
59-
styleClass="kanban-control-dropdown"
60-
(onChange)="onProjectSelected($event.value)">
61-
</p-dropdown>
62-
63-
<button pButton type="button" icon="pi pi-angle-right" class="p-button-rounded p-button-text p-button-sm kanban-control-nav" [disabled]="!canSelectNextProject || isLoadingProjects" (click)="selectNextProject()"></button>
64-
</div>
65-
</section>
45+
<div class="kanban-controls-grid">
46+
<section class="kanban-control-block">
47+
<div class="kanban-control-block__top">
48+
<span class="kanban-control-block__heading">Project Scope</span>
49+
<span class="kanban-control-block__counter">{{ selectedProjectIndex + 1 }} / {{ projects.length }}</span>
50+
</div>
6651

67-
<section class="kanban-control-block">
68-
<div class="kanban-control-block__top">
69-
<span class="kanban-control-block__heading">Task Lens</span>
70-
<span class="kanban-control-block__counter">{{ selectedAssigneeFilterLabel }}</span>
71-
</div>
52+
<div class="kanban-control-block__picker">
53+
<button pButton type="button" icon="pi pi-angle-left" class="p-button-rounded p-button-text p-button-sm kanban-control-nav" [disabled]="!canSelectPreviousProject || isLoadingProjects" (click)="selectPreviousProject()"></button>
54+
55+
<p-dropdown
56+
inputId="projectPicker"
57+
[options]="projects"
58+
optionLabel="name"
59+
optionValue="id"
60+
[ngModel]="selectedProjectId"
61+
[filter]="true"
62+
filterBy="name"
63+
[showClear]="false"
64+
[appendTo]="'body'"
65+
[disabled]="isLoadingProjects || projects.length === 0"
66+
placeholder="Select project"
67+
styleClass="kanban-control-dropdown"
68+
(onChange)="onProjectSelected($event.value)">
69+
</p-dropdown>
70+
71+
<button pButton type="button" icon="pi pi-angle-right" class="p-button-rounded p-button-text p-button-sm kanban-control-nav" [disabled]="!canSelectNextProject || isLoadingProjects" (click)="selectNextProject()"></button>
72+
</div>
73+
</section>
7274

73-
<div class="kanban-control-block__filter">
74-
<p-dropdown
75-
*ngIf="canManageAllTasks; else collaboratorLens"
76-
inputId="kanbanAssigneeFilter"
77-
[options]="managementAssigneeFilterOptions"
78-
optionLabel="label"
79-
optionValue="value"
80-
[(ngModel)]="selectedAssigneeFilter"
81-
[filter]="true"
82-
filterBy="label"
83-
[showClear]="false"
84-
[appendTo]="'body'"
85-
styleClass="kanban-control-dropdown"
86-
(onChange)="onAssigneeFilterChange($any($event).value)">
87-
</p-dropdown>
88-
89-
<ng-template #collaboratorLens>
90-
<div class="kanban-control-filter-inline">
91-
<div class="kanban-control-filter-buttons">
92-
<button
93-
*ngFor="let option of collaboratorAssigneeFilterOptions"
94-
pButton
95-
type="button"
96-
class="p-button-sm p-button-outlined kanban-control-filter-button"
97-
[class.kanban-control-filter-button--active]="selectedAssigneeFilter === option.value"
98-
[label]="option.label"
99-
(click)="onAssigneeFilterChange(option.value)">
100-
</button>
101-
</div>
75+
<section class="kanban-control-block">
76+
<div class="kanban-control-block__top">
77+
<span class="kanban-control-block__heading">Task Lens</span>
78+
<span class="kanban-control-block__counter">{{ selectedAssigneeFilterLabel }}</span>
79+
</div>
10280

103-
<p-dropdown
104-
inputId="kanbanAssigneeFilterUser"
105-
[options]="collaboratorAssigneeDirectoryOptions"
106-
optionLabel="label"
107-
optionValue="value"
108-
[ngModel]="selectedAssigneeFilter"
109-
[filter]="true"
110-
filterBy="label"
111-
[showClear]="false"
112-
[appendTo]="'body'"
113-
styleClass="kanban-control-dropdown kanban-control-dropdown--user"
114-
(onChange)="onAssigneeFilterChange($any($event).value)">
115-
</p-dropdown>
116-
</div>
117-
</ng-template>
118-
</div>
119-
</section>
81+
<div class="kanban-control-block__filter">
82+
<p-dropdown
83+
*ngIf="canManageAllTasks; else collaboratorLens"
84+
inputId="kanbanAssigneeFilter"
85+
[options]="managementAssigneeFilterOptions"
86+
optionLabel="label"
87+
optionValue="value"
88+
[(ngModel)]="selectedAssigneeFilter"
89+
[filter]="true"
90+
filterBy="label"
91+
[showClear]="false"
92+
[appendTo]="'body'"
93+
styleClass="kanban-control-dropdown"
94+
(onChange)="onAssigneeFilterChange($any($event).value)">
95+
</p-dropdown>
96+
97+
<ng-template #collaboratorLens>
98+
<div class="kanban-control-filter-inline">
99+
<div class="kanban-control-filter-buttons">
100+
<button
101+
*ngFor="let option of collaboratorAssigneeFilterOptions"
102+
pButton
103+
type="button"
104+
class="p-button-sm p-button-outlined kanban-control-filter-button"
105+
[class.kanban-control-filter-button--active]="selectedAssigneeFilter === option.value"
106+
[label]="option.label"
107+
(click)="onAssigneeFilterChange(option.value)">
108+
</button>
109+
</div>
110+
111+
<p-dropdown
112+
inputId="kanbanAssigneeFilterUser"
113+
[options]="collaboratorAssigneeDirectoryOptions"
114+
optionLabel="label"
115+
optionValue="value"
116+
[ngModel]="selectedAssigneeFilter"
117+
[filter]="true"
118+
filterBy="label"
119+
[showClear]="false"
120+
[appendTo]="'body'"
121+
styleClass="kanban-control-dropdown kanban-control-dropdown--user"
122+
(onChange)="onAssigneeFilterChange($any($event).value)">
123+
</p-dropdown>
124+
</div>
125+
</ng-template>
126+
</div>
127+
</section>
128+
</div>
120129
</div>
121130
</p-card>
122131

src/app/features/projects/components/project-kanban/project-kanban.component.scss

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,25 +48,42 @@
4848
padding: 0;
4949
}
5050

51+
.kanban-controls-shell {
52+
border: 1px solid var(--surface-border);
53+
border-radius: 12px;
54+
background: color-mix(in srgb, var(--surface-100) 55%, transparent);
55+
padding: 0.9rem;
56+
}
57+
58+
.kanban-controls-shell__header {
59+
display: flex;
60+
align-items: center;
61+
justify-content: space-between;
62+
gap: 0.75rem;
63+
margin-bottom: 0.75rem;
64+
}
65+
66+
.kanban-controls-shell__title {
67+
display: inline-flex;
68+
align-items: center;
69+
gap: 0.45rem;
70+
font-weight: 600;
71+
}
72+
5173
.kanban-controls-grid {
5274
display: grid;
5375
grid-template-columns: repeat(2, minmax(0, 1fr));
54-
gap: 0;
55-
border: 1px solid var(--surface-border);
56-
border-radius: 12px;
57-
background: color-mix(in srgb, var(--surface-100) 68%, transparent);
58-
overflow: hidden;
76+
gap: 1rem;
5977
}
6078

6179
.kanban-control-block {
6280
display: flex;
6381
flex-direction: column;
64-
gap: 0.5rem;
65-
padding: 0.8rem 0.9rem;
66-
}
67-
68-
.kanban-control-block + .kanban-control-block {
69-
border-left: 1px solid var(--surface-border);
82+
gap: 0.65rem;
83+
border: 1px solid var(--surface-border);
84+
border-radius: 10px;
85+
background: color-mix(in srgb, var(--surface-0) 72%, transparent);
86+
padding: 0.75rem;
7087
}
7188

7289
.kanban-control-block__top {
@@ -693,11 +710,6 @@
693710
grid-template-columns: 1fr;
694711
}
695712

696-
.kanban-control-block + .kanban-control-block {
697-
border-left: 0;
698-
border-top: 1px solid var(--surface-border);
699-
}
700-
701713
.kanban-control-block__picker {
702714
min-width: 100%;
703715
}

0 commit comments

Comments
 (0)