From 6d5b1673e6cd94d6b76ed1188f9c4f46055d07c7 Mon Sep 17 00:00:00 2001 From: Anil Sahoo Date: Tue, 19 Nov 2024 15:45:00 +0530 Subject: [PATCH] Fix SonarQube code smells for PgTree directory. --- .../components/PgTree/FileTreeItem/index.tsx | 18 ++-- .../js/components/PgTree/FileTreeX/index.tsx | 94 +++++++++---------- .../PgTree/services/keyboardHotkeys.ts | 20 ++-- .../static/js/components/PgTree/types.ts | 2 +- 4 files changed, 67 insertions(+), 67 deletions(-) diff --git a/web/pgadmin/static/js/components/PgTree/FileTreeItem/index.tsx b/web/pgadmin/static/js/components/PgTree/FileTreeItem/index.tsx index 4466d5246..27b83de59 100644 --- a/web/pgadmin/static/js/components/PgTree/FileTreeItem/index.tsx +++ b/web/pgadmin/static/js/components/PgTree/FileTreeItem/index.tsx @@ -39,7 +39,7 @@ export class FileTreeItem extends React.Component = new Map(); private static readonly refToItemIdMap: Map = new Map(); - private fileTreeEvent: IFileTreeXTriggerEvents; + private readonly fileTreeEvent: IFileTreeXTriggerEvents; constructor(props) { super(props); @@ -119,7 +119,7 @@ export class FileTreeItem extends React.Component => { + private readonly setActiveFile = async (FileOrDir): Promise => { this.props.changeDirectoryCount(FileOrDir.parent); if(FileOrDir._loaded !== true) { this.events.dispatch(FileTreeXEvent.onTreeEvents, window.event, 'added', FileOrDir); @@ -142,7 +142,7 @@ export class FileTreeItem extends React.Component { + private readonly handleDivRef = (r: HTMLDivElement) => { if (r === null) { FileTreeItem.itemIdToRefMap.delete(this.props.item.id); } else { @@ -151,42 +151,42 @@ export class FileTreeItem extends React.Component { + private readonly handleContextMenu = (ev: React.MouseEvent) => { const { item, itemType, onContextMenu } = this.props; if (itemType === ItemType.File || itemType === ItemType.Directory) { onContextMenu(ev, item as FileOrDir); } }; - private handleClick = (ev: React.MouseEvent) => { + private readonly handleClick = (ev: React.MouseEvent) => { const { item, itemType, onClick } = this.props; if (itemType === ItemType.File || itemType === ItemType.Directory) { onClick(ev, item as FileEntry, itemType); } }; - private handleDoubleClick = (ev: React.MouseEvent) => { + private readonly handleDoubleClick = (ev: React.MouseEvent) => { const { item, itemType, onDoubleClick } = this.props; if (itemType === ItemType.File || itemType === ItemType.Directory) { onDoubleClick(ev, item as FileEntry, itemType); } }; - private handleMouseEnter = (ev: React.MouseEvent) => { + private readonly handleMouseEnter = (ev: React.MouseEvent) => { const { item, itemType, onMouseEnter } = this.props; if (itemType === ItemType.File || itemType === ItemType.Directory) { onMouseEnter?.(ev, item as FileEntry); } }; - private handleMouseLeave = (ev: React.MouseEvent) => { + private readonly handleMouseLeave = (ev: React.MouseEvent) => { const { item, itemType, onMouseLeave } = this.props; if (itemType === ItemType.File || itemType === ItemType.Directory) { onMouseLeave?.(ev, item as FileEntry); } }; - private handleDragStartItem = (e: React.DragEvent) => { + private readonly handleDragStartItem = (e: React.DragEvent) => { const { item, itemType, events } = this.props; if (itemType === ItemType.File || itemType === ItemType.Directory) { const ref = FileTreeItem.itemIdToRefMap.get(item.id); diff --git a/web/pgadmin/static/js/components/PgTree/FileTreeX/index.tsx b/web/pgadmin/static/js/components/PgTree/FileTreeX/index.tsx index cc9237c77..d5be72e07 100644 --- a/web/pgadmin/static/js/components/PgTree/FileTreeX/index.tsx +++ b/web/pgadmin/static/js/components/PgTree/FileTreeX/index.tsx @@ -20,17 +20,17 @@ import AutoSizer from 'react-virtualized-auto-sizer'; export class FileTreeX extends React.Component { private fileTreeHandle: IFileTreeXHandle; - private activeFileDec: Decoration; - private pseudoActiveFileDec: Decoration; + private readonly activeFileDec: Decoration; + private readonly pseudoActiveFileDec: Decoration; private activeFile: FileOrDir; private pseudoActiveFile: FileOrDir; - private wrapperRef: React.RefObject = React.createRef(); - private events: Notificar; - private disposables: DisposablesComposite; + private readonly wrapperRef: React.RefObject = React.createRef(); + private readonly events: Notificar; + private readonly disposables: DisposablesComposite; private keyboardHotkeys: KeyboardHotkeys; private fileTreeEvent: IFileTreeXTriggerEvents; - private hoverTimeoutId: React.RefObject = React.createRef(); - private hoverDispatchId: React.RefObject = React.createRef(); + private readonly hoverTimeoutId: React.RefObject = React.createRef(); + private readonly hoverDispatchId: React.RefObject = React.createRef(); constructor(props: IFileTreeXProps) { super(props); this.events = new Notificar(); @@ -98,11 +98,11 @@ export class FileTreeX extends React.Component { this.disposables.dispose(); } - private handleTreeEvent = () => { + private readonly handleTreeEvent = () => { this.fileTreeEvent = this.props.onEvent; }; - private handleTreeReady = (handle: IFileTreeHandle) => { + private readonly handleTreeReady = (handle: IFileTreeHandle) => { const { onReady, model } = this.props; const scrollDiv = this.wrapperRef.current?.querySelector('div')?.querySelector('div'); if(this.props.onScroll) { @@ -169,7 +169,7 @@ export class FileTreeX extends React.Component { } }; - private onItemMouseEnter = (ev: React.MouseEvent, item: FileEntry | Directory) => { + private readonly onItemMouseEnter = (ev: React.MouseEvent, item: FileEntry | Directory) => { clearTimeout(this.hoverDispatchId.current??undefined); (this.hoverDispatchId as any).current = setTimeout(()=>{ clearTimeout(this.hoverTimeoutId.current??undefined); @@ -177,7 +177,7 @@ export class FileTreeX extends React.Component { }, 500); }; - private onItemMouseLeave = (ev: React.MouseEvent) => { + private readonly onItemMouseLeave = (ev: React.MouseEvent) => { clearTimeout(this.hoverTimeoutId.current??undefined); clearTimeout(this.hoverDispatchId.current??undefined); (this.hoverTimeoutId as any).current = setTimeout(()=>{ @@ -185,7 +185,7 @@ export class FileTreeX extends React.Component { }, 100); }; - private setActiveFile = async (fileOrDirOrPath: FileOrDir | string, ensureVisible, align): Promise => { + private readonly setActiveFile = async (fileOrDirOrPath: FileOrDir | string, ensureVisible, align): Promise => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -202,13 +202,13 @@ export class FileTreeX extends React.Component { this.events.dispatch(FileTreeXEvent.onTreeEvents, window.event, 'selected', fileH); if (fileH && ensureVisible === true) { - const alignTree = align !== undefined && align !== null ? align : 'auto'; + const alignTree = align ?? 'auto'; await this.fileTreeHandle.ensureVisible(fileH, alignTree); } } }; - private ensureVisible = async (fileOrDirOrPath: FileOrDir | string): Promise => { + private readonly ensureVisible = async (fileOrDirOrPath: FileOrDir | string): Promise => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -218,7 +218,7 @@ export class FileTreeX extends React.Component { } }; - private deSelectActiveFile = async (fileOrDirOrPath: FileOrDir | string): Promise => { + private readonly deSelectActiveFile = async (fileOrDirOrPath: FileOrDir | string): Promise => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -230,7 +230,7 @@ export class FileTreeX extends React.Component { } }; - private setPseudoActiveFile = async (fileOrDirOrPath: FileOrDir | string): Promise => { + private readonly setPseudoActiveFile = async (fileOrDirOrPath: FileOrDir | string): Promise => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -251,7 +251,7 @@ export class FileTreeX extends React.Component { this.events.dispatch(FileTreeXEvent.onTreeEvents, window.event, 'selected', fileH); }; - private create = async (parentDir, itemData): Promise => { + private readonly create = async (parentDir, itemData): Promise => { if (parentDir == undefined || parentDir == null) { parentDir = this.props.model.root; } @@ -281,13 +281,13 @@ export class FileTreeX extends React.Component { return newItem; }; - private update = async (item, itemData): Promise => { + private readonly update = async (item, itemData): Promise => { item._metadata.data = itemData; await this.props.update(item.path, itemData); this.events.dispatch(FileTreeXEvent.onTreeEvents, window.event, 'updated', item); }; - private refresh = async (item): Promise => { + private readonly refresh = async (item): Promise => { const isOpen = item.isExpanded; if (item.children && item.children.length > 0) { for(const entry of item.children) { @@ -312,7 +312,7 @@ export class FileTreeX extends React.Component { } }; - private unload = async (item): Promise => { + private readonly unload = async (item): Promise => { const isOpen = item.isExpanded; if (item.children && item.children.length > 0) { for(const entry of item.children) { @@ -325,7 +325,7 @@ export class FileTreeX extends React.Component { } }; - private remove = async (item): Promise => { + private readonly remove = async (item): Promise => { const {remove, model } = this.props; const path = item.path; await remove(path, false); @@ -346,7 +346,7 @@ export class FileTreeX extends React.Component { } }; - private first = async (fileOrDirOrPath: FileOrDir | string) => { + private readonly first = async (fileOrDirOrPath: FileOrDir | string) => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -359,7 +359,7 @@ export class FileTreeX extends React.Component { return null; }; - private parent = async (fileOrDirOrPath: FileOrDir | string) => { + private readonly parent = async (fileOrDirOrPath: FileOrDir | string) => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -372,7 +372,7 @@ export class FileTreeX extends React.Component { }; - private hasParent = async (fileOrDirOrPath: FileOrDir | string) => { + private readonly hasParent = async (fileOrDirOrPath: FileOrDir | string) => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -384,7 +384,7 @@ export class FileTreeX extends React.Component { return false; }; - private children = async (fileOrDirOrPath: FileOrDir | string) => { + private readonly children = async (fileOrDirOrPath: FileOrDir | string) => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -397,7 +397,7 @@ export class FileTreeX extends React.Component { }; - private isOpen = async (fileOrDirOrPath: FileOrDir | string) => { + private readonly isOpen = async (fileOrDirOrPath: FileOrDir | string) => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -409,7 +409,7 @@ export class FileTreeX extends React.Component { return false; }; - private isClosed = async (fileOrDirOrPath: FileOrDir | string) => { + private readonly isClosed = async (fileOrDirOrPath: FileOrDir | string) => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -421,7 +421,7 @@ export class FileTreeX extends React.Component { return false; }; - private itemData = async (fileOrDirOrPath: FileOrDir | string) => { + private readonly itemData = async (fileOrDirOrPath: FileOrDir | string) => { const fileH = typeof fileOrDirOrPath === 'string' ? await this.fileTreeHandle.getFileHandle(fileOrDirOrPath) : fileOrDirOrPath; @@ -433,7 +433,7 @@ export class FileTreeX extends React.Component { return null; }; - private setLabel = async(pathOrDir: string | Directory, label: string): Promise => { + private readonly setLabel = async(pathOrDir: string | Directory, label: string): Promise => { const dir = typeof pathOrDir === 'string' ? await this.fileTreeHandle.getFileHandle(pathOrDir) : pathOrDir; @@ -454,7 +454,7 @@ export class FileTreeX extends React.Component { }; - private changeDirectoryCount = async(pathOrDir: string | Directory): Promise => { + private readonly changeDirectoryCount = async(pathOrDir: string | Directory): Promise => { const dir = typeof pathOrDir === 'string' ? await this.fileTreeHandle.getFileHandle(pathOrDir) : pathOrDir; @@ -474,7 +474,7 @@ export class FileTreeX extends React.Component { }; - private closeDir = async (pathOrDir: string | Directory) => { + private readonly closeDir = async (pathOrDir: string | Directory) => { const dir = typeof pathOrDir === 'string' ? await this.fileTreeHandle.getFileHandle(pathOrDir) : pathOrDir; @@ -488,7 +488,7 @@ export class FileTreeX extends React.Component { } }; - private toggleDirectory = async (pathOrDir: string | Directory) => { + private readonly toggleDirectory = async (pathOrDir: string | Directory) => { const dir = typeof pathOrDir === 'string' ? await this.fileTreeHandle.getFileHandle(pathOrDir) : pathOrDir; @@ -517,7 +517,7 @@ export class FileTreeX extends React.Component { } }; - private addIcon = async (pathOrDir: string | Directory, icon) => { + private readonly addIcon = async (pathOrDir: string | Directory, icon) => { const dir = typeof pathOrDir === 'string' ? await this.fileTreeHandle.getFileHandle(pathOrDir) : pathOrDir; @@ -530,7 +530,7 @@ export class FileTreeX extends React.Component { }; - private addCssClass = async (pathOrDir: string | Directory, cssClass) => { + private readonly addCssClass = async (pathOrDir: string | Directory, cssClass) => { const dir = typeof pathOrDir === 'string' ? await this.fileTreeHandle.getFileHandle(pathOrDir) : pathOrDir; @@ -546,25 +546,25 @@ export class FileTreeX extends React.Component { }; - private showLoader = (ref: HTMLDivElement) => { + private readonly showLoader = (ref: HTMLDivElement) => { // get label ref and add loading class ref.style.background = 'none'; const label$ = ref.querySelector('i.directory-toggle') as HTMLDivElement; if (label$) label$.classList.add('loading'); }; - private hideLoader = (ref: HTMLDivElement) => { + private readonly hideLoader = (ref: HTMLDivElement) => { // remove loading class. ref.style.background = 'none'; const label$ = ref.querySelector('i.directory-toggle') as HTMLDivElement; if (label$) label$.classList.remove('loading'); }; - private handleBlur = () => { + private readonly handleBlur = () => { this.events.dispatch(FileTreeXEvent.OnBlur); }; - private handleItemClicked = async (ev: React.MouseEvent, item: FileOrDir, type: ItemType) => { + private readonly handleItemClicked = async (ev: React.MouseEvent, item: FileOrDir, type: ItemType) => { if (type === ItemType.Directory && ev.target.className.includes('directory-toggle')) { await this.toggleDirectory(item as Directory); } @@ -572,42 +572,42 @@ export class FileTreeX extends React.Component { }; - private handleItemDoubleClicked = async (ev: React.MouseEvent, item: FileOrDir) => { + private readonly handleItemDoubleClicked = async (ev: React.MouseEvent, item: FileOrDir) => { await this.toggleDirectory(item as Directory); await this.setActiveFile(item as FileEntry); }; - private getItemFromDOM = (clientReact) => { + private readonly getItemFromDOM = (clientReact) => { return FileTreeItem.refToItemIdMap.get(clientReact); }; - private getDOMFromItem = (item: FileOrDir) => { + private readonly getDOMFromItem = (item: FileOrDir) => { return FileTreeItem.itemIdToRefMap.get(item.id); }; - private handleClick = (ev: React.MouseEvent) => { + private readonly handleClick = (ev: React.MouseEvent) => { // clicked in "blank space" if (ev.currentTarget === ev.target) { this.setPseudoActiveFile(null); } }; - private handleItemCtxMenu = (ev: React.MouseEvent, item: FileOrDir) => { + private readonly handleItemCtxMenu = (ev: React.MouseEvent, item: FileOrDir) => { return this.props.onContextMenu?.(ev, item); }; - private handleKeyDown = (ev: React.KeyboardEvent) => { + private readonly handleKeyDown = (ev: React.KeyboardEvent) => { return this.keyboardHotkeys.handleKeyDown(ev); }; - private onResize = () => { + private readonly onResize = () => { if (this.wrapperRef.current != null) { this.resize(); } }; - private resize = (scrollX, scrollY) => { + private readonly resize = (scrollX, scrollY) => { const scrollXPos = scrollX || 0; const scrollYPos = scrollY || this.props.model.state.scrollOffset; const div = this.wrapperRef.current.querySelector('div').querySelector('div') as HTMLDivElement; @@ -617,7 +617,7 @@ export class FileTreeX extends React.Component { }; - private changeResolvePath = async (item: FileOrDir): Promise => { + private readonly changeResolvePath = async (item: FileOrDir): Promise => { // Change the path as per pgAdmin requirement: Item Id wise if (item.type === FileType.File) { item.resolvedPathCache = item.parent.path + '/' + item._metadata.data.id; diff --git a/web/pgadmin/static/js/components/PgTree/services/keyboardHotkeys.ts b/web/pgadmin/static/js/components/PgTree/services/keyboardHotkeys.ts index 27d219e92..52c6beb75 100644 --- a/web/pgadmin/static/js/components/PgTree/services/keyboardHotkeys.ts +++ b/web/pgadmin/static/js/components/PgTree/services/keyboardHotkeys.ts @@ -3,7 +3,7 @@ import { FileEntry, Directory, FileType } from 'react-aspen'; import { FileTreeXEvent, IFileTreeXHandle } from '../types'; export class KeyboardHotkeys { - private hotkeyActions = { + private readonly hotkeyActions = { 'ArrowUp': () => this.jumpToPrevItem(), 'ArrowDown': () => this.jumpToNextItem(), 'ArrowRight': () => this.expandOrJumpToFirstChild(), @@ -34,17 +34,17 @@ export class KeyboardHotkeys { } }; - private jumpToFirstItem = (): void => { + private readonly jumpToFirstItem = (): void => { const { root } = this.fileTreeX.getModel(); this.fileTreeX.setActiveFile(root.getFileEntryAtIndex(0), true); }; - private jumpToLastItem = (): void => { + private readonly jumpToLastItem = (): void => { const { root } = this.fileTreeX.getModel(); this.fileTreeX.setActiveFile(root.getFileEntryAtIndex(root.branchSize - 1), true); }; - private jumpToNextItem = (): void => { + private readonly jumpToNextItem = (): void => { const { root } = this.fileTreeX.getModel(); let currentPseudoActive = this.fileTreeX.getActiveFile(); if (!currentPseudoActive) { @@ -63,7 +63,7 @@ export class KeyboardHotkeys { } }; - private jumpToPrevItem = (): void => { + private readonly jumpToPrevItem = (): void => { const { root } = this.fileTreeX.getModel(); let currentPseudoActive = this.fileTreeX.getActiveFile(); if (!currentPseudoActive) { @@ -103,7 +103,7 @@ export class KeyboardHotkeys { } } - private selectFileOrToggleDirState = (): void => { + private readonly selectFileOrToggleDirState = (): void => { const currentPseudoActive = this.fileTreeX.getActiveFile(); if (!currentPseudoActive) { return; } if (currentPseudoActive.type === FileType.Directory) { @@ -113,7 +113,7 @@ export class KeyboardHotkeys { } }; - private toggleDirectoryExpand = (): void => { + private readonly toggleDirectoryExpand = (): void => { const currentPseudoActive = this.fileTreeX.getActiveFile(); if (!currentPseudoActive) { return; } if (currentPseudoActive.type === FileType.Directory) { @@ -121,7 +121,7 @@ export class KeyboardHotkeys { } }; - private resetSteppedOrSelectedItem = (): void => { + private readonly resetSteppedOrSelectedItem = (): void => { const currentPseudoActive = this.fileTreeX.getActiveFile(); if (currentPseudoActive) { return this.resetSteppedItem(); @@ -129,11 +129,11 @@ export class KeyboardHotkeys { this.fileTreeX.setActiveFile(null); }; - private resetSteppedItem = () => { + private readonly resetSteppedItem = () => { this.fileTreeX.setActiveFile(null); }; - private copyEntry = () => { + private readonly copyEntry = () => { const currentPseudoActive = this.fileTreeX.getActiveFile(); this.events.dispatch(FileTreeXEvent.onTreeEvents, null, 'copied', currentPseudoActive); }; diff --git a/web/pgadmin/static/js/components/PgTree/types.ts b/web/pgadmin/static/js/components/PgTree/types.ts index e89344116..2ab494c9e 100644 --- a/web/pgadmin/static/js/components/PgTree/types.ts +++ b/web/pgadmin/static/js/components/PgTree/types.ts @@ -9,7 +9,7 @@ export interface IFileTreeXTriggerEvents { } export interface IItemRendererX extends IItemRenderer { - getBoundingClientRectForItem(item: FileEntry | Directory): ClientRect + getBoundingClientRectForItem(item: FileEntry | Directory): DOMRect } // Here imagination is your limit! IFileTreeHandle has core low-level features you can build on top of as your application needs