Use FieldDefinition for company show page (#1171)

* Use FieldDefinition for company show page

* removing console.log

* fix conflicts

* fix address placeholder + company show page field definition ordering

* fix story

* add replacePlaceholder

* use AppPath enum in stories

* add routeParams

* fix people input story
This commit is contained in:
Weiko
2023-08-11 14:31:52 -07:00
committed by GitHub
parent 3978ef4edb
commit 4eb4d1488c
43 changed files with 463 additions and 478 deletions

View File

@ -1,46 +0,0 @@
import { EditableField } from '@/ui/editable-field/components/EditableField';
import { FieldContext } from '@/ui/editable-field/states/FieldContext';
import { IconUserCircle } from '@/ui/icon';
import { RelationPickerHotkeyScope } from '@/ui/input/relation-picker/types/RelationPickerHotkeyScope';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { UserChip } from '@/users/components/UserChip';
import { Company, User } from '~/generated/graphql';
import { CompanyAccountOwnerPickerFieldEditMode } from './CompanyAccountOwnerPickerFieldEditMode';
type OwnProps = {
company: Pick<Company, 'id' | 'accountOwnerId'> & {
accountOwner?: Pick<User, 'id' | 'displayName' | 'avatarUrl'> | null;
};
};
export function CompanyAccountOwnerEditableField({ company }: OwnProps) {
return (
<RecoilScope SpecificContext={FieldContext}>
<RecoilScope>
<EditableField
customEditHotkeyScope={{
scope: RelationPickerHotkeyScope.RelationPicker,
}}
iconLabel={<IconUserCircle />}
editModeContent={
<CompanyAccountOwnerPickerFieldEditMode company={company} />
}
displayModeContent={
company.accountOwner?.displayName ? (
<UserChip
id={company.accountOwner.id}
name={company.accountOwner?.displayName ?? ''}
pictureUrl={company.accountOwner?.avatarUrl ?? ''}
/>
) : (
<></>
)
}
isDisplayModeContentEmpty={!company.accountOwner}
isDisplayModeFixHeight={true}
/>
</RecoilScope>
</RecoilScope>
);
}

View File

@ -1,47 +0,0 @@
import styled from '@emotion/styled';
import { CompanyAccountOwnerPicker } from '@/companies/components/CompanyAccountOwnerPicker';
import { useEditableField } from '@/ui/editable-field/hooks/useEditableField';
import { Company, User } from '~/generated/graphql';
const StyledContainer = styled.div`
left: 0px;
position: absolute;
top: -8px;
`;
export type OwnProps = {
company: Pick<Company, 'id'> & {
accountOwner?: Pick<User, 'id' | 'displayName'> | null;
};
onSubmit?: () => void;
onCancel?: () => void;
};
export function CompanyAccountOwnerPickerFieldEditMode({
company,
onSubmit,
onCancel,
}: OwnProps) {
const { closeEditableField } = useEditableField();
function handleSubmit() {
closeEditableField();
onSubmit?.();
}
function handleCancel() {
closeEditableField();
onCancel?.();
}
return (
<StyledContainer>
<CompanyAccountOwnerPicker
company={company}
onCancel={handleCancel}
onSubmit={handleSubmit}
/>
</StyledContainer>
);
}

View File

@ -1,65 +0,0 @@
import { useEffect, useState } from 'react';
import { EditableField } from '@/ui/editable-field/components/EditableField';
import { FieldContext } from '@/ui/editable-field/states/FieldContext';
import { IconMap } from '@/ui/icon';
import { TextInputEdit } from '@/ui/input/text/components/TextInputEdit';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { Company, useUpdateOneCompanyMutation } from '~/generated/graphql';
type OwnProps = {
company: Pick<Company, 'id' | 'address'>;
};
export function CompanyAddressEditableField({ company }: OwnProps) {
const [internalValue, setInternalValue] = useState(company.address);
const [updateCompany] = useUpdateOneCompanyMutation();
useEffect(() => {
setInternalValue(company.address);
}, [company.address]);
async function handleChange(newValue: string) {
setInternalValue(newValue);
}
async function handleSubmit() {
await updateCompany({
variables: {
where: {
id: company.id,
},
data: {
address: internalValue ?? '',
},
},
});
}
async function handleCancel() {
setInternalValue(company.address);
}
return (
<RecoilScope SpecificContext={FieldContext}>
<EditableField
onSubmit={handleSubmit}
onCancel={handleCancel}
iconLabel={<IconMap />}
editModeContent={
<TextInputEdit
placeholder={'Address'}
autoFocus
value={internalValue}
onChange={(newValue: string) => {
handleChange(newValue);
}}
/>
}
displayModeContent={internalValue ?? ''}
isDisplayModeContentEmpty={!(internalValue !== '')}
/>
</RecoilScope>
);
}

View File

@ -1,79 +0,0 @@
import { useEffect, useState } from 'react';
import { EditableField } from '@/ui/editable-field/components/EditableField';
import { FieldContext } from '@/ui/editable-field/states/FieldContext';
import { EditableFieldEditModeDate } from '@/ui/editable-field/variants/components/EditableFieldEditModeDate';
import { IconCalendar } from '@/ui/icon';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { Company, useUpdateOneCompanyMutation } from '~/generated/graphql';
import { formatToHumanReadableDate } from '~/utils';
import { parseDate } from '~/utils/date-utils';
type OwnProps = {
company: Pick<Company, 'id' | 'createdAt'>;
};
export function CompanyCreatedAtEditableField({ company }: OwnProps) {
const [internalValue, setInternalValue] = useState(company.createdAt);
const [updateCompany] = useUpdateOneCompanyMutation();
useEffect(() => {
setInternalValue(company.createdAt);
}, [company.createdAt]);
// TODO: refactor change and submit
async function handleChange(newValue: string) {
setInternalValue(newValue);
await updateCompany({
variables: {
where: {
id: company.id,
},
data: {
createdAt: newValue ?? '',
},
},
});
}
async function handleSubmit() {
await updateCompany({
variables: {
where: {
id: company.id,
},
data: {
createdAt: internalValue ?? '',
},
},
});
}
async function handleCancel() {
setInternalValue(company.createdAt);
}
return (
<RecoilScope SpecificContext={FieldContext}>
<EditableField
onSubmit={handleSubmit}
onCancel={handleCancel}
iconLabel={<IconCalendar />}
editModeContent={
<EditableFieldEditModeDate
value={internalValue}
onChange={handleChange}
/>
}
displayModeContent={
internalValue !== ''
? formatToHumanReadableDate(parseDate(internalValue).toJSDate())
: 'No date'
}
isDisplayModeContentEmpty={!(internalValue !== '')}
/>
</RecoilScope>
);
}

View File

@ -1,67 +0,0 @@
import { useEffect, useState } from 'react';
import { EditableField } from '@/ui/editable-field/components/EditableField';
import { FieldDisplayURL } from '@/ui/editable-field/components/FieldDisplayURL';
import { FieldContext } from '@/ui/editable-field/states/FieldContext';
import { IconLink } from '@/ui/icon';
import { TextInputEdit } from '@/ui/input/text/components/TextInputEdit';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { Company, useUpdateOneCompanyMutation } from '~/generated/graphql';
type OwnProps = {
company: Pick<Company, 'id' | 'domainName'>;
};
export function CompanyDomainNameEditableField({ company }: OwnProps) {
const [internalValue, setInternalValue] = useState(company.domainName);
const [updateCompany] = useUpdateOneCompanyMutation();
useEffect(() => {
setInternalValue(company.domainName);
}, [company.domainName]);
async function handleChange(newValue: string) {
setInternalValue(newValue);
}
async function handleSubmit() {
await updateCompany({
variables: {
where: {
id: company.id,
},
data: {
domainName: internalValue ?? '',
},
},
});
}
async function handleCancel() {
setInternalValue(company.domainName);
}
return (
<RecoilScope SpecificContext={FieldContext}>
<EditableField
iconLabel={<IconLink />}
onCancel={handleCancel}
onSubmit={handleSubmit}
editModeContent={
<TextInputEdit
placeholder={'URL'}
autoFocus
value={internalValue}
onChange={(newValue: string) => {
handleChange(newValue);
}}
/>
}
displayModeContent={<FieldDisplayURL URL={internalValue} />}
useEditButton
isDisplayModeContentEmpty={!(internalValue !== '')}
/>
</RecoilScope>
);
}

View File

@ -1,80 +0,0 @@
import { useEffect, useState } from 'react';
import { EditableField } from '@/ui/editable-field/components/EditableField';
import { FieldContext } from '@/ui/editable-field/states/FieldContext';
import { IconUsers } from '@/ui/icon';
import { TextInputEdit } from '@/ui/input/text/components/TextInputEdit';
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
import { Company, useUpdateOneCompanyMutation } from '~/generated/graphql';
import {
canBeCastAsIntegerOrNull,
castAsIntegerOrNull,
} from '~/utils/cast-as-integer-or-null';
type OwnProps = {
company: Pick<Company, 'id' | 'employees'>;
};
export function CompanyEmployeesEditableField({ company }: OwnProps) {
const [internalValue, setInternalValue] = useState(
company.employees?.toString(),
);
const [updateCompany] = useUpdateOneCompanyMutation();
useEffect(() => {
setInternalValue(company.employees?.toString());
}, [company.employees]);
async function handleChange(newValue: string) {
setInternalValue(newValue);
}
async function handleSubmit() {
if (!canBeCastAsIntegerOrNull(internalValue)) {
handleCancel();
return;
}
const valueCastedAsNumberOrNull = castAsIntegerOrNull(internalValue);
await updateCompany({
variables: {
where: {
id: company.id,
},
data: {
employees: valueCastedAsNumberOrNull,
},
},
});
setInternalValue(valueCastedAsNumberOrNull?.toString());
}
async function handleCancel() {
setInternalValue(company.employees?.toString());
}
return (
<RecoilScope SpecificContext={FieldContext}>
<EditableField
onSubmit={handleSubmit}
onCancel={handleCancel}
iconLabel={<IconUsers />}
editModeContent={
<TextInputEdit
placeholder={'Employees'}
autoFocus
value={internalValue ?? ''}
onChange={(newValue: string) => {
handleChange(newValue);
}}
/>
}
displayModeContent={internalValue}
isDisplayModeContentEmpty={!(internalValue && internalValue !== '0')}
/>
</RecoilScope>
);
}

View File

@ -1,5 +1,7 @@
import { gql } from '@apollo/client';
import { useSetRecoilState } from 'recoil';
import { genericEntitiesFamilyState } from '@/ui/editable-field/states/genericEntitiesFamilyState';
import { useGetCompanyQuery } from '~/generated/graphql';
export const GET_COMPANY = gql`
@ -33,5 +35,13 @@ export const GET_COMPANY = gql`
`;
export function useCompanyQuery(id: string) {
return useGetCompanyQuery({ variables: { where: { id } } });
const updateCompanyShowPage = useSetRecoilState(
genericEntitiesFamilyState(id),
);
return useGetCompanyQuery({
variables: { where: { id } },
onCompleted: (data) => {
updateCompanyShowPage(data?.findUniqueCompany);
},
});
}