feat: activate, disable and erase fields in Object Detail (#2200)

* feat: activate and disable objects

Closes #2144, Closes #2148, Closes #2154

* feat: activate, disable and erase fields in Object Detail

Closes #2158

---------

Co-authored-by: Charles Bochet <charlesBochet@users.noreply.github.com>
This commit is contained in:
Thaïs
2023-10-24 08:30:13 +02:00
committed by GitHub
parent 26e8cd76be
commit 291feae595
9 changed files with 206 additions and 12 deletions

View File

@ -0,0 +1,30 @@
import { Field } from '~/generated/graphql';
import { useDeleteOneMetadataField } from './useDeleteOneMetadataField';
import { useUpdateOneMetadataField } from './useUpdateOneMetadataField';
export const useFieldMetadata = () => {
const { updateOneMetadataField } = useUpdateOneMetadataField();
const { deleteOneMetadataField } = useDeleteOneMetadataField();
const activateField = (metadataField: Field) =>
updateOneMetadataField({
fieldIdToUpdate: metadataField.id,
updatePayload: { isActive: true },
});
const disableField = (metadataField: Field) =>
updateOneMetadataField({
fieldIdToUpdate: metadataField.id,
updatePayload: { isActive: false },
});
const eraseField = (metadataField: Field) =>
deleteOneMetadataField(metadataField.id);
return {
activateField,
disableField,
eraseField,
};
};

View File

@ -35,6 +35,7 @@ export const useUpdateOneMetadataField = () => {
variables: { variables: {
idToUpdate: fieldIdToUpdate, idToUpdate: fieldIdToUpdate,
updatePayload: { updatePayload: {
...updatePayload,
label: updatePayload.label ?? undefined, label: updatePayload.label ?? undefined,
}, },
}, },

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 { IconArchiveOff, IconDotsVertical, IconTrash } 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 = ({
isCustomField,
onActivate,
onErase,
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

@ -1,8 +1,7 @@
import { ReactNode } from 'react';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { IconComponent } from '@/ui/display/icon/types/IconComponent';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon'; import { useLazyLoadIcon } from '@/ui/input/hooks/useLazyLoadIcon';
import { TableCell } from '@/ui/layout/table/components/TableCell'; import { TableCell } from '@/ui/layout/table/components/TableCell';
import { TableRow } from '@/ui/layout/table/components/TableRow'; import { TableRow } from '@/ui/layout/table/components/TableRow';
@ -13,7 +12,7 @@ import { ObjectFieldDataType } from '../../types/ObjectFieldDataType';
import { SettingsObjectFieldDataType } from './SettingsObjectFieldDataType'; import { SettingsObjectFieldDataType } from './SettingsObjectFieldDataType';
type SettingsObjectFieldItemTableRowProps = { type SettingsObjectFieldItemTableRowProps = {
ActionIcon: IconComponent; ActionIcon: ReactNode;
fieldItem: Field; fieldItem: Field;
}; };
@ -50,9 +49,7 @@ export const SettingsObjectFieldItemTableRow = ({
value={fieldItem.type as ObjectFieldDataType} value={fieldItem.type as ObjectFieldDataType}
/> />
</TableCell> </TableCell>
<StyledIconTableCell> <StyledIconTableCell>{ActionIcon}</StyledIconTableCell>
<LightIconButton Icon={ActionIcon} accent="tertiary" />
</StyledIconTableCell>
</StyledObjectFieldTableRow> </StyledObjectFieldTableRow>
); );
}; };

View File

@ -19,7 +19,7 @@ export const SettingsObjectDisabledMenuDropDown = ({
onActivate, onActivate,
onErase, onErase,
}: SettingsObjectDisabledMenuDropDownProps) => { }: SettingsObjectDisabledMenuDropDownProps) => {
const dropdownScopeId = scopeKey + '-settings-object-disabled-menu-dropdown'; const dropdownScopeId = `${scopeKey}-settings-object-disabled-menu-dropdown`;
const { closeDropdown } = useDropdown({ dropdownScopeId }); const { closeDropdown } = useDropdown({ dropdownScopeId });

View File

@ -4,6 +4,7 @@ export {
IconAlertCircle, IconAlertCircle,
IconAlertTriangle, IconAlertTriangle,
IconArchive, IconArchive,
IconArchiveOff,
IconArrowBack, IconArrowBack,
IconArrowDown, IconArrowDown,
IconArrowLeft, IconArrowLeft,

View File

@ -2,15 +2,18 @@ import { useEffect } from 'react';
import { useNavigate, useParams } from 'react-router-dom'; import { useNavigate, useParams } from 'react-router-dom';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useFieldMetadata } from '@/metadata/hooks/useFieldMetadata';
import { useObjectMetadata } from '@/metadata/hooks/useObjectMetadata'; import { useObjectMetadata } from '@/metadata/hooks/useObjectMetadata';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer'; import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import { SettingsAboutSection } from '@/settings/data-model/object-details/components/SettingsObjectAboutSection'; import { SettingsAboutSection } from '@/settings/data-model/object-details/components/SettingsObjectAboutSection';
import { SettingsObjectFieldActiveActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldActiveActionDropdown';
import { SettingsObjectFieldDisabledActionDropdown } from '@/settings/data-model/object-details/components/SettingsObjectFieldDisabledActionDropdown';
import { import {
SettingsObjectFieldItemTableRow, SettingsObjectFieldItemTableRow,
StyledObjectFieldTableRow, StyledObjectFieldTableRow,
} from '@/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow'; } from '@/settings/data-model/object-details/components/SettingsObjectFieldItemTableRow';
import { AppPath } from '@/types/AppPath'; import { AppPath } from '@/types/AppPath';
import { IconDotsVertical, IconPlus, IconSettings } from '@/ui/display/icon'; import { IconPlus, IconSettings } from '@/ui/display/icon';
import { H2Title } from '@/ui/display/typography/components/H2Title'; import { H2Title } from '@/ui/display/typography/components/H2Title';
import { Button } from '@/ui/input/button/components/Button'; import { Button } from '@/ui/input/button/components/Button';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'; import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
@ -41,6 +44,7 @@ export const SettingsObjectDetail = () => {
} }
}, [activeObject, activeObjects.length, navigate]); }, [activeObject, activeObjects.length, navigate]);
const { activateField, disableField, eraseField } = useFieldMetadata();
const activeFields = activeObject?.fields.filter( const activeFields = activeObject?.fields.filter(
(fieldItem) => fieldItem.isActive, (fieldItem) => fieldItem.isActive,
); );
@ -89,7 +93,18 @@ export const SettingsObjectDetail = () => {
<SettingsObjectFieldItemTableRow <SettingsObjectFieldItemTableRow
key={fieldItem.id} key={fieldItem.id}
fieldItem={fieldItem} fieldItem={fieldItem}
ActionIcon={IconDotsVertical} ActionIcon={
<SettingsObjectFieldActiveActionDropdown
isCustomField={fieldItem.isCustom}
scopeKey={fieldItem.id}
onEdit={() =>
navigate(
`/settings/objects/${pluralObjectName}/${fieldItem.name}`,
)
}
onDisable={() => disableField(fieldItem)}
/>
}
/> />
))} ))}
</TableSection> </TableSection>
@ -100,7 +115,14 @@ export const SettingsObjectDetail = () => {
<SettingsObjectFieldItemTableRow <SettingsObjectFieldItemTableRow
key={fieldItem.id} key={fieldItem.id}
fieldItem={fieldItem} fieldItem={fieldItem}
ActionIcon={IconDotsVertical} ActionIcon={
<SettingsObjectFieldDisabledActionDropdown
isCustomField={fieldItem.isCustom}
scopeKey={fieldItem.id}
onActivate={() => activateField(fieldItem)}
onErase={() => eraseField(fieldItem)}
/>
}
/> />
))} ))}
</TableSection> </TableSection>

