diff --git a/.dockerignore b/.dockerignore index 66772e0e5..a69b04a06 100644 --- a/.dockerignore +++ b/.dockerignore @@ -22,6 +22,7 @@ yarn-error.log* docker-compose.yml Dockerfile +docker/Dockerfile .env /public/config.js diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index c24743d00..000000000 --- a/.editorconfig +++ /dev/null @@ -1,7 +0,0 @@ -[*.{js,jsx,ts,tsx,vue}] -indent_style = space -indent_size = 2 -end_of_line = lf -trim_trailing_whitespace = true -insert_final_newline = true -max_line_length = 100 diff --git a/.eslintrc.js b/.eslintrc.js index e17b649aa..49905b733 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,9 +1,9 @@ module.exports = { root: true, env: { - es2021: true, + node: true, }, - extends: ['@weni/eslint-config/vue2'], + extends: ['@weni/eslint-config/vue3'], rules: { 'vue/multi-word-component-names': 'off', 'vue/no-unused-components': 'off', @@ -11,5 +11,10 @@ module.exports = { 'vue/valid-next-tick': 'off', 'no-unused-vars': 'off', 'no-undef': 'off', + 'vue/valid-attribute-name': 'off', + }, + parserOptions: { + parser: 'babel-eslint', + ecmaVersion: 2020, }, }; diff --git a/.github/workflows/build-ia-frontend-push-tag-dockerhub.yaml b/.github/workflows/build-ia-frontend-push-tag-dockerhub.yaml deleted file mode 100644 index 7ae80ef12..000000000 --- a/.github/workflows/build-ia-frontend-push-tag-dockerhub.yaml +++ /dev/null @@ -1,133 +0,0 @@ -name: Build IA Platform Frontend in Dockerhub(Push Tag) - -on: - push: - tags: - - '*.*.*-develop' - - '*.*.*-staging' - - '*.*.*' - -jobs: - docker: - runs-on: ubuntu-latest - steps: - - name: Set variables - run: | - TAG="$( echo "${GITHUB_REF}" | cut -d'/' -f3 )" - if grep -qs -e '^.*.*-develop' <<< "${TAG}" ; then - echo "Found environment: DEVELOP - ${TAG}" - echo "MANIFESTS_ENVIRONMENT=develop" | tee -a "${GITHUB_ENV}" - elif grep -qs -e '^.*.*-staging' <<< "${TAG}" ; then - echo "Found environment: STAGING - ${TAG}" - echo "MANIFESTS_ENVIRONMENT=staging" | tee -a "${GITHUB_ENV}" - elif grep -qs -e '^.*.*' <<< "${TAG}" ; then - echo "No environment found, assuming: PRODUCTION - ${TAG}" - echo "MANIFESTS_ENVIRONMENT=production" | tee -a "${GITHUB_ENV}" - else - echo 'Not a valid tag. Skipping...' - exit 1 - fi - echo "TAG=$TAG" | tee -a "${GITHUB_ENV}" - VERSION="${TAG}" - echo "VERSION=${VERSION}" | tee -a "${GITHUB_ENV}" - echo "COMMIT_SHA=$GITHUB_SHA" | tee -a "${GITHUB_ENV}" - echo "IMAGE_TAG=bothubit/platform-frontend:${TAG}" | tee -a "${GITHUB_ENV}" - echo "IMAGE_SOURCE_URL=https://github.com/weni-ai/ia-platform-frontend" | tee -a "${GITHUB_ENV}" - echo "MANIFESTS_REPOSITORY=weni-ai/kubernetes-manifests-artificial-intelligence" | tee -a "${GITHUB_ENV}" - echo "MANIFESTS_APPLICATION=platform-frontend" | tee -a "${GITHUB_ENV}" - echo "MANIFESTS_PATCH_TARGET=deployment-platform-frontend.json" | tee -a "${GITHUB_ENV}" - - - name: Check out the repo - uses: actions/checkout@v3 - with: - ref: "${{env.GITHUB_SHA}}" - - - name: Set up QEMU - uses: docker/setup-qemu-action@v2 - - - name: Set up Docker Buildx - uses: docker/setup-buildx-action@v2 - - - name: Login to DockerHub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Build and push - IA Platform Frontend Image - uses: docker/build-push-action@v3 - with: - context: . - labels: | - tag=${{env.TAG}} - commit=${{env.COMMIT_SHA}} - repository=${{env.IMAGE_SOURCE_URL}} - file: Dockerfile - push: true - tags: "${{env.IMAGE_TAG}}" - no-cache: true - - - name: Check out Kubernetes Manifests - uses: actions/checkout@master - with: - ref: main - repository: "${{ env.MANIFESTS_REPOSITORY }}" - token: "${{ secrets.DEVOPS_GITHUB_PERMANENT_TOKEN }}" - path: ./kubernetes-manifests/ - - - name: Update image on deployment - run: | - which jq > /dev/null 2>&1 || ( sudo apt update ; sudo apt install -y jq ) - # Dep: coreutils - verlte() { - [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ] - } - verlt(){ - [ "$1" = "$2" ] && return 1 || verlte $1 $2 - } - export PROJECT_DIR="${{ env.MANIFESTS_APPLICATION }}" - ENV_DIR="kubernetes-manifests/${{ env.MANIFESTS_APPLICATION }}/${MANIFESTS_ENVIRONMENT}" - for e in ${ENV_DIR}; do - echo "Update ${e}:" - if [ ! -d "${e}" ] ; then - echo "${e}: Does not exist, skipping" - elif [ ! -r "${e}/kustomization.yaml" ] ; then - echo "${e}/kustomization.yaml: Does not readable, skipping" - elif [ ! -r "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" ] ; then - echo "${e}/${{ env.MANIFESTS_PATCH_TARGET }}: Does not readable, skipping" - else - OLD_IMAGE=$( - cat "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" \ - | jq '.[] | select(.path == "/spec/template/spec/containers/0/image") | .value' - ) - echo "Old image to replace: ${OLD_IMAGE}" - OLD_VERSION=$( - echo "${OLD_IMAGE}" \ - | sed s'/^.*[v:-]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/'g \ - | head -n1 - ) - echo "Old image version to compare: ${OLD_VERSION}<=${{env.VERSION}}" - if verlte "${OLD_VERSION}" "${VERSION}" || [[ ! "${OLD_VERSION}" =~ [0-9]+\.[0-9]+\.[0-9]+ ]] ; then - echo 'New configurations:' - new_configuration=$( - cat "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" \ - | jq '(..|select(.path == "/spec/template/spec/containers/0/image")?) += {value: "'"${{env.IMAGE_TAG}}"'"}' - ) - echo "${new_configuration}" - echo "${new_configuration}" > "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" - else - echo "Version in file is greater than build, skipping update yaml" - fi - fi - done - - - name: Commit & Push changes - uses: actions-js/push@master - with: - github_token: "${{ secrets.DEVOPS_GITHUB_PERMANENT_TOKEN }}" - repository: "${{ env.MANIFESTS_REPOSITORY }}" - directory: ./kubernetes-manifests/ - branch: main - message: "From IA Platform Frontend Build (Push Tag ${{ env.MANIFESTS_ENVIRONMENT }})" - - diff --git a/.github/workflows/build-ia-frontend-push-tag-shared.yaml b/.github/workflows/build-ia-frontend-push-tag-shared.yaml new file mode 100644 index 000000000..b80d7cf98 --- /dev/null +++ b/.github/workflows/build-ia-frontend-push-tag-shared.yaml @@ -0,0 +1,144 @@ +name: Build Intelligence Webapp in Shared (Push Tag) + +on: + push: + tags: + - '*.*.*-develop' + - '*.*.*-staging' + - '*.*.*' + +jobs: + docker: + runs-on: ubuntu-latest + steps: + - name: Set variables + run: | + TAG="$( echo "${GITHUB_REF}" | cut -d'/' -f3 )" + if grep -qs -e '^.*.*-develop' <<< "${TAG}" ; then + echo "Found environment: DEVELOP - ${TAG}" + echo "MANIFESTS_ENVIRONMENT=develop" | tee "${GITHUB_ENV}" + echo "OLD_IMAGE=${{ secrets.ECR }}/intelligence:webapp-develop" | tee -a "${GITHUB_ENV}" + elif grep -qs -e '^.*.*-staging' <<< "${TAG}" ; then + echo "Found environment: STAGING - ${TAG}" + echo "MANIFESTS_ENVIRONMENT=staging" | tee -a "${GITHUB_ENV}" + echo "OLD_IMAGE=${{ secrets.ECR }}/intelligence:webapp-staging" | tee -a "${GITHUB_ENV}" + elif grep -qs -e '^.*.*' <<< "${TAG}" ; then + echo "No environment found, assuming: PRODUCTION - ${TAG}" + echo "MANIFESTS_ENVIRONMENT=production" | tee -a "${GITHUB_ENV}" + echo "OLD_IMAGE=${{ secrets.ECR }}/intelligence:webapp-production" | tee -a "${GITHUB_ENV}" + else + echo 'Not a valid tag. Skipping...' + exit 1 + fi + echo "TAG=$TAG" | tee -a "${GITHUB_ENV}" + VERSION="${TAG}" + echo "VERSION=${VERSION}" | tee -a "${GITHUB_ENV}" + echo "COMMIT_SHA=$GITHUB_SHA" | tee -a "${GITHUB_ENV}" + echo "IMAGE_TAG=${{ secrets.ECR }}/intelligence:webapp-${TAG}" | tee -a "${GITHUB_ENV}" + echo "IMAGE_SOURCE_URL=https://github.com/weni-ai/intelligence-webapp" | tee -a "${GITHUB_ENV}" + echo "MANIFESTS_REPOSITORY=weni-ai/kubernetes-manifests-connect" | tee -a "${GITHUB_ENV}" + echo "MANIFESTS_APPLICATION=intelligence-webapp" | tee -a "${GITHUB_ENV}" + echo "MANIFESTS_PATCH_TARGET=deployment.json" | tee -a "${GITHUB_ENV}" + + - name: Check out the repo + uses: actions/checkout@v4 + with: + ref: "${{env.GITHUB_SHA}}" + # On non dispatch build not need the repo + #repository: Ilhasoft/weni-engine + + - name: Set up QEMU + uses: docker/setup-qemu-action@v2 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v2 + + - name: Login to ECR + uses: docker/login-action@v2 + with: + registry: ${{ secrets.ECR }} + username: ${{ secrets.AWS_ACCESS_KEY_ID_SHARED }} # Credentials used to push image to ECR repository + password: ${{ secrets.AWS_SECRET_ACCESS_KEY_SHARED }} + + - name: Build and push - Intelligence-Webapp Image + uses: docker/build-push-action@v3 + with: + context: . + labels: | + tag=${{env.TAG}} + commit=${{env.COMMIT_SHA}} + repository=${{env.IMAGE_SOURCE_URL}} + file: docker/Dockerfile + push: true + build-args: | + OLD_IMAGE=${{env.OLD_IMAGE}} + tags: | + ${{env.IMAGE_TAG}} + ${{env.OLD_IMAGE}} + no-cache: true + + - name: Check out Kubernetes Manifests + # Now, checkout in kubernetes manifests to update image in deployments patches + uses: actions/checkout@master + with: + ref: main + repository: "${{ env.MANIFESTS_REPOSITORY }}" + token: "${{ secrets.DEVOPS_GITHUB_PERMANENT_TOKEN }}" + path: ./kubernetes-manifests/ + # Its uses other path to not mix with source code repository used to build + + - name: Update image on deployment + run: | + which jq > /dev/null 2>&1 || ( sudo apt update ; sudo apt install -y jq ) + # Dep: coreutils + verlte() { + [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ] + } + verlt(){ + [ "$1" = "$2" ] && return 1 || verlte $1 $2 + } + export PROJECT_DIR="${{ env.MANIFESTS_APPLICATION }}" + ENV_DIR="kubernetes-manifests/${{ env.MANIFESTS_APPLICATION }}/${MANIFESTS_ENVIRONMENT}" + for e in ${ENV_DIR}; do + echo "Update ${e}:" + if [ ! -d "${e}" ] ; then + echo "${e}: Does not exist, skipping" + elif [ ! -r "${e}/kustomization.yaml" ] ; then + echo "${e}/kustomization.yaml: Does not readable, skipping" + elif [ ! -r "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" ] ; then + echo "${e}/${{ env.MANIFESTS_PATCH_TARGET }}: Does not readable, skipping" + else + OLD_IMAGE=$( + cat "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" \ + | jq '.[] | select(.path == "/spec/template/spec/containers/0/image") | .value' + ) + echo "Old image to replace: ${OLD_IMAGE}" + OLD_VERSION=$( + echo "${OLD_IMAGE}" \ + | sed s'/^.*[v:-]\([0-9]*\.[0-9]*\.[0-9]*\).*$/\1/'g \ + | head -n1 + ) + echo "Old image version to compare: ${OLD_VERSION}<=${{env.VERSION}}" + if verlte "${OLD_VERSION}" "${VERSION}" || [[ ! "${OLD_VERSION}" =~ [0-9]+\.[0-9]+\.[0-9]+ ]] ; then + echo 'New configurations:' + new_configuration=$( + cat "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" \ + | jq '(..|select(.path == "/spec/template/spec/containers/0/image")?) += {value: "'"${{env.IMAGE_TAG}}"'"}' + ) + echo "${new_configuration}" + echo "${new_configuration}" > "${e}/${{ env.MANIFESTS_PATCH_TARGET }}" + else + echo "Version in file is greater than build, skipping update yaml" + fi + fi + done + + - name: Commit & Push changes + # Once made a change, commit new configuration + uses: actions-js/push@master + with: + github_token: "${{ secrets.DEVOPS_GITHUB_PERMANENT_TOKEN }}" + repository: "${{ env.MANIFESTS_REPOSITORY }}" + directory: ./kubernetes-manifests/ + branch: main + message: "From Intelligence Webapp Build (Push Tag ${{ env.MANIFESTS_ENVIRONMENT }})" diff --git a/.github/workflows/crowdin-download.yaml b/.github/workflows/crowdin-download.yaml new file mode 100644 index 000000000..b4fffa7d7 --- /dev/null +++ b/.github/workflows/crowdin-download.yaml @@ -0,0 +1,33 @@ +name: Crowdin Action + +on: + schedule: + - cron: '0 20 * * *' # Every day at 8pm (UTC) - https://crontab.guru/#0_20_*_*_* + +permissions: + contents: write + pull-requests: write + +jobs: + crowdin-download: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Synchronize with Crowdin + uses: crowdin/github-action@v2 + with: + upload_sources: false + upload_translations: false + download_translations: true + localization_branch_name: crowdin_translations + + create_pull_request: true + pull_request_title: '[CROWDIN] - New translations' + pull_request_body: 'New Crowdin pull request with translations' + pull_request_base_branch_name: 'main' + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/crowdin-upload.yaml b/.github/workflows/crowdin-upload.yaml new file mode 100644 index 000000000..4381a76c3 --- /dev/null +++ b/.github/workflows/crowdin-upload.yaml @@ -0,0 +1,23 @@ +name: Crowdin Action + +on: + push: + paths: [ 'src/locales/**' ] + branches: [ main ] + +jobs: + crowdin-upload: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Crowdin push + uses: crowdin/github-action@v2 + with: + upload_sources: true + upload_translations: true + download_translations: false + env: + CROWDIN_PROJECT_ID: ${{ secrets.CROWDIN_PROJECT_ID }} + CROWDIN_PERSONAL_TOKEN: ${{ secrets.CROWDIN_PERSONAL_TOKEN }} \ No newline at end of file diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml index 32e175298..711877562 100644 --- a/.github/workflows/unit-tests.yaml +++ b/.github/workflows/unit-tests.yaml @@ -15,10 +15,18 @@ jobs: run: yarn --frozen-lockfile - name: Run lint run: yarn lint --fix - - name: Run Unit Tests - run: yarn test:unit + - name: Run Unit Tests with Coverage + run: yarn vitest run --coverage + - name: Check Coverage Threshold + run: | + COVERAGE=$(jq '.total.lines.pct' coverage/coverage-summary.json) + COVERAGE=${COVERAGE//\"/} + if [ $(echo "$COVERAGE < 70" | bc) -eq 1 ]; then + echo "Coverage is below 70%: $COVERAGE%" + exit 1 + fi - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v3 - env: - CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} - + with: + file: ./coverage/coverage-final.json + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.gitignore b/.gitignore index efbff30da..2839b75d8 100644 --- a/.gitignore +++ b/.gitignore @@ -1,57 +1,26 @@ -.DS_Store -node_modules -/dist - -# Converages -/tests/unit/coverage/ - -# local env files -.env.development -.env.local -.env.*.local - -# Log files -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* - -# Editor directories and files -.idea -.vscode -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? - -.env -/public/config.js - - -# Created by https://www.toptal.com/developers/gitignore/api/vim -# Edit at https://www.toptal.com/developers/gitignore?templates=vim - -### Vim ### -# Swap -[._]*.s[a-v][a-z] -!*.svg # comment out if you don't need vector files -[._]*.sw[a-p] -[._]s[a-rt-v][a-z] -[._]ss[a-gi-z] -[._]sw[a-p] - -# Session -Session.vim -Sessionx.vim - -# Temporary -.netrwhist -*~ -# Auto-generated tag files -tags -# Persistent undo -[._]*.un~ - -# End of https://www.toptal.com/developers/gitignore/api/vim - +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +.DS_Store +dist +dist-ssr +*.local + +/cypress/videos/ +/cypress/screenshots/ +/coverage/ + +# Editor directories and files +.idea +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? diff --git a/.nvmrc b/.nvmrc deleted file mode 100644 index dac7c8da0..000000000 --- a/.nvmrc +++ /dev/null @@ -1 +0,0 @@ -12.20.0 \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index ed4eb62ec..000000000 --- a/.prettierrc.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "$schema": "https://json.schemastore.org/prettierrc", - "semi": true, - "singleQuote": true, - "useTabs": false, - "tabWidth": 2, - "trailingComma": "all", - "printWidth": 80, - "arrowParens": "always", - "bracketSpacing": true, - "endOfLine": "lf" -} diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 0c9970f4c..000000000 --- a/.travis.yml +++ /dev/null @@ -1,6 +0,0 @@ -language: node_js -before_script: > - yarn install -script: - - yarn lint - - yarn test:unit -u diff --git a/.vscode/snippets.code-snippets b/.vscode/snippets.code-snippets new file mode 100644 index 000000000..6545d8aec --- /dev/null +++ b/.vscode/snippets.code-snippets @@ -0,0 +1,231 @@ +{ + "Alert Store": { + "scope": "javascript", + "prefix": "alertStore", + "body": [ + "import { useAlertStore } from '@/store/Alert.js';", + "", + "const alertStore = useAlertStore();", + "", + "alertStore.add({", + "\ttype: '${1|success,error,default|}',", + "\ttext: '${2}',", + "});" + ], + "description": "Add Unnnic Alert" + }, + + "Unnnic Font": { + "scope": "scss", + "prefix": "unnnic-font", + "body": [ + "color: ${1|$unnnic-color-background-solo,$unnnic-color-background-sky,$unnnic-color-background-grass,$unnnic-color-background-carpet,$unnnic-color-background-snow,$unnnic-color-background-lightest,$unnnic-color-background-white,$unnnic-color-neutral-black,$unnnic-color-neutral-darkest,$unnnic-color-neutral-dark,$unnnic-color-neutral-cloudy,$unnnic-color-neutral-cleanest,$unnnic-color-neutral-clean,$unnnic-color-neutral-soft,$unnnic-color-neutral-lightest,$unnnic-color-neutral-light,$unnnic-color-neutral-white,$unnnic-color-neutral-snow,$unnnic-color-feedback-red,$unnnic-color-feedback-green,$unnnic-color-feedback-yellow,$unnnic-color-feedback-blue,$unnnic-color-feedback-grey,$unnnic-color-aux-blue,$unnnic-color-aux-purple,$unnnic-color-aux-orange,$unnnic-color-aux-lemon,$unnnic-color-aux-pink,$unnnic-color-aux-baby-blue,$unnnic-color-aux-baby-yellow,$unnnic-color-aux-baby-red,$unnnic-color-aux-baby-green,$unnnic-color-aux-baby-pink,$unnnic-color-aux-green-100,$unnnic-color-aux-green-300,$unnnic-color-aux-green-500,$unnnic-color-aux-green-700,$unnnic-color-aux-green-900,$unnnic-color-aux-blue-100,$unnnic-color-aux-blue-300,$unnnic-color-aux-blue-500,$unnnic-color-aux-blue-700,$unnnic-color-aux-blue-900,$unnnic-color-aux-purple-100,$unnnic-color-aux-purple-300,$unnnic-color-aux-purple-500,$unnnic-color-aux-purple-700,$unnnic-color-aux-purple-900,$unnnic-color-aux-red-100,$unnnic-color-aux-red-300,$unnnic-color-aux-red-500,$unnnic-color-aux-red-700,$unnnic-color-aux-red-900,$unnnic-color-aux-orange-100,$unnnic-color-aux-orange-300,$unnnic-color-aux-orange-500,$unnnic-color-aux-orange-700,$unnnic-color-aux-orange-900,$unnnic-color-aux-yellow-100,$unnnic-color-aux-yellow-300,$unnnic-color-aux-yellow-500,$unnnic-color-aux-yellow-700,$unnnic-color-aux-yellow-900,$unnnic-color-floweditor-blue,$unnnic-color-floweditor-purple,$unnnic-color-floweditor-wine,$unnnic-color-floweditor-orange,$unnnic-color-floweditor-pink,$unnnic-color-floweditor-turquoise,$unnnic-color-floweditor-green,$unnnic-color-weni-50,$unnnic-color-weni-100,$unnnic-color-weni-200,$unnnic-color-weni-300,$unnnic-color-weni-400,$unnnic-color-weni-500,$unnnic-color-weni-600,$unnnic-color-weni-700,$unnnic-color-weni-800,$unnnic-color-weni-900,$unnnic-color-weni-950,$unnnic-color-brand-weni,$unnnic-color-brand-weni-dark,$unnnic-color-brand-weni-soft,$unnnic-color-brand-sec-dark,$unnnic-color-brand-sec-soft,$unnnic-color-brand-sec|};", + "font-family: ${2|$unnnic-font-family-secondary,$unnnic-font-family-primary|};", + "font-weight: ${3|$unnnic-font-weight-regular,$unnnic-font-weight-black,$unnnic-font-weight-bold,$unnnic-font-weight-light|};", + "font-size: ${4|$unnnic-font-size-body-gt,$unnnic-font-size-body-sm,$unnnic-font-size-body-md,$unnnic-font-size-body-lg,$unnnic-font-size-title-sm,$unnnic-font-size-title-md,$unnnic-font-size-title-lg,$unnnic-font-size-h4,$unnnic-font-size-h3,$unnnic-font-size-h2,$unnnic-font-size-h1|};", + "line-height: $4 + \\$unnnic-line-height-md;", + ], + }, + + "Unnnic Spacing 4px": { + "scope": "scss", + "prefix": "$unnnic-spacing-nano", + "body": "\\$unnnic-spacing-nano", + }, + "Unnnic Spacing 8px": { + "scope": "scss", + "prefix": "$unnnic-spacing-xs", + "body": "\\$unnnic-spacing-xs", + }, + "Unnnic Spacing 12px": { + "scope": "scss", + "prefix": "$unnnic-spacing-ant", + "body": "\\$unnnic-spacing-ant", + }, + "Unnnic Spacing 16px": { + "scope": "scss", + "prefix": "$unnnic-spacing-sm", + "body": "\\$unnnic-spacing-sm", + }, + "Unnnic Spacing 24px": { + "scope": "scss", + "prefix": "$unnnic-spacing-md", + "body": "\\$unnnic-spacing-md", + }, + "Unnnic Spacing 32px": { + "scope": "scss", + "prefix": "$unnnic-spacing-lg", + "body": "\\$unnnic-spacing-lg", + }, + "Unnnic Spacing 40px": { + "scope": "scss", + "prefix": "$unnnic-spacing-xl", + "body": "\\$unnnic-spacing-xl", + }, + "Unnnic Spacing 48px": { + "scope": "scss", + "prefix": "$unnnic-spacing-giant", + "body": "\\$unnnic-spacing-giant", + }, + "Unnnic Spacing 64px": { + "scope": "scss", + "prefix": "$unnnic-spacing-xgiant", + "body": "\\$unnnic-spacing-xgiant", + }, + "Unnnic Spacing 80px": { + "scope": "scss", + "prefix": "$unnnic-spacing-awesome", + "body": "\\$unnnic-spacing-awesome", + }, + + "Unnnic Icon Size 40px": { + "scope": "scss", + "prefix": "$unnnic-icon-size-xl", + "body": "\\$unnnic-icon-size-xl", + }, + "Unnnic Icon Size 32px": { + "scope": "scss", + "prefix": "$unnnic-icon-size-lg", + "body": "\\$unnnic-icon-size-lg", + }, + "Unnnic Icon Size 24px": { + "scope": "scss", + "prefix": "$unnnic-icon-size-md", + "body": "\\$unnnic-icon-size-md", + }, + "Unnnic Icon Size 20px": { + "scope": "scss", + "prefix": "$unnnic-icon-size-ant", + "body": "\\$unnnic-icon-size-ant", + }, + "Unnnic Icon Size 16px": { + "scope": "scss", + "prefix": "$unnnic-icon-size-sm", + "body": "\\$unnnic-icon-size-sm", + }, + "Unnnic Icon Size 12px": { + "scope": "scss", + "prefix": "$unnnic-icon-size-xs", + "body": "\\$unnnic-icon-size-xs", + }, + + "Unnnic Avatar Size 104px": { + "scope": "scss", + "prefix": "$unnnic-avatar-size-lg", + "body": "\\$unnnic-avatar-size-lg", + }, + "Unnnic Avatar Size 72px": { + "scope": "scss", + "prefix": "$unnnic-avatar-size-md", + "body": "\\$unnnic-avatar-size-md", + }, + "Unnnic Avatar Size 40px": { + "scope": "scss", + "prefix": "$unnnic-avatar-size-sm", + "body": "\\$unnnic-avatar-size-sm", + }, + "Unnnic Avatar Size 32px": { + "scope": "scss", + "prefix": "$unnnic-avatar-size-xs", + "body": "\\$unnnic-avatar-size-xs", + }, + "Unnnic Avatar Size 20px": { + "scope": "scss", + "prefix": "$unnnic-avatar-size-nano", + "body": "\\$unnnic-avatar-size-nano", + }, + + "Unnnic Border Radius 4px": { + "scope": "scss", + "prefix": "$unnnic-border-radius-sm", + "body": "\\$unnnic-border-radius-sm", + }, + "Unnnic Border Radius 8px": { + "scope": "scss", + "prefix": "$unnnic-border-radius-md", + "body": "\\$unnnic-border-radius-md", + }, + "Unnnic Border Radius 16px": { + "scope": "scss", + "prefix": "$unnnic-border-radius-lg", + "body": "\\$unnnic-border-radius-lg", + }, + "Unnnic Border Radius 600px": { + "scope": "scss", + "prefix": "$unnnic-border-radius-pill", + "body": "\\$unnnic-border-radius-pill", + }, + + "Unnnic Border Width 1px": { + "scope": "scss", + "prefix": "$unnnic-border-width-thinner", + "body": "\\$unnnic-border-width-thinner", + }, + "Unnnic Border Width 2px": { + "scope": "scss", + "prefix": "$unnnic-border-width-thin", + "body": "\\$unnnic-border-width-thin", + }, + "Unnnic Border Width 4px": { + "scope": "scss", + "prefix": "$unnnic-border-width-thick", + "body": "\\$unnnic-border-width-thick", + }, + + "Unnnic Shadow Level 0px 4px 8px rgba(0, 0, 0, .12)": { + "scope": "scss", + "prefix": "$unnnic-shadow-level-near", + "body": "\\$unnnic-shadow-level-near", + }, + "Unnnic Shadow Level 0px 8px 16px rgba(0, 0, 0, .08)": { + "scope": "scss", + "prefix": "$unnnic-shadow-level-separated", + "body": "\\$unnnic-shadow-level-separated", + }, + "Unnnic Shadow Level 0px 12px 32px rgba(0, 0, 0, .04)": { + "scope": "scss", + "prefix": "$unnnic-shadow-level-far", + "body": "\\$unnnic-shadow-level-far", + }, + "Unnnic Shadow Level 0px 20px 40px rgba(0, 0, 0, .06)": { + "scope": "scss", + "prefix": "$unnnic-shadow-level-distant", + "body": "\\$unnnic-shadow-level-distant", + }, + + "Unnnic Opacity Level 0.8": { + "scope": "scss", + "prefix": "$unnnic-opacity-level-darkest", + "body": "\\$unnnic-opacity-level-darkest", + }, + "Unnnic Opacity Level 0.64": { + "scope": "scss", + "prefix": "$unnnic-opacity-level-dark", + "body": "\\$unnnic-opacity-level-dark", + }, + "Unnnic Opacity Level 0.48": { + "scope": "scss", + "prefix": "$unnnic-opacity-level-clarifying", + "body": "\\$unnnic-opacity-level-clarifying", + }, + "Unnnic Opacity Level 0.4": { + "scope": "scss", + "prefix": "$unnnic-opacity-level-overlay", + "body": "\\$unnnic-opacity-level-overlay", + }, + "Unnnic Opacity Level 0.32": { + "scope": "scss", + "prefix": "$unnnic-opacity-level-clear", + "body": "\\$unnnic-opacity-level-clear", + }, + "Unnnic Opacity Level 0.16": { + "scope": "scss", + "prefix": "$unnnic-opacity-level-light", + "body": "\\$unnnic-opacity-level-light", + }, + "Unnnic Opacity Level 0.08": { + "scope": "scss", + "prefix": "$unnnic-opacity-level-extra-light", + "body": "\\$unnnic-opacity-level-extra-light", + }, +} \ No newline at end of file diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 186e7ba7b..000000000 --- a/Dockerfile +++ /dev/null @@ -1,23 +0,0 @@ -FROM node:18.19.1-alpine3.19 as builder - -WORKDIR /app - -RUN apk add --no-cache git - -COPY package.json yarn.lock . -RUN yarn install - -COPY . . - -RUN yarn lint --fix -RUN yarn build - -FROM nginxinc/nginx-unprivileged:1.25 - -COPY --chown=nginx:root nginx.conf /etc/nginx/nginx.conf -COPY --from=builder --chown=nginx:nginx /app/dist /app/config.js.tmpl /usr/share/nginx/html/bothub-webapp -COPY docker-entrypoint.sh / - -EXPOSE 8080 -ENTRYPOINT ["/docker-entrypoint.sh"] -CMD ["nginx", "-g", "daemon off;"] diff --git a/README.md b/README.md index 04e6001aa..d360dd2e7 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ -[![codecov](https://codecov.io/gh/weni-ai/ia-platform-frontend/branch/main/graph/badge.svg)](https://codecov.io/gh/weni-ai/ia-platform-frontend) [![License: MPL 2.0](https://img.shields.io/badge/License-MPL_2.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0) +[![codecov](https://codecov.io/github/weni-ai/intelligence-webapp/graph/badge.svg?token=CCIUMVG2HW)](https://codecov.io/github/weni-ai/intelligence-webapp) [![License: MPL 2.0](https://img.shields.io/badge/License-MPL_2.0-brightgreen.svg)](https://opensource.org/licenses/MPL-2.0) *This project is a module of [Weni](https://github.com/weni-ai) integrated inside [Weni WebApp (Connect)](https://github.com/weni-ai/weni-webapp)* @@ -21,7 +21,7 @@ Weni - Artificial Intelligence is an open platform for predicting, training and # Main Technologies -- [Vue 2](https://v2.vuejs.org/) +- [Vue 3](https://vuejs.org/) - [Sass](https://sass-lang.com/) - [i18n](https://www.i18next.com/) - [Axios](https://axios-http.com/ptbr/docs/intro) @@ -31,7 +31,7 @@ Weni - Artificial Intelligence is an open platform for predicting, training and Before running the application, make sure you have installed the following tools on your machine: -- [Node.js 14.x](https://nodejs.org/en) +- [Node.js 18.x](https://nodejs.org/en) - [NPM](https://www.npmjs.com/) or [Yarn](https://yarnpkg.com/) (recommended) # Set up @@ -39,13 +39,13 @@ Before running the application, make sure you have installed the following tools 1. Open the terminal and clone the repository ``` - git clone https://github.com/weni-ai/ia-platform-frontend.git + git clone https://github.com/weni-ai/intelligence-webapp.git ``` 2. Enter the created directory ``` - cd ia-platform-frontend + cd intelligence-webapp ``` 3. Install the dependencies: @@ -83,17 +83,17 @@ Before running the application, make sure you have installed the following tools Start the server with: ``` - yarn start + yarn dev ``` -After that, it will be available at http://localhost:8080. +After that, it will be available at http://localhost:5173. # Development Workflow | Command | Description | |--|--| | yarn | Install dependencies -| yarn start | serve with hot reload at localhost:8080 +| yarn dev | serve with hot reload at localhost:5173 | yarn build | Build for production with minification | yarn build --report | Build for production and view the bundle analyzer report | yarn lint | Show lint warnings and errors diff --git a/build-docs.sh b/build-docs.sh deleted file mode 100644 index 84d255ec2..000000000 --- a/build-docs.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -export WORKDIR=$(pwd) -export DOCSDIR="$WORKDIR/docs" -rm -rf $DOCSDIR diff --git a/config.env.js b/config.env.js deleted file mode 100644 index 92864346c..000000000 --- a/config.env.js +++ /dev/null @@ -1,42 +0,0 @@ -/* eslint-disable no-self-assign */ -/* eslint-disable max-len */ -const packageDict = require('./package.json'); - -process.env.VITE_VERSION = packageDict.version; -process.env.VITE_API_BASE_URL = - process.env.VITE_API_BASE_URL || 'http://localhost:8000/'; -process.env.VITE_BOTHUB_NLP_BASE_URL = - process.env.VITE_BOTHUB_NLP_BASE_URL || 'http://localhost:2657/'; -process.env.VITE_BOTHUB_WEBAPP_BASE_URL = - process.env.VITE_BOTHUB_WEBAPP_BASE_URL || 'http://localhost:8080/'; -process.env.VITE_VERSION_ENABLED = process.env.VITE_VERSION_ENABLED || true; -process.env.VITE_BOTHUB_WEBAPP_USE_SENTRY = - process.env.VITE_BOTHUB_WEBAPP_USE_SENTRY || false; -process.env.VITE_SUPPORTED_LANGUAGES = - process.env.VITE_SUPPORTED_LANGUAGES || 'en|pt_br'; -process.env.VITE_BOTHUB_WEBAPP_USE_HOTJAR = - process.env.VITE_BOTHUB_WEBAPP_USE_HOTJAR || false; -process.env.VITE_BOTHUB_WEBAPP_LIGHTHOUSE_KEY = - process.env.VITE_BOTHUB_WEBAPP_LIGHTHOUSE_KEY || ''; -process.env.VITE_BOTHUB_WEBAPP_LIGHTHOUSE_ALGORITHM_ARTICLE_ID = - process.env.VITE_BOTHUB_WEBAPP_LIGHTHOUSE_ALGORITHM_ARTICLE_ID || ''; -process.env.VITE_BOTHUB_WEBAPP_PAYMENT_ENABLED = - process.env.VITE_BOTHUB_WEBAPP_PAYMENT_ENABLED || false; -process.env.VITE_BOTHUB_WEBAPP_TUTORIAL_ENABLED = - process.env.VITE_BOTHUB_WEBAPP_TUTORIAL_ENABLED || false; -process.env.VITE_BOTHUB_WEBAPP_HOTJAR_ID = - process.env.VITE_BOTHUB_WEBAPP_HOTJAR_ID || ''; -process.env.VITE_MAILCHIMP_LOGIN = process.env.VITE_MAILCHIMP_LOGIN || ''; -process.env.VITE_BOTHUB_WEBAPP_SENTRY = - process.env.VITE_BOTHUB_WEBAPP_SENTRY || ''; -process.env.VITE_MAILCHIMP_DATACENTER = - process.env.VITE_MAILCHIMP_DATACENTER || ''; -process.env.VITE_MAILCHIMP_USER_ID = process.env.VITE_MAILCHIMP_USER_ID || ''; -process.env.VITE_MAILCHIMP_LIST_ID = process.env.VITE_MAILCHIMP_LIST_ID || ''; -process.env.VITE_RECAPTCHA_TOKEN = process.env.VITE_RECAPTCHA_TOKEN || ''; -process.env.VITE_HELPHERO_ID = process.env.VITE_HELPHERO_ID || ''; -process.env.VITE_HELPHERO_TOUR = process.env.VITE_HELPHERO_TOUR || ''; -process.env.VITE_QA_FLOW_CHANNEL = process.env.VITE_QA_FLOW_CHANNEL || ''; -process.env.VITE_LOGROCKET_ID = process.env.VITE_LOGROCKET_ID || ''; -process.env.VITE_LOGROCKET_PARENT_DOMAIN = - process.env.VITE_LOGROCKET_PARENT_DOMAIN || ''; diff --git a/config.js.tmpl b/config.js.tmpl index fb3b6f686..34527ce33 100644 --- a/config.js.tmpl +++ b/config.js.tmpl @@ -6,12 +6,10 @@ const runtimeVariables = (() => ({ VITE_VERSION_ENABLED: ('${VITE_VERSION_ENABLED}' || true), VITE_BOTHUB_WEBAPP_USE_SENTRY: ('${VITE_BOTHUB_WEBAPP_USE_SENTRY}' || false), VITE_SUPPORTED_LANGUAGES: ('${VITE_SUPPORTED_LANGUAGES}' || 'en|pt_br'), - VITE_BOTHUB_WEBAPP_USE_HOTJAR: ('${VITE_BOTHUB_WEBAPP_USE_HOTJAR}' || ''), VITE_BOTHUB_WEBAPP_LIGHTHOUSE_KEY: ('${VITE_BOTHUB_WEBAPP_LIGHTHOUSE_KEY}' || ''), VITE_BOTHUB_WEBAPP_LIGHTHOUSE_ALGORITHM_ARTICLE_ID: ('${VITE_BOTHUB_WEBAPP_LIGHTHOUSE_ALGORITHM_ARTICLE_ID}' || ''), VITE_BOTHUB_WEBAPP_PAYMENT_ENABLED: ('${VITE_BOTHUB_WEBAPP_PAYMENT_ENABLED}'|| false), VITE_BOTHUB_WEBAPP_TUTORIAL_ENABLED: ('${VITE_BOTHUB_WEBAPP_TUTORIAL_ENABLED}' || false), - VITE_BOTHUB_WEBAPP_HOTJAR_ID: ('${VITE_BOTHUB_WEBAPP_HOTJAR_ID}' || ''), VITE_MAILCHIMP_LOGIN: ('${VITE_MAILCHIMP_LOGIN}' || ''), VITE_BOTHUB_WEBAPP_SENTRY: ('${VITE_BOTHUB_WEBAPP_SENTRY}' || ''), VITE_MAILCHIMP_DATACENTER: ('${VITE_MAILCHIMP_DATACENTER}' || ''), @@ -26,7 +24,14 @@ const runtimeVariables = (() => ({ VITE_OPTIONS_WENIGPT: ('${VITE_OPTIONS_WENIGPT}' || ''), SENTRY_ENVIRONMENT: ('${SENTRY_ENVIRONMENT}' || ''), NEXUS_API_BASE_URL: '${NEXUS_API_BASE_URL}', + NEXUS_WEBSOCKET_BASE_URL: '${NEXUS_WEBSOCKET_BASE_URL}', FLOWS_API_BASE_URL: '${FLOWS_API_BASE_URL}', + INTELLIGENCE_LEGACY_URL: '${INTELLIGENCE_LEGACY_URL}', + KEYCLOAK_SERVER: ('${KEYCLOAK_SERVER}' || ''), + KEYCLOAK_REALM: ('${KEYCLOAK_REALM}' || ''), + HOTJAR_ID: ('${HOTJAR_ID}' || ''), + TEMPLATE_LINK_FLOW_EDITOR: '${TEMPLATE_LINK_FLOW_EDITOR}', + VITE_ORGS_CAN_CREATE_CONTENT_AI: '${VITE_ORGS_CAN_CREATE_CONTENT_AI}', get(name){ return this[name]; diff --git a/crowdin.yml b/crowdin.yml new file mode 100644 index 000000000..5d3523680 --- /dev/null +++ b/crowdin.yml @@ -0,0 +1,15 @@ + +"project_id_env": "CROWDIN_PROJECT_ID" +"api_token_env": "CROWDIN_API_TOKEN" +"base_path": "." +"base_url": "https://api.crowdin.com" + +"preserve_hierarchy": true + + +files: [ + { + "source": "src/locales/en.json", + "translation": "src/locales/%locale%.json", + } +] \ No newline at end of file diff --git a/cypress.config.js b/cypress.config.js new file mode 100644 index 000000000..5b7f54671 --- /dev/null +++ b/cypress.config.js @@ -0,0 +1,9 @@ +const { defineConfig } = require('cypress'); + +module.exports = defineConfig({ + e2e: { + setupNodeEvents(on, config) { + // implement node event listeners here + }, + }, +}); diff --git a/cypress/e2e/AgentsPersona.cy.js b/cypress/e2e/AgentsPersona.cy.js new file mode 100644 index 000000000..be6287976 --- /dev/null +++ b/cypress/e2e/AgentsPersona.cy.js @@ -0,0 +1,40 @@ +function makeURL(pathname) { + return ( + 'http://localhost:5173/loginexternal/Bearer+eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICItZ0hUeXJvR0htanBUSXZFb1V3T1luTzVDS2JFbERNc0ZCLWNXWEVDWkpRIn0.eyJleHAiOjE3MjYyOTUxNDQsImlhdCI6MTcyNjI1MTk0NCwiYXV0aF90aW1lIjoxNzI2MjUxOTQzLCJqdGkiOiI2NjEzNWExYi04YWJlLTRhMTItOTI1ZS0wYTgzNThiYmU2MGMiLCJpc3MiOiJodHRwczovL2FjY291bnRzLndlbmkuYWkvYXV0aC9yZWFsbXMvd2VuaSIsImF1ZCI6ImFjY291bnQiLCJzdWIiOiIxMDA4NGQxNi0zOTUwLTQyOTAtOTMwZS02ZmI2MzU5MmRlZWIiLCJ0eXAiOiJCZWFyZXIiLCJhenAiOiJ3ZW5pLXdlYmFwcCIsInNlc3Npb25fc3RhdGUiOiJiY2MyZmRlOS05NWM0LTRjMmQtYTA3ZC00YjNhYWM4YmI5NjUiLCJhbGxvd2VkLW9yaWdpbnMiOlsiKiIsImh0dHA6Ly93ZW5pLXdlYmFwcC1kZXZlbG9wbWVudC53ZW5pLmFpOjkwMDAvKiJdLCJyZWFsbV9hY2Nlc3MiOnsicm9sZXMiOlsib2ZmbGluZV9hY2Nlc3MiLCJ1bWFfYXV0aG9yaXphdGlvbiJdfSwicmVzb3VyY2VfYWNjZXNzIjp7ImFjY291bnQiOnsicm9sZXMiOlsibWFuYWdlLWFjY291bnQiLCJtYW5hZ2UtYWNjb3VudC1saW5rcyIsInZpZXctcHJvZmlsZSJdfX0sInNjb3BlIjoiZW1haWwgb3BlbmlkIG9mZmxpbmVfYWNjZXNzIHByb2ZpbGUiLCJzaWQiOiJiY2MyZmRlOS05NWM0LTRjMmQtYTA3ZC00YjNhYWM4YmI5NjUiLCJpZGVudGl0eV9wcm92aWRlciI6Imdvb2dsZSIsImVtYWlsX3ZlcmlmaWVkIjp0cnVlLCJuYW1lIjoiTWF0aGV1cyBDcmlzdGlhbiIsInByZWZlcnJlZF91c2VybmFtZSI6Im1hdGhldXMuY3Jpc3RpYW5Ad2VuaS5haSIsImxvY2FsZSI6ImVuIiwiZ2l2ZW5fbmFtZSI6Ik1hdGhldXMiLCJmYW1pbHlfbmFtZSI6IkNyaXN0aWFuIiwiZW1haWwiOiJtYXRoZXVzLmNyaXN0aWFuQHdlbmkuYWkifQ.Ot7x95CFKXx8OrA6fzD6P-D-9uBHoHQUGn8lw4Da8zz1W9TbFAMfyzjzSkRNVt6u1kifWjKibfKvIxEv6p-3EDkAtR-Cdxgudmny23s2ToixXSK3lS1SyfMHAioHcS7dbzeuECmyItwq_yAnZ0e9w5-QduzadiMGLqzAypbTi1VnLtRuoxsWwrjgxp7X00OuXhji83i5pqn2O59Aw9c9Qq_2EWW2iio04tS6J-2rYPQksDd9HePBhABDk55A_8E9fRD-3MWDg1Zly2-nNSHe5YwQkYVux7u36GQIgnE25SoAwjOLZAIVUEsC_o0qsDptW6mHSJXjqaMhkLGcUhlVeA/428638/3c488c2e-25f0-4ae9-8b7b-3f31455f2356/?org_uuid=70174dd0-9ae0-4115-8ec0-951eed15047b&project_uuid=3c488c2e-25f0-4ae9-8b7b-3f31455f2356&next=' + + encodeURIComponent(pathname) + ); +} + +describe('template spec', () => { + it('passes', () => { + cy.visit(makeURL('router/personalization')); + + cy.intercept( + 'GET', + 'https://nexus.weni.ai/api/3c488c2e-25f0-4ae9-8b7b-3f31455f2356/router/', + { + fixture: 'getRouter.json', + }, + ); + + cy.intercept('GET', 'https://api.bothub.it/v2/account/my-profile/', { + fixture: 'getMyProfile.json', + }); + + cy.intercept( + 'GET', + 'https://accounts.weni.ai/auth/realms/weni/protocol/openid-connect/userinfo', + { + fixture: 'getKeycloakUserinfo.json', + }, + ); + + cy.intercept( + 'GET', + 'https://nexus.weni.ai/api/4cff4cc4-db37-4fac-a441-1fc118d9f47b/content-bases/c96a89a8-5919-403f-ae06-5ddc5d15f0cf/', + { + fixture: 'getRouterContentBase.json', + }, + ); + }); +}); diff --git a/cypress/fixtures/getKeycloakUserinfo.json b/cypress/fixtures/getKeycloakUserinfo.json new file mode 100644 index 000000000..f36037ee9 --- /dev/null +++ b/cypress/fixtures/getKeycloakUserinfo.json @@ -0,0 +1,10 @@ +{ + "sub": "10084d16-3950-4290-930e-6fb63592deeb", + "email_verified": true, + "name": "Matheus Cristian", + "preferred_username": "matheus.cristian@weni.ai", + "locale": "en", + "given_name": "Matheus", + "family_name": "Cristian", + "email": "matheus.cristian@weni.ai" +} \ No newline at end of file diff --git a/cypress/fixtures/getMyProfile.json b/cypress/fixtures/getMyProfile.json new file mode 100644 index 000000000..853e28cb9 --- /dev/null +++ b/cypress/fixtures/getMyProfile.json @@ -0,0 +1,8 @@ +{ + "nickname": "matheuscristian", + "name": "Matheus Cristian", + "locale": "Maceió, Brazil", + "is_organization": false, + "biography": "Front-end Developer passionate about Vue.js", + "language": "pt-br" +} \ No newline at end of file diff --git a/cypress/fixtures/getRouter.json b/cypress/fixtures/getRouter.json new file mode 100644 index 000000000..441d8db27 --- /dev/null +++ b/cypress/fixtures/getRouter.json @@ -0,0 +1,13 @@ +{ + "uuid": "c96a89a8-5919-403f-ae06-5ddc5d15f0cf", + "created_at": "2024-04-18T14:59:51.875074Z", + "modified_at": null, + "is_active": true, + "title": "preview", + "description": null, + "language": "pt-br", + "is_router": true, + "created_by": 19537, + "modified_by": null, + "intelligence": "4cff4cc4-db37-4fac-a441-1fc118d9f47b" +} \ No newline at end of file diff --git a/cypress/fixtures/getRouterContentBase.json b/cypress/fixtures/getRouterContentBase.json new file mode 100644 index 000000000..eb0538853 --- /dev/null +++ b/cypress/fixtures/getRouterContentBase.json @@ -0,0 +1,7 @@ +{ + "uuid": "c96a89a8-5919-403f-ae06-5ddc5d15f0cf", + "title": "preview", + "description": null, + "language": "pt-br", + "is_router": true +} \ No newline at end of file diff --git a/cypress/support/commands.js b/cypress/support/commands.js new file mode 100644 index 000000000..66ea16ef0 --- /dev/null +++ b/cypress/support/commands.js @@ -0,0 +1,25 @@ +// *********************************************** +// This example commands.js shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) \ No newline at end of file diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js new file mode 100644 index 000000000..0e7290a13 --- /dev/null +++ b/cypress/support/e2e.js @@ -0,0 +1,20 @@ +// *********************************************************** +// This example support/e2e.js is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' + +// Alternatively you can use CommonJS syntax: +// require('./commands') \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 648a8c02c..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,19 +0,0 @@ -version: '3.6' - -services: - bothub-webapp: - image: ${BOTHUB_WEBAPP_DOCKER_IMAGE_NAME:-bothubit/bothub-webapp}:${BOTHUB_WEBAPP_DOCKER_IMAGE_TAG:-latest} - build: - context: . - dockerfile: Dockerfile - environment: - - VITE_API_BASE_URL=${VITE_API_BASE_URL:-http://localhost:8000} - - VITE_BOTHUB_NLP_BASE_URL=${VITE_BOTHUB_NLP_BASE_URL:-http://localhost:2657/} - - VITE_BOTHUB_WEBAPP_BASE_URL=${VITE_BOTHUB_WEBAPP_BASE_URL:-http://localhost:8080/} - - VITE_SUPPORTED_LANGUAGES=${VITE_SUPPORTED_LANGUAGES:-en|pt_br} - - VITE_MAILCHIMP_LOGIN=${VITE_MAILCHIMP_LOGIN} - - VITE_MAILCHIMP_DATACENTER=${VITE_MAILCHIMP_DATACENTER} - - VITE_MAILCHIMP_USER_ID=${VITE_MAILCHIMP_USER_ID} - - VITE_MAILCHIMP_LIST_ID=${VITE_MAILCHIMP_LIST_ID} - ports: - - 80:80 diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh deleted file mode 100755 index 1f5430f53..000000000 --- a/docker-entrypoint.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/sh - -if [ ! -f /usr/share/nginx/html/bothub-webapp/config.js ] ; then - envsubst < /usr/share/nginx/html/bothub-webapp/config.js.tmpl > /usr/share/nginx/html/bothub-webapp/config.js -fi - -exec "$@" diff --git a/docker/Dockerfile b/docker/Dockerfile new file mode 100644 index 000000000..64dcfc9ec --- /dev/null +++ b/docker/Dockerfile @@ -0,0 +1,47 @@ +# syntax = docker/dockerfile:1 + +ARG NODE_VERSION="18.19.1" +ARG BASE_VERSION="alpine3.19" +ARG OLD_IMAGE="intelligence-webapp:latest" +ARG KEEP_DAYS=60 + +FROM node:${NODE_VERSION}-${BASE_VERSION} AS builder + +WORKDIR /app + +RUN apk add --no-cache git + +COPY package.json yarn.lock ./ + +RUN --mount=type=cache,target=/root/.yarn YARN_CACHE_FOLDER=/root/.yarn yarn install + +COPY . ./ + +RUN yarn build + +RUN ls /app +RUN ls /app/dist/assets + +FROM ${OLD_IMAGE} AS old_css + +FROM nginxinc/nginx-unprivileged:1.25-alpine + +ARG KEEP_DAYS + +COPY --chown=nginx:nginx docker/nginx.conf /etc/nginx/nginx.conf +COPY --chown=nginx:nginx docker/headers /usr/share/nginx/html/headers +COPY --chown=nginx:nginx docker/file_handler.sh / +COPY docker/docker-entrypoint.sh / +COPY --from=builder --chown=nginx:nginx /app/dist /app/config.js.tmpl /usr/share/nginx/html/bothub-webapp/ +COPY --from=old_css --chown=nginx:nginx /usr/share/nginx/html/bothub-webapp/assets/all.tx[t] /usr/share/nginx/html/bothub-webapp/assets/*.css /usr/share/nginx/html/bothub-webapp/assets/ + +RUN cd /usr/share/nginx/html/bothub-webapp/ \ + && ln -s /tmp/config.js \ + && /file_handler.sh css +#mv /usr/share/nginx/html/bothub-webapp/config.js /usr/share/nginx/html/bothub-webapp/config.js.tmpl \ + +EXPOSE 8080 + +ENTRYPOINT ["/docker-entrypoint.sh"] + +CMD ["nginx", "-g", "daemon off;"] diff --git a/docker/docker-entrypoint.sh b/docker/docker-entrypoint.sh new file mode 100755 index 000000000..da4cb741b --- /dev/null +++ b/docker/docker-entrypoint.sh @@ -0,0 +1,11 @@ +#!/bin/sh + +echo "COPY VARIABLES" + +if [ ! -f /tmp/config.js ] ; then + envsubst < /usr/share/nginx/html/bothub-webapp/config.js.tmpl > /tmp/config.js +fi + +echo "RUNNING SERVER" + +exec "$@" diff --git a/docker/file_handler.sh b/docker/file_handler.sh new file mode 100755 index 000000000..c4f68bac0 --- /dev/null +++ b/docker/file_handler.sh @@ -0,0 +1,114 @@ +#!/usr/bin/env sh + +FILES="" +CURRENT_TIME=$( date +%s ) +EXPIRE_TIME=$(( CURRENT_TIME-(30*24*60*60) )) +#EXPIRE_TIME=$(( CURRENT_TIME-1 )) + +dict_keys(){ + IFS="$( printf '\t' )" + echo "$1" | while read -r KEY VALUE ; do + echo "${KEY}" + done +} + +dict_values(){ + IFS="$( printf '\t' )" + echo "$1" | while read -r KEY VALUE ; do + echo "${VALUE}" + done +} + + +dict_set(){ + has_key="false" + IFS="$( printf '\t' )" + + while read -r KEY VALUE ; do + if [ "${KEY}" = "$2" ] ; then + printf '%s\t%s\n' "$2" "$3" + has_key='true' + else + printf '%s\t%s\n' "${KEY}" "${VALUE}" + fi + done <<-EOFDICT + $1 + EOFDICT + if [ "${has_key}" = 'false' ] ; then + printf '%s\t%s\n' "$2" "$3" + fi +} + +dict_get(){ + has_key="false" + IFS="$( printf '\t' )" + + while read -r KEY VALUE ; do + if [ "${KEY}" = "$2" ] ; then + echo "${VALUE}" + has_key='true' + break + fi + done <<-EOFDICT +$1 +EOFDICT + + if [ "${has_key}" = 'false' ] ; then + echo "$3" + fi +} + +load_files(){ + while read -r file_ctime filename ; do + if [ "${file_ctime}" -le "$( dict_get "${FILES}" "${filename}" "3199999999" )" ] ; then + FILES=$( dict_set "${FILES}" "${filename}" "${file_ctime}" ) + fi + done<&2 + rm -rf "${filename}" + fi + done +} + +generate_files(){ + while read -r filename ; do + if [ -r "${filename}" ] ; then + printf '%s\t%s\n' "${CURRENT_TIME}" "${filename}" + fi + done +} + +if [ "$1" = "delete_old" ]; then + shift + load_files "$@" + delete_old_files +elif [ "$1" = "print" ] ; then + shift + load_files "$@" + #echo "$FILES" + print_files +elif [ "$1" = "generate" ] ; then + generate_files +elif [ "$1" = "css" ] ; then + load_files < assets/all.txt +fi diff --git a/src/api/__mocks__/DELETE/v2/repository/translation/1.json b/docker/headers similarity index 100% rename from src/api/__mocks__/DELETE/v2/repository/translation/1.json rename to docker/headers diff --git a/nginx.conf b/docker/nginx.conf similarity index 60% rename from nginx.conf rename to docker/nginx.conf index 92ecd4a7e..89c4aea18 100644 --- a/nginx.conf +++ b/docker/nginx.conf @@ -24,6 +24,18 @@ http { access_log /dev/stdout main; server { + set $CSP_DEFAULT "default-src 'self' blob:"; + set $CSP_SCRIPT "script-src 'self' 'unsafe-eval' 'unsafe-inline' www.googletagmanager.com *.hotjar.com www.google-analytics.com cdn.logr-ingest.com"; + set $CSP_FONT "font-src 'self' data: fonts.gstatic.com"; + set $CSP_STYLE "style-src 'self' 'unsafe-hashes' 'unsafe-inline' ilhasoft.com.br fonts.googleapis.com"; + set $CSP_IMAGE "img-src 'self' data: blob: www.google-analytics.com www.google.com.br www.googletagmanager.com *.amazonaws.com https://tile.openstreetmap.org"; + set $CSP_CONNECT "connect-src 'self' blob: *.weni.ai *.bothub.it wss://*.weni.ai www.google-analytics.com analytics.google.com *.hotjar.io wss://ws.hotjar.com https://cdn.plyr.io"; + set $CSP_FRAME_SRC "frame-src 'self' https://td.doubleclick.net"; + set $CSP_WORKER_SRC "worker-src data: blob:"; + set $CSP_FRAME_ANCESTORS "frame-ancestors 'self' *.weni.ai"; + + add_header Content-Security-Policy "${CSP_DEFAULT}; ${CSP_SCRIPT}; ${CSP_STYLE}; ${CSP_FONT}; ${CSP_IMAGE}; ${CSP_CONNECT}; ${CSP_FRAME_SRC}; ${CSP_WORKER_SRC}; ${CSP_FRAME_ANCESTORS};"; + listen 8080; server_name localhost; client_max_body_size 32m; diff --git a/index.html b/index.html index de965e2b6..fd6878916 100644 --- a/index.html +++ b/index.html @@ -1,35 +1,28 @@ - - - - - - - - - - - - - - - - Weni - - - - -
- - - - + + + + + + + + Weni + + + +
+ + + diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 000000000..0649355cf --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + } + }, + "include": ["src/**/*"] + } \ No newline at end of file diff --git a/package.json b/package.json index 4f57e391a..b50c96359 100644 --- a/package.json +++ b/package.json @@ -1,83 +1,66 @@ -{ - "name": "bothub-webapp", - "version": "2.0.0", - "description": "Bothub web application", - "author": "Weni ", - "private": true, - "scripts": { - "lint": "eslint --ext .vue,.js --ignore-path .gitignore src", - "dev": "concurrently \"vite\" \"node --watch mock/server.mjs\"", - "build": "vite build", - "serve": "vite preview", - "vca": "vca --dir src", - "test:unit": "vitest --environment jsdom" - }, - "dependencies": { - "@mdi/font": "^7.4.47", - "@sentry/browser": "^5.29.2", - "@sentry/integrations": "^5.29.2", - "@weni/unnnic-system": "^1.24.12", - "axios": "^1.6.8", - "buefy": "^0.9.28", - "bulma": "0.9.4", - "chart.js": "^2.9.4", - "cors": "^2.8.5", - "dom-to-image-more": "^3.3.0", - "dompurify": "^3.1.3", - "express": "^4.19.2", - "file-saver": "^2.0.5", - "global": "^4.4.0", - "iframessa": "^2.0.0", - "jszip": "^3.10.1", - "lodash": "^4.17.21", - "logrocket": "^8.0.1", - "lorem-ipsum": "^2.0.8", - "marked": "^12.0.2", - "qrcode.vue": "1", - "query-string": "^8.2.0", - "v-show-slide": "^1.8.3", - "vue": "^2.7.7", - "vue-code-highlight": "^0.7.8", - "vue-highlightjs": "^1.3.3", - "vue-markdown": "npm:@adapttive/vue-markdown@^4.0.0", - "vue-mc": "^0.4.0", - "vue-mc-drf-model": "https://github.com/Ilhasoft/vue-mc-drf-model", - "vue-moment": "^4.1.0", - "vue-router": "^3.5.4", - "vue-stripe-elements-plus": "^1.0.4", - "vue-tour": "^2.0.0", - "vuedraggable": "^2.24.3", - "vuex": "^3.6.2", - "xlsx-with-styles": "^0.17.2" - }, - "devDependencies": { - "@tkskto/vue-component-analyzer": "^0.8.0", - "@vitejs/plugin-legacy": "^2.0.0", - "@vitejs/plugin-vue2": "^1.1.2", - "@vue/test-utils": "^1.3.0", - "@weni/eslint-config": "^1.0.1", - "concurrently": "^8.2.2", - "eslint": "^7.32.0", - "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^4.0.0", - "eslint-plugin-vue": "^8.0.3", - "immutability-helper": "^3.1.1", - "jsdom": "^20.0.0", - "terser": "^5.14.2", - "node-sass": "^9.0.0", - "sass": "^1.75.0", - "uuid": "^9.0.1", - "vite": "^3.0.2", - "vitest": "^0.18.1", - "vue-svg-inline-loader": "^2.1.5", - "vue-template-compiler": "^2.7.7" - }, - "browserslist": [ - "> 1%", - "last 2 versions", - "not dead" - ], - "resolutions": { - "strip-ansi": "6.0.1" - } -} +{ + "name": "intelligence-webapp", + "version": "2.0.0", + "description": "Intelligence Web Application", + "author": "Weni ", + "private": true, + "scripts": { + "lint": "eslint --ext .vue,.js --ignore-path .gitignore src", + "dev": "vite", + "build": "vite build", + "preview": "vite preview --port 4173", + "test:unit": "vitest --environment jsdom", + "test:coverage": "vitest run --coverage" + }, + "dependencies": { + "@sentry/browser": "^5.29.2", + "@sentry/integrations": "^5.29.2", + "@sentry/vue": "^8.9.2", + "@weni/unnnic-system": "2.17.0", + "axios": "^1.6.8", + "cors": "^2.8.5", + "cypress": "^13.14.2", + "date-fns": "^4.1.0", + "dompurify": "^3.1.3", + "express": "^4.19.2", + "iframessa": "^2.0.0", + "lodash": "^4.17.21", + "lorem-ipsum": "^2.0.8", + "marked": "^12.0.2", + "ol": "^10.2.1", + "pinia": "^2.2.2", + "plyr": "^3.7.8", + "qrcode.vue": "3.4.1", + "vue": "^3.5.8", + "vue-i18n": "^9.13.1", + "vue-router": "^4.4.0", + "vuex": "^4.1.0" + }, + "devDependencies": { + "@pinia/testing": "^0.1.5", + "@vitejs/plugin-legacy": "^2.0.0", + "@vitejs/plugin-vue": "^5.0.5", + "@vitest/coverage-istanbul": "2.1.4", + "@vitest/ui": "2.1.4", + "@vue/compiler-sfc": "^3.4.31", + "@vue/test-utils": "^2.4.6", + "@weni/eslint-config": "^1.0.4", + "babel-eslint": "^10.1.0", + "eslint": "^7.32.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.0.0", + "eslint-plugin-vue": "^9.27.0", + "immutability-helper": "^3.1.1", + "jsdom": "^24.1.0", + "prettier": "^3.3.2", + "sass": "^1.75.0", + "terser": "^5.14.2", + "uuid": "^9.0.1", + "vite": "^3.0.2", + "vitest": "2.1.4", + "vue-eslint-parser": "^9.4.3" + }, + "resolutions": { + "strip-ansi": "6.0.1" + } +} diff --git a/public/config.js b/public/config.js index 3d511ae92..6bdac80d1 100644 --- a/public/config.js +++ b/public/config.js @@ -27,9 +27,9 @@ const runtimeVariables = (() => ({ VITE_LOGROCKET_ID: 'weni/develop', VITE_LOGROCKET_PARENT_DOMAIN: 'https://dash-develop.weni.ai/', VITE_OPTIONS_WENIGPT: - '{"golfinho-1": "runpod", "boto-1": "ft:gpt-3.5-turbo-0125:weni:wenigpt:9Fpx8jej"}', - SENTRY_ENVIRONMENT: 'develop', - + '[{"name": "shark-1", "description": "router.tunings.fields.shark-1", "model": "shark-1"}]', + SENTRY_ENVIRONMENT: 'staging', + VITE_ORGS_CAN_CREATE_CONTENT_AI: '', get(name) { return this[name]; }, diff --git a/public/favicon-16x16.png b/public/favicon-16x16.png deleted file mode 100644 index 1702d8c0f..000000000 Binary files a/public/favicon-16x16.png and /dev/null differ diff --git a/public/favicon-32x32.png b/public/favicon-32x32.png deleted file mode 100644 index ab5dcaecb..000000000 Binary files a/public/favicon-32x32.png and /dev/null differ diff --git a/public/favicon.ico b/public/favicon.ico index 66bb06467..df36fcfb7 100644 Binary files a/public/favicon.ico and b/public/favicon.ico differ diff --git a/public/manifest.json b/public/manifest.json deleted file mode 100644 index 1a09f7c9b..000000000 --- a/public/manifest.json +++ /dev/null @@ -1,29 +0,0 @@ -{ - "name": "Weni Inteligência Artificial", - "short_name": "Weni Inteligência Artificial", - "start_url": "..", - "display": "standalone", - "background_color": "#f8f8f8", - "description": "Repository of examples for training and Natural Language Processing API.", - "icons": [ - { - "src": "\/favicon-16x16.png", - "sizes": "16x16", - "type": "image\/png", - "density": "0.75" - }, - { - "src": "\/favicon-32x32.png", - "sizes": "32x32", - "type": "image\/png", - "density": "1.0" - } - ], - "related_applications": [ - { - "platform": "web", - "url": "https://bothub.it" - } - ] - } - \ No newline at end of file diff --git a/public/weni-logo-green-en.svg b/public/weni-logo-green-en.svg deleted file mode 100644 index 06524ce39..000000000 --- a/public/weni-logo-green-en.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/weni-logo-green.svg b/public/weni-logo-green.svg deleted file mode 100644 index 4b254a079..000000000 --- a/public/weni-logo-green.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/weni-logo-white-en.svg b/public/weni-logo-white-en.svg deleted file mode 100644 index 3927bbe69..000000000 --- a/public/weni-logo-white-en.svg +++ /dev/null @@ -1,22 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/weni-logo-white.svg b/public/weni-logo-white.svg deleted file mode 100644 index a557a2f72..000000000 --- a/public/weni-logo-white.svg +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/App.vue b/src/App.vue index 1cd19d420..807f43e40 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,21 +1,33 @@