feat: add Object Edit form (#2090)

Closes #1910
This commit is contained in:
Thaïs
2023-10-17 21:03:59 +02:00
committed by GitHub
parent 54735c4880
commit 8894c52202
7 changed files with 103 additions and 11 deletions

View File

@ -0,0 +1,53 @@
import styled from '@emotion/styled';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { AutosizeTextInput } from '@/ui/input/components/AutosizeTextInput';
import { TextInput } from '@/ui/input/components/TextInput';
import { Section } from '@/ui/layout/section/components/Section';
type SettingsObjectFormSectionProps = {
singularName?: string;
pluralName?: string;
description?: string;
};
const StyledInputsContainer = styled.div`
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
margin-bottom: ${({ theme }) => theme.spacing(2)};
width: 100%;
`;
const StyledTextInput = styled(TextInput)`
flex: 1 0 auto;
`;
export const SettingsObjectFormSection = ({
singularName,
pluralName,
description,
}: SettingsObjectFormSectionProps) => (
<Section>
<H2Title
title="Name and description"
description="Name in both singular (e.g., 'Invoice') and plural (e.g., 'Invoices') forms."
/>
<StyledInputsContainer>
<StyledTextInput
label="Singular"
placeholder="Invoice"
value={singularName}
/>
<StyledTextInput
label="Plural"
placeholder="Invoices"
value={pluralName}
/>
</StyledInputsContainer>
<AutosizeTextInput
placeholder="Write a description"
minRows={4}
value={description}
/>
</Section>
);

View File

@ -0,0 +1,24 @@
import { Meta, StoryObj } from '@storybook/react';
import { ComponentDecorator } from '~/testing/decorators/ComponentDecorator';
import { SettingsObjectFormSection } from '../SettingsObjectFormSection';
const meta: Meta<typeof SettingsObjectFormSection> = {
title: 'Modules/Settings/DataModel/SettingsObjectFormSection',
component: SettingsObjectFormSection,
decorators: [ComponentDecorator],
};
export default meta;
type Story = StoryObj<typeof SettingsObjectFormSection>;
export const Default: Story = {};
export const WithDefaultValues: Story = {
args: {
singularName: 'Company',
pluralName: 'Companies',
description: 'Lorem ipsum',
},
};

View File

@ -20,15 +20,16 @@ import { ObjectFieldItem } from '../types/ObjectFieldItem';
export const activeObjectItems = [
{
name: 'Companies',
singularName: 'company',
singularName: 'Company',
Icon: IconBuildingSkyscraper,
type: 'standard',
fields: 23,
instances: 165,
description: 'Lorem ipsum',
},
{
name: 'People',
singularName: 'person',
singularName: 'Person',
Icon: IconUser,
type: 'standard',
fields: 16,

View File

@ -3,6 +3,7 @@ import styled from '@emotion/styled';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { IconPicker } from '@/ui/input/components/IconPicker';
import { Section } from '@/ui/layout/section/components/Section';
import ArrowRight from '../assets/ArrowRight.svg';
@ -33,7 +34,7 @@ export const SettingsObjectIconSection = ({
setIconPicker,
}: SettingsObjectIconSectionProps) => {
return (
<section>
<Section>
<H2Title
title="Icon"
description="The icon that will be displayed in the sidebar."
@ -50,6 +51,6 @@ export const SettingsObjectIconSection = ({
</StyledArrowContainer>
<SettingsObjectIconWithLabel Icon={Icon} label="Workspaces" />
</StyledContainer>
</section>
</Section>
);
};

View File

@ -13,6 +13,7 @@ import { InputHotkeyScope } from '../types/InputHotkeyScope';
const MAX_ROWS = 5;
export enum AutosizeTextInputVariant {
Default = 'default',
Icon = 'icon',
Button = 'button',
}
@ -24,6 +25,7 @@ type AutosizeTextInputProps = {
onFocus?: () => void;
variant?: AutosizeTextInputVariant;
buttonTitle?: string;
value?: string;
};
const StyledContainer = styled.div`
@ -112,14 +114,15 @@ export const AutosizeTextInput = ({
onValidate,
minRows = 1,
onFocus,
variant = AutosizeTextInputVariant.Icon,
variant = AutosizeTextInputVariant.Default,
buttonTitle,
value = '',
}: AutosizeTextInputProps) => {
const [isFocused, setIsFocused] = useState(false);
const [isHidden, setIsHidden] = useState(
variant === AutosizeTextInputVariant.Button,
);
const [text, setText] = useState('');
const [text, setText] = useState(value);
const isSendButtonDisabled = !text;
const words = text.split(/\s|\n/).filter((word) => word).length;

View File

@ -23,6 +23,7 @@ type TextInputComponentProps = Omit<
InputHTMLAttributes<HTMLInputElement>,
'onChange'
> & {
className?: string;
label?: string;
onChange?: (text: string) => void;
fullWidth?: boolean;
@ -103,6 +104,7 @@ const INPUT_TYPE_PASSWORD = 'password';
const TextInputComponent = (
{
className,
label,
value,
onChange,
@ -160,7 +162,7 @@ const TextInputComponent = (
};
return (
<StyledContainer fullWidth={fullWidth ?? false}>
<StyledContainer className={className} fullWidth={fullWidth ?? false}>
{label && <StyledLabel>{label + (required ? '*' : '')}</StyledLabel>}
<StyledInputContainer>
<StyledInput

View File

@ -2,6 +2,7 @@ import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsObjectFormSection } from '@/settings/data-model/components/SettingsObjectFormSection';
import { activeObjectItems } from '@/settings/data-model/constants/mockObjects';
import { SettingsObjectIconSection } from '@/settings/data-model/object-edit/SettingsObjectIconSection';
import { AppPath } from '@/types/AppPath';
@ -34,10 +35,17 @@ export const SettingsObjectEdit = () => {
]}
/>
{activeObject && (
<SettingsObjectIconSection
Icon={activeObject.Icon}
iconKey={activeObject.Icon.name}
/>
<>
<SettingsObjectIconSection
Icon={activeObject.Icon}
iconKey={activeObject.Icon.name}
/>
<SettingsObjectFormSection
singularName={activeObject.singularName}
pluralName={activeObject.name}
description={activeObject.description}
/>
</>
)}
</SettingsPageContainer>
</SubMenuTopBarContainer>