fix(ui): scroll issue [EE-6667] (#11084)

* Fix scroll issue

* fix minorissue

* address review comments

* add comment
pull/11092/head
Prabhat Khera 2024-02-09 15:35:34 +13:00 committed by GitHub
parent 43e56bf1c0
commit 671b22b5d6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 52 additions and 27 deletions

View File

@ -17,6 +17,7 @@
html { html {
font-size: 16px; font-size: 16px;
overflow-y: scroll; overflow-y: scroll;
scroll-behavior: smooth;
} }
html[theme='dark'], html[theme='dark'],

View File

@ -25,7 +25,7 @@ export const settingsModule = angular
) )
.component( .component(
'applicationSettingsPanel', 'applicationSettingsPanel',
r2a(withReactQuery(ApplicationSettingsPanel), ['onSuccess']) r2a(withReactQuery(ApplicationSettingsPanel), ['onSuccess', 'settings'])
) )
.component( .component(
'sslSettingsPanel', 'sslSettingsPanel',
@ -38,5 +38,5 @@ export const settingsModule = angular
) )
.component( .component(
'kubeSettingsPanel', 'kubeSettingsPanel',
r2a(withUIRouter(withReactQuery(KubeSettingsPanel)), []) r2a(withUIRouter(withReactQuery(KubeSettingsPanel)), ['settings'])
).name; ).name;

View File

