mirror of https://github.com/portainer/portainer
				
				
				
			fix(ui): scroll issue [EE-6667 (#11085)
* Fix scroll issue * fix minorissue * address review comments * add commentpull/11075/head
							parent
							
								
									538e7a823b
								
							
						
					
					
						commit
						ce4b0e759c
					
				| 
						 | 
				
			
			@ -17,6 +17,7 @@
 | 
			
		|||
html {
 | 
			
		||||
  font-size: 16px;
 | 
			
		||||
  overflow-y: scroll;
 | 
			
		||||
  scroll-behavior: smooth;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
html[theme='dark'],
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ export const settingsModule = angular
 | 
			
		|||
  )
 | 
			
		||||
  .component(
 | 
			
		||||
    'applicationSettingsPanel',
 | 
			
		||||
    r2a(withReactQuery(ApplicationSettingsPanel), ['onSuccess'])
 | 
			
		||||
    r2a(withReactQuery(ApplicationSettingsPanel), ['onSuccess', 'settings'])
 | 
			
		||||
  )
 | 
			
		||||
  .component(
 | 
			
		||||
    'sslSettingsPanel',
 | 
			
		||||
| 
						 | 
				
			
			@ -38,5 +38,5 @@ export const settingsModule = angular
 | 
			
		|||
  )
 | 
			
		||||
  .component(
 | 
			
		||||
    'kubeSettingsPanel',
 | 
			
		||||
    r2a(withUIRouter(withReactQuery(KubeSettingsPanel)), [])
 | 
			
		||||
    r2a(withUIRouter(withReactQuery(KubeSettingsPanel)), ['settings'])
 | 
			
		||||
  ).name;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
import { useMemo } from 'react';
 | 
			
		||||
import { useMemo, useEffect } from 'react';
 | 
			
		||||
 | 
			
		||||
import { useCurrentUser } from '@/react/hooks/useUser';
 | 
			
		||||
import helm from '@/assets/ico/vendor/helm.svg?c';
 | 
			
		||||
| 
						 | 
				
			
			@ -41,6 +41,19 @@ export function HelmRepositoryDatatable() {
 | 
			
		|||
    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 (
 | 
			
		||||
    <Datatable
 | 
			
		||||
      getRowId={(row) => String(row.Id)}
 | 
			
		||||
| 
						 | 
				
			
			@ -48,8 +61,9 @@ export function HelmRepositoryDatatable() {
 | 
			
		|||
      description={<HelmDatatableDescription />}
 | 
			
		||||
      settingsManager={tableState}
 | 
			
		||||
      columns={columns}
 | 
			
		||||
      title="Helm Repositories"
 | 
			
		||||
      title="Helm repositories"
 | 
			
		||||
      titleIcon={helm}
 | 
			
		||||
      titleId="helm-repositories"
 | 
			
		||||
      renderTableActions={(selectedRows) => (
 | 
			
		||||
        <HelmRepositoryDatatableActions selectedItems={selectedRows} />
 | 
			
		||||
      )}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ export function HelmRepositoryDatatableActions({ selectedItems }: Props) {
 | 
			
		|||
        data-cy="credentials-addButton"
 | 
			
		||||
        icon={Plus}
 | 
			
		||||
      >
 | 
			
		||||
        Add Helm Repository
 | 
			
		||||
        Add Helm repository
 | 
			
		||||
      </Button>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,10 +2,7 @@ import { Settings as SettingsIcon } from 'lucide-react';
 | 
			
		|||
import { Field, Form, Formik, useFormikContext } from 'formik';
 | 
			
		||||
 | 
			
		||||
import { EdgeCheckinIntervalField } from '@/react/edge/components/EdgeCheckInIntervalField';
 | 
			
		||||
import {
 | 
			
		||||
  useSettings,
 | 
			
		||||
  useUpdateSettingsMutation,
 | 
			
		||||
} from '@/react/portainer/settings/queries';
 | 
			
		||||
import { useUpdateSettingsMutation } from '@/react/portainer/settings/queries';
 | 
			
		||||
import { notifySuccess } from '@/portainer/services/notifications';
 | 
			
		||||
 | 
			
		||||
import { Widget } from '@@/Widget';
 | 
			
		||||
| 
						 | 
				
			
			@ -24,17 +21,13 @@ import { EnableTelemetryField } from './EnableTelemetryField';
 | 
			
		|||
 | 
			
		||||
export function ApplicationSettingsPanel({
 | 
			
		||||
  onSuccess,
 | 
			
		||||
  settings,
 | 
			
		||||
}: {
 | 
			
		||||
  onSuccess(settings: Settings): void;
 | 
			
		||||
  settings: Settings;
 | 
			
		||||
}) {
 | 
			
		||||
  const settingsQuery = useSettings();
 | 
			
		||||
  const mutation = useUpdateSettingsMutation();
 | 
			
		||||
 | 
			
		||||
  if (!settingsQuery.data) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const settings = settingsQuery.data;
 | 
			
		||||
  const initialValues: Values = {
 | 
			
		||||
    edgeAgentCheckinInterval: settings.EdgeAgentCheckinInterval,
 | 
			
		||||
    enableTelemetry: settings.EnableTelemetry,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,7 +8,8 @@ import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
 | 
			
		|||
import { LoadingButton } from '@@/buttons';
 | 
			
		||||
import { Widget } from '@@/Widget';
 | 
			
		||||
 | 
			
		||||
import { useSettings, useUpdateSettingsMutation } from '../../queries';
 | 
			
		||||
import { useUpdateSettingsMutation } from '../../queries';
 | 
			
		||||
import { Settings } from '../../types';
 | 
			
		||||
 | 
			
		||||
import { HelmSection } from './HelmSection';
 | 
			
		||||
import { KubeConfigSection } from './KubeConfigSection';
 | 
			
		||||
| 
						 | 
				
			
			@ -16,19 +17,14 @@ import { FormValues } from './types';
 | 
			
		|||
import { DeploymentOptionsSection } from './DeploymentOptionsSection';
 | 
			
		||||
import { validation } from './validation';
 | 
			
		||||
 | 
			
		||||
export function KubeSettingsPanel() {
 | 
			
		||||
  const settingsQuery = useSettings();
 | 
			
		||||
export function KubeSettingsPanel({ settings }: { settings: Settings }) {
 | 
			
		||||
  const queryClient = useQueryClient();
 | 
			
		||||
  const environmentId = useEnvironmentId(false);
 | 
			
		||||
  const mutation = useUpdateSettingsMutation();
 | 
			
		||||
 | 
			
		||||
  if (!settingsQuery.data) {
 | 
			
		||||
    return null;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const initialValues: FormValues = {
 | 
			
		||||
    helmRepositoryUrl: settingsQuery.data.HelmRepositoryURL || '',
 | 
			
		||||
    kubeconfigExpiry: settingsQuery.data.KubeconfigExpiry || '0',
 | 
			
		||||
    helmRepositoryUrl: settings.HelmRepositoryURL || '',
 | 
			
		||||
    kubeconfigExpiry: settings.KubeconfigExpiry || '0',
 | 
			
		||||
    globalDeploymentOptions: {
 | 
			
		||||
      ...{
 | 
			
		||||
        requireNoteOnApplications: false,
 | 
			
		||||
| 
						 | 
				
			
			@ -39,7 +35,7 @@ export function KubeSettingsPanel() {
 | 
			
		|||
        perEnvOverride: false,
 | 
			
		||||
        hideStacksFunctionality: false,
 | 
			
		||||
      },
 | 
			
		||||
      ...settingsQuery.data.GlobalDeploymentOptions,
 | 
			
		||||
      ...settings.GlobalDeploymentOptions,
 | 
			
		||||
    },
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,11 @@
 | 
			
		|||
import { useEffect } from 'react';
 | 
			
		||||
import angular from 'angular';
 | 
			
		||||
 | 
			
		||||
import { StateManager } from '@/portainer/services/types';
 | 
			
		||||
 | 
			
		||||
import { PageHeader } from '@@/PageHeader';
 | 
			
		||||
 | 
			
		||||
import { useSettings } from '../queries';
 | 
			
		||||
import { Settings } from '../types';
 | 
			
		||||
import { isBE } from '../../feature-flags/feature-flags.service';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -16,14 +18,33 @@ import { SSLSettingsPanelWrapper } from './SSLSettingsPanel/SSLSettingsPanel';
 | 
			
		|||
import { ExperimentalFeatures } from './ExperimentalFeatures';
 | 
			
		||||
 | 
			
		||||
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 (
 | 
			
		||||
    <>
 | 
			
		||||
      <PageHeader title="Settings" breadcrumbs="Settings" reload />
 | 
			
		||||
 | 
			
		||||
      <div className="mx-4 space-y-4">
 | 
			
		||||
        <ApplicationSettingsPanel onSuccess={handleSuccess} />
 | 
			
		||||
        {settingsQuery.data && (
 | 
			
		||||
          <>
 | 
			
		||||
            <ApplicationSettingsPanel
 | 
			
		||||
              onSuccess={handleSuccess}
 | 
			
		||||
              settings={settingsQuery.data}
 | 
			
		||||
            />
 | 
			
		||||
 | 
			
		||||
        <KubeSettingsPanel />
 | 
			
		||||
            <KubeSettingsPanel settings={settingsQuery.data} />
 | 
			
		||||
          </>
 | 
			
		||||
        )}
 | 
			
		||||
 | 
			
		||||
        <HelmCertPanel />
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue