Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature/users availability page #176

Merged
merged 101 commits into from
Oct 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
101 commits
Select commit Hold shift + click to select a range
8b54dbb
feat: create availability page
Manumartin95 Sep 18, 2023
6380655
feat: add routing to availability page
Manumartin95 Sep 18, 2023
1a90a46
feat: create availability table
Manumartin95 Sep 18, 2023
4070033
feat: create availability table cell header
Manumartin95 Sep 18, 2023
6ff6d6c
feat: add logic to set day of week and day of month
Manumartin95 Sep 18, 2023
5e564e5
feat: add border color to table header
Manumartin95 Sep 18, 2023
23854a0
feat: add login to set color on current day
Manumartin95 Sep 18, 2023
ad0d22d
feat: remove unused css
Manumartin95 Sep 18, 2023
02be822
feat: add isWeekend method
Manumartin95 Sep 18, 2023
7aee669
feat: update table cell header to have new backgroind if is it weekend
Manumartin95 Sep 18, 2023
05e867e
feat: add logic to paint holidays
Manumartin95 Sep 18, 2023
64caae8
refactor: add function to check holiday
Manumartin95 Sep 18, 2023
852b380
feat: add row content
Manumartin95 Sep 19, 2023
1785328
feat: update project repository to no require organization status to …
Manumartin95 Sep 19, 2023
3dbabc8
feat: update organization status to organization filters and update p…
Manumartin95 Sep 19, 2023
a26e63b
refactor: move project from administration feature to shared
Manumartin95 Sep 19, 2023
4dadf41
Revert "refactor: move project from administration feature to shared"
Manumartin95 Sep 19, 2023
e8edc86
refactor: project repository unification (administration part)
Manumartin95 Sep 19, 2023
14d7d65
refactor: project repository unification (binnacle part), substitutio…
Manumartin95 Sep 19, 2023
480500b
refactor: remove project from binnacle part and update mother files
Manumartin95 Sep 19, 2023
d862354
refactor: rename function name
Manumartin95 Sep 19, 2023
f6ff70a
fix: resolve role mother issues with project changes
Manumartin95 Sep 19, 2023
3601639
refactor: rename organization filters
Manumartin95 Sep 20, 2023
8afb546
feat: add organization filter to use case
Manumartin95 Sep 20, 2023
39cefe7
feat: add is imputable prop
Manumartin95 Sep 20, 2023
47c758a
Merge branch 'main' into feature/users_availability_page
Manumartin95 Sep 20, 2023
1494028
fix: resolve test issue
Manumartin95 Sep 20, 2023
4f57b69
refactor: rename get-project-list-qry
Manumartin95 Sep 20, 2023
8d010b9
test: remove unit test from projects table and create integration test
Manumartin95 Sep 20, 2023
78168c2
feat: add styling
Manumartin95 Sep 21, 2023
d01bbb0
feat: create cell component
Manumartin95 Sep 21, 2023
0615de0
feat: update background color styling
Manumartin95 Sep 21, 2023
71bb24a
feat: add navigation component to availability page
Manumartin95 Sep 21, 2023
b2dabfa
feat: create absence model
Manumartin95 Sep 21, 2023
28d1920
feat: create absence repository
Manumartin95 Sep 21, 2023
902a489
refactor: move project mother to test-utils file
Manumartin95 Sep 21, 2023
b452720
feat: create fake absence repository
Manumartin95 Sep 21, 2023
d10f95b
feat: add get absences qry and add absence repository to container
Manumartin95 Sep 21, 2023
b6a97f8
feat: add absence qry to table
Manumartin95 Sep 21, 2023
08b86fd
feat: add absence item to show absences
Manumartin95 Sep 21, 2023
736861c
feat: update user mother data
Manumartin95 Sep 21, 2023
2bb0816
feat: add logic for absence item width and put interval with 5 days o…
Manumartin95 Sep 21, 2023
46db4f0
feat: add logic to put absences in same row
Manumartin95 Sep 21, 2023
f5c6fa9
feat: add logic styling to keep the names in sticky position
Manumartin95 Sep 22, 2023
82f7093
feat: update css and add logic to scroll to is-today
Manumartin95 Sep 22, 2023
fdae4f8
feat: add translations
Manumartin95 Sep 22, 2023
4ae31b2
feat: add translations and update styling
Manumartin95 Sep 22, 2023
7efc72d
feat: move files
Manumartin95 Sep 22, 2023
46a0a5f
feat: change organization combo prop
Manumartin95 Sep 22, 2023
59315df
feat: add user literals
Manumartin95 Sep 22, 2023
1854526
feat: move files
Manumartin95 Sep 25, 2023
65f6e00
feat: add availability table filters
Manumartin95 Sep 25, 2023
d04b000
feat: update user filter params
Manumartin95 Sep 25, 2023
135e3d3
feat: add debounce time to make get users list query based on input v…
Manumartin95 Sep 25, 2023
1eec2af
feat: add filters schema and emit when input changes
Manumartin95 Sep 25, 2023
e5c313f
feat: make absence when filter changes
Manumartin95 Sep 25, 2023
b139673
fix: issue with test and new props
Manumartin95 Sep 25, 2023
841735b
feat: add new vacation qry to get holidays by year
Manumartin95 Sep 25, 2023
bdac324
feat: update availability table with new holidays query
Manumartin95 Sep 25, 2023
9834361
feat: add empty message to table
Manumartin95 Sep 25, 2023
e928b14
feat: update availability repository
Manumartin95 Sep 26, 2023
7a83d4b
feat: add new absence to mother
Manumartin95 Sep 26, 2023
958ebdd
feat: add background to activity table
Manumartin95 Sep 26, 2023
8c303ee
feat: add logic to print absences with days in start date or end date…
Manumartin95 Sep 26, 2023
9ae0418
feat: update styling
Manumartin95 Sep 26, 2023
006e7fa
feat: create chrono function
Manumartin95 Sep 26, 2023
01a8945
feat: update css
Manumartin95 Sep 26, 2023
5fa7265
feat: put a flag to control when the start date and endate are outsid…
Manumartin95 Sep 26, 2023
4844f1d
feat: update absence filters to receive an array
Manumartin95 Sep 27, 2023
468a2d5
feat: update literals
Manumartin95 Sep 27, 2023
4378da0
feat: add logic to print absence item correctly
Manumartin95 Sep 27, 2023
0a57fcf
refactor: move files
Manumartin95 Sep 27, 2023
c2e0e3b
feat: control text overflow
Manumartin95 Sep 27, 2023
8b7e4d2
refactor: add types
Manumartin95 Sep 27, 2023
93458ce
refactor: add constant to different conditions
Manumartin95 Sep 27, 2023
01e626c
refactor: add to availability cell the control to overlap absences
Manumartin95 Sep 27, 2023
1bc60be
feat: create http absence repository and update filters to use type s…
Manumartin95 Sep 27, 2023
6f92fb6
feat: remove comment
Manumartin95 Sep 27, 2023
d9ef1f6
feat: resolve type issue
Manumartin95 Sep 27, 2023
75a76c1
feat: make imputable nullable
Manumartin95 Sep 27, 2023
6488332
feat: modify absence repository with new type
Manumartin95 Sep 28, 2023
fe88620
feat: modify table with new type
Manumartin95 Sep 28, 2023
1fb7cea
feat: add named constants to absence calculation variables
Manumartin95 Sep 28, 2023
2070474
feat: add selected date interval as dependency of useEffect
Manumartin95 Sep 28, 2023
2513f67
feat: invalidate get absence qry cache
Manumartin95 Sep 28, 2023
e71bf04
feat: update item color
Manumartin95 Sep 28, 2023
f50fcb1
feat: add mobile styling and logic
Manumartin95 Sep 28, 2023
ddf8889
feat: show different message when there is no results with selected f…
Manumartin95 Sep 29, 2023
7ad249c
feat: add accessibility to absence item to show a resume of the absence
Manumartin95 Sep 29, 2023
ee7f86d
feat: add table header and spinner in loading state
Manumartin95 Oct 2, 2023
d173384
feat: update styling in availability table
Manumartin95 Oct 2, 2023
9f3afc6
feat: add styling
Manumartin95 Oct 2, 2023
91e74da
feat: update calendar control utils to only handle keypress when body…
Manumartin95 Oct 2, 2023
b4bbc0f
test: add integration test
Manumartin95 Oct 3, 2023
9e280dd
test: add filters mobile layout
Manumartin95 Oct 3, 2023
4c8d31f
test: add repository and qry filters
Manumartin95 Oct 3, 2023
e7cb3d1
feat: resolve padding issue
Manumartin95 Oct 3, 2023
7448b7e
Merge branch 'main' into feature/users_availability_page
Manumartin95 Oct 3, 2023
d708687
feat: update how scroll works
Manumartin95 Oct 3, 2023
44f7e9e
feat: update props to make them optional
Manumartin95 Oct 3, 2023
3fec67f
feat: delete project filter when there is no organization
Manumartin95 Oct 3, 2023
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
9 changes: 9 additions & 0 deletions src/app-routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { RequireBlockRole } from './shared/router/require-block-role'
import { RequireActivityApproval } from './shared/router/require-activity-approval'
import { LazyActivitiesPage } from './features/binnacle/features/activity/ui/activities-page.lazy'
import { useIsMobile } from './shared/hooks/use-is-mobile'
import { LazyAvailabilityPage } from './features/binnacle/features/availability/ui/availability-page.lazy'

