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

Merge branch 'support/apply-bootstrap4' into support/apply-bst4-PageRevisionList.jsx-mod-max-len

Yuki Takei 6 лет назад
Родитель
Сommit
043dac7e05

+ 15 - 16
src/client/js/components/Admin/Users/UserInviteModal.jsx

@@ -6,7 +6,7 @@ import { CopyToClipboard } from 'react-copy-to-clipboard';
 
 
 // import Button from 'react-bootstrap/es/Button';
 // import Button from 'react-bootstrap/es/Button';
 import {
 import {
-  Modal, ModalHeader, ModalBody, ModalFooter, Button,
+  Modal, ModalHeader, ModalBody, ModalFooter,
 } from 'reactstrap';
 } from 'reactstrap';
 
 
 import { toastSuccess, toastError } from '../../../util/apiNotification';
 import { toastSuccess, toastError } from '../../../util/apiNotification';
@@ -85,17 +85,17 @@ class UserInviteModal extends React.Component {
           </label>
           </label>
         </div>
         </div>
         <div>
         <div>
-          <Button bsStyle="danger" className="fcbtn btn btn-xs btn-danger btn-outline btn-rounded" onClick={this.onToggleModal}>
-          Cancel
-          </Button>
-          <Button
-            bsStyle="primary"
-            className="fcbtn btn btn-primary btn-outline btn-rounded btn-1b"
+          <button type="button" className="fcbtn btn btn-xs btn-outline-secondary" onClick={this.onToggleModal}>
+            Cancel
+          </button>
+          <button
+            type="button"
+            className="fcbtn btn btn-primary btn-1b"
             onClick={this.handleSubmit}
             onClick={this.handleSubmit}
             disabled={!this.validEmail()}
             disabled={!this.validEmail()}
           >
           >
-          Done
-          </Button>
+            Invite
+          </button>
         </div>
         </div>
       </>
       </>
     );
     );
@@ -109,13 +109,13 @@ class UserInviteModal extends React.Component {
         <label className="mr-3 text-left text-danger" style={{ flex: 1 }}>
         <label className="mr-3 text-left text-danger" style={{ flex: 1 }}>
           {t('user_management.send_temporary_password')}
           {t('user_management.send_temporary_password')}
         </label>
         </label>
-        <Button
-          bsStyle="primary"
-          className="fcbtn btn btn-primary btn-outline btn-rounded"
+        <button
+          type="button"
+          className="fcbtn btn btn-primary"
           onClick={this.onToggleModal}
           onClick={this.onToggleModal}
         >
         >
           Close
           Close
-        </Button>
+        </button>
       </>
       </>
     );
     );
   }
   }
