Skip to content

Commit

Permalink
Fix toggle re-render
Browse files Browse the repository at this point in the history
  • Loading branch information
Thomas Trompette committed Apr 9, 2024
1 parent f9c319e commit 7eaf811
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 81 deletions.
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCallback } from 'react';
import { ApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';

Expand All @@ -20,15 +21,18 @@ export const useSyncRemoteTable = () => {
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
});

const syncRemoteTable = async (input: RemoteTableInput) => {
return await mutate({
variables: {
input,
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(GET_MANY_REMOTE_TABLES) ?? ''],
});
};
const syncRemoteTable = useCallback(
async (input: RemoteTableInput) => {
return await mutate({
variables: {
input,
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(GET_MANY_REMOTE_TABLES) ?? ''],
});
},
[mutate],
);

return {
syncRemoteTable,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useCallback } from 'react';
import { ApolloClient, useMutation } from '@apollo/client';
import { getOperationName } from '@apollo/client/utilities';

Expand All @@ -20,15 +21,18 @@ export const useUnsyncRemoteTable = () => {
client: apolloMetadataClient ?? ({} as ApolloClient<any>),
});

const unsyncRemoteTable = async (input: RemoteTableInput) => {
return await mutate({
variables: {
input,
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(GET_MANY_REMOTE_TABLES) ?? ''],
});
};
const unsyncRemoteTable = useCallback(
async (input: RemoteTableInput) => {
return await mutate({
variables: {
input,
},
awaitRefetchQueries: true,
refetchQueries: [getOperationName(GET_MANY_REMOTE_TABLES) ?? ''],
});
},
[mutate],
);

