Browse Source

Merge branch 'master' into imprv/admin-home

Yuki Takei 2 months ago
parent
commit
a416a1ef2e
100 changed files with 699 additions and 1268 deletions
  1. 0 1
      .devcontainer/app/devcontainer.json
  2. 0 1
      .devcontainer/pdf-converter/devcontainer.json
  3. 0 88
      .eslintrc.js
  4. 2 2
      .github/workflows/ci-app.yml
  5. 1 1
      .github/workflows/ci-pdf-converter.yml
  6. 1 1
      .github/workflows/ci-slackbot-proxy.yml
  7. 5 30
      .github/workflows/release-rc.yml
  8. 11 46
      .github/workflows/release.yml
  9. 0 1
      .serena/memories/apps-app-development-patterns.md
  10. 3 13
      .serena/memories/coding_conventions.md
  11. 0 1
      .serena/memories/project_structure.md
  12. 1 2
      .serena/memories/task_completion_checklist.md
  13. 0 3
      .vscode/settings.json
  14. 1 1
      CLAUDE.md
  15. 0 199
      apps/app/.eslintrc.js
  16. 1 1
      apps/app/bin/openapi/generate-operation-ids/cli.spec.ts
  17. 1 1
      apps/app/bin/openapi/generate-operation-ids/cli.ts
  18. 1 1
      apps/app/bin/openapi/generate-operation-ids/generate-operation-ids.spec.ts
  19. 2 0
      apps/app/bin/print-memory-consumption.ts
  20. 1 2
      apps/app/config/migrate-mongo-config.js
  21. 0 1
      apps/app/config/next-i18next.config.js
  22. 0 3
      apps/app/next.config.js
  23. 0 2
      apps/app/package.json
  24. 0 16
      apps/app/playwright/.eslintrc.mjs
  25. 2 1
      apps/app/playwright/60-home/home.spec.ts
  26. 0 5
      apps/app/src/client/components/.eslintrc.js
  27. 0 11
      apps/app/src/client/components/Admin/App/AzureSetting.tsx
  28. 0 2
      apps/app/src/client/components/Admin/App/FileUploadSetting.tsx
  29. 0 7
      apps/app/src/client/components/Admin/App/GcsSetting.tsx
  30. 0 2
      apps/app/src/client/components/Admin/App/MaintenanceMode.tsx
  31. 0 1
      apps/app/src/client/components/Admin/App/MaskedInput.tsx
  32. 0 2
      apps/app/src/client/components/Admin/App/PageBulkExportSettings.tsx
  33. 0 1
      apps/app/src/client/components/Admin/App/SesSetting.tsx
  34. 0 3
      apps/app/src/client/components/Admin/App/SiteUrlSetting.tsx
  35. 0 1
      apps/app/src/client/components/Admin/App/SmtpSetting.tsx
  36. 0 1
      apps/app/src/client/components/Admin/AuditLog/AuditLogDisableMode.tsx
  37. 0 1
      apps/app/src/client/components/Admin/AuditLog/AuditLogSettings.tsx
  38. 0 1
      apps/app/src/client/components/Admin/AuditLogManagement.tsx
  39. 0 1
      apps/app/src/client/components/Admin/Common/AdminUpdateButtonRow.tsx
  40. 50 52
      apps/app/src/client/components/Admin/Customize/CustomizeLayoutSetting.tsx
  41. 50 56
      apps/app/src/client/components/Admin/Customize/CustomizeNoscriptSetting.tsx
  42. 43 45
      apps/app/src/client/components/Admin/Customize/CustomizeSidebarSetting.tsx
  43. 2 6
      apps/app/src/client/components/Admin/Customize/CustomizeThemeSetting.tsx
  44. 70 74
      apps/app/src/client/components/Admin/Customize/CustomizeTitle.tsx
  45. 0 1
      apps/app/src/client/components/Admin/ElasticsearchManagement/StatusTable.jsx
  46. 23 31
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportCollectionConfigurationModal.jsx
  47. 0 1
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportForm.jsx
  48. 0 1
      apps/app/src/client/components/Admin/ImportData/GrowiArchive/UploadForm.jsx
  49. 0 2
      apps/app/src/client/components/Admin/LegacySlackIntegration/LegacySlackIntegration.jsx
  50. 0 3
      apps/app/src/client/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx
  51. 0 1
      apps/app/src/client/components/Admin/MarkdownSetting/IndentForm.tsx
  52. 0 1
      apps/app/src/client/components/Admin/MarkdownSetting/LineBreakForm.jsx
  53. 0 4
      apps/app/src/client/components/Admin/Notification/GlobalNotification.jsx
  54. 0 3
      apps/app/src/client/components/Admin/Notification/ManageGlobalNotification.tsx
  55. 1 1
      apps/app/src/client/components/Admin/Notification/NotificationDeleteModal.jsx
  56. 1 8
      apps/app/src/client/components/Admin/Notification/NotificationSetting.jsx
  57. 1 1
      apps/app/src/client/components/Admin/Notification/TriggerEventCheckBox.jsx
  58. 1 1
      apps/app/src/client/components/Admin/Notification/UserNotificationRow.jsx
  59. 0 2
      apps/app/src/client/components/Admin/Notification/UserTriggerNotification.jsx
  60. 1 1
      apps/app/src/client/components/Admin/Security/DeleteAllShareLinksModal.jsx
  61. 202 206
      apps/app/src/client/components/Admin/Security/GitHubSecuritySettingContents.tsx
  62. 213 218
      apps/app/src/client/components/Admin/Security/GoogleSecuritySettingContents.tsx
  63. 0 12
      apps/app/src/client/components/Admin/Security/LdapSecuritySettingContents.tsx
  64. 0 1
      apps/app/src/client/components/Admin/Security/LocalSecuritySettingContents.tsx
  65. 0 2
      apps/app/src/client/components/Admin/Security/OidcSecuritySettingContents.tsx
  66. 0 4
      apps/app/src/client/components/Admin/Security/SamlSecuritySettingContents.tsx
  67. 0 2
      apps/app/src/client/components/Admin/Security/SecuritySetting/PageAccessRightsSettings.tsx
  68. 0 1
      apps/app/src/client/components/Admin/Security/SecuritySetting/PageDeleteRightsSettings.tsx
  69. 0 1
      apps/app/src/client/components/Admin/Security/SecuritySetting/SessionMaxAgeSettings.tsx
  70. 0 1
      apps/app/src/client/components/Admin/Security/SecuritySetting/UserHomepageDeletionSettings.tsx
  71. 0 2
      apps/app/src/client/components/Admin/SlackIntegration/Bridge.tsx
  72. 0 2
      apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithoutProxySecretTokenSection.jsx
  73. 1 5
      apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx
  74. 0 1
      apps/app/src/client/components/Admin/SlackIntegration/DeleteSlackBotSettingsModal.tsx
  75. 1 1
      apps/app/src/client/components/Admin/SlackIntegration/ManageCommandsProcess.jsx
  76. 1 2
      apps/app/src/client/components/Admin/SlackIntegration/ManageCommandsProcessWithoutProxy.jsx
  77. 1 7
      apps/app/src/client/components/Admin/SlackIntegration/WithProxyAccordions.jsx
  78. 0 5
      apps/app/src/client/components/Admin/UserGroupDetail/use-user-group-resource.ts
  79. 0 1
      apps/app/src/client/components/Admin/Users/GrantAdminButton.tsx
  80. 0 1
      apps/app/src/client/components/Admin/Users/GrantReadOnlyButton.tsx
  81. 0 1
      apps/app/src/client/components/Admin/Users/PasswordResetModal.jsx
  82. 0 1
      apps/app/src/client/components/Admin/Users/RevokeAdminMenuItem.tsx
  83. 0 1
      apps/app/src/client/components/Admin/Users/RevokeReadOnlyMenuItem.tsx
  84. 0 1
      apps/app/src/client/components/Admin/Users/StatusSuspendMenuItem.tsx
  85. 0 3
      apps/app/src/client/components/Admin/Users/UserInviteModal.jsx
  86. 0 1
      apps/app/src/client/components/Admin/Users/UserMenu.tsx
  87. 0 1
      apps/app/src/client/components/AlertSiteUrlUndefined.tsx
  88. 0 2
      apps/app/src/client/components/Common/CopyDropdown/CopyDropdown.tsx
  89. 0 5
      apps/app/src/client/components/Common/Dropdown/PageItemControl.tsx
  90. 0 2
      apps/app/src/client/components/Common/SubmittableInput/AutosizeSubmittableInput.tsx
  91. 0 1
      apps/app/src/client/components/Common/SubmittableInput/use-submittable.ts
  92. 0 2
      apps/app/src/client/components/LoginForm/LoginForm.tsx
  93. 0 1
      apps/app/src/client/components/Me/ProfileImageSettings.tsx
  94. 2 2
      apps/app/src/client/components/Navbar/GrowiContextualSubNavigation.tsx
  95. 0 2
      apps/app/src/client/components/NotAvailableForReadOnlyUser.tsx
  96. 0 2
      apps/app/src/client/components/PageAccessoriesModal/ShareLink/ShareLinkList.tsx
  97. 0 1
      apps/app/src/client/components/PageAttachment/DeleteAttachmentModal.tsx
  98. 0 1
      apps/app/src/client/components/PageComment/CommentEditor.tsx
  99. 1 8
      apps/app/src/client/components/PageDeleteModal/PageDeleteModal.tsx
  100. 1 3
      apps/app/src/client/components/PageEditor/Cheatsheet.tsx

+ 0 - 1
.devcontainer/app/devcontainer.json

@@ -26,7 +26,6 @@
         // AI
         // AI
         "anthropic.claude-code",
         "anthropic.claude-code",
         // linter
         // linter
-        "dbaeumer.vscode-eslint",
         "biomejs.biome",
         "biomejs.biome",
         "editorconfig.editorconfig",
         "editorconfig.editorconfig",
         "shinnn.stylelint",
         "shinnn.stylelint",

+ 0 - 1
.devcontainer/pdf-converter/devcontainer.json

@@ -15,7 +15,6 @@
   "customizations": {
   "customizations": {
     "vscode": {
     "vscode": {
       "extensions": [
       "extensions": [
-        "dbaeumer.vscode-eslint",
         "biomejs.biome",
         "biomejs.biome",
         "mhutchie.git-graph",
         "mhutchie.git-graph",
         "eamodio.gitlens"
         "eamodio.gitlens"

+ 0 - 88
.eslintrc.js

@@ -1,88 +0,0 @@
-/**
- * @type {import('eslint').Linter.Config}
- */
-module.exports = {
-  root: true, // https://eslint.org/docs/user-guide/configuring/configuration-files#cascading-and-hierarchy
-  extends: [
-    'weseek',
-    'weseek/typescript',
-  ],
-  plugins: [
-    'regex',
-  ],
-  ignorePatterns: [
-    'node_modules/**',
-  ],
-  rules: {
-    'import/prefer-default-export': 'off',
-    'import/order': [
-      'warn',
-      {
-        pathGroups: [
-          {
-            pattern: 'react',
-            group: 'builtin',
-            position: 'before',
-          },
-          {
-            pattern: '^/**',
-            group: 'parent',
-            position: 'before',
-          },
-          {
-            pattern: '~/**',
-            group: 'parent',
-            position: 'before',
-          },
-          {
-            pattern: '*.css',
-            group: 'type',
-            patternOptions: { matchBase: true },
-            position: 'after',
-          },
-          {
-            pattern: '*.scss',
-            group: 'type',
-            patternOptions: { matchBase: true },
-            position: 'after',
-          },
-        ],
-        alphabetize: {
-          order: 'asc',
-        },
-        pathGroupsExcludedImportTypes: ['react'],
-        'newlines-between': 'always',
-      },
-    ],
-    '@typescript-eslint/consistent-type-imports': 'warn',
-    '@typescript-eslint/explicit-module-boundary-types': 'off',
-    indent: [
-      'error',
-      2,
-      {
-        SwitchCase: 1,
-        ArrayExpression: 'first',
-        FunctionDeclaration: { body: 1, parameters: 2 },
-        FunctionExpression: { body: 1, parameters: 2 },
-      },
-    ],
-    'regex/invalid': ['error', [
-      {
-        regex: '\\?\\<\\!',
-        message: 'Do not use any negative lookbehind',
-      }, {
-        regex: '\\?\\<\\=',
-        message: 'Do not use any Positive lookbehind',
-      },
-    ]],
-  },
-  overrides: [
-    {
-      // enable the rule specifically for TypeScript files
-      files: ['*.ts', '*.mts', '*.tsx'],
-      rules: {
-        '@typescript-eslint/explicit-module-boundary-types': ['error'],
-      },
-    },
-  ],
-};

+ 2 - 2
.github/workflows/ci-app.yml

@@ -11,7 +11,7 @@ on:
     paths:
     paths:
       - .github/mergify.yml
       - .github/mergify.yml
       - .github/workflows/ci-app.yml
       - .github/workflows/ci-app.yml
-      - .eslint*
+      - biome.json
       - tsconfig.base.json
       - tsconfig.base.json
       - turbo.json
       - turbo.json
       - pnpm-lock.yaml
       - pnpm-lock.yaml
@@ -24,7 +24,7 @@ on:
     paths:
     paths:
       - .github/mergify.yml
       - .github/mergify.yml
       - .github/workflows/ci-app.yml
       - .github/workflows/ci-app.yml
-      - .eslint*
+      - biome.json
       - tsconfig.base.json
       - tsconfig.base.json
       - turbo.json
       - turbo.json
       - pnpm-lock.yaml
       - pnpm-lock.yaml

+ 1 - 1
.github/workflows/ci-pdf-converter.yml

@@ -9,7 +9,7 @@ on:
     paths:
     paths:
       - .github/mergify.yml
       - .github/mergify.yml
       - .github/workflows/ci-pdf-converter.yml
       - .github/workflows/ci-pdf-converter.yml
-      - .eslint*
+      - biome.json
       - tsconfig.base.json
       - tsconfig.base.json
       - turbo.json
       - turbo.json
       - pnpm-lock.yaml
       - pnpm-lock.yaml

+ 1 - 1
.github/workflows/ci-slackbot-proxy.yml

@@ -9,7 +9,7 @@ on:
     paths:
     paths:
       - .github/mergify.yml
       - .github/mergify.yml
       - .github/workflows/ci-slackbot-proxy.yml
       - .github/workflows/ci-slackbot-proxy.yml
-      - .eslint*
+      - biome.json
       - tsconfig.base.json
       - tsconfig.base.json
       - turbo.json
       - turbo.json
       - pnpm-lock.yaml
       - pnpm-lock.yaml

+ 5 - 30
.github/workflows/release-rc.yml

@@ -17,8 +17,7 @@ jobs:
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
 
 
     outputs:
     outputs:
-      TAGS_WESEEK: ${{ steps.meta-weseek.outputs.tags }}
-      TAGS_GROWILABS: ${{ steps.meta-growilabs.outputs.tags }}
+      TAGS: ${{ steps.meta.outputs.tags }}
 
 
     steps:
     steps:
     - uses: actions/checkout@v4
     - uses: actions/checkout@v4
@@ -27,19 +26,9 @@ jobs:
       uses: myrotvorets/info-from-package-json-action@v2.0.2
       uses: myrotvorets/info-from-package-json-action@v2.0.2
       id: package-json
       id: package-json
 
 
-    - name: Docker meta for weseek/growi
+    - name: Docker meta for docker.io
       uses: docker/metadata-action@v5
       uses: docker/metadata-action@v5
-      id: meta-weseek
-      with:
-        images: docker.io/weseek/growi
-        sep-tags: ','
-        tags: |
-          type=raw,value=${{ steps.package-json.outputs.packageVersion }}
-          type=raw,value=${{ steps.package-json.outputs.packageVersion }}.{{sha}}
-
-    - name: Docker meta for growilabs/growi
-      uses: docker/metadata-action@v5
-      id: meta-growilabs
+      id: meta
       with:
       with:
         images: docker.io/growilabs/growi
         images: docker.io/growilabs/growi
         sep-tags: ','
         sep-tags: ','
@@ -55,29 +44,15 @@ jobs:
     secrets:
     secrets:
       AWS_ROLE_TO_ASSUME_FOR_OIDC: ${{ secrets.AWS_ROLE_TO_ASSUME_FOR_OIDC }}
       AWS_ROLE_TO_ASSUME_FOR_OIDC: ${{ secrets.AWS_ROLE_TO_ASSUME_FOR_OIDC }}
 
 
-
-  publish-rc-image-for-growilabs:
+  publish-image-rc:
     needs: [determine-tags, build-image-rc]
     needs: [determine-tags, build-image-rc]
 
 
     uses: growilabs/growi/.github/workflows/reusable-app-create-manifests.yml@master
     uses: growilabs/growi/.github/workflows/reusable-app-create-manifests.yml@master
     with:
     with:
-      tags: ${{ needs.determine-tags.outputs.TAGS_GROWILABS }}
+      tags: ${{ needs.determine-tags.outputs.TAGS }}
       registry: docker.io
       registry: docker.io
       image-name: 'growilabs/growi'
       image-name: 'growilabs/growi'
       docker-registry-username: 'growimoogle'
       docker-registry-username: 'growimoogle'
       tag-temporary: latest-rc
       tag-temporary: latest-rc
     secrets:
     secrets:
       DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_PASSWORD_GROWIMOOGLE }}
       DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_PASSWORD_GROWIMOOGLE }}
-
-  publish-rc-image-for-weseek:
-    needs: [determine-tags, build-image-rc]
-
-    uses: growilabs/growi/.github/workflows/reusable-app-create-manifests.yml@master
-    with:
-      tags: ${{ needs.determine-tags.outputs.TAGS_WESEEK }}
-      registry: docker.io
-      image-name: 'growilabs/growi'
-      docker-registry-username: 'wsmoogle'
-      tag-temporary: latest-rc
-    secrets:
-      DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}

+ 11 - 46
.github/workflows/release.yml

@@ -1,4 +1,3 @@
-# TODO: https://redmine.weseek.co.jp/issues/171293
 name: Release
 name: Release
 
 
 on:
 on:
@@ -81,8 +80,7 @@ jobs:
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
 
 
     outputs:
     outputs:
-      TAGS_WESEEK: ${{ steps.meta-weseek.outputs.tags }}
-      TAGS_GROWILABS: ${{ steps.meta-growilabs.outputs.tags }}
+      TAGS: ${{ steps.meta.outputs.tags }}
 
 
     steps:
     steps:
     - uses: actions/checkout@v4
     - uses: actions/checkout@v4
@@ -91,21 +89,9 @@ jobs:
       uses: myrotvorets/info-from-package-json-action@v2.0.2
       uses: myrotvorets/info-from-package-json-action@v2.0.2
       id: package-json
       id: package-json
 
 
-    - name: Docker meta for weseek/growi
+    - name: Docker meta for docker.io
       uses: docker/metadata-action@v5
       uses: docker/metadata-action@v5
-      id: meta-weseek
-      with:
-        images: docker.io/weseek/growi
-        sep-tags: ','
-        tags: |
-          type=raw,value=latest
-          type=semver,value=${{ needs.create-github-release.outputs.RELEASED_VERSION }},pattern={{major}}
-          type=semver,value=${{ needs.create-github-release.outputs.RELEASED_VERSION }},pattern={{major}}.{{minor}}
-          type=semver,value=${{ needs.create-github-release.outputs.RELEASED_VERSION }},pattern={{major}}.{{minor}}.{{patch}}
-
-    - name: Docker meta for growilabs/growi
-      uses: docker/metadata-action@v5
-      id: meta-growilabs
+      id: meta
       with:
       with:
         images: docker.io/growilabs/growi
         images: docker.io/growilabs/growi
         sep-tags: ','
         sep-tags: ','
@@ -126,12 +112,12 @@ jobs:
     secrets:
     secrets:
       AWS_ROLE_TO_ASSUME_FOR_OIDC: ${{ secrets.AWS_ROLE_TO_ASSUME_FOR_OIDC }}
       AWS_ROLE_TO_ASSUME_FOR_OIDC: ${{ secrets.AWS_ROLE_TO_ASSUME_FOR_OIDC }}
 
 
-  publish-app-image-for-growilabs:
+  publish-app-image:
     needs: [determine-tags, build-app-image]
     needs: [determine-tags, build-app-image]
 
 
     uses: growilabs/growi/.github/workflows/reusable-app-create-manifests.yml@master
     uses: growilabs/growi/.github/workflows/reusable-app-create-manifests.yml@master
     with:
     with:
-      tags: ${{ needs.determine-tags.outputs.TAGS_GROWILABS }}
+      tags: ${{ needs.determine-tags.outputs.TAGS }}
       registry: docker.io
       registry: docker.io
       image-name: 'growilabs/growi'
       image-name: 'growilabs/growi'
       docker-registry-username: 'growimoogle'
       docker-registry-username: 'growimoogle'
@@ -139,42 +125,21 @@ jobs:
     secrets:
     secrets:
       DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_PASSWORD_GROWIMOOGLE }}
       DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_PASSWORD_GROWIMOOGLE }}
 
 
