mirror of
https://github.com/labring/sealos.git
synced 2026-09-24 15:46:19 +08:00
eat(frontend/desktop):change password (#4149)
This commit is contained in:
+3
-3
@@ -11,7 +11,7 @@
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
FROM node:18.15-alpine As base
|
||||
FROM node:20.4.0-alpine As base
|
||||
ENV PNPM_HOME="/pnpm"
|
||||
ENV PATH="$PNPM_HOME:$PATH"
|
||||
|
||||
@@ -60,7 +60,7 @@ ARG path
|
||||
RUN --mount=type=cache,id=pnpm,target=/pnpm/store pnpm --offline --filter=$name install && pnpm --filter=$name run build
|
||||
|
||||
# Production image, copy all the files and run next
|
||||
FROM node:current-alpine AS runner
|
||||
FROM node:20.4.0-alpine AS runner
|
||||
WORKDIR /app
|
||||
|
||||
ENV NODE_ENV production
|
||||
@@ -84,7 +84,7 @@ fi
|
||||
USER nextjs
|
||||
|
||||
# You only need to copy next.config.js if you are NOT using the default configuration
|
||||
# COPY --from=builder /app/desktop/next.config.js ./
|
||||
COPY --from=builder /app/$path/next.config.js ./$path/next.config.js
|
||||
COPY --from=builder /app/$path/public ./$path/public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/$path/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/$path/.next/static ./$path/.next/static
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
# Install dependencies only when needed
|
||||
FROM node:current-alpine AS deps
|
||||
FROM node:20.4.0-alpine AS deps
|
||||
# Check https://github.com/nodejs/docker-node/tree/b4117f9333da4138b03a546ec926ef50a31506c3#nodealpine to understand why libc6-compat might be needed.
|
||||
RUN apk add --no-cache libc6-compat && npm install -g pnpm
|
||||
WORKDIR /app
|
||||
|
||||
@@ -15,6 +15,7 @@ const nextConfig = withPWA({
|
||||
reactStrictMode: false,
|
||||
swcMinify: isProduction,
|
||||
output: 'standalone',
|
||||
transpilePackages: ['@sealos/ui'],
|
||||
experimental: {
|
||||
outputFileTracingRoot: path.join(__dirname, '../')
|
||||
}
|
||||
|
||||
@@ -8,12 +8,18 @@
|
||||
"start": "next start",
|
||||
"lint": "next lint",
|
||||
"test:e2e": "jest --testPathPattern=/e2e/ --runInBand",
|
||||
"test:e2e-namespace": "jest --testPathPattern=/e2e/namespace/ --runInBand",
|
||||
"test:e2e-auth": "jest --testPathPattern=/e2e/auth/ --runInBand",
|
||||
"test:ci": "jest --runInBand"
|
||||
},
|
||||
"dependencies": {
|
||||
"@alicloud/dysmsapi20170525": "^2.0.24",
|
||||
"@alicloud/openapi-client": "^0.4.6",
|
||||
"@alicloud/tea-util": "^1.4.7",
|
||||
"@chakra-ui/next-js": "^2.1.5",
|
||||
"@chakra-ui/react": "^2.8.1",
|
||||
"@emotion/react": "^11.11.1",
|
||||
"@emotion/styled": "^11.11.0",
|
||||
"@kubernetes/client-node": "^0.18.1",
|
||||
"@sealos/ui": "workspace:^",
|
||||
"@tanstack/react-query": "^4.35.3",
|
||||
@@ -23,6 +29,7 @@
|
||||
"dayjs": "^1.11.10",
|
||||
"eslint": "8.38.0",
|
||||
"eslint-config-next": "13.3.0",
|
||||
"framer-motion": "^10.16.4",
|
||||
"i18next": "^22.5.1",
|
||||
"immer": "^10.0.2",
|
||||
"js-cookie": "^3.0.5",
|
||||
|
||||
@@ -21,6 +21,14 @@
|
||||
"password tips": "Password must be 8 characters or more",
|
||||
"username tips": "Username must be 3-16 characters, including letters, numbers",
|
||||
"Password": "Password",
|
||||
"change": "change",
|
||||
"changePassword": "Change Password",
|
||||
"currentPassword": "Current Password",
|
||||
"newPassword": "New Password",
|
||||
"confirmNewPassword": "Confirm New Password",
|
||||
"passwordMismatch": "Passwords do not match",
|
||||
"passwordChangeSuccess": "Password changed successfully",
|
||||
"currentPasswordRequired": "Current password cannot be empty",
|
||||
"Verify password": "Verify password",
|
||||
"verify code tips": "6-digit Verification Code",
|
||||
"phone number tips": "Phone Number",
|
||||
|
||||
@@ -17,7 +17,17 @@
|
||||
"phone number tips": "手机号码",
|
||||
"password tips": "密码为8位以上字符",
|
||||
"username tips": "用户名为3-16位的英文或数字的字符",
|
||||
"currentPasswordRequired": "当前密码不能为空",
|
||||
"changePassword": "修改密码",
|
||||
"currentPassword": "当前密码",
|
||||
"newPassword": "新密码",
|
||||
"confirmNewPassword": "确认新密码",
|
||||
"passwordMismatch": "密码不一致",
|
||||
"passwordChangeSuccess": "密码修改成功",
|
||||
"passwordMismatch": "密码不一致",
|
||||
"newPassword": "新密码",
|
||||
"Verify password": "确认密码",
|
||||
"change": "修改",
|
||||
"Invalid username or password": "用户名或密码错误",
|
||||
"Invalid phone number": "无效的手机号码",
|
||||
"Invalid verification code": "无效的验证码",
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import { Session } from 'sealos-desktop-sdk/*';
|
||||
import * as k8s from '@kubernetes/client-node';
|
||||
import { _passwordLoginRequest, _passwordModifyRequest } from '@/api/auth';
|
||||
import { _setAuth, cleanDb, cleanK8s } from '@/__tests__/api/tools';
|
||||
import { _createRequest } from '@/api/namespace';
|
||||
import request from '@/__tests__/api/request';
|
||||
import { Db, MongoClient } from 'mongodb';
|
||||
describe('Password', () => {
|
||||
let session: Session;
|
||||
const createRequest = _createRequest(request);
|
||||
const modifyRequest = _passwordModifyRequest(request);
|
||||
let db: Db;
|
||||
let connection: MongoClient;
|
||||
const setAuth = _setAuth(request);
|
||||
beforeAll(async () => {
|
||||
//@ts-ignore
|
||||
const uri = process.env.MONGODB_URI as string;
|
||||
// console.log('MONGODB_URI', uri)
|
||||
connection = new MongoClient(uri);
|
||||
await connection.connect();
|
||||
db = connection.db();
|
||||
const kc = new k8s.KubeConfig();
|
||||
await cleanK8s(kc, db);
|
||||
await cleanDb(db);
|
||||
const res = await _passwordLoginRequest(request)({ user: 'createTest', password: 'testtest' });
|
||||
expect(res.data?.user).toBeDefined();
|
||||
session = res.data!;
|
||||
setAuth(session);
|
||||
console.log('create,', session.user);
|
||||
}, 100000);
|
||||
afterAll(async () => {
|
||||
await connection.close();
|
||||
});
|
||||
it('modify: null param', async () => {
|
||||
// @ts-ignore
|
||||
const res = await modifyRequest({});
|
||||
// 没参数
|
||||
expect(res.code).toBe(400);
|
||||
/** @ts-ignore **/
|
||||
const res2 = await modifyRequest({ oldPassword: 'testtest' });
|
||||
// 没参数
|
||||
expect(res2.code).toBe(400);
|
||||
/** @ts-ignore **/
|
||||
const res3 = await modifyRequest({ newPassword: 'zxafafa' });
|
||||
// 没参数
|
||||
expect(res3.code).toBe(400);
|
||||
});
|
||||
|
||||
it('error oldPassword', async () => {
|
||||
const res = await modifyRequest({ oldPassword: 'test', newPassword: 'testtest' });
|
||||
expect(res.code).toBe(409);
|
||||
});
|
||||
|
||||
it('same password', async () => {
|
||||
const res = await modifyRequest({ oldPassword: 'testtest', newPassword: 'testtest' });
|
||||
expect(res.code).toBe(409);
|
||||
});
|
||||
it('right password', async () => {
|
||||
const res = await modifyRequest({ oldPassword: 'testtest', newPassword: 'testtest2' });
|
||||
expect(res.code).toBe(200);
|
||||
const res2 = await _passwordLoginRequest(request)({
|
||||
user: 'createTest',
|
||||
password: 'testtest2'
|
||||
});
|
||||
expect(res2.code).toBe(200);
|
||||
});
|
||||
});
|
||||
@@ -4,13 +4,15 @@ import { TUserExist } from '@/types/user';
|
||||
import { ApiResp } from '@/types';
|
||||
import { AxiosInstance } from 'axios';
|
||||
|
||||
export const _passwordExistRequest = (request: AxiosInstance) => (user: string) =>
|
||||
request.post<any, ApiResp<TUserExist>, { user: string }>('/api/auth/password/exist', {
|
||||
user
|
||||
});
|
||||
export const _passwordExistRequest = (request: AxiosInstance) => (data: { user: string }) =>
|
||||
request.post<any, ApiResp<TUserExist>>('/api/auth/password/exist', data);
|
||||
export const _passwordLoginRequest =
|
||||
(request: AxiosInstance) => (data: { user: string; password: string }) =>
|
||||
request.post<any, ApiResp<Session>>('/api/auth/password', data);
|
||||
export const _passwordModifyRequest =
|
||||
(request: AxiosInstance) => (data: { oldPassword: string; newPassword: string }) =>
|
||||
request.post<any, ApiResp<{ message: string }>>('/api/auth/password/modify', data);
|
||||
|
||||
export const passwordExistRequest = _passwordExistRequest(request);
|
||||
export const passwordLoginRequest = _passwordLoginRequest(request);
|
||||
export const passwordModifyRequest = _passwordModifyRequest(request);
|
||||
|
||||
@@ -0,0 +1,190 @@
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
FlexProps,
|
||||
Image,
|
||||
Input,
|
||||
InputGroup,
|
||||
Modal,
|
||||
ModalBody,
|
||||
ModalCloseButton,
|
||||
ModalContent,
|
||||
ModalHeader,
|
||||
ModalOverlay,
|
||||
Spinner,
|
||||
Stack,
|
||||
useDisclosure
|
||||
} from '@chakra-ui/react';
|
||||
import { useMutation } from '@tanstack/react-query';
|
||||
import { useCustomToast } from '@/hooks/useCustomToast';
|
||||
import { ApiResp } from '@/types';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useForm } from 'react-hook-form';
|
||||
import { strongPassword } from '@/utils/crypto';
|
||||
import { passwordModifyRequest } from '@/api/auth';
|
||||
export default function PasswordModify(props: FlexProps) {
|
||||
const { onOpen, isOpen, onClose } = useDisclosure();
|
||||
const { t } = useTranslation();
|
||||
const { toast } = useCustomToast({ status: 'error' });
|
||||
const mutation = useMutation(passwordModifyRequest, {
|
||||
onSuccess(data) {
|
||||
if (data.code === 200) {
|
||||
toast({
|
||||
status: 'success',
|
||||
title: t('passwordChangeSuccess')
|
||||
});
|
||||
onClose();
|
||||
}
|
||||
},
|
||||
onError(error) {
|
||||
toast({ title: (error as ApiResp).message });
|
||||
}
|
||||
});
|
||||
const { register, handleSubmit, reset } = useForm<{
|
||||
oldPassword: string;
|
||||
newPassword: string;
|
||||
againPassword: string;
|
||||
}>();
|
||||
return (
|
||||
<>
|
||||
<Flex
|
||||
_hover={{
|
||||
bgColor: 'rgba(0, 0, 0, 0.03)'
|
||||
}}
|
||||
h="28px"
|
||||
p="4px"
|
||||
transition={'all 0.3s'}
|
||||
justify={'center'}
|
||||
fontSize={'12px'}
|
||||
color="#219BF4"
|
||||
align={'center'}
|
||||
cursor={'pointer'}
|
||||
{...props}
|
||||
onClick={() => {
|
||||
reset();
|
||||
onOpen();
|
||||
}}
|
||||
>
|
||||
{t('change')}
|
||||
</Flex>
|
||||
<Modal isOpen={isOpen} onClose={onClose} isCentered>
|
||||
<ModalOverlay />
|
||||
<ModalContent
|
||||
borderRadius={'4px'}
|
||||
maxW={'380px'}
|
||||
bgColor={'#FFF'}
|
||||
backdropFilter="blur(150px)"
|
||||
p="24px"
|
||||
>
|
||||
<ModalCloseButton right={'24px'} top="24px" p="0" />
|
||||
<ModalHeader p="0">{t('changePassword')}</ModalHeader>
|
||||
{mutation.isLoading ? (
|
||||
<Spinner mx={'auto'} />
|
||||
) : (
|
||||
<>
|
||||
<ModalBody h="100%" w="100%" p="0" mt="22px">
|
||||
<form
|
||||
onSubmit={handleSubmit(
|
||||
({ oldPassword, newPassword }) => {
|
||||
mutation.mutate({ oldPassword, newPassword });
|
||||
},
|
||||
(errors) => {
|
||||
if (errors.oldPassword) return toast({ title: t('currentPasswordRequired') });
|
||||
if (errors.newPassword) return toast({ title: t('password tips') });
|
||||
if (errors.againPassword) return toast({ title: t('passwordMismatch') });
|
||||
}
|
||||
)}
|
||||
>
|
||||
<Stack gap="10px">
|
||||
<Flex
|
||||
w="100%"
|
||||
borderRadius="2px"
|
||||
border="1px solid #DEE0E2"
|
||||
bg="#FBFBFC"
|
||||
align={'center'}
|
||||
py={'11px'}
|
||||
pl={'12px'}
|
||||
>
|
||||
<Input
|
||||
{...register('oldPassword', {
|
||||
required: true
|
||||
})}
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
_autofill={{
|
||||
bgColor: '#FBFBFC'
|
||||
}}
|
||||
placeholder={t('currentPassword') || ''}
|
||||
h="20px"
|
||||
fontSize={'14px'}
|
||||
variant={'unstyled'}
|
||||
borderRadius={'unset'}
|
||||
></Input>
|
||||
</Flex>
|
||||
<Flex
|
||||
w="100%"
|
||||
borderRadius="2px"
|
||||
border="1px solid #DEE0E2"
|
||||
bg="#FBFBFC"
|
||||
align={'center'}
|
||||
py={'11px'}
|
||||
pl={'12px'}
|
||||
>
|
||||
<Input
|
||||
{...register('newPassword', {
|
||||
required: true,
|
||||
validate: strongPassword
|
||||
})}
|
||||
type="password"
|
||||
placeholder={t('newPassword') || ''}
|
||||
autoComplete="new-password"
|
||||
_autofill={{
|
||||
bgColor: '#FBFBFC'
|
||||
}}
|
||||
h="20px"
|
||||
fontSize={'14px'}
|
||||
variant={'unstyled'}
|
||||
borderRadius={'unset'}
|
||||
></Input>
|
||||
</Flex>
|
||||
<Flex
|
||||
w="100%"
|
||||
borderRadius="2px"
|
||||
border="1px solid #DEE0E2"
|
||||
bg="#FBFBFC"
|
||||
align={'center'}
|
||||
py={'11px'}
|
||||
pl={'12px'}
|
||||
>
|
||||
<Input
|
||||
{...register('againPassword', {
|
||||
required: true,
|
||||
validate(value, formValues) {
|
||||
return value === formValues.newPassword;
|
||||
}
|
||||
})}
|
||||
type="password"
|
||||
_autofill={{
|
||||
bgColor: '#FBFBFC'
|
||||
}}
|
||||
autoComplete="new-password"
|
||||
placeholder={t('confirmNewPassword') || ''}
|
||||
h="20px"
|
||||
fontSize={'14px'}
|
||||
variant={'unstyled'}
|
||||
borderRadius={'unset'}
|
||||
></Input>
|
||||
</Flex>
|
||||
</Stack>
|
||||
<Button mt="24px" variant={'primary'} w="full" type="submit">
|
||||
{t('Confirm')}
|
||||
</Button>
|
||||
</form>
|
||||
</ModalBody>
|
||||
</>
|
||||
)}
|
||||
</ModalContent>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -17,24 +17,25 @@ import {
|
||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useRouter } from 'next/router';
|
||||
import { useContext, useEffect, useMemo } from 'react';
|
||||
import { useMemo } from 'react';
|
||||
import Iconfont from '../iconfont';
|
||||
import useAppStore from '@/stores/app';
|
||||
|
||||
import { ApiResp } from '@/types';
|
||||
import { formatMoney } from '@/utils/format';
|
||||
import { RechargeEnabledContext } from '@/pages';
|
||||
import TeamCenter from '@/components/team/TeamCenter';
|
||||
import NsList from '@/components/team/NsList';
|
||||
import { nsListRequest, switchRequest } from '@/api/namespace';
|
||||
import RightIcon from '../icons/RightArrow';
|
||||
import { NSType } from '@/types/team';
|
||||
import PasswordModify from './PasswordModify';
|
||||
import { useGlobalStore } from '@/stores/global';
|
||||
|
||||
const NsMenu = () => {
|
||||
const { t } = useTranslation();
|
||||
const session = useSessionStore((s) => s.session);
|
||||
const setSession = useSessionStore((s) => s.setSession);
|
||||
const { ns_uid, k8s_username } = session.user;
|
||||
const { ns_uid } = session.user;
|
||||
const router = useRouter();
|
||||
const mutation = useMutation({
|
||||
mutationFn: switchRequest,
|
||||
@@ -83,7 +84,7 @@ const NsMenu = () => {
|
||||
transition={'0.3s'}
|
||||
p="4px"
|
||||
>
|
||||
<Text fontSize="14px" fontWeight={'500'} color={'#363C42'}>
|
||||
<Text fontSize="13px" fontWeight={'500'} color={'#363C42'}>
|
||||
{namespace?.nstype === NSType.Private ? t('Default Team') : namespace?.teamName}
|
||||
</Text>
|
||||
<RightIcon w="16px" h="16px" />
|
||||
@@ -112,7 +113,6 @@ const NsMenu = () => {
|
||||
};
|
||||
export default function Index({ disclosure }: { disclosure: UseDisclosureReturn }) {
|
||||
const router = useRouter();
|
||||
const rechargeEnabled = useContext(RechargeEnabledContext);
|
||||
const { t } = useTranslation();
|
||||
const { delSession, getSession } = useSessionStore();
|
||||
const { user, kubeconfig } = getSession();
|
||||
@@ -133,7 +133,6 @@ export default function Index({ disclosure }: { disclosure: UseDisclosureReturn
|
||||
'/api/account/getAmount'
|
||||
)
|
||||
});
|
||||
|
||||
const balance = useMemo(() => {
|
||||
let real_balance = data?.data?.balance || 0;
|
||||
if (data?.data?.deductionBalance) {
|
||||
@@ -146,9 +145,17 @@ export default function Index({ disclosure }: { disclosure: UseDisclosureReturn
|
||||
delSession();
|
||||
router.replace('/signin');
|
||||
};
|
||||
const needPassword = useGlobalStore((s) => s.needPassword);
|
||||
const rechargeEnabled = useGlobalStore((s) => s.rechargeEnabled);
|
||||
return disclosure.isOpen ? (
|
||||
<>
|
||||
<Box position={'fixed'} inset={0} zIndex={'998'} onClick={disclosure.onClose}></Box>
|
||||
<Box
|
||||
position={'fixed'}
|
||||
inset={0}
|
||||
zIndex={'998'}
|
||||
cursor={'initial'}
|
||||
onClick={disclosure.onClose}
|
||||
></Box>
|
||||
<Box
|
||||
w="297px"
|
||||
bg="rgba(255, 255, 255, 0.6)"
|
||||
@@ -156,6 +163,7 @@ export default function Index({ disclosure }: { disclosure: UseDisclosureReturn
|
||||
position={'absolute'}
|
||||
top="48px"
|
||||
right={0}
|
||||
cursor={'initial'}
|
||||
zIndex={'999'}
|
||||
borderRadius={'8px'}
|
||||
p="20px"
|
||||
@@ -186,13 +194,26 @@ export default function Index({ disclosure }: { disclosure: UseDisclosureReturn
|
||||
mt="12px"
|
||||
bg="rgba(255, 255, 255, 0.6)"
|
||||
borderRadius={'8px'}
|
||||
fontSize={'13px'}
|
||||
gap={'0px'}
|
||||
>
|
||||
<Flex alignItems={'center'} borderBottom={'1px solid #0000001A'} p="16px">
|
||||
<Flex alignItems={'center'} borderBottom={'1px solid #0000001A'} px="16px" py="11px">
|
||||
<Text>{t('Manage Team')}</Text>
|
||||
<TeamCenter mr="0" />
|
||||
</Flex>
|
||||
<Flex alignItems={'center'} borderBottom={'1px solid #0000001A'} p="16px">
|
||||
{needPassword && (
|
||||
<Flex
|
||||
justify={'space-between'}
|
||||
alignItems={'center'}
|
||||
borderBottom={'1px solid #0000001A'}
|
||||
px="16px"
|
||||
py="11px"
|
||||
>
|
||||
<Text>{t('changePassword')}</Text>
|
||||
<PasswordModify mr="0" />
|
||||
</Flex>
|
||||
)}
|
||||
<Flex px="16px" py="11px" alignItems={'center'} borderBottom={'1px solid #0000001A'}>
|
||||
<Text>
|
||||
{t('Balance')}: {formatMoney(balance).toFixed(2)}
|
||||
</Text>
|
||||
@@ -217,14 +238,15 @@ export default function Index({ disclosure }: { disclosure: UseDisclosureReturn
|
||||
color={'#219BF4'}
|
||||
fontWeight="500"
|
||||
fontSize="12px"
|
||||
cursor={'pointer'}
|
||||
>
|
||||
{t('Charge')}
|
||||
</Box>
|
||||
)}
|
||||
</Flex>
|
||||
{
|
||||
<Flex alignItems={'center'} py="16px">
|
||||
<Text ml="16px">kubeconfig</Text>
|
||||
<Flex alignItems={'center'} px="16px" py="11px">
|
||||
<Text>kubeconfig</Text>
|
||||
<Box
|
||||
_hover={{
|
||||
bgColor: 'rgba(0, 0, 0, 0.03)'
|
||||
@@ -232,6 +254,7 @@ export default function Index({ disclosure }: { disclosure: UseDisclosureReturn
|
||||
transition={'0.3s'}
|
||||
p="4px"
|
||||
ml="auto"
|
||||
cursor={'pointer'}
|
||||
onClick={() => download('kubeconfig.yaml', kubeconfig)}
|
||||
>
|
||||
<Iconfont
|
||||
@@ -247,7 +270,6 @@ export default function Index({ disclosure }: { disclosure: UseDisclosureReturn
|
||||
}}
|
||||
p="4px"
|
||||
ml="8px"
|
||||
mr="20px"
|
||||
onClick={() => copyData(kubeconfig)}
|
||||
cursor={'pointer'}
|
||||
>
|
||||
|
||||
@@ -121,7 +121,7 @@ export default function DesktopContent(props: any) {
|
||||
textAlign={'center'}
|
||||
mt="8px"
|
||||
color={'#FFFFFF'}
|
||||
fontSize={'10px'}
|
||||
fontSize={'13px'}
|
||||
lineHeight={'16px'}
|
||||
>
|
||||
{item?.i18n?.[i18n?.language]?.name
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import { passwordExistRequest, passwordLoginRequest } from '@/api/auth';
|
||||
import request from '@/services/request';
|
||||
import useSessionStore from '@/stores/session';
|
||||
import { ApiResp, Session } from '@/types';
|
||||
@@ -43,15 +44,9 @@ export default function usePassword({
|
||||
if (data?.username && data?.password) {
|
||||
try {
|
||||
setIsLoading(true);
|
||||
const result = await request.post<any, ApiResp<TUserExist>, { user: string }>(
|
||||
'/api/auth/password/exist',
|
||||
{
|
||||
user: data.username
|
||||
}
|
||||
);
|
||||
|
||||
const result = await passwordExistRequest({ user: data.username });
|
||||
if (result?.code === 200) {
|
||||
const result = await request.post<any, ApiResp<Session>>('/api/auth/password', {
|
||||
const result = await passwordLoginRequest({
|
||||
user: data.username,
|
||||
password: data.password
|
||||
});
|
||||
|
||||
@@ -16,7 +16,6 @@ export default function Index(props: { userMenuStyleProps?: FlexProps }) {
|
||||
const [notificationAmount, setNotificationAmount] = useState(0);
|
||||
const accountDisclosure = useDisclosure();
|
||||
const showDisclosure = useDisclosure();
|
||||
const switchLangDisclosure = useDisclosure();
|
||||
const userInfo = useSessionStore((state) => state.getSession());
|
||||
if (!userInfo) return null;
|
||||
|
||||
@@ -75,7 +74,7 @@ export default function Index(props: { userMenuStyleProps?: FlexProps }) {
|
||||
background={'rgba(244, 246, 248, 0.7)'}
|
||||
boxShadow={'0px 1.2px 2.3px rgba(0, 0, 0, 0.2)'}
|
||||
/>
|
||||
{buttonList.map((item, index) => (
|
||||
{buttonList.map((item) => (
|
||||
<Flex
|
||||
w="36px"
|
||||
h="36px"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
import request from '@/services/request';
|
||||
import { useGlobalStore } from '@/stores/global';
|
||||
import { theme } from '@/styles/chakraTheme';
|
||||
import '@/styles/globals.scss';
|
||||
import { ApiResp, SystemEnv } from '@/types';
|
||||
import { ChakraProvider } from '@chakra-ui/react';
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
||||
import { QueryClient, QueryClientProvider, useQuery } from '@tanstack/react-query';
|
||||
import { appWithTranslation } from 'next-i18next';
|
||||
import type { AppProps } from 'next/app';
|
||||
import Router from 'next/router';
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { authSession, generateJWT } from '@/services/backend/auth';
|
||||
import { queryUsersByNamespace } from '@/services/backend/db/userToNamespace';
|
||||
import { switchNamespace } from '@/services/backend/kubernetes/user';
|
||||
import { jsonRes } from '@/services/backend/response';
|
||||
import * as jsYaml from 'js-yaml';
|
||||
import { Session } from 'sealos-desktop-sdk';
|
||||
@@ -14,11 +13,13 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const nsUsers = await queryUsersByNamespace({ namespaceId: ns_uid });
|
||||
const userInNs = nsUsers.find(
|
||||
(item) => item.userId === payload.user.uid && payload.user.k8s_username === item.k8s_username
|
||||
); // if (
|
||||
if (!userInNs) return jsonRes(res, { code: 403, message: 'you are not in this namespace' });
|
||||
const kubeconfig = jsYaml.dump(
|
||||
JSON.parse(switchNamespace(payload.kc, userInNs?.namespace?.id || '').exportConfig())
|
||||
);
|
||||
if (!userInNs) return jsonRes(res, { code: 403, message: 'you are not in this namespace' });
|
||||
|
||||
const oldKc = jsYaml.load(payload.kcRaw);
|
||||
// @ts-ignore
|
||||
oldKc.contexts[0].context.namespace = userInNs?.namespace?.id || '';
|
||||
const kubeconfig = jsYaml.dump(oldKc);
|
||||
const user = {
|
||||
ns_uid: userInNs.namespaceId,
|
||||
nsid: userInNs.namespace.id,
|
||||
@@ -48,6 +49,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
message: 'Successfully'
|
||||
});
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
jsonRes(res, { code: 500, message: 'fail to switch namespace' });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { jsonRes } from '@/services/backend/response';
|
||||
import { Session } from '@/types/session';
|
||||
import { hashPassword, strongPassword, verifyPassword } from '@/utils/crypto';
|
||||
import { enablePassword } from '@/services/enable';
|
||||
import { authSession } from '@/services/backend/auth';
|
||||
import { queryUser, updateUser } from '@/services/backend/db/user';
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
try {
|
||||
if (!enablePassword()) {
|
||||
throw new Error('PASSWORD_SALT is not defined');
|
||||
}
|
||||
const payload = await authSession(req.headers);
|
||||
if (!payload) return jsonRes(res, { code: 401, message: 'token verify error' });
|
||||
const uid = payload.user.uid;
|
||||
const { oldPassword, newPassword } = req.body;
|
||||
if (!oldPassword) return jsonRes(res, { code: 400, message: 'oldPassword is required' });
|
||||
if (!newPassword) return jsonRes(res, { code: 400, message: 'newPassword is required' });
|
||||
const _user = await queryUser({ id: uid, provider: 'uid' });
|
||||
if (!_user) return jsonRes(res, { code: 404, message: 'user is not founded' });
|
||||
if (!_user.password) {
|
||||
return jsonRes(res, { code: 409, message: 'Please login by password' });
|
||||
}
|
||||
if (
|
||||
!oldPassword ||
|
||||
!verifyPassword(oldPassword, _user.password) ||
|
||||
oldPassword === newPassword
|
||||
) {
|
||||
return jsonRes(res, { code: 409, message: 'password error' });
|
||||
}
|
||||
if (!strongPassword(newPassword)) {
|
||||
return jsonRes(res, {
|
||||
message:
|
||||
'Password must be at least 8 characters long and contain at least one uppercase letter, one lowercase letter, one number and one special character',
|
||||
code: 400
|
||||
});
|
||||
}
|
||||
const updateRes = await updateUser({
|
||||
id: uid,
|
||||
provider: 'uid',
|
||||
data: { password: hashPassword(newPassword) }
|
||||
});
|
||||
if (!updateRes.acknowledged) throw new Error('modify password error');
|
||||
console.log(
|
||||
'modify',
|
||||
updateRes,
|
||||
oldPassword,
|
||||
newPassword,
|
||||
'hash',
|
||||
hashPassword(oldPassword),
|
||||
hashPassword(newPassword)
|
||||
);
|
||||
return jsonRes<Session>(res, {
|
||||
code: 200,
|
||||
message: 'Successfully!'
|
||||
});
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
return jsonRes(res, {
|
||||
message: 'Failed to authenticate with password',
|
||||
code: 500
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,8 @@ import {
|
||||
enableGoogle,
|
||||
enableStripe,
|
||||
enableWechatRecharge,
|
||||
enableLicense
|
||||
enableLicense,
|
||||
enableRecharge
|
||||
} from '@/services/enable';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
@@ -26,7 +27,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
const stripeEnabled = enableStripe();
|
||||
const wechatEnabledRecharge = enableWechatRecharge();
|
||||
const licenseEnabled = enableLicense();
|
||||
|
||||
const rechargeEnabled = enableRecharge();
|
||||
jsonRes(res, {
|
||||
data: {
|
||||
SEALOS_CLOUD_DOMAIN: process.env.SEALOS_CLOUD_DOMAIN || 'cloud.sealos.io',
|
||||
@@ -43,6 +44,7 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
|
||||
needGoogle,
|
||||
stripeEnabled,
|
||||
wechatEnabledRecharge,
|
||||
rechargeEnabled,
|
||||
licenseEnabled
|
||||
}
|
||||
});
|
||||
|
||||
@@ -4,9 +4,10 @@ import MoreApps from '@/components/more_apps';
|
||||
import { enableRecharge } from '@/services/enable';
|
||||
import request from '@/services/request';
|
||||
import useAppStore from '@/stores/app';
|
||||
import { useGlobalStore } from '@/stores/global';
|
||||
import useSessionStore from '@/stores/session';
|
||||
import { ApiResp } from '@/types';
|
||||
import { SystemConfigType } from '@/types/system';
|
||||
import { SystemConfigType, SystemEnv } from '@/types/system';
|
||||
import { parseOpenappQuery } from '@/utils/format';
|
||||
import { compareFirstLanguages } from '@/utils/tools';
|
||||
import { Box, useColorMode } from '@chakra-ui/react';
|
||||
@@ -23,26 +24,23 @@ interface IMoreAppsContext {
|
||||
setShowMoreApps: (value: boolean) => void;
|
||||
}
|
||||
export const MoreAppsContext = createContext<IMoreAppsContext | null>(null);
|
||||
export const RechargeEnabledContext = createContext<boolean>(false);
|
||||
|
||||
export default function Home({
|
||||
rechargeEnabled,
|
||||
sealos_cloud_domain
|
||||
}: {
|
||||
rechargeEnabled: boolean;
|
||||
sealos_cloud_domain: string;
|
||||
}) {
|
||||
export default function Home({ sealos_cloud_domain }: { sealos_cloud_domain: string }) {
|
||||
const router = useRouter();
|
||||
const { isUserLogin, setSession } = useSessionStore();
|
||||
const { colorMode, toggleColorMode } = useColorMode();
|
||||
const init = useAppStore((state) => state.init);
|
||||
const setAutoLaunch = useAppStore((state) => state.setAutoLaunch);
|
||||
const cancelAutoLaunch = useAppStore((state) => state.cancelAutoLaunch);
|
||||
|
||||
const { data: systemConfig, refetch } = useQuery(['getSystemConfig'], () =>
|
||||
request<any, ApiResp<SystemConfigType>>('/api/system/getSystemConfig')
|
||||
);
|
||||
|
||||
const { data: platformEnv, isSuccess } = useQuery(['getPlatformEnv'], () =>
|
||||
request<any, ApiResp<SystemEnv>>('/api/platform/getEnv')
|
||||
);
|
||||
const setEnv = useGlobalStore((s) => s.setEnv);
|
||||
// @ts-ignore
|
||||
if (isSuccess) Object.entries(platformEnv?.data!).forEach(([k, v]) => setEnv(k, v));
|
||||
useEffect(() => {
|
||||
colorMode === 'dark' ? toggleColorMode() : null;
|
||||
}, [colorMode, toggleColorMode]);
|
||||
@@ -52,7 +50,6 @@ export default function Home({
|
||||
const { query } = router;
|
||||
const is_login = isUserLogin();
|
||||
const whitelistApps = ['system-fastdeploy'];
|
||||
console.log('index');
|
||||
if (!is_login) {
|
||||
const { appkey, appQuery } = parseOpenappQuery((query?.openapp as string) || '');
|
||||
// sealos_inside=true internal call
|
||||
@@ -95,11 +92,9 @@ export default function Home({
|
||||
return <Script key={i} {...item} />;
|
||||
})}
|
||||
<MoreAppsContext.Provider value={{ showMoreApps, setShowMoreApps }}>
|
||||
<RechargeEnabledContext.Provider value={rechargeEnabled}>
|
||||
<DesktopContent />
|
||||
<FloatButton />
|
||||
<MoreApps />
|
||||
</RechargeEnabledContext.Provider>
|
||||
<DesktopContent />
|
||||
<FloatButton />
|
||||
<MoreApps />
|
||||
</MoreAppsContext.Provider>
|
||||
</Box>
|
||||
);
|
||||
@@ -110,11 +105,9 @@ export async function getServerSideProps({ req, res, locales }: any) {
|
||||
res.setHeader('Set-Cookie', `NEXT_LOCALE=${local}; Max-Age=2592000; Secure; SameSite=None`);
|
||||
|
||||
const sealos_cloud_domain = process.env.SEALOS_CLOUD_DOMAIN || 'cloud.sealos.io';
|
||||
|
||||
return {
|
||||
props: {
|
||||
...(await serverSideTranslations(local, undefined, null, locales || [])),
|
||||
rechargeEnabled: enableRecharge(),
|
||||
sealos_cloud_domain
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2,7 +2,6 @@ import { IncomingHttpHeaders } from 'http';
|
||||
import { sign, verify } from 'jsonwebtoken';
|
||||
import { K8sApi } from './kubernetes/user';
|
||||
import { JWTPayload } from '@/types';
|
||||
import { queryUTN } from './db/userToNamespace';
|
||||
|
||||
const jwtSecret = (process.env.JWT_SECRET as string) || '123456789';
|
||||
export const authSession = async (header: IncomingHttpHeaders) => {
|
||||
@@ -26,7 +25,7 @@ export const authSession = async (header: IncomingHttpHeaders) => {
|
||||
const username = kc.getCurrentUser()?.name;
|
||||
const user = payload.user;
|
||||
if (!username || user.k8s_username !== username) throw new Error('user is invaild');
|
||||
return Promise.resolve({ kc, user });
|
||||
return Promise.resolve({ kc, user, kcRaw: payload.kubeconfig });
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
return Promise.resolve(null);
|
||||
@@ -47,7 +46,6 @@ export const verifyJWT: (token: string) => Promise<JWTPayload | null> = (token:
|
||||
});
|
||||
});
|
||||
export const generateJWT = (props: JWTPayload) => {
|
||||
console.log('jwt: ', props);
|
||||
return sign(props, jwtSecret, {
|
||||
expiresIn: '7d'
|
||||
});
|
||||
|
||||
@@ -28,15 +28,17 @@ export async function createUser({
|
||||
id,
|
||||
provider,
|
||||
name,
|
||||
avatar_url
|
||||
avatar_url,
|
||||
password
|
||||
}: {
|
||||
id: string;
|
||||
provider: Provider;
|
||||
name: string;
|
||||
avatar_url: string;
|
||||
password?: string;
|
||||
}) {
|
||||
if (!verifyProvider(provider)) return Promise.reject('provider error');
|
||||
const users = await connectToUserCollection();
|
||||
|
||||
let uid = uuid();
|
||||
const k8s_username = await get_k8s_username();
|
||||
let user: User = {
|
||||
@@ -50,10 +52,10 @@ export async function createUser({
|
||||
}
|
||||
]
|
||||
};
|
||||
if (!verifyProvider(provider)) return Promise.reject('provider error');
|
||||
user[provider] = id;
|
||||
await users.insertOne(user);
|
||||
return user;
|
||||
if (password && provider === 'password_user') user.password = password;
|
||||
const res = await users.insertOne(user);
|
||||
return res.acknowledged ? user : null;
|
||||
}
|
||||
export async function updateUser({
|
||||
id,
|
||||
|
||||
@@ -37,18 +37,6 @@ export function K8sApi(config: string): k8s.KubeConfig {
|
||||
}
|
||||
return kc;
|
||||
}
|
||||
export function switchNamespace(oldkc: k8s.KubeConfig, namespace: string) {
|
||||
console.log('old kc :', oldkc);
|
||||
const kc = new k8s.KubeConfig();
|
||||
// console.log(kc)
|
||||
const oldCtx = oldkc.contexts[0];
|
||||
// console.log(oldCtx)
|
||||
kc.loadFromOptions({
|
||||
...oldkc,
|
||||
contexts: [{ ...oldCtx, namespace }]
|
||||
});
|
||||
return kc;
|
||||
}
|
||||
export async function ListPods(
|
||||
kc: k8s.KubeConfig,
|
||||
ns: string
|
||||
|
||||
@@ -154,17 +154,16 @@ async function signUp({
|
||||
password?: string;
|
||||
}) {
|
||||
const ns_uid = uuid();
|
||||
const user = await createUser({ id, provider, name, avatar_url });
|
||||
if (provider === 'password_user') {
|
||||
await updateUser({
|
||||
id,
|
||||
provider: 'password_user',
|
||||
data: { password: hashPassword(password!) }
|
||||
}).catch(async (_) => {
|
||||
await removeUser({ id: '' + id, provider: 'password_user' });
|
||||
throw new Error('Failed to create user by password');
|
||||
});
|
||||
}
|
||||
let user: User | null = null;
|
||||
if (provider === 'password_user') {
|
||||
if (!password) return null;
|
||||
user = await createUser({ id, provider, name, avatar_url, password: hashPassword(password) });
|
||||
} else {
|
||||
user = await createUser({ id, provider, name, avatar_url });
|
||||
}
|
||||
if (!user) return null;
|
||||
const k8s_users = user.k8s_users || [];
|
||||
const userId = user.uid;
|
||||
if (!k8s_users) return null;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
import { create } from 'zustand';
|
||||
import { persist } from 'zustand/middleware';
|
||||
import { immer } from 'zustand/middleware/immer';
|
||||
import { Session, SystemEnv, sessionKey } from '@/types';
|
||||
|
||||
type GlobalState = SystemEnv & {
|
||||
setEnv: <T extends keyof SystemEnv>(env: T, val: SystemEnv[T]) => void;
|
||||
};
|
||||
|
||||
export const useGlobalStore = create<GlobalState>()(
|
||||
persist(
|
||||
immer((set) => ({
|
||||
callback_url: '',
|
||||
github_client_id: '',
|
||||
google_client_id: '',
|
||||
wechat_client_id: '',
|
||||
licenseEnabled: false,
|
||||
needGithub: false,
|
||||
needGoogle: false,
|
||||
needPassword: false,
|
||||
needSms: false,
|
||||
needWechat: false,
|
||||
private_protocol: '',
|
||||
service_protocol: '',
|
||||
stripeEnabled: false,
|
||||
wechatEnabledRecharge: false,
|
||||
SEALOS_CLOUD_DOMAIN: 'cloud.sealos.io',
|
||||
rechargeEnabled: false,
|
||||
setEnv(env, val) {
|
||||
set({ [env]: val });
|
||||
}
|
||||
})),
|
||||
{
|
||||
name: 'sealos-desktop-global'
|
||||
}
|
||||
)
|
||||
);
|
||||
@@ -15,22 +15,26 @@ body,
|
||||
iframe {
|
||||
border: none;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar,
|
||||
::-webkit-scrollbar {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-radius: 8px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-track,
|
||||
::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb,
|
||||
::-webkit-scrollbar-thumb {
|
||||
background: #6a6969;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
::-webkit-scrollbar-thumb:hover,
|
||||
::-webkit-scrollbar-thumb:hover {
|
||||
background: #999;
|
||||
@@ -47,8 +51,8 @@ iframe {
|
||||
fill: currentColor;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
input:-webkit-autofill {
|
||||
background-color: rgba($color: #000000, $alpha: 0.2) !important;
|
||||
background-image: none;
|
||||
color: #000;
|
||||
}
|
||||
@@ -60,11 +64,13 @@ div {
|
||||
border-radius: 10px;
|
||||
transition: 1s;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
&::-webkit-scrollbar-thumb,
|
||||
&::-webkit-scrollbar-thumb {
|
||||
background: rgba(189, 193, 197, 0.5) !important;
|
||||
}
|
||||
|
||||
&::-webkit-scrollbar-thumb:hover,
|
||||
&::-webkit-scrollbar-thumb:hover {
|
||||
background: rgba(189, 193, 197, 1) !important;
|
||||
|
||||
@@ -25,5 +25,6 @@ export type SystemEnv = {
|
||||
SEALOS_CLOUD_DOMAIN: string;
|
||||
stripeEnabled: boolean;
|
||||
wechatEnabledRecharge: boolean;
|
||||
rechargeEnabled: boolean;
|
||||
licenseEnabled: boolean;
|
||||
} & LoginProps;
|
||||
|
||||
Generated
+175
-20
@@ -48,6 +48,18 @@ importers:
|
||||
'@alicloud/tea-util':
|
||||
specifier: ^1.4.7
|
||||
version: 1.4.7
|
||||
'@chakra-ui/next-js':
|
||||
specifier: ^2.1.5
|
||||
version: 2.1.5(@chakra-ui/react@2.8.1)(@emotion/react@11.11.1)(next@13.3.0)(react@18.2.0)
|
||||
'@chakra-ui/react':
|
||||
specifier: ^2.8.1
|
||||
version: 2.8.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.0.37)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@emotion/react':
|
||||
specifier: ^11.11.1
|
||||
version: 11.11.1(@types/react@18.0.37)(react@18.2.0)
|
||||
'@emotion/styled':
|
||||
specifier: ^11.11.0
|
||||
version: 11.11.0(@emotion/react@11.11.1)(@types/react@18.0.37)(react@18.2.0)
|
||||
'@kubernetes/client-node':
|
||||
specifier: ^0.18.1
|
||||
version: 0.18.1
|
||||
@@ -75,6 +87,9 @@ importers:
|
||||
eslint-config-next:
|
||||
specifier: 13.3.0
|
||||
version: 13.3.0(eslint@8.38.0)(typescript@5.2.2)
|
||||
framer-motion:
|
||||
specifier: ^10.16.4
|
||||
version: 10.16.4(react-dom@18.2.0)(react@18.2.0)
|
||||
i18next:
|
||||
specifier: ^22.5.1
|
||||
version: 22.5.1
|
||||
@@ -2924,14 +2939,14 @@ packages:
|
||||
resolution: {integrity: sha512-IGM/yGUHS+8TOQrZGpAKOJl/xGBrmRYJrmbHfUE7zrG3PpQyXvbLDP1M+RggkCFVgHlJi2wpYIf0QtQlU0XZfw==}
|
||||
dev: false
|
||||
|
||||
/@chakra-ui/focus-lock@2.1.0(react@18.2.0):
|
||||
/@chakra-ui/focus-lock@2.1.0(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-EmGx4PhWGjm4dpjRqM4Aa+rCWBxP+Rq8Uc/nAVnD4YVqkEhBkrPTpui2lnjsuxqNaZ24fIAZ10cF1hlpemte/w==}
|
||||
peerDependencies:
|
||||
react: '>=18'
|
||||
dependencies:
|
||||
'@chakra-ui/dom-utils': 2.1.0
|
||||
react: 18.2.0
|
||||
react-focus-lock: 2.9.5(react@18.2.0)
|
||||
react-focus-lock: 2.9.5(@types/react@18.0.37)(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
@@ -3080,7 +3095,7 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@chakra-ui/modal@2.3.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0):
|
||||
/@chakra-ui/modal@2.3.1(@chakra-ui/system@2.6.1)(@types/react@18.0.37)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-TQv1ZaiJMZN+rR9DK0snx/OPwmtaGH1HbZtlYt4W4s6CzyK541fxLRTjIXfEzIGpvNW+b6VFuFjbcR78p4DEoQ==}
|
||||
peerDependencies:
|
||||
'@chakra-ui/system': '>=2.0.0'
|
||||
@@ -3089,7 +3104,7 @@ packages:
|
||||
react-dom: '>=18'
|
||||
dependencies:
|
||||
'@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/focus-lock': 2.1.0(react@18.2.0)
|
||||
'@chakra-ui/focus-lock': 2.1.0(@types/react@18.0.37)(react@18.2.0)
|
||||
'@chakra-ui/portal': 2.1.0(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/react-context': 2.1.0(react@18.2.0)
|
||||
'@chakra-ui/react-types': 2.0.7(react@18.2.0)
|
||||
@@ -3101,11 +3116,26 @@ packages:
|
||||
framer-motion: 10.16.4(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
react-remove-scroll: 2.5.6(react@18.2.0)
|
||||
react-remove-scroll: 2.5.6(@types/react@18.0.37)(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@chakra-ui/next-js@2.1.5(@chakra-ui/react@2.8.1)(@emotion/react@11.11.1)(next@13.3.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-bBd8zeXlAuVwDsjGN0/5ZZJknSbFeiZgJiGdbJo91v2lxKkOwo26b4ggc1ck1t+JR+daU6SrGBjlbQqSuWzyaA==}
|
||||
peerDependencies:
|
||||
'@chakra-ui/react': '>=2.4.0'
|
||||
'@emotion/react': '>=11'
|
||||
next: '>=13'
|
||||
react: '>=18'
|
||||
dependencies:
|
||||
'@chakra-ui/react': 2.8.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.0.37)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@emotion/cache': 11.11.0
|
||||
'@emotion/react': 11.11.1(@types/react@18.0.37)(react@18.2.0)
|
||||
next: 13.3.0(@babel/core@7.23.0)(react-dom@18.2.0)(react@18.2.0)(sass@1.68.0)
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@chakra-ui/next-js@2.1.5(@chakra-ui/react@2.8.1)(@emotion/react@11.11.1)(next@13.4.5)(react@18.2.0):
|
||||
resolution: {integrity: sha512-bBd8zeXlAuVwDsjGN0/5ZZJknSbFeiZgJiGdbJo91v2lxKkOwo26b4ggc1ck1t+JR+daU6SrGBjlbQqSuWzyaA==}
|
||||
peerDependencies:
|
||||
@@ -3454,6 +3484,77 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@chakra-ui/react@2.8.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(@types/react@18.0.37)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UL9Rtj4DovP3+oVbI06gsdfyJJb+wmS2RYnGNXjW9tsjCyXxjlBw9TAUj0jyOfWe0+zd/4juL8+J+QCwmdhptg==}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.0.0
|
||||
'@emotion/styled': ^11.0.0
|
||||
framer-motion: '>=4.0.0'
|
||||
react: '>=18'
|
||||
react-dom: '>=18'
|
||||
dependencies:
|
||||
'@chakra-ui/accordion': 2.3.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react@18.2.0)
|
||||
'@chakra-ui/alert': 2.2.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/avatar': 2.3.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/breadcrumb': 2.2.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/button': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/card': 2.2.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/checkbox': 2.3.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/close-button': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/control-box': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/counter': 2.1.0(react@18.2.0)
|
||||
'@chakra-ui/css-reset': 2.3.0(@emotion/react@11.11.1)(react@18.2.0)
|
||||
'@chakra-ui/editable': 3.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/focus-lock': 2.1.0(@types/react@18.0.37)(react@18.2.0)
|
||||
'@chakra-ui/form-control': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/hooks': 2.2.1(react@18.2.0)
|
||||
'@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/image': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/input': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/layout': 2.3.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/live-region': 2.1.0(react@18.2.0)
|
||||
'@chakra-ui/media-query': 3.3.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/menu': 2.2.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react@18.2.0)
|
||||
'@chakra-ui/modal': 2.3.1(@chakra-ui/system@2.6.1)(@types/react@18.0.37)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/number-input': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/pin-input': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/popover': 2.2.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react@18.2.0)
|
||||
'@chakra-ui/popper': 3.1.0(react@18.2.0)
|
||||
'@chakra-ui/portal': 2.1.0(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/progress': 2.2.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/provider': 2.4.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/radio': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/react-env': 3.1.0(react@18.2.0)
|
||||
'@chakra-ui/select': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/skeleton': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/skip-nav': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/slider': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/spinner': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/stat': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/stepper': 2.3.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/styled-system': 2.9.1
|
||||
'@chakra-ui/switch': 2.1.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react@18.2.0)
|
||||
'@chakra-ui/system': 2.6.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(react@18.2.0)
|
||||
'@chakra-ui/table': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/tabs': 3.0.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/tag': 3.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/textarea': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/theme': 3.3.0(@chakra-ui/styled-system@2.9.1)
|
||||
'@chakra-ui/theme-utils': 2.0.20
|
||||
'@chakra-ui/toast': 7.0.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/tooltip': 2.3.0(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/transition': 2.1.0(framer-motion@10.16.4)(react@18.2.0)
|
||||
'@chakra-ui/utils': 2.0.15
|
||||
'@chakra-ui/visually-hidden': 2.2.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@emotion/react': 11.11.1(@types/react@18.0.37)(react@18.2.0)
|
||||
'@emotion/styled': 11.11.0(@emotion/react@11.11.1)(@types/react@18.0.37)(react@18.2.0)
|
||||
framer-motion: 10.16.4(react-dom@18.2.0)(react@18.2.0)
|
||||
react: 18.2.0
|
||||
react-dom: 18.2.0(react@18.2.0)
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
dev: false
|
||||
|
||||
/@chakra-ui/react@2.8.1(@emotion/react@11.11.1)(@emotion/styled@11.11.0)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0):
|
||||
resolution: {integrity: sha512-UL9Rtj4DovP3+oVbI06gsdfyJJb+wmS2RYnGNXjW9tsjCyXxjlBw9TAUj0jyOfWe0+zd/4juL8+J+QCwmdhptg==}
|
||||
peerDependencies:
|
||||
@@ -3475,7 +3576,7 @@ packages:
|
||||
'@chakra-ui/counter': 2.1.0(react@18.2.0)
|
||||
'@chakra-ui/css-reset': 2.3.0(@emotion/react@11.11.1)(react@18.2.0)
|
||||
'@chakra-ui/editable': 3.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/focus-lock': 2.1.0(react@18.2.0)
|
||||
'@chakra-ui/focus-lock': 2.1.0(@types/react@18.0.37)(react@18.2.0)
|
||||
'@chakra-ui/form-control': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/hooks': 2.2.1(react@18.2.0)
|
||||
'@chakra-ui/icon': 3.2.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
@@ -3485,7 +3586,7 @@ packages:
|
||||
'@chakra-ui/live-region': 2.1.0(react@18.2.0)
|
||||
'@chakra-ui/media-query': 3.3.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/menu': 2.2.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react@18.2.0)
|
||||
'@chakra-ui/modal': 2.3.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/modal': 2.3.1(@chakra-ui/system@2.6.1)(@types/react@18.0.37)(framer-motion@10.16.4)(react-dom@18.2.0)(react@18.2.0)
|
||||
'@chakra-ui/number-input': 2.1.1(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/pin-input': 2.1.0(@chakra-ui/system@2.6.1)(react@18.2.0)
|
||||
'@chakra-ui/popover': 2.2.1(@chakra-ui/system@2.6.1)(framer-motion@10.16.4)(react@18.2.0)
|
||||
@@ -3956,6 +4057,7 @@ packages:
|
||||
|
||||
/@emotion/memoize@0.7.4:
|
||||
resolution: {integrity: sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
@@ -3984,6 +4086,27 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/react@11.11.1(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-5mlW1DquU5HaxjLkfkGN1GA/fvVGdyHURRiX/0FHl2cfIfRxSOfmxEH5YS43edp0OldZrZ+dkBKbngxcNCdZvA==}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: '>=16.8.0'
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.1
|
||||
'@emotion/babel-plugin': 11.11.0
|
||||
'@emotion/cache': 11.11.0
|
||||
'@emotion/serialize': 1.1.2
|
||||
'@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
|
||||
'@emotion/utils': 1.2.1
|
||||
'@emotion/weak-memoize': 0.3.1
|
||||
'@types/react': 18.0.37
|
||||
hoist-non-react-statics: 3.3.2
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/serialize@1.1.2:
|
||||
resolution: {integrity: sha512-zR6a/fkFP4EAcCMQtLOhIgpprZOwNmCldtpaISpvz348+DP4Mz8ZoKaGGCQpbzepNIUWbq4w6hNZkwDyKoS+HA==}
|
||||
dependencies:
|
||||
@@ -4019,6 +4142,27 @@ packages:
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/styled@11.11.0(@emotion/react@11.11.1)(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-hM5Nnvu9P3midq5aaXj4I+lnSfNi7Pmd4EWk1fOZ3pxookaQTNew6bp4JaCBYM4HVFZF9g7UjJmsUmC2JlxOng==}
|
||||
peerDependencies:
|
||||
'@emotion/react': ^11.0.0-rc.0
|
||||
'@types/react': '*'
|
||||
react: '>=16.8.0'
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.1
|
||||
'@emotion/babel-plugin': 11.11.0
|
||||
'@emotion/is-prop-valid': 1.2.1
|
||||
'@emotion/react': 11.11.1(@types/react@18.0.37)(react@18.2.0)
|
||||
'@emotion/serialize': 1.1.2
|
||||
'@emotion/use-insertion-effect-with-fallbacks': 1.0.1(react@18.2.0)
|
||||
'@emotion/utils': 1.2.1
|
||||
'@types/react': 18.0.37
|
||||
react: 18.2.0
|
||||
dev: false
|
||||
|
||||
/@emotion/unitless@0.8.1:
|
||||
resolution: {integrity: sha512-KOEGMu6dmJZtpadb476IsZBclKvILjopjUii3V+7MnXIQCYh8W3NgNcgwo21n9LXZX6EDIKvqfjYxXebDwxKmQ==}
|
||||
dev: false
|
||||
@@ -11172,6 +11316,7 @@ packages:
|
||||
|
||||
/jose@4.14.6:
|
||||
resolution: {integrity: sha512-EqJPEUlZD0/CSUMubKtMaYUOtWe91tZXTWMJZoKSbLk+KtdhNdcvppH8lA9XwVu2V4Ailvsj0GBZJ2ZwDjfesQ==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
@@ -11781,6 +11926,7 @@ packages:
|
||||
|
||||
/memory-pager@1.5.0:
|
||||
resolution: {integrity: sha512-ZS4Bp4r/Zoeq6+NLJpP+0Zzm0pR8whtGPf1XExKLJBAczGMnSi3It14OiNCStjQjM6NU1okjQGSxgEZN8eBYKg==}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
@@ -12664,6 +12810,7 @@ packages:
|
||||
/object-hash@2.2.0:
|
||||
resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==}
|
||||
engines: {node: '>= 6'}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
@@ -12753,6 +12900,7 @@ packages:
|
||||
/oidc-token-hash@5.0.3:
|
||||
resolution: {integrity: sha512-IF4PcGgzAr6XXSff26Sk/+P4KZFJVuHAJZj3wgO3vX2bMdNVp/QXTP3P7CEm9V1IdG8lDLY3HhiqpsE/nOwpPw==}
|
||||
engines: {node: ^10.13.0 || >=12.0.0}
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
@@ -13255,7 +13403,7 @@ packages:
|
||||
resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==}
|
||||
dev: false
|
||||
|
||||
/react-focus-lock@2.9.5(react@18.2.0):
|
||||
/react-focus-lock@2.9.5(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-h6vrdgUbsH2HeD5I7I3Cx1PPrmwGuKYICS+kB9m+32X/9xHRrAbxgvaBpG7BFBN9h3tO+C3qX1QAVESmi4CiIA==}
|
||||
peerDependencies:
|
||||
'@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0
|
||||
@@ -13265,12 +13413,13 @@ packages:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@babel/runtime': 7.23.1
|
||||
'@types/react': 18.0.37
|
||||
focus-lock: 0.11.6
|
||||
prop-types: 15.8.1
|
||||
react: 18.2.0
|
||||
react-clientside-effect: 1.2.6(react@18.2.0)
|
||||
use-callback-ref: 1.3.0(react@18.2.0)
|
||||
use-sidecar: 1.1.2(react@18.2.0)
|
||||
use-callback-ref: 1.3.0(@types/react@18.0.37)(react@18.2.0)
|
||||
use-sidecar: 1.1.2(@types/react@18.0.37)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react-hook-form@7.46.2(react@18.2.0):
|
||||
@@ -13349,7 +13498,7 @@ packages:
|
||||
szfe-tools: 0.0.0-beta.7
|
||||
dev: false
|
||||
|
||||
/react-remove-scroll-bar@2.3.4(react@18.2.0):
|
||||
/react-remove-scroll-bar@2.3.4(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
@@ -13359,12 +13508,13 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.0.37
|
||||
react: 18.2.0
|
||||
react-style-singleton: 2.2.1(react@18.2.0)
|
||||
react-style-singleton: 2.2.1(@types/react@18.0.37)(react@18.2.0)
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/react-remove-scroll@2.5.6(react@18.2.0):
|
||||
/react-remove-scroll@2.5.6(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-bO856ad1uDYLefgArk559IzUNeQ6SWH4QnrevIUjH+GczV56giDfl3h0Idptf2oIKxQmd1p9BN25jleKodTALg==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
@@ -13374,15 +13524,16 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.0.37
|
||||
react: 18.2.0
|
||||
react-remove-scroll-bar: 2.3.4(react@18.2.0)
|
||||
react-style-singleton: 2.2.1(react@18.2.0)
|
||||
react-remove-scroll-bar: 2.3.4(@types/react@18.0.37)(react@18.2.0)
|
||||
react-style-singleton: 2.2.1(@types/react@18.0.37)(react@18.2.0)
|
||||
tslib: 2.6.2
|
||||
use-callback-ref: 1.3.0(react@18.2.0)
|
||||
use-sidecar: 1.1.2(react@18.2.0)
|
||||
use-callback-ref: 1.3.0(@types/react@18.0.37)(react@18.2.0)
|
||||
use-sidecar: 1.1.2(@types/react@18.0.37)(react@18.2.0)
|
||||
dev: false
|
||||
|
||||
/react-style-singleton@2.2.1(react@18.2.0):
|
||||
/react-style-singleton@2.2.1(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
@@ -13392,6 +13543,7 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.0.37
|
||||
get-nonce: 1.0.1
|
||||
invariant: 2.2.4
|
||||
react: 18.2.0
|
||||
@@ -14083,6 +14235,7 @@ packages:
|
||||
|
||||
/sparse-bitfield@3.0.3:
|
||||
resolution: {integrity: sha512-kvzhi7vqKTfkh0PZU+2D2PIllw2ymqJKujUcyPMd9Y75Nv4nPbGJZXNhxsgdQab2BmlDct1YnfQCguEvHr7VsQ==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
memory-pager: 1.5.0
|
||||
dev: false
|
||||
@@ -14864,7 +15017,7 @@ packages:
|
||||
requires-port: 1.0.0
|
||||
dev: true
|
||||
|
||||
/use-callback-ref@1.3.0(react@18.2.0):
|
||||
/use-callback-ref@1.3.0(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
@@ -14874,11 +15027,12 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.0.37
|
||||
react: 18.2.0
|
||||
tslib: 2.6.2
|
||||
dev: false
|
||||
|
||||
/use-sidecar@1.1.2(react@18.2.0):
|
||||
/use-sidecar@1.1.2(@types/react@18.0.37)(react@18.2.0):
|
||||
resolution: {integrity: sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==}
|
||||
engines: {node: '>=10'}
|
||||
peerDependencies:
|
||||
@@ -14888,6 +15042,7 @@ packages:
|
||||
'@types/react':
|
||||
optional: true
|
||||
dependencies:
|
||||
'@types/react': 18.0.37
|
||||
detect-node-es: 1.1.0
|
||||
react: 18.2.0
|
||||
tslib: 2.6.2
|
||||
|
||||
@@ -9,4 +9,4 @@ module.exports = {
|
||||
locales: ['en', 'zh'],
|
||||
localeDetection: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,4 +9,4 @@ module.exports = {
|
||||
locales: ['en', 'zh'],
|
||||
localeDetection: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,4 +9,4 @@ module.exports = {
|
||||
locales: ['en', 'zh'],
|
||||
localeDetection: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,4 +9,4 @@ module.exports = {
|
||||
locales: ['en', 'zh'],
|
||||
localeDetection: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,4 +9,4 @@ module.exports = {
|
||||
locales: ['en', 'zh'],
|
||||
localeDetection: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -9,4 +9,4 @@ module.exports = {
|
||||
locales: ['en', 'zh'],
|
||||
localeDetection: false
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -85,7 +85,8 @@ const Header = ({
|
||||
h={'80px'}
|
||||
borderRadius={'8px'}
|
||||
backgroundColor={'#FBFBFC'}
|
||||
border={' 1px solid rgba(255, 255, 255, 0.50)'}>
|
||||
border={' 1px solid rgba(255, 255, 255, 0.50)'}
|
||||
>
|
||||
<Image src={templateDetail?.spec?.icon} alt="" width={'60px'} height={'60px'} />
|
||||
</Flex>
|
||||
<Flex ml={'24px'} w="520px" flexDirection={'column'}>
|
||||
@@ -102,7 +103,8 @@ const Header = ({
|
||||
_hover={{
|
||||
background: '#F4F6F8'
|
||||
}}
|
||||
onClick={(e) => goGithub(e, templateDetail?.spec?.gitRepo)}>
|
||||
onClick={(e) => goGithub(e, templateDetail?.spec?.gitRepo)}
|
||||
>
|
||||
<HomePageIcon />
|
||||
<Text fontSize={'12px '} fontWeight={400} pl="6px">
|
||||
{t('Home Page')}
|
||||
@@ -119,7 +121,8 @@ const Header = ({
|
||||
alignItems={'center'}
|
||||
_hover={{
|
||||
background: '#F4F6F8'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<ShareIcon />
|
||||
<Text fontSize={'12px '} fontWeight={400} color={'#485058'} pl="6px">
|
||||
{t('Share')}
|
||||
@@ -134,7 +137,8 @@ const Header = ({
|
||||
w="60px"
|
||||
flexDirection={'column'}
|
||||
justifyContent={'center'}
|
||||
alignItems={'center'}>
|
||||
alignItems={'center'}
|
||||
>
|
||||
<Flex {...IconBox}>
|
||||
<CopyLinkIcon />
|
||||
</Flex>
|
||||
@@ -150,7 +154,8 @@ const Header = ({
|
||||
<Flex
|
||||
flexDirection={'column'}
|
||||
alignItems={'center'}
|
||||
onClick={() => copyData(HtmlPart)}>
|
||||
onClick={() => copyData(HtmlPart)}
|
||||
>
|
||||
<Flex {...IconBox}>
|
||||
<HtmlIcon />
|
||||
</Flex>
|
||||
@@ -162,7 +167,8 @@ const Header = ({
|
||||
flexDirection={'column'}
|
||||
alignItems={'center'}
|
||||
ml="auto"
|
||||
onClick={() => copyData(MdPart)}>
|
||||
onClick={() => copyData(MdPart)}
|
||||
>
|
||||
<Flex {...IconBox}>
|
||||
<MdIcon />
|
||||
</Flex>
|
||||
@@ -188,7 +194,8 @@ const Header = ({
|
||||
mt={'8px'}
|
||||
fontSize={'12px'}
|
||||
color={'5A646E'}
|
||||
fontWeight={400}>
|
||||
fontWeight={400}
|
||||
>
|
||||
{templateDetail?.spec?.description}
|
||||
</Text>
|
||||
</Tooltip>
|
||||
@@ -203,7 +210,8 @@ const Header = ({
|
||||
bg={'myWhite.600'}
|
||||
borderColor={'myGray.200'}
|
||||
variant={'base'}
|
||||
onClick={handleExportYaml}>
|
||||
onClick={handleExportYaml}
|
||||
>
|
||||
{t('Export')} Yaml
|
||||
</Button>
|
||||
<Button px={4} minW={'140px'} h={'40px'} variant={'primary'} onClick={applyCb}>
|
||||
|
||||
@@ -256,7 +256,8 @@ export default function EditApp({ appName }: { appName?: string }) {
|
||||
overflow={'auto'}
|
||||
position={'relative'}
|
||||
borderRadius={'12px'}
|
||||
background={'linear-gradient(180deg, #FFF 0%, rgba(255, 255, 255, 0.70) 100%)'}>
|
||||
background={'linear-gradient(180deg, #FFF 0%, rgba(255, 255, 255, 0.70) 100%)'}
|
||||
>
|
||||
<Flex
|
||||
zIndex={99}
|
||||
position={'sticky'}
|
||||
@@ -268,13 +269,15 @@ export default function EditApp({ appName }: { appName?: string }) {
|
||||
justifyContent={'start'}
|
||||
alignItems={'center'}
|
||||
backgroundColor={'rgba(255, 255, 255)'}
|
||||
backdropBlur={'100px'}>
|
||||
backdropBlur={'100px'}
|
||||
>
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
fontWeight={500}
|
||||
fontSize={16}
|
||||
color={'#7B838B'}
|
||||
cursor={'pointer'}>
|
||||
cursor={'pointer'}
|
||||
>
|
||||
<Flex
|
||||
alignItems={'center'}
|
||||
css={{
|
||||
@@ -285,14 +288,16 @@ export default function EditApp({ appName }: { appName?: string }) {
|
||||
fill: '#219BF4'
|
||||
}
|
||||
}
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<Icon
|
||||
ml={'19px'}
|
||||
viewBox="0 0 15 15"
|
||||
fill={'#24282C'}
|
||||
w={'15px'}
|
||||
h="15px"
|
||||
onClick={() => router.push('/')}>
|
||||
onClick={() => router.push('/')}
|
||||
>
|
||||
<path d="M9.1875 13.1875L3.92187 7.9375C3.85937 7.875 3.81521 7.80729 3.78937 7.73438C3.76312 7.66146 3.75 7.58333 3.75 7.5C3.75 7.41667 3.76312 7.33854 3.78937 7.26562C3.81521 7.19271 3.85937 7.125 3.92187 7.0625L9.1875 1.79687C9.33333 1.65104 9.51562 1.57812 9.73438 1.57812C9.95312 1.57812 10.1406 1.65625 10.2969 1.8125C10.4531 1.96875 10.5312 2.15104 10.5312 2.35938C10.5312 2.56771 10.4531 2.75 10.2969 2.90625L5.70312 7.5L10.2969 12.0938C10.4427 12.2396 10.5156 12.4192 10.5156 12.6325C10.5156 12.8463 10.4375 13.0312 10.2812 13.1875C10.125 13.3438 9.94271 13.4219 9.73438 13.4219C9.52604 13.4219 9.34375 13.3438 9.1875 13.1875Z" />
|
||||
</Icon>
|
||||
<Text ml="4px" onClick={() => router.push('/')}>
|
||||
@@ -303,7 +308,8 @@ export default function EditApp({ appName }: { appName?: string }) {
|
||||
<Text
|
||||
onClick={copyTemplateLink}
|
||||
_hover={{ fill: '#219BF4', color: '#219BF4' }}
|
||||
color={router.pathname === '/deploy' ? '#262A32' : '#7B838B'}>
|
||||
color={router.pathname === '/deploy' ? '#262A32' : '#7B838B'}
|
||||
>
|
||||
{data?.templateYaml?.metadata?.name}
|
||||
</Text>
|
||||
</Flex>
|
||||
@@ -314,7 +320,8 @@ export default function EditApp({ appName }: { appName?: string }) {
|
||||
flexDirection={'column'}
|
||||
width={'100%'}
|
||||
flexGrow={1}
|
||||
backgroundColor={'rgba(255, 255, 255, 0.90)'}>
|
||||
backgroundColor={'rgba(255, 255, 255, 0.90)'}
|
||||
>
|
||||
<Header
|
||||
cloudDomain={platformEnvs?.SEALOS_CLOUD_DOMAIN || ''}
|
||||
templateDetail={data?.templateYaml!}
|
||||
|
||||
@@ -190,7 +190,8 @@ export default function Develop() {
|
||||
borderRadius={'8px'}
|
||||
overflowY={'hidden'}
|
||||
overflowX={'scroll'}
|
||||
flex={1}>
|
||||
flex={1}
|
||||
>
|
||||
{/* left */}
|
||||
<Flex flexDirection={'column'} w="50%" borderRight={'1px solid #EFF0F1'}>
|
||||
<Flex
|
||||
@@ -200,7 +201,8 @@ export default function Develop() {
|
||||
alignItems={'center'}
|
||||
backgroundColor={'#F8FAFB'}
|
||||
px="36px"
|
||||
borderRadius={'8px 8px 0px 0px '}>
|
||||
borderRadius={'8px 8px 0px 0px '}
|
||||
>
|
||||
<MyIcon name="dev" color={'#24282C'} w={'24px'} h={'24px'}></MyIcon>
|
||||
<Text fontWeight={'500'} fontSize={'16px'} color={'#24282C'} ml="8px">
|
||||
{t('develop.Development')}
|
||||
@@ -228,7 +230,8 @@ export default function Develop() {
|
||||
alignItems={'center'}
|
||||
backgroundColor={'#F8FAFB'}
|
||||
pl="42px"
|
||||
borderRadius={'8px 8px 0px 0px '}>
|
||||
borderRadius={'8px 8px 0px 0px '}
|
||||
>
|
||||
<MyIcon name="eyeShow" color={'#24282C'} w={'24px'} h={'24px'}></MyIcon>
|
||||
<Text fontWeight={'500'} fontSize={'16px'} color={'#24282C'} ml="8px">
|
||||
{t('develop.Preview')}
|
||||
@@ -240,7 +243,8 @@ export default function Develop() {
|
||||
pt="26px"
|
||||
pr={{ sm: '20px', md: '60px' }}
|
||||
borderBottom={'1px solid #EFF0F1'}
|
||||
flexDirection={'column'}>
|
||||
flexDirection={'column'}
|
||||
>
|
||||
<Text fontWeight={'500'} fontSize={'18px'} color={'#24282C'}>
|
||||
{t('develop.Configure Form')}
|
||||
</Text>
|
||||
@@ -256,7 +260,8 @@ export default function Develop() {
|
||||
minW={'100px'}
|
||||
h={'34px'}
|
||||
variant={'link'}
|
||||
onClick={handleExportYaml}>
|
||||
onClick={handleExportYaml}
|
||||
>
|
||||
{t('Export')} Yaml
|
||||
</Button>
|
||||
</Flex>
|
||||
|
||||
@@ -73,13 +73,15 @@ export default function AppList() {
|
||||
borderRadius={'12px'}
|
||||
background={'linear-gradient(180deg, #FFF 0%, rgba(255, 255, 255, 0.70) 100%)'}
|
||||
py={'36px'}
|
||||
px="42px">
|
||||
px="42px"
|
||||
>
|
||||
<Grid
|
||||
justifyContent={'center'}
|
||||
w={'100%'}
|
||||
gridTemplateColumns="repeat(auto-fill,minmax(300px,1fr))"
|
||||
gridGap={'24px'}
|
||||
minW={'765px'}>
|
||||
minW={'765px'}
|
||||
>
|
||||
{filterData &&
|
||||
filterData?.map((item: TemplateType) => {
|
||||
return (
|
||||
@@ -99,7 +101,8 @@ export default function AppList() {
|
||||
borderRadius={'8px'}
|
||||
backgroundColor={'#fff'}
|
||||
boxShadow={'0px 2px 4px 0px rgba(187, 196, 206, 0.25)'}
|
||||
border={'1px solid #EAEBF0'}>
|
||||
border={'1px solid #EAEBF0'}
|
||||
>
|
||||
<Box
|
||||
p={'6px'}
|
||||
w={'48px'}
|
||||
@@ -107,7 +110,8 @@ export default function AppList() {
|
||||
boxShadow={'0px 1px 2px 0.5px rgba(84, 96, 107, 0.20)'}
|
||||
borderRadius={'4px'}
|
||||
backgroundColor={'#fff'}
|
||||
border={' 1px solid rgba(255, 255, 255, 0.50)'}>
|
||||
border={' 1px solid rgba(255, 255, 255, 0.50)'}
|
||||
>
|
||||
<Image src={item?.spec?.icon} alt="" width={'36px'} height={'36px'} />
|
||||
</Box>
|
||||
<Flex mt={'12px'} alignItems={'center'} justifyContent="space-between">
|
||||
@@ -123,7 +127,8 @@ export default function AppList() {
|
||||
h={'28px'}
|
||||
borderRadius={'4px'}
|
||||
border={'1px solid #DEE0E2'}
|
||||
backgroundColor={'#F4F6F8'}>
|
||||
backgroundColor={'#F4F6F8'}
|
||||
>
|
||||
Deploy
|
||||
</Flex>
|
||||
</Flex>
|
||||
@@ -139,7 +144,8 @@ export default function AppList() {
|
||||
mt={'8px'}
|
||||
fontSize={'12px'}
|
||||
color={'5A646E'}
|
||||
fontWeight={400}>
|
||||
fontWeight={400}
|
||||
>
|
||||
{item?.spec?.description}
|
||||
</Text>
|
||||
<Flex mt={'auto'} justifyContent={'space-between'} alignItems={'center'}>
|
||||
@@ -155,7 +161,8 @@ export default function AppList() {
|
||||
fill="#5A646E"
|
||||
_hover={{
|
||||
fill: '#0884DD'
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
<path d="M13.6667 9.00004C13.4 9.00004 13.1667 9.23337 13.1667 9.50004V13.5C13.1667 13.6 13.1 13.6667 13 13.6667H3C2.9 13.6667 2.83333 13.6 2.83333 13.5V3.50004C2.83333 3.40004 2.9 3.33337 3 3.33337H7C7.26667 3.33337 7.5 3.10004 7.5 2.83337C7.5 2.56671 7.26667 2.33337 7 2.33337H3C2.36667 2.33337 1.83333 2.86671 1.83333 3.50004V13.5C1.83333 14.1334 2.36667 14.6667 3 14.6667H13C13.6333 14.6667 14.1667 14.1334 14.1667 13.5V9.50004C14.1667 9.23337 13.9333 9.00004 13.6667 9.00004Z" />
|
||||
<path d="M13.6667 2.33337H10C9.73333 2.33337 9.5 2.56671 9.5 2.83337C9.5 3.10004 9.73333 3.33337 10 3.33337H12.4667L7.96667 7.80004C7.76667 8.00004 7.76667 8.30004 7.96667 8.50004C8.06667 8.60004 8.2 8.63337 8.33333 8.63337C8.46667 8.63337 8.6 8.60004 8.7 8.50004L13.1667 4.03337V6.50004C13.1667 6.76671 13.4 7.00004 13.6667 7.00004C13.9333 7.00004 14.1667 6.76671 14.1667 6.50004V2.83337C14.1667 2.56671 13.9333 2.33337 13.6667 2.33337Z" />
|
||||
</Icon>
|
||||
|
||||
@@ -112,7 +112,8 @@ export default function AppList({ instanceName }: { instanceName: string }) {
|
||||
variant={'base'}
|
||||
leftIcon={<MyIcon name={'detail'} transform={'translateY(-1px)'} />}
|
||||
px={3}
|
||||
onClick={() => handleToDetailPage(item.name)}>
|
||||
onClick={() => handleToDetailPage(item.name)}
|
||||
>
|
||||
{t('Details')}
|
||||
</Button>
|
||||
</Flex>
|
||||
@@ -141,14 +142,16 @@ export default function AppList({ instanceName }: { instanceName: string }) {
|
||||
justifyContent={'center'}
|
||||
alignItems={'center'}
|
||||
background={'white'}
|
||||
p="32px">
|
||||
p="32px"
|
||||
>
|
||||
<Flex
|
||||
border={'1px dashed #9CA2A8'}
|
||||
borderRadius="50%"
|
||||
w={'48px'}
|
||||
h={'48px'}
|
||||
justifyContent="center"
|
||||
alignItems={'center'}>
|
||||
alignItems={'center'}
|
||||
>
|
||||
<MyIcon color={'#7B838B'} name="empty"></MyIcon>
|
||||
</Flex>
|
||||
<Text mt={'12px'} fontSize={14} color={'#5A646E'}>
|
||||
|
||||
@@ -100,7 +100,8 @@ export default function CronJobList({ instanceName }: { instanceName: string })
|
||||
variant={'base'}
|
||||
leftIcon={<MyIcon name={'detail'} transform={'translateY(-1px)'} />}
|
||||
px={3}
|
||||
onClick={() => handleToDetailPage(item.name)}>
|
||||
onClick={() => handleToDetailPage(item.name)}
|
||||
>
|
||||
{t('Details')}
|
||||
</Button>
|
||||
</Flex>
|
||||
@@ -129,14 +130,16 @@ export default function CronJobList({ instanceName }: { instanceName: string })
|
||||
justifyContent={'center'}
|
||||
alignItems={'center'}
|
||||
background={'white'}
|
||||
p="32px">
|
||||
p="32px"
|
||||
>
|
||||
<Flex
|
||||
border={'1px dashed #9CA2A8'}
|
||||
borderRadius="50%"
|
||||
w={'48px'}
|
||||
h={'48px'}
|
||||
justifyContent="center"
|
||||
alignItems={'center'}>
|
||||
alignItems={'center'}
|
||||
>
|
||||
<MyIcon color={'#7B838B'} name="empty"></MyIcon>
|
||||
</Flex>
|
||||
<Text mt={'12px'} fontSize={14} color={'#5A646E'}>
|
||||
|
||||
@@ -98,7 +98,8 @@ export default function AppList({ instanceName }: { instanceName: string }) {
|
||||
variant={'base'}
|
||||
leftIcon={<MyIcon name={'detail'} transform={'translateY(-1px)'} />}
|
||||
px={3}
|
||||
onClick={() => handleToDetailPage(item.name)}>
|
||||
onClick={() => handleToDetailPage(item.name)}
|
||||
>
|
||||
{t('Details')}
|
||||
</Button>
|
||||
</Flex>
|
||||
@@ -129,14 +130,16 @@ export default function AppList({ instanceName }: { instanceName: string }) {
|
||||
justifyContent={'center'}
|
||||
alignItems={'center'}
|
||||
background={'white'}
|
||||
p="32px">
|
||||
p="32px"
|
||||
>
|
||||
<Flex
|
||||
border={'1px dashed #9CA2A8'}
|
||||
borderRadius="50%"
|
||||
w={'48px'}
|
||||
h={'48px'}
|
||||
justifyContent="center"
|
||||
alignItems={'center'}>
|
||||
alignItems={'center'}
|
||||
>
|
||||
<MyIcon color={'#7B838B'} name="empty"></MyIcon>
|
||||
</Flex>
|
||||
<Text mt={'12px'} fontSize={14} color={'#5A646E'}>
|
||||
|
||||
@@ -86,7 +86,8 @@ const DelModal = ({
|
||||
variant={'solid'}
|
||||
isDisabled={inputValue !== name}
|
||||
isLoading={loading}
|
||||
onClick={handleDelApp}>
|
||||
onClick={handleDelApp}
|
||||
>
|
||||
{t('Confirm deletion')}
|
||||
</Button>
|
||||
</ModalFooter>
|
||||
|
||||
@@ -81,14 +81,16 @@ export default function OtherList({ instanceName }: { instanceName: string }) {
|
||||
justifyContent={'center'}
|
||||
alignItems={'center'}
|
||||
background={'white'}
|
||||
p="32px">
|
||||
p="32px"
|
||||
>
|
||||
<Flex
|
||||
border={'1px dashed #9CA2A8'}
|
||||
borderRadius="50%"
|
||||
w={'48px'}
|
||||
h={'48px'}
|
||||
justifyContent="center"
|
||||
alignItems={'center'}>
|
||||
alignItems={'center'}
|
||||
>
|
||||
<MyIcon color={'#7B838B'} name="empty"></MyIcon>
|
||||
</Flex>
|
||||
<Text mt={'12px'} fontSize={14} color={'#5A646E'}>
|
||||
|
||||
Reference in New Issue
Block a user