Browse Source

started refactor file content into plugin

Skylsmoi 6 years ago
parent
commit
4857c3125f

+ 2 - 0
jsonserver/server.js View File

@@ -25,6 +25,8 @@ server.post('/user/login', (req, res) => {
25 25
   else return res.jsonp('error')
26 26
 })
27 27
 
28
+server.get('/plugin/file_content', (req, res) => res.jsonp(jsonDb.file_content))
29
+
28 30
 server.get('/user/is_logged_in', (req, res) => res.jsonp(jsonDb.user_logged))
29 31
 
30 32
 server.get('/workspace/:id', (req, res) => res.jsonp(jsonDb.workspace_detail))

+ 46 - 8
jsonserver/static_db.json View File

@@ -9,6 +9,43 @@
9 9
       "email": "osef@algoo.fr"
10 10
     }
11 11
   },
12
+  "file_content": [{
13
+    "name": "PageHtml",
14
+    "componentLeft": "PageHtml",
15
+    "componentRight": "Timeline",
16
+    "customClass": "wsContentPageHtml",
17
+    "icon": "fa fa-file-word-o"
18
+  }, {
19
+    "name": "PageMarkdown",
20
+    "componentLeft": "PageMarkdown",
21
+    "componentRight": "undefined",
22
+    "customClass": "wsContentPageMarkdown",
23
+    "icon": "fa fa-file-code-o"
24
+  }, {
25
+    "name": "File",
26
+    "componentLeft": "File",
27
+    "componentRight": "undefined",
28
+    "customClass": "wsContentFile",
29
+    "icon": "fa fa-file-text-o"
30
+  }, {
31
+    "name": "Thread",
32
+    "componentLeft": "Thread",
33
+    "componentRight": "undefined",
34
+    "customClass": "wsContentThread",
35
+    "icon": "fa fa-comments-o"
36
+  }, {
37
+    "name": "Task",
38
+    "componentLeft": "Task",
39
+    "componentRight": "undefined",
40
+    "customClass": "wsContentTask",
41
+    "icon": "fa fa-list-ul"
42
+  }, {
43
+    "name": "Issue",
44
+    "componentLeft": "Issue",
45
+    "componentRight": "undefined",
46
+    "customClass": "wsContentIssue",
47
+    "icon": "fa fa-ticket"
48
+  }],
12 49
   "workspace_detail": {
13 50
     "id": 1,
14 51
     "title": "Mission interne - développement",
@@ -17,38 +54,39 @@
17 54
       {
18 55
         "id": 1,
19 56
         "title": "La programmation fonctionnelle",
20
-        "type": "pageHtml",
57
+        "type": "PageHtml",
21 58
         "status": "validated",
59
+        "version": "3",
22 60
         "text": "<h1>Mon titre nul</h1>Je suis le contenu de cette fameuse <b>page HTML</b><br /> sur la programmation fonctionnelle"
23 61
       },
24 62
       {
25 63
         "id": 2,
26 64
         "title": "La prommation fonctionnelle est-elle vraiment utile ?",
27
-        "type": "thread",
65
+        "type": "Thread",
28 66
         "status": "current"
29 67
       },
30 68
       {
31 69
         "id": 6,
32 70
         "title": "Une photo moche",
33
-        "type": "file",
71
+        "type": "File",
34 72
         "status": "current"
35 73
       },
36 74
       {
37 75
         "id": 10,
38 76
         "title": "le README.md d'un random repo github",
39
-        "type": "pageMarkdown",
77
+        "type": "PageMarkdown",
40 78
         "status": "current"
41 79
       },
42 80
       {
43 81
         "id": 7,
44 82
         "title": "Une liste de truc à faire que je ferai jamais",
45
-        "type": "task",
83
+        "type": "Task",
46 84
         "status": "current"
47 85
       },
48 86
       {
49 87
         "id": 8,
50 88
         "title": "Ça, ça marche pas. Merci de le fix",
51
-        "type": "issue",
89
+        "type": "Issue",
52 90
         "status": "current"
53 91
       },
54 92
       {
@@ -59,13 +97,13 @@
59 97
           {
60 98
             "id": 4,
61 99
             "title": "des trucs de backend",
62
-            "type": "file",
100
+            "type": "File",
63 101
             "status": "outdated"
64 102
           },
65 103
           {
66 104
             "id": 5,
67 105
             "title": "on s'emmerde",
68
-            "type": "pageHtml",
106
+            "type": "PageHtml",
69 107
             "status": "outdated"
70 108
           }
71 109
         ]

+ 13 - 1
src/action-creator.async.js View File

@@ -6,7 +6,9 @@ import {
6 6
   updateUserConnected,
7 7
   updateUserData,
8 8
   WORKSPACE,
9
-  updateWorkspaceData
9
+  updateWorkspaceData,
10
+  PLUGIN_LIST,
11
+  setPluginList
10 12
 } from './action-creator.sync.js'
11 13
 
12 14
 /*
@@ -114,3 +116,13 @@ export const getWorkspaceContent = workspaceId => async dispatch => {
114 116
   })
115 117
   if (fetchGetWorkspaceContent.status === 200) dispatch(updateWorkspaceData(fetchGetWorkspaceContent.json))
116 118
 }
119
+
120
+export const getPluginList = () => async dispatch => {
121
+  const fetchGetPluginList = await fetchWrapper({
122
+    url: `http://localhost:3001/plugin/file_content`,
123
+    param: {...FETCH_CONFIG, method: 'GET'},
124
+    actionName: PLUGIN_LIST,
125
+    dispatch
126
+  })
127
+  if (fetchGetPluginList.status === 200) dispatch(setPluginList(fetchGetPluginList.json))
128
+}

+ 3 - 0
src/action-creator.sync.js View File

@@ -11,3 +11,6 @@ export const updateWorkspaceData = workspace => ({ type: `Update/${WORKSPACE}`,
11 11
 export const FILE_CONTENT = 'FileContent'
12 12
 export const setActiveFileContent = file => ({ type: `Set/${FILE_CONTENT}/Active`, file })
13 13
 export const hideActiveFileContent = () => ({ type: `Set/${FILE_CONTENT}/Hide` })
14
+
15
+export const PLUGIN_LIST = 'Plugin/List'
16
+export const setPluginList = pluginList => ({ type: `Set/${PLUGIN_LIST}`, pluginList })

+ 30 - 0
src/component/PluginContentType.jsx View File

@@ -0,0 +1,30 @@
1
+import React from 'react'
2
+import PageHtml from '../plugin/ContentType/PageHtml/PageHtml.jsx'
3
+import Thread from '../plugin/ContentType/Thread/Thread.jsx'
4
+import Timeline from './Timeline.jsx'
5
+import {FILE_TYPE} from '../helper.js'
6
+
7
+const PluginContentType = props => {
8
+  // const [leftPart, rightPart] = (() => {
9
+  //   switch (props.file.type) {
10
+  //     case FILE_TYPE[0].name: // pageHtml
11
+  //       return [
12
+  //         <PageHtml version={props.file.version} text={props.file.text} />,
13
+  //         <Timeline customClass={`${props.customClass}__contentpage`} />
14
+  //       ]
15
+  //     case FILE_TYPE[3].name: // thread
16
+  //       return [
17
+  //         <Thread />
18
+  //       ]
19
+  //   }
20
+  // })()
21
+  // return [leftPart, rightPart]
22
+  const { componentLeft, componentRight, customClass, } = FILE_TYPE.find(p => p.name === props.file.type)
23
+
24
+  return [
25
+    genericPlugin.componentLeft,
26
+    genericPlugin.componentRight
27
+  ]
28
+}
29
+
30
+export default PluginContentType

+ 19 - 18
src/component/Workspace/FileContentViewer.jsx View File

@@ -4,27 +4,28 @@ import PopinFixed from '../common/PopinFixed/PopinFixed'
4 4
 import PopinFixedHeader from '../common/PopinFixed/PopinFixedHeader.jsx'
5 5
 import PopinFixedOption from '../common/PopinFixed/PopinFixedOption.jsx'
6 6
 import PopinFixedContent from '../common/PopinFixed/PopinFixedContent.jsx'
7
-import PageHtml from './FileType/PageHtml.jsx'
8
-import Thread from './FileType/Thread.jsx'
9
-import Timeline from '../Timeline.jsx'
10 7
 import { FILE_TYPE } from '../../helper.js'
8
+// import PluginContentType from '../PluginContentType.jsx'
9
+import PageHtml from '../../plugin/ContentType/PageHtml/PageHtml.jsx'
10
+// import Thread from '../../plugin/ContentType/Thread/Thread.jsx'
11 11
 
12 12
 const FileContentViewer = props => {
13
-  const { customClass, icon } = FILE_TYPE.find(f => f.name === props.file.type) || {customClass: '', icon: ''}
13
+  const defaultPlugin = {
14
+    customClass: '',
15
+    icon: '',
16
+    componentLeft: undefined,
17
+    componentRight: undefined
18
+  }
19
+  const { customClass, icon, componentLeft, componentRight } = FILE_TYPE.find(f => f.name === props.file.type) || defaultPlugin
14 20
 
15
-  const [leftPart, rightPart] = (() => {
16
-    switch (props.file.type) {
17
-      case FILE_TYPE[0].name: // pageHtml
18
-        return [
19
-          <PageHtml version={props.file.version} text={props.file.text} />,
20
-          <Timeline customClass={`${customClass}__contentpage`} />
21
-        ]
22
-      case FILE_TYPE[3].name: // thread
23
-        return [
24
-          <Thread />
25
-        ]
21
+  const PluginLeft = props => {
22
+    console.log('componentLeft === PageHtml.name', componentLeft === PageHtml.name)
23
+    switch (componentLeft) {
24
+      case PageHtml.name:
25
+        return <PageHtml version={props.file.version} text={props.file.text} />
26 26
     }
27
-  })()
27
+    // componentLeft is a string, I cant do <componentLeft /> because it needs to be a react object (component) like PageHtml is
28
+  }
28 29
 
29 30
   return (
30 31
     <PopinFixed customClass={`${customClass}`}>
@@ -38,8 +39,8 @@ const FileContentViewer = props => {
38 39
       <PopinFixedOption customClass={`${customClass}`} />
39 40
 
40 41
       <PopinFixedContent customClass={`${customClass}__contentpage`}>
41
-        { leftPart }
42
-        { rightPart }
42
+        {/* <PluginContentType customeClass={customClass} file={props.file} /> */}
43
+        <PluginLeft file={props.file} />
43 44
       </PopinFixedContent>