-  publish-app-image-for-weseek:
-    needs: [determine-tags, build-app-image]
-
-    uses: growilabs/growi/.github/workflows/reusable-app-create-manifests.yml@master
-    with:
-      tags: ${{ needs.determine-tags.outputs.TAGS_WESEEK }}
-      registry: docker.io
-      image-name: 'growilabs/growi'
-      docker-registry-username: 'wsmoogle'
-      tag-temporary: latest
-    secrets:
-      DOCKER_REGISTRY_PASSWORD: ${{ secrets.DOCKER_REGISTRY_PASSWORD }}
-
   post-publish:
   post-publish:
-    needs: [create-github-release, publish-app-image-for-growilabs, publish-app-image-for-weseek]
+    needs: [create-github-release, publish-app-image]
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
 
 
-    strategy:
-      matrix:
-        include:
-          - repository: weseek/growi
-            username: wsmoogle
-          - repository: growilabs/growi
-            username: growimoogle
-
     steps:
     steps:
     - uses: actions/checkout@v4
     - uses: actions/checkout@v4
       with:
       with:
         ref: v${{ needs.create-github-release.outputs.RELEASED_VERSION }}
         ref: v${{ needs.create-github-release.outputs.RELEASED_VERSION }}
 
 
     - name: Update Docker Hub Description
     - name: Update Docker Hub Description
-      uses: peter-evans/dockerhub-description@v4
+      uses: peter-evans/dockerhub-description@v3
       with:
       with:
-        username: ${{ matrix.username }}
-        password: ${{ (matrix.repository == 'weseek/growi' && secrets.DOCKER_REGISTRY_PASSWORD) || (matrix.repository == 'growilabs/growi' && secrets.DOCKER_REGISTRY_PASSWORD_GROWIMOOGLE) || 'INVALID_SECRET' }}
-        repository: ${{ matrix.repository }}
+        username: growimoogle
+        password: ${{ secrets.DOCKER_REGISTRY_PASSWORD_GROWIMOOGLE }}
+        repository: growilabs/growi
         readme-filepath: ./apps/app/docker/README.md
         readme-filepath: ./apps/app/docker/README.md
 
 
     - name: Slack Notification
     - name: Slack Notification
@@ -186,7 +151,7 @@ jobs:
 
 
 
 
   create-pr-for-next-rc:
   create-pr-for-next-rc:
-    needs: [create-github-release, publish-app-image-for-growilabs, publish-app-image-for-weseek]
+    needs: [create-github-release, publish-app-image]
     runs-on: ubuntu-latest
     runs-on: ubuntu-latest
 
 
     steps:
     steps:

+ 0 - 1
.serena/memories/apps-app-development-patterns.md

@@ -93,7 +93,6 @@ components/MyComponent/
 
 
 ### コード品質
 ### コード品質
 - [ ] TypeScript エラーなし
 - [ ] TypeScript エラーなし
-- [ ] ESLint ルール準拠
 - [ ] テストケース作成
 - [ ] テストケース作成
 - [ ] 型安全性確保
 - [ ] 型安全性確保
 - [ ] パフォーマンス影響確認
 - [ ] パフォーマンス影響確認

+ 3 - 13
.serena/memories/coding_conventions.md

@@ -6,19 +6,9 @@
 - **適用範囲**: 
 - **適用範囲**: 
   - dist/, node_modules/, coverage/ などは除外
   - dist/, node_modules/, coverage/ などは除外
   - .next/, bin/, config/ などのビルド成果物は除外
   - .next/, bin/, config/ などのビルド成果物は除外
-  - package.json, .eslintrc.js などの設定ファイルは除外
+  - package.json などの設定ファイルは除外
 - **推奨**: 新規開発では Biome を使用
 - **推奨**: 新規開発では Biome を使用
 
 
-### ESLint設定(廃止予定・過渡期)
-- **ベース設定**: weseek ESLint設定を使用
-- **TypeScript**: weseek/typescript 設定を適用
-- **React**: React関連のルールを適用
-- **主要なルール**:
-  - `import/prefer-default-export`: オフ(名前付きエクスポートを推奨)
-  - `import/order`: import文の順序を規定
-    - React を最初に
-    - 内部モジュール(`/**`)をparentグループの前に配置
-
 ## TypeScript設定
 ## TypeScript設定
 - **ターゲット**: ESNext
 - **ターゲット**: ESNext
 - **モジュール**: ESNext  
 - **モジュール**: ESNext  
@@ -37,7 +27,7 @@
 ## ファイル命名規則
 ## ファイル命名規則
 - TypeScript/JavaScriptファイル: キャメルケースまたはケバブケース
 - TypeScript/JavaScriptファイル: キャメルケースまたはケバブケース
 - コンポーネントファイル: PascalCase(Reactコンポーネント)
 - コンポーネントファイル: PascalCase(Reactコンポーネント)
-- 設定ファイル: ドット記法(.eslintrc.js など)
+- 設定ファイル: ドット記法(.biome.json など)
 
 
 ## テストファイル命名規則(Vitest)
 ## テストファイル命名規則(Vitest)
 vitest.workspace.mts の設定に基づく:
 vitest.workspace.mts の設定に基づく:
@@ -68,4 +58,4 @@ vitest.workspace.mts の設定に基づく:
 
 
 ## 移行ガイドライン
 ## 移行ガイドライン
 - 新規開発: Biome + Vitest を使用
 - 新規開発: Biome + Vitest を使用
-- 既存コード: 段階的に ESLint → Biome、Jest → Vitest に移行
+- 既存コード: 段階的に Jest → Vitest に移行

+ 0 - 1
.serena/memories/project_structure.md

@@ -86,5 +86,4 @@ src/
 - **turbo.json**: Turbo.jsビルド設定
 - **turbo.json**: Turbo.jsビルド設定
 - **tsconfig.base.json**: TypeScript基本設定
 - **tsconfig.base.json**: TypeScript基本設定
 - **biome.json**: Biome linter/formatter設定
 - **biome.json**: Biome linter/formatter設定
-- **.eslintrc.js**: ESLint設定(廃止予定)
 - **vitest.workspace.mts**: Vitestワークスペース設定
 - **vitest.workspace.mts**: Vitestワークスペース設定

+ 1 - 2
.serena/memories/task_completion_checklist.md

@@ -11,7 +11,6 @@ pnpm run lint:biome
 pnpm run lint
 pnpm run lint
 
 
 # 個別実行(必要に応じて)
 # 個別実行(必要に応じて)
-pnpm run lint:eslint      # ESLint(廃止予定)
 pnpm run lint:styles      # Stylelint
 pnpm run lint:styles      # Stylelint
 pnpm run lint:typecheck   # TypeScript型チェック
 pnpm run lint:typecheck   # TypeScript型チェック
 ```
 ```
@@ -82,7 +81,7 @@ pnpm run dev:migrate         # マイグレーション実行
 - 可能であればtest-with-vite/にVitestテストとして書き直し
 - 可能であればtest-with-vite/にVitestテストとして書き直し
 
 
 ## コミット前の最終チェック
 ## コミット前の最終チェック
-1. Biome(または過渡期はESLint)エラーが解消されているか
+1. Biome エラーが解消されているか
 2. Vitestテスト(または過渡期はJest)がパスしているか
 2. Vitestテスト(または過渡期はJest)がパスしているか
 3. 重要な変更はPlaywright E2Eテストも実行
 3. 重要な変更はPlaywright E2Eテストも実行
 4. ビルドが成功するか
 4. ビルドが成功するか

+ 0 - 3
.vscode/settings.json

