瀏覽代碼

feat(merge): merge wzy

fix: 列表宽度及内容充满
Lind 3 年之前
父節點
當前提交
f2c9075cac
共有 34 個文件被更改,包括 235 次插入146 次删除
  1. 二進制
      public/images/jar.png
  2. 二進制
      public/images/local.png
  3. 11 3
      src/app.tsx
  4. 7 3
      src/components/ProTableCard/CardItems/AccessConfig/index.tsx
  5. 1 1
      src/components/ProTableCard/CardItems/networkCard.tsx
  6. 3 3
      src/components/ProTableCard/CardItems/product.tsx
  7. 2 2
      src/components/ProTableCard/CardItems/protocol.tsx
  8. 1 1
      src/components/ProTableCard/CardItems/scene.tsx
  9. 1 1
      src/components/RadioCard/index.less
  10. 3 1
      src/locales/zh-CN/pages.ts
  11. 1 5
      src/pages/device/Category/index.tsx
  12. 10 10
      src/pages/device/Instance/Detail/Diagnose/Status/index.tsx
  13. 2 0
      src/pages/device/Instance/Detail/Running/Event/index.tsx
  14. 1 1
      src/pages/device/Instance/index.tsx
  15. 22 15
      src/pages/device/Product/Detail/Access/AccessConfig/index.tsx
  16. 6 6
      src/pages/device/Product/Detail/index.tsx
  17. 1 1
      src/pages/device/Product/Save/index.tsx
  18. 12 12
      src/pages/device/Product/index.tsx
  19. 5 2
      src/pages/link/AccessConfig/Detail/Access/index.tsx
  20. 2 2
      src/pages/link/AccessConfig/index.tsx
  21. 1 7
      src/pages/link/Certificate/index.tsx
  22. 2 2
      src/pages/link/Channel/Opcua/index.tsx
  23. 14 3
      src/pages/link/Protocol/index.tsx
  24. 52 31
      src/pages/link/Protocol/save/index.tsx
  25. 5 4
      src/pages/link/Type/index.tsx
  26. 33 18
      src/pages/media/Cascade/Save/index.tsx
  27. 1 1
      src/pages/media/Device/Save/index.tsx
  28. 3 1
      src/pages/media/SplitScreen/index.tsx
  29. 1 5
      src/pages/notice/Template/index.tsx
  30. 2 1
      src/pages/rule-engine/Alarm/Configuration/index.tsx
  31. 9 1
      src/pages/rule-engine/Alarm/Log/Detail/Info.tsx
  32. 7 0
      src/pages/rule-engine/Alarm/Log/Detail/index.less
  33. 4 2
      src/pages/system/Basis/index.tsx
  34. 10 1
      src/utils/util.ts

二進制
public/images/jar.png


二進制
public/images/local.png


+ 11 - 3
src/app.tsx

@@ -189,7 +189,7 @@ export const request: RequestConfig = {
               .catch(() => {
               .catch(() => {
                 notification.error({
                 notification.error({
                   key: 'error',
                   key: 'error',
-                  message: '系统错误',
+                  message: '系统开小差,请稍后重试',
                 });
                 });
               });
               });
           }
           }
@@ -198,7 +198,7 @@ export const request: RequestConfig = {
     }
     }
     if (!response) {
     if (!response) {
       notification.error({
       notification.error({
-        description: '您的网络发生异常,无法连接服务器',
+        description: '网络异常,请检查网络连接',
         message: '网络异常',
         message: '网络异常',
       });
       });
     }
     }
