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

Merge branch 'dev/7.0.x' into support/apply-colors-v7

Yuki Takei 2 лет назад
Родитель
Сommit
b2ac569cb6
45 измененных файлов с 117 добавлено и 78 удалено
  1. 2 3
      apps/app/_obsolete/src/styles/theme/_apply-colors-dark.scss
  2. 1 1
      apps/app/_obsolete/src/styles/theme/apply-colors.scss
  3. 1 1
      apps/app/src/components/Admin/App/FileUploadSetting.tsx
  4. 1 1
      apps/app/src/components/Admin/App/MaintenanceMode.tsx
  5. 1 1
      apps/app/src/components/Admin/App/QuestionnaireSettings.tsx
  6. 1 1
      apps/app/src/components/Admin/App/SiteUrlSetting.tsx
  7. 1 1
      apps/app/src/components/Admin/App/V5PageMigration.tsx
  8. 1 1
      apps/app/src/components/Admin/Customize/CustomizeCssSetting.tsx
  9. 2 2
      apps/app/src/components/Admin/Customize/CustomizeFunctionSetting.tsx
  10. 1 1
      apps/app/src/components/Admin/Customize/CustomizeNoscriptSetting.tsx
  11. 1 1
      apps/app/src/components/Admin/Customize/CustomizeScriptSetting.tsx
  12. 2 2
      apps/app/src/components/Admin/Customize/CustomizeSidebarSetting.tsx
  13. 1 1
      apps/app/src/components/Admin/Customize/CustomizeTitle.tsx
  14. 1 1
      apps/app/src/components/Admin/ExportArchiveData/SelectCollectionsModal.tsx
  15. 1 1
      apps/app/src/components/Admin/G2GDataTransferExportForm.tsx
  16. 1 1
      apps/app/src/components/Admin/ImportData/GrowiArchive/ImportForm.jsx
  17. 1 1
      apps/app/src/components/Admin/ImportData/GrowiArchiveSection.jsx
  18. 2 2
      apps/app/src/components/Admin/ImportData/ImportDataPageContents.jsx
  19. 1 1
      apps/app/src/components/Admin/LegacySlackIntegration/SlackConfiguration.jsx
  20. 3 3
      apps/app/src/components/Admin/MarkdownSetting/MarkDownSettingContents.tsx
  21. 1 1
      apps/app/src/components/Admin/Notification/GlobalNotification.jsx
  22. 1 1
      apps/app/src/components/Admin/Security/FacebookSecuritySetting.jsx
  23. 2 2
      apps/app/src/components/Admin/Security/LdapSecuritySettingContents.jsx
  24. 1 1
      apps/app/src/components/Admin/Security/SamlSecuritySettingContents.jsx
  25. 2 2
      apps/app/src/components/Admin/Security/SecuritySetting.jsx
  26. 1 1
      apps/app/src/components/Admin/UserGroupDetail/UserGroupUserModal.tsx
  27. 2 1
      apps/app/src/components/ErrorBoudary.jsx
  28. 1 1
      apps/app/src/components/Page/CopyDropdown.jsx
  29. 1 1
      apps/app/src/components/Page/CopyDropdown.module.scss
  30. 1 1
      apps/app/src/components/PageComment/DeleteCommentModal.tsx
  31. 1 1
      apps/app/src/components/PageEditor/LinkEditModal.tsx
  32. 1 1
      apps/app/src/components/PageEditorByHackmd.tsx
  33. 7 0
      apps/app/src/components/Presentation/Slides.tsx
  34. 1 1
      apps/app/src/components/ReactMarkdownComponents/SlideViewer.tsx
  35. 1 1
      apps/app/src/components/RevisionComparer/RevisionComparer.module.scss
  36. 1 1
      apps/app/src/components/RevisionComparer/RevisionComparer.tsx
  37. 2 1
      apps/app/src/server/routes/apiv3/users.js
  38. 1 2
      packages/core/scss/bootstrap/_override.scss
  39. 2 0
      packages/presentation/package.json
  40. 0 2
      packages/presentation/src/components/GrowiSlides.tsx
  41. 0 1
      packages/presentation/src/components/MarpSlides.tsx
  42. 0 4
      packages/presentation/src/components/Slides.global.scss
  43. 35 0
      packages/presentation/src/components/Slides.module.scss
  44. 10 6
      packages/presentation/src/components/Slides.tsx
  45. 16 18
      packages/presentation/src/services/growi-marpit.ts

+ 2 - 3
apps/app/_obsolete/src/styles/theme/_apply-colors-dark.scss

