removed unused files, unnecessary exports and renamed ownProps (#1225)
* remove unused files and rename ownProps * restore unused icons
This commit is contained in:
@ -1,116 +0,0 @@
|
|||||||
import { useState } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
import { useEditableField } from '@/ui/editable-field/hooks/useEditableField';
|
|
||||||
import { HotkeyScope } from '@/ui/utilities/hotkey/types/HotkeyScope';
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledProgressBarItemContainer = styled.div`
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
height: ${({ theme }) => theme.spacing(4)};
|
|
||||||
padding-right: ${({ theme }) => theme.spacing(1)};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledProgressBarItem = styled.div<{
|
|
||||||
isFirst: boolean;
|
|
||||||
isLast: boolean;
|
|
||||||
isActive: boolean;
|
|
||||||
}>`
|
|
||||||
background-color: ${({ theme, isActive }) =>
|
|
||||||
isActive
|
|
||||||
? theme.font.color.secondary
|
|
||||||
: theme.background.transparent.medium};
|
|
||||||
border-bottom-left-radius: ${({ theme, isFirst }) =>
|
|
||||||
isFirst ? theme.border.radius.sm : theme.border.radius.xs};
|
|
||||||
border-bottom-right-radius: ${({ theme, isLast }) =>
|
|
||||||
isLast ? theme.border.radius.sm : theme.border.radius.xs};
|
|
||||||
border-top-left-radius: ${({ theme, isFirst }) =>
|
|
||||||
isFirst ? theme.border.radius.sm : theme.border.radius.xs};
|
|
||||||
border-top-right-radius: ${({ theme, isLast }) =>
|
|
||||||
isLast ? theme.border.radius.sm : theme.border.radius.xs};
|
|
||||||
height: ${({ theme }) => theme.spacing(2)};
|
|
||||||
width: ${({ theme }) => theme.spacing(3)};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledProgressBarContainer = styled.div`
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
justify-content: flex-start;
|
|
||||||
width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledLabel = styled.div`
|
|
||||||
width: ${({ theme }) => theme.spacing(12)};
|
|
||||||
`;
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
value: number;
|
|
||||||
onChange?: (newValue: number) => void;
|
|
||||||
parentHotkeyScope?: HotkeyScope;
|
|
||||||
};
|
|
||||||
|
|
||||||
const PROBABILITY_VALUES = [
|
|
||||||
{ label: '0%', value: 0 },
|
|
||||||
{ label: '25%', value: 25 },
|
|
||||||
{ label: '50%', value: 50 },
|
|
||||||
{ label: '75%', value: 75 },
|
|
||||||
{ label: '100%', value: 100 },
|
|
||||||
];
|
|
||||||
|
|
||||||
export function ProbabilityFieldEditMode({ value, onChange }: OwnProps) {
|
|
||||||
const [nextProbabilityIndex, setNextProbabilityIndex] = useState<
|
|
||||||
number | null
|
|
||||||
>(null);
|
|
||||||
|
|
||||||
const probabilityIndex = Math.ceil(value / 25);
|
|
||||||
const { closeEditableField } = useEditableField();
|
|
||||||
|
|
||||||
function handleChange(newValue: number) {
|
|
||||||
onChange?.(newValue);
|
|
||||||
closeEditableField();
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledContainer>
|
|
||||||
<StyledLabel>
|
|
||||||
{
|
|
||||||
PROBABILITY_VALUES[
|
|
||||||
nextProbabilityIndex || nextProbabilityIndex === 0
|
|
||||||
? nextProbabilityIndex
|
|
||||||
: probabilityIndex
|
|
||||||
].label
|
|
||||||
}
|
|
||||||
</StyledLabel>
|
|
||||||
<StyledProgressBarContainer>
|
|
||||||
{PROBABILITY_VALUES.map((probability, i) => (
|
|
||||||
<StyledProgressBarItemContainer
|
|
||||||
key={i}
|
|
||||||
onClick={() => handleChange(probability.value)}
|
|
||||||
onMouseEnter={() => setNextProbabilityIndex(i)}
|
|
||||||
onMouseLeave={() => setNextProbabilityIndex(null)}
|
|
||||||
>
|
|
||||||
<StyledProgressBarItem
|
|
||||||
isActive={
|
|
||||||
nextProbabilityIndex || nextProbabilityIndex === 0
|
|
||||||
? i <= nextProbabilityIndex
|
|
||||||
: i <= probabilityIndex
|
|
||||||
}
|
|
||||||
key={probability.label}
|
|
||||||
isFirst={i === 0}
|
|
||||||
isLast={i === PROBABILITY_VALUES.length - 1}
|
|
||||||
/>
|
|
||||||
</StyledProgressBarItemContainer>
|
|
||||||
))}
|
|
||||||
</StyledProgressBarContainer>
|
|
||||||
</StyledContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -10,7 +10,7 @@ import {
|
|||||||
SortOrder,
|
SortOrder,
|
||||||
} from '~/generated/graphql';
|
} from '~/generated/graphql';
|
||||||
|
|
||||||
export type SelectStringKeys<T> = NonNullable<
|
type SelectStringKeys<T> = NonNullable<
|
||||||
{
|
{
|
||||||
[K in keyof T]: K extends '__typename'
|
[K in keyof T]: K extends '__typename'
|
||||||
? never
|
? never
|
||||||
@ -20,7 +20,7 @@ export type SelectStringKeys<T> = NonNullable<
|
|||||||
}[keyof T]
|
}[keyof T]
|
||||||
>;
|
>;
|
||||||
|
|
||||||
export type ExtractEntityTypeFromQueryResponse<T> = T extends {
|
type ExtractEntityTypeFromQueryResponse<T> = T extends {
|
||||||
searchResults: Array<infer U>;
|
searchResults: Array<infer U>;
|
||||||
}
|
}
|
||||||
? U
|
? U
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import { BoardColumnHotkeyScope } from '../types/BoardColumnHotkeyScope';
|
|||||||
|
|
||||||
import { BoardColumnMenu } from './BoardColumnMenu';
|
import { BoardColumnMenu } from './BoardColumnMenu';
|
||||||
|
|
||||||
export const StyledColumn = styled.div<{ isFirstColumn: boolean }>`
|
const StyledColumn = styled.div<{ isFirstColumn: boolean }>`
|
||||||
background-color: ${({ theme }) => theme.background.primary};
|
background-color: ${({ theme }) => theme.background.primary};
|
||||||
border-left: 1px solid
|
border-left: 1px solid
|
||||||
${({ theme, isFirstColumn }) =>
|
${({ theme, isFirstColumn }) =>
|
||||||
@ -33,27 +33,6 @@ const StyledHeader = styled.div`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const StyledColumnTitle = styled.h3<{
|
|
||||||
colorHexCode?: string;
|
|
||||||
colorName?: string;
|
|
||||||
}>`
|
|
||||||
align-items: center;
|
|
||||||
border-radius: ${({ theme }) => theme.border.radius.sm};
|
|
||||||
color: ${({ colorHexCode, colorName, theme }) =>
|
|
||||||
colorName ? theme.tag.text[colorName] : colorHexCode};
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
font-size: ${({ theme }) => theme.font.size.md};
|
|
||||||
font-style: normal;
|
|
||||||
font-weight: ${({ theme }) => theme.font.weight.medium};
|
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
|
||||||
margin: 0;
|
|
||||||
padding-bottom: ${({ theme }) => theme.spacing(1)};
|
|
||||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
|
||||||
padding-right: ${({ theme }) => theme.spacing(2)};
|
|
||||||
padding-top: ${({ theme }) => theme.spacing(1)};
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledAmount = styled.div`
|
const StyledAmount = styled.div`
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
color: ${({ theme }) => theme.font.color.tertiary};
|
||||||
margin-left: ${({ theme }) => theme.spacing(2)};
|
margin-left: ${({ theme }) => theme.spacing(2)};
|
||||||
@ -72,7 +51,7 @@ const StyledNumChildren = styled.div`
|
|||||||
width: 16px;
|
width: 16px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
export type BoardColumnProps = {
|
||||||
color: string;
|
color: string;
|
||||||
title: string;
|
title: string;
|
||||||
onTitleEdit: (title: string, color: string) => void;
|
onTitleEdit: (title: string, color: string) => void;
|
||||||
@ -90,7 +69,7 @@ export function BoardColumn({
|
|||||||
children,
|
children,
|
||||||
isFirstColumn,
|
isFirstColumn,
|
||||||
numChildren,
|
numChildren,
|
||||||
}: OwnProps) {
|
}: BoardColumnProps) {
|
||||||
const [isBoardColumnMenuOpen, setIsBoardColumnMenuOpen] =
|
const [isBoardColumnMenuOpen, setIsBoardColumnMenuOpen] =
|
||||||
React.useState(false);
|
React.useState(false);
|
||||||
|
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import { DropdownMenuSeparator } from '@/ui/dropdown/components/DropdownMenuSepa
|
|||||||
import { textInputStyle } from '@/ui/theme/constants/effects';
|
import { textInputStyle } from '@/ui/theme/constants/effects';
|
||||||
import { debounce } from '~/utils/debounce';
|
import { debounce } from '~/utils/debounce';
|
||||||
|
|
||||||
export const StyledEditTitleContainer = styled.div`
|
const StyledEditTitleContainer = styled.div`
|
||||||
--vertical-padding: ${({ theme }) => theme.spacing(1)};
|
--vertical-padding: ${({ theme }) => theme.spacing(1)};
|
||||||
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -28,7 +28,7 @@ const StyledEditModeInput = styled.input`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
export type BoardColumnEditTitleMenuProps = {
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
title: string;
|
title: string;
|
||||||
onTitleEdit: (title: string, color: string) => void;
|
onTitleEdit: (title: string, color: string) => void;
|
||||||
@ -64,7 +64,7 @@ export function BoardColumnEditTitleMenu({
|
|||||||
onTitleEdit,
|
onTitleEdit,
|
||||||
title,
|
title,
|
||||||
color,
|
color,
|
||||||
}: OwnProps) {
|
}: BoardColumnEditTitleMenuProps) {
|
||||||
const [internalValue, setInternalValue] = useState(title);
|
const [internalValue, setInternalValue] = useState(title);
|
||||||
const debouncedOnUpdateTitle = debounce(
|
const debouncedOnUpdateTitle = debounce(
|
||||||
(newTitle) => onTitleEdit(newTitle, color),
|
(newTitle) => onTitleEdit(newTitle, color),
|
||||||
|
|||||||
@ -1,17 +0,0 @@
|
|||||||
import { createContext } from 'react';
|
|
||||||
|
|
||||||
import { FieldDefinition } from '@/ui/editable-field/types/FieldDefinition';
|
|
||||||
import {
|
|
||||||
FieldMetadata,
|
|
||||||
FieldType,
|
|
||||||
} from '@/ui/editable-field/types/FieldMetadata';
|
|
||||||
|
|
||||||
export const FieldDefinitionContext = createContext<
|
|
||||||
FieldDefinition<FieldMetadata>
|
|
||||||
>({
|
|
||||||
id: '',
|
|
||||||
label: '',
|
|
||||||
icon: undefined,
|
|
||||||
type: 'unknown' satisfies FieldType,
|
|
||||||
metadata: {} as FieldMetadata,
|
|
||||||
});
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { boardCardIdsByColumnIdFamilyState } from '../states/boardCardIdsByColumnIdFamilyState';
|
|
||||||
import { boardColumnsState } from '../states/boardColumnsState';
|
|
||||||
import { isCardSelectedFamilyState } from '../states/isCardSelectedFamilyState';
|
|
||||||
|
|
||||||
export function useResetCardSelection() {
|
|
||||||
return useRecoilCallback(
|
|
||||||
({ snapshot, set }) =>
|
|
||||||
() => {
|
|
||||||
const boardColumns = snapshot
|
|
||||||
.getLoadable(boardColumnsState)
|
|
||||||
.valueOrThrow();
|
|
||||||
|
|
||||||
const cardIds = boardColumns.flatMap((boardColumn) =>
|
|
||||||
snapshot
|
|
||||||
.getLoadable(boardCardIdsByColumnIdFamilyState(boardColumn.id))
|
|
||||||
.valueOrThrow(),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const cardId of cardIds) {
|
|
||||||
set(isCardSelectedFamilyState(cardId), false);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -4,7 +4,7 @@ import styled from '@emotion/styled';
|
|||||||
import { DropdownMenu } from '@/ui/dropdown/components/DropdownMenu';
|
import { DropdownMenu } from '@/ui/dropdown/components/DropdownMenu';
|
||||||
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useListenClickOutside';
|
||||||
|
|
||||||
export const StyledDropdownMenuContainer = styled.ul<{
|
const StyledDropdownMenuContainer = styled.ul<{
|
||||||
anchor: 'left' | 'right';
|
anchor: 'left' | 'right';
|
||||||
}>`
|
}>`
|
||||||
padding: 0;
|
padding: 0;
|
||||||
@ -15,7 +15,7 @@ export const StyledDropdownMenuContainer = styled.ul<{
|
|||||||
top: 14px;
|
top: 14px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type DropdownMenuContainerProps = {
|
export type DropdownMenuContainerProps = {
|
||||||
anchor?: 'left' | 'right';
|
anchor?: 'left' | 'right';
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
|
|||||||
@ -1,4 +0,0 @@
|
|||||||
export type FilterSearchResult = {
|
|
||||||
id: string;
|
|
||||||
label: string;
|
|
||||||
};
|
|
||||||
@ -5,7 +5,7 @@ import { formatToHumanReadableDate } from '~/utils';
|
|||||||
|
|
||||||
import DatePicker from './DatePicker';
|
import DatePicker from './DatePicker';
|
||||||
|
|
||||||
export type StyledCalendarContainerProps = {
|
type StyledCalendarContainerProps = {
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
editModeHorizontalAlign?: 'left' | 'right';
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -31,7 +31,7 @@ const StyledCalendarContainer = styled.div<StyledCalendarContainerProps>`
|
|||||||
|
|
||||||
type DivProps = React.HTMLProps<HTMLDivElement>;
|
type DivProps = React.HTMLProps<HTMLDivElement>;
|
||||||
|
|
||||||
export const DateDisplay = forwardRef<HTMLDivElement, DivProps>(
|
const DateDisplay = forwardRef<HTMLDivElement, DivProps>(
|
||||||
({ value, onClick }, ref) => (
|
({ value, onClick }, ref) => (
|
||||||
<StyledInputContainer onClick={onClick} ref={ref}>
|
<StyledInputContainer onClick={onClick} ref={ref}>
|
||||||
{value && formatToHumanReadableDate(new Date(value as string))}
|
{value && formatToHumanReadableDate(new Date(value as string))}
|
||||||
@ -43,16 +43,16 @@ type DatePickerContainerProps = {
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const DatePickerContainer = ({ children }: DatePickerContainerProps) => {
|
const DatePickerContainer = ({ children }: DatePickerContainerProps) => {
|
||||||
return <StyledCalendarContainer>{children}</StyledCalendarContainer>;
|
return <StyledCalendarContainer>{children}</StyledCalendarContainer>;
|
||||||
};
|
};
|
||||||
|
|
||||||
type OwnProps = {
|
export type DateInputEditProps = {
|
||||||
value: Date | null | undefined;
|
value: Date | null | undefined;
|
||||||
onChange: (newDate: Date) => void;
|
onChange: (newDate: Date) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DateInputEdit({ onChange, value }: OwnProps) {
|
export function DateInputEdit({ onChange, value }: DateInputEditProps) {
|
||||||
return (
|
return (
|
||||||
<DatePicker
|
<DatePicker
|
||||||
date={value ?? new Date()}
|
date={value ?? new Date()}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import styled from '@emotion/styled';
|
|||||||
|
|
||||||
import { StyledInput } from '@/ui/table/editable-cell/type/components/TextCellEdit';
|
import { StyledInput } from '@/ui/table/editable-cell/type/components/TextCellEdit';
|
||||||
|
|
||||||
type OwnProps = {
|
export type DoubleTextInputEditProps = {
|
||||||
firstValue: string;
|
firstValue: string;
|
||||||
secondValue: string;
|
secondValue: string;
|
||||||
firstValuePlaceholder: string;
|
firstValuePlaceholder: string;
|
||||||
@ -11,7 +11,7 @@ type OwnProps = {
|
|||||||
onChange: (firstValue: string, secondValue: string) => void;
|
onChange: (firstValue: string, secondValue: string) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StyledDoubleTextContainer = styled.div`
|
const StyledDoubleTextContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
@ -30,7 +30,7 @@ export function DoubleTextInputEdit({
|
|||||||
firstValuePlaceholder,
|
firstValuePlaceholder,
|
||||||
secondValuePlaceholder,
|
secondValuePlaceholder,
|
||||||
onChange,
|
onChange,
|
||||||
}: OwnProps) {
|
}: DoubleTextInputEditProps) {
|
||||||
return (
|
return (
|
||||||
<StyledDoubleTextContainer>
|
<StyledDoubleTextContainer>
|
||||||
<StyledNameInput
|
<StyledNameInput
|
||||||
|
|||||||
@ -13,15 +13,10 @@ import { isDefined } from '~/utils/isDefined';
|
|||||||
import { useEntitySelectSearch } from '../hooks/useEntitySelectSearch';
|
import { useEntitySelectSearch } from '../hooks/useEntitySelectSearch';
|
||||||
import { EntityForSelect } from '../types/EntityForSelect';
|
import { EntityForSelect } from '../types/EntityForSelect';
|
||||||
|
|
||||||
import { SingleEntitySelectBase } from './SingleEntitySelectBase';
|
import {
|
||||||
|
EntitiesForSingleEntitySelect,
|
||||||
export type EntitiesForSingleEntitySelect<
|
SingleEntitySelectBase,
|
||||||
CustomEntityForSelect extends EntityForSelect,
|
} from './SingleEntitySelectBase';
|
||||||
> = {
|
|
||||||
loading: boolean;
|
|
||||||
selectedEntity: CustomEntityForSelect;
|
|
||||||
entitiesToSelect: CustomEntityForSelect[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export function SingleEntitySelect<
|
export function SingleEntitySelect<
|
||||||
CustomEntityForSelect extends EntityForSelect,
|
CustomEntityForSelect extends EntityForSelect,
|
||||||
|
|||||||
@ -4,13 +4,13 @@ import { textInputStyle } from '@/ui/theme/constants/effects';
|
|||||||
|
|
||||||
import { TextInputContainer } from './TextInputContainer';
|
import { TextInputContainer } from './TextInputContainer';
|
||||||
|
|
||||||
export const InplaceInputTextInput = styled.input`
|
const InplaceInputTextInput = styled.input`
|
||||||
margin: 0;
|
margin: 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
${textInputStyle}
|
${textInputStyle}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
export type TextInputEditProps = {
|
||||||
placeholder?: string;
|
placeholder?: string;
|
||||||
value?: string;
|
value?: string;
|
||||||
onChange?: (newValue: string) => void;
|
onChange?: (newValue: string) => void;
|
||||||
@ -22,7 +22,7 @@ export function TextInputEdit({
|
|||||||
value,
|
value,
|
||||||
onChange,
|
onChange,
|
||||||
autoFocus,
|
autoFocus,
|
||||||
}: OwnProps) {
|
}: TextInputEditProps) {
|
||||||
return (
|
return (
|
||||||
<TextInputContainer>
|
<TextInputContainer>
|
||||||
<InplaceInputTextInput
|
<InplaceInputTextInput
|
||||||
|
|||||||
@ -1,26 +0,0 @@
|
|||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
const TitleAndCollapseContainer = styled.div`
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TitleContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
font-size: ${({ theme }) => theme.font.size.lg};
|
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
|
||||||
width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
title: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export function PageTitle({ title }: OwnProps) {
|
|
||||||
return (
|
|
||||||
<TitleAndCollapseContainer>
|
|
||||||
<TitleContainer data-testid="top-bar-title">{title}</TitleContainer>
|
|
||||||
</TitleAndCollapseContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -13,7 +13,7 @@ import {
|
|||||||
} from '@/ui/section/components/Section';
|
} from '@/ui/section/components/Section';
|
||||||
import { H1Title, H1TitleFontColor } from '@/ui/typography/components/H1Title';
|
import { H1Title, H1TitleFontColor } from '@/ui/typography/components/H1Title';
|
||||||
|
|
||||||
interface ConfirmationModalProps {
|
export type ConfirmationModalProps = {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
subtitle: ReactNode;
|
subtitle: ReactNode;
|
||||||
@ -22,9 +22,9 @@ interface ConfirmationModalProps {
|
|||||||
deleteButtonText?: string;
|
deleteButtonText?: string;
|
||||||
confirmationPlaceholder?: string;
|
confirmationPlaceholder?: string;
|
||||||
confirmationValue?: string;
|
confirmationValue?: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
export const StyledCenteredButton = styled(Button)`
|
const StyledCenteredButton = styled(Button)`
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@ -9,17 +9,6 @@ import { useTheme } from '@emotion/react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { AnimationControls, motion, useAnimation } from 'framer-motion';
|
import { AnimationControls, motion, useAnimation } from 'framer-motion';
|
||||||
|
|
||||||
const Bar = styled.div<Pick<ProgressBarProps, 'barHeight'>>`
|
|
||||||
height: ${({ barHeight }) => barHeight}px;
|
|
||||||
overflow: hidden;
|
|
||||||
width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const BarFilling = styled(motion.div)`
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export type ProgressBarProps = {
|
export type ProgressBarProps = {
|
||||||
duration?: number;
|
duration?: number;
|
||||||
delay?: number;
|
delay?: number;
|
||||||
@ -34,6 +23,17 @@ export type ProgressBarControls = AnimationControls & {
|
|||||||
pause: () => Promise<any>;
|
pause: () => Promise<any>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const StyledBar = styled.div<Pick<ProgressBarProps, 'barHeight'>>`
|
||||||
|
height: ${({ barHeight }) => barHeight}px;
|
||||||
|
overflow: hidden;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const StyledBarFilling = styled(motion.div)`
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
export const ProgressBar = forwardRef<ProgressBarControls, ProgressBarProps>(
|
export const ProgressBar = forwardRef<ProgressBarControls, ProgressBarProps>(
|
||||||
(
|
(
|
||||||
{
|
{
|
||||||
@ -84,8 +84,8 @@ export const ProgressBar = forwardRef<ProgressBarControls, ProgressBarProps>(
|
|||||||
}, [controls, delay, duration, easing, autoStart, start]);
|
}, [controls, delay, duration, easing, autoStart, start]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Bar barHeight={barHeight}>
|
<StyledBar barHeight={barHeight}>
|
||||||
<BarFilling
|
<StyledBarFilling
|
||||||
style={{
|
style={{
|
||||||
originX: 0,
|
originX: 0,
|
||||||
// Seems like custom props are not well handled by react when used with framer-motion and emotion styled
|
// Seems like custom props are not well handled by react when used with framer-motion and emotion styled
|
||||||
@ -95,7 +95,7 @@ export const ProgressBar = forwardRef<ProgressBarControls, ProgressBarProps>(
|
|||||||
animate={controls}
|
animate={controls}
|
||||||
exit={{ scaleX: 0 }}
|
exit={{ scaleX: 0 }}
|
||||||
/>
|
/>
|
||||||
</Bar>
|
</StyledBar>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|||||||
@ -6,7 +6,7 @@ export type SnackBarOptions = SnackbarProps & {
|
|||||||
id: string;
|
id: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type SnackBarState = {
|
type SnackBarState = {
|
||||||
maxQueue: number;
|
maxQueue: number;
|
||||||
queue: SnackBarOptions[];
|
queue: SnackBarOptions[];
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,9 +0,0 @@
|
|||||||
import Skeleton from 'react-loading-skeleton';
|
|
||||||
|
|
||||||
export function CellSkeleton() {
|
|
||||||
return (
|
|
||||||
<div style={{ width: '100%', alignItems: 'center' }}>
|
|
||||||
<Skeleton />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -22,7 +22,7 @@ const StyledEditButtonContainer = styled(motion.div)`
|
|||||||
right: 5px;
|
right: 5px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const CellBaseContainer = styled.div`
|
const StyledCellBaseContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
@ -33,7 +33,7 @@ export const CellBaseContainer = styled.div`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
export type EditableCellProps = {
|
||||||
editModeContent: ReactElement;
|
editModeContent: ReactElement;
|
||||||
nonEditModeContent: ReactElement;
|
nonEditModeContent: ReactElement;
|
||||||
editModeHorizontalAlign?: 'left' | 'right';
|
editModeHorizontalAlign?: 'left' | 'right';
|
||||||
@ -59,7 +59,7 @@ export function EditableCell({
|
|||||||
transparent = false,
|
transparent = false,
|
||||||
maxContentWidth,
|
maxContentWidth,
|
||||||
useEditButton,
|
useEditButton,
|
||||||
}: OwnProps) {
|
}: EditableCellProps) {
|
||||||
const { isCurrentCellInEditMode } = useCurrentCellEditMode();
|
const { isCurrentCellInEditMode } = useCurrentCellEditMode();
|
||||||
const [isHovered, setIsHovered] = useState(false);
|
const [isHovered, setIsHovered] = useState(false);
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ export function EditableCell({
|
|||||||
<CellHotkeyScopeContext.Provider
|
<CellHotkeyScopeContext.Provider
|
||||||
value={editHotkeyScope ?? DEFAULT_CELL_SCOPE}
|
value={editHotkeyScope ?? DEFAULT_CELL_SCOPE}
|
||||||
>
|
>
|
||||||
<CellBaseContainer
|
<StyledCellBaseContainer
|
||||||
onMouseEnter={handleContainerMouseEnter}
|
onMouseEnter={handleContainerMouseEnter}
|
||||||
onMouseLeave={handleContainerMouseLeave}
|
onMouseLeave={handleContainerMouseLeave}
|
||||||
>
|
>
|
||||||
@ -128,7 +128,7 @@ export function EditableCell({
|
|||||||
</EditableCellDisplayMode>
|
</EditableCellDisplayMode>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</CellBaseContainer>
|
</StyledCellBaseContainer>
|
||||||
</CellHotkeyScopeContext.Provider>
|
</CellHotkeyScopeContext.Provider>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,14 +1,14 @@
|
|||||||
import { Ref } from 'react';
|
import { Ref } from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
type Props = {
|
export type EditableCellDisplayContainerProps = {
|
||||||
softFocus?: boolean;
|
softFocus?: boolean;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
scrollRef?: Ref<HTMLDivElement>;
|
scrollRef?: Ref<HTMLDivElement>;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EditableCellDisplayModeOuterContainer = styled.div<
|
const StyledEditableCellDisplayModeOuterContainer = styled.div<
|
||||||
Pick<Props, 'softFocus'>
|
Pick<EditableCellDisplayContainerProps, 'softFocus'>
|
||||||
>`
|
>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -22,12 +22,12 @@ export const EditableCellDisplayModeOuterContainer = styled.div<
|
|||||||
${(props) =>
|
${(props) =>
|
||||||
props.softFocus
|
props.softFocus
|
||||||
? `background: ${props.theme.background.transparent.secondary};
|
? `background: ${props.theme.background.transparent.secondary};
|
||||||
border-radius: ${props.theme.border.radius.sm};
|
border-radius: ${props.theme.border.radius.sm};
|
||||||
box-shadow: inset 0 0 0 1px ${props.theme.font.color.extraLight};`
|
box-shadow: inset 0 0 0 1px ${props.theme.font.color.extraLight};`
|
||||||
: ''}
|
: ''}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const EditableCellDisplayModeInnerContainer = styled.div`
|
const EditableCellDisplayModeInnerContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
@ -40,9 +40,9 @@ export function EditableCellDisplayContainer({
|
|||||||
softFocus,
|
softFocus,
|
||||||
onClick,
|
onClick,
|
||||||
scrollRef,
|
scrollRef,
|
||||||
}: React.PropsWithChildren<Props>) {
|
}: React.PropsWithChildren<EditableCellDisplayContainerProps>) {
|
||||||
return (
|
return (
|
||||||
<EditableCellDisplayModeOuterContainer
|
<StyledEditableCellDisplayModeOuterContainer
|
||||||
data-testid={
|
data-testid={
|
||||||
softFocus
|
softFocus
|
||||||
? 'editable-cell-soft-focus-mode'
|
? 'editable-cell-soft-focus-mode'
|
||||||
@ -55,6 +55,6 @@ export function EditableCellDisplayContainer({
|
|||||||
<EditableCellDisplayModeInnerContainer>
|
<EditableCellDisplayModeInnerContainer>
|
||||||
{children}
|
{children}
|
||||||
</EditableCellDisplayModeInnerContainer>
|
</EditableCellDisplayModeInnerContainer>
|
||||||
</EditableCellDisplayModeOuterContainer>
|
</StyledEditableCellDisplayModeOuterContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import styled from '@emotion/styled';
|
|||||||
|
|
||||||
import { overlayBackground } from '@/ui/theme/constants/effects';
|
import { overlayBackground } from '@/ui/theme/constants/effects';
|
||||||
|
|
||||||
export const EditableCellEditModeContainer = styled.div<OwnProps>`
|
const StyledEditableCellEditModeContainer = styled.div<EditableCellEditModeProps>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
border: ${({ transparent, theme }) =>
|
border: ${({ transparent, theme }) =>
|
||||||
transparent ? 'none' : `1px solid ${theme.border.color.light}`};
|
transparent ? 'none' : `1px solid ${theme.border.color.light}`};
|
||||||
@ -28,7 +28,7 @@ export const EditableCellEditModeContainer = styled.div<OwnProps>`
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
export type EditableCellEditModeProps = {
|
||||||
children: ReactElement;
|
children: ReactElement;
|
||||||
transparent?: boolean;
|
transparent?: boolean;
|
||||||
maxContentWidth?: number;
|
maxContentWidth?: number;
|
||||||
@ -43,9 +43,9 @@ export function EditableCellEditMode({
|
|||||||
children,
|
children,
|
||||||
transparent = false,
|
transparent = false,
|
||||||
maxContentWidth,
|
maxContentWidth,
|
||||||
}: OwnProps) {
|
}: EditableCellEditModeProps) {
|
||||||
return (
|
return (
|
||||||
<EditableCellEditModeContainer
|
<StyledEditableCellEditModeContainer
|
||||||
maxContentWidth={maxContentWidth}
|
maxContentWidth={maxContentWidth}
|
||||||
transparent={transparent}
|
transparent={transparent}
|
||||||
data-testid="editable-cell-edit-mode-container"
|
data-testid="editable-cell-edit-mode-container"
|
||||||
@ -53,6 +53,6 @@ export function EditableCellEditMode({
|
|||||||
editModeVerticalPosition={editModeVerticalPosition}
|
editModeVerticalPosition={editModeVerticalPosition}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
</EditableCellEditModeContainer>
|
</StyledEditableCellEditModeContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,17 +9,17 @@ import { useListenClickOutside } from '@/ui/utilities/pointer-event/hooks/useLis
|
|||||||
|
|
||||||
import { useEditableCell } from '../../hooks/useEditableCell';
|
import { useEditableCell } from '../../hooks/useEditableCell';
|
||||||
|
|
||||||
const EditableCellDateEditModeContainer = styled.div`
|
const StyledEditableCellDateEditModeContainer = styled.div`
|
||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export type EditableDateProps = {
|
export type DateCellEditProps = {
|
||||||
value: Date;
|
value: Date;
|
||||||
onSubmit: (date: Date) => void;
|
onSubmit: (date: Date) => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function DateCellEdit({ value, onSubmit }: EditableDateProps) {
|
export function DateCellEdit({ value, onSubmit }: DateCellEditProps) {
|
||||||
const { closeEditableCell } = useEditableCell();
|
const { closeEditableCell } = useEditableCell();
|
||||||
|
|
||||||
function handleDateChange(newDate: Date) {
|
function handleDateChange(newDate: Date) {
|
||||||
@ -51,8 +51,8 @@ export function DateCellEdit({ value, onSubmit }: EditableDateProps) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<EditableCellDateEditModeContainer ref={containerRef}>
|
<StyledEditableCellDateEditModeContainer ref={containerRef}>
|
||||||
<DateInputEdit onChange={handleDateChange} value={value} />
|
<DateInputEdit onChange={handleDateChange} value={value} />
|
||||||
</EditableCellDateEditModeContainer>
|
</StyledEditableCellDateEditModeContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,19 +0,0 @@
|
|||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { tableRowIdsState } from '../states/tableRowIdsState';
|
|
||||||
|
|
||||||
export function useSetTableRowIds() {
|
|
||||||
return useRecoilCallback(
|
|
||||||
({ set, snapshot }) =>
|
|
||||||
(rowIds: string[]) => {
|
|
||||||
const currentRowIds = snapshot
|
|
||||||
.getLoadable(tableRowIdsState)
|
|
||||||
.valueOrThrow();
|
|
||||||
|
|
||||||
if (JSON.stringify(rowIds) !== JSON.stringify(currentRowIds)) {
|
|
||||||
set(tableRowIdsState, rowIds);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { atomFamily } from 'recoil';
|
|
||||||
|
|
||||||
export const currentColumnNumberScopedState = atomFamily<number, string>({
|
|
||||||
key: 'currentColumnNumberScopedState',
|
|
||||||
default: 0,
|
|
||||||
});
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { atomFamily } from 'recoil';
|
|
||||||
|
|
||||||
export const currentRowEntityIdScopedState = atomFamily<string | null, string>({
|
|
||||||
key: 'currentRowEntityIdScopedState',
|
|
||||||
default: null,
|
|
||||||
});
|
|
||||||
@ -1,6 +0,0 @@
|
|||||||
import { atomFamily } from 'recoil';
|
|
||||||
|
|
||||||
export const currentRowNumberScopedState = atomFamily<number, string>({
|
|
||||||
key: 'currentRowNumberScopedState',
|
|
||||||
default: 0,
|
|
||||||
});
|
|
||||||
@ -1,5 +0,0 @@
|
|||||||
export type EntityUpdateFieldHook = () => <T>(
|
|
||||||
entityId: string,
|
|
||||||
fieldName: string,
|
|
||||||
value: T,
|
|
||||||
) => void | Promise<void>;
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import { CellPosition } from '../CellPosition';
|
|
||||||
|
|
||||||
export function isTablePosition(value: any): value is CellPosition {
|
|
||||||
return (
|
|
||||||
value && typeof value.row === 'number' && typeof value.column === 'number'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
export const StyledTag = styled.h3<{
|
const StyledTag = styled.h3<{
|
||||||
colorHexCode?: string;
|
colorHexCode?: string;
|
||||||
colorId?: string;
|
colorId?: string;
|
||||||
}>`
|
}>`
|
||||||
@ -23,13 +23,13 @@ export const StyledTag = styled.h3<{
|
|||||||
padding-top: ${({ theme }) => theme.spacing(1)};
|
padding-top: ${({ theme }) => theme.spacing(1)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
type OwnProps = {
|
export type TagProps = {
|
||||||
color?: string;
|
color?: string;
|
||||||
text: string;
|
text: string;
|
||||||
onClick?: () => void;
|
onClick?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function Tag({ color, text, onClick }: OwnProps) {
|
export function Tag({ color, text, onClick }: TagProps) {
|
||||||
const colorHexCode = color?.charAt(0) === '#' ? color : undefined;
|
const colorHexCode = color?.charAt(0) === '#' ? color : undefined;
|
||||||
const colorId = color?.charAt(0) === '#' ? undefined : color;
|
const colorId = color?.charAt(0) === '#' ? undefined : color;
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useEffect, useMemo, useState } from 'react';
|
|||||||
|
|
||||||
import { ColorScheme } from '~/generated/graphql';
|
import { ColorScheme } from '~/generated/graphql';
|
||||||
|
|
||||||
export type SystemColorScheme = ColorScheme.Light | ColorScheme.Dark;
|
type SystemColorScheme = ColorScheme.Light | ColorScheme.Dark;
|
||||||
|
|
||||||
export function useSystemColorScheme(): SystemColorScheme {
|
export function useSystemColorScheme(): SystemColorScheme {
|
||||||
const mediaQuery = useMemo(
|
const mediaQuery = useMemo(
|
||||||
|
|||||||
@ -2,13 +2,6 @@ import { AppHotkeyScope } from '../types/AppHotkeyScope';
|
|||||||
import { CustomHotkeyScopes } from '../types/CustomHotkeyScope';
|
import { CustomHotkeyScopes } from '../types/CustomHotkeyScope';
|
||||||
import { HotkeyScope } from '../types/HotkeyScope';
|
import { HotkeyScope } from '../types/HotkeyScope';
|
||||||
|
|
||||||
export const INITIAL_HOTKEYS_SCOPES: string[] = [AppHotkeyScope.App];
|
|
||||||
|
|
||||||
export const ALWAYS_ON_HOTKEYS_SCOPES: string[] = [
|
|
||||||
AppHotkeyScope.CommandMenu,
|
|
||||||
AppHotkeyScope.App,
|
|
||||||
];
|
|
||||||
|
|
||||||
export const DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES: CustomHotkeyScopes = {
|
export const DEFAULT_HOTKEYS_SCOPE_CUSTOM_SCOPES: CustomHotkeyScopes = {
|
||||||
commandMenu: true,
|
commandMenu: true,
|
||||||
goto: false,
|
goto: false,
|
||||||
|
|||||||
@ -1,103 +0,0 @@
|
|||||||
import { useHotkeysContext } from 'react-hotkeys-hook';
|
|
||||||
import { useRecoilCallback } from 'recoil';
|
|
||||||
|
|
||||||
import { internalHotkeysEnabledScopesState } from '../../states/internal/internalHotkeysEnabledScopesState';
|
|
||||||
|
|
||||||
export function useHotkeyScopes() {
|
|
||||||
const { disableScope, enableScope } = useHotkeysContext();
|
|
||||||
|
|
||||||
const disableAllHotkeyScopes = useRecoilCallback(
|
|
||||||
({ set, snapshot }) => {
|
|
||||||
return async () => {
|
|
||||||
const enabledScopes = await snapshot.getPromise(
|
|
||||||
internalHotkeysEnabledScopesState,
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const enabledScope of enabledScopes) {
|
|
||||||
disableScope(enabledScope);
|
|
||||||
}
|
|
||||||
|
|
||||||
set(internalHotkeysEnabledScopesState, []);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
[disableScope],
|
|
||||||
);
|
|
||||||
|
|
||||||
const enableHotkeyScope = useRecoilCallback(
|
|
||||||
({ set, snapshot }) => {
|
|
||||||
return async (scopeToEnable: string) => {
|
|
||||||
const enabledScopes = await snapshot.getPromise(
|
|
||||||
internalHotkeysEnabledScopesState,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!enabledScopes.includes(scopeToEnable)) {
|
|
||||||
enableScope(scopeToEnable);
|
|
||||||
set(internalHotkeysEnabledScopesState, [
|
|
||||||
...enabledScopes,
|
|
||||||
scopeToEnable,
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
[enableScope],
|
|
||||||
);
|
|
||||||
|
|
||||||
const disableHotkeyScope = useRecoilCallback(
|
|
||||||
({ set, snapshot }) => {
|
|
||||||
return async (scopeToDisable: string) => {
|
|
||||||
const enabledScopes = await snapshot.getPromise(
|
|
||||||
internalHotkeysEnabledScopesState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const scopeToRemoveIndex = enabledScopes.findIndex(
|
|
||||||
(scope) => scope === scopeToDisable,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (scopeToRemoveIndex > -1) {
|
|
||||||
disableScope(scopeToDisable);
|
|
||||||
|
|
||||||
enabledScopes.splice(scopeToRemoveIndex);
|
|
||||||
|
|
||||||
set(internalHotkeysEnabledScopesState, enabledScopes);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
[disableScope],
|
|
||||||
);
|
|
||||||
|
|
||||||
const setHotkeyScopes = useRecoilCallback(
|
|
||||||
({ set, snapshot }) => {
|
|
||||||
return async (scopesToSet: string[]) => {
|
|
||||||
const enabledScopes = await snapshot.getPromise(
|
|
||||||
internalHotkeysEnabledScopesState,
|
|
||||||
);
|
|
||||||
|
|
||||||
const scopesToDisable = enabledScopes.filter(
|
|
||||||
(enabledScope) => !scopesToSet.includes(enabledScope),
|
|
||||||
);
|
|
||||||
|
|
||||||
const scopesToEnable = scopesToSet.filter(
|
|
||||||
(scopeToSet) => !enabledScopes.includes(scopeToSet),
|
|
||||||
);
|
|
||||||
|
|
||||||
for (const scopeToDisable of scopesToDisable) {
|
|
||||||
disableScope(scopeToDisable);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const scopeToEnable of scopesToEnable) {
|
|
||||||
enableScope(scopeToEnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
set(internalHotkeysEnabledScopesState, scopesToSet);
|
|
||||||
};
|
|
||||||
},
|
|
||||||
[disableScope, enableScope],
|
|
||||||
);
|
|
||||||
|
|
||||||
return {
|
|
||||||
disableAllHotkeyScopes,
|
|
||||||
enableHotkeyScope,
|
|
||||||
disableHotkeyScope,
|
|
||||||
setHotkeyScopes,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { HotkeyScope } from '../types/HotkeyScope';
|
|
||||||
|
|
||||||
export function isSameHotkeyScope(
|
|
||||||
hotkeyScope1: HotkeyScope | undefined | null,
|
|
||||||
hotkeyScope2: HotkeyScope | undefined | null,
|
|
||||||
): boolean {
|
|
||||||
return JSON.stringify(hotkeyScope1) === JSON.stringify(hotkeyScope2);
|
|
||||||
}
|
|
||||||
@ -1,12 +0,0 @@
|
|||||||
import { useLocation } from 'react-router-dom';
|
|
||||||
import { useRecoilValue } from 'recoil';
|
|
||||||
|
|
||||||
import { currentPageLocationState } from '../states/currentPageLocationState';
|
|
||||||
|
|
||||||
export function useIsPageLoading() {
|
|
||||||
const currentLocation = useLocation().pathname;
|
|
||||||
|
|
||||||
const currentPageLocation = useRecoilValue(currentPageLocationState);
|
|
||||||
|
|
||||||
return currentLocation !== currentPageLocation;
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
import { RecoilState, Snapshot } from 'recoil';
|
|
||||||
|
|
||||||
export function getSnapshotScopedState<T>({
|
|
||||||
snapshot,
|
|
||||||
state,
|
|
||||||
contextScopeId,
|
|
||||||
}: {
|
|
||||||
snapshot: Snapshot;
|
|
||||||
state: (scopeId: string) => RecoilState<T>;
|
|
||||||
contextScopeId: string;
|
|
||||||
}) {
|
|
||||||
return snapshot.getLoadable(state(contextScopeId)).valueOrThrow();
|
|
||||||
}
|
|
||||||
@ -1,11 +0,0 @@
|
|||||||
import { RecoilState, Snapshot } from 'recoil';
|
|
||||||
|
|
||||||
export function getSnapshotState<T>({
|
|
||||||
snapshot,
|
|
||||||
state,
|
|
||||||
}: {
|
|
||||||
snapshot: Snapshot;
|
|
||||||
state: RecoilState<T>;
|
|
||||||
}) {
|
|
||||||
return snapshot.getLoadable(state).valueOrThrow();
|
|
||||||
}
|
|
||||||
@ -7,9 +7,10 @@ import { stringToHslColor } from '~/utils/string-to-hsl';
|
|||||||
import { getImageAbsoluteURIOrBase64 } from '../utils/getProfilePictureAbsoluteURI';
|
import { getImageAbsoluteURIOrBase64 } from '../utils/getProfilePictureAbsoluteURI';
|
||||||
|
|
||||||
export type AvatarType = 'squared' | 'rounded';
|
export type AvatarType = 'squared' | 'rounded';
|
||||||
|
|
||||||
export type AvatarSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
export type AvatarSize = 'xl' | 'lg' | 'md' | 'sm' | 'xs';
|
||||||
|
|
||||||
type OwnProps = {
|
export type AvatarProps = {
|
||||||
avatarUrl: string | null | undefined;
|
avatarUrl: string | null | undefined;
|
||||||
size: AvatarSize;
|
size: AvatarSize;
|
||||||
placeholder: string;
|
placeholder: string;
|
||||||
@ -17,7 +18,7 @@ type OwnProps = {
|
|||||||
type?: AvatarType;
|
type?: AvatarType;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const StyledAvatar = styled.div<OwnProps & { colorId: string }>`
|
const StyledAvatar = styled.div<AvatarProps & { colorId: string }>`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
background-color: ${({ avatarUrl, colorId }) =>
|
background-color: ${({ avatarUrl, colorId }) =>
|
||||||
!isNonEmptyString(avatarUrl) ? stringToHslColor(colorId, 75, 85) : 'none'};
|
!isNonEmptyString(avatarUrl) ? stringToHslColor(colorId, 75, 85) : 'none'};
|
||||||
@ -86,7 +87,7 @@ export function Avatar({
|
|||||||
placeholder,
|
placeholder,
|
||||||
colorId = placeholder,
|
colorId = placeholder,
|
||||||
type = 'squared',
|
type = 'squared',
|
||||||
}: OwnProps) {
|
}: AvatarProps) {
|
||||||
const noAvatarUrl = !isNonEmptyString(avatarUrl);
|
const noAvatarUrl = !isNonEmptyString(avatarUrl);
|
||||||
const [isInvalidAvatarUrl, setIsInvalidAvatarUrl] = useState(false);
|
const [isInvalidAvatarUrl, setIsInvalidAvatarUrl] = useState(false);
|
||||||
|
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { EntityChip } from '@/ui/chip/components/EntityChip';
|
import { EntityChip } from '@/ui/chip/components/EntityChip';
|
||||||
|
|
||||||
export type UserChipPropsType = {
|
export type UserChipProps = {
|
||||||
id: string;
|
id: string;
|
||||||
name: string;
|
name: string;
|
||||||
pictureUrl?: string;
|
pictureUrl?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function UserChip({ id, name, pictureUrl }: UserChipPropsType) {
|
export function UserChip({ id, name, pictureUrl }: UserChipProps) {
|
||||||
return (
|
return (
|
||||||
<EntityChip
|
<EntityChip
|
||||||
entityId={id}
|
entityId={id}
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { Entity } from '@/ui/input/relation-picker/types/EntityTypeForSelect';
|
|||||||
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/ui/utilities/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { useSearchUserQuery } from '~/generated/graphql';
|
import { useSearchUserQuery } from '~/generated/graphql';
|
||||||
|
|
||||||
export type OwnProps = {
|
export type UserPickerProps = {
|
||||||
userId: string;
|
userId: string;
|
||||||
onSubmit: (newUser: EntityForSelect | null) => void;
|
onSubmit: (newUser: EntityForSelect | null) => void;
|
||||||
onCancel?: () => void;
|
onCancel?: () => void;
|
||||||
@ -17,7 +17,12 @@ type UserForSelect = EntityForSelect & {
|
|||||||
entityType: Entity.User;
|
entityType: Entity.User;
|
||||||
};
|
};
|
||||||
|
|
||||||
export function UserPicker({ userId, onSubmit, onCancel, width }: OwnProps) {
|
export function UserPicker({
|
||||||
|
userId,
|
||||||
|
onSubmit,
|
||||||
|
onCancel,
|
||||||
|
width,
|
||||||
|
}: UserPickerProps) {
|
||||||
const [searchFilter] = useRecoilScopedState(
|
const [searchFilter] = useRecoilScopedState(
|
||||||
relationPickerSearchFilterScopedState,
|
relationPickerSearchFilterScopedState,
|
||||||
);
|
);
|
||||||
|
|||||||
@ -29,7 +29,7 @@ const DEFAULT_VIEW_FIELD_METADATA: ViewFieldTextMetadata = {
|
|||||||
fieldName: '',
|
fieldName: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const toViewFieldInput = (
|
const toViewFieldInput = (
|
||||||
objectName: 'company' | 'person',
|
objectName: 'company' | 'person',
|
||||||
viewFieldDefinition: ViewFieldDefinition<ViewFieldMetadata>,
|
viewFieldDefinition: ViewFieldDefinition<ViewFieldMetadata>,
|
||||||
) => ({
|
) => ({
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { Decorator } from '@storybook/react';
|
import { Decorator } from '@storybook/react';
|
||||||
|
|
||||||
const ColumnTitle = styled.h1`
|
const StyledColumnTitle = styled.h1`
|
||||||
font-size: ${({ theme }) => theme.font.size.lg};
|
font-size: ${({ theme }) => theme.font.size.lg};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||||
margin: ${({ theme }) => theme.spacing(2)};
|
margin: ${({ theme }) => theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RowsTitle = styled.h2`
|
const StyledRowsTitle = styled.h2`
|
||||||
color: ${({ theme }) => theme.font.color.secondary};
|
color: ${({ theme }) => theme.font.color.secondary};
|
||||||
font-size: ${({ theme }) => theme.font.size.md};
|
font-size: ${({ theme }) => theme.font.size.md};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||||
@ -15,7 +15,7 @@ const RowsTitle = styled.h2`
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RowTitle = styled.h3`
|
const StyledRowTitle = styled.h3`
|
||||||
color: ${({ theme }) => theme.font.color.tertiary};
|
color: ${({ theme }) => theme.font.color.tertiary};
|
||||||
font-size: ${({ theme }) => theme.font.size.md};
|
font-size: ${({ theme }) => theme.font.size.md};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||||
@ -23,7 +23,7 @@ const RowTitle = styled.h3`
|
|||||||
width: 100px;
|
width: 100px;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ElementTitle = styled.span`
|
const StyledElementTitle = styled.span`
|
||||||
color: ${({ theme }) => theme.font.color.light};
|
color: ${({ theme }) => theme.font.color.light};
|
||||||
font-size: ${({ theme }) => theme.font.size.xs};
|
font-size: ${({ theme }) => theme.font.size.xs};
|
||||||
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
font-weight: ${({ theme }) => theme.font.weight.semiBold};
|
||||||
@ -37,30 +37,30 @@ const StyledContainer = styled.div`
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const ColumnContainer = styled.div`
|
const StyledColumnContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: ${({ theme }) => theme.spacing(2)};
|
padding: ${({ theme }) => theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RowsContainer = styled.div`
|
const StyledRowsContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const RowContainer = styled.div`
|
const StyledRowContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex: 1;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
gap: ${({ theme }) => theme.spacing(2)};
|
gap: ${({ theme }) => theme.spacing(2)};
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const ElementContainer = styled.div`
|
const StyledElementContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export const CellContainer = styled.div`
|
const StyledCellContainer = styled.div`
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@ -87,29 +87,37 @@ export const CatalogDecorator: Decorator = (Story, context) => {
|
|||||||
return (
|
return (
|
||||||
<StyledContainer>
|
<StyledContainer>
|
||||||
{variable4.values.map((value4: string) => (
|
{variable4.values.map((value4: string) => (
|
||||||
<ColumnContainer key={value4}>
|
<StyledColumnContainer key={value4}>
|
||||||
{(variable4.labels?.(value4) || value4) && (
|
{(variable4.labels?.(value4) || value4) && (
|
||||||
<ColumnTitle>{variable4.labels?.(value4) || value4}</ColumnTitle>
|
<StyledColumnTitle>
|
||||||
|
{variable4.labels?.(value4) || value4}
|
||||||
|
</StyledColumnTitle>
|
||||||
)}
|
)}
|
||||||
{variable3.values.map((value3: string) => (
|
{variable3.values.map((value3: string) => (
|
||||||
<RowsContainer key={value3}>
|
<StyledRowsContainer key={value3}>
|
||||||
{(variable3.labels?.(value3) || value3) && (
|
{(variable3.labels?.(value3) || value3) && (
|
||||||
<RowsTitle>{variable3.labels?.(value3) || value3}</RowsTitle>
|
<StyledRowsTitle>
|
||||||
|
{variable3.labels?.(value3) || value3}
|
||||||
|
</StyledRowsTitle>
|
||||||
)}
|
)}
|
||||||
{variable2.values.map((value2: string) => (
|
{variable2.values.map((value2: string) => (
|
||||||
<RowContainer key={value2}>
|
<StyledRowContainer key={value2}>
|
||||||
{(variable2.labels?.(value2) || value2) && (
|
{(variable2.labels?.(value2) || value2) && (
|
||||||
<RowTitle>{variable2.labels?.(value2) || value2}</RowTitle>
|
<StyledRowTitle>
|
||||||
|
{variable2.labels?.(value2) || value2}
|
||||||
|
</StyledRowTitle>
|
||||||
)}
|
)}
|
||||||
{variable1.values.map((value1: string) => (
|
{variable1.values.map((value1: string) => (
|
||||||
<CellContainer key={value1} id={value1}>
|
<StyledCellContainer key={value1} id={value1}>
|
||||||
{(variable1.labels?.(value1) || value1) && (
|
{(variable1.labels?.(value1) || value1) && (
|
||||||
<ElementTitle>
|
<StyledElementTitle>
|
||||||
{variable1.labels?.(value1) || value1}
|
{variable1.labels?.(value1) || value1}
|
||||||
</ElementTitle>
|
</StyledElementTitle>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<ElementContainer {...options?.elementContainer}>
|
<StyledElementContainer
|
||||||
|
{...options?.StyledelementContainer}
|
||||||
|
>
|
||||||
<Story
|
<Story
|
||||||
args={{
|
args={{
|
||||||
...context.args,
|
...context.args,
|
||||||
@ -119,14 +127,14 @@ export const CatalogDecorator: Decorator = (Story, context) => {
|
|||||||
...variable4.props(value4),
|
...variable4.props(value4),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</ElementContainer>
|
</StyledElementContainer>
|
||||||
</CellContainer>
|
</StyledCellContainer>
|
||||||
))}
|
))}
|
||||||
</RowContainer>
|
</StyledRowContainer>
|
||||||
))}
|
))}
|
||||||
</RowsContainer>
|
</StyledRowsContainer>
|
||||||
))}
|
))}
|
||||||
</ColumnContainer>
|
</StyledColumnContainer>
|
||||||
))}
|
))}
|
||||||
</StyledContainer>
|
</StyledContainer>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
import { Decorator } from '@storybook/react';
|
|
||||||
|
|
||||||
import { ColumnIndexContext } from '../../modules/ui/table/contexts/ColumnIndexContext';
|
|
||||||
import { RowIndexContext } from '../../modules/ui/table/contexts/RowIndexContext';
|
|
||||||
|
|
||||||
export const CellPositionDecorator: Decorator = (Story) => (
|
|
||||||
<RowIndexContext.Provider value={1}>
|
|
||||||
<ColumnIndexContext.Provider value={1}>
|
|
||||||
<Story />
|
|
||||||
</ColumnIndexContext.Provider>
|
|
||||||
</RowIndexContext.Provider>
|
|
||||||
);
|
|
||||||
Reference in New Issue
Block a user