diff --git a/.circleci/config.yml b/.circleci/config.yml index 8cbb2304..e004c36c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -15,14 +15,14 @@ jobs: - checkout - add_ssh_keys: fingerprints: - - "39:25:57:64:62:43:1f:98:b1:5e:75:53:87:d8:e7:71" - - run: cp $HOME/.ssh/id_rsa_3925576462431f98b15e755387d8e771 id_rsa + - "4c:8e:00:16:94:44:d9:ad:e9:e9:2c:8b:02:d4:8d:7a" + - run: cp $HOME/.ssh/id_rsa_4c8e00169444d9ade9e92c8b02d48d7a id_rsa - setup_remote_docker: version: 20.10.12 docker_layer_caching: true - run: docker login rg.fr-par.scw.cloud/lecoffre -u nologin -p $SCW_SECRET_KEY - - run: docker build --tag rg.fr-par.scw.cloud/lecoffre/front:$TAG . - - run: docker push rg.fr-par.scw.cloud/lecoffre/front:$TAG + - run: docker build --tag rg.fr-par.scw.cloud/lecoffre/front:${CIRCLE_SHA1:0:7} . + - run: docker push rg.fr-par.scw.cloud/lecoffre/front:${CIRCLE_SHA1:0:7} deploy-docker-image: @@ -30,6 +30,10 @@ jobs: - image: cimg/base:stable environment: TAG: << pipeline.git.tag >> + parameters: + env: + type: string + default: stg steps: - checkout - kubernetes/install-kubeconfig: @@ -39,31 +43,61 @@ jobs: name: Deploy command: > helm upgrade - lecoffre-front devops/ -i -f devops/values.yaml - -n lecoffre + lecoffre-front devops/ -i -f devops/<>.values.yaml + -n lecoffre-<> --create-namespace --set lecoffreFront.image.repository='rg.fr-par.scw.cloud/lecoffre/front' - --set lecoffreFront.image.tag=$TAG + --set lecoffreFront.image.tag=${CIRCLE_SHA1:0:7} + workflows: version: 2 - build-and-register: + build-and-register-stg: jobs: - build-push-docker-image: filters: - tags: - only: /^v.*/ branches: - ignore: /.*/ + only: staging - deploy-docker-image: + env: stg requires: - build-push-docker-image context: - - staging + - sc-shared-prd filters: - tags: - only: /^v.*/ branches: - ignore: /.*/ + only: staging + + build-and-register-ppd: + jobs: + - build-push-docker-image: + filters: + branches: + only: preprod + - deploy-docker-image: + env: ppd + requires: + - build-push-docker-image + context: + - sc-shared-prd + filters: + branches: + only: preprod + + build-and-register-prd: + jobs: + - build-push-docker-image: + filters: + branches: + only: main + - deploy-docker-image: + env: prd + requires: + - build-push-docker-image + context: + - sc-shared-prd + filters: + branches: + only: main diff --git a/devops/Chart.yaml b/devops/Chart.yaml index b19e514c..208511fb 100644 --- a/devops/Chart.yaml +++ b/devops/Chart.yaml @@ -1,5 +1,5 @@ apiVersion: v2 -name: leCoffre-front +name: leCoffre-back description: A Helm chart for Kubernetes # A chart can be either an 'application' or a 'library' chart. @@ -21,4 +21,5 @@ version: 0.0.1 # incremented each time you make changes to the application. Versions are not expected to # follow Semantic Versioning. They should reflect the version the application is using. # It is recommended to use it with quotes. -appVersion: 0.5.0 +appVersion: 0.5.6 + diff --git a/devops/ppd.values.yaml b/devops/ppd.values.yaml new file mode 100644 index 00000000..19c4025a --- /dev/null +++ b/devops/ppd.values.yaml @@ -0,0 +1,34 @@ +dockerPullSecret: docker-pull-secret + +scwSecretKey: AgCgjF5QEzxT3GYTS5B6cmQ0e+0/qFWzKaUDSi+Vjc7RoameuvaIJvTXMBkS3he1oy1ulbB34v6vpZI2kxnGNqERA/U5BaYDAyfKSBwMAy4br7HVKhhuwkoF5qoG5JzJXseSmqB1U9vncVIGOZWzJc1Y4/eGlWcvLcLyfw2z/WEpyeNiWJfEhTYpJOB7gv0XnRb2U/JM3jRy1QgEUIk1WR6kgBalF+xaczPQ6uKh+PR2pqkbZa3WaKUrddmzNsgEz4d8PZMWt8IBwR2JOQEHUqCd34p/pJNyLdUgcdDhg02DKwn1oRoAxKTbAio/a7WrMbodjCb3TNWIYGal5mFmItZ7Ok/EBmUf4E85eOkTR+j8ynuuiexld3Q5Kw3o8LsHjgzVL9uP+T2rYaKkjtVt+YQRX1U8l9CrsdUEz0/wEBA0jwCWMfnh1qhD5pM/xwwjsEEAcK4rYV+Q7iAgGZZvZBCQ5aEHzrtn5D95tr1GZCV2hmrW6Seu+LKKLVBS1JmsuEsOuhudYsEK9m2RYVcxbjuS5eokKEjNrGobf2oB8rhBByavfw1JTBixR5JrI8lcYlnCa+oEhxXKJY+4Fx5SAB4YaLCMSo5vw6zsFQ3WKQzlEmCFt+EnapS+a+MGrdlwq07OHTDpvgk/1z39hopoCuhhKckGGfErLXsTYQvDOkFu+EPzgY7m7qDw/d9pSiht5tuSOkAqeOgm7tpNkUufZhaXmP+1aT7i+H5gq1JILGAmXzTI5Wc= + +lecoffreFront: + serviceAccountName: lecoffre-front-sa + command: "'sh', '-c', 'export $(xargs { Glissez / Déposez votre document dans la zone prévue à cet effet ou cliquez sur la zone puis sélectionnez le document correspondant. - {/* */} + ({ + document_type: DocumentType.hydrate({ + name: "Document annexe", + }), + })} + /> diff --git a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx index ee40ef15..6ec149a5 100644 --- a/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx +++ b/src/front/Components/Layouts/Collaborators/CollaboratorInformations/index.tsx @@ -33,7 +33,7 @@ export default function CollaboratorInformations(props: IProps) { useEffect(() => { if (!userSelected) return; - setIsAdminChecked(userSelected.role?.name === "admin" && !userSelected.office_role); + setIsAdminChecked(userSelected.role?.name === "admin"); }, [userSelected]); const handleRoleChange = useCallback((option: IOption) => { @@ -81,7 +81,21 @@ export default function CollaboratorInformations(props: IProps) { }), ); } else { - // retirer rôle admin + const defaultRole = await Roles.getInstance().getOne({ + where: { + name: "default", + }, + }); + + if (!defaultRole) return; + await Users.getInstance().put( + userSelected?.uid as string, + User.hydrate({ + uid: userSelected?.uid as string, + office_role: undefined, + role: defaultRole, + }), + ); } setAdminModalOpened(false); } catch (e) { diff --git a/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx b/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx index 87fd41de..f39bec59 100644 --- a/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx +++ b/src/front/Components/Layouts/Folder/AddClientToFolder/index.tsx @@ -203,9 +203,7 @@ class AddClientToFolderClass extends BasePage { const allCustomersToLink = this.state.selectedCustomers.concat(this.state.existingCustomers); let customersToLink: Partial[] = allCustomersToLink.map((customer) => { - return { - customer: { uid: customer.value }, - }; + return Customer.hydrate({ uid: customer.value as string }); }) as Partial[]; if (this.state.selectedOption === "new_customer") { diff --git a/src/front/Components/Layouts/Folder/AskDocuments/index.tsx b/src/front/Components/Layouts/Folder/AskDocuments/index.tsx index 67c19ab5..ff18c0c4 100644 --- a/src/front/Components/Layouts/Folder/AskDocuments/index.tsx +++ b/src/front/Components/Layouts/Folder/AskDocuments/index.tsx @@ -61,6 +61,7 @@ class AskDocumentsClass extends BasePage { const backUrl = Module.getInstance() .get() .modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", this.props.folderUid); + return ( {}}>
@@ -133,11 +134,7 @@ class AskDocumentsClass extends BasePage { q: { deed: { include: { - deed_has_document_types: { - include: { - document_type: true, - }, - }, + document_types: true, }, }, office: true, diff --git a/src/front/Components/Layouts/SelectFolder/classes.module.scss b/src/front/Components/Layouts/SelectFolder/classes.module.scss index 504eff91..6334c67f 100644 --- a/src/front/Components/Layouts/SelectFolder/classes.module.scss +++ b/src/front/Components/Layouts/SelectFolder/classes.module.scss @@ -1,16 +1,5 @@ .root { position: relative; - .background-container { - width: 100%; - height: 100%; - position: absolute; - z-index: -1; - - > img { - width: 100%; - object-fit: cover; - } - } .select-folder-container { max-width: 530px; padding: 80px 72px; diff --git a/src/front/Components/Layouts/SelectFolder/index.tsx b/src/front/Components/Layouts/SelectFolder/index.tsx index 8596700f..441461ef 100644 --- a/src/front/Components/Layouts/SelectFolder/index.tsx +++ b/src/front/Components/Layouts/SelectFolder/index.tsx @@ -1,14 +1,13 @@ -import DefaultTemplate from "@Front/Components/LayoutTemplates/DefaultTemplate"; -import classes from "./classes.module.scss"; -import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; -import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList"; -import { OfficeFolder } from "le-coffre-resources/dist/Customer"; -import { useCallback, useEffect, useState } from "react"; import Folders from "@Front/Api/LeCoffreApi/SuperAdmin/Folders/Folders"; +import BlockList, { IBlock } from "@Front/Components/DesignSystem/BlockList"; +import Typography, { ITypo } from "@Front/Components/DesignSystem/Typography"; +import DefaultDoubleSidePage from "@Front/Components/LayoutTemplates/DefaultDoubleSidePage"; +import { OfficeFolder } from "le-coffre-resources/dist/Customer"; import { useRouter } from "next/router"; -import Module from "@Front/Config/Module"; -import BackgroundImage from "@Assets/images/background.png"; -import Image from "next/image"; +import { useCallback, useEffect, useState } from "react"; + +import LandingImage from "../Login/landing-connect.jpeg"; +import classes from "./classes.module.scss"; export default function SelectFolder() { const [folders, setFolders] = useState([]); @@ -25,19 +24,14 @@ export default function SelectFolder() { const handleSelectBlock = useCallback( (block: IBlock) => { - router.push( - Module.getInstance().get().modules.pages.Folder.pages.FolderInformation.props.path.replace("[folderUid]", block.id), - ); + router.push("/client-dashboard"); }, [router], ); return ( - +
-
- background -
Vos dossiers @@ -56,6 +50,6 @@ export default function SelectFolder() {
-
+ ); } diff --git a/src/front/Components/Layouts/Users/UserInformations/index.tsx b/src/front/Components/Layouts/Users/UserInformations/index.tsx index 6a8c174d..5ade8659 100644 --- a/src/front/Components/Layouts/Users/UserInformations/index.tsx +++ b/src/front/Components/Layouts/Users/UserInformations/index.tsx @@ -12,7 +12,7 @@ import Typography, { ITypo, ITypoColor } from "@Front/Components/DesignSystem/Ty import DefaultUserDashboard from "@Front/Components/LayoutTemplates/DefaultUserDashboard"; import JwtService from "@Front/Services/JwtService/JwtService"; import Toasts from "@Front/Stores/Toasts"; -import User, { Appointment, Vote } from "le-coffre-resources/dist/SuperAdmin"; +import User, { Appointment, OfficeRole, Vote } from "le-coffre-resources/dist/SuperAdmin"; import { EAppointmentStatus, EVote } from "le-coffre-resources/dist/SuperAdmin/Appointment"; import Image from "next/image"; import { useRouter } from "next/router"; @@ -28,6 +28,7 @@ export default function UserInformations(props: IProps) { const [userSelected, setUserSelected] = useState(null); const [availableRoles, setAvailableRoles] = useState([]); + const [roleModalOpened, setRoleModalOpened] = useState(false); const [isSuperAdminModalOpened, setIsSuperAdminModalOpened] = useState(false); const [superAdminModalType, setSuperAdminModalType] = useState<"add" | "remove">("add"); const [adminModalType, setAdminModalType] = useState<"add" | "remove">("add"); @@ -36,8 +37,15 @@ export default function UserInformations(props: IProps) { const [isAdminChecked, setIsAdminChecked] = useState(false); const [isAdminModalOpened, setIsAdminModalOpened] = useState(false); + const [selectedOption, setSelectedOption] = useState(null); + const [currentAppointment, setCurrentAppointment] = useState(null); + const handleRoleChange = useCallback((option: IOption) => { + setSelectedOption(option); + setRoleModalOpened(true); + }, []); + /** When page change, get the user of the page */ const getUser = useCallback(async () => { @@ -83,7 +91,7 @@ export default function UserInformations(props: IProps) { const closeAdminModal = useCallback(() => { setIsAdminModalOpened(false); - setIsAdminChecked(userSelected?.role?.name === "admin" && !userSelected.office_role); + setIsAdminChecked(userSelected?.role?.name === "admin"); }, [userSelected]); const handleAdminChanged = (checked: boolean) => { @@ -111,7 +119,21 @@ export default function UserInformations(props: IProps) { }), ); } else { - // retirer rôle admin + const defaultRole = await Roles.getInstance().getOne({ + where: { + name: "default", + }, + }); + + if (!defaultRole) return; + await Users.getInstance().put( + userSelected?.uid as string, + User.hydrate({ + uid: userSelected?.uid as string, + office_role: undefined, + role: defaultRole, + }), + ); } setIsAdminModalOpened(false); }, [userSelected, adminModalType]); @@ -123,7 +145,7 @@ export default function UserInformations(props: IProps) { const closeSuperAdminModal = useCallback(() => { setIsSuperAdminModalOpened(false); - setIsSuperAdminChecked(userSelected?.role?.name === "super-admin" && !userSelected.office_role); + setIsSuperAdminChecked(userSelected?.role?.name === "super-admin"); }, [userSelected]); const handleSuperAdminChanged = (checked: boolean) => { @@ -156,11 +178,33 @@ export default function UserInformations(props: IProps) { setIsSuperAdminModalOpened(false); }, [userSelected, currentAppointment, superAdminModalType, getUser]); + const closeRoleModal = useCallback(() => { + setRoleModalOpened(false); + setSelectedOption({ + value: userSelected?.office_role ? userSelected?.office_role?.uid : userSelected?.role?.uid, + label: userSelected?.office_role ? userSelected?.office_role?.name : userSelected?.role?.name!, + }); + }, [userSelected?.office_role, userSelected?.role?.name, userSelected?.role?.uid]); + + const changeRole = useCallback(async () => { + await Users.getInstance().put( + userSelected?.uid as string, + User.hydrate({ + uid: userSelected?.uid as string, + office_role: OfficeRole.hydrate({ + uid: selectedOption?.value as string, + }), + }), + ); + setRoleModalOpened(false); + getUser(); + }, [getUser, selectedOption?.value, userSelected?.uid]); + /** Reset switch state when userSelect change */ useEffect(() => { if (!userSelected) return; setIsSuperAdminChecked(userSelected.role?.name === "super-admin"); - setIsAdminChecked(userSelected.role?.name === "admin" && !userSelected.office_role); + setIsAdminChecked(userSelected.role?.name === "admin"); }, [userSelected]); const userHasVoted = useCallback(() => { @@ -223,7 +267,8 @@ export default function UserInformations(props: IProps) { role.label !== "admin")} + onChange={handleRoleChange} selectedOption={{ value: userSelected?.office_role ? userSelected?.office_role?.uid : userSelected?.role?.uid, label: userSelected?.office_role ? userSelected?.office_role?.name : userSelected?.role?.name!, @@ -271,6 +316,21 @@ export default function UserInformations(props: IProps) {
+ +
+ + Attribuer le rôle de {selectedOption?.label} à{" "} + {userSelected?.contact?.first_name} {userSelected?.contact?.last_name} ? + +
+
; + return ; }