mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-30 22:50:10 +03:00
L #~: Add eslint config from npm packages (#1652)
This commit is contained in:
parent
fd69882757
commit
45c5e278a2
@ -1,103 +1,6 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es2021": true,
|
||||
"node": true
|
||||
},
|
||||
"extends": [
|
||||
"plugin:react/recommended",
|
||||
"plugin:jsdoc/recommended",
|
||||
"standard",
|
||||
"prettier"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
},
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"plugins": ["jsdoc", "react", "header", "prettier"],
|
||||
"rules": {
|
||||
"default-case": "off",
|
||||
"prefer-const": ["error", {
|
||||
"destructuring": "all"
|
||||
}],
|
||||
"arrow-body-style": ["error", "as-needed"],
|
||||
"no-restricted-syntax": [
|
||||
"error",
|
||||
"ForInStatement",
|
||||
"LabeledStatement",
|
||||
"WithStatement"
|
||||
],
|
||||
"no-return-assign": ["error", "except-parens"],
|
||||
"no-param-reassign": ["error", {
|
||||
"props": false
|
||||
}],
|
||||
"no-shadow": ["error", {
|
||||
"hoist": "all",
|
||||
"allow": ["resolve", "reject", "done", "next", "err", "error", "children"]
|
||||
}],
|
||||
"import/no-extraneous-dependencies": ["error", {
|
||||
"devDependencies": ["*.js"]
|
||||
}],
|
||||
"padding-line-between-statements": ["error", {
|
||||
"blankLine": "always",
|
||||
"prev": "*",
|
||||
"next": "return"
|
||||
}],
|
||||
"react/jsx-uses-react": "off",
|
||||
"react/react-in-jsx-scope": "off",
|
||||
"react/display-name": "warn",
|
||||
"react/no-array-index-key": "off",
|
||||
"react/require-default-props": "off",
|
||||
"react/forbid-prop-types": "off",
|
||||
"prettier/prettier": ["error", {
|
||||
"singleQuote": true,
|
||||
"semi": false,
|
||||
"trailingComma": "es5"
|
||||
}],
|
||||
"jsdoc/require-jsdoc": ["error", {
|
||||
"publicOnly": true,
|
||||
"require": {
|
||||
"ArrowFunctionExpression": true,
|
||||
"FunctionDeclaration": true,
|
||||
"FunctionExpression": true,
|
||||
"ClassDeclaration": true,
|
||||
"ClassExpression": true,
|
||||
"MethodDefinition": true
|
||||
}
|
||||
}],
|
||||
"jsdoc/check-indentation": 1,
|
||||
"jsdoc/check-line-alignment": 1,
|
||||
"jsdoc/check-syntax": 1,
|
||||
"jsdoc/match-description": 1,
|
||||
"jsdoc/require-asterisk-prefix": 1,
|
||||
"jsdoc/require-hyphen-before-param-description": 1,
|
||||
|
||||
"header/header": [2, "block", [
|
||||
" ------------------------------------------------------------------------- *",
|
||||
" * Copyright 2002-2021, OpenNebula Project, OpenNebula Systems *",
|
||||
" * *",
|
||||
" * Licensed under the Apache License, Version 2.0 (the \"License\"); you may *",
|
||||
" * not use this file except in compliance with the License. You may obtain *",
|
||||
" * a copy of the License at *",
|
||||
" * *",
|
||||
" * http://www.apache.org/licenses/LICENSE-2.0 *",
|
||||
" * *",
|
||||
" * Unless required by applicable law or agreed to in writing, software *",
|
||||
" * distributed under the License is distributed on an \"AS IS\" BASIS, *",
|
||||
" * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *",
|
||||
" * See the License for the specific language governing permissions and *",
|
||||
" * limitations under the License. *",
|
||||
" * ------------------------------------------------------------------------- "
|
||||
]
|
||||
]
|
||||
},
|
||||
"extends": ["opennebula"],
|
||||
"settings": {
|
||||
"react": {
|
||||
"version": "detect"
|
||||
},
|
||||
"import/resolver": {
|
||||
"alias": {
|
||||
"map": [
|
||||
|
1455
src/fireedge/package-lock.json
generated
1455
src/fireedge/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -33,21 +33,11 @@
|
||||
"@pmmmwh/react-refresh-webpack-plugin": "0.5.1",
|
||||
"cross-env": "7.0.2",
|
||||
"eslint": "7.32.0",
|
||||
"eslint-config-prettier": "8.3.0",
|
||||
"eslint-config-standard": "16.0.3",
|
||||
"eslint-config-opennebula": "2.0.0",
|
||||
"eslint-import-resolver-alias": "1.1.2",
|
||||
"eslint-import-resolver-webpack": "0.13.0",
|
||||
"eslint-plugin-babel": "5.3.1",
|
||||
"eslint-plugin-header": "3.1.1",
|
||||
"eslint-plugin-import": "2.22.1",
|
||||
"eslint-plugin-jsdoc": "35.4.1",
|
||||
"eslint-plugin-node": "11.1.0",
|
||||
"eslint-plugin-prettier": "4.0.0",
|
||||
"eslint-plugin-promise": "4.2.1",
|
||||
"eslint-plugin-react": "7.21.4",
|
||||
"opennebula-generatepotfile": "1.0.0",
|
||||
"opennebula-potojson": "1.0.0",
|
||||
"prettier": "2.5.0",
|
||||
"react-refresh": "0.10.0",
|
||||
"webpack-dev-middleware": "5.2.1",
|
||||
"webpack-hot-middleware": "2.25.1"
|
||||
@ -61,7 +51,6 @@
|
||||
"@babel/plugin-proposal-object-rest-spread": "7.15.6",
|
||||
"@babel/plugin-proposal-optional-chaining": "7.14.5",
|
||||
"@babel/preset-env": "7.15.8",
|
||||
"@babel/preset-react": "7.14.5",
|
||||
"@emotion/react": "11.6.0",
|
||||
"@emotion/styled": "11.6.0",
|
||||
"@hookform/devtools": "4.0.1",
|
||||
@ -77,7 +66,6 @@
|
||||
"@reduxjs/toolkit": "1.6.2",
|
||||
"atob": "2.1.2",
|
||||
"axios": "0.23.0",
|
||||
"babel-eslint": "10.1.0",
|
||||
"babel-loader": "8.2.1",
|
||||
"babel-plugin-module-resolver": "4.0.0",
|
||||
"btoa": "1.2.1",
|
||||
@ -156,4 +144,4 @@
|
||||
"yup": "0.32.9",
|
||||
"zeromq": "5.2.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,7 +37,7 @@ const optsFunc = {
|
||||
removeEnd: /(\))/g,
|
||||
regexTextCaptureIndex: 0,
|
||||
definitions,
|
||||
split: '.'
|
||||
split: '.',
|
||||
}
|
||||
|
||||
// React component <Translate word="word"/>
|
||||
@ -47,7 +47,7 @@ const optsComponent = {
|
||||
removeEnd: /('|"|}|'}|"}) \/>/g,
|
||||
regexTextCaptureIndex: 0,
|
||||
definitions,
|
||||
split: '.'
|
||||
split: '.',
|
||||
}
|
||||
|
||||
createReadStream(clientCode, optsFunc)
|
||||
|
@ -86,7 +86,11 @@ const ProvisionCard = memo(
|
||||
mediaProps={{
|
||||
component: 'div',
|
||||
children: (
|
||||
<Image src={imageUrl} withSources={image && !isExternalImage} />
|
||||
<Image
|
||||
alt={`${isProvider ? 'provider' : 'provision'}-logo`}
|
||||
src={imageUrl}
|
||||
withSources={image && !isExternalImage}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
subheader={`#${ID}`}
|
||||
|
@ -50,7 +50,11 @@ const ProvisionTemplateCard = memo(
|
||||
mediaProps={{
|
||||
component: 'div',
|
||||
children: (
|
||||
<Image src={imageUrl} withSources={image && !isExternalImage} />
|
||||
<Image
|
||||
alt="provision-logo"
|
||||
src={imageUrl}
|
||||
withSources={image && !isExternalImage}
|
||||
/>
|
||||
),
|
||||
}}
|
||||
subheader={description}
|
||||
|
@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import { useState, useEffect, useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {
|
||||
@ -32,7 +31,7 @@ import { useAuth } from 'client/features/Auth'
|
||||
import { useProvisionTemplate } from 'client/features/One'
|
||||
import { ListCards } from 'client/components/List'
|
||||
import { ProvisionTemplateCard } from 'client/components/Cards'
|
||||
import { sanitize, deepmerge } from 'client/utils'
|
||||
import { Step, sanitize, deepmerge } from 'client/utils'
|
||||
import { isValidProviderTemplate } from 'client/models/ProviderTemplate'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
@ -41,6 +40,12 @@ import { STEP_FORM_SCHEMA } from 'client/components/Forms/Provider/CreateForm/St
|
||||
import { STEP_ID as CONFIGURATION_ID } from 'client/components/Forms/Provider/CreateForm/Steps/BasicConfiguration'
|
||||
import { STEP_ID as CONNECTION_ID } from 'client/components/Forms/Provider/CreateForm/Steps/Connection'
|
||||
|
||||
export const STEP_ID = 'template'
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Markdown Description
|
||||
// ----------------------------------------------------------
|
||||
|
||||
const renderer = new Marked.Renderer()
|
||||
|
||||
renderer.link = (href, title, text) => `
|
||||
@ -50,7 +55,19 @@ renderer.link = (href, title, text) => `
|
||||
</a>
|
||||
`
|
||||
|
||||
export const STEP_ID = 'template'
|
||||
const Description = ({ description = '' }) => {
|
||||
const html = Marked(sanitize`${description}`, { renderer })
|
||||
|
||||
return <div dangerouslySetInnerHTML={{ __html: html }} />
|
||||
}
|
||||
|
||||
Description.propTypes = {
|
||||
description: PropTypes.string,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Step content : Select Provider Template
|
||||
// ----------------------------------------------------------
|
||||
|
||||
const Content = ({ data, setFormData }) => {
|
||||
const provisionTemplates = useProvisionTemplate()
|
||||
@ -138,12 +155,6 @@ const Content = ({ data, setFormData }) => {
|
||||
: handleSelect(deepmerge(template, extraPlainInfo))
|
||||
}
|
||||
|
||||
const RenderDescription = ({ description = '' }) => {
|
||||
const html = Marked(sanitize`${description}`, { renderer })
|
||||
|
||||
return <div dangerouslySetInnerHTML={{ __html: html }} />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* -- SELECTORS -- */}
|
||||
@ -196,7 +207,7 @@ const Content = ({ data, setFormData }) => {
|
||||
{useMemo(
|
||||
() =>
|
||||
providerDescription && (
|
||||
<RenderDescription description={providerDescription} />
|
||||
<Description description={providerDescription} />
|
||||
),
|
||||
[providerDescription]
|
||||
)}
|
||||
@ -229,6 +240,11 @@ const Content = ({ data, setFormData }) => {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Step to select the Provider Template.
|
||||
*
|
||||
* @returns {Step} Provider Template step
|
||||
*/
|
||||
const Template = () => ({
|
||||
id: STEP_ID,
|
||||
label: T.ProviderTemplate,
|
||||
|
@ -13,8 +13,8 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
import { useState, useCallback, useEffect, useMemo } from 'react'
|
||||
import { useState, useEffect, useMemo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import {
|
||||
Divider,
|
||||
Select,
|
||||
@ -30,7 +30,7 @@ import { useAuth } from 'client/features/Auth'
|
||||
import { useProvider, useProvisionTemplate } from 'client/features/One'
|
||||
import { ListCards } from 'client/components/List'
|
||||
import { ProvisionTemplateCard } from 'client/components/Cards'
|
||||
import { sanitize } from 'client/utils'
|
||||
import { Step, sanitize } from 'client/utils'
|
||||
import { isValidProvisionTemplate } from 'client/models/ProvisionTemplate'
|
||||
import { T } from 'client/constants'
|
||||
|
||||
@ -39,6 +39,12 @@ import { STEP_ID as CONFIGURATION_ID } from 'client/components/Forms/Provision/C
|
||||
import { STEP_ID as INPUTS_ID } from 'client/components/Forms/Provision/CreateForm/Steps/Inputs'
|
||||
import { STEP_FORM_SCHEMA } from 'client/components/Forms/Provision/CreateForm/Steps/Template/schema'
|
||||
|
||||
export const STEP_ID = 'template'
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Markdown Description
|
||||
// ----------------------------------------------------------
|
||||
|
||||
const renderer = new Marked.Renderer()
|
||||
|
||||
renderer.link = (href, title, text) => `
|
||||
@ -48,199 +54,208 @@ renderer.link = (href, title, text) => `
|
||||
</a>
|
||||
`
|
||||
|
||||
export const STEP_ID = 'template'
|
||||
const Description = ({ description = '' }) => {
|
||||
const html = Marked(sanitize`${description}`, { renderer })
|
||||
|
||||
return <div dangerouslySetInnerHTML={{ __html: html }} />
|
||||
}
|
||||
|
||||
Description.propTypes = {
|
||||
description: PropTypes.string,
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
// Step content : Select Provision Template
|
||||
// ----------------------------------------------------------
|
||||
|
||||
const Content = ({ data, setFormData }) => {
|
||||
const providers = useProvider()
|
||||
const provisionTemplates = useProvisionTemplate()
|
||||
const { providerConfig } = useAuth()
|
||||
const templateSelected = data?.[0]
|
||||
|
||||
const provisionTypes = useMemo(
|
||||
() => [
|
||||
...new Set(
|
||||
Object.values(providerConfig)
|
||||
.map((provider) => provider?.provision_type)
|
||||
.flat()
|
||||
),
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
const [providerSelected, setProvider] = useState(
|
||||
() => templateSelected?.provider
|
||||
)
|
||||
const [provisionSelected, setProvision] = useState(
|
||||
() => templateSelected?.provision_type ?? provisionTypes[0]
|
||||
)
|
||||
|
||||
const [templatesByProvisionSelected, providerTypes, providerDescription] =
|
||||
useMemo(() => {
|
||||
const templates = Object.values(
|
||||
provisionTemplates[provisionSelected]?.provisions
|
||||
).flat()
|
||||
const types = [...new Set(templates.map(({ provider }) => provider))]
|
||||
const provisionDescription =
|
||||
provisionTemplates?.[provisionSelected]?.description
|
||||
|
||||
return [templates, types, provisionDescription]
|
||||
}, [provisionSelected])
|
||||
|
||||
const templatesAvailable = useMemo(
|
||||
() =>
|
||||
templatesByProvisionSelected.filter(
|
||||
({ provider }) => providerSelected === provider
|
||||
),
|
||||
[providerSelected]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
// set first provision type
|
||||
!provisionSelected && setProvision(provisionTypes[0])
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
// set first provider type
|
||||
provisionSelected && !providerSelected && setProvider(providerTypes[0])
|
||||
}, [provisionSelected])
|
||||
|
||||
const { handleSelect, handleUnselect, handleClear } = useListForm({
|
||||
key: STEP_ID,
|
||||
setList: setFormData,
|
||||
})
|
||||
|
||||
const handleChangeProvision = (evt) => {
|
||||
setProvision(evt.target.value)
|
||||
setProvider(undefined)
|
||||
templateSelected && handleClear()
|
||||
}
|
||||
|
||||
const handleChangeProvider = (evt) => {
|
||||
setProvider(evt.target.value)
|
||||
templateSelected && handleClear()
|
||||
}
|
||||
|
||||
const handleClick = (template, isSelected) => {
|
||||
const { name, description, defaults, hosts } = template
|
||||
|
||||
// reset rest of form when change template
|
||||
const providerName =
|
||||
defaults?.provision?.provider_name ?? hosts?.[0]?.provision.provider_name
|
||||
const providerFromProvisionTemplate =
|
||||
providers?.filter(({ NAME }) => NAME === providerName) ?? []
|
||||
|
||||
setFormData({
|
||||
[PROVIDER_ID]: providerFromProvisionTemplate,
|
||||
[CONFIGURATION_ID]: { name, description },
|
||||
[INPUTS_ID]: undefined,
|
||||
})
|
||||
|
||||
isSelected
|
||||
? handleUnselect(name, (item) => item.name === name)
|
||||
: handleSelect({ ...template, provision_type: provisionSelected })
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* -- SELECTORS -- */}
|
||||
<Breadcrumbs separator={<NavArrowRight />}>
|
||||
<FormControl>
|
||||
<InputLabel color="secondary" shrink id="select-provision-type-label">
|
||||
{'Provision type'}
|
||||
</InputLabel>
|
||||
<Select
|
||||
color="secondary"
|
||||
inputProps={{ 'data-cy': 'select-provision-type' }}
|
||||
labelId="select-provision-type-label"
|
||||
native
|
||||
style={{ marginTop: '1em', minWidth: '8em' }}
|
||||
onChange={handleChangeProvision}
|
||||
value={provisionSelected}
|
||||
variant="outlined"
|
||||
>
|
||||
{provisionTypes.map((type) => (
|
||||
<option key={type} value={type}>
|
||||
{type}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<InputLabel color="secondary" shrink id="select-provider-type-label">
|
||||
{'Provider type'}
|
||||
</InputLabel>
|
||||
<Select
|
||||
color="secondary"
|
||||
inputProps={{ 'data-cy': 'select-provider-type' }}
|
||||
labelId="select-provider-type-label"
|
||||
native
|
||||
style={{ marginTop: '1em', minWidth: '8em' }}
|
||||
onChange={handleChangeProvider}
|
||||
value={providerSelected}
|
||||
variant="outlined"
|
||||
>
|
||||
{providerTypes.map((type) => (
|
||||
<option key={type} value={type}>
|
||||
{providerConfig[type]?.name ?? type}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Breadcrumbs>
|
||||
|
||||
{/* -- DESCRIPTION -- */}
|
||||
{useMemo(
|
||||
() =>
|
||||
providerDescription && (
|
||||
<Description description={providerDescription} />
|
||||
),
|
||||
[providerDescription]
|
||||
)}
|
||||
|
||||
<Divider style={{ margin: '1rem 0' }} />
|
||||
|
||||
{/* -- LIST -- */}
|
||||
<ListCards
|
||||
keyProp="name"
|
||||
list={templatesAvailable}
|
||||
gridProps={{ 'data-cy': 'provisions-templates' }}
|
||||
CardComponent={ProvisionTemplateCard}
|
||||
cardsProps={({ value = {} }) => {
|
||||
const isSelected = data?.some(
|
||||
(selected) => selected.name === value.name
|
||||
)
|
||||
const isValid = isValidProvisionTemplate(value)
|
||||
|
||||
return {
|
||||
image: value?.image,
|
||||
isSelected,
|
||||
isValid,
|
||||
handleClick: () => handleClick(value, isSelected),
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Step to select the Provision Template.
|
||||
*
|
||||
* @returns {Step} Provision Template step
|
||||
*/
|
||||
const Template = () => ({
|
||||
id: STEP_ID,
|
||||
label: T.ProvisionTemplate,
|
||||
resolver: () => STEP_FORM_SCHEMA,
|
||||
content: useCallback(({ data, setFormData }) => {
|
||||
const providers = useProvider()
|
||||
const provisionTemplates = useProvisionTemplate()
|
||||
const { providerConfig } = useAuth()
|
||||
const templateSelected = data?.[0]
|
||||
|
||||
const provisionTypes = useMemo(
|
||||
() => [
|
||||
...new Set(
|
||||
Object.values(providerConfig)
|
||||
.map((provider) => provider?.provision_type)
|
||||
.flat()
|
||||
),
|
||||
],
|
||||
[]
|
||||
)
|
||||
|
||||
const [providerSelected, setProvider] = useState(
|
||||
() => templateSelected?.provider
|
||||
)
|
||||
const [provisionSelected, setProvision] = useState(
|
||||
() => templateSelected?.provision_type ?? provisionTypes[0]
|
||||
)
|
||||
|
||||
const [templatesByProvisionSelected, providerTypes, providerDescription] =
|
||||
useMemo(() => {
|
||||
const templates = Object.values(
|
||||
provisionTemplates[provisionSelected]?.provisions
|
||||
).flat()
|
||||
const types = [...new Set(templates.map(({ provider }) => provider))]
|
||||
const provisionDescription =
|
||||
provisionTemplates?.[provisionSelected]?.description
|
||||
|
||||
return [templates, types, provisionDescription]
|
||||
}, [provisionSelected])
|
||||
|
||||
const templatesAvailable = useMemo(
|
||||
() =>
|
||||
templatesByProvisionSelected.filter(
|
||||
({ provider }) => providerSelected === provider
|
||||
),
|
||||
[providerSelected]
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
// set first provision type
|
||||
!provisionSelected && setProvision(provisionTypes[0])
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
// set first provider type
|
||||
provisionSelected && !providerSelected && setProvider(providerTypes[0])
|
||||
}, [provisionSelected])
|
||||
|
||||
const { handleSelect, handleUnselect, handleClear } = useListForm({
|
||||
key: STEP_ID,
|
||||
setList: setFormData,
|
||||
})
|
||||
|
||||
const handleChangeProvision = (evt) => {
|
||||
setProvision(evt.target.value)
|
||||
setProvider(undefined)
|
||||
templateSelected && handleClear()
|
||||
}
|
||||
|
||||
const handleChangeProvider = (evt) => {
|
||||
setProvider(evt.target.value)
|
||||
templateSelected && handleClear()
|
||||
}
|
||||
|
||||
const handleClick = (template, isSelected) => {
|
||||
const { name, description, defaults, hosts } = template
|
||||
|
||||
// reset rest of form when change template
|
||||
const providerName =
|
||||
defaults?.provision?.provider_name ??
|
||||
hosts?.[0]?.provision.provider_name
|
||||
const providerFromProvisionTemplate =
|
||||
providers?.filter(({ NAME }) => NAME === providerName) ?? []
|
||||
|
||||
setFormData({
|
||||
[PROVIDER_ID]: providerFromProvisionTemplate,
|
||||
[CONFIGURATION_ID]: { name, description },
|
||||
[INPUTS_ID]: undefined,
|
||||
})
|
||||
|
||||
isSelected
|
||||
? handleUnselect(name, (item) => item.name === name)
|
||||
: handleSelect({ ...template, provision_type: provisionSelected })
|
||||
}
|
||||
|
||||
const RenderDescription = ({ description = '' }) => {
|
||||
const html = Marked(sanitize`${description}`, { renderer })
|
||||
|
||||
return <div dangerouslySetInnerHTML={{ __html: html }} />
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
{/* -- SELECTORS -- */}
|
||||
<Breadcrumbs separator={<NavArrowRight />}>
|
||||
<FormControl>
|
||||
<InputLabel
|
||||
color="secondary"
|
||||
shrink
|
||||
id="select-provision-type-label"
|
||||
>
|
||||
{'Provision type'}
|
||||
</InputLabel>
|
||||
<Select
|
||||
color="secondary"
|
||||
inputProps={{ 'data-cy': 'select-provision-type' }}
|
||||
labelId="select-provision-type-label"
|
||||
native
|
||||
style={{ marginTop: '1em', minWidth: '8em' }}
|
||||
onChange={handleChangeProvision}
|
||||
value={provisionSelected}
|
||||
variant="outlined"
|
||||
>
|
||||
{provisionTypes.map((type) => (
|
||||
<option key={type} value={type}>
|
||||
{type}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
<FormControl>
|
||||
<InputLabel
|
||||
color="secondary"
|
||||
shrink
|
||||
id="select-provider-type-label"
|
||||
>
|
||||
{'Provider type'}
|
||||
</InputLabel>
|
||||
<Select
|
||||
color="secondary"
|
||||
inputProps={{ 'data-cy': 'select-provider-type' }}
|
||||
labelId="select-provider-type-label"
|
||||
native
|
||||
style={{ marginTop: '1em', minWidth: '8em' }}
|
||||
onChange={handleChangeProvider}
|
||||
value={providerSelected}
|
||||
variant="outlined"
|
||||
>
|
||||
{providerTypes.map((type) => (
|
||||
<option key={type} value={type}>
|
||||
{providerConfig[type]?.name ?? type}
|
||||
</option>
|
||||
))}
|
||||
</Select>
|
||||
</FormControl>
|
||||
</Breadcrumbs>
|
||||
|
||||
{/* -- DESCRIPTION -- */}
|
||||
{useMemo(
|
||||
() =>
|
||||
providerDescription && (
|
||||
<RenderDescription description={providerDescription} />
|
||||
),
|
||||
[providerDescription]
|
||||
)}
|
||||
|
||||
<Divider style={{ margin: '1rem 0' }} />
|
||||
|
||||
{/* -- LIST -- */}
|
||||
<ListCards
|
||||
keyProp="name"
|
||||
list={templatesAvailable}
|
||||
gridProps={{ 'data-cy': 'provisions-templates' }}
|
||||
CardComponent={ProvisionTemplateCard}
|
||||
cardsProps={({ value = {} }) => {
|
||||
const isSelected = data?.some(
|
||||
(selected) => selected.name === value.name
|
||||
)
|
||||
const isValid = isValidProvisionTemplate(value)
|
||||
|
||||
return {
|
||||
image: value?.image,
|
||||
isSelected,
|
||||
isValid,
|
||||
handleClick: () => handleClick(value, isSelected),
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
)
|
||||
}, []),
|
||||
content: Content,
|
||||
})
|
||||
|
||||
Content.propTypes = {
|
||||
data: PropTypes.any,
|
||||
setFormData: PropTypes.func,
|
||||
}
|
||||
|
||||
export default Template
|
||||
|
@ -90,6 +90,7 @@ export const LOGO = {
|
||||
// eslint-disable-next-line react/display-name
|
||||
renderValue: (value) => (
|
||||
<Image
|
||||
alt="logo"
|
||||
imgProps={{
|
||||
height: 25,
|
||||
width: 25,
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
/* eslint-disable jsdoc/require-jsdoc */
|
||||
/* eslint-disable react/prop-types */
|
||||
import { object, array, number } from 'yup'
|
||||
|
||||
import { StatusCircle, StatusChip } from 'client/components/Status'
|
||||
@ -22,6 +22,7 @@ import { Translate } from 'client/components/HOC'
|
||||
import { getState } from 'client/models/Image'
|
||||
import { stringToBoolean } from 'client/models/Helper'
|
||||
import { T, INPUT_TYPES } from 'client/constants'
|
||||
import { Field } from 'client/utils'
|
||||
|
||||
export const PARENT = 'DISK'
|
||||
|
||||
@ -74,6 +75,10 @@ const SIZE_FIELD = ({
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {object} [vmTemplate] - VM Template
|
||||
* @returns {Field[]} Section fields
|
||||
*/
|
||||
export const FIELDS = (vmTemplate) => {
|
||||
const disks = [vmTemplate?.TEMPLATE?.DISK ?? []].flat()
|
||||
|
||||
|
@ -67,6 +67,7 @@ const Image = memo(
|
||||
if (error.fail) {
|
||||
return (
|
||||
<img
|
||||
alt=""
|
||||
{...imageProps}
|
||||
src={imageInError}
|
||||
draggable={false}
|
||||
@ -85,10 +86,10 @@ const Image = memo(
|
||||
type={`image/${format}`}
|
||||
/>
|
||||
))}
|
||||
<img {...imageProps} src={src} onError={onImageFail} />
|
||||
<img alt="" {...imageProps} src={src} onError={onImageFail} />
|
||||
</picture>
|
||||
) : (
|
||||
<img {...imageProps} src={src} onError={onImageFail} />
|
||||
<img alt="" {...imageProps} src={src} onError={onImageFail} />
|
||||
)
|
||||
},
|
||||
(prev, next) => prev.src === next.src
|
||||
|
@ -14,25 +14,30 @@
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
import { useMediaQuery, Card, Skeleton } from '@mui/material'
|
||||
|
||||
import EnhancedTableStyles from 'client/components/Tables/Enhanced/styles'
|
||||
import { rowStyles } from 'client/components/Tables/styles'
|
||||
|
||||
const SkeletonCategory = ({ numberOfItems = 1 }) => (
|
||||
<>
|
||||
<Skeleton width={'30%'} height={40} />
|
||||
{[...new Array(numberOfItems)].map((_, idx) => (
|
||||
<Skeleton key={idx} width={'80%'} height={40} />
|
||||
))}
|
||||
</>
|
||||
)
|
||||
|
||||
SkeletonCategory.propTypes = {
|
||||
numberOfItems: PropTypes.number,
|
||||
}
|
||||
|
||||
const SkeletonTable = memo(() => {
|
||||
const isMobile = useMediaQuery((theme) => theme.breakpoints.down('md'))
|
||||
const classes = EnhancedTableStyles()
|
||||
const rowClasses = rowStyles()
|
||||
|
||||
const SkeletonCategory = ({ numberOfItems = 1 }) => (
|
||||
<>
|
||||
<Skeleton width={'30%'} height={40} />
|
||||
{[...new Array(numberOfItems)].map((_, idx) => (
|
||||
<Skeleton key={idx} width={'80%'} height={40} />
|
||||
))}
|
||||
</>
|
||||
)
|
||||
|
||||
const SkeletonRow = () => (
|
||||
<Card style={{ padding: '1em' }}>
|
||||
<div className={rowClasses.main}>
|
||||
|
@ -46,7 +46,11 @@ const Row = ({ original, value, ...props }) => {
|
||||
return (
|
||||
<div {...props} data-cy={`template-${ID}`}>
|
||||
<div className={classes.figure}>
|
||||
<Image src={logoSource} imgProps={{ className: classes.image }} />
|
||||
<Image
|
||||
alt="logo"
|
||||
src={logoSource}
|
||||
imgProps={{ className: classes.image }}
|
||||
/>
|
||||
</div>
|
||||
<div className={classes.main}>
|
||||
<div className={classes.title}>
|
||||
|
@ -13,7 +13,7 @@
|
||||
* See the License for the specific language governing permissions and *
|
||||
* limitations under the License. *
|
||||
* ------------------------------------------------------------------------- */
|
||||
import { memo, useEffect, useMemo, JSXElementConstructor } from 'react'
|
||||
import { memo, useEffect, useMemo, ReactElement } from 'react'
|
||||
import PropTypes from 'prop-types'
|
||||
|
||||
import makeStyles from '@mui/styles/makeStyles'
|
||||
@ -60,7 +60,7 @@ const useStyles = makeStyles(() => ({
|
||||
* @param {Function} props.handleCreate - Create a new Node
|
||||
* @param {Function} props.handleEdit - Edit a current Node
|
||||
* @param {Function} props.handleSetData - Set new list of nodes
|
||||
* @returns {JSXElementConstructor} ReactFlow component
|
||||
* @returns {ReactElement} ReactFlow component
|
||||
*/
|
||||
const Flow = memo(({ dataFields, handleCreate, handleEdit, handleSetData }) => {
|
||||
const { watch } = useFormContext()
|
||||
@ -112,6 +112,8 @@ const Flow = memo(({ dataFields, handleCreate, handleEdit, handleSetData }) => {
|
||||
)
|
||||
})
|
||||
|
||||
Flow.displayName = 'FlowGraph'
|
||||
|
||||
Flow.propTypes = {
|
||||
dataFields: PropTypes.arrayOf(PropTypes.string),
|
||||
handleCreate: PropTypes.func,
|
||||
|
@ -31,7 +31,13 @@ import { mapUserInputs, deepmerge } from 'client/utils'
|
||||
*/
|
||||
export const mapTiersToRoles = (tiers, networking, cluster) =>
|
||||
tiers?.map((data) => {
|
||||
const { template, parents, networks, user_inputs_values = {}, tier } = data
|
||||
const {
|
||||
template,
|
||||
parents,
|
||||
networks,
|
||||
user_inputs_values: userInputs = {},
|
||||
tier,
|
||||
} = data
|
||||
|
||||
const networksValue = networks
|
||||
?.reduce((res, id, idx) => {
|
||||
@ -54,7 +60,7 @@ export const mapTiersToRoles = (tiers, networking, cluster) =>
|
||||
parents: parentsValue,
|
||||
vm_template: template?.id ?? template?.app,
|
||||
vm_template_contents: networksValue,
|
||||
user_inputs_values: mapUserInputs(user_inputs_values),
|
||||
user_inputs_values: mapUserInputs(userInputs),
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -21,7 +21,10 @@ const getDevConfiguration = () => {
|
||||
const ReactRefreshPlugin = require('@pmmmwh/react-refresh-webpack-plugin')
|
||||
const TimeFixPlugin = require('time-fix-plugin')
|
||||
|
||||
const { defaultWebpackMode, defaultAppName } = require('./src/server/utils/constants/defaults')
|
||||
const {
|
||||
defaultWebpackMode,
|
||||
defaultAppName,
|
||||
} = require('./src/server/utils/constants/defaults')
|
||||
|
||||
const appName = defaultAppName ? `/${defaultAppName}` : ''
|
||||
|
||||
@ -30,12 +33,12 @@ const getDevConfiguration = () => {
|
||||
mode: defaultWebpackMode,
|
||||
entry: [
|
||||
'webpack-hot-middleware/client',
|
||||
path.resolve(__dirname, 'src/client/dev/index.js')
|
||||
path.resolve(__dirname, 'src/client/dev/index.js'),
|
||||
],
|
||||
output: {
|
||||
filename: 'bundle.dev.js',
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
publicPath: `${appName}/client`
|
||||
publicPath: `${appName}/client`,
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
@ -47,43 +50,46 @@ const getDevConfiguration = () => {
|
||||
loader: 'babel-loader',
|
||||
options: {
|
||||
babelrc: true,
|
||||
plugins: ['react-refresh/babel']
|
||||
}
|
||||
}
|
||||
]
|
||||
plugins: ['react-refresh/babel'],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
test: /\.css$/i,
|
||||
use: ['style-loader', 'css-loader']
|
||||
}
|
||||
]
|
||||
use: ['style-loader', 'css-loader'],
|
||||
},
|
||||
],
|
||||
},
|
||||
resolve: {
|
||||
extensions: ['.js'],
|
||||
alias: {
|
||||
process: 'process/browser'
|
||||
}
|
||||
process: 'process/browser',
|
||||
},
|
||||
},
|
||||
plugins: [
|
||||
new TimeFixPlugin(),
|
||||
new webpack.HotModuleReplacementPlugin(),
|
||||
ReactRefreshPlugin && new ReactRefreshPlugin({
|
||||
overlay: {
|
||||
sockIntegration: 'whm'
|
||||
}
|
||||
}),
|
||||
ReactRefreshPlugin &&
|
||||
new ReactRefreshPlugin({
|
||||
overlay: {
|
||||
sockIntegration: 'whm',
|
||||
},
|
||||
}),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify(defaultWebpackMode)
|
||||
}
|
||||
NODE_ENV: JSON.stringify(defaultWebpackMode),
|
||||
},
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser'
|
||||
})
|
||||
process: 'process/browser',
|
||||
}),
|
||||
],
|
||||
devtool: 'inline-source-map'
|
||||
devtool: 'inline-source-map',
|
||||
}
|
||||
} catch (e) { console.log('Error in webpack dev configuration: ', e) }
|
||||
} catch (e) {
|
||||
console.log('Error in webpack dev configuration: ', e)
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = getDevConfiguration()
|
||||
|
@ -20,19 +20,20 @@ const TerserPlugin = require('terser-webpack-plugin')
|
||||
const CopyPlugin = require('copy-webpack-plugin')
|
||||
const LoadablePlugin = require('@loadable/webpack-plugin')
|
||||
const TimeFixPlugin = require('time-fix-plugin')
|
||||
const { defaultApps, defaultFileStats, defaultAppName } = require('./src/server/utils/constants/defaults')
|
||||
const {
|
||||
defaultApps,
|
||||
defaultFileStats,
|
||||
defaultAppName,
|
||||
} = require('./src/server/utils/constants/defaults')
|
||||
|
||||
const js = {
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: path.resolve(__dirname, 'src')
|
||||
include: path.resolve(__dirname, 'src'),
|
||||
}
|
||||
const css = {
|
||||
test: /\.css$/i,
|
||||
use: [
|
||||
'style-loader',
|
||||
'css-loader'
|
||||
]
|
||||
use: ['style-loader', 'css-loader'],
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,24 +47,27 @@ const bundle = ({ assets = false, name = 'sunstone' }) => {
|
||||
new TimeFixPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify('production')
|
||||
}
|
||||
NODE_ENV: JSON.stringify('production'),
|
||||
},
|
||||
}),
|
||||
new webpack.ProvidePlugin({
|
||||
process: 'process/browser'
|
||||
process: 'process/browser',
|
||||
}),
|
||||
new LoadablePlugin({ filename: name + defaultFileStats })
|
||||
new LoadablePlugin({ filename: name + defaultFileStats }),
|
||||
]
|
||||
if (assets) {
|
||||
plugins.push(new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.resolve(__dirname, 'src', 'client', 'assets'),
|
||||
to: path.resolve(__dirname, 'dist', 'client', 'assets')
|
||||
}
|
||||
]
|
||||
}))
|
||||
plugins.push(
|
||||
new CopyPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.resolve(__dirname, 'src', 'client', 'assets'),
|
||||
to: path.resolve(__dirname, 'dist', 'client', 'assets'),
|
||||
},
|
||||
],
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
return {
|
||||
mode: 'production',
|
||||
entry: path.resolve(__dirname, 'src', 'client', `${name}.js`),
|
||||
@ -71,31 +75,30 @@ const bundle = ({ assets = false, name = 'sunstone' }) => {
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist', 'client'),
|
||||
filename: `bundle.${name}.js`,
|
||||
publicPath: `/${defaultAppName}/client/`
|
||||
publicPath: `/${defaultAppName}/client/`,
|
||||
},
|
||||
stats: {
|
||||
warnings: false
|
||||
warnings: false,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
process: 'process/browser'
|
||||
}
|
||||
process: 'process/browser',
|
||||
},
|
||||
},
|
||||
plugins,
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({ extractComments: false })
|
||||
]
|
||||
minimizer: [new TerserPlugin({ extractComments: false })],
|
||||
},
|
||||
module: {
|
||||
rules: [js, css]
|
||||
}
|
||||
rules: [js, css],
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {webpack.Configuration[]} - list of configuration
|
||||
*/
|
||||
module.exports = () => Object.entries(defaultApps).map(([key, values]) =>
|
||||
bundle({ ...values, name: key })
|
||||
)
|
||||
module.exports = () =>
|
||||
Object.entries(defaultApps).map(([key, values]) =>
|
||||
bundle({ ...values, name: key })
|
||||
)
|
||||
|
@ -19,12 +19,14 @@ const webpack = require('webpack')
|
||||
const nodeExternals = require('webpack-node-externals')
|
||||
const TerserPlugin = require('terser-webpack-plugin')
|
||||
const TimeFixPlugin = require('time-fix-plugin')
|
||||
const { defaultProductionWebpackMode } = require('./src/server/utils/constants/defaults')
|
||||
const {
|
||||
defaultProductionWebpackMode,
|
||||
} = require('./src/server/utils/constants/defaults')
|
||||
|
||||
const js = {
|
||||
test: /\.js$/,
|
||||
loader: 'babel-loader',
|
||||
include: path.resolve(__dirname, 'src')
|
||||
include: path.resolve(__dirname, 'src'),
|
||||
}
|
||||
|
||||
const css = {
|
||||
@ -33,18 +35,18 @@ const css = {
|
||||
{
|
||||
loader: 'css-loader',
|
||||
options: {
|
||||
esModule: false
|
||||
}
|
||||
}
|
||||
]
|
||||
esModule: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const worker = {
|
||||
test: /\.worker\.js$/,
|
||||
loader: 'worker-loader',
|
||||
options: {
|
||||
filename: '[name].js'
|
||||
}
|
||||
filename: '[name].js',
|
||||
},
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@ -52,33 +54,31 @@ module.exports = {
|
||||
entry: path.resolve(__dirname, 'src', 'server'),
|
||||
target: 'node',
|
||||
node: {
|
||||
__dirname: false
|
||||
__dirname: false,
|
||||
},
|
||||
externals: [nodeExternals()],
|
||||
output: {
|
||||
path: path.resolve(__dirname, 'dist'),
|
||||
filename: 'index.js'
|
||||
filename: 'index.js',
|
||||
},
|
||||
stats: {
|
||||
warnings: false
|
||||
warnings: false,
|
||||
},
|
||||
plugins: [
|
||||
new TimeFixPlugin(),
|
||||
new webpack.DefinePlugin({
|
||||
'process.env': {
|
||||
NODE_ENV: JSON.stringify(defaultProductionWebpackMode)
|
||||
}
|
||||
NODE_ENV: JSON.stringify(defaultProductionWebpackMode),
|
||||
},
|
||||
}),
|
||||
new webpack.optimize.LimitChunkCountPlugin({
|
||||
maxChunks: 1
|
||||
})
|
||||
maxChunks: 1,
|
||||
}),
|
||||
],
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({ extractComments: false })
|
||||
]
|
||||
minimizer: [new TerserPlugin({ extractComments: false })],
|
||||
},
|
||||
module: {
|
||||
rules: [js, worker, css]
|
||||
}
|
||||
rules: [js, worker, css],
|
||||
},
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user