mirror of
https://github.com/labring/sealos.git
synced 2026-10-30 18:09:56 +08:00
feat float button & add home button (#3617)
* feat float button & add home button * feat:terminal modify loading animation Signed-off-by: jingyang <3161362058@qq.com> --------- Signed-off-by: jingyang <3161362058@qq.com>
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M14.1031 13.3375L13.275 8.5625H13.5547C13.7797 8.5625 13.9609 8.38125 13.9609 8.15625V5.15625C13.9609 4.93125 13.7797 4.75 13.5547 4.75H9.71094V1.90625C9.71094 1.68125 9.52969 1.5 9.30469 1.5H6.80469C6.57969 1.5 6.39844 1.68125 6.39844 1.90625V4.75H2.55469C2.32969 4.75 2.14844 4.93125 2.14844 5.15625V8.15625C2.14844 8.38125 2.32969 8.5625 2.55469 8.5625H2.83437L2.00625 13.3375C2.00156 13.3609 2 13.3844 2 13.4062C2 13.6313 2.18125 13.8125 2.40625 13.8125H13.7031C13.7266 13.8125 13.75 13.8109 13.7719 13.8062C13.9938 13.7687 14.1422 13.5578 14.1031 13.3375ZM3.24219 5.84375H7.49219V2.59375H8.61719V5.84375H12.8672V7.46875H3.24219V5.84375ZM10.5547 12.7188V10.2812C10.5547 10.2125 10.4984 10.1562 10.4297 10.1562H9.67969C9.61094 10.1562 9.55469 10.2125 9.55469 10.2812V12.7188H6.55469V10.2812C6.55469 10.2125 6.49844 10.1562 6.42969 10.1562H5.67969C5.61094 10.1562 5.55469 10.2125 5.55469 10.2812V12.7188H3.22344L3.92812 8.65625H12.1797L12.8844 12.7188H10.5547Z" fill="#5A646E"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
@@ -0,0 +1,8 @@
|
||||
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="mask0_3339_120424" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="25" height="25">
|
||||
<rect x="0.392578" y="0.647522" width="24" height="24" fill="#D9D9D9"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0_3339_120424)">
|
||||
<path d="M4.39258 21.6475V9.64752L12.3926 3.64752L20.3926 9.64752V21.6475H14.3926V14.6475H10.3926V21.6475H4.39258Z" fill="#1C1B1F"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 472 B |
@@ -41,8 +41,8 @@
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
border-radius: 50%;
|
||||
background: rgba(21, 37, 57, 0.6);
|
||||
box-shadow: 0px 1.16667px 2.33333px rgba(0, 0, 0, 0.2);
|
||||
background: rgba(28, 32, 35, 0.9);
|
||||
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
@@ -78,6 +78,9 @@
|
||||
height: 32px;
|
||||
background: rgba(255, 255, 255, 0.9);
|
||||
box-shadow: 0px 0px 2.33333px rgba(0, 0, 0, 0.2);
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,7 +98,7 @@
|
||||
transform: scale(0.1);
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(150px);
|
||||
background: rgba(21, 37, 57, 0.75);
|
||||
background: rgba(28, 32, 35, 0.9);
|
||||
box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, 0.1);
|
||||
|
||||
&[data-open='true'] {
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
import useAppStore, { AppInfo } from '@/stores/app';
|
||||
import { Box, Flex, useDisclosure, Image } from '@chakra-ui/react';
|
||||
import { Box, Flex, useDisclosure, Image, Img } from '@chakra-ui/react';
|
||||
import clsx from 'clsx';
|
||||
import { MouseEvent, useMemo, useState } from 'react';
|
||||
import Draggable, { DraggableEventHandler } from 'react-draggable';
|
||||
import Iconfont from '../iconfont';
|
||||
import styles from './index.module.scss';
|
||||
import homeIcon from 'public/icons/home.svg';
|
||||
import { APPTYPE } from '@/types';
|
||||
|
||||
enum Suction {
|
||||
None,
|
||||
@@ -18,7 +20,8 @@ export default function Index(props: any) {
|
||||
runningInfo,
|
||||
setToHighestLayerById,
|
||||
currentAppPid,
|
||||
switchAppById
|
||||
switchAppById,
|
||||
updateOpenedAppInfo
|
||||
} = useAppStore();
|
||||
const { isOpen, onOpen, onClose } = useDisclosure();
|
||||
const [dragging, setDragging] = useState(false);
|
||||
@@ -27,6 +30,28 @@ export default function Index(props: any) {
|
||||
const [endPosition, setEndPosition] = useState({ x: 0, y: 0 });
|
||||
const [suction, setSuction] = useState(Suction.None);
|
||||
const [lockSuction, setLockSuction] = useState(true);
|
||||
// Hover Ball Menu
|
||||
const AppMenuLists: AppInfo[] = [
|
||||
{
|
||||
name: 'home',
|
||||
icon: '/icons/home.svg',
|
||||
zIndex: 99999,
|
||||
isShow: true,
|
||||
pid: -9,
|
||||
size: 'maxmin',
|
||||
cacheSize: 'maxmin',
|
||||
style: {},
|
||||
mouseDowning: false,
|
||||
key: `system-sealos-home`,
|
||||
type: APPTYPE.IFRAME,
|
||||
data: {
|
||||
url: '',
|
||||
desc: ''
|
||||
},
|
||||
displayType: 'hidden'
|
||||
},
|
||||
...runningInfo
|
||||
];
|
||||
|
||||
const [degree, contentSkewDegree, contentRotateDegree] = useMemo(() => {
|
||||
const len = apps?.length < 6 ? 6 : apps?.length > 8 ? 8 : apps?.length;
|
||||
@@ -100,6 +125,30 @@ export default function Index(props: any) {
|
||||
}
|
||||
};
|
||||
|
||||
// Handle icon click event
|
||||
const handleNavItem = (e: MouseEvent<HTMLDivElement>, item: AppInfo) => {
|
||||
if (item.key === 'system-sealos-home') {
|
||||
const isNotMinimized = runningInfo.some((item) => item.size !== 'minimize');
|
||||
runningInfo.forEach((item) => {
|
||||
updateOpenedAppInfo({
|
||||
...item,
|
||||
size: isNotMinimized ? 'minimize' : item.cacheSize
|
||||
});
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (item.pid === currentAppPid && item.size !== 'minimize') {
|
||||
updateOpenedAppInfo({
|
||||
...item,
|
||||
size: 'minimize',
|
||||
cacheSize: item.size
|
||||
});
|
||||
} else {
|
||||
switchAppById(item.pid);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Draggable
|
||||
@@ -151,7 +200,7 @@ export default function Index(props: any) {
|
||||
userSelect={'none'}
|
||||
style={{ display: suction === Suction.None ? 'block' : 'none' }}
|
||||
>
|
||||
{runningInfo?.map((item: AppInfo, index: number) => {
|
||||
{AppMenuLists?.map((item: AppInfo, index: number) => {
|
||||
return (
|
||||
<Box
|
||||
cursor={'pointer'}
|
||||
@@ -163,11 +212,8 @@ export default function Index(props: any) {
|
||||
? `rotate(${degree * (index + 1)}deg) skew(${90 - degree}deg)`
|
||||
: `rotate(75deg) skew(60deg)`
|
||||
}
|
||||
_hover={{ bg: 'rgba(21, 37, 57, 0.8)' }}
|
||||
onClick={(e) => {
|
||||
switchAppById(item.pid);
|
||||
setToHighestLayerById(item.pid);
|
||||
}}
|
||||
_hover={{ bg: 'rgba(88,90,93,0.5)' }}
|
||||
onClick={(e) => handleNavItem(e, item)}
|
||||
>
|
||||
<Flex
|
||||
justifyContent={'center'}
|
||||
|
||||
@@ -18,7 +18,7 @@ export default function MoreButton() {
|
||||
alignItems={'center'}
|
||||
w="110px"
|
||||
h="42px"
|
||||
background={'rgba(21, 37, 57, 0.6)'}
|
||||
background={'rgba(28, 32, 35, 0.60)'}
|
||||
boxShadow={'0px 1.16667px 2.33333px rgba(0, 0, 0, 0.2)'}
|
||||
position={'absolute'}
|
||||
bottom={'80px'}
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
height: 524px;
|
||||
background: rgba(255, 255, 255, 0.7);
|
||||
backdrop-filter: blur(150px);
|
||||
border-radius: 16px;
|
||||
border-radius: 12px;
|
||||
padding: 24px;
|
||||
z-index: 999;
|
||||
position: absolute;
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Box, Flex, Text, UseDisclosureProps } from '@chakra-ui/react';
|
||||
import { Box, Flex, Text, UseDisclosureProps, Img } from '@chakra-ui/react';
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
import clsx from 'clsx';
|
||||
import Iconfont from '@/components/iconfont';
|
||||
@@ -7,6 +7,7 @@ import request from '@/services/request';
|
||||
import { formatTime } from '@/utils/tools';
|
||||
import styles from './index.module.scss';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import warnIcon from 'public/icons/clear-outlined.svg';
|
||||
|
||||
type NotificationItem = {
|
||||
metadata: {
|
||||
@@ -111,7 +112,7 @@ export default function Notification(props: TNotification) {
|
||||
</Flex>
|
||||
{activePage === 'index' ? (
|
||||
<>
|
||||
<Flex>
|
||||
<Flex alignItems={'center'}>
|
||||
<Box
|
||||
className={clsx(activeTab === 'unread' && styles.active, styles.tab)}
|
||||
onClick={() => setActiveTab('unread')}
|
||||
@@ -125,14 +126,12 @@ export default function Notification(props: TNotification) {
|
||||
>
|
||||
{t('Have Read')}
|
||||
</Box>
|
||||
<Text
|
||||
ml={'auto'}
|
||||
color={'#434F61'}
|
||||
className={styles.tab}
|
||||
onClick={() => markAllAsRead()}
|
||||
>
|
||||
{t('Read All')}
|
||||
</Text>
|
||||
<Flex ml={'auto'} onClick={() => markAllAsRead()}>
|
||||
<Img src={warnIcon.src}></Img>
|
||||
<Text ml="4px" color={'#434F61'} className={styles.tab}>
|
||||
{t('Read All')}
|
||||
</Text>
|
||||
</Flex>
|
||||
</Flex>
|
||||
<Flex pt={'9px'} pb="12px" direction={'column'} h="430px" className={styles.scrollWrap}>
|
||||
{notifications?.map((item: NotificationItem) => {
|
||||
|
||||
@@ -32,8 +32,15 @@ export default function Home({ rechargeEnabled }: { rechargeEnabled: boolean })
|
||||
useEffect(() => {
|
||||
const { query } = router;
|
||||
const is_login = isUserLogin();
|
||||
const whitelistApps = ['system-fastdeploy'];
|
||||
|
||||
if (!isUpdate || !is_login) {
|
||||
const { appkey, appQuery } = parseOpenappQuery((query?.openapp as string) || '');
|
||||
// sealos_inside=true internal call
|
||||
if (whitelistApps.includes(appkey) && appQuery.indexOf('sealos_inside=true') === -1) {
|
||||
window.open(`https://fastdeploy.cloud.sealos.io/`, '_self');
|
||||
return;
|
||||
}
|
||||
if (appkey && typeof appQuery === 'string') setAutoLaunch(appkey, { raw: appQuery });
|
||||
router.replace(destination);
|
||||
} else {
|
||||
|
||||
@@ -129,8 +129,8 @@ const useAppStore = create<TOSState>()(
|
||||
get().setToHighestLayerById(alreadyApp.pid);
|
||||
return;
|
||||
}
|
||||
// Up to 8 apps
|
||||
if (get().runningInfo.length >= 8) {
|
||||
// Up to 7 apps && one home app
|
||||
if (get().runningInfo.length >= 7) {
|
||||
get().deleteLeastUsedAppByIndex();
|
||||
}
|
||||
if (app.type === APPTYPE.LINK) {
|
||||
@@ -158,14 +158,13 @@ const useAppStore = create<TOSState>()(
|
||||
},
|
||||
// maximize app
|
||||
switchAppById: (pid: number) => {
|
||||
// const zIndex = get().maxZIndex + 1;
|
||||
set((state) => {
|
||||
let _app = state.runningInfo.find((item) => item.pid === pid);
|
||||
if (!_app) return;
|
||||
_app.isShow = true;
|
||||
_app.size = _app.cacheSize;
|
||||
state.setToHighestLayerById(pid);
|
||||
});
|
||||
get().setToHighestLayerById(pid);
|
||||
},
|
||||
// get switch floor function
|
||||
setToHighestLayerById: (pid: number) => {
|
||||
|
||||
@@ -6,8 +6,10 @@
|
||||
"format": "prettier --config .prettierrc.js --write **/src/**/*.ts **/src/**/*.tsx **/src/**/*.scss **/tsconfig.*json **/*config.js **/*config.json",
|
||||
"preinstall": "npx only-allow pnpm",
|
||||
"dev-desktop": " pnpm -r --filter ./desktop run dev",
|
||||
"dev-app": " pnpm -r --filter ./providers/applaunchpad run dev",
|
||||
"dev-db": " pnpm -r --filter ./providers/dbprovider run dev",
|
||||
"dev-app": " pnpm -r --filter ./providers/applaunchpad run dev"
|
||||
"dev-cost": " pnpm -r --filter ./providers/costcenter run dev",
|
||||
"dev-terminal": " pnpm -r --filter ./providers/terminal run dev"
|
||||
},
|
||||
"workspaces": [
|
||||
"./packages/*",
|
||||
|
||||
@@ -1,2 +1,3 @@
|
||||
NEXT_PUBLIC_MOCK_KUBECONFIG=""
|
||||
SITE="https://cloud.sealos.io"
|
||||
TTYD_IMAGE="docker.io/labring/docker-terminal:1.20.4-6"
|
||||
@@ -55,7 +55,6 @@ export default function Index(props: ServiceEnv) {
|
||||
if (isLoading) {
|
||||
return (
|
||||
<Flex w="100%" h="100%" color="white" bg="#2b2b2b" overflow={'hidden'} position={'relative'}>
|
||||
<Box w="200px" backgroundColor={'#2C3035'}></Box>
|
||||
<Box w="100%" backgroundColor={'#2b2b2b'} position={'relative'}>
|
||||
<Box position={'absolute'} top="50%" left={'50%'} transform={'translate(-50%, -50%)'}>
|
||||
<Spinner
|
||||
|
||||
Reference in New Issue
Block a user