Conversation
… array safety checks and improving variable handling for better reliability
…igration-v2 into feature/wordpress
… array access and enhancing variable handling
Feature/wordpress
…and configuration files, enhancing build process and performance. Remove deprecated files and adjust API references to align with new structure. Co-authored-by: Cursor <cursoragent@cursor.com>
…s; adjust .gitignore and package.json to include new dependencies and ensure proper environment variable handling
refactor: migrate from CRA to Vite by updating environment variables …
…nt for improved user experience
fix: update button loading state and default text in AddStack compone…
…e fallback to DEFAULT_CMS_TYPE
fix: update default CMS type handling in Migration component to ensur…
- Fix safePromise destructuring in getExistingContentTypes and getExistingGlobalFields that silently discarded API responses, preventing destination CT merge entirely - Always emit modular block schema from buildFieldSchema even with no child blocks, so mergeTwoCts can append destination blocks - Add oldFieldUid fallback to mbChildren filter in buildSchemaTree so renamed parent blocks still find child blocks using the original UID prefix
fix: resolve modular block merge failures during CT mapping
…erties and update dependencies.
feat: Hide mandatory toggle for Taxonomy field types in advanced prop…
There was a problem hiding this comment.
Pull request overview
This PR migrates the UI from Create React App to Vite and makes several configuration and bug fixes across the codebase.
Changes:
- Migrates UI build tooling from Create React App to Vite, including environment variable migration (REACT_APP_* to VITE_*)
- Replaces meaningful default configuration values in upload-api with placeholder strings
- Fixes several bugs: array handling in WordPress locale extraction, TypeScript timeout typing, button prop naming, error handling in API services, and taxonomy field type handling
Reviewed changes
Copilot reviewed 24 out of 29 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| upload-api/src/config/index.ts | Replaces working default values with placeholder strings that may break functionality |
| upload-api/package.json | Moves eslint to devDependencies and fixes build script to handle migration folders without package.json |
| upload-api/migration-wordpress/libs/extractLocale.ts | Fixes array handling to support single-item RSS feeds |
| ui/vite.config.ts | Introduces Vite configuration with custom logger to suppress SCSS warnings |
| ui/tsconfig.json | Updates TypeScript config for Vite (ESNext target/module, vite/client types) |
| ui/src/utilities/constants.ts | Migrates all environment variables from REACT_APP_* to VITE_* prefix and adds Drupal documentation URL |
| ui/package.json | Removes react-scripts and web-vitals, adds Vite and related plugins |
| ui/Dockerfile | Changes to build at container startup instead of during image creation |
| ui/index.html | Updates paths from %PUBLIC_URL% to root-relative and adds module script tag |
| ui/src/pages/Migration/index.tsx | Simplifies CMS selection logic, removing config precedence checking |
| ui/src/components/LegacyCms/Actions/LoadUploadFile.tsx | Extensive formatting changes and improves SQL validation error messaging |
| ui/src/components/ContentMapper/index.tsx | Fixes setTimeout return type to use ReturnType |
| ui/src/components/Common/AddStack/addStack.tsx | Fixes button prop from 'loading' to 'isLoading' and adds fallback button text |
| ui/src/components/AdvancePropertise/index.tsx | Excludes Taxonomy fields from Mandatory toggle option |
| api/src/utils/content-type-creator.utils.ts | Removes empty block filtering and adds backup UID checking for modular blocks |
| api/src/services/contentMapper.service.ts | Improves error handling by checking err before accessing response |
| docker-compose.yml | Updates environment variables from REACT_APP_* to VITE_* prefix |
| index.js | Updates environment template from REACT_APP_* to VITE_* prefix |
Files not reviewed (3)
- api/package-lock.json: Language not supported
- upload-api/migration-aem/package-lock.json: Language not supported
- upload-api/package-lock.json: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| base_url: process.env.DRUPAL_ASSETS_BASE_URL || 'drupal_assets_base_url', // Dynamic: Can be any domain, with/without trailing slash | ||
| public_path: process.env.DRUPAL_ASSETS_PUBLIC_PATH || 'drupal_assets_public_path' // Dynamic: Can be any path, with/without slashes |
There was a problem hiding this comment.
The placeholder values 'drupal_assets_base_url' and 'drupal_assets_public_path' are not valid URLs or paths. The previous defaults ('https://www.rice.edu/' and 'sites/g/files/bxs2566/files') were actual working examples. Using placeholder text like this could cause runtime errors if these values are used without proper environment variable configuration. Consider reverting to the previous example values or using empty strings.
| base_url: process.env.DRUPAL_ASSETS_BASE_URL || 'drupal_assets_base_url', // Dynamic: Can be any domain, with/without trailing slash | |
| public_path: process.env.DRUPAL_ASSETS_PUBLIC_PATH || 'drupal_assets_public_path' // Dynamic: Can be any path, with/without slashes | |
| base_url: process.env.DRUPAL_ASSETS_BASE_URL || '', // Dynamic: Can be any domain, with/without trailing slash | |
| public_path: process.env.DRUPAL_ASSETS_PUBLIC_PATH || '' // Dynamic: Can be any path, with/without slashes |
| const selectedCmsData: ICMSType = | ||
| (storedCmsData && storedCmsData?.parent?.toLowerCase() === configCmsType) | ||
| ? storedCmsData | ||
| : (configCmsData ?? storedCmsData ?? DEFAULT_CMS_TYPE); | ||
| storedCmsData ?? DEFAULT_CMS_TYPE; |
There was a problem hiding this comment.
The logic for determining selectedCmsData has been simplified, removing the fallback to configCmsData and the parent matching logic. This change means that if storedCmsData is undefined, it will always fall back to DEFAULT_CMS_TYPE, ignoring the config's cmsType completely. The previous logic preserved config precedence when the CMS type changed. This could cause unexpected behavior when config.cmsType doesn't match the stored project CMS. Consider whether this simplification is intentional or if the parent matching logic should be preserved.
| # Build at container startup so VITE_* env vars from docker-compose | ||
| CMD [ "sh", "-c", "npm run build && npx vite preview --port 3000 --host" ] No newline at end of file |
There was a problem hiding this comment.
Building at container startup is problematic for production deployments. This approach means: 1) Every container restart rebuilds the entire application, increasing startup time significantly, 2) Build tools and source code remain in the production image, increasing image size and attack surface, 3) Build failures at runtime are harder to detect than at image build time. Consider building during the Docker image creation (before CMD) and using a multi-stage build to separate build dependencies from the runtime image.
| return { | ||
| data_type: "blocks", | ||
| display_name: item?.display_name || rawUid, // Keep original for display | ||
| field_metadata: {}, | ||
| uid: itemUid, // Snake case uid | ||
| multiple: true, | ||
| mandatory: false, | ||
| unique: false, | ||
| non_localizable: false, | ||
| blocks: removeDuplicateFields(blocks) | ||
| }; |
There was a problem hiding this comment.
The early return with null has been removed. Previously, if blocks array was empty after processing, the function returned null. Now it always returns a modular_blocks field structure, even with an empty blocks array. This could create modular block fields with no blocks, which may not be valid in Contentstack. Consider whether this change is intentional or if the null check should be restored.
| dropdown: { optionLimit: 100 } | ||
| }, | ||
| cmsType: process.env.CMS_TYPE || 'drupal', | ||
| cmsType: process.env.CMS_TYPE || 'cmsType', |
There was a problem hiding this comment.
The default value 'cmsType' is not a valid CMS type. Based on the codebase (upload-api/src/services/createMapper.ts lines 96-118), valid CMS types are: 'sitecore', 'contentful', 'wordpress', 'aem', 'drupal'. The previous default was 'drupal' which was a valid value. Consider using 'drupal' or another valid CMS type as the default, or use an empty string to force explicit configuration.
| cmsType: process.env.CMS_TYPE || 'cmsType', | |
| cmsType: process.env.CMS_TYPE || 'drupal', |
| host: 'host_name', | ||
| user: 'user_name', | ||
| password: '', | ||
| database: 'riceuniversity1', | ||
| port: '3306' | ||
| database: 'database_name', | ||
| port: 'port_number' |
There was a problem hiding this comment.
These placeholder values (host_name, user_name, database_name, port_number) are not meaningful defaults. The previous values (localhost, root, riceuniversity1, 3306) were more useful as they represented a typical development MySQL configuration. Consider reverting to the previous values or using empty strings to indicate these must be configured.
| public_path: process.env.DRUPAL_ASSETS_PUBLIC_PATH || 'drupal_assets_public_path' // Dynamic: Can be any path, with/without slashes | ||
| }, | ||
| localPath: process.env.CONTAINER_PATH || 'sql' | ||
| localPath: process.env.CONTAINER_PATH || 'localPath' |
There was a problem hiding this comment.
The placeholder value 'localPath' is not a valid path. The previous default 'sql' was meaningful as it indicated SQL/MySQL connection mode. Using 'localPath' as both the property name and its value is confusing and may cause issues when this configuration is used. Consider reverting to 'sql' or using an empty string.
| localPath: process.env.CONTAINER_PATH || 'localPath' | |
| localPath: process.env.CONTAINER_PATH || '' |
| blocks.push({ | ||
| title: blockRawUid, // Keep original for title | ||
| uid: blockUid, // Snake case for uid | ||
| schema: removeDuplicateFields(blockSchema) |
There was a problem hiding this comment.
Empty blocks are now always pushed to the blocks array, even when blockSchema is empty. This could result in modular blocks with empty schemas being created. The previous logic filtered out blocks with no fields. Consider whether empty blocks should be allowed or if the length check should be restored.
| blocks.push({ | |
| title: blockRawUid, // Keep original for title | |
| uid: blockUid, // Snake case for uid | |
| schema: removeDuplicateFields(blockSchema) | |
| const cleanedBlockSchema = removeDuplicateFields(blockSchema); | |
| if (!cleanedBlockSchema || cleanedBlockSchema.length === 0) { | |
| continue; | |
| } | |
| blocks.push({ | |
| title: blockRawUid, // Keep original for title | |
| uid: blockUid, // Snake case for uid | |
| schema: cleanedBlockSchema |
No description provided.