xieyonghong пре 3 година
родитељ
комит
2313d0dd12

+ 25 - 0
src/pages/rule-engine/Scene/Save/components/ParamsSelect/components/MTimePicker/index.less

@@ -0,0 +1,25 @@
+.manual-box {
+  position: relative;
+  width: 100%;
+  .manual-time-picker {
+    position: absolute;
+    top: -2px;
+    left: 0;
+    border: none;
+    visibility: hidden;
+    .ant-picker-input {
+      display: none !important;
+    }
+  }
+}
+
+.my-manual-time-picker {
+  width: 100%;
+  .ant-picker-panel-container {
+    position: relative;
+    box-shadow: none !important;
+    .ant-picker-panel {
+      width: 100%;
+    }
+  }
+}

+ 22 - 0
src/pages/rule-engine/Scene/Save/components/ParamsSelect/components/MTimePicker/index.tsx

@@ -0,0 +1,22 @@
+import { TimePicker } from 'antd';
+import './index.less';
+import { TimePickerProps } from 'antd/lib/time-picker';
+
+export default (props: TimePickerProps) => {
+  return (
+    <div id={'manual-box'} className={'manual-box'}>
+      <TimePicker
+        {...props}
+        value={props.value}
+        onChange={props.onChange}
+        className={'manual-time-picker'}
+        popupClassName={'my-manual-time-picker'}
+        open
+        // @ts-ignore
+        getPopupContainer={(trigger) => {
+          return trigger && trigger?.parentNode ? trigger.parentNode : document.body;
+        }}
+      />
+    </div>
+  );
+};

+ 57 - 0
src/pages/rule-engine/Scene/Save/components/ParamsSelect/index.less

@@ -0,0 +1,57 @@
+.select-wrapper {
+  position: relative;
+  width: 100%;
+  margin-bottom: 20px;
+  .select-container {
+    position: absolute;
+    top: 32px;
+    right: auto;
+    left: 0;
+    z-index: 99;
+    width: 100%;
+    min-width: 200px;
+    min-height: 340px;
+    padding: 8px 4px;
+    overflow: hidden;
+    overflow-y: auto;
+    color: rgba(0, 0, 0, 0.88);
+    font-size: 14px;
+    background-color: white;
+    border-radius: 2px;
+    box-shadow: 0 4px 18px rgba(0, 0, 0, 0.27);
+    .select-box {
+      padding: 4px;
+      .select-box-header-top {
+        width: 100%;
+        overflow-x: auto;
+        border-bottom: 1px solid #f0f0f0;
+        .select-box-header {
+          display: flex;
+          justify-content: flex-start;
+          justify-items: center;
+          width: max-content;
+          .select-header-title {
+            padding: 7px 14px;
+            overflow: hidden;
+            color: #999;
+            font-weight: 500;
+            font-size: 16px;
+            white-space: nowrap;
+            cursor: pointer;
+            &.active {
+              color: #323130;
+              border-bottom: 2px solid #2f54eb;
+            }
+          }
+        }
+
+        &::-webkit-scrollbar {
+          width: 0;
+        }
+      }
+      .select-box-content {
+        width: 100%;
+      }
+    }
+  }
+}

+ 112 - 0
src/pages/rule-engine/Scene/Save/components/ParamsSelect/index.tsx

