Skip to content

Commit

Permalink
Merge pull request #2369 from ever-co/stage
Browse files Browse the repository at this point in the history
Release
  • Loading branch information
evereq authored Apr 7, 2024
2 parents 6589f66 + 079dbdd commit c2ea188
Show file tree
Hide file tree
Showing 17 changed files with 351 additions and 229 deletions.
10 changes: 5 additions & 5 deletions apps/mobile/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4014,11 +4014,11 @@ axios@^0.27.2:
form-data "^4.0.0"

axios@^1.6.0:
version "1.6.2"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.2.tgz#de67d42c755b571d3e698df1b6504cde9b0ee9f2"
integrity sha512-7i24Ri4pmDRfJTR7LDBhsOTtcm+9kjX5WiY1X3wIisx6G9So3pfMkEiU7emUBe46oceVImccTEM3k6C5dbVW8A==
version "1.6.8"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.6.8.tgz#66d294951f5d988a00e87a0ffb955316a619ea66"
integrity sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==
dependencies:
follow-redirects "^1.15.0"
follow-redirects "^1.15.6"
form-data "^4.0.0"
proxy-from-env "^1.1.0"

Expand Down Expand Up @@ -7162,7 +7162,7 @@ flush-write-stream@^1.0.0:
inherits "^2.0.3"
readable-stream "^2.3.6"

follow-redirects@^1.0.0, follow-redirects@^1.14.9, follow-redirects@^1.15.0, follow-redirects@^1.4.1:
follow-redirects@^1.0.0, follow-redirects@^1.14.9, follow-redirects@^1.15.6, follow-redirects@^1.4.1:
version "1.15.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.6.tgz#7f815c0cda4249c74ff09e95ef97c23b5fd0399b"
integrity sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==
Expand Down
152 changes: 77 additions & 75 deletions apps/web/app/[locale]/auth/passcode/component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { useRouter } from 'next/navigation';
import { Dispatch, FormEvent, FormEventHandler, SetStateAction, useCallback, useEffect, useRef, useState } from 'react';

import stc from 'string-to-color';
import { ScrollArea, ScrollBar } from '@components/ui/scroll-bar';