44 45
     </PopinFixed>
45 46
   )

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

@@ -1,9 +1,9 @@
1 1
 import React from 'react'
2 2
 import classnames from 'classnames'
3 3
 import PropTypes from 'prop-types'
4
-import PageHtml from '../../Workspace/FileType/PageHtml.jsx'
5
-import Thread from '../../Workspace/FileType/Thread.jsx'
6
-import Timeline from '../../Timeline.jsx'
4
+// import PageHtml from '../../../plugin/ContentType/PageHtml/PageHtml.jsx'
5
+// import Thread from '../../../plugin/ContentType/Thread/Thread.jsx'
6
+// import Timeline from '../../Timeline.jsx'
7 7
 
8 8
 const PopinFixedContent = props => {
9 9
   return props.children.length === 2
@@ -26,17 +26,18 @@ const PopinFixedContent = props => {
26 26
 export default PopinFixedContent
27 27
 
28 28
 PopinFixedContent.propTypes = {
29
-  customClass: PropTypes.string,
29
+  customClass: PropTypes.string
30
+
30 31
   // from http://www.mattzabriskie.com/blog/react-validating-children
31
-  children: PropTypes.arrayOf((children, key, componentName /* , location, propFullName */) => {
32
-    if (
33
-      (Array.isArray(children.length) && (
34
-        children.length > 2 ||
35
-        (children.length === 2 && children.some(c => ![PageHtml, Thread, Timeline].includes(c.type)))
36
-      )) ||
37
-      (children.type === Timeline)
38
-    ) {
39
-      return new Error(`PropType Error: childrens of ${componentName} must be one of [PageHtml, Thread, Timeline, undefined].`)
40
-    }
41
-  }).isRequired
32
+  // children: PropTypes.arrayOf((children, key, componentName /* , location, propFullName */) => {
33
+  //   if (
34
+  //     (Array.isArray(children.length) && (
35
+  //       children.length > 2 ||
36
+  //       (children.length === 2 && children.some(c => ![PageHtml, Thread, Timeline].includes(c.type)))
37
+  //     )) ||
38
+  //     (children.type === Timeline)
39
+  //   ) {
40
+  //     return new Error(`PropType Error: childrens of ${componentName} must be one of [PageHtml, Thread, Timeline, undefined].`)
41
+  //   }
42
+  // }).isRequired
42 43
 }

+ 6 - 1
src/container/WorkspaceContent.jsx View File

@@ -8,7 +8,10 @@ import PageTitle from '../component/common/layout/PageTitle.jsx'
8 8
 import PageContent from '../component/common/layout/PageContent.jsx'
9 9
 import DropdownCreateButton from '../component/common/Input/DropdownCreateButton.jsx'
10 10
 import FileContentViewer from '../component/Workspace/FileContentViewer.jsx'
11
-import { getWorkspaceContent } from '../action-creator.async.js'
11
+import {
12
+  getPluginList,
13
+  getWorkspaceContent
14
+} from '../action-creator.async.js'
12 15
 import { setActiveFileContent, hideActiveFileContent } from '../action-creator.sync.js'
13 16
 
14 17
 class WorkspaceContent extends React.Component {
@@ -21,9 +24,11 @@ class WorkspaceContent extends React.Component {
21 24
 
22 25
   componentDidMount () {
23 26
     this.props.dispatch(getWorkspaceContent(/* this.props.workspace.id */1))
27
+    this.props.dispatch(getPluginList())
24 28
   }
25 29
 
26 30
   handleClickFileItem = file => {
31
+    console.log(file)
27 32
     this.props.dispatch(setActiveFileContent(file))
28 33
   }
29 34
 

+ 2 - 2
src/css/index.styl View File

@@ -17,6 +17,6 @@ html, body, #content, #content > div
17 17
 @import 'FileItemHeader'
18 18
 @import 'Folder'
19 19
 
20
-@import 'Thread'
21
-@import 'PageHtml'
20
+@import '../plugin/ContentType/Thread/Thread.styl'
21
+@import '../plugin/ContentType/PageHtml/PageHtml.styl'
22 22
 @import 'Timeline'

+ 24 - 12
src/helper.js View File

@@ -6,27 +6,39 @@ export const FETCH_CONFIG = {
6 6
 }
7 7
 
8 8
 export const FILE_TYPE = [{
9
-  name: 'pageHtml',
10
-  customClass: 'wsFilePageHtml',
9
+  name: 'PageHtml',
10
+  componentLeft: 'PageHtml',
11
+  componentRight: 'Timeline',
12
+  customClass: 'wsContentPageHtml',
11 13
   icon: 'fa fa-file-word-o'
12 14
 }, {
13
-  name: 'pageMarkdown',
14
-  customClass: 'wsFilePageMarkdown',
15
+  name: 'PageMarkdown',
16
+  componentLeft: 'PageMarkdown',
17
+  componentRight: 'undefined',
18
+  customClass: 'wsContentPageMarkdown',
15 19
   icon: 'fa fa-file-code-o'
16 20
 }, {
17
-  name: 'file',
18
-  customClass: 'wsFileFile',
21
+  name: 'File',
22
+  componentLeft: 'File',
23
+  componentRight: 'undefined',
24
+  customClass: 'wsContentFile',
19 25
   icon: 'fa fa-file-text-o'
20 26
 }, {
21
-  name: 'thread',
22
-  customClass: 'wsFileThread',
27
+  name: 'Thread',
28
+  componentLeft: 'Thread',
29
+  componentRight: 'undefined',
30
+  customClass: 'wsContentThread',
23 31
   icon: 'fa fa-comments-o'
24 32
 }, {
25
-  name: 'task',
26
-  customClass: 'wsFileTask',
33
+  name: 'Task',
34
+  componentLeft: 'Task',
35
+  componentRight: 'undefined',
36
+  customClass: 'wsContentTask',
27 37
   icon: 'fa fa-list-ul'
28 38
 }, {
29
-  name: 'issue',
30
-  customClass: 'wsFileIssue',
39
+  name: 'Issue',
40
+  componentLeft: 'Issue',
41
+  componentRight: 'undefined',
42
+  customClass: 'wsContentIssue',
31 43
   icon: 'fa fa-ticket'
32 44
 }]

src/component/Workspace/FileType/PageHtml.jsx → src/plugin/ContentType/PageHtml/PageHtml.jsx View File


src/css/PageHtml.styl → src/plugin/ContentType/PageHtml/PageHtml.styl View File

@@ -1,4 +1,4 @@
1
-.wsFilePageHtml
1
+.wsContentPageHtml
2 2
   width 1200px
3 3
   height calc(100% - 85px)
4 4
   overflow-Y auto
@@ -81,16 +81,16 @@
81 81
             background-color htmlColor
82 82
 
83 83
 .messagelistOpen
84
-  .wsFilePageHtml__contentpage__messagelist
84
+  .wsContentPageHtml__contentpage__messagelist
85 85
     flex 0
86 86
     min-height 0
87 87
 
88 88
 .received
89
-  .wsFilePageHtml__contentpage__messagelist__item__content
89
+  .wsContentPageHtml__contentpage__messagelist__item__content
90 90
       background-color htmlColor
91 91
 
92 92
 @media (min-width: max-xs) and (max-width: max-lg)
93
-  .wsFilePageHtml
93
+  .wsContentPageHtml
94 94
     &__contentpage
95 95
       display block
96 96
       overflow-Y scroll
@@ -117,19 +117,19 @@
117 117
               margin-left 15px
118 118
 
119 119
 @media (min-width: min-lg) and (max-width: max-lg)
120
-  .wsFilePageHtml
120
+  .wsContentPageHtml
121 121
     width 692px
122 122
     &__contentpage__texteditor__simpletext
123 123
       margin-left 15px
124 124
 
125 125
 @media (min-width: min-md) and (max-width: max-md)
126
-  .wsFilePageHtml
126
+  .wsContentPageHtml
127 127
     width 768px
128 128
     &__contentpage__texteditor__simpletext
129 129
       margin-left 25px
130 130
 
131 131
 @media (min-width: min-sm) and (max-width: max-sm)
132
-  .wsFilePageHtml
132
+  .wsContentPageHtml
133 133
       top 69px
134 134
       width 576px
135 135
       height calc(100% - 69px)
@@ -137,7 +137,7 @@
137 137
         margin-left 10px
138 138
 
139 139
 @media (max-width: max-xs)
140
-  .wsFilePageHtml
140
+  .wsContentPageHtml
141 141
     top 70px
142 142
     height calc(100% - 70px)
143 143
     width 100%

+ 14 - 0
src/plugin/ContentType/PageHtml/pageHtml.js View File

@@ -0,0 +1,14 @@
1
+import { PLUGIN_LIST } from '../../../action-creator.sync.js'
2
+
3
+export default function pageHtml (state = {
4
+  title: '',
5
+  version: 0
6
+}, action) {
7
+  switch (action.type) {
8
+    case `Set/${PLUGIN_LIST}`:
9
+      return action.pluginList.find(p => p.name === 'PageHtml')
10
+
11
+    default:
12
+      return state
13
+  }
14
+}

src/component/Workspace/FileType/Thread.jsx → src/plugin/ContentType/Thread/Thread.jsx View File


src/css/Thread.styl → src/plugin/ContentType/Thread/Thread.styl View File

@@ -1,4 +1,4 @@
1
-.wsFileThread
1
+.wsContentThread
2 2
   width 550px
3 3
   &__header
4 4
     color white
@@ -21,12 +21,12 @@
21 21
         color darkBlue
22 22
 
23 23
 .received
24
-  .wsFileThread__messagelist__item__content
24
+  .wsContentThread__messagelist__item__content
25 25
       background-color darkBlue
26 26
       color white
27 27
 
28 28
 @media (min-width: max-xs) and (max-width: max-lg)
29
-  .wsFileThread
29
+  .wsContentThread
30 30
     &__texteditor
31 31
       padding 7px
32 32
       &__simpletext
@@ -36,11 +36,11 @@
36 36
         width 80px
37 37
 
38 38
 @media (min-width: min-sm) and (max-width: max-sm)
39
-  .wsFileThread
39
+  .wsContentThread
40 40
     top 69px
41 41
 
42 42
 @media (max-width: max-xs)
43
-  .wsFileThread
43
+  .wsContentThread
44 44
     top 69px
45 45
     width 100%
46 46
     box-shadow none

+ 14 - 0
src/plugin/ContentType/Thread/thread.js View File

@@ -0,0 +1,14 @@
1
+import { PLUGIN_LIST } from '../../../action-creator.sync.js'
2
+
3
+export default function thread (state = {
4
+  title: '',
5
+  version: 0
6
+}, action) {
7
+  switch (action.type) {
8
+    case `Set/${PLUGIN_LIST}`:
9
+      return action.pluginList.find(p => p.name === 'Thread')
10
+
11
+    default:
12
+      return state
13
+  }
14
+}

+ 0 - 10
src/reducer/fileType/index.js View File

@@ -1,10 +0,0 @@
1
-import { combineReducers } from 'redux'
2
-
3
-// import color from './color.js'
4
-// import size from './size.js'
5
-// import price from './price.js'
6
-// import multicolor from './multicolor.js'
7
-
8
-export default combineReducers({
9
-
10
-})

+ 0 - 10
src/reducer/fileType/pageHtml.js View File

@@ -1,10 +0,0 @@
1
-export default function pageHtml (state = {
2
-  title: '',
3
-  version: 0,
4
-  text: ''
5
-}, action) {
6
-  switch (action.type) {
7
-    default:
8
-      return state
9
-  }
10
-}

+ 7 - 0
src/reducer/plugin.js View File

@@ -0,0 +1,7 @@
1
+import { combineReducers } from 'redux'
2
+import pageHtml from '../plugin/ContentType/PageHtml/pageHtml.js'
3
+import thread from '../plugin/ContentType/Thread/thread'
4
+
5
+export default combineReducers({
6
+  pageHtml, thread
7
+})

+ 2 - 1
src/reducer/root.js View File

@@ -2,7 +2,8 @@ import { combineReducers } from 'redux'
2 2
 import user from './user.js'
3 3
 import workspace from './workspace.js'
4 4
 import activeFileContent from './activeFileContent.js'
5
+import plugin from './plugin.js'
5 6
 
6
-const rootReducer = combineReducers({ user, workspace, activeFileContent })
7
+const rootReducer = combineReducers({ user, workspace, activeFileContent, plugin })
7 8
 
8 9
 export default rootReducer