@ -47,7 +47,7 @@ export function RequireOnboarded({
|
|||||||
}
|
}
|
||||||
}, [onboardingStatus, navigate]);
|
}, [onboardingStatus, navigate]);
|
||||||
|
|
||||||
if (onboardingStatus !== OnboardingStatus.Completed) {
|
if (onboardingStatus && onboardingStatus !== OnboardingStatus.Completed) {
|
||||||
return (
|
return (
|
||||||
<EmptyContainer>
|
<EmptyContainer>
|
||||||
<FadeInStyle>
|
<FadeInStyle>
|
||||||
|
|||||||
@ -59,11 +59,10 @@ export function useAuth() {
|
|||||||
setTokenPair(verifyResult.data?.verify.tokens);
|
setTokenPair(verifyResult.data?.verify.tokens);
|
||||||
|
|
||||||
setIsAuthenticating(false);
|
setIsAuthenticating(false);
|
||||||
setCurrentUser(verifyResult.data?.verify.user);
|
|
||||||
|
|
||||||
return verifyResult.data?.verify;
|
return verifyResult.data?.verify;
|
||||||
},
|
},
|
||||||
[setCurrentUser, setIsAuthenticating, setTokenPair, verify],
|
[setIsAuthenticating, setTokenPair, verify],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleLogin = useCallback(
|
const handleLogin = useCallback(
|
||||||
@ -77,7 +76,8 @@ export function useAuth() {
|
|||||||
|
|
||||||
const handleLogout = useCallback(() => {
|
const handleLogout = useCallback(() => {
|
||||||
setTokenPair(null);
|
setTokenPair(null);
|
||||||
}, [setTokenPair]);
|
setCurrentUser(null);
|
||||||
|
}, [setTokenPair, setCurrentUser]);
|
||||||
|
|
||||||
const handleSignUp = useCallback(
|
const handleSignUp = useCallback(
|
||||||
async (email: string, password: string, workspaceInviteHash?: string) => {
|
async (email: string, password: string, workspaceInviteHash?: string) => {
|
||||||
|
|||||||
@ -8,9 +8,10 @@ import {
|
|||||||
OnboardingStatus,
|
OnboardingStatus,
|
||||||
} from '../utils/getOnboardingStatus';
|
} from '../utils/getOnboardingStatus';
|
||||||
|
|
||||||
export function useOnboardingStatus(): OnboardingStatus {
|
export function useOnboardingStatus(): OnboardingStatus | undefined {
|
||||||
const [currentUser] = useRecoilState(currentUserState);
|
const [currentUser] = useRecoilState(currentUserState);
|
||||||
const isLoggedIn = useIsLogged();
|
const isLoggedIn = useIsLogged();
|
||||||
|
|
||||||
const onboardingStatus = useMemo(
|
const onboardingStatus = useMemo(
|
||||||
() => getOnboardingStatus(isLoggedIn, currentUser),
|
() => getOnboardingStatus(isLoggedIn, currentUser),
|
||||||
[currentUser, isLoggedIn],
|
[currentUser, isLoggedIn],
|
||||||
|
|||||||
@ -11,9 +11,15 @@ export function getOnboardingStatus(
|
|||||||
isLoggedIn: boolean,
|
isLoggedIn: boolean,
|
||||||
currentUser: CurrentUser | null,
|
currentUser: CurrentUser | null,
|
||||||
) {
|
) {
|
||||||
if (!isLoggedIn || !currentUser) {
|
if (!isLoggedIn) {
|
||||||
return OnboardingStatus.OngoingUserCreation;
|
return OnboardingStatus.OngoingUserCreation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// if the user has not been fetched yet, we can't know the onboarding status
|
||||||
|
if (!currentUser) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
if (!currentUser.workspaceMember?.workspace.displayName) {
|
if (!currentUser.workspaceMember?.workspace.displayName) {
|
||||||
return OnboardingStatus.OngoingWorkspaceCreation;
|
return OnboardingStatus.OngoingWorkspaceCreation;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -114,8 +114,8 @@ export function CompanyBoardCard() {
|
|||||||
[updatePipelineProgress],
|
[updatePipelineProgress],
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleCheckboxChange = () => {
|
const handleCheckboxChange = (checked: boolean) => {
|
||||||
setSelected(!selected);
|
setSelected(checked);
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!company || !pipelineProgress) {
|
if (!company || !pipelineProgress) {
|
||||||
|
|||||||
@ -1,79 +1,98 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { IconCheck } from '@/ui/icons/index';
|
import { IconCheck, IconMinus } from '@/ui/icons';
|
||||||
|
|
||||||
type OwnProps = {
|
type OwnProps = {
|
||||||
checked: boolean;
|
checked: boolean;
|
||||||
indeterminate?: boolean;
|
indeterminate?: boolean;
|
||||||
onChange: () => void;
|
onChange: (value: boolean) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledInputContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
`;
|
||||||
position: relative;
|
|
||||||
|
|
||||||
input[type='checkbox'] {
|
const StyledInput = styled.input<{ indeterminate?: boolean }>`
|
||||||
accent-color: ${({ theme }) => theme.color.blue};
|
cursor: pointer;
|
||||||
|
margin: 0;
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 10;
|
||||||
|
|
||||||
|
& + label {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
margin: 2px;
|
padding: 0;
|
||||||
user-select: none;
|
position: relative;
|
||||||
width: 14px;
|
width: 14px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='checkbox']::before {
|
& + label:before {
|
||||||
background-color: ${({ theme }) => theme.background.primary};
|
background: ${({ theme }) => theme.background.primary};
|
||||||
border: 1px solid ${({ theme }) => theme.font.color.tertiary};
|
border: 1px solid ${({ theme }) => theme.border.color.strong};
|
||||||
border-radius: ${({ theme }) => theme.border.radius.xs};
|
border-radius: ${({ theme }) => theme.border.radius.sm};
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type='checkbox']:hover::before {
|
&:checked + label:before {
|
||||||
border: 1px solid ${({ theme }) => theme.font.color.primary};
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type='checkbox']:checked::before {
|
|
||||||
border: 1px solid ${({ theme }) => theme.color.blue};
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
|
||||||
background: ${({ theme }) => theme.color.blue};
|
background: ${({ theme }) => theme.color.blue};
|
||||||
color: white;
|
border-color: ${({ theme }) => theme.color.blue};
|
||||||
|
}
|
||||||
|
|
||||||
|
& + label:before {
|
||||||
|
background: ${({ theme, indeterminate }) =>
|
||||||
|
indeterminate ? theme.color.blue : theme.background.primary};
|
||||||
|
border-color: ${({ theme, indeterminate }) =>
|
||||||
|
indeterminate ? theme.color.blue : theme.border.color.inverted};
|
||||||
|
}
|
||||||
|
|
||||||
|
& + label > svg {
|
||||||
height: 12px;
|
height: 12px;
|
||||||
left: 50%;
|
left: 1px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%;
|
stroke: ${({ theme }) => theme.grayScale.gray0};
|
||||||
transform: translate(-50%, -50%);
|
top: 1px;
|
||||||
width: 12px;
|
width: 12px;
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export function Checkbox({ checked, onChange, indeterminate }: OwnProps) {
|
export function Checkbox({ checked, onChange, indeterminate }: OwnProps) {
|
||||||
const ref = React.useRef<HTMLInputElement>(null);
|
const [isInternalChecked, setIsInternalChecked] = React.useState(false);
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
if (ref.current === null) return;
|
setIsInternalChecked(checked);
|
||||||
if (typeof indeterminate === 'boolean') {
|
}, [checked]);
|
||||||
ref.current.indeterminate = !checked && indeterminate;
|
|
||||||
}
|
function handleChange(value: boolean) {
|
||||||
}, [ref, indeterminate, checked]);
|
onChange(value);
|
||||||
|
setIsInternalChecked(!isInternalChecked);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer onClick={onChange}>
|
<StyledInputContainer>
|
||||||
<input
|
<StyledInput
|
||||||
ref={ref}
|
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
|
name="styled-checkbox"
|
||||||
data-testid="input-checkbox"
|
data-testid="input-checkbox"
|
||||||
checked={checked}
|
checked={isInternalChecked}
|
||||||
|
indeterminate={indeterminate}
|
||||||
|
onChange={(event) => handleChange(event.target.checked)}
|
||||||
/>
|
/>
|
||||||
{checked && <IconCheck />}
|
<label htmlFor="checkbox">
|
||||||
</StyledContainer>
|
{indeterminate ? (
|
||||||
|
<IconMinus />
|
||||||
|
) : isInternalChecked ? (
|
||||||
|
<IconCheck />
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</label>
|
||||||
|
</StyledInputContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -21,8 +21,8 @@ export function CheckboxCell() {
|
|||||||
|
|
||||||
const { currentRowSelected, setCurrentRowSelected } = useCurrentRowSelected();
|
const { currentRowSelected, setCurrentRowSelected } = useCurrentRowSelected();
|
||||||
|
|
||||||
function handleContainerClick() {
|
function onChange(checked: boolean) {
|
||||||
handleCheckboxChange(!currentRowSelected);
|
handleCheckboxChange(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleCheckboxChange(newCheckedValue: boolean) {
|
function handleCheckboxChange(newCheckedValue: boolean) {
|
||||||
@ -33,7 +33,7 @@ export function CheckboxCell() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<Checkbox checked={currentRowSelected} onChange={handleContainerClick} />
|
<Checkbox checked={currentRowSelected} onChange={onChange} />
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -17,18 +17,17 @@ const StyledContainer = styled.div`
|
|||||||
export const SelectAllCheckbox = () => {
|
export const SelectAllCheckbox = () => {
|
||||||
const { selectAllRows, allRowsSelectedStatus } = useSelectAllRows();
|
const { selectAllRows, allRowsSelectedStatus } = useSelectAllRows();
|
||||||
|
|
||||||
function handleContainerClick() {
|
|
||||||
selectAllRows();
|
|
||||||
}
|
|
||||||
|
|
||||||
const checked = allRowsSelectedStatus === 'all';
|
const checked = allRowsSelectedStatus === 'all';
|
||||||
const indeterminate = allRowsSelectedStatus === 'some';
|
const indeterminate = allRowsSelectedStatus === 'some';
|
||||||
|
function onChange(value: boolean) {
|
||||||
|
selectAllRows();
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={checked}
|
checked={checked}
|
||||||
onChange={handleContainerClick}
|
onChange={onChange}
|
||||||
indeterminate={indeterminate}
|
indeterminate={indeterminate}
|
||||||
/>
|
/>
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
|
|||||||
@ -15,6 +15,7 @@ export { IconColorSwatch } from '@tabler/icons-react';
|
|||||||
export { IconX } from '@tabler/icons-react';
|
export { IconX } from '@tabler/icons-react';
|
||||||
export { IconChevronLeft } from '@tabler/icons-react';
|
export { IconChevronLeft } from '@tabler/icons-react';
|
||||||
export { IconPlus } from '@tabler/icons-react';
|
export { IconPlus } from '@tabler/icons-react';
|
||||||
|
export { IconMinus } from '@tabler/icons-react';
|
||||||
export { IconLink } from '@tabler/icons-react';
|
export { IconLink } from '@tabler/icons-react';
|
||||||
export { IconUsers } from '@tabler/icons-react';
|
export { IconUsers } from '@tabler/icons-react';
|
||||||
export { IconCalendarEvent } from '@tabler/icons-react';
|
export { IconCalendarEvent } from '@tabler/icons-react';
|
||||||
|
|||||||
@ -18,7 +18,10 @@ export function useSelectAllRows() {
|
|||||||
.getLoadable(tableRowIdsState)
|
.getLoadable(tableRowIdsState)
|
||||||
.valueOrThrow();
|
.valueOrThrow();
|
||||||
|
|
||||||
if (allRowsSelectedStatus === 'none') {
|
if (
|
||||||
|
allRowsSelectedStatus === 'none' ||
|
||||||
|
allRowsSelectedStatus === 'some'
|
||||||
|
) {
|
||||||
for (const rowId of tableRowIds) {
|
for (const rowId of tableRowIds) {
|
||||||
set(isRowSelectedFamilyState(rowId), true);
|
set(isRowSelectedFamilyState(rowId), true);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -14,6 +14,7 @@ export const borderLight = {
|
|||||||
strong: grayScale.gray25,
|
strong: grayScale.gray25,
|
||||||
medium: grayScale.gray20,
|
medium: grayScale.gray20,
|
||||||
light: grayScale.gray15,
|
light: grayScale.gray15,
|
||||||
|
inverted: grayScale.gray55,
|
||||||
},
|
},
|
||||||
...common,
|
...common,
|
||||||
};
|
};
|
||||||
@ -23,6 +24,7 @@ export const borderDark = {
|
|||||||
strong: grayScale.gray60,
|
strong: grayScale.gray60,
|
||||||
medium: grayScale.gray65,
|
medium: grayScale.gray65,
|
||||||
light: grayScale.gray70,
|
light: grayScale.gray70,
|
||||||
|
inverted: grayScale.gray30,
|
||||||
},
|
},
|
||||||
...common,
|
...common,
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user