function AuthPasscode() {
const form = useAuthenticationPasscode();
Expand Down Expand Up @@ -173,8 +174,8 @@ function PasscodeScreen({ form, className }: { form: TAuthenticationPasscode } &
form.errors['code'] || form.errors['email']
? 'error'
: form.authenticated
? 'success'
: undefined
? 'success'
: undefined
}
autoFocus={form.authScreen.screen === 'passcode'}
/>
Expand Down Expand Up @@ -317,83 +318,84 @@ export function WorkSpaceComponent(props: IWorkSpace) {
<Text.Heading as="h3" className="text-center">
{t('pages.auth.SELECT_WORKSPACE')}
</Text.Heading>

<div className="flex flex-col w-full gap-4 max-h-[16.9375rem] overflow-scroll scrollbar-hide">
{props.workspaces?.map((worksace, index) => (
<div
key={index}
className={`w-full flex flex-col border border-[#0000001A] dark:border-[#34353D] ${
props.selectedWorkspace === index ? 'bg-[#FCFCFC] dark:bg-[#1F2024]' : ''
} hover:bg-[#FCFCFC] dark:hover:bg-[#1F2024] rounded-xl`}
>
<div className="text-base font-medium py-[1.25rem] px-4 flex flex-col gap-[1.0625rem]">
<div className="flex justify-between">
<span>{worksace.user.tenant.name}</span>
<span
className="hover:cursor-pointer"
onClick={() => {
props.setSelectedWorkspace(index);
if (
props.selectedTeam &&
!worksace.current_teams
?.map((team) => team.team_id)
.includes(props.selectedTeam)
) {
props.setSelectedTeam(worksace.current_teams[0].team_id);
}
}}
>
{props.selectedWorkspace === index ? (
<CheckCircleOutlineIcon className="w-6 h-6 stroke-[#27AE60] fill-[#27AE60]" />
) : (
<CircleIcon className="w-6 h-6" />
)}
</span>
</div>
<span className="bg-[#E5E5E5] w-full h-[1px]"></span>
{/* <div className="w-full h-[1px] bg-[#E5E5E5] dark:bg-[#34353D]"></div> */}
<div className="flex flex-col gap-4 px-5 py-1.5">
{worksace.current_teams?.map((team) => (
<div
key={`${index}-${team.team_id}`}
className="flex items-center justify-between gap-4 min-h-[2.875rem]"
<ScrollArea className='h-64 relative w-full pr-2 '>
<div className="flex flex-col gap-y-4 ">
{props.workspaces?.map((worksace, index) => (
<div
key={index}
className={`w-full flex flex-col border border-[#0000001A] dark:border-[#34353D] ${
props.selectedWorkspace === index ? 'bg-[#FCFCFC] dark:bg-[#1F2024]' : ''
} hover:bg-[#FCFCFC] dark:hover:bg-[#1F2024] rounded-xl`}
>
<div className="text-base font-medium py-[1.25rem] px-4 flex flex-col gap-[1.0625rem]">
<div className="flex justify-between">
<span>{worksace.user.tenant.name}</span>
<span
className="hover:cursor-pointer"
onClick={() => {
props.setSelectedWorkspace(index);
if (
props.selectedTeam &&
!worksace.current_teams
?.map((team) => team.team_id)
.includes(props.selectedTeam)
) {
props.setSelectedTeam(worksace.current_teams[0].team_id);
}
}}
>
<span className="flex items-center justify-between gap-4">
<Avatar
imageTitle={team.team_name}
size={34}
backgroundColor={`${stc(team.team_name)}80`}
/>
<div className="flex justify-between">
<span className="max-w-[14rem] whitespace-nowrap text-ellipsis overflow-hidden">
{team.team_name}
</span>
<span>({team.team_member_count})</span>
</div>
</span>
<span
className="hover:cursor-pointer"
onClick={() => {
props.setSelectedTeam(team.team_id);
if (props.selectedWorkspace !== index) {
props.setSelectedWorkspace(index);
}
}}
{props.selectedWorkspace === index ? (
<CheckCircleOutlineIcon className="w-6 h-6 stroke-[#27AE60] fill-[#27AE60]" />
) : (
<CircleIcon className="w-6 h-6" />
)}
</span>
</div>
<span className="bg-[#E5E5E5] w-full h-[1px]"></span>
{/* <div className="w-full h-[1px] bg-[#E5E5E5] dark:bg-[#34353D]"></div> */}
<div className="flex flex-col gap-4 px-5 py-1.5">
{worksace.current_teams?.map((team) => (
<div
key={`${index}-${team.team_id}`}
className="flex items-center justify-between gap-4 min-h-[2.875rem]"
>
{props.selectedTeam === team.team_id ? (
<CheckCircleOutlineIcon className="w-5 h-5 stroke-[#27AE60] fill-[#27AE60]" />
) : (
<CircleIcon className="w-5 h-5" />
)}
</span>
</div>
))}
<span className="flex items-center justify-between gap-4">
<Avatar
imageTitle={team.team_name}
size={34}
backgroundColor={`${stc(team.team_name)}80`}
/>
<div className="flex justify-between">
<span className="max-w-[14rem] whitespace-nowrap text-ellipsis overflow-hidden">
{team.team_name}
</span>
<span>({team.team_member_count})</span>
</div>
</span>
<span
className="hover:cursor-pointer"
onClick={() => {
props.setSelectedTeam(team.team_id);
if (props.selectedWorkspace !== index) {
props.setSelectedWorkspace(index);
}
}}
>
{props.selectedTeam === team.team_id ? (
<CheckCircleOutlineIcon className="w-5 h-5 stroke-[#27AE60] fill-[#27AE60]" />
) : (
<CircleIcon className="w-5 h-5" />
)}
</span>
</div>
))}
</div>
</div>
</div>
</div>
))}
</div>

))}
</div>
<ScrollBar className='-pr-20'/>
</ScrollArea>
<div className="flex items-center justify-between w-full">
<div className="flex flex-col space-y-2">
<div>
Expand Down
6 changes: 6 additions & 0 deletions apps/web/app/[locale]/kanban/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { useRecoilValue } from 'recoil';
import { fullWidthState } from '@app/stores/fullWidth';
import { CircleIcon } from 'lucide-react';
import { XMarkIcon } from '@heroicons/react/20/solid';
import Head from 'next/head';

const Kanban = () => {
const {
Expand Down Expand Up @@ -85,6 +86,11 @@ const Kanban = () => {
});
return (
<>
<Head>
<title>
{t('common.KANBAN')} {t('common.BOARD')}
</title>
</Head>
<MainLayout
showTimer={isTrackingEnabled}
footerClassName="fixed bottom-0 z-50 bg-white dark:bg-dark--theme"
Expand Down
42 changes: 40 additions & 2 deletions apps/web/app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import clsx from 'clsx';
import { notFound, useRouter } from 'next/navigation';
import { ReactNode, useEffect } from 'react';
import { usePathname } from 'next/navigation';
import { usePathname, useSearchParams } from 'next/navigation';
import { NextIntlClientProvider } from 'next-intl';
import { RecoilRoot } from 'recoil';
import { AppState } from 'lib/app/init-state';
Expand All @@ -17,7 +17,6 @@ import { JitsuOptions } from '@jitsu/jitsu-react/dist/useJitsu';
import { useCheckAPI } from '@app/hooks/useCheckAPI';

const locales = ['en', 'de', 'ar', 'bg', 'zh', 'nl', 'de', 'he', 'it', 'pl', 'pt', 'ru', 'es', 'fr'];

interface Props {
children: ReactNode;
params: { locale: string };
Expand Down Expand Up @@ -56,9 +55,45 @@ const LocaleLayout = ({ children, params: { locale }, pageProps }: Props) => {
if (!locales.includes(locale as any)) notFound();
const router = useRouter();
const pathname = usePathname();
const searchParams = useSearchParams();
const { isApiWork, loading } = useCheckAPI();
// Enable static rendering
// unstable_setRequestLocale(locale);
const formatTitle = (url: string) => {
// Separate the URL into pathname and query parts
const [pathname, queryString] = url.split('?');

// Ignore language codes or any initial two-letter or specific codes like 'ru', 'ur'
const segments = pathname
.split('/')
.filter((seg) => seg && seg.length > 2)
.map((seg) => {
// Replace dashes with spaces in the segment if it looks like a UUID or has digits (likely an ID)
if (seg.includes('-') || /\d/.test(seg)) {
return ''; // Exclude IDs from title
}
return seg.charAt(0).toUpperCase() + seg.slice(1).toLowerCase(); // Capitalize non-ID segments
})
.filter((seg: string) => seg); // Remove empty strings resulting from ID exclusion

// Process query parameters, specifically looking for 'name'
let namePart = '';
if (queryString) {
const params = new URLSearchParams(queryString);
if (params?.get('name')) {
const name = params.get('name') ?? '';
const nameValue = name.charAt(0).toUpperCase() + name.slice(1).toLowerCase();
namePart = nameValue;
}
}

// Combine the pathname segments with the name part, if present
const title = [...segments, namePart].filter((part) => part).join(' | ');

return title;
};

const name = searchParams?.get('name');

// eslint-disable-next-line @typescript-eslint/no-var-requires
const messages = require(`../../messages/${locale}.json`);
Expand All @@ -69,6 +104,9 @@ const LocaleLayout = ({ children, params: { locale }, pageProps }: Props) => {
}, [isApiWork, loading, router, pathname]);
return (
<html lang={locale} className={poppins.variable}>
<head>
<title>{formatTitle(`${pathname}${name ? `?name=${name}` : ''}`) || 'Home'}</title>
</head>
{/* <head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="" />
Expand Down
3 changes: 2 additions & 1 deletion apps/web/app/[locale]/profile/[memberId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
const fullWidth = useRecoilValue(fullWidthState);
const [activityFilter, setActivityFilter] = useState<FilterTab>('Tasks');
const setActivityTypeFilter = useSetRecoilState(activityTypeState);

const hook = useTaskFilter(profile);

const isManagerConnectedUser = activeTeamManagers.findIndex((member) => member.employee?.user?.id == user?.id);
Expand Down Expand Up @@ -69,6 +68,8 @@ const Profile = React.memo(function ProfilePage({ params }: { params: { memberId
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [profile.member]);

// Example usage

return (
<>
<MainLayout showTimer={profileIsAuthUser && isTrackingEnabled}>
Expand Down
8 changes: 5 additions & 3 deletions apps/web/app/hooks/features/useTaskInput.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
'use client';

import { useAuthenticateUser, useModal, useSyncRef } from '@app/hooks';
import { useAuthenticateUser, useModal, useSyncRef, useTaskStatus } from '@app/hooks';
import { useTeamTasks } from '@app/hooks/features/useTeamTasks';
import { ITaskLabelsItemList, Nullable } from '@app/interfaces';
import { ITaskStatus, ITeamTask } from '@app/interfaces/ITask';
Expand Down Expand Up @@ -36,7 +36,7 @@ export function useTaskInput({
} = {}) {
const { isOpen: isModalOpen, openModal, closeModal } = useModal();
const [closeableTask, setCloseableTaskTask] = useState<ITeamTask | null>(null);

const { taskStatus: taskStatusList } = useTaskStatus();
const {
tasks: teamTasks,
activeTeamTask,
Expand Down Expand Up @@ -140,11 +140,13 @@ export function useTaskInput({
}[];
} = {}) => {
if (query.trim().length < 2 || inputTask?.title === query.trim() || !userRef.current?.isEmailVerified) return;

const openId = taskStatusList.find((item) => item.value === 'open')?.id;
const statusId = taskStatusList.find((item) => item.name === taskStatus.current)?.id;
return createTask(
{
taskName: query.trim(),
issueType: taskIssue.current || 'Bug',
taskStatusId: statusId || openId as string,
status: taskStatus.current || undefined,
priority: taskPriority.current || undefined,
size: taskSize.current || undefined,
Expand Down
7 changes: 4 additions & 3 deletions apps/web/app/hooks/features/useTeamTasks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,7 @@ export function useTeamTasks() {
{
taskName,
issueType,
taskStatusId,
status = taskStatus[0]?.name,
priority,
size,
Expand All @@ -224,20 +225,19 @@ export function useTeamTasks() {
taskName: string;
issueType?: string;
status?: string;
taskStatusId: string;
priority?: string;
size?: string;
tags?: ITaskLabelsItemList[];
description?: string | null;
},
members?: { id: string }[]
) => {
const activeStatus = taskStatus.find((ts) => ts.name == status);
return createQueryCall(
{
title: taskName,
issueType,
status,
taskStatusId: activeStatus?.id,
priority,
size,
tags,
Expand All @@ -249,7 +249,8 @@ export function useTeamTasks() {
}
: {}),
...(description ? { description: `<p>${description}</p>` } : {}),
...(members ? { members } : {})
...(members ? { members } : {}),
taskStatusId: taskStatusId,
},
$user.current
).then((res) => {
Expand Down
Loading

0 comments on commit c2ea188

Please sign in to comment.