|
|
@@ -26,8 +26,10 @@ import AdlsIcon from '../../../components/icons/AdlsIcon';
|
|
|
import { BreadcrumbData } from '../types';
|
|
|
import Breadcrumb from './Breadcrumb/Breadcrumb';
|
|
|
import './PathBrowser.scss';
|
|
|
+import { getBreadcrumbs, getFileSystemAndPath } from './PathBrowser.util';
|
|
|
+
|
|
|
interface PathBrowserProps {
|
|
|
- breadcrumbs?: BreadcrumbData[];
|
|
|
+ filePath: string;
|
|
|
onFilepathChange: (path: string) => void;
|
|
|
seperator: string;
|
|
|
showIcon: boolean;
|
|
|
@@ -39,7 +41,7 @@ const defaultProps = {
|
|
|
};
|
|
|
|
|
|
const PathBrowser = ({
|
|
|
- breadcrumbs,
|
|
|
+ filePath,
|
|
|
onFilepathChange,
|
|
|
seperator,
|
|
|
showIcon,
|
|
|
@@ -48,12 +50,14 @@ const PathBrowser = ({
|
|
|
const [isEditMode, setIsEditMode] = useState(false);
|
|
|
|
|
|
const icons = {
|
|
|
- //hdfs file system begins with the first breadcrumb as "/" (ex: /user/demo)
|
|
|
- '/': <HdfsIcon />,
|
|
|
+ hdfs: <HdfsIcon />,
|
|
|
abfs: <AdlsIcon />,
|
|
|
s3: <S3Icon />
|
|
|
};
|
|
|
|
|
|
+ const { fileSystem, path } = getFileSystemAndPath(filePath);
|
|
|
+ const breadcrumbs = getBreadcrumbs(fileSystem, path);
|
|
|
+
|
|
|
const useOutsideAlerter = (ref: RefObject<HTMLDivElement>) => {
|
|
|
useEffect(() => {
|
|
|
// Alert if clicked on outside of element
|
|
|
@@ -72,18 +76,8 @@ const PathBrowser = ({
|
|
|
}, []);
|
|
|
};
|
|
|
|
|
|
- const extractFileSystem = (label: string) => {
|
|
|
- const fileSystemPrefix = label.substring(0, label.length - 3);
|
|
|
- //hdfs file system begins with the first breadcrumb as "/" (ex: /user/demo)
|
|
|
- if (fileSystemPrefix == '') {
|
|
|
- return label;
|
|
|
- } else {
|
|
|
- return fileSystemPrefix;
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- const wrapperRef = useRef<HTMLDivElement>(null);
|
|
|
- useOutsideAlerter(wrapperRef);
|
|
|
+ const breadcrumbInputRef = useRef<HTMLDivElement>(null);
|
|
|
+ useOutsideAlerter(breadcrumbInputRef);
|
|
|
|
|
|
const extractMenuItems = (breadcrumbMenu: BreadcrumbData[]) => {
|
|
|
const menu: MenuItemType[] = breadcrumbMenu.map(breadcrumb => {
|
|
|
@@ -97,125 +91,125 @@ const PathBrowser = ({
|
|
|
};
|
|
|
|
|
|
if (breadcrumbs) {
|
|
|
+ if (isEditMode) {
|
|
|
+ return (
|
|
|
+ <div ref={breadcrumbInputRef}>
|
|
|
+ <Input
|
|
|
+ prefix={showIcon ? icons[fileSystem] : <span />}
|
|
|
+ defaultValue={filePath}
|
|
|
+ onPressEnter={event => {
|
|
|
+ onFilepathChange((event.target as HTMLInputElement).value);
|
|
|
+ }}
|
|
|
+ className="hue-path-browser__input"
|
|
|
+ autoFocus
|
|
|
+ data-testid={`${testId}-input`}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+
|
|
|
return (
|
|
|
- <>
|
|
|
- {!isEditMode ? (
|
|
|
- <div className="hue-path-browser" data-testid={`${testId}`}>
|
|
|
- {showIcon && (
|
|
|
- <div
|
|
|
- className="hue-path-browser__file-system-icon"
|
|
|
- data-testid={`${testId}__file-system-icon`}
|
|
|
- >
|
|
|
- {icons[extractFileSystem(breadcrumbs[0].label)]}
|
|
|
- </div>
|
|
|
- )}
|
|
|
- <div className="hue-path-browser__breadcrumbs" data-testid={`${testId}-breadcrumb`}>
|
|
|
- {breadcrumbs.length <= 3 ? (
|
|
|
- breadcrumbs.map((item: BreadcrumbData, index: number) => {
|
|
|
- return (
|
|
|
- <React.Fragment key={item.url + index}>
|
|
|
- <Breadcrumb
|
|
|
- key={item.url}
|
|
|
- label={index === 0 ? extractFileSystem(item.label) : item.label}
|
|
|
- url={item.url}
|
|
|
- onFilepathChange={onFilepathChange}
|
|
|
- />
|
|
|
- {index != breadcrumbs.length - 1 && (
|
|
|
- <div
|
|
|
- className="hue-path-browser__breadcrumb-seperator"
|
|
|
- data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
- >
|
|
|
- {seperator}
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </React.Fragment>
|
|
|
- );
|
|
|
- })
|
|
|
- ) : (
|
|
|
- <>
|
|
|
+ <div className="hue-path-browser" data-testid={`${testId}`}>
|
|
|
+ {showIcon && (
|
|
|
+ <div
|
|
|
+ className="hue-path-browser__file-system-icon"
|
|
|
+ data-testid={`${testId}__file-system-icon`}
|
|
|
+ >
|
|
|
+ {icons[fileSystem]}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ <div className="hue-path-browser__breadcrumbs" data-testid={`${testId}-breadcrumb`}>
|
|
|
+ {breadcrumbs.length <= 3 ? (
|
|
|
+ breadcrumbs.map((item: BreadcrumbData, index: number) => {
|
|
|
+ return (
|
|
|
+ <React.Fragment key={item.url + index}>
|
|
|
<Breadcrumb
|
|
|
- label={extractFileSystem(breadcrumbs[0].label)}
|
|
|
- url={breadcrumbs[0].url}
|
|
|
+ key={item.url}
|
|
|
+ label={item.label}
|
|
|
+ url={item.url}
|
|
|
onFilepathChange={onFilepathChange}
|
|
|
- key={breadcrumbs[0].url}
|
|
|
/>
|
|
|
- <div
|
|
|
- className="hue-path-browser__breadcrumb-seperator"
|
|
|
- data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
- >
|
|
|
- {seperator}
|
|
|
- </div>
|
|
|
- <Dropdown
|
|
|
- overlayClassName="hue-path-browser__dropdown cuix antd"
|
|
|
- menu={{
|
|
|
- items: extractMenuItems(breadcrumbs.slice(1, breadcrumbs.length - 2)),
|
|
|
- className: 'hue-path-browser__dropdown-menu'
|
|
|
- }}
|
|
|
- trigger={['hover', 'click']}
|
|
|
- autoFocus
|
|
|
- data-testid={`${testId}-dropdown`}
|
|
|
- >
|
|
|
- <BorderlessButton
|
|
|
- data-event=""
|
|
|
- className="hue-path-browser__dropdown-button"
|
|
|
- data-testid={`${testId}-dropdown-btn`}
|
|
|
+ {index != breadcrumbs.length - 1 && (
|
|
|
+ <div
|
|
|
+ className="hue-path-browser__breadcrumb-seperator"
|
|
|
+ data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
>
|
|
|
- ..
|
|
|
- </BorderlessButton>
|
|
|
- </Dropdown>
|
|
|
- <div
|
|
|
- className="hue-path-browser__breadcrumb-seperator"
|
|
|
- data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
- >
|
|
|
- {seperator}
|
|
|
- </div>
|
|
|
- <Breadcrumb
|
|
|
- key={breadcrumbs[breadcrumbs.length - 2].url}
|
|
|
- label={breadcrumbs[breadcrumbs.length - 2].label}
|
|
|
- url={breadcrumbs[breadcrumbs.length - 2].url}
|
|
|
- onFilepathChange={onFilepathChange}
|
|
|
- />
|
|
|
- <div
|
|
|
- className="hue-path-browser__breadcrumb-seperator"
|
|
|
- data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
- >
|
|
|
- {seperator}
|
|
|
- </div>
|
|
|
- <Breadcrumb
|
|
|
- key={breadcrumbs[breadcrumbs.length - 1].url}
|
|
|
- label={breadcrumbs[breadcrumbs.length - 1].label}
|
|
|
- url={breadcrumbs[breadcrumbs.length - 1].url}
|
|
|
- onFilepathChange={onFilepathChange}
|
|
|
- />
|
|
|
- </>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- <BorderlessButton
|
|
|
- data-event=""
|
|
|
- className="hue-path-browser__toggle-breadcrumb-input-btn"
|
|
|
- aria-label="hue-path-browser__toggle-breadcrumb-input-btn"
|
|
|
- title="Edit path"
|
|
|
- onClick={() => {
|
|
|
- setIsEditMode(true);
|
|
|
- }}
|
|
|
- data-testid={`${testId}-toggle-input-btn`}
|
|
|
- ></BorderlessButton>
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <div ref={wrapperRef}>
|
|
|
- <Input
|
|
|
- prefix={showIcon ? icons[extractFileSystem(breadcrumbs[0].label)] : <span />}
|
|
|
- defaultValue={decodeURIComponent(breadcrumbs[breadcrumbs.length - 1].url)}
|
|
|
- onPressEnter={customPath => {
|
|
|
- onFilepathChange((customPath.target as HTMLInputElement).value);
|
|
|
- }}
|
|
|
- className="hue-path-browser__input"
|
|
|
- autoFocus
|
|
|
- data-testid={`${testId}-input`}
|
|
|
- ></Input>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </>
|
|
|
+ {seperator}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </React.Fragment>
|
|
|
+ );
|
|
|
+ })
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <Breadcrumb
|
|
|
+ label={breadcrumbs[0].label}
|
|
|
+ url={breadcrumbs[0].url}
|
|
|
+ onFilepathChange={onFilepathChange}
|
|
|
+ key={breadcrumbs[0].url}
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ className="hue-path-browser__breadcrumb-seperator"
|
|
|
+ data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
+ >
|
|
|
+ {seperator}
|
|
|
+ </div>
|
|
|
+ <Dropdown
|
|
|
+ overlayClassName="hue-path-browser__dropdown cuix antd"
|
|
|
+ menu={{
|
|
|
+ items: extractMenuItems(breadcrumbs.slice(1, breadcrumbs.length - 2)),
|
|
|
+ className: 'hue-path-browser__dropdown-menu'
|
|
|
+ }}
|
|
|
+ trigger={['hover', 'click']}
|
|
|
+ autoFocus
|
|
|
+ data-testid={`${testId}-dropdown`}
|
|
|
+ >
|
|
|
+ <BorderlessButton
|
|
|
+ data-event=""
|
|
|
+ className="hue-path-browser__dropdown-button"
|
|
|
+ data-testid={`${testId}-dropdown-btn`}
|
|
|
+ >
|
|
|
+ ..
|
|
|
+ </BorderlessButton>
|
|
|
+ </Dropdown>
|
|
|
+ <div
|
|
|
+ className="hue-path-browser__breadcrumb-seperator"
|
|
|
+ data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
+ >
|
|
|
+ {seperator}
|
|
|
+ </div>
|
|
|
+ <Breadcrumb
|
|
|
+ key={breadcrumbs[breadcrumbs.length - 2].url}
|
|
|
+ label={breadcrumbs[breadcrumbs.length - 2].label}
|
|
|
+ url={breadcrumbs[breadcrumbs.length - 2].url}
|
|
|
+ onFilepathChange={onFilepathChange}
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ className="hue-path-browser__breadcrumb-seperator"
|
|
|
+ data-testid={`${testId}-breadcrumb-seperator`}
|
|
|
+ >
|
|
|
+ {seperator}
|
|
|
+ </div>
|
|
|
+ <Breadcrumb
|
|
|
+ key={breadcrumbs[breadcrumbs.length - 1].url}
|
|
|
+ label={breadcrumbs[breadcrumbs.length - 1].label}
|
|
|
+ url={breadcrumbs[breadcrumbs.length - 1].url}
|
|
|
+ onFilepathChange={onFilepathChange}
|
|
|
+ />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <BorderlessButton
|
|
|
+ data-event=""
|
|
|
+ className="hue-path-browser__toggle-breadcrumb-input-btn"
|
|
|
+ aria-label="hue-path-browser__toggle-breadcrumb-input-btn"
|
|
|
+ title="Edit path"
|
|
|
+ onClick={() => {
|
|
|
+ setIsEditMode(true);
|
|
|
+ }}
|
|
|
+ data-testid={`${testId}-toggle-input-btn`}
|
|
|
+ ></BorderlessButton>
|
|
|
+ </div>
|
|
|
);
|
|
|
}
|
|
|
|