Browse Source

PopinFixedContent now have its right part hidable + Timeline handles hidable

Skylsmoi 5 years ago
parent
commit
388b4c4de6

+ 1 - 1
package.json View File

@@ -6,7 +6,7 @@
6 6
     "mockapi": "node jsonserver/server.js",
7 7
     "servdev": "NODE_ENV=development webpack-dev-server --watch --colors --inline --hot --progress",
8 8
     "servdevwindoz": "set NODE_ENV=development&& webpack-dev-server --watch --colors --inline --hot --progress",
9
-    "servdev-dashboard": "NODE_ENV=development webpack-dashboard -m -p 9871 -- webpack-dev-server --watch --colors --inline --hot --progress",
9
+    "servdev-dashboard": "NODE_ENV=development webpack-dashboard -m -p 9870 -- webpack-dev-server --watch --colors --inline --hot --progress",
10 10
     "buildwindoz": "set NODE_ENV=production&& webpack -p",
11 11
     "build": "NODE_ENV=production webpack -p",
12 12
     "buildtracimlib": "NODE_ENV=production webpack -p && echo '/* eslint-disable */' | cat - dist/tracim_lib.js > temp && mv temp dist/tracim_lib.js && printf '\n/* eslint-enable */\n' >> dist/tracim_lib.js",

+ 1 - 0
src/component/Input/SelectStatus/SelectStatus.jsx View File

