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

Merge branch 'dev/7.0.x' into support/142719-update-login-styles

Yuki Takei 2 лет назад
Родитель
Сommit
00b7bd739c
24 измененных файлов с 101 добавлено и 53 удалено
  1. 1 0
      apps/app/public/static/locales/en_US/translation.json
  2. 1 0
      apps/app/public/static/locales/ja_JP/translation.json
  3. 1 0
      apps/app/public/static/locales/zh_CN/translation.json
  4. 2 2
      apps/app/src/components/Admin/App/AppSetting.jsx
  5. 1 1
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithProxySettings.jsx
  6. 1 1
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettings.jsx
  7. 2 2
      apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx
  8. 1 1
      apps/app/src/components/Admin/SlackIntegration/OfficialBotSettings.jsx
  9. 4 4
      apps/app/src/components/Admin/SlackIntegration/WithProxyAccordions.jsx
  10. 6 2
      apps/app/src/components/Common/PagePathHierarchicalLink/PagePathHierarchicalLink.tsx
  11. 2 2
      apps/app/src/components/Me/UISettings.tsx
  12. 1 0
      apps/app/src/components/Navbar/GrowiContextualSubNavigation.tsx
  13. 1 1
      apps/app/src/components/PageEditor/EditorNavbar/EditorNavbar.tsx
  14. 1 1
      apps/app/src/components/PageHeader/PageHeader.tsx
  15. 1 0
      apps/app/src/components/PageHeader/PagePathHeader.module.scss
  16. 43 27
      apps/app/src/components/PageHeader/PagePathHeader.tsx
  17. 1 0
      apps/app/src/components/PageHeader/PageTitleHeader.module.scss
  18. 4 5
      apps/app/src/components/PageHeader/PageTitleHeader.tsx
  19. 4 0
      apps/app/src/components/Sidebar/AppTitle/AppTitle.module.scss
  20. 17 2
      apps/app/src/components/Sidebar/AppTitle/AppTitle.tsx
  21. 1 0
      apps/app/src/pages/installer.page.tsx
  22. 1 1
      apps/app/src/styles/_fonts.scss
  23. 2 1
      packages/editor/src/components/CodeMirrorEditor/Toolbar/DiagramButton.tsx
  24. 2 0
      packages/editor/src/components/CodeMirrorEditor/Toolbar/TextFormatTools.tsx

+ 1 - 0
apps/app/public/static/locales/en_US/translation.json

@@ -110,6 +110,7 @@
   "Error occurred": "Error occurred",
   "Input page name": "Input page name",
   "Input page name (optional)": "Input page name (optional)",
+  "Input parent page path": "Input parent page path",
   "New Page": "New page",
   "Create under": "Create page under below:",
   "V5 Page Migration": "Convert To V5 Compatibility",

+ 1 - 0
apps/app/public/static/locales/ja_JP/translation.json

@@ -109,6 +109,7 @@
   "Error occurred": "エラーが発生しました",
   "Input page name": "ページ名を入力",
   "Input page name (optional)": "ページ名を入力(空欄OK)",
+  "Input parent page path": "親ページのパスを入力",
   "New Page": "新規ページ",
   "Create under": "ページを以下に作成",
   "V5 Page Migration": "V5 互換形式 への変換",

+ 1 - 0
apps/app/public/static/locales/zh_CN/translation.json

@@ -115,6 +115,7 @@
   "Error occurred": "Error occurred",
   "Input page name": "Input page name",
   "Input page name (optional)": "Input page name (optional)",
+  "Input parent page path": "Input parent page path",
   "New Page": "新页面",
   "Create under": "Create page under below:",
   "V5 Page Migration": "转换为V5的兼容性",

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

