diff --git a/.github/workflows/workflow.deploy.yml b/.github/workflows/workflow.deploy.yml new file mode 100644 index 0000000..b078e1c --- /dev/null +++ b/.github/workflows/workflow.deploy.yml @@ -0,0 +1,282 @@ +on: + workflow_call: + inputs: + environment: + required: true + type: string + secrets: + APP_CLIENT_ID: + required: true + APP_DOMAIN_NAME: + required: true + AZURE_BOT_NAME: + required: true + AZURE_FUNC_NAME: + required: true + AZURE_WEB_NAME: + required: true + AZURE_CREDENTIALS: + required: true + CODECOV_TOKEN: + required: true + TELEMETRY_CONNECTION_STRING: + required: true + +jobs: + build-web: + runs-on: ubuntu-latest + environment: ${{inputs.environment}} + steps: + - name: Checkout repos + uses: actions/checkout@v4 + - name: Setup Node.js 20.x + uses: actions/setup-node@v4 + with: + node-version: 20.x + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + - name: Update .env + shell: pwsh + run: | + $content = Get-Content -Path ${{env.FILE_PATH}} + $content = $content -replace "{{APP_DOMAIN_NAME}}", "${{secrets.APP_DOMAIN_NAME}}" + $content = $content -replace "{{TELEMETRY_CONNECTION_STRING}}", "${{secrets.TELEMETRY_CONNECTION_STRING}}" + Out-File -FilePath ${{env.FILE_PATH}} -InputObject $content -Encoding UTF8 + env: + FILE_PATH: source/client/.env + - name: Update package.json + run: npm version ${{vars.BUILD_VERSION}} --no-git-tag-version + working-directory: source/client + - name: Restore client + run: npm ci + working-directory: source/client + - name: Audit client + run: npm audit --omit=dev + working-directory: source/client + - name: Restore server + run: dotnet restore + working-directory: source/server + - name: Test source + shell: pwsh + run: | + dotnet test ` + Karamem0.Commistant.Tests/Karamem0.Commistant.Tests.csproj ` + --filter TestCategory=Karamem0.Commistant.Web ` + -p:AltCover=true ` + -- NUnit.TestOutputXml=${{github.workspace}}/source/server/test + working-directory: source/server + - name: Build source + shell: pwsh + run: | + dotnet publish ` + Karamem0.Commistant.Web/Karamem0.Commistant.Web.csproj ` + -c Release ` + -p:PublishDir=${{github.workspace}}/source/server/build ` + -p:Version=${{vars.BUILD_VERSION}}.${{github.run_number}} ` + -p:FileVersion=${{vars.BUILD_VERSION}}.${{github.run_number}} + working-directory: source/server + - name: Upload build files + uses: actions/upload-artifact@v4 + with: + name: commistant-web + path: source/server/build + - name: Upload test results + uses: enricomi/publish-unit-test-result-action/linux@v2 + if: always() + with: + files: source/server/test/*.xml + check_name: web-test-results + - name: Upload coverage reports + uses: codecov/codecov-action@v4 + if: always() + with: + fail_ci_if_error: true + token: ${{secrets.CODECOV_TOKEN}} + slug: karamem0/commistant + deploy-web: + needs: build-web + environment: ${{inputs.environment}} + runs-on: ubuntu-latest + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: commistant-web + path: artifact + - name: Connect to Azure + uses: azure/login@v2 + with: + creds: ${{secrets.AZURE_CREDENTIALS}} + - name: Deploy artifacts + uses: azure/webapps-deploy@v2 + with: + app-name: ${{secrets.AZURE_WEB_NAME}} + package: artifact + build-func: + runs-on: ubuntu-latest + environment: ${{inputs.environment}} + steps: + - name: Checkout repos + uses: actions/checkout@v4 + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + - name: Restore source + run: dotnet restore + working-directory: source/server + - name: Test source + shell: pwsh + run: | + dotnet test ` + Karamem0.Commistant.Tests/Karamem0.Commistant.Tests.csproj ` + --filter TestCategory=Karamem0.Commistant.Functions ` + -p:AltCover=true ` + -- NUnit.TestOutputXml=${{github.workspace}}/source/server/test + working-directory: source/server + - name: Build source + shell: pwsh + run: | + dotnet publish ` + Karamem0.Commistant.Functions/Karamem0.Commistant.Functions.csproj ` + -c Release ` + -p:PublishDir=${{github.workspace}}/source/server/build ` + -p:Version=${{vars.BUILD_VERSION}}.${{github.run_number}} ` + -p:FileVersion=${{vars.BUILD_VERSION}}.${{github.run_number}} + working-directory: source/server + - name: Upload build files + uses: actions/upload-artifact@v4 + with: + name: commistant-func + path: source/server/build + - name: Upload test results + uses: enricomi/publish-unit-test-result-action/linux@v2 + if: always() + with: + files: source/server/test/*.xml + check_name: func-test-results + - name: Upload coverage reports + uses: codecov/codecov-action@v4 + if: always() + with: + fail_ci_if_error: true + token: ${{secrets.CODECOV_TOKEN}} + slug: karamem0/commistant + deploy-func: + needs: build-func + environment: ${{inputs.environment}} + runs-on: ubuntu-latest + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: commistant-func + path: artifact + - name: Connect to Azure + uses: azure/login@v2 + with: + creds: ${{secrets.AZURE_CREDENTIALS}} + - name: Deploy artifacts + uses: azure/webapps-deploy@v2 + with: + app-name: ${{secrets.AZURE_FUNC_NAME}} + package: artifact + build-bot: + runs-on: ubuntu-latest + environment: ${{inputs.environment}} + steps: + - name: Checkout repos + uses: actions/checkout@v4 + - name: Setup .NET Core + uses: actions/setup-dotnet@v4 + with: + dotnet-version: 8.x + - name: Update index.html + shell: pwsh + run: | + $content = Get-Content -Path ${{env.FILE_PATH}} + $content = $content -replace "{{APP_DOMAIN_NAME}}", "${{secrets.APP_DOMAIN_NAME}}" + Out-File -FilePath ${{env.FILE_PATH}} -InputObject $content -Encoding UTF8 + env: + FILE_PATH: source/server/Karamem0.Commistant.Bot/wwwroot/index.html + - name: Restore source + run: dotnet restore + working-directory: source/server + - name: Test source + shell: pwsh + run: | + dotnet test ` + Karamem0.Commistant.Tests/Karamem0.Commistant.Tests.csproj ` + --filter TestCategory=Karamem0.Commistant.Bot ` + -p:AltCover=true ` + -- NUnit.TestOutputXml=${{github.workspace}}/source/server/test + working-directory: source/server + - name: Build source + shell: pwsh + run: | + dotnet publish ` + Karamem0.Commistant.Bot/Karamem0.Commistant.Bot.csproj ` + -c Release ` + -p:PublishDir=${{github.workspace}}/source/server/build ` + -p:Version=${{vars.BUILD_VERSION}}.${{github.run_number}} ` + -p:FileVersion=${{vars.BUILD_VERSION}}.${{github.run_number}} + working-directory: source/server + - name: Upload build files + uses: actions/upload-artifact@v4 + with: + name: commistant-bot + path: source/server/build + - name: Upload test results + uses: enricomi/publish-unit-test-result-action/linux@v2 + if: always() + with: + files: source/server/test/*.xml + check_name: bot-test-results + - name: Upload coverage reports + uses: codecov/codecov-action@v4 + if: always() + with: + fail_ci_if_error: true + token: ${{secrets.CODECOV_TOKEN}} + slug: karamem0/commistant + deploy-bot: + needs: build-bot + environment: ${{inputs.environment}} + runs-on: ubuntu-latest + steps: + - name: Download artifacts + uses: actions/download-artifact@v4 + with: + name: commistant-bot + path: artifact + - name: Connect to Azure + uses: azure/login@v2 + with: + creds: ${{secrets.AZURE_CREDENTIALS}} + - name: Deploy artifacts + uses: azure/webapps-deploy@v2 + with: + app-name: ${{secrets.AZURE_BOT_NAME}} + package: artifact + build-manifest: + runs-on: ubuntu-latest + steps: + - name: Checkout repos + uses: actions/checkout@v4 + - name: Update manifest.json + shell: pwsh + run: | + $content = Get-Content -Path ${{env.FILE_PATH}} + $content = $content -Replace '{{APP_CLIENT_ID}}', '${{secrets.APP_CLIENT_ID}}' + $content = $content -Replace '{{APP_DOMAIN_NAME}}', '${{secrets.APP_DOMAIN_NAME}}' + $content = $content -Replace "{{APP_VERSION}}", "${{vars.BUILD_VERSION}}" + Out-File -FilePath ${{env.FILE_PATH}} -InputObject $content -Encoding UTF8 + env: + FILE_PATH: manifest/manifest.json + - name: Upload manifest files + uses: actions/upload-artifact@v4 + with: + name: commistant-manifest + path: manifest diff --git a/.github/workflows/workflow.release.yml b/.github/workflows/workflow.release.yml new file mode 100644 index 0000000..022bfab --- /dev/null +++ b/.github/workflows/workflow.release.yml @@ -0,0 +1,39 @@ +on: + workflow_call: + inputs: + environment: + required: true + type: string + secrets: + APP_CLIENT_ID: + required: true + APP_DOMAIN_NAME: + required: true + +jobs: + create-release: + runs-on: ubuntu-latest + environment: ${{inputs.environment}} + steps: + - name: Checkout repos + uses: actions/checkout@v4 + - name: Update manifest.json + shell: pwsh + run: | + $content = Get-Content -Path ${{env.FILE_PATH}} + $content = $content -Replace '{{APP_CLIENT_ID}}', '${{secrets.APP_CLIENT_ID}}' + $content = $content -Replace '{{APP_DOMAIN_NAME}}', '${{secrets.APP_DOMAIN_NAME}}' + $content = $content -Replace "{{APP_VERSION}}", "${{vars.BUILD_VERSION}}" + Out-File -FilePath ${{env.FILE_PATH}} -InputObject $content -Encoding UTF8 + env: + FILE_PATH: manifest/manifest.json + - name: Archive manifest files + shell: pwsh + run: Compress-Archive -Path manifest/* -DestinationPath manifest_${{vars.BUILD_VERSION}}.zip + - name: Create release + uses: softprops/action-gh-release@v1 + env: + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} + with: + files: | + manifest_${{vars.BUILD_VERSION}}.zip diff --git a/.github/workflows/workflow.yml b/.github/workflows/workflow.yml index b9cad7e..8caa18b 100644 --- a/.github/workflows/workflow.yml +++ b/.github/workflows/workflow.yml @@ -6,289 +6,40 @@ on: tags: - v*.*.* -env: - BUILD_VERSION: '3.0.9' - BUILD_CONFIGURATION: Release - jobs: - select-environment: - runs-on: ubuntu-latest - steps: - - name: Select environment from branch name - id: select-environment - shell: pwsh - run: | - Write-Output "env-name=$(@{'v${{env.BUILD_VERSION}}'='production';'main'='production';'develop'='development'}['${{github.ref_name}}'])" >> $env:GITHUB_OUTPUT - outputs: - env-name: ${{steps.select-environment.outputs.env-name}} - build-web: - needs: select-environment - runs-on: ubuntu-latest - environment: ${{needs.select-environment.outputs.env-name}} - steps: - - name: Checkout repos - uses: actions/checkout@v4 - - name: Setup Node.js 20.x - uses: actions/setup-node@v4 - with: - node-version: 20.x - - name: Setup .NET Core - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.x - - name: Update .env - shell: pwsh - run: | - $content = Get-Content -Path ${{env.FILE_PATH}} - $content = $content -replace "{{APP_DOMAIN_NAME}}", "${{secrets.APP_DOMAIN_NAME}}" - $content = $content -replace "{{TELEMETRY_CONNECTION_STRING}}", "${{secrets.TELEMETRY_CONNECTION_STRING}}" - Out-File -FilePath ${{env.FILE_PATH}} -InputObject $content -Encoding UTF8 - env: - FILE_PATH: source/client/.env - - name: Update package.json - run: npm version ${{env.BUILD_VERSION}} --no-git-tag-version - working-directory: source/client - - name: Restore client - run: npm ci - working-directory: source/client - - name: Audit client - run: npm audit --omit=dev - working-directory: source/client - - name: Restore server - run: dotnet restore - working-directory: source/server - - name: Test source - shell: pwsh - run: | - dotnet test ` - Karamem0.Commistant.Tests/Karamem0.Commistant.Tests.csproj ` - --filter TestCategory=Karamem0.Commistant.Web ` - -p:AltCover=true ` - -- NUnit.TestOutputXml=${{github.workspace}}/source/server/test - working-directory: source/server - - name: Build source - shell: pwsh - run: | - dotnet publish ` - Karamem0.Commistant.Web/Karamem0.Commistant.Web.csproj ` - -c ${{env.BUILD_CONFIGURATION}} ` - -p:PublishDir=${{github.workspace}}/source/server/build ` - -p:Version=${{env.BUILD_VERSION}}.${{github.run_number}} ` - -p:FileVersion=${{env.BUILD_VERSION}}.${{github.run_number}} - working-directory: source/server - - name: Upload build files - uses: actions/upload-artifact@v4 - with: - name: commistant-web - path: source/server/build - - name: Upload test results - uses: enricomi/publish-unit-test-result-action/linux@v2 - if: always() - with: - files: source/server/test/*.xml - check_name: web-test-results - - name: Upload coverage reports - uses: codecov/codecov-action@v4 - if: always() - with: - fail_ci_if_error: true - token: ${{secrets.CODECOV_TOKEN}} - slug: karamem0/commistant - build-func: - needs: select-environment - runs-on: ubuntu-latest - environment: ${{needs.select-environment.outputs.env-name}} - steps: - - name: Checkout repos - uses: actions/checkout@v4 - - name: Setup .NET Core - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.x - - name: Restore source - run: dotnet restore - working-directory: source/server - - name: Test source - shell: pwsh - run: | - dotnet test ` - Karamem0.Commistant.Tests/Karamem0.Commistant.Tests.csproj ` - --filter TestCategory=Karamem0.Commistant.Functions ` - -p:AltCover=true ` - -- NUnit.TestOutputXml=${{github.workspace}}/source/server/test - working-directory: source/server - - name: Build source - shell: pwsh - run: | - dotnet publish ` - Karamem0.Commistant.Functions/Karamem0.Commistant.Functions.csproj ` - -c ${{env.BUILD_CONFIGURATION}} ` - -p:PublishDir=${{github.workspace}}/source/server/build ` - -p:Version=${{env.BUILD_VERSION}}.${{github.run_number}} ` - -p:FileVersion=${{env.BUILD_VERSION}}.${{github.run_number}} - working-directory: source/server - - name: Upload build files - uses: actions/upload-artifact@v4 - with: - name: commistant-func - path: source/server/build - - name: Upload test results - uses: enricomi/publish-unit-test-result-action/linux@v2 - if: always() - with: - files: source/server/test/*.xml - check_name: func-test-results - - name: Upload coverage reports - uses: codecov/codecov-action@v4 - if: always() - with: - fail_ci_if_error: true - token: ${{secrets.CODECOV_TOKEN}} - slug: karamem0/commistant - build-bot: - needs: select-environment - runs-on: ubuntu-latest - environment: ${{needs.select-environment.outputs.env-name}} - steps: - - name: Checkout repos - uses: actions/checkout@v4 - - name: Setup .NET Core - uses: actions/setup-dotnet@v4 - with: - dotnet-version: 8.x - - name: Update index.html - shell: pwsh - run: | - $content = Get-Content -Path ${{env.FILE_PATH}} - $content = $content -replace "{{APP_DOMAIN_NAME}}", "${{secrets.APP_DOMAIN_NAME}}" - Out-File -FilePath ${{env.FILE_PATH}} -InputObject $content -Encoding UTF8 - env: - FILE_PATH: source/server/Karamem0.Commistant.Bot/wwwroot/index.html - - name: Restore source - run: dotnet restore - working-directory: source/server - - name: Test source - shell: pwsh - run: | - dotnet test ` - Karamem0.Commistant.Tests/Karamem0.Commistant.Tests.csproj ` - --filter TestCategory=Karamem0.Commistant.Bot ` - -p:AltCover=true ` - -- NUnit.TestOutputXml=${{github.workspace}}/source/server/test - working-directory: source/server - - name: Build source - shell: pwsh - run: | - dotnet publish ` - Karamem0.Commistant.Bot/Karamem0.Commistant.Bot.csproj ` - -c ${{env.BUILD_CONFIGURATION}} ` - -p:PublishDir=${{github.workspace}}/source/server/build ` - -p:Version=${{env.BUILD_VERSION}}.${{github.run_number}} ` - -p:FileVersion=${{env.BUILD_VERSION}}.${{github.run_number}} - working-directory: source/server - - name: Upload build files - uses: actions/upload-artifact@v4 - with: - name: commistant-bot - path: source/server/build - - name: Upload test results - uses: enricomi/publish-unit-test-result-action/linux@v2 - if: always() - with: - files: source/server/test/*.xml - check_name: bot-test-results - - name: Upload coverage reports - uses: codecov/codecov-action@v4 - if: always() - with: - fail_ci_if_error: true - token: ${{secrets.CODECOV_TOKEN}} - slug: karamem0/commistant - build-manifest: - needs: select-environment - runs-on: ubuntu-latest - environment: ${{needs.select-environment.outputs.env-name}} - steps: - - name: Checkout repos - uses: actions/checkout@v4 - - name: Update manifest.json - shell: pwsh - run: | - $content = Get-Content -Path ${{env.FILE_PATH}} - $content = $content -Replace '{{APP_CLIENT_ID}}', '${{secrets.APP_CLIENT_ID}}' - $content = $content -Replace '{{APP_DOMAIN_NAME}}', '${{secrets.APP_DOMAIN_NAME}}' - $content = $content -Replace "{{APP_VERSION}}", "${{env.BUILD_VERSION}}" - Out-File -FilePath ${{env.FILE_PATH}} -InputObject $content -Encoding UTF8 - env: - FILE_PATH: manifest/manifest.json - - name: Upload manifest files - uses: actions/upload-artifact@v4 - with: - name: commistant-manifest - path: manifest - deploy-source: - needs: - - select-environment - - build-web - - build-func - - build-bot - if: contains(github.ref, 'refs/heads/') - environment: ${{needs.select-environment.outputs.env-name}} - runs-on: windows-latest - steps: - - name: Connect to Azure - uses: azure/login@v2 - with: - creds: ${{secrets.AZURE_CREDENTIALS}} - - name: Download web build files - uses: actions/download-artifact@v4 - with: - name: commistant-web - path: artifact/commistant-web - - name: Deploy web - uses: azure/webapps-deploy@v2 - with: - app-name: ${{secrets.AZURE_WEB_NAME}} - package: artifact/commistant-web - - name: Download bot build files - uses: actions/download-artifact@v4 - with: - name: commistant-bot - path: artifact/commistant-bot - - name: Deploy bot - uses: azure/webapps-deploy@v2 - with: - app-name: ${{secrets.AZURE_BOT_NAME}} - package: artifact/commistant-bot - - name: Download func build files - uses: actions/download-artifact@v4 - with: - name: commistant-func - path: artifact/commistant-func - - name: Deploy func - uses: azure/webapps-deploy@v2 - with: - app-name: ${{secrets.AZURE_FUNC_NAME}} - package: artifact/commistant-func - release-source: - needs: - - build-manifest + deploy-development: + if: github.ref == 'refs/heads/develop' + uses: ./.github/workflows/workflow.deploy.yml + secrets: + APP_CLIENT_ID: ${{secrets.APP_CLIENT_ID}} + APP_DOMAIN_NAME: ${{secrets.APP_DOMAIN_NAME}} + AZURE_BOT_NAME: ${{secrets.AZURE_BOT_NAME}} + AZURE_FUNC_NAME: ${{secrets.AZURE_FUNC_NAME}} + AZURE_WEB_NAME: ${{secrets.AZURE_WEB_NAME}} + AZURE_CREDENTIALS: ${{secrets.AZURE_CREDENTIALS}} + CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} + TELEMETRY_CONNECTION_STRING: ${{secrets.TELEMETRY_CONNECTION_STRING}} + with: + environment: development + deploy-production: + if: github.ref == 'refs/heads/production' + uses: ./.github/workflows/workflow.deploy.yml + secrets: + APP_CLIENT_ID: ${{secrets.APP_CLIENT_ID}} + APP_DOMAIN_NAME: ${{secrets.APP_DOMAIN_NAME}} + AZURE_BOT_NAME: ${{secrets.AZURE_BOT_NAME}} + AZURE_FUNC_NAME: ${{secrets.AZURE_FUNC_NAME}} + AZURE_WEB_NAME: ${{secrets.AZURE_WEB_NAME}} + AZURE_CREDENTIALS: ${{secrets.AZURE_CREDENTIALS}} + CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} + TELEMETRY_CONNECTION_STRING: ${{secrets.TELEMETRY_CONNECTION_STRING}} + with: + environment: production + create-release: if: contains(github.ref, 'refs/tags/') - environment: development - runs-on: ubuntu-latest - steps: - - name: Download manifest files - uses: actions/download-artifact@v4 - with: - name: commistant-manifest - path: artifact - - name: Archive manifest files - shell: pwsh - run: Compress-Archive -Path artifact/* -DestinationPath manifest_${{env.BUILD_VERSION}}.zip - - name: Create release - uses: softprops/action-gh-release@v1 - env: - GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} - with: - files: | - manifest_${{env.BUILD_VERSION}}.zip + uses: ./.github/workflows/workflow.release.yml + secrets: + APP_CLIENT_ID: ${{secrets.APP_CLIENT_ID}} + APP_DOMAIN_NAME: ${{secrets.APP_DOMAIN_NAME}} + with: + environment: production diff --git a/source/client/eslint.config.mjs b/source/client/eslint.config.mjs index 7d836bc..af9c840 100644 --- a/source/client/eslint.config.mjs +++ b/source/client/eslint.config.mjs @@ -6,14 +6,13 @@ // https://github.com/karamem0/commistant/blob/main/LICENSE // -import path from 'path'; +import { FlatCompat } from '@eslint/eslintrc'; import { fileURLToPath } from 'url'; - import { fixupConfigRules } from '@eslint/compat'; -import { FlatCompat } from '@eslint/eslintrc'; -import js from '@eslint/js'; -import hooks from 'eslint-plugin-hooks'; import globals from 'globals'; +import hooks from 'eslint-plugin-hooks'; +import js from '@eslint/js'; +import path from 'path'; const compat = new FlatCompat({ baseDirectory: path.dirname(fileURLToPath(import.meta.url)), @@ -25,7 +24,6 @@ export default [ ...fixupConfigRules(compat.extends( 'plugin:@stylistic/recommended-extends', 'plugin:@typescript-eslint/recommended', - 'plugin:import/recommended', 'plugin:react/recommended', 'plugin:react-hooks/recommended', 'plugin:sonarjs/recommended-legacy' @@ -74,7 +72,12 @@ export default [ 'no-unused-vars': 'off', 'no-use-before-define': 'off', 'no-var': 'error', - 'sort-imports': 'off', + 'sort-imports': [ + 'error', + { + 'allowSeparatedGroups': true + } + ], 'space-before-function-paren': [ 'error', { @@ -199,66 +202,6 @@ export default [ ] } ], - 'import/default': 'off', - 'import/namespace': 'off', - 'import/no-named-as-default': 'off', - 'import/no-named-as-default-member': 'off', - 'import/no-unresolved': 'off', - 'import/order': [ - 'error', - { - 'pathGroups': [ - { - 'pattern': 'react', - 'group': 'builtin', - 'position': 'before' - }, - { - 'pattern': 'react-dom/**', - 'group': 'builtin', - 'position': 'before' - }, - { - 'pattern': 'react**', - 'group': 'builtin', - 'position': 'before' - }, - { - 'pattern': '@automapper/**', - 'group': 'builtin', - 'position': 'after' - }, - { - 'pattern': '@fluentui/**', - 'group': 'builtin', - 'position': 'after' - }, - { - 'pattern': '@microsoft/**', - 'group': 'builtin', - 'position': 'after' - }, - { - 'pattern': '@azure/**', - 'group': 'builtin', - 'position': 'after' - } - ], - 'pathGroupsExcludedImportTypes': [ - 'react', - 'react-dom/**', - 'react**', - '@automapper/**', - '@fluentui/**', - '@microsoft/**', - '@azure/**' - ], - 'alphabetize': { - 'order': 'asc' - }, - 'newlines-between': 'always' - } - ], 'react/no-unknown-property': [ 'error', { diff --git a/source/client/package-lock.json b/source/client/package-lock.json index 8073bc2..311bc31 100644 --- a/source/client/package-lock.json +++ b/source/client/package-lock.json @@ -41,7 +41,6 @@ "babel-plugin-formatjs": "^10.5.16", "eslint": "^8.57.0", "eslint-plugin-hooks": "^0.4.3", - "eslint-plugin-import": "^2.29.1", "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-sonarjs": "^1.0.4", @@ -3276,9 +3275,9 @@ "license": "MIT" }, "node_modules/@microsoft/teams-js": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/@microsoft/teams-js/-/teams-js-2.26.0.tgz", - "integrity": "sha512-FaD1TLwIefAH0knfTu+wjdjPRVuL37KM5dkJV1MSsSqQ8+BpqbMu7moibNQrKlDXQ8lsNDYOXF4DPEdrgEwMgA==", + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/@microsoft/teams-js/-/teams-js-2.27.0.tgz", + "integrity": "sha512-Ow/WQiuCj89Qsi0MDPWm11CtFlzfiyoJ6Owb04js7QqRMvByMBMfqljyBRDJAU8q2uVF11qFIKyRHIQmOx8eYQ==", "license": "MIT", "dependencies": { "base64-js": "^1.3.1", @@ -3781,17 +3780,10 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/node": { - "version": "22.5.0", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.0.tgz", - "integrity": "sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg==", + "version": "22.5.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.5.1.tgz", + "integrity": "sha512-KkHsxej0j9IW1KKOOAA/XBA0z08UFSrRQHErzEfA3Vgq57eXIMYboIlHJuYIfd+lwCQjtKqUu3UnmKbtUc9yRw==", "dev": true, "license": "MIT", "optional": true, @@ -4448,27 +4440,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array.prototype.findlastindex": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", - "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2", - "es-errors": "^1.3.0", - "es-object-atoms": "^1.0.0", - "es-shim-unscopables": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/array.prototype.flat": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", @@ -5464,56 +5435,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.8.2", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.2.tgz", - "integrity": "sha512-3XnC5fDyc8M4J2E8pt8pmSVRX2M+5yWMCfI/kDZwauQeFgzQOuhcRBFKjTeJagqgk4sFKxe1mvNVnaWwImx/Tg==", - "dev": true, - "license": "MIT", - "dependencies": { - "debug": "^3.2.7" - }, - "engines": { - "node": ">=4" - }, - "peerDependenciesMeta": { - "eslint": { - "optional": true - } - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, "node_modules/eslint-plugin-hooks": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/eslint-plugin-hooks/-/eslint-plugin-hooks-0.4.3.tgz", @@ -5527,71 +5448,6 @@ "node": ">=0.10.0" } }, - "node_modules/eslint-plugin-import": { - "version": "2.29.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", - "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", - "dev": true, - "license": "MIT", - "dependencies": { - "array-includes": "^3.1.7", - "array.prototype.findlastindex": "^1.2.3", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", - "debug": "^3.2.7", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.8.0", - "hasown": "^2.0.0", - "is-core-module": "^2.13.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.fromentries": "^2.0.7", - "object.groupby": "^1.0.1", - "object.values": "^1.1.7", - "semver": "^6.3.1", - "tsconfig-paths": "^3.15.0" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/semver": { - "version": "6.3.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", - "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - } - }, "node_modules/eslint-plugin-react": { "version": "7.35.0", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.35.0.tgz", @@ -7412,16 +7268,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -7582,21 +7428,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/object.groupby": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", - "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "define-properties": "^1.2.1", - "es-abstract": "^1.23.2" - }, - "engines": { - "node": ">= 0.4" - } - }, "node_modules/object.values": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", @@ -8837,16 +8668,6 @@ "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -8861,9 +8682,9 @@ } }, "node_modules/stylelint": { - "version": "16.8.2", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.8.2.tgz", - "integrity": "sha512-fInKATippQhcSm7AB+T32GpI+626yohrg33GkFT/5jzliUw5qhlwZq2UQQwgl3HsHrf09oeARi0ZwgY/UWEv9A==", + "version": "16.9.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.9.0.tgz", + "integrity": "sha512-31Nm3WjxGOBGpQqF43o3wO9L5AC36TPIe6030Lnm13H3vDMTcS21DrLh69bMX+DBilKqMMVLian4iG6ybBoNRQ==", "dev": true, "funding": [ { @@ -8877,9 +8698,9 @@ ], "license": "MIT", "dependencies": { - "@csstools/css-parser-algorithms": "^3.0.0", - "@csstools/css-tokenizer": "^3.0.0", - "@csstools/media-query-list-parser": "^3.0.0", + "@csstools/css-parser-algorithms": "^3.0.1", + "@csstools/css-tokenizer": "^3.0.1", + "@csstools/media-query-list-parser": "^3.0.1", "@csstools/selector-specificity": "^4.0.0", "@dual-bundle/import-meta-resolve": "^4.1.0", "balanced-match": "^2.0.0", @@ -8901,7 +8722,7 @@ "known-css-properties": "^0.34.0", "mathml-tag-names": "^2.1.3", "meow": "^13.2.0", - "micromatch": "^4.0.7", + "micromatch": "^4.0.8", "normalize-path": "^3.0.0", "picocolors": "^1.0.1", "postcss": "^8.4.41", @@ -8912,7 +8733,7 @@ "resolve-from": "^5.0.0", "string-width": "^4.2.3", "strip-ansi": "^7.1.0", - "supports-hyperlinks": "^3.0.0", + "supports-hyperlinks": "^3.1.0", "svg-tags": "^1.0.0", "table": "^6.8.2", "write-file-atomic": "^5.0.1" @@ -9152,9 +8973,9 @@ } }, "node_modules/stylelint/node_modules/file-entry-cache": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", - "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.1.0.tgz", + "integrity": "sha512-/pqPFG+FdxWQj+/WSuzXSDaNzxgTLr/OrR1QuqfEZzDakpdYE70PwUxL7BPUa8hpjbvY1+qvCl8k+8Tq34xJgg==", "dev": true, "license": "MIT", "dependencies": { @@ -9401,32 +9222,6 @@ "integrity": "sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==", "license": "Unlicense" }, - "node_modules/tsconfig-paths": { - "version": "3.15.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", - "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, "node_modules/tslib": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", diff --git a/source/client/package.json b/source/client/package.json index 7acce23..c281641 100644 --- a/source/client/package.json +++ b/source/client/package.json @@ -47,7 +47,6 @@ "babel-plugin-formatjs": "^10.5.16", "eslint": "^8.57.0", "eslint-plugin-hooks": "^0.4.3", - "eslint-plugin-import": "^2.29.1", "eslint-plugin-react": "^7.35.0", "eslint-plugin-react-hooks": "^4.6.2", "eslint-plugin-sonarjs": "^1.0.4", diff --git a/source/client/src/common/components/Snackbar.presenter.tsx b/source/client/src/common/components/Snackbar.presenter.tsx index bd427a6..e8ede7a 100644 --- a/source/client/src/common/components/Snackbar.presenter.tsx +++ b/source/client/src/common/components/Snackbar.presenter.tsx @@ -8,33 +8,32 @@ import React from 'react'; -import { useIntl } from 'react-intl'; - -import { Alert } from '@fluentui/react-components/unstable'; -import { ErrorBadgeIcon } from '@fluentui/react-icons-mdl2'; - -import { css } from '@emotion/react'; - +import { + Link, + MessageBar, + MessageBarActions, + MessageBarBody, + MessageBarIntent +} from '@fluentui/react-components'; import { EventHandler } from '../../types/Event'; +import { FormattedMessage } from 'react-intl'; +import { css } from '@emotion/react'; import messages from '../messages'; -import { SnackbarType } from '../types/Snackbar'; interface SnackbarProps { + intent?: MessageBarIntent, text?: string, - type?: SnackbarType, onDismiss?: EventHandler } -function Snackbar(props: SnackbarProps) { +function Snackbar(props: Readonly) { const { + intent, text, - type, onDismiss } = props; - const intl = useIntl(); - return text ? (
- - ), - onClick: onDismiss - }}> - {text} - + + + {text} + + + + + )} /> +
) : null; diff --git a/source/client/src/common/components/Snackbar.tsx b/source/client/src/common/components/Snackbar.tsx index 73320f0..6974a60 100644 --- a/source/client/src/common/components/Snackbar.tsx +++ b/source/client/src/common/components/Snackbar.tsx @@ -8,9 +8,8 @@ import React from 'react'; -import { useSnackbar } from '../providers/SnackbarProvider'; - import Presenter from './Snackbar.presenter'; +import { useSnackbar } from '../providers/SnackbarProvider'; function Snackbar() { @@ -24,8 +23,8 @@ function Snackbar() { return ( ); diff --git a/source/client/src/common/providers/SnackbarProvider.tsx b/source/client/src/common/providers/SnackbarProvider.tsx index bb5263e..6433882 100644 --- a/source/client/src/common/providers/SnackbarProvider.tsx +++ b/source/client/src/common/providers/SnackbarProvider.tsx @@ -8,12 +8,12 @@ import React from 'react'; +import { MessageBarIntent } from '@fluentui/react-components'; import Snackbar from '../components/Snackbar'; -import { SnackbarType } from '../types/Snackbar'; interface SnackbarProps { - text?: string, - type?: SnackbarType + intent?: MessageBarIntent, + text?: string } interface SnackbarContextProps { @@ -35,7 +35,7 @@ interface SnackbarProviderProps { children?: React.ReactNode } -function SnackbarProvider(props: SnackbarProviderProps) { +function SnackbarProvider(props: Readonly) { const { children } = props; diff --git a/source/client/src/common/types/Snackbar.tsx b/source/client/src/common/types/Snackbar.tsx deleted file mode 100644 index f22b825..0000000 --- a/source/client/src/common/types/Snackbar.tsx +++ /dev/null @@ -1,14 +0,0 @@ -// -// Copyright (c) 2022-2024 karamem0 -// -// This software is released under the MIT License. -// -// https://github.com/karamem0/commistant/blob/main/LICENSE -// - -export enum SnackbarType { - error = 'error', - info = 'info', - success = 'success', - warning = 'warning' -} diff --git a/source/client/src/features/error/pages/Error404Page.presenter.tsx b/source/client/src/features/error/pages/Error404Page.presenter.tsx index f2bb834..1e5d134 100644 --- a/source/client/src/features/error/pages/Error404Page.presenter.tsx +++ b/source/client/src/features/error/pages/Error404Page.presenter.tsx @@ -9,19 +9,16 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; - import { Text } from '@fluentui/react-components'; - import { css } from '@emotion/react'; - -import { useTheme } from '../../../providers/ThemeProvider'; import messages from '../messages'; +import { useTheme } from '../../../providers/ThemeProvider'; interface Error404PageProps { error?: string } -function Error404Page(props: Error404PageProps) { +function Error404Page(props: Readonly) { const { error } = props; diff --git a/source/client/src/features/error/pages/Error404Page.tsx b/source/client/src/features/error/pages/Error404Page.tsx index a57cb35..f5bcab6 100644 --- a/source/client/src/features/error/pages/Error404Page.tsx +++ b/source/client/src/features/error/pages/Error404Page.tsx @@ -14,7 +14,7 @@ interface Error404PageProps { error?: Error } -function Error404Page(props: Error404PageProps) { +function Error404Page(props: Readonly) { const { error } = props; diff --git a/source/client/src/features/error/pages/Error500Page.presenter.tsx b/source/client/src/features/error/pages/Error500Page.presenter.tsx index b36dfdf..a196e73 100644 --- a/source/client/src/features/error/pages/Error500Page.presenter.tsx +++ b/source/client/src/features/error/pages/Error500Page.presenter.tsx @@ -9,19 +9,16 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; - import { Text } from '@fluentui/react-components'; - import { css } from '@emotion/react'; - -import { useTheme } from '../../../providers/ThemeProvider'; import messages from '../messages'; +import { useTheme } from '../../../providers/ThemeProvider'; interface Error500PageProps { error?: string } -function Error500Page(props: Error500PageProps) { +function Error500Page(props: Readonly) { const { error } = props; diff --git a/source/client/src/features/error/pages/Error500Page.tsx b/source/client/src/features/error/pages/Error500Page.tsx index 9eb1292..1b054db 100644 --- a/source/client/src/features/error/pages/Error500Page.tsx +++ b/source/client/src/features/error/pages/Error500Page.tsx @@ -14,7 +14,7 @@ interface Error500PageProps { error?: Error } -function Error500Page(props: Error500PageProps) { +function Error500Page(props: Readonly) { const { error } = props; diff --git a/source/client/src/features/home/pages/HomePage.presenter.tsx b/source/client/src/features/home/pages/HomePage.presenter.tsx index c20b51b..e1709f9 100644 --- a/source/client/src/features/home/pages/HomePage.presenter.tsx +++ b/source/client/src/features/home/pages/HomePage.presenter.tsx @@ -8,27 +8,24 @@ import React from 'react'; -import { FormattedMessage } from 'react-intl'; - import { Button, Image, Link, Text } from '@fluentui/react-components'; +import { EventHandler } from '../../../types/Event'; +import { FormattedMessage } from 'react-intl'; import { GitHubLogoIcon } from '@fluentui/react-icons-mdl2'; - import { css } from '@emotion/react'; - -import { useTheme } from '../../../providers/ThemeProvider'; -import { EventHandler } from '../../../types/Event'; import messages from '../messages'; +import { useTheme } from '../../../providers/ThemeProvider'; interface HomePageProps { onLinkClick: EventHandler } -function HomePage(props: HomePageProps) { +function HomePage(props: Readonly) { const { onLinkClick } = props; diff --git a/source/client/src/features/home/pages/HomePage.tsx b/source/client/src/features/home/pages/HomePage.tsx index 3fa4132..fc91629 100644 --- a/source/client/src/features/home/pages/HomePage.tsx +++ b/source/client/src/features/home/pages/HomePage.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { Event } from '../../../types/Event'; - import Presenter from './HomePage.presenter'; function HomePage() { diff --git a/source/client/src/features/tab/components/ScheduleDropdown.presenter.tsx b/source/client/src/features/tab/components/ScheduleDropdown.presenter.tsx index ce5cd74..05698b5 100644 --- a/source/client/src/features/tab/components/ScheduleDropdown.presenter.tsx +++ b/source/client/src/features/tab/components/ScheduleDropdown.presenter.tsx @@ -9,7 +9,6 @@ import React from 'react'; import { Dropdown, Option } from '@fluentui/react-components'; - import { EventHandler } from '../../../types/Event'; interface ScheduleDropdownProps { @@ -20,7 +19,7 @@ interface ScheduleDropdownProps { onChange?: EventHandler } -function ScheduleDropdown(props: ScheduleDropdownProps, ref: React.Ref) { +function ScheduleDropdown(props: Readonly, ref: React.Ref) { const { disabled, @@ -52,4 +51,4 @@ function ScheduleDropdown(props: ScheduleDropdownProps, ref: React.Ref } -function ScheduleDropdown(props: ScheduleDropdownProps, ref: React.Ref) { +function ScheduleDropdown(props: Readonly, ref: React.Ref) { const { disabled, diff --git a/source/client/src/features/tab/pages/ConfigurePage.presenter.tsx b/source/client/src/features/tab/pages/ConfigurePage.presenter.tsx index 09da810..7561673 100644 --- a/source/client/src/features/tab/pages/ConfigurePage.presenter.tsx +++ b/source/client/src/features/tab/pages/ConfigurePage.presenter.tsx @@ -9,13 +9,10 @@ import React from 'react'; import { FormattedMessage } from 'react-intl'; - import { Text } from '@fluentui/react-components'; - import { css } from '@emotion/react'; - -import { useTheme } from '../../../providers/ThemeProvider'; import messages from '../messages'; +import { useTheme } from '../../../providers/ThemeProvider'; function ConfigurePage() { diff --git a/source/client/src/features/tab/pages/ConfigurePage.tsx b/source/client/src/features/tab/pages/ConfigurePage.tsx index 19a0005..936f70c 100644 --- a/source/client/src/features/tab/pages/ConfigurePage.tsx +++ b/source/client/src/features/tab/pages/ConfigurePage.tsx @@ -8,13 +8,10 @@ import React from 'react'; -import { useIntl } from 'react-intl'; - import { app, pages } from '@microsoft/teams-js'; - -import messages from '../messages'; - import Presenter from './ConfigurePage.presenter'; +import messages from '../messages'; +import { useIntl } from 'react-intl'; function ConfigurePage() { @@ -23,7 +20,7 @@ function ConfigurePage() { React.useEffect(() => { (async () => { await app.initialize(); - pages.config.registerOnSaveHandler((e: pages.config.SaveEvent) => { + pages.config.registerOnSaveHandler((e: pages.config.SaveEvent) => pages.config .setConfig({ websiteUrl: window.origin, @@ -32,8 +29,8 @@ function ConfigurePage() { suggestedDisplayName: intl.formatMessage(messages.AppName) }) .then(() => e.notifySuccess()) - .catch((error) => e.notifyFailure(error)); - }); + .catch((error) => e.notifyFailure(error)) + ); pages.config.setValidityState(true); })(); }, [ diff --git a/source/client/src/features/tab/pages/PropertyPage.presenter.tsx b/source/client/src/features/tab/pages/PropertyPage.presenter.tsx index f3352ce..1b921e3 100644 --- a/source/client/src/features/tab/pages/PropertyPage.presenter.tsx +++ b/source/client/src/features/tab/pages/PropertyPage.presenter.tsx @@ -8,23 +8,20 @@ import React from 'react'; -import { Controller, useForm } from 'react-hook-form'; -import { FormattedMessage, useIntl } from 'react-intl'; - import { Button, Field, Input, Subtitle2 } from '@fluentui/react-components'; - -import { css } from '@emotion/react'; - -import { useTheme } from '../../../providers/ThemeProvider'; -import { EventHandler } from '../../../types/Event'; +import { Controller, useForm } from 'react-hook-form'; +import { FormattedMessage, useIntl } from 'react-intl'; import { ConversationPropertyFormState } from '../../../types/Form'; +import { EventHandler } from '../../../types/Event'; import ScheduleDropdown from '../components/ScheduleDropdown'; +import { css } from '@emotion/react'; import messages from '../messages'; +import { useTheme } from '../../../providers/ThemeProvider'; interface PropertyPageProps { disabled?: boolean, @@ -32,7 +29,7 @@ interface PropertyPageProps { onSubmit?: EventHandler } -function PropertyPage(props: PropertyPageProps) { +function PropertyPage(props: Readonly) { const { disabled, diff --git a/source/client/src/features/tab/pages/PropertyPage.tsx b/source/client/src/features/tab/pages/PropertyPage.tsx index 1268ff3..3547651 100644 --- a/source/client/src/features/tab/pages/PropertyPage.tsx +++ b/source/client/src/features/tab/pages/PropertyPage.tsx @@ -8,16 +8,14 @@ import React from 'react'; -import { useIntl } from 'react-intl'; - -import { useSnackbar } from '../../../common/providers/SnackbarProvider'; -import { SnackbarType } from '../../../common/types/Snackbar'; -import { mapper } from '../../../mappings/AutoMapperProfile'; -import { useTeams } from '../../../providers/TeamsProvider'; import { useGetValue, useSetValue } from '../../../services/PropertyService'; -import { Event } from '../../../types/Event'; import { ConversationPropertyFormState } from '../../../types/Form'; +import { Event } from '../../../types/Event'; +import { mapper } from '../../../mappings/AutoMapperProfile'; import messages from '../messages'; +import { useIntl } from 'react-intl'; +import { useSnackbar } from '../../../common/providers/SnackbarProvider'; +import { useTeams } from '../../../providers/TeamsProvider'; import Presenter from './PropertyPage.presenter'; @@ -55,12 +53,12 @@ function PropertyPage() { 'ConversationPropertyFormState' )); setSnackbar({ - type: SnackbarType.success, + intent: 'success', text: intl.formatMessage(messages.SaveSucceeded) }); } catch (e) { setSnackbar({ - type: SnackbarType.error, + intent: 'error', text: intl.formatMessage(messages.SaveFailed) }); } diff --git a/source/client/src/main.tsx b/source/client/src/main.tsx index 283d2a6..096d102 100644 --- a/source/client/src/main.tsx +++ b/source/client/src/main.tsx @@ -10,23 +10,21 @@ import React from 'react'; import ReactDOM from 'react-dom/client'; -import { ErrorBoundary } from 'react-error-boundary'; +import * as ress from 'ress'; import { BrowserRouter, Route, Routes } from 'react-router-dom'; - -import { Global } from '@emotion/react'; -import * as ress from 'ress'; - -import SnackbarProvider from './common/providers/SnackbarProvider'; +import ConfigurePage from './features/tab/pages/ConfigurePage'; import Error404Page from './features/error/pages/Error404Page'; import Error500Page from './features/error/pages/Error500Page'; +import { ErrorBoundary } from 'react-error-boundary'; +import { Global } from '@emotion/react'; import HomePage from './features/home/pages/HomePage'; -import ConfigurePage from './features/tab/pages/ConfigurePage'; -import PropertyPage from './features/tab/pages/PropertyPage'; import IntlProvider from './providers/IntlProvider'; +import PropertyPage from './features/tab/pages/PropertyPage'; +import SnackbarProvider from './common/providers/SnackbarProvider'; import TeamsProvider from './providers/TeamsProvider'; import TelemetryProvider from './providers/TelemetryProvider'; import ThemeProvider from './providers/ThemeProvider'; diff --git a/source/client/src/mappings/AutoMapperProfile.ts b/source/client/src/mappings/AutoMapperProfile.ts index c251c13..fd1d63b 100644 --- a/source/client/src/mappings/AutoMapperProfile.ts +++ b/source/client/src/mappings/AutoMapperProfile.ts @@ -6,16 +6,15 @@ // https://github.com/karamem0/commistant/blob/main/LICENSE // +import { PojosMetadataMap, pojos } from '@automapper/pojos'; import { createMap, createMapper, forMember, mapFrom } from '@automapper/core'; -import { pojos, PojosMetadataMap } from '@automapper/pojos'; - -import { ConversationPropertyFormState } from '../types/Form'; import { ConversationProperty } from '../types/Model'; +import { ConversationPropertyFormState } from '../types/Form'; export const mapper = createMapper({ strategyInitializer: pojos() diff --git a/source/client/src/providers/IntlProvider.tsx b/source/client/src/providers/IntlProvider.tsx index 1a13e80..b0e8f17 100644 --- a/source/client/src/providers/IntlProvider.tsx +++ b/source/client/src/providers/IntlProvider.tsx @@ -9,9 +9,9 @@ import React from 'react'; import { + MessageFormatElement, IntlProvider as Provider, - createIntl, - MessageFormatElement + createIntl } from 'react-intl'; import ja from '../translations/compiled/ja.json'; @@ -26,7 +26,7 @@ const intl = createIntl({ messages: translations[window.navigator.language.substring(0, 2)] }); -function IntlProvider(props: React.PropsWithChildren) { +function IntlProvider(props: Readonly>) { const { children } = props; diff --git a/source/client/src/providers/TeamsProvider.tsx b/source/client/src/providers/TeamsProvider.tsx index b19a306..a49fa9a 100644 --- a/source/client/src/providers/TeamsProvider.tsx +++ b/source/client/src/providers/TeamsProvider.tsx @@ -8,11 +8,9 @@ import React from 'react'; -import { useError } from 'react-use'; - import { app, authentication } from '@microsoft/teams-js'; - import axios from 'axios'; +import { useError } from 'react-use'; interface TeamsContextProps { context?: app.Context diff --git a/source/client/src/providers/ThemeProvider.tsx b/source/client/src/providers/ThemeProvider.tsx index 5766036..a5798c2 100644 --- a/source/client/src/providers/ThemeProvider.tsx +++ b/source/client/src/providers/ThemeProvider.tsx @@ -10,16 +10,13 @@ import React from 'react'; import { FluentProvider as Provider, + Theme, teamsDarkTheme, teamsHighContrastTheme, - teamsLightTheme, - Theme + teamsLightTheme } from '@fluentui/react-components'; - import { app } from '@microsoft/teams-js'; - import { css } from '@emotion/react'; - import { inTeams } from '../utils/Teams'; interface ThemeContextProps { @@ -40,7 +37,7 @@ interface ThemeProviderProps { children?: React.ReactNode } -function ThemeProvider(props: ThemeProviderProps) { +function ThemeProvider(props: Readonly) { const { children } = props; diff --git a/source/client/src/services/PropertyService.ts b/source/client/src/services/PropertyService.ts index 58663af..63fb1ff 100644 --- a/source/client/src/services/PropertyService.ts +++ b/source/client/src/services/PropertyService.ts @@ -9,10 +9,8 @@ import React from 'react'; import { useAsyncFn, useError } from 'react-use'; - -import axios from 'axios'; - import { ConversationProperty } from '../types/Model'; +import axios from 'axios'; function getValue(meetingId: string): Promise { return axios diff --git a/source/client/src/types/Event.ts b/source/client/src/types/Event.ts index fd527b4..78872ed 100644 --- a/source/client/src/types/Event.ts +++ b/source/client/src/types/Event.ts @@ -8,7 +8,7 @@ import React from 'react'; -export type Event = globalThis.Event | React.SyntheticEvent | React.SyntheticEvent | Record; +export type Event = globalThis.Event | React.SyntheticEvent | Record; export type EventHandler = ( event?: Event, diff --git a/source/server/Karamem0.Commistant.Functions/Commands/EndMeetingCommand.cs b/source/server/Karamem0.Commistant.Functions/Commands/EndMeetingCommand.cs index 9ddf1b1..6d00d89 100644 --- a/source/server/Karamem0.Commistant.Functions/Commands/EndMeetingCommand.cs +++ b/source/server/Karamem0.Commistant.Functions/Commands/EndMeetingCommand.cs @@ -90,7 +90,7 @@ public override async Task ExecuteAsync( if (string.IsNullOrEmpty(property.EndMeetingUrl) is not true) { var bytes = await this.qrCodeService.CreateAsync(property.EndMeetingUrl, cancellationToken); - var base64 = WebEncoders.Base64UrlEncode(bytes); + var base64 = Convert.ToBase64String(bytes); card.Body.Add(new AdaptiveImage() { AltText = property.InMeetingUrl, diff --git a/source/server/Karamem0.Commistant.Functions/Commands/InMeetingCommand.cs b/source/server/Karamem0.Commistant.Functions/Commands/InMeetingCommand.cs index 5af06ab..c5cf7cf 100644 --- a/source/server/Karamem0.Commistant.Functions/Commands/InMeetingCommand.cs +++ b/source/server/Karamem0.Commistant.Functions/Commands/InMeetingCommand.cs @@ -86,7 +86,7 @@ public override async Task ExecuteAsync( if (string.IsNullOrEmpty(property.InMeetingUrl) is not true) { var bytes = await this.qrCodeService.CreateAsync(property.InMeetingUrl); - var base64 = WebEncoders.Base64UrlEncode(bytes); + var base64 = Convert.ToBase64String(bytes); card.Body.Add(new AdaptiveImage() { AltText = property.InMeetingUrl, diff --git a/source/server/Karamem0.Commistant.Functions/Commands/StartMeetingCommand.cs b/source/server/Karamem0.Commistant.Functions/Commands/StartMeetingCommand.cs index a6f8748..b946203 100644 --- a/source/server/Karamem0.Commistant.Functions/Commands/StartMeetingCommand.cs +++ b/source/server/Karamem0.Commistant.Functions/Commands/StartMeetingCommand.cs @@ -90,7 +90,7 @@ public override async Task ExecuteAsync( if (string.IsNullOrEmpty(property.StartMeetingUrl) is not true) { var bytes = await this.qrCodeService.CreateAsync(property.StartMeetingUrl); - var base64 = WebEncoders.Base64UrlEncode(bytes); + var base64 = Convert.ToBase64String(bytes); card.Body.Add(new AdaptiveImage() { AltText = property.InMeetingUrl,