util.ts 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. /*
  2. * <<
  3. * Davinci
  4. * ==
  5. * Copyright (C) 2016 - 2017 EDP
  6. * ==
  7. * Licensed under the Apache License, Version 2.0 (the "License");
  8. * you may not use this file except in compliance with the License.
  9. * You may obtain a copy of the License at
  10. *
  11. * http://www.apache.org/licenses/LICENSE-2.0
  12. *
  13. * Unless required by applicable law or agreed to in writing, software
  14. * distributed under the License is distributed on an "AS IS" BASIS,
  15. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  16. * See the License for the specific language governing permissions and
  17. * limitations under the License.
  18. * >>
  19. */
  20. import moment, { DurationInputArg2 } from 'moment'
  21. import {
  22. IControl,
  23. IControlRelatedView,
  24. IRenderTreeItem,
  25. IFilter,
  26. IControlOption,
  27. IControlCondition
  28. } from './types'
  29. import { uuid } from 'app/utils/util'
  30. import {
  31. ControlTypes,
  32. ControlTypesOperatorSetting,
  33. IS_RANGE_TYPE,
  34. ControlPanelTypes,
  35. DatePickerFormats,
  36. DatePickerFormatsSelectSetting,
  37. ControlFieldTypes,
  38. ControlDefaultValueTypes,
  39. ControlOptionTypes,
  40. ControlVisibilityTypes,
  41. IS_NUMBER_TYPE
  42. } from './constants'
  43. import { DEFAULT_CACHE_EXPIRED, SQL_NUMBER_TYPES } from 'app/globalConstants'
  44. import {
  45. IFormedView,
  46. IViewModelProps,
  47. IViewVariable,
  48. IFormedViews,
  49. IViewModel
  50. } from 'app/containers/View/types'
  51. import {
  52. ViewVariableValueTypes,
  53. ViewVariableTypes,
  54. ViewModelTypes
  55. } from 'app/containers/View/constants'
  56. import OperatorTypes from 'app/utils/operatorTypes'
  57. import { IFlatRelatedView } from './Config/ControlForm/types'
  58. import { IDashboardItem, QueryVariable } from 'app/containers/Dashboard/types'
  59. import { IWidgetFormed } from 'app/containers/Widget/types'
  60. import { IRelativeDate } from '../RelativeDatePicker/types'
  61. import { RelativeDateValueType } from '../RelativeDatePicker/constants'
  62. import { TreeNode } from 'antd/lib/tree-select'
  63. export function getDefaultGlobalControl(): IControl {
  64. const control: IControl = {
  65. key: uuid(8, 16),
  66. name: '新建控制器',
  67. type: ControlTypes.Select,
  68. operator: ControlTypesOperatorSetting[ControlTypes.Select].normal[0],
  69. optionType: ControlOptionTypes.Auto,
  70. defaultValueType: ControlDefaultValueTypes.Fixed,
  71. cache: false,
  72. expired: DEFAULT_CACHE_EXPIRED,
  73. width: 0,
  74. visibility: ControlVisibilityTypes.Visible,
  75. relatedItems: {},
  76. relatedViews: {}
  77. }
  78. return control
  79. }
  80. export function getDefaultLocalControl(view: IFormedView): IControl {
  81. const model = view.model || {}
  82. const modelList = Object.entries(model)
  83. const defaultFields = modelList[0]
  84. const control: IControl = {
  85. key: uuid(8, 16),
  86. name: '新建控制器',
  87. type: ControlTypes.Select,
  88. operator: ControlTypesOperatorSetting[ControlTypes.Select].normal[0],
  89. optionType: ControlOptionTypes.Auto,
  90. defaultValueType: ControlDefaultValueTypes.Fixed,
  91. cache: false,
  92. expired: DEFAULT_CACHE_EXPIRED,
  93. width: 0,
  94. visibility: ControlVisibilityTypes.Visible,
  95. relatedViews: {
  96. [view.id]: {
  97. fieldType: ControlFieldTypes.Column,
  98. fields: defaultFields && [defaultFields[0]]
  99. }
  100. }
  101. }
  102. return control
  103. }
  104. export function getVariableParams(
  105. control: IControl,
  106. fields: string[],
  107. value,
  108. variables: IViewVariable[]
  109. ) {
  110. const { type, dateFormat, multiple } = control
  111. const fieldsVariables = fields
  112. .map((name) => variables.find((v) => v.name === name))
  113. .filter((f) => !!f)
  114. let params = []
  115. if (
  116. value === void 0 ||
  117. value === null ||
  118. (typeof value === 'string' && !value.trim()) ||
  119. !fieldsVariables.length
  120. ) {
  121. return params
  122. }
  123. switch (type) {
  124. case ControlTypes.InputText:
  125. case ControlTypes.Radio:
  126. params = fieldsVariables.map(({ name, valueType }) => ({
  127. name,
  128. value: getValidVariableValue(value, valueType)
  129. }))
  130. break
  131. case ControlTypes.Select:
  132. case ControlTypes.TreeSelect:
  133. if (multiple) {
  134. if (value.length && value.length > 0) {
  135. params = fieldsVariables.map(({ name, valueType }) => ({
  136. name,
  137. value: value
  138. .map((val) => getValidVariableValue(val, valueType))
  139. .join(',')
  140. }))
  141. }
  142. } else {
  143. params = fieldsVariables.map(({ name, valueType }) => ({
  144. name,
  145. value: getValidVariableValue(value, valueType)
  146. }))
  147. }
  148. break
  149. case ControlTypes.NumberRange:
  150. case ControlTypes.Slider:
  151. params = value.reduce((arr, val, index) => {
  152. if (fieldsVariables[index] && val !== '' && !isNaN(val)) {
  153. const { name, valueType } = fieldsVariables[index]
  154. return arr.concat({
  155. name,
  156. value: getValidVariableValue(val, valueType)
  157. })
  158. }
  159. return arr
  160. }, [])
  161. break
  162. case ControlTypes.Date:
  163. if (multiple) {
  164. params = fieldsVariables.map(({ name }) => ({
  165. name,
  166. value: value
  167. .split(',')
  168. .map((v) => `'${v}'`)
  169. .join(',')
  170. }))
  171. } else {
  172. params = fieldsVariables.map(({ name }) => ({
  173. name,
  174. value: `'${moment(value).format(dateFormat)}'`
  175. }))
  176. }
  177. break
  178. case ControlTypes.DateRange:
  179. if (value.length) {
  180. params = value
  181. .map((v, index) => {
  182. return fieldsVariables[index]
  183. ? {
  184. name: fieldsVariables[index].name,
  185. value: `'${moment(v).format(dateFormat)}'`
  186. }
  187. : null
  188. })
  189. .filter((p) => p)
  190. }
  191. break
  192. default:
  193. const val = value.target.value.trim()
  194. if (val) {
  195. params = fieldsVariables.map(({ name, valueType }) => ({
  196. name,
  197. value: getValidVariableValue(val, valueType)
  198. }))
  199. }
  200. break
  201. }
  202. return params
  203. }
  204. export function getCustomOptionVariableParams(
  205. control: IControl,
  206. viewId: number,
  207. value,
  208. variables: IViewVariable[]
  209. ): QueryVariable {
  210. const { customOptions } = control
  211. let params = []
  212. if (
  213. value === void 0 ||
  214. value === null ||
  215. (typeof value === 'string' && !value.trim())
  216. ) {
  217. return params
  218. }
  219. Array.from([])
  220. .concat(value)
  221. .forEach((val) => {
  222. const selectedOption = customOptions.find((o) => o.value === val)
  223. if (selectedOption && selectedOption.variables[viewId]) {
  224. params = params.concat(
  225. getVariableParams(
  226. { ...control, multiple: false },
  227. [selectedOption.variables[viewId]],
  228. val,
  229. variables
  230. )
  231. )
  232. }
  233. })
  234. return params
  235. }
  236. // 全局过滤器 与 组件控制器 filter 操作
  237. export function getFilterParams(
  238. control: IControl,
  239. fields: string[],
  240. value,
  241. models: IViewModel
  242. ) {
  243. const { type, dateFormat, multiple, operator } = control // select '' true in
  244. // filter is related with only one field
  245. const filterFieldName = fields[0]
  246. const filters = []
  247. if (
  248. value === void 0 ||
  249. value === null ||
  250. (typeof value === 'string' && !value.trim()) ||
  251. !models[filterFieldName]
  252. ) {
  253. return filters
  254. }
  255. const { sqlType } = models[filterFieldName]
  256. const filterBase: IFilter = {
  257. name: filterFieldName,
  258. type: 'filter',
  259. value: getValidColumnValue(value, sqlType),
  260. sqlType,
  261. operator
  262. }
  263. switch (type) {
  264. case ControlTypes.InputText:
  265. case ControlTypes.Radio:
  266. filters.push(filterBase)
  267. break
  268. case ControlTypes.Select:
  269. case ControlTypes.TreeSelect:
  270. if (multiple) {
  271. if (Array.isArray(value) && value.length > 0) {
  272. filters.push({
  273. ...filterBase,
  274. value: value.map((val) => getValidColumnValue(val, sqlType))
  275. })
  276. }
  277. } else {
  278. filters.push(filterBase)
  279. }
  280. break
  281. case ControlTypes.NumberRange:
  282. case ControlTypes.Slider:
  283. value.forEach((val, index) => {
  284. if (val !== '' && !isNaN(val)) {
  285. filters.push({
  286. ...filterBase,
  287. operator: !index ? '>=' : '<=',
  288. value: getValidColumnValue(val, sqlType)
  289. })
  290. }
  291. })
  292. break
  293. case ControlTypes.Date:
  294. filters.push({
  295. ...filterBase,
  296. value: multiple
  297. ? value.split(',').map((val) => getValidColumnValue(val, sqlType))
  298. : getValidColumnValue(moment(value).format(dateFormat), sqlType)
  299. })
  300. break
  301. case ControlTypes.DateRange:
  302. if (value.length) {
  303. value.forEach((val, index) => {
  304. filters.push({
  305. ...filterBase,
  306. operator: !index ? '>=' : '<=',
  307. value: getValidColumnValue(moment(val).format(dateFormat), sqlType)
  308. })
  309. })
  310. }
  311. break
  312. default:
  313. const inputValue = value.target.value.trim()
  314. if (inputValue) {
  315. filters.push({
  316. ...filterBase,
  317. value: getValidColumnValue(inputValue, sqlType)
  318. })
  319. }
  320. break
  321. }
  322. return filters
  323. }
  324. export function getValidColumnValue(value, sqlType) {
  325. if (!value || !sqlType) {
  326. return value
  327. }
  328. return SQL_NUMBER_TYPES.includes(sqlType) ? value : `'${value}'`
  329. }
  330. export function getValidVariableValue(
  331. value,
  332. valueType: ViewVariableValueTypes
  333. ) {
  334. switch (valueType) {
  335. case ViewVariableValueTypes.String:
  336. case ViewVariableValueTypes.Date:
  337. return `'${value}'`
  338. case ViewVariableValueTypes.Boolean:
  339. if (typeof value === 'string') {
  340. if (value.toLowerCase() === 'false' || value.trim() === '') {
  341. return false
  342. } else {
  343. return true
  344. }
  345. } else {
  346. return !!value
  347. }
  348. default:
  349. return value
  350. }
  351. }
  352. export function transformRelativeDateValue(val: IRelativeDate) {
  353. const { type, value, valueType } = val
  354. return valueType === RelativeDateValueType.Prev
  355. ? moment()
  356. .subtract(value, `${type}s` as DurationInputArg2)
  357. .startOf(type)
  358. : moment()
  359. .add(value, `${type}s` as DurationInputArg2)
  360. .startOf(type)
  361. }
  362. export function getPreciseDefaultValue(control: IControl) {
  363. const { type, defaultValueType, defaultValue, multiple } = control
  364. switch (type) {
  365. case ControlTypes.DateRange:
  366. return defaultValueType === ControlDefaultValueTypes.Dynamic
  367. ? defaultValue.map((val) => transformRelativeDateValue(val))
  368. : Array.isArray(defaultValue)
  369. ? defaultValue.map((val) => moment(val))
  370. : defaultValue
  371. case ControlTypes.Date:
  372. if (defaultValue) {
  373. return defaultValueType === ControlDefaultValueTypes.Dynamic
  374. ? transformRelativeDateValue(defaultValue)
  375. : multiple
  376. ? defaultValue
  377. : moment(defaultValue)
  378. }
  379. default:
  380. return defaultValue
  381. }
  382. }
  383. export function stringifyDefaultValue(
  384. control: Partial<IControl>,
  385. defaultValue: any,
  386. defaultValueStart: IRelativeDate,
  387. defaultValueEnd: IRelativeDate
  388. ) {
  389. const { type, dateFormat, defaultValueType, multiple } = control
  390. switch (type) {
  391. case ControlTypes.DateRange:
  392. return defaultValueType === ControlDefaultValueTypes.Fixed
  393. ? Array.isArray(defaultValue)
  394. ? defaultValue.map((val) => val.format(dateFormat))
  395. : defaultValue
  396. : [defaultValueStart, defaultValueEnd]
  397. case ControlTypes.Date:
  398. return defaultValueType === ControlDefaultValueTypes.Fixed &&
  399. !multiple &&
  400. defaultValue
  401. ? defaultValue.format(dateFormat)
  402. : defaultValue
  403. default:
  404. return defaultValue
  405. }
  406. }
  407. export function parseDefaultValue(control: Partial<IControl>) {
  408. const { type, defaultValue, defaultValueType, multiple } = control
  409. switch (type) {
  410. case ControlTypes.DateRange:
  411. return defaultValueType === ControlDefaultValueTypes.Fixed
  412. ? Array.isArray(defaultValue)
  413. ? { defaultValue: defaultValue.map((val) => moment(val)) }
  414. : { defaultValue }
  415. : {
  416. defaultValueStart: defaultValue[0],
  417. defaultValueEnd: defaultValue[1]
  418. }
  419. case ControlTypes.Date:
  420. return defaultValueType === ControlDefaultValueTypes.Fixed &&
  421. !multiple &&
  422. defaultValue
  423. ? { defaultValue: moment(defaultValue) }
  424. : { defaultValue }
  425. default:
  426. return { defaultValue }
  427. }
  428. }
  429. export function transformOptions(
  430. control: IControl,
  431. options: object[]
  432. ): IControlOption[] | TreeNode[] {
  433. switch (control.type) {
  434. case ControlTypes.Select:
  435. case ControlTypes.Radio:
  436. switch (control.optionType) {
  437. case ControlOptionTypes.Auto:
  438. return Object.values(
  439. options.reduce((obj, o) => {
  440. Object.values(control.relatedViews).forEach(({ fields }) => {
  441. const value = o[fields[0]]
  442. if (value !== void 0 && !obj[value]) {
  443. obj[value] = { value, text: value }
  444. }
  445. })
  446. return obj
  447. }, {})
  448. )
  449. case ControlOptionTypes.Manual:
  450. const { valueField, textField } = control
  451. return Object.values(
  452. options.reduce((obj, o) => {
  453. const value = o[valueField]
  454. if (!obj[value]) {
  455. obj[value] = {
  456. value,
  457. text: textField ? o[textField] : o[valueField]
  458. }
  459. }
  460. return obj
  461. }, {})
  462. )
  463. default:
  464. return options as IControlOption[]
  465. }
  466. case ControlTypes.TreeSelect:
  467. const { valueField, textField, parentField } = control
  468. return options.map((o) => ({
  469. id: o[valueField],
  470. pId: o[parentField],
  471. value: o[valueField],
  472. title: textField ? o[textField] : o[valueField]
  473. }))
  474. default:
  475. return []
  476. }
  477. }
  478. export function getOperatorOptions(
  479. type: ControlTypes,
  480. multiple: boolean
  481. ): OperatorTypes[] {
  482. const operatorTypes = ControlTypesOperatorSetting[type]
  483. switch (type) {
  484. case ControlTypes.Select:
  485. case ControlTypes.Date:
  486. case ControlTypes.TreeSelect:
  487. return multiple ? operatorTypes['multiple'] : operatorTypes['normal']
  488. default:
  489. return operatorTypes as OperatorTypes[]
  490. }
  491. }
  492. export function getValidOperator(
  493. operator: OperatorTypes,
  494. type: ControlTypes,
  495. multiple: boolean
  496. ): OperatorTypes {
  497. const options = getOperatorOptions(type, multiple)
  498. return options.includes(operator) ? operator : options[0]
  499. }
  500. export function getDatePickerFormatOptions(
  501. type: ControlTypes,
  502. multiple: boolean
  503. ): DatePickerFormats[] {
  504. switch (type) {
  505. case ControlTypes.Date:
  506. case ControlTypes.DateRange:
  507. return multiple
  508. ? DatePickerFormatsSelectSetting['multiple']
  509. : DatePickerFormatsSelectSetting['normal']
  510. default:
  511. return []
  512. }
  513. }
  514. export function getValidDatePickerFormat(
  515. dateFormat: DatePickerFormats,
  516. type: ControlTypes,
  517. multiple: boolean
  518. ): DatePickerFormats {
  519. const options = getDatePickerFormatOptions(type, multiple)
  520. return options.includes(dateFormat) ? dateFormat : options[0]
  521. }
  522. export function getControlRenderTree(
  523. controls: IControl[]
  524. ): {
  525. renderTree: IRenderTreeItem[]
  526. flatTree: {
  527. [key: string]: IRenderTreeItem
  528. }
  529. } {
  530. const renderTree = []
  531. const flatTree = {}
  532. while (controls.length) {
  533. const control = { ...controls[0] }
  534. flatTree[control.key] = control
  535. if (control.parent) {
  536. if (!flatTree[control.parent]) {
  537. controls.push(control)
  538. controls.shift()
  539. continue
  540. }
  541. if (!flatTree[control.parent].children) {
  542. flatTree[control.parent].children = []
  543. }
  544. flatTree[control.parent].children.push(control)
  545. } else {
  546. renderTree.push(control)
  547. }
  548. controls.shift()
  549. }
  550. return {
  551. renderTree,
  552. flatTree
  553. }
  554. }
  555. export function getAllChildren(
  556. key: string,
  557. flatTree: { [key: string]: IRenderTreeItem }
  558. ) {
  559. let keys = []
  560. if (flatTree[key].children) {
  561. flatTree[key].children.forEach((c) => {
  562. keys = keys.concat(c.key).concat(getAllChildren(c.key, flatTree))
  563. })
  564. }
  565. return keys
  566. }
  567. export function getParents(
  568. parentKey: string,
  569. flatTree: {
  570. [key: string]: IRenderTreeItem
  571. }
  572. ): IRenderTreeItem[] {
  573. let parents = []
  574. const parent = flatTree[parentKey]
  575. if (parent) {
  576. const { children, ...rest } = parent
  577. parents = parents
  578. .concat({ ...rest })
  579. .concat(getParents(rest.parent, flatTree))
  580. }
  581. return parents
  582. }
  583. export function getRelatedViewModels(
  584. view: IFormedView,
  585. type: ControlTypes
  586. ): IViewModelProps[] {
  587. return Object.entries(view.model)
  588. .filter(([k, v]: [string, IViewModelProps]) => {
  589. return IS_NUMBER_TYPE[type]
  590. ? v.modelType === ViewModelTypes.Value
  591. : v.modelType === ViewModelTypes.Category
  592. })
  593. .map(([k, v]: [string, IViewModelProps]) => ({
  594. name: k,
  595. ...v
  596. }))
  597. }
  598. export function getDefaultRelatedView(
  599. view: IFormedView,
  600. type: ControlTypes,
  601. relatedView?: IControlRelatedView
  602. ): IFlatRelatedView {
  603. const { id, name } = view
  604. const models = getRelatedViewModels(view, type)
  605. const variables = view.variable.filter(
  606. (v) => v.type === ViewVariableTypes.Query
  607. )
  608. return {
  609. id,
  610. name,
  611. models,
  612. variables,
  613. ...(relatedView || {
  614. fieldType: ControlFieldTypes.Column,
  615. fields: void 0,
  616. operator: ControlTypesOperatorSetting[ControlTypes.Select].normal[0]
  617. })
  618. }
  619. }
  620. export function getEditingControlFormValues(
  621. control: IControl,
  622. formedViews?: IFormedViews,
  623. currentItems?: IDashboardItem[],
  624. widgets?: IWidgetFormed[]
  625. ) {
  626. if (control) {
  627. const { relatedItems, relatedViews, ...editingControlBase } = control
  628. const editingRelatedItemList = []
  629. const checkedViews = []
  630. if (currentItems && relatedItems) {
  631. currentItems.forEach((item) => {
  632. const widget = widgets.find((w) => w.id === item.widgetId)
  633. const checked = relatedItems[item.id]
  634. ? relatedItems[item.id].checked && !!relatedViews[widget.viewId]
  635. : false
  636. editingRelatedItemList.push({
  637. id: item.id,
  638. name: widget.name,
  639. viewId: widget.viewId,
  640. checked
  641. })
  642. if (checked && !checkedViews.includes(widget.viewId)) {
  643. checkedViews.push(widget.viewId)
  644. }
  645. })
  646. } else {
  647. const [viewId, relatedView] = Object.entries(relatedViews)[0]
  648. checkedViews.push(viewId)
  649. }
  650. const editingRelatedViewList = checkedViews.map((viewId) => {
  651. const view = formedViews[viewId]
  652. const relatedView = relatedViews[viewId]
  653. return getDefaultRelatedView(view, editingControlBase.type, relatedView)
  654. })
  655. return {
  656. editingControlBase,
  657. editingRelatedItemList,
  658. editingRelatedViewList
  659. }
  660. } else {
  661. return {
  662. editingControlBase: null,
  663. editingRelatedItemList: [],
  664. editingRelatedViewList: []
  665. }
  666. }
  667. }
  668. export function getPanelRenderState(
  669. type: ControlPanelTypes,
  670. controls: IControl[],
  671. items: string
  672. ) {
  673. const validControls: IControl[] = []
  674. const itemIds = items.split(',')
  675. const defaultValues = {}
  676. controls.forEach((control) => {
  677. defaultValues[control.key] = getPreciseDefaultValue(control)
  678. validControls.push({
  679. ...control,
  680. ...(type === ControlPanelTypes.Global && {
  681. relatedItems: Object.entries(control.relatedItems).reduce(
  682. (obj, [id, item]) => {
  683. if (itemIds.includes(id)) {
  684. obj[id] = item
  685. }
  686. return obj
  687. },
  688. {}
  689. )
  690. })
  691. })
  692. })
  693. const { renderTree, flatTree } = getControlRenderTree(validControls)
  694. return {
  695. renderTree,
  696. flatTree,
  697. defaultValues
  698. }
  699. }
  700. export function getControlConditionValue(
  701. controls: IControl[],
  702. conditions: IControlCondition[],
  703. controlValues: object
  704. ): boolean {
  705. const condition = conditions[0]
  706. if (condition) {
  707. const { control: conditionControlKey, operator, value } = condition
  708. if (conditionControlKey && operator && value) {
  709. const conditionControl = controls.find(
  710. (c) => c.key === conditionControlKey
  711. )
  712. if (conditionControl) {
  713. switch (operator) {
  714. case OperatorTypes.Equal:
  715. return controlValues[conditionControlKey] === value
  716. case OperatorTypes.NotEqual:
  717. return controlValues[conditionControlKey] !== value
  718. case OperatorTypes.In:
  719. return controlValues[conditionControlKey].includes(value)
  720. case OperatorTypes.NotIn:
  721. return !controlValues[conditionControlKey].includes(value)
  722. }
  723. }
  724. }
  725. }
  726. return false
  727. }
  728. export function getControlVisibility(
  729. controls: IControl[],
  730. control: IControl,
  731. controlValues: object
  732. ): boolean {
  733. const { visibility, conditions } = control
  734. switch (visibility) {
  735. case ControlVisibilityTypes.Conditional:
  736. return getControlConditionValue(controls, conditions, controlValues)
  737. case ControlVisibilityTypes.Visible:
  738. return true
  739. case ControlVisibilityTypes.Hidden:
  740. return false
  741. }
  742. }
  743. export function cleanInvisibleConditionalControlValues(
  744. controls: IControl[],
  745. changingControl: IControl,
  746. controlValues: object
  747. ): object {
  748. const updatedValues = {}
  749. controls.forEach((c) => {
  750. if (
  751. c.visibility === ControlVisibilityTypes.Conditional &&
  752. c.conditions[0] &&
  753. c.conditions[0].control === changingControl.key &&
  754. getControlConditionValue(controls, c.conditions, controlValues)
  755. ) {
  756. updatedValues[c.key] = getPreciseDefaultValue(c)
  757. }
  758. })
  759. return updatedValues
  760. }