Skip to content

Commit 4c6aa68

Browse files
committed
feat: add time util, calculate duration dynamically
Signed-off-by: warjiang <[email protected]>
1 parent 49b5a6d commit 4c6aa68

File tree

3 files changed

+79
-44
lines changed

3 files changed

+79
-44
lines changed

ui/apps/dashboard/src/main.tsx

Lines changed: 52 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,66 @@
11
import React from 'react';
22
import ReactDOM from 'react-dom/client';
33
import App from './App.tsx';
4-
import i18nInstance, {getLang} from '@/utils/i18n';
5-
import {initReactI18next} from 'react-i18next';
6-
import {loader} from '@monaco-editor/react';
4+
import i18nInstance, { getLang } from '@/utils/i18n';
5+
import { initReactI18next } from 'react-i18next';
6+
import dayjs from 'dayjs';
7+
import duration from 'dayjs/plugin/duration';
8+
import relativeTime from 'dayjs/plugin/relativeTime';
9+
import utc from 'dayjs/plugin/utc';
10+
import timezone from 'dayjs/plugin/timezone';
11+
import { loader } from '@monaco-editor/react';
712
import * as monaco from 'monaco-editor';
813
import editorWorker from 'monaco-editor/esm/vs/editor/editor.worker?worker';
914
// https://github.com/remcohaszing/monaco-yaml/issues/150
1015
import yamlWorker from '@/utils/workaround-yaml.worker?worker';
1116
import enTexts from '../locales/en-US.json';
1217
import zhTexts from '../locales/zh-CN.json';
13-
import {initRoute} from '@/routes/route.tsx';
18+
import { initRoute } from '@/routes/route.tsx';
1419

20+
dayjs.extend(duration);
21+
dayjs.extend(relativeTime);
22+
dayjs.extend(utc);
23+
dayjs.extend(timezone);
1524
window.MonacoEnvironment = {
16-
getWorker(_, label) {
17-
if (label === 'yaml') {
18-
return new yamlWorker();
19-
}
20-
return new editorWorker();
21-
},
25+
getWorker(_, label) {
26+
if (label === 'yaml') {
27+
return new yamlWorker();
28+
}
29+
return new editorWorker();
30+
},
2231
};
23-
loader.config({monaco});
32+
loader.config({ monaco });
2433

2534
i18nInstance
26-
.use(initReactI18next) // passes i18n down to react-i18next
27-
.init({
28-
debug: true,
29-
lng: getLang(), // if you're using a language detector, do not define the lng option
30-
fallbackLng: ['zh-CN'],
31-
resources: {
32-
zh: {
33-
translation: zhTexts,
34-
},
35-
en: {
36-
translation: enTexts,
37-
},
38-
},
39-
interpolation: {
40-
escapeValue: false, // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
41-
},
42-
saveMissing: true, // send not translated keys to endpoint,
43-
react: {
44-
useSuspense: false,
45-
},
46-
})
47-
.then(() => {
48-
initRoute();
49-
ReactDOM.createRoot(document.getElementById('root')!).render(
50-
<React.StrictMode>
51-
<App/>
52-
</React.StrictMode>,
53-
);
54-
})
55-
.catch(() => {
56-
57-
})
35+
.use(initReactI18next) // passes i18n down to react-i18next
36+
.init({
37+
debug: true,
38+
lng: getLang(), // if you're using a language detector, do not define the lng option
39+
fallbackLng: ['zh-CN'],
40+
resources: {
41+
zh: {
42+
translation: zhTexts,
43+
},
44+
en: {
45+
translation: enTexts,
46+
},
47+
},
48+
interpolation: {
49+
escapeValue: false, // react already safes from xss => https://www.i18next.com/translation-function/interpolation#unescape
50+
},
51+
saveMissing: true, // send not translated keys to endpoint,
52+
react: {
53+
useSuspense: false,
54+
},
55+
})
56+
.then(() => {
57+
initRoute();
58+
ReactDOM.createRoot(document.getElementById('root')!).render(
59+
<React.StrictMode>
60+
<App />
61+
</React.StrictMode>,
62+
);
63+
})
64+
.catch((err) => {
65+
console.error('initialization failed:', err);
66+
});

ui/apps/dashboard/src/pages/multicloud-resource-manage/workload/workload-detail-drawer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ import styles from './index.module.less';
1919
import { WorkloadKind } from '@/services/base.ts';
2020
import { cn } from '@/utils/cn';
2121
import TagList, { convertLabelToTags } from '@/components/tag-list';
22+
import { calculateDuration } from '@/utils/time.ts';
2223

2324
export interface WorkloadDetailDrawerProps {
2425
open: boolean;
@@ -140,7 +141,7 @@ const WorkloadDetailDrawer: FC<WorkloadDetailDrawerProps> = (props) => {
140141
'4a6341a8bcc68e0b7120dbc89014b6a2',
141142
'持续时间',
142143
)}
143-
value="2h"
144+
value={calculateDuration(detailData?.objectMeta?.creationTimestamp)}
144145
/>
145146
<Statistic
146147
className={styles['no-value']}

ui/apps/dashboard/src/utils/time.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/*
2+
Copyright 2025 The Karmada Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
import dayjs from 'dayjs';
18+
19+
export function calculateDuration(start: string | undefined) {
20+
if (!start) return '-';
21+
const startDate = dayjs.utc(start).local();
22+
const endDate = dayjs();
23+
const duration = dayjs.duration(endDate.diff(startDate));
24+
return duration.humanize();
25+
}

0 commit comments

Comments
 (0)