@ -1,4 +1,4 @@
import { useMemo } from 'react'; import { useMemo, useEffect } from 'react';
import { useCurrentUser } from '@/react/hooks/useUser'; import { useCurrentUser } from '@/react/hooks/useUser';
import helm from '@/assets/ico/vendor/helm.svg?c'; import helm from '@/assets/ico/vendor/helm.svg?c';
@ -41,6 +41,19 @@ export function HelmRepositoryDatatable() {
helmReposQuery.data?.UserRepositories, helmReposQuery.data?.UserRepositories,
]); ]);
useEffect(() => {
// window.location.hash will get everything after the hashbang
// the regex will match the the content after each hash
const timeout = setTimeout(() => {
const regEx = /#!.*#(.*)/;
const match = window.location.hash.match(regEx);
if (match && match[1]) {
document.getElementById(match[1])?.scrollIntoView();
}
}, 1000);
return () => clearTimeout(timeout);
}, []);
return ( return (
<Datatable <Datatable
getRowId={(row) => String(row.Id)} getRowId={(row) => String(row.Id)}
@ -48,8 +61,9 @@ export function HelmRepositoryDatatable() {
description={<HelmDatatableDescription />} description={<HelmDatatableDescription />}
settingsManager={tableState} settingsManager={tableState}
columns={columns} columns={columns}
title="Helm Repositories" title="Helm repositories"
titleIcon={helm} titleIcon={helm}
titleId="helm-repositories"
renderTableActions={(selectedRows) => ( renderTableActions={(selectedRows) => (
<HelmRepositoryDatatableActions selectedItems={selectedRows} /> <HelmRepositoryDatatableActions selectedItems={selectedRows} />
)} )}

View File

@ -36,7 +36,7 @@ export function HelmRepositoryDatatableActions({ selectedItems }: Props) {
data-cy="credentials-addButton" data-cy="credentials-addButton"
icon={Plus} icon={Plus}
> >
Add Helm Repository Add Helm repository
</Button> </Button>
</> </>
); );

View File

@ -2,10 +2,7 @@ import { Settings as SettingsIcon } from 'lucide-react';
import { Field, Form, Formik, useFormikContext } from 'formik'; import { Field, Form, Formik, useFormikContext } from 'formik';
import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField'; import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField';
import { import { useUpdateSettingsMutation } from '@/react/portainer/settings/queries';
useSettings,
useUpdateSettingsMutation,
} from '@/react/portainer/settings/queries';
import { notifySuccess } from '@/portainer/services/notifications'; import { notifySuccess } from '@/portainer/services/notifications';
import { Widget } from '@@/Widget'; import { Widget } from '@@/Widget';
@ -24,17 +21,13 @@ import { EnableTelemetryField } from './EnableTelemetryField';
export function ApplicationSettingsPanel({ export function ApplicationSettingsPanel({
onSuccess, onSuccess,
settings,
}: { }: {
onSuccess(settings: Settings): void; onSuccess(settings: Settings): void;
settings: Settings;
}) { }) {
const settingsQuery = useSettings();
const mutation = useUpdateSettingsMutation(); const mutation = useUpdateSettingsMutation();
if (!settingsQuery.data) {
return null;
}
const settings = settingsQuery.data;
const initialValues: Values = { const initialValues: Values = {
edgeAgentCheckinInterval: settings.EdgeAgentCheckinInterval, edgeAgentCheckinInterval: settings.EdgeAgentCheckinInterval,
enableTelemetry: settings.EnableTelemetry, enableTelemetry: settings.EnableTelemetry,

View File

@ -8,7 +8,8 @@ import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
import { LoadingButton } from '@@/buttons'; import { LoadingButton } from '@@/buttons';
import { Widget } from '@@/Widget'; import { Widget } from '@@/Widget';
import { useSettings, useUpdateSettingsMutation } from '../../queries'; import { useUpdateSettingsMutation } from '../../queries';
import { Settings } from '../../types';
import { HelmSection } from './HelmSection'; import { HelmSection } from './HelmSection';
import { KubeConfigSection } from './KubeConfigSection'; import { KubeConfigSection } from './KubeConfigSection';
@ -16,19 +17,14 @@ import { FormValues } from './types';
import { DeploymentOptionsSection } from './DeploymentOptionsSection'; import { DeploymentOptionsSection } from './DeploymentOptionsSection';
import { validation } from './validation'; import { validation } from './validation';
export function KubeSettingsPanel() { export function KubeSettingsPanel({ settings }: { settings: Settings }) {
const settingsQuery = useSettings();
const queryClient = useQueryClient(); const queryClient = useQueryClient();
const environmentId = useEnvironmentId(false); const environmentId = useEnvironmentId(false);
const mutation = useUpdateSettingsMutation(); const mutation = useUpdateSettingsMutation();
if (!settingsQuery.data) {
return null;
}
const initialValues: FormValues = { const initialValues: FormValues = {
helmRepositoryUrl: settingsQuery.data.HelmRepositoryURL || '', helmRepositoryUrl: settings.HelmRepositoryURL || '',
kubeconfigExpiry: settingsQuery.data.KubeconfigExpiry || '0', kubeconfigExpiry: settings.KubeconfigExpiry || '0',
globalDeploymentOptions: { globalDeploymentOptions: {
...{ ...{
requireNoteOnApplications: false, requireNoteOnApplications: false,
@ -39,7 +35,7 @@ export function KubeSettingsPanel() {
perEnvOverride: false, perEnvOverride: false,
hideStacksFunctionality: false, hideStacksFunctionality: false,
}, },
...settingsQuery.data.GlobalDeploymentOptions, ...settings.GlobalDeploymentOptions,
}, },
}; };

View File

@ -1,9 +1,11 @@
import { useEffect } from 'react';
import angular from 'angular'; import angular from 'angular';
import { StateManager } from '@/portainer/services/types'; import { StateManager } from '@/portainer/services/types';
import { PageHeader } from '@@/PageHeader'; import { PageHeader } from '@@/PageHeader';
import { useSettings } from '../queries';
import { Settings } from '../types'; import { Settings } from '../types';
import { isBE } from '../../feature-flags/feature-flags.service'; import { isBE } from '../../feature-flags/feature-flags.service';
@ -16,14 +18,33 @@ import { SSLSettingsPanelWrapper } from './SSLSettingsPanel/SSLSettingsPanel';
import { ExperimentalFeatures } from './ExperimentalFeatures'; import { ExperimentalFeatures } from './ExperimentalFeatures';
export function SettingsView() { export function SettingsView() {
const settingsQuery = useSettings();
useEffect(() => {
if (settingsQuery.data) {
const regEx = /#!.*#(.*)/;
const match = window.location.hash.match(regEx);
if (match && match[1]) {
document.getElementById(match[1])?.scrollIntoView();
}
}
}, [settingsQuery.data]);
return ( return (
<> <>
<PageHeader title="Settings" breadcrumbs="Settings" reload /> <PageHeader title="Settings" breadcrumbs="Settings" reload />
<div className="mx-4 space-y-4"> <div className="mx-4 space-y-4">
<ApplicationSettingsPanel onSuccess={handleSuccess} /> {settingsQuery.data && (
<>
<ApplicationSettingsPanel
onSuccess={handleSuccess}
settings={settingsQuery.data}
/>
<KubeSettingsPanel /> <KubeSettingsPanel settings={settingsQuery.data} />
</>
)}
<HelmCertPanel /> <HelmCertPanel />