Explorar o código

Merge branch 'support/apply-nextjs-2' into support/remarkize-task-lists-configurer-true

Yuki Takei %!s(int64=3) %!d(string=hai) anos
pai
achega
baf7456241

+ 0 - 0
packages/app/src/client/plugin.js → packages/app/_obsolete/src/client/plugin.js


+ 1 - 1
packages/app/package.json

@@ -37,7 +37,7 @@
     "lint": "run-p lint:*",
     "test": "cross-env NODE_ENV=test jest --passWithNoTests -- ",
     "test:ci": "cross-env NODE_ENV=test jest",
-    "prelint:eslint": "yarn resources:plugin",
+    "// prelint:eslint": "yarn resources:plugin",
     "prelint:swagger2openapi": "yarn openapi:v3",
     "reg:run": "reg-suit run",
     "//// misc": "",

+ 2 - 2
packages/app/src/client/services/AppContainer.js

@@ -1,6 +1,6 @@
 import { Container } from 'unstated';
 
-import { i18nFactory } from '../util/i18n';
+// import { i18nFactory } from '../util/i18n';
 
 /**
  * Service container related to options for Application
@@ -20,7 +20,7 @@ export default class AppContainer extends Container {
       const currentUser = JSON.parse(currentUserElem.textContent);
       userLocaleId = currentUser?.lang;
     }
-    this.i18n = i18nFactory(userLocaleId);
+    // this.i18n = i18nFactory(userLocaleId);
 
     this.containerInstances = {};
     this.componentInstances = {};

+ 1 - 5
packages/app/_obsolete/src/util/locale-utils.js → packages/app/src/client/util/locale-utils.ts

@@ -4,10 +4,6 @@ const DIAGRAMS_NET_LANG_MAP = {
   zh_CN: 'zh',
 };
 
-const getDiagramsNetLangCode = (lang) => {
+export const getDiagramsNetLangCode = (lang) => {
   return DIAGRAMS_NET_LANG_MAP[lang];
 };
-
-module.exports = {
-  getDiagramsNetLangCode,
-};

+ 2 - 4
packages/app/src/components/Admin/ManageExternalAccount.jsx

@@ -1,10 +1,9 @@
 import React, { Fragment } from 'react';
 
-import PropTypes from 'prop-types';
 import { useTranslation } from 'next-i18next';
+import PropTypes from 'prop-types';
 
 import AdminExternalAccountsContainer from '~/client/services/AdminExternalAccountsContainer';
-import AppContainer from '~/client/services/AppContainer';
 import { toastError } from '~/client/util/apiNotification';
 
 import PaginationWrapper from '../PaginationWrapper';
@@ -79,7 +78,6 @@ class ManageExternalAccount extends React.Component {
 
 ManageExternalAccount.propTypes = {
   t: PropTypes.func.isRequired, // i18next
-  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   adminExternalAccountsContainer: PropTypes.instanceOf(AdminExternalAccountsContainer).isRequired,
 };
 
@@ -88,6 +86,6 @@ const ManageExternalAccountWrapperFC = (props) => {
   return <ManageExternalAccount t={t} {...props} />;
 };
 
-const ManageExternalAccountWrapper = withUnstatedContainers(ManageExternalAccountWrapperFC, [AppContainer, AdminExternalAccountsContainer]);
+const ManageExternalAccountWrapper = withUnstatedContainers(ManageExternalAccountWrapperFC, [AdminExternalAccountsContainer]);
 
 export default ManageExternalAccountWrapper;

+ 2 - 4
packages/app/src/components/Admin/Users/ExternalAccountTable.jsx

@@ -1,11 +1,10 @@
 import React, { Fragment } from 'react';
 
 import dateFnsFormat from 'date-fns/format';
-import PropTypes from 'prop-types';
 import { useTranslation } from 'next-i18next';
+import PropTypes from 'prop-types';
 
 import AdminExternalAccountsContainer from '~/client/services/AdminExternalAccountsContainer';
-import AppContainer from '~/client/services/AppContainer';
 import { toastSuccess, toastError } from '~/client/util/apiNotification';
 
 import { withUnstatedContainers } from '../../UnstatedUtils';
@@ -119,7 +118,6 @@ class ExternalAccountTable extends React.Component {
 
 ExternalAccountTable.propTypes = {
   t: PropTypes.func.isRequired, // i18next
-  appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   adminExternalAccountsContainer: PropTypes.instanceOf(AdminExternalAccountsContainer).isRequired,
 };
 
@@ -128,7 +126,7 @@ const ExternalAccountTableWrapperFC = (props) => {
   return <ExternalAccountTable t={t} {...props} />;
 };
 
-const ExternalAccountTableWrapper = withUnstatedContainers(ExternalAccountTableWrapperFC, [AppContainer, AdminExternalAccountsContainer]);
+const ExternalAccountTableWrapper = withUnstatedContainers(ExternalAccountTableWrapperFC, [AdminExternalAccountsContainer]);
 
 
 export default ExternalAccountTableWrapper;

+ 3 - 7
packages/app/src/components/InstallerForm.jsx

@@ -1,13 +1,13 @@
 import React from 'react';
 
 import i18next from 'i18next';
-
 import { useTranslation, i18n } from 'next-i18next';
 import PropTypes from 'prop-types';
 
-import { useCsrfToken } from '~/stores/context';
 import { i18n as i18nConfig } from '^/config/next-i18next.config';
 
+import { useCsrfToken } from '~/stores/context';
+
 class InstallerForm extends React.Component {
 
   constructor(props) {
@@ -34,10 +34,6 @@ class InstallerForm extends React.Component {
       .then((res) => { return this.setState({ isValidUserName: res.data.valid }) });
   }
 
-  changeLanguage(meta) {
-    i18next.changeLanguage(meta.id);
-  }
-
   submitHandler() {
     if (this.state.isSubmittingDisabled) {
       return;
@@ -100,7 +96,7 @@ class InstallerForm extends React.Component {
                           data-testid={`dropdownLanguageMenu-${locale}`}
                           className="dropdown-item"
                           type="button"
-                          onClick={() => { this.changeLanguage(locale) }}
+                          onClick={() => { i18next.changeLanguage(locale) }}
                         >
                           {fixedT('meta.display_name')}
                         </button>

+ 1 - 9
packages/app/src/components/PageEditor.tsx

@@ -402,20 +402,12 @@ const PageEditor = (props: Props): JSX.Element => {
   const isUploadable = isUploadableImage || isUploadableFile;
 
 
-  // TODO: omit no-explicit-any -- 2022.06.02 Yuki Takei
-  // It is impossible to avoid the error
-  //  "Property '...' does not exist on type 'IntrinsicAttributes & RefAttributes<any>'"
-  //  because Editor is a class component and must be wrapped with React.forwardRef
-  // eslint-disable-next-line @typescript-eslint/no-explicit-any
-  const EditorAny = Editor as any;
-
   return (
     <div className="d-flex flex-wrap">
       <div className="page-editor-editor-container flex-grow-1 flex-basis-0 mw-0">
-        <EditorAny
+        <Editor
           ref={editorRef}
           value={markdown}
-          isMobile={isMobile}
           isUploadable={isUploadable}
           isUploadableFile={isUploadableFile}
           isTextlintEnabled={isTextlintEnabled}

+ 3 - 1
packages/app/src/components/PageEditor/Editor.tsx

@@ -27,9 +27,11 @@ type EditorPropsType = {
   noCdn?: boolean,
   isUploadable?: boolean,
   isUploadableFile?: boolean,
-  onChange?: () => void,
+  isTextlintEnabled?: boolean,
+  onChange?: (newValue: string) => void,
   onUpload?: (file) => void,
   indentSize?: number,
+  onScroll?: ({ line: number }) => void,
   onScrollCursorIntoView?: (line: number) => void,
   onSave?: () => Promise<void>,
   onPasteFiles?: (event: Event) => void,

+ 7 - 7
packages/app/src/components/Theme/ThemeFuture.module.scss

@@ -1,12 +1,12 @@
-@import '../variables';
-@import '../override-bootstrap-variables';
+@use '../../styles/variables' as *;
+@use '../../styles/bootstrap/variables' as *;
+@use '../../styles/theme/mixins/page-editor-mode-manager';
 
 $primary: #00b5b7;
 $themecolor: #16282d;
 $accentcolor: #00fff5;
 
-html[light],
-html[dark] {
+.theme :global {
   // Background colors
   $bgcolor-global: $themecolor;
   $bgcolor-inline-code: #1f1f22; //optional
@@ -83,13 +83,13 @@ html[dark] {
   // admin theme box
   $color-theme-color-box: lighten($primary, 20%);
 
-  @import 'apply-colors';
-  @import 'apply-colors-dark';
+  @import '../../styles/theme/apply-colors';
+  @import '../../styles/theme/apply-colors-dark';
 
   //Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include btn-page-editor-mode-manager(lighten($primary, 10%), $primary, darken($primary, 10%), darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 10%), $primary, darken($primary, 10%), darken($primary, 20%));
     }
   }
 

+ 8 - 0
packages/app/src/components/Theme/ThemeFuture.tsx

@@ -0,0 +1,8 @@
+import { ThemeInjector } from './utils/ThemeInjector';
+
+import styles from './ThemeFuture.module.scss';
+
+const ThemeFuture = ({ children }: { children: JSX.Element }): JSX.Element => {
+  return <ThemeInjector className={styles.theme}>{children}</ThemeInjector>;
+};
+export default ThemeFuture;

+ 7 - 7
packages/app/src/components/Theme/ThemeHalloween.module.scss

@@ -1,5 +1,6 @@
-@import '../variables';
-@import '../override-bootstrap-variables';
+@use '../../styles/variables' as *;
+@use '../../styles/bootstrap/variables' as *;
+@use '../../styles/theme/mixins/page-editor-mode-manager';
 
 $themecolor: #aa4a04;
 $themelight: #f0f8ff;
@@ -33,8 +34,7 @@ $light: lighten($secondary, 10%);
 
 //== Light Mode
 //
-html[light],
-html[dark] {
+.theme :global {
   // Background colors
   $bgcolor-global: #050000;
   $bgcolor-inline-code: #1f1f22; //optional
@@ -105,13 +105,13 @@ html[dark] {
   // admin theme box
   $color-theme-color-box: lighten($primary, 20%);
 
-  @import 'apply-colors';
-  @import 'apply-colors-dark';
+  @import '../../styles/theme/apply-colors';
+  @import '../../styles/theme/apply-colors-dark';
 
   //Button
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include btn-page-editor-mode-manager(lighten($primary, 35%), $primary, lighten($primary, 5%), darken($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 35%), $primary, lighten($primary, 5%), darken($primary, 20%));
     }
   }
 

+ 8 - 0
packages/app/src/components/Theme/ThemeHalloween.tsx

@@ -0,0 +1,8 @@
+import { ThemeInjector } from './utils/ThemeInjector';
+
+import styles from './ThemeHalloween.module.scss';
+
+const ThemeHalloween = ({ children }: { children: JSX.Element }): JSX.Element => {
+  return <ThemeInjector className={styles.theme}>{children}</ThemeInjector>;
+};
+export default ThemeHalloween;

+ 13 - 12
packages/app/src/components/Theme/ThemeHufflepuff.module.scss

@@ -1,5 +1,6 @@
-@import '../variables';
-@import '../override-bootstrap-variables';
+@use '../../styles/variables' as *;
+@use '../../styles/bootstrap/variables' as *;
+@use '../../styles/theme/mixins/page-editor-mode-manager';
 
 // == Define Bootstrap theme colors
 //
@@ -19,7 +20,7 @@
 
 //== Light Mode
 //
-html[light] {
+.theme[data-color-scheme='light'] :global {
   // Theme colors
   $themecolor: #eaab20;
   $themelight: #efe2cf;
@@ -91,16 +92,16 @@ html[light] {
   // admin theme box
   $color-theme-color-box: darken($primary, 5%);
 
-  @import 'apply-colors';
-  @import 'apply-colors-light';
+  @import '../../styles/theme/apply-colors';
+  @import '../../styles/theme/apply-colors-light';
 
   //Button
   .btn.btn-outline-primary {
-    @include btn-page-editor-mode-manager(darken($primary, 50%), darken($primary, 50%), lighten($primary, 20%));
+    @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 50%), darken($primary, 50%), lighten($primary, 20%));
   }
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include btn-page-editor-mode-manager(darken($primary, 70%), lighten($primary, 5%), lighten($primary, 20%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 70%), lighten($primary, 5%), lighten($primary, 20%));
     }
   }
 
@@ -156,7 +157,7 @@ html[light] {
   }
 }
 
-html[dark] {
+.theme[data-color-scheme='dark'] :global {
   // Theme colors
   $themecolor: #eaab20;
   $themedark: #3d3f38;
@@ -234,8 +235,8 @@ html[dark] {
   // admin theme box
   $color-theme-color-box: $primary;
 
-  @import 'apply-colors';
-  @import 'apply-colors-dark';
+  @import '../../styles/theme/apply-colors';
+  @import '../../styles/theme/apply-colors-dark';
 
   // Navs
   .nav-tabs {
@@ -260,11 +261,11 @@ html[dark] {
 
   // Button
   .btn.btn-outline-primary {
-    @include btn-page-editor-mode-manager(lighten($primary, 40%), lighten($primary, 15%), darken($primary, 10%), darken($primary, 30%));
+    @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 40%), lighten($primary, 15%), darken($primary, 10%), darken($primary, 30%));
   }
   .btn-group.grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include btn-page-editor-mode-manager(lighten($primary, 40%), lighten($primary, 15%), darken($primary, 0%), darken($primary, 30%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(lighten($primary, 40%), lighten($primary, 15%), darken($primary, 0%), darken($primary, 30%));
     }
   }
 

+ 8 - 0
packages/app/src/components/Theme/ThemeHufflepuff.tsx

@@ -0,0 +1,8 @@
+import { ThemeInjector } from './utils/ThemeInjector';
+
+import styles from './ThemeHufflepuff.module.scss';
+
+const ThemeHufflepuff = ({ children }: { children: JSX.Element }): JSX.Element => {
+  return <ThemeInjector className={styles.theme}>{children}</ThemeInjector>;
+};
+export default ThemeHufflepuff;

+ 7 - 7
packages/app/src/components/Theme/ThemeKibela.module.scss

@@ -1,5 +1,6 @@
-@import '../variables';
-@import '../override-bootstrap-variables';
+@use '../../styles/variables' as *;
+@use '../../styles/bootstrap/variables' as *;
+@use '../../styles/theme/mixins/page-editor-mode-manager';
 
 $bgcolor-theme: rgb(18, 86, 163);
 $themelight: #f4f5f6;
@@ -27,8 +28,7 @@ $lightthemecolor: rgba(181, 203, 247, 0.61);
 }
 
 // Light Mode
-html[light],
-html[dark] {
+.theme :global {
   // Background colors
   $bgcolor-navbar: white;
   $bgcolor-navbar-active: $bgcolor-theme;
@@ -98,13 +98,13 @@ html[dark] {
   // Sidebar list group
   $bgcolor-sidebar-list-group: #fafbff; // optional
 
-  @import 'apply-colors';
-  @import 'apply-colors-light';
+  @import '../../styles/theme/apply-colors';
+  @import '../../styles/theme/apply-colors-light';
 
   //Button
   .grw-page-editor-mode-manager {
     .btn.btn-outline-primary {
-      @include btn-page-editor-mode-manager(darken($primary, 15%), lighten($primary, 45%), lighten($primary, 50%));
+      @include page-editor-mode-manager.btn-page-editor-mode-manager(darken($primary, 15%), lighten($primary, 45%), lighten($primary, 50%));
     }
   }
 }

+ 8 - 0
packages/app/src/components/Theme/ThemeKibela.tsx

@@ -0,0 +1,8 @@
+import { ThemeInjector } from './utils/ThemeInjector';
+
+import styles from './ThemeKibela.module.scss';
+
+const ThemeKibela = ({ children }: { children: JSX.Element }): JSX.Element => {
+  return <ThemeInjector className={styles.theme}>{children}</ThemeInjector>;
+};
+export default ThemeKibela;

+ 21 - 9
packages/app/src/components/Theme/utils/ThemeProvider.tsx

@@ -11,12 +11,16 @@ const ThemeBlackboard = dynamic(() => import('../ThemeBlackboard'));
 const ThemeChristmas = dynamic(() => import('../ThemeChristmas'));
 const ThemeDefault = dynamic(() => import('../ThemeDefault'));
 const ThemeFireRed = dynamic(() => import('../ThemeFireRed'));
-const ThemeJadeGreen = dynamic(() => import('../ThemeJadeGreen'));
+const ThemeFuture = dynamic(() => import('../ThemeFuture'));
+const ThemeHalloween = dynamic(() => import('../ThemeHalloween'));
+const ThemeHufflepuff = dynamic(() => import('../ThemeHufflepuff'));
 const ThemeIsland = dynamic(() => import('../ThemeIsland'));
-const ThemeSpring = dynamic(() => import('../ThemeSpring'));
+const ThemeJadeGreen = dynamic(() => import('../ThemeJadeGreen'));
+const ThemeKibela = dynamic(() => import('../ThemeKibela'));
+const ThemeMonoBlue = dynamic(() => import('../ThemeMonoBlue'));
 const ThemeNature = dynamic(() => import('../ThemeNature'));
+const ThemeSpring = dynamic(() => import('../ThemeSpring'));
 const ThemeWood = dynamic(() => import('../ThemeWood'));
-const ThemeMonoBlue = dynamic(() => import('../ThemeMonoBlue'));
 
 
 type Props = {
@@ -34,18 +38,26 @@ export const ThemeProvider = ({ theme, children }: Props): JSX.Element => {
       return <ThemeChristmas>{children}</ThemeChristmas>;
     case GrowiThemes.FIRE_RED:
       return <ThemeFireRed>{children}</ThemeFireRed>;
-    case GrowiThemes.JADE_GREEN:
-      return <ThemeJadeGreen>{children}</ThemeJadeGreen>;
+    case GrowiThemes.FUTURE:
+      return <ThemeFuture>{children}</ThemeFuture>;
+    case GrowiThemes.HALLOWEEN:
+      return <ThemeHalloween>{children}</ThemeHalloween>;
+    case GrowiThemes.HUFFLEPUFF:
+      return <ThemeHufflepuff>{children}</ThemeHufflepuff>;
     case GrowiThemes.ISLAND:
       return <ThemeIsland>{children}</ThemeIsland>;
-    case GrowiThemes.SPRING:
-      return <ThemeSpring>{children}</ThemeSpring>;
+    case GrowiThemes.JADE_GREEN:
+      return <ThemeJadeGreen>{children}</ThemeJadeGreen>;
+    case GrowiThemes.KIBELA:
+      return <ThemeKibela>{children}</ThemeKibela>;
+    case GrowiThemes.MONO_BLUE:
+      return <ThemeMonoBlue>{children}</ThemeMonoBlue>;
     case GrowiThemes.NATURE:
       return <ThemeNature>{children}</ThemeNature>;
+    case GrowiThemes.SPRING:
+      return <ThemeSpring>{children}</ThemeSpring>;
     case GrowiThemes.WOOD:
       return <ThemeWood>{children}</ThemeWood>;
-    case GrowiThemes.MONO_BLUE:
-      return <ThemeMonoBlue>{children}</ThemeMonoBlue>;
     default:
       return <ThemeDefault>{children}</ThemeDefault>;
   }

+ 17 - 7
packages/app/src/pages/admin/[[...path]].page.tsx

@@ -54,6 +54,7 @@ const NotificationSetting = dynamic(() => import('../../components/Admin/Notific
 const SlackIntegration = dynamic(() => import('../../components/Admin/SlackIntegration/SlackIntegration'), { ssr: false });
 const LegacySlackIntegration = dynamic(() => import('../../components/Admin/LegacySlackIntegration/LegacySlackIntegration'), { ssr: false });
 const UserManagement = dynamic(() => import('../../components/Admin/UserManagement'), { ssr: false });
+const ManageExternalAccount = dynamic(() => import('../../components/Admin/ManageExternalAccount'), { ssr: false });
 const UserGroupPage = dynamic(() => import('../../components/Admin/UserGroup/UserGroupPage'), { ssr: false });
 const ElasticsearchManagement = dynamic(() => import('../../components/Admin/ElasticsearchManagement/ElasticsearchManagement'), { ssr: false });
 // named export
@@ -84,8 +85,8 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
 
   const { t } = useTranslation('admin');
   const router = useRouter();
-  const path = router.query.path || 'home';
-  const name = Array.isArray(path) ? path[0] : path;
+  const { path } = router.query;
+  const pagePathKeys: string[] = Array.isArray(path) ? path : ['home'];
 
   const adminPagesMap = {
     home: {
@@ -116,7 +117,6 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
     importer: {
       title: useCustomTitle(props, t('Import Data')),
       component: <DataImportPageContents />,
-
     },
     export: {
       title: useCustomTitle(props, t('Export Archive Data')),
@@ -141,6 +141,10 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
     users: {
       title: useCustomTitle(props, t('User_Management')),
       component: <UserManagement />,
+      'external-accounts': {
+        title: useCustomTitle(props, t('external_account_management')),
+        component: <ManageExternalAccount />,
+      },
     },
     'user-groups': {
       title: useCustomTitle(props, t('UserGroup Management')),
@@ -156,8 +160,14 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
     },
   };
 
-  const content = adminPagesMap[name];
-  const title = content.title;
+  const getTargetPageToRender = (pagesMap, keys) => {
+    return keys.reduce((pagesMap, key) => {
+      return pagesMap[key];
+    }, pagesMap);
+  };
+
+  const targetPage: {title: string, component: JSX.Element} = getTargetPageToRender(adminPagesMap, pagePathKeys);
+  const title = targetPage.title;
 
   useCurrentUser(props.currentUser != null ? JSON.parse(props.currentUser) : null);
   useIsMailerSetup(props.isMailerSetup);
@@ -235,8 +245,8 @@ const AdminMarkdownSettingsPage: NextPage<Props> = (props: Props) => {
 
   return (
     <Provider inject={[...injectableContainers, ...adminSecurityContainers]}>
-      <AdminLayout title={title} selectedNavOpt={name}>
-        {content.component}
+      <AdminLayout title={title} selectedNavOpt={pagePathKeys[0]}>
+        {targetPage.component}
       </AdminLayout>
     </Provider>
   );