rewrite plugins mgmt page with react
This commit is contained in:
parent
640a714d8e
commit
cd3260af3e
1
.github/workflows/CI.yml
vendored
1
.github/workflows/CI.yml
vendored
|
|
@ -88,6 +88,7 @@ jobs:
|
|||
run: |
|
||||
yarn lint
|
||||
yarn tsc -p . --noEmit
|
||||
yarn tsc -p ./resources/assets/tests --noEmit
|
||||
jest:
|
||||
name: Frontend Tests
|
||||
runs-on: ubuntu-latest
|
||||
|
|
|
|||
21
package.json
21
package.json
|
|
@ -18,10 +18,14 @@
|
|||
"dependencies": {
|
||||
"@babel/runtime": "^7.8.0",
|
||||
"@fortawesome/fontawesome-free": "^5.12.0",
|
||||
"@hot-loader/react-dom": "^16.11.0",
|
||||
"@tweenjs/tween.js": "^18.4.2",
|
||||
"admin-lte": "^3.0.1",
|
||||
"echarts": "^4.6.0",
|
||||
"jquery": "^3.4.1",
|
||||
"react": "^16.12.0",
|
||||
"react-dom": "^16.12.0",
|
||||
"react-hot-loader": "^4.12.18",
|
||||
"rxjs": "^6.5.3",
|
||||
"skinview3d": "^1.2.1",
|
||||
"vue": "^2.6.11",
|
||||
|
|
@ -35,10 +39,13 @@
|
|||
"@babel/plugin-transform-runtime": "^7.8.3",
|
||||
"@babel/preset-env": "^7.8.2",
|
||||
"@gplane/tsconfig": "^1.0.0",
|
||||
"@testing-library/react": "^9.4.0",
|
||||
"@types/bootstrap": "^4.3.1",
|
||||
"@types/echarts": "^4.4.2",
|
||||
"@types/jest": "^24.0.25",
|
||||
"@types/jquery": "^3.3.29",
|
||||
"@types/react": "^16.9.17",
|
||||
"@types/react-dom": "^16.9.4",
|
||||
"@types/webpack": "^4.41.2",
|
||||
"@typescript-eslint/eslint-plugin": "^2.8.0",
|
||||
"@typescript-eslint/parser": "^2.8.0",
|
||||
|
|
@ -188,12 +195,13 @@
|
|||
"js",
|
||||
"vue",
|
||||
"ts",
|
||||
"tsx",
|
||||
"json",
|
||||
"node"
|
||||
],
|
||||
"moduleNameMapper": {
|
||||
"^@/(.*)$": "<rootDir>/resources/assets/src/$1",
|
||||
"\\.css$": "<rootDir>/resources/assets/tests/__mocks__/style.ts",
|
||||
"\\.(css|styl)$": "<rootDir>/resources/assets/tests/__mocks__/style.ts",
|
||||
"\\.(png|jpg)$": "<rootDir>/resources/assets/tests/__mocks__/file.ts"
|
||||
},
|
||||
"setupFilesAfterEnv": [
|
||||
|
|
@ -204,6 +212,15 @@
|
|||
"<rootDir>/resources/assets/tests/setup",
|
||||
"<rootDir>/resources/assets/tests/utils"
|
||||
],
|
||||
"testRegex": "resources/assets/tests/.*\\.(spec|test)\\.(t|j)s$"
|
||||
"testMatch": [
|
||||
"<rootDir>/resources/assets/tests/**/*.test.ts",
|
||||
"<rootDir>/resources/assets/tests/**/*.test.tsx"
|
||||
],
|
||||
"globals": {
|
||||
"ts-jest": {
|
||||
"tsConfig": "<rootDir>/resources/assets/tests/tsconfig.json",
|
||||
"isolatedModules": true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
9
resources/assets/src/components/Loading.tsx
Normal file
9
resources/assets/src/components/Loading.tsx
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
import React from 'react'
|
||||
|
||||
const Loading = () => (
|
||||
<div className="container text-center" title="Loading...">
|
||||
<i className="fas fa-sync fa-spin"></i>
|
||||
</div>
|
||||
)
|
||||
|
||||
export default Loading
|
||||
|
|
@ -1,6 +1,9 @@
|
|||
import Vue from 'vue'
|
||||
import * as React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import './scripts/app'
|
||||
import routes from './scripts/route'
|
||||
import Loading from './components/Loading'
|
||||
|
||||
Vue.config.productionTip = false
|
||||
|
||||
|
|
@ -15,6 +18,17 @@ function loadModules() {
|
|||
if (route.module) {
|
||||
Promise.all(route.module.map(m => m()))
|
||||
}
|
||||
if (route.react) {
|
||||
const Component = React.lazy(
|
||||
route.react as (() => Promise<{ default: React.ComponentType }>)
|
||||
)
|
||||
const Root = () => (
|
||||
<React.Suspense fallback={<Loading />}>
|
||||
<Component />
|
||||
</React.Suspense>
|
||||
)
|
||||
ReactDOM.render(<Root />, document.querySelector(route.el))
|
||||
}
|
||||
if (route.component) {
|
||||
Vue.prototype.$route = new RegExp(`^${route.path}$`, 'i').exec(blessing.route)
|
||||
// eslint-disable-next-line no-new
|
||||
|
|
@ -44,5 +44,4 @@ Vue.use(_Vue => {
|
|||
})
|
||||
})
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/unbound-method
|
||||
window.trans = trans
|
||||
Object.assign(window, { trans })
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import { queryStringify } from './utils'
|
|||
import { showModal } from './notify'
|
||||
import { trans } from './i18n'
|
||||
|
||||
export interface ResponseBody {
|
||||
export interface ResponseBody<T = null> {
|
||||
code: number
|
||||
message: string
|
||||
data: T extends null ? never : T
|
||||
}
|
||||
|
||||
class HTTPError extends Error {
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ export default [
|
|||
},
|
||||
{
|
||||
path: 'admin/plugins/manage',
|
||||
component: () => import('../views/admin/Plugins.vue'),
|
||||
react: () => import('../views/admin/PluginsManagement'),
|
||||
el: '.content > .container-fluid',
|
||||
},
|
||||
{
|
||||
|
|
|
|||
9
resources/assets/src/shims.d.ts
vendored
9
resources/assets/src/shims.d.ts
vendored
|
|
@ -1,25 +1,22 @@
|
|||
import Vue from 'vue'
|
||||
import * as JQuery from 'jquery'
|
||||
import JQuery from 'jquery'
|
||||
import { ModalOptions, ModalResult } from './scripts/modal'
|
||||
import { Toast } from './scripts/toast'
|
||||
|
||||
type I18n = 'en' | 'zh_CN'
|
||||
|
||||
declare global {
|
||||
// eslint-disable-next-line no-redeclare
|
||||
let blessing: {
|
||||
base_url: string
|
||||
debug: boolean
|
||||
env: string
|
||||
fallback_locale: I18n
|
||||
locale: I18n
|
||||
fallback_locale: string
|
||||
locale: string
|
||||
site_name: string
|
||||
timezone: string
|
||||
version: string
|
||||
route: string
|
||||
extra: any
|
||||
i18n: object
|
||||
ui: object
|
||||
|
||||
fetch: {
|
||||
get(url: string, params?: object): Promise<object>
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
.box
|
||||
cursor default
|
||||
transition-property box-shadow
|
||||
transition-duration 0.3s
|
||||
width 32%
|
||||
@media (max-width: 1280px)
|
||||
width 47%
|
||||
@media (max-width: 768px)
|
||||
width 100%
|
||||
&:hover
|
||||
box-shadow 0 .5rem 1rem rgba(0,0,0,.15)
|
||||
|
||||
.content
|
||||
max-width 85%
|
||||
|
||||
.actions
|
||||
margin-top -7px
|
||||
a
|
||||
transition-property color
|
||||
transition-duration 0.3s
|
||||
color #000
|
||||
&:hover
|
||||
color #999
|
||||
&:not(:last-child)
|
||||
margin-right 9px
|
||||
|
||||
.description
|
||||
font-size 14px
|
||||
white-space nowrap
|
||||
overflow hidden
|
||||
text-overflow ellipsis
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
import React, { useCallback } from 'react'
|
||||
import { trans } from '../../../scripts/i18n'
|
||||
import { Plugin } from './types'
|
||||
import styles from './InfoBox.styl'
|
||||
|
||||
interface Props {
|
||||
plugin: Plugin
|
||||
onEnable(plugin: Plugin): void
|
||||
onDisable(plugin: Plugin): void
|
||||
onDelete(plugin: Plugin): void
|
||||
baseUrl: string
|
||||
}
|
||||
|
||||
const InfoBox: React.FC<Props> = props => {
|
||||
const { plugin } = props
|
||||
|
||||
const handleChange = useCallback(
|
||||
(event: React.ChangeEvent<HTMLInputElement>) => {
|
||||
event.preventDefault()
|
||||
|
||||
if (event.target.checked) {
|
||||
props.onEnable(plugin)
|
||||
} else {
|
||||
props.onDisable(plugin)
|
||||
}
|
||||
},
|
||||
[],
|
||||
)
|
||||
|
||||
const handleDelete = useCallback(() => {
|
||||
props.onDelete(plugin)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div className={`info-box mr-3 ${styles.box}`}>
|
||||
<span className={`info-box-icon bg-${plugin.icon.bg}`}>
|
||||
<i className={`${plugin.icon.faType} fa-${plugin.icon.fa}`} />
|
||||
</span>
|
||||
<div className={`info-box-content ${styles.content}`}>
|
||||
<div className="d-flex justify-content-between">
|
||||
<div>
|
||||
<input
|
||||
className="mr-2"
|
||||
type="checkbox"
|
||||
checked={plugin.enabled}
|
||||
title={
|
||||
plugin.enabled
|
||||
? trans('admin.disablePlugin')
|
||||
: trans('admin.enablePlugin')
|
||||
}
|
||||
onChange={handleChange}
|
||||
/>
|
||||
<strong className="mr-2">{plugin.title}</strong>
|
||||
<span className="text-gray">v{plugin.version}</span>
|
||||
</div>
|
||||
<div className={styles.actions}>
|
||||
{plugin.readme && (
|
||||
<a
|
||||
href={`${props.baseUrl}/admin/plugins/readme/${plugin.name}`}
|
||||
title={trans('admin.pluginReadme')}
|
||||
>
|
||||
<i className="fas fa-question" />
|
||||
</a>
|
||||
)}
|
||||
{plugin.enabled && plugin.config && (
|
||||
<a
|
||||
href={`${props.baseUrl}/admin/plugins/config/${plugin.name}`}
|
||||
title={trans('admin.configurePlugin')}
|
||||
>
|
||||
<i className="fas fa-cog" />
|
||||
</a>
|
||||
)}
|
||||
<a
|
||||
href="#"
|
||||
title={trans('admin.deletePlugin')}
|
||||
onClick={handleDelete}
|
||||
>
|
||||
<i className="fas fa-trash" />
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className={`mt-2 ${styles.description}`}>{plugin.description}</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(InfoBox)
|
||||
103
resources/assets/src/views/admin/PluginsManagement/index.tsx
Normal file
103
resources/assets/src/views/admin/PluginsManagement/index.tsx
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
import React, { useState, useEffect, useCallback } from 'react'
|
||||
import { hot } from 'react-hot-loader/root'
|
||||
import { trans } from '../../../scripts/i18n'
|
||||
import * as fetch from '../../../scripts/net'
|
||||
import { toast, showModal } from '../../../scripts/notify'
|
||||
import Loading from '../../../components/Loading'
|
||||
import alertUnresolved from '../../../components/mixins/alertUnresolvedPlugins'
|
||||
import InfoBox from './InfoBox'
|
||||
import { Plugin } from './types'
|
||||
|
||||
const PluginsManagement: React.FC = () => {
|
||||
const [loading, setLoading] = useState(false)
|
||||
const [plugins, setPlugins] = useState<Plugin[]>([])
|
||||
useEffect(() => {
|
||||
const getPlugins = async () => {
|
||||
setLoading(true)
|
||||
setPlugins(await fetch.get('/admin/plugins/data'))
|
||||
setLoading(false)
|
||||
}
|
||||
getPlugins()
|
||||
}, [])
|
||||
|
||||
const handleEnable = useCallback(async (plugin: Plugin, i: number) => {
|
||||
const {
|
||||
code,
|
||||
message,
|
||||
data: { reason } = { reason: [] },
|
||||
}: fetch.ResponseBody<{
|
||||
reason: string[]
|
||||
}> = await fetch.post('/admin/plugins/manage', {
|
||||
action: 'enable',
|
||||
name: plugin.name,
|
||||
})
|
||||
if (code === 0) {
|
||||
toast.success(message)
|
||||
setPlugins(plugins => {
|
||||
plugins.splice(i, 1, { ...plugin, enabled: true })
|
||||
return plugins.slice()
|
||||
})
|
||||
} else {
|
||||
alertUnresolved(message, reason)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleDisable = useCallback(async (plugin: Plugin, i: number) => {
|
||||
const { code, message } = await fetch.post('/admin/plugins/manage', {
|
||||
action: 'disable',
|
||||
name: plugin.name,
|
||||
})
|
||||
if (code === 0) {
|
||||
toast.success(message)
|
||||
setPlugins(plugins => {
|
||||
plugins.splice(i, 1, { ...plugin, enabled: false })
|
||||
return plugins.slice()
|
||||
})
|
||||
} else {
|
||||
toast.error(message)
|
||||
}
|
||||
}, [])
|
||||
|
||||
const handleDelete = useCallback(async (plugin: Plugin) => {
|
||||
try {
|
||||
await showModal({
|
||||
title: plugin.title,
|
||||
text: trans('admin.confirmDeletion'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
} catch {
|
||||
return
|
||||
}
|
||||
|
||||
const { code, message } = await fetch.post('/admin/plugins/manage', {
|
||||
action: 'delete',
|
||||
name: plugin.name,
|
||||
})
|
||||
if (code === 0) {
|
||||
const { name } = plugin
|
||||
setPlugins(plugins => plugins.filter(plugin => plugin.name !== name))
|
||||
toast.success(message)
|
||||
} else {
|
||||
toast.error(message)
|
||||
}
|
||||
}, [])
|
||||
|
||||
return loading ? (
|
||||
<Loading />
|
||||
) : (
|
||||
<div className="d-flex flex-wrap">
|
||||
{plugins.map((plugin, i) => (
|
||||
<InfoBox
|
||||
key={plugin.name}
|
||||
plugin={plugin}
|
||||
onEnable={plugin => handleEnable(plugin, i)}
|
||||
onDisable={plugin => handleDisable(plugin, i)}
|
||||
onDelete={handleDelete}
|
||||
baseUrl={blessing.base_url}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default hot(PluginsManagement)
|
||||
10
resources/assets/src/views/admin/PluginsManagement/types.ts
Normal file
10
resources/assets/src/views/admin/PluginsManagement/types.ts
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
export type Plugin = {
|
||||
name: string
|
||||
title: string
|
||||
description: string
|
||||
version: string
|
||||
enabled: boolean
|
||||
config: boolean
|
||||
readme: boolean
|
||||
icon: { fa: string; faType: 'fas' | 'fab'; bg: string }
|
||||
}
|
||||
9
resources/assets/src/webpack.d.ts
vendored
Normal file
9
resources/assets/src/webpack.d.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
declare module '*.vue' {
|
||||
import Vue from 'vue'
|
||||
|
||||
export default Vue
|
||||
}
|
||||
|
||||
declare module '*.styl' {
|
||||
export default {} as Record<string, string>
|
||||
}
|
||||
21
resources/assets/tests/tsconfig.json
Normal file
21
resources/assets/tests/tsconfig.json
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"extends": "../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"baseUrl": "..",
|
||||
"paths": {
|
||||
"@/scripts/*": [
|
||||
"./tests/ts-shims/*",
|
||||
"./src/scripts/*"
|
||||
],
|
||||
"@/components/*": [
|
||||
"./src/components/*"
|
||||
],
|
||||
"@/views/*": [
|
||||
"./src/views/*"
|
||||
]
|
||||
}
|
||||
},
|
||||
"include": [
|
||||
"."
|
||||
]
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
class Request {
|
||||
declare class Request {
|
||||
url: string
|
||||
|
||||
headers: Map<string, string>
|
||||
|
|
@ -19,3 +19,15 @@ interface Window {
|
|||
|
||||
$: jest.Mock
|
||||
}
|
||||
|
||||
declare let blessing: {
|
||||
base_url: string
|
||||
site_name: string
|
||||
timezone: string
|
||||
version: string
|
||||
route: string
|
||||
extra: any
|
||||
i18n: object
|
||||
fetch: any
|
||||
event: any
|
||||
}
|
||||
204
resources/assets/tests/views/admin/PluginsManagement.test.tsx
Normal file
204
resources/assets/tests/views/admin/PluginsManagement.test.tsx
Normal file
|
|
@ -0,0 +1,204 @@
|
|||
import React from 'react'
|
||||
import { render, wait, fireEvent } from '@testing-library/react'
|
||||
import { trans } from '@/scripts/i18n'
|
||||
import * as fetch from '@/scripts/net'
|
||||
import { showModal, toast } from '@/scripts/notify'
|
||||
import PluginsManagement from '@/views/admin/PluginsManagement'
|
||||
|
||||
jest.mock('@/scripts/net')
|
||||
jest.mock('@/scripts/notify')
|
||||
|
||||
test('show loading indicator', () => {
|
||||
fetch.get.mockResolvedValue([])
|
||||
const { queryByTitle } = render(<PluginsManagement />)
|
||||
expect(queryByTitle('Loading...')).not.toBeNull()
|
||||
})
|
||||
|
||||
test('plugin info box', async () => {
|
||||
fetch.get.mockResolvedValue([
|
||||
{
|
||||
name: 'a',
|
||||
title: 'My Plugin',
|
||||
version: '1.0.0',
|
||||
description: 'desc',
|
||||
config: true,
|
||||
readme: true,
|
||||
icon: {},
|
||||
enabled: true,
|
||||
},
|
||||
])
|
||||
|
||||
const { queryByTitle, queryByText } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
expect(queryByTitle(trans('admin.configurePlugin'))).not.toBeNull()
|
||||
expect(queryByTitle(trans('admin.pluginReadme'))).not.toBeNull()
|
||||
expect(queryByText('My Plugin')).not.toBeNull()
|
||||
expect(queryByText('v1.0.0')).not.toBeNull()
|
||||
expect(queryByText('desc')).not.toBeNull()
|
||||
})
|
||||
|
||||
describe('enable plugin', () => {
|
||||
beforeEach(() => {
|
||||
fetch.get.mockResolvedValue([
|
||||
{
|
||||
name: 'a',
|
||||
icon: {},
|
||||
enabled: false,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('successfully', async () => {
|
||||
fetch.get.mockResolvedValue([
|
||||
{
|
||||
name: 'a',
|
||||
icon: {},
|
||||
enabled: false,
|
||||
},
|
||||
])
|
||||
fetch.post.mockResolvedValue({ code: 0, message: '0' })
|
||||
|
||||
const { getByTitle } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
fireEvent.click(getByTitle(trans('admin.enablePlugin')))
|
||||
await wait()
|
||||
|
||||
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
|
||||
action: 'enable',
|
||||
name: 'a',
|
||||
})
|
||||
expect(toast.success).toBeCalled()
|
||||
})
|
||||
|
||||
it('failed', async () => {
|
||||
fetch.post.mockResolvedValue({
|
||||
code: 1,
|
||||
message: '1',
|
||||
data: { reason: ['abc'] },
|
||||
})
|
||||
|
||||
const { getByTitle } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
fireEvent.click(getByTitle(trans('admin.enablePlugin')))
|
||||
await wait()
|
||||
|
||||
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
|
||||
action: 'enable',
|
||||
name: 'a',
|
||||
})
|
||||
expect(showModal).toBeCalledWith({
|
||||
mode: 'alert',
|
||||
dangerousHTML: expect.stringContaining('<li>abc</li>'),
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('disable plugin', () => {
|
||||
beforeEach(() => {
|
||||
fetch.get.mockResolvedValue([
|
||||
{
|
||||
name: 'a',
|
||||
icon: {},
|
||||
enabled: true,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('successfully', async () => {
|
||||
fetch.post.mockResolvedValue({ code: 0, message: '0' })
|
||||
|
||||
const { getByTitle } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
fireEvent.click(getByTitle(trans('admin.disablePlugin')))
|
||||
await wait()
|
||||
|
||||
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
|
||||
action: 'disable',
|
||||
name: 'a',
|
||||
})
|
||||
expect(toast.success).toBeCalledWith('0')
|
||||
})
|
||||
|
||||
it('failed', async () => {
|
||||
fetch.post.mockResolvedValue({ code: 1, message: '1' })
|
||||
|
||||
const { getByTitle } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
fireEvent.click(getByTitle(trans('admin.disablePlugin')))
|
||||
await wait()
|
||||
|
||||
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
|
||||
action: 'disable',
|
||||
name: 'a',
|
||||
})
|
||||
expect(toast.error).toBeCalledWith('1')
|
||||
})
|
||||
})
|
||||
|
||||
describe('delete plugin', () => {
|
||||
beforeEach(() => {
|
||||
fetch.get.mockResolvedValue([
|
||||
{
|
||||
name: 'a',
|
||||
title: 'My Plugin',
|
||||
icon: {},
|
||||
enabled: false,
|
||||
},
|
||||
])
|
||||
})
|
||||
|
||||
it('rejected by user', async () => {
|
||||
showModal.mockRejectedValue({})
|
||||
|
||||
const { getByTitle } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
fireEvent.click(getByTitle(trans('admin.deletePlugin')))
|
||||
await wait()
|
||||
expect(showModal).toBeCalledWith({
|
||||
title: 'My Plugin',
|
||||
text: trans('admin.confirmDeletion'),
|
||||
okButtonType: 'danger',
|
||||
})
|
||||
expect(fetch.post).not.toBeCalled()
|
||||
})
|
||||
|
||||
it('successfully', async () => {
|
||||
showModal.mockResolvedValue({ value: '' })
|
||||
fetch.post.mockResolvedValue({ code: 0, message: '0' })
|
||||
|
||||
const { getByTitle, queryByText } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
fireEvent.click(getByTitle(trans('admin.deletePlugin')))
|
||||
await wait()
|
||||
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
|
||||
action: 'delete',
|
||||
name: 'a',
|
||||
})
|
||||
expect(toast.success).toBeCalledWith('0')
|
||||
expect(queryByText('My Plugin')).toBeNull()
|
||||
})
|
||||
|
||||
it('failed', async () => {
|
||||
showModal.mockResolvedValue({ value: '' })
|
||||
fetch.post.mockResolvedValue({ code: 1, message: '1' })
|
||||
|
||||
const { getByTitle, queryByText } = render(<PluginsManagement />)
|
||||
await wait()
|
||||
|
||||
fireEvent.click(getByTitle(trans('admin.deletePlugin')))
|
||||
await wait()
|
||||
expect(fetch.post).toBeCalledWith('/admin/plugins/manage', {
|
||||
action: 'delete',
|
||||
name: 'a',
|
||||
})
|
||||
expect(toast.error).toBeCalledWith('1')
|
||||
expect(queryByText('My Plugin')).not.toBeNull()
|
||||
})
|
||||
})
|
||||
6
resources/assets/tests/webpack.d.ts
vendored
6
resources/assets/tests/webpack.d.ts
vendored
|
|
@ -5,9 +5,5 @@ declare module '*.vue' {
|
|||
}
|
||||
|
||||
declare module '*.styl' {
|
||||
export default {}
|
||||
}
|
||||
|
||||
declare module '*.yml' {
|
||||
export default {}
|
||||
export default {} as Record<string, string>
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,22 +5,10 @@
|
|||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/scripts/*": [
|
||||
"./resources/assets/tests/ts-shims/*",
|
||||
"./resources/assets/src/scripts/*"
|
||||
],
|
||||
"@/components/*": [
|
||||
"./resources/assets/src/components/*"
|
||||
],
|
||||
"@/views/*": [
|
||||
"./resources/assets/src/views/*"
|
||||
]
|
||||
}
|
||||
"incremental": true
|
||||
},
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
"plugins",
|
||||
"vendor"
|
||||
"include": [
|
||||
"resources/assets/src",
|
||||
"resources/assets/webpack.d.ts"
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ const devMode = !process.argv.includes('-p')
|
|||
const config = {
|
||||
mode: devMode ? 'development' : 'production',
|
||||
entry: {
|
||||
app: './resources/assets/src/index.ts',
|
||||
app: ['react-hot-loader/patch', './resources/assets/src/index.tsx'],
|
||||
'language-chooser': './resources/assets/src/scripts/language-chooser.ts',
|
||||
style: [
|
||||
'bootstrap/dist/css/bootstrap.min.css',
|
||||
|
|
@ -46,8 +46,7 @@ const config = {
|
|||
use: ['cache-loader', 'vue-loader'],
|
||||
},
|
||||
{
|
||||
test: /\.(css|styl(us)?)$/,
|
||||
exclude: /node_modules/,
|
||||
test: /\.vue.*\.stylus$/,
|
||||
use: [
|
||||
'vue-style-loader',
|
||||
{ loader: 'css-loader', options: { importLoaders: 2 } },
|
||||
|
|
@ -55,6 +54,25 @@ const config = {
|
|||
'stylus-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /views.*\.styl$/,
|
||||
use: [
|
||||
'style-loader',
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
importLoaders: 2,
|
||||
modules: {
|
||||
localIdentName: devMode ? '[name]__[local]' : '[hash:base64]',
|
||||
},
|
||||
localsConvention: 'dashes',
|
||||
esModule: true,
|
||||
},
|
||||
},
|
||||
'postcss-loader',
|
||||
'stylus-loader',
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /(node_modules.*)\.css$/,
|
||||
use: [
|
||||
|
|
@ -93,7 +111,10 @@ const config = {
|
|||
}),
|
||||
],
|
||||
resolve: {
|
||||
extensions: ['.js', '.ts', '.vue', '.json'],
|
||||
extensions: ['.js', '.ts', '.tsx', '.vue', '.json'],
|
||||
alias: {
|
||||
'react-dom': '@hot-loader/react-dom',
|
||||
},
|
||||
},
|
||||
optimization: {
|
||||
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
|
||||
|
|
|
|||
212
yarn.lock
212
yarn.lock
|
|
@ -828,6 +828,13 @@
|
|||
levenary "^1.1.0"
|
||||
semver "^5.5.0"
|
||||
|
||||
"@babel/runtime@^7.6.2", "@babel/runtime@^7.7.6":
|
||||
version "7.8.3"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.3.tgz#0811944f73a6c926bb2ad35e918dcc1bfab279f1"
|
||||
integrity sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.2"
|
||||
|
||||
"@babel/runtime@^7.8.0":
|
||||
version "7.8.0"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.0.tgz#8c81711517c56b3d00c6de706b0fb13dc3531549"
|
||||
|
|
@ -960,6 +967,16 @@
|
|||
resolved "https://registry.npmjs.org/@gplane/tsconfig/-/tsconfig-1.0.0.tgz#c7e6d56ece3d045abe46d00aece990d8412440f0"
|
||||
integrity sha512-x0Lxt+oBXGVK8qYYLQvohFYQZlt9KgeVfkGAEXWOq38Gxu5KdcsGzPvyWPMhz5Og/U2pWXbjw4+rN4Qa7CPiWQ==
|
||||
|
||||
"@hot-loader/react-dom@^16.11.0":
|
||||
version "16.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@hot-loader/react-dom/-/react-dom-16.11.0.tgz#c0b483923b289db5431516f56ee2a69448ebf9bd"
|
||||
integrity sha512-cIOVB8YgT4EVCNiXK+gGuYl6adW/TKlW3N7GvgY5QgpL2NTWagF/oJxVscHSdR3O7NjJsoxdseB5spqwCHNIhA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.17.0"
|
||||
|
||||
"@jest/console@^24.7.1":
|
||||
version "24.7.1"
|
||||
resolved "https://registry.npmjs.org/@jest/console/-/console-24.7.1.tgz#32a9e42535a97aedfe037e725bd67e954b459545"
|
||||
|
|
@ -1131,11 +1148,37 @@
|
|||
resolved "https://registry.yarnpkg.com/@lgaitan/pace-progress/-/pace-progress-1.0.7.tgz#c96fbbd9fd4cf528feed34ea0c8f9d8b3e98f0dd"
|
||||
integrity sha1-yW+72f1M9Sj+7TTqDI+diz6Y8N0=
|
||||
|
||||
"@sheerun/mutationobserver-shim@^0.3.2":
|
||||
version "0.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b"
|
||||
integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q==
|
||||
|
||||
"@sweetalert2/theme-bootstrap-4@^2.2.1":
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@sweetalert2/theme-bootstrap-4/-/theme-bootstrap-4-2.2.1.tgz#a0e3496f2d5aa2993f8fe1c59dcec0673941cddb"
|
||||
integrity sha512-EzAc/HFO16wuZCmawdv0mxRknXtQ5XYmms8gHCcRBqVJsolwl0xKanH8wC2tf4O6dFLou6ZndNqii8ArQO66pA==
|
||||
|
||||
"@testing-library/dom@^6.11.0":
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-6.11.0.tgz#962a38f1a721fdb7c9e35e7579e33ff13a00eda4"
|
||||
integrity sha512-Pkx9LMIGshyNbfmecjt18rrAp/ayMqGH674jYER0SXj0iG9xZc+zWRjk2Pg9JgPBDvwI//xGrI/oOQkAi4YEew==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.6.2"
|
||||
"@sheerun/mutationobserver-shim" "^0.3.2"
|
||||
"@types/testing-library__dom" "^6.0.0"
|
||||
aria-query "3.0.0"
|
||||
pretty-format "^24.9.0"
|
||||
wait-for-expect "^3.0.0"
|
||||
|
||||
"@testing-library/react@^9.4.0":
|
||||
version "9.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@testing-library/react/-/react-9.4.0.tgz#b021ac8cb987c8dc54c6841875f745bf9b2e88e5"
|
||||
integrity sha512-XdhDWkI4GktUPsz0AYyeQ8M9qS/JFie06kcSnUVcpgOwFjAu9vhwR83qBl+lw9yZWkbECjL8Hd+n5hH6C0oWqg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.7.6"
|
||||
"@testing-library/dom" "^6.11.0"
|
||||
"@types/testing-library__react" "^9.1.2"
|
||||
|
||||
"@ttskch/select2-bootstrap4-theme@^1.3.2":
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/@ttskch/select2-bootstrap4-theme/-/select2-bootstrap4-theme-1.3.2.tgz#c9e17e34fb2cfd9f41b8efe3584165ccbdd96969"
|
||||
|
|
@ -1274,11 +1317,31 @@
|
|||
resolved "https://registry.npmjs.org/@types/node/-/node-12.7.5.tgz#e19436e7f8e9b4601005d73673b6dc4784ffcc2f"
|
||||
integrity sha512-9fq4jZVhPNW8r+UYKnxF1e2HkDWOWKM5bC2/7c9wPV835I0aOrVbS/Hw/pWPk2uKrNXQqg9Z959Kz+IYDd5p3w==
|
||||
|
||||
"@types/prop-types@*":
|
||||
version "15.7.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.3.tgz#2ab0d5da2e5815f94b0b9d4b95d1e5f243ab2ca7"
|
||||
integrity sha512-KfRL3PuHmqQLOG+2tGpRO26Ctg+Cq1E01D2DMriKEATHgWLfeNDmq9e29Q9WIky0dQ3NPkd1mzYH8Lm936Z9qw==
|
||||
|
||||
"@types/q@^1.5.1":
|
||||
version "1.5.2"
|
||||
resolved "https://registry.npmjs.org/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8"
|
||||
integrity sha512-ce5d3q03Ex0sy4R14722Rmt6MT07Ua+k4FwDfdcToYJcMKNtRVQvJ6JCAPdAmAnbRb6CsX6aYb9m96NGod9uTw==
|
||||
|
||||
"@types/react-dom@*", "@types/react-dom@^16.9.4":
|
||||
version "16.9.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.4.tgz#0b58df09a60961dcb77f62d4f1832427513420df"
|
||||
integrity sha512-fya9xteU/n90tda0s+FtN5Ym4tbgxpq/hb/Af24dvs6uYnYn+fspaxw5USlw0R8apDNwxsqumdRoCoKitckQqw==
|
||||
dependencies:
|
||||
"@types/react" "*"
|
||||
|
||||
"@types/react@*", "@types/react@^16.9.17":
|
||||
version "16.9.17"
|
||||
resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.17.tgz#58f0cc0e9ec2425d1441dd7b623421a867aa253e"
|
||||
integrity sha512-UP27In4fp4sWF5JgyV6pwVPAQM83Fj76JOcg02X5BZcpSu5Wx+fP9RMqc2v0ssBoQIFvD5JdKY41gjJJKmw6Bg==
|
||||
dependencies:
|
||||
"@types/prop-types" "*"
|
||||
csstype "^2.2.0"
|
||||
|
||||
"@types/sizzle@*":
|
||||
version "2.3.2"
|
||||
resolved "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz#a811b8c18e2babab7d542b3365887ae2e4d9de47"
|
||||
|
|
@ -1299,6 +1362,21 @@
|
|||
resolved "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.4.tgz#b4ffc7dc97b498c969b360a41eee247f82616370"
|
||||
integrity sha512-78AdXtlhpCHT0K3EytMpn4JNxaf5tbqbLcbIRoQIHzpTIyjpxLQKRoxU55ujBXAtg3Nl2h/XWvfDa9dsMOd0pQ==
|
||||
|
||||
"@types/testing-library__dom@*", "@types/testing-library__dom@^6.0.0":
|
||||
version "6.11.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-6.11.1.tgz#6058a6ac391db679f7c60dbb27b81f0620de2dd9"
|
||||
integrity sha512-ImChHtQqmjwraRLqBC2sgSQFtczeFvBmBcfhTYZn/3KwXbyD07LQykEQ0xJo7QHc1GbVvf7pRyGaIe6PkCdxEw==
|
||||
dependencies:
|
||||
pretty-format "^24.3.0"
|
||||
|
||||
"@types/testing-library__react@^9.1.2":
|
||||
version "9.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/testing-library__react/-/testing-library__react-9.1.2.tgz#e33af9124c60a010fc03a34eff8f8a34a75c4351"
|
||||
integrity sha512-CYaMqrswQ+cJACy268jsLAw355DZtPZGt3Jwmmotlcu8O/tkoXBI6AeZ84oZBJsIsesozPKzWzmv/0TIU+1E9Q==
|
||||
dependencies:
|
||||
"@types/react-dom" "*"
|
||||
"@types/testing-library__dom" "*"
|
||||
|
||||
"@types/uglify-js@*":
|
||||
version "3.0.4"
|
||||
resolved "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz#96beae23df6f561862a830b4288a49e86baac082"
|
||||
|
|
@ -1842,6 +1920,14 @@ argparse@^1.0.7:
|
|||
dependencies:
|
||||
sprintf-js "~1.0.2"
|
||||
|
||||
aria-query@3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc"
|
||||
integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=
|
||||
dependencies:
|
||||
ast-types-flow "0.0.7"
|
||||
commander "^2.11.0"
|
||||
|
||||
arr-diff@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"
|
||||
|
|
@ -1937,6 +2023,11 @@ ast-transform@0.0.0:
|
|||
esprima "~1.0.4"
|
||||
through "~2.3.4"
|
||||
|
||||
ast-types-flow@0.0.7:
|
||||
version "0.0.7"
|
||||
resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad"
|
||||
integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0=
|
||||
|
||||
ast-types@^0.7.0:
|
||||
version "0.7.8"
|
||||
resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.7.8.tgz#902d2e0d60d071bdcd46dc115e1809ed11c138a9"
|
||||
|
|
@ -2734,6 +2825,11 @@ combined-stream@^1.0.6, combined-stream@~1.0.6:
|
|||
dependencies:
|
||||
delayed-stream "~1.0.0"
|
||||
|
||||
commander@^2.11.0:
|
||||
version "2.20.3"
|
||||
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
|
||||
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
|
||||
|
||||
commander@^2.20.0, commander@~2.20.0:
|
||||
version "2.20.0"
|
||||
resolved "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz#d58bb2b5c1ee8f87b0d340027e9e94e222c5a422"
|
||||
|
|
@ -3171,6 +3267,11 @@ cssstyle@^1.0.0:
|
|||
dependencies:
|
||||
cssom "0.3.x"
|
||||
|
||||
csstype@^2.2.0:
|
||||
version "2.6.8"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.8.tgz#0fb6fc2417ffd2816a418c9336da74d7f07db431"
|
||||
integrity sha512-msVS9qTuMT5zwAGCVm4mxfrZ18BNc6Csd0oJAtiFMZ1FAx1CCvy2+5MDmYoix63LM/6NDbNtodCiGYGmFgO0dA==
|
||||
|
||||
cyclist@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9"
|
||||
|
|
@ -3657,6 +3758,11 @@ dom-serializer@0:
|
|||
domelementtype "^2.0.1"
|
||||
entities "^2.0.0"
|
||||
|
||||
dom-walk@^0.1.0:
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018"
|
||||
integrity sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=
|
||||
|
||||
domain-browser@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda"
|
||||
|
|
@ -4358,7 +4464,7 @@ fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0:
|
|||
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
|
||||
integrity sha1-1RQsDK7msRifh9OnYREGT4bIu/I=
|
||||
|
||||
fast-levenshtein@~2.0.4, fast-levenshtein@~2.0.6:
|
||||
fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.4, fast-levenshtein@~2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917"
|
||||
integrity sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=
|
||||
|
|
@ -4790,6 +4896,14 @@ global-prefix@^3.0.0:
|
|||
kind-of "^6.0.2"
|
||||
which "^1.3.1"
|
||||
|
||||
global@^4.3.0:
|
||||
version "4.4.0"
|
||||
resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406"
|
||||
integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w==
|
||||
dependencies:
|
||||
min-document "^2.19.0"
|
||||
process "^0.11.10"
|
||||
|
||||
globals@^11.1.0:
|
||||
version "11.12.0"
|
||||
resolved "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
|
||||
|
|
@ -4947,6 +5061,13 @@ hmac-drbg@^1.0.0:
|
|||
minimalistic-assert "^1.0.0"
|
||||
minimalistic-crypto-utils "^1.0.1"
|
||||
|
||||
hoist-non-react-statics@^3.3.0:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#101685d3aff3b23ea213163f6e8e12f4f111e19f"
|
||||
integrity sha512-wbg3bpgA/ZqWrZuMOeJi8+SKMhr7X9TesL/rXMjTzh0p0JUBo3II8DHboYbuIXWRlttrUFxwcu/5kygrCw8fJw==
|
||||
dependencies:
|
||||
react-is "^16.7.0"
|
||||
|
||||
homedir-polyfill@^1.0.1:
|
||||
version "1.0.3"
|
||||
resolved "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz#743298cef4e5af3e194161fbadcc2151d3a058e8"
|
||||
|
|
@ -6394,7 +6515,7 @@ loglevel@^1.6.6:
|
|||
resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.6.6.tgz#0ee6300cc058db6b3551fa1c4bf73b83bb771312"
|
||||
integrity sha512-Sgr5lbboAUBo3eXCSPL4/KoVz3ROKquOjcctxmHIt+vol2DrqTQe3SwkKKuYhEiWB5kYa13YyopJ69deJ1irzQ==
|
||||
|
||||
loose-envify@^1.0.0:
|
||||
loose-envify@^1.0.0, loose-envify@^1.1.0, loose-envify@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
|
||||
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
|
||||
|
|
@ -6626,6 +6747,13 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0:
|
|||
resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b"
|
||||
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
|
||||
|
||||
min-document@^2.19.0:
|
||||
version "2.19.0"
|
||||
resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685"
|
||||
integrity sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=
|
||||
dependencies:
|
||||
dom-walk "^0.1.0"
|
||||
|
||||
mini-css-extract-plugin@^0.9.0:
|
||||
version "0.9.0"
|
||||
resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-0.9.0.tgz#47f2cf07aa165ab35733b1fc97d4c46c0564339e"
|
||||
|
|
@ -7938,7 +8066,7 @@ pretty-format@^22.4.3:
|
|||
ansi-regex "^3.0.0"
|
||||
ansi-styles "^3.2.0"
|
||||
|
||||
pretty-format@^24.9.0:
|
||||
pretty-format@^24.3.0, pretty-format@^24.9.0:
|
||||
version "24.9.0"
|
||||
resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9"
|
||||
integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA==
|
||||
|
|
@ -7985,6 +8113,15 @@ prompts@^2.0.1:
|
|||
kleur "^3.0.2"
|
||||
sisteransi "^1.0.0"
|
||||
|
||||
prop-types@^15.6.1, prop-types@^15.6.2:
|
||||
version "15.7.2"
|
||||
resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
|
||||
integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
|
||||
dependencies:
|
||||
loose-envify "^1.4.0"
|
||||
object-assign "^4.1.1"
|
||||
react-is "^16.8.1"
|
||||
|
||||
proxy-addr@~2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz#34cbd64a2d81f4b1fd21e76f9f06c8a45299ee34"
|
||||
|
|
@ -8154,11 +8291,54 @@ rc@^1.2.7:
|
|||
minimist "^1.2.0"
|
||||
strip-json-comments "~2.0.1"
|
||||
|
||||
react-dom@^16.12.0:
|
||||
version "16.12.0"
|
||||
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-16.12.0.tgz#0da4b714b8d13c2038c9396b54a92baea633fe11"
|
||||
integrity sha512-LMxFfAGrcS3kETtQaCkTKjMiifahaMySFDn71fZUNpPHZQEzmk/GiAeIT8JSOrHB23fnuCOMruL2a8NYlw+8Gw==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
scheduler "^0.18.0"
|
||||
|
||||
react-hot-loader@^4.12.18:
|
||||
version "4.12.18"
|
||||
resolved "https://registry.yarnpkg.com/react-hot-loader/-/react-hot-loader-4.12.18.tgz#a9029e34af2690d76208f9a35189d73c2dfea6a7"
|
||||
integrity sha512-qYD0Qi9lIbg9jLyfmodfqvAQqCBsoPKxAhca8Nxvy2/2pO5Q9r2kM28jN0bbbSnhwK8dJ7FjsfVtXKOxMW+bqw==
|
||||
dependencies:
|
||||
fast-levenshtein "^2.0.6"
|
||||
global "^4.3.0"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
loader-utils "^1.1.0"
|
||||
prop-types "^15.6.1"
|
||||
react-lifecycles-compat "^3.0.4"
|
||||
shallowequal "^1.1.0"
|
||||
source-map "^0.7.3"
|
||||
|
||||
react-is@^16.7.0, react-is@^16.8.1:
|
||||
version "16.12.0"
|
||||
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.12.0.tgz#2cc0fe0fba742d97fd527c42a13bec4eeb06241c"
|
||||
integrity sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==
|
||||
|
||||
react-is@^16.8.4:
|
||||
version "16.8.6"
|
||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz#5bbc1e2d29141c9fbdfed456343fe2bc430a6a16"
|
||||
integrity sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==
|
||||
|
||||
react-lifecycles-compat@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362"
|
||||
integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==
|
||||
|
||||
react@^16.12.0:
|
||||
version "16.12.0"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-16.12.0.tgz#0c0a9c6a142429e3614834d5a778e18aa78a0b83"
|
||||
integrity sha512-fglqy3k5E+81pA8s+7K0/T3DBCF0ZDOher1elBFzF7O6arXJgzyu/FW+COxFvAWXJoJN9KIZbT2LXlukwphYTA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
prop-types "^15.6.2"
|
||||
|
||||
read-pkg-up@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-4.0.0.tgz#1b221c6088ba7799601c808f91161c66e58f8978"
|
||||
|
|
@ -8564,6 +8744,22 @@ sax@^1.2.4, sax@~1.2.4:
|
|||
resolved "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
||||
|
||||
scheduler@^0.17.0:
|
||||
version "0.17.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.17.0.tgz#7c9c673e4ec781fac853927916d1c426b6f3ddfe"
|
||||
integrity sha512-7rro8Io3tnCPuY4la/NuI5F2yfESpnfZyT6TtkXnSWVkcu0BCDJ+8gk5ozUaFaxpIyNuWAPXrH0yFcSi28fnDA==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
scheduler@^0.18.0:
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.18.0.tgz#5901ad6659bc1d8f3fdaf36eb7a67b0d6746b1c4"
|
||||
integrity sha512-agTSHR1Nbfi6ulI0kYNK0203joW2Y5W4po4l+v03tOoiJKpTBbxpNhWDvqc/4IcOw+KLmSiQLTasZ4cab2/UWQ==
|
||||
dependencies:
|
||||
loose-envify "^1.1.0"
|
||||
object-assign "^4.1.1"
|
||||
|
||||
schema-utils@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz#0b79a93204d7b600d4b2850d1f66c2a34951c770"
|
||||
|
|
@ -8743,6 +8939,11 @@ shallow-copy@~0.0.1:
|
|||
resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170"
|
||||
integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA=
|
||||
|
||||
shallowequal@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8"
|
||||
integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==
|
||||
|
||||
shebang-command@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea"
|
||||
|
|
@ -10019,6 +10220,11 @@ w3c-hr-time@^1.0.1:
|
|||
dependencies:
|
||||
browser-process-hrtime "^0.1.2"
|
||||
|
||||
wait-for-expect@^3.0.0:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.1.tgz#ec204a76b0038f17711e575720aaf28505ac7185"
|
||||
integrity sha512-3Ha7lu+zshEG/CeHdcpmQsZnnZpPj/UsG3DuKO8FskjuDbkx3jE3845H+CuwZjA2YWYDfKMU2KhnCaXMLd3wVw==
|
||||
|
||||
walker@^1.0.7, walker@~1.0.5:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user