return {
unsyncRemoteTable,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { useCallback } from 'react';
import { useCallback, useState } from 'react';
import styled from '@emotion/styled';
import { z } from 'zod';

import { useSyncRemoteTable } from '@/databases/hooks/useSyncRemoteTable';
import { useUnsyncRemoteTable } from '@/databases/hooks/useUnsyncRemoteTable';
import { SettingsListCard } from '@/settings/components/SettingsListCard';
import { Toggle } from '@/ui/input/components/Toggle';
import { RemoteTable } from '~/generated-metadata/graphql';
import { SettingsIntegrationSyncStatusToggle } from '@/settings/integrations/components/SettingsIntegrationSyncStatusToggle';
import { RemoteTable, RemoteTableStatus } from '~/generated-metadata/graphql';

export const settingsIntegrationsDatabaseTablesSchema = z.object({
syncedTablesByName: z.record(z.boolean()),
Expand Down Expand Up @@ -34,42 +34,57 @@ export const SettingsIntegrationDatabaseTablesListCard = ({
const { syncRemoteTable } = useSyncRemoteTable();
const { unsyncRemoteTable } = useUnsyncRemoteTable();

const [items] = useState(
tables.map((table) => ({
id: table.name,
...table,
})),
);

const onSyncUpdate = useCallback(
async (value: boolean, tableName: string) => {
const table = tables.filter((table) => table.name === tableName)[0];
const table = items.filter((table) => table.name === tableName)[0];

// eslint-disable-next-line @nx/workspace-explicit-boolean-predicates-in-if
if (!table) return;

if (value && table.status !== 'SYNCED') {
if (value) {
await syncRemoteTable({
remoteServerId: connectionId,
name: tableName,
schema: table.schema,
});
} else if (!value && table.status !== 'NOT_SYNCED') {
} else {
await unsyncRemoteTable({
remoteServerId: connectionId,
name: tableName,
schema: table.schema,
});
}
},
[connectionId, syncRemoteTable, tables, unsyncRemoteTable],
[connectionId, syncRemoteTable, items, unsyncRemoteTable],
);

const rowRightComponent = useCallback(
({
item,
}: {
item: { id: string; name: string; status: RemoteTableStatus };
}) => (
<StyledRowRightContainer>
<SettingsIntegrationSyncStatusToggle
item={item}
onSyncUpdate={onSyncUpdate}
/>
</StyledRowRightContainer>
),
[onSyncUpdate],
);
return (
<SettingsListCard
items={tables.map((table) => ({ id: table.name, ...table }))}
RowRightComponent={({ item: table }) => (
<StyledRowRightContainer>
<Toggle
value={table.status === 'SYNCED'}
onChange={(value) => onSyncUpdate(value, table.name)}
/>
</StyledRowRightContainer>
)}
getItemLabel={(table) => table.name}
items={items}
RowRightComponent={rowRightComponent}
getItemLabel={(table) => table.id}
/>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { useState } from 'react';

import { Toggle } from '@/ui/input/components/Toggle';
import { RemoteTableStatus } from '~/generated-metadata/graphql';

export const SettingsIntegrationSyncStatusToggle = ({
item: table,
onSyncUpdate,
}: {
item: { id: string; name: string; status: RemoteTableStatus };
onSyncUpdate: (value: boolean, tableName: string) => Promise<void>;
}) => {
const [isToggleLoading, setIsToggleLoading] = useState(false);

const onChange = async (newValue: boolean) => {
if (isToggleLoading) return;
setIsToggleLoading(true);
await onSyncUpdate(newValue, table.name);
setIsToggleLoading(false);
};

return (
<Toggle
value={table.status === RemoteTableStatus.Synced}
disabled={isToggleLoading}
onChange={onChange}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ type ContainerProps = {
isOn: boolean;
color?: string;
toggleSize: ToggleSize;
disabled?: boolean;
};

const StyledContainer = styled.div<ContainerProps>`
Expand All @@ -22,6 +23,8 @@ const StyledContainer = styled.div<ContainerProps>`
height: ${({ toggleSize }) => (toggleSize === 'small' ? 16 : 20)}px;
transition: background-color 0.3s ease;
width: ${({ toggleSize }) => (toggleSize === 'small' ? 24 : 32)}px;
opacity: ${({ disabled }) => (disabled ? 0.5 : 1)};
pointer-events: ${({ disabled }) => (disabled ? 'none' : 'auto')};
`;

const StyledCircle = styled(motion.div)<{
Expand All @@ -39,6 +42,7 @@ export type ToggleProps = {
color?: string;
toggleSize?: ToggleSize;
className?: string;
disabled?: boolean;
};

export const Toggle = ({
Expand All @@ -47,6 +51,7 @@ export const Toggle = ({
color,
toggleSize = 'medium',
className,
disabled,
}: ToggleProps) => {
const [isOn, setIsOn] = useState(value ?? false);

Expand Down Expand Up @@ -77,6 +82,7 @@ export const Toggle = ({
color={color}
toggleSize={toggleSize}
className={className}
disabled={disabled}
>
<StyledCircle
animate={isOn ? 'on' : 'off'}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,12 @@
import { useEffect } from 'react';
import { FormProvider, useForm } from 'react-hook-form';
import { useNavigate, useParams } from 'react-router-dom';
import { zodResolver } from '@hookform/resolvers/zod';
import { IconSettings } from 'twenty-ui';

import { useDeleteOneDatabaseConnection } from '@/databases/hooks/useDeleteOneDatabaseConnection';
import { useGetDatabaseConnection } from '@/databases/hooks/useGetDatabaseConnection';
import { useGetDatabaseConnectionTables } from '@/databases/hooks/useGetDatabaseConnectionTables';
import { SettingsPageContainer } from '@/settings/components/SettingsPageContainer';
import {
SettingsIntegrationDatabaseTablesListCard,
SettingsIntegrationsDatabaseTablesFormValues,
settingsIntegrationsDatabaseTablesSchema,
} from '@/settings/integrations/components/SettingsIntegrationDatabaseTablesListCard';
import { SettingsIntegrationDatabaseTablesListCard } from '@/settings/integrations/components/SettingsIntegrationDatabaseTablesListCard';
import { useSettingsIntegrationCategories } from '@/settings/integrations/hooks/useSettingsIntegrationCategories';
import { getConnectionDbName } from '@/settings/integrations/utils/getConnectionDbName';
import { getSettingsPagePath } from '@/settings/utils/getSettingsPagePath';
Expand Down Expand Up @@ -79,11 +73,6 @@ export const SettingsIntegrationDatabaseConnection = () => {
skip: !isIntegrationAvailable || !connection,
});

const formConfig = useForm<SettingsIntegrationsDatabaseTablesFormValues>({
mode: 'onTouched',
resolver: zodResolver(settingsIntegrationsDatabaseTablesSchema),
});

if (!isIntegrationAvailable || !connection) return null;

const settingsIntegrationsPagePath = getSettingsPagePath(
Expand All @@ -93,44 +82,43 @@ export const SettingsIntegrationDatabaseConnection = () => {
const connectionName = getConnectionDbName({ integration, connection });

return (
// eslint-disable-next-line react/jsx-props-no-spreading
<FormProvider {...formConfig}>
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
<Breadcrumb
links={[
{
children: 'Integrations',
href: settingsIntegrationsPagePath,
},
{
children: integration.text,
href: `${settingsIntegrationsPagePath}/${databaseKey}`,
},
{ children: connectionName },
]}
<SubMenuTopBarContainer Icon={IconSettings} title="Settings">
<SettingsPageContainer>
<Breadcrumb
links={[
{
children: 'Integrations',
href: settingsIntegrationsPagePath,
},
{
children: integration.text,
href: `${settingsIntegrationsPagePath}/${databaseKey}`,
},
{ children: connectionName },
]}
/>
<Section>
<H2Title title="About" description="About this remote object" />
<SettingsIntegrationDatabaseConnectionSummaryCard
databaseLogoUrl={integration.from.image}
connectionId={connectionId}
connectionName={connectionName}
onRemove={deleteConnection}
/>
<Section>
<H2Title title="About" description="About this remote object" />
<SettingsIntegrationDatabaseConnectionSummaryCard
databaseLogoUrl={integration.from.image}
connectionId={connectionId}
connectionName={connectionName}
onRemove={deleteConnection}
/>
</Section>
<Section>
<H2Title
title="Tables"
description="Select the tables that should be tracked"
/>
</Section>
<Section>
<H2Title
title="Tables"
description="Select the tables that should be tracked"
/>
{!!tables.length && (
<SettingsIntegrationDatabaseTablesListCard
connectionId={connectionId}
tables={tables}
/>
</Section>
</SettingsPageContainer>
</SubMenuTopBarContainer>
</FormProvider>
)}
</Section>
</SettingsPageContainer>
</SubMenuTopBarContainer>
);
};

0 comments on commit 7eaf811

Please sign in to comment.