From 3b2bb45468e185a7a26dc0edccc3283775d58a9f Mon Sep 17 00:00:00 2001 From: dvankeke Date: Wed, 17 Jun 2026 13:48:13 +0200 Subject: [PATCH 1/6] feat: git configure edit modal --- src/components/modals/ConfigureGitModal.tsx | 66 +++++++++++++++------ 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/src/components/modals/ConfigureGitModal.tsx b/src/components/modals/ConfigureGitModal.tsx index 0ce86d7d..339a23ad 100644 --- a/src/components/modals/ConfigureGitModal.tsx +++ b/src/components/modals/ConfigureGitModal.tsx @@ -9,7 +9,7 @@ import { useEffect, useMemo, useState } from 'react' import { Controller, useForm } from 'react-hook-form' import { useLocalStorage } from 'react-use' import { useSession } from 'providers/Session' -import { useMigrateGitMutation } from 'redux/otomiApi' +import { useGetGitSettingsQuery, useMigrateGitMutation } from 'redux/otomiApi' import { GitSettingsFormValues, gitSettingsSchema } from './gitSettingsValidator' const MODAL_TITLE = 'Configure Git Repository' @@ -216,6 +216,14 @@ function getErrorMessage(error: unknown): string { return 'Something went wrong while migrating Git settings.' } +const emptyGitFormValues: GitSettingsFormValues = { + repoUrl: '', + branch: '', + username: '', + password: '', + email: '', +} + export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalProps) { const { user: { isPlatformAdmin }, @@ -225,6 +233,24 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr } = useSession() const [showGitWizard, setShowGitWizard] = useLocalStorage('showGitConfigureWizard', true) + + const isControlled = typeof open === 'boolean' + const actualOpen = useMemo(() => (isControlled ? !!open : !!showGitWizard), [isControlled, open, showGitWizard]) + + const { data: gitSettings, isFetching: isFetchingGitSettings } = useGetGitSettingsQuery(undefined, { + skip: !isPlatformAdmin || !isPreInstalled || !actualOpen, + }) + + const hasGitConfiguration = !!gitSettings?.repoUrl + + const getGitFormValues = (): GitSettingsFormValues => ({ + repoUrl: gitSettings?.repoUrl || '', + branch: gitSettings?.branch || '', + username: gitSettings?.username || '', + password: gitSettings?.password || '', + email: gitSettings?.email || '', + }) + const [showFormStep, setShowFormStep] = useState(false) const [isTransitioning, setIsTransitioning] = useState(false) const [submitError, setSubmitError] = useState('') @@ -239,25 +265,16 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr reset, } = useForm({ resolver: yupResolver(gitSettingsSchema), - defaultValues: { - repoUrl: '', - branch: '', - username: '', - password: '', - email: '', - }, + defaultValues: emptyGitFormValues, mode: 'onBlur', }) - const isControlled = typeof open === 'boolean' - const actualOpen = useMemo(() => (isControlled ? !!open : !!showGitWizard), [isControlled, open, showGitWizard]) - const resetModalState = () => { - setShowFormStep(false) + setShowFormStep(hasGitConfiguration) setSubmitError('') setMigrationSucceeded(false) setIsTransitioning(false) - reset() + reset(getGitFormValues()) } useEffect(() => { @@ -269,9 +286,19 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr }, [isPreInstalled, isControlled, setShowGitWizard]) useEffect(() => { - if (!actualOpen) resetModalState() + if (!actualOpen) { + resetModalState() + return + } + + if (!gitSettings) return + + reset(getGitFormValues()) + + if (hasGitConfiguration) setShowFormStep(true) + // eslint-disable-next-line react-hooks/exhaustive-deps - }, [actualOpen]) + }, [actualOpen, gitSettings, hasGitConfiguration]) const handleClose = () => { resetModalState() @@ -356,7 +383,12 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr > - {!showFormStep ? ( + {isFetchingGitSettings ? ( + + {MODAL_TITLE} + Loading Git settings... + + ) : !showFormStep ? ( <> {MODAL_TITLE} @@ -513,7 +545,7 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr From 35520170baf766b73d3ad8a200bc6f0fc2692aac Mon Sep 17 00:00:00 2001 From: dvankeke Date: Wed, 17 Jun 2026 14:30:46 +0200 Subject: [PATCH 2/6] feat: welcome screen enhanched --- src/components/modals/ConfigureGitModal.tsx | 61 ++++++++++++++++++--- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/src/components/modals/ConfigureGitModal.tsx b/src/components/modals/ConfigureGitModal.tsx index 339a23ad..53f3dce2 100644 --- a/src/components/modals/ConfigureGitModal.tsx +++ b/src/components/modals/ConfigureGitModal.tsx @@ -1,7 +1,8 @@ /* eslint-disable no-nested-ternary */ +import ContentCopyIcon from '@mui/icons-material/ContentCopy' import { yupResolver } from '@hookform/resolvers/yup' import { LoadingButton } from '@mui/lab' -import { Box, Button, Modal, Typography, styled } from '@mui/material' +import { Box, Button, IconButton, Modal, Tooltip, Typography, styled } from '@mui/material' import { FetchBaseQueryError } from '@reduxjs/toolkit/query' import InformationBanner from 'components/InformationBanner' import { TextField } from 'components/forms/TextField' @@ -88,6 +89,25 @@ const IntroParagraph = styled(BodyText)({ marginBottom: '24px', }) +const DefaultGitUrlBlock = styled(Box)(({ theme }) => ({ + marginTop: '24px', + padding: '14px 16px', + borderRadius: 8, + border: '1px solid rgba(145, 158, 171, 0.24)', + backgroundColor: theme.palette.cm.rowAlter, + display: 'flex', + alignItems: 'center', + justifyContent: 'space-between', + gap: '16px', +})) + +const DefaultGitUrlText = styled(Typography)({ + overflow: 'hidden', + textOverflow: 'ellipsis', + whiteSpace: 'nowrap', + fontFamily: 'monospace', +}) + const SectionTitle = styled(Typography)({ marginBottom: '4px', fontWeight: 550, @@ -228,6 +248,7 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr const { user: { isPlatformAdmin }, settings: { + cluster: { domainSuffix }, otomi: { isPreInstalled }, }, } = useSession() @@ -241,14 +262,17 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr skip: !isPlatformAdmin || !isPreInstalled || !actualOpen, }) - const hasGitConfiguration = !!gitSettings?.repoUrl + const defaultGitUrl = gitSettings?.repoUrl || '' + const isDefaultGitConfiguration = gitSettings?.repoUrl?.includes('gitea-http.gitea.svc.cluster.local') ?? false + const hasGitConfiguration = !!gitSettings?.repoUrl && !isDefaultGitConfiguration + const displayedRepoUrl = isDefaultGitConfiguration ? `https://git.${domainSuffix}/otomi/values` : '' const getGitFormValues = (): GitSettingsFormValues => ({ - repoUrl: gitSettings?.repoUrl || '', - branch: gitSettings?.branch || '', - username: gitSettings?.username || '', - password: gitSettings?.password || '', - email: gitSettings?.email || '', + repoUrl: hasGitConfiguration ? gitSettings?.repoUrl || '' : '', + branch: hasGitConfiguration ? gitSettings?.branch || '' : '', + username: hasGitConfiguration ? gitSettings?.username || '' : '', + password: hasGitConfiguration ? gitSettings?.password || '' : '', + email: hasGitConfiguration ? gitSettings?.email || '' : '', }) const [showFormStep, setShowFormStep] = useState(false) @@ -294,8 +318,7 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr if (!gitSettings) return reset(getGitFormValues()) - - if (hasGitConfiguration) setShowFormStep(true) + setShowFormStep(hasGitConfiguration) // eslint-disable-next-line react-hooks/exhaustive-deps }, [actualOpen, gitSettings, hasGitConfiguration]) @@ -311,6 +334,11 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr setShowGitWizard(false) } + const handleCopyDefaultGitUrl = async () => { + if (!displayedRepoUrl) return + await navigator.clipboard.writeText(displayedRepoUrl) + } + const goToFormStep = () => { setIsTransitioning(true) @@ -402,6 +430,21 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr Configuring an external Git Repo is recommended for installing App Platform. + + {!!defaultGitUrl && ( + + + Current internal Git repository + {displayedRepoUrl} + + + + + + + + + )} From ae1fa1b52cc4c1212eacecf78dae272b39feecef Mon Sep 17 00:00:00 2001 From: dvankeke Date: Wed, 17 Jun 2026 14:46:17 +0200 Subject: [PATCH 3/6] feat: git configure edit modal logic --- src/components/InformationBanner.tsx | 2 +- src/components/Setting.tsx | 4 +-- src/components/modals/ConfigureGitModal.tsx | 31 +++++++++++++++++++++ src/pages/SettingsOverview.tsx | 2 +- src/redux/otomiApi.ts | 15 ++++++++++ 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/src/components/InformationBanner.tsx b/src/components/InformationBanner.tsx index ad01db56..f47086e8 100644 --- a/src/components/InformationBanner.tsx +++ b/src/components/InformationBanner.tsx @@ -24,7 +24,7 @@ export default function InformationBanner({ message, children, small, sx }: Prop return ( - {message} + {message} {children} ) diff --git a/src/components/Setting.tsx b/src/components/Setting.tsx index c5dc5c01..b2efc367 100644 --- a/src/components/Setting.tsx +++ b/src/components/Setting.tsx @@ -58,9 +58,7 @@ export const getSettingUiSchema = (settings: GetSettingsInfoApiResponse, setting adminPassword: { 'ui:widget': 'hidden' }, useORCS: { 'ui:widget': 'hidden' }, aiEnabled: { 'ui:widget': 'hidden' }, - git: { - password: { 'ui:widget': 'password' }, - }, + git: { 'ui:widget': 'hidden' }, }, kms: { sops: { diff --git a/src/components/modals/ConfigureGitModal.tsx b/src/components/modals/ConfigureGitModal.tsx index 53f3dce2..3cbee218 100644 --- a/src/components/modals/ConfigureGitModal.tsx +++ b/src/components/modals/ConfigureGitModal.tsx @@ -285,6 +285,7 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr const { control, handleSubmit, + getValues, formState: { errors }, reset, } = useForm({ @@ -339,6 +340,14 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr await navigator.clipboard.writeText(displayedRepoUrl) } + const handleCopyRepoUrl = async () => { + const repoUrl = getValues('repoUrl') + + if (!repoUrl) return + + await navigator.clipboard.writeText(repoUrl) + } + const goToFormStep = () => { setIsTransitioning(true) @@ -488,6 +497,10 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr {MODAL_TITLE} + {hasGitConfiguration && ( + + )} + {!!submitError && } @@ -502,6 +515,24 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr fullWidth error={!!errors.repoUrl} helperText={errors.repoUrl?.message} + InputProps={ + hasGitConfiguration + ? { + endAdornment: ( + + + + + + ), + } + : undefined + } /> )} /> diff --git a/src/pages/SettingsOverview.tsx b/src/pages/SettingsOverview.tsx index ef5d2ff8..70533db7 100644 --- a/src/pages/SettingsOverview.tsx +++ b/src/pages/SettingsOverview.tsx @@ -35,7 +35,7 @@ export default function SettingsOverview() { { title: 'Backup', path: '/settings/platformBackups', icon: getIcon('backup_icon.svg'), id: 'backup' }, { title: 'Object Storage', path: '/settings/obj', icon: getIcon('cloud_upload.svg'), id: 'objectStorage' }, { - title: 'Git', + title: 'GitOps', icon: getIcon('git_icon.svg'), id: 'git', onClick: () => setOpenGitModal(true), diff --git a/src/redux/otomiApi.ts b/src/redux/otomiApi.ts index 3e549ecf..6b589c89 100644 --- a/src/redux/otomiApi.ts +++ b/src/redux/otomiApi.ts @@ -382,6 +382,9 @@ const injectedRtkApi = api.injectEndpoints({ body: queryArg.body, }), }), + getGitSettings: build.query({ + query: () => ({ url: `/v2/git` }), + }), migrateGit: build.mutation({ query: (queryArg) => ({ url: `/v2/git`, method: 'PUT', body: queryArg.body }), }), @@ -4257,6 +4260,9 @@ export type GetSettingsInfoApiResponse = /** status 200 The request is successfu git?: { repoUrl?: string branch?: string + username?: string + password?: string + email?: string } } ingressClassNames?: string[] @@ -4860,6 +4866,14 @@ export type EditAppApiArg = { } } } +export type GetGitSettingsApiResponse = /** status 200 Current Git settings */ { + repoUrl: string + username?: string + password: string + email: string + branch: string +} +export type GetGitSettingsApiArg = void export type MigrateGitApiResponse = /** status 200 Migration successful. API is now locked. */ undefined export type MigrateGitApiArg = { /** New git configuration to migrate to. */ @@ -4974,6 +4988,7 @@ export const { useToggleAppsMutation, useGetTeamAppQuery, useEditAppMutation, + useGetGitSettingsQuery, useMigrateGitMutation, useGetApiStatusQuery, } = injectedRtkApi From b6d03ca888356813edfe25ce274d93023b0fcc30 Mon Sep 17 00:00:00 2001 From: Dennis van Kekem <38350840+dennisvankekem@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:05:36 +0200 Subject: [PATCH 4/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/components/modals/ConfigureGitModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/modals/ConfigureGitModal.tsx b/src/components/modals/ConfigureGitModal.tsx index 3cbee218..62c1774c 100644 --- a/src/components/modals/ConfigureGitModal.tsx +++ b/src/components/modals/ConfigureGitModal.tsx @@ -448,7 +448,7 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr - + From b18bcaf38e0d0a962bb4130f4dd4f30824deb5fd Mon Sep 17 00:00:00 2001 From: Dennis van Kekem <38350840+dennisvankekem@users.noreply.github.com> Date: Mon, 22 Jun 2026 10:06:04 +0200 Subject: [PATCH 5/6] Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- src/components/modals/ConfigureGitModal.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/modals/ConfigureGitModal.tsx b/src/components/modals/ConfigureGitModal.tsx index 62c1774c..ea6610b0 100644 --- a/src/components/modals/ConfigureGitModal.tsx +++ b/src/components/modals/ConfigureGitModal.tsx @@ -265,7 +265,7 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr const defaultGitUrl = gitSettings?.repoUrl || '' const isDefaultGitConfiguration = gitSettings?.repoUrl?.includes('gitea-http.gitea.svc.cluster.local') ?? false const hasGitConfiguration = !!gitSettings?.repoUrl && !isDefaultGitConfiguration - const displayedRepoUrl = isDefaultGitConfiguration ? `https://git.${domainSuffix}/otomi/values` : '' + const displayedRepoUrl = isDefaultGitConfiguration && domainSuffix ? `https://git.${domainSuffix}/otomi/values` : '' const getGitFormValues = (): GitSettingsFormValues => ({ repoUrl: hasGitConfiguration ? gitSettings?.repoUrl || '' : '', From 6d6274d8f3b5fbe59551a4fd053417aa37790c18 Mon Sep 17 00:00:00 2001 From: dvankeke Date: Mon, 22 Jun 2026 10:10:57 +0200 Subject: [PATCH 6/6] fix: no welcome modal --- src/components/modals/ConfigureGitModal.tsx | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/components/modals/ConfigureGitModal.tsx b/src/components/modals/ConfigureGitModal.tsx index ea6610b0..785a68ed 100644 --- a/src/components/modals/ConfigureGitModal.tsx +++ b/src/components/modals/ConfigureGitModal.tsx @@ -263,7 +263,7 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr }) const defaultGitUrl = gitSettings?.repoUrl || '' - const isDefaultGitConfiguration = gitSettings?.repoUrl?.includes('gitea-http.gitea.svc.cluster.local') ?? false + const isDefaultGitConfiguration = gitSettings?.repoUrl?.includes('git-server.git-server.svc.cluster.local') ?? false const hasGitConfiguration = !!gitSettings?.repoUrl && !isDefaultGitConfiguration const displayedRepoUrl = isDefaultGitConfiguration && domainSuffix ? `https://git.${domainSuffix}/otomi/values` : '' @@ -448,7 +448,11 @@ export default function ConfigureGitModal({ open, onClose }: ConfigureGitModalPr - +