mirror of
https://github.com/IT4Change/ohmyform-ui.git
synced 2025-12-13 09:45:50 +00:00
add field logic in admin
This commit is contained in:
parent
bef465f8d3
commit
1f37215af4
@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
- show error message on homepage in case there is a problem with api connection
|
||||
- new slider field type
|
||||
- new card layout for forms
|
||||
- field logic
|
||||
|
||||
### Changed
|
||||
|
||||
|
||||
@ -1,10 +1,22 @@
|
||||
import { DeleteOutlined } from '@ant-design/icons/lib'
|
||||
import { Button, Card, Checkbox, Form, Input, Popconfirm, Popover, Tag } from 'antd'
|
||||
import { DeleteOutlined, PlusOutlined } from '@ant-design/icons/lib'
|
||||
import {
|
||||
Button,
|
||||
Card,
|
||||
Checkbox,
|
||||
Form,
|
||||
Input,
|
||||
Popconfirm,
|
||||
Popover,
|
||||
Space,
|
||||
Tag,
|
||||
Tooltip,
|
||||
} from 'antd'
|
||||
import { FormInstance } from 'antd/lib/form'
|
||||
import { FieldData } from 'rc-field-form/lib/interface'
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FormFieldFragment } from '../../../graphql/fragment/form.fragment'
|
||||
import { FormFieldFragment, FormFieldLogicFragment } from '../../../graphql/fragment/form.fragment'
|
||||
import { LogicBlock } from './logic.block'
|
||||
import { adminTypes } from './types'
|
||||
import { TextType } from './types/text.type'
|
||||
|
||||
@ -47,12 +59,57 @@ export const FieldCard: React.FC<Props> = (props) => {
|
||||
return () => clearTimeout(id)
|
||||
}, [nextTitle])
|
||||
|
||||
const addLogic = useCallback((add: (defaults: unknown) => void, index: number) => {
|
||||
return (
|
||||
<Form.Item wrapperCol={{ span: 24 }}>
|
||||
<Space
|
||||
style={{
|
||||
width: '100%',
|
||||
justifyContent: 'flex-end',
|
||||
}}
|
||||
>
|
||||
<Button
|
||||
type="dashed"
|
||||
onClick={() => {
|
||||
const defaults: FormFieldLogicFragment = {
|
||||
id: `NEW-${Date.now()}`,
|
||||
formula: null,
|
||||
action: null,
|
||||
jumpTo: null,
|
||||
visible: null,
|
||||
disable: null,
|
||||
require: null,
|
||||
enabled: false,
|
||||
}
|
||||
|
||||
add(defaults)
|
||||
}}
|
||||
>
|
||||
<PlusOutlined /> {t('form:logic.add')}
|
||||
</Button>
|
||||
</Space>
|
||||
</Form.Item>
|
||||
)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<Card
|
||||
title={nextTitle}
|
||||
title={<Tooltip title={`@${field.name as string}`}>nextTitle</Tooltip>}
|
||||
type={'inner'}
|
||||
extra={
|
||||
<div>
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{() => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
|
||||
const slug = form.getFieldValue(['form', 'fields', field.name as string, 'slug'])
|
||||
|
||||
if (!slug) {
|
||||
return null
|
||||
}
|
||||
|
||||
return <Tag color={'warning'}>Slug: {slug}</Tag>
|
||||
}}
|
||||
</Form.Item>
|
||||
<Popover
|
||||
placement={'left'}
|
||||
content={
|
||||
@ -90,7 +147,6 @@ export const FieldCard: React.FC<Props> = (props) => {
|
||||
</Popconfirm>
|
||||
</div>
|
||||
}
|
||||
actions={[<DeleteOutlined key={'delete'} onClick={() => remove(index)} />]}
|
||||
>
|
||||
<Form.Item name={[field.name as string, 'type']} noStyle>
|
||||
<Input type={'hidden'} />
|
||||
@ -122,6 +178,35 @@ export const FieldCard: React.FC<Props> = (props) => {
|
||||
</Form.Item>
|
||||
|
||||
<TypeComponent field={field} form={form} />
|
||||
|
||||
<Form.List name={[field.name as string, 'logic']}>
|
||||
{(logic, { add, remove, move }) => {
|
||||
const addAndMove = (index) => (defaults) => {
|
||||
add(defaults)
|
||||
move(fields.length, index)
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
{addLogic(addAndMove(0), 0)}
|
||||
{logic.map((field, index) => (
|
||||
<div key={field.key}>
|
||||
<Form.Item wrapperCol={{ span: 24 }} noStyle>
|
||||
<LogicBlock
|
||||
field={field}
|
||||
form={form}
|
||||
fields={fields}
|
||||
index={index}
|
||||
remove={remove}
|
||||
/>
|
||||
</Form.Item>
|
||||
{addLogic(addAndMove(index + 1), index + 1)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)
|
||||
}}
|
||||
</Form.List>
|
||||
</Card>
|
||||
)
|
||||
}
|
||||
|
||||
198
components/form/admin/logic.block.tsx
Normal file
198
components/form/admin/logic.block.tsx
Normal file
@ -0,0 +1,198 @@
|
||||
import { DeleteOutlined } from '@ant-design/icons'
|
||||
import { Alert, Button, Checkbox, Form, Mentions, Popconfirm, Select } from 'antd'
|
||||
import { FormInstance } from 'antd/lib/form'
|
||||
import { FieldData } from 'rc-field-form/lib/interface'
|
||||
import React from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FormFieldFragment } from '../../../graphql/fragment/form.fragment'
|
||||
import { useMath } from '../../use.math'
|
||||
|
||||
interface Props {
|
||||
form: FormInstance
|
||||
fields: FormFieldFragment[]
|
||||
field: FieldData
|
||||
remove: (index: number) => void
|
||||
index: number
|
||||
}
|
||||
|
||||
export const LogicBlock: React.FC<Props> = (props) => {
|
||||
const { t } = useTranslation()
|
||||
const { form, field, fields, remove, index } = props
|
||||
const evaluator = useMath()
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
borderRight: '5px solid #DDD',
|
||||
paddingRight: 10,
|
||||
}}
|
||||
>
|
||||
<Form.Item
|
||||
name={[field.name as string, 'formula']}
|
||||
labelCol={{ span: 6 }}
|
||||
label={'Formula'}
|
||||
rules={[{ required: true, message: 'combine other fields' }]}
|
||||
extra={'Save form to get new IDs and slugs'}
|
||||
>
|
||||
<Mentions rows={1}>
|
||||
{fields.map((field) => (
|
||||
<Mentions.Option key={field.id} value={field.id}>
|
||||
{field.title}
|
||||
</Mentions.Option>
|
||||
))}
|
||||
</Mentions>
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{(form) => {
|
||||
try {
|
||||
const defaults = {}
|
||||
|
||||
fields.forEach((field) => {
|
||||
defaults[`@${field.id}`] = field.value
|
||||
|
||||
if (field.slug) {
|
||||
defaults[`$${field.slug}`] = field.value
|
||||
}
|
||||
})
|
||||
|
||||
const result = evaluator(
|
||||
form.getFieldValue([...form.prefixName, field.name as string, 'formula']),
|
||||
defaults
|
||||
)
|
||||
|
||||
return (
|
||||
<Alert
|
||||
type={result ? 'success' : 'warning'}
|
||||
message={
|
||||
result
|
||||
? 'would trigger action with current default values'
|
||||
: 'would NOT trigger action with current default values'
|
||||
}
|
||||
style={{ marginBottom: 24 }}
|
||||
/>
|
||||
)
|
||||
} catch (e) {
|
||||
return <Alert message={e.message} type={'error'} style={{ marginBottom: 24 }} />
|
||||
}
|
||||
}}
|
||||
</Form.Item>
|
||||
<Form.Item name={[field.name as string, 'action']} labelCol={{ span: 6 }} label={'Action'}>
|
||||
<Select
|
||||
options={[
|
||||
{
|
||||
value: 'jumpTo',
|
||||
label: t('form:logic.action.jumpTo'),
|
||||
},
|
||||
{
|
||||
value: 'visible',
|
||||
label: t('form:logic.action.visible'),
|
||||
},
|
||||
{
|
||||
value: 'disable',
|
||||
label: t('form:logic.action.disable'),
|
||||
},
|
||||
{
|
||||
value: 'require',
|
||||
label: t('form:logic.action.require'),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</Form.Item>
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{(form) => (
|
||||
<Form.Item
|
||||
hidden={
|
||||
form.getFieldValue([...form.prefixName, field.name as string, 'action']) !== 'jumpTo'
|
||||
}
|
||||
labelCol={{ span: 6 }}
|
||||
label={t('form:logic.action.jumpTo')}
|
||||
rules={[{ required: true, message: 'Jump target is required' }]}
|
||||
extra={'after selecting field (works best with clickable values)'}
|
||||
>
|
||||
<Select
|
||||
options={fields
|
||||
.filter((field) => !/NEW/i.test(field.id))
|
||||
.map((field) => ({
|
||||
value: field.id,
|
||||
label: field.title,
|
||||
}))}
|
||||
/>
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{(form) => (
|
||||
<Form.Item
|
||||
hidden={
|
||||
form.getFieldValue([...form.prefixName, field.name as string, 'action']) !== 'visible'
|
||||
}
|
||||
initialValue={true}
|
||||
labelCol={{ span: 6 }}
|
||||
label={t('form:logic.action.visible')}
|
||||
valuePropName={'checked'}
|
||||
getValueFromEvent={(checked: boolean) => (checked ? '1' : '')}
|
||||
getValueProps={(e: string) => ({ checked: !!e })}
|
||||
>
|
||||
<Checkbox />
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{(form) => (
|
||||
<Form.Item
|
||||
hidden={
|
||||
form.getFieldValue([...form.prefixName, field.name as string, 'action']) !== 'disable'
|
||||
}
|
||||
initialValue={false}
|
||||
labelCol={{ span: 6 }}
|
||||
label={t('form:logic.action.disable')}
|
||||
valuePropName={'checked'}
|
||||
getValueFromEvent={(checked: boolean) => (checked ? '1' : '')}
|
||||
getValueProps={(e: string) => ({ checked: !!e })}
|
||||
>
|
||||
<Checkbox />
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item noStyle shouldUpdate>
|
||||
{(form) => (
|
||||
<Form.Item
|
||||
hidden={
|
||||
form.getFieldValue([...form.prefixName, field.name as string, 'action']) !== 'require'
|
||||
}
|
||||
initialValue={true}
|
||||
labelCol={{ span: 6 }}
|
||||
label={t('form:logic.action.require')}
|
||||
valuePropName={'checked'}
|
||||
getValueFromEvent={(checked: boolean) => (checked ? '1' : '')}
|
||||
getValueProps={(e: string) => ({ checked: !!e })}
|
||||
>
|
||||
<Checkbox />
|
||||
</Form.Item>
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item>
|
||||
<div style={{ textAlign: 'right' }}>
|
||||
<Popconfirm
|
||||
placement={'right'}
|
||||
title={t('type:confirmDelete')}
|
||||
okText={t('type:deleteNow')}
|
||||
okButtonProps={{ danger: true }}
|
||||
onConfirm={() => {
|
||||
remove(index)
|
||||
}}
|
||||
>
|
||||
<Button danger>
|
||||
<DeleteOutlined />
|
||||
</Button>
|
||||
</Popconfirm>
|
||||
</div>
|
||||
</Form.Item>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
29
components/use.math.ts
Normal file
29
components/use.math.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { all, create } from 'mathjs'
|
||||
import { useState } from 'react'
|
||||
|
||||
export const useMath = (): ((
|
||||
expression: string,
|
||||
values?: { [id: string]: string | number }
|
||||
) => boolean) => {
|
||||
const [math] = useState(create(all, {}))
|
||||
|
||||
return (expression, values) => {
|
||||
try {
|
||||
let processed = expression
|
||||
|
||||
Object.keys(values).forEach((key) => {
|
||||
const r = new RegExp(key.replace('$', '\\$'), 'ig')
|
||||
|
||||
if (r.test(processed)) {
|
||||
processed = processed.replace(r, String(values[key]))
|
||||
}
|
||||
})
|
||||
|
||||
const result = math.evaluate(processed)
|
||||
|
||||
return Boolean(result)
|
||||
} catch (e) {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -56,6 +56,15 @@
|
||||
},
|
||||
"hooksTab": "WebHooks",
|
||||
"loading": "Loading Form",
|
||||
"logic": {
|
||||
"add": "Add Logic",
|
||||
"action": {
|
||||
"jumpTo": "Jump To",
|
||||
"visible": "Visible",
|
||||
"disable": "Disable",
|
||||
"require": "Require"
|
||||
}
|
||||
},
|
||||
"mange": "Edit Form \"{{title}}\"",
|
||||
"new": "New Form",
|
||||
"next": "Next",
|
||||
|
||||
@ -25,6 +25,7 @@
|
||||
"i18next": "^19.9.2",
|
||||
"i18next-browser-languagedetector": "^6.1.0",
|
||||
"isomorphic-fetch": "^3.0.0",
|
||||
"mathjs": "^9.3.2",
|
||||
"next": "^10.2.0",
|
||||
"next-images": "^1.7.0",
|
||||
"next-redux-wrapper": "^6.0.2",
|
||||
@ -47,6 +48,7 @@
|
||||
"devDependencies": {
|
||||
"@types/axios": "^0.14.0",
|
||||
"@types/lifeomic__axios-fetch": "^1.5.0",
|
||||
"@types/mathjs": "^6.0.12",
|
||||
"@types/node": "^14.14.43",
|
||||
"@types/node-fetch": "^2.5.10",
|
||||
"@types/react": "^17.0.4",
|
||||
|
||||
61
yarn.lock
61
yarn.lock
@ -409,6 +409,13 @@
|
||||
"@types/node-fetch" "*"
|
||||
axios "^0.21.0"
|
||||
|
||||
"@types/mathjs@^6.0.12":
|
||||
version "6.0.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/mathjs/-/mathjs-6.0.12.tgz#1c2a60352852676e10936ce150b9500d36555973"
|
||||
integrity sha512-bpKs8CDJ0aOiiJguywryE/U6Wre/uftJ89xhp4aCgF4oRb3Yug2VyZ87958gmSeq4WMsvWPMs2Q5TtFv+dJtaA==
|
||||
dependencies:
|
||||
decimal.js "^10.0.0"
|
||||
|
||||
"@types/node-fetch@*":
|
||||
version "2.5.7"
|
||||
resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c"
|
||||
@ -1291,6 +1298,11 @@ commondir@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b"
|
||||
integrity sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=
|
||||
|
||||
complex.js@^2.0.11:
|
||||
version "2.0.13"
|
||||
resolved "https://registry.yarnpkg.com/complex.js/-/complex.js-2.0.13.tgz#00cf7ba082565e164813b7bbbb0ced5d2aba172a"
|
||||
integrity sha512-UEWd3G3/kd3lJmsdLsDh9qfinJlujL4hIFn3Vo4/G5eqehPsgCHf2CLhFs77tVkOp2stt/jbNit7Q1XFANFltA==
|
||||
|
||||
compress-commons@^4.0.2:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/compress-commons/-/compress-commons-4.0.2.tgz#d6896be386e52f37610cef9e6fa5defc58c31bd7"
|
||||
@ -1507,6 +1519,11 @@ debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
decimal.js@^10.0.0, decimal.js@^10.2.1:
|
||||
version "10.2.1"
|
||||
resolved "https://registry.yarnpkg.com/decimal.js/-/decimal.js-10.2.1.tgz#238ae7b0f0c793d3e3cea410108b35a2c01426a3"
|
||||
integrity sha512-KaL7+6Fw6i5A2XSnsbhm/6B+NuEA7TZ4vqxnd5tXz9sbKtrN9Srj8ab4vKVdK8YAqZO9P1kg45Y6YLoduPf+kw==
|
||||
|
||||
deep-is@^0.1.3:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34"
|
||||
@ -1753,6 +1770,11 @@ escalade@^3.1.1:
|
||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
|
||||
|
||||
escape-latex@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/escape-latex/-/escape-latex-1.2.0.tgz#07c03818cf7dac250cce517f4fda1b001ef2bca1"
|
||||
integrity sha512-nV5aVWW1K0wEiUIEdZ4erkGGH8mDxGyxSeqPzRNtWP7ataw+/olFObw7hujFWlVjNsaDFw5VZ5NzVSIqRgfTiw==
|
||||
|
||||
escape-string-regexp@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
|
||||
@ -2110,6 +2132,11 @@ form-data@^3.0.0:
|
||||
combined-stream "^1.0.8"
|
||||
mime-types "^2.1.12"
|
||||
|
||||
fraction.js@^4.0.13:
|
||||
version "4.1.0"
|
||||
resolved "https://registry.yarnpkg.com/fraction.js/-/fraction.js-4.1.0.tgz#229ec1cedc8c3c7e5d2d20688ba64f0a43af5830"
|
||||
integrity sha512-o9lSKpK0TDqDwTL24Hxqi6I99s942l6TYkfl6WvGWgLOIFz/YonSGKfiSeMadoiNvTfqnfOa9mjb5SGVbBK9/w==
|
||||
|
||||
fs-constants@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad"
|
||||
@ -2646,6 +2673,11 @@ isomorphic-fetch@^3.0.0:
|
||||
node-fetch "^2.6.1"
|
||||
whatwg-fetch "^3.4.1"
|
||||
|
||||
javascript-natural-sort@^0.7.1:
|
||||
version "0.7.1"
|
||||
resolved "https://registry.yarnpkg.com/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz#f9e2303d4507f6d74355a73664d1440fb5a0ef59"
|
||||
integrity sha1-+eIwPUUH9tdDVac2ZNFED7Wg71k=
|
||||
|
||||
jest-worker@27.0.0-next.5:
|
||||
version "27.0.0-next.5"
|
||||
resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-27.0.0-next.5.tgz#5985ee29b12a4e191f4aae4bb73b97971d86ec28"
|
||||
@ -2925,6 +2957,20 @@ material-colors@^1.2.1:
|
||||
resolved "https://registry.yarnpkg.com/material-colors/-/material-colors-1.2.6.tgz#6d1958871126992ceecc72f4bcc4d8f010865f46"
|
||||
integrity sha512-6qE4B9deFBIa9YSpOc9O0Sgc43zTeVYbgDT5veRKSlB2+ZuHNoVVxA1L/ckMUayV9Ay9y7Z/SZCLcGteW9i7bg==
|
||||
|
||||
mathjs@^9.3.2:
|
||||
version "9.3.2"
|
||||
resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-9.3.2.tgz#6523dd5c963d200ff1cea0ff7963b10521b82185"
|
||||
integrity sha512-0YKSKAeN9OkbIQrxfxnBT4kk/KlH71piWOsvVvAasyRIj/Xd/zlpc5VP/aFxwr+llOq2F3f6booPEu2fWv3yjQ==
|
||||
dependencies:
|
||||
complex.js "^2.0.11"
|
||||
decimal.js "^10.2.1"
|
||||
escape-latex "^1.2.0"
|
||||
fraction.js "^4.0.13"
|
||||
javascript-natural-sort "^0.7.1"
|
||||
seedrandom "^3.0.5"
|
||||
tiny-emitter "^2.1.0"
|
||||
typed-function "^2.0.0"
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f"
|
||||
@ -4272,6 +4318,11 @@ scroll-into-view-if-needed@^2.2.25:
|
||||
dependencies:
|
||||
compute-scroll-into-view "^1.0.14"
|
||||
|
||||
seedrandom@^3.0.5:
|
||||
version "3.0.5"
|
||||
resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7"
|
||||
integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==
|
||||
|
||||
semver@^6.0.0:
|
||||
version "6.3.0"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
@ -4658,6 +4709,11 @@ timers-browserify@^2.0.4:
|
||||
dependencies:
|
||||
setimmediate "^1.0.4"
|
||||
|
||||
tiny-emitter@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tiny-emitter/-/tiny-emitter-2.1.0.tgz#1d1a56edfc51c43e863cbb5382a72330e3555423"
|
||||
integrity sha512-NB6Dk1A9xgQPMoGqC5CVXn123gWyte215ONT5Pp5a0yt4nlEoO1ZWeCwpncaekPHXO60i47ihFnZPiRPjRMq4Q==
|
||||
|
||||
tinycolor2@^1.4.1:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/tinycolor2/-/tinycolor2-1.4.1.tgz#f4fad333447bc0b07d4dc8e9209d8f39a8ac77e8"
|
||||
@ -4797,6 +4853,11 @@ type-fest@^0.8.1:
|
||||
resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.8.1.tgz#09e249ebde851d3b1e48d27c105444667f17b83d"
|
||||
integrity sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==
|
||||
|
||||
typed-function@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.0.0.tgz#15ab3825845138a8b1113bd89e60cd6a435739e8"
|
||||
integrity sha512-Hhy1Iwo/e4AtLZNK10ewVVcP2UEs408DS35ubP825w/YgSBK1KVLwALvvIG4yX75QJrxjCpcWkzkVRB0BwwYlA==
|
||||
|
||||
typescript@^4.2.4:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user