mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2025-09-26 00:40:13 +00:00
fix: display duplicate entry (#5853)
* fix: some issue * fix: add colors * fix: do not allow people who are not appflowy
This commit is contained in:
parent
dda798752f
commit
4b0368d552
@ -59,17 +59,6 @@ function AsTemplate ({
|
|||||||
await loadTemplate();
|
await loadTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
notify.info({
|
|
||||||
type: 'success',
|
|
||||||
title: t('template.uploadSuccess'),
|
|
||||||
message: t('template.uploadSuccessDescription'),
|
|
||||||
okText: t('template.viewTemplate'),
|
|
||||||
onOk: () => {
|
|
||||||
const url = import.meta.env.AF_BASE_URL?.includes('test') ? 'https://test.appflowy.io' : 'https://appflowy.io';
|
|
||||||
|
|
||||||
window.open(`${url}/templates/${selectedCategoryIds[0]}/${viewId}`, '_blank');
|
|
||||||
},
|
|
||||||
});
|
|
||||||
handleBack();
|
handleBack();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
@ -77,8 +66,7 @@ function AsTemplate ({
|
|||||||
notify.error(error.toString());
|
notify.error(error.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
}, [service, selectedCreatorId, selectedCategoryIds, viewId, isNewTemplate, isFeatured, viewUrl, template, t, handleBack, loadTemplate]);
|
}, [service, selectedCreatorId, selectedCategoryIds, isNewTemplate, isFeatured, viewId, viewUrl, template, loadTemplate, handleBack]);
|
||||||
|
|
||||||
const submitRef = React.useRef<HTMLInputElement>(null);
|
const submitRef = React.useRef<HTMLInputElement>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -8,7 +8,58 @@ import { ReactComponent as CloudUploadIcon } from '@/assets/cloud_add.svg';
|
|||||||
|
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
function CreatorAvatar ({ src, name, enableUpload, onChange, size }: {
|
const colorArray = [
|
||||||
|
'#5287D8',
|
||||||
|
'#6E9DE3',
|
||||||
|
'#8BB3ED',
|
||||||
|
'#A7C9F7',
|
||||||
|
'#979EB6',
|
||||||
|
'#A2A8BF',
|
||||||
|
'#ACB2C8',
|
||||||
|
'#C1C7DA',
|
||||||
|
'#E8AF53',
|
||||||
|
'#E6C25A',
|
||||||
|
'#E6D26F',
|
||||||
|
'#E6E288',
|
||||||
|
'#589599',
|
||||||
|
'#68AD8E',
|
||||||
|
'#79C47F',
|
||||||
|
'#8CDB6A',
|
||||||
|
'#AA94DC',
|
||||||
|
'#C49EEB',
|
||||||
|
'#BAACEE',
|
||||||
|
'#D5C4FB',
|
||||||
|
'#F597D2',
|
||||||
|
'#FCB2E3',
|
||||||
|
'#FDC5E8',
|
||||||
|
'#F8D2E1',
|
||||||
|
'#D1D269',
|
||||||
|
'#C7C98D',
|
||||||
|
'#CED09B',
|
||||||
|
'#DAD9B6',
|
||||||
|
'#DDD2C6',
|
||||||
|
'#DDD6C7',
|
||||||
|
'#EADED3',
|
||||||
|
'#FED5C4',
|
||||||
|
'#72A7D8',
|
||||||
|
'#8FCAE3',
|
||||||
|
'#64B3DA',
|
||||||
|
'#52B2D4',
|
||||||
|
'#90A4FF',
|
||||||
|
'#A8BEF4',
|
||||||
|
'#AEBDFF',
|
||||||
|
'#C2CDFF',
|
||||||
|
'#86C1B7',
|
||||||
|
'#A6D8D0',
|
||||||
|
'#A7D7A8',
|
||||||
|
'#C8E4C9',
|
||||||
|
'#FF9494',
|
||||||
|
'#FFBDBD',
|
||||||
|
'#DCA8A8',
|
||||||
|
'#E3C4C4',
|
||||||
|
];
|
||||||
|
|
||||||
|
function CreatorAvatar({ src, name, enableUpload, onChange, size }: {
|
||||||
src: string;
|
src: string;
|
||||||
name: string;
|
name: string;
|
||||||
enableUpload?: boolean;
|
enableUpload?: boolean;
|
||||||
@ -20,7 +71,7 @@ function CreatorAvatar ({ src, name, enableUpload, onChange, size }: {
|
|||||||
|
|
||||||
const [tab, setTab] = React.useState(0);
|
const [tab, setTab] = React.useState(0);
|
||||||
const avatarProps = useMemo(() => {
|
const avatarProps = useMemo(() => {
|
||||||
return stringAvatar(name || '');
|
return stringAvatar(name || '', colorArray);
|
||||||
}, [name]);
|
}, [name]);
|
||||||
const [openModal, setOpenModal] = React.useState(false);
|
const [openModal, setOpenModal] = React.useState(false);
|
||||||
|
|
||||||
@ -46,15 +97,21 @@ function CreatorAvatar ({ src, name, enableUpload, onChange, size }: {
|
|||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Avatar src={src} className={'w-full h-full object-cover p-2'} {...avatarProps} sx={{
|
<Avatar
|
||||||
...avatarProps?.sx,
|
src={src}
|
||||||
bgcolor: imageUrl ? 'var(--bg-body)' : avatarProps?.sx.bgcolor,
|
className={'w-full h-full object-cover p-2'} {...avatarProps}
|
||||||
width: size || undefined,
|
sx={{
|
||||||
height: size || undefined,
|
...avatarProps?.sx,
|
||||||
}}
|
bgcolor: imageUrl ? 'var(--bg-body)' : avatarProps?.sx.bgcolor,
|
||||||
|
width: size || undefined,
|
||||||
|
height: size || undefined,
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
{enableUpload && showUpload && (
|
{enableUpload && showUpload && (
|
||||||
<Tooltip title={t('template.creator.uploadAvatar')} arrow>
|
<Tooltip
|
||||||
|
title={t('template.creator.uploadAvatar')}
|
||||||
|
arrow
|
||||||
|
>
|
||||||
<Button
|
<Button
|
||||||
component="label"
|
component="label"
|
||||||
role={undefined}
|
role={undefined}
|
||||||
@ -79,24 +136,38 @@ function CreatorAvatar ({ src, name, enableUpload, onChange, size }: {
|
|||||||
disabled: !imageUrl,
|
disabled: !imageUrl,
|
||||||
}}
|
}}
|
||||||
onOk={() => {
|
onOk={() => {
|
||||||
if (!imageUrl) return;
|
if(!imageUrl) return;
|
||||||
onChange?.(imageUrl);
|
onChange?.(imageUrl);
|
||||||
setOpenModal(false);
|
setOpenModal(false);
|
||||||
}} title={t('template.uploadAvatar')}
|
}}
|
||||||
|
title={t('template.uploadAvatar')}
|
||||||
onCancel={() => setOpenModal(false)}
|
onCancel={() => setOpenModal(false)}
|
||||||
onClose={() => setOpenModal(false)} open={openModal}
|
onClose={() => setOpenModal(false)}
|
||||||
|
open={openModal}
|
||||||
>
|
>
|
||||||
<div className={'min-w-[400px] flex flex-col gap-4'}>
|
<div className={'min-w-[400px] flex flex-col gap-4'}>
|
||||||
<ViewTabs value={tab} onChange={(_, newValue) => {
|
<ViewTabs
|
||||||
setTab(newValue);
|
value={tab}
|
||||||
setImageUrl(src);
|
onChange={(_, newValue) => {
|
||||||
}}
|
setTab(newValue);
|
||||||
|
setImageUrl(src);
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<ViewTab value={0} label={t('document.imageBlock.embedLink.label')} />
|
<ViewTab
|
||||||
<ViewTab value={1} label={t('button.upload')} />
|
value={0}
|
||||||
|
label={t('document.imageBlock.embedLink.label')}
|
||||||
|
/>
|
||||||
|
<ViewTab
|
||||||
|
value={1}
|
||||||
|
label={t('button.upload')}
|
||||||
|
/>
|
||||||
|
|
||||||
</ViewTabs>
|
</ViewTabs>
|
||||||
<TabPanel className={'w-full'} value={tab} index={0}>
|
<TabPanel
|
||||||
|
className={'w-full'}
|
||||||
|
value={tab}
|
||||||
|
index={0}
|
||||||
|
>
|
||||||
<OutlinedInput
|
<OutlinedInput
|
||||||
size={'small'}
|
size={'small'}
|
||||||
value={imageUrl}
|
value={imageUrl}
|
||||||
@ -109,7 +180,11 @@ function CreatorAvatar ({ src, name, enableUpload, onChange, size }: {
|
|||||||
placeholder={t('document.imageBlock.embedLink.placeholder')}
|
placeholder={t('document.imageBlock.embedLink.placeholder')}
|
||||||
/>
|
/>
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
<TabPanel className={'w-full flex flex-col gap-2'} value={tab} index={1}>
|
<TabPanel
|
||||||
|
className={'w-full flex flex-col gap-2'}
|
||||||
|
value={tab}
|
||||||
|
index={1}
|
||||||
|
>
|
||||||
<UploadAvatar onChange={setImageUrl} />
|
<UploadAvatar onChange={setImageUrl} />
|
||||||
</TabPanel>
|
</TabPanel>
|
||||||
|
|
||||||
|
@ -2,9 +2,7 @@ import { TemplateSummary, TemplateCategory } from '@/application/template.type';
|
|||||||
import CreatorAvatar from '@/components/as-template/creator/CreatorAvatar';
|
import CreatorAvatar from '@/components/as-template/creator/CreatorAvatar';
|
||||||
import React, { useMemo } from 'react';
|
import React, { useMemo } from 'react';
|
||||||
|
|
||||||
const url = import.meta.env.AF_BASE_URL?.includes('test') ? 'https://test.appflowy.io' : 'https://appflowy.io';
|
function TemplateItem({ template, category }: { template: TemplateSummary; category: TemplateCategory }) {
|
||||||
|
|
||||||
function TemplateItem ({ template, category }: { template: TemplateSummary; category: TemplateCategory }) {
|
|
||||||
const iframeUrl = useMemo(() => {
|
const iframeUrl = useMemo(() => {
|
||||||
const url = new URL(template.view_url);
|
const url = new URL(template.view_url);
|
||||||
|
|
||||||
@ -17,20 +15,26 @@ function TemplateItem ({ template, category }: { template: TemplateSummary; cate
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<a
|
<div
|
||||||
href={`${url}/templates/${category.id}/${template.view_id}`}
|
|
||||||
className={'relative rounded-[16px] pt-4 px-4 h-[230px] w-full overflow-hidden'}
|
className={'relative rounded-[16px] pt-4 px-4 h-[230px] w-full overflow-hidden'}
|
||||||
target={'_blank'}
|
|
||||||
style={{
|
style={{
|
||||||
backgroundColor: category?.bg_color,
|
backgroundColor: category?.bg_color,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<iframe loading={'lazy'} className={'w-full h-full'} src={iframeUrl} />
|
<iframe
|
||||||
</a>
|
loading={'lazy'}
|
||||||
|
className={'w-full h-full'}
|
||||||
|
src={iframeUrl}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<div className={'template-info'}>
|
<div className={'template-info'}>
|
||||||
<div className={'template-creator'}>
|
<div className={'template-creator'}>
|
||||||
<div className={'avatar'}>
|
<div className={'avatar'}>
|
||||||
<CreatorAvatar size={40} src={template.creator.avatar_url} name={template.creator.name} />
|
<CreatorAvatar
|
||||||
|
size={40}
|
||||||
|
src={template.creator.avatar_url}
|
||||||
|
name={template.creator.name}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div className={'right-info'}>
|
<div className={'right-info'}>
|
||||||
<div className={'template-name'}>{template.name}</div>
|
<div className={'template-name'}>{template.name}</div>
|
||||||
|
@ -5,7 +5,7 @@ import CardField from '@/components/database/components/field/CardField';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { EventWrapperProps } from 'react-big-calendar';
|
import { EventWrapperProps } from 'react-big-calendar';
|
||||||
|
|
||||||
export function Event({ event }: EventWrapperProps<CalendarEvent>) {
|
export function Event ({ event }: EventWrapperProps<CalendarEvent>) {
|
||||||
const { id } = event;
|
const { id } = event;
|
||||||
const [rowId] = id.split(':');
|
const [rowId] = id.split(':');
|
||||||
const showFields = useFieldsSelector();
|
const showFields = useFieldsSelector();
|
||||||
@ -15,7 +15,7 @@ export function Event({ event }: EventWrapperProps<CalendarEvent>) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'px-1 py-0.5'}>
|
<div className={'px-1 py-0.5'}>
|
||||||
<RichTooltip content={<EventPaper rowId={rowId} />} open={open} placement='right' onClose={() => setOpen(false)}>
|
<RichTooltip content={<EventPaper rowId={rowId} />} open={open} placement="right" onClose={() => setOpen(false)}>
|
||||||
<div
|
<div
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (window.innerWidth < 768) {
|
if (window.innerWidth < 768) {
|
||||||
@ -25,7 +25,7 @@ export function Event({ event }: EventWrapperProps<CalendarEvent>) {
|
|||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
className={
|
className={
|
||||||
'flex min-h-[24px] cursor-pointer flex-col gap-2 rounded-md border border-line-border bg-bg-body p-2 text-xs text-xs shadow-sm hover:bg-fill-list-active hover:shadow'
|
'flex min-h-[24px] cursor-pointer flex-col gap-2 rounded-md border border-line-divider bg-bg-body p-2 text-xs shadow-sm hover:bg-fill-list-active hover:shadow'
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{showFields.map((field) => {
|
{showFields.map((field) => {
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { usePublishContext } from '@/application/publish';
|
import { usePublishContext } from '@/application/publish';
|
||||||
|
import { useCurrentUser } from '@/components/app/app.hooks';
|
||||||
import { openOrDownload } from '@/components/publish/header/utils';
|
import { openOrDownload } from '@/components/publish/header/utils';
|
||||||
import { createHotkey, HOT_KEY_NAME } from '@/utils/hotkeys';
|
import { createHotkey, HOT_KEY_NAME } from '@/utils/hotkeys';
|
||||||
import { Divider, IconButton, Tooltip } from '@mui/material';
|
import { Divider, IconButton, Tooltip } from '@mui/material';
|
||||||
@ -10,11 +11,11 @@ import Breadcrumb from './Breadcrumb';
|
|||||||
import { ReactComponent as Logo } from '@/assets/logo.svg';
|
import { ReactComponent as Logo } from '@/assets/logo.svg';
|
||||||
import MoreActions from './MoreActions';
|
import MoreActions from './MoreActions';
|
||||||
import { ReactComponent as SideOutlined } from '@/assets/side_outlined.svg';
|
import { ReactComponent as SideOutlined } from '@/assets/side_outlined.svg';
|
||||||
// import { Duplicate } from './duplicate';
|
import { Duplicate } from './duplicate';
|
||||||
|
|
||||||
export const HEADER_HEIGHT = 48;
|
export const HEADER_HEIGHT = 48;
|
||||||
|
|
||||||
export function PublishViewHeader ({ onOpenDrawer, openDrawer }: { onOpenDrawer: () => void; openDrawer: boolean }) {
|
export function PublishViewHeader({ onOpenDrawer, openDrawer }: { onOpenDrawer: () => void; openDrawer: boolean }) {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const viewMeta = usePublishContext()?.viewMeta;
|
const viewMeta = usePublishContext()?.viewMeta;
|
||||||
const crumbs = useMemo(() => {
|
const crumbs = useMemo(() => {
|
||||||
@ -27,7 +28,7 @@ export function PublishViewHeader ({ onOpenDrawer, openDrawer }: { onOpenDrawer:
|
|||||||
const extra = ancestor?.extra ? JSON.parse(ancestor.extra) : {};
|
const extra = ancestor?.extra ? JSON.parse(ancestor.extra) : {};
|
||||||
|
|
||||||
icon = extra.icon?.value || ancestor.icon?.value;
|
icon = extra.icon?.value || ancestor.icon?.value;
|
||||||
} catch (e) {
|
} catch(e) {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +50,7 @@ export function PublishViewHeader ({ onOpenDrawer, openDrawer }: { onOpenDrawer:
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const onKeyDown = useCallback((e: KeyboardEvent) => {
|
const onKeyDown = useCallback((e: KeyboardEvent) => {
|
||||||
switch (true) {
|
switch(true) {
|
||||||
case createHotkey(HOT_KEY_NAME.TOGGLE_SIDEBAR)(e):
|
case createHotkey(HOT_KEY_NAME.TOGGLE_SIDEBAR)(e):
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
// setOpen((prev) => !prev);
|
// setOpen((prev) => !prev);
|
||||||
@ -68,13 +69,17 @@ export function PublishViewHeader ({ onOpenDrawer, openDrawer }: { onOpenDrawer:
|
|||||||
|
|
||||||
const handleOpenPopover = useCallback(() => {
|
const handleOpenPopover = useCallback(() => {
|
||||||
debounceClosePopover.cancel();
|
debounceClosePopover.cancel();
|
||||||
if (openDrawer) {
|
if(openDrawer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
setOpenPopover(true);
|
setOpenPopover(true);
|
||||||
}, [openDrawer, debounceClosePopover]);
|
}, [openDrawer, debounceClosePopover]);
|
||||||
|
|
||||||
|
const currentUser = useCurrentUser();
|
||||||
|
|
||||||
|
const isAppFlowyUser = currentUser?.email?.endsWith('@appflowy.io');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
@ -113,8 +118,12 @@ export function PublishViewHeader ({ onOpenDrawer, openDrawer }: { onOpenDrawer:
|
|||||||
<div className={'flex items-center gap-2'}>
|
<div className={'flex items-center gap-2'}>
|
||||||
|
|
||||||
<MoreActions />
|
<MoreActions />
|
||||||
{/*<Duplicate />*/}
|
{isAppFlowyUser && <Duplicate />}
|
||||||
<Divider orientation={'vertical'} className={'mx-2'} flexItem />
|
<Divider
|
||||||
|
orientation={'vertical'}
|
||||||
|
className={'mx-2'}
|
||||||
|
flexItem
|
||||||
|
/>
|
||||||
<Tooltip title={t('publish.downloadApp')}>
|
<Tooltip title={t('publish.downloadApp')}>
|
||||||
<button onClick={openOrDownload}>
|
<button onClick={openOrDownload}>
|
||||||
<Logo className={'h-6 w-6'} />
|
<Logo className={'h-6 w-6'} />
|
||||||
|
@ -6,7 +6,7 @@ import { useSearchParams } from 'react-router-dom';
|
|||||||
import { useDuplicate } from '@/components/publish/header/duplicate/useDuplicate';
|
import { useDuplicate } from '@/components/publish/header/duplicate/useDuplicate';
|
||||||
import DuplicateModal from '@/components/publish/header/duplicate/DuplicateModal';
|
import DuplicateModal from '@/components/publish/header/duplicate/DuplicateModal';
|
||||||
|
|
||||||
export function Duplicate () {
|
export function Duplicate() {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { loginOpen, duplicateOpen, handleDuplicateClose, handleLoginClose, url } = useDuplicate();
|
const { loginOpen, duplicateOpen, handleDuplicateClose, handleLoginClose, url } = useDuplicate();
|
||||||
const [, setSearch] = useSearchParams();
|
const [, setSearch] = useSearchParams();
|
||||||
@ -19,11 +19,23 @@ export function Duplicate () {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Button onClick={handleClick} size={'small'} variant={'outlined'} color={'inherit'}>
|
<Button
|
||||||
|
onClick={handleClick}
|
||||||
|
size={'small'}
|
||||||
|
variant={'outlined'}
|
||||||
|
color={'inherit'}
|
||||||
|
>
|
||||||
{t('publish.saveThisPage')}
|
{t('publish.saveThisPage')}
|
||||||
</Button>
|
</Button>
|
||||||
<LoginModal redirectTo={url} open={loginOpen} onClose={handleLoginClose} />
|
<LoginModal
|
||||||
{duplicateOpen && <DuplicateModal open={duplicateOpen} onClose={handleDuplicateClose} />}
|
redirectTo={url}
|
||||||
|
open={loginOpen}
|
||||||
|
onClose={handleLoginClose}
|
||||||
|
/>
|
||||||
|
{duplicateOpen && <DuplicateModal
|
||||||
|
open={duplicateOpen}
|
||||||
|
onClose={handleDuplicateClose}
|
||||||
|
/>}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -44,12 +44,12 @@ export const gradientMap = {
|
|||||||
|
|
||||||
// Convert ARGB to RGBA
|
// Convert ARGB to RGBA
|
||||||
// Flutter uses ARGB, but CSS uses RGBA
|
// Flutter uses ARGB, but CSS uses RGBA
|
||||||
function argbToRgba (color: string): string {
|
function argbToRgba(color: string): string {
|
||||||
const hex = color.replace(/^#|0x/, '');
|
const hex = color.replace(/^#|0x/, '');
|
||||||
|
|
||||||
const hasAlpha = hex.length === 8;
|
const hasAlpha = hex.length === 8;
|
||||||
|
|
||||||
if (!hasAlpha) {
|
if(!hasAlpha) {
|
||||||
return color.replace('0x', '#');
|
return color.replace('0x', '#');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,30 +61,34 @@ function argbToRgba (color: string): string {
|
|||||||
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
return `rgba(${r}, ${g}, ${b}, ${a})`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function renderColor (color: string) {
|
export function renderColor(color: string) {
|
||||||
if (colorMap[color as ColorEnum]) {
|
if(colorMap[color as ColorEnum]) {
|
||||||
return colorMap[color as ColorEnum];
|
return colorMap[color as ColorEnum];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (gradientMap[color as GradientEnum]) {
|
if(gradientMap[color as GradientEnum]) {
|
||||||
return gradientMap[color as GradientEnum];
|
return gradientMap[color as GradientEnum];
|
||||||
}
|
}
|
||||||
|
|
||||||
return argbToRgba(color);
|
return argbToRgba(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stringToColor (string: string) {
|
export function stringToColor(string: string, colorArray?: string[]) {
|
||||||
let hash = 0;
|
let hash = 0;
|
||||||
let i;
|
let i;
|
||||||
|
|
||||||
/* eslint-disable no-bitwise */
|
/* eslint-disable no-bitwise */
|
||||||
for (i = 0; i < string.length; i += 1) {
|
for(i = 0; i < string.length; i += 1) {
|
||||||
hash = string.charCodeAt(i) + ((hash << 5) - hash);
|
hash = string.charCodeAt(i) + ((hash << 5) - hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(colorArray) {
|
||||||
|
return colorArray[string.slice(0, 1).charCodeAt(0) % colorArray.length];
|
||||||
|
}
|
||||||
|
|
||||||
let color = '#';
|
let color = '#';
|
||||||
|
|
||||||
for (i = 0; i < 3; i += 1) {
|
for(i = 0; i < 3; i += 1) {
|
||||||
const value = (hash >> (i * 8)) & 0xff;
|
const value = (hash >> (i * 8)) & 0xff;
|
||||||
|
|
||||||
color += `00${value.toString(16)}`.slice(-2);
|
color += `00${value.toString(16)}`.slice(-2);
|
||||||
@ -94,14 +98,14 @@ export function stringToColor (string: string) {
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function stringAvatar (name: string) {
|
export function stringAvatar(name: string, colorArray?: string[]) {
|
||||||
if (!name) {
|
if(!name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
sx: {
|
sx: {
|
||||||
bgcolor: stringToColor(name),
|
bgcolor: stringToColor(name, colorArray),
|
||||||
},
|
},
|
||||||
children: `${name.split('')[0]}`,
|
children: `${name.split('')[0]}`,
|
||||||
};
|
};
|
||||||
|
@ -2358,7 +2358,7 @@
|
|||||||
"mustSelectPrimaryDatabase": "The primary view must be selected",
|
"mustSelectPrimaryDatabase": "The primary view must be selected",
|
||||||
"noDatabaseSelected": "No database selected, please select at least one database.",
|
"noDatabaseSelected": "No database selected, please select at least one database.",
|
||||||
"unableToDeselectPrimaryDatabase": "Unable to deselect primary database",
|
"unableToDeselectPrimaryDatabase": "Unable to deselect primary database",
|
||||||
"saveThisPage": "Save this page",
|
"saveThisPage": "Start with this template",
|
||||||
"duplicateTitle": "Where would you like to add",
|
"duplicateTitle": "Where would you like to add",
|
||||||
"selectWorkspace": "Select a workspace",
|
"selectWorkspace": "Select a workspace",
|
||||||
"addTo": "Add to",
|
"addTo": "Add to",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user