-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: split board header into separate component
- Loading branch information
Showing
8 changed files
with
341 additions
and
294 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
55 changes: 55 additions & 0 deletions
55
...src/app/modules/board/components/board-header-options/board-header-options.component.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
@if (boardMode() === 0) { | ||
@if (isAdmin() && !isDemo) { | ||
<button | ||
title="Settings" | ||
aria-label="Settings" | ||
class="button-action" | ||
(click)="settings()"> | ||
<mat-icon svgIcon="settings"></mat-icon> | ||
</button> | ||
} | ||
<button | ||
title="Share" | ||
aria-label="Share" | ||
class="button-action" | ||
(click)="share()"> | ||
<mat-icon svgIcon="share"></mat-icon> | ||
</button> | ||
<button | ||
title="Download" | ||
aria-label="Download" | ||
class="button-action" | ||
(click)="export()"> | ||
<mat-icon svgIcon="download"></mat-icon> | ||
</button> | ||
} | ||
|
||
@if (allowSwitchMode()) { | ||
<div class="change-mode-button-holder"> | ||
@if (boardMode() === 0) { | ||
<button | ||
title="Edit board" | ||
aria-label="Edit board" | ||
class="change-mode-button change-edit" | ||
(click)="changeBoardMode(1)"> | ||
Edit board | ||
</button> | ||
} @else { | ||
<button | ||
title="Edit board" | ||
aria-label="Edit board" | ||
class="change-mode-button change-close" | ||
(click)="changeBoardMode(0)"> | ||
Close board edition | ||
<mat-icon>close</mat-icon> | ||
</button> | ||
} | ||
</div> | ||
} | ||
|
||
@if (boardMode() === 0 && !isDemo && showUsers() && users().length > 0) { | ||
<button class="user-count"> | ||
<mat-icon svgIcon="user"></mat-icon> | ||
<span class="user-hover">{{ users().length + 1 }} Users</span> | ||
</button> | ||
} |
165 changes: 165 additions & 0 deletions
165
...src/app/modules/board/components/board-header-options/board-header-options.component.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,165 @@ | ||
:host { | ||
--toolbar-button-height: 3rem; | ||
--toolbar-button-width: 3rem; | ||
|
||
align-items: center; | ||
cursor: default; | ||
display: flex; | ||
justify-content: space-between; | ||
right: 1rem; | ||
position: fixed; | ||
top: 1rem; | ||
transition: background 0.5s ease; | ||
background: var(--blur-bg); | ||
border-radius: var(--radius-6); | ||
gap: var(--spacing-1); | ||
margin-inline-start: auto; | ||
flex-shrink: 0; | ||
padding: var(--size-2); | ||
height: 65px; | ||
backdrop-filter: blur(90px); | ||
} | ||
|
||
.change-mode-button-holder { | ||
display: flex; | ||
} | ||
|
||
.change-mode-button { | ||
align-items: center; | ||
display: flex; | ||
font-family: | ||
"Inter", | ||
-apple-system, | ||
system-ui, | ||
sans-serif; | ||
justify-content: center; | ||
block-size: 50px; | ||
padding: var(--spacing-3) var(--spacing-4); | ||
color: var(--grey-90); | ||
background: var(--grey-30); | ||
border-radius: var(--radius-6); | ||
font-size: var(--font-size-1); | ||
|
||
mat-icon { | ||
--icon-size: 16px; | ||
inline-size: var(--icon-size); | ||
block-size: var(--icon-size); | ||
font-size: var(--icon-size); | ||
margin-block-start: 1px; | ||
} | ||
|
||
&:hover { | ||
background: var(--grey-40); | ||
} | ||
} | ||
|
||
.change-edit mat-icon { | ||
margin-inline-end: 2px; | ||
} | ||
|
||
.change-close mat-icon { | ||
margin-inline-start: 4px; | ||
} | ||
|
||
.textarea { | ||
color: var(--white); | ||
background: transparent; | ||
border: none; | ||
height: 100%; | ||
outline: none; | ||
overflow: hidden; | ||
resize: none; | ||
} | ||
|
||
.button-action { | ||
display: flex; | ||
align-items: center; | ||
color: var(--primary-color-button-bg); | ||
border-radius: var(--radius-round); | ||
padding: var(--spacing-2); | ||
justify-content: center; | ||
height: var(--toolbar-button-height); | ||
width: var(--toolbar-button-width); | ||
.mat-icon { | ||
color: var(--primary-color-button-bg); | ||
fill: var(--primary-color-button-bg); | ||
} | ||
&:hover { | ||
transition: background 0.2s ease; | ||
background: var(--grey-30); | ||
} | ||
} | ||
|
||
.avatar { | ||
border-radius: var(--radius-round); | ||
width: 48px; | ||
height: 48px; | ||
img { | ||
display: block; | ||
} | ||
} | ||
|
||
.user-count { | ||
align-items: center; | ||
background: var(--grey-30); | ||
border-radius: 30px; | ||
box-sizing: border-box; | ||
color: #2c2c2c; | ||
display: inline-flex; | ||
font-family: | ||
"Work Sans", | ||
-apple-system, | ||
system-ui, | ||
sans-serif; | ||
font-size: var(--font-size-1); | ||
font-weight: 400; | ||
height: 44px; | ||
width: 44px; | ||
justify-content: center; | ||
line-height: 1.2; | ||
margin-left: 8px; | ||
position: relative; | ||
|
||
&:hover { | ||
background: var(--grey-40); | ||
|
||
.user-hover { | ||
background: var(--grey-90); | ||
border-radius: 20px; | ||
color: var(--white); | ||
display: flex; | ||
align-items: center; | ||
font-size: 16px; | ||
font-weight: var(--font-weight-medium); | ||
line-height: 1.2; | ||
height: 44px; | ||
width: 200%; | ||
padding: 0 16px; | ||
opacity: 1; | ||
|
||
&::after { | ||
content: ""; | ||
position: absolute; | ||
top: 50%; /* Start at vertical center */ | ||
left: calc(100% - 0.18rem); /* Align to the right edge */ | ||
transform: translateY(-50%); /* Center vertically */ | ||
|
||
/* Create the triangle using borders */ | ||
width: 0; | ||
height: 0; | ||
border-left: 10px solid #1f255a; /* Color matches the bubble background */ | ||
border-top: 6px solid transparent; | ||
border-bottom: 6px solid transparent; | ||
} | ||
} | ||
} | ||
|
||
.user-hover { | ||
height: 0; | ||
width: 0; | ||
opacity: 0; | ||
position: absolute; | ||
right: calc(100% + 0.5rem); | ||
top: 0; | ||
} | ||
} |
112 changes: 112 additions & 0 deletions
112
...b/src/app/modules/board/components/board-header-options/board-header-options.component.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
import { | ||
Component, | ||
ChangeDetectionStrategy, | ||
inject, | ||
input, | ||
} from '@angular/core'; | ||
import { Store } from '@ngrx/store'; | ||
import { PageActions } from '../../actions/page.actions'; | ||
import { selectIsAdmin, selectUserId } from '../../selectors/page.selectors'; | ||
import { ExportService } from '../../services/export.service'; | ||
import { MatIconModule } from '@angular/material/icon'; | ||
import { MatDialog, MatDialogModule } from '@angular/material/dialog'; | ||
import { ShareBoardComponent } from '../share-board/share-board.component'; | ||
import { pageFeature } from '../../reducers/page.reducer'; | ||
import { BoardSettingsComponent } from '../board-settings/board-settings.component'; | ||
import { toSignal } from '@angular/core/rxjs-interop'; | ||
import { map } from 'rxjs'; | ||
import { computed } from '@angular/core'; | ||
import { ConfigService } from '../../../../services/config.service'; | ||
import { MatButtonModule } from '@angular/material/button'; | ||
import { BoardFacade } from '../../../../services/board-facade.service'; | ||
|
||
@Component({ | ||
selector: 'tapiz-board-header-options', | ||
templateUrl: './board-header-options.component.html', | ||
styleUrls: ['./board-header-options.component.scss'], | ||
changeDetection: ChangeDetectionStrategy.OnPush, | ||
imports: [MatIconModule, MatDialogModule, MatButtonModule], | ||
}) | ||
export class BoardHeaderOptionsComponent { | ||
#exportService = inject(ExportService); | ||
#store = inject(Store); | ||
#dialog = inject(MatDialog); | ||
#boardFacade = inject(BoardFacade); | ||
#boardUsers = this.#store.selectSignal(pageFeature.selectBoardUsers); | ||
#configService = inject(ConfigService); | ||
#users = toSignal( | ||
this.#boardFacade | ||
.getUsers() | ||
.pipe(map((users) => users.map((user) => user.content))), | ||
{ initialValue: [] }, | ||
); | ||
userId = this.#store.selectSignal(selectUserId); | ||
users = computed(() => { | ||
const boardUsers = this.#boardUsers(); | ||
|
||
return this.#users() | ||
.filter((user) => user.id !== this.userId()) | ||
.map((user) => { | ||
const boardUser = boardUsers.find( | ||
(boardUser) => boardUser.id === user.id, | ||
); | ||
|
||
return { | ||
...user, | ||
picture: boardUser?.picture, | ||
}; | ||
}); | ||
}); | ||
#settings = toSignal(this.#boardFacade.getSettings(), { initialValue: null }); | ||
|
||
showUsers = computed(() => { | ||
return !this.#settings()?.content.anonymousMode; | ||
}); | ||
|
||
allowSwitchMode = input(true); | ||
|
||
boardMode = this.#store.selectSignal(pageFeature.selectBoardMode); | ||
isAdmin = this.#store.selectSignal(selectIsAdmin); | ||
boardId = this.#store.selectSignal(pageFeature.selectBoardId); | ||
|
||
get isDemo() { | ||
return !!this.#configService.config.DEMO; | ||
} | ||
|
||
changeBoardMode(boardMode: number) { | ||
this.#store.dispatch( | ||
PageActions.changeBoardMode({ | ||
boardMode, | ||
}), | ||
); | ||
} | ||
|
||
export() { | ||
this.#exportService.getExportFile().then( | ||
(url) => { | ||
const fileLink = document.createElement('a'); | ||
|
||
fileLink.href = url; | ||
fileLink.download = `${this.boardId()}.json`; | ||
fileLink.click(); | ||
}, | ||
() => { | ||
console.error('export error'); | ||
}, | ||
); | ||
} | ||
|
||
share() { | ||
this.#dialog.open(ShareBoardComponent, { | ||
width: '600px', | ||
autoFocus: 'dialog', | ||
}); | ||
} | ||
|
||
settings() { | ||
this.#dialog.open(BoardSettingsComponent, { | ||
width: '600px', | ||
autoFocus: 'dialog', | ||
}); | ||
} | ||
} |
Oops, something went wrong.