@pareto-engineering/design-system 2.0.0-alpha.48 → 2.0.0-alpha.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/cjs/f/FormInput/FormInput.js +7 -0
  2. package/dist/cjs/f/fields/QueryCombobox/QueryCombobox.js +14 -8
  3. package/dist/cjs/f/fields/QuerySelect/QuerySelect.js +201 -0
  4. package/dist/cjs/f/fields/QuerySelect/index.js +15 -0
  5. package/dist/cjs/f/fields/QuerySelect/styles.scss +21 -0
  6. package/dist/cjs/f/fields/SelectInput/SelectInput.js +15 -3
  7. package/dist/cjs/f/fields/SelectInput/styles.scss +27 -14
  8. package/dist/cjs/f/fields/index.js +9 -1
  9. package/dist/es/f/FormInput/FormInput.js +8 -1
  10. package/dist/es/f/fields/QueryCombobox/QueryCombobox.js +14 -8
  11. package/dist/es/f/fields/QuerySelect/QuerySelect.js +179 -0
  12. package/dist/es/f/fields/QuerySelect/index.js +2 -0
  13. package/dist/es/f/fields/QuerySelect/styles.scss +21 -0
  14. package/dist/es/f/fields/SelectInput/SelectInput.js +14 -3
  15. package/dist/es/f/fields/SelectInput/styles.scss +27 -14
  16. package/dist/es/f/fields/index.js +2 -1
  17. package/package.json +1 -1
  18. package/src/__snapshots__/Storyshots.test.js.snap +582 -246
  19. package/src/stories/f/FormInput.stories.jsx +124 -6
  20. package/src/stories/f/QueryCombobox.stories.jsx +6 -4
  21. package/src/stories/f/QuerySelect.stories.jsx +134 -0
  22. package/src/stories/f/__generated__/FormInputAllTaskStatusesQuery.graphql.js +122 -0
  23. package/src/stories/f/__generated__/QuerySelectAllTaskStatusesQuery.graphql.js +122 -0
  24. package/src/ui/f/FormInput/FormInput.jsx +10 -0
  25. package/src/ui/f/fields/QueryCombobox/QueryCombobox.jsx +17 -13
  26. package/src/ui/f/fields/QuerySelect/QuerySelect.jsx +200 -0
  27. package/src/ui/f/fields/QuerySelect/index.js +2 -0
  28. package/src/ui/f/fields/SelectInput/SelectInput.jsx +16 -3
  29. package/src/ui/f/fields/SelectInput/styles.scss +27 -14
  30. package/src/ui/f/fields/index.js +1 -0
@@ -186,16 +186,134 @@ export const WithQueryCombobox = () => {
186
186
  ],
187
187
  },
