Migrate to a monorepo structure (#2909)

This commit is contained in:
Charles Bochet
2023-12-10 18:10:54 +01:00
committed by GitHub
parent a70a9281eb
commit 5bdca9de6c
2304 changed files with 37152 additions and 25869 deletions

View File

@ -0,0 +1,111 @@
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconArchive, IconDotsVertical, IconPencil } from '@/ui/display/icon';
import { Tag } from '@/ui/display/tag/components/Tag';
import { H2Title } from '@/ui/display/typography/components/H2Title';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { Card } from '@/ui/layout/card/components/Card';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { Section } from '@/ui/layout/section/components/Section';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
type SettingsAboutSectionProps = {
iconKey?: string;
isCustom: boolean;
name: string;
onDisable: () => void;
onEdit: () => void;
};
const StyledCard = styled(Card)`
align-items: center;
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
padding: ${({ theme }) => theme.spacing(2)};
`;
const StyledName = styled.div`
color: ${({ theme }) => theme.font.color.primary};
display: flex;
gap: ${({ theme }) => theme.spacing(2)};
margin-right: auto;
`;
const StyledTag = styled(Tag)`
box-sizing: border-box;
height: ${({ theme }) => theme.spacing(6)};
`;
const dropdownScopeId = 'settings-object-edit-about-menu-dropdown';
export const SettingsAboutSection = ({
iconKey = '',
isCustom,
name,
onDisable,
onEdit,
}: SettingsAboutSectionProps) => {
const theme = useTheme();
const { Icon } = useLazyLoadIcon(iconKey);
const { closeDropdown } = useDropdown({ dropdownScopeId });
const handleEdit = () => {
onEdit();
closeDropdown();
};
const handleDisable = () => {
onDisable();
closeDropdown();
};
return (
<Section>
<H2Title title="About" description="Manage your object" />
<StyledCard>
<StyledName>
{!!Icon && <Icon size={theme.icon.size.md} />}
{name}
</StyledName>
{isCustom ? (
<StyledTag color="orange" text="Custom" />
) : (
<StyledTag color="blue" text="Standard" />
)}
<DropdownScope dropdownScopeId={dropdownScopeId}>
<Dropdown
clickableComponent={
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
}
dropdownComponents={
<DropdownMenu width="160px">
<DropdownMenuItemsContainer>
<MenuItem
text="Edit"
LeftIcon={IconPencil}
onClick={handleEdit}
/>
<MenuItem
text="Disable"
LeftIcon={IconArchive}
onClick={handleDisable}
/>
</DropdownMenuItemsContainer>
</DropdownMenu>
}
dropdownHotkeyScope={{
scope: dropdownScopeId,
}}
/>
</DropdownScope>
</StyledCard>
</Section>
);
};

View File

@ -0,0 +1,70 @@
import {
IconArchive,
IconDotsVertical,
IconEye,
IconPencil,
} from '@/ui/display/icon';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
type SettingsObjectFieldActiveActionDropdownProps = {
isCustomField?: boolean;
onDisable: () => void;
onEdit: () => void;
scopeKey: string;
};
export const SettingsObjectFieldActiveActionDropdown = ({
isCustomField,
onDisable,
onEdit,
scopeKey,
}: SettingsObjectFieldActiveActionDropdownProps) => {
const dropdownScopeId = `${scopeKey}-settings-field-active-action-dropdown`;
const { closeDropdown } = useDropdown({ dropdownScopeId });
const handleEdit = () => {
onEdit();
closeDropdown();
};
const handleDisable = () => {
onDisable();
closeDropdown();
};
return (
<DropdownScope dropdownScopeId={dropdownScopeId}>
<Dropdown
clickableComponent={
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
}
dropdownComponents={
<DropdownMenu width="160px">
<DropdownMenuItemsContainer>
<MenuItem
text={isCustomField ? 'Edit' : 'View'}
LeftIcon={isCustomField ? IconPencil : IconEye}
onClick={handleEdit}
/>
<MenuItem
text="Disable"
LeftIcon={IconArchive}
onClick={handleDisable}
/>
</DropdownMenuItemsContainer>
</DropdownMenu>
}
dropdownHotkeyScope={{
scope: dropdownScopeId,
}}
/>
</DropdownScope>
);
};