@@ -1,8 +1,6 @@
 {
 {
   "files.eol": "\n",
   "files.eol": "\n",
 
 
-  "eslint.workingDirectories": [{ "mode": "auto" }],
-
   "[typescript]": {
   "[typescript]": {
     "editor.defaultFormatter": "biomejs.biome"
     "editor.defaultFormatter": "biomejs.biome"
   },
   },
@@ -24,7 +22,6 @@
   "scss.validate": false,
   "scss.validate": false,
 
 
   "editor.codeActionsOnSave": {
   "editor.codeActionsOnSave": {
-    "source.fixAll.eslint": "explicit",
     "source.fixAll.biome": "explicit",
     "source.fixAll.biome": "explicit",
     "source.organizeImports.biome": "explicit",
     "source.organizeImports.biome": "explicit",
     "source.fixAll.markdownlint": "explicit",
     "source.fixAll.markdownlint": "explicit",

+ 1 - 1
CLAUDE.md

@@ -31,7 +31,7 @@ GROWI is a team collaboration software using markdown - a wiki platform with hie
 
 
 ### Testing and Quality
 ### Testing and Quality
 - `turbo run test @apps/app` - Run Jest and Vitest test suites with coverage
 - `turbo run test @apps/app` - Run Jest and Vitest test suites with coverage
-- `turbo run lint @apps/app` - Run all linters (TypeScript, ESLint, Biome, Stylelint, OpenAPI)
+- `turbo run lint @apps/app` - Run all linters (TypeScript, Biome, Stylelint, OpenAPI)
 - `cd apps/app && pnpm run lint:typecheck` - TypeScript type checking only
 - `cd apps/app && pnpm run lint:typecheck` - TypeScript type checking only
 - `cd apps/app && pnpm run test:vitest` - Run Vitest unit tests
 - `cd apps/app && pnpm run test:vitest` - Run Vitest unit tests
 - `cd apps/app && pnpm run test:jest` - Run Jest integration tests
 - `cd apps/app && pnpm run test:jest` - Run Jest integration tests

+ 0 - 199
apps/app/.eslintrc.js

@@ -1,199 +0,0 @@
-/**
- * @type {import('eslint').Linter.Config}
- */
-module.exports = {
-  extends: ['next/core-web-vitals', 'weseek/react'],
-  plugins: [],
-  ignorePatterns: [
-    'dist/**',
-    '**/dist/**',
-    'transpiled/**',
-    'public/**',
-    'src/linter-checker/**',
-    'tmp/**',
-    'next-env.d.ts',
-    'next.config.js',
-    'playwright.config.ts',
-    'test/integration/global-setup.js',
-    'test/integration/global-teardown.js',
-    'test/integration/setup-crowi.ts',
-    'test/integration/crowi/**',
-    'test/integration/middlewares/**',
-    'test/integration/migrations/**',
-    'test/integration/models/**',
-    'test/integration/service/**',
-    'test/integration/setup.js',
-    'playwright/**',
-    'test-with-vite/**',
-    'public/**',
-    'bin/**',
-    'config/**',
-    'src/styles/**',
-    'src/linter-checker/**',
-    'src/migrations/**',
-    'src/models/**',
-    'src/features/**',
-    'src/stores-universal/**',
-    'src/interfaces/**',
-    'src/utils/**',
-    'src/components/**',
-    'src/client/components/DescendantsPageListModal/**',
-    'src/client/components/ItemsTree/**',
-    'src/client/components/LoginForm/**',
-    'src/client/components/Page/**',
-    'src/client/components/PageAttachment/**',
-    'src/client/components/PageDeleteModal/**',
-    'src/client/components/PageDuplicateModal/**',
-    'src/client/components/PageList/**',
-    'src/client/components/PageManagement/**',
-    'src/client/components/PagePathNavSticky/**',
-    'src/client/components/PagePresentationModal/**',
-    'src/client/components/PageRenameModal/**',
-    'src/client/components/PageSelectModal/**',
-    'src/client/components/PageSideContents/**',
-    'src/client/components/*.tsx',
-    'src/client/components/*.jsx',
-    'src/client/components/*.ts',
-    'src/client/components/*.js',
-    'src/client/components/Admin/*.ts',
-    'src/client/components/Admin/*.tsx',
-    'src/client/components/Admin/*.scss',
-    'src/client/components/Admin/AdminHome/**',
-    'src/client/components/Admin/Common/**',
-    'src/client/components/Admin/ElasticsearchManagement/**',
-    'src/client/components/Admin/ExportArchiveData/**',
-    'src/client/components/Admin/ImportData/**',
-    'src/client/components/Admin/LegacySlackIntegration/**',
-    'src/client/components/Admin/MarkdownSetting/**',
-    'src/client/components/Admin/App/**',
-    'src/client/components/Admin/AuditLog/**',
-    'src/client/components/Admin/Customize/**',
-    'src/client/components/Admin/Notification/**',
-    'src/client/components/Admin/Security/**',
-    'src/client/components/Admin/SlackIntegration/**',
-    'src/client/components/Admin/Users/**',
-    'src/client/components/Admin/UserGroup/**',
-    'src/client/components/Admin/UserGroupDetail/**',
-    'src/client/components/Me/**',
-    'src/client/components/Bookmarks/**',
-    'src/client/components/InAppNotification/**',
-    'src/client/components/PageTags/**',
-    'src/client/components/ReactMarkdownComponents/**',
-    'src/client/components/AuthorInfo/**',
-    'src/client/components/Common/**',
-    'src/client/components/CreateTemplateModal/**',
-    'src/client/components/CustomNavigation/**',
-    'src/client/components/DeleteBookmarkFolderModal/**',
-    'src/client/components/EmptyTrashModal/**',
-    'src/client/components/GrantedGroupsInheritanceSelectModal/**',
-    'src/client/components/Icons/**',
-    'src/client/components/Maintenance/**',
-    'src/client/components/PageControls/**',
-    'src/client/components/PageComment/**',
-    'src/client/components/PageAccessoriesModal/**',
-    'src/client/components/PageHistory/**',
-    'src/client/components/Presentation/**',
-    'src/client/components/PutbackPageModal/**',
-    'src/client/components/RecentActivity/**',
-    'src/client/components/RecentCreated/**',
-    'src/client/components/RevisionComparer/**',
-    'src/client/components/ShortcutsModal/**',
-    'src/client/components/StaffCredit/**',
-    'src/client/components/TemplateModal/**',
-    'src/client/components/PageEditor/**',
-    'src/client/components/Hotkeys/**',
-    'src/client/components/Navbar/**',
-    'src/client/components/PageHeader/**',
-    'src/client/components/Sidebar/**',
-    'src/services/**',
-    'src/states/**',
-    'src/stores/**',
-    'src/pages/**',
-    'src/server/crowi/**',
-    'src/server/events/**',
-    'src/server/interfaces/**',
-    'src/server/models/**',
-    'src/server/util/**',
-    'src/server/app.ts',
-    'src/server/repl.ts',
-    'src/server/middlewares/**',
-    'src/server/routes/*.js',
-    'src/server/routes/*.ts',
-    'src/server/routes/attachment/**',
-    'src/server/routes/apiv3/interfaces/**',
-    'src/server/routes/apiv3/pages/**',
-    'src/server/routes/apiv3/user/**',
-    'src/server/routes/apiv3/personal-setting/**',
-    'src/server/routes/apiv3/security-settings/**',
-    'src/server/routes/apiv3/app-settings/**',
-    'src/server/routes/apiv3/page/**',
-    'src/server/routes/apiv3/*.js',
-    'src/server/routes/apiv3/*.ts',
-    'src/server/service/*.ts',
-    'src/server/service/*.js',
-    'src/server/service/access-token/**',
-    'src/server/service/config-manager/**',
-    'src/server/service/page/**',
-    'src/server/service/page-listing/**',
-    'src/server/service/revision/**',
-    'src/server/service/s2s-messaging/**',
-    'src/server/service/search-delegator/**',
-    'src/server/service/search-reconnect-context/**',
-    'src/server/service/slack-command-handler/**',
-    'src/server/service/slack-event-handler/**',
-    'src/server/service/socket-io/**',
-    'src/server/service/system-events/**',
-    'src/server/service/user-notification/**',
-    'src/server/service/yjs/**',
-    'src/server/service/file-uploader/**',
-    'src/server/service/global-notification/**',
-    'src/server/service/growi-bridge/**',
-    'src/server/service/growi-info/**',
-    'src/server/service/import/**',
-    'src/server/service/in-app-notification/**',
-    'src/server/service/interfaces/**',
-    'src/server/service/normalize-data/**',
-    'src/server/service/page/**',
-    'src/client/interfaces/**',
-    'src/client/models/**',
-    'src/client/services/**',
-    'src/client/util/**',
-  ],
-  settings: {
-    // resolve path aliases by eslint-import-resolver-typescript
-    'import/resolver': {
-      typescript: {},
-    },
-  },
-  rules: {
-    'space-before-function-paren': 'off',
-    '@typescript-eslint/no-var-requires': 'off',
-
-    // set 'warn' temporarily -- 2021.08.02 Yuki Takei
-    '@typescript-eslint/no-use-before-define': ['warn'],
-    '@typescript-eslint/no-this-alias': ['warn'],
-  },
-  overrides: [
-    {
-      // enable the rule specifically for JavaScript files
-      files: ['*.js', '*.mjs', '*.jsx'],
-      rules: {
-        // set 'warn' temporarily -- 2023.08.14 Yuki Takei
-        'react/prop-types': 'warn',
-        // set 'warn' temporarily -- 2023.08.14 Yuki Takei
-        'no-unused-vars': ['warn'],
-      },
-    },
-    {
-      // enable the rule specifically for TypeScript files
-      files: ['*.ts', '*.mts', '*.tsx'],
-      rules: {
-        'no-unused-vars': 'off',
-        // set 'warn' temporarily -- 2023.08.14 Yuki Takei
-        'react/prop-types': 'warn',
-        // set 'warn' temporarily -- 2022.07.25 Yuki Takei
-        '@typescript-eslint/explicit-module-boundary-types': ['warn'],
-      },
-    },
-  ],
-};

+ 1 - 1
apps/app/bin/openapi/generate-operation-ids/cli.spec.ts

@@ -90,7 +90,7 @@ describe('cli', () => {
     await cliModule.main();
     await cliModule.main();
 
 
     // Verify error was logged
     // Verify error was logged
-    // eslint-disable-next-line no-console
+    // biome-ignore lint/suspicious/noConsole: This is a test file
     expect(console.error).toHaveBeenCalledWith(error);
     expect(console.error).toHaveBeenCalledWith(error);
 
 
     // Verify writeFileSync was not called
     // Verify writeFileSync was not called

+ 1 - 1
apps/app/bin/openapi/generate-operation-ids/cli.ts

@@ -16,9 +16,9 @@ export const main = async (): Promise<void> => {
   const { out: outputFile, overwriteExisting } = program.opts();
   const { out: outputFile, overwriteExisting } = program.opts();
   const [inputFile] = program.args;
   const [inputFile] = program.args;
 
 
-  // eslint-disable-next-line no-console
   const jsonStrings = await generateOperationIds(inputFile, {
   const jsonStrings = await generateOperationIds(inputFile, {
     overwriteExisting,
     overwriteExisting,
+    // biome-ignore lint/suspicious/noConsole: Allow to dump errors
   }).catch(console.error);
   }).catch(console.error);
   if (jsonStrings != null) {
   if (jsonStrings != null) {
     writeFileSync(outputFile ?? inputFile, jsonStrings);
     writeFileSync(outputFile ?? inputFile, jsonStrings);

+ 1 - 1
apps/app/bin/openapi/generate-operation-ids/generate-operation-ids.spec.ts

@@ -18,7 +18,7 @@ async function cleanup(filePath: string): Promise<void> {
     await fs.unlink(filePath);
     await fs.unlink(filePath);
     await fs.rmdir(path.dirname(filePath));
     await fs.rmdir(path.dirname(filePath));
   } catch (err) {
   } catch (err) {
-    // eslint-disable-next-line no-console
+    // biome-ignore lint/suspicious/noConsole: This is a test file
     console.error('Cleanup failed:', err);
     console.error('Cleanup failed:', err);
   }
   }
 }
 }

+ 2 - 0
apps/app/bin/print-memory-consumption.ts

@@ -11,6 +11,8 @@
  *        print-memory-consumption.ts [--port=9229] [--host=localhost] [--json]
  *        print-memory-consumption.ts [--port=9229] [--host=localhost] [--json]
  */
  */
 
 
+/** biome-ignore-all lint/suspicious/noConsole: Allow printing to console */
+
 import { get } from 'node:http';
 import { get } from 'node:http';
 import WebSocket from 'ws';
 import WebSocket from 'ws';
 
 

+ 1 - 2
apps/app/config/migrate-mongo-config.js

@@ -9,8 +9,7 @@ const isProduction = process.env.NODE_ENV === 'production';
 const { URL } = require('node:url');
 const { URL } = require('node:url');
 
 
 const { getMongoUri, mongoOptions } = isProduction
 const { getMongoUri, mongoOptions } = isProduction
-  ? // eslint-disable-next-line import/extensions, import/no-unresolved
-    require('../dist/server/util/mongoose-utils')
+  ? require('../dist/server/util/mongoose-utils')
   : require('../src/server/util/mongoose-utils');
   : require('../src/server/util/mongoose-utils');
 
 
 // get migrationsDir from env var
 // get migrationsDir from env var

+ 0 - 1
apps/app/config/next-i18next.config.js

@@ -22,7 +22,6 @@ module.exports = {
   localePath: path.resolve('./public/static/locales'),
   localePath: path.resolve('./public/static/locales'),
   serializeConfig: false,
   serializeConfig: false,
 
 
-  // eslint-disable-next-line no-nested-ternary
   use: isDev
   use: isDev
     ? isServer()
     ? isServer()
       ? [new HMRPlugin({ webpack: { server: true } })]
       ? [new HMRPlugin({ webpack: { server: true } })]

+ 0 - 3
apps/app/next.config.js

@@ -105,9 +105,6 @@ module.exports = async (phase) => {
     i18n,
     i18n,
 
 
     // for build
     // for build
-    eslint: {
-      ignoreDuringBuilds: true,
-    },
     typescript: {
     typescript: {
       tsconfigPath: 'tsconfig.build.client.json',
       tsconfigPath: 'tsconfig.build.client.json',
     },
     },

+ 0 - 2
apps/app/package.json

@@ -27,7 +27,6 @@
     "//// for CI": "",
     "//// for CI": "",
     "launch-dev:ci": "cross-env NODE_ENV=development pnpm run dev:migrate && pnpm run ts-node src/server/app.ts --ci",
     "launch-dev:ci": "cross-env NODE_ENV=development pnpm run dev:migrate && pnpm run ts-node src/server/app.ts --ci",
     "lint:typecheck": "vue-tsc --noEmit",
     "lint:typecheck": "vue-tsc --noEmit",
-    "lint:eslint": "eslint --quiet \"**/*.{js,mjs,jsx,ts,mts,tsx}\"",
     "lint:biome": "biome check --diagnostic-level=error",
     "lint:biome": "biome check --diagnostic-level=error",
     "lint:styles": "stylelint \"src/**/*.scss\"",
     "lint:styles": "stylelint \"src/**/*.scss\"",
     "lint:openapi:apiv3": "node node_modules/swagger2openapi/oas-validate tmp/openapi-spec-apiv3.json",
     "lint:openapi:apiv3": "node node_modules/swagger2openapi/oas-validate tmp/openapi-spec-apiv3.json",
@@ -309,7 +308,6 @@
     "diff2html": "^3.4.47",
     "diff2html": "^3.4.47",
     "downshift": "^8.2.3",
     "downshift": "^8.2.3",
     "eazy-logger": "^3.1.0",
     "eazy-logger": "^3.1.0",
-    "eslint-plugin-jest": "^26.5.3",
     "fastest-levenshtein": "^1.0.16",
     "fastest-levenshtein": "^1.0.16",
     "fslightbox-react": "^1.7.6",
     "fslightbox-react": "^1.7.6",
     "handsontable": "=6.2.2",
     "handsontable": "=6.2.2",

+ 0 - 16
apps/app/playwright/.eslintrc.mjs

@@ -1,16 +0,0 @@
-import playwright from 'eslint-plugin-playwright';
-
-// eslint-disable-next-line import/no-anonymous-default-export
-export default [
-  {
-    ...playwright.configs['flat/recommended'],
-    files: ['./**'],
-  },
-  {
-    files: ['./**'],
-    rules: {
-      // Customize Playwright rules
-      // ...
-    },
-  },
-];

+ 2 - 1
apps/app/playwright/60-home/home.spec.ts

@@ -1,3 +1,5 @@
+/** biome-ignore-all lint/performance/noAwaitInLoops: Allow in tests */
+
 import { expect, test } from '@playwright/test';
 import { expect, test } from '@playwright/test';
 
 
 test('Visit User home', async ({ page }) => {
 test('Visit User home', async ({ page }) => {
@@ -74,7 +76,6 @@ test('Access Password setting', async ({ page }) => {
 
 
   const toastElementsCount = await toastElements.count();
   const toastElementsCount = await toastElements.count();
   for (let i = 0; i < toastElementsCount; i++) {
   for (let i = 0; i < toastElementsCount; i++) {
-    // eslint-disable-next-line no-await-in-loop
     await toastElements.nth(i).click();
     await toastElements.nth(i).click();
   }
   }
 
 

+ 0 - 5
apps/app/src/client/components/.eslintrc.js

@@ -1,5 +0,0 @@
-module.exports = {
-  extends: '../../../.eslintrc.js',
-  rules: {
-  },
-};

+ 0 - 11
apps/app/src/client/components/Admin/App/AzureSetting.tsx

@@ -87,7 +87,6 @@ export const AzureSettingMolecule = (
       {azureUseOnlyEnvVars && (
       {azureUseOnlyEnvVars && (
         <p
         <p
           className="alert alert-info"
           className="alert alert-info"
-          // eslint-disable-next-line react/no-danger
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes <br> and <code> from i18n strings
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes <br> and <code> from i18n strings
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('admin:app_setting.azure_note_for_the_only_env_option', {
             __html: t('admin:app_setting.azure_note_for_the_only_env_option', {
@@ -129,9 +128,7 @@ export const AzureSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {
@@ -159,9 +156,7 @@ export const AzureSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {
@@ -189,9 +184,7 @@ export const AzureSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {
@@ -221,9 +214,7 @@ export const AzureSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {
@@ -253,9 +244,7 @@ export const AzureSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {

+ 0 - 2
apps/app/src/client/components/Admin/App/FileUploadSetting.tsx

@@ -135,9 +135,7 @@ const FileUploadSetting = (): JSX.Element => {
             <span className="material-symbols-outlined">help</span>
             <span className="material-symbols-outlined">help</span>
             <b>FIXED</b>
             <b>FIXED</b>
             <br />
             <br />
-            {/* eslint-disable-next-line react/no-danger */}
             <b
             <b
-              // eslint-disable-next-line react/no-danger
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t('admin:app_setting.fixed_by_env_var', {
                 __html: t('admin:app_setting.fixed_by_env_var', {

+ 0 - 7
apps/app/src/client/components/Admin/App/GcsSetting.tsx

@@ -82,7 +82,6 @@ export const GcsSettingMolecule = (
       {gcsUseOnlyEnvVars && (
       {gcsUseOnlyEnvVars && (
         <p
         <p
           className="alert alert-info"
           className="alert alert-info"
-          // eslint-disable-next-line react/no-danger
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('admin:app_setting.note_for_the_only_env_option', {
             __html: t('admin:app_setting.note_for_the_only_env_option', {
@@ -126,9 +125,7 @@ export const GcsSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {
@@ -158,9 +155,7 @@ export const GcsSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {
@@ -190,9 +185,7 @@ export const GcsSettingMolecule = (
                 tabIndex={-1}
                 tabIndex={-1}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('admin:app_setting.use_env_var_if_empty', {
                     __html: t('admin:app_setting.use_env_var_if_empty', {

+ 0 - 2
apps/app/src/client/components/Admin/App/MaintenanceMode.tsx

@@ -42,7 +42,6 @@ export const MaintenanceMode: FC = () => {
       );
       );
     }
     }
 
 
-    // eslint-disable-next-line max-len
     toastSuccess(
     toastSuccess(
       isMaintenanceMode
       isMaintenanceMode
         ? t('admin:maintenance_mode.successfully_ended_maintenance_mode')
         ? t('admin:maintenance_mode.successfully_ended_maintenance_mode')
@@ -65,7 +64,6 @@ export const MaintenanceMode: FC = () => {
             ? t('admin:maintenance_mode.warning_message_to_end')
             ? t('admin:maintenance_mode.warning_message_to_end')
             : t('admin:maintenance_mode.warning_message_to_start')
             : t('admin:maintenance_mode.warning_message_to_start')
         }
         }
-        // eslint-disable-next-line max-len
         supplymentaryMessage={
         supplymentaryMessage={
           isMaintenanceMode
           isMaintenanceMode
             ? null
             ? null

+ 0 - 1
apps/app/src/client/components/Admin/App/MaskedInput.tsx

@@ -10,7 +10,6 @@ type Props = {
   value?: string;
   value?: string;
   onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
   onChange?: (e: ChangeEvent<HTMLInputElement>) => void;
   tabIndex?: number | undefined;
   tabIndex?: number | undefined;
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
   register?: UseFormRegister<any>;
   register?: UseFormRegister<any>;
   fieldName?: string;
   fieldName?: string;
 };
 };

+ 0 - 2
apps/app/src/client/components/Admin/App/PageBulkExportSettings.tsx

@@ -105,9 +105,7 @@ const PageBulkExportSettings = (): JSX.Element => {
               </div>
               </div>
               {data?.useOnlyEnvVarsForIsBulkExportPagesEnabled && (
               {data?.useOnlyEnvVarsForIsBulkExportPagesEnabled && (
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
-                  {/* eslint-disable-next-line react/no-danger */}
                   <b
                   <b
-                    // eslint-disable-next-line react/no-danger
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('admin:app_setting.fixed_by_env_var', {
                       __html: t('admin:app_setting.fixed_by_env_var', {

+ 0 - 1
apps/app/src/client/components/Admin/App/SesSetting.tsx

@@ -7,7 +7,6 @@ import { withUnstatedContainers } from '../../UnstatedUtils';
 
 
 type Props = {
 type Props = {
   adminAppContainer?: AdminAppContainer;
   adminAppContainer?: AdminAppContainer;
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
   register: UseFormRegister<any>;
   register: UseFormRegister<any>;
 };
 };
 
 

+ 0 - 3
apps/app/src/client/components/Admin/App/SiteUrlSetting.tsx

@@ -60,7 +60,6 @@ const SiteUrlSetting = (props: Props) => {
         <div className="row">
         <div className="row">
           <p
           <p
             className="alert alert-info"
             className="alert alert-info"
-            // eslint-disable-next-line react/no-danger
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
               __html: t('site_url.note_for_the_only_env_option', {
               __html: t('site_url.note_for_the_only_env_option', {
@@ -96,7 +95,6 @@ const SiteUrlSetting = (props: Props) => {
                   {...register('siteUrl')}
                   {...register('siteUrl')}
                 />
                 />
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                     dangerouslySetInnerHTML={{ __html: t('site_url.help') }}
                     dangerouslySetInnerHTML={{ __html: t('site_url.help') }}
@@ -111,7 +109,6 @@ const SiteUrlSetting = (props: Props) => {
                   readOnly
                   readOnly
                 />
                 />
                 <p className="form-text text-muted">
                 <p className="form-text text-muted">
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{

+ 0 - 1
apps/app/src/client/components/Admin/App/SmtpSetting.tsx

@@ -8,7 +8,6 @@ import { withUnstatedContainers } from '../../UnstatedUtils';
 
 
 type Props = {
 type Props = {
   adminAppContainer?: AdminAppContainer;
   adminAppContainer?: AdminAppContainer;
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
   register: UseFormRegister<any>;
   register: UseFormRegister<any>;
 };
 };
 
 

+ 0 - 1
apps/app/src/client/components/Admin/AuditLog/AuditLogDisableMode.tsx

@@ -19,7 +19,6 @@ export const AuditLogDisableMode: FC = () => {
                 {t('audit_log_management.audit_log')}
                 {t('audit_log_management.audit_log')}
               </h1>
               </h1>
               <h3
               <h3
-                // eslint-disable-next-line react/no-danger
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('audit_log_management.disable_mode_explanation'),
                   __html: t('audit_log_management.disable_mode_explanation'),

+ 0 - 1
apps/app/src/client/components/Admin/AuditLog/AuditLogSettings.tsx

@@ -33,7 +33,6 @@ export const AuditLogSettings: FC = () => {
         <b>FIXED</b>
         <b>FIXED</b>
         <br />
         <br />
         <b
         <b
-          // eslint-disable-next-line react/no-danger
           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('admin:audit_log_management.fixed_by_env_var', {
             __html: t('admin:audit_log_management.fixed_by_env_var', {

+ 0 - 1
apps/app/src/client/components/Admin/AuditLogManagement.tsx

@@ -158,7 +158,6 @@ export const AuditLogManagement: FC = () => {
       const isNan = Number.isNaN(inputNumber);
       const isNan = Number.isNaN(inputNumber);
 
 
       if (!isNan) {
       if (!isNan) {
-        // eslint-disable-next-line no-nested-ternary
         const jumpPageNumber =
         const jumpPageNumber =
           inputNumber > totalPagingPages
           inputNumber > totalPagingPages
             ? totalPagingPages
             ? totalPagingPages

+ 0 - 1
apps/app/src/client/components/Admin/Common/AdminUpdateButtonRow.tsx

@@ -15,7 +15,6 @@ const AdminUpdateButtonRow = (props: Props): JSX.Element => {
       <div className="col-md-3"></div>
       <div className="col-md-3"></div>
       <div className="col-md-9">
       <div className="col-md-9">
         <button
         <button
-          // eslint-disable-next-line react/button-has-type
           type={props.type ?? 'button'}
           type={props.type ?? 'button'}
           className="btn btn-primary"
           className="btn btn-primary"
           onClick={props.onClick}
           onClick={props.onClick}

+ 50 - 52
apps/app/src/client/components/Admin/Customize/CustomizeLayoutSetting.tsx

@@ -56,68 +56,66 @@ const CustomizeLayoutSetting = (): JSX.Element => {
   }
   }
 
 
   return (
   return (
-    <React.Fragment>
-      <div className="row">
-        <div className="col-12">
-          <h2 className="admin-setting-header">
-            {t('customize_settings.layout')}
-          </h2>
+    <div className="row">
+      <div className="col-12">
+        <h2 className="admin-setting-header">
+          {t('customize_settings.layout')}
+        </h2>
 
 
-          <div className="d-flex justify-content-around mt-5">
-            <div className="row row-cols-2">
-              <div className="col">
-                <button
-                  type="button"
-                  className={`card border border-4 ${!isContainerFluid ? 'border-primary' : ''}`}
-                  onClick={() => setIsContainerFluid(false)}
-                  aria-pressed={!isContainerFluid}
-                >
-                  {/* eslint-disable-next-line @next/next/no-img-element */}
-                  <img
-                    className="card-img-top"
-                    src={`/images/customize-settings/default-${resolvedTheme}.svg`}
-                    alt={t('customize_settings.layout_options.default')}
-                  />
-                  <div className="card-body text-center">
-                    {t('customize_settings.layout_options.default')}
-                  </div>
-                </button>
-              </div>
-              <div className="col">
-                <button
-                  type="button"
-                  className={`card border border-4 ${isContainerFluid ? 'border-primary' : ''}`}
-                  onClick={() => setIsContainerFluid(true)}
-                  aria-pressed={isContainerFluid}
-                >
-                  {/* eslint-disable-next-line @next/next/no-img-element */}
-                  <img
-                    className="card-img-top"
-                    src={`/images/customize-settings/fluid-${resolvedTheme}.svg`}
-                    alt={t('customize_settings.layout_options.expanded')}
-                  />
-                  <div className="card-body text-center">
-                    {t('customize_settings.layout_options.expanded')}
-                  </div>
-                </button>
-              </div>
+        <div className="d-flex justify-content-around mt-5">
+          <div className="row row-cols-2">
+            <div className="col">
+              <button
+                type="button"
+                className={`card border border-4 ${!isContainerFluid ? 'border-primary' : ''}`}
+                onClick={() => setIsContainerFluid(false)}
+                aria-pressed={!isContainerFluid}
+              >
+                {/* biome-ignore lint/performance/noImgElement: Ignore for SVG */}
+                <img
+                  className="card-img-top"
+                  src={`/images/customize-settings/default-${resolvedTheme}.svg`}
+                  alt={t('customize_settings.layout_options.default')}
+                />
+                <div className="card-body text-center">
+                  {t('customize_settings.layout_options.default')}
+                </div>
+              </button>
             </div>
             </div>
-          </div>
-
-          <div className="row my-3">
-            <div className="mx-auto">
+            <div className="col">
               <button
               <button
                 type="button"
                 type="button"
-                className="btn btn-primary"
-                onClick={onClickSubmit}
+                className={`card border border-4 ${isContainerFluid ? 'border-primary' : ''}`}
+                onClick={() => setIsContainerFluid(true)}
+                aria-pressed={isContainerFluid}
               >
               >
-                {t('Update')}
+                {/* biome-ignore lint/performance/noImgElement: Ignore for SVG */}
+                <img
+                  className="card-img-top"
+                  src={`/images/customize-settings/fluid-${resolvedTheme}.svg`}
+                  alt={t('customize_settings.layout_options.expanded')}
+                />
+                <div className="card-body text-center">
+                  {t('customize_settings.layout_options.expanded')}
+                </div>
               </button>
               </button>
             </div>
             </div>
           </div>
           </div>
         </div>
         </div>
+
+        <div className="row my-3">
+          <div className="mx-auto">
+            <button
+              type="button"
+              className="btn btn-primary"
+              onClick={onClickSubmit}
+            >
+              {t('Update')}
+            </button>
+          </div>
+        </div>
       </div>
       </div>
-    </React.Fragment>
+    </div>
   );
   );
 };
 };
 
 

+ 50 - 56
apps/app/src/client/components/Admin/Customize/CustomizeNoscriptSetting.tsx

@@ -51,67 +51,61 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
   );
   );
 
 
   return (
   return (
-    <React.Fragment>
-      <div className="row">
-        <div className="col-12">
-          <h2 className="admin-setting-header">
-            {t('admin:customize_settings.custom_noscript')}
-          </h2>
+    <div className="row">
+      <div className="col-12">
+        <h2 className="admin-setting-header">
+          {t('admin:customize_settings.custom_noscript')}
+        </h2>
 
 
-          <Card className="card custom-card bg-body-tertiary my-3">
-            <CardBody className="px-0 py-2">
-              <span
-                // eslint-disable-next-line react/no-danger
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('admin:customize_settings.custom_noscript_detail'),
-                }}
-              />
-            </CardBody>
-          </Card>
+        <Card className="card custom-card bg-body-tertiary my-3">
+          <CardBody className="px-0 py-2">
+            <span
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('admin:customize_settings.custom_noscript_detail'),
+              }}
+            />
+          </CardBody>
+        </Card>
 
 
-          <form onSubmit={handleSubmit(onSubmit)}>
-            <div>
-              <textarea
-                className="form-control mb-2"
-                rows={8}
-                {...register('customizeNoscript')}
-              />
-            </div>
+        <form onSubmit={handleSubmit(onSubmit)}>
+          <div>
+            <textarea
+              className="form-control mb-2"
+              rows={8}
+              {...register('customizeNoscript')}
+            />
+          </div>
 
 
-            <button
-              type="button"
-              className="btn btn-link text-muted p-0"
-              data-bs-toggle="collapse"
-              data-bs-target="#collapseExampleHtml"
-              aria-expanded="false"
-              aria-controls="collapseExampleHtml"
-            >
-              <span
-                className="material-symbols-outlined me-1"
-                aria-hidden="true"
-              >
-                navigate_next
-              </span>
-              Example for Google Tag Manager
-            </button>
-            <div className="collapse" id="collapseExampleHtml">
-              <PrismAsyncLight style={oneDark} language="javascript">
-                {`<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
-  height="0"
-  width="0"
-  style="display:none;visibility:hidden"></iframe>`}
-              </PrismAsyncLight>
-            </div>
+          <button
+            type="button"
+            className="btn btn-link text-muted p-0"
+            data-bs-toggle="collapse"
+            data-bs-target="#collapseExampleHtml"
+            aria-expanded="false"
+            aria-controls="collapseExampleHtml"
+          >
+            <span className="material-symbols-outlined me-1" aria-hidden="true">
+              navigate_next
+            </span>
+            Example for Google Tag Manager
+          </button>
+          <div className="collapse" id="collapseExampleHtml">
+            <PrismAsyncLight style={oneDark} language="javascript">
+              {`<iframe src="https://www.googletagmanager.com/ns.html?id=GTM-XXXXXXX"
+height="0"
+width="0"
+style="display:none;visibility:hidden"></iframe>`}
+            </PrismAsyncLight>
+          </div>
 
 
-            <AdminUpdateButtonRow
-              type="submit"
-              disabled={adminCustomizeContainer.state.retrieveError != null}
-            />
-          </form>
-        </div>
+          <AdminUpdateButtonRow
+            type="submit"
+            disabled={adminCustomizeContainer.state.retrieveError != null}
+          />
+        </form>
       </div>
       </div>
-    </React.Fragment>
+    </div>
   );
   );
 };
 };
 
 

+ 43 - 45
apps/app/src/client/components/Admin/Customize/CustomizeSidebarSetting.tsx

@@ -37,62 +37,60 @@ const CustomizeSidebarsetting = (): JSX.Element => {
   const { isSidebarCollapsedMode } = data;
   const { isSidebarCollapsedMode } = data;
 
 
   return (
   return (
-    <React.Fragment>
-      <div className="row">
-        <div className="col-12">
-          <h2 className="admin-setting-header">
-            {t('customize_settings.default_sidebar_mode.title')}
-          </h2>
+    <div className="row">
+      <div className="col-12">
+        <h2 className="admin-setting-header">
+          {t('customize_settings.default_sidebar_mode.title')}
+        </h2>
 
 
-          <Card className="card custom-card bg-body-tertiary my-3">
-            <CardBody className="px-0 py-2">
-              {t('customize_settings.default_sidebar_mode.desc')}
-            </CardBody>
-          </Card>
+        <Card className="card custom-card bg-body-tertiary my-3">
+          <CardBody className="px-0 py-2">
+            {t('customize_settings.default_sidebar_mode.desc')}
+          </CardBody>
+        </Card>
 
 
-          <div className="d-flex justify-content-around mt-5">
-            <div className="row row-cols-2">
-              <div className="col">
-                <button
-                  type="button"
-                  className={`card border border-4 ${isSidebarCollapsedMode ? 'border-primary' : ''}`}
-                  onClick={() => setIsSidebarCollapsedMode(true)}
-                  aria-pressed={isSidebarCollapsedMode}
-                >
-                  {/* eslint-disable-next-line @next/next/no-img-element */}
-                  <img src={collapsedIconFileName} alt="Collapsed Mode" />
-                  <div className="card-body text-center">Collapsed Mode</div>
-                </button>
-              </div>
-              <div className="col">
-                <button
-                  type="button"
-                  className={`card border border-4 ${!isSidebarCollapsedMode ? 'border-primary' : ''}`}
-                  onClick={() => setIsSidebarCollapsedMode(false)}
-                  aria-pressed={!isSidebarCollapsedMode}
-                >
-                  {/* eslint-disable-next-line @next/next/no-img-element */}
-                  <img src={dockIconFileName} alt="Dock Mode" />
-                  <div className="card-body  text-center">Dock Mode</div>
-                </button>
-              </div>
+        <div className="d-flex justify-content-around mt-5">
+          <div className="row row-cols-2">
+            <div className="col">
+              <button
+                type="button"
+                className={`card border border-4 ${isSidebarCollapsedMode ? 'border-primary' : ''}`}
+                onClick={() => setIsSidebarCollapsedMode(true)}
+                aria-pressed={isSidebarCollapsedMode}
+              >
+                {/* biome-ignore lint/performance/noImgElement: Ignore for SVG */}
+                <img src={collapsedIconFileName} alt="Collapsed Mode" />
+                <div className="card-body text-center">Collapsed Mode</div>
+              </button>
             </div>
             </div>
-          </div>
-
-          <div className="row my-3">
-            <div className="mx-auto">
+            <div className="col">
               <button
               <button
                 type="button"
                 type="button"
-                onClick={onClickSubmit}
-                className="btn btn-primary"
+                className={`card border border-4 ${!isSidebarCollapsedMode ? 'border-primary' : ''}`}
+                onClick={() => setIsSidebarCollapsedMode(false)}
+                aria-pressed={!isSidebarCollapsedMode}
               >
               >
-                {t('Update')}
+                {/* biome-ignore lint/performance/noImgElement: Ignore for SVG */}
+                <img src={dockIconFileName} alt="Dock Mode" />
+                <div className="card-body  text-center">Dock Mode</div>
               </button>
               </button>
             </div>
             </div>
           </div>
           </div>
         </div>
         </div>
+
+        <div className="row my-3">
+          <div className="mx-auto">
+            <button
+              type="button"
+              onClick={onClickSubmit}
+              className="btn btn-primary"
+            >
+              {t('Update')}
+            </button>
+          </div>
+        </div>
       </div>
       </div>
-    </React.Fragment>
+    </div>
   );
   );
 };
 };
 
 

+ 2 - 6
apps/app/src/client/components/Admin/Customize/CustomizeThemeSetting.tsx

@@ -1,4 +1,4 @@
-import React, { type JSX, useCallback, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
 import { PresetThemes, PresetThemesMetadatas } from '@growi/preset-themes';
 import { PresetThemes, PresetThemesMetadatas } from '@growi/preset-themes';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 
 
@@ -8,11 +8,7 @@ import { useSWRxGrowiThemeSetting } from '~/stores/admin/customize';
 import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 import AdminUpdateButtonRow from '../Common/AdminUpdateButtonRow';
 import CustomizeThemeOptions from './CustomizeThemeOptions';
 import CustomizeThemeOptions from './CustomizeThemeOptions';
 
 
-// eslint-disable-next-line @typescript-eslint/ban-types
-type Props = {};
-
-// eslint-disable-next-line @typescript-eslint/no-unused-vars
-const CustomizeThemeSetting = (props: Props): JSX.Element => {
+const CustomizeThemeSetting = (): JSX.Element => {
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 
   const { data, error, update } = useSWRxGrowiThemeSetting();
   const { data, error, update } = useSWRxGrowiThemeSetting();

+ 70 - 74
apps/app/src/client/components/Admin/Customize/CustomizeTitle.tsx

@@ -1,5 +1,5 @@
 import type { FC } from 'react';
 import type { FC } from 'react';
-import React, { useCallback, useEffect } from 'react';
+import { useCallback, useEffect } from 'react';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import { useForm } from 'react-hook-form';
 import { useForm } from 'react-hook-form';
 import { Card, CardBody } from 'reactstrap';
 import { Card, CardBody } from 'reactstrap';
@@ -44,82 +44,78 @@ export const CustomizeTitle: FC = () => {
   );
   );
 
 
   return (
   return (
-    <React.Fragment>
-      <div className="row">
-        <div className="col-12">
-          <h2 className="admin-setting-header">
-            {t('admin:customize_settings.custom_title')}
-          </h2>
-        </div>
+    <div className="row">
+      <div className="col-12">
+        <h2 className="admin-setting-header">
+          {t('admin:customize_settings.custom_title')}
+        </h2>
+      </div>
+
+      <div className="col-12">
+        <Card className="card custom-card bg-body-tertiary mb-3">
+          <CardBody className="px-0 py-2">
+            <p
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('admin:customize_settings.custom_title_detail'),
+              }}
+            />
+            <ul>
+              <li>
+                <span
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t(
+                      'admin:customize_settings.custom_title_detail_placeholder1',
+                    ),
+                  }}
+                />
+              </li>
+              <li>
+                <span
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t(
+                      'admin:customize_settings.custom_title_detail_placeholder2',
+                    ),
+                  }}
+                />
+              </li>
+              <li>
+                <span
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t(
+                      'admin:customize_settings.custom_title_detail_placeholder3',
+                    ),
+                  }}
+                />
+              </li>
+            </ul>
+          </CardBody>
+        </Card>
+      </div>
 
 
+      {/* TODO i18n */}
+      <div className="form-text text-muted col-12 mb-3">
+        Default Value:{' '}
+        <code>
+          &#123;&#123;pagename&#125;&#125; - &#123;&#123;sitename&#125;&#125;
+        </code>
+        <br />
+        Default Output Example:{' '}
+        <code className="xml">
+          &lt;title&gt;Page name - My GROWI&lt;&#047;title&gt;
+        </code>
+      </div>
+      <form onSubmit={handleSubmit(onSubmit)}>
         <div className="col-12">
         <div className="col-12">
-          <Card className="card custom-card bg-body-tertiary mb-3">
-            <CardBody className="px-0 py-2">
-              {/* eslint-disable react/no-danger */}
-              <p
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('admin:customize_settings.custom_title_detail'),
-                }}
-              />
-              <ul>
-                <li>
-                  <span
-                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                    dangerouslySetInnerHTML={{
-                      __html: t(
-                        'admin:customize_settings.custom_title_detail_placeholder1',
-                      ),
-                    }}
-                  />
-                </li>
-                <li>
-                  <span
-                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                    dangerouslySetInnerHTML={{
-                      __html: t(
-                        'admin:customize_settings.custom_title_detail_placeholder2',
-                      ),
-                    }}
-                  />
-                </li>
-                <li>
-                  <span
-                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                    dangerouslySetInnerHTML={{
-                      __html: t(
-                        'admin:customize_settings.custom_title_detail_placeholder3',
-                      ),
-                    }}
-                  />
-                </li>
-              </ul>
-              {/* eslint-enable react/no-danger */}
-            </CardBody>
-          </Card>
+          <input className="form-control" {...register('customizeTitle')} />
         </div>
         </div>
-
-        {/* TODO i18n */}
-        <div className="form-text text-muted col-12 mb-3">
-          Default Value:{' '}
-          <code>
-            &#123;&#123;pagename&#125;&#125; - &#123;&#123;sitename&#125;&#125;
-          </code>
-          <br />
-          Default Output Example:{' '}
-          <code className="xml">
-            &lt;title&gt;Page name - My GROWI&lt;&#047;title&gt;
-          </code>
+        <div className="col-12">
+          <AdminUpdateButtonRow type="submit" disabled={false} />
         </div>
         </div>
-        <form onSubmit={handleSubmit(onSubmit)}>
-          <div className="col-12">
-            <input className="form-control" {...register('customizeTitle')} />
-          </div>
-          <div className="col-12">
-            <AdminUpdateButtonRow type="submit" disabled={false} />
-          </div>
-        </form>
-      </div>
-    </React.Fragment>
+      </form>
+    </div>
   );
   );
 };
 };

+ 0 - 1
apps/app/src/client/components/Admin/ElasticsearchManagement/StatusTable.jsx

@@ -29,7 +29,6 @@ class StatusTable extends React.PureComponent {
       );
       );
     } else {
     } else {
       connectionStatusLabel = isConnected ? (
       connectionStatusLabel = isConnected ? (
-        // eslint-disable-next-line max-len
         <span
         <span
           data-testid="connection-status-badge-connected"
           data-testid="connection-status-badge-connected"
           className="badge text-bg-success"
           className="badge text-bg-success"

+ 23 - 31
apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportCollectionConfigurationModal.jsx

@@ -1,5 +1,3 @@
-/* eslint-disable react/no-danger */
-
 import React from 'react';
 import React from 'react';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
@@ -54,7 +52,6 @@ class ImportCollectionConfigurationModal extends React.Component {
     const translationBase =
     const translationBase =
       'admin:importer_management.growi_settings.configuration.pages';
       'admin:importer_management.growi_settings.configuration.pages';
 
 
-    /* eslint-disable react/no-unescaped-entities */
     return (
     return (
       <>
       <>
         <div className="form-check form-check-warning">
         <div className="form-check form-check-warning">
@@ -187,7 +184,6 @@ class ImportCollectionConfigurationModal extends React.Component {
         </div>
         </div>
       </>
       </>
     );
     );
-    /* eslint-enable react/no-unescaped-entities */
   }
   }
 
 
   renderRevisionsContents() {
   renderRevisionsContents() {
@@ -197,36 +193,32 @@ class ImportCollectionConfigurationModal extends React.Component {
     const translationBase =
     const translationBase =
       'admin:importer_management.growi_settings.configuration.revisions';
       'admin:importer_management.growi_settings.configuration.revisions';
 
 
-    /* eslint-disable react/no-unescaped-entities */
     return (
     return (
-      <>
-        <div className="form-check form-check-warning">
-          <input
-            id="cbOpt1"
-            type="checkbox"
-            className="form-check-input"
-            checked={option.isOverwriteAuthorWithCurrentUser || false} // add ' || false' to avoid uncontrolled input warning
-            onChange={() =>
-              this.changeHandler({
-                isOverwriteAuthorWithCurrentUser:
-                  !option.isOverwriteAuthorWithCurrentUser,
-              })
-            }
+      <div className="form-check form-check-warning">
+        <input
+          id="cbOpt1"
+          type="checkbox"
+          className="form-check-input"
+          checked={option.isOverwriteAuthorWithCurrentUser || false} // add ' || false' to avoid uncontrolled input warning
+          onChange={() =>
+            this.changeHandler({
+              isOverwriteAuthorWithCurrentUser:
+                !option.isOverwriteAuthorWithCurrentUser,
+            })
+          }
+        />
+        <label htmlFor="cbOpt1" className="form-label form-check-label">
+          {t(`${translationBase}.overwrite_author.label`)}
+          <p
+            className="form-text text-muted mt-0"
+            // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
+            dangerouslySetInnerHTML={{
+              __html: t(`${translationBase}.overwrite_author.desc`),
+            }}
           />
           />
-          <label htmlFor="cbOpt1" className="form-label form-check-label">
-            {t(`${translationBase}.overwrite_author.label`)}
-            <p
-              className="form-text text-muted mt-0"
-              // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
-              dangerouslySetInnerHTML={{
-                __html: t(`${translationBase}.overwrite_author.desc`),
-              }}
-            />
-          </label>
-        </div>
-      </>
+        </label>
+      </div>
     );
     );
-    /* eslint-enable react/no-unescaped-entities */
   }
   }
 
 
   render() {
   render() {

+ 0 - 1
apps/app/src/client/components/Admin/ImportData/GrowiArchive/ImportForm.jsx

@@ -110,7 +110,6 @@ class ImportForm extends React.Component {
     const { socket } = this.props;
     const { socket } = this.props;
 
 
     // websocket event
     // websocket event
-    // eslint-disable-next-line object-curly-newline
     socket.on(
     socket.on(
       'admin:onProgressForImport',
       'admin:onProgressForImport',
       ({ collectionName, collectionProgress, appendedErrors }) => {
       ({ collectionName, collectionProgress, appendedErrors }) => {

+ 0 - 1
apps/app/src/client/components/Admin/ImportData/GrowiArchive/UploadForm.jsx

@@ -18,7 +18,6 @@ class UploadForm extends React.Component {
 
 
   changeFileName(e) {
   changeFileName(e) {
     // to trigger rerender at onChange event
     // to trigger rerender at onChange event
-    // eslint-disable-next-line react/no-unused-state
     this.setState({ dummy: e.target.files[0].name });
     this.setState({ dummy: e.target.files[0].name });
   }
   }
 
 

+ 0 - 2
apps/app/src/client/components/Admin/LegacySlackIntegration/LegacySlackIntegration.jsx

@@ -38,7 +38,6 @@ const LegacySlackIntegration = (props) => {
       {isDisabled && (
       {isDisabled && (
         <div className="alert alert-danger">
         <div className="alert alert-danger">
           <span className="material-symbols-outlined">remove</span>
           <span className="material-symbols-outlined">remove</span>
-          {/* eslint-disable-next-line react/no-danger */}
           <span
           <span
             // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
             // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
@@ -50,7 +49,6 @@ const LegacySlackIntegration = (props) => {
 
 
       <div className="alert alert-warning">
       <div className="alert alert-warning">
         <span className="material-symbols-outlined">info</span>
         <span className="material-symbols-outlined">info</span>
-        {/* eslint-disable-next-line react/no-danger */}
         <span
         <span
           // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
           // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{

+ 0 - 3
apps/app/src/client/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx

@@ -157,7 +157,6 @@ const SlackConfiguration = (props) => {
                 RECOMMENDED
                 RECOMMENDED
               </span>
               </span>
               <br />
               <br />
-              {/* eslint-disable-next-line react/no-danger */}
               <span
               <span
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
@@ -224,7 +223,6 @@ const SlackConfiguration = (props) => {
           <li className="ms-3">
           <li className="ms-3">
             {t('notification_settings.how_to.workspace')}
             {t('notification_settings.how_to.workspace')}
             <ol>
             <ol>
-              {/* eslint-disable-next-line react/no-danger */}
               <li
               <li
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
@@ -238,7 +236,6 @@ const SlackConfiguration = (props) => {
           <li className="ms-3">
           <li className="ms-3">
             {t('notification_settings.how_to.at_growi')}
             {t('notification_settings.how_to.at_growi')}
             <ol>
             <ol>
-              {/* eslint-disable-next-line react/no-danger */}
               <li
               <li
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: translation contains HTML markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{

+ 0 - 1
apps/app/src/client/components/Admin/MarkdownSetting/IndentForm.tsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-danger */
 import React, { useCallback } from 'react';
 import React, { useCallback } from 'react';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import {
 import {

+ 0 - 1
apps/app/src/client/components/Admin/MarkdownSetting/LineBreakForm.jsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-danger */
 import React from 'react';
 import React from 'react';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';

+ 0 - 4
apps/app/src/client/components/Admin/Notification/GlobalNotification.jsx

@@ -40,7 +40,6 @@ const GlobalNotification = (props) => {
       </h2>
       </h2>
 
 
       <p className="card custom-card bg-body-tertiary">
       <p className="card custom-card bg-body-tertiary">
-        {/* eslint-disable-next-line react/no-danger */}
         <span
         <span
           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
@@ -67,7 +66,6 @@ const GlobalNotification = (props) => {
               className="form-label form-check-label"
               className="form-label form-check-label"
               htmlFor="isNotificationForOwnerPageEnabled"
               htmlFor="isNotificationForOwnerPageEnabled"
             >
             >
-              {/* eslint-disable-next-line react/no-danger */}
               <span
               <span
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
@@ -98,7 +96,6 @@ const GlobalNotification = (props) => {
               className="form-label form-check-label"
               className="form-label form-check-label"
               htmlFor="isNotificationForGroupPageEnabled"
               htmlFor="isNotificationForGroupPageEnabled"
             >
             >
-              {/* eslint-disable-next-line react/no-danger */}
               <span
               <span
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
@@ -136,7 +133,6 @@ const GlobalNotification = (props) => {
         <thead>
         <thead>
           <tr>
           <tr>
             <th>ON/OFF</th>
             <th>ON/OFF</th>
-            {/* eslint-disable-next-line react/no-danger */}
             <th>
             <th>
               {t('notification_settings.trigger_path')}{' '}
               {t('notification_settings.trigger_path')}{' '}
               <span
               <span

+ 0 - 3
apps/app/src/client/components/Admin/Notification/ManageGlobalNotification.tsx

@@ -148,7 +148,6 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
           <h3>
           <h3>
             <label htmlFor="triggerPath" className="form-label">
             <label htmlFor="triggerPath" className="form-label">
               {t('notification_settings.trigger_path')}
               {t('notification_settings.trigger_path')}
-              {/* eslint-disable-next-line react/no-danger */}
               <small
               <small
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
@@ -230,7 +229,6 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
               </div>
               </div>
 
 
               <p className="p-2">
               <p className="p-2">
-                {/* eslint-disable-next-line react/no-danger */}
                 {!isMailerSetup && (
                 {!isMailerSetup && (
                   <span
                   <span
                     className="form-text text-muted"
                     className="form-text text-muted"
@@ -270,7 +268,6 @@ const ManageGlobalNotification = (props: Props): JSX.Element => {
                 />
                 />
               </div>
               </div>
               <p className="p-2">
               <p className="p-2">
-                {/* eslint-disable-next-line react/no-danger */}
                 <span
                 <span
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{

+ 1 - 1
apps/app/src/client/components/Admin/Notification/NotificationDeleteModal.jsx

@@ -50,7 +50,7 @@ NotificationDeleteModal.propTypes = {
   notificationForConfiguration: PropTypes.object.isRequired,
   notificationForConfiguration: PropTypes.object.isRequired,
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+// biome-ignore lint:*:noExplicitModuleBoundaryTypes: Temporary Alternative to @typescript-eslint/explicit-module-boundary-types
 const NotificationDeleteModalWrapperFC = (props) => {
 const NotificationDeleteModalWrapperFC = (props) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 

+ 1 - 8
apps/app/src/client/components/Admin/Notification/NotificationSetting.jsx

@@ -1,4 +1,4 @@
-import React, { useCallback, useEffect, useState } from 'react';
+import { useCallback, useEffect, useState } from 'react';
 import { SlackbotType } from '@growi/slack';
 import { SlackbotType } from '@growi/slack';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
@@ -16,8 +16,6 @@ import UserTriggerNotification from './UserTriggerNotification';
 
 
 const logger = loggerFactory('growi:NotificationSetting');
 const logger = loggerFactory('growi:NotificationSetting');
 
 
-let retrieveErrors = null;
-
 const SettingsIcon = () => (
 const SettingsIcon = () => (
   <span className="material-symbols-outlined">settings</span>
   <span className="material-symbols-outlined">settings</span>
 );
 );
@@ -33,7 +31,6 @@ const navTabMapping = {
   },
   },
 };
 };
 
 
-// eslint-disable-next-line react/prop-types
 const Badge = ({ isEnabled }) => {
 const Badge = ({ isEnabled }) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 
@@ -57,7 +54,6 @@ const SkeletonListItem = () => (
   </li>
   </li>
 );
 );
 
 
-// eslint-disable-next-line react/prop-types
 const SlackIntegrationListItem = ({ isEnabled, currentBotType }) => {
 const SlackIntegrationListItem = ({ isEnabled, currentBotType }) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 
@@ -78,7 +74,6 @@ const SlackIntegrationListItem = ({ isEnabled, currentBotType }) => {
       </h4>
       </h4>
       {isCautionVisible && (
       {isCautionVisible && (
         <ul className="mt-2 ps-4">
         <ul className="mt-2 ps-4">
-          {/* eslint-disable-next-line react/no-danger */}
           <li
           <li
             // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
             // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
@@ -91,7 +86,6 @@ const SlackIntegrationListItem = ({ isEnabled, currentBotType }) => {
   );
   );
 };
 };
 
 
-// eslint-disable-next-line react/prop-types
 const LegacySlackIntegrationListItem = ({ isEnabled }) => {
 const LegacySlackIntegrationListItem = ({ isEnabled }) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 
@@ -106,7 +100,6 @@ const LegacySlackIntegrationListItem = ({ isEnabled }) => {
       {isEnabled && (
       {isEnabled && (
         <ul className="mt-2 ps-4">
         <ul className="mt-2 ps-4">
           <li>
           <li>
-            {/* eslint-disable-next-line react/no-danger */}
             <span
             <span
               className="text-danger"
               className="text-danger"
               // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
               // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup

+ 1 - 1
apps/app/src/client/components/Admin/Notification/TriggerEventCheckBox.jsx

@@ -34,7 +34,7 @@ TriggerEventCheckBox.propTypes = {
   children: PropTypes.object.isRequired,
   children: PropTypes.object.isRequired,
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+// biome-ignore lint:*:noExplicitModuleBoundaryTypes: Temporary Alternative to @typescript-eslint/explicit-module-boundary-types
 const TriggerEventCheckBoxWrapperFC = (props) => {
 const TriggerEventCheckBoxWrapperFC = (props) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 

+ 1 - 1
apps/app/src/client/components/Admin/Notification/UserNotificationRow.jsx

@@ -46,7 +46,7 @@ UserNotificationRow.propTypes = {
   onClickDeleteBtn: PropTypes.func.isRequired,
   onClickDeleteBtn: PropTypes.func.isRequired,
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+// biome-ignore lint:*:noExplicitModuleBoundaryTypes: Temporary Alternative to @typescript-eslint/explicit-module-boundary-types
 const UserNotificationRowWrapperWrapperFC = (props) => {
 const UserNotificationRowWrapperWrapperFC = (props) => {
   const { t } = useTranslation();
   const { t } = useTranslation();
 
 

+ 0 - 2
apps/app/src/client/components/Admin/Notification/UserTriggerNotification.jsx

@@ -113,7 +113,6 @@ class UserTriggerNotification extends React.Component {
                   }}
                   }}
                 />
                 />
                 <p className="p-2 mb-0">
                 <p className="p-2 mb-0">
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
@@ -142,7 +141,6 @@ class UserTriggerNotification extends React.Component {
                   />
                   />
                 </div>
                 </div>
                 <p className="p-2 mb-0">
                 <p className="p-2 mb-0">
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{

+ 1 - 1
apps/app/src/client/components/Admin/Security/DeleteAllShareLinksModal.jsx

@@ -48,7 +48,7 @@ DeleteAllShareLinksModal.propTypes = {
   onClickDeleteButton: PropTypes.func,
   onClickDeleteButton: PropTypes.func,
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+// biome-ignore lint:*:noExplicitModuleBoundaryTypes: Temporary Alternative to @typescript-eslint/explicit-module-boundary-types
 const DeleteAllShareLinksModalWrapperFC = (props) => {
 const DeleteAllShareLinksModalWrapperFC = (props) => {
   const { t } = useTranslation('admin');
   const { t } = useTranslation('admin');
 
 

+ 202 - 206
apps/app/src/client/components/Admin/Security/GitHubSecuritySettingContents.tsx

@@ -1,5 +1,4 @@
-/* eslint-disable react/no-danger */
-import React, { useCallback, useEffect } from 'react';
+import { useCallback, useEffect } from 'react';
 import { pathUtils } from '@growi/core/dist/utils';
 import { pathUtils } from '@growi/core/dist/utils';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import { useForm } from 'react-hook-form';
 import { useForm } from 'react-hook-form';
@@ -62,243 +61,240 @@ const GitHubSecurityManagementContents = (props: Props) => {
 
 
   return (
   return (
     <form onSubmit={handleSubmit(onClickSubmit)}>
     <form onSubmit={handleSubmit(onClickSubmit)}>
-      <React.Fragment>
-        <h2 className="alert-anchor border-bottom">
-          {t('security_settings.OAuth.GitHub.name')}
-        </h2>
+      <h2 className="alert-anchor border-bottom">
+        {t('security_settings.OAuth.GitHub.name')}
+      </h2>
 
 
-        {retrieveError != null && (
-          <div className="alert alert-danger">
-            <p>
-              {t('Error occurred')} : {retrieveError}
-            </p>
+      {retrieveError != null && (
+        <div className="alert alert-danger">
+          <p>
+            {t('Error occurred')} : {retrieveError}
+          </p>
+        </div>
+      )}
+
+      <div className="row my-4">
+        <div className="col-6 offset-3">
+          <div className="form-check form-switch form-check-success">
+            <input
+              id="isGitHubEnabled"
+              className="form-check-input"
+              type="checkbox"
+              checked={
+                adminGeneralSecurityContainer.state.isGitHubEnabled || false
+              }
+              onChange={() => {
+                adminGeneralSecurityContainer.switchIsGitHubOAuthEnabled();
+              }}
+            />
+            <label
+              className="form-label form-check-label"
+              htmlFor="isGitHubEnabled"
+            >
+              {t('security_settings.OAuth.GitHub.enable_github')}
+            </label>
           </div>
           </div>
-        )}
+          {!adminGeneralSecurityContainer.state.setupStrategies.includes(
+            'github',
+          ) &&
+            isGitHubEnabled && (
+              <div className="badge text-bg-warning">
+                {t('security_settings.setup_is_not_yet_complete')}
+              </div>
+            )}
+        </div>
+      </div>
 
 
-        <div className="row my-4">
-          <div className="col-6 offset-3">
-            <div className="form-check form-switch form-check-success">
-              <input
-                id="isGitHubEnabled"
-                className="form-check-input"
-                type="checkbox"
-                checked={
-                  adminGeneralSecurityContainer.state.isGitHubEnabled || false
-                }
-                onChange={() => {
-                  adminGeneralSecurityContainer.switchIsGitHubOAuthEnabled();
+      <div className="row mb-4">
+        <label
+          className="form-label col-12 col-md-3 text-start text-md-end py-2"
+          htmlFor="gitHubCallbackUrl"
+        >
+          {t('security_settings.callback_URL')}
+        </label>
+        <div className="col-12 col-md-6">
+          <input
+            id="gitHubCallbackUrl"
+            className="form-control"
+            type="text"
+            value={gitHubCallbackUrl}
+            readOnly
+          />
+          <p className="form-text text-muted small">
+            {t('security_settings.desc_of_callback_URL', {
+              AuthName: 'OAuth',
+            })}
+          </p>
+          {(siteUrl == null || siteUrl === '') && (
+            <div className="alert alert-danger">
+              <span className="material-symbols-outlined">error</span>
+              <span
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                dangerouslySetInnerHTML={{
+                  __html: t('alert.siteUrl_is_not_set', {
+                    link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
+                    ns: 'commons',
+                  }),
                 }}
                 }}
               />
               />
-              <label
-                className="form-label form-check-label"
-                htmlFor="isGitHubEnabled"
-              >
-                {t('security_settings.OAuth.GitHub.enable_github')}
-              </label>
             </div>
             </div>
-            {!adminGeneralSecurityContainer.state.setupStrategies.includes(
-              'github',
-            ) &&
-              isGitHubEnabled && (
-                <div className="badge text-bg-warning">
-                  {t('security_settings.setup_is_not_yet_complete')}
-                </div>
-              )}
-          </div>
+          )}
         </div>
         </div>
+      </div>
 
 
-        <div className="row mb-4">
-          <label
-            className="form-label col-12 col-md-3 text-start text-md-end py-2"
-            htmlFor="gitHubCallbackUrl"
-          >
-            {t('security_settings.callback_URL')}
-          </label>
-          <div className="col-12 col-md-6">
-            <input
-              id="gitHubCallbackUrl"
-              className="form-control"
-              type="text"
-              value={gitHubCallbackUrl}
-              readOnly
-            />
-            <p className="form-text text-muted small">
-              {t('security_settings.desc_of_callback_URL', {
-                AuthName: 'OAuth',
-              })}
-            </p>
-            {(siteUrl == null || siteUrl === '') && (
-              <div className="alert alert-danger">
-                <span className="material-symbols-outlined">error</span>
-                <span // eslint-disable-next-line max-len
+      {isGitHubEnabled && (
+        <>
+          <h3 className="border-bottom mb-4">
+            {t('security_settings.configuration')}
+          </h3>
+
+          <div className="row mb-4">
+            <label
+              htmlFor="githubClientId"
+              className="col-3 text-end py-2 form-label"
+            >
+              {t('security_settings.clientID')}
+            </label>
+            <div className="col-6">
+              <input
+                className="form-control"
+                type="text"
+                {...register('githubClientId')}
+              />
+              <p className="form-text text-muted">
+                <small
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
-                    __html: t('alert.siteUrl_is_not_set', {
-                      link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
-                      ns: 'commons',
+                    __html: t('security_settings.Use env var if empty', {
+                      env: 'OAUTH_GITHUB_CLIENT_ID',
                     }),
                     }),
                   }}
                   }}
                 />
                 />
-              </div>
-            )}
+              </p>
+            </div>
           </div>
           </div>
-        </div>
 
 
-        {isGitHubEnabled && (
-          <React.Fragment>
-            <h3 className="border-bottom mb-4">
-              {t('security_settings.configuration')}
-            </h3>
-
-            <div className="row mb-4">
-              <label
-                htmlFor="githubClientId"
-                className="col-3 text-end py-2 form-label"
-              >
-                {t('security_settings.clientID')}
-              </label>
-              <div className="col-6">
-                <input
-                  className="form-control"
-                  type="text"
-                  {...register('githubClientId')}
+          <div className="row mb-3">
+            <label
+              htmlFor="githubClientSecret"
+              className="col-3 text-end py-2 form-label"
+            >
+              {t('security_settings.client_secret')}
+            </label>
+            <div className="col-6">
+              <input
+                className="form-control"
+                type="text"
+                {...register('githubClientSecret')}
+              />
+              <p className="form-text text-muted">
+                <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t('security_settings.Use env var if empty', {
+                      env: 'OAUTH_GITHUB_CLIENT_SECRET',
+                    }),
+                  }}
                 />
                 />
-                <p className="form-text text-muted">
-                  <small
-                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                    dangerouslySetInnerHTML={{
-                      __html: t('security_settings.Use env var if empty', {
-                        env: 'OAUTH_GITHUB_CLIENT_ID',
-                      }),
-                    }}
-                  />
-                </p>
-              </div>
+              </p>
             </div>
             </div>
+          </div>
 
 
-            <div className="row mb-3">
-              <label
-                htmlFor="githubClientSecret"
-                className="col-3 text-end py-2 form-label"
-              >
-                {t('security_settings.client_secret')}
-              </label>
-              <div className="col-6">
+          <div className="row mb-3">
+            <div className="offset-3 col-6 text-start">
+              <div className="form-check form-check-success">
                 <input
                 <input
-                  className="form-control"
-                  type="text"
-                  {...register('githubClientSecret')}
+                  id="bindByUserNameGitHub"
+                  className="form-check-input"
+                  type="checkbox"
+                  checked={
+                    adminGitHubSecurityContainer.state
+                      .isSameUsernameTreatedAsIdenticalUser || false
+                  }
+                  onChange={() => {
+                    adminGitHubSecurityContainer.switchIsSameUsernameTreatedAsIdenticalUser();
+                  }}
                 />
                 />
-                <p className="form-text text-muted">
-                  <small
-                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                    dangerouslySetInnerHTML={{
-                      __html: t('security_settings.Use env var if empty', {
-                        env: 'OAUTH_GITHUB_CLIENT_SECRET',
-                      }),
-                    }}
-                  />
-                </p>
-              </div>
-            </div>
-
-            <div className="row mb-3">
-              <div className="offset-3 col-6 text-start">
-                <div className="form-check form-check-success">
-                  <input
-                    id="bindByUserNameGitHub"
-                    className="form-check-input"
-                    type="checkbox"
-                    checked={
-                      adminGitHubSecurityContainer.state
-                        .isSameUsernameTreatedAsIdenticalUser || false
-                    }
-                    onChange={() => {
-                      adminGitHubSecurityContainer.switchIsSameUsernameTreatedAsIdenticalUser();
-                    }}
-                  />
-                  <label
-                    className="form-check-label"
-                    htmlFor="bindByUserNameGitHub"
-                  >
-                    <span
-                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                      dangerouslySetInnerHTML={{
-                        __html: t(
-                          'security_settings.Treat email matching as identical',
-                        ),
-                      }}
-                    />
-                  </label>
-                </div>
-                <p className="form-text text-muted">
-                  <small
+                <label
+                  className="form-check-label"
+                  htmlFor="bindByUserNameGitHub"
+                >
+                  <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
-                        'security_settings.Treat email matching as identical_warn',
+                        'security_settings.Treat email matching as identical',
                       ),
                       ),
                     }}
                     }}
                   />
                   />
-                </p>
+                </label>
               </div>
               </div>
+              <p className="form-text text-muted">
+                <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t(
+                      'security_settings.Treat email matching as identical_warn',
+                    ),
+                  }}
+                />
+              </p>
             </div>
             </div>
+          </div>
 
 
-            <div className="row mb-4">
-              <div className="offset-3 col-5">
-                <button
-                  type="submit"
-                  className="btn btn-primary"
-                  disabled={retrieveError != null}
-                >
-                  {t('Update')}
-                </button>
-              </div>
+          <div className="row mb-4">
+            <div className="offset-3 col-5">
+              <button
+                type="submit"
+                className="btn btn-primary"
+                disabled={retrieveError != null}
+              >
+                {t('Update')}
+              </button>
             </div>
             </div>
-          </React.Fragment>
-        )}
+          </div>
+        </>
+      )}
 
 
-        <hr />
+      <hr />
 
 
-        <div style={{ minHeight: '300px' }}>
-          <h4>
-            <span className="material-symbols-outlined" aria-hidden="true">
-              help
-            </span>
-            <a href="#collapseHelpForGitHubOauth" data-bs-toggle="collapse">
-              {' '}
-              {t('security_settings.OAuth.how_to.github')}
-            </a>
-          </h4>
-          <div className="card custom-card bg-body-tertiary">
-            <ol id="collapseHelpForGitHubOauth" className="collapse mb-0">
-              {/* eslint-disable-next-line max-len */}
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.GitHub.register_1', {
-                    link: '<a href="https://github.com/settings/developers" target=_blank>GitHub Developer Settings</a>',
-                  }),
-                }}
-              />
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.GitHub.register_2', {
-                    url: gitHubCallbackUrl,
-                  }),
-                }}
-              />
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.GitHub.register_3'),
-                }}
-              />
-            </ol>
-          </div>
+      <div style={{ minHeight: '300px' }}>
+        <h4>
+          <span className="material-symbols-outlined" aria-hidden="true">
+            help
+          </span>
+          <a href="#collapseHelpForGitHubOauth" data-bs-toggle="collapse">
+            {' '}
+            {t('security_settings.OAuth.how_to.github')}
+          </a>
+        </h4>
+        <div className="card custom-card bg-body-tertiary">
+          <ol id="collapseHelpForGitHubOauth" className="collapse mb-0">
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.GitHub.register_1', {
+                  link: '<a href="https://github.com/settings/developers" target=_blank>GitHub Developer Settings</a>',
+                }),
+              }}
+            />
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.GitHub.register_2', {
+                  url: gitHubCallbackUrl,
+                }),
+              }}
+            />
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.GitHub.register_3'),
+              }}
+            />
+          </ol>
         </div>
         </div>
-      </React.Fragment>
+      </div>
     </form>
     </form>
   );
   );
 };
 };

+ 213 - 218
apps/app/src/client/components/Admin/Security/GoogleSecuritySettingContents.tsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-danger */
 import React, { useCallback, useEffect } from 'react';
 import React, { useCallback, useEffect } from 'react';
 import { pathUtils } from '@growi/core/dist/utils';
 import { pathUtils } from '@growi/core/dist/utils';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
@@ -62,256 +61,252 @@ const GoogleSecurityManagementContents = (props: Props) => {
 
 
   return (
   return (
     <form onSubmit={handleSubmit(onClickSubmit)}>
     <form onSubmit={handleSubmit(onClickSubmit)}>
-      <React.Fragment>
-        <h2 className="alert-anchor border-bottom">
-          {t('security_settings.OAuth.Google.name')}
-        </h2>
+      <h2 className="alert-anchor border-bottom">
+        {t('security_settings.OAuth.Google.name')}
+      </h2>
 
 
-        {retrieveError != null && (
-          <div className="alert alert-danger">
-            <p>
-              {t('Error occurred')} : {retrieveError}
-            </p>
+      {retrieveError != null && (
+        <div className="alert alert-danger">
+          <p>
+            {t('Error occurred')} : {retrieveError}
+          </p>
+        </div>
+      )}
+
+      <div className="row my-4">
+        <div className="col-6 offset-3">
+          <div className="form-check form-switch form-check-success">
+            <input
+              id="isGoogleEnabled"
+              className="form-check-input"
+              type="checkbox"
+              checked={
+                adminGeneralSecurityContainer.state.isGoogleEnabled || false
+              }
+              onChange={() => {
+                adminGeneralSecurityContainer.switchIsGoogleOAuthEnabled();
+              }}
+            />
+            <label
+              className="form-label form-check-label"
+              htmlFor="isGoogleEnabled"
+            >
+              {t('security_settings.OAuth.Google.enable_google')}
+            </label>
           </div>
           </div>
-        )}
+          {!adminGeneralSecurityContainer.state.setupStrategies.includes(
+            'google',
+          ) &&
+            isGoogleEnabled && (
+              <div className="badge text-bg-warning">
+                {t('security_settings.setup_is_not_yet_complete')}
+              </div>
+            )}
+        </div>
+      </div>
 
 
-        <div className="row my-4">
-          <div className="col-6 offset-3">
-            <div className="form-check form-switch form-check-success">
-              <input
-                id="isGoogleEnabled"
-                className="form-check-input"
-                type="checkbox"
-                checked={
-                  adminGeneralSecurityContainer.state.isGoogleEnabled || false
-                }
-                onChange={() => {
-                  adminGeneralSecurityContainer.switchIsGoogleOAuthEnabled();
+      <div className="row mb-5">
+        <label
+          className="form-label col-12 col-md-3 text-start text-md-end py-2"
+          htmlFor="googleCallbackUrl"
+        >
+          {t('security_settings.callback_URL')}
+        </label>
+        <div className="col-12 col-md-6">
+          <input
+            id="googleCallbackUrl"
+            className="form-control"
+            type="text"
+            value={googleCallbackUrl}
+            readOnly
+          />
+          <p className="form-text text-muted small">
+            {t('security_settings.desc_of_callback_URL', {
+              AuthName: 'OAuth',
+            })}
+          </p>
+          {(siteUrl == null || siteUrl === '') && (
+            <div className="alert alert-danger">
+              <span className="material-symbols-outlined">error</span>
+              <span
+                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                dangerouslySetInnerHTML={{
+                  __html: t('alert.siteUrl_is_not_set', {
+                    link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
+                    ns: 'commons',
+                  }),
                 }}
                 }}
               />
               />
-              <label
-                className="form-label form-check-label"
-                htmlFor="isGoogleEnabled"
-              >
-                {t('security_settings.OAuth.Google.enable_google')}
-              </label>
             </div>
             </div>
-            {!adminGeneralSecurityContainer.state.setupStrategies.includes(
-              'google',
-            ) &&
-              isGoogleEnabled && (
-                <div className="badge text-bg-warning">
-                  {t('security_settings.setup_is_not_yet_complete')}
-                </div>
-              )}
-          </div>
+          )}
         </div>
         </div>
+      </div>
 
 
-        <div className="row mb-5">
-          <label
-            className="form-label col-12 col-md-3 text-start text-md-end py-2"
-            htmlFor="googleCallbackUrl"
-          >
-            {t('security_settings.callback_URL')}
-          </label>
-          <div className="col-12 col-md-6">
-            <input
-              id="googleCallbackUrl"
-              className="form-control"
-              type="text"
-              value={googleCallbackUrl}
-              readOnly
-            />
-            <p className="form-text text-muted small">
-              {t('security_settings.desc_of_callback_URL', {
-                AuthName: 'OAuth',
-              })}
-            </p>
-            {(siteUrl == null || siteUrl === '') && (
-              <div className="alert alert-danger">
-                <span className="material-symbols-outlined">error</span>
-                <span
-                  // eslint-disable-next-line max-len
+      {isGoogleEnabled && (
+        <React.Fragment>
+          <h3 className="border-bottom mb-4">
+            {t('security_settings.configuration')}
+          </h3>
+
+          <div className="row mb-4">
+            <label
+              htmlFor="googleClientId"
+              className="col-3 text-end py-2 form-label"
+            >
+              {t('security_settings.clientID')}
+            </label>
+            <div className="col-6">
+              <input
+                className="form-control"
+                type="text"
+                {...register('googleClientId')}
+              />
+              <p className="form-text text-muted">
+                <small
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
-                    __html: t('alert.siteUrl_is_not_set', {
-                      link: `<a href="/admin/app">${t('headers.app_settings', { ns: 'commons' })}<span class="material-symbols-outlined">login</span></a>`,
-                      ns: 'commons',
+                    __html: t('security_settings.Use env var if empty', {
+                      env: 'OAUTH_GOOGLE_CLIENT_ID',
                     }),
                     }),
                   }}
                   }}
                 />
                 />
-              </div>
-            )}
+              </p>
+            </div>
           </div>
           </div>
-        </div>
 
 
-        {isGoogleEnabled && (
-          <React.Fragment>
-            <h3 className="border-bottom mb-4">
-              {t('security_settings.configuration')}
-            </h3>
-
-            <div className="row mb-4">
-              <label
-                htmlFor="googleClientId"
-                className="col-3 text-end py-2 form-label"
-              >
-                {t('security_settings.clientID')}
-              </label>
-              <div className="col-6">
-                <input
-                  className="form-control"
-                  type="text"
-                  {...register('googleClientId')}
+          <div className="row mb-4">
+            <label
+              htmlFor="googleClientSecret"
+              className="col-3 text-end py-2 form-label"
+            >
+              {t('security_settings.client_secret')}
+            </label>
+            <div className="col-6">
+              <input
+                className="form-control"
+                type="password"
+                {...register('googleClientSecret')}
+              />
+              <p className="form-text text-muted">
+                <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t('security_settings.Use env var if empty', {
+                      env: 'OAUTH_GOOGLE_CLIENT_SECRET',
+                    }),
+                  }}
                 />
                 />
-                <p className="form-text text-muted">
-                  <small
-                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                    dangerouslySetInnerHTML={{
-                      __html: t('security_settings.Use env var if empty', {
-                        env: 'OAUTH_GOOGLE_CLIENT_ID',
-                      }),
-                    }}
-                  />
-                </p>
-              </div>
+              </p>
             </div>
             </div>
+          </div>
 
 
-            <div className="row mb-4">
-              <label
-                htmlFor="googleClientSecret"
-                className="col-3 text-end py-2 form-label"
-              >
-                {t('security_settings.client_secret')}
-              </label>
-              <div className="col-6">
+          <div className="row mb-3">
+            <div className="offset-3 col-6">
+              <div className="form-check form-check-success">
                 <input
                 <input
-                  className="form-control"
-                  type="password"
-                  {...register('googleClientSecret')}
+                  id="bindByUserNameGoogle"
+                  className="form-check-input"
+                  type="checkbox"
+                  checked={
+                    adminGoogleSecurityContainer.state
+                      .isSameEmailTreatedAsIdenticalUser || false
+                  }
+                  onChange={() => {
+                    adminGoogleSecurityContainer.switchIsSameEmailTreatedAsIdenticalUser();
+                  }}
                 />
                 />
-                <p className="form-text text-muted">
-                  <small
-                    // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                    dangerouslySetInnerHTML={{
-                      __html: t('security_settings.Use env var if empty', {
-                        env: 'OAUTH_GOOGLE_CLIENT_SECRET',
-                      }),
-                    }}
-                  />
-                </p>
-              </div>
-            </div>
-
-            <div className="row mb-3">
-              <div className="offset-3 col-6">
-                <div className="form-check form-check-success">
-                  <input
-                    id="bindByUserNameGoogle"
-                    className="form-check-input"
-                    type="checkbox"
-                    checked={
-                      adminGoogleSecurityContainer.state
-                        .isSameEmailTreatedAsIdenticalUser || false
-                    }
-                    onChange={() => {
-                      adminGoogleSecurityContainer.switchIsSameEmailTreatedAsIdenticalUser();
-                    }}
-                  />
-                  <label
-                    className="form-check-label"
-                    htmlFor="bindByUserNameGoogle"
-                  >
-                    <span
-                      // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                      dangerouslySetInnerHTML={{
-                        __html: t(
-                          'security_settings.Treat email matching as identical',
-                        ),
-                      }}
-                    />
-                  </label>
-                </div>
-                <p className="form-text text-muted">
-                  <small
+                <label
+                  className="form-check-label"
+                  htmlFor="bindByUserNameGoogle"
+                >
+                  <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
-                        'security_settings.Treat email matching as identical_warn',
+                        'security_settings.Treat email matching as identical',
                       ),
                       ),
                     }}
                     }}
                   />
                   />
-                </p>
+                </label>
               </div>
               </div>
+              <p className="form-text text-muted">
+                <small
+                  // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+                  dangerouslySetInnerHTML={{
+                    __html: t(
+                      'security_settings.Treat email matching as identical_warn',
+                    ),
+                  }}
+                />
+              </p>
             </div>
             </div>
+          </div>
 
 
-            <div className="row mb-4">
-              <div className="offset-3 col-5">
-                <button
-                  type="submit"
-                  className="btn btn-primary"
-                  disabled={retrieveError != null}
-                >
-                  {t('Update')}
-                </button>
-              </div>
+          <div className="row mb-4">
+            <div className="offset-3 col-5">
+              <button
+                type="submit"
+                className="btn btn-primary"
+                disabled={retrieveError != null}
+              >
+                {t('Update')}
+              </button>
             </div>
             </div>
-          </React.Fragment>
-        )}
+          </div>
+        </React.Fragment>
+      )}
 
 
-        <hr />
+      <hr />
 
 
-        <div style={{ minHeight: '300px' }}>
-          <h4>
-            <span className="material-symbols-outlined" aria-hidden="true">
-              help
-            </span>
-            <a href="#collapseHelpForGoogleOauth" data-bs-toggle="collapse">
-              {' '}
-              {t('security_settings.OAuth.how_to.google')}
-            </a>
-          </h4>
-          <div className="card custom-card bg-body-tertiary">
-            <ol id="collapseHelpForGoogleOauth" className="collapse mb-0">
-              {/* eslint-disable-next-line max-len */}
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.Google.register_1', {
-                    link: '<a href="https://console.cloud.google.com/apis/credentials" target=_blank>Google Cloud Platform API Manager</a>',
-                  }),
-                }}
-              />
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.Google.register_2'),
-                }}
-              />
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.Google.register_3'),
-                }}
-              />
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.Google.register_4', {
-                    url: googleCallbackUrl,
-                  }),
-                }}
-              />
-              <li
-                // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
-                dangerouslySetInnerHTML={{
-                  __html: t('security_settings.OAuth.Google.register_5'),
-                }}
-              />
-            </ol>
-          </div>
+      <div style={{ minHeight: '300px' }}>
+        <h4>
+          <span className="material-symbols-outlined" aria-hidden="true">
+            help
+          </span>
+          <a href="#collapseHelpForGoogleOauth" data-bs-toggle="collapse">
+            {' '}
+            {t('security_settings.OAuth.how_to.google')}
+          </a>
+        </h4>
+        <div className="card custom-card bg-body-tertiary">
+          <ol id="collapseHelpForGoogleOauth" className="collapse mb-0">
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.Google.register_1', {
+                  link: '<a href="https://console.cloud.google.com/apis/credentials" target=_blank>Google Cloud Platform API Manager</a>',
+                }),
+              }}
+            />
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.Google.register_2'),
+              }}
+            />
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.Google.register_3'),
+              }}
+            />
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.Google.register_4', {
+                  url: googleCallbackUrl,
+                }),
+              }}
+            />
+            <li
+              // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
+              dangerouslySetInnerHTML={{
+                __html: t('security_settings.OAuth.Google.register_5'),
+              }}
+            />
+          </ol>
         </div>
         </div>
-      </React.Fragment>
+      </div>
     </form>
     </form>
   );
   );
 };
 };

+ 0 - 12
apps/app/src/client/components/Admin/Security/LdapSecuritySettingContents.tsx

@@ -157,7 +157,6 @@ const LdapSecuritySettingContents = (props: Props) => {
               <small>
               <small>
                 <p
                 <p
                   className="form-text text-muted"
                   className="form-text text-muted"
-                  // eslint-disable-next-line react/no-danger
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
                     __html: t('security_settings.ldap.server_url_detail'),
                     __html: t('security_settings.ldap.server_url_detail'),
@@ -238,7 +237,6 @@ const LdapSecuritySettingContents = (props: Props) => {
                   <small>
                   <small>
                     {t('security_settings.ldap.bind_DN_user_detail1')}
                     {t('security_settings.ldap.bind_DN_user_detail1')}
                     <br />
                     <br />
-                    {/* eslint-disable-next-line react/no-danger */}
                     <span
                     <span
                       // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
@@ -322,7 +320,6 @@ const LdapSecuritySettingContents = (props: Props) => {
                 <small>
                 <small>
                   {t('security_settings.ldap.search_filter_detail1')}
                   {t('security_settings.ldap.search_filter_detail1')}
                   <br />
                   <br />
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
@@ -330,7 +327,6 @@ const LdapSecuritySettingContents = (props: Props) => {
                     }}
                     }}
                   />
                   />
                   <br />
                   <br />
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
@@ -374,7 +370,6 @@ const LdapSecuritySettingContents = (props: Props) => {
                 {...register('ldapAttrMapUsername')}
                 {...register('ldapAttrMapUsername')}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
@@ -405,7 +400,6 @@ const LdapSecuritySettingContents = (props: Props) => {
                   htmlFor="isSameUsernameTreatedAsIdenticalUser"
                   htmlFor="isSameUsernameTreatedAsIdenticalUser"
                 >
                 >
                   <span
                   <span
-                    // eslint-disable-next-line react/no-danger
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t(
                       __html: t(
@@ -416,7 +410,6 @@ const LdapSecuritySettingContents = (props: Props) => {
                 </label>
                 </label>
               </div>
               </div>
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{
@@ -489,7 +482,6 @@ const LdapSecuritySettingContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small>
                 <small>
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
@@ -521,7 +513,6 @@ const LdapSecuritySettingContents = (props: Props) => {
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small>
                 <small>
-                  {/* eslint-disable react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
@@ -548,13 +539,11 @@ const LdapSecuritySettingContents = (props: Props) => {
                       ),
                       ),
                     }}
                     }}
                   />
                   />
-                  {/* eslint-enable react/no-danger */}
                 </small>
                 </small>
               </p>
               </p>
               <p className="form-text text-muted">
               <p className="form-text text-muted">
                 <small>
                 <small>
                   {t('security_settings.example')}:
                   {t('security_settings.example')}:
-                  {/* eslint-disable-next-line react/no-danger */}
                   <span
                   <span
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
@@ -585,7 +574,6 @@ const LdapSecuritySettingContents = (props: Props) => {
                 {...register('ldapGroupDnProperty')}
                 {...register('ldapGroupDnProperty')}
               />
               />
               <p className="form-text text-muted">
               <p className="form-text text-muted">
-                {/* eslint-disable-next-line react/no-danger */}
                 <small
                 <small
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                   dangerouslySetInnerHTML={{
                   dangerouslySetInnerHTML={{

+ 0 - 1
apps/app/src/client/components/Admin/Security/LocalSecuritySettingContents.tsx

@@ -75,7 +75,6 @@ const LocalSecuritySettingContents = (props: Props): JSX.Element => {
       {adminLocalSecurityContainer.state.useOnlyEnvVars && (
       {adminLocalSecurityContainer.state.useOnlyEnvVars && (
         <p
         <p
           className="alert alert-info"
           className="alert alert-info"
-          // eslint-disable-next-line max-len
           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
           dangerouslySetInnerHTML={{
           dangerouslySetInnerHTML={{
             __html: t('security_settings.Local.note for the only env option', {
             __html: t('security_settings.Local.note for the only env option', {

+ 0 - 2
apps/app/src/client/components/Admin/Security/OidcSecuritySettingContents.tsx

@@ -180,7 +180,6 @@ const OidcSecurityManagementContents = (props: Props) => {
             <div className="alert alert-danger">
             <div className="alert alert-danger">
               <span className="material-symbols-outlined">error</span>
               <span className="material-symbols-outlined">error</span>
               <span
               <span
-                // eslint-disable-next-line max-len
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('alert.siteUrl_is_not_set', {
                   __html: t('alert.siteUrl_is_not_set', {
@@ -628,7 +627,6 @@ const OidcSecurityManagementContents = (props: Props) => {
                 <div className="alert alert-danger">
                 <div className="alert alert-danger">
                   <span className="material-symbols-outlined">error</span>
                   <span className="material-symbols-outlined">error</span>
                   <span
                   <span
-                    // eslint-disable-next-line max-len
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                     dangerouslySetInnerHTML={{
                     dangerouslySetInnerHTML={{
                       __html: t('alert.siteUrl_is_not_set', {
                       __html: t('alert.siteUrl_is_not_set', {

+ 0 - 4
apps/app/src/client/components/Admin/Security/SamlSecuritySettingContents.tsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-danger */
 import React, { useCallback, useEffect, useState } from 'react';
 import React, { useCallback, useEffect, useState } from 'react';
 import { pathUtils } from '@growi/core/dist/utils';
 import { pathUtils } from '@growi/core/dist/utils';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
@@ -158,7 +157,6 @@ const SamlSecurityManagementContents = (props: Props) => {
             <div className="alert alert-danger">
             <div className="alert alert-danger">
               <span className="material-symbols-outlined">error</span>
               <span className="material-symbols-outlined">error</span>
               <span
               <span
-                // eslint-disable-next-line max-len
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{
                   __html: t('alert.siteUrl_is_not_set', {
                   __html: t('alert.siteUrl_is_not_set', {
@@ -466,7 +464,6 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     {...register('samlAttrMapFirstName')}
                     {...register('samlAttrMapFirstName')}
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
-                    {/* eslint-disable-next-line max-len */}
                     <small
                     <small
                       // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{
@@ -522,7 +519,6 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
                     {...register('samlAttrMapLastName')}
                     {...register('samlAttrMapLastName')}
                   />
                   />
                   <p className="form-text text-muted">
                   <p className="form-text text-muted">
-                    {/* eslint-disable-next-line max-len */}
                     <small
                     <small
                       // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                       dangerouslySetInnerHTML={{
                       dangerouslySetInnerHTML={{

+ 0 - 2
apps/app/src/client/components/Admin/Security/SecuritySetting/PageAccessRightsSettings.tsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-danger */
 import type React from 'react';
 import type React from 'react';
 
 
 import type AdminGeneralSecurityContainer from '~/client/services/AdminGeneralSecurityContainer';
 import type AdminGeneralSecurityContainer from '~/client/services/AdminGeneralSecurityContainer';
@@ -68,7 +67,6 @@ export const PageAccessRightsSettings: React.FC<Props> = ({
               <span className="material-symbols-outlined me-1">error</span>
               <span className="material-symbols-outlined me-1">error</span>
               <b>FIXED</b>
               <b>FIXED</b>
               <br />
               <br />
-              {/* eslint-disable-next-line react/no-danger */}
               <b
               <b
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                 dangerouslySetInnerHTML={{
                 dangerouslySetInnerHTML={{

+ 0 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting/PageDeleteRightsSettings.tsx

@@ -330,7 +330,6 @@ export const PageDeleteRightsSettings: React.FC<Props> = ({
                     <p className="card custom-card bg-warning-sublte">
                     <p className="card custom-card bg-warning-sublte">
                       <span className="text-warning">
                       <span className="text-warning">
                         <span className="material-symbols-outlined">info</span>
                         <span className="material-symbols-outlined">info</span>
-                        {/* eslint-disable-next-line react/no-danger */}
                         <span
                         <span
                           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                           // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
                           dangerouslySetInnerHTML={{
                           dangerouslySetInnerHTML={{

+ 0 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting/SessionMaxAgeSettings.tsx

@@ -25,7 +25,6 @@ export const SessionMaxAgeSettings: React.FC<Props> = ({ register, t }) => {
             {...register('sessionMaxAge')}
             {...register('sessionMaxAge')}
             placeholder="2592000000"
             placeholder="2592000000"
           />
           />
-          {/* eslint-disable-next-line react/no-danger */}
           <p
           <p
             className="form-text text-muted"
             className="form-text text-muted"
             // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup
             // biome-ignore lint/security/noDangerouslySetInnerHtml: trusted translation markup

+ 0 - 1
apps/app/src/client/components/Admin/Security/SecuritySetting/UserHomepageDeletionSettings.tsx

@@ -1,4 +1,3 @@
-/* eslint-disable react/no-danger */
 import type React from 'react';
 import type React from 'react';
 
 
 import type AdminGeneralSecurityContainer from '~/client/services/AdminGeneralSecurityContainer';
 import type AdminGeneralSecurityContainer from '~/client/services/AdminGeneralSecurityContainer';

+ 0 - 2
apps/app/src/client/components/Admin/SlackIntegration/Bridge.tsx

@@ -35,7 +35,6 @@ const BridgeCore = (props: BridgeCoreProps): JSX.Element => {
           <span className={iconClass}>{iconName}</span>
           <span className={iconClass}>{iconName}</span>
           <small
           <small
             className="ms-2 d-none d-lg-inline"
             className="ms-2 d-none d-lg-inline"
-            // eslint-disable-next-line react/no-danger
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             dangerouslySetInnerHTML={{ __html: description }}
             dangerouslySetInnerHTML={{ __html: description }}
           />
           />
@@ -52,7 +51,6 @@ const BridgeCore = (props: BridgeCoreProps): JSX.Element => {
         className="d-block d-lg-none"
         className="d-block d-lg-none"
       >
       >
         <small
         <small
-          // eslint-disable-next-line react/no-danger
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
           dangerouslySetInnerHTML={{ __html: description }}
           dangerouslySetInnerHTML={{ __html: description }}
         />
         />

+ 0 - 2
apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithoutProxySecretTokenSection.jsx

@@ -80,7 +80,6 @@ const CustomBotWithoutProxySecretTokenSection = (props) => {
             readOnly
             readOnly
           />
           />
           <p className="form-text text-muted">
           <p className="form-text text-muted">
-            {/* eslint-disable-next-line max-len, react/no-danger */}
             <small
             <small
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
@@ -114,7 +113,6 @@ const CustomBotWithoutProxySecretTokenSection = (props) => {
             readOnly
             readOnly
           />
           />
           <p className="form-text text-muted">
           <p className="form-text text-muted">
-            {/* eslint-disable-next-line react/no-danger */}
             <small
             <small
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{

+ 1 - 5
apps/app/src/client/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx

@@ -31,8 +31,7 @@ const CustomBotWithoutProxySettingsAccordion = (props) => {
   const successMessage = 'Successfully sent to Slack workspace.';
   const successMessage = 'Successfully sent to Slack workspace.';
 
 
   const { t } = useTranslation();
   const { t } = useTranslation();
-  // eslint-disable-next-line no-unused-vars
-  const [defaultOpenAccordionKeys, setDefaultOpenAccordionKeys] = useState(
+  const [defaultOpenAccordionKeys, _setDefaultOpenAccordionKeys] = useState(
     new Set([activeStep]),
     new Set([activeStep]),
   );
   );
   const [isLatestConnectionSuccess, setIsLatestConnectionSuccess] =
   const [isLatestConnectionSuccess, setIsLatestConnectionSuccess] =
@@ -177,7 +176,6 @@ const CustomBotWithoutProxySettingsAccordion = (props) => {
         defaultIsActive={defaultOpenAccordionKeys.has(
         defaultIsActive={defaultOpenAccordionKeys.has(
           botInstallationStep.REGISTER_SLACK_CONFIGURATION,
           botInstallationStep.REGISTER_SLACK_CONFIGURATION,
         )}
         )}
-        // eslint-disable-next-line max-len
         title={
         title={
           <>
           <>
             <span className="me-3">3</span>
             <span className="me-3">3</span>
@@ -202,7 +200,6 @@ const CustomBotWithoutProxySettingsAccordion = (props) => {
         defaultIsActive={defaultOpenAccordionKeys.has(
         defaultIsActive={defaultOpenAccordionKeys.has(
           botInstallationStep.CONNECTION_TEST,
           botInstallationStep.CONNECTION_TEST,
         )}
         )}
-        // eslint-disable-next-line max-len
         title={
         title={
           <>
           <>
             <span className="me-3">4</span>
             <span className="me-3">4</span>
@@ -219,7 +216,6 @@ const CustomBotWithoutProxySettingsAccordion = (props) => {
         defaultIsActive={defaultOpenAccordionKeys.has(
         defaultIsActive={defaultOpenAccordionKeys.has(
           botInstallationStep.CONNECTION_TEST,
           botInstallationStep.CONNECTION_TEST,
         )}
         )}
-        // eslint-disable-next-line max-len
         title={
         title={
           <>
           <>
             <span className="me-3">5</span>
             <span className="me-3">5</span>

+ 0 - 1
apps/app/src/client/components/Admin/SlackIntegration/DeleteSlackBotSettingsModal.tsx

@@ -48,7 +48,6 @@ export const DeleteSlackBotSettingsModal = React.memo(
         : t('admin:slack_integration.slackbot_settings_notice');
         : t('admin:slack_integration.slackbot_settings_notice');
       return (
       return (
         <span
         <span
-          // eslint-disable-next-line react/no-danger
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
           // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
           dangerouslySetInnerHTML={{ __html: htmlContent }}
           dangerouslySetInnerHTML={{ __html: htmlContent }}
         />
         />

+ 1 - 1
apps/app/src/client/components/Admin/SlackIntegration/ManageCommandsProcess.jsx

@@ -236,7 +236,7 @@ PermissionSettingsForEachCategoryComponent.propTypes = {
   permissionSettings: PropTypes.object,
   permissionSettings: PropTypes.object,
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+// biome-ignore lint:*:noExplicitModuleBoundaryTypes: Temporary Alternative to @typescript-eslint/explicit-module-boundary-types
 const ManageCommandsProcess = ({
 const ManageCommandsProcess = ({
   slackAppIntegrationId,
   slackAppIntegrationId,
   permissionsForBroadcastUseCommands,
   permissionsForBroadcastUseCommands,

+ 1 - 2
apps/app/src/client/components/Admin/SlackIntegration/ManageCommandsProcessWithoutProxy.jsx

@@ -174,7 +174,7 @@ SinglePermissionSettingComponent.propTypes = {
   onPermissionListChanged: PropTypes.func,
   onPermissionListChanged: PropTypes.func,
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
+// biome-ignore lint:*:noExplicitModuleBoundaryTypes: Temporary Alternative to @typescript-eslint/explicit-module-boundary-types
 const ManageCommandsProcessWithoutProxy = ({
 const ManageCommandsProcessWithoutProxy = ({
   commandPermission,
   commandPermission,
   eventActionsPermission,
   eventActionsPermission,
@@ -263,7 +263,6 @@ const ManageCommandsProcessWithoutProxy = ({
           <div className="form-check">
           <div className="form-check">
             <div className="row mb-5 d-block">
             <div className="row mb-5 d-block">
               {defaultCommandsName.map((commandName) => {
               {defaultCommandsName.map((commandName) => {
-                // eslint-disable-next-line max-len
                 return (
                 return (
                   <SinglePermissionSettingComponent
                   <SinglePermissionSettingComponent
                     key={`${commandName}-component`}
                     key={`${commandName}-component`}

+ 1 - 7
apps/app/src/client/components/Admin/SlackIntegration/WithProxyAccordions.jsx

@@ -1,5 +1,4 @@
-/* eslint-disable react/prop-types */
-import React, { useState } from 'react';
+import { useState } from 'react';
 import { SlackbotType } from '@growi/slack';
 import { SlackbotType } from '@growi/slack';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
@@ -138,7 +137,6 @@ const RegisteringProxyUrlProcess = () => {
       <ol>
       <ol>
         <li>
         <li>
           <p
           <p
-            // eslint-disable-next-line react/no-danger
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
               __html: t('admin:slack_integration.accordion.copy_proxy_url'),
               __html: t('admin:slack_integration.accordion.copy_proxy_url'),
@@ -154,7 +152,6 @@ const RegisteringProxyUrlProcess = () => {
         </li>
         </li>
         <li>
         <li>
           <p
           <p
-            // eslint-disable-next-line react/no-danger
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
               __html: t(
               __html: t(
@@ -271,7 +268,6 @@ const GeneratingTokensAndRegisteringProxyServiceProcess = (props) => {
           <li>
           <li>
             <p
             <p
               className="ms-2"
               className="ms-2"
-              // eslint-disable-next-line react/no-danger
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t(
                 __html: t(
@@ -285,7 +281,6 @@ const GeneratingTokensAndRegisteringProxyServiceProcess = (props) => {
               className="ms-2"
               className="ms-2"
               // TODO: Add dynamic link
               // TODO: Add dynamic link
               // TODO: Add logo
               // TODO: Add logo
-              // eslint-disable-next-line react/no-danger
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t('admin:slack_integration.accordion.paste_growi_url'),
                 __html: t('admin:slack_integration.accordion.paste_growi_url'),
@@ -309,7 +304,6 @@ const GeneratingTokensAndRegisteringProxyServiceProcess = (props) => {
           <li>
           <li>
             <p
             <p
               className="ms-2"
               className="ms-2"
-              // eslint-disable-next-line react/no-danger
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t(
                 __html: t(

+ 0 - 5
apps/app/src/client/components/Admin/UserGroupDetail/use-user-group-resource.ts

@@ -13,7 +13,6 @@ import {
   useSWRxUserGroupRelations,
   useSWRxUserGroupRelations,
 } from '~/stores/user-group';
 } from '~/stores/user-group';
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 export const useUserGroup = (userGroupId: string, isExternalGroup: boolean) => {
 export const useUserGroup = (userGroupId: string, isExternalGroup: boolean) => {
   const userGroupRes = useSWRxUserGroup(isExternalGroup ? null : userGroupId);
   const userGroupRes = useSWRxUserGroup(isExternalGroup ? null : userGroupId);
   const externalUserGroupRes = useSWRxExternalUserGroup(
   const externalUserGroupRes = useSWRxExternalUserGroup(
@@ -22,7 +21,6 @@ export const useUserGroup = (userGroupId: string, isExternalGroup: boolean) => {
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 export const useUserGroupRelations = (
 export const useUserGroupRelations = (
   userGroupId: string,
   userGroupId: string,
   isExternalGroup: boolean,
   isExternalGroup: boolean,
@@ -36,7 +34,6 @@ export const useUserGroupRelations = (
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 export const useChildUserGroupList = (
 export const useChildUserGroupList = (
   userGroupId: string,
   userGroupId: string,
   isExternalGroup: boolean,
   isExternalGroup: boolean,
@@ -52,7 +49,6 @@ export const useChildUserGroupList = (
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 export const useUserGroupRelationList = (
 export const useUserGroupRelationList = (
   userGroupIds: string[],
   userGroupIds: string[],
   isExternalGroup: boolean,
   isExternalGroup: boolean,
@@ -66,7 +62,6 @@ export const useUserGroupRelationList = (
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
   return isExternalGroup ? externalUserGroupRes : userGroupRes;
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
 export const useAncestorUserGroups = (
 export const useAncestorUserGroups = (
   userGroupId: string,
   userGroupId: string,
   isExternalGroup: boolean,
   isExternalGroup: boolean,

+ 0 - 1
apps/app/src/client/components/Admin/Users/GrantAdminButton.tsx

@@ -40,7 +40,6 @@ const GrantAdminButton = (props: GrantAdminButtonProps): JSX.Element => {
 /**
 /**
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
-// eslint-disable-next-line max-len
 const GrantAdminButtonWrapper: React.ForwardRefExoticComponent<
 const GrantAdminButtonWrapper: React.ForwardRefExoticComponent<
   Pick<any, string | number | symbol> & React.RefAttributes<any>
   Pick<any, string | number | symbol> & React.RefAttributes<any>
 > = withUnstatedContainers(GrantAdminButton, [AdminUsersContainer]);
 > = withUnstatedContainers(GrantAdminButton, [AdminUsersContainer]);

+ 0 - 1
apps/app/src/client/components/Admin/Users/GrantReadOnlyButton.tsx

@@ -37,7 +37,6 @@ const GrantReadOnlyButton: React.FC<{
 /**
 /**
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
-// eslint-disable-next-line max-len
 const GrantReadOnlyButtonWrapper: React.ForwardRefExoticComponent<
 const GrantReadOnlyButtonWrapper: React.ForwardRefExoticComponent<
   Pick<any, string | number | symbol> & React.RefAttributes<any>
   Pick<any, string | number | symbol> & React.RefAttributes<any>
 > = withUnstatedContainers(GrantReadOnlyButton, [AdminUsersContainer]);
 > = withUnstatedContainers(GrantReadOnlyButton, [AdminUsersContainer]);

+ 0 - 1
apps/app/src/client/components/Admin/Users/PasswordResetModal.jsx

@@ -85,7 +85,6 @@ class PasswordResetModal extends React.Component {
         {!isMailerSetup ? (
         {!isMailerSetup ? (
           <p
           <p
             className="form-label form-text text-muted mb-0"
             className="form-label form-text text-muted mb-0"
-            // eslint-disable-next-line react/no-danger
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
             dangerouslySetInnerHTML={{
             dangerouslySetInnerHTML={{
               __html: t('admin:mailer_setup_required'),
               __html: t('admin:mailer_setup_required'),

+ 0 - 1
apps/app/src/client/components/Admin/Users/RevokeAdminMenuItem.tsx

@@ -61,7 +61,6 @@ const RevokeAdminMenuItem = (props: Props): JSX.Element => {
 /**
 /**
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
-// eslint-disable-next-line max-len
 const RevokeAdminMenuItemWrapper: React.ForwardRefExoticComponent<
 const RevokeAdminMenuItemWrapper: React.ForwardRefExoticComponent<
   Pick<any, string | number | symbol> & React.RefAttributes<any>
   Pick<any, string | number | symbol> & React.RefAttributes<any>
 > = withUnstatedContainers(RevokeAdminMenuItem, [AdminUsersContainer]);
 > = withUnstatedContainers(RevokeAdminMenuItem, [AdminUsersContainer]);

+ 0 - 1
apps/app/src/client/components/Admin/Users/RevokeReadOnlyMenuItem.tsx

@@ -37,7 +37,6 @@ const RevokeReadOnlyMenuItem: React.FC<{
 /**
 /**
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
-// eslint-disable-next-line max-len
 const RevokeReadOnlyMenuItemWrapper: React.ForwardRefExoticComponent<
 const RevokeReadOnlyMenuItemWrapper: React.ForwardRefExoticComponent<
   Pick<any, string | number | symbol> & React.RefAttributes<any>
   Pick<any, string | number | symbol> & React.RefAttributes<any>
 > = withUnstatedContainers(RevokeReadOnlyMenuItem, [AdminUsersContainer]);
 > = withUnstatedContainers(RevokeReadOnlyMenuItem, [AdminUsersContainer]);

+ 0 - 1
apps/app/src/client/components/Admin/Users/StatusSuspendMenuItem.tsx

@@ -61,7 +61,6 @@ const StatusSuspendMenuItem = (props: Props): JSX.Element => {
 /**
 /**
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
-// eslint-disable-next-line max-len
 const StatusSuspendMenuItemWrapper: React.ForwardRefExoticComponent<
 const StatusSuspendMenuItemWrapper: React.ForwardRefExoticComponent<
   Pick<any, string | number | symbol> & React.RefAttributes<any>
   Pick<any, string | number | symbol> & React.RefAttributes<any>
 > = withUnstatedContainers(StatusSuspendMenuItem, [AdminUsersContainer]);
 > = withUnstatedContainers(StatusSuspendMenuItem, [AdminUsersContainer]);

+ 0 - 3
apps/app/src/client/components/Admin/Users/UserInviteModal.jsx

@@ -126,10 +126,8 @@ class UserInviteModal extends React.Component {
             {t('admin:user_management.invite_modal.invite_thru_email')}
             {t('admin:user_management.invite_modal.invite_thru_email')}
           </label>
           </label>
           {isMailerSetup ? (
           {isMailerSetup ? (
-            // eslint-disable-next-line react/no-danger
             <p
             <p
               className="form-text text-muted"
               className="form-text text-muted"
-              // eslint-disable-next-line react/no-danger
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{
                 __html: t(
                 __html: t(
@@ -138,7 +136,6 @@ class UserInviteModal extends React.Component {
               }}
               }}
             />
             />
           ) : (
           ) : (
-            // eslint-disable-next-line react/no-danger
             <p
             <p
               className="form-text text-muted"
               className="form-text text-muted"
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings
               // biome-ignore lint/security/noDangerouslySetInnerHtml: includes markup from i18n strings

+ 0 - 1
apps/app/src/client/components/Admin/Users/UserMenu.tsx

@@ -146,7 +146,6 @@ const UserMenu = (props: UserMenuProps) => {
 /**
 /**
  * Wrapper component for using unstated
  * Wrapper component for using unstated
  */
  */
-// eslint-disable-next-line max-len
 const UserMenuWrapper: React.ForwardRefExoticComponent<
 const UserMenuWrapper: React.ForwardRefExoticComponent<
   Pick<any, string | number | symbol> & React.RefAttributes<any>
   Pick<any, string | number | symbol> & React.RefAttributes<any>
 > = withUnstatedContainers(UserMenu, [AdminUsersContainer]);
 > = withUnstatedContainers(UserMenu, [AdminUsersContainer]);

+ 0 - 1
apps/app/src/client/components/AlertSiteUrlUndefined.tsx

@@ -5,7 +5,6 @@ import { useSiteUrl } from '~/states/global';
 
 
 const isValidUrl = (str: string): boolean => {
 const isValidUrl = (str: string): boolean => {
   try {
   try {
-    // eslint-disable-next-line no-new
     new URL(str);
     new URL(str);
     return true;
     return true;
   } catch {
   } catch {

+ 0 - 2
apps/app/src/client/components/Common/CopyDropdown/CopyDropdown.tsx

@@ -37,7 +37,6 @@ interface CopyDropdownProps {
   isShareLinkMode?: boolean;
   isShareLinkMode?: boolean;
 }
 }
 
 
-/* eslint-disable react/prop-types */
 const DropdownItemContents: React.FC<DropdownItemContentsProps> = ({
 const DropdownItemContents: React.FC<DropdownItemContentsProps> = ({
   title,
   title,
   contents,
   contents,
@@ -53,7 +52,6 @@ const DropdownItemContents: React.FC<DropdownItemContentsProps> = ({
     </div>
     </div>
   </>
   </>
 );
 );
-/* eslint-enable react/prop-types */
 
 
 export const CopyDropdown: React.FC<CopyDropdownProps> = (props) => {
 export const CopyDropdown: React.FC<CopyDropdownProps> = (props) => {
   const [dropdownOpen, setDropdownOpen] = useState(false);
   const [dropdownOpen, setDropdownOpen] = useState(false);

+ 0 - 5
apps/app/src/client/components/Common/Dropdown/PageItemControl.tsx

@@ -96,7 +96,6 @@ const PageItemControlDropdownMenu = React.memo(
       alignEnd,
       alignEnd,
     } = props;
     } = props;
 
 
-    // eslint-disable-next-line react-hooks/rules-of-hooks
     const bookmarkItemClickedHandler = useCallback(async () => {
     const bookmarkItemClickedHandler = useCallback(async () => {
       if (onClickBookmarkMenuItem == null) return;
       if (onClickBookmarkMenuItem == null) return;
 
 
@@ -110,7 +109,6 @@ const PageItemControlDropdownMenu = React.memo(
       await onClickBookmarkMenuItem(pageId, !pageInfo.isBookmarked);
       await onClickBookmarkMenuItem(pageId, !pageInfo.isBookmarked);
     }, [onClickBookmarkMenuItem, pageId, pageInfo]);
     }, [onClickBookmarkMenuItem, pageId, pageInfo]);
 
 
-    // eslint-disable-next-line react-hooks/rules-of-hooks
     const renameItemClickedHandler = useCallback(async () => {
     const renameItemClickedHandler = useCallback(async () => {
       if (onClickRenameMenuItem == null) return;
       if (onClickRenameMenuItem == null) return;
 
 
@@ -125,7 +123,6 @@ const PageItemControlDropdownMenu = React.memo(
       await onClickRenameMenuItem(pageId, pageInfo);
       await onClickRenameMenuItem(pageId, pageInfo);
     }, [onClickRenameMenuItem, pageId, pageInfo]);
     }, [onClickRenameMenuItem, pageId, pageInfo]);
 
 
-    // eslint-disable-next-line react-hooks/rules-of-hooks
     const duplicateItemClickedHandler = useCallback(async () => {
     const duplicateItemClickedHandler = useCallback(async () => {
       if (onClickDuplicateMenuItem == null) {
       if (onClickDuplicateMenuItem == null) {
         return;
         return;
@@ -140,7 +137,6 @@ const PageItemControlDropdownMenu = React.memo(
       await onClickRevertMenuItem(pageId);
       await onClickRevertMenuItem(pageId);
     }, [onClickRevertMenuItem, pageId]);
     }, [onClickRevertMenuItem, pageId]);
 
 
-    // eslint-disable-next-line react-hooks/rules-of-hooks
     const deleteItemClickedHandler = useCallback(async () => {
     const deleteItemClickedHandler = useCallback(async () => {
       if (onClickDeleteMenuItem == null) return;
       if (onClickDeleteMenuItem == null) return;
 
 
@@ -154,7 +150,6 @@ const PageItemControlDropdownMenu = React.memo(
       await onClickDeleteMenuItem(pageId, pageInfo);
       await onClickDeleteMenuItem(pageId, pageInfo);
     }, [onClickDeleteMenuItem, pageId, pageInfo]);
     }, [onClickDeleteMenuItem, pageId, pageInfo]);
 
 
-    // eslint-disable-next-line react-hooks/rules-of-hooks
     const pathRecoveryItemClickedHandler = useCallback(async () => {
     const pathRecoveryItemClickedHandler = useCallback(async () => {
       if (onClickPathRecoveryMenuItem == null) {
       if (onClickPathRecoveryMenuItem == null) {
         return;
         return;

+ 0 - 2
apps/app/src/client/components/Common/SubmittableInput/AutosizeSubmittableInput.tsx

@@ -10,9 +10,7 @@ export const getAdjustedMaxWidthForAutosizeInput = (
   size: 'sm' | 'md' | 'lg' = 'md',
   size: 'sm' | 'md' | 'lg' = 'md',
   isValid?: boolean,
   isValid?: boolean,
 ): number => {
 ): number => {
-  // eslint-disable-next-line no-nested-ternary
   const bsFormPaddingSize = size === 'sm' ? 8 : size === 'md' ? 12 : 16; // by bootstrap form
   const bsFormPaddingSize = size === 'sm' ? 8 : size === 'md' ? 12 : 16; // by bootstrap form
-  // eslint-disable-next-line no-nested-ternary
   const bsValidationIconSize = size === 'sm' ? 25 : size === 'md' ? 24 : 26; // by bootstrap form validation
   const bsValidationIconSize = size === 'sm' ? 25 : size === 'md' ? 24 : 26; // by bootstrap form validation
 
 
   return (
   return (

+ 0 - 1
apps/app/src/client/components/Common/SubmittableInput/use-submittable.ts

@@ -87,7 +87,6 @@ export const useSubmittable = (
   );
   );
 
 
   const {
   const {
-    // eslint-disable-next-line @typescript-eslint/no-unused-vars
     value: _value,
     value: _value,
     onSubmit: _onSubmit,
     onSubmit: _onSubmit,
     onCancel: _onCancel,
     onCancel: _onCancel,

+ 0 - 2
apps/app/src/client/components/LoginForm/LoginForm.tsx

@@ -148,7 +148,6 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
       return (
       return (
         <div className="alert alert-danger">
         <div className="alert alert-danger">
           {errors.map((err, index) => {
           {errors.map((err, index) => {
-            // eslint-disable-next-line react/no-danger
             return (
             return (
               <small
               <small
                 key={`${err.code}-${index}`}
                 key={`${err.code}-${index}`}
@@ -203,7 +202,6 @@ export const LoginForm = (props: LoginFormProps): JSX.Element => {
               {t('login.enabled_ldap_has_configuration_problem')}
               {t('login.enabled_ldap_has_configuration_problem')}
             </strong>
             </strong>
             <br />
             <br />
-            {/* eslint-disable-next-line react/no-danger */}
             <span
             <span
               // biome-ignore lint/security/noDangerouslySetInnerHtml: rendered HTML from translations
               // biome-ignore lint/security/noDangerouslySetInnerHtml: rendered HTML from translations
               dangerouslySetInnerHTML={{
               dangerouslySetInnerHTML={{

+ 0 - 1
apps/app/src/client/components/Me/ProfileImageSettings.tsx

@@ -66,7 +66,6 @@ const ProfileImageSettings = (): JSX.Element => {
           }),
           }),
         );
         );
 
 
-        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         setUploadedPictureSrc((response as any).attachment.filePathProxied);
         setUploadedPictureSrc((response as any).attachment.filePathProxied);
       } catch (err) {
       } catch (err) {
         toastError(err);
         toastError(err);

+ 2 - 2
apps/app/src/client/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -124,7 +124,7 @@ const PageOperationMenuItems = (
   const [isBulkExportTooltipOpen, setIsBulkExportTooltipOpen] = useState(false);
   const [isBulkExportTooltipOpen, setIsBulkExportTooltipOpen] = useState(false);
 
 
   const syncLatestRevisionBodyHandler = useCallback(async () => {
   const syncLatestRevisionBodyHandler = useCallback(async () => {
-    // eslint-disable-next-line no-alert
+    // biome-ignore lint/suspicious/noAlert: Allow to use confirm dialog here
     const answer = window.confirm(t('sync-latest-revision-body.confirm'));
     const answer = window.confirm(t('sync-latest-revision-body.confirm'));
     if (answer) {
     if (answer) {
       try {
       try {
@@ -137,7 +137,7 @@ const PageOperationMenuItems = (
         }
         }
 
 
         if (res?.isYjsDataBroken) {
         if (res?.isYjsDataBroken) {
-          // eslint-disable-next-line no-alert
+          // biome-ignore lint/suspicious/noAlert: Allow to use confirm dialog here
           window.alert(t('sync-latest-revision-body.alert'));
           window.alert(t('sync-latest-revision-body.alert'));
           return;
           return;
         }
         }

+ 0 - 2
apps/app/src/client/components/NotAvailableForReadOnlyUser.tsx

@@ -8,7 +8,6 @@ import { isRomUserAllowedToCommentAtom } from '~/states/server-configurations';
 
 
 import { NotAvailable } from './NotAvailable';
 import { NotAvailable } from './NotAvailable';
 
 
-// eslint-disable-next-line react/prop-types
 export const NotAvailableForReadOnlyUser: React.FC<{
 export const NotAvailableForReadOnlyUser: React.FC<{
   children: JSX.Element;
   children: JSX.Element;
 }> = ({ children }) => {
 }> = ({ children }) => {
@@ -28,7 +27,6 @@ export const NotAvailableForReadOnlyUser: React.FC<{
 };
 };
 NotAvailableForReadOnlyUser.displayName = 'NotAvailableForReadOnlyUser';
 NotAvailableForReadOnlyUser.displayName = 'NotAvailableForReadOnlyUser';
 
 
-// eslint-disable-next-line react/prop-types
 export const NotAvailableIfReadOnlyUserNotAllowedToComment: React.FC<{
 export const NotAvailableIfReadOnlyUserNotAllowedToComment: React.FC<{
   children: JSX.Element;
   children: JSX.Element;
 }> = ({ children }) => {
 }> = ({ children }) => {

+ 0 - 2
apps/app/src/client/components/PageAccessoriesModal/ShareLink/ShareLinkList.tsx

@@ -5,7 +5,6 @@ import { useTranslation } from 'next-i18next';
 import { CopyDropdown } from '../../Common/CopyDropdown';
 import { CopyDropdown } from '../../Common/CopyDropdown';
 
 
 type ShareLinkTrProps = {
 type ShareLinkTrProps = {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
   shareLink: any;
   shareLink: any;
   isAdmin?: boolean;
   isAdmin?: boolean;
   onDelete?: () => void;
   onDelete?: () => void;
@@ -68,7 +67,6 @@ const ShareLinkTr = (props: ShareLinkTrProps): JSX.Element => {
 };
 };
 
 
 type Props = {
 type Props = {
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
   shareLinks: any[];
   shareLinks: any[];
   onClickDeleteButton?: (shareLinkId: string) => void;
   onClickDeleteButton?: (shareLinkId: string) => void;
   isAdmin?: boolean;
   isAdmin?: boolean;

+ 0 - 1
apps/app/src/client/components/PageAttachment/DeleteAttachmentModal.tsx

@@ -73,7 +73,6 @@ const DeleteAttachmentModalSubstance = ({
     }
     }
 
 
     const content = attachment.fileFormat.match(/image\/.+/i) ? (
     const content = attachment.fileFormat.match(/image\/.+/i) ? (
-      // eslint-disable-next-line @next/next/no-img-element
       <img src={attachment.filePathProxied} alt="deleting attachment" />
       <img src={attachment.filePathProxied} alt="deleting attachment" />
     ) : (
     ) : (
       ''
       ''

+ 0 - 1
apps/app/src/client/components/PageComment/CommentEditor.tsx

@@ -187,7 +187,6 @@ export const CommentEditor = (props: CommentEditorProps): JSX.Element => {
         err.message || 'An unknown error occured when posting comment';
         err.message || 'An unknown error occured when posting comment';
       setError(errorMessage);
       setError(errorMessage);
     }
     }
-    // eslint-disable-next-line max-len
   }, [
   }, [
     currentCommentId,
     currentCommentId,
     initializeEditor,
     initializeEditor,

+ 1 - 8
apps/app/src/client/components/PageDeleteModal/PageDeleteModal.tsx

@@ -1,5 +1,5 @@
 import type { FC } from 'react';
 import type { FC } from 'react';
-import React, { useCallback, useEffect, useMemo, useState } from 'react';
+import { useCallback, useEffect, useMemo, useState } from 'react';
 import type { IPageInfoForEntity, IPageToDeleteWithMeta } from '@growi/core';
 import type { IPageInfoForEntity, IPageToDeleteWithMeta } from '@growi/core';
 import { isIPageInfoForEntity } from '@growi/core';
 import { isIPageInfoForEntity } from '@growi/core';
 import { pagePathUtils } from '@growi/core/dist/utils';
 import { pagePathUtils } from '@growi/core/dist/utils';
@@ -38,7 +38,6 @@ const deleteIconAndKey = {
   },
   },
 };
 };
 
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
 const isIPageInfoForEntityForDeleteModal = (
 const isIPageInfoForEntityForDeleteModal = (
   pageInfo: any | undefined,
   pageInfo: any | undefined,
 ): pageInfo is IPageInfoForEntity => {
 ): pageInfo is IPageInfoForEntity => {
@@ -63,7 +62,6 @@ export const PageDeleteModal: FC = () => {
     () =>
     () =>
       (pages ?? []).filter((p) => !isIPageInfoForEntityForDeleteModal(p.meta)),
       (pages ?? []).filter((p) => !isIPageInfoForEntityForDeleteModal(p.meta)),
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
-    // eslint-disable-next-line react-hooks/exhaustive-deps
     [pageIds, pagesLength],
     [pageIds, pagesLength],
   );
   );
 
 
@@ -84,7 +82,6 @@ export const PageDeleteModal: FC = () => {
       return null;
       return null;
     },
     },
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
-    // eslint-disable-next-line react-hooks/exhaustive-deps
     [pageIds, pagesLength, injectTo],
     [pageIds, pagesLength, injectTo],
   );
   );
 
 
@@ -107,7 +104,6 @@ export const PageDeleteModal: FC = () => {
   const pagePaths = useMemo(
   const pagePaths = useMemo(
     () => pages?.map((p) => p.data?.path ?? '') ?? [],
     () => pages?.map((p) => p.data?.path ?? '') ?? [],
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
-    // eslint-disable-next-line react-hooks/exhaustive-deps
     [pageIds, pagesLength],
     [pageIds, pagesLength],
   );
   );
 
 
@@ -128,7 +124,6 @@ export const PageDeleteModal: FC = () => {
       ? 'completely'
       ? 'completely'
       : 'temporary';
       : 'temporary';
 
 
-  // eslint-disable-next-line @typescript-eslint/no-unused-vars
   const [errs, setErrs] = useState<Error[] | null>(null);
   const [errs, setErrs] = useState<Error[] | null>(null);
 
 
   // initialize when opening modal
   // initialize when opening modal
@@ -229,7 +224,6 @@ export const PageDeleteModal: FC = () => {
       }
       }
     },
     },
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
     // Optimization: Use pageIds and pagesLength instead of pages array reference to avoid unnecessary re-computation
-    // eslint-disable-next-line react-hooks/exhaustive-deps
     [
     [
       pageIds,
       pageIds,
       pagesLength,
       pagesLength,
@@ -369,7 +363,6 @@ export const PageDeleteModal: FC = () => {
       </>
       </>
     );
     );
     // Optimization: Use direct dependencies instead of JSX.Element reference for better performance
     // Optimization: Use direct dependencies instead of JSX.Element reference for better performance
-    // eslint-disable-next-line react-hooks/exhaustive-deps
   }, [
   }, [
     isOpened,
     isOpened,
     t,
     t,

+ 1 - 3
apps/app/src/client/components/PageEditor/Cheatsheet.tsx

@@ -1,6 +1,4 @@
-/* eslint-disable max-len */
-
-import React, { type JSX } from 'react';
+import type { JSX } from 'react';
 import { useTranslation } from 'next-i18next';
 import { useTranslation } from 'next-i18next';
 import { PrismAsyncLight } from 'react-syntax-highlighter';
 import { PrismAsyncLight } from 'react-syntax-highlighter';
 import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
 import { oneDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';

Some files were not shown because too many files changed in this diff