@@ -226,7 +226,7 @@ const MenuItemIcon = (
 
 
 // ProLayout 支持的api https://procomponents.ant.design/components/layout
 // ProLayout 支持的api https://procomponents.ant.design/components/layout
 export const layout: RunTimeLayoutConfig = ({ initialState }) => {
 export const layout: RunTimeLayoutConfig = ({ initialState }) => {
-  console.log({ ...initialState });
+  // console.log({ ...initialState });
   return {
   return {
     navTheme: 'light',
     navTheme: 'light',
     headerTheme: 'light',
     headerTheme: 'light',
@@ -235,6 +235,14 @@ export const layout: RunTimeLayoutConfig = ({ initialState }) => {
     waterMarkProps: {
     waterMarkProps: {
       // content: initialState?.currentUser?.name,
       // content: initialState?.currentUser?.name,
     },
     },
+    itemRender: (route, _, routes) => {
+      const chilck = routes.indexOf(route) > 1;
+      return chilck && route.path !== '/iot/rule-engine/Alarm' ? (
+        <Link to={route.path}>{route.breadcrumbName}</Link>
+      ) : (
+        <span>{route.breadcrumbName}</span>
+      );
+    },
     footerRender: () => <Footer />,
     footerRender: () => <Footer />,
     onPageChange: () => {
     onPageChange: () => {
       const { location } = history;
       const { location } = history;

+ 7 - 3
src/components/ProTableCard/CardItems/AccessConfig/index.tsx

@@ -25,7 +25,7 @@ export default (props: AccessConfigCardProps) => {
       status={props.state.value}
       status={props.state.value}
       statusText={props.state.text}
       statusText={props.state.text}
       statusNames={{
       statusNames={{
-        enabled: StatusColorEnum.processing,
+        enabled: StatusColorEnum.success,
         disabled: StatusColorEnum.error,
         disabled: StatusColorEnum.error,
       }}
       }}
       showTool={props.showTool}
       showTool={props.showTool}
@@ -39,10 +39,14 @@ export default (props: AccessConfigCardProps) => {
         <div className="card">
         <div className="card">
           <div className="header">
           <div className="header">
             <div className="title ellipsis">
             <div className="title ellipsis">
-              <Tooltip title={props.name}>{props.name || '--'}</Tooltip>
+              <Tooltip title={props.name} placement="topLeft">
+                {props.name || '--'}
+              </Tooltip>
             </div>
             </div>
             <div className="desc">
             <div className="desc">
-              <Tooltip title={props.description}>{props.description || '--'}</Tooltip>
+              <Tooltip title={props.description} placement="topLeft">
+                {props.description || '--'}
+              </Tooltip>
             </div>
             </div>
           </div>
           </div>
           <div className="container">
           <div className="container">

+ 1 - 1
src/components/ProTableCard/CardItems/networkCard.tsx

@@ -50,7 +50,7 @@ export default (props: NoticeCardProps) => {
       statusText={props.state.text}
       statusText={props.state.text}
       statusNames={{
       statusNames={{
         disabled: StatusColorEnum.error,
         disabled: StatusColorEnum.error,
-        enabled: StatusColorEnum.processing,
+        enabled: StatusColorEnum.success,
       }}
       }}
       showMask={false}
       showMask={false}
     >
     >

+ 3 - 3
src/components/ProTableCard/CardItems/product.tsx

@@ -113,12 +113,12 @@ export default (props: ProductCardProps) => {
       actions={props.actions}
       actions={props.actions}
       status={props.state}
       status={props.state}
       statusText={intl.formatMessage({
       statusText={intl.formatMessage({
-        id: `pages.system.tenant.assetInformation.${props.state ? 'published' : 'unpublished'}`,
-        defaultMessage: '已发布',
+        id: `pages.device.product.status.${props.state ? 'enabled' : 'disabled'}`,
+        defaultMessage: '正常',
       })}
       })}
       statusNames={{
       statusNames={{
         0: StatusColorEnum.error,
         0: StatusColorEnum.error,
-        1: StatusColorEnum.processing,
+        1: StatusColorEnum.success,
       }}
       }}
     >
     >
       <div className={'pro-table-card-item'}>
       <div className={'pro-table-card-item'}>

+ 2 - 2
src/components/ProTableCard/CardItems/protocol.tsx

@@ -20,9 +20,9 @@ export default (props: ProcotolCardProps) => {
       showMask={false}
       showMask={false}
       actions={props.actions}
       actions={props.actions}
       status={props.state === 1 ? 'enabled' : 'disabled'}
       status={props.state === 1 ? 'enabled' : 'disabled'}
-      statusText={props.state === 1 ? '已发布' : '未发布'}
+      statusText={props.state === 1 ? '正常' : '禁用'}
       statusNames={{
       statusNames={{
-        enabled: StatusColorEnum.processing,
+        enabled: StatusColorEnum.success,
         disabled: StatusColorEnum.error,
         disabled: StatusColorEnum.error,
       }}
       }}
     >
     >

+ 1 - 1
src/components/ProTableCard/CardItems/scene.tsx

@@ -26,7 +26,7 @@ export default (props: DeviceCardProps) => {
       status={props.state.value}
       status={props.state.value}
       statusText={props.state.text}
       statusText={props.state.text}
       statusNames={{
       statusNames={{
-        started: StatusColorEnum.processing,
+        started: StatusColorEnum.success,
         disable: StatusColorEnum.error,
         disable: StatusColorEnum.error,
         notActive: StatusColorEnum.warning,
         notActive: StatusColorEnum.warning,
       }}
       }}

+ 1 - 1
src/components/RadioCard/index.less

@@ -26,7 +26,7 @@
     }
     }
 
 
     &:not(:last-child) {
     &:not(:last-child) {
-      margin-right: 10px;
+      margin-right: 24px;
     }
     }
 
 
     &:hover,
     &:hover,

+ 3 - 1
src/locales/zh-CN/pages.ts

@@ -192,6 +192,8 @@ export default {
   'pages.device.product.deviceClass': '设备分类',
   'pages.device.product.deviceClass': '设备分类',
   'pages.device.product.status.published': '已发布',
   'pages.device.product.status.published': '已发布',
   'pages.device.product.status.unpublished': '未发布',
   'pages.device.product.status.unpublished': '未发布',
+  'pages.device.product.status.enabled': '正常',
+  'pages.device.product.status.disabled': '禁用',
   'pages.device.product.status.all': '全部',
   'pages.device.product.status.all': '全部',
   'pages.device.productDetail': '产品详情',
   'pages.device.productDetail': '产品详情',
   'pages.device.productDetail.id': '产品ID',
   'pages.device.productDetail.id': '产品ID',
@@ -238,7 +240,7 @@ export default {
   'pages.device.productDetail.setting': '应用配置',
   'pages.device.productDetail.setting': '应用配置',
   'pages.device.productDetail.disable': '停用',
   'pages.device.productDetail.disable': '停用',
   'pages.device.productDetail.enabled': '启用',
   'pages.device.productDetail.enabled': '启用',
-  'pages.device.productDetail.deleteTip': '已发布的产品不能进行删除操作',
+  'pages.device.productDetail.deleteTip': '已启用的产品不能进行删除操作',
 
 
   // 设备管理-设备分类
   // 设备管理-设备分类
   'pages.device.type.device': '直连设备',
   'pages.device.type.device': '直连设备',

+ 1 - 5
src/pages/device/Category/index.tsx

@@ -65,9 +65,7 @@ const Category = observer(() => {
         defaultMessage: '分类名称',
         defaultMessage: '分类名称',
       }),
       }),
       dataIndex: 'name',
       dataIndex: 'name',
-      width: 300,
       ellipsis: true,
       ellipsis: true,
-      fixed: 'left',
     },
     },
     {
     {
       title: '分类排序',
       title: '分类排序',
@@ -94,8 +92,7 @@ const Category = observer(() => {
         defaultMessage: '操作',
         defaultMessage: '操作',
       }),
       }),
       valueType: 'option',
       valueType: 'option',
-      width: 200,
-      fixed: 'right',
+      width: 120,
       render: (text, record) => [
       render: (text, record) => [
         <PermissionButton
         <PermissionButton
           key="editable"
           key="editable"
@@ -182,7 +179,6 @@ const Category = observer(() => {
       <ProTable
       <ProTable
         params={param}
         params={param}
         search={false}
         search={false}
-        scroll={{ x: 1366 }}
         request={async (params) => {
         request={async (params) => {
           const response = await service.queryTree({
           const response = await service.queryTree({
             paging: false,
             paging: false,

+ 10 - 10
src/pages/device/Instance/Detail/Diagnose/Status/index.tsx

@@ -47,13 +47,13 @@ const Status = observer((props: Props) => {
       key: 'product',
       key: 'product',
       name: '产品状态',
       name: '产品状态',
       data: 'product',
       data: 'product',
-      desc: '诊断产品状态是否已发布,未发布的状态将导致连接失败',
+      desc: '诊断产品状态是否正常,禁用状态将导致连接失败',
     },
     },
     {
     {
       key: 'device',
       key: 'device',
       name: '设备状态',
       name: '设备状态',
       data: 'device',
       data: 'device',
-      desc: '诊断设备状态是否已启用,未启用的状态将导致连接失败',
+      desc: '诊断设备状态是否正常,禁用状态将导致连接失败。',
     },
     },
     {
     {
       key: 'device-access',
       key: 'device-access',
@@ -207,7 +207,7 @@ const Status = observer((props: Props) => {
                                 text={
                                 text={
                                   networkPermission.action ? (
                                   networkPermission.action ? (
                                     <span>
                                     <span>
-                                      网络组件未启用, 请
+                                      网络组件已禁用, 请
                                       <Popconfirm
                                       <Popconfirm
                                         title="确认启用"
                                         title="确认启用"
                                         onConfirm={async () => {
                                         onConfirm={async () => {
@@ -229,7 +229,7 @@ const Status = observer((props: Props) => {
                                       网络组件
                                       网络组件
                                     </span>
                                     </span>
                                   ) : (
                                   ) : (
-                                    '网络组件未启用,请联系管理员'
+                                    '网络组件已禁用,请联系管理员'
                                   )
                                   )
                                 }
                                 }
                               />
                               />
@@ -327,9 +327,9 @@ const Status = observer((props: Props) => {
                   text={
                   text={
                     productPermission.action ? (
                     productPermission.action ? (
                       <span>
                       <span>
-                        产品未发布,请
+                        产品已禁用,请
                         <Popconfirm
                         <Popconfirm
-                          title="确认发布"
+                          title="确认启用"
                           onConfirm={async () => {
                           onConfirm={async () => {
                             const resp = await service.deployProduct(
                             const resp = await service.deployProduct(
                               InstanceModel.detail?.productId || '',
                               InstanceModel.detail?.productId || '',
@@ -345,12 +345,12 @@ const Status = observer((props: Props) => {
                             }
                             }
                           }}
                           }}
                         >
                         >
-                          <a>发布</a>
+                          <a>启用</a>
                         </Popconfirm>
                         </Popconfirm>
                         产品
                         产品
                       </span>
                       </span>
                     ) : (
                     ) : (
-                      '无产品发布权限时:产品未发布,请联系管理员处理'
+                      '无产品发布权限时:产品已禁用,请联系管理员处理'
                     )
                     )
                   }
                   }
                 />
                 />
@@ -383,7 +383,7 @@ const Status = observer((props: Props) => {
                 text={
                 text={
                   devicePermission.action ? (
                   devicePermission.action ? (
                     <span>
                     <span>
-                      设备未启用,请
+                      设备已禁用,请
                       <Popconfirm
                       <Popconfirm
                         title="确认启用"
                         title="确认启用"
                         onConfirm={async () => {
                         onConfirm={async () => {
@@ -405,7 +405,7 @@ const Status = observer((props: Props) => {
                       设备
                       设备
                     </span>
                     </span>
                   ) : (
                   ) : (
-                    '设备未启用,请联系管理员处理'
+                    '设备已禁用,请联系管理员处理'
                   )
                   )
                 }
                 }
               />
               />

+ 2 - 0
src/pages/device/Instance/Detail/Running/Event/index.tsx

@@ -27,6 +27,7 @@ const EventLog = (props: Props) => {
       dataIndex: 'timestamp',
       dataIndex: 'timestamp',
       title: '时间',
       title: '时间',
       sorter: true,
       sorter: true,
+      ellipsis: true,
       renderText: (text: string) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
       renderText: (text: string) => moment(text).format('YYYY-MM-DD HH:mm:ss'),
     },
     },
     {
     {
@@ -95,6 +96,7 @@ const EventLog = (props: Props) => {
               key: i.id,
               key: i.id,
               title: i.name,
               title: i.name,
               dataIndex: i.id,
               dataIndex: i.id,
+              ellipsis: true,
               renderText: (text) => (typeof text === 'object' ? JSON.stringify(text) : text),
               renderText: (text) => (typeof text === 'object' ? JSON.stringify(text) : text),
             } as ProColumns),
             } as ProColumns),
         )
         )

+ 1 - 1
src/pages/device/Instance/index.tsx

@@ -394,7 +394,7 @@ const Instance = () => {
         defaultMessage: '操作',
         defaultMessage: '操作',
       }),
       }),
       valueType: 'option',
       valueType: 'option',
-      width: 200,
+      width: 120,
       fixed: 'right',
       fixed: 'right',
       render: (text, record) => tools(record),
       render: (text, record) => tools(record),
     },
     },

+ 22 - 15
src/pages/device/Product/Detail/Access/AccessConfig/index.tsx

@@ -59,11 +59,11 @@ const AccessConfig = (props: Props) => {
       valueType: 'select',
       valueType: 'select',
       valueEnum: {
       valueEnum: {
         disabled: {
         disabled: {
-          text: '已停止',
+          text: '禁用',
           status: 'disabled',
           status: 'disabled',
         },
         },
         enabled: {
         enabled: {
-          text: '已启动',
+          text: '正常',
           status: 'enabled',
           status: 'enabled',
         },
         },
       },
       },
@@ -98,19 +98,26 @@ const AccessConfig = (props: Props) => {
             messageProtocol: currrent.protocol,
             messageProtocol: currrent.protocol,
           });
           });
           if (resp.status === 200) {
           if (resp.status === 200) {
-            service1
-              .changeDeploy(productModel.current?.id || '', 'deploy')
-              .subscribe((response) => {
-                if (response) {
-                  service1.detail(productModel.current?.id || '').then((res) => {
-                    if (res.status === 200) {
-                      productModel.current = { ...res.result };
-                      message.success('操作成功!');
-                    }
-                    close();
-                  });
-                }
-              });
+            service1.detail(productModel.current?.id || '').then((res) => {
+              if (res.status === 200) {
+                productModel.current = { ...res.result };
+                message.success('操作成功!');
+              }
+              close();
+            });
+            // service1
+            //   .changeDeploy(productModel.current?.id || '', 'deploy')
+            //   .subscribe((response) => {
+            //     if (response) {
+            //       service1.detail(productModel.current?.id || '').then((res) => {
+            //         if (res.status === 200) {
+            //           productModel.current = { ...res.result };
+            //           message.success('操作成功!');
+            //         }
+            //         close();
+            //       });
+            //     }
+            //   });
           }
           }
         } else {
         } else {
           message.success('请选择接入方式');
           message.success('请选择接入方式');

+ 6 - 6
src/pages/device/Product/Detail/index.tsx

@@ -264,7 +264,7 @@ const ProductDetail = observer(() => {
       subTitle={
       subTitle={
         permission.update ? (
         permission.update ? (
           <Popconfirm
           <Popconfirm
-            title={productModel.current?.state === 1 ? '确认取消发布' : '确认发布'}
+            title={productModel.current?.state === 1 ? '确认禁用' : '确认启用'}
             onConfirm={() => {
             onConfirm={() => {
               changeDeploy(statusMap[productModel.current?.state || 0].action);
               changeDeploy(statusMap[productModel.current?.state || 0].action);
             }}
             }}
@@ -272,8 +272,8 @@ const ProductDetail = observer(() => {
             <Switch
             <Switch
               key={2}
               key={2}
               checked={productModel.current?.state === 1}
               checked={productModel.current?.state === 1}
-              checkedChildren="已发布"
-              unCheckedChildren="未发布"
+              checkedChildren="正常"
+              unCheckedChildren="禁用"
             />
             />
           </Popconfirm>
           </Popconfirm>
         ) : (
         ) : (
@@ -287,8 +287,8 @@ const ProductDetail = observer(() => {
               key={2}
               key={2}
               disabled
               disabled
               checked={productModel.current?.state === 1}
               checked={productModel.current?.state === 1}
-              checkedChildren="已发布"
-              unCheckedChildren="未发布"
+              checkedChildren="正常"
+              unCheckedChildren="禁用"
             />
             />
           </Tooltip>
           </Tooltip>
         )
         )
@@ -304,7 +304,7 @@ const ProductDetail = observer(() => {
               changeDeploy('deploy');
               changeDeploy('deploy');
             },
             },
           }}
           }}
-          tooltip={productModel.current?.state === 0 ? { title: '请先发布产品' } : undefined}
+          tooltip={productModel.current?.state === 0 ? { title: '请先启用产品' } : undefined}
           isPermission={permission.update}
           isPermission={permission.update}
           disabled={productModel.current?.state === 0}
           disabled={productModel.current?.state === 0}
         >
         >

+ 1 - 1
src/pages/device/Product/Save/index.tsx

@@ -121,7 +121,7 @@ const Save = (props: Props) => {
         form.resetFields();
         form.resetFields();
         close();
         close();
       }}
       }}
-      width={610}
+      width={640}
       title={intl.formatMessage({
       title={intl.formatMessage({
         id: `pages.data.option.${props.model || 'add'}`,
         id: `pages.data.option.${props.model || 'add'}`,
         defaultMessage: '新增',
         defaultMessage: '新增',

+ 12 - 12
src/pages/device/Product/index.tsx

@@ -30,8 +30,8 @@ import useLocation from '@/hooks/route/useLocation';
 
 
 export const service = new Service('device-product');
 export const service = new Service('device-product');
 export const statusMap = {
 export const statusMap = {
-  1: <Badge status="processing" text="已发布" />,
-  0: <Badge status="error" text="未发布" />,
+  1: <Badge status="success" text="正常" />,
+  0: <Badge status="error" text="禁用" />,
 };
 };
 export const productModel = model<{
 export const productModel = model<{
   current: ProductItem | undefined;
   current: ProductItem | undefined;
@@ -62,10 +62,10 @@ const Product = observer(() => {
   const status = {
   const status = {
     1: (
     1: (
       <Badge
       <Badge
-        status="processing"
+        status="success"
         text={intl.formatMessage({
         text={intl.formatMessage({
-          id: 'pages.system.tenant.assetInformation.published',
-          defaultMessage: '已发布',
+          id: 'pages.device.product.status.enabled',
+          defaultMessage: '正常',
         })}
         })}
       />
       />
     ),
     ),
@@ -73,8 +73,8 @@ const Product = observer(() => {
       <Badge
       <Badge
         status="error"
         status="error"
         text={intl.formatMessage({
         text={intl.formatMessage({
-          id: 'pages.system.tenant.assetInformation.unpublished',
-          defaultMessage: '未发布',
+          id: 'pages.device.product.status.disabled',
+          defaultMessage: '禁用',
         })}
         })}
       />
       />
     ),
     ),
@@ -298,15 +298,15 @@ const Product = observer(() => {
         // },
         // },
         0: {
         0: {
           text: intl.formatMessage({
           text: intl.formatMessage({
-            id: 'pages.device.product.status.unpublished',
-            defaultMessage: '未发布',
+            id: 'pages.device.product.status.disabled',
+            defaultMessage: '禁用',
           }),
           }),
           status: 0,
           status: 0,
         },
         },
         1: {
         1: {
           text: intl.formatMessage({
           text: intl.formatMessage({
-            id: 'pages.device.product.status.published',
-            defaultMessage: '已发布',
+            id: 'pages.device.product.status.enabled',
+            defaultMessage: '正常',
           }),
           }),
           status: 1,
           status: 1,
         },
         },
@@ -582,7 +582,7 @@ const Product = observer(() => {
                     ? {
                     ? {
                         title: intl.formatMessage({
                         title: intl.formatMessage({
                           id: 'pages.device.productDetail.deleteTip',
                           id: 'pages.device.productDetail.deleteTip',
-                          defaultMessage: '已发布的产品不能进行删除操作',
+                          defaultMessage: '已启用的产品不能进行删除操作',
                         }),
                         }),
                       }
                       }
                     : undefined
                     : undefined

+ 5 - 2
src/pages/link/AccessConfig/Detail/Access/index.tsx

@@ -22,6 +22,7 @@ import { getButtonPermission, getMenuPathByCode, MENUS_CODE } from '@/utils/menu
 import { ExclamationCircleFilled } from '@ant-design/icons';
 import { ExclamationCircleFilled } from '@ant-design/icons';
 import TitleComponent from '@/components/TitleComponent';
 import TitleComponent from '@/components/TitleComponent';
 import { PermissionButton } from '@/components';
 import { PermissionButton } from '@/components';
+import { useDomFullHeight } from '@/hooks';
 
 
 interface Props {
 interface Props {
   change: () => void;
   change: () => void;
@@ -31,7 +32,7 @@ interface Props {
 
 
 const Access = (props: Props) => {
 const Access = (props: Props) => {
   const [form] = Form.useForm();
   const [form] = Form.useForm();
-
+  const { minHeight } = useDomFullHeight(`.access`);
   const history = useHistory();
   const history = useHistory();
 
 
   const [current, setCurrent] = useState<number>(0);
   const [current, setCurrent] = useState<number>(0);
@@ -356,6 +357,7 @@ const Access = (props: Props) => {
               </Row>
               </Row>
             ) : (
             ) : (
               <Empty
               <Empty
+                style={{ marginTop: '10%', marginBottom: '10%' }}
                 description={
                 description={
                   <span>
                   <span>
                     暂无数据
                     暂无数据
@@ -451,6 +453,7 @@ const Access = (props: Props) => {
               </Row>
               </Row>
             ) : (
             ) : (
               <Empty
               <Empty
+                style={{ marginTop: '10%', marginBottom: '10%' }}
                 description={
                 description={
                   <span>
                   <span>
                     暂无数据
                     暂无数据
@@ -628,7 +631,7 @@ const Access = (props: Props) => {
   };
   };
 
 
   return (
   return (
-    <Card>
+    <Card className="access" style={{ minHeight }}>
       {!props.data?.id && (
       {!props.data?.id && (
         <Button
         <Button
           type="link"
           type="link"

+ 2 - 2
src/pages/link/AccessConfig/index.tsx

@@ -31,11 +31,11 @@ const AccessConfig = () => {
       valueType: 'select',
       valueType: 'select',
       valueEnum: {
       valueEnum: {
         disabled: {
         disabled: {
-          text: '已停止',
+          text: '禁用',
           status: 'disabled',
           status: 'disabled',
         },
         },
         enabled: {
         enabled: {
-          text: '已启动',
+          text: '正常',
           status: 'enabled',
           status: 'enabled',
         },
         },
       },
       },

+ 1 - 7
src/pages/link/Certificate/index.tsx

@@ -29,7 +29,6 @@ const Certificate = () => {
       title: '证书标准',
       title: '证书标准',
       render: (_, record: any) => <span>{record.type?.text || '-'}</span>,
       render: (_, record: any) => <span>{record.type?.text || '-'}</span>,
       valueType: 'select',
       valueType: 'select',
-      fixed: 'left',
       valueEnum: {
       valueEnum: {
         common: {
         common: {
           text: '国际标准',
           text: '国际标准',
@@ -40,13 +39,11 @@ const Certificate = () => {
     {
     {
       dataIndex: 'name',
       dataIndex: 'name',
       title: '证书名称',
       title: '证书名称',
-      width: '30%',
       ellipsis: true,
       ellipsis: true,
     },
     },
     {
     {
       dataIndex: 'description',
       dataIndex: 'description',
       title: '说明',
       title: '说明',
-      width: '30%',
       ellipsis: true,
       ellipsis: true,
       render: (text: any) => (
       render: (text: any) => (
         <div style={{ width: '100%' }} className="ellipsis">
         <div style={{ width: '100%' }} className="ellipsis">
@@ -62,9 +59,7 @@ const Certificate = () => {
         defaultMessage: '操作',
         defaultMessage: '操作',
       }),
       }),
       valueType: 'option',
       valueType: 'option',
-      align: 'center',
-      width: 200,
-      fixed: 'right',
+      width: 100,
       render: (text, record) => [
       render: (text, record) => [
         <PermissionButton
         <PermissionButton
           key={'update'}
           key={'update'}
@@ -125,7 +120,6 @@ const Certificate = () => {
         params={param}
         params={param}
         columns={columns}
         columns={columns}
         search={false}
         search={false}
-        scroll={{ x: 1366 }}
         rowKey="id"
         rowKey="id"
         tableClassName={'link-certificate'}
         tableClassName={'link-certificate'}
         tableStyle={{ minHeight }}
         tableStyle={{ minHeight }}

+ 2 - 2
src/pages/link/Channel/Opcua/index.tsx

@@ -71,8 +71,8 @@ const Opcua = () => {
         },
         },
         enabled: {
         enabled: {
           text: intl.formatMessage({
           text: intl.formatMessage({
-            id: 'pages.data.option.enabled',
-            defaultMessage: '启用',
+            id: 'pages.device.product.status.enabled',
+            defaultMessage: '正常',
           }),
           }),
           status: 'enabled',
           status: 'enabled',
         },
         },

+ 14 - 3
src/pages/link/Protocol/index.tsx

@@ -73,8 +73,19 @@ const Protocol = () => {
     {
     {
       dataIndex: 'state',
       dataIndex: 'state',
       title: '状态',
       title: '状态',
+      valueType: 'select',
+      valueEnum: {
+        0: {
+          text: '禁用',
+          status: 0,
+        },
+        1: {
+          text: '正常',
+          status: 1,
+        },
+      },
       renderText: (text) => (
       renderText: (text) => (
-        <Badge color={text !== 1 ? 'red' : 'green'} text={text !== 1 ? '未发布' : '已发布'} />
+        <Badge color={text !== 1 ? 'red' : 'green'} text={text !== 1 ? '禁用' : '正常'} />
       ),
       ),
     },
     },
     {
     {
@@ -114,10 +125,10 @@ const Protocol = () => {
           type={'link'}
           type={'link'}
           style={{ padding: 0 }}
           style={{ padding: 0 }}
           tooltip={{
           tooltip={{
-            title: record.state === 1 ? '撤销' : '发布',
+            title: record.state === 1 ? '禁用' : '启用',
           }}
           }}
           popConfirm={{
           popConfirm={{
-            title: `确认${record.state === 1 ? '撤销' : '发布'}`,
+            title: `确认${record.state === 1 ? '禁用' : '启用'}`,
             onConfirm: () => {
             onConfirm: () => {
               if (record.state === 1) {
               if (record.state === 1) {
                 modifyState(record.id, 'un-deploy');
                 modifyState(record.id, 'un-deploy');

+ 52 - 31
src/pages/link/Protocol/save/index.tsx

@@ -1,4 +1,4 @@
-import { Button, message, Modal } from 'antd';
+import { Button, Modal } from 'antd';
 import { createForm, registerValidateRules } from '@formily/core';
 import { createForm, registerValidateRules } from '@formily/core';
 import { createSchemaField } from '@formily/react';
 import { createSchemaField } from '@formily/react';
 import React, { useEffect, useState } from 'react';
 import React, { useEffect, useState } from 'react';
@@ -9,7 +9,8 @@ import { service } from '@/pages/link/Protocol';
 import FileUpload from '../FileUpload';
 import FileUpload from '../FileUpload';
 import type { ProtocolItem } from '@/pages/link/Protocol/typings';
 import type { ProtocolItem } from '@/pages/link/Protocol/typings';
 import { PermissionButton } from '@/components';
 import { PermissionButton } from '@/components';
-
+import { RadioCard } from '@/components';
+import { onlyMessage } from '@/utils/util';
 interface Props {
 interface Props {
   data: ProtocolItem | undefined;
   data: ProtocolItem | undefined;
   close: () => void;
   close: () => void;
@@ -44,6 +45,7 @@ const Save = (props: Props) => {
       Select,
       Select,
       FileUpload,
       FileUpload,
       FormGrid,
       FormGrid,
+      RadioCard,
     },
     },
     scope: {
     scope: {
       icon(name: any) {
       icon(name: any) {
@@ -59,8 +61,9 @@ const Save = (props: Props) => {
         type: 'void',
         type: 'void',
         'x-component': 'FormGrid',
         'x-component': 'FormGrid',
         'x-component-props': {
         'x-component-props': {
-          maxColumns: 1,
-          minColumns: 1,
+          maxColumns: 2,
+          minColumns: 2,
+          columnGap: 24,
         },
         },
         properties: {
         properties: {
           id: {
           id: {
@@ -69,7 +72,7 @@ const Save = (props: Props) => {
             'x-decorator': 'FormItem',
             'x-decorator': 'FormItem',
             'x-disabled': !!props.data?.id,
             'x-disabled': !!props.data?.id,
             'x-decorator-props': {
             'x-decorator-props': {
-              gridSpan: 1,
+              gridSpan: 2,
             },
             },
             'x-validator': [
             'x-validator': [
               {
               {
@@ -112,7 +115,7 @@ const Save = (props: Props) => {
             'x-component': 'Input',
             'x-component': 'Input',
             'x-decorator': 'FormItem',
             'x-decorator': 'FormItem',
             'x-decorator-props': {
             'x-decorator-props': {
-              gridSpan: 1,
+              gridSpan: 2,
             },
             },
             'x-component-props': {
             'x-component-props': {
               placeholder: '请输入名称',
               placeholder: '请输入名称',
@@ -130,14 +133,30 @@ const Save = (props: Props) => {
           },
           },
           type: {
           type: {
             title: '类型',
             title: '类型',
-            'x-component': 'Select',
+            'x-component': 'RadioCard',
             'x-decorator': 'FormItem',
             'x-decorator': 'FormItem',
             'x-disabled': !!props.data?.id,
             'x-disabled': !!props.data?.id,
             'x-decorator-props': {
             'x-decorator-props': {
+              gridSpan: 2,
               tooltip: <div>jar:上传协议jar包,文件格式支持.jar或.zip</div>,
               tooltip: <div>jar:上传协议jar包,文件格式支持.jar或.zip</div>,
             },
             },
             'x-component-props': {
             'x-component-props': {
-              placeholder: '请选择类型',
+              model: 'singular',
+              itemStyle: {
+                width: '50%',
+              },
+              options: [
+                {
+                  label: 'Jar',
+                  value: 'jar',
+                  imgUrl: require('/public/images/jar.png'),
+                },
+                {
+                  label: 'Local',
+                  value: 'local',
+                  imgUrl: require('/public/images/local.png'),
+                },
+              ],
             },
             },
             'x-validator': [
             'x-validator': [
               {
               {
@@ -145,11 +164,11 @@ const Save = (props: Props) => {
                 message: '请选择类型',
                 message: '请选择类型',
               },
               },
             ],
             ],
-            enum: [
-              { label: 'jar', value: 'jar' },
-              { label: 'local', value: 'local' },
-              // { label: 'script', value: 'script' },
-            ],
+            // enum: [
+            //   { label: 'jar', value: 'jar' },
+            //   { label: 'local', value: 'local' },
+            //   // { label: 'script', value: 'script' },
+            // ],
           },
           },
           configuration: {
           configuration: {
             type: 'object',
             type: 'object',
@@ -159,10 +178,9 @@ const Save = (props: Props) => {
                 'x-decorator': 'FormItem',
                 'x-decorator': 'FormItem',
                 'x-visible': false,
                 'x-visible': false,
                 'x-decorator-props': {
                 'x-decorator-props': {
+                  gridSpan: 2,
                   tooltip: (
                   tooltip: (
-                    <div>
-                      local:填写本地协议编译目录绝对地址,如:d:/workspace/protocol/target/classes
-                    </div>
+                    <div>local:填写本地协议编译目录绝对地址,如:d:/protocol/target/classes</div>
                   ),
                   ),
                 },
                 },
                 'x-validator': [
                 'x-validator': [
@@ -189,6 +207,9 @@ const Save = (props: Props) => {
             title: '说明',
             title: '说明',
             'x-component': 'Input.TextArea',
             'x-component': 'Input.TextArea',
             'x-decorator': 'FormItem',
             'x-decorator': 'FormItem',
+            'x-decorator-props': {
+              gridSpan: 2,
+            },
             'x-component-props': {
             'x-component-props': {
               rows: 3,
               rows: 3,
               showCount: true,
               showCount: true,
@@ -209,7 +230,7 @@ const Save = (props: Props) => {
       response = await service.update(value);
       response = await service.update(value);
     }
     }
     if (response && response.status === 200) {
     if (response && response.status === 200) {
-      message.success('操作成功');
+      onlyMessage('操作成功');
       if (deploy) {
       if (deploy) {
         await service.modifyState(value.id, 'deploy');
         await service.modifyState(value.id, 'deploy');
       }
       }
@@ -242,20 +263,20 @@ const Save = (props: Props) => {
         >
         >
           保存
           保存
         </Button>,
         </Button>,
-        <Button
-          key={3}
-          type="primary"
-          onClick={() => {
-            save(true);
-          }}
-          disabled={
-            props.data?.id
-              ? !permission.update && !permission.action
-              : !permission.add && !permission.action
-          }
-        >
-          保存并发布
-        </Button>,
+        // <Button
+        //   key={3}
+        //   type="primary"
+        //   onClick={() => {
+        //     save(true);
+        //   }}
+        //   disabled={
+        //     props.data?.id
+        //       ? !permission.update && !permission.action
+        //       : !permission.add && !permission.action
+        //   }
+        // >
+        //   保存并发布
+        // </Button>,
       ]}
       ]}
     >
     >
       <Form form={form} layout="vertical">
       <Form form={form} layout="vertical">

+ 5 - 4
src/pages/link/Type/index.tsx

@@ -126,17 +126,17 @@ const Network = () => {
       valueType: 'select',
       valueType: 'select',
       valueEnum: {
       valueEnum: {
         disabled: {
         disabled: {
-          text: '已停止',
+          text: '禁用',
           status: 'disabled',
           status: 'disabled',
         },
         },
         enabled: {
         enabled: {
-          text: '已启动',
+          text: '正常',
           status: 'enabled',
           status: 'enabled',
         },
         },
       },
       },
       render: (text, record) => {
       render: (text, record) => {
         if (record.state.value === 'enabled') {
         if (record.state.value === 'enabled') {
-          return <Badge color="lime" text="正常" />;
+          return <Badge color="#52c41a" text="正常" />;
         }
         }
         return <Badge color="red" text="禁用" />;
         return <Badge color="red" text="禁用" />;
       },
       },
@@ -144,6 +144,7 @@ const Network = () => {
     {
     {
       dataIndex: 'description',
       dataIndex: 'description',
       title: '说明',
       title: '说明',
+      ellipsis: true,
     },
     },
     {
     {
       title: intl.formatMessage({
       title: intl.formatMessage({
@@ -151,7 +152,7 @@ const Network = () => {
         defaultMessage: '操作',
         defaultMessage: '操作',
       }),
       }),
       valueType: 'option',
       valueType: 'option',
-      width: 200,
+      width: 120,
       fixed: 'right',
       fixed: 'right',
       render: (text, record) => [
       render: (text, record) => [
         <PermissionButton
         <PermissionButton

+ 33 - 18
src/pages/media/Cascade/Save/index.tsx

@@ -80,6 +80,10 @@ const Save = () => {
                 host: sipConfigs.host,
                 host: sipConfigs.host,
                 port: sipConfigs.port,
                 port: sipConfigs.port,
               },
               },
+              remotePublic: {
+                host: sipConfigs.publicHost,
+                port: sipConfigs.publicPort,
+              },
             },
             },
           };
           };
           form.setFieldsValue(data);
           form.setFieldsValue(data);
@@ -117,6 +121,8 @@ const Save = () => {
               remotePort: values.sipConfigs.public.port,
               remotePort: values.sipConfigs.public.port,
               host: values.sipConfigs.local.host,
               host: values.sipConfigs.local.host,
               port: values.sipConfigs.local.port,
               port: values.sipConfigs.local.port,
+              publicHost: values.sipConfigs.remotePublic.host,
+              publicPort: values.sipConfigs.remotePublic.port,
             };
             };
             delete values.sipConfigs;
             delete values.sipConfigs;
             delete sipConfigs.public;
             delete sipConfigs.public;
@@ -227,24 +233,6 @@ const Save = () => {
             </Col>
             </Col>
             <Col span={12}>
             <Col span={12}>
               <Form.Item
               <Form.Item
-                label="传输协议"
-                name={['sipConfigs', 'transport']}
-                rules={[{ required: true, message: '请选择传输协议' }]}
-              >
-                <Radio.Group
-                  optionType="button"
-                  buttonStyle="solid"
-                  onChange={(e) => {
-                    setTransport(e.target.value);
-                  }}
-                >
-                  <Radio.Button value="UDP">UDP</Radio.Button>
-                  <Radio.Button value="TCP">TCP</Radio.Button>
-                </Radio.Group>
-              </Form.Item>
-            </Col>
-            <Col span={12}>
-              <Form.Item
                 label={
                 label={
                   <span>
                   <span>
                     SIP本地地址
                     SIP本地地址
@@ -264,6 +252,33 @@ const Save = () => {
             </Col>
             </Col>
             <Col span={12}>
             <Col span={12}>
               <Form.Item
               <Form.Item
+                label="SIP远程地址"
+                name={['sipConfigs', 'remotePublic']}
+                rules={[{ required: true, message: '请输入SIP远程地址' }, { validator: checkSIP }]}
+              >
+                <SipComponent />
+              </Form.Item>
+            </Col>
+            <Col span={24}>
+              <Form.Item
+                label="传输协议"
+                name={['sipConfigs', 'transport']}
+                rules={[{ required: true, message: '请选择传输协议' }]}
+              >
+                <Radio.Group
+                  optionType="button"
+                  buttonStyle="solid"
+                  onChange={(e) => {
+                    setTransport(e.target.value);
+                  }}
+                >
+                  <Radio.Button value="UDP">UDP</Radio.Button>
+                  <Radio.Button value="TCP">TCP</Radio.Button>
+                </Radio.Group>
+              </Form.Item>
+            </Col>
+            <Col span={12}>
+              <Form.Item
                 label="用户"
                 label="用户"
                 name={['sipConfigs', 'user']}
                 name={['sipConfigs', 'user']}
                 rules={[{ required: true, message: '请输入用户' }]}
                 rules={[{ required: true, message: '请输入用户' }]}

+ 1 - 1
src/pages/media/Device/Save/index.tsx

@@ -122,7 +122,7 @@ export default (props: SaveProps) => {
           form.resetFields();
           form.resetFields();
           close();
           close();
         }}
         }}
-        width={610}
+        width={640}
         title={intl.formatMessage({
         title={intl.formatMessage({
           id: `pages.data.option.${props.model || 'add'}`,
           id: `pages.data.option.${props.model || 'add'}`,
           defaultMessage: '新增',
           defaultMessage: '新增',

+ 3 - 1
src/pages/media/SplitScreen/index.tsx

@@ -6,11 +6,13 @@ import { ScreenPlayer } from '@/components';
 import { ptzStart, ptzStop, ptzTool } from './service';
 import { ptzStart, ptzStop, ptzTool } from './service';
 import { useRef, useState } from 'react';
 import { useRef, useState } from 'react';
 import './index.less';
 import './index.less';
+import { useDomFullHeight } from '@/hooks';
 
 
 const SplitScreen = () => {
 const SplitScreen = () => {
   const [deviceId, setDeviceId] = useState('');
   const [deviceId, setDeviceId] = useState('');
   const [channelId, setChannelId] = useState('');
   const [channelId, setChannelId] = useState('');
   const player = useRef<any>(null);
   const player = useRef<any>(null);
+  const { minHeight } = useDomFullHeight(`.splitScreen`);
 
 
   const getMediaUrl = (dId: string, cId: string): string => {
   const getMediaUrl = (dId: string, cId: string): string => {
     return ptzStart(dId, cId, 'mp4');
     return ptzStart(dId, cId, 'mp4');
@@ -24,7 +26,7 @@ const SplitScreen = () => {
 
 
   return (
   return (
     <PageContainer>
     <PageContainer>
-      <Card>
+      <Card style={{ minHeight }} className="splitScreen">
         <div className="split-screen">
         <div className="split-screen">
           <LeftTree onSelect={mediaStart} />
           <LeftTree onSelect={mediaStart} />
           <div className="right-content">
           <div className="right-content">

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

@@ -99,8 +99,6 @@ const Template = observer(() => {
       dataIndex: 'name',
       dataIndex: 'name',
       title: '模版名称',
       title: '模版名称',
       ellipsis: true,
       ellipsis: true,
-      fixed: 'left',
-      width: '25%',
     },
     },
     {
     {
       dataIndex: 'provider',
       dataIndex: 'provider',
@@ -120,9 +118,8 @@ const Template = observer(() => {
         defaultMessage: '操作',
         defaultMessage: '操作',
       }),
       }),
       valueType: 'option',
       valueType: 'option',
-      align: 'center',
+      align: 'left',
       width: 200,
       width: 200,
-      fixed: 'right',
       render: (text, record) => [
       render: (text, record) => [
         <PermissionButton
         <PermissionButton
           key="edit"
           key="edit"
@@ -229,7 +226,6 @@ const Template = observer(() => {
         rowKey="id"
         rowKey="id"
         search={false}
         search={false}
         params={param}
         params={param}
-        scroll={{ x: 1366 }}
         columns={columns}
         columns={columns}
         headerTitle={
         headerTitle={
           <Space>
           <Space>

+ 2 - 1
src/pages/rule-engine/Alarm/Configuration/index.tsx

@@ -99,8 +99,9 @@ const Configuration = () => {
     {
     {
       title: '操作',
       title: '操作',
       valueType: 'option',
       valueType: 'option',
-      align: 'center',
+      align: 'left',
       fixed: 'right',
       fixed: 'right',
+      width: 150,
       render: (_, record) => [
       render: (_, record) => [
         record.sceneTriggerType === 'manual' && (
         record.sceneTriggerType === 'manual' && (
           <PermissionButton
           <PermissionButton

+ 9 - 1
src/pages/rule-engine/Alarm/Log/Detail/Info.tsx

@@ -2,6 +2,7 @@ import { Descriptions, Modal } from 'antd';
 import { useEffect, useState } from 'react';
 import { useEffect, useState } from 'react';
 import moment from 'moment';
 import moment from 'moment';
 import { Store } from 'jetlinks-store';
 import { Store } from 'jetlinks-store';
+import styles from './index.less';
 
 
 interface Props {
 interface Props {
   data: Partial<AlarmLogHistoryItem>;
   data: Partial<AlarmLogHistoryItem>;
@@ -16,7 +17,14 @@ const Info = (props: Props) => {
   }, [props.data]);
   }, [props.data]);
 
 
   return (
   return (
-    <Modal title={'详情'} visible onCancel={props.close} onOk={props.close} width={1000}>
+    <Modal
+      title={'详情'}
+      visible
+      onCancel={props.close}
+      onOk={props.close}
+      width={1000}
+      className={styles.conent}
+    >
       <Descriptions bordered column={2}>
       <Descriptions bordered column={2}>
         {data.targetType === 'device' && (
         {data.targetType === 'device' && (
           <>
           <>

+ 7 - 0
src/pages/rule-engine/Alarm/Log/Detail/index.less

@@ -0,0 +1,7 @@
+.conent {
+  :global {
+    .ant-descriptions-bordered .ant-descriptions-item-label {
+      min-width: 180px;
+    }
+  }
+}

+ 4 - 2
src/pages/system/Basis/index.tsx

@@ -10,6 +10,7 @@ import { LoadingOutlined, PlusOutlined } from '@ant-design/icons';
 import styles from './index.less';
 import styles from './index.less';
 import { PageContainer } from '@ant-design/pro-layout';
 import { PageContainer } from '@ant-design/pro-layout';
 import Service from './service';
 import Service from './service';
+import { useDomFullHeight } from '@/hooks';
 
 
 const Basis = () => {
 const Basis = () => {
   const service = new Service();
   const service = new Service();
@@ -18,6 +19,7 @@ const Basis = () => {
   const { permission: userPermission } = usePermissions('system/Basis');
   const { permission: userPermission } = usePermissions('system/Basis');
   const [imageUrl, setImageUrl] = useState<string>('');
   const [imageUrl, setImageUrl] = useState<string>('');
   const [loading, setLoading] = useState(false);
   const [loading, setLoading] = useState(false);
+  const { minHeight } = useDomFullHeight(`.basis`);
 
 
   const uploadProps: UploadProps = {
   const uploadProps: UploadProps = {
     showUploadList: false,
     showUploadList: false,
@@ -108,7 +110,7 @@ const Basis = () => {
 
 
   return (
   return (
     <PageContainer>
     <PageContainer>
-      <Card>
+      <Card className="basis" style={{ minHeight }}>
         <div
         <div
           style={{
           style={{
             display: 'flex',
             display: 'flex',
@@ -121,7 +123,7 @@ const Basis = () => {
               <Form.Item
               <Form.Item
                 label="系统名称"
                 label="系统名称"
                 name="title"
                 name="title"
-                rules={[{ required: true, message: '请输入系统名称' }]}
+                // rules={[{ required: true, message: '请输入系统名称' }]}
               >
               >
                 <Input />
                 <Input />
               </Form.Item>
               </Form.Item>

+ 10 - 1
src/utils/util.ts

@@ -2,7 +2,7 @@ import moment from 'moment';
 import type { Field, FieldDataSource } from '@formily/core';
 import type { Field, FieldDataSource } from '@formily/core';
 import { action } from '@formily/reactive';
 import { action } from '@formily/reactive';
 import Token from '@/utils/token';
 import Token from '@/utils/token';
-
+import { message } from 'antd';
 /**
 /**
  * 下载文件
  * 下载文件
  * @param url 下载链接
  * @param url 下载链接
@@ -118,3 +118,12 @@ export const getDomFullHeight = (className: string, extraHeight: number = 0): nu
   }
   }
   return 0;
   return 0;
 };
 };
+export const onlyMessage = (
+  msg: string,
+  type: 'success' | 'error' | 'warning' = 'success',
+  key: number = 1,
+) =>
+  message[type]({
+    content: msg,
+    key: key,
+  });