Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d0bcb4d3b0 | ||
|
|
4952332ff3 | ||
|
|
4a3030d83f | ||
|
|
7cd46fe5c0 | ||
|
|
a4025893ba | ||
|
|
8a3a4bf928 | ||
|
|
91da7f852d | ||
|
|
082582026d | ||
|
|
1c87eced8b | ||
|
|
bc4c1fd498 | ||
|
|
97ec8e5752 | ||
|
|
cd36eba13c |
+3
-16
@@ -1,4 +1,5 @@
|
||||
import { type ThemeColor, MAIN_COLOR_NAMES } from 'twenty-ui/theme';
|
||||
import { getDefaultColorForCustomObject } from 'twenty-shared/application';
|
||||
import { type ThemeColor } from 'twenty-ui/theme';
|
||||
|
||||
import { DEFAULT_NAV_ITEM_ICON_COLOR } from '@/navigation-menu-item/constants/NavigationMenuItemDefaultIconColor.constant';
|
||||
import { CoreObjectNameSingular } from 'twenty-shared/types';
|
||||
@@ -19,20 +20,6 @@ const STANDARD_OBJECT_ICON_COLOR: Partial<
|
||||
[CoreObjectNameSingular.WorkflowVersion]: DEFAULT_NAV_ITEM_ICON_COLOR,
|
||||
};
|
||||
|
||||
const CUSTOM_OBJECT_ICON_COLORS: ThemeColor[] = MAIN_COLOR_NAMES.filter(
|
||||
(color) => color !== 'gray',
|
||||
);
|
||||
|
||||
const getColorForCustomObject = (seed: string): ThemeColor => {
|
||||
let hash = 0;
|
||||
for (let index = 0; index < seed.length; index += 1) {
|
||||
hash = (hash << 5) - hash + seed.charCodeAt(index);
|
||||
hash |= 0;
|
||||
}
|
||||
const index = Math.abs(hash) % CUSTOM_OBJECT_ICON_COLORS.length;
|
||||
return CUSTOM_OBJECT_ICON_COLORS[index];
|
||||
};
|
||||
|
||||
export const getStandardObjectIconColor = (nameSingular: string): ThemeColor =>
|
||||
STANDARD_OBJECT_ICON_COLOR[nameSingular as CoreObjectNameSingular] ??
|
||||
getColorForCustomObject(nameSingular);
|
||||
getDefaultColorForCustomObject(nameSingular);
|
||||
|
||||
+9
-8
@@ -187,14 +187,15 @@ export const SidePanelNavigationMenuItemEditPage = () => {
|
||||
commandGroups={[]}
|
||||
selectableItemIds={getOrganizeActionsSelectableItemIds(true)}
|
||||
>
|
||||
{selectedItem && (
|
||||
<SidePanelGroup heading={t`Customize`}>
|
||||
<SidePanelEditColorOption
|
||||
navigationMenuItemId={selectedItem.id}
|
||||
color={parseThemeColor(selectedItem.color)}
|
||||
/>
|
||||
</SidePanelGroup>
|
||||
)}
|
||||
{selectedItem &&
|
||||
selectedItemType !== NavigationMenuItemType.RECORD && (
|
||||
<SidePanelGroup heading={t`Customize`}>
|
||||
<SidePanelEditColorOption
|
||||
navigationMenuItemId={selectedItem.id}
|
||||
color={parseThemeColor(selectedItem.color)}
|
||||
/>
|
||||
</SidePanelGroup>
|
||||
)}
|
||||
<SidePanelEditOrganizeActions
|
||||
canMoveUp={canMoveUp}
|
||||
canMoveDown={canMoveDown}
|
||||
|
||||
+7
-3
@@ -4,9 +4,9 @@ import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { TypeOrmQueryService } from '@ptc-org/nestjs-query-typeorm';
|
||||
import {
|
||||
FeatureFlagKey,
|
||||
ViewKey,
|
||||
ViewOpenRecordIn,
|
||||
ViewType,
|
||||
ViewKey,
|
||||
ViewVisibility,
|
||||
} from 'twenty-shared/types';
|
||||
import { fromArrayToUniqueKeyRecord, isDefined } from 'twenty-shared/utils';
|
||||
@@ -31,6 +31,7 @@ import { fromUpdateObjectInputToFlatObjectMetadataAndRelatedFlatEntities } from
|
||||
import { type FlatPageLayoutTab } from 'src/engine/metadata-modules/flat-page-layout-tab/types/flat-page-layout-tab.type';
|
||||
import { type FlatPageLayoutWidget } from 'src/engine/metadata-modules/flat-page-layout-widget/types/flat-page-layout-widget.type';
|
||||
import { type FlatPageLayout } from 'src/engine/metadata-modules/flat-page-layout/types/flat-page-layout.type';
|
||||
import { getDefaultColorForCustomObject } from 'twenty-shared/application';
|
||||
import { CreateObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/create-object.input';
|
||||
import { DeleteOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/delete-object.input';
|
||||
import { UpdateOneObjectInput } from 'src/engine/metadata-modules/object-metadata/dtos/update-object.input';
|
||||
@@ -470,6 +471,7 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
const flatNavigationMenuItemToCreate =
|
||||
await this.computeFlatNavigationMenuItemToCreate({
|
||||
view: flatDefaultViewToCreate,
|
||||
objectMetadata: flatObjectMetadataToCreate,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId: workspaceCustomFlatApplication.id,
|
||||
workspaceCustomApplicationUniversalIdentifier:
|
||||
@@ -684,11 +686,13 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
|
||||
private async computeFlatNavigationMenuItemToCreate({
|
||||
view,
|
||||
objectMetadata,
|
||||
workspaceId,
|
||||
workspaceCustomApplicationId,
|
||||
workspaceCustomApplicationUniversalIdentifier,
|
||||
}: {
|
||||
view: UniversalFlatView & { id: string };
|
||||
objectMetadata: { nameSingular: string; icon: string | null };
|
||||
workspaceId: string;
|
||||
workspaceCustomApplicationId: string;
|
||||
workspaceCustomApplicationUniversalIdentifier: string;
|
||||
@@ -725,8 +729,8 @@ export class ObjectMetadataService extends TypeOrmQueryService<ObjectMetadataEnt
|
||||
folderUniversalIdentifier: null,
|
||||
name: null,
|
||||
link: null,
|
||||
icon: null,
|
||||
color: null,
|
||||
icon: objectMetadata.icon ?? null,
|
||||
color: getDefaultColorForCustomObject(objectMetadata.nameSingular),
|
||||
position: nextPosition,
|
||||
workspaceId,
|
||||
applicationId: workspaceCustomApplicationId,
|
||||
|
||||
@@ -53,6 +53,7 @@ export type {
|
||||
export type { ServerVariables } from './server-variables.type';
|
||||
export type { SkillManifest } from './skillManifestType';
|
||||
export type { SyncableEntityOptions } from './syncableEntityOptionsType';
|
||||
export { getDefaultColorForCustomObject } from './utils/getDefaultColorForCustomObject.util';
|
||||
export type {
|
||||
ViewManifestFilterValue,
|
||||
ViewFieldManifest,
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import {
|
||||
MAIN_COLOR_NAMES,
|
||||
type ThemeColorName,
|
||||
} from '../../constants/MainColorNames';
|
||||
|
||||
export const getDefaultColorForCustomObject = (
|
||||
nameSingular: string,
|
||||
): ThemeColorName => {
|
||||
const customObjectColors = MAIN_COLOR_NAMES.filter(
|
||||
(color): color is Exclude<ThemeColorName, 'gray'> => color !== 'gray',
|
||||
);
|
||||
let hash = 0;
|
||||
for (let index = 0; index < nameSingular.length; index += 1) {
|
||||
hash = (hash << 5) - hash + nameSingular.charCodeAt(index);
|
||||
hash |= 0;
|
||||
}
|
||||
const index = Math.abs(hash) % customObjectColors.length;
|
||||
return customObjectColors[index];
|
||||
};
|
||||
@@ -0,0 +1,54 @@
|
||||
export type ThemeColorName =
|
||||
| 'red'
|
||||
| 'ruby'
|
||||
| 'crimson'
|
||||
| 'tomato'
|
||||
| 'orange'
|
||||
| 'amber'
|
||||
| 'yellow'
|
||||
| 'lime'
|
||||
| 'grass'
|
||||
| 'green'
|
||||
| 'jade'
|
||||
| 'mint'
|
||||
| 'turquoise'
|
||||
| 'cyan'
|
||||
| 'sky'
|
||||
| 'blue'
|
||||
| 'iris'
|
||||
| 'violet'
|
||||
| 'purple'
|
||||
| 'plum'
|
||||
| 'pink'
|
||||
| 'bronze'
|
||||
| 'gold'
|
||||
| 'brown'
|
||||
| 'gray';
|
||||
|
||||
export const MAIN_COLOR_NAMES: ThemeColorName[] = [
|
||||
'red',
|
||||
'ruby',
|
||||
'crimson',
|
||||
'tomato',
|
||||
'orange',
|
||||
'amber',
|
||||
'yellow',
|
||||
'lime',
|
||||
'grass',
|
||||
'green',
|
||||
'jade',
|
||||
'mint',
|
||||
'turquoise',
|
||||
'cyan',
|
||||
'sky',
|
||||
'blue',
|
||||
'iris',
|
||||
'violet',
|
||||
'purple',
|
||||
'plum',
|
||||
'pink',
|
||||
'bronze',
|
||||
'gold',
|
||||
'brown',
|
||||
'gray',
|
||||
];
|
||||
@@ -29,6 +29,8 @@ export { FILES_FIELD_MAX_NUMBER_OF_VALUES } from './FilesFieldMaxNumberOfValues'
|
||||
export { GROUP_BY_DATE_GRANULARITY_THAT_REQUIRE_TIME_ZONE } from './GroupByDateGranularityThatRequireTimeZone';
|
||||
export { IANA_TIME_ZONES } from './IanaTimeZones';
|
||||
export { LABEL_IDENTIFIER_FIELD_METADATA_TYPES } from './LabelIdentifierFieldMetadataTypes';
|
||||
export type { ThemeColorName } from './MainColorNames';
|
||||
export { MAIN_COLOR_NAMES } from './MainColorNames';
|
||||
export { MULTI_ITEM_FIELD_DEFAULT_MAX_VALUES } from './MultiItemFieldDefaultMaxValues';
|
||||
export { MULTI_ITEM_FIELD_MIN_MAX_VALUES } from './MultiItemFieldMinMaxValues';
|
||||
export { MUTATION_MAX_MERGE_RECORDS } from './MutationMaxMergeRecords';
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { MAIN_COLORS_LIGHT } from './MainColorsLight';
|
||||
import { MAIN_COLOR_NAMES, type ThemeColorName } from 'twenty-shared/constants';
|
||||
|
||||
export const MAIN_COLOR_NAMES = Object.keys(MAIN_COLORS_LIGHT) as ThemeColor[];
|
||||
export { MAIN_COLOR_NAMES };
|
||||
|
||||
export type ThemeColor = keyof typeof MAIN_COLORS_LIGHT;
|
||||
export type ThemeColor = ThemeColorName;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
import * as RadixColors from '@radix-ui/colors';
|
||||
import type { ThemeColorName } from 'twenty-shared/constants';
|
||||
import { GRAY_SCALE_LIGHT } from './GrayScaleLight';
|
||||
|
||||
export const MAIN_COLORS_LIGHT = {
|
||||
export const MAIN_COLORS_LIGHT: Record<ThemeColorName, string> = {
|
||||
// Reds
|
||||
red: RadixColors.redP3.red9,
|
||||
ruby: RadixColors.rubyP3.ruby9,
|
||||
|
||||
Reference in New Issue
Block a user