Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support tagging launchpad and database application sources #4975

Merged
merged 6 commits into from
Aug 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions frontend/desktop/src/pages/api/desktop/getBilling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
method: 'POST',
body: JSON.stringify({
endTime: currentTime,
kubeConfig: kc.exportConfig(),
appType: '',
namespace,
kubeConfig: realKc,
// appType: '',
// namespace,
startTime: timeOneMonthAgo
})
})
Expand All @@ -45,9 +45,9 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
method: 'POST',
body: JSON.stringify({
endTime: currentTime,
kubeConfig: kc.exportConfig(),
appType: '',
namespace,
kubeConfig: realKc,
// appType: '',
// namespace,
startTime: time24HoursAgo
})
})
Expand Down
2 changes: 0 additions & 2 deletions frontend/providers/applaunchpad/.vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,9 @@
"ts"
],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.keepFulfilled": false,
"i18n-ally.sourceLanguage": "zh",
"i18n-ally.displayLanguage": "zh",
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.json",
"i18n-ally.extract.targetPickingStrategy": "most-similar-by-key"
}
15 changes: 10 additions & 5 deletions frontend/providers/applaunchpad/public/locales/en/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"Application paused": "Application Paused",
"Application Type": "Type",
"Applications": "Applications",
"Are you sure you want to delete the file or folder?": "Are you sure you want to delete this file\/folder?",
"Are you sure you want to delete the file or folder?": "Are you sure you want to delete this file/folder?",
"Are you sure you want to delete this application? If you proceed, all data for this project will be deleted": "Are you sure you want to delete this application? All project data will be permanently lost if you proceed.",
"Attribute": "Attribute",
"Auto scaling": "Scaling",
Expand Down Expand Up @@ -133,7 +133,7 @@
"Memory target value": "Target Memory Usage",
"Min Storage Value": "Minimum size is",
"mount path": "Mount path",
"Mount Path Auth": "Mount path must match: \/^[0-9a-zA-Z_\/][0-9a-zA-Z_\/.-]*[0-9a-zA-Z_\/]$\/",
"Mount Path Auth": "Mount path must match: /^[0-9a-zA-Z_/][0-9a-zA-Z_/.-]*[0-9a-zA-Z_/]$/",
"Name": "Name",
"Network Configuration": "Network",
"Network port conflict": "Container port conflict",
Expand All @@ -160,7 +160,7 @@
"Pause": "Pause",
"pause_message": "Pausing the service will stop the calculation of charges for CPU and memory, but charges for storage and external network ports will still apply. Would you like to pause now?",
"Paused": "Paused",
"Perday": "\/day",
"Perday": "/day",
"Please confirm to restart the Pod?": "Are you sure you want to restart this pod?",
"Please enter": "Please enter",
"please enter app name": "please enter: {{appName}}",
Expand Down Expand Up @@ -250,7 +250,12 @@
"App Store": "App Store",
"Manage all resources": "Manage all resources",
"Remind": "Remind",
"Confirm to go": "Confirm to go",
"Delete anyway": "Delete anyway",
"Delete Template App Tip": "To fully remove this app and all its components, please uninstall it directly from the App Store."
"delete_template_app_tip": "The app is deployed via the app store. \nSimply deleting the app won't clear out all of the app's components, which may still accrue charges. \nTo completely uninstall an app and clean all related components, uninstall the entire app from the App Store.",
"delete_sealaf_app_tip": "The application is deployed via cloud development. \nSimply deleting the app won't clear out all of the app's components, which may still accrue charges. \nTo completely uninstall the app and clean all related components, uninstall the entire app in cloud development.",
"remind": "remind",
"update_sealaf_app_tip": "This application is deployed through cloud development. To change the application, please go to cloud development.",
"confirm_to_go": "Confirm",
"app_store": "App Store",
"sealaf": "sealaf"
}
11 changes: 8 additions & 3 deletions frontend/providers/applaunchpad/public/locales/zh/common.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
"Memory target value": "内存目标值",
"Min Storage Value": "容量最小为",
"mount path": "挂载路径",
"Mount Path Auth": "挂载路径格式须满足: \/^[0-9a-zA-Z_\/][0-9a-zA-Z_\/.-]*[0-9a-zA-Z_\/]$\/",
"Mount Path Auth": "挂载路径格式须满足: /^[0-9a-zA-Z_/][0-9a-zA-Z_/.-]*[0-9a-zA-Z_/]$/",
"Name": "名字",
"Network Configuration": "网络配置",
"Network port conflict": "容器端口冲突",
Expand Down Expand Up @@ -250,7 +250,12 @@
"App Store": "应用商店",
"Manage all resources": "管理所有资源",
"Remind": "提醒",
"Confirm to go": "确认前往",
"Delete anyway": "仍要删除",
"Delete Template App Tip": "该应用是通过应用商店部署的,如果您想完全卸载该应用并清理所有相关的组件,请到应用商店中将整个应用删除。"
"delete_template_app_tip": "该应用是通过应用商店部署的。仅删除应用无法清除应用的所有组件,这些组件可能仍会产生费用。要彻底卸载应用并清理所有相关组件,请在应用商店中卸载整个应用。",
"delete_sealaf_app_tip": "该应用是通过云开发部署的。仅删除应用无法清除应用的所有组件,这些组件可能仍会产生费用。要彻底卸载应用并清理所有相关组件,请在云开发中卸载整个应用。",
"remind": "提醒",
"update_sealaf_app_tip": "该应用是通过云开发部署的,变更该应用请到云开发中进行。",
"confirm_to_go": "确认前往",
"sealaf": "云开发",
"app_store": "应用商店"
}
13 changes: 13 additions & 0 deletions frontend/providers/applaunchpad/src/constants/app.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { TAppSourceType } from '@/types/app';

