Procházet zdrojové kódy

Merge branch 'next' of github.com:jetlinks/jetlinks-ui-antd into next-wzy

wzyyy před 3 roky
rodič
revize
6cab5cc5c4
42 změnil soubory, kde provedl 619 přidání a 308 odebrání
  1. 53 0
      src/components/Ellipsis/index.less
  2. 104 0
      src/components/Ellipsis/index.tsx
  3. 5 6
      src/components/ProTableCard/CardItems/AccessConfig/index.less
  4. 46 27
      src/components/ProTableCard/CardItems/AccessConfig/index.tsx
  5. 24 17
      src/components/ProTableCard/CardItems/AlarmConfig.tsx
  6. 19 16
      src/components/ProTableCard/CardItems/Stream/index.tsx
  7. 7 4
      src/components/ProTableCard/CardItems/aliyun.tsx
  8. 17 12
      src/components/ProTableCard/CardItems/cascade.tsx
  9. 27 21
      src/components/ProTableCard/CardItems/device.tsx
  10. 15 13
      src/components/ProTableCard/CardItems/duerOs.tsx
  11. 11 6
      src/components/ProTableCard/CardItems/mediaDevice.tsx
  12. 9 7
      src/components/ProTableCard/CardItems/networkCard.tsx
  13. 18 13
      src/components/ProTableCard/CardItems/noticeConfig.tsx
  14. 15 13
      src/components/ProTableCard/CardItems/noticeTemplate.tsx
  15. 11 21
      src/components/ProTableCard/CardItems/product.tsx
  16. 17 15
      src/components/ProTableCard/CardItems/protocol.tsx
  17. 3 2
      src/components/ProTableCard/CardItems/ruleInstance.tsx
  18. 9 7
      src/components/ProTableCard/CardItems/scene.tsx
  19. 0 2
      src/components/ProTableCard/index.less
  20. 9 3
      src/components/SearchComponent/index.tsx
  21. 1 0
      src/components/index.ts
  22. 0 1
      src/pages/demo/AMap/index.tsx
  23. 46 22
      src/pages/device/Instance/Detail/Info/index.tsx
  24. 32 14
      src/pages/device/Instance/Detail/index.tsx
  25. 33 11
      src/pages/device/Product/Detail/Access/index.tsx
  26. 24 12
      src/pages/device/Product/Detail/BaseInfo/index.tsx
  27. 15 8
      src/pages/device/Product/Detail/index.tsx
  28. 1 0
      src/pages/device/Product/typings.d.ts
  29. 1 5
      src/pages/link/AccessConfig/Detail/Access/index.less
  30. 19 12
      src/pages/link/AccessConfig/Detail/Access/index.tsx
  31. 8 9
      src/pages/link/AccessConfig/Detail/Media/SipSelectComponent/index.tsx
  32. 1 1
      src/pages/notice/Template/Detail/index.tsx
  33. 1 0
      src/pages/notice/Template/index.tsx
  34. 4 0
      src/pages/rule-engine/Scene/Save/action/action.tsx
  35. 2 2
      src/pages/rule-engine/Scene/Save/trigger/index.tsx
  36. 4 0
      src/pages/rule-engine/Scene/TriggerTerm/index.tsx
  37. 1 1
      src/pages/system/Department/Assets/deivce/bind.tsx
  38. 1 0
      src/pages/system/Department/Assets/deivce/index.tsx
  39. 1 0
      src/pages/system/Department/Assets/product/index.tsx
  40. 3 5
      src/pages/system/Department/Tree/tree.tsx
  41. 1 0
      src/pages/system/Menu/Detail/buttons.tsx
  42. 1 0
      src/pages/system/Menu/Detail/edit.tsx

+ 53 - 0
src/components/Ellipsis/index.less

@@ -0,0 +1,53 @@
+.ellipsis-warp {
+  position: relative;
+  width: 100%;
+  white-space: normal;
+}
+
+.ellipsis-max {
+  position: absolute;
+  top: -9999999999px;
+  left: 0;
+  z-index: -200;
+  width: max-content;
+}
+
+.ellipsis-title {
+  width: 100%;
+}
+
+.ellipsis {
+  display: -webkit-box;
+  overflow: hidden;
+  text-align: left;
+  text-overflow: ellipsis;
+  word-break: break-all;
+}
+
+.ellipsis-1 {
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 1;
+}
+
+.ellipsis-2 {
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 2;
+}
+
+.ellipsis-3 {
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 3;
+}
+
+.ellipsis-4 {
+  -webkit-box-orient: vertical;
+  -webkit-line-clamp: 4;
+}
+
+//.ellipsis-70 {
+//  width: 70%;
+//  overflow: hidden;
+//  white-space: nowrap;
+//  text-align: left;
+//  text-overflow: ellipsis;
+//}

+ 104 - 0
src/components/Ellipsis/index.tsx

@@ -0,0 +1,104 @@
+import React, { useState, useRef, useEffect } from 'react';
+import { unmountComponentAtNode } from 'react-dom';
+import { useSize } from 'ahooks';
+import Style from './index.less';
+import classnames from 'classnames';
+import { Tooltip } from 'antd';
+import type { TooltipProps } from 'antd';
+
+interface EllipsisProps {
+  title?: string | number;
+  maxWidth?: string | number;
+  /**
+   * 用于max-width的情况
+   */
+  limitWidth?: number;
+  style?: React.CSSProperties;
+  titleStyle?: React.CSSProperties;
+  titleClassName?: string;
+  showToolTip?: boolean;
+  tooltip?: Omit<TooltipProps, 'title'>;
+  /**
+   * @default 1
+   */
+  row?: 1 | 2 | 3 | 4;
+}
+
+export default (props: EllipsisProps) => {
+  const parentNode = useRef<HTMLDivElement | null>(null);
+  const extraNode = useRef<HTMLDivElement | null>(null);
+  const titleNode = useRef<HTMLDivElement | null>(null);
+  const extraSize = useSize(extraNode.current);
+  const [isEllipsis, setIsEllipsis] = useState(false);
+  // const [show, setShow] = useState(false);
+
+  useEffect(() => {
+    if (extraNode.current && props.title) {
+      extraNode.current.innerHTML = props.title as string;
+      extraNode.current.setAttribute('style', 'display: block');
+    }
+  }, [props.title, extraNode.current]);
+
+  useEffect(() => {
+    if (extraNode.current && parentNode.current) {
+      const extraWidth = window.getComputedStyle(extraNode.current).getPropertyValue('width');
+      const parentWidth = window.getComputedStyle(parentNode.current).getPropertyValue('width');
+      const extraWidthNumber = extraWidth ? Number(extraWidth.replace('px', '')) : 0;
+      const parentWidthNumber = parentWidth ? Number(parentWidth.replace('px', '')) : 0;
+
+      // console.log(extraWidthNumber, parentWidthNumber, props.title)
+      if (extraWidthNumber && parentWidthNumber) {
+        const _width = props.limitWidth
+          ? props.limitWidth * (props.row || 1)
+          : parentWidthNumber * (props.row || 1);
+        console.log(extraSize.width, _width, props.title);
+        if (extraWidthNumber >= _width) {
+          setIsEllipsis(true);
+        } else {
+          setIsEllipsis(false);
+        }
+        if (extraNode.current) {
+          unmountComponentAtNode(extraNode.current);
+          extraNode.current.innerHTML = '';
+          extraNode.current.setAttribute('style', 'display: none');
+        }
+      }
+    }
+  }, [extraSize, extraNode.current]);
+
+  const ellipsisTitleClass = `ellipsis-${props.row || 1}`;
+
+  const ellipsisNode = (
+    <div
+      ref={titleNode}
+      className={classnames(
+        'ellipsis-title',
+        Style.ellipsis,
+        Style[ellipsisTitleClass],
+        props.titleClassName,
+      )}
+      style={{ ...props.titleStyle, width: props.maxWidth || '100%' }}
+    >
+      {props.title}
+    </div>
+  );
+
+  return (
+    <div className={Style['ellipsis-warp']} style={props.style} ref={parentNode}>
+      {isEllipsis && props.showToolTip !== false ? (
+        <Tooltip {...props.tooltip} title={props.title}>
+          {ellipsisNode}
+        </Tooltip>
+      ) : (
+        ellipsisNode
+      )}
+      <div
+        className={classnames(props.titleClassName?.replace('ellipsis', ''), Style['ellipsis-max'])}
+        style={{ ...props.titleStyle, width: 'max-content !important' }}
+        ref={extraNode}
+      >
+        {props.title}
+      </div>
+    </div>
+  );
+};