@@ -0,0 +1,112 @@
+import { DownOutlined } from '@ant-design/icons';
+import { Input } from 'antd';
+import { useState, useEffect, useRef, ReactNode } from 'react';
+import './index.less';
+import classNames from 'classnames';
+import { InputProps } from 'antd/lib/input/Input';
+
+export interface ItemProps {
+  key: string;
+  label: string;
+  content: ReactNode;
+}
+
+interface Props {
+  placeholder?: string;
+  value: any;
+  onChange: (dt: any) => void;
+  inputProps?: InputProps;
+  itemList: ItemProps[];
+  style?: object;
+  tabKey: string;
+}
+
+export default (props: Props) => {
+  const [visible, setVisible] = useState<boolean>(false);
+  const [tabKey, setTabKey] = useState<string>(props?.tabKey || props.itemList[0]?.key);
+  const wrapperRef = useRef<any>(null);
+  const nodeRef = useRef<any>(null);
+  const [value, setValue] = useState<any>(props.value);
+  // const [showValue, setShowValue] = useState<string | undefined>('');
+
+  useEffect(() => {
+    setTabKey(props.tabKey);
+  }, [props.tabKey]);
+
+  useEffect(() => {
+    setValue(props.value);
+  }, [props.value]);
+
+  const handleClick = (e: any) => {
+    if (visible && e.target) {
+      if (!(wrapperRef.current && wrapperRef.current.contains(e.target))) {
+        setVisible(false);
+      }
+    }
+  };
+
+  useEffect(() => {
+    window.addEventListener('click', handleClick);
+    return () => {
+      window.removeEventListener('click', handleClick);
+    };
+  });
+
+  // const contentRender = (item: ItemProps | undefined) => {
+  //   switch (item?.type) {
+  //     case 'time-picker':
+  //       return <MTimePicker {...item.children} value={value} onChange={(time: any, timeString: string) => {
+  //         setShowValue(timeString)
+  //         console.log(timeString)
+  //         setValue(time)
+  //       }} />;
+  //     case 'tree':
+  //       return <Tree {...item.children} height={300} defaultExpandAll />
+  //     default:
+  //       return null;
+  //   }
+  // }
+
+  return (
+    <div className={'select-wrapper'} ref={wrapperRef} style={props.style}>
+      <Input
+        suffix={<DownOutlined style={{ color: 'rgba(0, 0, 0, 0.25)' }} />}
+        {...props.inputProps}
+        value={value}
+        onFocus={() => {
+          setVisible(true);
+        }}
+      />
+      {visible && (
+        <div className={'select-container'} ref={nodeRef}>
+          <div className={'select-box'}>
+            <div className={'select-box-header-top'}>
+              <div className={'select-box-header'}>
+                {(props.itemList || []).map((item) => (
+                  <div
+                    key={item.key}
+                    className={classNames(
+                      'select-header-title',
+                      item.key === tabKey ? 'active' : '',
+                    )}
+                    onClick={() => {
+                      setTabKey(item.key);
+                    }}
+                  >
+                    {item.label}
+                  </div>
+                ))}
+              </div>
+            </div>
+            <div className={'select-box-content'}>
+              {
+                (props?.itemList || []).find((item) => item.key === tabKey)?.content || ''
+                // contentRender((props?.itemList || []).find(item => item.key === tabKey))
+              }
+            </div>
+          </div>
+        </div>
+      )}
+    </div>
+  );
+};

+ 79 - 0
src/pages/rule-engine/Scene/Save/device/index.tsx

@@ -1,8 +1,87 @@
 import Terms from '@/pages/rule-engine/Scene/Save/terms';
+import ParamsSelect, { ItemProps } from '@/pages/rule-engine/Scene/Save/components/ParamsSelect';
+import { useState } from 'react';
+import { DataNode } from 'antd/es/tree';
+import { Tree } from 'antd';
+import MTimePicker from '../components/ParamsSelect/components/MTimePicker';
 
 export default () => {
+  const [value, setValue] = useState<any>(null);
+  const treeData: DataNode[] = [
+    {
+      title: 'parent 1',
+      key: '0-0',
+      children: [
+        {
+          title: 'parent 1-0',
+          key: '0-0-0',
+          children: [
+            {
+              title: 'leaf',
+              key: '0-0-0-0',
+            },
+            {
+              title: 'leaf',
+              key: '0-0-0-1',
+            },
+          ],
+        },
+        {
+          title: 'parent 1-1',
+          key: '0-0-1',
+          children: [{ title: 'sss', key: '0-0-1-0' }],
+        },
+      ],
+    },
+  ];
+  const [showValue, setShowValue] = useState<any>('');
+  const itemList: ItemProps[] = [
+    {
+      label: `手动输入`,
+      key: 'manual',
+      content: (
+        <MTimePicker
+          value={value}
+          onChange={(time: any, timeString: string) => {
+            setShowValue(timeString);
+            setValue(time);
+          }}
+        />
+      ),
+    },
+    {
+      label: `内置参数`,
+      key: 'built-in',
+      content: (
+        <Tree
+          treeData={treeData}
+          height={300}
+          defaultExpandAll
+          onSelect={(selectedKeys) => {
+            setValue(selectedKeys[0]);
+            setShowValue(selectedKeys[0]);
+          }}
+        />
+      ),
+    },
+  ];
+
   return (
     <div>
+      <div>
+        <ParamsSelect
+          style={{ width: 250 }}
+          inputProps={{
+            placeholder: '请选择',
+          }}
+          tabKey={'manual'}
+          itemList={itemList}
+          value={showValue}
+          onChange={(val: any) => {
+            setValue(val.timeString);
+          }}
+        />
+      </div>
       <Terms />
     </div>
   );