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
6 changes: 6 additions & 0 deletions api/src/controllers/projects.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,11 @@ const updateMigrationExecution = async (req: Request, res: Response): Promise<vo
res.status(project.status).json(project);
}

const getMigratedStacks = async (req: Request, res: Response): Promise<void> => {
const project = await projectService.getMigratedStacks(req);
res.status(project.status).json(project);
}

export const projectController = {
getAllProjects,
getProject,
Expand All @@ -187,4 +192,5 @@ export const projectController = {
revertProject,
updateStackDetails,
updateMigrationExecution,
getMigratedStacks,
};
2 changes: 2 additions & 0 deletions api/src/routes/projects.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,4 +80,6 @@ router.patch("/:projectId/stack-details", asyncRouter(projectController.updateSt
//update migration execution key
router.put("/:projectId/migration-excution",asyncRouter(projectController.updateMigrationExecution));

router.get("/:projectId/get-migrated-stacks", asyncRouter(projectController.getMigratedStacks))

export default router;
48 changes: 47 additions & 1 deletion api/src/services/projects.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1212,6 +1212,51 @@ const updateMigrationExecution = async (req: Request) => {
};


/**
* get the destination_stack_id of completed projects.
*
* @param req - The request object containing the parameters and body.
* @returns An object with the status and data of the update operation.
* @throws ExceptionFunction if an error occurs during the process.
*/
const getMigratedStacks = async(req: Request) => {

const { token_payload } = req.body;
const srcFunc = "getMigratedStacks";

try {
await ProjectModelLowdb.read();
const projects = ProjectModelLowdb.data?.projects || [];

// Map through projects to extract `destinationstack` key
const destinationStacks = projects.filter((project: any) => project?.status === 5 && project.current_step === 5)
.map((project: any) => project.destination_stack_id);

return {
status: HTTP_CODES.OK,
destinationStacks
};

} catch (error:any) {
// Log error message
logger.error(
getLogMessage(
srcFunc,
"Error occurred while while getting all destinationstack id's of projects",
token_payload,
error
)
);

// Throw a custom exception with the error details
throw new ExceptionFunction(
error?.message || HTTP_TEXTS.INTERNAL_ERROR,
error?.statusCode || error?.status || HTTP_CODES.SERVER_ERROR
);

}

}

export const projectService = {
getAllProjects,
Expand All @@ -1229,5 +1274,6 @@ export const projectService = {
revertProject,
updateStackDetails,
updateContentMapper,
updateMigrationExecution
updateMigrationExecution,
getMigratedStacks
};
4 changes: 4 additions & 0 deletions ui/src/components/Common/Card/card.scss
Original file line number Diff line number Diff line change
Expand Up @@ -148,4 +148,8 @@
p {
color: $color-stepper-title;
}
}
.Card__disabled{
cursor: not-allowed;
opacity: .5;
}
7 changes: 4 additions & 3 deletions ui/src/components/Common/Card/card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ type CardProps = {
onCardClick?: (T: any) => unknown;
selectedCard: any;
cardType?: string;
disabled: boolean;
};

/**
Expand All @@ -25,7 +26,7 @@ type CardProps = {
* @param cardType - The type of the card.
* @param idField - The field name for the card's ID. Defaults to 'id'.
*/
const Card = ({ data, selectedCard, onCardClick, cardType, idField = 'id' }: CardProps) => {
const Card = ({ data, selectedCard, onCardClick, cardType, idField = 'id',disabled }: CardProps) => {
const imgStyle = {
width: cardType === 'legacyCMS' ? '60px' : '46px',
height: cardType === 'legacyCMS' ? '60px' : '46px'
Expand All @@ -51,9 +52,9 @@ const Card = ({ data, selectedCard, onCardClick, cardType, idField = 'id' }: Car
<div
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
className={`connector_list ${cardType === 'legacyCMS' ? 'trigger_list' : ''}`}
className={`connector_list ${cardType === 'legacyCMS' ? 'trigger_list' : ''} ${disabled ? 'Card__disabled' : ''} `}
style={{ position: 'relative' }}
onClick={handleClick}
onClick={!disabled ? handleClick : undefined}
>
{data.description && (
<div style={{ position: 'absolute' }}>
Expand Down
12 changes: 8 additions & 4 deletions ui/src/components/DestinationStack/Actions/LoadStacks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
const newMigrationData = useSelector((state:RootState)=>state?.migration?.newMigrationData);
const selectedOrganisation = useSelector((state:RootState)=>state?.authentication?.selectedOrganisation);
const dispatch = useDispatch();

/**** ALL UseStates HERE ****/
const [selectedStack, setSelectedStack] = useState<IDropDown | null>(
null
Expand All @@ -61,7 +62,8 @@ const LoadStacks = (props: LoadFileFormatProps) => {
default: false,
master_locale: '',
locales: [],
created_at: ''
created_at: '',
disabled: false,
}
];
const [allStack, setAllStack] = useState<IDropDown[]>(newMigrationData?.destination_stack?.stackArray);
Expand Down Expand Up @@ -106,7 +108,8 @@ const LoadStacks = (props: LoadFileFormatProps) => {
locales: resp?.data?.stack?.locales,
created_at: resp?.data?.stack?.created_at,
uid: resp?.data?.stack?.api_key,
isNewStack: true
isNewStack: true,
isDisabled: false,
};

setSelectedStack(newCreatedStack);
Expand Down Expand Up @@ -183,7 +186,7 @@ const LoadStacks = (props: LoadFileFormatProps) => {
if (allStack?.length <= 0) {
setAllStack(loadingOption);
const stackData = await getAllStacksInOrg(selectedOrganisation?.value, ''); // org id will always be there

const stackArray = validateArray(stackData?.data?.stacks)
? stackData?.data?.stacks?.map((stack: StackResponse) => ({
label: stack?.name,
Expand All @@ -192,7 +195,8 @@ const LoadStacks = (props: LoadFileFormatProps) => {
master_locale: stack?.master_locale,
locales: stack?.locales,
created_at: stack?.created_at,
isNewStack: newStackCreated
isNewStack: newStackCreated,
isDisabled: newMigrationDataRef?.current?.destination_stack?.migratedStacks?.includes(stack?.api_key),
}))
: [];

Expand Down
3 changes: 2 additions & 1 deletion ui/src/components/LegacyCms/Actions/LoadSelectCms.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => {
}
};

dispatch(updateNewMigrationData(newMigrationDataObj));
//dispatch(updateNewMigrationData(newMigrationDataObj));

setCmsData(filteredCmsData)

Expand Down Expand Up @@ -205,6 +205,7 @@ const LoadSelectCms = (props: LoadSelectCmsProps) => {
onCardClick={data?.cms_id !== selectedCard?.cms_id ? handleCardClick : undefined}
selectedCard={selectedCard}
idField="cms_id"
disabled={newMigrationData?.project_current_step > 1}
/>
))}
</div>))
Expand Down
5 changes: 5 additions & 0 deletions ui/src/components/LogScreen/MigrationLogViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,11 @@ const MigrationLogViewer = ({ serverPath }: LogsType) => {
const message = logObject.message;

return (
newMigrationData?.destination_stack?.migratedStacks?.includes(newMigrationData?.destination_stack?.selectedStack?.value) ?
<div key={`${index?.toString}`} style={logStyles[level] || logStyles.info} className="log-entry text-center">
<div className="log-message">Migration has already done in selected stack. Please create a new project.</div>
</div>
:
message === "Migration logs will appear here once the process begins."
? <div key={`${index?.toString}`} style={logStyles[level] || logStyles.info} className="log-entry text-center">
<div className="log-message">{message}</div>
Expand Down
4 changes: 3 additions & 1 deletion ui/src/components/MigrationFlowHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ const MigrationFlowHeader = ({projectData, handleOnClick, isLoading, finalExecut
finalExecutionStarted ||
newMigrationData?.migration_execution?.migrationStarted || newMigrationData?.migration_execution?.migrationCompleted;

const destinationStackMigrated = params?.stepId === '5' && newMigrationData?.destination_stack?.migratedStacks?.includes(newMigrationData?.destination_stack?.selectedStack?.value);

return (
<div className='d-flex align-items-center justify-content-between migration-flow-header'>
<div className='d-flex align-items-center'>
Expand All @@ -96,7 +98,7 @@ const MigrationFlowHeader = ({projectData, handleOnClick, isLoading, finalExecut
version="v2"
aria-label='Save and Continue'
isLoading={isLoading || newMigrationData?.isprojectMapped}
disabled={isStep4AndNotMigrated || isStepInvalid || isExecutionStarted}
disabled={isStep4AndNotMigrated || isStepInvalid || isExecutionStarted || destinationStackMigrated}
>
{stepValue}
</Button>
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/Modal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const Modal = (props: ProjectModalProps) => {
return 'Project name is required.';
} else if (!/^[^\s].*$/.test(value)) {
setInputValue(false);
return 'Please enter a valid project name.';
//return 'Please enter a valid project name.';
} else {
setInputValue(true);
}
Expand Down
2 changes: 1 addition & 1 deletion ui/src/components/ProjectsHeader/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const ProjectsHeader = ({
placeholder={searchPlaceholder}
type="secondary"
onChange={(search: string) =>{
setSearchText(search)}
search.trim()?.length > 0 ? setSearchText(search?.trim()) : setSearchText(search)}
}
width="large"
onClear={true}
Expand Down
7 changes: 6 additions & 1 deletion ui/src/context/app/app.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ export interface IDestinationStack {
selectedOrg: IDropDown;
selectedStack: IDropDown;
stackArray: IDropDown[];
migratedStacks: string[];

}
export interface IContentMapper {
existingGlobal: ContentTypeList[] | (() => ContentTypeList[]);
Expand Down Expand Up @@ -220,6 +222,7 @@ export interface IDropDown {
locales: locales[];
created_at: string;
isNewStack?: boolean;
isDisabled?:boolean;
}
export interface ITestMigration {
stack_link: string;
Expand Down Expand Up @@ -258,7 +261,8 @@ export const DEFAULT_DROPDOWN: IDropDown = {
master_locale: '',
locales: [],
created_at: '',
isNewStack: false
isNewStack: false,
isDisabled: false,
};

export const DEFAULT_ORGANISATION: Organization = {
Expand Down Expand Up @@ -330,6 +334,7 @@ export const DEFAULT_DESTINATION_STACK: IDestinationStack = {
selectedOrg: DEFAULT_DROPDOWN,
selectedStack: DEFAULT_DROPDOWN,
stackArray: [],
migratedStacks: [],
};

export const DEFAULT_CONTENT_MAPPER: IContentMapper = {
Expand Down
6 changes: 5 additions & 1 deletion ui/src/pages/Migration/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import ContentMapper from '../../components/ContentMapper';
import TestMigration from '../../components/TestMigration';
import MigrationExecution from '../../components/MigrationExecution';
import SaveChangesModal from '../../components/Common/SaveChangesModal';
import { getMigratedStacks } from '../../services/api/project.service';

type StepperComponentRef = {
handleStepChange: (step: number) => void;
Expand Down Expand Up @@ -161,6 +162,8 @@ const Migration = () => {
if (isEmptyString(selectedOrganisation?.value) || isEmptyString(params?.projectId)) return;

const data = await getMigrationData(selectedOrganisation?.value, params?.projectId ?? '');
const migratedstacks = await getMigratedStacks(selectedOrganisation?.value, projectId );

if (data) {
setIsLoading(false);
setProjectData(data?.data);
Expand Down Expand Up @@ -229,7 +232,8 @@ const Migration = () => {
destination_stack: {
selectedOrg: selectedOrganisationData,
selectedStack: selectedStackData,
stackArray:[]
stackArray:[],
migratedStacks: migratedstacks?.data?.destinationStacks,
},
content_mapping: {
isDropDownChanged: false,
Expand Down
12 changes: 12 additions & 0 deletions ui/src/services/api/project.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,15 @@ export const deleteProject = async (orgId: string, projectId: string) => {
}
}
};

export const getMigratedStacks = async (orgId: string, projectId: string) => {
try {
return await getCall(`${API_VERSION}/org/${orgId}/project/${projectId}/get-migrated-stacks`, options());
} catch (error) {
if (error instanceof Error) {
throw new Error(`Error in userSession: ${error.message}`);
} else {
throw new Error('Unknown error in userSession');
}
}
};
Loading