+ 5 - 6
src/components/ProTableCard/CardItems/AccessConfig/index.less

@@ -37,7 +37,6 @@
 
       .header {
         .access-title {
-          width: calc(100% - 70px);
           font-weight: 700;
           font-size: 18px;
         }
@@ -81,19 +80,19 @@
 
         .procotol {
           .desc {
-            width: 100%;
-            overflow: hidden;
+            //width: 100%;
+            //overflow: hidden;
             color: #666;
             font-weight: 400;
             font-size: 12px;
-            white-space: nowrap;
-            text-overflow: ellipsis;
+            //white-space: nowrap;
+            //text-overflow: ellipsis;
           }
         }
       }
 
       .desc {
-        width: 100%;
+        //width: 100%;
         margin-right: 10px;
         margin-bottom: 10px;
         color: #666;

+ 46 - 27
src/components/ProTableCard/CardItems/AccessConfig/index.tsx

@@ -1,6 +1,6 @@
 import React from 'react';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import { Badge, Tooltip } from 'antd';
 import type { AccessItem } from '@/pages/link/AccessConfig/typings';
@@ -40,10 +40,13 @@ export default (props: AccessConfigCardProps) => {
         </div>
         <div className="card">
           <div className="header">
-            <div className="access-title ellipsis">
-              <Tooltip placement="topLeft" title={props.name}>
-                {props.name}
-              </Tooltip>
+            {/*<div className="access-title ellipsis">*/}
+            {/*  <Tooltip placement="topLeft" title={props.name}>*/}
+            {/*    {props.name}*/}
+            {/*  </Tooltip>*/}
+            {/*</div>*/}
+            <div style={{ width: 'calc(100% - 70px)' }} className={'access-title'}>
+              <Ellipsis title={props.name} />
             </div>
           </div>
           {(props.protocolDetail?.name || props?.channelInfo?.name) && (
@@ -79,34 +82,50 @@ export default (props: AccessConfigCardProps) => {
                 <div className="procotol">
                   <div className="subTitle">协议</div>
                   <div className="desc">
-                    <Tooltip placement="topLeft" title={props.protocolDetail?.name}>
-                      {props.protocolDetail?.name}
-                    </Tooltip>
+                    <Ellipsis
+                      title={props.protocolDetail?.name}
+                      tooltip={{ placement: 'topLeft' }}
+                    />
+                    {/*<Tooltip placement="topLeft" title={props.protocolDetail?.name}>*/}
+                    {/*  {props.protocolDetail?.name}*/}
+                    {/*</Tooltip>*/}
                   </div>
                 </div>
               )}
             </div>
           )}
-          <div className="desc ellipsis">
-            {!!props?.description ? (
-              <Tooltip placement="topLeft" title={props?.description}>
-                {props?.description}
-              </Tooltip>
-            ) : (
-              <Tooltip
-                placement="topLeft"
-                title={
-                  (Store.get('access-providers') || []).find((i: any) => i?.id === props?.provider)
+          <Ellipsis
+            title={
+              !!props?.description
+                ? props?.description
+                : (Store.get('access-providers') || []).find((i: any) => i?.id === props?.provider)
                     ?.description
-                }
-              >
-                {
-                  (Store.get('access-providers') || []).find((i: any) => i?.id === props?.provider)
-                    ?.description
-                }
-              </Tooltip>
-            )}
-          </div>
+            }
+            tooltip={{
+              placement: 'topLeft',
+            }}
+            titleClassName={'desc'}
+          />
+          {/*<div className="desc ellipsis">*/}
+          {/*  {!!props?.description ? (*/}
+          {/*    <Tooltip placement="topLeft" title={props?.description}>*/}
+          {/*      {props?.description}*/}
+          {/*    </Tooltip>*/}
+          {/*  ) : (*/}
+          {/*    <Tooltip*/}
+          {/*      placement="topLeft"*/}
+          {/*      title={*/}
+          {/*        (Store.get('access-providers') || []).find((i: any) => i?.id === props?.provider)*/}
+          {/*          ?.description*/}
+          {/*      }*/}
+          {/*    >*/}
+          {/*      {*/}
+          {/*        (Store.get('access-providers') || []).find((i: any) => i?.id === props?.provider)*/}
+          {/*          ?.description*/}
+          {/*      }*/}
+          {/*    </Tooltip>*/}
+          {/*  )}*/}
+          {/*</div>*/}
         </div>
       </div>
       <div className={'checked-icon'}>

+ 24 - 17
src/components/ProTableCard/CardItems/AlarmConfig.tsx

@@ -1,9 +1,8 @@
 import React from 'react';
-import { PermissionButton, TableCard } from '@/components';
+import { Ellipsis, PermissionButton, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import { Tooltip } from 'antd';
 import { Store } from 'jetlinks-store';
 import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import { useHistory } from 'umi';
@@ -36,9 +35,10 @@ export default (props: AlarmConfigProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>
-              <Tooltip title={props?.name}>{props?.name}</Tooltip>
-            </span>
+            {/*<span className={'card-item-header-name ellipsis'}>*/}
+            {/*  <Tooltip title={props?.name}>{props?.name}</Tooltip>*/}
+            {/*</span>*/}
+            <Ellipsis title={props?.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
@@ -64,19 +64,26 @@ export default (props: AlarmConfigProps) => {
             </div>
             <div>
               <label>告警级别</label>
-              <div className={'ellipsis'}>
-                <Tooltip
-                  title={
-                    (Store.get('default-level') || []).find(
-                      (item: any) => item?.level === props?.level,
-                    )?.title || props?.level
-                  }
-                >
-                  {(Store.get('default-level') || []).find(
+              <Ellipsis
+                title={
+                  (Store.get('default-level') || []).find(
                     (item: any) => item?.level === props?.level,
-                  )?.title || props?.level}
-                </Tooltip>
-              </div>
+                  )?.title || props?.level
+                }
+              />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip*/}
+              {/*    title={*/}
+              {/*      (Store.get('default-level') || []).find(*/}
+              {/*        (item: any) => item?.level === props?.level,*/}
+              {/*      )?.title || props?.level*/}
+              {/*    }*/}
+              {/*  >*/}
+              {/*    {(Store.get('default-level') || []).find(*/}
+              {/*      (item: any) => item?.level === props?.level,*/}
+              {/*    )?.title || props?.level}*/}
+              {/*  </Tooltip>*/}
+              {/*</div>*/}
             </div>
           </div>
         </div>

+ 19 - 16
src/components/ProTableCard/CardItems/Stream/index.tsx

@@ -1,8 +1,7 @@
 import React from 'react';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import './index.less';
-import { Tooltip } from 'antd';
 
 export interface StreamCardProps extends StreamItem {
   detail?: React.ReactNode;
@@ -27,30 +26,34 @@ export default (props: StreamCardProps) => {
         </div>
         <div className="card">
           <div className="header">
-            <div className="stream-title ellipsis">
-              <Tooltip title={props.name}>{props.name}</Tooltip>
-            </div>
+            {/*<div className="stream-title ellipsis">*/}
+            {/*  <Tooltip title={props.name}>{props.name}</Tooltip>*/}
+            {/*</div>*/}
+            <Ellipsis title={props?.name} titleClassName={'stream-title'} />
           </div>
           <div className="container">
             <div>
               <label>服务商</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props?.provider}>{props?.provider}</Tooltip>
-              </div>
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip title={props?.provider}>{props?.provider}</Tooltip>*/}
+              {/*</div>*/}
+              <Ellipsis title={props?.provider} titleClassName={'stream-title'} />
             </div>
             <div>
               <label>RTP IP</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props?.configuration?.rtpIp}>{props?.configuration?.rtpIp}</Tooltip>
-              </div>
+              <Ellipsis title={props?.configuration?.rtpIp} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip title={props?.configuration?.rtpIp}>{props?.configuration?.rtpIp}</Tooltip>*/}
+              {/*</div>*/}
             </div>
             <div>
               <label>API HOST</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props?.configuration?.apiHost}>
-                  {props?.configuration?.apiHost}
-                </Tooltip>
-              </div>
+              <Ellipsis title={props?.configuration?.apiHost} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip title={props?.configuration?.apiHost}>*/}
+              {/*    {props?.configuration?.apiHost}*/}
+              {/*  </Tooltip>*/}
+              {/*</div>*/}
             </div>
           </div>
         </div>

