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

Merge pull request #2298 from weseek/impl/reactify-tooltip

Impl/reactify tooltip
Yuki Takei 5 лет назад
Родитель
Сommit
d12507529f

+ 1 - 0
CHANGES.md

@@ -7,6 +7,7 @@
 * Fix: Storing the state of sidebar
 * Fix: Comments order should be asc
 * Fix: Show/Hide replies button doesn't work
+* Fix: Tooltip doesn't work
 * Fix: Change the display of the scroll bar when modal is shown
 * Fix: Submit with enter key on Create/Rename modals
 * Fix: Show/Hide Unlink redirection button conditions

+ 12 - 11
src/client/js/components/Admin/Notification/GlobalNotificationList.jsx

@@ -9,7 +9,9 @@ import { toastSuccess, toastError } from '../../../util/apiNotification';
 
 import AppContainer from '../../../services/AppContainer';
 import AdminNotificationContainer from '../../../services/AdminNotificationContainer';
+
 import NotificationDeleteModal from './NotificationDeleteModal';
+import NotificationTypeIcon from './NotificationTypeIcon';
 
 const logger = loggerFactory('growi:GolobalNotificationList');
 
@@ -91,44 +93,43 @@ class GlobalNotificationList extends React.Component {
                 {notification.triggerPath}
               </td>
               <td>
-                <ul className="list-inline">
+                <ul className="list-inline mb-0">
                   {notification.triggerEvents.includes('pageCreate') && (
-                  <li className="list-inline-item badge badge-pill badge-success" data-toggle="tooltip" data-placement="top" title="Page Create">
+                  <li className="list-inline-item badge badge-pill badge-success">
                     <i className="icon-doc"></i> CREATE
                   </li>
                 )}
                   {notification.triggerEvents.includes('pageEdit') && (
-                  <li className="list-inline-item badge badge-pill badge-warning" data-toggle="tooltip" data-placement="top" title="Page Edit">
+                  <li className="list-inline-item badge badge-pill badge-warning">
                     <i className="icon-pencil"></i> EDIT
                   </li>
                 )}
                   {notification.triggerEvents.includes('pageMove') && (
-                  <li className="list-inline-item badge badge-pill badge-pink" data-toggle="tooltip" data-placement="top" title="Page Move">
+                  <li className="list-inline-item badge badge-pill badge-pink">
                     <i className="icon-action-redo"></i> MOVE
                   </li>
                 )}
                   {notification.triggerEvents.includes('pageDelete') && (
-                  <li className="list-inline-item badge badge-pill badge-danger" data-toggle="tooltip" data-placement="top" title="Page Delte">
+                  <li className="list-inline-item badge badge-pill badge-danger">
                     <i className="icon-fire"></i> DELETE
                   </li>
                 )}
                   {notification.triggerEvents.includes('pageLike') && (
-                  <li className="list-inline-item badge badge-pill badge-info" data-toggle="tooltip" data-placement="top" title="Page Like">
+                  <li className="list-inline-item badge badge-pill badge-info">
                     <i className="icon-like"></i> LIKE
                   </li>
                 )}
                   {notification.triggerEvents.includes('comment') && (
-                  <li className="list-inline-item badge badge-pill badge-secondary" data-toggle="tooltip" data-placement="top" title="New Comment">
+                  <li className="list-inline-item badge badge-pill badge-secondary">
                     <i className="icon-fw icon-bubble"></i> POST
                   </li>
                 )}
                 </ul>
               </td>
               <td>
-                {notification.__t === 'mail'
-                  && <span data-toggle="tooltip" data-placement="top" title="Email"><i className="ti-email"></i> {notification.toEmail}</span>}
-                {notification.__t === 'slack'
-                  && <span data-toggle="tooltip" data-placement="top" title="Slack"><i className="fa fa-hashtag"></i> {notification.slackChannels}</span>}
+                <NotificationTypeIcon notification={notification} />
+                { notification.__t === 'mail' && notification.toEmail }
+                { notification.__t === 'slack' && notification.slackChannels }
               </td>
               <td className="td-abs-center">
                 <div className="dropdown">

+ 43 - 0
src/client/js/components/Admin/Notification/NotificationTypeIcon.jsx

@@ -0,0 +1,43 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+
+import { UncontrolledTooltip } from 'reactstrap';
+
+const SlackIcon = (props) => {
+  const { __t, _id, provider } = props.notification;
+
+  let type = 'slack';
+
+  // User trigger notification
+  if (provider != null) {
+    // only slack type
+  }
+
+  // Global notification
+  if (__t != null) {
+    if (__t === 'mail') {
+      type = 'mail';
+    }
+  }
+
+  const elemId = `notification-${type}-${_id}`;
+  const className = type === 'mail'
+    ? 'icon-fw fa fa-envelope-o'
+    : 'icon-fw fa fa-hashtag';
+
+  return (
+    <>
+      <i id={elemId} className={className}></i>
+      <UncontrolledTooltip target={elemId}>Slack</UncontrolledTooltip>
+    </>
+  );
+};
+
+SlackIcon.propTypes = {
+  // supports 2 types:
+  //   User trigger notification -> has 'provider: slack'
+  //   Global notification -> has '__t: slack|mail'
+  notification: PropTypes.object.isRequired,
+};
+
+export default SlackIcon;

+ 5 - 2
src/client/js/components/Admin/Notification/UserNotificationRow.jsx

@@ -7,19 +7,22 @@ import { createSubscribedElement } from '../../UnstatedUtils';
 import AppContainer from '../../../services/AppContainer';
 import AdminNotificationContainer from '../../../services/AdminNotificationContainer';
 
+import NotificationTypeIcon from './NotificationTypeIcon';
 
 class UserNotificationRow extends React.PureComponent {
 
   render() {
     const { t, notification } = this.props;
+    const id = `user-notification-${notification._id}`;
+
     return (
       <React.Fragment>
-        <tr className="admin-notif-row" key={notification._id}>
+        <tr className="admin-notif-row" key={id}>
           <td className="px-4">
             {notification.pathPattern}
           </td>
           <td className="px-4">
-            <span data-toggle="tooltip" data-placement="top" title="Slack"><i className="fa fa-hashtag"></i> {notification.channel}</span>
+            <NotificationTypeIcon notification={notification} />{notification.channel}
           </td>
           <td>
             <button type="submit" className="btn btn-outline-danger" onClick={() => { this.props.onClickDeleteBtn(notification._id) }}>{t('Delete')}</button>

+ 10 - 2
src/client/js/components/User/UserPicture.jsx

@@ -4,6 +4,8 @@ import PropTypes from 'prop-types';
 
 import { userPageRoot } from '@commons/util/path-utils';
 
+import { UncontrolledTooltip } from 'reactstrap';
+
 const DEFAULT_IMAGE = '/images/icons/user.svg';
 
 // TODO UserComponent?
@@ -64,10 +66,16 @@ export default class UserPicture extends React.Component {
 
   withTooltip = (RootElm) => {
     const { user } = this.props;
-    const title = `@${user.username}<br />${user.name}`;
+    const id = `user-picture-${Math.random().toString(32).substring(2)}`;
 
     return props => (
-      <RootElm data-toggle="tooltip" data-placement="bottom" data-html="true" title={title}>{props.children}</RootElm>
+      <>
+        <RootElm id={id}>{props.children}</RootElm>
+        <UncontrolledTooltip placement="bottom" target={id}>
+          @{user.username}<br />
+          {user.name}
+        </UncontrolledTooltip>
+      </>
     );
   }
 

+ 8 - 4
src/client/styles/scss/_admin.scss

@@ -47,10 +47,14 @@
   }
 
   .admin-notification {
-    .td-abs-center {
-      width: 1px; // to keep the cell small
-      text-align: center;
-      vertical-align: middle;
+    table .admin-notif-list {
+      td {
+        vertical-align: middle;
+      }
+      .td-abs-center {
+        width: 1px; // to keep the cell small
+        text-align: center;
+      }
     }
   }