export const AppRoutes: FC = () => {
const isMobile = useIsMobile()
Expand Down Expand Up @@ -108,6 +109,14 @@ export const AppRoutes: FC = () => {
</RequireBlockRole>
}
/>
<Route
path={rawPaths.availability}
element={
<RequireAuth>
<LazyAvailabilityPage />
</RequireAuth>
}
/>
</Routes>
</Suspense>
</>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { mock } from 'jest-mock-extended'
import { ProjectRepository } from '../domain/project-repository'
import { BlockProjectCmd } from './block-project-cmd'
import { ProjectRepository } from '../../../../shared/project/domain/project-repository'

describe('BlockProjectCmd', () => {
it('should block a project', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import { Command, UseCaseKey } from '@archimedes/arch'
import { ADMINISTRATION_PROJECT_REPOSITORY } from '../../../../../shared/di/container-tokens'
import { PROJECT_REPOSITORY } from '../../../../../shared/di/container-tokens'
import { Id } from '../../../../../shared/types/id'
import { inject, singleton } from 'tsyringe'
import type { ProjectRepository } from '../domain/project-repository'
import type { ProjectRepository } from '../../../../shared/project/domain/project-repository'

@UseCaseKey('BlockProjectCmd')
@singleton()
export class BlockProjectCmd extends Command<{ projectId: Id; date: Date }> {
constructor(
@inject(ADMINISTRATION_PROJECT_REPOSITORY) private projectRepository: ProjectRepository
) {
constructor(@inject(PROJECT_REPOSITORY) private projectRepository: ProjectRepository) {
super()
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
import { GetUsersListQry } from '../../../../shared/user/application/get-users-list-qry'
import { mock } from 'jest-mock-extended'
import { ProjectRepository } from '../domain/project-repository'
import { GetProjectsWithBlockerUserName } from './get-projects-with-blocker-user-name'
import { ProjectsWithUserName } from '../domain/services/projects-with-user-name'
import { GetProjectsListQry } from './get-projects-list-qry'
import { ProjectMother } from '../domain/tests/project-mother'
import { GetProjectsQry } from '../../../../shared/project/application/binnacle/get-projects-qry'
import { ProjectMother } from '../../../../../test-utils/mothers/project-mother'

describe('GetProjectsListQry', () => {
describe('GetProjectsWithBlockerUserName', () => {
it('should get the project list', async () => {
const { getProjectsListQry, projectRepository, getUsersListQry } = setup()
const organizationWithStatus = {
organizationId: 1,
open: true
}

projectRepository.getProjects.mockResolvedValue(
projectRepository.execute.mockResolvedValue(
ProjectMother.projectsFilteredByOrganizationDateIso()
)

await getProjectsListQry.internalExecute(organizationWithStatus)

expect(projectRepository.getProjects).toBeCalledWith(organizationWithStatus)
expect(projectRepository.execute).toBeCalledWith(organizationWithStatus)
expect(getUsersListQry.execute).toHaveBeenCalledWith({ ids: [2, 1] })
})

Expand All @@ -30,29 +30,29 @@ describe('GetProjectsListQry', () => {
open: true
}

projectRepository.getProjects.mockResolvedValue([
projectRepository.execute.mockResolvedValue([
ProjectMother.projectsFilteredByOrganizationDateIso()[2]
])

await getProjectsListQry.internalExecute(organizationWithStatus)

expect(projectRepository.getProjects).toBeCalledWith(organizationWithStatus)
expect(projectRepository.execute).toBeCalledWith(organizationWithStatus)
expect(getUsersListQry.execute).not.toHaveBeenCalled()
})
})

function setup() {
const projectRepository = mock<ProjectRepository>()
const getProjectQry = mock<GetProjectsQry>()
const getUsersListQry = mock<GetUsersListQry>()
const projectsWithUserName = mock<ProjectsWithUserName>()

return {
getProjectsListQry: new GetProjectsListQry(
projectRepository,
getProjectsListQry: new GetProjectsWithBlockerUserName(
getProjectQry,
getUsersListQry,
projectsWithUserName
),
projectRepository,
projectRepository: getProjectQry,
getUsersListQry,
projectsWithUserName
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import { InvalidateCache, Query, UseCaseKey } from '@archimedes/arch'
import { GetUsersListQry } from '../../../../shared/user/application/get-users-list-qry'
import { singleton } from 'tsyringe'
import { Id } from '../../../../../shared/types/id'
import { Project } from '../../../../shared/project/domain/project'
import { ProjectOrganizationFilters } from '../../../../shared/project/domain/project-organization-filters'
import { ProjectsWithUserName } from '../domain/services/projects-with-user-name'
import { GetProjectsQry } from '../../../../shared/project/application/binnacle/get-projects-qry'

@UseCaseKey('GetProjectsWithBlockerUserName')
@InvalidateCache
@singleton()
export class GetProjectsWithBlockerUserName extends Query<Project[], ProjectOrganizationFilters> {
constructor(
private getProjectsQry: GetProjectsQry,
private getUsersListQry: GetUsersListQry,
private projectsWithUserName: ProjectsWithUserName
) {
super()
}

async internalExecute(organizationStatus?: ProjectOrganizationFilters): Promise<Project[]> {
if (organizationStatus) {
const projects = await this.getProjectsQry.execute(organizationStatus)

const blockerUserIds = projects
.map((project) => project.blockedByUser)
.filter((id) => id !== null) as Id[]

if (blockerUserIds.length > 0) {
const uniqueBlockerUserIds = Array.from(new Set(blockerUserIds))
const usersList = await this.getUsersListQry.execute({
ids: uniqueBlockerUserIds
})
return this.projectsWithUserName.addProjectBlockerUserName(projects, usersList)
}
return projects
}
return []
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { mock } from 'jest-mock-extended'
import { ProjectRepository } from '../domain/project-repository'
import { UnblockProjectCmd } from './unblock-project-cmd'
import { ProjectRepository } from '../../../../shared/project/domain/project-repository'

describe('UnblockProjectCmd', () => {
it('should unblock a project', async () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
import { Command, Id, UseCaseKey } from '@archimedes/arch'
import { ADMINISTRATION_PROJECT_REPOSITORY } from '../../../../../shared/di/container-tokens'
import { PROJECT_REPOSITORY } from '../../../../../shared/di/container-tokens'
import { inject, singleton } from 'tsyringe'
import type { ProjectRepository } from '../domain/project-repository'
import type { ProjectRepository } from '../../../../shared/project/domain/project-repository'

@UseCaseKey('UnblockProjectCmd')
@singleton()
export class UnblockProjectCmd extends Command<Id> {
constructor(
@inject(ADMINISTRATION_PROJECT_REPOSITORY) private projectRepository: ProjectRepository
) {
constructor(@inject(PROJECT_REPOSITORY) private projectRepository: ProjectRepository) {
super()
}

Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { singleton } from 'tsyringe'
import { UserInfo } from '../../../../../shared/user/domain/user-info'
import { Project } from '../project'
import { Project } from '../../../../../shared/project/domain/project'

@singleton()
export class ProjectsWithUserName {
addUserNameToProjects(projectsWithoutUserName: Project[], usersList: UserInfo[]): Project[] {
addProjectBlockerUserName(projectsWithoutUserName: Project[], usersList: UserInfo[]): Project[] {
return projectsWithoutUserName.map((projectWithoutUserName) => {
const { blockedByUser, ...projectDetails } = projectWithoutUserName

Expand Down

This file was deleted.

This file was deleted.

Loading