@@ -5,7 +5,7 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
|
|||||||
});
|
});
|
||||||
|
|
||||||
module.exports = withBundleAnalyzer({
|
module.exports = withBundleAnalyzer({
|
||||||
reactStrictMode: true,
|
reactStrictMode: false,
|
||||||
eslint: {
|
eslint: {
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -25,6 +25,8 @@
|
|||||||
"ci": "yarn test && yarn lint --fix && yarn typecheck && yarn prettier:write"
|
"ci": "yarn test && yarn lint --fix && yarn typecheck && yarn prettier:write"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"@dnd-kit/core": "^6.0.1",
|
||||||
|
"@dnd-kit/sortable": "^7.0.0",
|
||||||
"@mantine/core": "^4.2.6",
|
"@mantine/core": "^4.2.6",
|
||||||
"@mantine/dates": "^4.2.6",
|
"@mantine/dates": "^4.2.6",
|
||||||
"@mantine/dropzone": "^4.2.6",
|
"@mantine/dropzone": "^4.2.6",
|
||||||
|
|||||||
@@ -6,22 +6,17 @@ import {
|
|||||||
Image,
|
Image,
|
||||||
Button,
|
Button,
|
||||||
Select,
|
Select,
|
||||||
AspectRatio,
|
|
||||||
Text,
|
|
||||||
Card,
|
|
||||||
LoadingOverlay,
|
LoadingOverlay,
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
Tooltip,
|
Tooltip,
|
||||||
Title,
|
Title,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { useForm } from '@mantine/form';
|
import { useForm } from '@mantine/form';
|
||||||
import { motion } from 'framer-motion';
|
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { Apps } from 'tabler-icons-react';
|
import { Apps } from 'tabler-icons-react';
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
import { useConfig } from '../../tools/state';
|
import { useConfig } from '../../tools/state';
|
||||||
import { ServiceTypeList } from '../../tools/types';
|
import { ServiceTypeList } from '../../tools/types';
|
||||||
import { AppShelfItemWrapper } from './AppShelfItemWrapper';
|
|
||||||
|
|
||||||
export function AddItemShelfButton(props: any) {
|
export function AddItemShelfButton(props: any) {
|
||||||
const [opened, setOpened] = useState(false);
|
const [opened, setOpened] = useState(false);
|
||||||
@@ -52,56 +47,6 @@ export function AddItemShelfButton(props: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function AddItemShelfItem(props: any) {
|
|
||||||
const [opened, setOpened] = useState(false);
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<Modal
|
|
||||||
size="xl"
|
|
||||||
radius="md"
|
|
||||||
opened={props.opened || opened}
|
|
||||||
onClose={() => setOpened(false)}
|
|
||||||
title="Add a service"
|
|
||||||
>
|
|
||||||
<AddAppShelfItemForm setOpened={setOpened} />
|
|
||||||
</Modal>
|
|
||||||
<AppShelfItemWrapper>
|
|
||||||
<Card.Section>
|
|
||||||
<Group position="center" mx="lg">
|
|
||||||
<Text
|
|
||||||
// TODO: #1 Remove this hack to get the text to be centered.
|
|
||||||
ml={15}
|
|
||||||
style={{
|
|
||||||
alignSelf: 'center',
|
|
||||||
alignContent: 'center',
|
|
||||||
alignItems: 'center',
|
|
||||||
justifyContent: 'center',
|
|
||||||
justifyItems: 'center',
|
|
||||||
}}
|
|
||||||
mt="sm"
|
|
||||||
weight={500}
|
|
||||||
>
|
|
||||||
Add a service
|
|
||||||
</Text>
|
|
||||||
</Group>
|
|
||||||
</Card.Section>
|
|
||||||
<Card.Section>
|
|
||||||
<AspectRatio ratio={5 / 3} m="xl">
|
|
||||||
<motion.i
|
|
||||||
whileHover={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
scale: 1.1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Apps style={{ cursor: 'pointer' }} onClick={() => setOpened(true)} size={60} />
|
|
||||||
</motion.i>
|
|
||||||
</AspectRatio>
|
|
||||||
</Card.Section>
|
|
||||||
</AppShelfItemWrapper>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
function MatchIcon(name: string, form: any) {
|
function MatchIcon(name: string, form: any) {
|
||||||
fetch(
|
fetch(
|
||||||
`https://cdn.jsdelivr.net/gh/walkxhub/dashboard-icons/png/${name
|
`https://cdn.jsdelivr.net/gh/walkxhub/dashboard-icons/png/${name
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { SimpleGrid } from '@mantine/core';
|
import { SimpleGrid } from '@mantine/core';
|
||||||
import AppShelf, { AppShelfItem } from './AppShelf';
|
import AppShelf from './AppShelf';
|
||||||
|
import { AppShelfItem } from './AppShelfItem';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
title: 'Item Shelf',
|
title: 'Item Shelf',
|
||||||
|
|||||||
@@ -1,112 +1,79 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { motion } from 'framer-motion';
|
import { Grid } from '@mantine/core';
|
||||||
import { Text, AspectRatio, Card, Image, Center, Grid, createStyles, Anchor } from '@mantine/core';
|
import {
|
||||||
|
closestCenter,
|
||||||
|
DndContext,
|
||||||
|
DragOverlay,
|
||||||
|
MouseSensor,
|
||||||
|
useSensor,
|
||||||
|
useSensors,
|
||||||
|
} from '@dnd-kit/core';
|
||||||
|
import { arrayMove, SortableContext } from '@dnd-kit/sortable';
|
||||||
import { useConfig } from '../../tools/state';
|
import { useConfig } from '../../tools/state';
|
||||||
import { serviceItem } from '../../tools/types';
|
|
||||||
import AppShelfMenu from './AppShelfMenu';
|
|
||||||
import PingComponent from '../modules/ping/PingModule';
|
|
||||||
|
|
||||||
const useStyles = createStyles((theme) => ({
|
import { SortableAppShelfItem, AppShelfItem } from './AppShelfItem';
|
||||||
item: {
|
|
||||||
transition: 'box-shadow 150ms ease, transform 100ms ease',
|
|
||||||
|
|
||||||
'&:hover': {
|
|
||||||
boxShadow: `${theme.shadows.md} !important`,
|
|
||||||
transform: 'scale(1.05)',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
const AppShelf = (props: any) => {
|
const AppShelf = (props: any) => {
|
||||||
const { config } = useConfig();
|
const [activeId, setActiveId] = useState(null);
|
||||||
|
const { config, setConfig } = useConfig();
|
||||||
|
const sensors = useSensors(
|
||||||
|
useSensor(MouseSensor, {
|
||||||
|
// Require the mouse to move by 10 pixels before activating
|
||||||
|
activationConstraint: {
|
||||||
|
delay: 250,
|
||||||
|
tolerance: 5,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
function handleDragStart(event: any) {
|
||||||
|
const { active } = event;
|
||||||
|
|
||||||
|
setActiveId(active.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
function handleDragEnd(event: any) {
|
||||||
|
const { active, over } = event;
|
||||||
|
|
||||||
|
if (active.id !== over.id) {
|
||||||
|
const newConfig = { ...config };
|
||||||
|
const activeIndex = newConfig.services.findIndex((e) => e.id === active.id);
|
||||||
|
const overIndex = newConfig.services.findIndex((e) => e.id === over.id);
|
||||||
|
newConfig.services = arrayMove(newConfig.services, activeIndex, overIndex);
|
||||||
|
setConfig(newConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
setActiveId(null);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Grid gutter="xl" align="center">
|
<DndContext
|
||||||
{config.services.map((service) => (
|
sensors={sensors}
|
||||||
<Grid.Col key={service.id} span={6} xl={2} xs={4} sm={3} md={3}>
|
collisionDetection={closestCenter}
|
||||||
<AppShelfItem key={service.id} service={service} />
|
onDragStart={handleDragStart}
|
||||||
</Grid.Col>
|
onDragEnd={handleDragEnd}
|
||||||
))}
|
>
|
||||||
</Grid>
|
<SortableContext items={config.services}>
|
||||||
|
<Grid gutter="xl" align="center">
|
||||||
|
{config.services.map((service) => (
|
||||||
|
<Grid.Col key={service.id} span={6} xl={2} xs={4} sm={3} md={3}>
|
||||||
|
<SortableAppShelfItem service={service} key={service.id} id={service.id} />
|
||||||
|
</Grid.Col>
|
||||||
|
))}
|
||||||
|
</Grid>
|
||||||
|
</SortableContext>
|
||||||
|
<DragOverlay
|
||||||
|
style={{
|
||||||
|
// Add a shadow to the drag overlay
|
||||||
|
boxShadow: '0 0 10px rgba(0, 0, 0, 0.5)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{activeId ? (
|
||||||
|
<AppShelfItem service={config.services.find((e) => e.id === activeId)} id={activeId} />
|
||||||
|
) : null}
|
||||||
|
</DragOverlay>
|
||||||
|
</DndContext>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export function AppShelfItem(props: any) {
|
|
||||||
const { service }: { service: serviceItem } = props;
|
|
||||||
const [hovering, setHovering] = useState(false);
|
|
||||||
const { classes, theme } = useStyles();
|
|
||||||
return (
|
|
||||||
<motion.div
|
|
||||||
animate={{
|
|
||||||
scale: [0.9, 1.06, 1],
|
|
||||||
rotate: [0, 5, 0],
|
|
||||||
}}
|
|
||||||
transition={{ duration: 0.6, type: 'spring', damping: 10, mass: 0.75, stiffness: 100 }}
|
|
||||||
key={service.name}
|
|
||||||
onHoverStart={() => {
|
|
||||||
setHovering(true);
|
|
||||||
}}
|
|
||||||
onHoverEnd={() => {
|
|
||||||
setHovering(false);
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Card withBorder radius="lg" shadow="md" className={classes.item}>
|
|
||||||
<Card.Section>
|
|
||||||
<Anchor
|
|
||||||
target="_blank"
|
|
||||||
href={service.url}
|
|
||||||
style={{ color: 'inherit', fontStyle: 'inherit', fontSize: 'inherit' }}
|
|
||||||
>
|
|
||||||
<Text mt="sm" align="center" lineClamp={1} weight={550}>
|
|
||||||
{service.name}
|
|
||||||
</Text>
|
|
||||||
</Anchor>
|
|
||||||
<motion.div
|
|
||||||
style={{
|
|
||||||
position: 'absolute',
|
|
||||||
top: 15,
|
|
||||||
right: 15,
|
|
||||||
alignSelf: 'flex-end',
|
|
||||||
}}
|
|
||||||
animate={{
|
|
||||||
opacity: hovering ? 1 : 0,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<AppShelfMenu service={service} />
|
|
||||||
</motion.div>
|
|
||||||
</Card.Section>
|
|
||||||
<Center>
|
|
||||||
<Card.Section>
|
|
||||||
<AspectRatio
|
|
||||||
ratio={3 / 5}
|
|
||||||
m="xl"
|
|
||||||
style={{
|
|
||||||
width: 150,
|
|
||||||
height: 90,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<motion.i
|
|
||||||
whileHover={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
scale: 1.1,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Image
|
|
||||||
width={80}
|
|
||||||
height={80}
|
|
||||||
src={service.icon}
|
|
||||||
fit="contain"
|
|
||||||
onClick={() => {
|
|
||||||
window.open(service.url);
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</motion.i>
|
|
||||||
</AspectRatio>
|
|
||||||
<PingComponent url={service.url} />
|
|
||||||
</Card.Section>
|
|
||||||
</Center>
|
|
||||||
</Card>
|
|
||||||
</motion.div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default AppShelf;
|
export default AppShelf;
|
||||||
|
|||||||
123
src/components/AppShelf/AppShelfItem.tsx
Normal file
123
src/components/AppShelf/AppShelfItem.tsx
Normal file
@@ -0,0 +1,123 @@
|
|||||||
|
import {
|
||||||
|
Text,
|
||||||
|
Card,
|
||||||
|
Anchor,
|
||||||
|
AspectRatio,
|
||||||
|
Image,
|
||||||
|
Center,
|
||||||
|
createStyles,
|
||||||
|
} from '@mantine/core';
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useSortable } from '@dnd-kit/sortable';
|
||||||
|
import { CSS } from '@dnd-kit/utilities';
|
||||||
|
import { serviceItem } from '../../tools/types';
|
||||||
|
import PingComponent from '../modules/ping/PingModule';
|
||||||
|
import AppShelfMenu from './AppShelfMenu';
|
||||||
|
|
||||||
|
const useStyles = createStyles((theme) => ({
|
||||||
|
item: {
|
||||||
|
transition: 'box-shadow 150ms ease, transform 100ms ease',
|
||||||
|
|
||||||
|
'&:hover': {
|
||||||
|
boxShadow: `${theme.shadows.md} !important`,
|
||||||
|
transform: 'scale(1.05)',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}));
|
||||||
|
|
||||||
|
export function SortableAppShelfItem(props: any) {
|
||||||
|
const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
|
||||||
|
id: props.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
const style = {
|
||||||
|
transform: CSS.Transform.toString(transform),
|
||||||
|
transition,
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={setNodeRef} style={style} {...attributes} {...listeners}>
|
||||||
|
<AppShelfItem service={props.service} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function AppShelfItem(props: any) {
|
||||||
|
const { service }: { service: serviceItem } = props;
|
||||||
|
const [hovering, setHovering] = useState(false);
|
||||||
|
const { classes, theme } = useStyles();
|
||||||
|
return (
|
||||||
|
<motion.div
|
||||||
|
animate={{
|
||||||
|
scale: [0.9, 1.06, 1],
|
||||||
|
rotate: [0, 5, 0],
|
||||||
|
}}
|
||||||
|
transition={{ duration: 0.6, type: 'spring', damping: 10, mass: 0.75, stiffness: 100 }}
|
||||||
|
key={service.name}
|
||||||
|
onHoverStart={() => {
|
||||||
|
setHovering(true);
|
||||||
|
}}
|
||||||
|
onHoverEnd={() => {
|
||||||
|
setHovering(false);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Card withBorder radius="lg" shadow="md" className={classes.item}>
|
||||||
|
<Card.Section>
|
||||||
|
<Anchor
|
||||||
|
target="_blank"
|
||||||
|
href={service.url}
|
||||||
|
style={{ color: 'inherit', fontStyle: 'inherit', fontSize: 'inherit' }}
|
||||||
|
>
|
||||||
|
<Text mt="sm" align="center" lineClamp={1} weight={550}>
|
||||||
|
{service.name}
|
||||||
|
</Text>
|
||||||
|
</Anchor>
|
||||||
|
<motion.div
|
||||||
|
style={{
|
||||||
|
position: 'absolute',
|
||||||
|
top: 15,
|
||||||
|
right: 15,
|
||||||
|
alignSelf: 'flex-end',
|
||||||
|
}}
|
||||||
|
animate={{
|
||||||
|
opacity: hovering ? 1 : 0,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<AppShelfMenu service={service} />
|
||||||
|
</motion.div>
|
||||||
|
</Card.Section>
|
||||||
|
<Center>
|
||||||
|
<Card.Section>
|
||||||
|
<AspectRatio
|
||||||
|
ratio={3 / 5}
|
||||||
|
m="xl"
|
||||||
|
style={{
|
||||||
|
width: 150,
|
||||||
|
height: 90,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<motion.i
|
||||||
|
whileHover={{
|
||||||
|
cursor: 'pointer',
|
||||||
|
scale: 1.1,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Image
|
||||||
|
width={80}
|
||||||
|
height={80}
|
||||||
|
src={service.icon}
|
||||||
|
fit="contain"
|
||||||
|
onClick={() => {
|
||||||
|
window.open(service.url);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</motion.i>
|
||||||
|
</AspectRatio>
|
||||||
|
<PingComponent url={service.url} />
|
||||||
|
</Card.Section>
|
||||||
|
</Center>
|
||||||
|
</Card>
|
||||||
|
</motion.div>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import { useMantineTheme, Card } from '@mantine/core';
|
|
||||||
|
|
||||||
export function AppShelfItemWrapper(props: any) {
|
|
||||||
const { children, hovering } = props;
|
|
||||||
const theme = useMantineTheme();
|
|
||||||
return (
|
|
||||||
<Card
|
|
||||||
style={{
|
|
||||||
boxShadow: hovering ? '0px 0px 3px rgba(0, 0, 0, 0.5)' : '0px 0px 1px rgba(0, 0, 0, 0.5)',
|
|
||||||
backgroundColor: theme.colorScheme === 'dark' ? theme.colors.dark[6] : theme.colors.gray[1],
|
|
||||||
}}
|
|
||||||
radius="md"
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</Card>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
2
src/components/AppShelf/index.ts
Normal file
2
src/components/AppShelf/index.ts
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
export { default as AppShelf } from './AppShelf';
|
||||||
|
export * from './AppShelfItem';
|
||||||
@@ -6,7 +6,6 @@ const stylesServer = createStylesServer();
|
|||||||
export default class _Document extends Document {
|
export default class _Document extends Document {
|
||||||
static async getInitialProps(ctx: DocumentContext) {
|
static async getInitialProps(ctx: DocumentContext) {
|
||||||
const initialProps = await Document.getInitialProps(ctx);
|
const initialProps = await Document.getInitialProps(ctx);
|
||||||
|
|
||||||
// Add your app specific logic here
|
// Add your app specific logic here
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
31
yarn.lock
31
yarn.lock
@@ -1143,6 +1143,37 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz#1d572bfbbe14b7704e0ba0f39b74815b84870d70"
|
||||||
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
integrity sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==
|
||||||
|
|
||||||
|
"@dnd-kit/accessibility@^3.0.0":
|
||||||
|
version "3.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@dnd-kit/accessibility/-/accessibility-3.0.0.tgz#b56e3750414fd907b7d6972b3116aa8f96d07fde"
|
||||||
|
integrity sha512-QwaQ1IJHQHMMuAGOOYHQSx7h7vMZPfO97aDts8t5N/MY7n2QTDSnW+kF7uRQ1tVBkr6vJ+BqHWG5dlgGvwVjow==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
"@dnd-kit/core@^6.0.1":
|
||||||
|
version "6.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/@dnd-kit/core/-/core-6.0.1.tgz#fe1970e4490ae5c911b2837f9b5e55217e048ea7"
|
||||||
|
integrity sha512-ZyYmh6S1hvEkywdlwh1d0VW6UnkbP4zb0iZwBGHP4eePlPLDl0t18HaXcgbpVcFWQTUAQtEZVIJKUYBJdVQVsA==
|
||||||
|
dependencies:
|
||||||
|
"@dnd-kit/accessibility" "^3.0.0"
|
||||||
|
"@dnd-kit/utilities" "^3.2.0"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
"@dnd-kit/sortable@^7.0.0":
|
||||||
|
version "7.0.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@dnd-kit/sortable/-/sortable-7.0.0.tgz#b094b288a8bd37cb74af0ed347b5ca4cfe6ce795"
|
||||||
|
integrity sha512-Em6d1n18lMmpRnNB9mmBWN/X7wNDnIw26tab+c7H0jCjW9UQ0+lRV+vatB1lLzFZlgQgIas/A/TXZDY16RQA5Q==
|
||||||
|
dependencies:
|
||||||
|
"@dnd-kit/utilities" "^3.2.0"
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
|
"@dnd-kit/utilities@^3.2.0":
|
||||||
|
version "3.2.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@dnd-kit/utilities/-/utilities-3.2.0.tgz#b3e956ea63a1347c9d0e1316b037ddcc6140acda"
|
||||||
|
integrity sha512-h65/pn2IPCCIWwdlR2BMLqRkDxpTEONA+HQW3n765HBijLYGyrnTCLa2YQt8VVjjSQD6EfFlTE6aS2Q/b6nb2g==
|
||||||
|
dependencies:
|
||||||
|
tslib "^2.0.0"
|
||||||
|
|
||||||
"@emotion/cache@11.7.1", "@emotion/cache@^11.7.1":
|
"@emotion/cache@11.7.1", "@emotion/cache@^11.7.1":
|
||||||
version "11.7.1"
|
version "11.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539"
|
resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-11.7.1.tgz#08d080e396a42e0037848214e8aa7bf879065539"
|
||||||
|
|||||||
Reference in New Issue
Block a user