Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions api/src/services/migration.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -986,13 +986,14 @@ const getLogs = async (req: Request): Promise<any> => {
}
if (fs.existsSync(absolutePath)) {
let index = 0;
const logs = await fs.promises.readFile(absolutePath, "utf8");
const logs = await fs?.promises?.readFile?.(absolutePath, "utf8");
let logEntries = logs
?.split("\n")
?.map((line) => {
try {
const parsedLine = JSON?.parse(line)
parsedLine['id'] = index;
parsedLine && (parsedLine['id'] = index);

++index;
return parsedLine ? parsedLine : null;
} catch (error) {
Expand Down
33 changes: 3 additions & 30 deletions api/src/services/runCli.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,9 @@ const determineLogLevel = (text: string): string => {
* Strips ANSI color codes from text to create clean logs
*/
const stripAnsiCodes = (text: string): string => {
const ESC = '\u001b';
// This regex removes all ANSI escape sequences (color codes)
return text.replace(/\u001b\[\d+m/g, '');
return text?.replace(new RegExp(`${ESC}\\[[0-9;]*m`, 'g'), '');
};

/**
Expand Down Expand Up @@ -206,34 +207,6 @@ export const runCli = async (
// Debug which log path is being used
console.info(`Log path for CLI commands: ${transformePath}`);

// Test writing all log levels directly to the file
try {
const testLogs = [
{
level: 'info',
message: 'TEST INFO LOG',
timestamp: new Date().toISOString(),
},
{
level: 'warn',
message: 'TEST WARNING LOG',
timestamp: new Date().toISOString(),
},
{
level: 'error',
message: 'TEST ERROR LOG',
timestamp: new Date().toISOString(),
},
];

for (const log of testLogs) {
fs.appendFileSync(transformePath, JSON.stringify(log) + '\n');
}
console.info('Test logs written successfully');
} catch (err) {
console.error('Failed to write test logs:', err);
}

// Make sure to set the global.currentLogFile to the project log file
// This is the key part - setting the log file path to the migration service log file
await setLogFilePath(transformePath);
Expand Down Expand Up @@ -377,4 +350,4 @@ export const runCli = async (
}
};

export const utilsCli = { runCli };
export const utilsCli = { runCli };
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import { Button, Checkbox, Icon, Radio, Search, Tooltip } from '@contentstack/ve
import React, { useEffect, useState } from 'react';

import WordWrapper from '../../WordWrapper/WordWrapper';
import { IFilterStatusType, IFilterType } from './filterModal.interface';

import './FilterModal.scss';
import { IFilterStatusType, IFilterType } from './filterModal.interface';

/**
* Props for the FilterModal component.
Expand Down
8 changes: 8 additions & 0 deletions ui/src/components/Common/Modal/LogModal/LogModal.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
@import '../../../../scss/variables';

.text {
font-size: $size-font-medium;
line-height: $line-height-reset;
color: #3d3f4c;
text-transform: capitalize;
}
23 changes: 23 additions & 0 deletions ui/src/components/Common/Modal/LogModal/LogModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ModalBody, ModalHeader } from '@contentstack/venus-components'
import { LogEntry } from '../../../ExecutionLogs/executionlog.interface';
import './LogModal.scss'

interface LogModalProps {
readonly props: {
closeModal: () => void;
};
readonly data: LogEntry;
}

export default function LogModal({ props, data }: LogModalProps) {
return (
<>
<ModalHeader title={data?.level} closeModal={props?.closeModal} closeIconTestId="cs-default-header-close" className='text'/>

<ModalBody className="modalBodyCustomClass">
{data?.methodName && (<><h3>Method Name: {data?.methodName}</h3><br /></>)}
<p className='text'>{data?.message}</p>
</ModalBody>
</>
);
}
6 changes: 5 additions & 1 deletion ui/src/components/Common/Settings/Settings.scss
Original file line number Diff line number Diff line change
Expand Up @@ -114,4 +114,8 @@
.back-button {
cursor: pointer;
margin-bottom: 20px;
}
}

.PageLayout--primary--v2 .PageLayout__body--left-drawer {
display: none;
}
72 changes: 42 additions & 30 deletions ui/src/components/Common/Settings/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { useSelector } from 'react-redux';
import { useSelector, useDispatch } from 'react-redux';
import { Params, useNavigate, useParams } from 'react-router';
import {
Icon,
Expand Down Expand Up @@ -31,9 +31,8 @@ import DeleteProjectModal from '../DeleteProjectModal';

//stylesheet
import './Settings.scss';
import { useDispatch } from 'react-redux';
import { updateNewMigrationData } from '../../../store/slice/migrationDataSlice';
import { DEFAULT_NEW_MIGRATION } from '../../../context/app/app.interface';
import { DEFAULT_NEW_MIGRATION, INewMigration } from '../../../context/app/app.interface';
import ExecutionLog from '../../../components/ExecutionLogs';
import AuditLogs from '../../AuditLogs';

Expand All @@ -45,16 +44,19 @@ const Settings = () => {
const params: Params<string> = useParams();

const [cmsData, setCmsData] = useState<Setting>();
const [active, setActive] = useState<string>();
const [currentHeader, setCurrentHeader] = useState<string>();
const [projectName, setProjectName] = useState('');
const [projectId, setProjectId] = useState('');

const [projectDescription, setProjectDescription] = useState('');

const selectedOrganisation = useSelector(
(state: RootState) => state?.authentication?.selectedOrganisation
);

const newMigrationData = useSelector((state: RootState) => state?.migration?.newMigrationData);

const active_state = newMigrationData?.settings?.active_state;

const currentStep = useSelector(
(state: RootState) => state?.migration?.newMigrationData?.project_current_step
);
Expand All @@ -68,7 +70,6 @@ const Settings = () => {
getCMSDataFromFile(CS_ENTRIES.SETTING)
.then((data) => {
setCmsData(data);
setActive(data?.project?.title);
setCurrentHeader(data?.project?.title);
})
.catch((err) => {
Expand All @@ -84,7 +85,6 @@ const Settings = () => {
if (status === HTTP_CODES.OK) {
setProjectName(data?.name);
setProjectDescription(data?.description);
setProjectId(params?.projectId ?? '');
}
};

Expand Down Expand Up @@ -133,13 +133,11 @@ const Settings = () => {
};

const handleDeleteProject = async (closeModal: () => void): Promise<void> => {
//setIsLoading(true);
const response = await deleteProject(selectedOrganisation?.value, params?.projectId ?? '');

if (response?.status === HTTP_CODES.OK) {
//setIsLoading(false);
if (response?.status === HTTP_CODES?.OK) {
closeModal();
dispatch(updateNewMigrationData(DEFAULT_NEW_MIGRATION));
dispatch(updateNewMigrationData(newMigrationData));
setTimeout(() => {
navigate('/projects');
}, 800);
Expand All @@ -158,7 +156,8 @@ const Settings = () => {

const handleBack = () => {
navigate(`/projects/${params?.projectId}/migration/steps/${currentStep}`);
}
dispatch(updateNewMigrationData({...newMigrationData, settings: DEFAULT_NEW_MIGRATION?.settings }));
};

const handleClick = () => {
cbModal({
Expand Down Expand Up @@ -207,7 +206,7 @@ const Settings = () => {
const content = {
component: (
<div>
{active === cmsData?.project?.title && (
{active_state === cmsData?.project?.title && (
<div className="content-block">
<div data-test-id="cs-stack-setting-general" className="stack-settings__heading">
{cmsData?.project?.general}
Expand Down Expand Up @@ -261,13 +260,8 @@ const Settings = () => {
</div>
</div>
)}
{active === cmsData?.execution_logs?.title && (
<ExecutionLog projectId={projectId} />
)}
{active === cmsData?.audit_logs?.title &&
<AuditLogs />

}
{active_state === cmsData?.execution_logs?.title && <ExecutionLog />}
{active_state === cmsData?.audit_logs?.title && <AuditLogs />}
</div>
)
};
Expand All @@ -291,42 +285,60 @@ const Settings = () => {
withTooltip={true}
tooltipContent={'Back'}
tooltipPosition="right"
className='back-button'
className="back-button"
/>
</div>
{cmsData?.title}
</div>

<ListRow
rightArrow={true}
active={active === cmsData?.project?.title}
active={active_state === cmsData?.project?.title}
content={cmsData?.project?.title}
leftIcon={<Icon icon="Stacks" version="v2" />}
onClick={() => {
setActive(cmsData?.project?.title);
setCurrentHeader(cmsData?.project?.title);
const activeTabState: INewMigration = {
...newMigrationData,
settings: {
active_state: cmsData?.project?.title ?? ''
}
};
dispatch(updateNewMigrationData(activeTabState));
}}
version="v2"
/>

<ListRow
rightArrow={true}
active={active === cmsData?.execution_logs?.title}
active={active_state === cmsData?.execution_logs?.title}
content={cmsData?.execution_logs?.title}
leftIcon={<Icon icon="ExecutionLog" version="v2" />}
onClick={() => {
setActive(cmsData?.execution_logs?.title);
setCurrentHeader(cmsData?.execution_logs?.title);
const activeTabState: INewMigration = {
...newMigrationData,
settings: {
active_state: cmsData?.execution_logs?.title ?? ''
}
};
dispatch(updateNewMigrationData(activeTabState));
}}
version="v2"
/>
<ListRow
rightArrow={true}
active={active === cmsData?.audit_logs?.title}
active={active_state === cmsData?.audit_logs?.title}
content={cmsData?.audit_logs?.title}
leftIcon={<Icon icon="Stacks" version="v2" />}
onClick={() => {
setActive(cmsData?.audit_logs?.title);
const activeTabState: INewMigration = {
...newMigrationData,
settings: {
active_state: cmsData?.audit_logs?.title ?? ''
}
};
dispatch(updateNewMigrationData(activeTabState));
setCurrentHeader(cmsData?.audit_logs?.title);
}}
version="v2"
Expand All @@ -338,18 +350,18 @@ const Settings = () => {
const header = {
component: (
<div>
{active === cmsData?.project?.title ? (
{active_state === cmsData?.project?.title ? (
<PageHeader
testId="header"
className="action-component-title"
title={{ label: currentHeader }}
title={{ label: active_state }}
actions={pageActions}
/>
) : (
<PageHeader
testId="header"
className="action-component-title"
title={{ label: currentHeader }}
title={{ label: active_state }}
/>
)}
</div>
Expand Down
Loading