@@ -19,6 +19,7 @@ export const SelectStatus = props => {
19 19
         style={{color: props.selectedStatus ? props.selectedStatus.hexcolor : 'transparent'}}
20 20
         disabled={props.disabled}
21 21
       >
22
+        <span className='selectStatus__dropdownbtn__label'>Status :</span>
22 23
         {props.selectedStatus ? props.selectedStatus.label : ''}
23 24
         <div className='selectStatus__dropdownbtn__icon'>
24 25
           <i className={`fa fa-${props.selectedStatus ? props.selectedStatus.faIcon : ''}`} />

+ 3 - 0
src/component/Input/SelectStatus/SelectStatus.styl View File

@@ -9,6 +9,9 @@
9 9
       color fontColor
10 10
     &:hover
11 11
       background-color transparent
12
+    &__label
13
+      margin-right 10px
14
+      color #333
12 15
     &__icon
13 16
       display inline-block
14 17
       margin 0 15px

+ 12 - 3
src/component/PopinFixed/PopinFixed.styl View File

@@ -85,14 +85,23 @@
85 85
     display flex
86 86
     flex-wrap wrap
87 87
     // 209 = wsContentGeneric:top wsContentGeneric__header:height - wsContentGeneric__option:height
88
+    width 200% // to allow transform translateX of right part
88 89
     height calc(100% - 209px)
89 90
     &__left
90
-      width 55%
91
-      height calc(100% - 20px) // 20px => margin of timeline
91
+      transition width 0.4s ease
92
+      width 25%
93
+      height calc(100% - 10px) // 10px => margin of timeline
92 94
     &__right
93
-      width 45%
95
+      transition width 0.4s ease
96
+      width calc(25% - 10px)
94 97
       height calc(100% - 10px) // 10px => margin of timeline
95 98
 
99
+.rightPartClose
100
+  .wsContentGeneric__content__left
101
+    width calc(50% - 50px)
102
+  //.wsContentGeneric__content__right
103
+  //  width 50px // 50px is the width of the rightPart header (eg. timeline__header)
104
+
96 105
 @media (min-width: min-sm) and (max-width: max-lg)
97 106
 
98 107
   .wsContentGeneric__content

+ 40 - 16
src/component/PopinFixed/PopinFixedContent.jsx View File

@@ -2,24 +2,48 @@ import React from 'react'
2 2
 import classnames from 'classnames'
3 3
 import PropTypes from 'prop-types'
4 4
 
5
-const PopinFixedContent = props => {
6
-  return props.children.length === 2
7
-    ? (
8
-      <div className={classnames('wsContentGeneric__content', `${props.customClass}__content`)}>
9
-        <div className={classnames('wsContentGeneric__content__left', `${props.customClass}__content__left`)}>
10
-          {props.children[0]}
11
-        </div>
5
+class PopinFixedContent extends React.Component {
6
+  constructor (props) {
7
+    super(props)
8
+    this.state = {
9
+      rightPartOpen: false
10
+    }
11
+  }
12
+
13
+  componentDidMount () {
14
+    if (this.props.showRightPartOnLoad) this.setState({rightPartOpen: true})
15
+  }
12 16
 
13
-        <div className={classnames('wsContentGeneric__content__right', `${props.customClass}__content__right`)}>
14
-          {props.children[1]}
17
+  handleToggleRightPart = () => {
18
+    this.setState(prev => ({rightPartOpen: !prev.rightPartOpen}))
19
+  }
20
+
21
+  render () {
22
+    return this.props.children.length === 2
23
+      ? (
24
+        <div className={classnames(
25
+          'wsContentGeneric__content',
26
+          `${this.props.customClass}__content`,
27
+          {'rightPartOpen': this.state.rightPartOpen, 'rightPartClose': !this.state.rightPartOpen}
28
+        )}>
29
+          <div className={classnames('wsContentGeneric__content__left', `${this.props.customClass}__content__left`)}>
30
+            {this.props.children[0]}
31
+          </div>
32
+
33
+          <div className={classnames('wsContentGeneric__content__right', `${this.props.customClass}__content__right`)}>
34
+            {React.cloneElement(this.props.children[1], {
35
+              toggleRightPart: this.handleToggleRightPart,
36
+              rightPartOpen: this.state.rightPartOpen
37
+            })}
38
+          </div>
15 39
         </div>
16
-      </div>
17
-    )
18
-    : (
19
-      <div className={classnames('wsContentGeneric__content', `${props.customClass}__content`)}>
20
-        { props.children }
21
-      </div>
22
-    )
40
+      )
41
+      : (
42
+        <div className={classnames('wsContentGeneric__content', `${this.props.customClass}__content`)}>
43
+          {this.props.children}
44
+        </div>
45
+      )
46
+  }
23 47
 }
24 48
 
25 49
 export default PopinFixedContent

+ 5 - 5
src/component/Timeline/Comment.jsx View File

@@ -4,22 +4,22 @@ import classnames from 'classnames'
4 4
 const Comment = props => (
5 5
   <li className={classnames(
6 6
     `${props.customClass}__messagelist__item`,
7
-    'timeline__messagelist__item', {
7
+    'timeline__body__messagelist__item', {
8 8
       'received': props.fromMe, // @FIXME : invert names of class (received should be !fromMe)
9 9
       'sended': !props.fromMe
10 10
     }
11 11
   )}>
12
-    <div className={classnames(`${props.customClass}__messagelist__item__wrapper`, 'timeline__messagelist__item__wrapper')}>
13
-      <div className={classnames(`${props.customClass}__messagelist__item__avatar`, 'timeline__messagelist__item__avatar')}>
12
+    <div className={classnames(`${props.customClass}__messagelist__item__wrapper`, 'timeline__body__messagelist__item__wrapper')}>
13
+      <div className={classnames(`${props.customClass}__messagelist__item__avatar`, 'timeline__body__messagelist__item__avatar')}>
14 14
         {props.avatar ? <img src={props.avatar} /> : ''}
15 15
       </div>
16 16
     </div>
17 17
     <div
18
-      className={classnames(`${props.customClass}__messagelist__item__createhour`, 'timeline__messagelist__item__createhour')}>
18
+      className={classnames(`${props.customClass}__messagelist__item__createhour`, 'timeline__body__messagelist__item__createhour')}>
19 19
       {props.createdAt}
20 20
     </div>
21 21
     <div
22
-      className={classnames(`${props.customClass}__messagelist__item__content`, 'timeline__messagelist__item__content')}
22
+      className={classnames(`${props.customClass}__messagelist__item__content`, 'timeline__body__messagelist__item__content')}
23 23
       dangerouslySetInnerHTML={{__html: props.text}}
24 24
     />
25 25
   </li>

+ 3 - 3
src/component/Timeline/Revision.jsx View File

@@ -2,17 +2,17 @@ import React from 'react'
2 2
 import classnames from 'classnames'
3 3
 
4 4
 const Revision = props => (
5
-  <li className={classnames(`${props.customClass}__messagelist__version`, 'timeline__messagelist__version')} >
5
+  <li className={classnames(`${props.customClass}__messagelist__version`, 'timeline__body__messagelist__version')} >
6 6
     <button
7 7
       type='button'
8
-      className={classnames(`${props.customClass}__messagelist__version__btn`, 'timeline__messagelist__version__btn btn')}
8
+      className={classnames(`${props.customClass}__messagelist__version__btn`, 'timeline__body__messagelist__version__btn btn')}
9 9
       onClick={props.onClickRevision}
10 10
     >
11 11
       <i className='fa fa-code-fork' />
12 12
       version {props.number}
13 13
     </button>
14 14
 
15
-    <div className={classnames(`${props.customClass}__messagelist__version__date`, 'timeline__messagelist__version__date')}>
15
+    <div className={classnames(`${props.customClass}__messagelist__version__date`, 'timeline__body__messagelist__version__date')}>
16 16
       Créé le {props.createdAt}
17 17
     </div>
18 18
   </li>

+ 69 - 64
src/component/Timeline/Timeline.jsx View File

@@ -26,80 +26,85 @@ class Timeline extends React.Component {
26 26
     }
27 27
 
28 28
     return (
29
-      <div className='timeline'>
29
+      <div className={classnames('timeline')}>
30 30
         {props.showHeader &&
31
-          <div className={classnames(`${props.customClass}__header`, 'timeline__header')}>
32
-            Timeline
31
+          <div
32
+            className={classnames(`${props.customClass}__header`, 'timeline__header')}
33
+            onClick={props.toggleRightPart}
34
+          >
35
+            <span className='timeline__header__text'>Timeline</span>
33 36
           </div>
34 37
         }
35 38
 
36
-        <ul className={classnames(`${props.customClass}__messagelist`, 'timeline__messagelist')}>
37
-          {props.timelineData.map(content => {
38
-            switch (content.timelineType) {
39
-              case 'comment':
40
-                return <Comment
41
-                  customClass={props.customClass}
42
-                  avatar={content.author.avatar_url}
43
-                  createdAt={content.created}
44
-                  text={content.raw_content}
45
-                  fromMe={props.loggedUser.user_id === content.author.user_id}
46
-                  key={`comment_${content.content_id}`}
47
-                />
39
+        <div className='timeline__body'>
40
+          <ul className={classnames(`${props.customClass}__messagelist`, 'timeline__body__messagelist')}>
41
+            {props.timelineData.map(content => {
42
+              switch (content.timelineType) {
43
+                case 'comment':
44
+                  return <Comment
45
+                    customClass={props.customClass}
46
+                    avatar={content.author.avatar_url}
47
+                    createdAt={content.created}
48
+                    text={content.raw_content}
49
+                    fromMe={props.loggedUser.user_id === content.author.user_id}
50
+                    key={`comment_${content.content_id}`}
51
+                  />
48 52
 
49
-              case 'revision':
50
-                return <Revision
51
-                  customClass={props.customClass}
52
-                  createdAt={content.created}
53
-                  number={content.number}
54
-                  key={`revision_${content.revision_id}`}
55
-                  onClickRevision={() => props.onClickRevisionBtn(content)}
56
-                />
57
-            }
58
-          })}
59
-          <li style={{visibility: 'hidden'}} ref={el => { this.timelineBottom = el }} />
60
-        </ul>
53
+                case 'revision':
54
+                  return <Revision
55
+                    customClass={props.customClass}
56
+                    createdAt={content.created}
57
+                    number={content.number}
58
+                    key={`revision_${content.revision_id}`}
59
+                    onClickRevision={() => props.onClickRevisionBtn(content)}
60
+                  />
61
+              }
62
+            })}
63
+            <li style={{visibility: 'hidden'}} ref={el => { this.timelineBottom = el }} />
64
+          </ul>
61 65
 
62
-        <form className={classnames(`${props.customClass}__texteditor`, 'timeline__texteditor')}>
63
-          <div className={classnames(`${props.customClass}__texteditor__textinput`, 'timeline__texteditor__textinput')}>
64
-            <textarea
65
-              id='wysiwygTimelineComment'
66
-              placeholder='Taper votre message ici'
67
-              value={props.newComment}
68
-              onChange={props.onChangeNewComment}
69
-              disabled={props.disableComment}
70
-            />
71
-          </div>
72
-
73
-          <div className={classnames(`${props.customClass}__texteditor__wrapper`, 'timeline__texteditor__wrapper')}>
74
-            <div className={classnames(`${props.customClass}__texteditor__advancedtext`, 'timeline__texteditor__advancedtext')}>
75
-              <button
76
-                type='button'
77
-                className={classnames(
78
-                  `${props.customClass}__texteditor__advancedtext__btn timeline__texteditor__advancedtext__btn btn btn-outline-primary`
79
-                )}
80
-                onClick={props.onClickWysiwygBtn}
66
+          <form className={classnames(`${props.customClass}__texteditor`, 'timeline__body__texteditor')}>
67
+            <div className={classnames(`${props.customClass}__texteditor__textinput`, 'timeline__body__texteditor__textinput')}>
68
+              <textarea
69
+                id='wysiwygTimelineComment'
70
+                placeholder='Taper votre message ici'
71
+                value={props.newComment}
72
+                onChange={props.onChangeNewComment}
81 73
                 disabled={props.disableComment}
82
-              >
83
-                {props.wysiwyg ? 'Texte Simple' : 'Texte Avancé'}
84
-              </button>
74
+              />
85 75
             </div>
86 76
 
87
-            <div className={classnames(`${props.customClass}__texteditor__submit`, 'timeline__texteditor__submit')}>
88
-              <button
89
-                type='button'
90
-                className={classnames(`${props.customClass}__texteditor__submit__btn`, 'timeline__texteditor__submit__btn btn')}
91
-                onClick={props.onClickValidateNewCommentBtn}
92
-                disabled={props.disableComment}
93
-              >
94
-                Envoyer
95
-                <div
96
-                  className={classnames(`${props.customClass}__texteditor__submit__btn__icon`, 'timeline__texteditor__submit__btn__icon')}>
97
-                  <i className='fa fa-paper-plane-o' />
98
-                </div>
99
-              </button>
77
+            <div className={classnames(`${props.customClass}__texteditor__wrapper`, 'timeline__body__texteditor__wrapper')}>
78
+              <div className={classnames(`${props.customClass}__texteditor__advancedtext`, 'timeline__body__texteditor__advancedtext')}>
79
+                <button
80
+                  type='button'
81
+                  className={classnames(
82
+                    `${props.customClass}__texteditor__advancedtext__btn timeline__body__texteditor__advancedtext__btn btn btn-outline-primary`
83
+                  )}
84
+                  onClick={props.onClickWysiwygBtn}
85
+                  disabled={props.disableComment}
86
+                >
87
+                  {props.wysiwyg ? 'Texte Simple' : 'Texte Avancé'}
88
+                </button>
89
+              </div>
90
+
91
+              <div className={classnames(`${props.customClass}__texteditor__submit`, 'timeline__body__texteditor__submit')}>
92
+                <button
93
+                  type='button'
94
+                  className={classnames(`${props.customClass}__texteditor__submit__btn`, 'timeline__body__texteditor__submit__btn btn')}
95
+                  onClick={props.onClickValidateNewCommentBtn}
96
+                  disabled={props.disableComment}
97
+                >
98
+                  Envoyer
99
+                  <div
100
+                    className={classnames(`${props.customClass}__texteditor__submit__btn__icon`, 'timeline__body__texteditor__submit__btn__icon')}>
101
+                    <i className='fa fa-paper-plane-o' />
102
+                  </div>
103
+                </button>
104
+              </div>
100 105
             </div>
101
-          </div>
102
-        </form>
106
+          </form>
107
+        </div>
103 108
       </div>
104 109
     )
105 110
   }

+ 93 - 84
src/component/Timeline/Timeline.styl View File

@@ -2,105 +2,114 @@
2 2
 
3 3
 .timeline
4 4
   display flex
5
-  flex-direction column
5
+  flex-direction row
6 6
   margin 10px 10px 10px 5px
7 7
   border-radius 10px
8 8
   width 100%
9 9
   height 100%
10 10
   &__header
11
-    flex 0 1 auto
12
-    border-radius 10px 10px 0 0
11
+    display flex
12
+    width 50px
13
+    border-radius 10px 0 0 10px
13 14
     padding 15px
15
+    background-color grey-hover
14 16
     text-align center
15 17
     font-size 20px
16 18
     color darkGrey
17
-    background-color grey-hover
18
-  &__messagelist
19
-    flex 1 1 auto
20
-    margin-bottom 0
21
-    padding-left 0
22
-    border-bottom 1px solid grey
23
-    background-color off-white
24
-    overflow-y auto
25
-    list-style none
26
-    &__item
27
-      padding 0 25px 0 35px
28
-      &__avatar
29
-        position relative
30
-        top 40px
31
-        left -20px
32
-        border-radius 50%
33
-        width 45px
34
-        height 45px
35
-        & > img
19
+    cursor pointer
20
+    &__text
21
+      margin auto 0 auto -25px
22
+      transform rotate(-90deg)
23
+  &__body
24
+    display flex
25
+    flex-direction column
26
+    width 100%
27
+    &__messagelist
28
+      flex 1 1 auto
29
+      margin-bottom 0
30
+      padding-left 0
31
+      border-bottom 1px solid grey
32
+      background-color off-white
33
+      overflow-y auto
34
+      list-style none
35
+      &__item
36
+        padding 0 25px 0 35px
37
+        &__avatar
38
+          position relative
39
+          top 40px
40
+          left -20px
41
+          border-radius 50%
36 42
           width 45px
37 43
           height 45px
38
-          border-radius 25px
39
-      &__createhour
40
-        margin-left 35px
41
-        opacity 0.7
42
-        font-size 14px
43
-      &__content
44
-        display inline-block
45
-        border 1px solid grey
46
-        border-radius 5px
47
-        padding 15px
48
-        background-color off-white
49
-        font-size 15px
50
-    &__version
51
-      display flex
52
-      justify-content space-between
53
-      margin 20px 0 20px 0
54
-      padding 10px 15px
55
-      width 100%
56
-      background-color lightGrey
57
-      &__btn
44
+          & > img
45
+            width 45px
46
+            height 45px
47
+            border-radius 25px
48
+        &__createhour
49
+          margin-left 35px
50
+          opacity 0.7
51
+          font-size 14px
52
+        &__content
53
+          display inline-block
54
+          border 1px solid grey
55
+          border-radius 5px
56
+          padding 15px
57
+          background-color off-white
58
+          font-size 15px
59
+      &__version
58 60
         display flex
59
-        justify-content center
60
-        padding 5px 20px
61
-        border-radius 5px
62
-        width 145px
63
-        color white
64
-        font-size 17px
65
-        cursor pointer
66
-        & > i
67
-          margin-right 10px
68
-          color off-white
69
-          font-size 22px
70
-      &__date
71
-        color fontColor
72
-        font-size 17px
73
-        margin auto 0
74
-  &__texteditor
75
-    flex 1 0 auto
76
-    margin 20px
77
-    &__textinput
78
-      width 100%
79
-      & > textarea
80
-        border-radius 5px
81
-        border 1.5px solid grey
82
-        padding 5px
83
-        height 80px
61
+        justify-content space-between
62
+        margin 20px 0 20px 0
63
+        padding 10px 15px
84 64
         width 100%
85
-    &__wrapper
86
-      display flex
87
-      align-items center
88
-      justify-content flex-end
89
-      margin-top 10px
90
-    &__advancedtext
91
-      margin-right 15px
92
-      cursor pointer
93
-    &__submit
94
-      &__btn
95
-        display inline-block
65
+        background-color lightGrey
66
+        &__btn
67
+          display flex
68
+          justify-content center
69
+          padding 5px 20px
70
+          border-radius 5px
71
+          width 145px
72
+          color white
73
+          font-size 17px
74
+          cursor pointer
75
+          & > i
76
+            margin-right 10px
77
+            color off-white
78
+            font-size 22px
79
+        &__date
80
+          color fontColor
81
+          font-size 17px
82
+          margin auto 0
83
+    &__texteditor
84
+      flex 1 0 auto
85
+      margin 20px
86
+      &__textinput
87
+        width 100%
88
+        & > textarea
89
+          border-radius 5px
90
+          border 1.5px solid grey
91
+          padding 5px
92
+          height 80px
93
+          width 100%
94
+      &__wrapper
95
+        display flex
96
+        align-items center
97
+        justify-content flex-end
98
+        margin-top 10px
99
+      &__advancedtext
100
+        margin-right 15px
96 101
         cursor pointer
97
-        &__icon
102
+      &__submit
103
+        &__btn
98 104
           display inline-block
99
-          margin-left 20px
105
+          cursor pointer
106
+          &__icon
107
+            display inline-block
108
+            margin-left 20px
100 109
 
101 110
 .received
102 111
   text-align right
103
-  .timeline__messagelist__item
112
+  .timeline__body__messagelist__item
104 113
     &__wrapper
105 114
       display flex
106 115
       flex-direction row-reverse
@@ -121,7 +130,7 @@
121 130
 
122 131
 @media (min-width: min-sm) and (max-width: max-lg)
123 132
 
124
-  .timeline
133
+  .timeline__body
125 134
     &__messagelist
126 135
       min-height 350px
127 136
       max-height 700px
@@ -132,7 +141,7 @@
132 141
 
133 142
 @media (min-width: min-sm) and (max-width: max-sm)
134 143
 
135
-  .timeline
144
+  .timeline__body
136 145
     &__messagelist__item
137 146
       margin-right 35px
138 147
     &__texteditor
@@ -151,7 +160,7 @@
151 160
 
152 161
 @media (max-width: max-xs)
153 162
 
154
-  .timeline
163
+  .timeline__body
155 164
     &__texteditor
156 165
       display flex
157 166
       align-items center

+ 15 - 6
src/index.dev.js View File

@@ -18,7 +18,7 @@ import CardPopup from './component/CardPopup/CardPopup.jsx'
18 18
 import CardPopupCreateContent from './component/CardPopup/CardPopupCreateContent.jsx'
19 19
 
20 20
 ReactDOM.render(
21
-  <div>
21
+  <div style={{width: '1200px'}}>
22 22
     <PopinFixed customClass={`${'randomClass'}`}>
23 23
       <PopinFixedHeader
24 24
         customClass={`${'randomClass'}`}
@@ -75,17 +75,26 @@ ReactDOM.render(
75 75
           {/* <TextAreaApp customClass={'randomClass'} text={'woot'} /> */}
76 76
         </div>
77 77
 
78
-        {/*
79 78
         <Timeline
80 79
           customClass={`${'randomClass'}__contentpage`}
81 80
           loggedUser={{
82
-            id: 1,
83
-            name: 'smoi',
84
-            avatar: 'https://www.algoo.fr/static/images/algoo_images/algoo-logo.jpg'
81
+            user_id: 5,
82
+            username: 'Smoi',
83
+            firstname: 'Côme',
84
+            lastname: 'Stoilenom',
85
+            email: 'osef@algoo.fr',
86
+            avatar_url: 'https://avatars3.githubusercontent.com/u/11177014?s=460&v=4'
85 87
           }}
86 88
           timelineData={TimelineDebugData}
89
+          newComment={''}
90
+          disableComment={false}
91
+          wysiwyg={false}
92
+          onChangeNewComment={() => {}}
93
+          onClickValidateNewCommentBtn={() => {}}
94
+          onClickWysiwygBtn={() => {}}
95
+          onClickRevisionBtn={() => {}}
96
+          shouldScrollToBottom={true}
87 97
         />
88
-        */}
89 98
       </PopinFixedContent>
90 99
     </PopinFixed>
91 100
   </div>