Просмотр исходного кода

Merge remote-tracking branch 'origin/master' into feat/136128-144923-autofocus-on-PageTitleHeader-when-editing-Untitled-page

WNomunomu 1 год назад
Родитель
Сommit
26de2cfbbf
100 измененных файлов с 640 добавлено и 1208 удалено
  1. 11 0
      .changeset/config.json
  2. 5 5
      .github/workflows/release.yml
  3. 14 5
      .stylelintrc.json
  4. 72 1
      CHANGELOG.md
  5. 3 17
      apps/app/.stylelintrc.json
  6. 0 710
      apps/app/_obsolete/src/styles/theme/apply-colors.scss
  7. 1 1
      apps/app/docker/README.md
  8. 13 11
      apps/app/package.json
  9. 1 1
      apps/app/src/components/Admin/App/AppSetting.jsx
  10. 4 5
      apps/app/src/components/Admin/App/FileUploadSetting.tsx
  11. 1 1
      apps/app/src/components/Admin/App/MailSetting.tsx
  12. 8 11
      apps/app/src/components/Admin/App/MaintenanceMode.tsx
  13. 3 1
      apps/app/src/components/Admin/App/MaskedInput.module.scss
  14. 6 6
      apps/app/src/components/Admin/App/QuestionnaireSettings.tsx
  15. 46 50
      apps/app/src/components/Admin/App/SiteUrlSetting.tsx
  16. 1 1
      apps/app/src/components/Admin/Customize/CustomizeCssSetting.tsx
  17. 6 6
      apps/app/src/components/Admin/Customize/CustomizeFunctionSetting.tsx
  18. 2 2
      apps/app/src/components/Admin/Customize/CustomizeNoscriptSetting.tsx
  19. 2 2
      apps/app/src/components/Admin/Customize/CustomizeScriptSetting.tsx
  20. 2 2
      apps/app/src/components/Admin/Customize/CustomizeSidebarSetting.tsx
  21. 4 4
      apps/app/src/components/Admin/Customize/CustomizeThemeOptions.tsx
  22. 4 3
      apps/app/src/components/Admin/Customize/CustomizeTitle.tsx
  23. 1 1
      apps/app/src/components/Admin/Customize/PagingSizeUncontrolledDropdown.jsx
  24. 1 1
      apps/app/src/components/Admin/Customize/ThemeColorBox.module.scss
  25. 1 1
      apps/app/src/components/Admin/ElasticsearchManagement/ElasticsearchManagement.tsx
  26. 8 6
      apps/app/src/components/Admin/ElasticsearchManagement/RebuildIndexControls.jsx
  27. 10 9
      apps/app/src/components/Admin/ElasticsearchManagement/StatusTable.jsx
  28. 2 2
      apps/app/src/components/Admin/ExportArchiveData/SelectCollectionsModal.tsx
  29. 1 1
      apps/app/src/components/Admin/ExportArchiveDataPage.tsx
  30. 1 1
      apps/app/src/components/Admin/FullTextSearchManagement.tsx
  31. 1 1
      apps/app/src/components/Admin/ImportData/GrowiArchive/UploadForm.jsx
  32. 2 2
      apps/app/src/components/Admin/ImportData/GrowiArchiveSection.jsx
  33. 11 11
      apps/app/src/components/Admin/ImportData/ImportDataPageContents.jsx
  34. 6 6
      apps/app/src/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx
  35. 6 6
      apps/app/src/components/Admin/MarkdownSetting/MarkDownSettingContents.tsx
  36. 2 2
      apps/app/src/components/Admin/MarkdownSetting/WhitelistInput.jsx
  37. 4 4
      apps/app/src/components/Admin/MarkdownSetting/XssForm.jsx
  38. 10 9
      apps/app/src/components/Admin/Notification/GlobalNotification.jsx
  39. 4 4
      apps/app/src/components/Admin/Notification/NotificationSetting.jsx
  40. 16 14
      apps/app/src/components/Admin/Security/GitHubSecuritySettingContents.jsx
  41. 17 15
      apps/app/src/components/Admin/Security/GoogleSecuritySettingContents.jsx
  42. 30 30
      apps/app/src/components/Admin/Security/LdapSecuritySettingContents.jsx
  43. 11 11
      apps/app/src/components/Admin/Security/LocalSecuritySettingContents.jsx
  44. 30 28
      apps/app/src/components/Admin/Security/OidcSecuritySettingContents.jsx
  45. 41 45
      apps/app/src/components/Admin/Security/SamlSecuritySettingContents.jsx
  46. 3 3
      apps/app/src/components/Admin/Security/SecurityManagementContents.jsx
  47. 12 12
      apps/app/src/components/Admin/Security/SecuritySetting.jsx
  48. 11 12
      apps/app/src/components/Admin/Security/ShareLinkSetting.tsx
  49. 9 9
      apps/app/src/components/Admin/UserGroup/UserGroupForm.tsx
  50. 3 3
      apps/app/src/components/Admin/UserGroup/UserGroupTable.tsx
  51. 1 1
      apps/app/src/components/Admin/UserGroupDetail/UserGroupUserTable.tsx
  52. 2 1
      apps/app/src/components/Admin/UserManagement.module.scss
  53. 1 1
      apps/app/src/components/AuthorInfo/AuthorInfo.module.scss
  54. 1 1
      apps/app/src/components/Bookmarks/BookmarkFolderMenu.tsx
  55. 1 2
      apps/app/src/components/Bookmarks/BookmarkFolderTree.tsx
  56. 24 8
      apps/app/src/components/Bookmarks/BookmarkItem.tsx
  57. 1 2
      apps/app/src/components/Common/CopyDropdown/CopyDropdown.module.scss
  58. 1 3
      apps/app/src/components/Common/DrawerToggler/DrawerToggler.module.scss
  59. 1 1
      apps/app/src/components/Common/PagePathHierarchicalLink/CollapsedParentsDropdown.module.scss
  60. 1 2
      apps/app/src/components/Common/PagePathNav/PagePathNav.module.scss
  61. 1 1
      apps/app/src/components/Common/PagePathNav/PagePathNav.tsx
  62. 3 2
      apps/app/src/components/Common/PageViewLayout.module.scss
  63. 2 2
      apps/app/src/components/CustomNavigation/CustomNav.module.scss
  64. 2 2
      apps/app/src/components/DescendantsPageListModal.module.scss
  65. 1 1
      apps/app/src/components/Icons/GrowiLogo.module.scss
  66. 4 0
      apps/app/src/components/ItemsTree/ItemsTree.module.scss
  67. 2 0
      apps/app/src/components/ItemsTree/ItemsTreeContentSkeleton.module.scss
  68. 12 2
      apps/app/src/components/Layout/Admin.module.scss
  69. 3 3
      apps/app/src/components/Layout/AdminLayout.tsx
  70. 28 0
      apps/app/src/components/Layout/BasicLayout.module.scss
  71. 7 1
      apps/app/src/components/Layout/BasicLayout.tsx
  72. 17 13
      apps/app/src/components/Layout/NoLoginLayout.module.scss
  73. 1 1
      apps/app/src/components/Layout/SearchResultLayout.module.scss
  74. 3 4
      apps/app/src/components/LoginForm/LoginForm.module.scss
  75. 0 0
      apps/app/src/components/Me/ColorModeSettings.module.scss
  76. 0 2
      apps/app/src/components/Me/ColorModeSettings.tsx
  77. 1 1
      apps/app/src/components/Me/UISettings.module.scss
  78. 2 2
      apps/app/src/components/Navbar/GrowiContextualSubNavigation.module.scss
  79. 1 0
      apps/app/src/components/Navbar/GrowiNavbarBottom.module.scss
  80. 3 1
      apps/app/src/components/Navbar/PageEditorModeManager.module.scss
  81. 2 2
      apps/app/src/components/PageAccessoriesModal/PageAccessoriesModal.module.scss
  82. 2 2
      apps/app/src/components/PageAccessoriesModal/ShareLink/ShareLinkList.tsx
  83. 1 1
      apps/app/src/components/PageComment.module.scss
  84. 6 7
      apps/app/src/components/PageComment/Comment.module.scss
  85. 2 3
      apps/app/src/components/PageComment/CommentEditor.module.scss
  86. 1 0
      apps/app/src/components/PageComment/CommentPreview.module.scss
  87. 1 0
      apps/app/src/components/PageComment/DeleteCommentModal.module.scss
  88. 2 1
      apps/app/src/components/PageComment/SwitchingButtonGroup.module.scss
  89. 4 4
      apps/app/src/components/PageComment/_comment-inheritance.scss
  90. 2 1
      apps/app/src/components/PageContentFooter.module.scss
  91. 3 3
      apps/app/src/components/PageControls/BookmarkButtons.module.scss
  92. 2 3
      apps/app/src/components/PageControls/LikeButtons.module.scss
  93. 1 3
      apps/app/src/components/PageControls/PageControls.module.scss
  94. 15 10
      apps/app/src/components/PageControls/PageControls.tsx
  95. 1 3
      apps/app/src/components/PageControls/SearchButton.module.scss
  96. 1 3
      apps/app/src/components/PageControls/SeenUserInfo.module.scss
  97. 1 3
      apps/app/src/components/PageControls/SubscribeButton.module.scss
  98. 1 1
      apps/app/src/components/PageControls/_button-styles.scss
  99. 0 3
      apps/app/src/components/PageCreateModal.module.scss
  100. 2 1
      apps/app/src/components/PageEditor/EditorNavbar/EditorNavbar.module.scss

+ 11 - 0
.changeset/config.json

@@ -0,0 +1,11 @@
+{
+  "$schema": "https://unpkg.com/@changesets/config@3.0.0/schema.json",
+  "changelog": ["@changesets/changelog-github", { "repo": "weseek/growi" }],
+  "commit": false,
+  "fixed": [],
+  "linked": [],
+  "access": "restricted",
+  "baseBranch": "master",
+  "updateInternalDependencies": "patch",
+  "ignore": []
+}

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

@@ -103,7 +103,7 @@ jobs:
           type=semver,value=${{ needs.create-github-release.outputs.RELEASED_VERSION }},pattern={{major}}.{{minor}}.{{patch}}
 
 
-  build-image:
+  build-app-image:
     needs: create-github-release
 
     uses: weseek/growi/.github/workflows/reusable-app-build-image.yml@master
@@ -115,8 +115,8 @@ jobs:
       AWS_ROLE_TO_ASSUME_FOR_OIDC: ${{ secrets.AWS_ROLE_TO_ASSUME_FOR_OIDC }}
 
 
-  publish-image:
-    needs: [determine-tags, build-image]
+  publish-app-image:
+    needs: [determine-tags, build-app-image]
 
     uses: weseek/growi/.github/workflows/reusable-app-create-manifests.yml@master
     with:
@@ -129,7 +129,7 @@ jobs:
 
 
   post-publish:
-    needs: [create-github-release, publish-image]
+    needs: [create-github-release, publish-app-image]
     runs-on: ubuntu-latest
 
     steps:
@@ -154,7 +154,7 @@ jobs:
 
 
   create-pr-for-next-rc:
-    needs: [create-github-release, publish-image]
+    needs: [create-github-release, publish-app-image]
     runs-on: ubuntu-latest
 
     steps:

+ 14 - 5
.stylelintrc.json

@@ -1,16 +1,25 @@
 {
   "extends": [
+    "stylelint-config-recommended-scss",
     "stylelint-config-recess-order"
   ],
-  "customSyntax": "postcss-scss",
   "rules": {
-    "indentation": 2,
-    "string-quotes": "single",
+    "no-duplicate-selectors": null,
+    "scss/comment-no-empty": null,
+    "scss/at-extend-no-missing-placeholder": null,
     "rule-empty-line-before": [ "always-multi-line", {
       "except": ["after-single-line-comment", "first-nested"],
       "ignore": ["after-comment", "inside-block"]
     } ],
-    "selector-combinator-space-before": "always",
-    "selector-combinator-space-after": "always"
+    "color-function-notation": "legacy",
+    "selector-pseudo-class-no-unknown": [
+      true,
+      {
+        "ignorePseudoClasses": [
+          "global",
+          "local"
+        ]
+      }
+    ]
   }
 }

+ 72 - 1
CHANGELOG.md

@@ -1,9 +1,80 @@
 # Changelog
 
-## [Unreleased](https://github.com/weseek/growi/compare/v7.0.3...HEAD)
+## [Unreleased](https://github.com/weseek/growi/compare/v7.0.7...HEAD)
 
 *Please do not manually update this file. We've automated the process.*
 
