Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 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