+ 7 - 4
src/components/ProTableCard/CardItems/aliyun.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import { StatusColorEnum } from '@/components/BadgeStatus';
@@ -31,16 +31,19 @@ export default (props: AliyunCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props?.name}</span>
+            <Ellipsis title={props?.name} titleClassName={'card-item-header-name'} />
+            {/*<span className={'card-item-header-name ellipsis'}>{props?.name}</span>*/}
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>网桥产品</label>
-              <div className={'ellipsis'}>{props?.bridgeProductName || ''}</div>
+              <Ellipsis title={props?.bridgeProductName || ''} />
+              {/*<div className={'ellipsis'}>{props?.bridgeProductName || ''}</div>*/}
             </div>
             <div>
               <label>说明</label>
-              <div className={'ellipsis'}>{props?.description || ''}</div>
+              <Ellipsis title={props?.description || ''} />
+              {/*<div className={'ellipsis'}>{props?.description || ''}</div>*/}
             </div>
           </div>
         </div>

+ 17 - 12
src/components/ProTableCard/CardItems/cascade.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import type { CascadeItem } from '@/pages/media/Cascade/typings';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import { Badge } from 'antd';
@@ -32,21 +32,26 @@ export default (props: CascadeCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props.name}</span>
+            {/*<span className={'card-item-header-name ellipsis'}>{props.name}</span>*/}
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div>通道数量: {props?.count || 0}</div>
           <div style={{ display: 'flex', width: '100%' }}>
             <Badge status={props.onlineStatus?.value === 'offline' ? 'error' : 'success'} />
-            <div
-              style={{
-                width: '90%',
-                overflow: 'hidden',
-                whiteSpace: 'nowrap',
-                textOverflow: 'ellipsis',
-              }}
-            >
-              sip:{props.sipConfigs[0]?.sipId}@{props.sipConfigs[0]?.hostAndPort}
-            </div>
+            {/*<div*/}
+            {/*  style={{*/}
+            {/*    width: '90%',*/}
+            {/*    overflow: 'hidden',*/}
+            {/*    whiteSpace: 'nowrap',*/}
+            {/*    textOverflow: 'ellipsis',*/}
+            {/*  }}*/}
+            {/*>*/}
+            {/*  sip:{props.sipConfigs[0]?.sipId}@{props.sipConfigs[0]?.hostAndPort}*/}
+            {/*</div>*/}
+            <Ellipsis
+              title={`sip:${props.sipConfigs[0]?.sipId}@${props.sipConfigs[0]?.hostAndPort}`}
+              maxWidth={'90%'}
+            />
           </div>
         </div>
       </div>

+ 27 - 21
src/components/ProTableCard/CardItems/device.tsx

@@ -1,11 +1,10 @@
 import React, { useState } from 'react';
 import type { DeviceInstance } from '@/pages/device/Instance/typings';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import { TableCard } from '@/components';
+import { TableCard, Ellipsis } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import { CheckOutlined } from '@ant-design/icons';
-import { Tooltip } from 'antd';
 
 export interface DeviceCardProps extends Partial<DeviceInstance> {
   detail?: React.ReactNode;
@@ -67,34 +66,36 @@ export const ExtraDeviceCard = (props: DeviceCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <div className={'card-item-header-name'}>
-              <Tooltip title={props.name}>
-                <div className={'ellipsis'}>{props.name}</div>
-              </Tooltip>
-            </div>
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content-flex'}>
             <div className={'flex-auto'}>
               <label>ID</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props.id}>{props.id || ''}</Tooltip>
-              </div>
+              <Ellipsis title={props.id || ''} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip title={props.id}>{props.id || ''}</Tooltip>*/}
+              {/*</div>*/}
             </div>
             {props.cardType === 'bind' ? (
               <div className={'flex-auto'}>
                 <label>说明</label>
-                <Tooltip title={props.describe}>
-                  <div className={'ellipsis'}>{props.describe}</div>
-                </Tooltip>
+                <Ellipsis title={props.describe || ''} titleClassName={'ellipsis'} />
+                {/*<Tooltip title={props.describe}>*/}
+                {/*  <div className={'ellipsis'}>{props.describe}</div>*/}
+                {/*</Tooltip>*/}
               </div>
             ) : (
               <div className={'flex-auto'}>
                 <label>资产权限</label>
-                <div className={'ellipsis'}>
-                  <Tooltip title={handlePermissionsMap(props.grantedPermissions)}>
-                    {handlePermissionsMap(props.grantedPermissions)}
-                  </Tooltip>
-                </div>
+                <Ellipsis
+                  title={handlePermissionsMap(props.grantedPermissions)}
+                  titleClassName={'ellipsis'}
+                />
+                {/*<div className={'ellipsis'}>*/}
+                {/*  <Tooltip title={handlePermissionsMap(props.grantedPermissions)}>*/}
+                {/*    {handlePermissionsMap(props.grantedPermissions)}*/}
+                {/*  </Tooltip>*/}
+                {/*</div>*/}
               </div>
             )}
           </div>
@@ -128,16 +129,21 @@ export default (props: DeviceCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props.name}</span>
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>设备类型</label>
-              <div className={'ellipsis'}>{props.deviceType ? props.deviceType.text : ''}</div>
+              <Ellipsis
+                title={props.deviceType ? props.deviceType.text : ''}
+                titleClassName={'ellipsis'}
+              />
+              {/*<div className={'ellipsis'}>{props.deviceType ? props.deviceType.text : ''}</div>*/}
             </div>
             <div>
               <label>产品名称</label>
-              <div className={'ellipsis'}>{props.productName || ''}</div>
+              <Ellipsis title={props.productName} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>{props.productName || ''}</div>*/}
             </div>
           </div>
         </div>

+ 15 - 13
src/components/ProTableCard/CardItems/duerOs.tsx

@@ -1,8 +1,7 @@
 import React from 'react';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
-import { Tooltip } from 'antd';
 import { DuerOSItem } from '@/pages/cloud/DuerOS/typings';
 import { StatusColorEnum } from '@/components/BadgeStatus';
 
@@ -34,24 +33,27 @@ export default (props: DuerOSProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>
-              <Tooltip title={props?.name} placement="topLeft">
-                {props?.name}
-              </Tooltip>
-            </span>
+            <Ellipsis title={props?.name} titleClassName={'card-item-header-name'} />
+            {/*<span className={'card-item-header-name ellipsis'}>*/}
+            {/*  <Tooltip title={props?.name} placement="topLeft">*/}
+            {/*    {props?.name}*/}
+            {/*  </Tooltip>*/}
+            {/*</span>*/}
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>产品</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props?.productName || ''}>{props?.productName || ''}</Tooltip>
-              </div>
+              <Ellipsis title={props?.productName || ''} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip title={props?.productName || ''}>{props?.productName || ''}</Tooltip>*/}
+              {/*</div>*/}
             </div>
             <div>
               <label>设备类型</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props.applianceType?.text}>{props.applianceType?.text}</Tooltip>
-              </div>
+              <Ellipsis title={props.applianceType?.text} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip title={props.applianceType?.text}>{props.applianceType?.text}</Tooltip>*/}
+              {/*</div>*/}
             </div>
           </div>
         </div>

+ 11 - 6
src/components/ProTableCard/CardItems/mediaDevice.tsx

