Bug Fix: company create from people + scroll settings (#545)
This commit is contained in:
@ -12,7 +12,6 @@ export function useHotkeysScopeStackAutoSync() {
|
|||||||
|
|
||||||
const hotkeysScopeStack = useRecoilValue(hotkeysScopeStackState);
|
const hotkeysScopeStack = useRecoilValue(hotkeysScopeStackState);
|
||||||
const customHotkeysScopes = useRecoilValue(customHotkeysScopesState);
|
const customHotkeysScopes = useRecoilValue(customHotkeysScopesState);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (hotkeysScopeStack.length === 0) {
|
if (hotkeysScopeStack.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@ -20,9 +20,7 @@ export function PeopleCompanyCell({ people }: OwnProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<EditableCell
|
<EditableCell
|
||||||
editHotkeysScope={
|
editHotkeysScope={{ scope: InternalHotkeysScope.RelationPicker }}
|
||||||
!isCreating ? { scope: InternalHotkeysScope.RelationPicker } : undefined
|
|
||||||
}
|
|
||||||
editModeContent={
|
editModeContent={
|
||||||
isCreating ? (
|
isCreating ? (
|
||||||
<PeopleCompanyCreateCell people={people} />
|
<PeopleCompanyCreateCell people={people} />
|
||||||
|
|||||||
@ -1,12 +1,10 @@
|
|||||||
import { useRef, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useHotkeys } from 'react-hotkeys-hook';
|
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
|
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
import { relationPickerSearchFilterScopedState } from '@/relation-picker/states/relationPickerSearchFilterScopedState';
|
||||||
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
import { isCreateModeScopedState } from '@/ui/components/editable-cell/states/isCreateModeScopedState';
|
||||||
import { DoubleTextInput } from '@/ui/components/inputs/DoubleTextInput';
|
import { EditableCellDoubleTextEditMode } from '@/ui/components/editable-cell/types/EditableCellDoubleTextEditMode';
|
||||||
import { useListenClickOutsideArrayOfRef } from '@/ui/hooks/useListenClickOutsideArrayOfRef';
|
|
||||||
import { logError } from '@/utils/logs/logError';
|
import { logError } from '@/utils/logs/logError';
|
||||||
import {
|
import {
|
||||||
Person,
|
Person,
|
||||||
@ -31,8 +29,6 @@ export function PeopleCompanyCreateCell({ people }: OwnProps) {
|
|||||||
const [insertCompany] = useInsertCompanyMutation();
|
const [insertCompany] = useInsertCompanyMutation();
|
||||||
const [updatePeople] = useUpdatePeopleMutation();
|
const [updatePeople] = useUpdatePeopleMutation();
|
||||||
|
|
||||||
const containerRef = useRef(null);
|
|
||||||
|
|
||||||
function handleDoubleTextChange(leftValue: string, rightValue: string): void {
|
function handleDoubleTextChange(leftValue: string, rightValue: string): void {
|
||||||
setCompanyDomainName(leftValue);
|
setCompanyDomainName(leftValue);
|
||||||
setCompanyName(rightValue);
|
setCompanyName(rightValue);
|
||||||
@ -65,34 +61,18 @@ export function PeopleCompanyCreateCell({ people }: OwnProps) {
|
|||||||
// TODO: handle error better
|
// TODO: handle error better
|
||||||
logError(error);
|
logError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
setIsCreating(false);
|
setIsCreating(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
useHotkeys(
|
|
||||||
'enter, escape',
|
|
||||||
() => {
|
|
||||||
handleCompanyCreate(companyName, companyDomainName);
|
|
||||||
},
|
|
||||||
{
|
|
||||||
enableOnFormTags: true,
|
|
||||||
enableOnContentEditable: true,
|
|
||||||
preventDefault: true,
|
|
||||||
},
|
|
||||||
[companyName, companyDomainName, handleCompanyCreate],
|
|
||||||
);
|
|
||||||
|
|
||||||
useListenClickOutsideArrayOfRef([containerRef], () => {
|
|
||||||
handleCompanyCreate(companyName, companyDomainName);
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoubleTextInput
|
<EditableCellDoubleTextEditMode
|
||||||
leftValue={companyDomainName}
|
firstValue={companyDomainName}
|
||||||
rightValue={companyName}
|
secondValue={companyName}
|
||||||
leftValuePlaceholder="URL"
|
firstValuePlaceholder="URL"
|
||||||
rightValuePlaceholder="Name"
|
secondValuePlaceholder="Name"
|
||||||
onChange={handleDoubleTextChange}
|
onChange={handleDoubleTextChange}
|
||||||
|
onSubmit={() => handleCompanyCreate(companyName, companyDomainName)}
|
||||||
|
onExit={() => setIsCreating(false)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Key } from 'ts-key-enum';
|
import { Key } from 'ts-key-enum';
|
||||||
|
|
||||||
|
import { useAddToHotkeysScopeStack } from '@/hotkeys/hooks/useAddToHotkeysScopeStack';
|
||||||
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
import { useScopedHotkeys } from '@/hotkeys/hooks/useScopedHotkeys';
|
||||||
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
import { InternalHotkeysScope } from '@/hotkeys/types/internal/InternalHotkeysScope';
|
||||||
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
import { useRecoilScopedState } from '@/recoil-scope/hooks/useRecoilScopedState';
|
||||||
@ -31,6 +32,8 @@ export function PeopleCompanyPicker({ people }: OwnProps) {
|
|||||||
|
|
||||||
const { closeEditableCell } = useEditableCell();
|
const { closeEditableCell } = useEditableCell();
|
||||||
|
|
||||||
|
const addToScopeStack = useAddToHotkeysScopeStack();
|
||||||
|
|
||||||
const companies = useFilteredSearchEntityQuery({
|
const companies = useFilteredSearchEntityQuery({
|
||||||
queryHook: useSearchCompanyQuery,
|
queryHook: useSearchCompanyQuery,
|
||||||
selectedIds: [people.company?.id ?? ''],
|
selectedIds: [people.company?.id ?? ''],
|
||||||
@ -59,6 +62,7 @@ export function PeopleCompanyPicker({ people }: OwnProps) {
|
|||||||
|
|
||||||
function handleCreate() {
|
function handleCreate() {
|
||||||
setIsCreating(true);
|
setIsCreating(true);
|
||||||
|
addToScopeStack({ scope: InternalHotkeysScope.CellDoubleTextInput });
|
||||||
}
|
}
|
||||||
|
|
||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
|
|||||||
@ -15,6 +15,8 @@ type OwnProps = {
|
|||||||
firstValuePlaceholder: string;
|
firstValuePlaceholder: string;
|
||||||
secondValuePlaceholder: string;
|
secondValuePlaceholder: string;
|
||||||
onChange: (firstValue: string, secondValue: string) => void;
|
onChange: (firstValue: string, secondValue: string) => void;
|
||||||
|
onSubmit?: (firstValue: string, secondValue: string) => void;
|
||||||
|
onExit?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
@ -34,6 +36,8 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
firstValuePlaceholder,
|
firstValuePlaceholder,
|
||||||
secondValuePlaceholder,
|
secondValuePlaceholder,
|
||||||
onChange,
|
onChange,
|
||||||
|
onSubmit,
|
||||||
|
onExit,
|
||||||
}: OwnProps) {
|
}: OwnProps) {
|
||||||
const [focusPosition, setFocusPosition] = useState<'left' | 'right'>('left');
|
const [focusPosition, setFocusPosition] = useState<'left' | 'right'>('left');
|
||||||
|
|
||||||
@ -53,6 +57,9 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
() => {
|
() => {
|
||||||
closeCell();
|
closeCell();
|
||||||
moveDown();
|
moveDown();
|
||||||
|
if (onSubmit) {
|
||||||
|
onSubmit(firstValue, secondValue);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellDoubleTextInput,
|
InternalHotkeysScope.CellDoubleTextInput,
|
||||||
[closeCell],
|
[closeCell],
|
||||||
@ -61,6 +68,9 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
useScopedHotkeys(
|
useScopedHotkeys(
|
||||||
Key.Escape,
|
Key.Escape,
|
||||||
() => {
|
() => {
|
||||||
|
if (onExit) {
|
||||||
|
onExit();
|
||||||
|
}
|
||||||
closeCell();
|
closeCell();
|
||||||
},
|
},
|
||||||
InternalHotkeysScope.CellDoubleTextInput,
|
InternalHotkeysScope.CellDoubleTextInput,
|
||||||
@ -74,6 +84,9 @@ export function EditableCellDoubleTextEditMode({
|
|||||||
setFocusPosition('right');
|
setFocusPosition('right');
|
||||||
secondValueInputRef.current?.focus();
|
secondValueInputRef.current?.focus();
|
||||||
} else {
|
} else {
|
||||||
|
if (onExit) {
|
||||||
|
onExit();
|
||||||
|
}
|
||||||
closeCell();
|
closeCell();
|
||||||
moveRight();
|
moveRight();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,58 +0,0 @@
|
|||||||
import { ChangeEvent, useRef } from 'react';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
|
|
||||||
type OwnProps = {
|
|
||||||
leftValue: string;
|
|
||||||
rightValue: string;
|
|
||||||
leftValuePlaceholder: string;
|
|
||||||
rightValuePlaceholder: string;
|
|
||||||
onChange: (leftValue: string, rightValue: string) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
|
||||||
align-items: center;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
|
|
||||||
& > input:last-child {
|
|
||||||
border-left: 1px solid ${({ theme }) => theme.border.color.light};
|
|
||||||
padding-left: ${({ theme }) => theme.spacing(2)};
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledEditInplaceInput = styled.input`
|
|
||||||
height: 18px;
|
|
||||||
width: 45%;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export function DoubleTextInput({
|
|
||||||
leftValue,
|
|
||||||
rightValue,
|
|
||||||
leftValuePlaceholder,
|
|
||||||
rightValuePlaceholder,
|
|
||||||
onChange,
|
|
||||||
}: OwnProps) {
|
|
||||||
const firstValueInputRef = useRef<HTMLInputElement>(null);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StyledContainer>
|
|
||||||
<StyledEditInplaceInput
|
|
||||||
autoFocus
|
|
||||||
placeholder={leftValuePlaceholder}
|
|
||||||
ref={firstValueInputRef}
|
|
||||||
value={leftValue}
|
|
||||||
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
onChange(event.target.value, rightValue);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<StyledEditInplaceInput
|
|
||||||
placeholder={rightValuePlaceholder}
|
|
||||||
ref={firstValueInputRef}
|
|
||||||
value={rightValue}
|
|
||||||
onChange={(event: ChangeEvent<HTMLInputElement>) => {
|
|
||||||
onChange(leftValue, event.target.value);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</StyledContainer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@ -91,12 +91,6 @@ const StyledTableWithHeader = styled.div`
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const StyledTableScrollableContainer = styled.div`
|
|
||||||
flex: 1;
|
|
||||||
height: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
`;
|
|
||||||
|
|
||||||
export function EntityTable<TData extends { id: string }, SortField>({
|
export function EntityTable<TData extends { id: string }, SortField>({
|
||||||
data,
|
data,
|
||||||
columns,
|
columns,
|
||||||
@ -137,7 +131,7 @@ export function EntityTable<TData extends { id: string }, SortField>({
|
|||||||
availableSorts={availableSorts}
|
availableSorts={availableSorts}
|
||||||
onSortsUpdate={onSortsUpdate}
|
onSortsUpdate={onSortsUpdate}
|
||||||
/>
|
/>
|
||||||
<StyledTableScrollableContainer ref={tableBodyRef}>
|
<div ref={tableBodyRef}>
|
||||||
<StyledTable>
|
<StyledTable>
|
||||||
<thead>
|
<thead>
|
||||||
{table.getHeaderGroups().map((headerGroup) => (
|
{table.getHeaderGroups().map((headerGroup) => (
|
||||||
@ -171,7 +165,7 @@ export function EntityTable<TData extends { id: string }, SortField>({
|
|||||||
))}
|
))}
|
||||||
</tbody>
|
</tbody>
|
||||||
</StyledTable>
|
</StyledTable>
|
||||||
</StyledTableScrollableContainer>
|
</div>
|
||||||
</StyledTableWithHeader>
|
</StyledTableWithHeader>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,6 +7,8 @@ const StyledPanel = styled.div`
|
|||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
height: 100%;
|
||||||
|
overflow: auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
|||||||
@ -13,6 +13,7 @@ const StyledContainer = styled.div`
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
padding: ${({ theme }) => theme.spacing(8)};
|
padding: ${({ theme }) => theme.spacing(8)};
|
||||||
|
padding-bottom: ${({ theme }) => theme.spacing(10)};
|
||||||
width: 350px;
|
width: 350px;
|
||||||
> * + * {
|
> * + * {
|
||||||
margin-top: ${({ theme }) => theme.spacing(8)};
|
margin-top: ${({ theme }) => theme.spacing(8)};
|
||||||
@ -33,27 +34,29 @@ export function SettingsProfile() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<NoTopBarContainer>
|
<NoTopBarContainer>
|
||||||
<StyledContainer>
|
<div>
|
||||||
<MainSectionTitle>Profile</MainSectionTitle>
|
<StyledContainer>
|
||||||
<StyledSectionContainer>
|
<MainSectionTitle>Profile</MainSectionTitle>
|
||||||
<SubSectionTitle title="Picture" />
|
<StyledSectionContainer>
|
||||||
<ProfilePictureUploader />
|
<SubSectionTitle title="Picture" />
|
||||||
</StyledSectionContainer>
|
<ProfilePictureUploader />
|
||||||
<StyledSectionContainer>
|
</StyledSectionContainer>
|
||||||
<SubSectionTitle
|
<StyledSectionContainer>
|
||||||
title="Name"
|
<SubSectionTitle
|
||||||
description="Your name as it will be displayed"
|
title="Name"
|
||||||
/>
|
description="Your name as it will be displayed"
|
||||||
<NameFields />
|
/>
|
||||||
</StyledSectionContainer>
|
<NameFields />
|
||||||
<StyledSectionContainer>
|
</StyledSectionContainer>
|
||||||
<SubSectionTitle
|
<StyledSectionContainer>
|
||||||
title="Email"
|
<SubSectionTitle
|
||||||
description="The email associated to your account"
|
title="Email"
|
||||||
/>
|
description="The email associated to your account"
|
||||||
<EmailField />
|
/>
|
||||||
</StyledSectionContainer>
|
<EmailField />
|
||||||
</StyledContainer>
|
</StyledSectionContainer>
|
||||||
|
</StyledContainer>
|
||||||
|
</div>
|
||||||
</NoTopBarContainer>
|
</NoTopBarContainer>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user