feat: soft delete (#6576)
Implement soft delete on standards and custom objects. This is a temporary solution, when we drop `pg_graphql` we should rely on the `softDelete` functions of TypeORM. --------- Co-authored-by: Félix Malfait <felix.malfait@gmail.com> Co-authored-by: Lucas Bordeau <bordeau.lucas@gmail.com>
This commit is contained in:
@ -3,7 +3,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import rehypeStringify from 'rehype-stringify';
|
||||
import remarkParse from 'remark-parse';
|
||||
import remarkRehype from 'remark-rehype';
|
||||
import { H1Title, IconSettings } from 'twenty-ui';
|
||||
import { H1Title, IconRocket } from 'twenty-ui';
|
||||
import { unified } from 'unified';
|
||||
import { visit } from 'unist-util-visit';
|
||||
|
||||
@ -108,7 +108,7 @@ export const Releases = () => {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Releases">
|
||||
<SubMenuTopBarContainer Icon={IconRocket} title="Releases">
|
||||
<SettingsPageContainer>
|
||||
<StyledH1Title title="Releases" />
|
||||
<ScrollWrapper>
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { H1Title, H2Title, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconUserCircle } from 'twenty-ui';
|
||||
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { ChangePassword } from '@/settings/profile/components/ChangePassword';
|
||||
@ -10,14 +9,9 @@ import { ProfilePictureUploader } from '@/settings/profile/components/ProfilePic
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
|
||||
const StyledH1Title = styled(H1Title)`
|
||||
margin-bottom: 0;
|
||||
`;
|
||||
|
||||
export const SettingsProfile = () => (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer Icon={IconUserCircle} title="Profile">
|
||||
<SettingsPageContainer>
|
||||
<StyledH1Title title="Profile" />
|
||||
<Section>
|
||||
<H2Title title="Picture" />
|
||||
<ProfilePictureUploader />
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { H1Title, H2Title, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconSettings } from 'twenty-ui';
|
||||
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { DeleteWorkspace } from '@/settings/profile/components/DeleteWorkspace';
|
||||
@ -9,14 +8,9 @@ import { WorkspaceLogoUploader } from '@/settings/workspace/components/Workspace
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
|
||||
const StyledH1Title = styled(H1Title)`
|
||||
margin-bottom: 0;
|
||||
`;
|
||||
|
||||
export const SettingsWorkspace = () => (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="General">
|
||||
<SettingsPageContainer>
|
||||
<StyledH1Title title="General" />
|
||||
<Section>
|
||||
<H2Title title="Picture" />
|
||||
<WorkspaceLogoUploader />
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useState } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { H1Title, H2Title, IconSettings, IconTrash } from 'twenty-ui';
|
||||
import { H2Title, IconTrash, IconUsers } from 'twenty-ui';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
@ -18,10 +18,6 @@ import { WorkspaceInviteLink } from '@/workspace/components/WorkspaceInviteLink'
|
||||
import { WorkspaceInviteTeam } from '@/workspace/components/WorkspaceInviteTeam';
|
||||
import { WorkspaceMemberCard } from '@/workspace/components/WorkspaceMemberCard';
|
||||
|
||||
const StyledH1Title = styled(H1Title)`
|
||||
margin-bottom: 0;
|
||||
`;
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
align-items: center;
|
||||
display: flex;
|
||||
@ -50,9 +46,8 @@ export const SettingsWorkspaceMembers = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer Icon={IconUsers} title="Members">
|
||||
<SettingsPageContainer>
|
||||
<StyledH1Title title="Members" />
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Invite by email"
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useRecoilValue } from 'recoil';
|
||||
import { H2Title, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconAt } from 'twenty-ui';
|
||||
|
||||
import { ConnectedAccount } from '@/accounts/types/ConnectedAccount';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
@ -14,7 +14,6 @@ import { SettingsAccountsSettingsSection } from '@/settings/accounts/components/
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
|
||||
|
||||
export const SettingsAccounts = () => {
|
||||
@ -37,10 +36,8 @@ export const SettingsAccounts = () => {
|
||||
const isBlocklistEnabled = useIsFeatureEnabled('IS_BLOCKLIST_ENABLED');
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer Icon={IconAt} title="Account">
|
||||
<SettingsPageContainer>
|
||||
<Breadcrumb links={[{ children: 'Accounts' }]} />
|
||||
|
||||
{loading ? (
|
||||
<SettingsAccountLoader />
|
||||
) : (
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
import { IconSettings } from 'twenty-ui';
|
||||
|
||||
import { SettingsAccountsCalendarChannelsContainer } from '@/settings/accounts/components/SettingsAccountsCalendarChannelsContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||
@ -7,11 +5,13 @@ import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { IconCalendarEvent } from 'twenty-ui';
|
||||
|
||||
export const SettingsAccountsCalendars = () => {
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SettingsPageContainer>
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconCalendarEvent}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
@ -21,6 +21,9 @@ export const SettingsAccountsCalendars = () => {
|
||||
{ children: 'Calendars' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<Section>
|
||||
<SettingsAccountsCalendarChannelsContainer />
|
||||
</Section>
|
||||
|
||||
@ -1,20 +1,23 @@
|
||||
import { IconSettings } from 'twenty-ui';
|
||||
|
||||
import { SettingsAccountsMessageChannelsContainer } from '@/settings/accounts/components/SettingsAccountsMessageChannelsContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { IconMail } from 'twenty-ui';
|
||||
|
||||
export const SettingsAccountsEmails = () => (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SettingsPageContainer>
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconMail}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Accounts', href: '/settings/accounts' },
|
||||
{ children: 'Emails' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<Section>
|
||||
<SettingsAccountsMessageChannelsContainer />
|
||||
</Section>
|
||||
|
||||
@ -1,20 +1,23 @@
|
||||
import { IconSettings } from 'twenty-ui';
|
||||
|
||||
import { SettingsNewAccountSection } from '@/settings/accounts/components/SettingsNewAccountSection';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { IconAt } from 'twenty-ui';
|
||||
|
||||
export const SettingsNewAccount = () => {
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SettingsPageContainer>
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconAt}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Accounts', href: '/settings/accounts' },
|
||||
{ children: `New` },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsNewAccountSection />
|
||||
</SettingsPageContainer>
|
||||
</SubMenuTopBarContainer>
|
||||
|
||||
@ -16,12 +16,13 @@ const REVERT_PUBLIC_KEY = 'pk_live_a87fee8c-28c7-494f-99a3-996ff89f9918';
|
||||
export const SettingsCRMMigration = () => {
|
||||
const currentWorkspace = useRecoilValue(currentWorkspaceState);
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconSettings}
|
||||
title={<Breadcrumb links={[{ children: 'Migrate' }]} />}
|
||||
actionButton={<SettingsReadDocumentationButton />}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb links={[{ children: 'Migrate' }]} />
|
||||
<SettingsReadDocumentationButton />
|
||||
</SettingsHeaderContainer>
|
||||
<SettingsHeaderContainer></SettingsHeaderContainer>
|
||||
<Section>
|
||||
<RevertConnect
|
||||
config={{
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { zodResolver } from '@hookform/resolvers/zod';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { H2Title, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconHierarchy2 } from 'twenty-ui';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useCreateOneObjectMetadataItem } from '@/object-metadata/hooks/useCreateOneObjectMetadataItem';
|
||||
@ -70,25 +70,30 @@ export const SettingsNewObject = () => {
|
||||
return (
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
<FormProvider {...formConfig}>
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconHierarchy2}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Objects',
|
||||
href: settingsObjectsPagePath,
|
||||
},
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
actionButton={
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
isCancelDisabled={isSubmitting}
|
||||
onCancel={() => navigate(settingsObjectsPagePath)}
|
||||
onSave={formConfig.handleSubmit(handleSave)}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Objects',
|
||||
href: settingsObjectsPagePath,
|
||||
},
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
isCancelDisabled={isSubmitting}
|
||||
onCancel={() => navigate(settingsObjectsPagePath)}
|
||||
onSave={formConfig.handleSubmit(handleSave)}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<SettingsHeaderContainer></SettingsHeaderContainer>
|
||||
<Section>
|
||||
<H2Title
|
||||
title="About"
|
||||
|
||||
@ -1,12 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { H2Title, IconPlus, IconSettings } from 'twenty-ui';
|
||||
|
||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||
import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
|
||||
import { getDisabledFieldMetadataItems } from '@/object-metadata/utils/getDisabledFieldMetadataItems';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsObjectSummaryCard } from '@/settings/data-model/object-details/components/SettingsObjectSummaryCard';
|
||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
@ -15,7 +10,10 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
|
||||
import styled from '@emotion/styled';
|
||||
import { isNonEmptyArray } from '@sniptt/guards';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { H2Title, IconHierarchy2, IconPlus } from 'twenty-ui';
|
||||
import { SettingsObjectFieldTable } from '~/pages/settings/data-model/SettingsObjectFieldTable';
|
||||
|
||||
const StyledDiv = styled.div`
|
||||
@ -49,14 +47,18 @@ export const SettingsObjectDetailPageContent = ({
|
||||
const shouldDisplayAddFieldButton = !objectMetadataItem.isRemote;
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SettingsPageContainer>
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconHierarchy2}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Objects', href: '/settings/objects' },
|
||||
{ children: objectMetadataItem.labelPlural },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<Section>
|
||||
<H2Title title="About" description="Manage your object" />
|
||||
<SettingsObjectSummaryCard
|
||||
|
||||
@ -5,12 +5,13 @@ import pick from 'lodash.pick';
|
||||
import { useEffect } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { H2Title, IconArchive, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconArchive, IconHierarchy2 } from 'twenty-ui';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
@ -30,7 +31,6 @@ import { Button } from '@/ui/input/button/components/Button';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { RecordFieldValueSelectorContextProvider } from '@/object-record/record-store/contexts/RecordFieldValueSelectorContext';
|
||||
|
||||
const objectEditFormSchema = z
|
||||
.object({})
|
||||
@ -108,22 +108,26 @@ export const SettingsObjectEdit = () => {
|
||||
return (
|
||||
<RecordFieldValueSelectorContextProvider>
|
||||
<FormProvider {...formConfig}>
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconHierarchy2}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Objects',
|
||||
href: settingsObjectsPagePath,
|
||||
},
|
||||
{
|
||||
children: activeObjectMetadataItem.labelPlural,
|
||||
href: `${settingsObjectsPagePath}/${objectSlug}`,
|
||||
},
|
||||
{ children: 'Edit' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Objects',
|
||||
href: settingsObjectsPagePath,
|
||||
},
|
||||
{
|
||||
children: activeObjectMetadataItem.labelPlural,
|
||||
href: `${settingsObjectsPagePath}/${objectSlug}`,
|
||||
},
|
||||
{ children: 'Edit' },
|
||||
]}
|
||||
/>
|
||||
{activeObjectMetadataItem.isCustom && (
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
|
||||
@ -6,7 +6,7 @@ import pick from 'lodash.pick';
|
||||
import { useEffect } from 'react';
|
||||
import { FormProvider, useForm } from 'react-hook-form';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { H2Title, IconArchive, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconArchive, IconHierarchy2 } from 'twenty-ui';
|
||||
import { z } from 'zod';
|
||||
|
||||
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
|
||||
@ -172,19 +172,23 @@ export const SettingsObjectFieldEdit = () => {
|
||||
<RecordFieldValueSelectorContextProvider>
|
||||
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
||||
<FormProvider {...formConfig}>
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconHierarchy2}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Objects', href: '/settings/objects' },
|
||||
{
|
||||
children: activeObjectMetadataItem.labelPlural,
|
||||
href: `/settings/objects/${objectSlug}`,
|
||||
},
|
||||
{ children: activeMetadataField.label },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Objects', href: '/settings/objects' },
|
||||
{
|
||||
children: activeObjectMetadataItem.labelPlural,
|
||||
href: `/settings/objects/${objectSlug}`,
|
||||
},
|
||||
{ children: activeMetadataField.label },
|
||||
]}
|
||||
/>
|
||||
{shouldDisplaySaveAndCancel && (
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
|
||||
@ -5,7 +5,6 @@ import { H2Title, IconPlus, IconSettings } from 'twenty-ui';
|
||||
|
||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
|
||||
import { useFieldMetadataItem } from '@/object-metadata/hooks/useFieldMetadataItem';
|
||||
@ -85,27 +84,31 @@ export const SettingsObjectNewFieldStep1 = () => {
|
||||
if (!activeObjectMetadataItem) return null;
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Objects', href: '/settings/objects' },
|
||||
{
|
||||
children: activeObjectMetadataItem.labelPlural,
|
||||
href: `/settings/objects/${objectSlug}`,
|
||||
},
|
||||
{ children: 'New Field' },
|
||||
]}
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconSettings}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Objects', href: '/settings/objects' },
|
||||
{
|
||||
children: activeObjectMetadataItem.labelPlural,
|
||||
href: `/settings/objects/${objectSlug}`,
|
||||
},
|
||||
{ children: 'New Field' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
actionButton={
|
||||
!activeObjectMetadataItem.isRemote && (
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => navigate(`/settings/objects/${objectSlug}`)}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
{!activeObjectMetadataItem.isRemote && (
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => navigate(`/settings/objects/${objectSlug}`)}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
)}
|
||||
</SettingsHeaderContainer>
|
||||
)
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<StyledSection>
|
||||
<H2Title
|
||||
title="Check deactivated fields"
|
||||
|
||||
@ -1,12 +1,25 @@
|
||||
import { ReactFlowProvider } from 'reactflow';
|
||||
import { IconSettings } from 'twenty-ui';
|
||||
|
||||
import { SettingsDataModelOverview } from '@/settings/data-model/graph-overview/components/SettingsDataModelOverview';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { IconHierarchy2 } from 'twenty-ui';
|
||||
|
||||
export const SettingsObjectOverview = () => {
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconHierarchy2}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Data model', href: '/settings/objects' },
|
||||
{
|
||||
children: 'Overview',
|
||||
},
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<ReactFlowProvider>
|
||||
<SettingsDataModelOverview />
|
||||
</ReactFlowProvider>
|
||||
|
||||
@ -1,19 +1,12 @@
|
||||
import { useTheme } from '@emotion/react';
|
||||
import styled from '@emotion/styled';
|
||||
import {
|
||||
H1Title,
|
||||
H2Title,
|
||||
IconChevronRight,
|
||||
IconPlus,
|
||||
IconSettings,
|
||||
} from 'twenty-ui';
|
||||
import { H2Title, IconChevronRight, IconHierarchy2, IconPlus } from 'twenty-ui';
|
||||
|
||||
import { useDeleteOneObjectMetadataItem } from '@/object-metadata/hooks/useDeleteOneObjectMetadataItem';
|
||||
import { useFilteredObjectMetadataItems } from '@/object-metadata/hooks/useFilteredObjectMetadataItems';
|
||||
import { useUpdateOneObjectMetadataItem } from '@/object-metadata/hooks/useUpdateOneObjectMetadataItem';
|
||||
import { getObjectSlug } from '@/object-metadata/utils/getObjectSlug';
|
||||
import { useCombinedGetTotalCount } from '@/object-record/multiple-objects/hooks/useCombinedGetTotalCount';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import {
|
||||
SettingsObjectMetadataItemTableRow,
|
||||
@ -42,10 +35,6 @@ const StyledIconChevronRight = styled(IconChevronRight)`
|
||||
color: ${({ theme }) => theme.font.color.tertiary};
|
||||
`;
|
||||
|
||||
const StyledH1Title = styled(H1Title)`
|
||||
margin-bottom: 0;
|
||||
`;
|
||||
|
||||
export const SettingsObjects = () => {
|
||||
const theme = useTheme();
|
||||
|
||||
@ -115,19 +104,21 @@ export const SettingsObjects = () => {
|
||||
);
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconHierarchy2}
|
||||
title="Data model"
|
||||
actionButton={
|
||||
<UndecoratedLink to={getSettingsPagePath(SettingsPath.NewObject)}>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title="Add object"
|
||||
accent="blue"
|
||||
size="small"
|
||||
/>
|
||||
</UndecoratedLink>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<StyledH1Title title="Objects" />
|
||||
<UndecoratedLink to={getSettingsPagePath(SettingsPath.NewObject)}>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title="Add object"
|
||||
accent="blue"
|
||||
size="small"
|
||||
/>
|
||||
</UndecoratedLink>
|
||||
</SettingsHeaderContainer>
|
||||
<>
|
||||
<SettingsObjectCoverImage />
|
||||
<Section>
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { H2Title, IconPlus, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconCode, IconPlus } from 'twenty-ui';
|
||||
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsApiKeysTable } from '@/settings/developers/components/SettingsApiKeysTable';
|
||||
import { SettingsReadDocumentationButton } from '@/settings/developers/components/SettingsReadDocumentationButton';
|
||||
@ -9,7 +8,6 @@ import { SettingsWebhooksTable } from '@/settings/developers/components/Settings
|
||||
import { Button } from '@/ui/input/button/components/Button';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
|
||||
const StyledButtonContainer = styled.div`
|
||||
display: flex;
|
||||
@ -19,12 +17,12 @@ const StyledButtonContainer = styled.div`
|
||||
|
||||
export const SettingsDevelopers = () => {
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconCode}
|
||||
title="Developers"
|
||||
actionButton={<SettingsReadDocumentationButton />}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb links={[{ children: 'Developers' }]} />
|
||||
<SettingsReadDocumentationButton />
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
<H2Title
|
||||
title="API keys"
|
||||
|
||||
@ -4,16 +4,16 @@ import { DateTime } from 'luxon';
|
||||
import { useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useRecoilState } from 'recoil';
|
||||
import { H2Title, IconRepeat, IconSettings, IconTrash } from 'twenty-ui';
|
||||
import { H2Title, IconCode, IconRepeat, IconTrash } from 'twenty-ui';
|
||||
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { ApiKeyInput } from '@/settings/developers/components/ApiKeyInput';
|
||||
import { ApiKeyNameInput } from '@/settings/developers/components/ApiKeyNameInput';
|
||||
import { apiKeyTokenState } from '@/settings/developers/states/generatedApiKeyTokenState';
|
||||
import { ApiKey } from '@/settings/developers/types/api-key/ApiKey';
|
||||
import { computeNewExpirationDate } from '@/settings/developers/utils/compute-new-expiration-date';
|
||||
import { formatExpiration } from '@/settings/developers/utils/format-expiration';
|
||||
@ -24,7 +24,6 @@ import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer'
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
|
||||
import { apiKeyTokenState } from '@/settings/developers/states/generatedApiKeyTokenState';
|
||||
|
||||
const StyledInfo = styled.span`
|
||||
color: ${({ theme }) => theme.font.color.light};
|
||||
@ -121,16 +120,18 @@ export const SettingsDevelopersApiKeyDetail = () => {
|
||||
return (
|
||||
<>
|
||||
{apiKeyData?.name && (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconCode}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: `${apiKeyName} API Key` },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: `${apiKeyName} API Key` },
|
||||
]}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
{apiKeyToken ? (
|
||||
<>
|
||||
|
||||
@ -1,25 +1,24 @@
|
||||
import { DateTime } from 'luxon';
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { H2Title, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconCode } from 'twenty-ui';
|
||||
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { EXPIRATION_DATES } from '@/settings/developers/constants/ExpirationDates';
|
||||
import { apiKeyTokenState } from '@/settings/developers/states/generatedApiKeyTokenState';
|
||||
import { ApiKey } from '@/settings/developers/types/api-key/ApiKey';
|
||||
import { Select } from '@/ui/input/components/Select';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { useGenerateApiKeyTokenMutation } from '~/generated/graphql';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { Key } from 'ts-key-enum';
|
||||
import { apiKeyTokenState } from '@/settings/developers/states/generatedApiKeyTokenState';
|
||||
import { useSetRecoilState } from 'recoil';
|
||||
|
||||
export const SettingsDevelopersApiKeysNew = () => {
|
||||
const [generateOneApiKeyToken] = useGenerateApiKeyTokenMutation();
|
||||
@ -64,23 +63,27 @@ export const SettingsDevelopersApiKeysNew = () => {
|
||||
};
|
||||
const canSave = !!formValues.name && createOneApiKey;
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconCode}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: 'New API Key' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
actionButton={
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => {
|
||||
navigate('/settings/developers');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: 'New API Key' },
|
||||
]}
|
||||
/>
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => {
|
||||
navigate('/settings/developers');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
<H2Title title="Name" description="Name of your API key" />
|
||||
<TextInput
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { useState } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { H2Title, IconSettings, IconTrash } from 'twenty-ui';
|
||||
import { H2Title, IconCode, IconTrash } from 'twenty-ui';
|
||||
|
||||
import { useObjectMetadataItems } from '@/object-metadata/hooks/useObjectMetadataItems';
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
@ -9,7 +9,6 @@ import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
|
||||
import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
|
||||
import { useUpdateOneRecord } from '@/object-record/hooks/useUpdateOneRecord';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { Webhook } from '@/settings/developers/types/webhook/Webhook';
|
||||
import { Button } from '@/ui/input/button/components/Button';
|
||||
@ -88,23 +87,27 @@ export const SettingsDevelopersWebhooksDetail = () => {
|
||||
return (
|
||||
<>
|
||||
{webhookData?.targetUrl && (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconCode}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: 'Webhook' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
actionButton={
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!isDirty}
|
||||
onCancel={() => {
|
||||
navigate('/settings/developers');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: 'Webhook' },
|
||||
]}
|
||||
/>
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!isDirty}
|
||||
onCancel={() => {
|
||||
navigate('/settings/developers');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Endpoint URL"
|
||||
|
||||
@ -1,11 +1,10 @@
|
||||
import { useState } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { H2Title, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconCode } from 'twenty-ui';
|
||||
|
||||
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
|
||||
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { Webhook } from '@/settings/developers/types/webhook/Webhook';
|
||||
import { TextInput } from '@/ui/input/components/TextInput';
|
||||
@ -35,23 +34,27 @@ export const SettingsDevelopersWebhooksNew = () => {
|
||||
};
|
||||
const canSave = !!formValues.targetUrl && createOneWebhook;
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconCode}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: 'New webhook' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
actionButton={
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => {
|
||||
navigate('/settings/developers');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Developers', href: '/settings/developers' },
|
||||
{ children: 'New webhook' },
|
||||
]}
|
||||
/>
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => {
|
||||
navigate('/settings/developers');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Endpoint URL"
|
||||
|
||||
@ -42,8 +42,9 @@ export const SettingsIntegrationDatabase = () => {
|
||||
if (!isIntegrationAvailable) return null;
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SettingsPageContainer>
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconSettings}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
@ -53,6 +54,9 @@ export const SettingsIntegrationDatabase = () => {
|
||||
{ children: integration.text },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsIntegrationPreview
|
||||
integrationLogoUrl={integration.from.image}
|
||||
/>
|
||||
|
||||
@ -3,10 +3,21 @@ import { IconSettings } from 'twenty-ui';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsIntegrationEditDatabaseConnectionContainer } from '@/settings/integrations/database-connection/components/SettingsIntegrationEditDatabaseConnectionContainer';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
|
||||
export const SettingsIntegrationEditDatabaseConnection = () => {
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconSettings}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
// TODO
|
||||
{ children: 'Edit connection' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsIntegrationEditDatabaseConnectionContainer />
|
||||
</SettingsPageContainer>
|
||||
|
||||
@ -8,7 +8,6 @@ import { z } from 'zod';
|
||||
import { useCreateOneDatabaseConnection } from '@/databases/hooks/useCreateOneDatabaseConnection';
|
||||
import { getForeignDataWrapperType } from '@/databases/utils/getForeignDataWrapperType';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import {
|
||||
SettingsIntegrationDatabaseConnectionForm,
|
||||
@ -132,34 +131,38 @@ export const SettingsIntegrationNewDatabaseConnection = () => {
|
||||
};
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconSettings}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Integrations',
|
||||
href: settingsIntegrationsPagePath,
|
||||
},
|
||||
{
|
||||
children: integration.text,
|
||||
href: `${settingsIntegrationsPagePath}/${databaseKey}`,
|
||||
},
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
actionButton={
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() =>
|
||||
navigate(`${settingsIntegrationsPagePath}/${databaseKey}`)
|
||||
}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<FormProvider
|
||||
// eslint-disable-next-line react/jsx-props-no-spreading
|
||||
{...formConfig}
|
||||
>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{
|
||||
children: 'Integrations',
|
||||
href: settingsIntegrationsPagePath,
|
||||
},
|
||||
{
|
||||
children: integration.text,
|
||||
href: `${settingsIntegrationsPagePath}/${databaseKey}`,
|
||||
},
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() =>
|
||||
navigate(`${settingsIntegrationsPagePath}/${databaseKey}`)
|
||||
}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
<H2Title
|
||||
title="Connect a new database"
|
||||
|
||||
@ -1,18 +1,15 @@
|
||||
import { IconSettings } from 'twenty-ui';
|
||||
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsIntegrationGroup } from '@/settings/integrations/components/SettingsIntegrationGroup';
|
||||
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { IconApps } from 'twenty-ui';
|
||||
|
||||
export const SettingsIntegrations = () => {
|
||||
const integrationCategories = useSettingsIntegrationCategories();
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer Icon={IconApps} title="Integrations">
|
||||
<SettingsPageContainer>
|
||||
<Breadcrumb links={[{ children: 'Integrations' }]} />
|
||||
{integrationCategories.map((group) => (
|
||||
<SettingsIntegrationGroup key={group.key} integrationGroup={group} />
|
||||
))}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import styled from '@emotion/styled';
|
||||
import { H1Title, H2Title, IconSettings } from 'twenty-ui';
|
||||
import { H2Title, IconColorSwatch } from 'twenty-ui';
|
||||
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { ColorSchemePicker } from '@/ui/input/color-scheme/components/ColorSchemePicker';
|
||||
@ -8,17 +7,12 @@ import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { useColorScheme } from '@/ui/theme/hooks/useColorScheme';
|
||||
import { DateTimeSettings } from '~/pages/settings/profile/appearance/components/DateTimeSettings';
|
||||
|
||||
const StyledH1Title = styled(H1Title)`
|
||||
margin-bottom: 0;
|
||||
`;
|
||||
|
||||
export const SettingsAppearance = () => {
|
||||
const { colorScheme, setColorScheme } = useColorScheme();
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer Icon={IconColorSwatch} title="Appearance">
|
||||
<SettingsPageContainer>
|
||||
<StyledH1Title title="Appearance" />
|
||||
<Section>
|
||||
<H2Title title="Theme" />
|
||||
<ColorSchemePicker value={colorScheme} onChange={setColorScheme} />
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import { useResetRecoilState } from 'recoil';
|
||||
import { settingsServerlessFunctionCodeEditorOutputParamsState } from '@/settings/serverless-functions/states/settingsServerlessFunctionCodeEditorOutputParamsState';
|
||||
import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
|
||||
import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
|
||||
import { settingsServerlessFunctionCodeEditorOutputParamsState } from '@/settings/serverless-functions/states/settingsServerlessFunctionCodeEditorOutputParamsState';
|
||||
import { useResetRecoilState } from 'recoil';
|
||||
|
||||
export const ResetServerlessFunctionStatesEffect = () => {
|
||||
const resetSettingsServerlessFunctionInput = useResetRecoilState(
|
||||
|
||||
@ -1,25 +1,24 @@
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { IconCode, IconSettings, IconTestPipe } from 'twenty-ui';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SettingsServerlessFunctionCodeEditorTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionCodeEditorTab';
|
||||
import { SettingsServerlessFunctionSettingsTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionSettingsTab';
|
||||
import { SettingsServerlessFunctionTestTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab';
|
||||
import { SettingsServerlessFunctionTestTabEffect } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTabEffect';
|
||||
import { useExecuteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useExecuteOneServerlessFunction';
|
||||
import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
||||
import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
|
||||
import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
|
||||
import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { TabList } from '@/ui/layout/tab/components/TabList';
|
||||
import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { useParams } from 'react-router-dom';
|
||||
import { useRecoilValue, useSetRecoilState } from 'recoil';
|
||||
import { SettingsServerlessFunctionCodeEditorTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionCodeEditorTab';
|
||||
import { SettingsServerlessFunctionSettingsTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionSettingsTab';
|
||||
import { useServerlessFunctionUpdateFormState } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
||||
import { SettingsServerlessFunctionTestTab } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTab';
|
||||
import { useExecuteOneServerlessFunction } from '@/settings/serverless-functions/hooks/useExecuteOneServerlessFunction';
|
||||
import { SnackBarVariant } from '@/ui/feedback/snack-bar-manager/components/SnackBar';
|
||||
import { useSnackBar } from '@/ui/feedback/snack-bar-manager/hooks/useSnackBar';
|
||||
import { useUpdateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useUpdateOneServerlessFunction';
|
||||
import { IconCode, IconFunction, IconSettings, IconTestPipe } from 'twenty-ui';
|
||||
import { useDebouncedCallback } from 'use-debounce';
|
||||
import { SettingsServerlessFunctionTestTabEffect } from '@/settings/serverless-functions/components/tabs/SettingsServerlessFunctionTestTabEffect';
|
||||
import { settingsServerlessFunctionOutputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionOutputState';
|
||||
import { settingsServerlessFunctionInputState } from '@/settings/serverless-functions/states/settingsServerlessFunctionInputState';
|
||||
|
||||
const TAB_LIST_COMPONENT_ID = 'serverless-function-detail';
|
||||
|
||||
@ -145,16 +144,18 @@ export const SettingsServerlessFunctionDetail = () => {
|
||||
|
||||
return (
|
||||
formValues.name && (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconFunction}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Functions', href: '/settings/functions' },
|
||||
{ children: `${formValues.name}` },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Functions', href: '/settings/functions' },
|
||||
{ children: `${formValues.name}` },
|
||||
]}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
<TabList tabListId={TAB_LIST_COMPONENT_ID} tabs={tabs} />
|
||||
</Section>
|
||||
|
||||
@ -1,31 +1,36 @@
|
||||
import { IconPlus, IconSettings } from 'twenty-ui';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsServerlessFunctionsTable } from '@/settings/serverless-functions/components/SettingsServerlessFunctionsTable';
|
||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { Button } from '@/ui/input/button/components/Button';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Section } from '@/ui/layout/section/components/Section';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { UndecoratedLink } from '@/ui/navigation/link/components/UndecoratedLink';
|
||||
import { IconFunction, IconPlus } from 'twenty-ui';
|
||||
|
||||
export const SettingsServerlessFunctions = () => {
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconFunction}
|
||||
title="Functions"
|
||||
actionButton={
|
||||
<UndecoratedLink
|
||||
to={getSettingsPagePath(SettingsPath.NewServerlessFunction)}
|
||||
>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title="New Function"
|
||||
accent="blue"
|
||||
size="small"
|
||||
/>
|
||||
</UndecoratedLink>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb links={[{ children: 'Functions' }]} />
|
||||
<UndecoratedLink
|
||||
to={getSettingsPagePath(SettingsPath.NewServerlessFunction)}
|
||||
>
|
||||
<Button
|
||||
Icon={IconPlus}
|
||||
title="New Function"
|
||||
accent="blue"
|
||||
size="small"
|
||||
/>
|
||||
</UndecoratedLink>
|
||||
</SettingsHeaderContainer>
|
||||
<Section>
|
||||
<SettingsServerlessFunctionsTable />
|
||||
|
||||
@ -1,19 +1,18 @@
|
||||
import { IconSettings } from 'twenty-ui';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SettingsHeaderContainer } from '@/settings/components/SettingsHeaderContainer';
|
||||
import { SaveAndCancelButtons } from '@/settings/components/SaveAndCancelButtons/SaveAndCancelButtons';
|
||||
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
|
||||
import { SubMenuTopBarContainer } from '@/ui/layout/page/SubMenuTopBarContainer';
|
||||
import { Breadcrumb } from '@/ui/navigation/bread-crumb/components/Breadcrumb';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
import { useCreateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useCreateOneServerlessFunction';
|
||||
import { DEFAULT_CODE } from '@/ui/input/code-editor/components/CodeEditor';
|
||||
import { ServerlessFunctionNewFormValues } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
||||
import { SettingsServerlessFunctionNewForm } from '@/settings/serverless-functions/components/SettingsServerlessFunctionNewForm';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
import { useState } from 'react';
|
||||
import { useCreateOneServerlessFunction } from '@/settings/serverless-functions/hooks/useCreateOneServerlessFunction';
|
||||
import { ServerlessFunctionNewFormValues } from '@/settings/serverless-functions/hooks/useServerlessFunctionUpdateFormState';
|
||||
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
|
||||
import { SettingsPath } from '@/types/SettingsPath';
|
||||
import { DEFAULT_CODE } from '@/ui/input/code-editor/components/CodeEditor';
|
||||
import { useState } from 'react';
|
||||
import { IconFunction } from 'twenty-ui';
|
||||
import { isDefined } from '~/utils/isDefined';
|
||||
|
||||
export const SettingsServerlessFunctionsNew = () => {
|
||||
const navigate = useNavigate();
|
||||
@ -54,23 +53,27 @@ export const SettingsServerlessFunctionsNew = () => {
|
||||
const canSave = !!formValues.name && createOneServerlessFunction;
|
||||
|
||||
return (
|
||||
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
|
||||
<SubMenuTopBarContainer
|
||||
Icon={IconFunction}
|
||||
title={
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Functions', href: '/settings/functions' },
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
}
|
||||
actionButton={
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => {
|
||||
navigate('/settings/functions');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
}
|
||||
>
|
||||
<SettingsPageContainer>
|
||||
<SettingsHeaderContainer>
|
||||
<Breadcrumb
|
||||
links={[
|
||||
{ children: 'Functions', href: '/settings/functions' },
|
||||
{ children: 'New' },
|
||||
]}
|
||||
/>
|
||||
<SaveAndCancelButtons
|
||||
isSaveDisabled={!canSave}
|
||||
onCancel={() => {
|
||||
navigate('/settings/functions');
|
||||
}}
|
||||
onSave={handleSave}
|
||||
/>
|
||||
</SettingsHeaderContainer>
|
||||
<SettingsServerlessFunctionNewForm
|
||||
formValues={formValues}
|
||||
onChange={onChange}
|
||||
|
||||
Reference in New Issue
Block a user