@@ -40,7 +40,7 @@ const AppSetting = (props) => {
           <input
             className="form-control"
             type="text"
-            defaultValue={adminAppContainer.state.title || ''}
+            value={adminAppContainer.state.title || ''}
             onChange={(e) => {
               adminAppContainer.changeTitle(e.target.value);
             }}
@@ -60,7 +60,7 @@ const AppSetting = (props) => {
           <input
             className="form-control"
             type="text"
-            defaultValue={adminAppContainer.state.confidential || ''}
+            value={adminAppContainer.state.confidential || ''}
             onChange={(e) => {
               adminAppContainer.changeConfidential(e.target.value);
             }}

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

@@ -93,7 +93,7 @@ const CustomBotWithProxySettings = (props) => {
     <>
       <h2 className="admin-setting-header mb-2">{t('admin:slack_integration.custom_bot_with_proxy_integration')}
         <a href={t('admin:slack_integration.docs_url.custom_bot_with_proxy')} target="_blank" rel="noopener noreferrer">
-          <span className="growi-custom-icons btn-link ms-2 fs-3">external_link</span>
+          <span className="growi-custom-icons btn-link ms-2">external_link</span>
         </a>
       </h2>
 

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

@@ -24,7 +24,7 @@ const CustomBotWithoutProxySettings = (props) => {
     <>
       <h2 className="admin-setting-header">{t('admin:slack_integration.custom_bot_without_proxy_integration')}
         <a href={t('admin:slack_integration.docs_url.custom_bot_without_proxy')} target="_blank" rel="noopener noreferrer">
-          <span className="growi-custom-icons btn-link ms-2 fs-3">external_link</span>
+          <span className="growi-custom-icons btn-link ms-2">external_link</span>
         </a>
       </h2>
 

+ 2 - 2
apps/app/src/components/Admin/SlackIntegration/CustomBotWithoutProxySettingsAccordion.jsx

@@ -78,7 +78,7 @@ const CustomBotWithoutProxySettingsAccordion = (props) => {
         <div className="my-5 d-flex flex-column align-items-center">
           <button type="button" className="btn btn-primary text-nowrap" onClick={() => window.open('https://api.slack.com/apps', '_blank')}>
             {t('admin:slack_integration.accordion.create_bot')}
-            <span className="growi-custom-icons ms-2"><small>external_link</small></span>
+            <span className="growi-custom-icons ms-2">external_link</span>
           </button>
           <a
             href={t('admin:slack_integration.docs_url.custom_bot_without_proxy_setting')}
@@ -88,7 +88,7 @@ const CustomBotWithoutProxySettingsAccordion = (props) => {
             <p className="text-center mt-1">
               <small>
                 {t('admin:slack_integration.accordion.how_to_create_a_bot')}
-                <span className="growi-custom-icons ms-2"><small><small>external_link</small></small></span>
+                <span className="growi-custom-icons ms-2">external_link</span>
               </small>
             </p>
           </a>

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

@@ -78,7 +78,7 @@ const OfficialBotSettings = (props) => {
       <h2 className="admin-setting-header">{t('admin:slack_integration.official_bot_integration')}
         <a href={t('admin:slack_integration.docs_url.official_bot')} target="_blank" rel="noopener noreferrer">
           <span
-            className="growi-custom-icons btn-link ms-2 fs-3"
+            className="growi-custom-icons btn-link ms-2"
             onClick={() => window.open(`${t('admin:slack_integration.docs_url.official_bot')}`, '_blank')}
           >
             external_link

+ 4 - 4
apps/app/src/components/Admin/SlackIntegration/WithProxyAccordions.jsx

@@ -25,7 +25,7 @@ const BotCreateProcess = () => {
     <div className="my-5 d-flex flex-column align-items-center">
       <button type="button" className="btn btn-primary text-nowrap" onClick={() => window.open('https://api.slack.com/apps', '_blank')}>
         {t('admin:slack_integration.accordion.create_bot')}
-        <span className="growi-custom-icons ms-2"><small>external_link</small></span>
+        <span className="growi-custom-icons ms-2">external_link</span>
       </button>
       <a
         href={t('admin:slack_integration.docs_url.custom_bot_with_proxy_setting')}
@@ -35,7 +35,7 @@ const BotCreateProcess = () => {
         <p className="text-center mt-1">
           <small>
             {t('admin:slack_integration.accordion.how_to_create_a_bot')}
-            <span className="growi-custom-icons ms-2"><small><small>external_link</small></small></span>
+            <span className="growi-custom-icons ms-2">external_link</span>
           </small>
         </p>
       </a>
@@ -49,7 +49,7 @@ const BotInstallProcessForOfficialBot = () => {
     <div className="my-5 d-flex flex-column align-items-center">
       <button type="button" className="btn btn-primary text-nowrap" onClick={() => window.open('https://slackbot-proxy.growi.org/', '_blank')}>
         {t('admin:slack_integration.accordion.install_now')}
-        <span className="growi-custom-icons ms-2"><small>external_link</small></span>
+        <span className="growi-custom-icons ms-2">external_link</span>
       </button>
       <a
         href={t('admin:slack_integration.docs_url.official_bot_setting')}
@@ -59,7 +59,7 @@ const BotInstallProcessForOfficialBot = () => {
         <p className="text-center mt-1">
           <small>
             {t('admin:slack_integration.accordion.how_to_install')}
-            <span className="growi-custom-icons ms-2"><small><small>external_link</small></small></span>
+            <span className="growi-custom-icons ms-2">external_link</span>
           </small>
         </p>
       </a>

+ 6 - 2
apps/app/src/components/Common/PagePathHierarchicalLink/PagePathHierarchicalLink.tsx

@@ -13,6 +13,7 @@ type PagePathHierarchicalLinkProps = {
   linkedPagePathByHtml?: LinkedPagePath,
   basePath?: string,
   isInTrash?: boolean,
+  isIconHidden?: boolean,
 
   // !!INTERNAL USE ONLY!!
   isInnerElem?: boolean,
@@ -23,16 +24,18 @@ export const PagePathHierarchicalLink = memo((props: PagePathHierarchicalLinkPro
     linkedPagePath, linkedPagePathByHtml, basePath, isInTrash, isInnerElem,
   } = props;
 
+  const isIconHidden = props.isIconHidden ?? false;
+
   // eslint-disable-next-line react/prop-types
   const RootElm = useCallback(({ children }) => {
     return isInnerElem
       ? <>{children}</>
-      : <span className="text-break">{children}</span>;
+      : <span className="text-break" id="grw-page-path-hierarchical-link">{children}</span>;
   }, [isInnerElem]);
 
   // render root element
   if (linkedPagePath.isRoot) {
-    if (basePath != null) {
+    if (basePath != null || isIconHidden) {
       return <></>;
     }
 
@@ -76,6 +79,7 @@ export const PagePathHierarchicalLink = memo((props: PagePathHierarchicalLinkPro
           basePath={basePath}
           isInTrash={isInTrash || linkedPagePath.isInTrash}
           isInnerElem
+          isIconHidden={isIconHidden}
         />
       ) }
       { isSeparatorRequired && (

+ 2 - 2
apps/app/src/components/Me/UISettings.tsx

@@ -57,7 +57,7 @@ export const UISettings = (): JSX.Element => {
               label="Collapsed"
               additionalClasses={styles['grw-sidebar-mode-icon']}
             >
-              <span className="growi-custom-icons">sidebar-collapsed</span>
+              <span className="growi-custom-icons fs-6">sidebar-collapsed</span>
             </IconWithTooltip>
             <div className="form-check form-switch ms-1">
 
@@ -71,7 +71,7 @@ export const UISettings = (): JSX.Element => {
               <label className="form-label form-check-label" htmlFor="swSidebarMode"></label>
             </div>
             <IconWithTooltip id="iwt-sidebar-dock" label="Dock" additionalClasses={styles['grw-sidebar-mode-icon']}>
-              <span className="growi-custom-icons">sidebar-dock</span>
+              <span className="growi-custom-icons fs-6">sidebar-dock</span>
             </IconWithTooltip>
           </div>
           <div className="ms-2">

+ 1 - 0
apps/app/src/components/Navbar/GrowiContextualSubNavigation.tsx

@@ -295,6 +295,7 @@ const GrowiContextualSubNavigation = (props: GrowiContextualSubNavigationProps):
           d-flex align-items-center justify-content-end px-2 px-sm-3 px-md-4 py-1 gap-2 gap-md-4 d-print-none
         `}
         data-testid="grw-contextual-sub-nav"
+        id="grw-contextual-sub-nav"
       >
         {pageId != null && (
           <PageControls

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

@@ -12,7 +12,7 @@ export const EditorNavbar = (): JSX.Element => {
   const { data: editingUsers } = useEditingUsers();
 
   return (
-    <div className={`${moduleClass} d-flex justify-content-between px-4 py-1`}>
+    <div className={`${moduleClass} d-flex justify-content-between px-4 py-1 ms-3`}>
       <PageHeader />
       <EditingUserList
         userList={editingUsers?.userList ?? []}

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

@@ -17,7 +17,7 @@ export const PageHeader: FC = () => {
   }
 
   return (
-    <div className={moduleClass}>
+    <div className={`${moduleClass} w-100`}>
       <PagePathHeader
         currentPage={currentPage}
       />

+ 1 - 0
apps/app/src/components/PageHeader/PagePathHeader.module.scss

@@ -1,4 +1,5 @@
 .page-path-header :global {
+  max-width: calc(100vw - 650px);
   input {
     min-width: 20px;
     min-height: unset;

+ 43 - 27
apps/app/src/components/PageHeader/PagePathHeader.tsx

@@ -1,5 +1,7 @@
-import { useState, useEffect, useCallback } from 'react';
-import type { FC } from 'react';
+import {
+  useState, useEffect, useCallback, memo, useMemo,
+} from 'react';
+import type { CSSProperties, FC } from 'react';
 
 import type { IPagePopulatedToShowRevision } from '@growi/core';
 import { DevidedPagePath } from '@growi/core/dist/models';
@@ -24,7 +26,7 @@ type Props = {
   currentPage: IPagePopulatedToShowRevision
 }
 
-export const PagePathHeader: FC<Props> = (props) => {
+export const PagePathHeader: FC<Props> = memo((props: Props) => {
   const { t } = useTranslation();
   const { currentPage } = props;
 
@@ -37,6 +39,8 @@ export const PagePathHeader: FC<Props> = (props) => {
   const [isHover, setHover] = useState(false);
   const [editingParentPagePath, setEditingParentPagePath] = useState(parentPagePath);
 
+  // const [isIconHidden, setIsIconHidden] = useState(false);
+
   const { data: PageSelectModalData, open: openPageSelectModal } = usePageSelectModal();
   const isOpened = PageSelectModalData?.isOpened ?? false;
 
@@ -71,22 +75,25 @@ export const PagePathHeader: FC<Props> = (props) => {
     setRenameInputShown(true);
   }, [parentPagePath]);
 
-  const clickOutSideHandler = useCallback((e) => {
-    const container = document.getElementById('page-path-header');
-
-    if (container && !container.contains(e.target)) {
-      setRenameInputShown(false);
-    }
-  }, []);
-
-  useEffect(() => {
-    document.addEventListener('click', clickOutSideHandler);
-
-    return () => {
-      document.removeEventListener('click', clickOutSideHandler);
-    };
-  }, [clickOutSideHandler]);
-
+  // TODO: https://redmine.weseek.co.jp/issues/141062
+  // Truncate left side and don't use getElementById
+  //
+  // useEffect(() => {
+  //   const areaElem = document.getElementById('grw-page-path-header-container');
+  //   const linkElem = document.getElementById('grw-page-path-hierarchical-link');
+
+  //   const areaElemWidth = areaElem?.offsetWidth;
+  //   const linkElemWidth = linkElem?.offsetWidth;
+
+  //   if (areaElemWidth && linkElemWidth) {
+  //     setIsIconHidden(linkElemWidth > areaElemWidth);
+  //   }
+  //   else {
+  //     setIsIconHidden(false);
+  //   }
+  // }, [currentPage]);
+  //
+  // const styles: CSSProperties | undefined = isIconHidden ? { direction: 'rtl' } : undefined;
 
   if (dPagePath.isRoot) {
     return <></>;
@@ -95,27 +102,36 @@ export const PagePathHeader: FC<Props> = (props) => {
   return (
     <div
       id="page-path-header"
-      className={`d-flex ${moduleClass} small`}
+      className={`d-flex ${moduleClass} small position-relative`}
       onMouseEnter={() => setHover(true)}
       onMouseLeave={() => setHover(false)}
     >
-      <div className="me-2">
+      <div
+        id="grw-page-path-header-container"
+        className="me-2 d-inline-block overflow-hidden"
+      >
         { isRenameInputShown && (
-          <div className="position-absolute">
+          <div className="position-absolute w-100">
             <ClosableTextInput
-              useAutosizeInput
               value={editingParentPagePath}
-              placeholder={t('Input page name')}
+              placeholder={t('Input parent page path')}
               inputClassName="form-control-sm"
               onPressEnter={onPressEnter}
               onPressEscape={onPressEscape}
               onChange={onInputChange}
               validationTarget={ValidationTarget.PAGE}
+              onClickOutside={onPressEscape}
             />
           </div>
         ) }
-        <div className={`${isRenameInputShown ? 'invisible' : ''}`}>
-          <PagePathHierarchicalLink linkedPagePath={linkedPagePath} />
+        <div
+          className={`${isRenameInputShown ? 'invisible' : ''} text-truncate`}
+          // style={styles}
+        >
+          <PagePathHierarchicalLink
+            linkedPagePath={linkedPagePath}
+            // isIconHidden={isIconHidden}
+          />
         </div>
       </div>
 
@@ -140,4 +156,4 @@ export const PagePathHeader: FC<Props> = (props) => {
       {isOpened && <PageSelectModal />}
     </div>
   );
-};
+});

+ 1 - 0
apps/app/src/components/PageHeader/PageTitleHeader.module.scss

@@ -1,4 +1,5 @@
 .page-title-header :global {
+  max-width: calc(100vw - 650px);
   input {
     min-width: 20px;
     min-height: unset;

+ 4 - 5
apps/app/src/components/PageHeader/PageTitleHeader.tsx

@@ -70,12 +70,11 @@ export const PageTitleHeader: FC<Props> = (props) => {
 
 
   return (
-    <div className={`d-flex align-items-center ${moduleClass} ${props.className ?? ''}`}>
-      <div className="me-1">
+    <div className={`d-flex ${moduleClass} ${props.className ?? ''} position-relative`}>
+      <div className="me-1 d-inline-block overflow-hidden">
         { isRenameInputShown && (
-          <div className="position-absolute">
+          <div className="position-absolute w-100">
             <ClosableTextInput
-              useAutosizeInput
               value={editedPageTitle}
               placeholder={t('Input page name')}
               inputClassName="fs-4"
@@ -87,7 +86,7 @@ export const PageTitleHeader: FC<Props> = (props) => {
             />
           </div>
         ) }
-        <h1 className={`mb-0 fs-4 ${isRenameInputShown ? 'invisible' : ''}`} onClick={onClickPageTitle}>
+        <h1 className={`mb-0 fs-4 ${isRenameInputShown ? 'invisible' : ''} text-truncate`} onClick={onClickPageTitle}>
           {pageTitle}
         </h1>
       </div>

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

@@ -22,6 +22,10 @@
       padding: (($height - $logomark-height) / 2) (($width - $logomark-width) / 2);
     }
   }
+
+  .confidential-tooltip {
+    max-width: 180px;
+  }
 }
 
 

+ 17 - 2
apps/app/src/components/Sidebar/AppTitle/AppTitle.tsx

@@ -1,8 +1,9 @@
 import React, { memo } from 'react';
 
 import Link from 'next/link';
+import { UncontrolledTooltip } from 'reactstrap';
 
-import { useAppTitle, useIsDefaultLogo } from '~/stores/context';
+import { useAppTitle, useConfidential, useIsDefaultLogo } from '~/stores/context';
 
 import { SidebarBrandLogo } from '../SidebarBrandLogo';
 
@@ -19,6 +20,7 @@ const AppTitleSubstance = memo((props: Props): JSX.Element => {
 
   const { data: isDefaultLogo } = useIsDefaultLogo();
   const { data: appTitle } = useAppTitle();
+  const { data: confidential } = useConfidential();
 
   return (
     <div className={`${styles['grw-app-title']} ${className} d-flex d-edit-none`}>
@@ -27,12 +29,25 @@ const AppTitleSubstance = memo((props: Props): JSX.Element => {
         <SidebarBrandLogo isDefaultLogo={isDefaultLogo} />
       </Link>
       <div className="flex-grow-1 d-flex align-items-center justify-content-between gap-3 overflow-hidden">
-        <div className="grw-site-name text-truncate">
+        <div id="grw-site-name" className="grw-site-name text-truncate">
           <Link href="/" className="fs-4">
             {appTitle}
           </Link>
         </div>
       </div>
+      {!(confidential == null || confidential === '')
+      && (
+        <UncontrolledTooltip
+          className="d-none d-sm-block confidential-tooltip"
+          innerClassName="text-start"
+          data-testid="confidential-tooltip"
+          placement="top"
+          target="grw-site-name"
+          fade={false}
+        >
+          {confidential}
+        </UncontrolledTooltip>
+      )}
     </div>
   );
 });

+ 1 - 0
apps/app/src/pages/installer.page.tsx

@@ -47,6 +47,7 @@ const InstallerPage: NextPage<Props> = (props: Props) => {
         i18n: t('installer.tab'),
       },
       external_accounts: {
+        // TODO: chack and fix font-size. see: https://redmine.weseek.co.jp/issues/143015
         Icon: () => <span className="growi-custom-icons me-2">external_link</span>,
         Content: DataTransferForm,
         i18n: tCommons('g2g_data_transfer.tab'),

+ 1 - 1
apps/app/src/styles/_fonts.scss

@@ -25,7 +25,7 @@
 
 .growi-custom-icons {
   font-family: var(--grw-font-family-custom-icon);
-  font-size: 16px;
+  font-size: 0.8em;
   font-style: normal;
   -webkit-font-smoothing: auto;
   -moz-osx-font-smoothing: auto;

+ 2 - 1
packages/editor/src/components/CodeMirrorEditor/Toolbar/DiagramButton.tsx

@@ -14,7 +14,8 @@ export const DiagramButton = (props: Props): JSX.Element => {
   }, [editorKey, openDrawioModal]);
   return (
     <button type="button" className="btn btn-toolbar-button" onClick={onClickDiagramButton}>
-      <span className="growi-custom-icons">drawer_io</span>
+      {/* TODO: chack and fix font-size. see: https://redmine.weseek.co.jp/issues/143015 */}
+      <span className="growi-custom-icons fs-6">drawer_io</span>
     </button>
   );
 };

+ 2 - 0
packages/editor/src/components/CodeMirrorEditor/Toolbar/TextFormatTools.tsx

@@ -69,6 +69,7 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
             <span className="material-symbols-outlined fs-5">format_strikethrough</span>
           </button>
           <button type="button" className="btn btn-toolbar-button" onClick={() => onClickInsertPrefix('#', true)}>
+            {/* TODO: chack and fix font-size. see: https://redmine.weseek.co.jp/issues/143015 */}
             <span className="growi-custom-icons">header</span>
           </button>
           <button type="button" className="btn btn-toolbar-button" onClick={() => onClickInsertMarkdownElements('`', '`')}>
@@ -81,6 +82,7 @@ export const TextFormatTools = (props: TextFormatToolsType): JSX.Element => {
             <span className="material-symbols-outlined fs-5">format_list_numbered</span>
           </button>
           <button type="button" className="btn btn-toolbar-button" onClick={() => onClickInsertPrefix('>')}>
+            {/* TODO: chack and fix font-size. see: https://redmine.weseek.co.jp/issues/143015 */}
             <span className="growi-custom-icons">format_quote</span>
           </button>
           <button type="button" className="btn btn-toolbar-button" onClick={() => onClickInsertPrefix('- [ ]')}>