АРХ - МЕЖПРОЕКТНАЯ КОММУНИКАЦИЯ: миграция простых CustomSelect-пикеров на SelectionDropdown
This commit is contained in:
parent
305357478e
commit
a49e18d0e5
|
|
@ -23,8 +23,9 @@ import {
|
|||
} from "@plane/propel/icons";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { TExternalContourRequest, TNameDescriptionLoader } from "@plane/types";
|
||||
import { ControlLink, CustomSelect, Header, Row, Tooltip } from "@plane/ui";
|
||||
import { ControlLink, Header, Row, Tooltip } from "@plane/ui";
|
||||
import { copyUrlToClipboard, generateWorkItemLink } from "@plane/utils";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
import { NameDescriptionUpdateStatus } from "@/components/issues/issue-update-status";
|
||||
import { useProject } from "@/hooks/store/use-project";
|
||||
import { useProjectExternalContoursBoard } from "@/hooks/store/use-project-external-contours-board";
|
||||
|
|
@ -228,19 +229,20 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
|||
)}
|
||||
|
||||
{currentMode && !embedIssue && (
|
||||
<CustomSelect
|
||||
value={currentMode}
|
||||
onChange={(value: TExternalContourPeekMode) => setPeekMode(value)}
|
||||
customButton={
|
||||
<SelectionDropdown
|
||||
menuButton={
|
||||
<Tooltip tooltipContent={t("common.toggle_peek_view_layout")}>
|
||||
<button type="button">
|
||||
<span>
|
||||
<currentMode.icon className="h-4 w-4 text-tertiary hover:text-secondary" />
|
||||
</button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
{PEEK_OPTIONS.map((mode) => (
|
||||
<CustomSelect.Option key={mode.key} value={mode.key}>
|
||||
menuButtonWrapperClassName="flex items-center"
|
||||
options={PEEK_OPTIONS.map((mode) => ({
|
||||
key: mode.key,
|
||||
isChecked: currentMode.key === mode.key,
|
||||
onClick: () => setPeekMode(mode.key),
|
||||
title: (
|
||||
<div
|
||||
className={`flex items-center gap-1.5 ${
|
||||
currentMode.key === mode.key ? "text-secondary" : "text-placeholder hover:text-secondary"
|
||||
|
|
@ -249,9 +251,9 @@ export const ExternalContoursIssueActionsHeader = observer(function ExternalCont
|
|||
<mode.icon className="-my-1 h-4 w-4 flex-shrink-0" />
|
||||
{t(mode.i18n_title)}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
)}
|
||||
|
||||
{issue?.project_id && issue.sequence_id && (
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
// plane package imports
|
||||
import type { ChartXAxisProperty } from "@plane/types";
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
|
||||
type Props = {
|
||||
value?: ChartXAxisProperty;
|
||||
|
|
@ -21,16 +21,28 @@ type Props = {
|
|||
export function SelectXAxis(props: Props) {
|
||||
const { value, onChange, options, hiddenOptions, allowNoValue, label } = props;
|
||||
return (
|
||||
<CustomSelect value={value} label={label} onChange={onChange} maxHeight="lg">
|
||||
{allowNoValue && <CustomSelect.Option value={null}>No value</CustomSelect.Option>}
|
||||
{options.map((item) => {
|
||||
if (hiddenOptions?.includes(item.value)) return null;
|
||||
return (
|
||||
<CustomSelect.Option key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</CustomSelect.Option>
|
||||
);
|
||||
})}
|
||||
</CustomSelect>
|
||||
<SelectionDropdown
|
||||
menuButton={label ?? "Select"}
|
||||
options={[
|
||||
...(allowNoValue
|
||||
? [
|
||||
{
|
||||
key: "__none__",
|
||||
title: "No value",
|
||||
isChecked: value == null,
|
||||
onClick: () => onChange(null),
|
||||
},
|
||||
]
|
||||
: []),
|
||||
...options
|
||||
.filter((item) => !hiddenOptions?.includes(item.value))
|
||||
.map((item) => ({
|
||||
key: item.value,
|
||||
title: item.label,
|
||||
isChecked: value === item.value,
|
||||
onClick: () => onChange(item.value),
|
||||
})),
|
||||
]}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { EEstimateSystem } from "@plane/constants";
|
|||
import { ProjectIcon } from "@plane/propel/icons";
|
||||
import type { ChartYAxisMetric } from "@plane/types";
|
||||
// plane package imports
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
// hooks
|
||||
import { useProjectEstimates } from "@/hooks/store/estimates";
|
||||
// plane web constants
|
||||
|
|
@ -44,27 +44,22 @@ export const SelectYAxis = observer(function SelectYAxis({ value, onChange, hidd
|
|||
};
|
||||
|
||||
return (
|
||||
<CustomSelect
|
||||
value={value}
|
||||
label={
|
||||
<SelectionDropdown
|
||||
menuButton={
|
||||
<div className="flex items-center gap-2">
|
||||
<ProjectIcon className="h-3 w-3" />
|
||||
<span>{options.find((v) => v.value === value)?.label ?? "Add Metric"}</span>
|
||||
</div>
|
||||
}
|
||||
onChange={onChange}
|
||||
maxHeight="lg"
|
||||
>
|
||||
{options.map((item) => {
|
||||
if (hiddenOptions?.includes(item.value)) return null;
|
||||
return (
|
||||
isEstimateEnabled(item.value) && (
|
||||
<CustomSelect.Option key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</CustomSelect.Option>
|
||||
)
|
||||
);
|
||||
})}
|
||||
</CustomSelect>
|
||||
options={options
|
||||
.filter((item) => !hiddenOptions?.includes(item.value))
|
||||
.filter((item) => isEstimateEnabled(item.value))
|
||||
.map((item) => ({
|
||||
key: item.value,
|
||||
title: item.label,
|
||||
isChecked: value === item.value,
|
||||
onClick: () => onChange(item.value),
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -25,11 +25,12 @@ type Props = {
|
|||
menuButtonWrapperClassName?: string;
|
||||
options: TSelectionDropdownOption[];
|
||||
placement?: Placement;
|
||||
tabIndex?: number;
|
||||
title?: ReactNode;
|
||||
};
|
||||
|
||||
export function SelectionDropdown(props: Props) {
|
||||
const { disabled = false, menuButton, menuButtonWrapperClassName, options, placement = "bottom-start", title } = props;
|
||||
const { disabled = false, menuButton, menuButtonWrapperClassName, options, placement = "bottom-start", tabIndex, title } = props;
|
||||
|
||||
const renderedOptions = options.filter((option) => option.shouldRender !== false);
|
||||
|
||||
|
|
@ -39,6 +40,7 @@ export function SelectionDropdown(props: Props) {
|
|||
menuButtonWrapperClassName={menuButtonWrapperClassName}
|
||||
placement={placement}
|
||||
disabled={disabled}
|
||||
tabIndex={tabIndex}
|
||||
>
|
||||
{({ closeDropdown }) => (
|
||||
<div className="vertical-scrollbar relative scrollbar-sm h-full w-full overflow-y-auto px-2.5 py-2">
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import React from "react";
|
|||
import { CalendarDays } from "lucide-react";
|
||||
// ui
|
||||
import { CalendarAfterIcon, CalendarBeforeIcon } from "@plane/propel/icons";
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
|
||||
type Props = {
|
||||
title: string;
|
||||
|
|
@ -42,9 +42,8 @@ const dueDateRange: DueDate[] = [
|
|||
|
||||
export function DateFilterSelect({ title, value, onChange }: Props) {
|
||||
return (
|
||||
<CustomSelect
|
||||
value={value}
|
||||
label={
|
||||
<SelectionDropdown
|
||||
menuButton={
|
||||
<div className="flex items-center gap-2 text-11">
|
||||
{dueDateRange.find((item) => item.value === value)?.icon}
|
||||
<span>
|
||||
|
|
@ -52,16 +51,18 @@ export function DateFilterSelect({ title, value, onChange }: Props) {
|
|||
</span>
|
||||
</div>
|
||||
}
|
||||
onChange={onChange}
|
||||
>
|
||||
{dueDateRange.map((option, index) => (
|
||||
<CustomSelect.Option key={index} value={option.value}>
|
||||
menuButtonWrapperClassName="flex items-center"
|
||||
options={dueDateRange.map((option) => ({
|
||||
key: option.value,
|
||||
isChecked: value === option.value,
|
||||
onClick: () => onChange(option.value),
|
||||
title: (
|
||||
<div className="flex items-center gap-2">
|
||||
<span>{option.icon}</span>
|
||||
{title} {option.name}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import type { I_THEME_OPTION } from "@plane/constants";
|
|||
import { THEME_OPTIONS } from "@plane/constants";
|
||||
import { useTranslation } from "@plane/i18n";
|
||||
// constants
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
// ui
|
||||
|
||||
type Props = {
|
||||
|
|
@ -22,70 +22,54 @@ export function ThemeSwitch(props: Props) {
|
|||
// translation
|
||||
const { t } = useTranslation();
|
||||
|
||||
const renderThemeSwatch = (themeOption: I_THEME_OPTION) => (
|
||||
<div
|
||||
className="relative flex h-4 w-4 rotate-45 transform items-center justify-center rounded-full border-1"
|
||||
style={{
|
||||
borderColor: themeOption.icon.border,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="h-full w-1/2 rounded-l-full"
|
||||
style={{
|
||||
background: themeOption.icon.color1,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="h-full w-1/2 rounded-r-full border-l"
|
||||
style={{
|
||||
borderLeftColor: themeOption.icon.border,
|
||||
background: themeOption.icon.color2,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
return (
|
||||
<CustomSelect
|
||||
value={value}
|
||||
label={
|
||||
<SelectionDropdown
|
||||
placement="bottom-end"
|
||||
menuButton={
|
||||
value ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<div
|
||||
className="relative flex h-4 w-4 rotate-45 transform items-center justify-center rounded-full border-1"
|
||||
style={{
|
||||
borderColor: value.icon.border,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="h-full w-1/2 rounded-l-full"
|
||||
style={{
|
||||
background: value.icon.color1,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="h-full w-1/2 rounded-r-full border-l"
|
||||
style={{
|
||||
borderLeftColor: value.icon.border,
|
||||
background: value.icon.color2,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{renderThemeSwatch(value)}
|
||||
{t(value.key)}
|
||||
</div>
|
||||
) : (
|
||||
t("select_your_theme")
|
||||
)
|
||||
}
|
||||
onChange={onChange}
|
||||
buttonClassName="border border-subtle-1"
|
||||
placement="bottom-end"
|
||||
input
|
||||
>
|
||||
{THEME_OPTIONS.map((themeOption) => (
|
||||
<CustomSelect.Option key={themeOption.value} value={themeOption}>
|
||||
menuButtonWrapperClassName="flex w-full items-center justify-between rounded-full border border-subtle-1 px-3 py-2 text-13"
|
||||
options={THEME_OPTIONS.map((themeOption) => ({
|
||||
key: themeOption.value,
|
||||
isChecked: value?.value === themeOption.value,
|
||||
onClick: () => onChange(themeOption),
|
||||
title: (
|
||||
<div className="flex items-center gap-2">
|
||||
<div
|
||||
className="relative flex h-4 w-4 rotate-45 transform items-center justify-center rounded-full border border-1"
|
||||
style={{
|
||||
borderColor: themeOption.icon.border,
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className="h-full w-1/2 rounded-l-full"
|
||||
style={{
|
||||
background: themeOption.icon.color1,
|
||||
}}
|
||||
/>
|
||||
<div
|
||||
className="h-full w-1/2 rounded-r-full border-l"
|
||||
style={{
|
||||
borderLeftColor: themeOption.icon.border,
|
||||
background: themeOption.icon.color2,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{renderThemeSwatch(themeOption)}
|
||||
{t(themeOption.key)}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import React from "react";
|
|||
import { observer } from "mobx-react";
|
||||
import type { TCycleEstimateType } from "@plane/types";
|
||||
import { EEstimateSystem } from "@plane/types";
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
import { useProjectEstimates } from "@/hooks/store/estimates";
|
||||
import { useCycle } from "@/hooks/store/use-cycle";
|
||||
// local imports
|
||||
|
|
@ -30,19 +30,16 @@ export const EstimateTypeDropdown = observer(function EstimateTypeDropdown(props
|
|||
return (getIsPointsDataAvailable(cycleId) || isCurrentProjectEstimateEnabled) &&
|
||||
currentProjectEstimateType !== EEstimateSystem.CATEGORIES ? (
|
||||
<div className="relative flex items-center gap-2">
|
||||
<CustomSelect
|
||||
value={value}
|
||||
label={<span>{cycleEstimateOptions.find((v) => v.value === value)?.label ?? "None"}</span>}
|
||||
onChange={onChange}
|
||||
maxHeight="lg"
|
||||
buttonClassName="bg-surface-2 border-none rounded-sm text-13 font-medium "
|
||||
>
|
||||
{cycleEstimateOptions.map((item) => (
|
||||
<CustomSelect.Option key={item.value} value={item.value}>
|
||||
{item.label}
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
<SelectionDropdown
|
||||
menuButton={<span>{cycleEstimateOptions.find((v) => v.value === value)?.label ?? "None"}</span>}
|
||||
menuButtonWrapperClassName="flex items-center rounded-sm bg-surface-2 px-2 py-1 text-13 font-medium"
|
||||
options={cycleEstimateOptions.map((item) => ({
|
||||
key: item.value,
|
||||
title: item.label,
|
||||
isChecked: value === item.value,
|
||||
onClick: () => onChange(item.value),
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
) : showDefault ? (
|
||||
<span className="capitalize">{cycleEstimateOptions.find((v) => v.value === value)?.label ?? value}</span>
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
|||
import { Tooltip } from "@plane/propel/tooltip";
|
||||
import type { TNameDescriptionLoader } from "@plane/types";
|
||||
import { EIssuesStoreType } from "@plane/types";
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
import { copyUrlToClipboard, generateWorkItemLink } from "@plane/utils";
|
||||
// hooks
|
||||
import { useIssueDetail } from "@/hooks/store/use-issue-detail";
|
||||
|
|
@ -185,19 +185,20 @@ export const IssuePeekOverviewHeader = observer(function IssuePeekOverviewHeader
|
|||
</Tooltip>
|
||||
{currentMode && showLayoutSwitcher && (
|
||||
<div className="flex flex-shrink-0 items-center gap-2">
|
||||
<CustomSelect
|
||||
value={currentMode}
|
||||
onChange={(val: any) => setPeekMode(val)}
|
||||
customButton={
|
||||
<SelectionDropdown
|
||||
menuButton={
|
||||
<Tooltip tooltipContent={t("common.toggle_peek_view_layout")} isMobile={isMobile}>
|
||||
<button type="button" className="">
|
||||
<span>
|
||||
<currentMode.icon className="h-4 w-4 text-tertiary hover:text-secondary" />
|
||||
</button>
|
||||
</span>
|
||||
</Tooltip>
|
||||
}
|
||||
>
|
||||
{PEEK_OPTIONS.map((mode) => (
|
||||
<CustomSelect.Option key={mode.key} value={mode.key}>
|
||||
menuButtonWrapperClassName="flex items-center"
|
||||
options={PEEK_OPTIONS.map((mode) => ({
|
||||
key: mode.key,
|
||||
isChecked: currentMode.key === mode.key,
|
||||
onClick: () => setPeekMode(mode.key),
|
||||
title: (
|
||||
<div
|
||||
className={`flex items-center gap-1.5 ${
|
||||
currentMode.key === mode.key ? "text-secondary" : "text-placeholder hover:text-secondary"
|
||||
|
|
@ -206,9 +207,9 @@ export const IssuePeekOverviewHeader = observer(function IssuePeekOverviewHeader
|
|||
<mode.icon className="-my-1 h-4 w-4 flex-shrink-0" />
|
||||
{t(mode.i18n_title)}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
{metaSlot}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import { useTranslation } from "@plane/i18n";
|
|||
import type { TModuleStatus } from "@plane/propel/icons";
|
||||
import { ModuleStatusIcon } from "@plane/propel/icons";
|
||||
import type { IModule } from "@plane/types";
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
|
||||
type Props = {
|
||||
isDisabled: boolean;
|
||||
|
|
@ -27,8 +27,8 @@ export const ModuleStatusDropdown = observer(function ModuleStatusDropdown(props
|
|||
if (!moduleStatus) return <></>;
|
||||
|
||||
return (
|
||||
<CustomSelect
|
||||
customButton={
|
||||
<SelectionDropdown
|
||||
menuButton={
|
||||
<span
|
||||
className={`flex h-6 w-20 items-center justify-center rounded-sm text-center text-11 ${
|
||||
isDisabled ? "cursor-not-allowed" : "cursor-pointer"
|
||||
|
|
@ -41,20 +41,19 @@ export const ModuleStatusDropdown = observer(function ModuleStatusDropdown(props
|
|||
{(moduleStatus && t(moduleStatus?.i18n_label)) ?? t("project_modules.status.backlog")}
|
||||
</span>
|
||||
}
|
||||
value={moduleStatus?.value}
|
||||
onChange={(val: TModuleStatus) => {
|
||||
handleModuleDetailsChange({ status: val });
|
||||
}}
|
||||
disabled={isDisabled}
|
||||
>
|
||||
{MODULE_STATUS.map((status) => (
|
||||
<CustomSelect.Option key={status.value} value={status.value}>
|
||||
menuButtonWrapperClassName="flex"
|
||||
options={MODULE_STATUS.map((status) => ({
|
||||
key: status.value,
|
||||
isChecked: moduleStatus?.value === status.value,
|
||||
onClick: () => handleModuleDetailsChange({ status: status.value as TModuleStatus }),
|
||||
title: (
|
||||
<div className="flex items-center gap-2">
|
||||
<ModuleStatusIcon status={status.value} />
|
||||
{t(status.i18n_label)}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { useTranslation } from "@plane/i18n";
|
|||
import { StatePropertyIcon, ModuleStatusIcon } from "@plane/propel/icons";
|
||||
import type { IModule } from "@plane/types";
|
||||
// ui
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
// types
|
||||
// constants
|
||||
|
||||
|
|
@ -34,9 +34,8 @@ export function ModuleStatusSelect({ control, error, tabIndex }: Props) {
|
|||
render={({ field: { value, onChange } }) => {
|
||||
const selectedValue = MODULE_STATUS.find((s) => s.value === value);
|
||||
return (
|
||||
<CustomSelect
|
||||
value={value}
|
||||
label={
|
||||
<SelectionDropdown
|
||||
menuButton={
|
||||
<div
|
||||
className={`flex items-center justify-center gap-2 py-0.5 text-11 ${error ? "text-danger-primary" : ""}`}
|
||||
>
|
||||
|
|
@ -50,19 +49,20 @@ export function ModuleStatusSelect({ control, error, tabIndex }: Props) {
|
|||
)}
|
||||
</div>
|
||||
}
|
||||
onChange={onChange}
|
||||
tabIndex={tabIndex}
|
||||
noChevron
|
||||
>
|
||||
{MODULE_STATUS.map((status) => (
|
||||
<CustomSelect.Option key={status.value} value={status.value}>
|
||||
menuButtonWrapperClassName="flex"
|
||||
options={MODULE_STATUS.map((status) => ({
|
||||
key: status.value,
|
||||
isChecked: value === status.value,
|
||||
onClick: () => onChange(status.value),
|
||||
title: (
|
||||
<div className="flex items-center gap-2">
|
||||
<ModuleStatusIcon status={status.value} />
|
||||
{t(status.i18n_label)}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
);
|
||||
}}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import { useTranslation } from "@plane/i18n";
|
|||
import { StatePropertyIcon } from "@plane/propel/icons";
|
||||
import type { IModule } from "@plane/types";
|
||||
// ui
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
// types
|
||||
// common
|
||||
// constants
|
||||
|
|
@ -38,8 +38,8 @@ export function SidebarStatusSelect({ control, submitChanges, watch }: Props) {
|
|||
control={control}
|
||||
name="status"
|
||||
render={({ field: { value } }) => (
|
||||
<CustomSelect
|
||||
label={
|
||||
<SelectionDropdown
|
||||
menuButton={
|
||||
<span className={`flex items-center gap-2 text-left capitalize ${value ? "" : "text-primary"}`}>
|
||||
<span
|
||||
className="h-2 w-2 flex-shrink-0 rounded-full"
|
||||
|
|
@ -50,20 +50,19 @@ export function SidebarStatusSelect({ control, submitChanges, watch }: Props) {
|
|||
{watch("status")}
|
||||
</span>
|
||||
}
|
||||
value={value}
|
||||
onChange={(value: any) => {
|
||||
submitChanges({ status: value });
|
||||
}}
|
||||
>
|
||||
{MODULE_STATUS.map((option) => (
|
||||
<CustomSelect.Option key={option.value} value={option.value}>
|
||||
menuButtonWrapperClassName="flex"
|
||||
options={MODULE_STATUS.map((option) => ({
|
||||
key: option.value,
|
||||
isChecked: value === option.value,
|
||||
onClick: () => submitChanges({ status: option.value }),
|
||||
title: (
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="h-2 w-2 flex-shrink-0 rounded-full" style={{ backgroundColor: option.color }} />
|
||||
{t(option.i18n_label)}
|
||||
</div>
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</CustomSelect>
|
||||
),
|
||||
}))}
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import { observer } from "mobx-react";
|
|||
import { START_OF_THE_WEEK_OPTIONS } from "@plane/constants";
|
||||
import { TOAST_TYPE, setToast } from "@plane/propel/toast";
|
||||
import type { EStartOfTheWeek } from "@plane/types";
|
||||
import { CustomSelect } from "@plane/ui";
|
||||
import { SelectionDropdown } from "@/components/common/selection-dropdown";
|
||||
// components
|
||||
import { SettingsControlItem } from "@/components/settings/control-item";
|
||||
// hooks
|
||||
|
|
@ -38,23 +38,17 @@ export const StartOfWeekPreference = observer(function StartOfWeekPreference(pro
|
|||
title={props.option.title}
|
||||
description={props.option.description}
|
||||
control={
|
||||
<CustomSelect
|
||||
value={userProfile.start_of_the_week}
|
||||
label={getStartOfWeekLabel(userProfile.start_of_the_week)}
|
||||
onChange={handleStartOfWeekChange}
|
||||
buttonClassName="border border-subtle-1"
|
||||
input
|
||||
maxHeight="lg"
|
||||
<SelectionDropdown
|
||||
placement="bottom-end"
|
||||
>
|
||||
<>
|
||||
{START_OF_THE_WEEK_OPTIONS.map((day) => (
|
||||
<CustomSelect.Option key={day.value} value={day.value}>
|
||||
{day.label}
|
||||
</CustomSelect.Option>
|
||||
))}
|
||||
</>
|
||||
</CustomSelect>
|
||||
menuButton={getStartOfWeekLabel(userProfile.start_of_the_week)}
|
||||
menuButtonWrapperClassName="flex w-full items-center justify-between rounded-full border border-subtle-1 px-3 py-2 text-13"
|
||||
options={START_OF_THE_WEEK_OPTIONS.map((day) => ({
|
||||
key: `${day.value}`,
|
||||
title: day.label,
|
||||
isChecked: userProfile.start_of_the_week === day.value,
|
||||
onClick: () => handleStartOfWeekChange(day.value),
|
||||
}))}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
|
|
|||
Loading…
Reference in New Issue