@@ -1,7 +1,7 @@
 import React from 'react';
 import type { DeviceItem } from '@/pages/media/Device/typings';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 
@@ -33,24 +33,29 @@ export default (props: ProductCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props.name}</span>
+            {/*<span className={'card-item-header-name ellipsis'}>{props.name}</span>*/}
+            <Ellipsis title={props?.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>厂商</label>
-              <div className={'ellipsis'}>{props.manufacturer || ''}</div>
+              <Ellipsis title={props?.manufacturer} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>{props.manufacturer || ''}</div>*/}
             </div>
             <div>
               <label>通道数量</label>
-              <div className={'ellipsis'}>{props.channelNumber || 0}</div>
+              <Ellipsis title={props?.channelNumber} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>{props.channelNumber || 0}</div>*/}
             </div>
             <div>
               <label>型号</label>
-              <div className={'ellipsis'}>{props.model || ''}</div>
+              <Ellipsis title={props?.model} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>{props.model || ''}</div>*/}
             </div>
             <div>
               <label>接入方式</label>
-              <div className={'ellipsis'}>{props.provider || ''}</div>
+              <Ellipsis title={props?.provider} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>{props.provider || ''}</div>*/}
             </div>
           </div>
         </div>

+ 9 - 7
src/components/ProTableCard/CardItems/networkCard.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import { NetworkItem } from '@/pages/link/Type/typings';
@@ -64,16 +64,18 @@ export default (props: NoticeCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>
-              <Tooltip title={props.name}>{props.name}</Tooltip>
-            </span>
+            {/*<span className={'card-item-header-name ellipsis'}>*/}
+            {/*  <Tooltip title={props.name}>{props.name}</Tooltip>*/}
+            {/*</span>*/}
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>类型</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props?.type}>{props.type}</Tooltip>
-              </div>
+              <Ellipsis title={props?.type} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip title={props?.type}>{props.type}</Tooltip>*/}
+              {/*</div>*/}
             </div>
             <div>
               <label>详情</label>

+ 18 - 13
src/components/ProTableCard/CardItems/noticeConfig.tsx

@@ -1,9 +1,8 @@
 import React from 'react';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import { imgMap, typeList } from './noticeTemplate';
