Files
twenty/packages/twenty-front/src/modules/command-menu/pages/page-layout/components/CommandMenuPageLayoutIframeSettings.tsx
T
Paul Rastoin 4135a6473a [BREAKING_CHANGE_DASHBOARDS][DASHBOARD_CACHE_FLUSH_REQUIRED] Refactor page layout widget configuration type (#16671)
# Introduction
In this pull-request we're refactoring the page layout widget
configuration entity to be containing its discriminated key simplifying
underlying code and maintainability
- Made the configuration and title non nullable
- Introduced a generic predicate for the `widgetConfigurationType`
- Upgraded command to remove `graphType` and insert new
`configurationType` to existing entries
- Migrated frontend to new type system

---------

Co-authored-by: bosiraphael <raphael.bosi@gmail.com>
Co-authored-by: Raphaël Bosi <71827178+bosiraphael@users.noreply.github.com>
2025-12-29 15:46:59 +01:00

91 lines
2.6 KiB
TypeScript

import { usePageLayoutIdFromContextStoreTargetedRecord } from '@/command-menu/pages/page-layout/hooks/usePageLayoutFromContextStoreTargetedRecord';
import { useWidgetInEditMode } from '@/command-menu/pages/page-layout/hooks/useWidgetInEditMode';
import { FormTextFieldInput } from '@/object-record/record-field/ui/form-types/components/FormTextFieldInput';
import { useUpdatePageLayoutWidget } from '@/page-layout/hooks/useUpdatePageLayoutWidget';
import styled from '@emotion/styled';
import { t } from '@lingui/core/macro';
import { isNonEmptyString, isString } from '@sniptt/guards';
import { useState } from 'react';
import { isDefined, isValidUrl } from 'twenty-shared/utils';
import { WidgetConfigurationType } from '~/generated/graphql';
const StyledContainer = styled.div`
display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(3)};
padding: ${({ theme }) => theme.spacing(2)};
`;
export const CommandMenuPageLayoutIframeSettings = () => {
const { pageLayoutId } = usePageLayoutIdFromContextStoreTargetedRecord();
const { widgetInEditMode } = useWidgetInEditMode(pageLayoutId);
const { updatePageLayoutWidget } = useUpdatePageLayoutWidget(pageLayoutId);
const widgetConfiguration = widgetInEditMode?.configuration;
const configUrl =
widgetConfiguration && 'url' in widgetConfiguration
? widgetConfiguration.url
: null;
const [url, setUrl] = useState<string | null>(
isString(configUrl) ? configUrl : null,
);
const [urlError, setUrlError] = useState('');
if (!isDefined(widgetInEditMode)) {
return null;
}
const validateUrl = (urlString: string): boolean => {
const trimmedUrl = urlString.trim();
if (!isNonEmptyString(trimmedUrl)) {
setUrlError('');
return true;
}
if (!isValidUrl(trimmedUrl)) {
setUrlError(t`Please enter a valid URL`);
return false;
}
setUrlError('');
return true;
};
const handleUrlChange = (value: string) => {
setUrl(value);
if (!validateUrl(value)) {
return;
}
const trimmedValue = value.trim();
updatePageLayoutWidget(widgetInEditMode.id, {
configuration: {
__typename: 'IframeConfiguration',
configurationType: WidgetConfigurationType.IFRAME,
url: isNonEmptyString(trimmedValue) ? trimmedValue : null,
},
});
};
return (
<>
<StyledContainer>
<FormTextFieldInput
label={t`URL to Embed`}
placeholder={t`https://example.com/embed`}
defaultValue={url}
onChange={handleUrlChange}
error={urlError}
/>
</StyledContainer>
</>
);
};