View File

@ -0,0 +1,68 @@
import { css, useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { IconTwentyStar } from '@/ui/display/icon/components/IconTwentyStar';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { FieldMetadataType } from '~/generated-metadata/graphql';
import { settingsFieldMetadataTypes } from '../../constants/settingsFieldMetadataTypes';
type SettingsObjectFieldDataTypeProps = {
onClick?: () => void;
Icon?: IconComponent;
label?: string;
value: FieldMetadataType;
};
const StyledDataType = styled.div<{ value: FieldMetadataType }>`
align-items: center;
border: 1px solid transparent;
border-radius: ${({ theme }) => theme.border.radius.sm};
display: flex;
font-size: ${({ theme }) => theme.font.size.sm};
gap: ${({ theme }) => theme.spacing(1)};
height: 20px;
overflow: hidden;
padding: 0 ${({ theme }) => theme.spacing(2)};
${({ onClick }) =>
onClick
? css`
cursor: pointer;
`
: ''}
${({ theme, value }) =>
value === FieldMetadataType.Relation
? css`
border-color: ${theme.color.purple20};
color: ${theme.color.purple};
`
: ''}
`;
const StyledLabelContainer = styled.div`
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
`;
export const SettingsObjectFieldDataType = ({
onClick,
value,
Icon = settingsFieldMetadataTypes[value]?.Icon ?? IconTwentyStar,
label = settingsFieldMetadataTypes[value]?.label,
}: SettingsObjectFieldDataTypeProps) => {
const theme = useTheme();
const StyledIcon = styled(Icon)`
flex: 1 0 auto;
`;
return (
<StyledDataType onClick={onClick} value={value}>
<StyledIcon size={theme.icon.size.sm} />
<StyledLabelContainer>{label}</StyledLabelContainer>
</StyledDataType>
);
};

View File

@ -0,0 +1,66 @@
import { IconArchiveOff, IconDotsVertical } from '@/ui/display/icon';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { Dropdown } from '@/ui/layout/dropdown/components/Dropdown';
import { DropdownMenu } from '@/ui/layout/dropdown/components/DropdownMenu';
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { DropdownScope } from '@/ui/layout/dropdown/scopes/DropdownScope';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
type SettingsObjectFieldDisabledActionDropdownProps = {
isCustomField?: boolean;
onActivate: () => void;
onErase: () => void;
scopeKey: string;
};
export const SettingsObjectFieldDisabledActionDropdown = ({
onActivate,
scopeKey,
}: SettingsObjectFieldDisabledActionDropdownProps) => {
const dropdownScopeId = `${scopeKey}-settings-field-disabled-action-dropdown`;
const { closeDropdown } = useDropdown({ dropdownScopeId });
const handleActivate = () => {
onActivate();
closeDropdown();
};
// const handleErase = () => {
// onErase();
// closeDropdown();
// };
return (
<DropdownScope dropdownScopeId={dropdownScopeId}>
<Dropdown
clickableComponent={
<LightIconButton Icon={IconDotsVertical} accent="tertiary" />
}
dropdownComponents={
<DropdownMenu width="160px">
<DropdownMenuItemsContainer>
<MenuItem
text="Activate"
LeftIcon={IconArchiveOff}
onClick={handleActivate}
/>
{/* {isCustomField && (
<MenuItem
text="Erase"
accent="danger"
LeftIcon={IconTrash}
onClick={handleErase}
/>
)} */}
</DropdownMenuItemsContainer>
</DropdownMenu>
}
dropdownHotkeyScope={{
scope: dropdownScopeId,
}}
/>
</DropdownScope>
);
};

View File

@ -0,0 +1,89 @@
import { ReactNode } from 'react';
import { useNavigate } from 'react-router-dom';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useRelationMetadata } from '@/object-metadata/hooks/useRelationMetadata';
import { FieldMetadataItem } from '@/object-metadata/types/FieldMetadataItem';
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
import { relationTypes } from '../../constants/relationTypes';
import { settingsFieldMetadataTypes } from '../../constants/settingsFieldMetadataTypes';
import { SettingsObjectFieldDataType } from './SettingsObjectFieldDataType';
type SettingsObjectFieldItemTableRowProps = {
ActionIcon: ReactNode;
fieldMetadataItem: FieldMetadataItem;
};
export const StyledObjectFieldTableRow = styled(TableRow)`
grid-template-columns: 180px 148px 148px 36px;
`;
const StyledNameTableCell = styled(TableCell)`
color: ${({ theme }) => theme.font.color.primary};
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledIconTableCell = styled(TableCell)`
justify-content: center;
padding-right: ${({ theme }) => theme.spacing(1)};
`;
export const SettingsObjectFieldItemTableRow = ({
ActionIcon,
fieldMetadataItem: fieldMetadataItem,
}: SettingsObjectFieldItemTableRowProps) => {
const theme = useTheme();
const { Icon } = useLazyLoadIcon(fieldMetadataItem.icon ?? '');
const navigate = useNavigate();
// TODO: parse with zod and merge types with FieldType (create a subset of FieldType for example)
const fieldDataTypeIsSupported =
fieldMetadataItem.type in settingsFieldMetadataTypes;
const { relationObjectMetadataItem, relationType } = useRelationMetadata({
fieldMetadataItem,
});
if (!fieldDataTypeIsSupported) return null;
const RelationIcon = relationType
? relationTypes[relationType].Icon
: undefined;
return (
<StyledObjectFieldTableRow>
<StyledNameTableCell>
{!!Icon && <Icon size={theme.icon.size.md} />}
{fieldMetadataItem.label}
</StyledNameTableCell>
<TableCell>
{fieldMetadataItem.isCustom ? 'Custom' : 'Standard'}
</TableCell>
<TableCell>
<SettingsObjectFieldDataType
Icon={RelationIcon}
label={relationObjectMetadataItem?.labelPlural}
onClick={
relationObjectMetadataItem?.namePlural &&
!relationObjectMetadataItem.isSystem
? () =>
navigate(
`/settings/objects/${getObjectSlug(
relationObjectMetadataItem,
)}`,
)
: undefined
}
value={fieldMetadataItem.type}
/>
</TableCell>
<StyledIconTableCell>{ActionIcon}</StyledIconTableCell>
</StyledObjectFieldTableRow>
);
};

View File

@ -0,0 +1,65 @@
import { ReactNode } from 'react';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
import { useFindManyRecords } from '@/object-record/hooks/useFindManyRecords';
import { Tag } from '@/ui/display/tag/components/Tag';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow';
type SettingsObjectItemTableRowProps = {
action: ReactNode;
objectItem: ObjectMetadataItem;
onClick?: () => void;
};
export const StyledObjectTableRow = styled(TableRow)`
grid-template-columns: 180px 98.7px 98.7px 98.7px 36px;
`;
const StyledNameTableCell = styled(TableCell)`
color: ${({ theme }) => theme.font.color.primary};
gap: ${({ theme }) => theme.spacing(2)};
`;
const StyledActionTableCell = styled(TableCell)`
justify-content: center;
padding-right: ${({ theme }) => theme.spacing(1)};
`;
export const SettingsObjectItemTableRow = ({
action,
objectItem,
onClick,
}: SettingsObjectItemTableRowProps) => {
const theme = useTheme();
const { records } = useFindManyRecords({
objectNameSingular: objectItem.nameSingular,
});
const { Icon } = useLazyLoadIcon(objectItem.icon ?? '');
return (
<StyledObjectTableRow key={objectItem.namePlural} onClick={onClick}>
<StyledNameTableCell>
{!!Icon && <Icon size={theme.icon.size.md} />}
{objectItem.labelPlural}
</StyledNameTableCell>
<TableCell>
{objectItem.isCustom ? (
<Tag color="orange" text="Custom" />
) : (
<Tag color="blue" text="Standard" />
)}
</TableCell>
<TableCell align="right">
{objectItem.fields.filter((field) => !field.isSystem).length}
</TableCell>
<TableCell align="right">{records.length}</TableCell>
<StyledActionTableCell>{action}</StyledActionTableCell>
</StyledObjectTableRow>
);
};