export enum AppStatusEnum {
running = 'running',
creating = 'creating',
Expand Down Expand Up @@ -85,8 +87,19 @@ export const appDeployKey = 'cloud.sealos.io/app-deploy-manager';
export const publicDomainKey = `cloud.sealos.io/app-deploy-manager-domain`;
export const gpuNodeSelectorKey = 'nvidia.com/gpu.product';
export const gpuResourceKey = 'nvidia.com/gpu';
export const templateDeployKey = 'cloud.sealos.io/deploy-on-sealos';
export const sealafDeployKey = 'sealaf-app';

export enum Coin {
cny = 'cny',
shellCoin = 'shellCoin',
usd = 'usd'
}

export const AppSourceConfigs: Array<{
key: string;
type: TAppSourceType;
}> = [
{ key: templateDeployKey, type: 'app_store' },
{ key: sealafDeployKey, type: 'sealaf' }
];
28 changes: 24 additions & 4 deletions frontend/providers/applaunchpad/src/mock/apps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,12 @@ export const MOCK_APPS: AppListItemType[] = [
maxReplicas: 1,
minReplicas: 1,
storeAmount: 0,
labels: {}
labels: {},
source: {
hasSource: false,
sourceName: '',
sourceType: 'app_store'
}
},
{
id: 'string2',
Expand All @@ -50,7 +55,12 @@ export const MOCK_APPS: AppListItemType[] = [
maxReplicas: 1,
minReplicas: 1,
storeAmount: 0,
labels: {}
labels: {},
source: {
hasSource: false,
sourceName: '',
sourceType: 'app_store'
}
},
{
id: 'string3',
Expand All @@ -74,7 +84,12 @@ export const MOCK_APPS: AppListItemType[] = [
maxReplicas: 1,
minReplicas: 1,
storeAmount: 0,
labels: {}
labels: {},
source: {
hasSource: false,
sourceName: '',
sourceType: 'app_store'
}
}
];
export const MOCK_NAMESPACE = 'ns-34dccadb-8e62-4205-8c1b-fc2dc146cd68';
Expand Down Expand Up @@ -272,5 +287,10 @@ export const MOCK_APP_DETAIL: AppDetailType = {
serverAddress: ''
},
storeList: [],
labels: {}
labels: {},
source: {
hasSource: false,
sourceName: '',
sourceType: 'app_store'
}
};
Original file line number Diff line number Diff line change
@@ -1,29 +1,28 @@
import React, { useMemo, useState } from 'react';
import GPUItem from '@/components/GPUItem';
import MyIcon from '@/components/Icon';
import { MOCK_APP_DETAIL } from '@/mock/apps';
import { useUserStore } from '@/store/user';
import type { AppDetailType } from '@/types/app';
import { printMemory, useCopyData } from '@/utils/tools';
import {
Box,
Flex,
useTheme,
Tag,
Accordion,
AccordionButton,
AccordionIcon,
AccordionItem,
AccordionPanel,
AccordionIcon
Box,
Flex,
Tag,
useTheme
} from '@chakra-ui/react';
import type { AppDetailType } from '@/types/app';
import { useCopyData, printMemory } from '@/utils/tools';
import { useUserStore } from '@/store/user';
import styles from '../index.module.scss';
import dynamic from 'next/dynamic';
const ConfigMapDetailModal = dynamic(() => import('./ConfigMapDetailModal'));
import { MOCK_APP_DETAIL } from '@/mock/apps';
import { useTranslation } from 'next-i18next';
import { MyTooltip } from '@sealos/ui';
import GPUItem from '@/components/GPUItem';
import MyIcon from '@/components/Icon';
import { has } from 'lodash';
import { templateDeployKey } from '@/constants/account';
import { useTranslation } from 'next-i18next';
import dynamic from 'next/dynamic';
import React, { useMemo, useState } from 'react';
import { sealosApp } from 'sealos-desktop-sdk/app';
import styles from '../index.module.scss';

const ConfigMapDetailModal = dynamic(() => import('./ConfigMapDetailModal'));

const AppBaseInfo = ({ app = MOCK_APP_DETAIL }: { app: AppDetailType }) => {
const { t } = useTranslation();
Expand All @@ -35,12 +34,6 @@ const AppBaseInfo = ({ app = MOCK_APP_DETAIL }: { app: AppDetailType }) => {
value: string;
}>();

const [hasApplicationSource, sourceName] = useMemo(() => {
return app?.labels
? [has(app.labels, templateDeployKey), app.labels[templateDeployKey]]
: [false, ''];
}, [app.labels]);

const appInfoTable = useMemo<
{
name: string;
Expand Down Expand Up @@ -106,7 +99,7 @@ const AppBaseInfo = ({ app = MOCK_APP_DETAIL }: { app: AppDetailType }) => {

return (
<Box px={6} py={7} position={'relative'}>
{hasApplicationSource && (
{app?.source?.hasSource && (
<Box fontSize={'base'} mb={'12px'}>
<Flex alignItems={'center'} gap={'8px'} color={'grayModern.600'} fontWeight={'bold'}>
<MyIcon w={'16px'} name={'target'}></MyIcon>
Expand All @@ -120,17 +113,25 @@ const AppBaseInfo = ({ app = MOCK_APP_DETAIL }: { app: AppDetailType }) => {
}}
cursor={'pointer'}
onClick={() => {
if (sourceName) {
if (!app?.source?.sourceName) return;
if (app.source.sourceType === 'app_store') {
sealosApp.runEvents('openDesktopApp', {
appKey: 'system-template',
pathname: '/instance',
query: { instanceName: sourceName }
query: { instanceName: app.source.sourceName }
});
}
if (app.source.sourceType === 'sealaf') {
sealosApp.runEvents('openDesktopApp', {
appKey: 'system-sealaf',
pathname: '/',
query: { instanceName: app.source.sourceName }
});
}
}}
>
<Box flex={'0 0 110px'} w={0} color={'grayModern.900'}>
{t('App Store')}
{t(app.source?.sourceType)}
</Box>
<Box color={'grayModern.600'}>{t('Manage all resources')}</Box>
<MyIcon name="upperRight" width={'14px'} color={'grayModern.600'} />
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { delAppByName } from '@/api/app';
import MyIcon from '@/components/Icon';
import { templateDeployKey } from '@/constants/account';
import { TAppSource, TAppSourceType } from '@/types/app';
import {
Box,
Button,
Expand All @@ -15,7 +15,6 @@ import {
ModalOverlay
} from '@chakra-ui/react';
import { useMessage } from '@sealos/ui';
import { has } from 'lodash';
import { useTranslation } from 'next-i18next';
import { useCallback, useEffect, useRef, useState } from 'react';
import { sealosApp } from 'sealos-desktop-sdk/app';
Expand All @@ -29,12 +28,12 @@ const DelModal = ({
appName,
onClose,
onSuccess,
labels
source
}: {
appName: string;
onClose: () => void;
onSuccess: () => void;
labels: { [key: string]: string };
source?: TAppSource;
}) => {
const { t } = useTranslation();
const [inputValue, setInputValue] = useState('');
Expand All @@ -45,10 +44,14 @@ const DelModal = ({

useEffect(() => {
if (!pageManuallyChangedRef.current) {
const hasApplicationSource = has(labels, templateDeployKey);
hasApplicationSource ? setActivePage(Page.REMINDER) : setActivePage(Page.DELETION_WARNING);
source?.hasSource ? setActivePage(Page.REMINDER) : setActivePage(Page.DELETION_WARNING);
}
}, [labels]);
}, [source]);

const deleteTypeTipMap: Record<TAppSourceType, string> = {
app_store: t('delete_template_app_tip'),
sealaf: t('delete_sealaf_app_tip')
};

const handleDelApp = useCallback(async () => {
try {
Expand All @@ -71,14 +74,21 @@ const DelModal = ({
}, [appName, toast, t, onSuccess, onClose]);

const openTemplateApp = () => {
if (!labels) return;
const sourceName = labels[templateDeployKey];
sealosApp.runEvents('openDesktopApp', {
appKey: 'system-template',
pathname: '/instance',
query: { instanceName: sourceName },
messageData: { type: 'InternalAppCall', name: sourceName }
});
if (!source?.hasSource) return;
if (source?.sourceType === 'app_store') {
sealosApp.runEvents('openDesktopApp', {
appKey: 'system-template',
pathname: '/instance',
query: { instanceName: source?.sourceName }
});
}
if (source?.sourceType === 'sealaf') {
sealosApp.runEvents('openDesktopApp', {
appKey: 'system-sealaf',
pathname: '/',
query: { instanceName: source?.sourceName }
});
}
onClose();
};

Expand All @@ -96,8 +106,8 @@ const DelModal = ({

<ModalBody>
<Box color={'myGray.600'}>
{activePage === Page.REMINDER
? t('Delete Template App Tip')
{activePage === Page.REMINDER && source?.sourceType
? deleteTypeTipMap[source?.sourceType]
: t(
'Are you sure you want to delete this application? If you proceed, all data for this project will be deleted'
)}
Expand Down Expand Up @@ -125,7 +135,7 @@ const DelModal = ({
<Button width={'64px'} onClick={onClose} variant={'outline'}>
{t('Cancel')}
</Button>
{activePage === Page.REMINDER && (
{activePage === Page.REMINDER && source?.sourceType !== 'sealaf' && (
<Button
ml={3}
variant={'outline'}
Expand All @@ -144,7 +154,7 @@ const DelModal = ({
isLoading={loading}
onClick={activePage === Page.REMINDER ? openTemplateApp : handleDelApp}
>
{activePage === Page.REMINDER ? t('Confirm to go') : t('Delete')}
{activePage === Page.REMINDER ? t('confirm_to_go') : t('Delete')}
</Button>
</ModalFooter>
</ModalContent>
Expand Down
Loading
Loading