diff --git a/.talismanrc b/.talismanrc index ce32ff786..28aed1441 100644 --- a/.talismanrc +++ b/.talismanrc @@ -81,6 +81,9 @@ fileignoreconfig: checksum: 1fec859f4d41e1acb5cdab8fdfba7c1978532a7f98f4fd26674153755f926d64 - filename: ui/package-lock.json checksum: 4abcc89c75b7ddca8128fd72faafbb9b159f02611d96325bcd355283074ce287 + - filename: ui/src/components/ContentMapper/index.scss + checksum: 46f8fde3b745feba40943f00d8d52714d0f320202c86b62f6c5ded73c2dbcf4c + fileignoreconfig: - filename: api/src/services/migration.service.ts diff --git a/api/src/services/migration.service.ts b/api/src/services/migration.service.ts index 28ca8b450..62618dd66 100644 --- a/api/src/services/migration.service.ts +++ b/api/src/services/migration.service.ts @@ -34,7 +34,7 @@ import fsPromises from 'fs/promises'; import { matchesSearchText } from '../utils/search.util.js'; import { taxonomyService } from './taxonomy.service.js'; import { globalFieldServie } from './globalField.service.js'; -// import { getSafePath } from "../utils/sanitize-path.utils.js"; +import { getSafePath } from '../utils/sanitize-path.utils.js'; /** * Creates a test stack. @@ -727,7 +727,16 @@ const getAuditData = async (req: Request): Promise => { } }; if (entriesSelectFieldExists) { - const fileContent = await fsPromises?.readFile(entriesSelectFieldPath, 'utf8'); + const safeEntriesSelectFieldPath = getSafePath(entriesSelectFieldPath); + // Ensure the sanitized path is within the auditLogPath directory + if (!safeEntriesSelectFieldPath.startsWith(auditLogPath)) { + throw new BadRequestError('Access to this file is not allowed.'); + } + // Additional path traversal prevention + if (!safeEntriesSelectFieldPath.startsWith(auditLogPath) || safeEntriesSelectFieldPath.includes('..')) { + throw new BadRequestError('Access to this file is not allowed.'); + } + const fileContent = await fsPromises?.readFile(safeEntriesSelectFieldPath, 'utf8'); try { if (typeof fileContent === 'string') { const parsed = JSON?.parse(fileContent); @@ -739,7 +748,12 @@ const getAuditData = async (req: Request): Promise => { } } if (entriesExists) { - const fileContent = await fsPromises?.readFile(entriesPath, 'utf8'); + const safeEntriesPath = getSafePath(entriesPath); + // Ensure the sanitized path is within the auditLogPath directory + if (!safeEntriesPath.startsWith(auditLogPath)) { + throw new BadRequestError('Access to this file is not allowed.'); + } + const fileContent = await fsPromises?.readFile(safeEntriesPath, 'utf8'); try { if (typeof fileContent === 'string') { const parsed = JSON?.parse(fileContent); @@ -753,7 +767,19 @@ const getAuditData = async (req: Request): Promise => { fileData = combinedData; } else { if (fs?.existsSync(filePath)) { - const fileContent = await fsPromises?.readFile(filePath, 'utf8'); + const safeFilePath = getSafePath(filePath); + // Ensure the sanitized path is within the auditLogPath directory + if (!safeFilePath.startsWith(auditLogPath)) { + throw new BadRequestError('Access to this file is not allowed.'); + } + // Prevent path traversal by checking for '..' and ensuring the path is within auditLogPath + if ( + safeFilePath.includes('..') || + !safeFilePath.startsWith(auditLogPath) + ) { + throw new BadRequestError('Path traversal detected or access to this file is not allowed.'); + } + const fileContent = await fsPromises?.readFile(safeFilePath, 'utf8'); try { if (typeof fileContent === 'string') { fileData = JSON?.parse(fileContent); diff --git a/ui/package-lock.json b/ui/package-lock.json index 7b1322b3f..6e162b436 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -20200,4 +20200,4 @@ } } } -} +} \ No newline at end of file diff --git a/ui/src/components/AuditLogs/index.scss b/ui/src/components/AuditLogs/index.scss index d124d17d6..4060f0649 100644 --- a/ui/src/components/AuditLogs/index.scss +++ b/ui/src/components/AuditLogs/index.scss @@ -1,63 +1,72 @@ .select-container { - display: flex; + display: flex; - .select-wrapper { - display: flex; - margin-left: 1rem; - } + .select-wrapper { + display: flex; + margin-left: 1rem; + } } .Search-input-show { - margin-bottom: 4px; + margin-bottom: 4px; } -.PageLayout--primary .PageLayout__leftSidebar+.PageLayout__content .PageLayout__body { - width: calc(100% - 15rem); +.PageLayout--primary .PageLayout__leftSidebar + .PageLayout__content .PageLayout__body { + width: calc(100% - 15rem); } .Table__head__row { - height: 100% !important; + height: 100% !important; } .PageLayout__body { - .table-height { - .Table { - height: calc(100vh - 12.75rem) !important; - } - - .Table.TableWithPaginated { - .Table__body { - height: calc(100vh - 18.5rem) !important; - } - } + .table-height { + .Table { + height: calc(100vh - 12.75rem) !important; + } + + .Table.TableWithPaginated { + .Table__body { + height: calc(100vh - 18.5rem) !important; + } } + } } .custom-empty-state { - .Icon--original { - width: 207px !important; - height: auto !important; - max-width: 100%; - display: block; - margin: 0 auto; - } + .Icon--original { + width: 207px !important; + height: auto !important; + max-width: 100%; + display: block; + margin: 0 auto; + } } .Table__head__column { - align-items: center; - display: flex; - justify-content: space-between; + align-items: center; + display: flex; + justify-content: space-between; } .TablePagination { - position: sticky; - bottom: 0; + position: sticky; + bottom: 0; } .tree-struct { - width: 300px !important; + width: 300px !important; } .missing-val { - width: 270px !important; -} \ No newline at end of file + width: 270px !important; +} + +.tooltip-text { + max-width: 220px; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + vertical-align: middle; + } \ No newline at end of file diff --git a/ui/src/components/AuditLogs/index.tsx b/ui/src/components/AuditLogs/index.tsx index 5a139f049..4e9e7780e 100644 --- a/ui/src/components/AuditLogs/index.tsx +++ b/ui/src/components/AuditLogs/index.tsx @@ -1,440 +1,460 @@ import React, { useState, useEffect } from 'react'; import { useSelector } from 'react-redux'; import { useParams } from 'react-router'; -import { Button, EmptyState, InfiniteScrollTable, Select } from '@contentstack/venus-components'; +import { + Button, + EmptyState, + InfiniteScrollTable, + Select, + Tooltip +} from '@contentstack/venus-components'; // Redux import { RootState } from '../../store'; // Service import { getAuditData } from '../../services/api/project.service'; // Interfaces -import { - StackOption, - FileOption, - TableDataItem, - FilterOption -} from './auditLogs.interface'; +import { StackOption, FileOption, TableDataItem, FilterOption } from './auditLogs.interface'; import './index.scss'; import { auditLogsConstants } from '../../utilities/constants'; import AuditFilterModal from '../AuditFilterModal'; -const renderCell = (value: any) =>
{value ?? '-'}
; - +// const renderCell = (value: string | null | undefined) =>
{value ?? '-'}
; +const renderCell = (value: string | null | undefined, flag = 0) => ( + flag ? +
{value ?? '-'}
+
:
{value ?? '-'}
+); const AuditLogs: React.FC = () => { - const params = useParams<{ projectId?: string }>(); - const [loading, setLoading] = useState(false); - const [selectedStack, setSelectedStack] = useState(null); - const [stackOptions, setStackOptions] = useState([]); - const [selectedFile, setSelectedFile] = useState(null); - const [fileOptions, setFileOptions] = useState([]); - const [searchText, setSearchText] = useState(''); - const [tableData, setTableData] = useState([]); - const [totalCounts, setTotalCounts] = useState(0); - const [tableUid, setTableUid] = useState(0); - const [filterOption, setFilterOption] = useState('all'); - const [filterValue, setFilterValue] = useState([]); - const [isCursorInside, setIsCursorInside] = useState(true); - const [isFilterApplied, setIsFilterApplied] = useState(false); - const [isFilterDropdownOpen, setIsFilterDropdownOpen] = useState(false); - const [dropDownOptions, setDropDownOptions] = useState(); - const selectedOrganisation = useSelector( - (state: RootState) => state?.authentication?.selectedOrganisation - ); - const stacks = useSelector((state: RootState) => state?.migration?.newMigrationData?.testStacks); - const isMigDone = useSelector((state: RootState) => state?.migration?.newMigrationData?.migration_execution?.migrationCompleted); - const label1 = useSelector((state: RootState) => state?.migration?.newMigrationData?.stackDetails?.label); - const value1 = useSelector((state: RootState) => state?.migration?.newMigrationData?.stackDetails?.value); - useEffect(() => { - if (stacks && stacks?.length > 0) { - const formattedOptions: StackOption[] = stacks.map((stack: any) => ({ - label: stack?.stackName, - value: stack?.stackUid, - ...stack - })); - if (isMigDone && label1 && value1) { - formattedOptions.push({ - label: label1, - value: value1, - ...stacks - }); - } - setStackOptions(formattedOptions); - if (!selectedStack) { - setSelectedStack(formattedOptions[stacks?.length - 1]); - updateFileOptionsForStack(formattedOptions[0]); - } - } - }, [stacks]); - const updateFileOptionsForStack = (stack: StackOption | null) => { - if (stack && selectedOrganisation?.value) { - const predefinedOptions: FileOption[] = [ - { label: 'Content Types', value: 'content-types' }, - { label: 'Global Fields', value: 'global-fields' }, - { label: 'Entries', value: 'Entries_Select_feild' } - ]; - setFileOptions(predefinedOptions); - if (predefinedOptions?.length > 0) { - handleFileChange(predefinedOptions?.[0]); - } - } - }; - const handleStackChange = async (selectedOption: StackOption | null) => { - setSelectedStack(selectedOption); - resetFileSelection(); - if (selectedOption) { - updateFileOptionsForStack(selectedOption); - } - }; - const resetFileSelection = () => { - setSelectedFile(null); + const params = useParams<{ projectId?: string }>(); + const [loading, setLoading] = useState(false); + const [selectedStack, setSelectedStack] = useState(null); + const [stackOptions, setStackOptions] = useState([]); + const [selectedFile, setSelectedFile] = useState(null); + const [fileOptions, setFileOptions] = useState([]); + const [searchText, setSearchText] = useState(''); + const [tableData, setTableData] = useState([]); + const [totalCounts, setTotalCounts] = useState(0); + const [tableUid, setTableUid] = useState(0); + const [filterOption, setFilterOption] = useState('all'); + const [filterValue, setFilterValue] = useState([]); + const [isCursorInside, setIsCursorInside] = useState(true); + const [isFilterApplied, setIsFilterApplied] = useState(false); + const [isFilterDropdownOpen, setIsFilterDropdownOpen] = useState(false); + const [dropDownOptions, setDropDownOptions] = useState(); + const selectedOrganisation = useSelector( + (state: RootState) => state?.authentication?.selectedOrganisation + ); + const stacks = useSelector((state: RootState) => state?.migration?.newMigrationData?.testStacks); + const isMigDone = useSelector( + (state: RootState) => + state?.migration?.newMigrationData?.migration_execution?.migrationCompleted + ); + const label1 = useSelector( + (state: RootState) => state?.migration?.newMigrationData?.stackDetails?.label + ); + const value1 = useSelector( + (state: RootState) => state?.migration?.newMigrationData?.stackDetails?.value + ); + useEffect(() => { + if (stacks && stacks?.length > 0) { + const formattedOptions: StackOption[] = stacks.map((stack) => ({ + label: stack?.stackName || '', + value: stack?.stackUid || '', + stackName: stack?.stackName, + stackUid: stack?.stackUid, + isMigrated: stack?.isMigrated + })); + if (isMigDone && label1 && value1) { + formattedOptions.push({ + label: label1, + value: value1, + ...stacks + }); + } + setStackOptions(formattedOptions); + if (!selectedStack) { + setSelectedStack(formattedOptions[stacks?.length - 1]); + updateFileOptionsForStack(formattedOptions[0]); + } + } + }, [stacks]); + const updateFileOptionsForStack = (stack: StackOption | null) => { + if (stack && selectedOrganisation?.value) { + const predefinedOptions: FileOption[] = [ + { label: 'Content Types', value: 'content-types' }, + { label: 'Global Fields', value: 'global-fields' }, + { label: 'Entries', value: 'Entries_Select_feild' } + ]; + setFileOptions(predefinedOptions); + if (predefinedOptions?.length > 0) { + handleFileChange(predefinedOptions?.[0]); + } + } + }; + const handleStackChange = async (selectedOption: StackOption | null) => { + setSelectedStack(selectedOption); + resetFileSelection(); + if (selectedOption) { + updateFileOptionsForStack(selectedOption); + } + }; + const resetFileSelection = () => { + setSelectedFile(null); + setTableData([]); + setSearchText(''); + setTotalCounts(0); + setFilterValue([]); + setFilterOption('all'); + setIsFilterApplied(false); + }; + + const fetchTableData = async ({ + skip = 0, + limit = 30, + startIndex = 0, + stopIndex = 30, + searchText = 'null', + filter = filterOption + }) => { + if (!selectedStack || !selectedFile || !selectedOrganisation?.value) { + return { data: [], count: 0 }; + } + searchText = searchText === '' ? 'null' : searchText; + setLoading(true); + try { + const response = await getAuditData( + selectedOrganisation?.value, + params?.projectId ?? '', + selectedStack?.value, + selectedFile?.value, + skip, + limit, + startIndex, + stopIndex, + searchText, + filter + ); + if (response?.data) { + setTableData(response?.data?.data || []); + setTotalCounts(response?.data?.totalCount || 0); + return { + data: response?.data?.data || [], + count: response?.data?.totalCount || 0 + }; + } + return { data: [], count: 0 }; + } catch (error) { + console.error('Error fetching audit data:', error); + if (startIndex === 0) { setTableData([]); - setSearchText(''); setTotalCounts(0); - setFilterValue([]); - setFilterOption('all'); - setIsFilterApplied(false); + } + return { data: [], count: 0 }; + } finally { + setLoading(false); + } + }; + const handleFileChange = async (selectedOption: FileOption | null) => { + setSelectedFile(selectedOption); + setDropDownOptions(selectedOption?.value); + setSearchText(''); + setFilterValue([]); + setFilterOption('all'); + setIsFilterApplied(false); + if (selectedOption) { + setTableUid((prevUid) => prevUid + 1); + } + }; + + const ColumnFilter = () => { + const closeModal = () => { + setIsFilterDropdownOpen(false); + }; + const openFilterDropdown = () => { + if (!isFilterDropdownOpen) { + setIsFilterDropdownOpen(true); + } + setIsFilterDropdownOpen(true); }; - const fetchTableData = async ({ - skip = 0, - limit = 30, - startIndex = 0, - stopIndex = 30, - searchText = 'null', - filter = filterOption - }) => { - if (!selectedStack || !selectedFile || !selectedOrganisation?.value) { - return { data: [], count: 0 }; - } - searchText = searchText === '' ? 'null' : searchText; - setLoading(true); - try { - const response = await getAuditData( - selectedOrganisation?.value, - params?.projectId ?? '', - selectedStack?.value, - selectedFile?.value, - skip, - limit, - startIndex, - stopIndex, - searchText, - filter - ); - if (response?.data) { - setTableData(response?.data?.data || []); - setTotalCounts(response?.data?.totalCount || 0); - return { - data: response?.data?.data || [], - count: response?.data?.totalCount || 0 - }; - } - return { data: [], count: 0 }; - } catch (error) { - console.error('Error fetching audit data:', error); - if (startIndex === 0) { - setTableData([]); - setTotalCounts(0); - } - return { data: [], count: 0 }; - } finally { - setLoading(false); + const iconProps = { + className: isFilterApplied + ? auditLogsConstants?.filterIcon?.filterOn + : auditLogsConstants?.filterIcon?.filterOff, + withTooltip: true, + tooltipContent: 'Filter', + tooltipPosition: 'left' + }; + // Method to update filter value + const updateValue = ({ value, isChecked }: { value: FilterOption; isChecked: boolean }) => { + try { + let filterValueCopy = [...filterValue]; + if (!filterValueCopy.length && isChecked) { + filterValueCopy.push(value); + } else if (isChecked) { + const updatedFilter = filterValueCopy.filter((v) => v?.value !== value?.value); + filterValueCopy = [...updatedFilter, value]; + } else if (!isChecked) { + filterValueCopy = filterValueCopy.filter((v) => v?.value !== value?.value); } + setFilterValue(filterValueCopy); + } catch (error) { + // console.error('Error updating filter value:', error); + } + }; + const handleClickOutside = () => { + if (!isCursorInside) { + closeModal && closeModal(); + } }; - const handleFileChange = async (selectedOption: FileOption | null) => { - setSelectedFile(selectedOption); - setDropDownOptions(selectedOption?.value); - setSearchText(''); - setFilterValue([]); - setFilterOption('all'); - setIsFilterApplied(false); - if (selectedOption) { - setTableUid((prevUid) => prevUid + 1); + const onApply = () => { + try { + if (!filterValue?.length) { + const newFilter = 'all'; + setFilterOption(newFilter); + fetchTableData({ filter: newFilter }); + closeModal(); + setIsFilterApplied(false); + return; } + const usersQueryArray = filterValue.map((item) => item.value); + const newFilter = + usersQueryArray?.length > 1 ? usersQueryArray.join('-') : usersQueryArray[0]; + setFilterOption(newFilter); + fetchTableData({ filter: newFilter }); + setIsFilterApplied(true); + closeModal(); + } catch (error) { + console.error('Error applying filter:', error); + } }; + useEffect(() => { + document.addEventListener('click', handleClickOutside, false); + return () => { + document.removeEventListener('click', handleClickOutside, false); + }; + }, [isCursorInside]); + return ( +
{ + setIsCursorInside(true); + }} + onMouseLeave={() => { + setIsCursorInside(false); + }}> +
+ ); + }; + const contentTypeHeader = [ + { + Header: 'Title', + accessor: (data: TableDataItem) => renderCell(data?.name), + addToColumnSelector: true, + disableSortBy: true + }, + { + Header: 'Field Name', + accessor: (data: TableDataItem) => renderCell(data?.display_name), + addToColumnSelector: true, + disableSortBy: true + }, + { + Header: 'Field Type', + accessor: (data: TableDataItem) => renderCell(data?.data_type), + addToColumnSelector: true, + disableSortBy: true, + filter: ColumnFilter + }, + { + Header: 'Missing Reference', + accessor: (data: TableDataItem) => { + const missing = Array.isArray(data?.missingRefs) + ? data.missingRefs.join(', ') + : typeof data?.missingRefs === 'string' + ? data?.missingRefs + : '-'; + return renderCell(missing, 1); + }, + addToColumnSelector: true, + disableSortBy: true + }, + { + Header: 'Tree Structure', + accessor: (data: TableDataItem) => renderCell(data?.treeStr), + addToColumnSelector: true, + disableSortBy: true + }, + { + Header: 'Fix Status', + accessor: (data: TableDataItem) => renderCell(data?.fixStatus), + addToColumnSelector: true, + disableSortBy: true + } + ]; + const entryHeader = [ + { + Header: 'Entry UID', + accessor: (data: TableDataItem) => renderCell(data?.uid), + addToColumnSelector: true, + disableSortBy: true, + disableResizing: false, + canDragDrop: true, + width: 350 + }, + { + Header: 'Name', + accessor: (data: TableDataItem) => renderCell(data?.name), + addToColumnSelector: true, + disableSortBy: true, + disableResizing: false, + canDragDrop: true, + width: 200 + }, + { + Header: 'Display Name', + accessor: (data: TableDataItem) => renderCell(data?.display_name), + addToColumnSelector: true, + disableSortBy: true + }, + { + Header: 'Display Type', + accessor: (data: TableDataItem) => renderCell(data?.display_type || data?.data_type), + addToColumnSelector: true, + disableSortBy: true, + filter: ColumnFilter + }, + { + Header: 'Missing Value', + cssClass: 'missing-val', + accessor: (data: TableDataItem) => { + if (data?.missingCTSelectFieldValues) { + return renderCell(data?.missingCTSelectFieldValues); + } + if (typeof data?.missingRefs === 'object' && data?.missingRefs) { + const ctUid = (data?.missingRefs as any)?.[0]?._content_type_uid; + if (Array.isArray(ctUid)) { + return renderCell(ctUid?.length > 0 ? ctUid?.join(', ') : null); + } else if (typeof ctUid === 'string') { + return renderCell(ctUid); + } + } + return renderCell(null); + }, + addToColumnSelector: true, + disableSortBy: true + }, + { + Header: 'Tree Structure', + width: 300, + accessor: (data: TableDataItem) => renderCell(data?.treeStr), + addToColumnSelector: true, + disableSortBy: true, + default: false, + cssClass: 'tree-struct' + } + ]; - const ColumnFilter = () => { - const closeModal = () => { - setIsFilterDropdownOpen(false); - }; - const openFilterDropdown = () => { - if (!isFilterDropdownOpen) { - setIsFilterDropdownOpen(true); - } - setIsFilterDropdownOpen(true); - }; - - const iconProps = { - className: isFilterApplied - ? auditLogsConstants?.filterIcon?.filterOn - : auditLogsConstants?.filterIcon?.filterOff, - withTooltip: true, - tooltipContent: 'Filter', - tooltipPosition: 'left' - }; - // Method to update filter value - const updateValue = ({ value, isChecked }: { value: FilterOption; isChecked: boolean }) => { - try { - let filterValueCopy = [...filterValue]; - if (!filterValueCopy.length && isChecked) { - filterValueCopy.push(value); - } else if (isChecked) { - const updatedFilter = filterValueCopy.filter((v) => v?.value !== value?.value); - filterValueCopy = [...updatedFilter, value]; - } else if (!isChecked) { - filterValueCopy = filterValueCopy.filter((v) => v?.value !== value?.value); - } - setFilterValue(filterValueCopy); - } catch (error) { - // console.error('Error updating filter value:', error); - } - }; - const handleClickOutside = () => { - if (!isCursorInside) { - closeModal && closeModal(); + const exportCtaComponent = ( +
+
+ +
+
+ ); + return ( +
+ setSearchText(value)} + withExportCta={{ + component: exportCtaComponent, + showExportCta: true + }} + customEmptyState={ + { - try { - if (!filterValue?.length) { - const newFilter = 'all'; - setFilterOption(newFilter); - fetchTableData({ filter: newFilter }); - closeModal(); - setIsFilterApplied(false); - return; - } - const usersQueryArray = filterValue.map((item) => item.value); - const newFilter = - usersQueryArray?.length > 1 ? usersQueryArray.join('-') : usersQueryArray[0]; - setFilterOption(newFilter); - fetchTableData({ filter: newFilter }); - setIsFilterApplied(true); - closeModal(); - } catch (error) { - console.error('Error applying filter:', error); + moduleIcon={ + searchText === '' + ? auditLogsConstants?.emptyStateIcon?.noLogs + : auditLogsConstants?.emptyStateIcon?.noMatch } - }; - useEffect(() => { - document.addEventListener('click', handleClickOutside, false); - return () => { - document.removeEventListener('click', handleClickOutside, false); - }; - }, [isCursorInside]); - return ( -
{ - setIsCursorInside(true); - }} - onMouseLeave={() => { - setIsCursorInside(false); - }}> -
- ); - }; - const contentTypeHeader = [ - { - Header: 'Title', - accessor: (data: TableDataItem) => renderCell(data?.name), - addToColumnSelector: true, - disableSortBy: true, - }, - { - Header: 'Field Name', - accessor: (data: TableDataItem) => renderCell(data?.display_name), - addToColumnSelector: true, - disableSortBy: true, - }, - { - Header: 'Field Type', - accessor: (data: TableDataItem) => renderCell(data?.data_type), - addToColumnSelector: true, - disableSortBy: true, - filter: ColumnFilter - }, - { - Header: 'Missing Reference', - accessor: (data: TableDataItem) => { - const missing = Array.isArray(data?.missingRefs) - ? data.missingRefs.join(', ') - : typeof data?.missingRefs === 'string' - ? data?.missingRefs - : '-'; - return renderCell(missing); - }, - addToColumnSelector: true, - disableSortBy: true, - }, - { - Header: 'Tree Structure', - accessor: (data: TableDataItem) => renderCell(data?.treeStr), - addToColumnSelector: true, - disableSortBy: true, - }, - { - Header: 'Fix Status', - accessor: (data: TableDataItem) => renderCell(data?.fixStatus), - addToColumnSelector: true, - disableSortBy: true, + type="secondary" + className="custom-empty-state" + /> } - ]; - const entryHeader = [ - { - Header: 'Entry UID', - accessor: (data: TableDataItem) => renderCell(data?.uid), - addToColumnSelector: true, - disableSortBy: true, - disableResizing: false, - canDragDrop: true, - width: 350 - }, - { - Header: 'Name', - accessor: (data: TableDataItem) => renderCell(data?.name), - addToColumnSelector: true, - disableSortBy: true, - disableResizing: false, - canDragDrop: true, - width: 200 - }, - { - Header: 'Display Name', - accessor: (data: TableDataItem) => renderCell(data?.display_name), - addToColumnSelector: true, - disableSortBy: true, - }, - { - Header: 'Display Type', - accessor: (data: TableDataItem) => renderCell(data?.display_type || data?.data_type), - addToColumnSelector: true, - disableSortBy: true, - filter: ColumnFilter - }, - { - Header: 'Missing Value', - cssClass: "missing-val", - accessor: (data: TableDataItem) => { - if (data?.missingCTSelectFieldValues) { - return renderCell(data?.missingCTSelectFieldValues); - } - if (typeof data?.missingRefs === 'object' && data?.missingRefs) { - const ctUid = (data?.missingRefs as any)?.[0]?._content_type_uid; - if (Array.isArray(ctUid)) { - return renderCell(ctUid?.length > 0 ? ctUid?.join(', ') : null); - } else if (typeof ctUid === 'string') { - return renderCell(ctUid); - } - } - return renderCell(null); - }, - addToColumnSelector: true, - disableSortBy: true, - }, - { - Header: 'Tree Structure', - width: 300, - accessor: (data: TableDataItem) => renderCell(data?.treeStr), - addToColumnSelector: true, - disableSortBy: true, - default: false, - cssClass: "tree-struct" - } - ]; - - const exportCtaComponent = ( -
-
- -
-
- ); - return ( -
- setSearchText(value)} - withExportCta={{ - component: exportCtaComponent, - showExportCta: true - }} - customEmptyState={ - - } - /> -
- ); -} -export default AuditLogs; \ No newline at end of file + /> +
+ ); +}; +export default AuditLogs; diff --git a/ui/src/components/Common/Modal/LogModal/LogModal.scss b/ui/src/components/Common/Modal/LogModal/LogModal.scss index eea1c767d..1a704224c 100644 --- a/ui/src/components/Common/Modal/LogModal/LogModal.scss +++ b/ui/src/components/Common/Modal/LogModal/LogModal.scss @@ -5,4 +5,11 @@ line-height: $line-height-reset; color: #3d3f4c; text-transform: capitalize; +} + +.log-modal { + word-break: break-word; + overflow-wrap: break-word ; + white-space: pre-wrap; + width: 100%; } \ No newline at end of file diff --git a/ui/src/components/Common/Modal/LogModal/LogModal.tsx b/ui/src/components/Common/Modal/LogModal/LogModal.tsx index a89960257..4d91ded88 100644 --- a/ui/src/components/Common/Modal/LogModal/LogModal.tsx +++ b/ui/src/components/Common/Modal/LogModal/LogModal.tsx @@ -16,7 +16,9 @@ export default function LogModal({ props, data }: LogModalProps) { {data?.methodName && (<>

Method Name: {data?.methodName}


)} -

{data?.message}

+
+

{data?.message}

+
); diff --git a/ui/src/components/ContentMapper/index.scss b/ui/src/components/ContentMapper/index.scss index 11d01fdc3..495799a5e 100644 --- a/ui/src/components/ContentMapper/index.scss +++ b/ui/src/components/ContentMapper/index.scss @@ -155,6 +155,9 @@ .Table__body__column { padding: 0 1.25rem; } + .Table-select-body { + width: 68px; + } .cms-field { // text-transform: capitalize; // overflow: hidden;