-
dispatch(updateFileListElement({ ...props.file, checked: e.target.checked }))}
- />
-
+ {(props.listOnly === undefined || !props.listOnly) && (
+
dispatch(updateFileListElement({ ...props.file, checked: e.target.checked }))}
+ />
+ )}
+
{
+ if (props.listOnly === true) {
+ dispatch(showFileTreeElementInfo(props.file));
+ }
+ }}
+ onContextMenu={(e) => {
+ openFileContextMenu(e);
+ }}>
{formatName(props.file.searchTerm, props.file.name)}
diff --git a/binocular-frontend-new/src/components/tabs/fileTree/fileList/fileListElements/fileListFolder.tsx b/binocular-frontend-new/src/components/tabs/fileTree/fileList/fileListElements/fileListFolder.tsx
index c85aa782..a8b6017b 100644
--- a/binocular-frontend-new/src/components/tabs/fileTree/fileList/fileListElements/fileListFolder.tsx
+++ b/binocular-frontend-new/src/components/tabs/fileTree/fileList/fileListElements/fileListFolder.tsx
@@ -4,18 +4,32 @@ import FolderIcon from '../../../../../assets/folder_gray.svg';
import FolderOpenIcon from '../../../../../assets/folder_open_gray.svg';
import FileListFile from './fileListFile.tsx';
import { AppDispatch, useAppDispatch } from '../../../../../redux';
-import { updateFileListElement } from '../../../../../redux/reducer/data/filesReducer.ts';
+import { showFileTreeElementInfo, updateFileListElement } from '../../../../../redux/reducer/data/filesReducer.ts';
import { formatName } from '../fileListUtilities/fileTreeUtilities.tsx';
+import { showContextMenu } from '../../../../contextMenu/contextMenuHelper.ts';
+import infoIcon from '../../../../../assets/info_gray.svg';
-function FileListFolder(props: { folder: FileTreeElementType; foldedOut: boolean }) {
+function FileListFolder(props: { folder: FileTreeElementType; foldedOut: boolean; listOnly?: boolean }) {
const dispatch: AppDispatch = useAppDispatch();
+ function openFolderContextMenu(e: React.MouseEvent
) {
+ e.preventDefault();
+ e.stopPropagation();
+ showContextMenu(e.clientX, e.clientY, [
+ {
+ label: 'info',
+ icon: infoIcon,
+ function: () => dispatch(showFileTreeElementInfo(props.folder)),
+ },
+ ]);
+ }
+
return (
<>
- {props.folder.foldedOut ? (
+ {props.listOnly === true || props.folder.foldedOut ? (
<>
@@ -46,9 +69,15 @@ function FileListFolder(props: { folder: FileTreeElementType; foldedOut: boolean
.sort((e) => (e.type === FileTreeElementTypeType.Folder ? -1 : 1))
.map((element, i) => {
if (element.type === FileTreeElementTypeType.Folder && element.children) {
- return ;
+ return (
+
+ );
} else {
- return ;
+ return ;
}
})}
@@ -63,6 +92,9 @@ function FileListFolder(props: { folder: FileTreeElementType; foldedOut: boolean
/>
dispatch(updateFileListElement({ ...props.folder, foldedOut: true }))}
+ onContextMenu={(e) => {
+ openFolderContextMenu(e);
+ }}
className={fileListElementsStyles.element}>
{formatName(props.folder.searchTerm, props.folder.name)}
diff --git a/binocular-frontend-new/src/components/tabs/fileTree/fileTreeElementInfoDialog/fileTreeElementInfoDialog.tsx b/binocular-frontend-new/src/components/tabs/fileTree/fileTreeElementInfoDialog/fileTreeElementInfoDialog.tsx
new file mode 100644
index 00000000..84cf8d94
--- /dev/null
+++ b/binocular-frontend-new/src/components/tabs/fileTree/fileTreeElementInfoDialog/fileTreeElementInfoDialog.tsx
@@ -0,0 +1,79 @@
+import { useSelector } from 'react-redux';
+import { RootState } from '../../../../redux';
+import { FileTreeElementType, FileTreeElementTypeType } from '../../../../types/data/fileListType.ts';
+import FileListFolder from '../fileList/fileListElements/fileListFolder.tsx';
+import { filterFileTree } from '../fileList/fileListUtilities/fileTreeUtilities.tsx';
+import FileSearch from '../fileSearch/fileSearch.tsx';
+import { useState } from 'react';
+
+function FileTreeElementInfoDialog() {
+ const selectedFileTreeElement: FileTreeElementType | undefined = useSelector((state: RootState) => state.files.selectedFileTreeElement);
+ const [fileSearch, setFileSearch] = useState('');
+
+ return (
+
+ );
+}
+
+export default FileTreeElementInfoDialog;
diff --git a/binocular-frontend-new/src/index.scss b/binocular-frontend-new/src/index.scss
index 7ab49525..a43ce90b 100644
--- a/binocular-frontend-new/src/index.scss
+++ b/binocular-frontend-new/src/index.scss
@@ -17,6 +17,10 @@
@apply text-lg;
@apply underline;
}
+ a {
+ @apply text-accent;
+ @apply underline;
+ }
}
@tailwind components;
@tailwind utilities;
diff --git a/binocular-frontend-new/src/plugins/interfaces/visualizationPlugin.ts b/binocular-frontend-new/src/plugins/interfaces/visualizationPlugin.ts
index 4f927521..9dc9e532 100644
--- a/binocular-frontend-new/src/plugins/interfaces/visualizationPlugin.ts
+++ b/binocular-frontend-new/src/plugins/interfaces/visualizationPlugin.ts
@@ -4,6 +4,7 @@ import { AuthorType } from '../../types/data/authorType.ts';
import { SprintType } from '../../types/data/sprintType.ts';
import { Reducer, Store } from '@reduxjs/toolkit';
import { ParametersType } from '../../types/parameters/parametersType.ts';
+import { FileListElementType } from '../../types/data/fileListType.ts';
export interface VisualizationPlugin
{
name: string;
@@ -15,6 +16,7 @@ export interface VisualizationPlugin {
// Not every dataPlugin has all capabilities.
// !!
authorList: AuthorType[]; //list of Users set by Binocular
+ fileList: FileListElementType[]; //list of Users set by Binocular
sprintList: SprintType[]; //list of Sprints set by Binocular
parameters: ParametersType; // General Parameters Provided By Binocular
chartContainerRef: RefObject; //forwarded ref that should reference the chart div
diff --git a/binocular-frontend-new/src/redux/reducer/data/filesReducer.ts b/binocular-frontend-new/src/redux/reducer/data/filesReducer.ts
index d43f94b1..2a53b074 100644
--- a/binocular-frontend-new/src/redux/reducer/data/filesReducer.ts
+++ b/binocular-frontend-new/src/redux/reducer/data/filesReducer.ts
@@ -7,6 +7,7 @@ export interface FilesInitialState {
fileLists: { [id: number]: FileListElementType[] };
fileCounts: { [id: number]: number };
dataPluginId: number | undefined;
+ selectedFileTreeElement?: FileTreeElementType;
}
const initialState: FilesInitialState = {
@@ -14,6 +15,7 @@ const initialState: FilesInitialState = {
fileLists: {},
fileCounts: {},
dataPluginId: undefined,
+ selectedFileTreeElement: undefined,
};
export const filesSlice = createSlice({
@@ -51,10 +53,14 @@ export const filesSlice = createSlice({
});
localStorage.setItem(`${filesSlice.name}StateV${Config.localStorageVersion}`, JSON.stringify(state));
},
+ showFileTreeElementInfo: (state, action: PayloadAction) => {
+ (document.getElementById('fileTreeElementInfoDialog') as HTMLDialogElement).showModal();
+ state.selectedFileTreeElement = action.payload;
+ },
},
});
-export const { setFilesDataPluginId, setFileList, updateFileListElement } = filesSlice.actions;
+export const { setFilesDataPluginId, setFileList, updateFileListElement, showFileTreeElementInfo } = filesSlice.actions;
export default filesSlice.reducer;
function updateFileTreeRecursive(fileTree: FileTreeElementType, element: FileTreeElementType, checked?: boolean): string[] {
diff --git a/binocular-frontend-new/src/types/data/fileListType.ts b/binocular-frontend-new/src/types/data/fileListType.ts
index 592ed048..46c49142 100644
--- a/binocular-frontend-new/src/types/data/fileListType.ts
+++ b/binocular-frontend-new/src/types/data/fileListType.ts
@@ -17,6 +17,6 @@ export interface FileTreeElementType {
}
export enum FileTreeElementTypeType {
- Folder,
- File,
+ Folder = 'Folder',
+ File = 'File',
}