@@ -132,12 +132,11 @@
   //   /*
   //   /*
   //   * Card
   //   * Card
   //   */
   //   */
-  //   .card:not([class*='bg-']):not(.well):not(.card-disabled) {
+  //   .card:not([class*='bg-']):not(.custom-card):not(.card-disabled) {
   //     @extend .bg-dark;
   //     @extend .bg-dark;
   //   }
   //   }
 
 
-  //   [TODO] GW-3219 modify common color of well in dark theme, then remove below css.
-  //   .card.well {
+  //   .card.custom-card {
   //     border-color: var(--secondary);
   //     border-color: var(--secondary);
   //   }
   //   }
 
 

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

@@ -400,7 +400,7 @@ ul.pagination {
 /*
 /*
  * cards
  * cards
  */
  */
-.card.well {
+.card.custom-card {
   color: var(--color-global);
   color: var(--color-global);
   background-color: var(--bgcolor-card);
   background-color: var(--bgcolor-card);
   border-color: var(--light);
   border-color: var(--light);

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

@@ -27,7 +27,7 @@ export const FileUploadSettingMolecule = React.memo((props: FileUploadSettingMol
 
 
   return (
   return (
     <>
     <>
-      <p className="card well my-3">
+      <p className="card custom-card my-3">
         {t('admin:app_setting.file_upload')}
         {t('admin:app_setting.file_upload')}
         <br />
         <br />
         <br />
         <br />

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

@@ -54,7 +54,7 @@ export const MaintenanceMode: FC = () => {
         onConfirm={onConfirmHandler}
         onConfirm={onConfirmHandler}
         onCancel={() => closeModal()}
         onCancel={() => closeModal()}
       />
       />
-      <p className="card well">
+      <p className="card custom-card">
         {t('admin:maintenance_mode.description')}
         {t('admin:maintenance_mode.description')}
         <br />
         <br />
         <br />
         <br />

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

@@ -49,7 +49,7 @@ const QuestionnaireSettings = (): JSX.Element => {
 
 
   return (
   return (
     <div id="questionnaire-settings" className="mb-5">
     <div id="questionnaire-settings" className="mb-5">
-      <p className="card well">
+      <p className="card custom-card">
         <div className="mb-4">{t('app_setting.questionnaire_settings_explanation')}</div>
         <div className="mb-4">{t('app_setting.questionnaire_settings_explanation')}</div>
         <span>
         <span>
           <div className="mb-2">
           <div className="mb-2">

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

@@ -35,7 +35,7 @@ const SiteUrlSetting = (props: Props) => {
 
 
   return (
   return (
     <React.Fragment>
     <React.Fragment>
-      <p className="card well">{t('site_url.desc')}</p>
+      <p className="card custom-card">{t('site_url.desc')}</p>
       {!adminAppContainer.state.isSetSiteUrl
       {!adminAppContainer.state.isSetSiteUrl
           && (<p className="alert alert-danger"><i className="icon-exclamation"></i> {t('site_url.warn')}</p>)}
           && (<p className="alert alert-danger"><i className="icon-exclamation"></i> {t('site_url.warn')}</p>)}
 
 

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

@@ -133,7 +133,7 @@ const V5PageMigration: FC<Props> = (props: Props) => {
         onConfirm={onConfirm}
         onConfirm={onConfirm}
         onCancel={() => setIsV5PageMigrationModalShown(false)}
         onCancel={() => setIsV5PageMigrationModalShown(false)}
       />
       />
-      <p className="card well">
+      <p className="card custom-card">
         {t('admin:v5_page_migration.migration_desc')}
         {t('admin:v5_page_migration.migration_desc')}
         <br />
         <br />
         <br />
         <br />

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

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

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

@@ -37,7 +37,7 @@ const CustomizeFunctionSetting = (props: Props): JSX.Element => {
       <div className="row">
       <div className="row">
         <div className="col-12">
         <div className="col-12">
           <h2 className="admin-setting-header">{t('admin:customize_settings.function')}</h2>
           <h2 className="admin-setting-header">{t('admin:customize_settings.function')}</h2>
-          <Card className="card well my-3">
+          <Card className="card custom-card my-3">
             <CardBody className="px-0 py-2">
             <CardBody className="px-0 py-2">
               {t('admin:customize_settings.function_desc')}
               {t('admin:customize_settings.function_desc')}
             </CardBody>
             </CardBody>
@@ -152,7 +152,7 @@ const CustomizeFunctionSetting = (props: Props): JSX.Element => {
                   </a>
                   </a>
                   <br></br>
                   <br></br>
                   <a
                   <a
-                    href={`${t('admin:customize_settings.function_options.marp_in_gorwi_link')}`}
+                    href={`${t('admin:customize_settings.function_options.marp_in_growi_link')}`}
                     target="_blank"
                     target="_blank"
                     rel="noopener noreferrer"
                     rel="noopener noreferrer"
                   >{`${t('admin:customize_settings.function_options.marp_in_growi')}`}
                   >{`${t('admin:customize_settings.function_options.marp_in_growi')}`}

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

@@ -36,7 +36,7 @@ const CustomizeNoscriptSetting = (props: Props): JSX.Element => {
         <div className="col-12">
         <div className="col-12">
           <h2 className="admin-setting-header">{t('admin:customize_settings.custom_noscript')}</h2>
           <h2 className="admin-setting-header">{t('admin:customize_settings.custom_noscript')}</h2>
 
 
-          <Card className="card well my-3">
+          <Card className="card custom-card my-3">
             <CardBody className="px-0 py-2">
             <CardBody className="px-0 py-2">
               <span
               <span
                 // eslint-disable-next-line react/no-danger
                 // eslint-disable-next-line react/no-danger

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

@@ -35,7 +35,7 @@ const CustomizeScriptSetting = (props: Props): JSX.Element => {
       <div className="row">
       <div className="row">
         <div className="col-12">
         <div className="col-12">
           <h2 className="admin-setting-header">{t('admin:customize_settings.custom_script')}</h2>
           <h2 className="admin-setting-header">{t('admin:customize_settings.custom_script')}</h2>
-          <Card className="card well">
+          <Card className="card custom-card">
             <CardBody className="px-0 py-2">
             <CardBody className="px-0 py-2">
               {t('admin:customize_settings.write_java')}<br />
               {t('admin:customize_settings.write_java')}<br />
               {t('admin:customize_settings.reflect_change')}
               {t('admin:customize_settings.reflect_change')}

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

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

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

@@ -37,7 +37,7 @@ export const CustomizeTitle: FC = () => {
         </div>
         </div>
 
 
         <div className="col-12">
         <div className="col-12">
-          <Card className="card well">
+          <Card className="card custom-card">
             <CardBody className="px-0 py-2">
             <CardBody className="px-0 py-2">
               {/* eslint-disable react/no-danger */}
               {/* eslint-disable react/no-danger */}
               <p dangerouslySetInnerHTML={{ __html: t('admin:customize_settings.custom_title_detail') }} />
               <p dangerouslySetInnerHTML={{ __html: t('admin:customize_settings.custom_title_detail') }} />

+ 1 - 1
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');
     const html = t('admin:export_management.desc_password_seed');
 
 
     // eslint-disable-next-line react/no-danger
     // eslint-disable-next-line react/no-danger
-    return <div className="card well" dangerouslySetInnerHTML={{ __html: html }}></div>;
+    return <div className="card custom-card" dangerouslySetInnerHTML={{ __html: html }}></div>;
   }, [selectedCollections, t]);
   }, [selectedCollections, t]);
 
 
   const renderCheckboxes = useCallback((collectionNames, color?) => {
   const renderCheckboxes = useCallback((collectionNames, color?) => {

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

@@ -212,7 +212,7 @@ const G2GDataTransferExportForm = (props: Props): JSX.Element => {
         </div>
         </div>
       </form>
       </form>
 
 
-      <div className="card well small my-4">
+      <div className="card custom-card small my-4">
         <ul>
         <ul>
           <li>{t('admin:importer_management.growi_settings.description_of_import_mode.about')}</li>
           <li>{t('admin:importer_management.growi_settings.description_of_import_mode.about')}</li>
           <ul>
           <ul>

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

@@ -459,7 +459,7 @@ class ImportForm extends React.Component {
           </div>
           </div>
         </form>
         </form>
 
 
-        <div className="card well small my-4">
+        <div className="card custom-card small my-4">
           <ul>
           <ul>
             <li>{t('admin:importer_management.growi_settings.description_of_import_mode.about')}</li>
             <li>{t('admin:importer_management.growi_settings.description_of_import_mode.about')}</li>
             <ul>
             <ul>

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

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

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

@@ -57,7 +57,7 @@ class ImportDataPageContents extends React.Component {
               </tbody>
               </tbody>
             </table>
             </table>
 
 
-            <div className="card well mb-0 small">
+            <div className="card custom-card mb-0 small">
               <ul>
               <ul>
                 <li>{t('importer_management.page_skip')}</li>
                 <li>{t('importer_management.page_skip')}</li>
               </ul>
               </ul>
@@ -163,7 +163,7 @@ class ImportDataPageContents extends React.Component {
                 </tr>
                 </tr>
               </tbody>
               </tbody>
             </table>
             </table>
-            <div className="card well mb-0 small">
+            <div className="card custom-card mb-0 small">
               <ul>
               <ul>
                 <li>{t('importer_management.page_skip')}</li>
                 <li>{t('importer_management.page_skip')}</li>
               </ul>
               </ul>

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

@@ -101,7 +101,7 @@ class SlackConfiguration extends React.Component {
             <React.Fragment>
             <React.Fragment>
               <h2 className="border-bottom mb-5">{t('notification_settings.slack_app_configuration')}</h2>
               <h2 className="border-bottom mb-5">{t('notification_settings.slack_app_configuration')}</h2>
 
 
-              <div className="well card">
+              <div className="card custom-card">
                 <span className="text-danger"><i className="icon-fw icon-exclamation"></i>NOT RECOMMENDED</span>
                 <span className="text-danger"><i className="icon-fw icon-exclamation"></i>NOT RECOMMENDED</span>
                 <br />
                 <br />
                 {/* eslint-disable-next-line react/no-danger */}
                 {/* eslint-disable-next-line react/no-danger */}

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

@@ -43,21 +43,21 @@ const MarkDownSettingContents = React.memo((props: Props): JSX.Element => {
     <div data-testid="admin-markdown">
     <div data-testid="admin-markdown">
       {/* Line Break Setting */}
       {/* Line Break Setting */}
       <h2 className="admin-setting-header">{t('markdown_settings.lineBreak_header')}</h2>
       <h2 className="admin-setting-header">{t('markdown_settings.lineBreak_header')}</h2>
-      <Card className="card well my-3">
+      <Card className="card custom-card my-3">
         <CardBody className="px-0 py-2">{ t('markdown_settings.lineBreak_desc') }</CardBody>
         <CardBody className="px-0 py-2">{ t('markdown_settings.lineBreak_desc') }</CardBody>
       </Card>
       </Card>
       <LineBreakForm />
       <LineBreakForm />
 
 
       {/* Indent Setting */}
       {/* Indent Setting */}
       <h2 className="admin-setting-header">{t('markdown_settings.indent_header')}</h2>
       <h2 className="admin-setting-header">{t('markdown_settings.indent_header')}</h2>
-      <Card className="card well my-3">
+      <Card className="card custom-card my-3">
         <CardBody className="px-0 py-2">{t('markdown_settings.indent_desc') }</CardBody>
         <CardBody className="px-0 py-2">{t('markdown_settings.indent_desc') }</CardBody>
       </Card>
       </Card>
       <IndentForm />
       <IndentForm />
 
 
       {/* XSS Setting */}
       {/* XSS Setting */}
       <h2 className="admin-setting-header">{ t('markdown_settings.xss_header') }</h2>
       <h2 className="admin-setting-header">{ t('markdown_settings.xss_header') }</h2>
-      <Card className="card well my-3">
+      <Card className="card custom-card my-3">
         <CardBody className="px-0 py-2">{ t('markdown_settings.xss_desc') }</CardBody>
         <CardBody className="px-0 py-2">{ t('markdown_settings.xss_desc') }</CardBody>
       </Card>
       </Card>
       <XssForm />
       <XssForm />

+ 1 - 1
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>
       <h2 className="border-bottom my-4">{t('notification_settings.valid_page')}</h2>
 
 
-      <p className="card well">
+      <p className="card custom-card">
         {/* eslint-disable-next-line react/no-danger */}
         {/* eslint-disable-next-line react/no-danger */}
         <span dangerouslySetInnerHTML={{ __html: t('notification_settings.link_notification_help') }} />
         <span dangerouslySetInnerHTML={{ __html: t('notification_settings.link_notification_help') }} />
       </p>
       </p>

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

@@ -18,7 +18,7 @@ class FacebookSecurityManagement extends React.Component {
           Facebook OAuth { t('admin:security_settings.configuration') }
           Facebook OAuth { t('admin:security_settings.configuration') }
         </h2>
         </h2>
 
 
-        <p className="well">(TBD)</p>
+        <p className="card custom-card">(TBD)</p>
       </>
       </>
     );
     );
   }
   }

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

@@ -177,7 +177,7 @@ class LdapSecuritySettingContents extends React.Component {
               </div>
               </div>
               <div className="col-md-6">
               <div className="col-md-6">
                 {(adminLdapSecurityContainer.state.isUserBind) ? (
                 {(adminLdapSecurityContainer.state.isUserBind) ? (
-                  <p className="well card passport-ldap-userbind">
+                  <p className="card custom-card passport-ldap-userbind">
                     <small>
                     <small>
                       {t('security_settings.ldap.bind_DN_password_user_detail')}
                       {t('security_settings.ldap.bind_DN_password_user_detail')}
                     </small>
                     </small>
@@ -185,7 +185,7 @@ class LdapSecuritySettingContents extends React.Component {
                 )
                 )
                   : (
                   : (
                     <>
                     <>
-                      <p className="well card passport-ldap-managerbind">
+                      <p className="card custom-card passport-ldap-managerbind">
                         <small>
                         <small>
                           {t('security_settings.ldap.bind_DN_password_manager_detail')}
                           {t('security_settings.ldap.bind_DN_password_manager_detail')}
                         </small>
                         </small>

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

@@ -204,7 +204,7 @@ class SamlSecurityManagementContents extends React.Component {
                     <div>
                     <div>
                       <small>
                       <small>
                         e.g.
                         e.g.
-                        <pre className="well card">{`-----BEGIN CERTIFICATE-----
+                        <pre className="card custom-card">{`-----BEGIN CERTIFICATE-----
 MIICBzCCAXACCQD4US7+0A/b/zANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJK
 MIICBzCCAXACCQD4US7+0A/b/zANBgkqhkiG9w0BAQsFADBIMQswCQYDVQQGEwJK
 UDEOMAwGA1UECAwFVG9reW8xFTATBgNVBAoMDFdFU0VFSywgSW5jLjESMBAGA1UE
 UDEOMAwGA1UECAwFVG9reW8xFTATBgNVBAoMDFdFU0VFSywgSW5jLjESMBAGA1UE
 ...
 ...

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

@@ -280,7 +280,7 @@ class SecuritySetting extends React.Component {
                   </button>
                   </button>
                   <Collapse isOpen={expantDeleteOptionsState}>
                   <Collapse isOpen={expantDeleteOptionsState}>
                     <div className="pb-4">
                     <div className="pb-4">
-                      <p className="card well">
+                      <p className="card custom-card">
                         <span className="text-warning">
                         <span className="text-warning">
                           <i className="icon-info"></i>
                           <i className="icon-info"></i>
                           {/* eslint-disable-next-line react/no-danger */}
                           {/* eslint-disable-next-line react/no-danger */}
@@ -490,7 +490,7 @@ class SecuritySetting extends React.Component {
             />
             />
             {/* eslint-disable-next-line react/no-danger */}
             {/* eslint-disable-next-line react/no-danger */}
             <p className="form-text text-muted" dangerouslySetInnerHTML={{ __html: t('security_settings.max_age_desc') }} />
             <p className="form-text text-muted" dangerouslySetInnerHTML={{ __html: t('security_settings.max_age_desc') }} />
-            <p className="card well">
+            <p className="card custom-card">
               <span className="text-warning">
               <span className="text-warning">
                 <i className="icon-info"></i> {t('security_settings.max_age_caution')}
                 <i className="icon-info"></i> {t('security_settings.max_age_caution')}
               </span>
               </span>

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

@@ -48,7 +48,7 @@ const UserGroupUserModal = (props: Props): JSX.Element => {
         {t('admin:user_group_management.add_modal.add_user') }
         {t('admin:user_group_management.add_modal.add_user') }
       </ModalHeader>
       </ModalHeader>
       <ModalBody>
       <ModalBody>
-        <p className="card well">{t('admin:user_group_management.add_modal.description')}</p>
+        <p className="card custom-card">{t('admin:user_group_management.add_modal.description')}</p>
         <div className="p-3">
         <div className="p-3">
           <UserGroupUserFormByInput
           <UserGroupUserFormByInput
             userGroup={userGroup}
             userGroup={userGroup}

+ 2 - 1
apps/app/src/components/ErrorBoudary.jsx

@@ -1,4 +1,5 @@
 import React from 'react';
 import React from 'react';
+
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
 /**
 /**
@@ -35,7 +36,7 @@ class ErrorBoundary extends React.Component {
           <div className="card-header">Error occured in {firstStack}</div>
           <div className="card-header">Error occured in {firstStack}</div>
           <div className="card-body">
           <div className="card-body">
             <h5>{error && error.toString()}</h5>
             <h5>{error && error.toString()}</h5>
-            <details className="card well small mb-0" style={{ whiteSpace: 'pre-wrap' }}>
+            <details className="card custom-card small mb-0" style={{ whiteSpace: 'pre-wrap' }}>
               {errorInfo.componentStack}
               {errorInfo.componentStack}
             </details>
             </details>
           </div>
           </div>

+ 1 - 1
apps/app/src/components/Page/CopyDropdown.jsx

@@ -19,7 +19,7 @@ const { encodeSpaces } = pagePathUtils;
 const DropdownItemContents = ({ title, contents }) => (
 const DropdownItemContents = ({ title, contents }) => (
   <>
   <>
     <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
     <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
-    <div className="card well mb-1 p-2">{contents}</div>
+    <div className="card custom-card mb-1 p-2">{contents}</div>
   </>
   </>
 );
 );
 /* eslint-enable react/prop-types */
 /* eslint-enable react/prop-types */

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

@@ -13,7 +13,7 @@
       background-color: unset;
       background-color: unset;
     }
     }
 
 
-    .well {
+    .card {
       font-size: 0.7em;
       font-size: 0.7em;
       word-break: break-all;
       word-break: break-all;
     }
     }

+ 1 - 1
apps/app/src/components/PageComment/DeleteCommentModal.tsx

@@ -56,7 +56,7 @@ export const DeleteCommentModal = (props: DeleteCommentModalProps): JSX.Element
     return (
     return (
       <>
       <>
         <UserPicture user={comment.creator} size="xs" /> <strong><Username user={comment.creator}></Username></strong> wrote on {commentDate}:
         <UserPicture user={comment.creator} size="xs" /> <strong><Username user={comment.creator}></Username></strong> wrote on {commentDate}:
-        <p className="card well comment-body mt-2 p-2">{commentBodyElement}</p>
+        <p className="card custom-card comment-body mt-2 p-2">{commentBodyElement}</p>
       </>
       </>
     );
     );
   };
   };

+ 1 - 1
apps/app/src/components/PageEditor/LinkEditModal.tsx

@@ -296,7 +296,7 @@ export const LinkEditModal = (): JSX.Element => {
 
 
   const renderPathFormatForm = (): JSX.Element => {
   const renderPathFormatForm = (): JSX.Element => {
     return (
     return (
-      <div className="card well pt-3">
+      <div className="card custom-card pt-3">
         <form className="mb-0">
         <form className="mb-0">
           <div className="mb-0 row">
           <div className="mb-0 row">
             <label className="form-label col-sm-3">{t('link_edit.path_format')}</label>
             <label className="form-label col-sm-3">{t('link_edit.path_format')}</label>

+ 1 - 1
apps/app/src/components/PageEditorByHackmd.tsx

@@ -504,7 +504,7 @@ export const PageEditorByHackmd = (): JSX.Element => {
           <div className="bg-box p-5 text-center">
           <div className="bg-box p-5 text-center">
             <h2 className="text-warning"><i className="icon-fw icon-exclamation"></i> {t('hackmd.integration_failed')}</h2>
             <h2 className="text-warning"><i className="icon-fw icon-exclamation"></i> {t('hackmd.integration_failed')}</h2>
             <h4>{errorMessage}</h4>
             <h4>{errorMessage}</h4>
-            <p className="card well text-danger">
+            <p className="card custom-card text-danger">
               {errorReason}
               {errorReason}
             </p>
             </p>
             {/* eslint-disable-next-line react/no-danger */}
             {/* eslint-disable-next-line react/no-danger */}

+ 7 - 0
apps/app/src/components/Presentation/Slides.tsx

@@ -0,0 +1,7 @@
+import { Slides as SlidesSubstance, type SlidesProps } from '@growi/presentation';
+
+import '@growi/presentation/dist/style.css';
+
+export const Slides = (props: SlidesProps): JSX.Element => {
+  return <SlidesSubstance {...props} />;
+};

+ 1 - 1
apps/app/src/components/ReactMarkdownComponents/SlideViewer.tsx

@@ -6,7 +6,7 @@ import { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown';
 import { usePresentationViewOptions } from '~/stores/slide-viewer-renderer';
 import { usePresentationViewOptions } from '~/stores/slide-viewer-renderer';
 
 
 
 
-const Slides = dynamic(() => import('@growi/presentation').then(mod => mod.Slides), { ssr: false });
+const Slides = dynamic(() => import('../Presentation/Slides').then(mod => mod.Slides), { ssr: false });
 
 
 type SlideViewerProps = {
 type SlideViewerProps = {
   marp: string | undefined,
   marp: string | undefined,

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

@@ -27,7 +27,7 @@
         background-color: unset;
         background-color: unset;
       }
       }
 
 
-      .well {
+      .card {
         font-size: 0.7em;
         font-size: 0.7em;
         word-break: break-all;
         word-break: break-all;
       }
       }

+ 1 - 1
apps/app/src/components/RevisionComparer/RevisionComparer.tsx

@@ -17,7 +17,7 @@ const { encodeSpaces } = pagePathUtils;
 const DropdownItemContents = ({ title, contents }) => (
 const DropdownItemContents = ({ title, contents }) => (
   <>
   <>
     <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
     <div className="h6 mt-1 mb-2"><strong>{title}</strong></div>
-    <div className="card well mb-1 p-2">{contents}</div>
+    <div className="card custom-card mb-1 p-2">{contents}</div>
   </>
   </>
 );
 );
 
 

+ 2 - 1
apps/app/src/server/routes/apiv3/users.js

@@ -187,11 +187,12 @@ module.exports = (crowi) => {
   const sendEmailByUser = async(user) => {
   const sendEmailByUser = async(user) => {
     const { appService, mailService } = crowi;
     const { appService, mailService } = crowi;
     const appTitle = appService.getAppTitle();
     const appTitle = appService.getAppTitle();
+    const locale = configManager.getConfig('crowi', 'app:globalLang');
 
 
     await mailService.send({
     await mailService.send({
       to: user.email,
       to: user.email,
       subject: `New password for ${appTitle}`,
       subject: `New password for ${appTitle}`,
-      template: path.join(crowi.localeDir, 'en_US/admin/userResetPassword.ejs'),
+      template: path.join(crowi.localeDir, `${locale}/admin/userResetPassword.ejs`),
       vars: {
       vars: {
         email: user.email,
         email: user.email,
         password: user.password,
         password: user.password,

+ 1 - 2
packages/core/scss/bootstrap/_override.scss

@@ -81,8 +81,7 @@
 // .card-header:first-child {
 // .card-header:first-child {
 // }
 // }
 
 
-// // Well (substitute Well of bootstrap3)
-// .card.well {
+// .card.custom-card {
 //   min-height: 20px;
 //   min-height: 20px;
 //   padding: $card-spacer-y $card-spacer-x;
 //   padding: $card-spacer-y $card-spacer-x;
 // }
 // }

+ 2 - 0
packages/presentation/package.json

@@ -38,6 +38,8 @@
     "hast-util-sanitize": "^4.1.0",
     "hast-util-sanitize": "^4.1.0",
     "hast-util-select": "^5.0.5",
     "hast-util-select": "^5.0.5",
     "react-markdown": "^8.0.7",
     "react-markdown": "^8.0.7",
+    "remark-frontmatter": "^4.0.1",
+    "remark-stringify": "^10.0.0",
     "unified": "^10.1.2",
     "unified": "^10.1.2",
     "unist-util-find-after": "^4.0.0",
     "unist-util-find-after": "^4.0.0",
     "unist-util-visit": "^4.0.0"
     "unist-util-visit": "^4.0.0"

+ 0 - 2
packages/presentation/src/components/GrowiSlides.tsx

@@ -5,8 +5,6 @@ import type { PresentationOptions } from '../consts';
 import { MARP_CONTAINER_CLASS_NAME, presentationMarpit, slideMarpit } from '../services/growi-marpit';
 import { MARP_CONTAINER_CLASS_NAME, presentationMarpit, slideMarpit } from '../services/growi-marpit';
 import * as extractSections from '../services/renderer/extract-sections';
 import * as extractSections from '../services/renderer/extract-sections';
 
 
-
-import './Slides.global.scss';
 import { PresentationRichSlideSection, RichSlideSection } from './RichSlideSection';
 import { PresentationRichSlideSection, RichSlideSection } from './RichSlideSection';
 
 
 
 

+ 0 - 1
packages/presentation/src/components/MarpSlides.tsx

@@ -1,6 +1,5 @@
 import Head from 'next/head';
 import Head from 'next/head';
 
 
-import './Slides.global.scss';
 import { presentationMarpit, slideMarpit } from '../services/growi-marpit';
 import { presentationMarpit, slideMarpit } from '../services/growi-marpit';
 
 
 type Props = {
 type Props = {

+ 0 - 4
packages/presentation/src/components/Slides.global.scss

@@ -1,4 +0,0 @@
-div.slides.marpit > section :is(pre, marp-pre) {
-  padding: 0;
-  border: none;
-}

+ 35 - 0
packages/presentation/src/components/Slides.module.scss

@@ -0,0 +1,35 @@
+.slides-styles :global {
+  // Reset _wiki.scss, vendor.scss and other css in <div class=slides marpit>.
+  // This ensures that Marp is rendered currently.
+  .slides {
+    *, *:before, *::after {
+      box-sizing: initial;
+    }
+
+    *::before, *::after {
+      all: initial;
+    }
+
+    h1,
+    h2,
+    h3,
+    h4,
+    h5,
+    h6,
+    p {
+      font-weight: initial;
+      line-height: initial;
+      border: initial;
+    }
+
+    code {
+      color: unset;
+    }
+
+  }
+
+  section {
+    padding: 0;
+    border: none;
+  }
+}

+ 10 - 6
packages/presentation/src/components/Slides.tsx

@@ -4,23 +4,27 @@ import type { PresentationOptions } from '../consts';
 import { GrowiSlides } from './GrowiSlides';
 import { GrowiSlides } from './GrowiSlides';
 import { MarpSlides } from './MarpSlides';
 import { MarpSlides } from './MarpSlides';
 
 
-import './Slides.global.scss';
+import styles from './Slides.module.scss';
 
 
-type Props = {
+export type SlidesProps = {
   options: PresentationOptions,
   options: PresentationOptions,
   children?: string,
   children?: string,
   hasMarpFlag?: boolean,
   hasMarpFlag?: boolean,
   presentation?: boolean,
   presentation?: boolean,
 }
 }
 
 
-export const Slides = (props: Props): JSX.Element => {
+export const Slides = (props: SlidesProps): JSX.Element => {
   const {
   const {
     options, children, hasMarpFlag, presentation,
     options, children, hasMarpFlag, presentation,
   } = props;
   } = props;
 
 
   return (
   return (
-    hasMarpFlag
-      ? <MarpSlides presentation={presentation}>{children}</MarpSlides>
-      : <GrowiSlides options={options} presentation={presentation}>{children}</GrowiSlides>
+    <div className={`${styles['slides-styles']}`}>
+      {
+        hasMarpFlag
+          ? <MarpSlides presentation={presentation}>{children}</MarpSlides>
+          : <GrowiSlides options={options} presentation={presentation}>{children}</GrowiSlides>
+      }
+    </div>
   );
   );
 };
 };

+ 16 - 18
packages/presentation/src/services/growi-marpit.ts

@@ -1,4 +1,4 @@
-import { Marp } from '@marp-team/marp-core';
+import { Marp, MarpOptions } from '@marp-team/marp-core';
 import { Element } from '@marp-team/marpit';
 import { Element } from '@marp-team/marpit';
 
 
 export const MARP_CONTAINER_CLASS_NAME = 'marpit';
 export const MARP_CONTAINER_CLASS_NAME = 'marpit';
@@ -36,28 +36,26 @@ const lineNumber = (md) => {
   });
   });
 };
 };
 
 
-export const slideMarpit = new Marp({
+const marpitOption: MarpOptions = {
   container: [
   container: [
     new Element('div', { class: `slides ${MARP_CONTAINER_CLASS_NAME}` }),
     new Element('div', { class: `slides ${MARP_CONTAINER_CLASS_NAME}` }),
   ],
   ],
-  slideContainer: [
-    new Element('section', { class: 'shadow rounded m-2' }),
-  ],
   inlineSVG: true,
   inlineSVG: true,
   emoji: undefined,
   emoji: undefined,
   html: false,
   html: false,
   math: false,
   math: false,
-}).use(lineNumber);
+};
 
 
-export const presentationMarpit = new Marp({
-  container: [
-    new Element('div', { class: `slides ${MARP_CONTAINER_CLASS_NAME}` }),
-  ],
-  slideContainer: [
-    new Element('section', { class: 'm-2' }),
-  ],
-  inlineSVG: true,
-  emoji: undefined,
-  html: false,
-  math: false,
-});
+const slideMarpitOption = marpitOption;
+slideMarpitOption.slideContainer = (
+  [new Element('section', { class: 'shadow rounded m-2' })]
+);
+
+export const slideMarpit = new Marp(slideMarpitOption).use(lineNumber);
+
+const presentationMarpitOption = marpitOption;
+presentationMarpitOption.slideContainer = (
+  [new Element('section', { class: 'm-2' })]
+);
+
+export const presentationMarpit = new Marp(presentationMarpitOption);