@@ -188,8 +188,8 @@ class UserInviteModal extends React.Component {
 
 
 
 
     return (
     return (
-      <Modal isOpen={adminUsersContainer.state.isUserInviteModalShown} toggle={this.props.onToggleModal}>
-        <ModalHeader toggle={this.props.onToggleModal} className="modal-header">
+      <Modal isOpen={adminUsersContainer.state.isUserInviteModalShown} toggle={this.onToggleModal}>
+        <ModalHeader toggle={this.onToggleModal} className="modal-header">
           { t('user_management.invite_users') }
           { t('user_management.invite_users') }
         </ModalHeader>
         </ModalHeader>
         <ModalBody>
         <ModalBody>
@@ -218,7 +218,6 @@ UserInviteModal.propTypes = {
   t: PropTypes.func.isRequired, // i18next
   t: PropTypes.func.isRequired, // i18next
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   appContainer: PropTypes.instanceOf(AppContainer).isRequired,
   adminUsersContainer: PropTypes.instanceOf(AdminUsersContainer).isRequired,
   adminUsersContainer: PropTypes.instanceOf(AdminUsersContainer).isRequired,
-  onToggleModal: PropTypes.func.isRequired, // for cancel evnet handling
 };
 };
 
 
 export default withTranslation()(UserInviteModalWrapper);
 export default withTranslation()(UserInviteModalWrapper);

+ 13 - 22
src/client/js/components/PageComment/Comment.jsx

@@ -3,13 +3,10 @@ import PropTypes from 'prop-types';
 
 
 import { format, formatDistanceStrict } from 'date-fns';
 import { format, formatDistanceStrict } from 'date-fns';
 
 
-// TODO: GW-333
-// import Tooltip from 'react-bootstrap/es/Tooltip';
-// import OverlayTrigger from 'react-bootstrap/es/OverlayTrigger';
-
 import {
 import {
   Button,
   Button,
   Collapse,
   Collapse,
+  UncontrolledTooltip,
 } from 'reactstrap';
 } from 'reactstrap';
 
 
 import AppContainer from '../../services/AppContainer';
 import AppContainer from '../../services/AppContainer';
@@ -266,23 +263,17 @@ class Comment extends React.Component {
     const showReEditor = this.state.showReEditorIds.has(commentId);
     const showReEditor = this.state.showReEditorIds.has(commentId);
 
 
     const rootClassName = this.getRootClassName(comment);
     const rootClassName = this.getRootClassName(comment);
-    const commentDate = formatDistanceStrict(createdAt, new Date());
     const commentBody = isMarkdown ? this.renderRevisionBody() : this.renderText(comment.comment);
     const commentBody = isMarkdown ? this.renderRevisionBody() : this.renderText(comment.comment);
     const revHref = `?revision=${comment.revision}`;
     const revHref = `?revision=${comment.revision}`;
     const revFirst8Letters = comment.revision.substr(-8);
     const revFirst8Letters = comment.revision.substr(-8);
     const revisionLavelClassName = this.getRevisionLabelClassName();
     const revisionLavelClassName = this.getRevisionLabelClassName();
 
 
-    const commentDateTooltip = (
-      <Tooltip id={`commentDateTooltip-${comment._id}`}>
-        {format(createdAt, 'yyyy/MM/dd HH:mm')}
-      </Tooltip>
-    );
-    const editedDateTooltip = isEdited
-      ? (
-        <Tooltip id={`editedDateTooltip-${comment._id}`}>
-          {format(updatedAt, 'yyyy/MM/dd HH:mm')}
-        </Tooltip>
-      )
+    const commentedDateId = `commentDate-${comment._id}`;
+    const commentedDate = <span id={commentedDateId}>{formatDistanceStrict(createdAt, new Date())}</span>;
+    const commentedDateFormatted = format(createdAt, 'yyyy/MM/dd HH:mm');
+    const editedDateId = `editedDate-${comment._id}`;
+    const editedDateFormatted = isEdited
+      ? format(updatedAt, 'yyyy/MM/dd HH:mm')
       : null;
       : null;
 
 
     return (
     return (
@@ -306,13 +297,13 @@ class Comment extends React.Component {
               </div>
               </div>
               <div className="page-comment-body">{commentBody}</div>
               <div className="page-comment-body">{commentBody}</div>
               <div className="page-comment-meta">
               <div className="page-comment-meta">
-                <OverlayTrigger overlay={commentDateTooltip} placement="bottom">
-                  <span>{commentDate}</span>
-                </OverlayTrigger>
+                {commentedDate}
+                <UncontrolledTooltip placement="bottom" fade={false} target={commentedDateId}>{commentedDateFormatted}</UncontrolledTooltip>
                 { isEdited && (
                 { isEdited && (
-                  <OverlayTrigger overlay={editedDateTooltip} placement="bottom">
-                    <span>&nbsp;(edited)</span>
-                  </OverlayTrigger>
+                  <>
+                    <span id={editedDateId}>&nbsp;(edited)</span>
+                    <UncontrolledTooltip placement="bottom" fade={false} target={editedDateId}>{editedDateFormatted}</UncontrolledTooltip>
+                  </>
                 ) }
                 ) }
                 <span className="ml-2"><a className={revisionLavelClassName} href={revHref}>{revFirst8Letters}</a></span>
                 <span className="ml-2"><a className={revisionLavelClassName} href={revHref}>{revFirst8Letters}</a></span>
               </div>
               </div>

+ 36 - 24
src/client/js/components/PageComment/CommentEditor.jsx

@@ -1,12 +1,9 @@
 import React from 'react';
 import React from 'react';
 import PropTypes from 'prop-types';
 import PropTypes from 'prop-types';
 
 
-// TODO: GW-333
-// import Tab from 'react-bootstrap/es/Tab';
-// import Tabs from 'react-bootstrap/es/Tabs';
-
 import {
 import {
   Button,
   Button,
+  TabContent, TabPane, Nav, NavItem, NavLink,
 } from 'reactstrap';
 } from 'reactstrap';
 
 
 import * as toastr from 'toastr';
 import * as toastr from 'toastr';
@@ -44,7 +41,7 @@ class CommentEditor extends React.Component {
       comment: this.props.commentBody || '',
       comment: this.props.commentBody || '',
       isMarkdown: true,
       isMarkdown: true,
       html: '',
       html: '',
-      key: 1,
+      activeTab: 1,
       isUploadable,
       isUploadable,
       isUploadableFile,
       isUploadableFile,
       errorMessage: undefined,
       errorMessage: undefined,
@@ -75,8 +72,8 @@ class CommentEditor extends React.Component {
     this.editor.setGfmMode(value);
     this.editor.setGfmMode(value);
   }
   }
 
 
-  handleSelect(key) {
-    this.setState({ key });
+  handleSelect(activeTab) {
+    this.setState({ activeTab });
     this.renderHtml(this.state.comment);
     this.renderHtml(this.state.comment);
   }
   }
 
 
@@ -98,7 +95,7 @@ class CommentEditor extends React.Component {
       comment: '',
       comment: '',
       isMarkdown: true,
       isMarkdown: true,
       html: '',
       html: '',
-      key: 1,
+      activeTab: 1,
       errorMessage: undefined,
       errorMessage: undefined,
     });
     });
     // reset value
     // reset value
@@ -217,6 +214,8 @@ class CommentEditor extends React.Component {
 
 
   render() {
   render() {
     const { appContainer, commentContainer } = this.props;
     const { appContainer, commentContainer } = this.props;
+    const { activeTab } = this.state;
+
     const username = appContainer.me;
     const username = appContainer.me;
     const user = appContainer.findUser(username);
     const user = appContainer.findUser(username);
     const commentPreview = this.state.isMarkdown ? this.getCommentHtml() : null;
     const commentPreview = this.state.isMarkdown ? this.getCommentHtml() : null;
@@ -226,6 +225,11 @@ class CommentEditor extends React.Component {
     const isBaloonStyle = layoutType.match(/crowi-plus|growi|kibela/);
     const isBaloonStyle = layoutType.match(/crowi-plus|growi|kibela/);
 
 
     const errorMessage = <span className="text-danger text-right mr-2">{this.state.errorMessage}</span>;
     const errorMessage = <span className="text-danger text-right mr-2">{this.state.errorMessage}</span>;
+    const cancelButton = (
+      <Button outline color="danger" size="xs" className="fcbtn btn-rounded" onClick={this.toggleEditor}>
+        Cancel
+      </Button>
+    );
     const submitButton = (
     const submitButton = (
       <Button
       <Button
         outline
         outline
@@ -247,8 +251,20 @@ class CommentEditor extends React.Component {
           ) }
           ) }
           <div className="comment-form-main">
           <div className="comment-form-main">
             <div className="comment-write">
             <div className="comment-write">
-              <Tabs activeKey={this.state.key} id="comment-form-tabs" onSelect={this.handleSelect} animation={false}>
-                <Tab eventKey={1} title="Write">
+              <Nav tabs>
+                <NavItem>
+                  <NavLink type="button" className={activeTab === 1 ? 'active' : ''} onClick={() => this.handleSelect(1)}>
+                    Write
+                  </NavLink>
+                </NavItem>
+                <NavItem>
+                  <NavLink type="button" className={activeTab === 2 ? 'active' : ''} onClick={() => this.handleSelect(2)}>
+                    Preview
+                  </NavLink>
+                </NavItem>
+              </Nav>
+              <TabContent activeTab={activeTab}>
+                <TabPane tabId={1}>
                   <Editor
                   <Editor
                     ref={(c) => { this.editor = c }}
                     ref={(c) => { this.editor = c }}
                     value={this.state.comment}
                     value={this.state.comment}
@@ -262,20 +278,20 @@ class CommentEditor extends React.Component {
                     onUpload={this.uploadHandler}
                     onUpload={this.uploadHandler}
                     onCtrlEnter={this.postHandler}
                     onCtrlEnter={this.postHandler}
                   />
                   />
-                </Tab>
+                </TabPane>
                 { this.state.isMarkdown && (
                 { this.state.isMarkdown && (
-                  <Tab eventKey={2} title="Preview">
+                  <TabPane tabId={2}>
                     <div className="comment-form-preview">
                     <div className="comment-form-preview">
                       {commentPreview}
                       {commentPreview}
                     </div>
                     </div>
-                  </Tab>
+                  </TabPane>
                 ) }
                 ) }
-              </Tabs>
+              </TabContent>
             </div>
             </div>
             <div className="comment-submit">
             <div className="comment-submit">
               <div className="d-flex">
               <div className="d-flex">
                 <label style={{ flex: 1 }}>
                 <label style={{ flex: 1 }}>
-                  { isBaloonStyle && this.state.key === 1 && (
+                  { isBaloonStyle && activeTab === 1 && (
                     <span>
                     <span>
                       <input
                       <input
                         type="checkbox"
                         type="checkbox"
@@ -289,7 +305,7 @@ class CommentEditor extends React.Component {
                     </span>
                     </span>
                   ) }
                   ) }
                 </label>
                 </label>
-                <span className="hidden-xs">{ this.state.errorMessage && errorMessage }</span>
+                <span className="d-none d-sm-inline">{ this.state.errorMessage && errorMessage }</span>
                 { this.state.hasSlackConfig
                 { this.state.hasSlackConfig
                   && (
                   && (
                   <div className="form-inline align-self-center mr-md-2">
                   <div className="form-inline align-self-center mr-md-2">
@@ -302,18 +318,14 @@ class CommentEditor extends React.Component {
                   </div>
                   </div>
                   )
                   )
                 }
                 }
-                <div>
-                  <Button outline color="danger" size="xs" className="fcbtn btn-rounded" onClick={this.toggleEditor}>
-                    Cancel
-                  </Button>
+                <div className="d-none d-sm-block">
+                  <span className="mr-2">{cancelButton}</span><span>{submitButton}</span>
                 </div>
                 </div>
-                &nbsp;&nbsp;&nbsp;&nbsp;
-                <div className="hidden-xs">{submitButton}</div>
               </div>
               </div>
-              <div className="visible-xs mt-2">
+              <div className="d-block d-sm-none mt-2">
                 <div className="d-flex justify-content-end">
                 <div className="d-flex justify-content-end">
                   { this.state.errorMessage && errorMessage }
                   { this.state.errorMessage && errorMessage }
-                  <div>{submitButton}</div>
+                  <span className="mr-2">{cancelButton}</span><span>{submitButton}</span>
                 </div>
                 </div>
               </div>
               </div>
             </div>
             </div>