-
Notifications
You must be signed in to change notification settings - Fork 98
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(*): init logs to customer module #14281
base: feat/logs-to-customer-module
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
{ | ||
"key_management_service_logs": "logs", | ||
"key_management_service_logs_description": "Une description à définir." | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import LogsToCustomerModule from '@ovh-ux/logs-to-customer/src/LogsToCustomer.module'; | ||
import { Description } from '@ovh-ux/manager-react-components'; | ||
import React from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { useParams } from 'react-router-dom'; | ||
|
||
export default function KmsLogs() { | ||
const { okmsId } = useParams(); | ||
const { t } = useTranslation('key-management-service/logs'); | ||
|
||
return ( | ||
<div className="flex flex-col gap-4"> | ||
<Description>{t('key_management_service_logs_description')}</Description> | ||
<LogsToCustomerModule | ||
logApiVersion="v2" | ||
logApiBaseUrl={`/okms/resource/${okmsId}/log`} | ||
/> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
{ | ||
"name": "@ovh-ux/logs-to-customer", | ||
"version": "1.0.0", | ||
"private": true, | ||
"description": "", | ||
"license": "BSD-3-Clause", | ||
"author": "OVH SAS", | ||
"type": "module", | ||
"main": "./src/index.ts", | ||
"scripts": { | ||
"dev": "tsc" | ||
}, | ||
"dependencies": {}, | ||
"devDependencies": { | ||
"@ovh-ux/manager-core-api": "^0.9.0", | ||
"@ovh-ux/manager-react-components": "^1.41.1", | ||
"@ovh-ux/manager-vite-config": "^0.8.2", | ||
"@testing-library/react": "^16.0.0", | ||
"@vitejs/plugin-react": "^4.2.1", | ||
"react-i18next": "^14.0.5", | ||
"tailwindcss": "^3.4.4", | ||
"typescript": "^4.3.2", | ||
"vite": "^5.2.13", | ||
"vitest": "^1.2.0" | ||
}, | ||
"peerDependencies": { | ||
"@ovh-ux/manager-core-api": "^0.9.0", | ||
"@ovh-ux/manager-react-components": "^1.41.1", | ||
"@ovh-ux/manager-react-shell-client": "^0.8.1", | ||
"@ovh-ux/manager-tailwind-config": "^0.2.0", | ||
"@ovhcloud/ods-common-core": "17.2.2", | ||
"@ovhcloud/ods-common-theming": "17.2.2", | ||
"@ovhcloud/ods-components": "17.2.2", | ||
"@ovhcloud/ods-theme-blue-jeans": "17.2.2", | ||
"@tanstack/react-query": "^5.51.21", | ||
"i18next": "^23.8.2", | ||
"react": "^18.2.0", | ||
"react-dom": "^18.2.0", | ||
"react-i18next": "^14.0.5", | ||
"react-router": "^6.21.3", | ||
"react-router-dom": "^6.3.0" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { createContext } from 'react'; | ||
import { LogKind } from './data/types/dbaas/logs'; | ||
|
||
export interface LogProviderProps { | ||
currentLogKind?: LogKind; | ||
logApiBaseUrl: string; | ||
} | ||
|
||
export const LogsContext = createContext<LogProviderProps>({ | ||
logApiBaseUrl: '', | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import React, { useEffect, useMemo, useState } from 'react'; | ||
import { Outlet } from 'react-router-dom'; | ||
import { useQueryClient } from '@tanstack/react-query'; | ||
import { | ||
OsdsButton, | ||
OsdsMessage, | ||
OsdsSpinner, | ||
OsdsText, | ||
} from '@ovhcloud/ods-components/react'; | ||
import { | ||
ODS_BUTTON_SIZE, | ||
ODS_BUTTON_VARIANT, | ||
ODS_MESSAGE_TYPE, | ||
ODS_SPINNER_SIZE, | ||
} from '@ovhcloud/ods-components'; | ||
import { ODS_THEME_COLOR_INTENT } from '@ovhcloud/ods-common-theming'; | ||
import { getLogKindsQueryKey, useLogKinds } from './data/hooks/useLogKinds'; | ||
import LogKindsSelector from './components/logKindsSelector/LogKindsSelector.component'; | ||
import { LogKind } from './data/types/dbaas/logs'; | ||
import { LogApiVersion } from './data/types/apiVersion'; | ||
import { LogsContext } from './LogsToCustomer.context'; | ||
|
||
export interface ILogsToCustomerModule { | ||
logApiBaseUrl: string; | ||
logApiVersion: LogApiVersion; | ||
} | ||
|
||
export default function LogsToCustomerModule({ | ||
logApiBaseUrl, | ||
logApiVersion, | ||
}: Readonly<ILogsToCustomerModule>) { | ||
const queryClient = useQueryClient(); | ||
const [currentLogKind, setCurrentLogKind] = useState<LogKind>(); | ||
|
||
const { data: logKinds, error, isPending } = useLogKinds({ | ||
baseUrl: logApiBaseUrl, | ||
apiVersion: logApiVersion, | ||
}); | ||
|
||
useEffect(() => { | ||
if (!isPending && logKinds?.length > 0) setCurrentLogKind(logKinds[0]); | ||
}, [logKinds, isPending]); | ||
|
||
const LogsContextValues = useMemo( | ||
() => ({ | ||
currentLogKind, | ||
logApiBaseUrl, | ||
}), | ||
[currentLogKind, logApiBaseUrl], | ||
); | ||
|
||
if (isPending) | ||
return ( | ||
<div className="flex py-8"> | ||
<OsdsSpinner inline size={ODS_SPINNER_SIZE.md} /> | ||
</div> | ||
); | ||
|
||
if (error) | ||
return ( | ||
<div className="flex flex-col gap-4"> | ||
<OsdsMessage | ||
color={ODS_THEME_COLOR_INTENT.error} | ||
type={ODS_MESSAGE_TYPE.error} | ||
> | ||
<OsdsText color={ODS_THEME_COLOR_INTENT.error}> | ||
<div>Une erreur est survenue</div> | ||
{error && <strong>{error.message}</strong>} | ||
</OsdsText> | ||
</OsdsMessage> | ||
<OsdsButton | ||
size={ODS_BUTTON_SIZE.sm} | ||
color={ODS_THEME_COLOR_INTENT.primary} | ||
variant={ODS_BUTTON_VARIANT.flat} | ||
onClick={() => | ||
queryClient.refetchQueries({ | ||
queryKey: getLogKindsQueryKey(logApiBaseUrl), | ||
}) | ||
} | ||
> | ||
reload logs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. manage translation |
||
</OsdsButton> | ||
</div> | ||
); | ||
|
||
if (logKinds.length === 0) return <div>no logkinds</div>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. manage translation |
||
|
||
return ( | ||
<div className="flex flex-col gap-8"> | ||
<LogKindsSelector | ||
logKinds={logKinds} | ||
currentLogKind={currentLogKind} | ||
setCurrentLogKind={setCurrentLogKind} | ||
/> | ||
<LogsContext.Provider value={LogsContextValues}> | ||
<Outlet /> | ||
</LogsContext.Provider> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
import React from 'react'; | ||
import { useTranslation } from 'react-i18next'; | ||
import { Description } from '@ovh-ux/manager-react-components'; | ||
import { OsdsSelect, OsdsSelectOption } from '@ovhcloud/ods-components/react'; | ||
import './translations'; | ||
import { LogKind } from '../../data/types/dbaas/logs'; | ||
|
||
interface ILogKindsSelector { | ||
logKinds: LogKind[]; | ||
currentLogKind: LogKind; | ||
setCurrentLogKind: React.Dispatch<React.SetStateAction<LogKind>>; | ||
} | ||
|
||
export default function LogKindsSelector({ | ||
logKinds, | ||
currentLogKind, | ||
setCurrentLogKind, | ||
}: Readonly<ILogKindsSelector>) { | ||
const { t } = useTranslation('logKindsSelector'); | ||
|
||
// TODO: Design Specs for usecase: One kind. | ||
if (logKinds.length === 1) { | ||
return <div>{logKinds[0].displayName}</div>; | ||
} | ||
|
||
return ( | ||
<div className="flex flex-col gap-4"> | ||
<Description>{t('logKindsSelector_select_label')}</Description> | ||
<OsdsSelect | ||
value={currentLogKind?.kindId} | ||
onOdsValueChange={(event) => { | ||
const newLogKind = logKinds.find( | ||
(k) => k.kindId === event.detail.value, | ||
); | ||
setCurrentLogKind(newLogKind); | ||
Comment on lines
+32
to
+35
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. So if newLogKind is |
||
}} | ||
> | ||
{logKinds.map((k) => ( | ||
<OsdsSelectOption key={k.kindId} value={k.kindId}> | ||
{k.displayName} | ||
</OsdsSelectOption> | ||
))} | ||
</OsdsSelect> | ||
</div> | ||
); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"logKindsSelector_select_label": "Sélectionnez le type de log" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import i18next from 'i18next'; | ||
|
||
// import de_DE from './Messages_de_DE.json'; | ||
// import en_GB from './Messages_en_GB.json'; | ||
Comment on lines
+3
to
+4
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could be managed with fast translation to avoid commenting all the translation imports |
||
// import es_ES from './Messages_es_ES.json'; | ||
// import fr_CA from './Messages_fr_CA.json'; | ||
import fr_FR from './Messages_fr_FR.json'; | ||
// import it_IT from './Messages_it_IT.json'; | ||
// import pl_PL from './Messages_pl_PL.json'; | ||
// import pt_PT from './Messages_pt_PT.json'; | ||
|
||
function addTranslations() { | ||
// i18next.addResources('de_DE', 'logKindsSelector', de_DE); | ||
// i18next.addResources('en_GB', 'logKindsSelector', en_GB); | ||
// i18next.addResources('es_ES', 'logKindsSelector', es_ES); | ||
// i18next.addResources('fr_CA', 'logKindsSelector', fr_CA); | ||
i18next.addResources('fr_FR', 'logKindsSelector', fr_FR); | ||
// i18next.addResources('it_IT', 'logKindsSelector', it_IT); | ||
// i18next.addResources('pl_PL', 'logKindsSelector', pl_PL); | ||
// i18next.addResources('pt_PT', 'logKindsSelector', pt_PT); | ||
} | ||
|
||
if (i18next.isInitialized) { | ||
addTranslations(); | ||
} else { | ||
i18next.on('initialized', addTranslations); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import React, { useContext } from 'react'; | ||
import { LogsContext } from '../../LogsToCustomer.context'; | ||
|
||
export default function LogsTail() { | ||
const { currentLogKind, logApiBaseUrl } = useContext(LogsContext); | ||
|
||
return ( | ||
<div className="flex gap-8 flex-col p-8"> | ||
<h3>Live tail</h3> | ||
<ul> | ||
<li> | ||
CurrentLogKind: <b>{currentLogKind?.displayName}</b> | ||
</li> | ||
<li> | ||
logApiBaseUrl: <b>{logApiBaseUrl}</b> | ||
</li> | ||
</ul> | ||
Comment on lines
+9
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No translation needed ? At least it should be readable There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is temporary content, everything in theses components will be reworked. |
||
</div> | ||
); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
manage translation