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

Release #2106

Merged
merged 13 commits into from
Jan 19, 2024
Merged

Release #2106

Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 11 additions & 1 deletion apps/web/app/[locale]/profile/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,12 @@ import React, { useCallback, useMemo, useState } from 'react';
import { useTranslations } from 'next-intl';
import stc from 'string-to-color';

import { useRecoilValue } from 'recoil';
import { useRecoilValue, useSetRecoilState } from 'recoil';
import { fullWidthState } from '@app/stores/fullWidth';
import { ScreenshootTab } from 'lib/features/activity/screenshoots';
import { AppsTab } from 'lib/features/activity/apps';
import { VisitedSitesTab } from 'lib/features/activity/visited-sites';
import { activityTypeState } from '@app/stores/activity-type';

type FilterTab = 'Tasks' | 'Screenshots' | 'Apps' | 'Visited Sites';

Expand All @@ -30,6 +31,7 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
const { isTrackingEnabled, activeTeam } = useOrganizationTeams();
const fullWidth = useRecoilValue(fullWidthState);
const [activityFilter, setActivityFilter] = useState<FilterTab>('Tasks');
const setActivityTypeFilter = useSetRecoilState(activityTypeState);

const hook = useTaskFilter(profile);
const canSeeActivity = profile.userProfile?.id === user?.id || user?.role?.name?.toUpperCase() == 'MANAGER';
Expand Down Expand Up @@ -57,6 +59,14 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
[setActivityFilter]
);

React.useEffect(() => {
setActivityTypeFilter((prev) => ({
...prev,
member: profile.member ? profile.member : null
}));
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [profile.member]);

return (
<>
<MainLayout showTimer={!profileIsAuthUser && isTrackingEnabled}>
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/[locale]/task/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { useTranslations } from 'next-intl';

import { fullWidthState } from '@app/stores/fullWidth';
import { useRecoilValue } from 'recoil';
import { TaskActivity } from 'lib/features/task/task-activity';

const TaskDetails = () => {
const profile = useUserProfilePage();
Expand Down Expand Up @@ -84,7 +85,7 @@ const TaskDetails = () => {
{/* <IssueCard related={true} /> */}

{/* <CompletionBlock /> */}
{/* <TaskActivity /> */}
<TaskActivity />
</div>
</section>
<div className="flex flex-col mt-4 lg:mt-0 3xl:min-w-[24rem] w-full lg:w-[30%]">
Expand Down
18 changes: 10 additions & 8 deletions apps/web/app/api/organization-team/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export async function PUT(req: Request) {
if (!user) return NextResponse.json({}, { status: 400 });

const body = await req.json();

const getTeamStatus = async () => {
const { data: team } = await getOrganizationTeamRequest(
{
Expand All @@ -48,6 +49,7 @@ export async function PUT(req: Request) {
};

await updateOrganizationTeamRequest(body, access_token);

return $res(await getTeamStatus());
}

Expand All @@ -59,13 +61,13 @@ export async function DELETE(req: Request, { params }: { params: { id: string }
const { id } = params;

if (id) {
return $res(
await deleteOrganizationTeamRequest({
id: id as string,
bearer_token: access_token,
tenantId,
organizationId
})
);
const response = await deleteOrganizationTeamRequest({
id: id as string,
bearer_token: access_token,
tenantId,
organizationId
});

return $res(response.data);
}
}
34 changes: 17 additions & 17 deletions apps/web/app/api/organization-team/employee/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@ export async function DELETE(req: Request, { params }: { params: { id: string }
return NextResponse.json({}, { status: 405 });
}

return $res(
await removeEmployeeOrganizationTeamRequest({
bearer_token: access_token,
tenantId,
employeeId: id.toString()
})
);
const response = await removeEmployeeOrganizationTeamRequest({
bearer_token: access_token,
tenantId,
employeeId: id.toString()
});

return $res(response.data);
}

export async function PUT(req: Request, { params }: { params: { id: string } }) {
Expand All @@ -39,14 +39,14 @@ export async function PUT(req: Request, { params }: { params: { id: string } })
return NextResponse.json({}, { status: 405 });
}

return $res(
await addEmployeeOrganizationTeamOrderRequest({
bearer_token: access_token,
tenantId,
employeeId: id.toString(),
order,
organizationTeamId: body.organizationTeamId,
organizationId: body.organizationId
})
);
const response = await addEmployeeOrganizationTeamOrderRequest({
bearer_token: access_token,
tenantId,
employeeId: id.toString(),
order,
organizationTeamId: body.organizationTeamId,
organizationId: body.organizationId
});

return $res(response.data);
}
16 changes: 9 additions & 7 deletions apps/web/app/api/organization-team/teams/[id]/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,14 @@ export async function DELETE(req: Request, { params }: { params: { id: string }
if (!user) return NextResponse.json({}, { status: 401 });

const { id } = params;

if (!id) return NextResponse.json({}, { status: 400 });
return $res(
await removeUserFromAllTeam({
userId: id as string,
bearer_token: access_token,
tenantId
})
);

const response = await removeUserFromAllTeam({
userId: id as string,
bearer_token: access_token,
tenantId
});

return $res(response.data);
}
3 changes: 3 additions & 0 deletions apps/web/app/hooks/features/useTimeDailyActivity.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ export function useTimeDailyActivity(type?: string) {
}
})
.catch((err) => console.log(err));
} else {
if (type == 'APP') setVisitedApps([]);
else setVisitedSites([]);
}
},
// eslint-disable-next-line react-hooks/exhaustive-deps
Expand Down
2 changes: 1 addition & 1 deletion apps/web/app/hooks/features/useTimeSlot.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ export function useTimeSlots(hasFilter?: boolean) {
setTimeSlots(response.data[0].timeSlots);
}
});
}
} else setTimeSlots([]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [hasFilter, activityFilter.member?.employeeId, profile.member?.employeeId, user?.id, queryCall, setTimeSlots]);

