|
1 | 1 | import React from 'react'
|
2 |
| -import { Link } from 'react-router-dom' |
3 | 2 | import PropTypes from 'prop-types'
|
4 |
| -import classNames from 'classnames' |
5 |
| -import resolveBadgeUrl from '../lib/badge-url' |
| 3 | +import { badgeUrlFromPath, staticBadgeUrl } from '../../lib/make-badge-url' |
6 | 4 |
|
7 |
| -const Badge = ({ |
8 |
| - title, |
9 |
| - exampleUrl, |
10 |
| - previewUrl, |
11 |
| - urlPattern, |
12 |
| - documentation, |
13 |
| - baseUrl, |
14 |
| - longCache, |
15 |
| - shouldDisplay = () => true, |
16 |
| - onClick, |
17 |
| -}) => { |
18 |
| - const handleClick = onClick |
19 |
| - ? () => |
20 |
| - onClick({ |
21 |
| - title, |
22 |
| - exampleUrl, |
23 |
| - previewUrl, |
24 |
| - urlPattern, |
25 |
| - documentation, |
26 |
| - }) |
27 |
| - : undefined |
| 5 | +export default class BadgeExamples extends React.Component { |
| 6 | + static propTypes = { |
| 7 | + definitions: PropTypes.array.isRequired, |
| 8 | + baseUrl: PropTypes.string, |
| 9 | + longCache: PropTypes.bool.isRequired, |
| 10 | + onClick: PropTypes.func.isRequired, |
| 11 | + } |
| 12 | + |
| 13 | + renderExample(exampleData) { |
| 14 | + const { baseUrl, longCache, onClick } = this.props |
| 15 | + const { title, example, preview } = exampleData |
| 16 | + |
| 17 | + let previewUrl |
| 18 | + // There are two alternatives for `preview`. Refer to the schema in |
| 19 | + // `services/service-definitions.js`. |
| 20 | + if (preview.label !== undefined) { |
| 21 | + const { label, message, color } = preview |
| 22 | + previewUrl = staticBadgeUrl({ baseUrl, label, message, color }) |
| 23 | + } else { |
| 24 | + const { path, queryParams } = preview |
| 25 | + previewUrl = badgeUrlFromPath({ baseUrl, path, queryParams, longCache }) |
| 26 | + } |
| 27 | + |
| 28 | + // There are two alternatives for `example`. Refer to the schema in |
| 29 | + // `services/service-definitions.js`. |
| 30 | + let exampleUrl |
| 31 | + if (example.pattern !== undefined) { |
| 32 | + const { pattern, namedParams, queryParams } = example |
| 33 | + exampleUrl = badgeUrlFromPath({ |
| 34 | + baseUrl, |
| 35 | + path: pattern, |
| 36 | + namedParams, |
| 37 | + queryParams, |
| 38 | + }) |
| 39 | + } else { |
| 40 | + const { path, queryParams } = example |
| 41 | + exampleUrl = badgeUrlFromPath({ baseUrl, path, queryParams }) |
| 42 | + } |
| 43 | + |
| 44 | + const key = `${title} ${previewUrl} ${exampleUrl}` |
28 | 45 |
|
29 |
| - const previewImage = previewUrl ? ( |
30 |
| - <img |
31 |
| - className={classNames('badge-img', { clickable: onClick })} |
32 |
| - onClick={handleClick} |
33 |
| - src={resolveBadgeUrl(previewUrl, baseUrl, { longCache })} |
34 |
| - alt="" |
35 |
| - /> |
36 |
| - ) : ( |
37 |
| - '\u00a0' |
38 |
| - ) // non-breaking space |
39 |
| - const resolvedExampleUrl = resolveBadgeUrl( |
40 |
| - urlPattern || previewUrl, |
41 |
| - baseUrl, |
42 |
| - { longCache: false } |
43 |
| - ) |
| 46 | + const handleClick = () => onClick(exampleData) |
44 | 47 |
|
45 |
| - if (shouldDisplay()) { |
46 | 48 | return (
|
47 |
| - <tr> |
48 |
| - <th |
49 |
| - className={classNames({ clickable: onClick })} |
50 |
| - onClick={handleClick} |
51 |
| - > |
| 49 | + <tr key={key}> |
| 50 | + <th className="clickable" onClick={handleClick}> |
52 | 51 | {title}:
|
53 | 52 | </th>
|
54 |
| - <td>{previewImage}</td> |
55 | 53 | <td>
|
56 |
| - <code |
57 |
| - className={classNames({ clickable: onClick })} |
| 54 | + <img |
| 55 | + className="badge-img clickable" |
58 | 56 | onClick={handleClick}
|
59 |
| - > |
60 |
| - {resolvedExampleUrl} |
| 57 | + src={previewUrl} |
| 58 | + alt="" |
| 59 | + /> |
| 60 | + </td> |
| 61 | + <td> |
| 62 | + <code className="clickable" onClick={handleClick}> |
| 63 | + {exampleUrl} |
61 | 64 | </code>
|
62 | 65 | </td>
|
63 | 66 | </tr>
|
64 | 67 | )
|
65 | 68 | }
|
66 |
| - return null |
67 |
| -} |
68 |
| -Badge.propTypes = { |
69 |
| - title: PropTypes.string.isRequired, |
70 |
| - exampleUrl: PropTypes.string, |
71 |
| - previewUrl: PropTypes.string, |
72 |
| - urlPattern: PropTypes.string, |
73 |
| - documentation: PropTypes.string, |
74 |
| - baseUrl: PropTypes.string, |
75 |
| - longCache: PropTypes.bool.isRequired, |
76 |
| - shouldDisplay: PropTypes.func, |
77 |
| - onClick: PropTypes.func.isRequired, |
78 |
| -} |
79 | 69 |
|
80 |
| -const Category = ({ category, examples, baseUrl, longCache, onClick }) => { |
81 |
| - if (examples.filter(example => example.shouldDisplay()).length === 0) { |
82 |
| - return null |
83 |
| - } |
84 |
| - return ( |
85 |
| - <div> |
86 |
| - <Link to={`/examples/${category.id}`}> |
87 |
| - <h3 id={category.id}>{category.name}</h3> |
88 |
| - </Link> |
89 |
| - <table className="badge"> |
90 |
| - <tbody> |
91 |
| - {examples.map(badgeData => ( |
92 |
| - <Badge |
93 |
| - key={badgeData.key} |
94 |
| - {...badgeData} |
95 |
| - baseUrl={baseUrl} |
96 |
| - longCache={longCache} |
97 |
| - onClick={onClick} |
98 |
| - /> |
99 |
| - ))} |
100 |
| - </tbody> |
101 |
| - </table> |
102 |
| - </div> |
103 |
| - ) |
104 |
| -} |
105 |
| -Category.propTypes = { |
106 |
| - category: PropTypes.shape({ |
107 |
| - id: PropTypes.string.isRequired, |
108 |
| - name: PropTypes.string.isRequired, |
109 |
| - }).isRequired, |
110 |
| - examples: PropTypes.arrayOf( |
111 |
| - PropTypes.shape({ |
112 |
| - title: PropTypes.string.isRequired, |
113 |
| - exampleUrl: PropTypes.string, |
114 |
| - previewUrl: PropTypes.string, |
115 |
| - urlPattern: PropTypes.string, |
116 |
| - documentation: PropTypes.string, |
117 |
| - }) |
118 |
| - ).isRequired, |
119 |
| - baseUrl: PropTypes.string, |
120 |
| - longCache: PropTypes.bool.isRequired, |
121 |
| - onClick: PropTypes.func.isRequired, |
122 |
| -} |
| 70 | + render() { |
| 71 | + const { definitions } = this.props |
123 | 72 |
|
124 |
| -const BadgeExamples = ({ categories, baseUrl, longCache, onClick }) => ( |
125 |
| - <div> |
126 |
| - {categories.map((categoryData, i) => ( |
127 |
| - <Category |
128 |
| - key={i} |
129 |
| - {...categoryData} |
130 |
| - baseUrl={baseUrl} |
131 |
| - longCache={longCache} |
132 |
| - onClick={onClick} |
133 |
| - /> |
134 |
| - ))} |
135 |
| - </div> |
136 |
| -) |
137 |
| -BadgeExamples.propTypes = { |
138 |
| - categories: PropTypes.arrayOf( |
139 |
| - PropTypes.shape({ |
140 |
| - category: Category.propTypes.category, |
141 |
| - examples: Category.propTypes.examples, |
142 |
| - }) |
143 |
| - ), |
144 |
| - baseUrl: PropTypes.string, |
145 |
| - longCache: PropTypes.bool.isRequired, |
146 |
| - onClick: PropTypes.func.isRequired, |
147 |
| -} |
| 73 | + if (!definitions) { |
| 74 | + return null |
| 75 | + } |
| 76 | + |
| 77 | + const flattened = definitions.reduce((accum, current) => { |
| 78 | + const { examples } = current |
| 79 | + return accum.concat(examples) |
| 80 | + }, []) |
148 | 81 |
|
149 |
| -export { Badge, BadgeExamples } |
| 82 | + return ( |
| 83 | + <div> |
| 84 | + <table className="badge"> |
| 85 | + <tbody> |
| 86 | + {flattened.map(exampleData => this.renderExample(exampleData))} |
| 87 | + </tbody> |
| 88 | + </table> |
| 89 | + </div> |
| 90 | + ) |
| 91 | + } |
| 92 | +} |
0 commit comments