-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(cozy-devtools): Add first version to test providers
- Loading branch information
Showing
16 changed files
with
1,241 additions
and
0 deletions.
There are no files selected for viewing
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
## Cozy-Devtools | ||
|
||
Cozy-Devtools exposes a devtool that can be injected in an app for debug | ||
and better developer experience. It is inspired by the [awesome devtools | ||
for react-query][react-query devtools]. | ||
|
||
To activate it, just run in your browser console: | ||
|
||
```js | ||
flag('debug', true) | ||
``` | ||
|
||
### Usage | ||
|
||
Before using the devtools, you need to install cozy-ui and react-inspector. | ||
|
||
```bash | ||
yarn add cozy-ui # >= 48.0.0 | ||
yarn add react-inspector # >= 5.1.0 | ||
``` | ||
|
||
Next, you need to add it to your app, inside a CozyProvider. | ||
|
||
```jsx | ||
import CozyClient, { CozyProvider } from 'cozy-client' | ||
import CozyDevtools from 'cozy-client/dist/devtools' | ||
|
||
const App = () => { | ||
return <CozyProvider client={client}> | ||
/* Your app is here */ | ||
{ process.env.NODE_ENV !== 'production' ? <CozyDevtools /> : null } | ||
</CozyProvider> | ||
} | ||
``` | ||
|
||
### Panels | ||
|
||
- The devtools is made of several "panels". | ||
- There are default panels and the app can also inject its own adhoc panels. | ||
|
||
#### Queries | ||
|
||
Shows current queries inside cozy-client cache. Allows to see the data of | ||
the query. The execution time is also shown, and is very valuable to track | ||
down performance issues. It uses the execution statistics collected | ||
from CouchDB. | ||
|
||
#### Flags | ||
|
||
Shows all the current flags and allow to modify them. | ||
|
||
#### Libraries | ||
|
||
Show library versions based on the global **VERSIONS** variable that | ||
should be injected by the app. If it is defined, the panel will be blank. | ||
|
||
#### PouchLink | ||
|
||
If you use the PouchLink to synchronize your data to PouchDB, you can use | ||
the optional devtool PouchLink devtool panel. Since PouchDB is optional, | ||
it is not available by default and you need to explicitly tell the Devtools | ||
to display it. | ||
|
||
```jsx | ||
import PouchDevtools from 'cozy-client/dist/devtools/Pouch' | ||
|
||
() => <CozyDevTools panels={{ id: 'pouch', Component: PouchDevtools}} /> | ||
``` | ||
|
||
### Ideas for next features | ||
|
||
- Performance tips in query panels | ||
|
||
- Show index related tips | ||
- Show slow queries | ||
- Show repeating queries | ||
- Show queries downloading too much data | ||
|
||
- Actions on queries | ||
|
||
- Reset data inside query | ||
- Refetch | ||
- Set to error | ||
- Delete from store | ||
|
||
If you have any other idea, please [open an issue][open-issue] 👍 | ||
|
||
[react-query devtools]: https://github.com/tannerlinsley/react-query-devtools | ||
|
||
[open-issue]: https://github.com/cozy/cozy-libs/issues/new |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
module.exports = { | ||
presets: ['cozy-app'], | ||
env: { | ||
transpilation: { | ||
ignore: ['**/*.spec.jsx', '**/*.spec.js', '**/*.spec.tsx', '**/*.spec.ts'] | ||
}, | ||
test: { | ||
presets: [['cozy-app', { transformRuntime: { helpers: true } }]] | ||
} | ||
}, | ||
ignore: ['examples/**/*', '**/*.md', '**/*.snap'] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
module.exports = { | ||
testPathIgnorePatterns: ['node_modules', 'dist'], | ||
testEnvironment: 'jest-environment-jsdom-sixteen', | ||
testURL: 'http://localhost/', | ||
moduleFileExtensions: ['js', 'jsx', 'json', 'ts', 'tsx'], | ||
moduleDirectories: ['src', 'node_modules'], | ||
moduleNameMapper: { | ||
'^cozy-client$': 'cozy-client/dist/index' | ||
}, | ||
transformIgnorePatterns: ['node_modules/(?!(cozy-ui)'], | ||
transform: { | ||
'^.+\\.(ts|tsx|js|jsx)?$': 'babel-jest' | ||
}, | ||
globals: { | ||
__ALLOW_HTTP__: false, | ||
cozy: {} | ||
}, | ||
setupFilesAfterEnv: ['jest-canvas-mock'] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"name": "cozy-devtools", | ||
"version": "0.0.1", | ||
"description": "Cozy-Devtools exposes a devtool that can be injected in an app for debug and better developer experience.", | ||
"main": "dist/index.js", | ||
"license": "MIT", | ||
"homepage": "https://github.com/cozy/cozy-libs/blob/master/packages/cozy-devtools/README.md", | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/cozy/cozy-libs.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/cozy/cozy-libs/issues" | ||
}, | ||
"scripts": { | ||
"build": "rm -rf ./dist && env BABEL_ENV=transpilation babel --extensions .js,.jsx,.md,.styl,.json,.snap ./src -d ./dist --copy-files --no-copy-ignored --verbose", | ||
"start": "yarn build --watch", | ||
"prepublishOnly": "yarn build", | ||
"test": "env NODE_ENV=test jest --passWithNoTests", | ||
"lint": "cd .. && yarn eslint --ext js,jsx packages/cozy-devtools" | ||
}, | ||
"devDependencies": { | ||
"babel-preset-cozy-app": "^2.5.0", | ||
"cozy-client": "^50.0.0", | ||
"cozy-flags": "^4.3.0", | ||
"cozy-intent": "^2.26.0", | ||
"cozy-pouch-link": "^50.0.0", | ||
"cozy-ui": "^111.19.0", | ||
"react": "^16.12.0", | ||
"react-dom": "^16.12.0", | ||
"stylus": "0.64.0" | ||
}, | ||
"dependencies": { | ||
"date-fns": "2.29.3", | ||
"lodash": "4.17.13", | ||
"react-inspector": "5.1.1" | ||
}, | ||
"peerDependencies": { | ||
"cozy-client": ">=50.0.0", | ||
"cozy-flags": ">=4.3.0", | ||
"cozy-intent": ">=2.26.0", | ||
"cozy-pouch-link": ">=50.0.0", | ||
"cozy-ui": ">=111.19.0", | ||
"react": ">=16.12.0", | ||
"react-dom": ">=16.12.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import React, { useEffect, useState } from 'react' | ||
|
||
import flag from 'cozy-flags' | ||
import Button from 'cozy-ui/transpiled/react/Buttons' | ||
import TextField from 'cozy-ui/transpiled/react/TextField' | ||
|
||
import { isJSONString, makeHumanValue } from './helpers' | ||
|
||
const FlagEdit = ({ flag: editedFlag }) => { | ||
const [formData, setFormData] = useState({ | ||
key: '', | ||
name: '', | ||
value: '', | ||
humanValue: '' | ||
}) | ||
|
||
useEffect(() => { | ||
if (editedFlag) setFormData(editedFlag) | ||
}, [editedFlag]) | ||
|
||
const handleSubmit = e => { | ||
e.preventDefault() | ||
if (!formData.name || !formData.value) return | ||
|
||
/** @type {any} */ | ||
let value = formData.value | ||
if (isJSONString(value)) { | ||
value = JSON.parse(value) | ||
} else if (value === 'true' || value === 'false') { | ||
value = Boolean(value) | ||
} | ||
|
||
flag(formData.name, value) | ||
location.reload() | ||
} | ||
|
||
const handleFlagNameChange = e => { | ||
setFormData({ | ||
...formData, | ||
key: `flag__${e.target.value}`, | ||
name: e.target.value | ||
}) | ||
} | ||
|
||
const handleFlagValueChange = e => { | ||
let value = e.target.value | ||
if (Number.isInteger(value)) { | ||
value = parseInt(value) | ||
} | ||
setFormData({ | ||
...formData, | ||
value, | ||
humanValue: makeHumanValue(value) | ||
}) | ||
} | ||
|
||
return ( | ||
<form onSubmit={handleSubmit} className="u-mt-1 u-flex-items-center u-flex"> | ||
<TextField | ||
label="Name" | ||
name="name" | ||
onChange={handleFlagNameChange} | ||
value={formData.name} | ||
size="small" | ||
variant="outlined" | ||
/> | ||
<TextField | ||
label="Value" | ||
name="value" | ||
onChange={handleFlagValueChange} | ||
value={formData.humanValue} | ||
size="small" | ||
variant="outlined" | ||
className="u-ml-1" | ||
/> | ||
<Button type="submit" label="Edit" className="u-ml-1" /> | ||
</form> | ||
) | ||
} | ||
|
||
export { FlagEdit } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import React from 'react' | ||
import { ObjectInspector } from 'react-inspector' | ||
|
||
import flagUtils from 'cozy-flags' | ||
import Checkbox from 'cozy-ui/transpiled/react/Checkbox' | ||
import Icon from 'cozy-ui/transpiled/react/Icon' | ||
import IconButton from 'cozy-ui/transpiled/react/IconButton' | ||
import PenIcon from 'cozy-ui/transpiled/react/Icons/Pen' | ||
import TrashIcon from 'cozy-ui/transpiled/react/Icons/Trash' | ||
import ListItem from 'cozy-ui/transpiled/react/ListItem' | ||
import ListItemIcon from 'cozy-ui/transpiled/react/ListItemIcon' | ||
import ListItemSecondaryAction from 'cozy-ui/transpiled/react/ListItemSecondaryAction' | ||
import ListItemText from 'cozy-ui/transpiled/react/ListItemText' | ||
|
||
const FlagItem = ({ flag, onEdit, onTrash }) => { | ||
const handleCheckboxChange = e => { | ||
flagUtils(flag.name, e.target.checked) | ||
location.reload() | ||
} | ||
|
||
return ( | ||
<ListItem size="small"> | ||
<ListItemIcon> | ||
{flag.type === 'boolean' ? ( | ||
<Checkbox | ||
size="small" | ||
checked={flag.value} | ||
onChange={handleCheckboxChange} | ||
/> | ||
) : null} | ||
</ListItemIcon> | ||
<ListItemText | ||
primary={flag.humanName} | ||
secondary={ | ||
flag.type === 'object' ? ( | ||
<ObjectInspector data={flag.value} /> | ||
) : flag.type !== 'boolean' ? ( | ||
flag.humanValue | ||
) : null | ||
} | ||
/> | ||
<ListItemSecondaryAction> | ||
<IconButton onClick={() => onEdit(flag)}> | ||
<Icon icon={PenIcon} /> | ||
</IconButton> | ||
<IconButton onClick={() => onTrash(flag)}> | ||
<Icon icon={TrashIcon} /> | ||
</IconButton> | ||
</ListItemSecondaryAction> | ||
</ListItem> | ||
) | ||
} | ||
|
||
export default FlagItem |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import React, { useState } from 'react' | ||
|
||
import List from 'cozy-ui/transpiled/react/List' | ||
import Typography from 'cozy-ui/transpiled/react/Typography' | ||
|
||
import { FlagEdit } from './FlagEdit' | ||
import FlagItem from './FlagItem' | ||
import { computeFlags } from './helpers' | ||
import PanelContent from '../PanelContent' | ||
|
||
const Flags = () => { | ||
const [edited, setEdited] = useState(null) | ||
|
||
const flags = computeFlags() | ||
|
||
const handleEdit = flag => { | ||
setEdited(flag) | ||
} | ||
|
||
const handleTrash = flag => { | ||
if (localStorage.getItem(flag.key)) { | ||
localStorage.removeItem(flag.key) | ||
location.reload() | ||
} | ||
} | ||
|
||
return ( | ||
<PanelContent> | ||
<Typography variant="subtitle1">Flags</Typography> | ||
<List dense className="u-maw-6"> | ||
{flags.map(flag => ( | ||
<FlagItem | ||
key={flag.key} | ||
flag={flag} | ||
onEdit={handleEdit} | ||
onTrash={handleTrash} | ||
/> | ||
))} | ||
</List> | ||
<FlagEdit flag={edited} /> | ||
</PanelContent> | ||
) | ||
} | ||
|
||
export default Flags |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import flag from 'cozy-flags' | ||
|
||
const human = name => { | ||
return name.replace(/[a-z][A-Z]/g, str => str[0] + ' ' + str[1].toLowerCase()) | ||
} | ||
|
||
export const makeHumanValue = value => { | ||
return typeof value === 'object' ? JSON.stringify(value) : value.toString() | ||
} | ||
|
||
export const computeFlags = () => { | ||
return flag.list().map(name => { | ||
const value = flag(name) | ||
return { | ||
key: `flag__${name}`, | ||
name, | ||
type: typeof value, | ||
humanName: human(name), | ||
value, | ||
humanValue: makeHumanValue(value) | ||
} | ||
}) | ||
} | ||
|
||
export const isJSONString = str => { | ||
try { | ||
JSON.parse(str) | ||
return true | ||
} catch (e) { | ||
return false | ||
} | ||
} |
Oops, something went wrong.