View File

@ -14,6 +14,7 @@ import { AppPath } from '@/types/AppPath';
import { IconMinus, IconPlus, IconSettings } from '@/ui/display/icon'; import { IconMinus, IconPlus, IconSettings } from '@/ui/display/icon';
import { H2Title } from '@/ui/display/typography/components/H2Title'; import { H2Title } from '@/ui/display/typography/components/H2Title';
import { Button } from '@/ui/input/button/components/Button'; import { Button } from '@/ui/input/button/components/Button';
import { LightIconButton } from '@/ui/input/button/components/LightIconButton';
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'; import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
import { Section } from '@/ui/layout/section/components/Section'; import { Section } from '@/ui/layout/section/components/Section';
import { Table } from '@/ui/layout/table/components/Table'; import { Table } from '@/ui/layout/table/components/Table';
@ -93,7 +94,9 @@ export const SettingsObjectNewFieldStep1 = () => {
<SettingsObjectFieldItemTableRow <SettingsObjectFieldItemTableRow
key={fieldItem.id} key={fieldItem.id}
fieldItem={fieldItem} fieldItem={fieldItem}
ActionIcon={IconMinus} ActionIcon={
<LightIconButton Icon={IconMinus} accent="tertiary" />
}
/> />
))} ))}
</TableSection> </TableSection>
@ -104,7 +107,9 @@ export const SettingsObjectNewFieldStep1 = () => {
<SettingsObjectFieldItemTableRow <SettingsObjectFieldItemTableRow
key={fieldItem.name} key={fieldItem.name}
fieldItem={fieldItem} fieldItem={fieldItem}
ActionIcon={IconPlus} ActionIcon={
<LightIconButton Icon={IconPlus} accent="tertiary" />
}
/> />
))} ))}
</TableSection> </TableSection>