Implement full tab widget frontend (#19568)
https://github.com/user-attachments/assets/488e0145-ff49-4205-8fd3-0eb4f614c054
This commit is contained in:
committed by
GitHub
parent
8425afd930
commit
6829fc315a
+1
-1
@@ -95,7 +95,7 @@ export const DEFAULT_NOTE_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
title: 'Note',
|
||||
icon: 'IconNotes',
|
||||
position: 150,
|
||||
layoutMode: PageLayoutTabLayoutMode.CANVAS,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
pageLayoutId: DEFAULT_NOTE_RECORD_PAGE_LAYOUT_ID,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
|
||||
+1
-1
@@ -92,7 +92,7 @@ export const DEFAULT_TASK_RECORD_PAGE_LAYOUT: PageLayout = {
|
||||
title: 'Note',
|
||||
icon: 'IconNotes',
|
||||
position: 150,
|
||||
layoutMode: PageLayoutTabLayoutMode.CANVAS,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
pageLayoutId: DEFAULT_TASK_RECORD_PAGE_LAYOUT_ID,
|
||||
createdAt: new Date().toISOString(),
|
||||
updatedAt: new Date().toISOString(),
|
||||
|
||||
@@ -161,6 +161,8 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
|
||||
variant === 'side-column' &&
|
||||
!isRecordPageGlobalEditionEnabled;
|
||||
|
||||
const isCanvasVariant = variant === 'canvas';
|
||||
|
||||
const widgetCard = (
|
||||
<WidgetCard
|
||||
headerLess={!showHeader}
|
||||
@@ -171,8 +173,8 @@ export const WidgetRenderer = ({ widget }: WidgetRendererProps) => {
|
||||
isDragging={isDragging}
|
||||
isResizing={isResizing}
|
||||
isLastWidget={isLastWidget}
|
||||
onMouseEnter={handleMouseEnter}
|
||||
onMouseLeave={handleMouseLeave}
|
||||
onMouseEnter={isCanvasVariant ? undefined : handleMouseEnter}
|
||||
onMouseLeave={isCanvasVariant ? undefined : handleMouseLeave}
|
||||
data-widget-id={widget.id}
|
||||
data-testid={widget.id}
|
||||
className="widget"
|
||||
|
||||
+7
@@ -106,6 +106,9 @@ const StyledWidgetCard = styled.div<WidgetCardStyledProps>`
|
||||
&:hover {
|
||||
// border-color shorthand must precede border-bottom-color longhand for correct CSS cascade
|
||||
border-color: ${(props) => {
|
||||
if (props.variant === 'canvas') {
|
||||
return computeBorderColor(props);
|
||||
}
|
||||
if (
|
||||
props.isEditable &&
|
||||
!props.isDragging &&
|
||||
@@ -118,6 +121,10 @@ const StyledWidgetCard = styled.div<WidgetCardStyledProps>`
|
||||
}};
|
||||
|
||||
border-bottom-color: ${(props) => {
|
||||
if (props.variant === 'canvas') {
|
||||
return computeBorderColor(props);
|
||||
}
|
||||
|
||||
const { variant, isEditable } = props;
|
||||
|
||||
if (variant === 'side-column' && !isEditable) {
|
||||
|
||||
+4
-1
@@ -16,6 +16,7 @@ import {
|
||||
type IconComponent,
|
||||
} from 'twenty-ui/display';
|
||||
import { ThemeContext } from 'twenty-ui/theme-constants';
|
||||
import { PageLayoutTabLayoutMode } from '~/generated-metadata/graphql';
|
||||
|
||||
type PageLayoutHeaderInfo = {
|
||||
headerIcon: IconComponent | undefined;
|
||||
@@ -65,10 +66,12 @@ export const usePageLayoutHeaderInfo = ({
|
||||
? tab.title
|
||||
: '';
|
||||
|
||||
const isCanvasTab = tab.layoutMode === PageLayoutTabLayoutMode.CANVAS;
|
||||
|
||||
return {
|
||||
headerIcon: IconAppWindow,
|
||||
headerIconColor: iconColor,
|
||||
headerType: t`Tab`,
|
||||
headerType: isCanvasTab ? t`Full tab widget` : t`Tab`,
|
||||
title,
|
||||
isReadonly: false,
|
||||
tab,
|
||||
|
||||
+32
-1
@@ -1,17 +1,23 @@
|
||||
import { useCallback } from 'react';
|
||||
|
||||
import { PageLayoutComponentInstanceContext } from '@/page-layout/states/contexts/PageLayoutComponentInstanceContext';
|
||||
import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDraftComponentState';
|
||||
import { pageLayoutEditingWidgetIdComponentState } from '@/page-layout/states/pageLayoutEditingWidgetIdComponentState';
|
||||
import { pageLayoutTabSettingsOpenTabIdComponentState } from '@/page-layout/states/pageLayoutTabSettingsOpenTabIdComponentState';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { useIsDashboardPageLayout } from '@/side-panel/pages/page-layout/hooks/useIsDashboardPageLayout';
|
||||
import { useNavigatePageLayoutSidePanel } from '@/side-panel/pages/page-layout/hooks/useNavigatePageLayoutSidePanel';
|
||||
import { sidePanelPageState } from '@/side-panel/states/sidePanelPageState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useSetAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useSetAtomComponentState';
|
||||
import { useSetAtomState } from '@/ui/utilities/state/jotai/hooks/useSetAtomState';
|
||||
import { t } from '@lingui/core/macro';
|
||||
import { SidePanelPages } from 'twenty-shared/types';
|
||||
import { WidgetType } from '~/generated-metadata/graphql';
|
||||
import {
|
||||
PageLayoutTabLayoutMode,
|
||||
WidgetType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
export const useOpenWidgetSettingsInSidePanel = (
|
||||
pageLayoutIdFromProps?: string,
|
||||
@@ -32,6 +38,16 @@ export const useOpenWidgetSettingsInSidePanel = (
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
const setSidePanelPage = useSetAtomState(sidePanelPageState);
|
||||
|
||||
const pageLayoutDraft = useAtomComponentStateValue(
|
||||
pageLayoutDraftComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const setPageLayoutTabSettingsOpenTabId = useSetAtomComponentState(
|
||||
pageLayoutTabSettingsOpenTabIdComponentState,
|
||||
pageLayoutId,
|
||||
);
|
||||
|
||||
const openWidgetSettingsInSidePanel = useCallback(
|
||||
({
|
||||
widgetId,
|
||||
@@ -112,12 +128,27 @@ export const useOpenWidgetSettingsInSidePanel = (
|
||||
return;
|
||||
}
|
||||
|
||||
const containingTab = pageLayoutDraft.tabs.find((tab) =>
|
||||
tab.widgets.some((w) => w.id === widgetId),
|
||||
);
|
||||
|
||||
if (containingTab?.layoutMode === PageLayoutTabLayoutMode.CANVAS) {
|
||||
setPageLayoutTabSettingsOpenTabId(containingTab.id);
|
||||
navigatePageLayoutSidePanel({
|
||||
sidePanelPage: SidePanelPages.PageLayoutTabSettings,
|
||||
resetNavigationStack: true,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
setSidePanelPage(SidePanelPages.CommandMenuDisplay);
|
||||
closeSidePanelMenu();
|
||||
},
|
||||
[
|
||||
isDashboardPageLayout,
|
||||
pageLayoutDraft,
|
||||
setPageLayoutEditingWidgetId,
|
||||
setPageLayoutTabSettingsOpenTabId,
|
||||
navigatePageLayoutSidePanel,
|
||||
closeSidePanelMenu,
|
||||
setSidePanelPage,
|
||||
|
||||
+190
@@ -0,0 +1,190 @@
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { CommandMenuItemDropdown } from '@/command-menu/components/CommandMenuItemDropdown';
|
||||
import { type PageLayoutWidget } from '@/page-layout/types/PageLayoutWidget';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { CanvasTabWidgetVisibilityDropdownContent } from '@/side-panel/pages/page-layout/components/dropdown-content/CanvasTabWidgetVisibilityDropdownContent';
|
||||
import { TAB_SETTINGS_SELECTABLE_ITEM_IDS } from '@/side-panel/pages/page-layout/constants/settings/TabSettingsSelectableItemIds';
|
||||
import { useTranslatedVisibilityLabel } from '@/side-panel/pages/page-layout/hooks/useTranslatedVisibilityLabel';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconChevronLeft,
|
||||
IconChevronRight,
|
||||
IconEyeX,
|
||||
IconPinned,
|
||||
IconRefreshDot,
|
||||
IconTrash,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
const RESET_TAB_TO_DEFAULT_MODAL_ID = 'reset-canvas-tab-to-default-modal';
|
||||
|
||||
type CanvasTabSettingsContentProps = {
|
||||
pageLayoutId: string;
|
||||
canvasWidget: PageLayoutWidget | undefined;
|
||||
canSetAsPinned: boolean;
|
||||
canMoveLeft: boolean;
|
||||
canMoveRight: boolean;
|
||||
canShowResetToDefault: boolean;
|
||||
canDelete: boolean;
|
||||
onMoveLeft: () => void;
|
||||
onMoveRight: () => void;
|
||||
onSetAsPinned: () => void;
|
||||
onResetToDefault: () => void;
|
||||
onDelete: () => void;
|
||||
};
|
||||
|
||||
export const CanvasTabSettingsContent = ({
|
||||
pageLayoutId,
|
||||
canvasWidget,
|
||||
canSetAsPinned,
|
||||
canMoveLeft,
|
||||
canMoveRight,
|
||||
canShowResetToDefault,
|
||||
canDelete,
|
||||
onMoveLeft,
|
||||
onMoveRight,
|
||||
onSetAsPinned,
|
||||
onResetToDefault,
|
||||
onDelete,
|
||||
}: CanvasTabSettingsContentProps) => {
|
||||
const { t } = useLingui();
|
||||
const { openModal } = useModal();
|
||||
|
||||
const visibilityLabel = useTranslatedVisibilityLabel(
|
||||
canvasWidget?.conditionalAvailabilityExpression,
|
||||
);
|
||||
|
||||
const handleResetToDefault = () => {
|
||||
openModal(RESET_TAB_TO_DEFAULT_MODAL_ID);
|
||||
};
|
||||
|
||||
const selectableItemIds = [
|
||||
...(canSetAsPinned ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED] : []),
|
||||
...(canMoveLeft ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT] : []),
|
||||
...(canMoveRight ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT] : []),
|
||||
...(isDefined(canvasWidget)
|
||||
? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.VISIBILITY_RESTRICTION]
|
||||
: []),
|
||||
...(canShowResetToDefault
|
||||
? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT]
|
||||
: []),
|
||||
...(canDelete ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE] : []),
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidePanelList selectableItemIds={selectableItemIds}>
|
||||
<SidePanelGroup heading={t`Placement`}>
|
||||
{canSetAsPinned && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED}
|
||||
onEnter={onSetAsPinned}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED}
|
||||
Icon={IconPinned}
|
||||
label={t`Pin tab`}
|
||||
onClick={onSetAsPinned}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canMoveLeft && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
|
||||
onEnter={onMoveLeft}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
|
||||
Icon={IconChevronLeft}
|
||||
label={t`Move left`}
|
||||
onClick={onMoveLeft}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canMoveRight && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
|
||||
onEnter={onMoveRight}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
|
||||
Icon={IconChevronRight}
|
||||
label={t`Move right`}
|
||||
onClick={onMoveRight}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
</SidePanelGroup>
|
||||
<SidePanelGroup heading={t`Manage`}>
|
||||
{isDefined(canvasWidget) && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.VISIBILITY_RESTRICTION}
|
||||
>
|
||||
<CommandMenuItemDropdown
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.VISIBILITY_RESTRICTION}
|
||||
label={t`Visibility restriction`}
|
||||
Icon={IconEyeX}
|
||||
dropdownId={
|
||||
TAB_SETTINGS_SELECTABLE_ITEM_IDS.VISIBILITY_RESTRICTION
|
||||
}
|
||||
dropdownComponents={
|
||||
<DropdownContent>
|
||||
<CanvasTabWidgetVisibilityDropdownContent
|
||||
widgetId={canvasWidget.id}
|
||||
currentExpression={
|
||||
canvasWidget.conditionalAvailabilityExpression
|
||||
}
|
||||
pageLayoutId={pageLayoutId}
|
||||
/>
|
||||
</DropdownContent>
|
||||
}
|
||||
dropdownPlacement="bottom-end"
|
||||
description={visibilityLabel}
|
||||
contextualTextPosition="right"
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canShowResetToDefault && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT}
|
||||
onEnter={handleResetToDefault}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT}
|
||||
Icon={IconRefreshDot}
|
||||
label={t`Reset to default`}
|
||||
onClick={handleResetToDefault}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canDelete && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
|
||||
onEnter={onDelete}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
|
||||
Icon={IconTrash}
|
||||
label={t`Delete`}
|
||||
onClick={onDelete}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
</SidePanelGroup>
|
||||
</SidePanelList>
|
||||
<ConfirmationModal
|
||||
modalInstanceId={RESET_TAB_TO_DEFAULT_MODAL_ID}
|
||||
title={t`Reset to default`}
|
||||
subtitle={t`This will cancel all modifications done on the tab and its widgets. Edit mode will be canceled and the page will refresh. This action cannot be undone.`}
|
||||
onConfirmClick={onResetToDefault}
|
||||
confirmButtonText={t`Reset`}
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+157
@@ -0,0 +1,157 @@
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { TAB_SETTINGS_SELECTABLE_ITEM_IDS } from '@/side-panel/pages/page-layout/constants/settings/TabSettingsSelectableItemIds';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import {
|
||||
IconChevronLeft,
|
||||
IconChevronRight,
|
||||
IconCopyPlus,
|
||||
IconPinned,
|
||||
IconRefreshDot,
|
||||
IconTrash,
|
||||
} from 'twenty-ui/display';
|
||||
|
||||
const RESET_TAB_TO_DEFAULT_MODAL_ID = 'reset-regular-tab-to-default-modal';
|
||||
|
||||
type RegularTabSettingsContentProps = {
|
||||
canSetAsPinned: boolean;
|
||||
canMoveLeft: boolean;
|
||||
canMoveRight: boolean;
|
||||
canShowResetToDefault: boolean;
|
||||
canDelete: boolean;
|
||||
onMoveLeft: () => void;
|
||||
onMoveRight: () => void;
|
||||
onSetAsPinned: () => void;
|
||||
onDuplicate: () => void;
|
||||
onResetToDefault: () => void;
|
||||
onDelete: () => void;
|
||||
};
|
||||
|
||||
export const RegularTabSettingsContent = ({
|
||||
canSetAsPinned,
|
||||
canMoveLeft,
|
||||
canMoveRight,
|
||||
canShowResetToDefault,
|
||||
canDelete,
|
||||
onMoveLeft,
|
||||
onMoveRight,
|
||||
onSetAsPinned,
|
||||
onDuplicate,
|
||||
onResetToDefault,
|
||||
onDelete,
|
||||
}: RegularTabSettingsContentProps) => {
|
||||
const { t } = useLingui();
|
||||
const { openModal } = useModal();
|
||||
|
||||
const handleResetToDefault = () => {
|
||||
openModal(RESET_TAB_TO_DEFAULT_MODAL_ID);
|
||||
};
|
||||
|
||||
const selectableItemIds = [
|
||||
...(canMoveLeft ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT] : []),
|
||||
...(canMoveRight ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT] : []),
|
||||
...(canSetAsPinned ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED] : []),
|
||||
TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE,
|
||||
...(canShowResetToDefault
|
||||
? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT]
|
||||
: []),
|
||||
...(canDelete ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE] : []),
|
||||
];
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidePanelList selectableItemIds={selectableItemIds}>
|
||||
<SidePanelGroup heading={t`Settings`}>
|
||||
{canMoveLeft && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
|
||||
onEnter={onMoveLeft}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
|
||||
Icon={IconChevronLeft}
|
||||
label={t`Move left`}
|
||||
onClick={onMoveLeft}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canMoveRight && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
|
||||
onEnter={onMoveRight}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
|
||||
Icon={IconChevronRight}
|
||||
label={t`Move right`}
|
||||
onClick={onMoveRight}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canSetAsPinned && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED}
|
||||
onEnter={onSetAsPinned}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED}
|
||||
Icon={IconPinned}
|
||||
label={t`Set as pinned tab`}
|
||||
onClick={onSetAsPinned}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE}
|
||||
onEnter={onDuplicate}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE}
|
||||
Icon={IconCopyPlus}
|
||||
label={t`Duplicate`}
|
||||
onClick={onDuplicate}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
{canShowResetToDefault && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT}
|
||||
onEnter={handleResetToDefault}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT}
|
||||
Icon={IconRefreshDot}
|
||||
label={t`Reset to default`}
|
||||
onClick={handleResetToDefault}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canDelete && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
|
||||
onEnter={onDelete}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
|
||||
Icon={IconTrash}
|
||||
label={t`Delete`}
|
||||
onClick={onDelete}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
</SidePanelGroup>
|
||||
</SidePanelList>
|
||||
<ConfirmationModal
|
||||
modalInstanceId={RESET_TAB_TO_DEFAULT_MODAL_ID}
|
||||
title={t`Reset to default`}
|
||||
subtitle={t`This will cancel all modifications done on the tab and its widgets. Edit mode will be canceled and the page will refresh. This action cannot be undone.`}
|
||||
onConfirmClick={onResetToDefault}
|
||||
confirmButtonText={t`Reset`}
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
+38
-124
@@ -1,4 +1,3 @@
|
||||
import { CommandMenuItem } from '@/command-menu/components/CommandMenuItem';
|
||||
import { currentWorkspaceState } from '@/auth/states/currentWorkspaceState';
|
||||
import { useDeletePageLayoutTab } from '@/page-layout/hooks/useDeletePageLayoutTab';
|
||||
import { useDuplicatePageLayoutTab } from '@/page-layout/hooks/useDuplicatePageLayoutTab';
|
||||
@@ -9,40 +8,27 @@ import { pageLayoutDraftComponentState } from '@/page-layout/states/pageLayoutDr
|
||||
import { pageLayoutTabSettingsOpenTabIdComponentState } from '@/page-layout/states/pageLayoutTabSettingsOpenTabIdComponentState';
|
||||
import { getTabListInstanceIdFromPageLayoutAndRecord } from '@/page-layout/utils/getTabListInstanceIdFromPageLayoutAndRecord';
|
||||
import { sortTabsByPosition } from '@/page-layout/utils/sortTabsByPosition';
|
||||
import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { SidePanelList } from '@/side-panel/components/SidePanelList';
|
||||
import { useSidePanelMenu } from '@/side-panel/hooks/useSidePanelMenu';
|
||||
import { TAB_SETTINGS_SELECTABLE_ITEM_IDS } from '@/side-panel/pages/page-layout/constants/settings/TabSettingsSelectableItemIds';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { CanvasTabSettingsContent } from '@/side-panel/pages/page-layout/components/CanvasTabSettingsContent';
|
||||
import { RegularTabSettingsContent } from '@/side-panel/pages/page-layout/components/RegularTabSettingsContent';
|
||||
import { useAtomComponentState } from '@/ui/utilities/state/jotai/hooks/useAtomComponentState';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useAtomStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomStateValue';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { isDefined } from 'twenty-shared/utils';
|
||||
import {
|
||||
IconChevronLeft,
|
||||
IconChevronRight,
|
||||
IconCopyPlus,
|
||||
IconPinned,
|
||||
IconRefreshDot,
|
||||
IconTrash,
|
||||
} from 'twenty-ui/display';
|
||||
import { PageLayoutType } from '~/generated-metadata/graphql';
|
||||
PageLayoutTabLayoutMode,
|
||||
PageLayoutType,
|
||||
} from '~/generated-metadata/graphql';
|
||||
|
||||
type SidePanelPageLayoutTabSettingsContentProps = {
|
||||
pageLayoutId: string;
|
||||
recordId: string;
|
||||
};
|
||||
|
||||
const RESET_TAB_TO_DEFAULT_MODAL_ID = 'reset-tab-to-default-modal';
|
||||
|
||||
export const SidePanelPageLayoutTabSettingsContent = ({
|
||||
pageLayoutId,
|
||||
recordId,
|
||||
}: SidePanelPageLayoutTabSettingsContentProps) => {
|
||||
const { t } = useLingui();
|
||||
const { closeSidePanelMenu } = useSidePanelMenu();
|
||||
|
||||
const currentWorkspace = useAtomStateValue(currentWorkspaceState);
|
||||
@@ -76,7 +62,6 @@ export const SidePanelPageLayoutTabSettingsContent = ({
|
||||
const { setAsPinnedTab } = useSetAsPinnedTab(pageLayoutId);
|
||||
const { resetPageLayoutTabToDefault } =
|
||||
useResetPageLayoutTabToDefault(pageLayoutId);
|
||||
const { openModal } = useModal();
|
||||
|
||||
if (!isDefined(pageLayoutTabSettingsOpenTabId)) {
|
||||
return null;
|
||||
@@ -110,114 +95,43 @@ export const SidePanelPageLayoutTabSettingsContent = ({
|
||||
};
|
||||
|
||||
const handleResetToDefault = () => {
|
||||
openModal(RESET_TAB_TO_DEFAULT_MODAL_ID);
|
||||
};
|
||||
|
||||
const handleConfirmReset = () => {
|
||||
resetPageLayoutTabToDefault(tab.id);
|
||||
};
|
||||
|
||||
const selectableItemIds = [
|
||||
...(canMoveLeft ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT] : []),
|
||||
...(canMoveRight ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT] : []),
|
||||
...(canSetAsPinned ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED] : []),
|
||||
TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE,
|
||||
...(canShowResetToDefault
|
||||
? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT]
|
||||
: []),
|
||||
...(canDelete ? [TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE] : []),
|
||||
];
|
||||
const isCanvasTab = tab.layoutMode === PageLayoutTabLayoutMode.CANVAS;
|
||||
|
||||
if (isCanvasTab) {
|
||||
return (
|
||||
<CanvasTabSettingsContent
|
||||
pageLayoutId={pageLayoutId}
|
||||
canvasWidget={tab.widgets.at(0)}
|
||||
canSetAsPinned={canSetAsPinned}
|
||||
canMoveLeft={canMoveLeft}
|
||||
canMoveRight={canMoveRight}
|
||||
canShowResetToDefault={canShowResetToDefault}
|
||||
canDelete={canDelete}
|
||||
onMoveLeft={() => moveLeft(tab.id)}
|
||||
onMoveRight={() => moveRight(tab.id)}
|
||||
onSetAsPinned={() => setAsPinnedTab(tab.id)}
|
||||
onResetToDefault={handleResetToDefault}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<SidePanelList selectableItemIds={selectableItemIds}>
|
||||
<SidePanelGroup heading={t`Settings`}>
|
||||
{canMoveLeft && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
|
||||
onEnter={() => moveLeft(tab.id)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_LEFT}
|
||||
Icon={IconChevronLeft}
|
||||
label={t`Move left`}
|
||||
onClick={() => moveLeft(tab.id)}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canMoveRight && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
|
||||
onEnter={() => moveRight(tab.id)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.MOVE_RIGHT}
|
||||
Icon={IconChevronRight}
|
||||
label={t`Move right`}
|
||||
onClick={() => moveRight(tab.id)}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canSetAsPinned && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED}
|
||||
onEnter={() => setAsPinnedTab(tab.id)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.SET_AS_PINNED}
|
||||
Icon={IconPinned}
|
||||
label={t`Set as pinned tab`}
|
||||
onClick={() => setAsPinnedTab(tab.id)}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE}
|
||||
onEnter={() => duplicateTab(tab.id)}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DUPLICATE}
|
||||
Icon={IconCopyPlus}
|
||||
label={t`Duplicate`}
|
||||
onClick={() => duplicateTab(tab.id)}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
{canShowResetToDefault && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT}
|
||||
onEnter={handleResetToDefault}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.RESET_TO_DEFAULT}
|
||||
Icon={IconRefreshDot}
|
||||
label={t`Reset to default`}
|
||||
onClick={handleResetToDefault}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
{canDelete && (
|
||||
<SelectableListItem
|
||||
itemId={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
|
||||
onEnter={handleDelete}
|
||||
>
|
||||
<CommandMenuItem
|
||||
id={TAB_SETTINGS_SELECTABLE_ITEM_IDS.DELETE}
|
||||
Icon={IconTrash}
|
||||
label={t`Delete`}
|
||||
onClick={handleDelete}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
)}
|
||||
</SidePanelGroup>
|
||||
</SidePanelList>
|
||||
<ConfirmationModal
|
||||
modalInstanceId={RESET_TAB_TO_DEFAULT_MODAL_ID}
|
||||
title={t`Reset to default`}
|
||||
subtitle={t`This will cancel all modifications done on the tab and its widgets. Edit mode will be canceled and the page will refresh. This action cannot be undone.`}
|
||||
onConfirmClick={handleConfirmReset}
|
||||
confirmButtonText={t`Reset`}
|
||||
confirmButtonAccent="danger"
|
||||
/>
|
||||
</>
|
||||
<RegularTabSettingsContent
|
||||
canSetAsPinned={canSetAsPinned}
|
||||
canMoveLeft={canMoveLeft}
|
||||
canMoveRight={canMoveRight}
|
||||
canShowResetToDefault={canShowResetToDefault}
|
||||
canDelete={canDelete}
|
||||
onMoveLeft={() => moveLeft(tab.id)}
|
||||
onMoveRight={() => moveRight(tab.id)}
|
||||
onSetAsPinned={() => setAsPinnedTab(tab.id)}
|
||||
onDuplicate={() => duplicateTab(tab.id)}
|
||||
onResetToDefault={handleResetToDefault}
|
||||
onDelete={handleDelete}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
+5
-10
@@ -7,8 +7,8 @@ import { SidePanelGroup } from '@/side-panel/components/SidePanelGroup';
|
||||
import { WidgetVisibilityDropdownContent } from '@/side-panel/pages/page-layout/components/dropdown-content/WidgetVisibilityDropdownContent';
|
||||
import { WIDGET_SETTINGS_SELECTABLE_ITEM_IDS } from '@/side-panel/pages/page-layout/constants/settings/WidgetSettingsSelectableItemIds';
|
||||
import { useNavigatePageLayoutSidePanel } from '@/side-panel/pages/page-layout/hooks/useNavigatePageLayoutSidePanel';
|
||||
import { useTranslatedVisibilityLabel } from '@/side-panel/pages/page-layout/hooks/useTranslatedVisibilityLabel';
|
||||
import { useWidgetInEditMode } from '@/side-panel/pages/page-layout/hooks/useWidgetInEditMode';
|
||||
import { getVisibilityLabel } from '@/side-panel/pages/page-layout/utils/getVisibilityLabel';
|
||||
import { DropdownContent } from '@/ui/layout/dropdown/components/DropdownContent';
|
||||
import { ConfirmationModal } from '@/ui/layout/modal/components/ConfirmationModal';
|
||||
import { useModal } from '@/ui/layout/modal/hooks/useModal';
|
||||
@@ -51,19 +51,14 @@ export const WidgetSettingsManageSection = ({
|
||||
|
||||
const { openModal } = useModal();
|
||||
|
||||
const visibilityLabel = useTranslatedVisibilityLabel(
|
||||
widgetInEditMode?.conditionalAvailabilityExpression,
|
||||
);
|
||||
|
||||
if (!isDefined(pageLayoutEditingWidgetId)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const visibilityLabel = getVisibilityLabel(
|
||||
widgetInEditMode?.conditionalAvailabilityExpression,
|
||||
{
|
||||
anyDevice: t`Any device`,
|
||||
mobile: t`Mobile`,
|
||||
desktop: t`Desktop`,
|
||||
},
|
||||
);
|
||||
|
||||
const handleResetToDefault = () => {
|
||||
openModal(RESET_WIDGET_TO_DEFAULT_MODAL_ID);
|
||||
};
|
||||
|
||||
+75
@@ -0,0 +1,75 @@
|
||||
import { useUpdatePageLayoutWidget } from '@/page-layout/hooks/useUpdatePageLayoutWidget';
|
||||
import { VISIBILITY_OPTIONS } from '@/side-panel/pages/page-layout/constants/VisibilityOptions';
|
||||
import { useVisibilityLabels } from '@/side-panel/pages/page-layout/hooks/useVisibilityLabels';
|
||||
import { expressionToOptionId } from '@/side-panel/pages/page-layout/utils/expressionToOptionId';
|
||||
import { optionIdToExpression } from '@/side-panel/pages/page-layout/utils/optionIdToExpression';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
import { SelectableList } from '@/ui/layout/selectable-list/components/SelectableList';
|
||||
import { SelectableListItem } from '@/ui/layout/selectable-list/components/SelectableListItem';
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
|
||||
type CanvasTabWidgetVisibilityDropdownContentProps = {
|
||||
widgetId: string;
|
||||
currentExpression: string | null | undefined;
|
||||
pageLayoutId: string;
|
||||
};
|
||||
|
||||
export const CanvasTabWidgetVisibilityDropdownContent = ({
|
||||
widgetId,
|
||||
currentExpression,
|
||||
pageLayoutId,
|
||||
}: CanvasTabWidgetVisibilityDropdownContentProps) => {
|
||||
const currentOptionId = expressionToOptionId(currentExpression);
|
||||
|
||||
const dropdownId = useAvailableComponentInstanceIdOrThrow(
|
||||
DropdownComponentInstanceContext,
|
||||
);
|
||||
|
||||
const selectedItemId = useAtomComponentStateValue(
|
||||
selectedItemIdComponentState,
|
||||
dropdownId,
|
||||
);
|
||||
|
||||
const { updatePageLayoutWidget } = useUpdatePageLayoutWidget(pageLayoutId);
|
||||
|
||||
const { closeDropdown } = useCloseDropdown();
|
||||
|
||||
const handleSelectVisibility = (optionId: string) => {
|
||||
updatePageLayoutWidget(widgetId, {
|
||||
conditionalAvailabilityExpression: optionIdToExpression(optionId),
|
||||
});
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
const visibilityLabels = useVisibilityLabels();
|
||||
|
||||
return (
|
||||
<DropdownMenuItemsContainer>
|
||||
<SelectableList
|
||||
selectableListInstanceId={dropdownId}
|
||||
focusId={dropdownId}
|
||||
selectableItemIdArray={VISIBILITY_OPTIONS.map((option) => option.id)}
|
||||
>
|
||||
{VISIBILITY_OPTIONS.map((option) => (
|
||||
<SelectableListItem
|
||||
key={option.id}
|
||||
itemId={option.id}
|
||||
onEnter={() => handleSelectVisibility(option.id)}
|
||||
>
|
||||
<MenuItemSelect
|
||||
text={visibilityLabels[option.id] ?? option.id}
|
||||
selected={currentOptionId === option.id}
|
||||
focused={selectedItemId === option.id}
|
||||
onClick={() => handleSelectVisibility(option.id)}
|
||||
/>
|
||||
</SelectableListItem>
|
||||
))}
|
||||
</SelectableList>
|
||||
</DropdownMenuItemsContainer>
|
||||
);
|
||||
};
|
||||
+5
-49
@@ -1,8 +1,10 @@
|
||||
import { EXPRESSION_DEVICE_DESKTOP } from '@/side-panel/pages/page-layout/constants/ExpressionDeviceDesktop';
|
||||
import { EXPRESSION_DEVICE_MOBILE } from '@/side-panel/pages/page-layout/constants/ExpressionDeviceMobile';
|
||||
import { VISIBILITY_OPTIONS } from '@/side-panel/pages/page-layout/constants/VisibilityOptions';
|
||||
import { usePageLayoutIdFromContextStore } from '@/side-panel/pages/page-layout/hooks/usePageLayoutIdFromContextStore';
|
||||
import { useUpdateCurrentWidgetConfig } from '@/side-panel/pages/page-layout/hooks/useUpdateCurrentWidgetConfig';
|
||||
import { useVisibilityLabels } from '@/side-panel/pages/page-layout/hooks/useVisibilityLabels';
|
||||
import { useWidgetInEditMode } from '@/side-panel/pages/page-layout/hooks/useWidgetInEditMode';
|
||||
import { expressionToOptionId } from '@/side-panel/pages/page-layout/utils/expressionToOptionId';
|
||||
import { optionIdToExpression } from '@/side-panel/pages/page-layout/utils/optionIdToExpression';
|
||||
import { DropdownMenuItemsContainer } from '@/ui/layout/dropdown/components/DropdownMenuItemsContainer';
|
||||
import { DropdownComponentInstanceContext } from '@/ui/layout/dropdown/contexts/DropdownComponentInstanceContext';
|
||||
import { useCloseDropdown } from '@/ui/layout/dropdown/hooks/useCloseDropdown';
|
||||
@@ -11,51 +13,9 @@ import { SelectableListItem } from '@/ui/layout/selectable-list/components/Selec
|
||||
import { selectedItemIdComponentState } from '@/ui/layout/selectable-list/states/selectedItemIdComponentState';
|
||||
import { useAvailableComponentInstanceIdOrThrow } from '@/ui/utilities/state/component-state/hooks/useAvailableComponentInstanceIdOrThrow';
|
||||
import { useAtomComponentStateValue } from '@/ui/utilities/state/jotai/hooks/useAtomComponentStateValue';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
import { MenuItemSelect } from 'twenty-ui/navigation';
|
||||
|
||||
const VISIBILITY_ANY_DEVICE = 'any-device';
|
||||
const VISIBILITY_MOBILE = 'mobile';
|
||||
const VISIBILITY_DESKTOP = 'desktop';
|
||||
|
||||
const VISIBILITY_OPTIONS = [
|
||||
{ id: VISIBILITY_ANY_DEVICE },
|
||||
{ id: VISIBILITY_MOBILE },
|
||||
{ id: VISIBILITY_DESKTOP },
|
||||
] as const;
|
||||
|
||||
const expressionToOptionId = (
|
||||
expression: string | null | undefined,
|
||||
): string => {
|
||||
if (!expression) {
|
||||
return VISIBILITY_ANY_DEVICE;
|
||||
}
|
||||
|
||||
if (expression === EXPRESSION_DEVICE_MOBILE) {
|
||||
return VISIBILITY_MOBILE;
|
||||
}
|
||||
|
||||
if (expression === EXPRESSION_DEVICE_DESKTOP) {
|
||||
return VISIBILITY_DESKTOP;
|
||||
}
|
||||
|
||||
return VISIBILITY_ANY_DEVICE;
|
||||
};
|
||||
|
||||
const optionIdToExpression = (optionId: string): string | null => {
|
||||
switch (optionId) {
|
||||
case VISIBILITY_MOBILE:
|
||||
return EXPRESSION_DEVICE_MOBILE;
|
||||
case VISIBILITY_DESKTOP:
|
||||
return EXPRESSION_DEVICE_DESKTOP;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
export const WidgetVisibilityDropdownContent = () => {
|
||||
const { t } = useLingui();
|
||||
|
||||
const { pageLayoutId } = usePageLayoutIdFromContextStore();
|
||||
|
||||
const { widgetInEditMode } = useWidgetInEditMode(pageLayoutId);
|
||||
@@ -85,11 +45,7 @@ export const WidgetVisibilityDropdownContent = () => {
|
||||
closeDropdown();
|
||||
};
|
||||
|
||||
const visibilityLabels: Record<string, string> = {
|
||||
[VISIBILITY_ANY_DEVICE]: t`Any device`,
|
||||
[VISIBILITY_MOBILE]: t`Mobile`,
|
||||
[VISIBILITY_DESKTOP]: t`Desktop`,
|
||||
};
|
||||
const visibilityLabels = useVisibilityLabels();
|
||||
|
||||
return (
|
||||
<DropdownMenuItemsContainer>
|
||||
|
||||
+1
@@ -0,0 +1 @@
|
||||
export const VISIBILITY_ANY_DEVICE = 'any-device';
|
||||
+1
@@ -0,0 +1 @@
|
||||
export const VISIBILITY_DESKTOP = 'desktop';
|
||||
+1
@@ -0,0 +1 @@
|
||||
export const VISIBILITY_MOBILE = 'mobile';
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
import { VISIBILITY_ANY_DEVICE } from '@/side-panel/pages/page-layout/constants/VisibilityAnyDevice';
|
||||
import { VISIBILITY_DESKTOP } from '@/side-panel/pages/page-layout/constants/VisibilityDesktop';
|
||||
import { VISIBILITY_MOBILE } from '@/side-panel/pages/page-layout/constants/VisibilityMobile';
|
||||
|
||||
export const VISIBILITY_OPTIONS = [
|
||||
{ id: VISIBILITY_ANY_DEVICE },
|
||||
{ id: VISIBILITY_MOBILE },
|
||||
{ id: VISIBILITY_DESKTOP },
|
||||
] as const;
|
||||
+1
@@ -3,6 +3,7 @@ export const TAB_SETTINGS_SELECTABLE_ITEM_IDS = {
|
||||
MOVE_RIGHT: 'tab-move-right',
|
||||
SET_AS_PINNED: 'tab-set-as-pinned',
|
||||
DUPLICATE: 'tab-duplicate',
|
||||
VISIBILITY_RESTRICTION: 'tab-visibility-restriction',
|
||||
RESET_TO_DEFAULT: 'tab-reset-to-default',
|
||||
DELETE: 'tab-delete',
|
||||
} as const;
|
||||
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { getVisibilityLabel } from '@/side-panel/pages/page-layout/utils/getVisibilityLabel';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
|
||||
export const useTranslatedVisibilityLabel = (
|
||||
expression: string | null | undefined,
|
||||
): string => {
|
||||
const { t } = useLingui();
|
||||
|
||||
return getVisibilityLabel(expression, {
|
||||
anyDevice: t`Any device`,
|
||||
mobile: t`Mobile`,
|
||||
desktop: t`Desktop`,
|
||||
});
|
||||
};
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
import { VISIBILITY_ANY_DEVICE } from '@/side-panel/pages/page-layout/constants/VisibilityAnyDevice';
|
||||
import { VISIBILITY_DESKTOP } from '@/side-panel/pages/page-layout/constants/VisibilityDesktop';
|
||||
import { VISIBILITY_MOBILE } from '@/side-panel/pages/page-layout/constants/VisibilityMobile';
|
||||
import { useLingui } from '@lingui/react/macro';
|
||||
|
||||
export const useVisibilityLabels = (): Record<string, string> => {
|
||||
const { t } = useLingui();
|
||||
|
||||
return {
|
||||
[VISIBILITY_ANY_DEVICE]: t`Any device`,
|
||||
[VISIBILITY_MOBILE]: t`Mobile`,
|
||||
[VISIBILITY_DESKTOP]: t`Desktop`,
|
||||
};
|
||||
};
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
import { EXPRESSION_DEVICE_DESKTOP } from '@/side-panel/pages/page-layout/constants/ExpressionDeviceDesktop';
|
||||
import { EXPRESSION_DEVICE_MOBILE } from '@/side-panel/pages/page-layout/constants/ExpressionDeviceMobile';
|
||||
import { VISIBILITY_ANY_DEVICE } from '@/side-panel/pages/page-layout/constants/VisibilityAnyDevice';
|
||||
import { VISIBILITY_DESKTOP } from '@/side-panel/pages/page-layout/constants/VisibilityDesktop';
|
||||
import { VISIBILITY_MOBILE } from '@/side-panel/pages/page-layout/constants/VisibilityMobile';
|
||||
|
||||
export const expressionToOptionId = (
|
||||
expression: string | null | undefined,
|
||||
): string => {
|
||||
if (!expression) {
|
||||
return VISIBILITY_ANY_DEVICE;
|
||||
}
|
||||
|
||||
if (expression === EXPRESSION_DEVICE_MOBILE) {
|
||||
return VISIBILITY_MOBILE;
|
||||
}
|
||||
|
||||
if (expression === EXPRESSION_DEVICE_DESKTOP) {
|
||||
return VISIBILITY_DESKTOP;
|
||||
}
|
||||
|
||||
return VISIBILITY_ANY_DEVICE;
|
||||
};
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
import { EXPRESSION_DEVICE_DESKTOP } from '@/side-panel/pages/page-layout/constants/ExpressionDeviceDesktop';
|
||||
import { EXPRESSION_DEVICE_MOBILE } from '@/side-panel/pages/page-layout/constants/ExpressionDeviceMobile';
|
||||
import { VISIBILITY_DESKTOP } from '@/side-panel/pages/page-layout/constants/VisibilityDesktop';
|
||||
import { VISIBILITY_MOBILE } from '@/side-panel/pages/page-layout/constants/VisibilityMobile';
|
||||
|
||||
export const optionIdToExpression = (optionId: string): string | null => {
|
||||
switch (optionId) {
|
||||
case VISIBILITY_MOBILE:
|
||||
return EXPRESSION_DEVICE_MOBILE;
|
||||
case VISIBILITY_DESKTOP:
|
||||
return EXPRESSION_DEVICE_DESKTOP;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
+3
-3
@@ -140,7 +140,7 @@ export const TAB_PROPS = {
|
||||
title: 'Note',
|
||||
position: 15,
|
||||
icon: 'IconNotes',
|
||||
layoutMode: PageLayoutTabLayoutMode.CANVAS,
|
||||
layoutMode: PageLayoutTabLayoutMode.VERTICAL_LIST,
|
||||
},
|
||||
flow: {
|
||||
title: 'Flow',
|
||||
@@ -203,13 +203,13 @@ export const WIDGET_PROPS = {
|
||||
title: 'Note',
|
||||
type: WidgetType.FIELD_RICH_TEXT,
|
||||
gridPosition: GRID_POSITIONS.RICH_TEXT,
|
||||
position: CANVAS_LAYOUT_POSITIONS.DEFAULT,
|
||||
position: VERTICAL_LIST_LAYOUT_POSITIONS.FIRST,
|
||||
},
|
||||
taskRichText: {
|
||||
title: 'Task',
|
||||
type: WidgetType.FIELD_RICH_TEXT,
|
||||
gridPosition: GRID_POSITIONS.RICH_TEXT,
|
||||
position: CANVAS_LAYOUT_POSITIONS.DEFAULT,
|
||||
position: VERTICAL_LIST_LAYOUT_POSITIONS.FIRST,
|
||||
},
|
||||
workflow: {
|
||||
title: 'Flow',
|
||||
|
||||
Reference in New Issue
Block a user