feat(Color, Dropdown, ModelForm): enhance color handling in Color class and Dropdown options

This commit is contained in:
Nawaz Dhandala
2025-11-11 14:05:30 +00:00
parent 5a41c66953
commit 14a5671645
4 changed files with 75 additions and 10 deletions

View File

@@ -19,9 +19,9 @@ export default class Color extends DatabaseProperty {
this._color = v;
}
public constructor(color: string) {
public constructor(color: string | Color) {
super();
this.color = color;
this.color = color.toString();
}
public override toString(): string {

View File

@@ -31,6 +31,7 @@ export interface DropdownOption {
label: string;
description?: string;
labels?: Array<DropdownOptionLabel>;
color?: Color;
}
export interface ComponentProps {
@@ -266,6 +267,29 @@ const Dropdown: FunctionComponent<ComponentProps> = (
);
};
const renderOptionColorIndicator: (
color?: Color | string,
) => ReactElement | null = (color?: Color | string): ReactElement | null => {
const normalizedColor: string | undefined = color
? new Color(color).toString()
: undefined;
if (!normalizedColor) {
return null;
}
return (
<span
aria-hidden="true"
className="h-2.5 w-2.5 flex-none rounded-full border border-gray-200"
style={{
backgroundColor: normalizedColor,
}}
title={normalizedColor}
></span>
);
};
const getLabelStyle: (color?: string) => {
backgroundColor: string;
color: string;
@@ -401,10 +425,13 @@ const Dropdown: FunctionComponent<ComponentProps> = (
if (meta.context === "value") {
return (
<div className="flex flex-wrap items-center gap-1">
<span className="text-sm font-medium text-gray-900">
{option.label}
</span>
<div className="flex flex-wrap items-center gap-2">
<div className="flex items-center gap-2">
{renderOptionColorIndicator(option.color)}
<span className="text-sm font-medium text-gray-900">
{option.label}
</span>
</div>
{renderAssociatedLabels(
visibleLabels,
meta.context,
@@ -416,9 +443,12 @@ const Dropdown: FunctionComponent<ComponentProps> = (
return (
<div className="flex flex-col gap-1">
<span className="text-sm font-medium text-gray-900">
{option.label}
</span>
<div className="flex items-center gap-2">
{renderOptionColorIndicator(option.color)}
<span className="text-sm font-medium text-gray-900">
{option.label}
</span>
</div>
{option.description ? (
<span className="text-xs text-gray-500">{option.description}</span>
) : null}

View File

@@ -414,6 +414,16 @@ const ModelForm: <TBaseModel extends BaseModel>(
[field.dropdownModal.valueField]: true,
} as any;
let colorColumnName: string | null = null;
let shouldSelectColorColumn: boolean = false;
colorColumnName = tempModel.getFirstColorColumn();
if (colorColumnName) {
select[colorColumnName] = true;
shouldSelectColorColumn = true;
}
const accessControlColumnName: string | null =
tempModel.getAccessControlColumn();
@@ -452,6 +462,15 @@ const ModelForm: <TBaseModel extends BaseModel>(
].toString(),
};
if (colorColumnName && shouldSelectColorColumn) {
const color: Color = item.getColumnValue(
colorColumnName,
) as Color;
if (color) {
option.color = color;
}
}
if (accessControlColumnName) {
const labelsForItem: Array<AccessControlModel> = (
((item as any)[

View File

@@ -1,6 +1,7 @@
import NumberUtil from "../../Utils/Number";
import { DropdownOption } from "../Components/Dropdown/Dropdown";
import BaseModel from "../../Models/DatabaseModels/DatabaseBaseModel/DatabaseBaseModel";
import Color from "../../Types/Color";
type Enum<E> = Record<keyof E, number | string> & { [k: number]: string };
@@ -52,10 +53,25 @@ export default class DropdownUtil {
valueField: string;
}): Array<DropdownOption> {
return data.array.map((item: TBaseModel) => {
return {
const option: DropdownOption = {
label: item.getColumnValue(data.labelField) as string,
value: item.getColumnValue(data.valueField) as string,
};
const colorColumnName: string | null =
typeof item.getFirstColorColumn === "function"
? item.getFirstColorColumn()
: null;
if (colorColumnName) {
const color = item.getColumnValue(colorColumnName) as Color;
if (color) {
option.color = color;
}
}
return option;
});
}