188
188
  {
189
- type :'query-combobox',
190
- name :'team',
191
- query :FETCH_TEAMS_QUERY,
189
+ type :'query-combobox',
190
+ name :'team',
191
+ query:{
192
+ graphql :FETCH_TEAMS_QUERY,
193
+ accessor:'allTeams',
194
+ },
192
195
  label :'Search for a team',
193
196
  optionsKeyMap:{
194
- value:'id',
195
- label:'name',
197
+ value :'id',
198
+ getLabel:(node) => node.name,
199
+ },
200
+ searchVariable:'name_Icontains',
201
+ },
202
+ {
203
+ type :'query-combobox',
204
+ name :'teams',
205
+ query:{
206
+ graphql :FETCH_TEAMS_QUERY,
207
+ accessor:'allTeams',
208
+ },
209
+ label :'Search for teams',
210
+ optionsKeyMap:{
211
+ value :'id',
212
+ getLabel:(node) => node.name,
196
213
  },
197
- graphQlNode :'allTeams',
198
214
  searchVariable:'name_Icontains',
215
+ multiple :true,
216
+ },
217
+ ]
218
+
219
+ mockRelayOperation(allTeamsMockData)
220
+ mockRelayOperation(allTeamsMockData)
221
+ mockRelayOperation(allTeamsMockData)
222
+
223
+ return (
224
+ <>
225
+ {
226
+ inputMap.map((input) => <FormInput {...input} key={input.name} />)
227
+ }
228
+ <FormDebugger />
229
+
230
+ </>
231
+ )
232
+ }
233
+
234
+ const statuses = [
235
+ 'Backlog',
236
+ 'In Review',
237
+ 'In Progress',
238
+ 'Requested',
239
+ 'Blocked',
240
+ 'Completed',
241
+ ]
242
+ const allTaskStatusesMockData = {
243
+ PageInfo() {
244
+ return {
245
+ hasNextPage :true,
246
+ hasPreviousPage:true,
247
+ }
248
+ },
249
+ TaskStatusNodeConnection:() => ({
250
+ pageInfo:{
251
+ hasNextPage :true,
252
+ hasPreviousPage:true,
253
+ },
254
+
255
+ edges:statuses.map((status) => ({
256
+ node:{
257
+ id:generateNodeId('TaskStatusNode'),
258
+ status,
259
+ },
260
+ })),
261
+ }),
262
+ }
263
+
264
+ const FETCH_ALL_TASK_STATUSES = graphql`
265
+ query FormInputAllTaskStatusesQuery {
266
+ allTaskStatuses {
267
+ edges {
268
+ node {
269
+ id
270
+ status
271
+ }
272
+ }
273
+ }
274
+ }
275
+ `
276
+
277
+ export const WithPrefetchedQuerySelect = () => {
278
+ mockRelayOperation(allTaskStatusesMockData)
279
+
280
+ const inputMap = [
281
+ {
282
+ type :'text',
283
+ name :'firstName',
284
+ label:"What's your first name ?",
285
+ },
286
+ {
287
+ type :'choices',
288
+ name :'colors',
289
+ label :'What are your favourite colors ?',
290
+ options:[
291
+ {
292
+ value:'red',
293
+ label:'Color Red',
294
+ },
295
+ {
296
+ value:'blue',
297
+ label:'Color Blue',
298
+ },
299
+ {
300
+ value:'green',
301
+ label:'Color Green',
302
+ },
303
+ ],
304
+ },
305
+ {
306
+ type :'query-select',
307
+ name :'status',
308
+ query:{
309
+ graphql :FETCH_ALL_TASK_STATUSES,
310
+ accessor:'allTaskStatuses',
311
+ },
312
+ label :'Select Task Status',
313
+ optionsKeyMap:{
314
+ value :'id',
315
+ getLabel:(node) => node.status,
316
+ },
199
317
  },
200
318
  ]
201
319
 
@@ -118,15 +118,17 @@ const ResolvedTemplate = ({ multiple, defaultFormikState }) => {
118
118
  return (
119
119
  <>
120
120
  <QueryCombobox
121
- query={FETCH_TEAMS_QUERY}
122
121
  label="Search for a team"
123
122
  optionsKeyMap={{
124
- value:'id',
125
- label:'name',
123
+ value :'id',
124
+ getLabel:(node) => node.name,
125
+ }}
126
+ query={{
127
+ graphql :FETCH_TEAMS_QUERY,
128
+ accessor:'allTeams',
126
129
  }}
127
130
  name={name}
128
131
  multiple={multiple}
129
- graphQlNode="allTeams"
130
132
  searchVariable="name_Icontains"
131
133
  />
132
134
  <div
@@ -0,0 +1,134 @@
1
+ /* @pareto-engineering/generator-front 1.0.12 */
2
+ import * as React from 'react'
3
+
4
+ import { QuerySelect, FormDebugger } from 'ui'
5
+
6
+ import { Formik, Form } from 'formik'
7
+
8
+ import generateNodeId from '../utils/generateNodeId'
9
+
10
+ import {
11
+ RelayEnvironmentProvider,
12
+ mockRelayOperation,
13
+ environment,
14
+ } from '../utils/relay'
15
+
16
+ export default {
17
+ title :'f/fields/QuerySelect',
18
+ component :QuerySelect,
19
+ subcomponents:{
20
+ // Item:QuerySelect.Item
21
+ },
22
+ decorators:[
23
+ // storyfn => <div className="">{ storyfn() }</div>,
24
+ (storyfn) => (
25
+ <RelayEnvironmentProvider>
26
+ { storyfn() }
27
+ </RelayEnvironmentProvider>
28
+ ),
29
+ ],
30
+ argTypes:{
31
+ backgroundColor:{ control: 'color' },
32
+ },
33
+ }
34
+ const statuses = [
35
+ 'Backlog',
36
+ 'In Review',
37
+ 'In Progress',
38
+ 'Requested',
39
+ 'Blocked',
40
+ 'Completed',
41
+ ]
42
+ const allTaskStatusesMockData = {
43
+ PageInfo() {
44
+ return {
45
+ hasNextPage :true,
46
+ hasPreviousPage:true,
47
+ }
48
+ },
49
+ TaskStatusNodeConnection:() => ({
50
+ pageInfo:{
51
+ hasNextPage :true,
52
+ hasPreviousPage:true,
53
+ },
54
+
55
+ edges:statuses.map((status) => ({
56
+ node:{
57
+ id:generateNodeId('TaskStatusNode'),
58
+ status,
59
+ },
60
+ })),
61
+ }),
62
+ }
63
+
64
+ const FETCH_ALL_TASK_STATUSES = graphql`
65
+ query QuerySelectAllTaskStatusesQuery {
66
+ allTaskStatuses {
67
+ edges {
68
+ node {
69
+ id
70
+ status
71
+ }
72
+ }
73
+ }
74
+ }
75
+ `
76
+
77
+ // eslint-disable-next-line react/prop-types
78
+ const Template = ({ isLoading, defaultFormikState }) => {
79
+ if (isLoading) {
80
+ setTimeout(() => {
81
+ mockRelayOperation(allTaskStatusesMockData)
82
+ environment.mock.queuePendingOperation(
83
+ FETCH_ALL_TASK_STATUSES,
84
+ )
85
+ }, 500)
86
+ } else {
87
+ mockRelayOperation(allTaskStatusesMockData)
88
+ environment.mock.queuePendingOperation(
89
+ FETCH_ALL_TASK_STATUSES,
90
+ )
91
+ }
92
+
93
+ const Content = () => (
94
+ <>
95
+ <QuerySelect
96
+ name="status"
97
+ label="Select Task Status"
98
+ query={{
99
+ graphql :FETCH_ALL_TASK_STATUSES,
100
+ accessor:'allTaskStatuses',
101
+ }}
102
+ optionsKeyMap={{
103
+ value :'id',
104
+ getLabel:(node) => node.status,
105
+ }}
106
+ />
107
+ <FormDebugger />
108
+ </>
109
+ )
110
+
111
+ const initialValues = defaultFormikState ?? { status: '' }
112
+
113
+ return (
114
+ <Formik
115
+ initialValues={initialValues}
116
+ >
117
+ <Form>
118
+ <Content />
119
+ </Form>
120
+ </Formik>
121
+ )
122
+ }
123
+
124
+ export const Base = Template.bind({})
125
+ export const WithDefaultValue = Template.bind({})
126
+ WithDefaultValue.args = {
127
+ defaultFormikState:{
128
+ status:'VGFza1N0YXR1c05vZGU6NGRiYjNlMmItMGIxYy00ZjIxLTk0MmUtZTNjZGQwMjdiNjU3',
129
+ },
130
+ }
131
+ export const LoadingOptions = Template.bind({})
132
+ LoadingOptions.args = {
133
+ isLoading:true,
134
+ }
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @flow
3
+ */
4
+
5
+ /* eslint-disable */
6
+
7
+ 'use strict';
8
+
9
+ /*::
10
+ import type { ConcreteRequest } from 'relay-runtime';
11
+ export type FormInputAllTaskStatusesQueryVariables = {||};
12
+ export type FormInputAllTaskStatusesQueryResponse = {|
13
+ +allTaskStatuses: ?{|
14
+ +edges: $ReadOnlyArray<?{|
15
+ +node: ?{|
16
+ +id: string,
17
+ +status: string,
18
+ |}
19
+ |}>
20
+ |}
21
+ |};
22
+ export type FormInputAllTaskStatusesQuery = {|
23
+ variables: FormInputAllTaskStatusesQueryVariables,
24
+ response: FormInputAllTaskStatusesQueryResponse,
25
+ |};
26
+ */
27
+
28
+
29
+ /*
30
+ query FormInputAllTaskStatusesQuery {
31
+ allTaskStatuses {
32
+ edges {
33
+ node {
34
+ id
35
+ status
36
+ }
37
+ }
38
+ }
39
+ }
40
+ */
41
+
42
+ const node/*: ConcreteRequest*/ = (function(){
43
+ var v0 = [
44
+ {
45
+ "alias": null,
46
+ "args": null,
47
+ "concreteType": "TaskStatusNodeConnection",
48
+ "kind": "LinkedField",
49
+ "name": "allTaskStatuses",
50
+ "plural": false,
51
+ "selections": [
52
+ {
53
+ "alias": null,
54
+ "args": null,
55
+ "concreteType": "TaskStatusNodeEdge",
56
+ "kind": "LinkedField",
57
+ "name": "edges",
58
+ "plural": true,
59
+ "selections": [
60
+ {
61
+ "alias": null,
62
+ "args": null,
63
+ "concreteType": "TaskStatusNode",
64
+ "kind": "LinkedField",
65
+ "name": "node",
66
+ "plural": false,
67
+ "selections": [
68
+ {
69
+ "alias": null,
70
+ "args": null,
71
+ "kind": "ScalarField",
72
+ "name": "id",
73
+ "storageKey": null
74
+ },
75
+ {
76
+ "alias": null,
77
+ "args": null,
78
+ "kind": "ScalarField",
79
+ "name": "status",
80
+ "storageKey": null
81
+ }
82
+ ],
83
+ "storageKey": null
84
+ }
85
+ ],
86
+ "storageKey": null
87
+ }
88
+ ],
89
+ "storageKey": null
90
+ }
91
+ ];
92
+ return {
93
+ "fragment": {
94
+ "argumentDefinitions": [],
95
+ "kind": "Fragment",
96
+ "metadata": null,
97
+ "name": "FormInputAllTaskStatusesQuery",
98
+ "selections": (v0/*: any*/),
99
+ "type": "Query",
100
+ "abstractKey": null
101
+ },
102
+ "kind": "Request",
103
+ "operation": {
104
+ "argumentDefinitions": [],
105
+ "kind": "Operation",
106
+ "name": "FormInputAllTaskStatusesQuery",
107
+ "selections": (v0/*: any*/)
108
+ },
109
+ "params": {
110
+ "cacheID": "54ce3d351c6ef9fa16c73a954fc5cfea",
111
+ "id": null,
112
+ "metadata": {},
113
+ "name": "FormInputAllTaskStatusesQuery",
114
+ "operationKind": "query",
115
+ "text": "query FormInputAllTaskStatusesQuery {\n allTaskStatuses {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n"
116
+ }
117
+ };
118
+ })();
119
+ // prettier-ignore
120
+ (node/*: any*/).hash = 'a86a4a669c61db10cd2bd9b72b3eeb12';
121
+
122
+ module.exports = node;
@@ -0,0 +1,122 @@
1
+ /**
2
+ * @flow
3
+ */
4
+
5
+ /* eslint-disable */
6
+
7
+ 'use strict';
8
+
9
+ /*::
10
+ import type { ConcreteRequest } from 'relay-runtime';
11
+ export type QuerySelectAllTaskStatusesQueryVariables = {||};
12
+ export type QuerySelectAllTaskStatusesQueryResponse = {|
13
+ +allTaskStatuses: ?{|
14
+ +edges: $ReadOnlyArray<?{|
15
+ +node: ?{|
16
+ +id: string,
17
+ +status: string,
18
+ |}
19
+ |}>
20
+ |}
21
+ |};
22
+ export type QuerySelectAllTaskStatusesQuery = {|
23
+ variables: QuerySelectAllTaskStatusesQueryVariables,
24
+ response: QuerySelectAllTaskStatusesQueryResponse,
25
+ |};
26
+ */
27
+
28
+
29
+ /*
30
+ query QuerySelectAllTaskStatusesQuery {
31
+ allTaskStatuses {
32
+ edges {
33
+ node {
34
+ id
35
+ status
36
+ }
37
+ }
38
+ }
39
+ }
40
+ */
41
+
42
+ const node/*: ConcreteRequest*/ = (function(){
43
+ var v0 = [
44
+ {
45
+ "alias": null,
46
+ "args": null,
47
+ "concreteType": "TaskStatusNodeConnection",
48
+ "kind": "LinkedField",
49
+ "name": "allTaskStatuses",
50
+ "plural": false,
51
+ "selections": [
52
+ {
53
+ "alias": null,
54
+ "args": null,
55
+ "concreteType": "TaskStatusNodeEdge",
56
+ "kind": "LinkedField",
57
+ "name": "edges",
58
+ "plural": true,
59
+ "selections": [
60
+ {
61
+ "alias": null,
62
+ "args": null,
63
+ "concreteType": "TaskStatusNode",
64
+ "kind": "LinkedField",
65
+ "name": "node",
66
+ "plural": false,
67
+ "selections": [
68
+ {
69
+ "alias": null,
70
+ "args": null,
71
+ "kind": "ScalarField",
72
+ "name": "id",
73
+ "storageKey": null
74
+ },
75
+ {
76
+ "alias": null,
77
+ "args": null,
78
+ "kind": "ScalarField",
79
+ "name": "status",
80
+ "storageKey": null
81
+ }
82
+ ],
83
+ "storageKey": null
84
+ }
85
+ ],
86
+ "storageKey": null
87
+ }
88
+ ],
89
+ "storageKey": null
90
+ }
91
+ ];
92
+ return {
93
+ "fragment": {
94
+ "argumentDefinitions": [],
95
+ "kind": "Fragment",
96
+ "metadata": null,
97
+ "name": "QuerySelectAllTaskStatusesQuery",
98
+ "selections": (v0/*: any*/),
99
+ "type": "Query",
100
+ "abstractKey": null
101
+ },
102
+ "kind": "Request",
103
+ "operation": {
104
+ "argumentDefinitions": [],
105
+ "kind": "Operation",
106
+ "name": "QuerySelectAllTaskStatusesQuery",
107
+ "selections": (v0/*: any*/)
108
+ },
109
+ "params": {
110
+ "cacheID": "bd929dd60893f2a67f23d8cd2fb003de",
111
+ "id": null,
112
+ "metadata": {},
113
+ "name": "QuerySelectAllTaskStatusesQuery",
114
+ "operationKind": "query",
115
+ "text": "query QuerySelectAllTaskStatusesQuery {\n allTaskStatuses {\n edges {\n node {\n id\n status\n }\n }\n }\n}\n"
116
+ }
117
+ };
118
+ })();
119
+ // prettier-ignore
120
+ (node/*: any*/).hash = '31d9d1e820e814f7cee8ef7b273074ab';
121
+
122
+ module.exports = node;
@@ -11,6 +11,7 @@ import {
11
11
  ChoicesInput,
12
12
  SelectInput,
13
13
  QueryCombobox,
14
+ QuerySelect,
14
15
  } from '../fields'
15
16
 
16
17
  // Local Definitions
@@ -74,6 +75,15 @@ const FormInput = ({
74
75
  />
75
76
  )
76
77
  }
78
+ if (type === 'query-select') {
79
+ return (
80
+ <QuerySelect
81
+ className={newClassName}
82
+ disabled={disabled}
83
+ {...otherProps}
84
+ />
85
+ )
86
+ }
77
87
  if (extraTypes?.[type]) {
78
88
  const Component = extraTypes[type]
79
89
  return (
@@ -28,7 +28,6 @@ const QueryCombobox = ({
28
28
  description,
29
29
  disabled,
30
30
  debounceMs,
31
- graphQlNode,
32
31
  searchVariable,
33
32
  extraVariables,
34
33
  optionsKeyMap,
@@ -52,6 +51,8 @@ const QueryCombobox = ({
52
51
 
53
52
  const [options, setOptions] = useState([])
54
53
 
54
+ const { graphql, accessor } = query
55
+
55
56
  const getOptions = (inputValue) => {
56
57
  if (isFetching) return
57
58
 
@@ -66,7 +67,7 @@ const QueryCombobox = ({
66
67
 
67
68
  fetchQuery(
68
69
  environment,
69
- query,
70
+ graphql,
70
71
  variables,
71
72
  )
72
73
  .subscribe({
@@ -81,9 +82,9 @@ const QueryCombobox = ({
81
82
  if (setError)setError(fetchError.message)
82
83
  },
83
84
  next:(data) => {
84
- setOptions(data[graphQlNode].edges.map(({ node }) => ({
85
+ setOptions(data[accessor].edges.map(({ node }) => ({
85
86
  value:node[optionsKeyMap.value],
86
- label:node[optionsKeyMap.label],
87
+ label:optionsKeyMap.getLabel(node),
87
88
  })))
88
89
  },
89
90
  })
@@ -161,12 +162,15 @@ QueryCombobox.propTypes = {
161
162
  debounceMs:PropTypes.number,
162
163
 
163
164
  /**
164
- * The query to fetch the options
165
+ * The graphql query to fetch the options and the accessor to destructure the results from
165
166
  */
166
- query:PropTypes.oneOfType([
167
- PropTypes.string,
168
- PropTypes.object,
169
- ]).isRequired,
167
+ query:PropTypes.shape({
168
+ accessor:PropTypes.string,
169
+ graphql :PropTypes.oneOfType([
170
+ PropTypes.string,
171
+ PropTypes.object,
172
+ ]).isRequired,
173
+ }),
170
174
 
171
175
  /**
172
176
  * The extra variables required to be used in the query.
@@ -178,8 +182,8 @@ QueryCombobox.propTypes = {
178
182
  * i.e `{ value: 'id', label: 'name' }`
179
183
  */
180
184
  optionsKeyMap:PropTypes.shape({
181
- value:PropTypes.string.isRequired,
182
- label:PropTypes.string.isRequired,
185
+ value :PropTypes.string.isRequired,
186
+ getLabel:PropTypes.func.isRequired,
183
187
  }),
184
188
 
185
189
  /**
@@ -210,8 +214,8 @@ QueryCombobox.propTypes = {
210
214
 
211
215
  QueryCombobox.defaultProps = {
212
216
  optionsKeyMap:{
213
- value:'id',
214
- label:'name',
217
+ value :'id',
218
+ getLabel:(node) => node.name,
215
219
  },
216
220
  multiple :false,
217
221
  color :'background2',