Expand Down
6 changes: 5 additions & 1 deletion apps/web/app/hooks/features/useUserProfilePage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,21 @@ import { useAuthTeamTasks } from './useAuthTeamTasks';
import { useOrganizationTeams } from './useOrganizationTeams';
import { useTaskStatistics } from './useTaskStatistics';
import { useTeamTasks } from './useTeamTasks';
import { useRecoilValue } from 'recoil';
import { activityTypeState } from '@app/stores/activity-type';

export function useUserProfilePage() {
const { activeTeam } = useOrganizationTeams();
const { activeTeamTask, updateTask } = useTeamTasks();
const activityFilter = useRecoilValue(activityTypeState);

const { user: auth } = useAuthenticateUser();
const { getTasksStatsData } = useTaskStatistics();

const params = useParams();
const memberId: string = useMemo(() => {
return (params?.memberId || '') as string;
return (params?.memberId ?? activityFilter.member?.id ?? '') as string;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [params]);

const members = activeTeam?.members || [];
Expand Down
55 changes: 42 additions & 13 deletions apps/web/app/services/client/api/organization-team.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import { CreateResponse, DeleteResponse, ISuccessResponse, PaginationResponse } from '@app/interfaces/IDataResponse';
import { DeleteResponse, PaginationResponse } from '@app/interfaces/IDataResponse';

import {
IOrganizationTeamList,
IOrganizationTeamWithMStatus,
IOrganizationTeamUpdate,
IOrganizationTeam,
TimerSource,
OT_Member
} from '@app/interfaces';
import moment from 'moment';
import api, { get } from '../axios';
import api, { deleteApi, get, put } from '../axios';
import { GAUZY_API_BASE_SERVER_URL } from '@app/constants';
import { getOrganizationIdCookie, getTenantIdCookie } from '@app/helpers';

export async function getOrganizationTeamsAPI(organizationId: string, tenantId: string) {
const relations = [
Expand Down Expand Up @@ -76,30 +77,58 @@ export async function getOrganizationTeamAPI(teamId: string, organizationId: str
return get<IOrganizationTeamList>(endpoint);
}

export function editOrganizationTeamAPI(data: IOrganizationTeamUpdate) {
return api.put<IOrganizationTeamList>(`/organization-team/${data.id}`, data);
export async function editOrganizationTeamAPI(data: IOrganizationTeamUpdate) {
const tenantId = getTenantIdCookie();
const organizationId = getOrganizationIdCookie();

let response = await put<IOrganizationTeamList>(`/organization-team/${data.id}`, data);

if (GAUZY_API_BASE_SERVER_URL.value) {
response = await getOrganizationTeamAPI(data.id, organizationId, tenantId);
}

return response;
}
export function updateOrganizationTeamAPI(teamId: string, data: Partial<IOrganizationTeamUpdate>) {
return api.put<IOrganizationTeamWithMStatus>(`/organization-team/${teamId}`, data);

export async function updateOrganizationTeamAPI(teamId: string, data: Partial<IOrganizationTeamUpdate>) {
const tenantId = getTenantIdCookie();
const organizationId = getOrganizationIdCookie();

let response = await put<IOrganizationTeamList>(`/organization-team/${teamId}`, data);

if (GAUZY_API_BASE_SERVER_URL.value) {
response = await getOrganizationTeamAPI(teamId, organizationId, tenantId);
}

return response;
}

export function deleteOrganizationTeamAPI(id: string) {
return api.delete<CreateResponse<IOrganizationTeam>>(`/organization-team/${id}`);
const organizationId = getOrganizationIdCookie();

return deleteApi<IOrganizationTeam>(`/organization-team/${id}?organizationId=${organizationId}`);
}

export function removeEmployeeOrganizationTeamAPI(employeeId: string) {
return api.delete<boolean>(`/organization-team/employee/${employeeId}`);
const endpoint = GAUZY_API_BASE_SERVER_URL.value
? `/organization-team-employee/${employeeId}`
: `/organization-team/employee/${employeeId}`;

return deleteApi<boolean>(endpoint);
}

export function editEmployeeOrderOrganizationTeamAPI(
employeeId: string,
data: { order: number; organizationTeamId: string; organizationId: string },
tenantId?: string
) {
return api.put<CreateResponse<OT_Member>>(`/organization-team/employee/${employeeId}`, data, {
headers: { 'Tenant-Id': tenantId }
});
const endpoint = GAUZY_API_BASE_SERVER_URL.value
? `/organization-team-employee/${employeeId}`
: `/organization-team/employee/${employeeId}`;

return put<OT_Member>(endpoint, data, { tenantId });
}

export function removeUserFromAllTeamAPI(userId: string) {
return api.delete<DeleteResponse | CreateResponse<ISuccessResponse>>(`/organization-team/teams/${userId}`);
return deleteApi<DeleteResponse>(`/organization-team/teams/${userId}`);
}
3 changes: 1 addition & 2 deletions apps/web/app/services/server/requests/organization-team.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,15 +187,14 @@ export function addEmployeeOrganizationTeamOrderRequest({
organizationTeamId: string;
organizationId: string;
}) {
console.log({ order, tenantId, employeeId });
const res = serverFetch({
path: `/organization-team-employee/${employeeId}`,
method: 'PUT',
bearer_token,
body: { order, organizationTeamId, organizationId },
tenantId
});
res.then((d) => console.log(d.data));

return res;
}

Expand Down
2 changes: 1 addition & 1 deletion apps/web/lib/features/activity/apps.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import AppVisitedItem from './components/app-visited-Item';
// import { AppVisitedModal } from './components/app-visited-details';

export function AppsTab() {
const { visitedApps, loading } = useTimeDailyActivity();
const { visitedApps, loading } = useTimeDailyActivity('APP');
const t = useTranslations();
const apps = groupAppsByHour(visitedApps);
return (
Expand Down
68 changes: 68 additions & 0 deletions apps/web/lib/features/task/task-activity.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { clsxm } from '@app/utils';
import { Tab } from '@headlessui/react';
import { Card } from 'lib/components';
import { ActivityFilters } from '@app/constants';
import React from 'react';

export function TaskActivity() {
return (
<Card
className="w-full p-4 md:px-4 dark:bg-[#25272D] flex flex-col gap-6 border border-[#00000014] dark:border-[#26272C]"
shadow="bigger"
>
<div className="shadow-lg rounded-lg p-4 bg-light dark:bg-dark border border-[#00000014] dark:border-[#26272C]">
<h3 className="text-xl font-semibold py-2">{'05.01.2024'}</h3>
<UserTaskActivity />
<UserTaskActivity />
</div>

<div className="shadow-lg rounded-lg p-4 bg-light dark:bg-dark border border-[#00000014] dark:border-[#26272C]">
<h3 className="text-xl font-semibold py-2">{'04.01.2024'}</h3>
<UserTaskActivity />
</div>

<div className="shadow-lg rounded-lg p-4 bg-light dark:bg-dark border border-[#00000014] dark:border-[#26272C]">
<h3 className="text-xl font-semibold py-2">{'03.01.2024'}</h3>
<UserTaskActivity />
<UserTaskActivity />
<UserTaskActivity />
</div>
</Card>
);
}

const UserTaskActivity = () => {
return (
<div className="shadow-md rounded-md p-4 my-4 bg-[#00000014] dark:bg-[#26272C]">
<div className="flex items-center gap-2 my-2">
<h4 className="text-lg">{'Cedric medium'}</h4>
<span>{'05:30'}</span>
</div>
<Tab.Group>
<Tab.List className="w-full flex rounded-xl bg-gray-200 dark:bg-[#FFFFFF14] p-2">
{Object.values(ActivityFilters).filter(filter => filter !== 'Tasks').map((filter: string) => (
<Tab
key={filter}
className={({ selected }) =>
clsxm(
'w-full rounded-lg py-2.5 text-sm font-medium leading-5',
' focus:outline-none focus:ring-2',
selected
? 'bg-white dark:bg-dark text-blue-700 shadow'
: ' hover:bg-white/[0.50]'
)
}
>
{filter}
</Tab>
))}
</Tab.List>
<Tab.Panels>
<Tab.Panel className="w-full mx-4 py-4">{'Screenshoot Team Tab'}</Tab.Panel>
<Tab.Panel className="w-full mx-4 py-4">{'Apps Tab'}</Tab.Panel>
<Tab.Panel className="w-full mx-4 py-4">{'VisitedSites Tab'}</Tab.Panel>
</Tab.Panels>
</Tab.Group>
</div>
);
};
Loading
Loading