+## [v7.0.7](https://github.com/weseek/growi/compare/v7.0.6...v7.0.7) - 2024-05-27
+
+### 🚀 Improvement
+
+* imprv: Behavior of dropdown toggle in groundglassbar (#8832) @maeshinshin
+* imprv: toastr location (#8831) @yuki-takei
+
+### 🐛 Bug Fixes
+
+* fix: Do not insert initial value when input is empty in editor (#8773) @miya
+
+### 🧰 Maintenance
+
+* support: Apply changesets (#8840) @yuki-takei
+* support: Upgrade yjs packages (#8839) @yuki-takei
+* support: Upgrade stylelint (#8835) @yuki-takei
+
+## [v7.0.6](https://github.com/weseek/growi/compare/v7.0.5...v7.0.6) - 2024-05-20
+
+### 🐛 Bug Fixes
+
+* fix: S3 configurations are considered invalid wrongly (#8823) @yuki-takei
+
+### 🧰 Maintenance
+
+* support: Publish @growi/core-styles package (#8819) @yuki-takei
+
+## [v7.0.5](https://github.com/weseek/growi/compare/v7.0.4...v7.0.5) - 2024-05-20
+
+### 🚀 Improvement
+
+* imprv: Behavior of dropdown toggle for WIP in 'Page Tree' sidebar (#8796) @maeshinshin
+* imprv: Hide the page creation button for users without editing permissions (#8808) @miya
+* imprv: Add config to toggle ACL between public_read and private on PutObject when using S3 with FileUploader (#8778) @ToshihitoKon
+
+### 🐛 Bug Fixes
+
+* fix: BookmarkItem occures an error when the related page has been deleted 2 (#8818) @yuki-takei
+* fix: BookmarkItem occures an error when the related page has been deleted (#8817) @yuki-takei
+* fix: Display share page date (#8809) @TatsuyaIse
+* fix: Admin layout (#8806) @satof3
+
+### 🧰 Maintenance
+
+* support: Modify env var for S3 Object-ACL (#8805) @yuki-takei
+
+## [v7.0.4](https://github.com/weseek/growi/compare/v7.0.3...v7.0.4) - 2024-05-13
+
+### 💎 Features
+
+* feat: Add a button to open PageCreateModal in the new page creation lead (#8774) @miya
+* feat: Show Yjs status indicator in SubNavigation (#8709) @miya
+* feat: Apply locale to defualt page title (#8600) @jam411
+
+### 🚀 Improvement
+
+* imprv: Behavior when creating first user fails (#8801) @miya
+* imprv: Add indexes for performance (#8800) @yuki-takei
+* imprv: Autosize Input for rename (#8795) @yuki-takei
+* imprv: behavior of dropdown toggle in 'Recent Changes' sidebar (#8782) @maeshinshin
+* imprv: Hide  personal drop down when guest user (#8786) @kazutoweseek
+
+### 🐛 Bug Fixes
+
+* fix: Drawio not available with GROWI slides (#8725) @reiji-h
+* fix: Auto-scroll to the active page in the page tree (#8772) @reiji-h
+
+### 🧰 Maintenance
+
+* ci(deps): bump ejs from 3.1.9 to 3.1.10 (#8784) @dependabot
+
 ## [v7.0.3](https://github.com/weseek/growi/compare/v7.0.2...v7.0.3) - 2024-05-01
 
 ### 🚀 Improvement

+ 3 - 17
apps/app/.stylelintrc.json

@@ -1,20 +1,6 @@
 {
-  "extends": [
-    "stylelint-config-recess-order"
-  ],
-  "customSyntax": "postcss-scss",
+  "extends": "../../.stylelintrc.json",
   "ignoreFiles": [
-    "src/styles/prebuilt/*.css",
-    "src/linter-checker/test.scss"
-  ],
-  "rules": {
-    "indentation": 2,
-    "string-quotes": "single",
-    "rule-empty-line-before": [ "always-multi-line", {
-      "except": ["after-single-line-comment", "first-nested"],
-      "ignore": ["after-comment", "inside-block"]
-    } ],
-    "selector-combinator-space-before": "always",
-    "selector-combinator-space-after": "always"
-  }
+    "src/styles/prebuilt/*.css"
+  ]
 }

+ 0 - 710
apps/app/_obsolete/src/styles/theme/apply-colors.scss

@@ -1,710 +0,0 @@
-@use '@growi/core/scss/bootstrap/init' as *;
-
-@use '../variables' as var;
-@use '../mixins';
-@use '../atoms/mixins/code';
-@use './mixins/hsl-button';
-@use './hsl-functions' as hsl;
-
-@import 'apply-colors-dark';
-@import 'apply-colors-light';
-
-//
-//== Apply to Bootstrap
-//
-
-// determine optional variables
-$bgcolor-search-top-dropdown: var(--bgcolor-search-top-dropdown,var(--secondary));
-$bgcolor-sidebar-nav-item-active: var(--bgcolor-sidebar-nav-item-active,#{hsl.darken(var(--primary),10%)});
-$text-shadow-sidebar-nav-item-active: var(--text-shadow-sidebar-nav-item-active,1px 1px 2px var(--primary));
-$bgcolor-inline-code: var(--bgcolor-inline-code, #{$gray-100});
-$color-inline-code: var(--color-inline-code, #{darken($red, 15%)});
-$bordercolor-inline-code: var(--bordercolor-inline-code, #{$gray-400});
-$bordercolor-nav-tabs: var(--bordercolor-nav-tabs, #{$gray-300});
-$bordercolor-nav-tabs-hover: var(--bordercolor-nav-tabs-hover,#{$gray-200} #{$gray-200} #{$bordercolor-nav-tabs});
-$border-nav-tabs-link-active: var(--border-nav-tabs-link-active, #{$gray-600});
-$bordercolor-nav-tabs-active: var(--bordercolor-nav-tabs-active,$bordercolor-nav-tabs $bordercolor-nav-tabs var(--bgcolor-global));
-$color-btn-reload-in-sidebar: var(--color-btn-reload-in-sidebar,#{$gray-500});
-$bgcolor-keyword-highlighted: var(--bgcolor-keyword-highlighted,#{var.$grw-marker-yellow});
-$color-page-list-group-item-meta: var(--color-page-list-group-item-meta,#{$gray-500});
-$color-search-page-list-title: var(--color-search-page-list-title,var(--color-global));
-
-// override bootstrap variables
-$body-bg: var(--bgcolor-global);
-$body-color: var(--color-global);
-$link-color: var(--color-link);
-$link-hover-color: var(--color-link-hover);
-$input-focus-color: var(--color-global);
-$nav-tabs-border-color: $bordercolor-nav-tabs;
-$nav-tabs-link-hover-border-color: $bordercolor-nav-tabs-hover;
-$nav-tabs-link-active-color: var(--color-nav-tabs-link-active);
-$nav-tabs-link-active-bg: var(--bgcolor-global);
-$nav-tabs-link-active-border-color: $bordercolor-nav-tabs-active;
-$theme-colors: map-merge($theme-colors, ( primary: $primary ));
-
-// TODO: activate (https://redmine.weseek.co.jp/issues/128307)
-// @import 'reboot-bootstrap-buttons';
-// @import 'reboot-bootstrap-colors';
-// @import 'reboot-bootstrap-theme-colors';
-// @import 'hsl-reboot-bootstrap-theme-colors';
-// @import 'reboot-bootstrap-nav';
-// @import 'reboot-toastr-colors';
-
-// determine variables with bootstrap function (These variables can be used after importing bootstrap above)
-$color-modal-header: var(--color-modal-header,#{hsl.contrast(var(--primary))});
-
-code:not([class^='language-']) {
-  @include code.code-inline-color($color-inline-code, $bgcolor-inline-code, $bordercolor-inline-code);
-}
-
-.code-highlighted {
-  border-color: $bordercolor-inline-code;
-}
-
-//
-//== Apply to Bootstrap Elements
-//
-
-// TODO: activate (https://redmine.weseek.co.jp/issues/128307)
-// theme-color-level() dropped in bootstrap v5
-// Alert link
-// @each $color, $value in $theme-colors {
-//   .alert.alert-#{$color} {
-//     a,
-//     a:hover {
-//       color: theme-color-level($color, $alert-color-level - 2);
-//     }
-//   }
-// }
-
-// Dropdown
-.grw-apperance-mode-dropdown {
-  .grw-sidebar-mode-icon svg {
-    fill: var(--secondary);
-  }
-  .grw-color-mode-icon svg {
-    fill: var(--color-global);
-  }
-  .grw-color-mode-icon-muted svg {
-    fill: var(--secondary);
-  }
-}
-
-// TODO: activate (https://redmine.weseek.co.jp/issues/128307)
-// form-control-focus() dropped in bootstrap v5
-// Form
-// .form-control {
-//   @include form-control-focus();
-// }
-
-// Tabs
-.nav.nav-tabs .nav-link.active {
-  color: var(--color-link);
-  background: transparent;
-
-  &:hover,
-  &:focus {
-    color: var(--color-link-hover);
-  }
-}
-
-// Pagination
-ul.pagination {
-  li.page-item.disabled {
-    button.page-link {
-      color: $gray-400;
-    }
-  }
-  li.page-item.active {
-    button.page-link {
-      color: hsl.contrast(var(--primary));
-      background-color: var(--primary);
-      &:hover,
-      &:focus {
-        color: hsl.contrast(var(--primary));
-        background-color: var(--primary);
-      }
-    }
-  }
-  li.page-item {
-    button.page-link {
-      color: var(--primary);
-      border-color: var(--secondary) !important;
-      &:hover,
-      &:active,
-      &:focus {
-        color: var(--primary);
-      }
-    }
-  }
-}
-
-//
-//== Apply to Handsontable
-//
-.handsontable {
-  color: initial;
-}
-
-//
-//== Apply to GROWI Elements
-//
-
-.grw-logo {
-  // set transition for fill
-  svg, svg * {
-    transition: fill 0.8s ease-out;
-  }
-
-  svg {
-    fill: var(--fillcolor-logo-mark);
-  }
-
-  &:hover {
-    svg {
-      .group1 {
-        fill: var.$growi-green;
-      }
-
-      .group2 {
-        fill: var.$growi-blue;
-      }
-    }
-  }
-}
-
-.grw-navbar {
-  background: var(--bgcolor-navbar);
-  .nav-item .nav-link {
-    color: var(--color-link-nabvar);
-  }
-
-  border-image: var(--border-image-navbar) !important;
-  border-image-slice: 1 !important;
-
-  .grw-app-title {
-    color: var(--fillcolor-logo-mark);
-  }
-}
-
-.grw-global-search {
-  .btn-secondary.dropdown-toggle {
-    @include hsl-button.button-variant(var(--bgcolor-search-top-dropdown), var(--bgcolor-search-top-dropdown));
-  }
-
-  // for https://youtrack.weseek.co.jp/issue/GW-2603
-  .search-typeahead {
-    background-color: hsl.alpha(var(--bgcolor-global),10%);
-  }
-  input.form-control {
-    border: none;
-  }
-}
-
-.grw-sidebar {
-  $color-resize-button: var(--color-resize-button,var(--color-global));
-  $bgcolor-resize-button: var(--bgcolor-resize-button,white);
-  $color-resize-button-hover: var(--color-resize-button-hover,var(--color-reversal));
-  $bgcolor-resize-button-hover: var(--bgcolor-resize-button-hover,#{hsl.lighten(var(--bgcolor-resize-button), 5%)});
-  // .grw-navigation-resize-button {
-  //   .hexagon-container svg {
-  //     .background {
-  //       fill: var(--bgcolor-resize-button);
-  //     }
-  //     .icon {
-  //       fill: var(--color-resize-button);
-  //     }
-  //   }
-  //   &:hover .hexagon-container svg {
-  //     .background {
-  //       fill: var(--bgcolor-resize-button-hover);
-  //     }
-  //     .icon {
-  //       fill: var(--color-resize-button-hover);
-  //     }
-  //   }
-  // }
-  div.grw-contextual-navigation {
-    > div {
-      color: var(--color-sidebar-context);
-      background-color: var(--bgcolor-sidebar-context);
-    }
-  }
-
-  .grw-sidebar-nav {
-    .btn {
-      @include hsl-button.button-variant(
-        var(--bgcolor-sidebar),
-        var(--bgcolor-sidebar),
-      );
-    }
-  }
-  .grw-sidebar-nav-primary-container {
-    .btn.active {
-      i {
-        text-shadow: $text-shadow-sidebar-nav-item-active;
-      }
-      // fukidashi
-      &:after {
-        border-right-color: var(--bgcolor-sidebar-context) !important;
-      }
-    }
-  }
-
-  .grw-sidebar-content-header {
-    .grw-btn-reload {
-      color: $color-btn-reload-in-sidebar;
-    }
-
-    .grw-recent-changes-resize-button {
-      .form-check-label::before {
-        background-color: var(--primary);
-      }
-
-      .form-check-label::after {
-        background-color: var(--bgcolor-global);
-      }
-
-      .form-check-input:not(:checked) + .form-check-label::before {
-        color: var(--bgcolor-global);
-      }
-
-      .form-check-input:checked + .form-check-label::before {
-        color: var(--bgcolor-global);
-        background-color: var(--primary);
-        border-color: var(--primary);
-      }
-      .form-check-input:checked + .form-check-label::after {
-        color: var(--bgcolor-global);
-      }
-    }
-  }
-
-  .grw-pagetree, .grw-foldertree {
-    .list-group-item {
-      .grw-pagetree-title-anchor, .grw-foldertree-title-anchor {
-        color: inherit;
-      }
-    }
-  }
-
-  .grw-pagetree-footer {
-    .h5.grw-private-legacy-pages-anchor {
-      color: inherit;
-    }
-  }
-
-  .grw-recent-changes {
-    .list-group {
-      .list-group-item {
-        background-color: transparent !important;
-
-        .icon-lock {
-          color: var(--color-link);
-        }
-
-        .grw-recent-changes-item-lower {
-          color: $gray-500;
-
-          svg {
-            fill: $gray-500;
-          }
-        }
-      }
-    }
-  }
-
-}
-
-/*
- * Icon
- */
-.editor-container .navbar-editor svg {
-  fill: var(--color-editor-icons);
-}
-
-// page preview button in link form
-.btn-page-preview svg {
-  fill: white;
-}
-
-/*
- * Modal
- */
-.modal {
-  .modal-header {
-    border-bottom-color: var(--border-color-theme);
-    .modal-title {
-      color: $color-modal-header;
-    }
-    .btn-close {
-      color: $color-modal-header;
-      opacity: 0.5;
-
-      &:hover {
-        opacity: 0.9;
-      }
-    }
-  }
-
-  .modal-content {
-    background-color: var(--bgcolor-global);
-  }
-
-  .modal-footer {
-    border-top-color: var(--border-color-theme);
-  }
-}
-
-.grw-page-accessories-modal,.grw-descendants-page-list-modal {
-  .modal-header {
-    .btn-close {
-      color: #{hsl.contrast(var(--bgcolor-global))};
-    }
-  }
-}
-
-.grw-custom-nav-tab {
-  .nav-item {
-    &:hover,
-    &:focus {
-      background-color: hsl.alpha(var(--color-link),10%);
-    }
-    .nav-link {
-      -webkit-appearance: none;
-      color: var(--color-link);
-      svg {
-        fill: var(--color-link);
-      }
-
-      // Disabled state lightens text
-      &.disabled {
-        color: $nav-link-disabled-color;
-        svg {
-          fill: $nav-link-disabled-color;
-        }
-      }
-    }
-  }
-
-  .grw-nav-slide-hr {
-    border-color: var(--color-link) !important;
-  }
-}
-
-/*
- * cards
- */
-.card.custom-card {
-  color: var(--color-global);
-  background-color: var(--bgcolor-card);
-  border-color: var(--light);
-  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
-}
-
-/*
- * Form Slider
- */
-.admin-page {
-  span.slider {
-    background-color: $gray-300;
-
-    &:before {
-      background-color: white;
-    }
-  }
-
-  input:checked + .slider {
-    background-color: #007bff;
-  }
-
-  input:focus + .slider {
-    box-shadow: 0 0 1px #007bff;
-  }
-}
-
-/*
- * GROWI wiki
- */
-.wiki {
-  h1,
-  h2,
-  h3,
-  h4,
-  h5,
-  h6,
-  h7 {
-    &.blink {
-      @include mixins.blink-bgcolor(var(--bgcolor-blinked-section));
-    }
-  }
-
-  .highlighted-keyword {
-    background: linear-gradient(transparent 60%, $bgcolor-keyword-highlighted 60%);
-  }
-
-  a {
-    color: var(--color-link-wiki);
-
-    &:hover {
-      color: var(--color-link-wiki-hover);
-    }
-  }
-
-  // table with handsontable modal button
-  .editable-with-handsontable {
-    button {
-      color: var(--color-link-wiki);
-    }
-
-    button:hover {
-      color: var(--color-link-wiki-hover);
-    }
-  }
-}
-
-/*
- * GROWI page-list
- */
-.page-list {
-  // List group
-  .list-group {
-    .list-group-item {
-      background-color: var(--bgcolor-global) !important;
-      a {
-        svg {
-          fill: var(--color-global);
-        }
-
-        &:hover {
-          svg {
-            fill: var(--color-global);
-          }
-        }
-      }
-
-      .page-list-meta {
-        color: $color-page-list-group-item-meta;
-        svg {
-          fill: $color-page-list-group-item-meta;
-        }
-      }
-
-      &.list-group-item-action {
-        background-color: var(--bgcolor-list);
-        &.active {
-          border-left-color: var(--primary);
-        }
-      }
-    }
-  }
-}
-
-/*
- * GROWI Editor
- */
-.layout-root.editing {
-  background-color: hsl.darken(var(--bgcolor-global),2%);
-
-  &.builtin-editor {
-    .page-editor-editor-container {
-      border-right-color: var(--border-color-theme);
-    }
-  }
-
-  .navbar-editor {
-    background-color: var(--bgcolor-global); // same color with active tab
-    border-bottom-color: var(--border-color-theme);
-  }
-
-  .page-editor-preview-container {
-    background-color: var(--bgcolor-global);
-  }
-}
-
-
-/*
- * Preview for editing /Sidebar
- */
-.page-editor-preview-body.preview-sidebar {
-  color: var(--color-sidebar-context);
-  background-color: var(--bgcolor-sidebar-context);
-}
-
-/*
- * GROWI Grid Edit Modal
- */
-.grw-grid-edit-preview {
-  .desktop-preview,
-  .tablet-preview,
-  .mobile-preview {
-    background: var(--bgcolor-global);
-  }
-  .grid-edit-border-for-each-cols {
-    border: 2px solid var(--bgcolor-global);
-  }
-}
-
-.grid-preview-col-0 {
-  background: var.$growi-blue;
-}
-
-.grid-preview-col-1 {
-  background: var(--info);
-}
-
-.grid-preview-col-2 {
-  background: var(--success);
-}
-
-.grid-preview-col-3 {
-  background: var.$growi-green;
-}
-
-/*
- * GROWI comment form
- */
-.page-comments-row {
-  background: var(--bgcolor-subnav);
-  .page-comment .page-comment-main,
-  .page-comment-form .comment-form-main {
-    background-color: var(--bgcolor-global);
-
-    .nav.nav-tabs {
-      > li > a.active {
-        background: transparent;
-        border-bottom: solid 1px hsl.darken(var(--bgcolor-global),4%);
-        border-bottom-color: hsl.darken(var(--bgcolor-global),4%);
-      }
-    }
-  }
-}
-
-/*
- * GROWI search result
- */
-.search-result-base {
-  .grw-search-page-nav {
-    background-color: var(--bgcolor-subnav);
-  }
-  .search-control {
-    background-color: var(--bgcolor-global);
-  }
-  .page-list {
-    .highlighted-keyword {
-      background: linear-gradient(transparent 60%, $bgcolor-keyword-highlighted 60%);
-    }
-  }
-}
-
-/*
- * react bootstrap typeahead
- */
-mark.rbt-highlight-text {
-  // Temporarily the highlight color is black
-  color: black;
-}
-
-/*
- * GROWI page content footer
- */
-.page-content-footer {
-  background-color: hsl.darken(var(--bgcolor-global),2%);
-  border-top-color: var(--border-color-theme);
-}
-
-/*
- * GROWI admin page #layoutOptions #themeOptions
- */
-.admin-page {
-  #layoutOptions {
-    .customize-layout-card {
-      &.border-active {
-        border-color: var(--color-theme-color-box);
-      }
-    }
-  }
-
-  #themeOptions {
-    .theme-option-container.active {
-      .theme-option-name {
-        color: var(--color-global);
-      }
-      a {
-        background-color: var(--color-theme-color-box);
-        border-color: var(--color-theme-color-box);
-      }
-    }
-  }
-}
-
-/*
- * HackMd
- */
-.bg-box {
-  background-color: var(--bgcolor-global);
-}
-
-/*
-  Slack Integration
-*/
-.selecting-bot-type {
-  .bot-type-disc {
-    width: 20px;
-  }
-}
-
-/*
-  In App Notification
-*/
-.grw-unopend-notification {
-  width: 7px;
-  height: 7px;
-  background-color: var(--primary);
-}
-
-/*
-Emoji picker modal
-*/
-.emoji-picker-modal {
-  background-color: transparent !important;
-}
-
-/*
-Expand / compress button bookmark list on users page
-*/
-.grw-user-page-list-m {
-  .grw-expand-compress-btn {
-    color: $body-color;
-    background-color: $body-bg;
-    &.active {
-      background-color: hsl.darken($body-bg, 12%),
-    }
-  }
-}
-
-/*
- * Questionnaire modal
- */
-.grw-questionnaire-btn-group {
-  .btn-outline-primary {
-    @include hsl-button.button-outline-variant(
-      #{hsl.lighten(var(--primary), 30%)} !important,
-      #{hsl.contrast(var(--primary))} !important,
-      var(--primary) !important,
-      #{hsl.lighten(var(--primary), 30%)} !important,
-    );
-    &:not(:disabled):not(.disabled):active,
-    &:not(:disabled):not(.disabled).active {
-      color: #{hsl.contrast(var(--primary))} !important;
-      background-color: var(--primary) !important;
-    }
-  }
-}
-
-/*
- * revision-history-diff
- */
-.revision-history-diff {
-  background-color: white;
-}

+ 1 - 1
apps/app/docker/README.md

@@ -10,7 +10,7 @@ GROWI Official docker image
 Supported tags and respective Dockerfile links
 ------------------------------------------------
 
-* [`7.0.3`, `7.0`, `7`, `latest` (Dockerfile)](https://github.com/weseek/growi/blob/v7.0.3/apps/app/docker/Dockerfile)
+* [`7.0.7`, `7.0`, `7`, `latest` (Dockerfile)](https://github.com/weseek/growi/blob/v7.0.7/apps/app/docker/Dockerfile)
 * [`6.3.2`, `6.3`, `6` (Dockerfile)](https://github.com/weseek/growi/blob/v6.3.2/apps/app/docker/Dockerfile)
 * [`6.2.4`, `6.2` (Dockerfile)](https://github.com/weseek/growi/blob/v6.2.4/apps/app/docker/Dockerfile)
 * [`6.1.15`, `6.1` (Dockerfile)](https://github.com/weseek/growi/blob/v6.1.15/apps/app/docker/Dockerfile)

+ 13 - 11
apps/app/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@growi/app",
-  "version": "7.0.4-RC.0",
+  "version": "7.0.8-RC.0",
   "license": "MIT",
   "scripts": {
     "//// for production": "",
@@ -29,7 +29,7 @@
     "dev:ci": "yarn cross-env NODE_ENV=development yarn ts-node src/server/app.ts --ci",
     "lint:typecheck": "npx -y tsc",
     "lint:eslint": "yarn eslint --quiet \"**/*.{js,jsx,ts,tsx}\"",
-    "lint:styles": "stylelint src/**/*.scss",
+    "lint:styles": "stylelint \"src/**/*.scss\"",
     "lint:swagger2openapi": "node node_modules/.bin/oas-validate tmp/swagger.json",
     "lint": "run-p lint:*",
     "prelint:swagger2openapi": "yarn openapi:v3",
@@ -71,7 +71,6 @@
     "@godaddy/terminus": "^4.9.0",
     "@google-cloud/storage": "^5.8.5",
     "@growi/core": "link:../../packages/core",
-    "@growi/custom-icons": "link:../../packages/custom-icons",
     "@growi/pluginkit": "link:../../packages/pluginkit",
     "@growi/preset-templates": "link:../../packages/preset-templates",
     "@growi/preset-themes": "link:../../packages/preset-themes",
@@ -179,7 +178,7 @@
     "react-syntax-highlighter": "^15.5.0",
     "react-toastify": "^9.1.3",
     "react-use-ripple": "^1.5.2",
-    "reactstrap": "^9.2.0",
+    "reactstrap": "^9.2.2",
     "reconnecting-websocket": "^4.4.0",
     "redis": "^3.0.2",
     "rehype-katex": "^6.0.2",
@@ -195,7 +194,7 @@
     "remark-toc": "^8.0.1",
     "remark-wiki-link": "^1.0.4",
     "sanitize-filename": "^1.6.3",
-    "socket.io": "^4.7.2",
+    "socket.io": "^4.7.5",
     "stream-to-promise": "^3.0.0",
     "string-width": "=4.2.2",
     "superjson": "^1.9.1",
@@ -211,20 +210,24 @@
     "validator": "^13.7.0",
     "ws": "^8.3.0",
     "xss": "^1.0.14",
-    "y-mongodb-provider": "^0.1.7",
-    "y-socket.io": "^1.1.0",
-    "yjs": "^13.6.12"
+    "y-mongodb-provider": "^0.1.10",
+    "y-socket.io": "^1.1.3",
+    "yjs": "^13.6.15"
   },
   "// comments for defDependencies": {
+    "bootstrap": "v5.3.3 has a bug. refs: https://github.com/twbs/bootstrap/issues/39798",
     "@handsontable/react": "v3 requires handsontable >= 7.0.0.",
     "handsontable": "v7.0.0 or above is no loger MIT lisence."
   },
   "devDependencies": {
+    "@growi/core-styles": "link:../../packages/core-styles",
+    "@growi/custom-icons": "link:../../packages/custom-icons",
     "@growi/editor": "link:../../packages/editor",
     "@growi/presentation": "link:../../packages/presentation",
     "@growi/ui": "link:../../packages/ui",
     "@handsontable/react": "=2.1.0",
     "@next/bundle-analyzer": "^14.1.3",
+    "@popperjs/core": "^2.11.8",
     "@swc-node/jest": "^1.6.2",
     "@swc/jest": "^0.2.24",
     "@testing-library/react": "^14.1.2",
@@ -239,9 +242,8 @@
     "@types/url-join": "^4.0.2",
     "@vitejs/plugin-react": "^4.2.1",
     "@vitest/coverage-v8": "^0.34.6",
-    "autoprefixer": "^9.0.0",
     "babel-loader": "^8.2.5",
-    "bootstrap": "^5.3.1",
+    "bootstrap": "=5.3.2",
     "connect-browser-sync": "^2.1.0",
     "cypress-real-events": "^1.12.0",
     "diff2html": "^3.4.47",
@@ -278,7 +280,7 @@
     "sass": "^1.53.0",
     "simple-load-script": "^1.0.2",
     "simplebar-react": "^2.3.6",
-    "socket.io-client": "^4.2.0",
+    "socket.io-client": "^4.7.5",
     "source-map-loader": "^4.0.1",
     "swagger2openapi": "^7.0.8",
     "tsc-alias": "^1.2.9"

+ 1 - 1
apps/app/src/components/Admin/App/AppSetting.jsx

@@ -138,7 +138,7 @@ const AppSetting = (props) => {
         </div>
       </div>
 
-      <div className="row mb-5">
+      <div className="row mb-2">
         <label
           className="text-start text-md-end col-md-3 col-form-label"
         >

+ 4 - 5
apps/app/src/components/Admin/App/FileUploadSetting.tsx

@@ -1,4 +1,5 @@
-import React, { ChangeEvent, useCallback } from 'react';
+import type { ChangeEvent } from 'react';
+import React, { useCallback } from 'react';
 
 import { useTranslation } from 'next-i18next';
 
@@ -30,11 +31,9 @@ export const FileUploadSettingMolecule = React.memo((props: FileUploadSettingMol
 
   return (
     <>
-      <p className="card custom-card my-3">
+      <p className="card custom-card bg-warning-subtle my-3">
         {t('admin:app_setting.file_upload')}
-        <br />
-        <br />
-        <span className="text-danger">
+        <span className="text-danger mt-1">
           <span className="material-symbols-outlined">link_off</span>
           {t('admin:app_setting.change_setting')}
         </span>

+ 1 - 1
apps/app/src/components/Admin/App/MailSetting.tsx

@@ -62,7 +62,7 @@ const MailSetting = (props: Props) => {
         </div>
       </div>
 
-      <div className="row mb-5">
+      <div className="row mb-2">
         <label className="form-label text-start text-md-end col-md-3 col-form-label">
           {t('admin:app_setting.transmission_method')}
         </label>

+ 8 - 11
apps/app/src/components/Admin/App/MaintenanceMode.tsx

@@ -1,4 +1,5 @@
-import React, { FC, useState, useCallback } from 'react';
+import type { FC } from 'react';
+import React, { useState, useCallback } from 'react';
 
 import { useTranslation } from 'next-i18next';
 
@@ -54,21 +55,17 @@ export const MaintenanceMode: FC = () => {
         onConfirm={onConfirmHandler}
         onCancel={() => closeModal()}
       />
-      <p className="card custom-card">
+      <p className="card custom-card bg-warning-subtle">
         {t('admin:maintenance_mode.description')}
-        <br />
-        <br />
-        <span className="text-warning">
+        <span className="text-warning mt-1">
           <span className="material-symbols-outlined">error</span>
           {t('admin:maintenance_mode.supplymentary_message_to_start')}
         </span>
       </p>
-      <div className="row my-3">
-        <div className="mx-auto">
-          <button type="button" className="btn btn-success" onClick={() => openModal()}>
-            {isMaintenanceMode ? t('admin:maintenance_mode.end_maintenance_mode') : t('admin:maintenance_mode.start_maintenance_mode')}
-          </button>
-        </div>
+      <div className="mx-auto my-3">
+        <button type="button" className="btn btn-success" onClick={() => openModal()}>
+          {isMaintenanceMode ? t('admin:maintenance_mode.end_maintenance_mode') : t('admin:maintenance_mode.start_maintenance_mode')}
+        </button>
       </div>
     </div>
   );

+ 3 - 1
apps/app/src/components/Admin/App/MaskedInput.module.scss

@@ -1,3 +1,5 @@
+/* stylelint-disable selector-class-pattern */
+
 .MaskedInput {
   position: relative;
   display: flex;
@@ -5,7 +7,7 @@
 
 .PasswordReveal {
   position: absolute;
-  top: 0rem;
+  top: 0;
   right: 0.5rem;
   left: auto;
   font-size: 1.4rem;

+ 6 - 6
apps/app/src/components/Admin/App/QuestionnaireSettings.tsx

@@ -50,8 +50,8 @@ const QuestionnaireSettings = (): JSX.Element => {
 
   return (
     <div id="questionnaire-settings" className="mb-5">
-      <p className="card custom-card">
-        <div className="mb-4">{t('app_setting.questionnaire_settings_explanation')}</div>
+      <p className="card custom-card bg-info-subtle">
+        <div className="mb-3">{t('app_setting.questionnaire_settings_explanation')}</div>
         <span>
           <div className="mb-2">
             <span className="text-info me-2"><span className="material-symbols-outlined">info</span>{t('app_setting.about_data_sent')}</span>
@@ -72,8 +72,8 @@ const QuestionnaireSettings = (): JSX.Element => {
 
       {!isLoading && (
         <>
-          <div className="row my-3">
-            <div className="form-check form-switch form-check-info col-md-5 offset-md-5">
+          <div className="my-4">
+            <div className="form-check form-switch form-check-info">
               <input
                 type="checkbox"
                 className="form-check-input"
@@ -87,8 +87,8 @@ const QuestionnaireSettings = (): JSX.Element => {
             </div>
           </div>
 
-          <div className="row my-4">
-            <div className="form-check form-check-info col-md-5 offset-md-5">
+          <div className="my-4">
+            <div className="form-check form-check-info">
               <input
                 type="checkbox"
                 className="form-check-input"

+ 46 - 50
apps/app/src/components/Admin/App/SiteUrlSetting.tsx

@@ -35,65 +35,61 @@ const SiteUrlSetting = (props: Props) => {
 
   return (
     <React.Fragment>
-      <p className="card custom-card">{t('site_url.desc')}</p>
+      <p className="card custom-card bg-body-tertiary">{t('site_url.desc')}</p>
       {!adminAppContainer.state.isSetSiteUrl
           && (<p className="alert alert-danger"><span className="material-symbols-outlined">error</span> {t('site_url.warn')}</p>)}
 
       { adminAppContainer.state.siteUrlUseOnlyEnvVars && (
         <div className="row">
-          <div className="col-md-9 offset-md-3">
-            <p
-              className="alert alert-info"
-              // eslint-disable-next-line react/no-danger
-              dangerouslySetInnerHTML={{
-                __html: t('site_url.note_for_the_only_env_option', { env: 'APP_SITE_URL_USES_ONLY_ENV_VARS' }),
-              }}
-            />
-          </div>
+          <p
+            className="alert alert-info"
+            // eslint-disable-next-line react/no-danger
+            dangerouslySetInnerHTML={{
+              __html: t('site_url.note_for_the_only_env_option', { env: 'APP_SITE_URL_USES_ONLY_ENV_VARS' }),
+            }}
+          />
         </div>
       ) }
 
       <div className="row">
-        <div className="col-md-9 offset-md-3">
-          <table className="table settings-table">
-            <colgroup>
-              <col className="from-db" />
-              <col className="from-env-vars" />
-            </colgroup>
-            <thead>
-              <tr>
-                <th>Database</th>
-                <th>Environment variables</th>
-              </tr>
-            </thead>
-            <tbody>
-              <tr>
-                <td>
-                  <input
-                    className="form-control"
-                    type="text"
-                    name="settingForm[app:siteUrl]"
-                    defaultValue={adminAppContainer.state.siteUrl || ''}
-                    disabled={adminAppContainer.state.siteUrlUseOnlyEnvVars ?? true}
-                    onChange={(e) => { adminAppContainer.changeSiteUrl(e.target.value) }}
-                    placeholder="e.g. https://my.growi.org"
-                  />
-                  <p className="form-text text-muted">
-                    {/* eslint-disable-next-line react/no-danger */}
-                    <span dangerouslySetInnerHTML={{ __html: t('site_url.help') }} />
-                  </p>
-                </td>
-                <td>
-                  <input className="form-control" type="text" value={adminAppContainer.state.envSiteUrl || ''} readOnly />
-                  <p className="form-text text-muted">
-                    {/* eslint-disable-next-line react/no-danger */}
-                    <span dangerouslySetInnerHTML={{ __html: t('use_env_var_if_empty', { variable: 'APP_SITE_URL' }) }} />
-                  </p>
-                </td>
-              </tr>
-            </tbody>
-          </table>
-        </div>
+        <table className="table settings-table">
+          <colgroup>
+            <col className="from-db" />
+            <col className="from-env-vars" />
+          </colgroup>
+          <thead>
+            <tr>
+              <th>Database</th>
+              <th>Environment variables</th>
+            </tr>
+          </thead>
+          <tbody>
+            <tr>
+              <td>
+                <input
+                  className="form-control"
+                  type="text"
+                  name="settingForm[app:siteUrl]"
+                  defaultValue={adminAppContainer.state.siteUrl || ''}
+                  disabled={adminAppContainer.state.siteUrlUseOnlyEnvVars ?? true}
+                  onChange={(e) => { adminAppContainer.changeSiteUrl(e.target.value) }}
+                  placeholder="e.g. https://my.growi.org"
+                />
+                <p className="form-text text-muted">
+                  {/* eslint-disable-next-line react/no-danger */}
+                  <span dangerouslySetInnerHTML={{ __html: t('site_url.help') }} />
+                </p>
+              </td>
+              <td>
+                <input className="form-control" type="text" value={adminAppContainer.state.envSiteUrl || ''} readOnly />
+                <p className="form-text text-muted">
+                  {/* eslint-disable-next-line react/no-danger */}
+                  <span dangerouslySetInnerHTML={{ __html: t('use_env_var_if_empty', { variable: 'APP_SITE_URL' }) }} />
+                </p>
+              </td>
+            </tr>
+          </tbody>
+        </table>
       </div>
 
       <AdminUpdateButtonRow onClick={submitHandler} disabled={adminAppContainer.state.retrieveError != null} />

+ 1 - 1
apps/app/src/components/Admin/Customize/CustomizeCssSetting.tsx

@@ -34,7 +34,7 @@ const CustomizeCssSetting = (props: Props): JSX.Element => {
         <div className="col-12">
           <h2 className="admin-setting-header">{t('admin:customize_settings.custom_css')}</h2>
 
-          <Card className="card custom-card my-3">
+          <Card className="card custom-card bg-body-tertiary my-3">
             <CardBody className="px-0 py-2">
               { t('admin:customize_settings.write_css') }<br />
               { t('admin:customize_settings.reflect_change') }

+ 6 - 6
apps/app/src/components/Admin/Customize/CustomizeFunctionSetting.tsx

@@ -37,15 +37,15 @@ const CustomizeFunctionSetting = (props: Props): JSX.Element => {
       <div className="row">
         <div className="col-12">
           <h2 className="admin-setting-header">{t('admin:customize_settings.function')}</h2>
-          <Card className="card custom-card my-3">
+          <Card className="card custom-card bg-body-tertiary my-3">
             <CardBody className="px-0 py-2">
               {t('admin:customize_settings.function_desc')}
             </CardBody>
           </Card>
 
 
-          <div className="row">
-            <div className="offset-md-3 col-md-6 text-start">
+          <div className="row mt-4">
+            <div className="offset-md-2 col-md-7 text-start">
               <CustomizeFunctionOption
                 optionId="isEnabledAttachTitleHeader"
                 label={t('admin:customize_settings.function_options.attach_title_header')}
@@ -89,7 +89,7 @@ const CustomizeFunctionSetting = (props: Props): JSX.Element => {
           />
 
           <div className="row">
-            <div className="offset-md-3 col-md-6 text-start">
+            <div className="offset-md-2 col-md-7 text-start">
               <CustomizeFunctionOption
                 optionId="isEnabledStaleNotification"
                 label={t('admin:customize_settings.function_options.stale_notification')}
@@ -104,7 +104,7 @@ const CustomizeFunctionSetting = (props: Props): JSX.Element => {
           </div>
 
           <div className="row">
-            <div className="offset-md-3 col-md-6 text-start">
+            <div className="offset-md-2 col-md-7 text-start">
               <CustomizeFunctionOption
                 optionId="isAllReplyShown"
                 label={t('admin:customize_settings.function_options.show_all_reply_comments')}
@@ -119,7 +119,7 @@ const CustomizeFunctionSetting = (props: Props): JSX.Element => {
           </div>
 
           <div className="row">
-            <div className="offset-md-3 col-md-6 text-start">
+            <div className="offset-md-2 col-md-7 text-start">
               <CustomizeFunctionOption
                 optionId="isSearchScopeChildrenAsDefault"
                 label={t('admin:customize_settings.function_options.select_search_scope_children_as_default')}

+ 2 - 2
apps/app/src/components/Admin/Customize/CustomizeNoscriptSetting.tsx

@@ -36,7 +36,7 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
         <div className="col-12">
           <h2 className="admin-setting-header">{t('admin:customize_settings.custom_noscript')}</h2>
 
-          <Card className="card custom-card my-3">
+          <Card className="card custom-card bg-body-tertiary my-3">
             <CardBody className="px-0 py-2">
               <span
                 // eslint-disable-next-line react/no-danger
@@ -47,7 +47,7 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
 
           <div>
             <textarea
-              className="form-control"
+              className="form-control mb-2"
               name="customizeNoscript"
               rows={8}
               defaultValue={adminCustomizeContainer.state.currentCustomizeNoscript || ''}

+ 2 - 2
apps/app/src/components/Admin/Customize/CustomizeScriptSetting.tsx

@@ -35,7 +35,7 @@ const CustomizeScriptSetting = (props: Props): JSX.Element => {
       <div className="row">
         <div className="col-12">
           <h2 className="admin-setting-header">{t('admin:customize_settings.custom_script')}</h2>
-          <Card className="card custom-card">
+          <Card className="card custom-card bg-body-tertiary mb-3">
             <CardBody className="px-0 py-2">
               {t('admin:customize_settings.write_java')}<br />
               {t('admin:customize_settings.reflect_change')}
@@ -44,7 +44,7 @@ const CustomizeScriptSetting = (props: Props): JSX.Element => {
 
           <div>
             <textarea
-              className="form-control"
+              className="form-control mb-2"
               name="customizeScript"
               rows={8}
               defaultValue={adminCustomizeContainer.state.currentCustomizeScript || ''}

+ 2 - 2
apps/app/src/components/Admin/Customize/CustomizeSidebarSetting.tsx

@@ -42,7 +42,7 @@ const CustomizeSidebarsetting = (): JSX.Element => {
 
           <h2 className="admin-setting-header">{t('customize_settings.default_sidebar_mode.title')}</h2>
 
-          <Card className="card custom-card my-3">
+          <Card className="card custom-card bg-body-tertiary my-3">
             <CardBody className="px-0 py-2">
               {t('customize_settings.default_sidebar_mode.desc')}
             </CardBody>
@@ -79,7 +79,7 @@ const CustomizeSidebarsetting = (): JSX.Element => {
             </div>
           </div>
 
-          <Card className="card custom-card my-5">
+          <Card className="card custom-card bg-body-tertiary my-5">
             <CardBody className="px-0 py-2">
               {t('customize_settings.default_sidebar_mode.dock_mode_default_desc')}
             </CardBody>

+ 4 - 4
apps/app/src/components/Admin/Customize/CustomizeThemeOptions.tsx

@@ -29,8 +29,8 @@ const CustomizeThemeOptions = (props: Props): JSX.Element => {
 
       {/* Light and Dark Themes */}
       <div>
-        <h3>{t('customize_settings.theme_desc.light_and_dark')}</h3>
-        <div className="hstack gap-3">
+        <h3 className="mb-3">{t('customize_settings.theme_desc.light_and_dark')}</h3>
+        <div className="hstack gap-3 flex-wrap">
           {lightNDarkThemes.map((theme) => {
             return (
               <ThemeColorBox
@@ -46,8 +46,8 @@ const CustomizeThemeOptions = (props: Props): JSX.Element => {
 
       {/* Only one mode Theme */}
       <div className="mt-3">
-        <h3>{t('customize_settings.theme_desc.unique')}</h3>
-        <div className="hstack gap-3">
+        <h3 className="mb-3">{t('customize_settings.theme_desc.unique')}</h3>
+        <div className="hstack gap-3 align-items-start flex-wrap">
           {oneModeThemes.map((theme) => {
             return (
               <ThemeColorBox

+ 4 - 3
apps/app/src/components/Admin/Customize/CustomizeTitle.tsx

@@ -1,4 +1,5 @@
-import React, { FC, useState } from 'react';
+import type { FC } from 'react';
+import React, { useState } from 'react';
 
 import { useTranslation } from 'next-i18next';
 import { Card, CardBody } from 'reactstrap';
@@ -37,7 +38,7 @@ export const CustomizeTitle: FC = () => {
         </div>
 
         <div className="col-12">
-          <Card className="card custom-card">
+          <Card className="card custom-card bg-body-tertiary mb-3">
             <CardBody className="px-0 py-2">
               {/* eslint-disable react/no-danger */}
               <p dangerouslySetInnerHTML={{ __html: t('admin:customize_settings.custom_title_detail') }} />
@@ -58,7 +59,7 @@ export const CustomizeTitle: FC = () => {
         </div>
 
         {/* TODO i18n */}
-        <div className="form-text text-muted col-12">
+        <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>

+ 1 - 1
apps/app/src/components/Admin/Customize/PagingSizeUncontrolledDropdown.jsx

@@ -18,7 +18,7 @@ const PagingSizeUncontrolledDropdown = (props) => {
   return (
     <React.Fragment>
       <div className="row">
-        <div className="offset-md-3 col-md-6 text-start">
+        <div className="offset-md-2 col-md-7 text-start">
           <div className="my-0 w-100">
             <label className="form-label">{props.label}</label>
           </div>

+ 1 - 1
apps/app/src/components/Admin/Customize/ThemeColorBox.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 // layout
 .theme-option-container :global {

+ 1 - 1
apps/app/src/components/Admin/ElasticsearchManagement/ElasticsearchManagement.tsx

@@ -97,7 +97,7 @@ const ElasticsearchManagement = () => {
       socket.off(SocketEventName.FinishAddPage);
       socket.off(SocketEventName.RebuildingFailed);
     };
-  }, [socket]);
+  }, [retrieveIndicesStatus, socket]);
 
 
   const reconnect = async() => {

+ 8 - 6
apps/app/src/components/Admin/ElasticsearchManagement/RebuildIndexControls.jsx

@@ -71,12 +71,14 @@ class RebuildIndexControls extends React.Component {
     const header = isRebuildingCompleted ? getCompletedLabel() : getSkipLabel();
 
     return (
-      <LabeledProgressBar
-        header={header}
-        currentCount={current}
-        errorsCount={skip}
-        totalCount={total}
-      />
+      <div className="mb-3">
+        <LabeledProgressBar
+          header={header}
+          currentCount={current}
+          errorsCount={skip}
+          totalCount={total}
+        />
+      </div>
     );
   }
 

+ 10 - 9
apps/app/src/components/Admin/ElasticsearchManagement/StatusTable.jsx

@@ -6,7 +6,7 @@ import PropTypes from 'prop-types';
 class StatusTable extends React.PureComponent {
 
   renderPreInitializedLabel() {
-    return <span className="badge rounded-pill bg-default">――</span>;
+    return <span className="badge text-bg-default">――</span>;
   }
 
   renderConnectionStatusLabels() {
@@ -17,13 +17,13 @@ class StatusTable extends React.PureComponent {
     } = this.props;
 
     const errorOccuredLabel = isErrorOccuredOnSearchService
-      ? <span className="badge rounded-pill bg-danger ms-2">{ t('full_text_search_management.connection_status_label_erroroccured') }</span>
+      ? <span className="badge text-bg-danger ms-2">{ t('full_text_search_management.connection_status_label_erroroccured') }</span>
       : null;
 
     let connectionStatusLabel = null;
     if (!isConfigured) {
       connectionStatusLabel = (
-        <span className="badge rounded-pill bg-default">
+        <span className="badge text-bg-default">
           { t('full_text_search_management.connection_status_label_unconfigured') }
         </span>
       );
@@ -31,8 +31,8 @@ class StatusTable extends React.PureComponent {
     else {
       connectionStatusLabel = isConnected
         // eslint-disable-next-line max-len
-        ? <span data-testid="connection-status-badge-connected" className="badge rounded-pill bg-success">{ t('full_text_search_management.connection_status_label_connected') }</span>
-        : <span className="badge rounded-pill bg-danger">{ t('full_text_search_management.connection_status_label_disconnected') }</span>;
+        ? <span data-testid="connection-status-badge-connected" className="badge text-bg-success">{ t('full_text_search_management.connection_status_label_connected') }</span>
+        : <span className="badge text-bg-danger">{ t('full_text_search_management.connection_status_label_disconnected') }</span>;
     }
 
     return (
@@ -46,8 +46,8 @@ class StatusTable extends React.PureComponent {
     const { t, isNormalized } = this.props;
 
     return isNormalized
-      ? <span className="badge rounded-pill bg-info">{ t('full_text_search_management.indices_status_label_normalized') }</span>
-      : <span className="badge rounded-pill bg-warning text-dark">{ t('full_text_search_management.indices_status_label_unnormalized') }</span>;
+      ? <span className="badge text-bg-info">{ t('full_text_search_management.indices_status_label_normalized') }</span>
+      : <span className="badge text-bg-warning">{ t('full_text_search_management.indices_status_label_unnormalized') }</span>;
   }
 
   renderIndexInfoPanel(indexName, body = {}, aliases = []) {
@@ -55,8 +55,9 @@ class StatusTable extends React.PureComponent {
 
     const aliasLabels = aliases.map((aliasName) => {
       return (
-        <span key={`badge-${indexName}-${aliasName}`} className="badge rounded-pill bg-primary me-2">
-          <span className="material-symbols-outlined">sell</span> {aliasName}
+        <span key={`badge-${indexName}-${aliasName}`} className="badge text-bg-primary me-2">
+          <span className="material-symbols-outlined">sell</span>
+          <span>{aliasName}</span>
         </span>
       );
     });

+ 2 - 2
apps/app/src/components/Admin/ExportArchiveData/SelectCollectionsModal.tsx

@@ -103,7 +103,7 @@ const SelectCollectionsModal = (props: Props): JSX.Element => {
     const html = t('admin:export_management.desc_password_seed');
 
     // eslint-disable-next-line react/no-danger
-    return <div className="card custom-card" dangerouslySetInnerHTML={{ __html: html }}></div>;
+    return <div className="card custom-card bg-body-tertiary" dangerouslySetInnerHTML={{ __html: html }}></div>;
   }, [selectedCollections, t]);
 
   const renderCheckboxes = useCallback((collectionNames, color?) => {
@@ -156,7 +156,7 @@ const SelectCollectionsModal = (props: Props): JSX.Element => {
   }, [isAllChecked, checkAll]);
 
   return (
-    <Modal isOpen={isOpen} toggle={onClose}>
+    <Modal size="lg" isOpen={isOpen} toggle={onClose}>
       <ModalHeader tag="h4" toggle={onClose} className="text-info">
         {t('admin:export_management.export_collections')}
       </ModalHeader>

+ 1 - 1
apps/app/src/components/Admin/ExportArchiveDataPage.tsx

@@ -151,7 +151,7 @@ const ExportArchiveDataPage = (): JSX.Element => {
       ) }
 
       <div className="mt-5">
-        <h3>{t('export_management.exported_data_list')}</h3>
+        <h3 className="mb-3">{t('export_management.exported_data_list')}</h3>
         <ArchiveFilesTable
           zipFileStats={zipFileStats}
           onZipFileStatRemove={onZipFileStatRemove}

+ 1 - 1
apps/app/src/components/Admin/FullTextSearchManagement.tsx

@@ -9,7 +9,7 @@ export const FullTextSearchManagement = (): JSX.Element => {
 
   return (
     <div data-testid="admin-full-text-search">
-      <h2> { t('full_text_search_management.elasticsearch_management') } </h2>
+      <h2 className="mb-4"> { t('full_text_search_management.elasticsearch_management') } </h2>
       <ElasticsearchManagement />
     </div>
   );

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

@@ -75,7 +75,7 @@ class UploadForm extends React.Component {
             </div>
           </div>
           <div className="row">
-            <div className="mx-auto">
+            <div className="mx-auto mt-3">
               <button type="submit" className="btn btn-primary" disabled={!this.validateForm()}>
                 {t('admin:importer_management.growi_settings.upload')}
               </button>

+ 2 - 2
apps/app/src/components/Admin/ImportData/GrowiArchiveSection.jsx

@@ -92,8 +92,8 @@ class GrowiArchiveSection extends React.Component {
 
     return (
       <Fragment>
-        <h2>{t('importer_management.import_growi_archive')}</h2>
-        <div className="card custom-card mb-4 small">
+        <h2 className="mb-3">{t('importer_management.import_growi_archive')}</h2>
+        <div className="card custom-card bg-body-tertiary mb-4 small">
           <ul>
             <li>{t('importer_management.skip_username_and_email_when_overlapped')}</li>
             <li>{t('importer_management.prepare_new_account_for_migration')}</li>

+ 11 - 11
apps/app/src/components/Admin/ImportData/ImportDataPageContents.jsx

@@ -57,13 +57,13 @@ class ImportDataPageContents extends React.Component {
               </tbody>
             </table>
 
-            <div className="card custom-card mb-0 small">
+            <div className="card custom-card bg-body-tertiary mb-0 small">
               <ul>
                 <li>{t('importer_management.page_skip')}</li>
               </ul>
             </div>
 
-            <div className="row">
+            <div className="row mt-4">
               <input type="password" name="dummypass" style={{ display: 'none', top: '-100px', left: '-100px' }} />
             </div>
 
@@ -83,7 +83,7 @@ class ImportDataPageContents extends React.Component {
 
             </div>
 
-            <div className="row">
+            <div className="row mt-3">
               <label htmlFor="settingForm[importer:esa:access_token]" className="text-start text-md-end col-md-3 col-form-label">
                 {t('importer_management.esa_settings.access_token')}
               </label>
@@ -98,12 +98,12 @@ class ImportDataPageContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row mt-3">
               <div className="offset-md-3 col-md-6">
                 <input
                   id="testConnectionToEsa"
                   type="button"
-                  className="btn btn-primary btn-esa"
+                  className="btn btn-primary btn-esa me-3"
                   name="Esa"
                   onClick={adminImportContainer.esaHandleSubmit}
                   value={t('importer_management.import')}
@@ -163,16 +163,16 @@ class ImportDataPageContents extends React.Component {
                 </tr>
               </tbody>
             </table>
-            <div className="card custom-card mb-0 small">
+            <div className="card custom-card bg-body-tertiary mb-3 small">
               <ul>
                 <li>{t('importer_management.page_skip')}</li>
               </ul>
             </div>
 
-            <div className="row">
+            <div className="row mt-3">
               <input type="password" name="dummypass" style={{ display: 'none', top: '-100px', left: '-100px' }} />
             </div>
-            <div className="row">
+            <div className="row mt-3">
               <label htmlFor="settingForm[importer:qiita:team_name]" className="text-start text-md-end col-md-3 col-form-label">
                 {t('importer_management.qiita_settings.team_name')}
               </label>
@@ -187,7 +187,7 @@ class ImportDataPageContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row mt-3">
               <label htmlFor="settingForm[importer:qiita:access_token]" className="text-start text-md-end col-md-3 col-form-label">
                 {t('importer_management.qiita_settings.access_token')}
               </label>
@@ -203,12 +203,12 @@ class ImportDataPageContents extends React.Component {
             </div>
 
 
-            <div className="row">
+            <div className="row mt-3">
               <div className="offset-md-3 col-md-6">
                 <input
                   id="testConnectionToQiita"
                   type="button"
-                  className="btn btn-primary btn-qiita"
+                  className="btn btn-primary btn-qiita me-3"
                   name="Qiita"
                   onClick={adminImportContainer.qiitaHandleSubmit}
                   value={t('importer_management.import')}

+ 6 - 6
apps/app/src/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx

@@ -99,9 +99,9 @@ class SlackConfiguration extends React.Component {
         )
           : (
             <React.Fragment>
-              <h2 className="border-bottom mb-5">{t('notification_settings.slack_app_configuration')}</h2>
+              <h2 className="border-bottom mb-3">{t('notification_settings.slack_app_configuration')}</h2>
 
-              <div className="card custom-card">
+              <div className="card custom-card bg-danger-subtle">
                 <span className="text-danger"><span className="material-symbols-outlined">error</span>NOT RECOMMENDED</span>
                 <br />
                 {/* eslint-disable-next-line react/no-danger */}
@@ -116,7 +116,7 @@ class SlackConfiguration extends React.Component {
                 </a>
               </div>
 
-              <div className="row mb-5">
+              <div className="row mb-5 mt-4">
                 <label className="form-label col-md-3 text-start text-md-end">OAuth access token</label>
                 <div className="col-md-6">
                   <input
@@ -144,8 +144,8 @@ class SlackConfiguration extends React.Component {
           <a href="#collapseHelpForIwh" data-bs-toggle="collapse">{t('notification_settings.how_to.header')}</a>
         </h3>
 
-        <ol id="collapseHelpForIwh" className="collapse">
-          <li>
+        <ol id="collapseHelpForIwh" className="collapse card custom-card bg-body-tertiary">
+          <li className="ms-3">
             {t('notification_settings.how_to.workspace')}
             <ol>
               {/* eslint-disable-next-line react/no-danger */}
@@ -154,7 +154,7 @@ class SlackConfiguration extends React.Component {
               <li>{t('notification_settings.how_to.workspace_desc3')}</li>
             </ol>
           </li>
-          <li>
+          <li className="ms-3">
             {t('notification_settings.how_to.at_growi')}
             <ol>
               {/* eslint-disable-next-line react/no-danger */}

+ 6 - 6
apps/app/src/components/Admin/MarkdownSetting/MarkDownSettingContents.tsx

@@ -40,24 +40,24 @@ const MarkDownSettingContents = React.memo((props: Props): JSX.Element => {
   }, [adminMarkDownContainer]);
 
   return (
-    <div data-testid="admin-markdown">
+    <div data-testid="admin-markdown" className="mb-5">
       {/* Line Break Setting */}
       <h2 className="admin-setting-header">{t('markdown_settings.lineBreak_header')}</h2>
-      <Card className="card custom-card my-3">
+      <Card className="card custom-card bg-body-tertiary my-3">
         <CardBody className="px-0 py-2">{ t('markdown_settings.lineBreak_desc') }</CardBody>
       </Card>
       <LineBreakForm />
 
       {/* Indent Setting */}
-      <h2 className="admin-setting-header">{t('markdown_settings.indent_header')}</h2>
-      <Card className="card custom-card my-3">
+      <h2 className="admin-setting-header mt-5">{t('markdown_settings.indent_header')}</h2>
+      <Card className="card custom-card bg-body-tertiary my-3">
         <CardBody className="px-0 py-2">{t('markdown_settings.indent_desc') }</CardBody>
       </Card>
       <IndentForm />
 
       {/* XSS Setting */}
-      <h2 className="admin-setting-header">{ t('markdown_settings.xss_header') }</h2>
-      <Card className="card custom-card my-3">
+      <h2 className="admin-setting-header mt-5">{ t('markdown_settings.xss_header') }</h2>
+      <Card className="card custom-card bg-body-tertiary my-3">
         <CardBody className="px-0 py-2">{ t('markdown_settings.xss_desc') }</CardBody>
       </Card>
       <XssForm />

+ 2 - 2
apps/app/src/components/Admin/MarkdownSetting/WhitelistInput.jsx

@@ -41,7 +41,7 @@ class WhitelistInput extends React.Component {
         <div className="mt-4">
           <div className="d-flex justify-content-between">
             {t('markdown_settings.xss_options.tag_names')}
-            <p id="btn-import-tags" className="btn btn-sm btn-primary mb-0" onClick={this.onClickRecommendTagButton}>
+            <p id="btn-import-tags" className="btn btn-sm btn-primary" onClick={this.onClickRecommendTagButton}>
               {t('markdown_settings.xss_options.import_recommended', { target: 'Tags' })}
             </p>
           </div>
@@ -58,7 +58,7 @@ class WhitelistInput extends React.Component {
         <div className="mt-4">
           <div className="d-flex justify-content-between">
             {t('markdown_settings.xss_options.tag_attributes')}
-            <p id="btn-import-tags" className="btn btn-sm btn-primary mb-0" onClick={this.onClickRecommendAttrButton}>
+            <p id="btn-import-tags" className="btn btn-sm btn-primary" onClick={this.onClickRecommendAttrButton}>
               {t('markdown_settings.xss_options.import_recommended', { target: 'Attrs' })}
             </p>
           </div>

+ 4 - 4
apps/app/src/components/Admin/MarkdownSetting/XssForm.jsx

@@ -45,10 +45,10 @@ class XssForm extends React.Component {
     const rehypeRecommendedAttributes = JSON.stringify(sanitizeDefaultSchema.attributes);
 
     return (
-      <div className="col-12 my-3">
+      <div className="col-12 mt-3">
         <div className="row">
 
-          <div className="col-md-6 col-sm-12 align-self-start mb-4">
+          <div className="col-md-6 col-sm-12 align-self-start">
             <div className="form-check">
               <input
                 type="radio"
@@ -90,7 +90,7 @@ class XssForm extends React.Component {
             </div>
           </div>
 
-          <div className="col-md-6 col-sm-12 align-self-start mb-4">
+          <div className="col-md-6 col-sm-12 align-self-start">
             <div className="form-check">
               <input
                 type="radio"
@@ -119,7 +119,7 @@ class XssForm extends React.Component {
       <React.Fragment>
         <fieldset className="col-12">
           <div>
-            <div className="col-8 offset-4 my-3">
+            <div className="col-8 offset-4 mt-3">
               <div className="form-check form-switch form-check-success">
                 <input
                   type="checkbox"

+ 10 - 9
apps/app/src/components/Admin/Notification/GlobalNotification.jsx

@@ -36,7 +36,7 @@ const GlobalNotification = (props) => {
     <>
       <h2 className="border-bottom my-4">{t('notification_settings.valid_page')}</h2>
 
-      <p className="card custom-card">
+      <p className="card custom-card bg-body-tertiary">
         {/* eslint-disable-next-line react/no-danger */}
         <span dangerouslySetInnerHTML={{ __html: t('notification_settings.link_notification_help') }} />
       </p>
@@ -75,7 +75,7 @@ const GlobalNotification = (props) => {
           </div>
         </div>
       </div>
-      <div className="row my-3">
+      <div className="row mt-3 mb-5">
         <div className="col-sm-5 offset-sm-4">
           <button
             type="button"
@@ -87,14 +87,15 @@ const GlobalNotification = (props) => {
         </div>
       </div>
 
-      <h2 className="border-bottom mb-5">{t('notification_settings.notification_list')}
-        <button
-          className="btn btn-outline-secondary pull-right"
-          type="button"
-          onClick={() => router.push('/admin/global-notification/new')}
-        >{t('notification_settings.add_notification')}
-        </button>
+      <h2 className="border-bottom mb-3">
+        {t('notification_settings.notification_list')}
       </h2>
+      <button
+        className="btn btn-outline-secondary mb-3"
+        type="button"
+        onClick={() => router.push('/admin/global-notification/new')}
+      >{t('notification_settings.add_notification')}
+      </button>
       <table className="table table-bordered">
         <thead>
           <tr>

+ 4 - 4
apps/app/src/components/Admin/Notification/NotificationSetting.jsx

@@ -31,14 +31,14 @@ const Badge = ({ isEnabled }) => {
   const { t } = useTranslation('admin');
 
   return isEnabled
-    ? <span className="badge bg-success">{t('external_notification.enabled')}</span>
-    : <span className="badge bg-primary">{t('external_notification.disabled')}</span>;
+    ? <span className="badge text-bg-success">{t('external_notification.enabled')}</span>
+    : <span className="badge text-bg-primary">{t('external_notification.disabled')}</span>;
 };
 
 const SkeletonListItem = () => (
   <li className="list-group-item">
     <h4 className="mb-2">
-      <span className="badge bg-primary">――</span>
+      <span className="badge text-bg-primary">――</span>
       <span className="ms-2">...</span>
     </h4>
   </li>
@@ -51,7 +51,7 @@ const SlackIntegrationListItem = ({ isEnabled, currentBotType }) => {
   const isCautionVisible = currentBotType === SlackbotType.OFFICIAL || currentBotType === SlackbotType.CUSTOM_WITH_PROXY;
 
   return (
-    <li data-testid="slack-integration-list-item" className="list-group-item">
+    <li data-testid="slack-integration-list-item" className="list-group-item bg-body-tertiary">
       <h4>
         <Badge isEnabled={isEnabled} />
         <a href="/admin/slack-integration" className="ms-2">{t('slack_integration.slack_integration')}</a>

+ 16 - 14
apps/app/src/components/Admin/Security/GitHubSecuritySettingContents.jsx

@@ -56,7 +56,7 @@ class GitHubSecurityManagementContents extends React.Component {
           </div>
         )}
 
-        <div className="row">
+        <div className="row my-4">
           <div className="col-6 offset-3">
             <div className="form-check form-switch form-check-success">
               <input
@@ -71,11 +71,11 @@ class GitHubSecurityManagementContents extends React.Component {
               </label>
             </div>
             {(!adminGeneralSecurityContainer.state.setupStrategies.includes('github') && isGitHubEnabled)
-              && <div className="badge bg-warning text-dark">{t('security_settings.setup_is_not_yet_complete')}</div>}
+              && <div className="badge text-bg-warning">{t('security_settings.setup_is_not_yet_complete')}</div>}
           </div>
         </div>
 
-        <div className="row mb-5">
+        <div className="row mb-4">
           <label className="form-label col-12 col-md-3 text-start text-md-end py-2">{t('security_settings.callback_URL')}</label>
           <div className="col-12 col-md-6">
             <input
@@ -100,9 +100,9 @@ class GitHubSecurityManagementContents extends React.Component {
         {isGitHubEnabled && (
           <React.Fragment>
 
-            <h3 className="border-bottom">{t('security_settings.configuration')}</h3>
+            <h3 className="border-bottom mb-4">{t('security_settings.configuration')}</h3>
 
-            <div className="row mb-5">
+            <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
@@ -118,7 +118,7 @@ class GitHubSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <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
@@ -134,7 +134,7 @@ class GitHubSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-3">
               <div className="offset-3 col-6 text-start">
                 <div className="form-check form-check-success">
                   <input
@@ -156,7 +156,7 @@ class GitHubSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row my-3">
+            <div className="row mb-4">
               <div className="offset-3 col-5">
                 <div className="btn btn-primary" disabled={adminGitHubSecurityContainer.state.retrieveError != null} onClick={this.onClickSubmit}>
                   {t('Update')}
@@ -174,12 +174,14 @@ class GitHubSecurityManagementContents extends React.Component {
             <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>
-          <ol id="collapseHelpForGitHubOauth" className="collapse">
-            {/* eslint-disable-next-line max-len */}
-            <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.GitHub.register_1', { link: '<a href="https://github.com/settings/developers" target=_blank>GitHub Developer Settings</a>' }) }} />
-            <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.GitHub.register_2', { url: gitHubCallbackUrl }) }} />
-            <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.GitHub.register_3') }} />
-          </ol>
+          <div className="card custom-card bg-body-tertiary">
+            <ol id="collapseHelpForGitHubOauth" className="collapse mb-0">
+              {/* eslint-disable-next-line max-len */}
+              <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.GitHub.register_1', { link: '<a href="https://github.com/settings/developers" target=_blank>GitHub Developer Settings</a>' }) }} />
+              <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.GitHub.register_2', { url: gitHubCallbackUrl }) }} />
+              <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.GitHub.register_3') }} />
+            </ol>
+          </div>
         </div>
 
       </React.Fragment>

+ 17 - 15
apps/app/src/components/Admin/Security/GoogleSecuritySettingContents.jsx

@@ -54,7 +54,7 @@ class GoogleSecurityManagementContents extends React.Component {
           </div>
         )}
 
-        <div className="row">
+        <div className="row my-4">
           <div className="col-6 offset-3">
             <div className="form-check form-switch form-check-success">
               <input
@@ -69,7 +69,7 @@ class GoogleSecurityManagementContents extends React.Component {
               </label>
             </div>
             {(!adminGeneralSecurityContainer.state.setupStrategies.includes('google') && isGoogleEnabled)
-              && <div className="badge bg-warning text-dark">{t('security_settings.setup_is_not_yet_complete')}</div>}
+              && <div className="badge text-bg-warning">{t('security_settings.setup_is_not_yet_complete')}</div>}
           </div>
         </div>
 
@@ -99,9 +99,9 @@ class GoogleSecurityManagementContents extends React.Component {
         {isGoogleEnabled && (
           <React.Fragment>
 
-            <h3 className="border-bottom">{t('security_settings.configuration')}</h3>
+            <h3 className="border-bottom mb-4">{t('security_settings.configuration')}</h3>
 
-            <div className="row mb-5">
+            <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
@@ -117,7 +117,7 @@ class GoogleSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <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
@@ -133,7 +133,7 @@ class GoogleSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-3">
               <div className="offset-3 col-6">
                 <div className="form-check form-check-success">
                   <input
@@ -155,7 +155,7 @@ class GoogleSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row my-3">
+            <div className="row mb-4">
               <div className="offset-3 col-5">
                 <button
                   type="button"
@@ -178,14 +178,16 @@ class GoogleSecurityManagementContents extends React.Component {
             <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>
-          <ol id="collapseHelpForGoogleOauth" className="collapse">
-            {/* eslint-disable-next-line max-len */}
-            <li 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 dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_2') }} />
-            <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_3') }} />
-            <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_4', { url: googleCallbackUrl }) }} />
-            <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_5') }} />
-          </ol>
+          <div className="card custom-card bg-body-tertiary">
+            <ol id="collapseHelpForGoogleOauth" className="collapse mb-0">
+              {/* eslint-disable-next-line max-len */}
+              <li 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 dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_2') }} />
+              <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_3') }} />
+              <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_4', { url: googleCallbackUrl }) }} />
+              <li dangerouslySetInnerHTML={{ __html: t('security_settings.OAuth.Google.register_5') }} />
+            </ol>
+          </div>
         </div>
 
       </React.Fragment>

+ 30 - 30
apps/app/src/components/Admin/Security/LdapSecuritySettingContents.jsx

@@ -54,11 +54,11 @@ class LdapSecuritySettingContents extends React.Component {
     return (
       <React.Fragment>
 
-        <h2 className="alert-anchor border-bottom">
+        <h2 className="alert-anchor border-bottom mb-4">
           LDAP
         </h2>
 
-        <div className="row">
+        <div className="row my-4">
           <div className="col-6 offset-3">
             <div className="form-check form-switch form-check-success">
               <input
@@ -73,7 +73,7 @@ class LdapSecuritySettingContents extends React.Component {
               </label>
             </div>
             {(!adminGeneralSecurityContainer.state.setupStrategies.includes('ldap') && isLdapEnabled)
-              && <div className="badge bg-warning text-dark">{t('security_settings.setup_is_not_yet_complete')}</div>}
+              && <div className="badge text-bg-warning">{t('security_settings.setup_is_not_yet_complete')}</div>}
           </div>
         </div>
 
@@ -81,13 +81,13 @@ class LdapSecuritySettingContents extends React.Component {
         {isLdapEnabled && (
           <React.Fragment>
 
-            <h3 className="border-bottom">{t('security_settings.configuration')}</h3>
+            <h3 className="border-bottom mb-4">{t('security_settings.configuration')}</h3>
 
-            <div className="row">
+            <div className="row my-3">
               <label htmlFor="serverUrl" className="text-start text-md-end col-md-3 col-form-label">
                 Server URL
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -106,11 +106,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong>{t('security_settings.ldap.bind_mode')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <div className="dropdown">
                   <button
                     className="btn btn-outline-secondary dropdown-toggle"
@@ -136,11 +136,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong>Bind DN</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -171,11 +171,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <div htmlFor="bindDNPassword" className="text-start text-md-end col-md-3 col-form-label">
                 <strong>{t('security_settings.ldap.bind_DN_password')}</strong>
               </div>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 {(adminLdapSecurityContainer.state.isUserBind) ? (
                   <p className="card custom-card passport-ldap-userbind">
                     <small>
@@ -202,11 +202,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong>{t('security_settings.ldap.search_filter')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -234,15 +234,15 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <h3 className="alert-anchor border-bottom">
+            <h3 className="alert-anchor border-bottom mb-4">
               Attribute Mapping ({t('optional')})
             </h3>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong htmlFor="attrMapUsername">{t('username')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -258,8 +258,8 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
-              <div className="offset-md-3 col-md-6">
+            <div className="row my-3">
+              <div className="offset-md-3 col-md-9">
                 <div className="form-check form-check-success">
                   <input
                     type="checkbox"
@@ -282,11 +282,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong htmlFor="attrMapMail">{t('Email')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -303,11 +303,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong htmlFor="attrMapName">{t('Name')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -324,15 +324,15 @@ class LdapSecuritySettingContents extends React.Component {
             </div>
 
 
-            <h3 className="alert-anchor border-bottom">
+            <h3 className="alert-anchor border-bottom mb-4">
               {t('security_settings.ldap.group_search_filter')} ({t('optional')})
             </h3>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong htmlFor="groupSearchBase">{t('security_settings.ldap.group_search_base_DN')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -350,11 +350,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong htmlFor="groupSearchFilter">{t('security_settings.ldap.group_search_filter')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"
@@ -381,11 +381,11 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
             </div>
 
-            <div className="row">
+            <div className="row my-3">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">
                 <strong htmlFor="groupDnProperty">{t('security_settings.ldap.group_search_user_DN_property')}</strong>
               </label>
-              <div className="col-md-6">
+              <div className="col-md-9">
                 <input
                   className="form-control"
                   type="text"

+ 11 - 11
apps/app/src/components/Admin/Security/LocalSecuritySettingContents.jsx

@@ -62,7 +62,7 @@ class LocalSecuritySettingContents extends React.Component {
           />
         )}
 
-        <div className="row mb-5">
+        <div className="row mt-4 mb-5">
           <div className="col-6 offset-3">
             <div className="form-check form-switch form-check-success">
               <input
@@ -88,10 +88,10 @@ class LocalSecuritySettingContents extends React.Component {
             <h3 className="border-bottom">{t('security_settings.configuration')}</h3>
 
             <div className="row">
-              <div className="col-12 col-md-3 text-start text-md-end py-2">
+              <div className="col-12 col-md-4 text-start text-md-end py-2">
                 <strong>{t('security_settings.register_limitation')}</strong>
               </div>
-              <div className="col-12 col-md-6">
+              <div className="col-12 col-md-8">
                 <div className="dropdown">
                   <button
                     className="btn btn-outline-secondary dropdown-toggle"
@@ -139,10 +139,10 @@ class LocalSecuritySettingContents extends React.Component {
               </div>
             </div>
             <div className="row">
-              <div className="col-12 col-md-3 text-start text-md-end">
+              <div className="col-12 col-md-4 text-start text-md-end">
                 <strong dangerouslySetInnerHTML={{ __html: t('security_settings.The whitelist of registration permission E-mail address') }} />
               </div>
-              <div className="col-12 col-md-6">
+              <div className="col-12 col-md-8">
                 <textarea
                   className="form-control"
                   type="textarea"
@@ -163,8 +163,8 @@ class LocalSecuritySettingContents extends React.Component {
             </div>
 
             <div className="row">
-              <label className="col-12 col-md-3 text-start text-md-end  col-form-label">{t('security_settings.Local.password_reset_by_users')}</label>
-              <div className="col-12 col-md-6">
+              <label className="col-12 col-md-4 text-start text-md-end  col-form-label">{t('security_settings.Local.password_reset_by_users')}</label>
+              <div className="col-12 col-md-8">
                 <div className="form-check form-switch form-check-success">
                   <input
                     type="checkbox"
@@ -178,7 +178,7 @@ class LocalSecuritySettingContents extends React.Component {
                   </label>
                 </div>
                 {!isMailerSetup && (
-                  <div className="alert alert-warning p-1 my-1 small d-inline-block">
+                  <div className="alert alert-warning p-2 my-1 small d-inline-block">
                     <span>{t('commons:alert.password_reset_please_enable_mailer')}</span>
                     <Link href="/admin/app#mail-settings">
                       <span className="material-symbols-outlined">link</span> {t('app_setting.mail_settings')}
@@ -192,8 +192,8 @@ class LocalSecuritySettingContents extends React.Component {
             </div>
 
             <div className="row">
-              <label className="col-12 col-md-3 text-start text-md-end  col-form-label">{t('security_settings.Local.email_authentication')}</label>
-              <div className="col-12 col-md-6">
+              <label className="col-12 col-md-4 text-start text-md-end  col-form-label">{t('security_settings.Local.email_authentication')}</label>
+              <div className="col-12 col-md-8">
                 <div className="form-check form-switch form-check-success">
                   <input
                     type="checkbox"
@@ -207,7 +207,7 @@ class LocalSecuritySettingContents extends React.Component {
                   </label>
                 </div>
                 {!isMailerSetup && (
-                  <div className="alert alert-warning p-1 my-1 small d-inline-block">
+                  <div className="alert alert-warning p-2 my-1 small d-inline-block">
                     <span>{t('commons:alert.please_enable_mailer')}</span>
                     <Link href="/admin/app#mail-settings">
                       <span className="material-symbols-outlined">link</span> {t('app_setting.mail_settings')}

+ 30 - 28
apps/app/src/components/Admin/Security/OidcSecuritySettingContents.jsx

@@ -48,7 +48,7 @@ class OidcSecurityManagementContents extends React.Component {
           {t('security_settings.OAuth.OIDC.name')}
         </h2>
 
-        <div className="row mb-5">
+        <div className="row  my-4">
           <div className="offset-3 col-6">
             <div className="form-check form-switch form-check-success">
               <input
@@ -63,7 +63,7 @@ class OidcSecurityManagementContents extends React.Component {
               </label>
             </div>
             {(!adminGeneralSecurityContainer.state.setupStrategies.includes('oidc') && isOidcEnabled)
-              && <div className="badge bg-warning text-dark">{t('security_settings.setup_is_not_yet_complete')}</div>}
+              && <div className="badge text-bg-warning">{t('security_settings.setup_is_not_yet_complete')}</div>}
           </div>
         </div>
 
@@ -92,9 +92,9 @@ class OidcSecurityManagementContents extends React.Component {
         {isOidcEnabled && (
           <>
 
-            <h3 className="border-bottom">{t('security_settings.configuration')}</h3>
+            <h3 className="border-bottom mb-4">{t('security_settings.configuration')}</h3>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcProviderName" className="text-start text-md-end col-md-3 col-form-label">{t('security_settings.providerName')}</label>
               <div className="col-md-6">
                 <input
@@ -107,7 +107,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcIssuerHost" className="text-start text-md-end col-md-3 col-form-label">{t('security_settings.issuerHost')}</label>
               <div className="col-md-6">
                 <input
@@ -123,7 +123,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcClientId" className="text-start text-md-end col-md-3 col-form-label">{t('security_settings.clientID')}</label>
               <div className="col-md-6">
                 <input
@@ -139,7 +139,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcClientSecret" className="text-start text-md-end col-md-3 col-form-label">{t('security_settings.client_secret')}</label>
               <div className="col-md-6">
                 <input
@@ -155,7 +155,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcAuthorizationEndpoint" className="text-start text-md-end col-md-3 col-form-label">
                 {t('security_settings.authorization_endpoint')}
               </label>
@@ -173,7 +173,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcTokenEndpoint" className="text-start text-md-end col-md-3 col-form-label">{t('security_settings.token_endpoint')}</label>
               <div className="col-md-6">
                 <input
@@ -189,7 +189,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcRevocationEndpoint" className="text-start text-md-end col-md-3 col-form-label">
                 {t('security_settings.revocation_endpoint')}
               </label>
@@ -207,7 +207,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcIntrospectionEndpoint" className="text-start text-md-end col-md-3 col-form-label">
                 {t('security_settings.introspection_endpoint')}
               </label>
@@ -225,7 +225,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcUserInfoEndpoint" className="text-start text-md-end col-md-3 col-form-label">
                 {t('security_settings.userinfo_endpoint')}
               </label>
@@ -243,7 +243,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcEndSessionEndpoint" className="text-start text-md-end col-md-3 col-form-label">
                 {t('security_settings.end_session_endpoint')}
               </label>
@@ -261,7 +261,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcRegistrationEndpoint" className="text-start text-md-end col-md-3 col-form-label">
                 {t('security_settings.registration_endpoint')}
               </label>
@@ -279,7 +279,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcJWKSUri" className="text-start text-md-end col-md-3 col-form-label">{t('security_settings.jwks_uri')}</label>
               <div className="col-md-6">
                 <input
@@ -295,11 +295,11 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <h3 className="alert-anchor border-bottom">
+            <h3 className="alert-anchor border-bottom mb-4">
               Attribute Mapping ({t('optional')})
             </h3>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcAttrMapId" className="text-start text-md-end col-md-3 col-form-label">Identifier</label>
               <div className="col-md-6">
                 <input
@@ -315,7 +315,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcAttrMapUserName" className="text-start text-md-end col-md-3 col-form-label">{t('username')}</label>
               <div className="col-md-6">
                 <input
@@ -331,7 +331,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcAttrMapName" className="text-start text-md-end col-md-3 col-form-label">{t('Name')}</label>
               <div className="col-md-6">
                 <input
@@ -347,7 +347,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label htmlFor="oidcAttrMapEmail" className="text-start text-md-end col-md-3 col-form-label">{t('Email')}</label>
               <div className="col-md-6">
                 <input
@@ -363,7 +363,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <label className="form-label text-start text-md-end col-md-3 col-form-label">{t('security_settings.callback_URL')}</label>
               <div className="col-md-6">
                 <input
@@ -385,7 +385,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <div className="offset-md-3 col-md-6">
                 <div className="form-check form-check-success">
                   <input
@@ -407,7 +407,7 @@ class OidcSecurityManagementContents extends React.Component {
               </div>
             </div>
 
-            <div className="row mb-5">
+            <div className="row mb-4">
               <div className="offset-md-3 col-md-6">
                 <div className="form-check form-check-success">
                   <input
@@ -452,11 +452,13 @@ class OidcSecurityManagementContents extends React.Component {
             <span className="material-symbols-outlined" aria-hidden="true">help</span>
             <a href="#collapseHelpForOidcOauth" data-bs-toggle="collapse"> {t('security_settings.OAuth.how_to.oidc')}</a>
           </h4>
-          <ol id="collapseHelpForOidcOauth" className="collapse">
-            <li>{t('security_settings.OAuth.OIDC.register_1')}</li>
-            <li>{t('security_settings.OAuth.OIDC.register_2')}</li>
-            <li>{t('security_settings.OAuth.OIDC.register_3')}</li>
-          </ol>
+          <div className=" card custom-card bg-body-tertiary">
+            <ol id="collapseHelpForOidcOauth" className="collapse mb-0">
+              <li>{t('security_settings.OAuth.OIDC.register_1')}</li>
+              <li>{t('security_settings.OAuth.OIDC.register_2')}</li>
+              <li>{t('security_settings.OAuth.OIDC.register_3')}</li>
+            </ol>
+          </div>
         </div>
 
       </>

+ 41 - 45
apps/app/src/components/Admin/Security/SamlSecuritySettingContents.jsx

@@ -64,7 +64,7 @@ class SamlSecurityManagementContents extends React.Component {
           />
         )}
 
-        <div className="row mb-5">
+        <div className="row mt-4 mb-5">
           <div className="col-6 offset-3">
             <div className="form-check form-switch form-check-success">
               <input
@@ -80,7 +80,7 @@ class SamlSecurityManagementContents extends React.Component {
               </label>
             </div>
             {(!adminGeneralSecurityContainer.state.setupStrategies.includes('saml') && isSamlEnabled)
-              && <div className="badge bg-warning text-dark">{t('security_settings.setup_is_not_yet_complete')}</div>}
+              && <div className="badge text-bg-warning">{t('security_settings.setup_is_not_yet_complete')}</div>}
           </div>
         </div>
 
@@ -112,7 +112,7 @@ class SamlSecurityManagementContents extends React.Component {
             {(adminSamlSecurityContainer.state.missingMandatoryConfigKeys.length !== 0) && (
               <div className="alert alert-danger">
                 {t('security_settings.missing mandatory configs')}
-                <ul>
+                <ul className="mb-0">
                   {adminSamlSecurityContainer.state.missingMandatoryConfigKeys.map((configKey) => {
                     const key = configKey.replace('security:passport-saml:', '');
                     return <li key={configKey}>{t(`security_settings.form_item_name.${key}`)}</li>;
@@ -122,7 +122,7 @@ class SamlSecurityManagementContents extends React.Component {
             )}
 
 
-            <h3 className="alert-anchor border-bottom">
+            <h3 className="alert-anchor border-bottom mb-3">
               Basic Settings
             </h3>
 
@@ -232,7 +232,7 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
               </tbody>
             </table>
 
-            <h3 className="alert-anchor border-bottom">
+            <h3 className="alert-anchor border-bottom mt-5 mb-3">
               Attribute Mapping
             </h3>
 
@@ -386,55 +386,51 @@ pWVdnzS1VCO8fKsJ7YYIr+JmHvseph3kFUOI5RqkCcMZlKUv83aUThsTHw==
               </tbody>
             </table>
 
-            <h3 className="alert-anchor border-bottom">
+            <h3 className="alert-anchor border-bottom mt-5 mb-4">
               Attribute Mapping Options
             </h3>
 
-            <div className="row mb-5">
-              <div className="offset-md-3 col-md-6 text-start">
-                <div className="form-check form-check-success">
-                  <input
-                    id="bindByUserName-SAML"
-                    className="form-check-input"
-                    type="checkbox"
-                    checked={adminSamlSecurityContainer.state.isSameUsernameTreatedAsIdenticalUser || false}
-                    onChange={() => { adminSamlSecurityContainer.switchIsSameUsernameTreatedAsIdenticalUser() }}
-                  />
-                  <label
-                    className="form-label form-check-label"
-                    htmlFor="bindByUserName-SAML"
-                    dangerouslySetInnerHTML={{ __html: t('security_settings.Treat username matching as identical') }}
-                  />
-                </div>
-                <p className="form-text text-muted">
-                  <small dangerouslySetInnerHTML={{ __html: t('security_settings.Treat username matching as identical_warn') }} />
-                </p>
+            <div className="row ms-3">
+              <div className="form-check form-check-success">
+                <input
+                  id="bindByUserName-SAML"
+                  className="form-check-input"
+                  type="checkbox"
+                  checked={adminSamlSecurityContainer.state.isSameUsernameTreatedAsIdenticalUser || false}
+                  onChange={() => { adminSamlSecurityContainer.switchIsSameUsernameTreatedAsIdenticalUser() }}
+                />
+                <label
+                  className="form-label form-check-label"
+                  htmlFor="bindByUserName-SAML"
+                  dangerouslySetInnerHTML={{ __html: t('security_settings.Treat username matching as identical') }}
+                />
               </div>
+              <p className="form-text text-muted">
+                <small dangerouslySetInnerHTML={{ __html: t('security_settings.Treat username matching as identical_warn') }} />
+              </p>
             </div>
 
-            <div className="row mb-5">
-              <div className="offset-md-3 col-md-6 text-start">
-                <div className="form-check form-check-success">
-                  <input
-                    id="bindByEmail-SAML"
-                    className="form-check-input"
-                    type="checkbox"
-                    checked={adminSamlSecurityContainer.state.isSameEmailTreatedAsIdenticalUser || false}
-                    onChange={() => { adminSamlSecurityContainer.switchIsSameEmailTreatedAsIdenticalUser() }}
-                  />
-                  <label
-                    className="form-label form-check-label"
-                    htmlFor="bindByEmail-SAML"
-                    dangerouslySetInnerHTML={{ __html: t('security_settings.Treat email matching as identical') }}
-                  />
-                </div>
-                <p className="form-text text-muted">
-                  <small dangerouslySetInnerHTML={{ __html: t('security_settings.Treat email matching as identical_warn') }} />
-                </p>
+            <div className="row mb-5 ms-3">
+              <div className="form-check form-check-success">
+                <input
+                  id="bindByEmail-SAML"
+                  className="form-check-input"
+                  type="checkbox"
+                  checked={adminSamlSecurityContainer.state.isSameEmailTreatedAsIdenticalUser || false}
+                  onChange={() => { adminSamlSecurityContainer.switchIsSameEmailTreatedAsIdenticalUser() }}
+                />
+                <label
+                  className="form-label form-check-label"
+                  htmlFor="bindByEmail-SAML"
+                  dangerouslySetInnerHTML={{ __html: t('security_settings.Treat email matching as identical') }}
+                />
               </div>
+              <p className="form-text text-muted">
+                <small dangerouslySetInnerHTML={{ __html: t('security_settings.Treat email matching as identical_warn') }} />
+              </p>
             </div>
 
-            <h3 className="alert-anchor border-bottom">
+            <h3 className="alert-anchor border-bottom mb-4">
               Attribute-based Login Control
             </h3>
 

+ 3 - 3
apps/app/src/components/Admin/Security/SecurityManagementContents.jsx

@@ -75,8 +75,8 @@ const SecurityManagementContents = () => {
 
       {/* XSS configuration link */}
       <div className="mb-5">
-        <h2 className="border-bottom">{t('security_settings.xss_prevent_setting')}</h2>
-        <div className="text-center">
+        <h2 className="border-bottom pb-2">{t('security_settings.xss_prevent_setting')}</h2>
+        <div className="mt-4">
           <Link
             href="/admin/markdown/#preventXSS"
             style={{ fontSize: 'large' }}
@@ -87,7 +87,7 @@ const SecurityManagementContents = () => {
       </div>
 
       <div className="auth-mechanism-configurations">
-        <h2 className="border-bottom">{t('security_settings.Authentication mechanism settings')}</h2>
+        <h2 className="border-bottom pb-2">{t('security_settings.Authentication mechanism settings')}</h2>
         <CustomNav
           activeTab={activeTab}
           navTabMapping={navTabMapping}

+ 12 - 12
apps/app/src/components/Admin/Security/SecuritySetting.jsx

@@ -252,7 +252,7 @@ class SecuritySetting extends React.Component {
     return (
       <div key={`page-delete-permission-dropdown-${deletionType}`} className="row">
 
-        <div className="col-md-3 text-md-end">
+        <div className="col-md-4 text-md-end">
           {!isRecursiveDeletion(deletionType) && isTypeDeletion(deletionType) && (
             <strong>{t('security_settings.page_delete')}</strong>
           )}
@@ -261,7 +261,7 @@ class SecuritySetting extends React.Component {
           )}
         </div>
 
-        <div className="col-md-6">
+        <div className="col-md-8">
           {
             !isRecursiveDeletion(deletionType)
               ? (
@@ -301,7 +301,7 @@ class SecuritySetting extends React.Component {
                   </button>
                   <Collapse isOpen={expantDeleteOptionsState}>
                     <div className="pb-4">
-                      <p className="card custom-card">
+                      <p className="card custom-card bg-warning-sublte">
                         <span className="text-warning">
                           <span className="material-symbols-outlined">info</span>
                           {/* eslint-disable-next-line react/no-danger */}
@@ -412,12 +412,12 @@ class SecuritySetting extends React.Component {
           </table>
         </div>
 
-        <h4>{t('security_settings.page_access_rights')}</h4>
+        <h4 className="mb-3">{t('security_settings.page_access_rights')}</h4>
         <div className="row mb-4">
-          <div className="col-md-3 text-md-end py-2">
+          <div className="col-md-4 text-md-end py-2">
             <strong>{t('security_settings.Guest Users Access')}</strong>
           </div>
-          <div className="col-md-9">
+          <div className="col-md-8">
             <div className="dropdown">
               <button
                 className={`btn btn-outline-secondary dropdown-toggle text-end col-12
@@ -457,7 +457,7 @@ class SecuritySetting extends React.Component {
           </div>
         </div>
 
-        <h4>{t('security_settings.page_delete_rights')}</h4>
+        <h4 className="mb-3">{t('security_settings.page_delete_rights')}</h4>
         {/* Render PageDeletePermission */}
         {
           [
@@ -474,9 +474,9 @@ class SecuritySetting extends React.Component {
           ].map(arr => this.renderPageDeletePermission(arr[0], arr[1], arr[2], arr[3]))
         }
 
-        <h4>{t('security_settings.user_homepage_deletion.user_homepage_deletion')}</h4>
+        <h4 className="mb-3">{t('security_settings.user_homepage_deletion.user_homepage_deletion')}</h4>
         <div className="row mb-4">
-          <div className="col-6 offset-3">
+          <div className="col-md-10 offset-md-2">
             <div className="form-check form-switch form-check-success">
               <input
                 type="checkbox"
@@ -512,9 +512,9 @@ class SecuritySetting extends React.Component {
         <h4>{t('security_settings.session')}</h4>
         <div className="row">
           <label className="text-start text-md-end col-md-3 col-form-label">{t('security_settings.max_age')}</label>
-          <div className="col-md-6">
+          <div className="col-md-8">
             <input
-              className="form-control col-md-3"
+              className="form-control col-md-4"
               type="text"
               defaultValue={adminGeneralSecurityContainer.state.sessionMaxAge || ''}
               onChange={(e) => {
@@ -524,7 +524,7 @@ class SecuritySetting extends React.Component {
             />
             {/* eslint-disable-next-line react/no-danger */}
             <p className="form-text text-muted" dangerouslySetInnerHTML={{ __html: t('security_settings.max_age_desc') }} />
-            <p className="card custom-card">
+            <p className="card custom-card bg-warning-subtle">
               <span className="text-warning">
                 <span className="material-symbols-outlined">info</span> {t('security_settings.max_age_caution')}
               </span>

+ 11 - 12
apps/app/src/components/Admin/Security/ShareLinkSetting.tsx

@@ -102,19 +102,9 @@ const ShareLinkSetting = (props: ShareLinkSettingProps) => {
 
   return (
     <>
-      <div className="mb-3">
-        <button
-          className="pull-right btn btn-danger"
-          disabled={shareLinks.length === 0}
-          type="button"
-          onClick={() => setIsDeleteConfirmModalShown(true)}
-        >
-          {t('security_settings.delete_all_share_links')}
-        </button>
-        <h2 className="alert-anchor border-bottom">{t('security_settings.share_link_management')}</h2>
-      </div>
+      <h2 className="alert-anchor border-bottom mb-4">{t('security_settings.share_link_management')}</h2>
       <h4>{t('security_settings.share_link_rights')}</h4>
-      <div className="row mb-5">
+      <div className="row mt-4 mb-5">
         <div className="col-6 offset-3">
           <div className="form-check form-switch form-check-success">
             <input
@@ -154,6 +144,15 @@ const ShareLinkSetting = (props: ShareLinkSettingProps) => {
         )
       }
 
+      <button
+        className="pull-right btn btn-danger mt-2"
+        disabled={shareLinks.length === 0}
+        type="button"
+        onClick={() => setIsDeleteConfirmModalShown(true)}
+      >
+        {t('security_settings.delete_all_share_links')}
+      </button>
+
       <DeleteAllShareLinksModal
         isOpen={isDeleteConfirmModalShown}
         onClose={() => setIsDeleteConfirmModalShown(false)}

+ 9 - 9
apps/app/src/components/Admin/UserGroup/UserGroupForm.tsx

@@ -74,18 +74,18 @@ export const UserGroupForm: FC<Props> = (props: Props) => {
         )}
         {
           userGroup?.createdAt != null && (
-            <div className="row">
+            <div className="row mb-3">
               <p className="col-md-2 col-form-label">{t('Created')}</p>
-              <p className="col-md-4 my-auto">{dateFnsFormat(new Date(userGroup.createdAt), 'yyyy-MM-dd')}</p>
+              <p className="col-md-6 my-auto">{dateFnsFormat(new Date(userGroup.createdAt), 'yyyy-MM-dd')}</p>
             </div>
           )
         }
 
-        <div className="row">
+        <div className="row mb-3">
           <label htmlFor="name" className="col-md-2 col-form-label">
             {t('user_group_management.group_name')}
           </label>
-          <div className="col-md-4 my-auto">
+          <div className="col-md-6 my-auto">
             <input
               className="form-control"
               type="text"
@@ -99,20 +99,20 @@ export const UserGroupForm: FC<Props> = (props: Props) => {
           </div>
         </div>
 
-        <div className="row">
+        <div className="row mb-3">
           <label htmlFor="description" className="col-md-2 col-form-label">
             {t('Description')}
           </label>
-          <div className="col-md-4">
+          <div className="col-md-6">
             <textarea className="form-control" name="description" value={currentDescription} onChange={onChangeDescriptionHandler} />
           </div>
         </div>
 
-        <div className="row">
+        <div className="row mb-3">
           <label htmlFor="parent" className="col-md-2 col-form-label">
             {t('user_group_management.parent_group')}
           </label>
-          <div className="dropdown col-md-4">
+          <div className="dropdown col-md-6">
             <button
               type="button"
               id="dropdownMenuButton"
@@ -154,7 +154,7 @@ export const UserGroupForm: FC<Props> = (props: Props) => {
           </div>
         </div>
 
-        <div className="row">
+        <div className="row mb-5">
           <div className="offset-md-2 col-md-10">
             <button type="submit" className="btn btn-primary">
               {submitButtonLabel}

+ 3 - 3
apps/app/src/components/Admin/UserGroup/UserGroupTable.tsx

@@ -138,7 +138,7 @@ export const UserGroupTable: FC<Props> = ({
   }, [userGroupRelations, childUserGroups]);
 
   return (
-    <div data-testid="grw-user-group-table">
+    <div data-testid="grw-user-group-table" className="mb-5">
       <h3>{headerLabel}</h3>
 
       <table className="table table-bordered table-user-list">
@@ -179,7 +179,7 @@ export const UserGroupTable: FC<Props> = ({
                 <td>
                   <ul className="list-inline">
                     {users != null && users.map((user) => {
-                      return <li key={user._id} className="list-inline-item badge rounded-pill bg-warning text-dark">{user.username}</li>;
+                      return <li key={user._id} className="list-inline-item badge text-bg-warning">{user.username}</li>;
                     })}
                   </ul>
                 </td>
@@ -187,7 +187,7 @@ export const UserGroupTable: FC<Props> = ({
                   <ul className="list-inline">
                     {groupIdToChildGroupsMap[group._id] != null && groupIdToChildGroupsMap[group._id].map((group) => {
                       return (
-                        <li key={group._id} className="list-inline-item badge badge-success">
+                        <li key={group._id} className="list-inline-item badge text-bg-success">
                           {isAclEnabled
                             ? (
                               <Link href={`/admin/user-group-detail/${group._id}?isExternalGroup=${isExternalGroup}`}>{group.name}</Link>

+ 1 - 1
apps/app/src/components/Admin/UserGroupDetail/UserGroupUserTable.tsx

@@ -17,7 +17,7 @@ export const UserGroupUserTable = (props: Props): JSX.Element => {
   const { t } = useTranslation('admin');
 
   return (
-    <table className="table table-bordered table-user-list">
+    <table className="table table-bordered table-user-list mb-5">
       <thead>
         <tr>
           <th style={{ width: '100px' }}>#</th>

+ 2 - 1
apps/app/src/components/Admin/UserManagement.module.scss

@@ -1,9 +1,10 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 // styles for admin user search
 .search-typeahead :global {
   position: relative;
   width: 100%;
+
   // corner radius
   border-top-right-radius: bs.$border-radius;
   border-bottom-right-radius: bs.$border-radius;

+ 1 - 1
apps/app/src/components/AuthorInfo/AuthorInfo.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 $author-font-size: 12px;
 $date-font-size: 11px;

+ 1 - 1
apps/app/src/components/Bookmarks/BookmarkFolderMenu.tsx

@@ -67,7 +67,7 @@ export const BookmarkFolderMenu = (props: BookmarkFolderMenuProps): JSX.Element
     if (isOpen && bookmarkFolders != null) {
       bookmarkFolders.forEach((bookmarkFolder) => {
         bookmarkFolder.bookmarks.forEach((bookmark) => {
-          if (bookmark.page._id === pageId) {
+          if (bookmark.page?._id === pageId) {
             setSelectedItem(bookmarkFolder._id);
           }
         });

+ 1 - 2
apps/app/src/components/Bookmarks/BookmarkFolderTree.tsx

@@ -121,9 +121,8 @@ export const BookmarkFolderTree: React.FC<Props> = (props: Props) => {
           );
         })}
         {userBookmarks?.map(userBookmark => (
-          <div key={userBookmark._id} className="grw-foldertree-item-container grw-root-bookmarks">
+          <div key={userBookmark?._id} className="grw-foldertree-item-container grw-root-bookmarks">
             <BookmarkItem
-              key={userBookmark._id}
               isReadOnlyUser={!!isReadOnlyUser}
               isOperable={props.isOperable}
               bookmarkedPage={userBookmark}

+ 24 - 8
apps/app/src/components/Bookmarks/BookmarkItem.tsx

@@ -28,7 +28,7 @@ import { DragAndDropWrapper } from './DragAndDropWrapper';
 type Props = {
   isReadOnlyUser: boolean
   isOperable: boolean,
-  bookmarkedPage: IPageHasId,
+  bookmarkedPage: IPageHasId | null,
   level: number,
   parentFolder: BookmarkFolderItems | null,
   canMoveToRoot: boolean,
@@ -50,17 +50,17 @@ export const BookmarkItem = (props: Props): JSX.Element => {
   const { open: openPutBackPageModal } = usePutBackPageModal();
   const [isRenameInputShown, setRenameInputShown] = useState(false);
 
-  const { data: pageInfo, mutate: mutatePageInfo } = useSWRxPageInfo(bookmarkedPage._id);
+  const { data: pageInfo, mutate: mutatePageInfo } = useSWRxPageInfo(bookmarkedPage?._id);
   const { trigger: mutateCurrentPage } = useSWRMUTxCurrentPage();
-  const dPagePath = new DevidedPagePath(bookmarkedPage.path, false, true);
-  const { latter: pageTitle, former: formerPagePath } = dPagePath;
-  const bookmarkItemId = `bookmark-item-${bookmarkedPage._id}`;
+
   const paddingLeft = BASE_BOOKMARK_PADDING + (BASE_FOLDER_PADDING * (level));
   const dragItem: Partial<DragItemDataType> = {
     ...bookmarkedPage, parentFolder,
   };
 
   const onClickMoveToRootHandler = useCallback(async() => {
+    if (bookmarkedPage == null) return;
+
     try {
       await addBookmarkToFolder(bookmarkedPage._id, null);
       bookmarkFolderTreeMutation();
@@ -68,7 +68,7 @@ export const BookmarkItem = (props: Props): JSX.Element => {
     catch (err) {
       toastError(err);
     }
-  }, [bookmarkFolderTreeMutation, bookmarkedPage._id]);
+  }, [bookmarkFolderTreeMutation, bookmarkedPage]);
 
   const bookmarkMenuItemClickHandler = useCallback(async(pageId: string, shouldBookmark: boolean) => {
     if (shouldBookmark) {
@@ -90,6 +90,9 @@ export const BookmarkItem = (props: Props): JSX.Element => {
   }, []);
 
   const rename = useCallback(async(inputText: string) => {
+    if (bookmarkedPage == null) return;
+
+
     if (inputText.trim() === '') {
       return cancel();
     }
@@ -111,9 +114,11 @@ export const BookmarkItem = (props: Props): JSX.Element => {
       setRenameInputShown(true);
       toastError(err);
     }
-  }, [bookmarkedPage.path, bookmarkedPage._id, bookmarkedPage.revision, cancel, bookmarkFolderTreeMutation, mutatePageInfo]);
+  }, [bookmarkedPage, cancel, bookmarkFolderTreeMutation, mutatePageInfo]);
 
   const deleteMenuItemClickHandler = useCallback(async(_pageId: string, pageInfo: IPageInfoAll | undefined): Promise<void> => {
+    if (bookmarkedPage == null) return;
+
     if (bookmarkedPage._id == null || bookmarkedPage.path == null) {
       throw Error('_id and path must not be null.');
     }
@@ -128,9 +133,11 @@ export const BookmarkItem = (props: Props): JSX.Element => {
     };
 
     onClickDeleteMenuItemHandler(pageToDelete);
-  }, [bookmarkedPage._id, bookmarkedPage.path, bookmarkedPage.revision, onClickDeleteMenuItemHandler]);
+  }, [bookmarkedPage, onClickDeleteMenuItemHandler]);
 
   const putBackClickHandler = useCallback(() => {
+    if (bookmarkedPage == null) return;
+
     const { _id: pageId, path } = bookmarkedPage;
     const putBackedHandler = async() => {
       try {
@@ -148,6 +155,15 @@ export const BookmarkItem = (props: Props): JSX.Element => {
     openPutBackPageModal({ pageId, path }, { onPutBacked: putBackedHandler });
   }, [bookmarkedPage, openPutBackPageModal, bookmarkFolderTreeMutation, router, mutateCurrentPage, t]);
 
+  if (bookmarkedPage == null) {
+    return <></>;
+  }
+
+  const dPagePath = new DevidedPagePath(bookmarkedPage.path, false, true);
+  const { latter: pageTitle, former: formerPagePath } = dPagePath;
+
+  const bookmarkItemId = `bookmark-item-${bookmarkedPage._id}`;
+
   return (
     <DragAndDropWrapper
       item={dragItem}

+ 1 - 2
apps/app/src/components/Common/CopyDropdown/CopyDropdown.module.scss

@@ -1,5 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
 
 .grw-copy-dropdown :global {

+ 1 - 3
apps/app/src/components/Common/DrawerToggler/DrawerToggler.module.scss

@@ -1,5 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '~/styles/variables' as var;
 
 
@@ -7,7 +6,6 @@
   .btn {
     --bs-btn-color: rgba(var(--bs-tertiary-color-rgb), 0.5);
     --bs-btn-bg: transparent;
-
     --bs-btn-hover-color: rgba(var(--bs-tertiary-color-rgb), 0.7);
 
     width: var.$grw-sidebar-nav-width;

+ 1 - 1
apps/app/src/components/Common/PagePathHierarchicalLink/CollapsedParentsDropdown.module.scss

@@ -1,5 +1,5 @@
 
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .collapsed-parents-dropdown-menu {
   --bs-dropdown-zindex: #{bs.$zindex-fixed};

+ 1 - 2
apps/app/src/components/Common/PagePathNav/PagePathNav.module.scss

@@ -1,5 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
 
 .grw-mx-02em {

+ 1 - 1
apps/app/src/components/Common/PagePathNav/PagePathNav.tsx

@@ -98,7 +98,7 @@ export const PagePathNav = (props: Props): JSX.Element => {
         { pageId != null && !isNotFound && (
           <div className="d-flex align-items-center ms-2">
             { isWipPage && (
-              <span className="badge rounded-pill text-bg-secondary ms-1 me-1">WIP</span>
+              <span className="badge text-bg-secondary ms-1 me-1">WIP</span>
             )}
             <CopyDropdown pageId={pageId} pagePath={pagePath} dropdownToggleId={copyDropdownId} dropdownToggleClassName="p-2">
               <span className="material-symbols-outlined">content_paste</span>

+ 3 - 2
apps/app/src/components/Common/PageViewLayout.module.scss

@@ -1,5 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '~/styles/mixins';
 @use '~/styles/variables' as var;
 
@@ -9,6 +8,7 @@ $page-view-layout-margin-top: 32px;
 
 .page-view-layout :global {
   $page-content-footer-min-heigh: 130px;
+
   min-height: calc(100vh - #{$subnavigation-height + $page-view-layout-margin-top + $page-content-footer-min-heigh});
 }
 
@@ -42,6 +42,7 @@ $page-view-layout-margin-top: 32px;
     position: sticky;
 
     $page-path-nav-height: 99px;
+
     top: calc($subnavigation-height + $page-view-layout-margin-top + $page-path-nav-height + 4px);
   }
 }

+ 2 - 2
apps/app/src/components/CustomNavigation/CustomNav.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .grw-custom-nav-tab :global {
   .nav-title {
@@ -10,7 +10,7 @@
   }
 
   .grw-nav-slide-hr {
-    border-top: 0rem;
+    border-top: 0;
     border-bottom: 3px solid;
     transition: 0.3s ease-in-out;
   }

+ 2 - 2
apps/app/src/components/DescendantsPageListModal.module.scss

@@ -1,7 +1,7 @@
 .grw-descendants-page-list-modal :global {
   .modal-header {
     button.btn-close {
-      margin: auto 0rem auto auto;
+      margin: auto 0 auto auto;
     }
   }
 
@@ -13,6 +13,6 @@
     max-height: calc(100vh - 100px);
   }
   ul.pagination {
-    margin-bottom: 0rem;
+    margin-bottom: 0;
   }
 }

+ 1 - 1
apps/app/src/components/Icons/GrowiLogo.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/growi-official-colors';
+@use '@growi/core-styles/scss/variables/growi-official-colors';
 
 // == Colors
 .grw-logo :global {

+ 4 - 0
apps/app/src/components/ItemsTree/ItemsTree.module.scss

@@ -0,0 +1,4 @@
+/* stylelint-disable-next-line block-no-empty */
+.items-tree :global {
+
+}

+ 2 - 0
apps/app/src/components/ItemsTree/ItemsTreeContentSkeleton.module.scss

@@ -2,10 +2,12 @@
 
 .text-skeleton-level1 {
   @include mixins.grw-skeleton-text($font-size:16px, $line-height: 40px);
+
   padding-left: 12px;
 }
 
 .text-skeleton-level2 {
   @extend .text-skeleton-level1;
+
   padding-left: 12px + 10px * 2;
 }

+ 12 - 2
apps/app/src/components/Layout/Admin.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as *;
+@use '@growi/core-styles/scss/bootstrap/init' as *;
 @use '~/styles/mixins';
 
 $slack-work-space-name-card-background: #fff5ff;
@@ -34,9 +34,17 @@ $slack-work-space-name-card-border: #efc1f6;
   }
 
   .admin-setting-header {
+    margin-bottom: 20px;
     border-bottom: 1px solid transparent;
   }
 
+  .custom-card {
+    padding: 8px 16px;
+    ul {
+      margin-bottom: 0;
+    }
+  }
+
   .admin-security {
     .passport-logo {
       height: 32px;
@@ -106,6 +114,7 @@ $slack-work-space-name-card-border: #efc1f6;
       border-width: 2px;
     }
   }
+
   // TODO: change to utility class on Bootstrap 5
   .slack-connection-log {
     .slack-connection-log-title {
@@ -165,6 +174,7 @@ $slack-work-space-name-card-border: #efc1f6;
       &.with-proxy {
         .hr-container {
           margin-top: 40px;
+
           @include media-breakpoint-up(lg) {
             margin-top: 65px;
           }
@@ -181,7 +191,7 @@ $slack-work-space-name-card-border: #efc1f6;
   //// TODO: migrate to Bootstrap 4
   //// omit all .btn-toggle and use Switches
   //// https://getbootstrap.com/docs/4.2/components/forms/#switches
-  //
+
   // Toggle Twitter Bootstrap button class when active
   // https://jsfiddle.net/ms040m01/3/
   // @mixin active-color($color, $bg-color, $border-color) {

+ 3 - 3
apps/app/src/components/Layout/AdminLayout.tsx

@@ -31,7 +31,7 @@ const AdminLayout = ({
     <RawLayout>
       <div className={`admin-page ${styles['admin-page']}`}>
 
-        <header className="py-0 container-fluid">
+        <header className="py-0 container">
           <h1 className="p-3 fs-2 d-flex align-items-center">
             <Link href="/" className="d-block mb-1 me-2">
               <GrowiLogo />
@@ -40,12 +40,12 @@ const AdminLayout = ({
           </h1>
         </header>
         <div className="main">
-          <div className="container-fluid">
+          <div className="container">
             <div className="row">
               <div className="col-lg-3">
                 <AdminNavigation />
               </div>
-              <div className="col-lg-9">
+              <div className="col-lg-9 mb-5">
                 {children}
               </div>
             </div>

+ 28 - 0
apps/app/src/components/Layout/BasicLayout.module.scss

@@ -0,0 +1,28 @@
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
+@use '~/styles/mixins';
+
+
+// for react-toastify
+.grw-basic-layout :global {
+  .Toastify .Toastify__toast-container {
+    top: 2.5em;
+
+    @include bs.media-breakpoint-down(md) {
+      top: 6.5em;
+    }
+  }
+}
+
+.grw-basic-layout {
+  @include mixins.with-editing() {
+    .Toastify .Toastify__toast-container {
+      top: 5em;
+
+      @include bs.media-breakpoint-down(md) {
+        top: 7em;
+      }
+    }
+  }
+}
+
+

+ 7 - 1
apps/app/src/components/Layout/BasicLayout.tsx

@@ -9,6 +9,12 @@ import { Sidebar } from '../Sidebar';
 
 import { RawLayout } from './RawLayout';
 
+
+import styles from './BasicLayout.module.scss';
+
+const moduleClass = styles['grw-basic-layout'] ?? '';
+
+
 const AlertSiteUrlUndefined = dynamic(() => import('../AlertSiteUrlUndefined').then(mod => mod.AlertSiteUrlUndefined), { ssr: false });
 const DeleteAttachmentModal = dynamic(() => import('../PageAttachment/DeleteAttachmentModal').then(mod => mod.DeleteAttachmentModal), { ssr: false });
 const HotkeysManager = dynamic(() => import('../Hotkeys/HotkeysManager'), { ssr: false });
@@ -35,7 +41,7 @@ type Props = {
 
 export const BasicLayout = ({ children, className }: Props): JSX.Element => {
   return (
-    <RawLayout className={`${className ?? ''}`}>
+    <RawLayout className={`${moduleClass} ${className ?? ''}`}>
       <DndProvider backend={HTML5Backend}>
 
         <div className="page-wrapper flex-row">

+ 17 - 13
apps/app/src/components/Layout/NoLoginLayout.module.scss

@@ -1,10 +1,17 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-@use '@growi/core/scss/growi-official-colors' as var;
+/* stylelint-disable scss/no-global-function-names */
+
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/variables/growi-official-colors' as var;
 
 
 .nologin :global {
   height: 100vh;
 
+  .nologin-header,
+  .nologin-dialog {
+    max-width: 480px;
+  }
+
   // layout
   .main {
     width: 100vw;
@@ -54,11 +61,6 @@
     }
   }
 
-  .nologin-header,
-  .nologin-dialog {
-    max-width: 480px;
-  }
-
 }
 
 .link-switch {
@@ -80,9 +82,10 @@
   .nologin :global {
     // background color
     $color-gradient: #3c465c;
-    background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
-      linear-gradient(135deg, var.$growi-green 10%, hsla(225, 95%, 50%, 0) 70%), linear-gradient(225deg, var.$growi-blue 10%, hsla(140, 90%, 50%, 0) 80%),
-      linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+
+    background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340deg, 100%, 55%, 0%) 70%),
+      linear-gradient(135deg, var.$growi-green 10%, hsla(225deg, 95%, 50%, 0%) 70%), linear-gradient(225deg, var.$growi-blue 10%, hsla(140deg, 90%, 50%, 0%) 80%),
+      linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35deg, 95%, 55%, 0%) 70%);
 
     .nologin-header {
       background-color: rgba(white, 0.3);
@@ -134,9 +137,10 @@
   .nologin :global {
     // background color
     $color-gradient: #3c465c;
-    background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340, 100%, 55%, 0) 70%),
-      linear-gradient(135deg, var.$growi-green 10%, hsla(225, 95%, 50%, 0) 70%), linear-gradient(225deg, var.$growi-blue 10%, hsla(140, 90%, 50%, 0) 80%),
-      linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35, 95%, 55%, 0) 70%);
+
+    background: linear-gradient(45deg, darken($color-gradient, 30%) 0%, hsla(340deg, 100%, 55%, 0%) 70%),
+      linear-gradient(135deg, var.$growi-green 10%, hsla(225deg, 95%, 50%, 0%) 70%), linear-gradient(225deg, var.$growi-blue 10%, hsla(140deg, 90%, 50%, 0%) 80%),
+      linear-gradient(315deg, darken($color-gradient, 25%) 100%, hsla(35deg, 95%, 55%, 0%) 70%);
 
     .nologin-header {
       background-color: rgba(black, 0.3);

+ 1 - 1
apps/app/src/components/Layout/SearchResultLayout.module.scss

@@ -1,5 +1,5 @@
 @use '~/styles/variables' as var;
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .on-search :global {
   .page-wrapper {

+ 3 - 4
apps/app/src/components/LoginForm/LoginForm.module.scss

@@ -1,5 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '~/styles/atoms/placeholders/buttons';
 
 .login-form :global {
@@ -24,8 +23,8 @@
   }
 
   .text-line {
-    &:before,
-    &:after {
+    &::before,
+    &::after {
       flex-grow: 1;
       height: 1px;
       margin:0 1em;

+ 0 - 0
apps/app/src/components/Me/ColorModeSettings.module.scss


+ 0 - 2
apps/app/src/components/Me/ColorModeSettings.tsx

@@ -4,8 +4,6 @@ import { useTranslation } from 'react-i18next';
 
 import { Themes, useNextThemes } from '~/stores/use-next-themes';
 
-// import styles from './ColorModeSettings.module.scss';
-
 
 type ColorModeSettingsButtonProps = {
   isActive: boolean,

+ 1 - 1
apps/app/src/components/Me/UISettings.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .grw-sidebar-mode-icon {
   display: flex;

+ 2 - 2
apps/app/src/components/Navbar/GrowiContextualSubNavigation.module.scss

@@ -1,5 +1,5 @@
 @use '~/styles/mixins';
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .grw-contextual-sub-navigation {
   @include bs.media-breakpoint-down(md) {
@@ -9,7 +9,7 @@
   }
 }
 
-@include mixins.editing() {
+@include mixins.at-editing() {
   .grw-contextual-sub-navigation {
     position: fixed;
     right: 0;

+ 1 - 0
apps/app/src/components/Navbar/GrowiNavbarBottom.module.scss

@@ -4,6 +4,7 @@
 .grw-navbar-bottom :global {
   // apply transition
   transition-property: bottom;
+
   @include mixins.apply-navigation-transition();
 
   .navbar {

+ 3 - 1
apps/app/src/components/Navbar/PageEditorModeManager.module.scss

@@ -1,5 +1,5 @@
 // @mixin page-editor-mode-manager($textColor, $borderColor, $bgColorHoverAndActive, $bgColor: white) {
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '~/styles/mixins';
 
 .grw-page-editor-mode-manager :global {
@@ -20,6 +20,7 @@
 .grw-page-editor-mode-manager-skeleton :global {
   width: 90px;
   height: 38px;
+
   @include bs.media-breakpoint-up(md) {
     width: 179px;
     height: 30px;
@@ -47,6 +48,7 @@
     }
   }
 }
+
 @include bs.color-mode(dark) {
   .grw-page-editor-mode-manager :global {
     .btn {

+ 2 - 2
apps/app/src/components/PageAccessoriesModal/PageAccessoriesModal.module.scss

@@ -1,7 +1,7 @@
 .grw-page-accessories-modal :global {
   .modal-header {
     button.btn-close {
-      margin: auto 0rem auto auto;
+      margin: auto 0 auto auto;
     }
   }
 
@@ -13,6 +13,6 @@
     max-height: calc(100vh - 100px);
   }
   ul.pagination {
-    margin-bottom: 0rem;
+    margin-bottom: 0;
   }
 }

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

@@ -52,8 +52,8 @@ const ShareLinkTr = (props: ShareLinkTrProps): JSX.Element => {
       <td style={{ verticalAlign: 'middle' }}>
         {shareLink.expiredAt && <span>{dateFnsFormat(new Date(shareLink.expiredAt), 'yyyy-MM-dd HH:mm')}</span>}
       </td>
-      <td style={{ maxWidth: '0', textAlign: 'center' }}>
-        <button className="btn btn-outline-warning" type="button" onClick={onDelete}>
+      <td style={{ maxWidth: '50', textAlign: 'center' }}>
+        <button className="btn btn-outline-danger" type="button" onClick={onDelete}>
           <span className="material-symbols-outlined">delete</span>{t('Delete')}
         </button>
       </td>

+ 1 - 1
apps/app/src/components/PageComment.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .page-comment-styles :global {
   .page-comments {

+ 6 - 7
apps/app/src/components/PageComment/Comment.module.scss

@@ -1,14 +1,12 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '../../styles/variables' as var;
-@use './_comment-inheritance';
+@use './comment-inheritance';
 
 .comment-styles :global {
 
   .page-comment {
     position: relative;
     pointer-events: none;
-
     scroll-margin-top: var.$grw-scroll-margin-top-in-view;
 
     // background
@@ -49,8 +47,9 @@
     }
 
     // older comments
-    &.page-comment-older {
-    }
+    // &.page-comment-older {
+    // }
+
     // newer comments
     &.page-comment-newer {
       opacity: 0.7;
@@ -71,7 +70,6 @@
     .page-comment-meta {
       display: flex;
       justify-content: flex-end;
-
       font-size: 0.9em;
       color: bs.$gray-400;
     }
@@ -84,6 +82,7 @@
     height: 66px;
     padding: 1em;
     margin-left: 4.5em;
+
     @include bs.media-breakpoint-down(xs) {
       margin-left: 3.5em;
     }

+ 2 - 3
apps/app/src/components/PageComment/CommentEditor.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use './comment-inheritance';
 @use '../PageEditor/page-editor-inheritance';
 
@@ -31,8 +31,7 @@
     min-height: comment-inheritance.$codemirror-default-height !important;
   }
   .comment-preview-container {
-    min-height: page-editor-inheritance.$navbar-editor-height
-      + comment-inheritance.$codemirror-default-height;
+    min-height: page-editor-inheritance.$navbar-editor-height + comment-inheritance.$codemirror-default-height;
     padding-top: 0.5em;
   }
 }

+ 1 - 0
apps/app/src/components/PageComment/CommentPreview.module.scss

@@ -1,2 +1,3 @@
+/* stylelint-disable-next-line block-no-empty */
 .grw-comment-preview {
 }

+ 1 - 0
apps/app/src/components/PageComment/DeleteCommentModal.module.scss

@@ -3,6 +3,7 @@
   .modal-content .modal-body {
     .comment-body {
       max-height: 13em;
+
       // scrollable
       overflow-y: auto;
     }

+ 2 - 1
apps/app/src/components/PageComment/SwitchingButtonGroup.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 
 .btn-group-switching :global {
@@ -31,6 +31,7 @@
     }
   }
 }
+
 @include bs.color-mode(dark) {
   .btn-group-switching :global {
     .btn {

+ 4 - 4
apps/app/src/components/PageComment/_comment-inheritance.scss

@@ -1,11 +1,11 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 %comment-section {
   position: relative;
   padding: 1em;
 
   // speech balloon
-  &:before {
+  &::before {
     position: absolute;
     top: 1.5em;
     left: -1em;
@@ -32,8 +32,8 @@ $codemirror-default-height: 300px;
 @include bs.color-mode(light) {
   %bg-comment {
     background-color: rgba( bs.$gray-200, 0.5 );
-    border: 1px solid bs.$gray-200;
     backdrop-filter: blur(10px);
+    border: 1px solid bs.$gray-200;
   }
 }
 
@@ -41,7 +41,7 @@ $codemirror-default-height: 300px;
 @include bs.color-mode(dark) {
   %bg-comment {
     background-color: rgba( bs.$gray-800, 0.3 );
-    border: 1px solid bs.$gray-700;
     backdrop-filter: blur(10px);
+    border: 1px solid bs.$gray-700;
   }
 }

+ 2 - 1
apps/app/src/components/PageContentFooter.module.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .page-content-footer :global {
   border-top: solid 1px transparent;
@@ -6,6 +6,7 @@
     font-size: 0.95em;
   }
 }
+
 // TODO: Should Soft Coding see: https://github.com/weseek/growi/pull/6404
 .page-content-footer-skeleton :global {
   width: 300px;

+ 3 - 3
apps/app/src/components/PageControls/BookmarkButtons.module.scss

@@ -1,7 +1,5 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
-
 @use './button-styles';
 
 .btn-group-bookmark :global {
@@ -13,12 +11,14 @@
   }
   .total-counts {
     @extend %btn-total-counts-basis;
+
     padding-left: 5px;
   }
 }
 
 // == Colors
 .btn-group-bookmark :global {
+  /* stylelint-disable-next-line no-descending-specificity */
   .btn-bookmark {
     @include btn-muted.colorize(bs.$orange);
   }

+ 2 - 3
apps/app/src/components/PageControls/LikeButtons.module.scss

@@ -1,7 +1,5 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
-
 @use './button-styles';
 
 .btn-group-like :global {
@@ -13,6 +11,7 @@
   }
   .total-counts {
     @extend %btn-total-counts-basis;
+
     padding-left: 5px;
   }
 }

+ 1 - 3
apps/app/src/components/PageControls/PageControls.module.scss

@@ -1,7 +1,5 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
-
 @use './button-styles';
 
 // PageItemControl styles

+ 15 - 10
apps/app/src/components/PageControls/PageControls.tsx

@@ -66,7 +66,7 @@ const Tags = (props: TagsProps): JSX.Element => {
 };
 
 type WideViewMenuItemProps = AdditionalMenuItemsRendererProps & {
-  onClickMenuItem: (newValue: boolean) => void,
+  onClickMenuItem: () => void,
   expandContentWidth?: boolean,
 }
 
@@ -77,24 +77,27 @@ const WideViewMenuItem = (props: WideViewMenuItemProps): JSX.Element => {
     onClickMenuItem, expandContentWidth,
   } = props;
 
+  const menuItemClickedHandler = useCallback((e: React.MouseEvent<HTMLInputElement>) => {
+    e.preventDefault();
+    onClickMenuItem();
+  }, [onClickMenuItem]);
+
   return (
-    <DropdownItem
-      onClick={() => onClickMenuItem(!(expandContentWidth))}
-      className="grw-page-control-dropdown-item"
+    <div
+      className="grw-page-control-dropdown-item dropdown-item"
+      onClick={menuItemClickedHandler}
     >
       <div className="form-check form-switch ms-1">
         <input
-          id="switchContentWidth"
           className="form-check-input"
           type="checkbox"
           checked={expandContentWidth}
-          onChange={() => {}}
         />
-        <label className="form-label form-check-label" htmlFor="switchContentWidth">
+        <label className="form-label form-check-label">
           { t('wide_view') }
         </label>
       </div>
-    </DropdownItem>
+    </div>
   );
 };
 
@@ -224,7 +227,9 @@ const PageControlsSubstance = (props: PageControlsSubstanceProps): JSX.Element =
     onClickDeleteMenuItem(pageToDelete);
   }, [onClickDeleteMenuItem, pageId, pageInfo, path, revisionId]);
 
-  const switchContentWidthClickHandler = useCallback(async(newValue: boolean) => {
+  const switchContentWidthClickHandler = useCallback(() => {
+
+    const newValue = !expandContentWidth;
     if (onClickSwitchContentWidth == null || (isGuestUser ?? true) || (isReadOnlyUser ?? true)) {
       logger.warn('Could not switch content width', {
         onClickSwitchContentWidth: onClickSwitchContentWidth == null ? 'null' : 'not null',
@@ -242,7 +247,7 @@ const PageControlsSubstance = (props: PageControlsSubstanceProps): JSX.Element =
     catch (err) {
       toastError(err);
     }
-  }, [isGuestUser, isReadOnlyUser, onClickSwitchContentWidth, pageId, pageInfo]);
+  }, [expandContentWidth, isGuestUser, isReadOnlyUser, onClickSwitchContentWidth, pageId, pageInfo]);
 
   const additionalMenuItemOnTopRenderer = useMemo(() => {
     if (!isIPageInfoForEntity(pageInfo)) {

+ 1 - 3
apps/app/src/components/PageControls/SearchButton.module.scss

@@ -1,7 +1,5 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
-
 @use './button-styles';
 
 .btn-search :global {

+ 1 - 3
apps/app/src/components/PageControls/SeenUserInfo.module.scss

@@ -1,7 +1,5 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
-
 @use './button-styles';
 
 .grw-seen-user-info :global {

+ 1 - 3
apps/app/src/components/PageControls/SubscribeButton.module.scss

@@ -1,7 +1,5 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
-
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 @use '@growi/ui/scss/atoms/btn-muted';
-
 @use './button-styles';
 
 .btn-subscribe :global {

+ 1 - 1
apps/app/src/components/PageControls/_button-styles.scss

@@ -1,4 +1,4 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 %btn-basis {
   --bs-btn-padding-x: 6px;

+ 0 - 3
apps/app/src/components/PageCreateModal.module.scss

@@ -2,9 +2,6 @@
   .page-today-input1 {
     width: 60px;
   }
-  .page-today-input2 {
-  }
-
   .grw-btn-create-page {
     min-width: 90px;
   }

+ 2 - 1
apps/app/src/components/PageEditor/EditorNavbar/EditorNavbar.module.scss

@@ -1,7 +1,8 @@
-@use '@growi/core/scss/bootstrap/init' as bs;
+@use '@growi/core-styles/scss/bootstrap/init' as bs;
 
 .editor-navbar :global {
   min-height: 72px;
+
   @include bs.media-breakpoint-down(sm) {
     min-height: 96px;
   }

Некоторые файлы не были показаны из-за большого количества измененных файлов