-import { Tooltip } from 'antd';
 
 export interface NoticeCardProps extends ConfigItem {
   detail?: React.ReactNode;
@@ -20,24 +19,30 @@ export default (props: NoticeCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>
-              <Tooltip placement="topLeft" title={props.name}>
-                {props.name}
-              </Tooltip>
-            </span>
+            {/*<span className={'card-item-header-name ellipsis'}>*/}
+            {/*  <Tooltip placement="topLeft" title={props.name}>*/}
+            {/*    {props.name}*/}
+            {/*  </Tooltip>*/}
+            {/*</span>*/}
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>通知方式</label>
-              <div className={'ellipsis'}>{typeList[props.type][props.provider] || '暂无'}</div>
+              <Ellipsis
+                title={typeList[props.type][props.provider] || '暂无'}
+                titleClassName={'ellipsis'}
+              />
+              {/*<div className={'ellipsis'}>{typeList[props.type][props.provider] || '暂无'}</div>*/}
             </div>
             <div>
               <label>说明</label>
-              <div className={'ellipsis'}>
-                <Tooltip placement="topLeft" title={props.description}>
-                  {props.description}
-                </Tooltip>
-              </div>
+              <Ellipsis title={props.description} titleClassName={'ellipsis'} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip placement="topLeft" title={props.description}>*/}
+              {/*    {props.description}*/}
+              {/*  </Tooltip>*/}
+              {/*</div>*/}
             </div>
           </div>
         </div>

+ 15 - 13
src/components/ProTableCard/CardItems/noticeTemplate.tsx

@@ -1,8 +1,7 @@
 import React from 'react';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
-import { Tooltip } from 'antd';
 
 export interface NoticeCardProps extends TemplateItem {
   detail?: React.ReactNode;
@@ -65,24 +64,27 @@ export default (props: NoticeCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>
-              <Tooltip placement="topLeft" title={props.name}>
-                {props.name}
-              </Tooltip>
-            </span>
+            {/*<span className={'card-item-header-name ellipsis'}>*/}
+            {/*  <Tooltip placement="topLeft" title={props.name}>*/}
+            {/*    {props.name}*/}
+            {/*  </Tooltip>*/}
+            {/*</span>*/}
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>通知方式</label>
-              <div className={'ellipsis'}>{typeList[props.type][props.provider] || '暂无'}</div>
+              <Ellipsis title={typeList[props.type][props.provider] || '暂无'} />
+              {/*<div className={'ellipsis'}>{typeList[props.type][props.provider] || '暂无'}</div>*/}
             </div>
             <div>
               <label>说明</label>
-              <div className={'ellipsis'}>
-                <Tooltip placement="topLeft" title={props.description}>
-                  {props.description}
-                </Tooltip>
-              </div>
+              <Ellipsis tooltip={{ placement: 'topLeft' }} title={props.description} />
+              {/*<div className={'ellipsis'}>*/}
+              {/*  <Tooltip placement="topLeft" title={props.description}>*/}
+              {/*    {props.description}*/}
+              {/*  </Tooltip>*/}
+              {/*</div>*/}
             </div>
           </div>
         </div>

+ 11 - 21
src/components/ProTableCard/CardItems/product.tsx

@@ -2,10 +2,9 @@ import React, { useState } from 'react';
 import type { ProductItem } from '@/pages/device/Product/typings';
 import { StatusColorEnum } from '@/components/BadgeStatus';
 import { useIntl } from 'umi';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
-import { Tooltip } from 'antd';
 import { CheckOutlined } from '@ant-design/icons';
 
 export interface ProductCardProps extends Partial<ProductItem> {
@@ -74,11 +73,7 @@ export const ExtraProductCard = (props: ProductCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <div className={'card-item-header-name'}>
-              <Tooltip title={props.name}>
-                <div className={'ellipsis'}>{props.name}</div>
-              </Tooltip>
-            </div>
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content-items'} style={{ display: 'flex', gap: 12 }}>
             {props.content}
@@ -86,25 +81,20 @@ export const ExtraProductCard = (props: ProductCardProps) => {
           <div className={'card-item-content-flex'}>
             <div className={'flex-auto'}>
               <label>ID</label>
-              <div className={'ellipsis'}>
-                <Tooltip title={props.id}>{props.id || ''}</Tooltip>
-              </div>
+              <Ellipsis title={props.id || ''} titleClassName={'ellipsis'} />
             </div>
             {props.cardType === 'bind' ? (
               <div className={'flex-auto'}>
                 <label>说明</label>
-                <Tooltip title={props.describe}>
-                  <div className={'ellipsis'}>{props.describe}</div>
-                </Tooltip>
+                <Ellipsis title={props.describe} titleClassName={'ellipsis'} />
               </div>
             ) : (
               <div className={'flex-auto'}>
                 <label>资产权限</label>
-                <div className={'ellipsis'}>
-                  <Tooltip title={handlePermissionsMap(props.grantedPermissions)}>
-                    {handlePermissionsMap(props.grantedPermissions)}
-                  </Tooltip>
-                </div>
+                <Ellipsis
+                  title={handlePermissionsMap(props.grantedPermissions)}
+                  titleClassName={'ellipsis'}
+                />
               </div>
             )}
           </div>
@@ -141,16 +131,16 @@ export default (props: ProductCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props.name}</span>
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>设备类型</label>
-              <div className={'ellipsis'}>{props?.deviceType?.text}</div>
+              <Ellipsis title={props?.deviceType?.text} titleClassName={'ellipsis'} />
             </div>
             <div>
               <label>接入方式</label>
-              <div className={'ellipsis'}>{props.protocolName || '未接入'}</div>
+              <Ellipsis title={props.protocolName || '未接入'} titleClassName={'ellipsis'} />
             </div>
           </div>
         </div>

+ 17 - 15
src/components/ProTableCard/CardItems/protocol.tsx

@@ -1,10 +1,10 @@
 import React from 'react';
 import type { ProtocolItem } from '@/pages/link/Protocol/typings';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
-import { Col, Row, Tooltip } from 'antd';
+import { Col, Row } from 'antd';
 
 export interface ProcotolCardProps extends ProtocolItem {
   detail?: React.ReactNode;
@@ -32,24 +32,26 @@ export default (props: ProcotolCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <Tooltip title={props.name}>
-              <span className={'card-item-header-name ellipsis'}>{props.name}</span>
-            </Tooltip>
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
+            {/*<Tooltip title={props.name}>*/}
+            {/*  <span className={'card-item-header-name ellipsis'}>{props.name}</span>*/}
+            {/*</Tooltip>*/}
           </div>
           <Row gutter={24}>
             <Col span={12}>
               <div>
                 <div style={{ color: 'rgba(0, 0, 0, 0.75)', fontSize: 12 }}>ID</div>
-                <div
-                  style={{
-                    width: '100%',
-                    overflow: 'hidden',
-                    whiteSpace: 'nowrap',
-                    textOverflow: 'ellipsis',
-                  }}
-                >
-                  <Tooltip title={props.id}>{props.id}</Tooltip>
-                </div>
+                {/*<div*/}
+                {/*  style={{*/}
+                {/*    width: '100%',*/}
+                {/*    overflow: 'hidden',*/}
+                {/*    whiteSpace: 'nowrap',*/}
+                {/*    textOverflow: 'ellipsis',*/}
+                {/*  }}*/}
+                {/*>*/}
+                {/*  <Tooltip title={props.id}>{props.id}</Tooltip>*/}
+                {/*</div>*/}
+                <Ellipsis title={props.id} />
               </div>
             </Col>
             <Col span={12}>

+ 3 - 2
src/components/ProTableCard/CardItems/ruleInstance.tsx

@@ -1,5 +1,5 @@
 import React from 'react';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import { StatusColorEnum } from '@/components/BadgeStatus';
 import '@/style/common.less';
 import type { InstanceItem } from '@/pages/rule-engine/Instance/typings';
@@ -30,7 +30,8 @@ export default (props: RuleInstanceCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>{props.name}</span>
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
+            {/*<span className={'card-item-header-name ellipsis'}>{props.name}</span>*/}
           </div>
           <div className={'card-item-content'}>{props.description}</div>
         </div>

+ 9 - 7
src/components/ProTableCard/CardItems/scene.tsx

@@ -1,10 +1,9 @@
 import React from 'react';
 import { StatusColorEnum } from '@/components/BadgeStatus';
-import { TableCard } from '@/components';
+import { Ellipsis, TableCard } from '@/components';
 import '@/style/common.less';
 import '../index.less';
 import type { SceneItem } from '@/pages/rule-engine/Scene/typings';
-import { Tooltip } from 'antd';
 
 export interface DeviceCardProps extends SceneItem {
   tools: React.ReactNode[];
@@ -37,18 +36,21 @@ export default (props: DeviceCardProps) => {
         </div>
         <div className={'card-item-body'}>
           <div className={'card-item-header'}>
-            <span className={'card-item-header-name ellipsis'}>
-              <Tooltip title={props.name}>{props.name}</Tooltip>
-            </span>
+            {/*<span className={'card-item-header-name ellipsis'}>*/}
+            {/*  <Tooltip title={props.name}>{props.name}</Tooltip>*/}
+            {/*</span>*/}
+            <Ellipsis title={props.name} titleClassName={'card-item-header-name'} />
           </div>
           <div className={'card-item-content'}>
             <div>
               <label>触发方式</label>
-              <div className={'ellipsis'}>{TriggerWayType[props.triggerType]}</div>
+              <Ellipsis title={TriggerWayType[props.triggerType]} />
+              {/*<div className={'ellipsis'}>{TriggerWayType[props.triggerType]}</div>*/}
             </div>
             <div>
               <label>说明</label>
-              <div className={'ellipsis'}>{props.description || ''}</div>
+              <Ellipsis title={props.description} />
+              {/*<div className={'ellipsis'}>{props.description || ''}</div>*/}
             </div>
           </div>
         </div>

+ 0 - 2
src/components/ProTableCard/index.less

@@ -46,7 +46,6 @@
           margin-bottom: 12px;
 
           .card-item-header-name {
-            max-width: 100%;
             font-weight: bold;
             font-size: 16px;
           }
@@ -81,7 +80,6 @@
           }
 
           .ellipsis {
-            max-width: 70%;
             font-weight: bold;
             font-size: 14px;
           }

+ 9 - 3
src/components/SearchComponent/index.tsx

@@ -550,22 +550,28 @@ const SearchComponent = <T extends Record<string, any>>(props: Props<T>) => {
       setExpand(false);
       handleForm(true);
     }
-
+    const params = new URLSearchParams(_location.search);
+    params.delete('q');
+    params.delete('target');
     if (
       (value.terms1 && value.terms1.length && value.terms1?.some((item) => item.value)) ||
       (value.terms2 && value.terms2.length && value.terms2?.some((item) => item.value))
     ) {
       if (type) {
+        params.append('q', JSON.stringify(value));
+        if (props.target) {
+          params.append('target', props.target);
+        }
         _history.push({
           hash: _location.hash,
-          search: `q=${JSON.stringify(value)}&target=${props.target}`,
+          search: '?' + params.toString(),
         });
         // setUrl({ q: JSON.stringify(value), target: props.target });
       }
     } else {
       _history.push({
         hash: _location.hash,
-        search: '?',
+        search: '?' + params.toString(),
       });
     }
     onSearch({ terms: _temp });

+ 1 - 0
src/components/index.ts

@@ -14,3 +14,4 @@ export { default as PathSimplifier } from './AMapComponent/PathSimplifier';
 export { default as Empty } from './Empty';
 export { default as GeoPoint } from './GeoPoint';
 export { default as MetadataJsonInput } from './FormItems/MetadataJsonInput';
+export { default as Ellipsis } from './Ellipsis';

+ 0 - 1
src/pages/demo/AMap/index.tsx

@@ -91,7 +91,6 @@ export default () => {
       <div style={{ position: 'absolute', top: 0 }}>
         <Select
           showSearch
-          allowClear
           options={data}
           filterOption={false}
           onSearch={debounce(onSearch, 300)}

+ 46 - 22
src/pages/device/Instance/Detail/Info/index.tsx

@@ -1,4 +1,4 @@
-import { Card, Descriptions, Tooltip } from 'antd';
+import { Card, Descriptions } from 'antd';
 import { InstanceModel } from '@/pages/device/Instance';
 import moment from 'moment';
 import { observer } from '@formily/react';
@@ -10,7 +10,7 @@ import { useState } from 'react';
 import type { DeviceInstance } from '../../typings';
 import { EditOutlined } from '@ant-design/icons';
 import Tags from '@/pages/device/Instance/Detail/Tags';
-import { PermissionButton } from '@/components';
+import { Ellipsis, PermissionButton } from '@/components';
 import { useDomFullHeight } from '@/hooks';
 
 const Info = observer(() => {
@@ -47,11 +47,17 @@ const Info = observer(() => {
               defaultMessage: '设备ID',
             })}
           >
-            <Tooltip placement="topLeft" title={InstanceModel.detail?.id}>
-              <div className="ellipsis" style={{ maxWidth: 250 }}>
-                {InstanceModel.detail?.id}
-              </div>
-            </Tooltip>
+            <Ellipsis
+              title={InstanceModel.detail?.id}
+              tooltip={{ placement: 'topLeft' }}
+              style={{ maxWidth: 250 }}
+              limitWidth={250}
+            />
+            {/*<Tooltip placement="topLeft" title={InstanceModel.detail?.id}>*/}
+            {/*  <div className="ellipsis" style={{ maxWidth: 250 }}>*/}
+            {/*    {InstanceModel.detail?.id}*/}
+            {/*  </div>*/}
+            {/*</Tooltip>*/}
           </Descriptions.Item>
           <Descriptions.Item
             label={intl.formatMessage({
@@ -59,18 +65,30 @@ const Info = observer(() => {
               defaultMessage: '产品名称',
             })}
           >
-            <Tooltip placement="topLeft" title={InstanceModel.detail?.productName}>
-              <div className="ellipsis" style={{ maxWidth: 250 }}>
-                {InstanceModel.detail?.productName}
-              </div>
-            </Tooltip>
+            <Ellipsis
+              title={InstanceModel.detail?.productName}
+              tooltip={{ placement: 'topLeft' }}
+              style={{ maxWidth: 250 }}
+              limitWidth={250}
+            />
+            {/*<Tooltip placement="topLeft" title={InstanceModel.detail?.productName}>*/}
+            {/*  <div className="ellipsis" style={{ maxWidth: 250 }}>*/}
+            {/*    {InstanceModel.detail?.productName}*/}
+            {/*  </div>*/}
+            {/*</Tooltip>*/}
           </Descriptions.Item>
           <Descriptions.Item label={'产品分类'}>
-            <Tooltip placement="topLeft" title={InstanceModel.detail?.classifiedName}>
-              <div className="ellipsis" style={{ maxWidth: 250 }}>
-                {InstanceModel.detail?.classifiedName}
-              </div>
-            </Tooltip>
+            <Ellipsis
+              title={InstanceModel.detail?.classifiedName}
+              tooltip={{ placement: 'topLeft' }}
+              style={{ maxWidth: 250 }}
+              limitWidth={250}
+            />
+            {/*<Tooltip placement="topLeft" title={InstanceModel.detail?.classifiedName}>*/}
+            {/*  <div className="ellipsis" style={{ maxWidth: 250 }}>*/}
+            {/*    {InstanceModel.detail?.classifiedName}*/}
+            {/*  </div>*/}
+            {/*</Tooltip>*/}
           </Descriptions.Item>
           <Descriptions.Item
             label={intl.formatMessage({
@@ -129,11 +147,17 @@ const Info = observer(() => {
               defaultMessage: '说明',
             })}
           >
-            <Tooltip placement="topLeft" title={InstanceModel.detail?.description}>
-              <div className="ellipsis" style={{ maxWidth: 250 }}>
-                {InstanceModel.detail?.description}
-              </div>
-            </Tooltip>
+            <Ellipsis
+              title={InstanceModel.detail?.description}
+              tooltip={{ placement: 'topLeft' }}
+              style={{ maxWidth: 250 }}
+              limitWidth={250}
+            />
+            {/*<Tooltip placement="topLeft" title={InstanceModel.detail?.description}>*/}
+            {/*  <div className="ellipsis" style={{ maxWidth: 250 }}>*/}
+            {/*    {InstanceModel.detail?.description}*/}
+            {/*  </div>*/}
+            {/*</Tooltip>*/}
           </Descriptions.Item>
         </Descriptions>
         <Config />

+ 32 - 14
src/pages/device/Instance/Detail/index.tsx

@@ -23,7 +23,7 @@ import { Store } from 'jetlinks-store';
 import SystemConst from '@/utils/const';
 import { getMenuPathByCode, getMenuPathByParams, MENUS_CODE } from '@/utils/menu';
 import useSendWebsocketMessage from '@/hooks/websocket/useSendWebsocketMessage';
-import { PermissionButton } from '@/components';
+import { Ellipsis, PermissionButton } from '@/components';
 import { QuestionCircleOutlined } from '@ant-design/icons';
 import Service from '@/pages/device/Instance/service';
 import useLocation from '@/hooks/route/useLocation';
@@ -297,11 +297,17 @@ const InstanceDetail = observer(() => {
       content={
         <Descriptions size="small" column={4}>
           <Descriptions.Item label={'ID'}>
-            <Tooltip placement="topLeft" title={InstanceModel.detail?.id}>
-              <div className="ellipsis" style={{ maxWidth: 250 }}>
-                {InstanceModel.detail?.id}
-              </div>
-            </Tooltip>
+            <Ellipsis
+              title={InstanceModel.detail?.id}
+              tooltip={{ placement: 'topLeft' }}
+              style={{ maxWidth: 250 }}
+              limitWidth={250}
+            />
+            {/*<Tooltip placement="topLeft" title={InstanceModel.detail?.id}>*/}
+            {/*  <div className="ellipsis" style={{ maxWidth: 250 }}>*/}
+            {/*    {InstanceModel.detail?.id}*/}
+            {/*  </div>*/}
+            {/*</Tooltip>*/}
           </Descriptions.Item>
           <Descriptions.Item label={'所属产品'}>
             <PermissionButton
@@ -322,20 +328,32 @@ const InstanceDetail = observer(() => {
                 }
               }}
             >
-              <div className="ellipsis" style={{ width: 250 }}>
-                {InstanceModel.detail?.productName}
-              </div>
+              <Ellipsis
+                title={InstanceModel.detail?.productName}
+                tooltip={{ placement: 'topLeft' }}
+                style={{ maxWidth: 250 }}
+                limitWidth={250}
+              />
+              {/*<div className="ellipsis" style={{ width: 250 }}>*/}
+              {/*  {InstanceModel.detail?.productName}*/}
+              {/*</div>*/}
             </PermissionButton>
           </Descriptions.Item>
         </Descriptions>
       }
       title={
         <div style={{ display: 'flex', alignItems: 'center' }}>
-          <Tooltip placement="topLeft" title={InstanceModel.detail?.name}>
-            <div className="ellipsis" style={{ maxWidth: 250 }}>
-              {InstanceModel.detail?.name}
-            </div>
-          </Tooltip>
+          {/*<Tooltip placement="topLeft" title={InstanceModel.detail?.name}>*/}
+          {/*  <div className="ellipsis" style={{ maxWidth: 250 }}>*/}
+          {/*    {InstanceModel.detail?.name}*/}
+          {/*  </div>*/}
+          {/*</Tooltip>*/}
+          <Ellipsis
+            title={InstanceModel.detail?.name}
+            tooltip={{ placement: 'topLeft' }}
+            style={{ maxWidth: 250 }}
+            limitWidth={250}
+          />
           <Divider type="vertical" />
           <Space>
             {deviceStatus.get(InstanceModel.detail?.state?.value)}

+ 33 - 11
src/pages/device/Product/Detail/Access/index.tsx

@@ -27,6 +27,7 @@ import { onlyMessage } from '@/utils/util';
 import Driver from 'driver.js';
 import 'driver.js/dist/driver.min.css';
 import './index.less';
+import { Ellipsis } from '@/components';
 
 const componentMap = {
   string: 'Input',
@@ -412,6 +413,14 @@ const Access = () => {
           labelAlign: 'left',
           layout: 'vertical',
         },
+        'x-validator': [
+          {
+            required: !!item?.type?.expands?.required,
+            message: `${item.type.type === 'enum' ? '请选择' : '请输入'}${item.name}`,
+          },
+        ],
+        required: !!item?.type?.expands?.required,
+        default: item?.type?.expands?.defaultValue,
         enum:
           item?.type?.type === 'enum' && item?.type?.elements
             ? (item?.type?.elements || []).map((t: { value: string; text: string }) => {
@@ -597,23 +606,36 @@ const Access = () => {
                   }
                 />
                 <div className={styles.context}>
-                  <Tooltip placement="topLeft" title={access?.name}>
-                    <div className="ellipsis-70">{access?.name}</div>
-                  </Tooltip>
+                  {/*<Tooltip placement="topLeft" title={access?.name}>*/}
+                  {/*  <div className="ellipsis-70">{access?.name}</div>*/}
+                  {/*</Tooltip>*/}
+                  <Ellipsis
+                    title={access?.name}
+                    tooltip={{ placement: 'topLeft' }}
+                    maxWidth={'70%'}
+                  />
                 </div>
                 <div className={styles.context}>
-                  <Tooltip
-                    placement="topLeft"
+                  {/*<Tooltip*/}
+                  {/*  placement="topLeft"*/}
+                  {/*  title={*/}
+                  {/*    access?.description ||*/}
+                  {/*    dataSource.find((item) => item?.id === access?.provider)?.description*/}
+                  {/*  }*/}
+                  {/*>*/}
+                  {/*  <div className="ellipsis-70">*/}
+                  {/*    {access?.description ||*/}
+                  {/*      dataSource.find((item) => item?.id === access?.provider)?.description}*/}
+                  {/*  </div>*/}
+                  {/*</Tooltip>*/}
+                  <Ellipsis
                     title={
                       access?.description ||
                       dataSource.find((item) => item?.id === access?.provider)?.description
                     }
-                  >
-                    <div className="ellipsis-70">
-                      {access?.description ||
-                        dataSource.find((item) => item?.id === access?.provider)?.description}
-                    </div>
-                  </Tooltip>
+                    tooltip={{ placement: 'topLeft' }}
+                    maxWidth={'70%'}
+                  />
                 </div>
               </div>
 

+ 24 - 12
src/pages/device/Product/Detail/BaseInfo/index.tsx

@@ -1,11 +1,11 @@
 import { productModel, service } from '@/pages/device/Product';
-import { Button, Descriptions, Tooltip } from 'antd';
+import { Button, Descriptions } from 'antd';
 import { useState } from 'react';
 import { useIntl } from '@@/plugin-locale/localeExports';
 import { EditOutlined } from '@ant-design/icons';
 import { getDateFormat } from '@/utils/util';
 import Save from '@/pages/device/Product/Save';
-import { PermissionButton } from '@/components';
+import { Ellipsis, PermissionButton } from '@/components';
 
 // const componentMap = {
 //   string: 'Input',
@@ -172,11 +172,17 @@ const BaseInfo = (props: BaseInfoProps) => {
         bordered
       >
         <Descriptions.Item label={'ID'}>
-          <Tooltip placement="topLeft" title={productModel.current?.id}>
-            <div className="ellipsis-70" style={{ width: 300 }}>
-              {productModel.current?.id}
-            </div>
-          </Tooltip>
+          <Ellipsis
+            title={productModel.current?.id}
+            tooltip={{ placement: 'topLeft' }}
+            maxWidth={'90%'}
+            style={{ width: 300 }}
+          />
+          {/*<Tooltip placement="topLeft" title={productModel.current?.id}>*/}
+          {/*  <div className="ellipsis-70" style={{ width: 300 }}>*/}
+          {/*    {productModel.current?.id}*/}
+          {/*  </div>*/}
+          {/*</Tooltip>*/}
         </Descriptions.Item>
         <Descriptions.Item
           label={intl.formatMessage({
@@ -184,11 +190,17 @@ const BaseInfo = (props: BaseInfoProps) => {
             defaultMessage: '产品分类',
           })}
         >
-          <Tooltip placement="topLeft" title={productModel.current?.classifiedName}>
-            <div className="ellipsis-70" style={{ width: 300 }}>
-              {productModel.current?.classifiedName}
-            </div>
-          </Tooltip>
+          <Ellipsis
+            title={productModel.current?.classifiedName}
+            tooltip={{ placement: 'topLeft' }}
+            maxWidth={'90%'}
+            style={{ width: 300 }}
+          />
+          {/*<Tooltip placement="topLeft" title={productModel.current?.classifiedName}>*/}
+          {/*  <div className="ellipsis-70" style={{ width: 300 }}>*/}
+          {/*    {productModel.current?.classifiedName}*/}
+          {/*  </div>*/}
+          {/*</Tooltip>*/}
         </Descriptions.Item>
         <Descriptions.Item
           label={intl.formatMessage({

+ 15 - 8
src/pages/device/Product/Detail/index.tsx

@@ -15,7 +15,7 @@ import { getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import encodeQuery from '@/utils/encodeQuery';
 import MetadataMap from '@/pages/device/Instance/Detail/MetadataMap';
 import SystemConst from '@/utils/const';
-import { PermissionButton } from '@/components';
+import { Ellipsis, PermissionButton } from '@/components';
 import { QuestionCircleOutlined } from '@ant-design/icons';
 import { onlyMessage } from '@/utils/util';
 import Parsing from '../../Instance/Detail/Parsing';
@@ -308,8 +308,9 @@ const ProductDetail = observer(() => {
                     type: 'and',
                   };
                   if (url) {
-                    console.log(`${url}?q=${JSON.stringify(searchParams)}`);
-                    history.push(`${url}?q=${JSON.stringify(searchParams)}`);
+                    const params = new URLSearchParams();
+                    params.append('q', JSON.stringify(searchParams));
+                    history.push(`${url}?${params.toString()}`);
                   }
                 }}
               >
@@ -320,11 +321,17 @@ const ProductDetail = observer(() => {
         </Spin>
       }
       title={
-        <Tooltip placement="topLeft" title={productModel.current?.name}>
-          <div className="ellipsis" style={{ maxWidth: 250 }}>
-            {productModel.current?.name}
-          </div>
-        </Tooltip>
+        <Ellipsis
+          title={productModel.current?.name}
+          tooltip={{ placement: 'topLeft' }}
+          style={{ maxWidth: 250 }}
+          limitWidth={250}
+        />
+        // <Tooltip placement="topLeft" title={productModel.current?.name}>
+        //   <div className="ellipsis" style={{ maxWidth: 250 }}>
+        //     {productModel.current?.name}
+        //   </div>
+        // </Tooltip>
       }
       subTitle={
         permission.update ? (

+ 1 - 0
src/pages/device/Product/typings.d.ts

@@ -40,6 +40,7 @@ export type ConfigProperty = {
     id: string;
     type: string;
     elements?: any[];
+    expands?: any;
   };
   scopes: any[];
 };

+ 1 - 5
src/pages/link/AccessConfig/Detail/Access/index.less

@@ -20,7 +20,7 @@
 }
 
 .title {
-  width: 100%;
+  width: calc(100% - 88px);
   overflow: hidden;
   font-weight: 800;
   white-space: nowrap;
@@ -28,14 +28,10 @@
 }
 
 .desc {
-  width: 100%;
   margin-top: 10px;
-  overflow: hidden;
   color: rgba(0, 0, 0, 0.55);
   font-weight: 400;
   font-size: 13px;
-  white-space: nowrap;
-  text-overflow: ellipsis;
 }
 
 .cardContent {

+ 19 - 12
src/pages/link/AccessConfig/Detail/Access/index.tsx

@@ -8,7 +8,7 @@ import ReactMarkdown from 'react-markdown';
 import { getButtonPermission, getMenuPathByCode, MENUS_CODE } from '@/utils/menu';
 import { CheckOutlined, InfoCircleOutlined } from '@ant-design/icons';
 import TitleComponent from '@/components/TitleComponent';
-import { PermissionButton } from '@/components';
+import { Ellipsis, PermissionButton } from '@/components';
 import { useDomFullHeight } from '@/hooks';
 import { onlyMessage } from '@/utils/util';
 import { descriptionList, MetworkTypeMapping, ProcotoleMapping } from './data';
@@ -314,9 +314,10 @@ const Access = (props: Props) => {
                       }}
                     >
                       <div className={styles.title}>
-                        <Tooltip placement="topLeft" title={item.name}>
-                          {item.name}
-                        </Tooltip>
+                        <Ellipsis title={item.name} tooltip={{ placement: 'topLeft' }} />
+                        {/*<Tooltip placement="topLeft" title={item.name}>*/}
+                        {/*  {item.name}*/}
+                        {/*</Tooltip>*/}
                       </div>
                       <div className={styles.cardContent}>
                         <Tooltip
@@ -354,14 +355,20 @@ const Access = (props: Props) => {
                             ))}
                           </div>
                         </Tooltip>
-                        <div className={styles.desc}>
-                          <Tooltip
-                            placement="topLeft"
-                            title={item?.description || descriptionList[props.provider?.id]}
-                          >
-                            {item?.description || descriptionList[props.provider?.id]}
-                          </Tooltip>
-                        </div>
+                        <Ellipsis
+                          title={item?.description || descriptionList[props.provider?.id]}
+                          tooltip={{ placement: 'topLeft' }}
+                          titleClassName={styles.desc}
+                        />
+                        {/*<div className={styles.desc}>*/}
+                        {/*  <Tooltip*/}
+                        {/*    placement="topLeft"*/}
+                        {/*    title={item?.description || descriptionList[props.provider?.id]}*/}
+                        {/*  >*/}
+                        {/*    {item?.description || descriptionList[props.provider?.id]}*/}
+                        {/*  </Tooltip>*/}
+                        {/*  */}
+                        {/*</div>*/}
                       </div>
                       <div className={styles.checkedIcon}>
                         <div>

+ 8 - 9
src/pages/link/AccessConfig/Detail/Media/SipSelectComponent/index.tsx

@@ -21,15 +21,14 @@ const SipSelectComponent = (props: SipSelectComponentProps) => {
   }, [value]);
 
   useEffect(() => {
-    if (!props.type) {
-      setData(value || { host: '0.0.0.0' });
-      if (!value) {
-        const dt: any = props.data.find((i) => i.host === '0.0.0.0');
-        setList(dt?.portList || []);
-      } else {
-        const dt: any = props.data.find((i) => i.host === value.host);
-        setList(dt?.portList || []);
-      }
+    if (!props.type && !value) {
+      setData({ host: '0.0.0.0' });
+      const dt: any = props.data.find((i) => i.host === '0.0.0.0');
+      setList(dt?.portList || []);
+    }
+    if (value) {
+      const dt: any = props.data.find((i) => i.host === value.host);
+      setList(dt?.portList || []);
     }
   }, [props.type]);
 

+ 1 - 1
src/pages/notice/Template/Detail/index.tsx

@@ -1371,7 +1371,7 @@ const Detail = observer(() => {
             </Form>
           </Col>
           <Col span={12} push={2}>
-            {docMap[id][provider]}
+            {docMap?.[id]?.[provider]}
           </Col>
         </Row>
       </Card>

+ 1 - 0
src/pages/notice/Template/index.tsx

@@ -235,6 +235,7 @@ const Template = observer(() => {
               isPermission={templatePermission.add}
               onClick={() => {
                 state.current = undefined;
+                console.log(id);
                 history.push(getMenuPathByParams(MENUS_CODE['notice/Template/Detail'], id));
               }}
               key="button"

+ 4 - 0
src/pages/rule-engine/Scene/Save/action/action.tsx

@@ -174,6 +174,7 @@ export default observer((props: ActionProps) => {
           rules={[{ required: true, message: '请选择通知方式' }]}
         >
           <Select
+            allowClear
             options={messageType}
             fieldNames={{ value: 'id', label: 'name' }}
             placeholder={'请选择通知方式'}
@@ -195,6 +196,7 @@ export default observer((props: ActionProps) => {
           rules={[{ required: true, message: '请选择通知配置' }]}
         >
           <Select
+            allowClear
             options={messageConfig}
             loading={messageConfigLoading}
             fieldNames={{ value: 'id', label: 'name' }}
@@ -216,6 +218,7 @@ export default observer((props: ActionProps) => {
           rules={[{ required: true, message: '请选择通知模板' }]}
         >
           <Select
+            allowClear
             options={messageTemplate}
             loading={messageTemplateLoading}
             fieldNames={{ value: 'id', label: 'name' }}
@@ -295,6 +298,7 @@ export default observer((props: ActionProps) => {
             rules={[{ required: true, message: '请选择执行条件' }]}
           >
             <Select
+              allowClear
               options={
                 !props.parallel
                   ? [

+ 2 - 2
src/pages/rule-engine/Scene/Save/trigger/index.tsx

@@ -67,7 +67,7 @@ export default observer((props: TriggerProps) => {
         newOperator = [...newOperator, { label: '功能调用', value: OperatorEnum.invokeFunction }];
         setFunctions(metadataObj.functions);
       }
-      setOperatorOptions(newOperator);
+      setOperatorOptions(Object.keys(metadataObj).length ? newOperator : undefined);
     } catch (err) {
       console.warn('handleMetadata === ', err);
     }
@@ -154,7 +154,7 @@ export default observer((props: TriggerProps) => {
                 props.form?.resetFields([['trigger', 'device', 'selector']]);
                 props.form?.resetFields([['trigger', 'device', 'selectorValues']]);
                 props.form?.resetFields([['trigger', 'device', 'operation']]);
-                productIdChange(key, node.metadata);
+                productIdChange(key, node?.metadata);
                 setSelector('fixed');
                 props.form?.setFieldsValue({
                   trigger: {

+ 4 - 0
src/pages/rule-engine/Scene/TriggerTerm/index.tsx

@@ -306,6 +306,9 @@ const TriggerTerm = (props: Props, ref: any) => {
                     type: 'string',
                     // "x-decorator": 'FormItem',
                     'x-component': 'FTermTypeSelect',
+                    'x-component-props': {
+                      allowClear: true,
+                    },
                     'x-value': 'and',
                   },
                   layout: {
@@ -328,6 +331,7 @@ const TriggerTerm = (props: Props, ref: any) => {
                         'x-component-props': {
                           placeholder: '请选择参数',
                           fieldNames: { value: 'column', label: 'name', options: 'children' },
+                          allowClear: true,
                           // treeNodeLabelProp: 'name',
                         },
                         'x-reactions': '{{useAsyncDataSource(getParseTerm)}}',

+ 1 - 1
src/pages/system/Department/Assets/deivce/bind.tsx

@@ -134,7 +134,7 @@ const Bind = observer((props: Props) => {
         },
       },
     ];
-    if (Object.keys(params).length) {
+    if (Object.keys(params).length && params.productId) {
       _params.push({
         type: 'and',
         column: 'productId$product-info',

+ 1 - 0
src/pages/system/Department/Assets/deivce/index.tsx

@@ -318,6 +318,7 @@ export default observer((props: { parentId: string }) => {
         search={false}
         params={searchParam}
         gridColumn={2}
+        height={'none'}
         scroll={{ x: 1366 }}
         request={async (params) => {
           params.sorts = [{ name: 'createTime', order: 'desc' }];

+ 1 - 0
src/pages/system/Department/Assets/product/index.tsx

@@ -277,6 +277,7 @@ export default observer((props: { parentId: string }) => {
         search={false}
         gridColumn={2}
         params={searchParam}
+        height={'none'}
         request={async (params) => {
           params.sorts = [{ name: 'createTime', order: 'desc' }];
           if (!props.parentId) {

+ 3 - 5
src/pages/system/Department/Tree/tree.tsx

@@ -1,4 +1,4 @@
-import { Button, Input, Tooltip, Tree } from 'antd';
+import { Button, Input, Tree } from 'antd';
 import {
   DeleteOutlined,
   EditOutlined,
@@ -8,7 +8,7 @@ import {
 } from '@ant-design/icons';
 import { useEffect, useRef, useState } from 'react';
 import { service } from '@/pages/system/Department';
-import { Empty, PermissionButton } from '@/components';
+import { Ellipsis, Empty, PermissionButton } from '@/components';
 import { useIntl, useLocation } from 'umi';
 import { debounce } from 'lodash';
 import Save from '../save';
@@ -234,9 +234,7 @@ export default (props: TreeProps) => {
                   }}
                 >
                   <span className={'tree-node-name--title'}>
-                    <Tooltip title={nodeData.name}>
-                      <span className={'ellipsis'}>{nodeData.name}</span>
-                    </Tooltip>
+                    <Ellipsis title={nodeData.name} />
                   </span>
                   <span
                     className={classnames('tree-node-name--btn', {

+ 1 - 0
src/pages/system/Menu/Detail/buttons.tsx

@@ -340,6 +340,7 @@ export default (props: ButtonsProps) => {
             required={true}
           >
             <Input
+              allowClear
               onChange={debounce(filterThree, 500)}
               style={{ width: 300, marginBottom: 12 }}
               placeholder={'请输入权限名称'}

+ 1 - 0
src/pages/system/Menu/Detail/edit.tsx

@@ -295,6 +295,7 @@ export default (props: EditProps) => {
                   })}
                 >
                   <Input
+                    allowClear
                     onChange={debounce(filterThree, 500)}
                     style={{ width: 300, marginBottom: 12 }}
                     placeholder={'请输入权限名称'}