From b7c6fd130045dee369f37c9fc7d80eb84e49c482 Mon Sep 17 00:00:00 2001 From: SandipBajracharya Date: Fri, 13 Feb 2026 18:32:57 +0545 Subject: [PATCH 1/3] feat(OUT-3136): update associations in CU and CRM view - [x] in CU view, only show shared and assigned task - [x] in CRM view, show both associated and shared task - [x] auto load association to current CU in task creation modal --- src/app/api/comments/comment.service.ts | 40 ++++++------ src/app/api/tasks/public/public.service.ts | 4 +- src/app/api/tasks/subtasks.service.ts | 4 +- src/app/api/tasks/tasks.service.ts | 11 ++-- src/app/api/tasks/tasksShared.service.ts | 46 +++++++------- src/app/ui/NewTaskForm.tsx | 71 ++++++++++++---------- src/types/common.ts | 8 +++ src/types/dto/tasks.dto.ts | 2 +- 8 files changed, 106 insertions(+), 80 deletions(-) diff --git a/src/app/api/comments/comment.service.ts b/src/app/api/comments/comment.service.ts index bfd59ea88..95ae9ea94 100755 --- a/src/app/api/comments/comment.service.ts +++ b/src/app/api/comments/comment.service.ts @@ -2,7 +2,7 @@ import { AttachmentsService } from '@/app/api/attachments/attachments.service' import { PublicCommentSerializer } from '@/app/api/comments/public/public.serializer' import { sendCommentCreateNotifications } from '@/jobs/notifications' import { sendReplyCreateNotifications } from '@/jobs/notifications/send-reply-create-notifications' -import { InitiatedEntity } from '@/types/common' +import { InitiatedEntity, TempClientFilter } from '@/types/common' import { CreateAttachmentRequestSchema } from '@/types/dto/attachments.dto' import { CommentsPublicFilterType, CommentWithAttachments, CreateComment, UpdateComment } from '@/types/dto/comment.dto' import { DISPATCHABLE_EVENT } from '@/types/webhook' @@ -463,9 +463,10 @@ export class CommentService extends BaseService { } } - protected getClientOrCompanyAssigneeFilter(includeViewer: boolean = true): Prisma.TaskWhereInput { + protected getClientOrCompanyAssigneeFilter(includeAssociatedTask: boolean = true): Prisma.TaskWhereInput { const clientId = z.string().uuid().parse(this.user.clientId) const companyId = z.string().uuid().parse(this.user.companyId) + const isCuPortal = !this.user.internalUserId && (clientId || companyId) const filters = [] @@ -476,29 +477,32 @@ export class CommentService extends BaseService { // Get company tasks for the client's companyId { companyId, clientId: null }, ) - if (includeViewer) - filters.push( - // Get tasks that includes the client as a viewer - { - associations: { - hasSome: [{ clientId, companyId }, { companyId }], - }, + if (includeAssociatedTask) { + const tempClientFilter: TempClientFilter = { + associations: { + hasSome: [{ clientId, companyId }, { companyId }], }, - ) + } + if (isCuPortal) tempClientFilter.isShared = true + // Get tasks that includes the client as a association + filters.push(tempClientFilter) + } } else if (companyId) { filters.push( // Get only company tasks for the client's companyId { clientId: null, companyId }, ) - if (includeViewer) - filters.push( - // Get tasks that includes the company as a viewer - { - associations: { - hasSome: [{ companyId }], - }, + + // Get tasks that includes the company as a association + if (includeAssociatedTask) { + const tempCompanyFilter: TempClientFilter = { + associations: { + hasSome: [{ companyId }], }, - ) + } + if (isCuPortal) tempCompanyFilter.isShared = true + filters.push(tempCompanyFilter) + } } return filters.length > 0 ? { OR: filters } : {} } //Repeated twice because taskSharedService is an abstract class. diff --git a/src/app/api/tasks/public/public.service.ts b/src/app/api/tasks/public/public.service.ts index 302a28c05..1841279e9 100644 --- a/src/app/api/tasks/public/public.service.ts +++ b/src/app/api/tasks/public/public.service.ts @@ -174,7 +174,7 @@ export class PublicTasksService extends TasksSharedService { if (!validatedIds.internalUserId) { throw new APIError(httpStatus.BAD_REQUEST, `Task cannot be created with viewers if its not assigned to an IU.`) } - viewers = await this.validateViewers(data.associations) + viewers = await this.validateAssociations(data.associations) console.info('PublicTasksService#createTask | Associations validated for task:', viewers) } @@ -291,7 +291,7 @@ export class PublicTasksService extends TasksSharedService { if (associationsResetCondition || !associations?.length) { associations = [] // reset associations to [] if task is not reassigned to IU. } else if (associations?.length) { - associations = await this.validateViewers(associations) + associations = await this.validateAssociations(associations) } } return associations diff --git a/src/app/api/tasks/subtasks.service.ts b/src/app/api/tasks/subtasks.service.ts index 164118b73..a2a540a92 100644 --- a/src/app/api/tasks/subtasks.service.ts +++ b/src/app/api/tasks/subtasks.service.ts @@ -14,6 +14,7 @@ interface Assignable { clientId: string | null companyId: string | null associations: JsonValue[] + isShared: boolean } export class SubtaskService extends BaseService { @@ -136,7 +137,8 @@ export class SubtaskService extends BaseService { (task.clientId === null && task.companyId === this.user.companyId) || (viewer && (!viewer?.clientId || viewer?.clientId === this.user.clientId) && - viewer.companyId === this.user.companyId) + viewer.companyId === this.user.companyId && + task.isShared) ) }) } else { diff --git a/src/app/api/tasks/tasks.service.ts b/src/app/api/tasks/tasks.service.ts index a5b08b51f..e09b0e145 100644 --- a/src/app/api/tasks/tasks.service.ts +++ b/src/app/api/tasks/tasks.service.ts @@ -166,7 +166,7 @@ export class TasksService extends TasksSharedService { `Task cannot be created and shared with associations if its not assigned to an IU.`, ) } - associations = await this.validateViewers(data.associations) + associations = await this.validateAssociations(data.associations) console.info('TasksService#createTask | Associations validated for task:', associations) } @@ -368,13 +368,15 @@ export class TasksService extends TasksSharedService { let associations: Associations = AssociationsSchema.parse(prevTask.associations) // check if current or previous assignee is a client or company - const viewersResetCondition = shouldUpdateUserIds ? !!clientId || !!companyId : prevTask.clientId || prevTask.companyId + const associationsResetCondition = shouldUpdateUserIds + ? !!clientId || !!companyId + : prevTask.clientId || prevTask.companyId if (data.associations) { // only update of associations attribute is available. No associations in payload attribute means the data remains as it is in DB. - if (viewersResetCondition || !data.associations?.length) { + if (associationsResetCondition || !data.associations?.length) { associations = [] // reset associations to [] if task is not reassigned to IU. } else if (data.associations?.length) { - associations = await this.validateViewers(data.associations) + associations = await this.validateAssociations(data.associations) } } @@ -679,6 +681,7 @@ export class TasksService extends TasksSharedService { companyId: true, internalUserId: true, associations: true, + isShared: true, }, }), ) as Promise[], diff --git a/src/app/api/tasks/tasksShared.service.ts b/src/app/api/tasks/tasksShared.service.ts index 82ab6bb33..417cec180 100644 --- a/src/app/api/tasks/tasksShared.service.ts +++ b/src/app/api/tasks/tasksShared.service.ts @@ -1,6 +1,6 @@ import { maxSubTaskDepth } from '@/constants/tasks' import { MAX_FETCH_ASSIGNEE_COUNT } from '@/constants/users' -import { InternalUsers, Uuid } from '@/types/common' +import { InternalUsers, TempClientFilter, Uuid } from '@/types/common' import { CreateAttachmentRequestSchema } from '@/types/dto/attachments.dto' import { CreateTaskRequest, CreateTaskRequestSchema, Associations } from '@/types/dto/tasks.dto' import { getFileNameFromPath } from '@/utils/attachmentUtils' @@ -29,7 +29,7 @@ export abstract class TasksSharedService extends BaseService { * If user is a client, return filter for just the tasks assigned to this clientId. * If user is a client and has a companyId, return filter for just the tasks assigned to this clientId `OR` to this companyId */ - protected buildTaskPermissions(id?: string, includeViewer: boolean = true) { + protected buildTaskPermissions(id?: string, includeAssociatedTask: boolean = true) { const user = this.user // Default filters @@ -39,15 +39,16 @@ export abstract class TasksSharedService extends BaseService { } if (user.clientId || user.companyId) { - filters = { ...filters, ...this.getClientOrCompanyAssigneeFilter(includeViewer) } + filters = { ...filters, ...this.getClientOrCompanyAssigneeFilter(includeAssociatedTask) } } return filters } - protected getClientOrCompanyAssigneeFilter(includeViewer: boolean = true): Prisma.TaskWhereInput { + protected getClientOrCompanyAssigneeFilter(includeAssociatedTask: boolean = true): Prisma.TaskWhereInput { const clientId = z.string().uuid().safeParse(this.user.clientId).data const companyId = z.string().uuid().parse(this.user.companyId) + const isCuPortal = !this.user.internalUserId && (clientId || companyId) const filters = [] @@ -58,29 +59,32 @@ export abstract class TasksSharedService extends BaseService { // Get company tasks for the client's companyId { companyId, clientId: null }, ) - if (includeViewer) - filters.push( - // Get tasks that includes the client as a viewer - { - associations: { - hasSome: [{ clientId, companyId }, { companyId }], - }, + + // Get tasks that includes the client as a association + if (includeAssociatedTask) { + const tempClientFilter: TempClientFilter = { + associations: { + hasSome: [{ clientId, companyId }, { companyId }], }, - ) + } + if (isCuPortal) tempClientFilter.isShared = true + filters.push(tempClientFilter) + } } else if (companyId) { filters.push( // Get only company tasks for the client's companyId { clientId: null, companyId }, ) - if (includeViewer) - filters.push( - // Get tasks that includes the company as a viewer - { - associations: { - hasSome: [{ companyId }], - }, + if (includeAssociatedTask) { + const tempCompanyFilter: TempClientFilter = { + associations: { + hasSome: [{ companyId }], }, - ) + } + if (isCuPortal) tempCompanyFilter.isShared = true + // Get tasks that includes the company as a viewer + filters.push(tempCompanyFilter) + } } return filters.length > 0 ? { OR: filters } : {} } @@ -357,7 +361,7 @@ export abstract class TasksSharedService extends BaseService { return { completedBy: null, completedByUserType: null, workflowStateStatus: workflowState.type } } - protected async validateViewers(associations: Associations) { + protected async validateAssociations(associations: Associations) { if (!associations?.length) return [] const association = associations[0] try { diff --git a/src/app/ui/NewTaskForm.tsx b/src/app/ui/NewTaskForm.tsx index bc410cb0e..5ef4abd38 100644 --- a/src/app/ui/NewTaskForm.tsx +++ b/src/app/ui/NewTaskForm.tsx @@ -114,7 +114,7 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => } const [assigneeValue, setAssigneeValue] = useState(getDefaultAssigneeValue) - const [taskViewerValue, setTaskViewerValue] = useState( + const [taskAssociationsValue, setTaskAssociationsValue] = useState( !!previewMode ? (getSelectorAssigneeFromFilterOptions( assignee, @@ -194,24 +194,24 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => } else if (!checkEmptyAssignee(filterOptions[FilterOptions.ASSIGNEE])) { store.dispatch(setCreateTaskFields({ targetField: 'userIds', value: filterOptions[FilterOptions.ASSIGNEE] })) } else if (filterOptions[FilterOptions.TYPE]) { - if (!assigneeValue) return - const correctedObject = getAssigneeTypeCorrected(assigneeValue) - if (!correctedObject) return - const newUserIds = getSelectedUserIds([{ ...assigneeValue, object: correctedObject }]) - store.dispatch(setCreateTaskFields({ targetField: 'userIds', value: newUserIds })) - - // set default task viewers when filter by type "My tasks" is applied on preview mode - if (!!previewMode && taskViewerValue) { - const correctedViewerObject = getAssigneeTypeCorrected(taskViewerValue) + // set default task associations when filter by type is applied on preview mode + if (!!previewMode && taskAssociationsValue) { + const correctedViewerObject = getAssigneeTypeCorrected(taskAssociationsValue) if (!correctedViewerObject) return store.dispatch( setCreateTaskFields({ targetField: 'associations', - value: getSelectedViewerIds([{ ...taskViewerValue, object: correctedViewerObject }]), + value: getSelectedViewerIds([{ ...taskAssociationsValue, object: correctedViewerObject }]), }), ) } + + if (!assigneeValue) return + const correctedObject = getAssigneeTypeCorrected(assigneeValue) + if (!correctedObject) return + const newUserIds = getSelectedUserIds([{ ...assigneeValue, object: correctedObject }]) + store.dispatch(setCreateTaskFields({ targetField: 'userIds', value: newUserIds })) } else { store.dispatch(setCreateTaskFields({ targetField: 'userIds', value: emptyAssignee })) } @@ -245,7 +245,7 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => store.dispatch(setCreateTaskFields({ targetField: 'isShared', value: false })) } if (inputValue.length && inputValue[0].object !== UserRole.IU) { - setTaskViewerValue(null) + setTaskAssociationsValue(null) store.dispatch( setMultipleCreateTaskFields([ { targetField: 'associations', value: [] }, @@ -255,22 +255,23 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => } // if preview mode, auto-select current CU as viewer - if (!!previewMode && inputValue.length && inputValue[0].object === UserRole.IU && previewClientCompany.companyId) { - if (!taskViewerValue) - setTaskViewerValue( + if ( + !!previewMode && + ((inputValue.length && inputValue[0].object === UserRole.IU) || !inputValue.length) && + previewClientCompany.companyId + ) { + if (!taskAssociationsValue) + setTaskAssociationsValue( getSelectorAssigneeFromFilterOptions( assignee, { internalUserId: null, ...previewClientCompany }, // if preview mode, default select the respective client/company as viewer ) ?? null, ) store.dispatch( - setMultipleCreateTaskFields([ - { - targetField: 'associations', - value: [{ clientId: previewClientCompany.clientId || undefined, companyId: previewClientCompany.companyId }], - }, - { targetField: 'isShared', value: true }, - ]), + setCreateTaskFields({ + targetField: 'associations', + value: [{ clientId: previewClientCompany.clientId || undefined, companyId: previewClientCompany.companyId }], + }), ) } @@ -282,7 +283,7 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => // client association conditions const baseCondition = assigneeValue && assigneeValue.type === FilterByOptions.IUS - const showSharedToggle = baseCondition && taskViewerValue + const showSharedToggle = baseCondition && taskAssociationsValue const showAssociation = !assigneeValue || baseCondition return ( @@ -384,18 +385,22 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => hideIusList disabled={!!previewMode} name="Set related to" - initialValue={taskViewerValue || undefined} + initialValue={taskAssociationsValue || undefined} onChange={(inputValue) => { const newUserIds = getSelectedViewerIds(inputValue) const selectedTaskViewers = getSelectorAssignee(assignee, inputValue) - setTaskViewerValue(selectedTaskViewers || null) + setTaskAssociationsValue(selectedTaskViewers || null) store.dispatch(setCreateTaskFields({ targetField: 'associations', value: newUserIds })) }} buttonContent={ : + taskAssociationsValue ? ( + + ) : ( + + ) } height="30px" padding="4px 8px" @@ -403,7 +408,8 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => (taskViewerValue ? theme.color.gray[600] : theme.color.text.textDisabled), + color: (theme) => + taskAssociationsValue ? theme.color.gray[600] : theme.color.text.textDisabled, textOverflow: 'ellipsis', whiteSpace: 'nowrap', overflow: 'hidden', @@ -411,7 +417,7 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => maxWidth: { xs: '60px', sm: '100px' }, }} > - {getAssigneeName(taskViewerValue as IAssigneeCombined, 'Related to')} + {getAssigneeName(taskAssociationsValue as IAssigneeCombined, 'Related to')} } /> @@ -429,11 +435,10 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => > - store.dispatch( - setCreateTaskFields({ targetField: 'isShared', value: !store.getState().createTask.isShared }), - ) - } + onChange={() => { + const localSharedState = store.getState().createTask.isShared + store.dispatch(setCreateTaskFields({ targetField: 'isShared', value: !localSharedState })) + }} checked={store.getState().createTask.isShared} className="p-1.5 py-2" // px-1.5 is not working /> diff --git a/src/types/common.ts b/src/types/common.ts index 59f35cd2a..3d0b7526c 100644 --- a/src/types/common.ts +++ b/src/types/common.ts @@ -334,3 +334,11 @@ export enum SelectorFieldType { ASSIGNEE = 'assignee', ASSOCIATION = 'association', } + +export const TempClientFilterSchema = z.object({ + associations: z.object({ + hasSome: z.array(z.object({ clientId: z.string().uuid().optional(), companyId: z.string().uuid() })), + }), + isShared: z.boolean().optional(), +}) +export type TempClientFilter = z.infer diff --git a/src/types/dto/tasks.dto.ts b/src/types/dto/tasks.dto.ts index 2e99eb6ad..29613a85e 100644 --- a/src/types/dto/tasks.dto.ts +++ b/src/types/dto/tasks.dto.ts @@ -141,7 +141,7 @@ export const SubTaskStatusSchema = z.object({ export type SubTaskStatusResponse = z.infer -export type AncestorTaskResponse = Pick & { +export type AncestorTaskResponse = Pick & { internalUserId: string | null clientId: string | null companyId: string | null From 10fdc4aa1e986774c181c9b59decf19134af480b Mon Sep 17 00:00:00 2001 From: SandipBajracharya Date: Fri, 13 Feb 2026 18:37:29 +0545 Subject: [PATCH 2/3] feat(OUT-3136): add disable option in copilot toggle component and disable in CU view --- src/app/detail/ui/NewTaskCard.tsx | 1 + src/app/detail/ui/Sidebar.tsx | 10 ++++++++-- src/app/ui/NewTaskForm.tsx | 1 + src/components/inputs/CopilotToggle.tsx | 5 +++-- 4 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/app/detail/ui/NewTaskCard.tsx b/src/app/detail/ui/NewTaskCard.tsx index fabfeb472..0473cde81 100644 --- a/src/app/detail/ui/NewTaskCard.tsx +++ b/src/app/detail/ui/NewTaskCard.tsx @@ -485,6 +485,7 @@ export const NewTaskCard = ({ {showShareToggle && ( { setIsShared(!isShared) handleFieldChange('isShared', !isShared) diff --git a/src/app/detail/ui/Sidebar.tsx b/src/app/detail/ui/Sidebar.tsx index dca1c9bc2..f98b466b1 100644 --- a/src/app/detail/ui/Sidebar.tsx +++ b/src/app/detail/ui/Sidebar.tsx @@ -608,7 +608,7 @@ export const Sidebar = ({ hideIusList name="Set related to" onChange={handleTaskAssociationChange} - disabled={(disabled && !previewMode) || fromNotificationCenter} // allow visibility change in preview mode + disabled={(disabled && !previewMode) || fromNotificationCenter} // allow association change in preview mode initialValue={taskAssociationValue || undefined} buttonContent={ theme.color.borders.border, height: '1px' }} /> - + )} diff --git a/src/app/ui/NewTaskForm.tsx b/src/app/ui/NewTaskForm.tsx index 5ef4abd38..2cbd56483 100644 --- a/src/app/ui/NewTaskForm.tsx +++ b/src/app/ui/NewTaskForm.tsx @@ -435,6 +435,7 @@ export const NewTaskForm = ({ handleCreate, handleClose }: NewTaskFormProps) => > { const localSharedState = store.getState().createTask.isShared store.dispatch(setCreateTaskFields({ targetField: 'isShared', value: !localSharedState })) diff --git a/src/components/inputs/CopilotToggle.tsx b/src/components/inputs/CopilotToggle.tsx index 1c6d5bd2c..aa4b3cc10 100644 --- a/src/components/inputs/CopilotToggle.tsx +++ b/src/components/inputs/CopilotToggle.tsx @@ -5,12 +5,13 @@ type CopilotToggleProps = { label: string onChange: () => void checked: boolean + disabled?: boolean } & React.HTMLAttributes -export const CopilotToggle = ({ label, onChange, checked, className }: CopilotToggleProps) => { +export const CopilotToggle = ({ label, onChange, checked, className, disabled }: CopilotToggleProps) => { return (
- +
) } From 193fdf94938b77d65f871cdabd0f3c4a748d9e25 Mon Sep 17 00:00:00 2001 From: SandipBajracharya Date: Tue, 17 Feb 2026 16:55:25 +0545 Subject: [PATCH 3/3] feat(OUT-3160): add an unassigned view in IU and CRM dashboard - [x] new separate view for unassigned tasks - [x] association tasks are also shown in unassigned view. Not shared as shared tasks require IU as assignee. - [x] update tabs copy - [x] implement in IU and CRM view --- .../FilterSelector/FilterTypeSection.tsx | 6 ++-- src/hooks/useFilter.tsx | 3 ++ src/hooks/useFilterBar.tsx | 28 +++++++++++++------ src/types/interfaces.ts | 1 + src/types/objectMaps.ts | 6 ++-- 5 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/components/inputs/FilterSelector/FilterTypeSection.tsx b/src/components/inputs/FilterSelector/FilterTypeSection.tsx index b347de67d..5c8b09337 100644 --- a/src/components/inputs/FilterSelector/FilterTypeSection.tsx +++ b/src/components/inputs/FilterSelector/FilterTypeSection.tsx @@ -16,7 +16,7 @@ export const FilterTypeSection = ({ setFilterMode, filterModes }: FilterTypeSect filterOptions: { type }, } = useSelector(selectTaskBoard) - const disabled = type === FilterOptionsKeywords.CLIENTS ? [FilterType.Association, FilterType.IsShared] : [] + const disabled = type === FilterOptionsKeywords.CLIENTS || FilterOptionsKeywords.UNASSIGNED ? [FilterType.IsShared] : [] const removed = type.length > 20 ? [FilterType.Assignee] : [] return ( @@ -68,7 +68,9 @@ export const FilterTypeSection = ({ setFilterMode, filterModes }: FilterTypeSect -
Client association is only available
+
+ Shared with is only available +
for tasks assigned to internal users.
} diff --git a/src/hooks/useFilter.tsx b/src/hooks/useFilter.tsx index d996d22a0..dbbde26f0 100644 --- a/src/hooks/useFilter.tsx +++ b/src/hooks/useFilter.tsx @@ -148,6 +148,9 @@ function filterByType(filteredTasks: TaskResponse[], filterValue: string): TaskR case FilterOptionsKeywords.TEAM: return filteredTasks.filter((task) => task?.assigneeType?.includes('internalUser')) + case FilterOptionsKeywords.UNASSIGNED: + return filteredTasks.filter((task) => !task.assigneeId) + default: return filteredTasks.filter((task) => task.assigneeId == assigneeType) } diff --git a/src/hooks/useFilterBar.tsx b/src/hooks/useFilterBar.tsx index cc0146438..bf137bf93 100644 --- a/src/hooks/useFilterBar.tsx +++ b/src/hooks/useFilterBar.tsx @@ -57,22 +57,27 @@ export const useFilterBar = () => { const iuFilterButtons = [ { - name: 'My tasks', + name: 'Me', onClick: () => handleFilterTypeClick({ filterTypeValue: IUTokenSchema.parse(tokenPayload).internalUserId }), id: 'MyTasks', }, { - name: 'Team tasks', + name: 'Team', onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.TEAM }), id: 'TeamTasks', }, { - name: `${getWorkspaceLabels(workspace, true).individualTerm} tasks`, + name: `${getWorkspaceLabels(workspace, true).individualTerm}`, onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.CLIENTS }), id: 'ClientTasks', }, { - name: 'All tasks', + name: 'Unassigned', + onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.UNASSIGNED }), + id: 'UnassignedTasks', + }, + { + name: 'All', onClick: () => handleFilterTypeClick({ filterTypeValue: '' }), id: 'AllTasks', }, @@ -80,12 +85,12 @@ export const useFilterBar = () => { const clientFilterButtons = [ { - name: 'All tasks', + name: 'All', onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.CLIENT_WITH_VIEWERS }), id: 'AllTasks', }, { - name: 'My tasks', + name: 'Me', onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.CLIENTS }), id: 'MyTasks', }, @@ -93,19 +98,24 @@ export const useFilterBar = () => { const previewFilterButtons = [ { - name: 'My tasks', + name: 'Me', onClick: () => { handleFilterTypeClick({ filterTypeValue: IUTokenSchema.parse(tokenPayload).internalUserId }) }, id: 'MyTasks', }, { - name: 'Team tasks', + name: 'Team', onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.TEAM }), id: 'TeamTasks', }, { - name: `${getWorkspaceLabels(workspace, true).individualTerm} tasks`, + name: 'Unassigned', + onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.UNASSIGNED }), + id: 'UnassignedTasks', + }, + { + name: `${getWorkspaceLabels(workspace, true).individualTerm}`, onClick: () => handleFilterTypeClick({ filterTypeValue: FilterOptionsKeywords.CLIENTS }), id: 'ClientTasks', }, diff --git a/src/types/interfaces.ts b/src/types/interfaces.ts index 52f5f827d..3b98e71f3 100644 --- a/src/types/interfaces.ts +++ b/src/types/interfaces.ts @@ -70,6 +70,7 @@ export enum FilterByOptions { export enum FilterOptionsKeywords { CLIENTS = 'clients_companies', TEAM = 'ius', + UNASSIGNED = 'unassigned', CLIENT_WITH_VIEWERS = 'client_with_viewers', } diff --git a/src/types/objectMaps.ts b/src/types/objectMaps.ts index fb55a4951..41e0c41af 100644 --- a/src/types/objectMaps.ts +++ b/src/types/objectMaps.ts @@ -5,7 +5,8 @@ import { StateType } from '@prisma/client' export const filterTypeToButtonIndexMap: Record = { [FilterOptionsKeywords.CLIENTS]: 2, [FilterOptionsKeywords.TEAM]: 1, - '': 3, + [FilterOptionsKeywords.UNASSIGNED]: 3, + '': 4, } export const clientFilterTypeToButtonIndexMap: Record = { @@ -14,8 +15,9 @@ export const clientFilterTypeToButtonIndexMap: Record = { } export const previewFilterTypeToButtonIndexMap: Record = { - [FilterOptionsKeywords.CLIENTS]: 2, [FilterOptionsKeywords.TEAM]: 1, + [FilterOptionsKeywords.UNASSIGNED]: 2, + [FilterOptionsKeywords.CLIENTS]: 3, } export const filterOptionsMap: Record = {