From 0a6cfe5a6aaa0bd63d7c45339a8c71a4ac2d3021 Mon Sep 17 00:00:00 2001 From: Apoorv Mishra Date: Thu, 4 Aug 2022 14:18:19 +0530 Subject: [PATCH] feat: Choose random color on collection creation (#3912) Choose a random color from a shared color palette between backend and frontend during collection creation. --- app/components/IconPicker.tsx | 16 +++------------- app/scenes/CollectionNew.tsx | 4 +++- server/routes/api/collections.test.ts | 2 ++ server/routes/api/collections.ts | 4 +++- shared/random.ts | 6 +++++- shared/utils/collections.ts | 13 +++++++++++++ 6 files changed, 29 insertions(+), 16 deletions(-) diff --git a/app/components/IconPicker.tsx b/app/components/IconPicker.tsx index c4ce12416..40415d587 100644 --- a/app/components/IconPicker.tsx +++ b/app/components/IconPicker.tsx @@ -40,6 +40,7 @@ import { useTranslation } from "react-i18next"; import { useMenuState, MenuButton, MenuItem } from "reakit/Menu"; import styled, { useTheme } from "styled-components"; import breakpoint from "styled-components-breakpoint"; +import { colorPalette } from "@shared/utils/collections"; import ContextMenu from "~/components/ContextMenu"; import Flex from "~/components/Flex"; import { LabelText } from "~/components/Input"; @@ -200,18 +201,7 @@ export const icons = { keywords: "warning alert error", }, }; -const colors = [ - "#4E5C6E", - "#0366d6", - "#9E5CF7", - "#FF825C", - "#FF5C80", - "#FFBE0B", - "#42DED1", - "#00D084", - "#FF4DFA", - "#2F362F", -]; + type Props = { onOpen?: () => void; onClose?: () => void; @@ -272,7 +262,7 @@ function IconPicker({ onOpen, onClose, icon, color, onChange }: Props) { onChange(color.hex, icon)} - colors={colors} + colors={colorPalette} triangle="hide" styles={{ default: { diff --git a/app/scenes/CollectionNew.tsx b/app/scenes/CollectionNew.tsx index 5ea45a095..8e26bb6bc 100644 --- a/app/scenes/CollectionNew.tsx +++ b/app/scenes/CollectionNew.tsx @@ -3,6 +3,8 @@ import { observable } from "mobx"; import { observer } from "mobx-react"; import * as React from "react"; import { withTranslation, Trans, WithTranslation } from "react-i18next"; +import { randomElement } from "@shared/random"; +import { colorPalette } from "@shared/utils/collections"; import { CollectionValidation } from "@shared/validations"; import RootStore from "~/stores/RootStore"; import Collection from "~/models/Collection"; @@ -30,7 +32,7 @@ class CollectionNew extends React.Component { icon = ""; @observable - color = "#4E5C6E"; + color = randomElement(colorPalette); @observable sharing = true; diff --git a/server/routes/api/collections.test.ts b/server/routes/api/collections.test.ts index 83ef11467..8a25d2b76 100644 --- a/server/routes/api/collections.test.ts +++ b/server/routes/api/collections.test.ts @@ -1,4 +1,5 @@ import TestServer from "fetch-test-server"; +import { colorPalette } from "@shared/utils/collections"; import { Document, CollectionUser, CollectionGroup } from "@server/models"; import webService from "@server/services/web"; import { @@ -1054,6 +1055,7 @@ describe("#collections.create", () => { expect(body.data.name).toBe("Test"); expect(body.data.sort.field).toBe("index"); expect(body.data.sort.direction).toBe("asc"); + expect(colorPalette.includes(body.data.color)).toBeTruthy(); expect(body.policies.length).toBe(1); expect(body.policies[0].abilities.read).toBeTruthy(); }); diff --git a/server/routes/api/collections.ts b/server/routes/api/collections.ts index bc03264d2..611ac760b 100644 --- a/server/routes/api/collections.ts +++ b/server/routes/api/collections.ts @@ -2,6 +2,8 @@ import fractionalIndex from "fractional-index"; import invariant from "invariant"; import Router from "koa-router"; import { Sequelize, Op, WhereOptions } from "sequelize"; +import { randomElement } from "@shared/random"; +import { colorPalette } from "@shared/utils/collections"; import collectionExporter from "@server/commands/collectionExporter"; import teamUpdater from "@server/commands/teamUpdater"; import { sequelize } from "@server/database/sequelize"; @@ -50,7 +52,7 @@ const router = new Router(); router.post("collections.create", auth(), async (ctx) => { const { name, - color, + color = randomElement(colorPalette), description, permission, sharing, diff --git a/shared/random.ts b/shared/random.ts index 5871a7b6b..d0a7c5016 100644 --- a/shared/random.ts +++ b/shared/random.ts @@ -2,4 +2,8 @@ const randomInteger = (min: number, max: number) => { return Math.floor(Math.random() * (max - min + 1) + min); }; -export { randomInteger }; +const randomElement = (arr: T[]): T => { + return arr[randomInteger(0, arr.length - 1)]; +}; + +export { randomInteger, randomElement }; diff --git a/shared/utils/collections.ts b/shared/utils/collections.ts index 16be536b7..9b9e60487 100644 --- a/shared/utils/collections.ts +++ b/shared/utils/collections.ts @@ -28,3 +28,16 @@ export const sortNavigationNodes = ( : document.children, })); }; + +export const colorPalette = [ + "#4E5C6E", + "#0366d6", + "#9E5CF7", + "#FF825C", + "#FF5C80", + "#FFBE0B", + "#42DED1", + "#00D084", + "#FF4DFA", + "#2F362F", +];