diff --git a/.gitignore b/.gitignore index 361669648..7504567ef 100644 --- a/.gitignore +++ b/.gitignore @@ -351,4 +351,7 @@ MigrationBackup/ uploade-api/node_modules uploade-api/build -package-lock.json \ No newline at end of file +package-lock.json +ui/.env +uplaode-api/sitecoreMigrationData +uplaode-api/extracted_files diff --git a/api/example.env b/api/example.env deleted file mode 100644 index 7879b26de..000000000 --- a/api/example.env +++ /dev/null @@ -1,5 +0,0 @@ -PORT= -APP_TOKEN_KEY= -MONGODB_URI= -UPLOAD_BUCKET= -AWS_REGION= \ No newline at end of file diff --git a/api/src/constants/index.ts b/api/src/constants/index.ts index 775ced39e..6e02edc21 100644 --- a/api/src/constants/index.ts +++ b/api/src/constants/index.ts @@ -72,6 +72,10 @@ export const HTTP_TEXTS = { "Sorry, the requested content mapper id does not exists.", ADMIN_LOGIN_ERROR: "Sorry, You Don't have admin access in any of the Organisation", + PROJECT_DELETE: + "Project Deleted Successfully", + PROJECT_REVERT: + "Project Reverted Successfully" }; export const HTTP_RESPONSE_HEADERS = { diff --git a/api/src/controllers/projects.controller.ts b/api/src/controllers/projects.controller.ts index b2b89b08b..223254c94 100644 --- a/api/src/controllers/projects.controller.ts +++ b/api/src/controllers/projects.controller.ts @@ -59,6 +59,11 @@ const deleteProject = async (req: Request, res: Response): Promise => { res.status(200).json(project); }; +const revertProject = async (req: Request, res: Response): Promise => { + const project = await projectService.revertProject(req); + res.status(project.status).json(project); +}; + export const projectController = { getAllProjects, getProject, @@ -72,4 +77,5 @@ export const projectController = { updateDestinationStack, updateCurrentStep, deleteProject, + revertProject }; diff --git a/api/src/database.ts b/api/src/database.ts index 0f4d162cd..859a3b0eb 100644 --- a/api/src/database.ts +++ b/api/src/database.ts @@ -4,6 +4,7 @@ import fs from "fs"; const connectToDatabase = async () => { try { + //check if the database folder exists if (!fs.existsSync("./database")) { fs.mkdirSync("./database"); } diff --git a/api/src/models/project-lowdb.ts b/api/src/models/project-lowdb.ts index bf413d59c..c7fb3c394 100644 --- a/api/src/models/project-lowdb.ts +++ b/api/src/models/project-lowdb.ts @@ -41,6 +41,7 @@ interface Project { execution_log: [ExecutionLog]; created_at: string; updated_at: string; + isDeleted: boolean; } interface ProjectDocument { diff --git a/api/src/routes/projects.routes.ts b/api/src/routes/projects.routes.ts index 7450e467b..2cca80ab5 100644 --- a/api/src/routes/projects.routes.ts +++ b/api/src/routes/projects.routes.ts @@ -68,4 +68,7 @@ router.put( // Delete a project route router.delete("/:projectId", asyncRouter(projectController.deleteProject)); +//revert Project Route +router.patch("/:projectId", asyncRouter(projectController.revertProject)) + export default router; diff --git a/api/src/services/contentMapper.service.ts b/api/src/services/contentMapper.service.ts index 6076dd4ff..3c5fa1ec6 100644 --- a/api/src/services/contentMapper.service.ts +++ b/api/src/services/contentMapper.service.ts @@ -34,7 +34,7 @@ const putTestData = async (req: Request) => { return { id, isDeleted: true, ...field }; }); FieldMapperModel.update((data: any) => { - data.field_mapper = [...data?.field_mapper, ...fields]; + data.field_mapper = [...data?.field_mapper ?? [], ...fields]; }); contentTypes[index].fieldMapping = fieldIds; }); @@ -44,7 +44,7 @@ const putTestData = async (req: Request) => { const contentType = contentTypes.map((item: any) => { const id = uuidv4(); contentIds.push(id); - return { id, ...item }; + return { ...item, id }; }); await ContentTypesMapperModelLowdb.update((data: any) => { @@ -251,7 +251,6 @@ const updateContentType = async (req: Request) => { if ( [ - NEW_PROJECT_STATUS[0], NEW_PROJECT_STATUS[5], NEW_PROJECT_STATUS[4], ].includes(project.status) || diff --git a/api/src/services/projects.service.ts b/api/src/services/projects.service.ts index e091c6901..83d2121bc 100644 --- a/api/src/services/projects.service.ts +++ b/api/src/services/projects.service.ts @@ -1,5 +1,8 @@ import { Request } from "express"; import ProjectModelLowdb from "../models/project-lowdb.js"; +import ContentTypesMapperModelLowdb from "../models/contentTypesMapper-lowdb.js" +import FieldMapperModel from "../models/FieldMapper.js"; + import { BadRequestError, ExceptionFunction, @@ -12,7 +15,7 @@ import { NEW_PROJECT_STATUS, } from "../constants/index.js"; import { config } from "../config/index.js"; -import { getLogMessage, safePromise } from "../utils/index.js"; +import { getLogMessage, isEmpty, safePromise } from "../utils/index.js"; import getAuthtoken from "../utils/auth.utils.js"; import https from "../utils/https.utils.js"; import getProjectUtil from "../utils/get-project.utils.js"; @@ -32,6 +35,7 @@ const getAllProjects = async (req: Request) => { org_id: orgId, region, owner: user_id, + isDeleted:false }) .value(); @@ -85,6 +89,7 @@ const createProject = async (req: Request) => { created_by: user_id, updated_at: new Date().toISOString(), created_at: new Date().toISOString(), + isDeleted:false }; try { @@ -629,7 +634,7 @@ const updateCurrentStep = async (req: Request) => { ProjectModelLowdb.update((data: any) => { data.projects[projectIndex].current_step = STEPPER_STEPS.CONTENT_MAPPING; - data.projects[projectIndex].status = NEW_PROJECT_STATUS[3]; + // data.projects[projectIndex].status = NEW_PROJECT_STATUS[3]; data.projects[projectIndex].updated_at = new Date().toISOString(); }); break; @@ -660,13 +665,132 @@ const updateCurrentStep = async (req: Request) => { }; const deleteProject = async (req: Request) => { - const orgId = req?.params?.orgId; - const projectId = req?.params?.projectId; + const { orgId, projectId } = req.params; + const decodedToken = req.body.token_payload; + const { user_id = "", region = "" } = decodedToken; + const srcFunc = "deleteProject"; - //Add logic to delete Project from DB - return { orgId, projectId }; + await ProjectModelLowdb.read(); + const projectIndex = (await getProjectUtil( + projectId, + { + id: projectId, + org_id: orgId, + region: region, + owner: user_id, + }, + srcFunc, + true + )) as number; + + const projects = ProjectModelLowdb.data.projects[projectIndex]; + if (!projects) throw new NotFoundError(HTTP_TEXTS.PROJECT_NOT_FOUND); + + if (projects?.status == NEW_PROJECT_STATUS[5]) { + const content_mapper_id = projects?.content_mapper; + + await ContentTypesMapperModelLowdb.read(); + await FieldMapperModel.read(); + if (!isEmpty(content_mapper_id)) { + content_mapper_id.map((item: any) => { + const contentMapperData = ContentTypesMapperModelLowdb.chain + .get("ContentTypesMappers") + .find({ id: item }) + .value(); + + const fieldMappingIds = contentMapperData?.fieldMapping; + + //delete all fieldMapping which is related content Mapper and Project + if (!isEmpty(fieldMappingIds)) { + (fieldMappingIds || []).forEach((field: any) => { + const fieldIndex = FieldMapperModel.chain + .get("field_mapper") + .findIndex({ id: field }) + .value(); + if (fieldIndex > -1) { + FieldMapperModel.update((data: any) => { + delete data.field_mapper[fieldIndex]; + }); + } + }); + } + //delete all content Mapper which is related to Project + const contentMapperID = ContentTypesMapperModelLowdb.chain + .get("ContentTypesMappers") + .findIndex({ id: item }) + .value(); + ContentTypesMapperModelLowdb.update((Cdata: any) => { + delete Cdata.ContentTypesMappers[contentMapperID]; + }); + }); + } + //delete Project + ProjectModelLowdb.update((Pdata: any) => { + delete Pdata.projects[projectIndex]; + }); + } else { + ProjectModelLowdb.update((data: any) => { + data.projects[projectIndex].isDeleted = true; + }); + } + + logger.info( + getLogMessage( + srcFunc, + `Project [Id : ${projectId}] Deleted Successfully`, + decodedToken + ) + ); + return { + status: HTTP_CODES.OK, + data: { + message: HTTP_TEXTS.PROJECT_DELETE, + }, + }; }; +const revertProject = async (req: Request) => { + const { orgId, projectId } = req?.params; + const decodedToken = req.body.token_payload; + const { user_id = "", region = "" } = decodedToken; + const srcFunc = "revertProject"; + + await ProjectModelLowdb.read(); + const projectIndex = (await getProjectUtil( + projectId, + { + id: projectId, + org_id: orgId, + region: region, + owner: user_id, + }, + srcFunc, + true + )) as number; + + const projects = ProjectModelLowdb.data.projects[projectIndex]; + if (!projects){ + throw new NotFoundError(HTTP_TEXTS.PROJECT_NOT_FOUND); + } else{ + ProjectModelLowdb.update((data: any) => { + data.projects[projectIndex].isDeleted = false; + }); + logger.info( + getLogMessage( + srcFunc, + `Project [Id : ${projectId}] Reverted Successfully`, + decodedToken + ) + ); + return { + status: HTTP_CODES.OK, + data: { + message: HTTP_TEXTS.PROJECT_REVERT, + Project:projects + }, + }; + } +} export const projectService = { getAllProjects, getProject, @@ -680,4 +804,5 @@ export const projectService = { updateDestinationStack, updateCurrentStep, deleteProject, + revertProject }; diff --git a/ui/packaga-lock.json b/ui/package-lock.json similarity index 98% rename from ui/packaga-lock.json rename to ui/package-lock.json index ba1efe929..d5e165910 100644 --- a/ui/packaga-lock.json +++ b/ui/package-lock.json @@ -9,22 +9,25 @@ "version": "0.1.0", "dependencies": { "@contentstack/json-rte-serializer": "^2.0.5", - "@contentstack/utils": "1.3.1", "@contentstack/venus-components": "1.5.1", + "@reduxjs/toolkit": "^2.2.5", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "@types/react": "^18.2.28", "@types/react-dom": "^18.2.13", + "@types/react-redux": "^7.1.33", "axios": "^1.5.1", "bootstrap": "5.1.3", "html-react-parser": "^4.2.9", "react": "^18.2.0", "react-dom": "^18.2.0", "react-final-form": "^6.5.9", + "react-redux": "^9.1.2", "react-router": "^6.17.0", "react-router-dom": "^6.16.0", "react-scripts": "5.0.1", + "redux-persist": "^6.0.0", "sass": "^1.68.0", "typescript": "^4.9.5", "web-vitals": "^2.1.4" @@ -2031,11 +2034,6 @@ "uuid": "^8.3.2" } }, - "node_modules/@contentstack/utils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@contentstack/utils/-/utils-1.3.1.tgz", - "integrity": "sha512-qvhEYAxPzUAC++pA2y6W9uMHAsyeFhRLd/bw/Mw2TblBkOxf62W1ASuRdJZz2bfSYp8aAX4HBC22DvzYvkLgHg==" - }, "node_modules/@contentstack/venus-components": { "version": "1.5.1", "resolved": "https://npm.pkg.github.com/download/@contentstack/venus-components/1.5.1/463c96c30d838f3fe4c5c9b47cd152527f0bd367", @@ -2240,6 +2238,35 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/@contentstack/venus-components/node_modules/react-redux": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@contentstack/venus-components/node_modules/react-redux/node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, "node_modules/@contentstack/venus-components/node_modules/react-select": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/react-select/-/react-select-3.2.0.tgz", @@ -2410,6 +2437,14 @@ "react-dom": "^15.0.0 || ^16.0.0" } }, + "node_modules/@contentstack/venus-components/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/@contentstack/venus-components/node_modules/scheduler": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", @@ -4839,6 +4874,38 @@ "resolved": "https://registry.npmjs.org/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz", "integrity": "sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg==" }, + "node_modules/@reduxjs/toolkit": { + "version": "2.2.5", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.2.5.tgz", + "integrity": "sha512-aeFA/s5NCG7NoJe/MhmwREJxRkDs0ZaSqt0MxhWUrwCf1UQXpwR87RROJEql0uAkLI6U7snBOYOcKw83ew3FPg==", + "dependencies": { + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, + "node_modules/@reduxjs/toolkit/node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/@remix-run/router": { "version": "1.14.2", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.14.2.tgz", @@ -5461,22 +5528,22 @@ } }, "node_modules/@testing-library/dom": { - "version": "9.3.4", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.4.tgz", - "integrity": "sha512-FlS4ZWlp97iiNWig0Muq8p+3rVDjRiYE+YKGbAqXOu9nwJFFOdL00kFpz42M+4huzYi86vAK1sOOfyOG45muIQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.1.0.tgz", + "integrity": "sha512-wdsYKy5zupPyLCW2Je5DLHSxSfbIp6h80WoHOQc+RPtmPGA52O9x5MJEkv92Sjonpq+poOAtUKhh1kBGAXBrNA==", "peer": true, "dependencies": { "@babel/code-frame": "^7.10.4", "@babel/runtime": "^7.12.5", "@types/aria-query": "^5.0.1", - "aria-query": "5.1.3", + "aria-query": "5.3.0", "chalk": "^4.1.0", "dom-accessibility-api": "^0.5.9", "lz-string": "^1.5.0", "pretty-format": "^27.0.2" }, "engines": { - "node": ">=14" + "node": ">=18" } }, "node_modules/@testing-library/dom/node_modules/ansi-styles": { @@ -5494,6 +5561,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@testing-library/dom/node_modules/aria-query": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.3.0.tgz", + "integrity": "sha512-b0P0sZPKtyu8HkeRAfCq0IfURZK+SuwMjY1UXGBU27wpAiTwQAIlq56IbIO+ytk/JjS1fMR14ee5WBBfKi5J6A==", + "peer": true, + "dependencies": { + "dequal": "^2.0.3" + } + }, "node_modules/@testing-library/dom/node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", @@ -6154,6 +6230,14 @@ "redux": "^4.0.0" } }, + "node_modules/@types/react-redux/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -6230,10 +6314,15 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/webpack-env": { - "version": "1.18.4", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.4.tgz", - "integrity": "sha512-I6e+9+HtWADAWeeJWDFQtdk4EVSAbj6Rtz4q8fJ7mSr1M0jzlFcs8/HZ+Xb5SHzVm1dxH7aUiI+A8kA8Gcrm0A==", + "version": "1.18.5", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.18.5.tgz", + "integrity": "sha512-wz7kjjRRj8/Lty4B+Kr0LN6Ypc/3SymeCCGSbaXp2leH0ZVg/PriNiOwNj4bD4uphI7A8NXS4b6Gl373sfO5mA==", "peer": true }, "node_modules/@types/ws": { @@ -6905,7 +6994,9 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "engines": ["node >= 0.8.0"], + "engines": [ + "node >= 0.8.0" + ], "bin": { "ansi-html": "bin/ansi-html" } @@ -7950,13 +8041,18 @@ } }, "node_modules/call-bind": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", - "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.1", - "set-function-length": "^1.1.1" + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -9216,16 +9312,19 @@ } }, "node_modules/define-data-property": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", - "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", "dependencies": { - "get-intrinsic": "^1.2.1", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.0" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/define-lazy-prop": { @@ -9388,6 +9487,14 @@ "redux": "^4.0.4" } }, + "node_modules/dnd-core/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/dns-packet": { "version": "5.6.1", "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.1.tgz", @@ -9775,6 +9882,25 @@ "resolved": "https://registry.npmjs.org/es-array-method-boxes-properly/-/es-array-method-boxes-properly-1.0.0.tgz", "integrity": "sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==" }, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "dependencies": { + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-get-iterator": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/es-get-iterator/-/es-get-iterator-1.1.3.tgz", @@ -11328,7 +11454,9 @@ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, "optional": true, - "os": ["darwin"], + "os": [ + "darwin" + ], "engines": { "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } @@ -11383,15 +11511,19 @@ } }, "node_modules/get-intrinsic": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", - "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", "dependencies": { + "es-errors": "^1.3.0", "function-bind": "^1.1.2", "has-proto": "^1.0.1", "has-symbols": "^1.0.3", "hasown": "^2.0.0" }, + "engines": { + "node": ">= 0.4" + }, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -11623,11 +11755,11 @@ } }, "node_modules/has-property-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", - "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", "dependencies": { - "get-intrinsic": "^1.2.2" + "es-define-property": "^1.0.0" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -19418,12 +19550,12 @@ } }, "node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", + "version": "6.12.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.12.1.tgz", + "integrity": "sha512-zWmv4RSuB9r2mYQw3zxQuHWeU+42aKi1wWig/j4ele4ygELZ7PEO6MM7rim9oAQH2A5MWfsAVf/jPvTPgCbvUQ==", "peer": true, "dependencies": { - "side-channel": "^1.0.4" + "side-channel": "^1.0.6" }, "engines": { "node": ">=0.6" @@ -19577,6 +19709,38 @@ "react-dom": "^16.8.5 || ^17.0.0 || ^18.0.0" } }, + "node_modules/react-beautiful-dnd/node_modules/react-redux": { + "version": "7.2.9", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", + "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/react-redux": "^7.1.20", + "hoist-non-react-statics": "^3.3.2", + "loose-envify": "^1.4.0", + "prop-types": "^15.7.2", + "react-is": "^17.0.2" + }, + "peerDependencies": { + "react": "^16.8.3 || ^17 || ^18" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-beautiful-dnd/node_modules/redux": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", + "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", + "dependencies": { + "@babel/runtime": "^7.9.2" + } + }, "node_modules/react-color": { "version": "2.19.3", "resolved": "https://registry.npmjs.org/react-color/-/react-color-2.19.3.tgz", @@ -19888,25 +20052,23 @@ "integrity": "sha512-+PbtI3VuDV0l6CleQMsx2gtK0JZbZKbpdu5ynr+lbsuvtmgbNcS3VM0tuY2QjFNOcWxvXeHjDpy42RO+4U2rug==" }, "node_modules/react-redux": { - "version": "7.2.9", - "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-7.2.9.tgz", - "integrity": "sha512-Gx4L3uM182jEEayZfRbI/G11ZpYdNAnBs70lFVMNdHJI76XYtR+7m0MN+eAs7UHBPhWXcnFPaS+9owSCJQHNpQ==", + "version": "9.1.2", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.1.2.tgz", + "integrity": "sha512-0OA4dhM1W48l3uzmv6B7TXPCGmokUU4p1M44DGN2/D9a1FjVPukVjER1PcPX97jIg6aUeLq1XJo1IpfbgULn0w==", "dependencies": { - "@babel/runtime": "^7.15.4", - "@types/react-redux": "^7.1.20", - "hoist-non-react-statics": "^3.3.2", - "loose-envify": "^1.4.0", - "prop-types": "^15.7.2", - "react-is": "^17.0.2" + "@types/use-sync-external-store": "^0.0.3", + "use-sync-external-store": "^1.0.0" }, "peerDependencies": { - "react": "^16.8.3 || ^17 || ^18" + "@types/react": "^18.2.25", + "react": "^18.0", + "redux": "^5.0.0" }, "peerDependenciesMeta": { - "react-dom": { + "@types/react": { "optional": true }, - "react-native": { + "redux": { "optional": true } } @@ -20386,11 +20548,24 @@ } }, "node_modules/redux": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/redux/-/redux-4.2.1.tgz", - "integrity": "sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==", - "dependencies": { - "@babel/runtime": "^7.9.2" + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==" + }, + "node_modules/redux-persist": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/redux-persist/-/redux-persist-6.0.0.tgz", + "integrity": "sha512-71LLMbUq2r02ng2We9S215LtPu3fY0KgaGE0k8WRgl6RkqxtGfl7HUozz1Dftwsb0D/5mZ8dwAaPbtnzfvbEwQ==", + "peerDependencies": { + "redux": ">4.0.0" + } + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "peerDependencies": { + "redux": "^5.0.0" } }, "node_modules/reflect.getprototypeof": { @@ -20604,6 +20779,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/reselect": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.0.tgz", + "integrity": "sha512-aw7jcGLDpSgNDyWBQLv2cedml85qd95/iszJjN988zX1t7AVRJi19d9kto5+W7oCfQ94gyo40dVbT6g2k4/kXg==" + }, "node_modules/resize-observer-polyfill": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", @@ -21171,15 +21351,16 @@ } }, "node_modules/set-function-length": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", - "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", "dependencies": { - "define-data-property": "^1.1.1", + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.2", + "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.1" + "has-property-descriptors": "^1.0.2" }, "engines": { "node": ">= 0.4" @@ -21236,13 +21417,17 @@ } }, "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -21583,9 +21768,9 @@ } }, "node_modules/store2": { - "version": "2.14.2", - "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.2.tgz", - "integrity": "sha512-siT1RiqlfQnGqgT/YzXVUNsom9S0H1OX+dpdGN1xkyYATo4I6sep5NmsRD/40s3IIOvlCq6akxkqG82urIZW1w==", + "version": "2.14.3", + "resolved": "https://registry.npmjs.org/store2/-/store2-2.14.3.tgz", + "integrity": "sha512-4QcZ+yx7nzEFiV4BMLnr/pRa5HYzNITX2ri0Zh6sT9EyQHbBHacC6YigllUPU9X3D0f/22QCgfokpKs52YRrUg==", "peer": true }, "node_modules/string_decoder": { @@ -22779,6 +22964,14 @@ "react": "^16.8.0 || ^17.0.0 || ^18.0.0" } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", diff --git a/ui/package.json b/ui/package.json index 61ce94f3e..ca22c2f2f 100644 --- a/ui/package.json +++ b/ui/package.json @@ -4,22 +4,25 @@ "private": true, "dependencies": { "@contentstack/json-rte-serializer": "^2.0.5", - "@contentstack/utils": "1.3.1", "@contentstack/venus-components": "1.5.1", + "@reduxjs/toolkit": "^2.2.5", "@testing-library/jest-dom": "^5.17.0", "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^13.5.0", "@types/react": "^18.2.28", "@types/react-dom": "^18.2.13", + "@types/react-redux": "^7.1.33", "axios": "^1.5.1", "bootstrap": "5.1.3", "html-react-parser": "^4.2.9", "react": "^18.2.0", "react-dom": "^18.2.0", "react-final-form": "^6.5.9", + "react-redux": "^9.1.2", "react-router": "^6.17.0", "react-router-dom": "^6.16.0", "react-scripts": "5.0.1", + "redux-persist": "^6.0.0", "sass": "^1.68.0", "typescript": "^4.9.5", "web-vitals": "^2.1.4" @@ -62,4 +65,4 @@ "last 1 safari version" ] } -} +} \ No newline at end of file diff --git a/ui/public/favicon.ico b/ui/public/favicon.ico index a1c0f9fa7..3efd5e491 100644 Binary files a/ui/public/favicon.ico and b/ui/public/favicon.ico differ diff --git a/ui/public/images/ContentstackLogo.png b/ui/public/images/ContentstackLogo.png new file mode 100644 index 000000000..d2552da4e Binary files /dev/null and b/ui/public/images/ContentstackLogo.png differ diff --git a/ui/public/images/login_bg.webp b/ui/public/images/login_bg.webp new file mode 100644 index 000000000..936abed6d Binary files /dev/null and b/ui/public/images/login_bg.webp differ diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 6e841111b..5221fac64 100644 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -2,25 +2,37 @@ import AppRouter from './components/Common/router'; import ErrorBoundary from './components/ErrorBoundary'; import AppContextProvider from './context/app/app.provider'; import AppLayout from './components/layout/AppLayout'; -import { Suspense } from 'react'; +import { Suspense, useEffect } from 'react'; import { FullPageLoader } from '@contentstack/venus-components'; +import { persistor, store } from './store'; // Styles import '@contentstack/venus-components/build/main.css'; import './scss/App.scss'; +import { Provider} from 'react-redux'; +import { PersistGate } from 'redux-persist/integration/react'; function App() { + return ( }> - - - - - + + } persistor={persistor}> + + + + + ); } export default App; + + +function dispatch(arg0: any) { + throw new Error('Function not implemented.'); +} + diff --git a/ui/src/cmsData/login.json b/ui/src/cmsData/login.json index 0c6bd9df7..e680eae6a 100644 --- a/ui/src/cmsData/login.json +++ b/ui/src/cmsData/login.json @@ -6,7 +6,7 @@ "copyrightText": "Contentstack Inc. All rights reserved.", "created_at": "2024-02-22T11:20:53.435Z", "created_by": "bltb317ebe35429ebe6", - "heading": "Stacks Not Suites", + "heading": "GAIN YOUR EXPERIENCE EDGE", "login": { "title": "Log in to Contentstack", "email": "Email", @@ -29,12 +29,12 @@ "tags": [], "title": "Login", "two_factor_authentication": { - "title": "Two-factor Authentication", + "title": "Two-Factor Authentication", "security_code": { "title": "Enter the security code generated in Authy app", "placeholder": "Enter the security code" }, - "send_sms": { "pre_link_text": "I don't have the app.", "link_text": "Send me an SMS" }, + "send_sms": { "pre_link_text": "Don't have an account?", "link_text": "Send me an SMS" }, "cta": { "title": "Verify", "url": "", diff --git a/ui/src/cmsData/main_header.json b/ui/src/cmsData/main_header.json index 0a8e22541..f5760d37d 100644 --- a/ui/src/cmsData/main_header.json +++ b/ui/src/cmsData/main_header.json @@ -22,7 +22,7 @@ "file_size": "10160", "tags": [], "filename": "icon-cs-mobile.svg", - "url": "https://images.contentstack.io/v3/assets/bltd3620ec6418ad3ad/blt4a17564224d007f3/652f91e5fe1f57912c211dfc/icon-cs-mobile.svg", + "url": "https://images.contentstack.io/v3/assets/blt7359e2a55efae483/blt0b9a8281aeac3ec0/664c27d3c9024c35b5ad593a/CS_logo.png", "ACL": [], "is_dir": false, "parent_uid": "blt8e7f7872baa3a09e", diff --git a/ui/src/cmsData/projects.json b/ui/src/cmsData/projects.json index d74389fc6..d482d9410 100644 --- a/ui/src/cmsData/projects.json +++ b/ui/src/cmsData/projects.json @@ -10,6 +10,13 @@ "open_in_new_tab": false, "with_icon": true }, + "restore_cta": { + "open_in_new_tab": false, + "theme": "secondary", + "title": "Restore Projects", + "url": "", + "with_icon": false + }, "tags": [], "locale": "en-us", "uid": "blta1dbec2d70eaa448", @@ -68,7 +75,7 @@ "type": "doc", "_version": 12 }, - "heading": "Welcome to Contentstack Migrations", + "heading": "Welcome to Content Migrations", "help_text": { "type": "doc", "attrs": {}, diff --git a/ui/src/cmsData/setting.json b/ui/src/cmsData/setting.json index f56d3cb5d..6c0c138e7 100644 --- a/ui/src/cmsData/setting.json +++ b/ui/src/cmsData/setting.json @@ -1,5 +1,5 @@ { - "title": "Setting page", + "title": "Settings", "project": { "title": "Project", "name": "Project Name", diff --git a/ui/src/components/AccountPage/index.scss b/ui/src/components/AccountPage/index.scss index 830efa2a3..9af38e4f2 100644 --- a/ui/src/components/AccountPage/index.scss +++ b/ui/src/components/AccountPage/index.scss @@ -6,10 +6,20 @@ height: 100vh; overflow: hidden; + &__logo { + display: inline-block; + height: 3.75rem; + left: 4%; + position: relative; + top: 5%; + z-index: 10; + } + &__intro { - background-color: $color-brand-primary-base; - flex: 0 0 35%; - height: 100%; + background-image: url("../../../public/images/login_bg.webp"); + background-repeat: no-repeat; + background-size: cover; + height: 100vh; position: relative; width: 35%; } @@ -41,18 +51,31 @@ } &__heading { - left: 15%; + -webkit-box-orient: vertical; + -webkit-box-direction: normal; + -webkit-box-align: center; + -ms-flex-align: center; + grid-row-gap: .5rem; + align-items: center; + display: -webkit-box; + display: -ms-flexbox; + display: flex; + -ms-flex-direction: column; + flex-direction: column; + left: 8%; position: absolute; - top: 40%; + row-gap: .5rem; + top: 30%; z-index: 10; &_title { color: $color-brand-white-base; font-family: $font-family-secondary; - font-size: 2.5rem; + font-size: 3.8rem; font-weight: $font-weight-extra-bold; - line-height: 49px; - max-width: $px-260; + letter-spacing: .04em; + line-height: 3.625rem; + // max-width: $px-260; text-transform: uppercase; } &_subtitle { @@ -65,16 +88,6 @@ } } - &__logo { - display: inline-block; - height: 28px !important; - left: 15%; - margin-top: $space-50; - position: relative; - width: $px-159 !important; - z-index: 10; - } - &__circle { border-radius: $radii-50; position: absolute; diff --git a/ui/src/components/AccountPage/index.tsx b/ui/src/components/AccountPage/index.tsx index 655113ec4..4b1316670 100644 --- a/ui/src/components/AccountPage/index.tsx +++ b/ui/src/components/AccountPage/index.tsx @@ -1,6 +1,3 @@ -// Libraries -import { Icon } from '@contentstack/venus-components'; - // Interface import { AccountObj } from './accountPage.interface'; @@ -8,7 +5,7 @@ import { AccountObj } from './accountPage.interface'; import './index.scss'; const AccountPage = (props: AccountObj): JSX.Element => { - const { heading, subtitle, copyrightText } = props.data; + const { heading, copyrightText } = props.data; const currentYear = new Date().getFullYear(); const previousYear = currentYear - 1; @@ -17,22 +14,10 @@ const AccountPage = (props: AccountObj): JSX.Element => { // eslint-disable-next-line react/no-unknown-property
- + Contentstack

{heading}

-

{subtitle}

- - - - - - -
{props?.children}
diff --git a/ui/src/components/AdvancePropertise/advanceProperties.interface.ts b/ui/src/components/AdvancePropertise/advanceProperties.interface.ts new file mode 100644 index 000000000..8f0c0bf44 --- /dev/null +++ b/ui/src/components/AdvancePropertise/advanceProperties.interface.ts @@ -0,0 +1,37 @@ +import { FieldMapType } from '../ContentMapper/contentMapper.interface'; + +export interface SchemaProps { + fieldtype: string; + value: any; + rowId: string; + updateFieldSettings: (rowId: string, value: any, checkBoxChanged: boolean) => void; + isLocalised: boolean; + closeModal: () => void; + data: FieldMapType; + projectId?: string; +} + +export interface Props { + data: SchemaProps; + states?: StateType; + handleChange?: (field: string, event: any, checkBoxChanged: boolean) => void; + handleToggle?: (field: string, value: boolean, checkBoxChanged: boolean) => void; +} + +export interface StateType { + minChars?: string; + maxChars?: number; + minRange?: number; + maxRange?: number; + minSize?: string; + maxSize?: number; + defaultValue?: string; + validationRegex?: string; + title?: string; + url?: string; + mandatory?: boolean; + allowImagesOnly?: boolean; + nonLocalizable?: boolean; + embedObject?: boolean; + embedAssests?: boolean; +} \ No newline at end of file diff --git a/ui/src/components/AdvancePropertise/index.scss b/ui/src/components/AdvancePropertise/index.scss index 3df80f930..212c06f8b 100644 --- a/ui/src/components/AdvancePropertise/index.scss +++ b/ui/src/components/AdvancePropertise/index.scss @@ -1,3 +1,5 @@ +@import '../../scss/variables'; + .options-class { display: flex; flex-direction: column; @@ -7,13 +9,76 @@ grid-template-columns: 1fr; gap: 20px; } -.validation-input { - margin-bottom: 20px; -} .option-label { - margin-bottom: 20px; + margin-bottom: $px-10; } .non-localizable-message { margin-top: 0; margin-left: 30px; } +.modal-data { + padding: 0.75rem; + .radio-field { + margin-bottom: 0.75rem; + } + .Radio { + width: calc(33.33333% - .66667rem); + padding: .5rem; + margin: 0 !important; + } + .FieldLabel { + margin-bottom: $px-8; + } + .info-style { + margin-top: .75rem; + margin-bottom: 1.5rem; + .Info__border { + border-left-color: #0469e3; + } + } + .options-class { + line-height: $line-height-reset; + } + .nl-note { + color: $color-font-base; + font-size: $size-font-large; + line-height: $line-height-default; + margin-left: 2.75rem; + margin-top: -.25rem !important; + } + .ToggleWrap { + margin-top: 0.5rem; + padding: 0 0.5rem + } + .Field { + margin-bottom: $px-24; + } + .fields-group-separator { + color: $color-base-black-base; + margin: 0 16px; + } + .Select { + .Select__menu { + .Select__menu-list { + .Select__option { + .Checkbox { + align-items: center; + display: flex; + } + .Checkbox__label { + height: auto; + } + } + } + } + } + .Select__menu { + position: relative; + z-index: 10000; + } + .Select__control--menu-is-open { + position: relative; + border: 2px solid red; + z-index: 10000; + } +} diff --git a/ui/src/components/AdvancePropertise/index.tsx b/ui/src/components/AdvancePropertise/index.tsx index 58b52f25d..dbf0e5b8e 100644 --- a/ui/src/components/AdvancePropertise/index.tsx +++ b/ui/src/components/AdvancePropertise/index.tsx @@ -1,119 +1,362 @@ -import { useState } from 'react'; - +// Libraries +import { useEffect, useState } from 'react'; import { ModalBody, ModalHeader, + Field, FieldLabel, TextInput, ToggleSwitch, - Tooltip + Tooltip, + Icon, + Select } from '@contentstack/venus-components'; +// Service +import { getContentTypes } from '../../services/api/migration.service'; + +// Interfaces +import { SchemaProps } from './advanceProperties.interface'; +import { ContentType } from '../ContentMapper/contentMapper.interface'; + +// Styles import './index.scss'; -export interface SchemaProps { - fieldtype: string; - value: any; - rowId: string; - updateFieldSettings: (rowId: string, value: any, checkBoxChanged: boolean) => void; - isLocalised: boolean; - closeModal: () => void; - data: any; -} const AdvancePropertise = (props: SchemaProps) => { const [toggleStates, setToggleStates] = useState({ + minChars: props?.value?.MinChars, + maxChars: props?.value?.MaxChars, + minRange: props?.value?.MinRange, + maxRange: props?.value?.MaxRange, + minSize: props?.value?.minSize, + maxSize: props?.value?.maxSize, + defaultValue: props?.value?.DefaultValue, validationRegex: props?.value?.ValidationRegex, + title: props?.value?.title, + url: props?.value?.url, mandatory: props?.value?.Mandatory, - multiple: props?.value?.Multiple, - unique: props?.value?.Unique, - nonLocalizable: props?.value?.NonLocalizable + allowImagesOnly: props?.value?.AllowImagesOnly, + nonLocalizable: props?.value?.NonLocalizable, + embedObject: true, + embedAssests: true }); - const handleToggleChange = (field: string, value: boolean, checkBoxChanged: boolean) => { + const [contentTypes, setContentTypes] = useState([]); + const [CTValue, setCTValue] = useState(null); + + useEffect(() => { + fetchContentTypes(''); + }, []) + + // Fetch content types list + const fetchContentTypes = async (searchText: string) => { + const { data } = await getContentTypes(props?.projectId || '', 0, 10, searchText || ''); //org id will always present + + setContentTypes(data?.contentTypes); + }; + + const handleOnChange = (field: string, event: React.ChangeEvent, checkBoxChanged: boolean) => { setToggleStates((prevStates) => ({ ...prevStates, - [field]: value + [field]: (event.target as HTMLInputElement)?.value })); props?.updateFieldSettings( props?.rowId, - { [field?.charAt(0)?.toUpperCase() + field?.slice(1)]: value }, + { [field?.charAt(0)?.toUpperCase() + field?.slice(1)]: (event.target as HTMLInputElement)?.value }, checkBoxChanged ); }; - const handleOnChange = (field: string, event: any, checkBoxChanged: boolean) => { + const handleToggleChange = (field: string, value: boolean, checkBoxChanged: boolean) => { setToggleStates((prevStates) => ({ ...prevStates, - [field]: event?.target?.value + [field]: value })); props?.updateFieldSettings( props?.rowId, - { [field?.charAt(0)?.toUpperCase() + field?.slice(1)]: event?.target?.value }, + { [field?.charAt(0)?.toUpperCase() + field?.slice(1)]: value }, checkBoxChanged ); }; + const option = Array.isArray(contentTypes) + ? contentTypes.map((option) => ({ label: option?.otherCmsTitle, value: option?.otherCmsTitle })) + : [{ label: contentTypes, value: contentTypes }]; + return ( <> - + - - Validation (Regex) - - handleOnChange('validationRegex', e, true)} - /> - - Options - -
- handleToggleChange('mandatory', e?.target?.checked, true)} - /> - handleToggleChange('multiple', e?.target?.checked, true)} - /> - handleToggleChange('unique', e?.target?.checked, true)} - /> - - handleToggleChange('nonLocalizable', e?.target?.checked, true)} - /> - -

- If enabled, editing this field is restricted in localized entries. The field will use - the value of the master-language entry in all localized entries. -

+
+ {(props?.fieldtype === 'Single Line Textbox' || props?.fieldtype === 'Multi Line Textbox') && ( + + + Number of Characters + +
+ ) => handleOnChange('minChars', e, true))} + /> + to + ) => handleOnChange('maxChars', e, true))} + /> +
+
+ )} + + {(props?.fieldtype === 'Single Line Textbox' || props?.fieldtype === 'Multi Line Textbox') && ( + <> + + + Default Value + + + + + ) => handleOnChange('defaultValue', e, true))} + /> + + + + + Validation (Regex) + + + + + ) => handleOnChange('validationRegex', e, true))} + /> + + + )} + + {props?.fieldtype === 'Number' && ( + + + Range + +
+ ) => handleOnChange('minRange', e, true))} + /> + to + ) => handleOnChange('maxRange', e, true))} + /> +
+
+ )} + + {props?.fieldtype === 'File' && ( + + + File Size Limit (MB) + + + + +
+ ) => handleOnChange('minSize', e, true))} + /> + to + ) => handleOnChange('maxSize', e, true))} + /> +
+
+ )} + + {props?.fieldtype === 'Link' && ( + <> +
+ + Default Value + + + + +
+ + + + Title: + + ) => handleOnChange('title', e, true))} + /> + + + + + Url: + + ) => handleOnChange('url', e, true))} + /> + + + )} + + + + Other Options + +
+ {(props?.fieldtype === 'HTML Rich text Editor' || props?.fieldtype === 'JSON Rich Text Editor') && ( + <> +
+ ) => handleToggleChange('embedObject', (e.target as HTMLInputElement)?.checked, true))} + /> +
+ + {toggleStates?.embedObject && ( +