DashboardLinkageConfig.tsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  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 React from 'react'
  21. import { Button, Modal } from 'antd'
  22. import { SQL_NUMBER_TYPES, DEFAULT_SPLITER } from 'app/globalConstants'
  23. import { decodeMetricName, getAggregatorLocale } from 'containers/Widget/components/util'
  24. import { IFormedViews } from 'containers/View/types'
  25. import { IWidgetConfig } from 'containers/Widget/components/Widget'
  26. import LinkageConfig from 'components/Linkages/LinkageConfig'
  27. const styles = require('../Dashboard.less')
  28. interface IDashboardLinkageConfigProps {
  29. currentDashboard: any
  30. currentItems: any[]
  31. currentItemsInfo: any
  32. linkages: any[]
  33. views: IFormedViews
  34. widgets: any[]
  35. visible: boolean
  36. loading: boolean
  37. onCancel: () => void
  38. onSave: (filterItems: any[]) => void
  39. onGetWidgetInfo: (itemId: number) => void
  40. }
  41. interface IDashboardLinkageConfigStates {
  42. linkageCascaderSource: any[]
  43. savingLinkageConfig: boolean
  44. }
  45. export class DashboardLinkageConfig extends React.Component<IDashboardLinkageConfigProps, IDashboardLinkageConfigStates> {
  46. public constructor (props: IDashboardLinkageConfigProps) {
  47. super(props)
  48. this.state = {
  49. linkageCascaderSource: [],
  50. savingLinkageConfig: false
  51. }
  52. }
  53. public componentWillReceiveProps (nextProps: IDashboardLinkageConfigProps) {
  54. const { visible } = nextProps
  55. if (visible) {
  56. const linkageCascaderSource = this.getLinkageConfigSource()
  57. this.setState({ linkageCascaderSource })
  58. }
  59. }
  60. private getLinkageConfigSource = () => {
  61. const { currentItems, widgets, views, currentItemsInfo } = this.props
  62. if (!currentItemsInfo) { return [] }
  63. const linkageConfigSource = []
  64. Object.keys(currentItemsInfo).forEach((infoKey) => {
  65. const dashboardItem = currentItems.find((ci) => `${ci.id}` === infoKey)
  66. const widget = widgets.find((w) => w.id === dashboardItem.widgetId)
  67. const { cols, rows, metrics, color, label } = widget.config
  68. const view = views[widget.viewId]
  69. const { model, variable } = view
  70. let triggerDimensions = [...cols, ...rows].map(({ name }) => name)
  71. if (color) {
  72. triggerDimensions = triggerDimensions.concat(color.items.map(({ name }) => name))
  73. }
  74. if (label) {
  75. triggerDimensions = triggerDimensions.concat(label.items.map(({ name }) => name))
  76. }
  77. const triggerColumns = [
  78. ...[...new Set(triggerDimensions)]
  79. .filter((name) => model[name])
  80. .map((name) => {
  81. return {
  82. label: name,
  83. value: [name, model[name].sqlType, 'column'].join(DEFAULT_SPLITER)
  84. }
  85. }),
  86. ...metrics.map(({ name, agg }) => {
  87. const metricName = decodeMetricName(name)
  88. return {
  89. label: `${getAggregatorLocale(agg)} ${metricName}`,
  90. value: [`${agg}(${metricName})`, SQL_NUMBER_TYPES[SQL_NUMBER_TYPES.length - 1], 'column'].join(DEFAULT_SPLITER)
  91. }
  92. })
  93. ]
  94. const linkagerColumns = Object.entries(model)
  95. .map(([name, value]) => ({
  96. label: name,
  97. value: [name, value.sqlType, 'column'].join(DEFAULT_SPLITER)
  98. }))
  99. const variables = variable.map(({ name }) => {
  100. return {
  101. label: `${name}[变量]`,
  102. value: [name, null, 'variable'].join(DEFAULT_SPLITER)
  103. }
  104. })
  105. linkageConfigSource.push({
  106. label: widget.name,
  107. value: infoKey,
  108. children: {
  109. triggerColumns,
  110. linkagerColumns,
  111. variables
  112. }
  113. })
  114. })
  115. return linkageConfigSource
  116. }
  117. private onSavingLinkageConfig = () => {
  118. this.setState({
  119. savingLinkageConfig: !this.state.savingLinkageConfig
  120. })
  121. }
  122. public render () {
  123. const { visible, loading, onSave, onGetWidgetInfo, linkages, onCancel } = this.props
  124. const { linkageCascaderSource, savingLinkageConfig } = this.state
  125. const modalButtons = [(
  126. <Button
  127. key="cancel"
  128. size="large"
  129. onClick={onCancel}
  130. >
  131. 取 消
  132. </Button>
  133. ), (
  134. <Button
  135. key="submit"
  136. size="large"
  137. type="primary"
  138. loading={loading}
  139. disabled={loading}
  140. onClick={this.onSavingLinkageConfig}
  141. >
  142. 保 存
  143. </Button>
  144. )]
  145. return (
  146. <Modal
  147. title="联动关系配置"
  148. wrapClassName="ant-modal-large"
  149. maskClosable={false}
  150. visible={visible}
  151. onCancel={onCancel}
  152. footer={modalButtons}
  153. >
  154. <div className={styles.modalLinkageConfig}>
  155. <LinkageConfig
  156. linkages={linkages}
  157. cascaderSource={linkageCascaderSource}
  158. onGetWidgetInfo={onGetWidgetInfo}
  159. saving={savingLinkageConfig}
  160. onSave={onSave}
  161. />
  162. </div>
  163. </Modal>
  164. )
  165. }
  166. }
  167. export default DashboardLinkageConfig