You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by GitBox <gi...@apache.org> on 2021/04/10 15:54:06 UTC

[GitHub] [apisix-dashboard] LiteSun opened a new pull request #1739: feat: add limit-count plugin

LiteSun opened a new pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739


   Please answer these questions before submitting a pull request, **or your PR will get closed**.
   
   **Why submit this pull request?**
   
   - [ ] Bugfix
   - [ ] New feature provided
   - [ ] Improve performance
   - [ ] Backport patches
   
   **What changes will this PR take into?**
   
   Please update this section with detailed description.
   
   **Related issues**
   
   fix/resolve #0001
   
   **Checklist:**
   
   - [ ] Did you explain what problem does this PR solve? Or what new features have been added?
   - [ ] Have you added corresponding test cases?
   - [ ] Have you modified the corresponding document?
   - [ ] Is this PR backward compatible? If it is not backward compatible, please discuss on the mailing list first
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r613088764



##########
File path: web/src/components/Plugin/locales/zh-CN.ts
##########
@@ -21,4 +21,18 @@ export default {
   'component.step.select.pluginTemplate.select.option': '手动配置',
   'component.plugin.pluginTemplate.tip1': '1. 若路由已配置插件,则插件模板数据将与已配置的插件数据合并。',
   'component.plugin.pluginTemplate.tip2': '2. 插件模板相同的插件会覆盖掉原有的插件。',
+
+  // limit-count
+  'component.pluginForm.limit-count.count.tooltip': '指定时间窗口内的请求数量阈值。',
+  'component.pluginForm.limit-count.time_window.tooltip': '时间窗口的大小(以秒为单位),超过这个时间就会重置。',
+  'component.pluginForm.limit-count.key.tooltip': '用来做请求计数的有效值。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名规定时间内的请求次数。我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端规定时间内多次的连接我们的服务。当前接受的 key 有:"remote_addr"(客户端 IP 地址), "server_addr"(服务端 IP 地址), 请求头中的"X-Forwarded-For" 或 "X-Real-IP", "consumer_name"(consumer 的 username), "service_id" 。',

Review comment:
       just use `服务器地址`
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611386625



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        required

Review comment:
       `time_window` is `时间窗口`, you could refer to `Konga` for a reference.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r615329231



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      rules={[
+        { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` },
+        { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }
+      ]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password` }]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name` }]}
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                style={{ marginBottom: 0 }}
+                required
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        noStyle
+                        validateTrigger={['onChange', 'onBlur', 'onClick']}
+                        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name` }, { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }]}
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: ['', ''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}

Review comment:
       No, it won't.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611381837



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        required

Review comment:
       ```suggestion
           rules={[{ required: true, message: 'Please input time_window' }]}
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit 2cf677e5db70fc42489e6798d397ec47603bfa38
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit 2b7439860912b3d4f869502caf9678701cef18cc
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/6072d5fbd96cf30007ed4926


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817605077


   > redist Doms lost when edited once again
   > ![2021-04-12 15-45-00屏幕截图](https://user-images.githubusercontent.com/2561857/114359376-7719fb80-9ba6-11eb-942e-696d17d409ea.png)
   > 
   > test step:
   > 1.
   > configure the `limit-count` and submit
   > ![2021-04-12 16-05-43屏幕截图](https://user-images.githubusercontent.com/2561857/114361686-fdcfd800-9ba8-11eb-8e5b-d817875bc8c1.png)
   > 
   > 1. click `enable` button to edit it again, you will get the trouble
   > 
   > @LiteSun
   
   Tks for your report. I will check it.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit edc362b3bdb1167433ae54a867603fcc5db2fe99
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit c173197f5659aaa6ed96fc4752c0308382e66f43
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611610923



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -169,15 +169,15 @@ const LimitCount: React.FC<Props> = ({ form }) => {
         label="count"
         name="count"
         tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
-        required
+        rules={[{ required: true, message: 'Please input count' }]}

Review comment:
       no, add `i18n` please




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit 80c3e3e5795db751e2f30ca8ba8e63c0208a3270
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611378220



##########
File path: web/src/components/Plugin/locales/zh-CN.ts
##########
@@ -21,4 +21,18 @@ export default {
   'component.step.select.pluginTemplate.select.option': '手动配置',
   'component.plugin.pluginTemplate.tip1': '1. 若路由已配置插件,则插件模板数据将与已配置的插件数据合并。',
   'component.plugin.pluginTemplate.tip2': '2. 插件模板相同的插件会覆盖掉原有的插件。',
+
+  // limit-count
+  'component.pluginForm.limit-count.count.tooltip': '指定时间窗口内的请求数量阈值。',
+  'component.pluginForm.limit-count.time_window.tooltip': '时间窗口的大小(以秒为单位),超过这个时间就会重置。',
+  'component.pluginForm.limit-count.key.tooltip': '用来做请求计数的有效值。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名规定时间内的请求次数。我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端规定时间内多次的连接我们的服务。当前接受的 key 有:"remote_addr"(客户端 IP 地址), "server_addr"(服务端 IP 地址), 请求头中的"X-Forwarded-For" 或 "X-Real-IP", "consumer_name"(consumer 的 username), "service_id" 。',

Review comment:
       May I ask what is the meaning of `服务器区域`?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611378220



##########
File path: web/src/components/Plugin/locales/zh-CN.ts
##########
@@ -21,4 +21,18 @@ export default {
   'component.step.select.pluginTemplate.select.option': '手动配置',
   'component.plugin.pluginTemplate.tip1': '1. 若路由已配置插件,则插件模板数据将与已配置的插件数据合并。',
   'component.plugin.pluginTemplate.tip2': '2. 插件模板相同的插件会覆盖掉原有的插件。',
+
+  // limit-count
+  'component.pluginForm.limit-count.count.tooltip': '指定时间窗口内的请求数量阈值。',
+  'component.pluginForm.limit-count.time_window.tooltip': '时间窗口的大小(以秒为单位),超过这个时间就会重置。',
+  'component.pluginForm.limit-count.key.tooltip': '用来做请求计数的有效值。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名规定时间内的请求次数。我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端规定时间内多次的连接我们的服务。当前接受的 key 有:"remote_addr"(客户端 IP 地址), "server_addr"(服务端 IP 地址), 请求头中的"X-Forwarded-For" 或 "X-Real-IP", "consumer_name"(consumer 的 username), "service_id" 。',

Review comment:
       May I ask what the meaning of `服务器区域`?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817161003


   Please add your description for this PR


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817646820


   > redist Doms lost when edited once again
    @liuxiran fixed.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun merged pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun merged pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit 2b7439860912b3d4f869502caf9678701cef18cc
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611179469



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="key"
+        name="key"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.key.tooltip' })}
+      >
+        <Select>
+          {["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for", "consumer_name", "service_id"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      <Form.Item
+        label="rejected_code"
+        name="rejected_code"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.rejected_code.tooltip' })}
+      >
+        <InputNumber min={200} max={599} />
+      </Form.Item>
+      <Form.Item
+        label="policy"
+        name="policy"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.policy.tooltip' })}
+      >
+        <Select onChange={(e: PolicyProps) => { setPoicy(e) }}>
+          {["local", "redis", "redis-cluster"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}

Review comment:
       key

##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="key"
+        name="key"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.key.tooltip' })}
+      >
+        <Select>
+          {["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for", "consumer_name", "service_id"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      <Form.Item
+        label="rejected_code"
+        name="rejected_code"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.rejected_code.tooltip' })}
+      >
+        <InputNumber min={200} max={599} />
+      </Form.Item>
+      <Form.Item
+        label="policy"
+        name="policy"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.policy.tooltip' })}
+      >
+        <Select onChange={(e: PolicyProps) => { setPoicy(e) }}>
+          {["local", "redis", "redis-cluster"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      { Boolean(policy === 'redis') && <RedisForm />}

Review comment:
       extra space?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] liuxiran commented on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
liuxiran commented on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817587780


   redist Doms lost when edited once again
   ![2021-04-12 15-45-00屏幕截图](https://user-images.githubusercontent.com/2561857/114359376-7719fb80-9ba6-11eb-942e-696d17d409ea.png)
   
   test step:
   1. 
   configure the `limit-count` and submit
   ![2021-04-12 16-05-43屏幕截图](https://user-images.githubusercontent.com/2561857/114361686-fdcfd800-9ba8-11eb-8e5b-d817875bc8c1.png)
   
   
   
   
   2. click `enable` button to edit it again, you will get the trouble
   
   
   @LiteSun 


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit 88bd2e48580e83db6cac9ada6e0e966a71f31ff5
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit d8967058b4a81d27075964d6114e3521e3ee2b4b
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/60779ae5a53e2e00071fb5a7


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611468894



##########
File path: web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js
##########
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* eslint-disable no-undef */
+
+context('Create and delete consumer with limit-count plugin form', () => {
+  beforeEach(() => {
+    cy.login();
+
+    cy.fixture('selector.json').as('domSelector');
+    cy.fixture('data.json').as('data');
+  });
+
+  const selector = {
+    count: '#count',
+    time_window: '#time_window',
+    redis_timeout: '#time_window',
+    key: '#key',
+    rejected_code: '#rejected_code',
+    policy: '#policy',
+    redis_host: '#redis_host',
+    redis_port: '#redis_port',
+    redis_password: '#redis_password',
+    redis_database: '#redis_database',
+    redis_timeout: '#redis_timeout',
+    redis_cluster_name: '#redis_cluster_name',
+    redis_cluster_nodes_0: '#redis_cluster_nodes_0',
+    redis_cluster_nodes_1: '#redis_cluster_nodes_1',
+  }
+
+  const data = {
+    count: 1,
+    time_window: 1,
+    redis_timeout: 10,
+    rejected_code: 500,
+    redis_host: '127.0.0.1',
+    redis_password: 'redis_password',
+    redis_cluster_name: 'redis_cluster_name',
+    redis_cluster_nodes_0: "redis.cluster1",
+    redis_cluster_nodes_1: "redis.cluster1",

Review comment:
       updated.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r612175863



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -169,15 +169,15 @@ const LimitCount: React.FC<Props> = ({ form }) => {
         label="count"
         name="count"
         tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
-        required
+        rules={[{ required: true, message: 'Please input count' }]}

Review comment:
       ok




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] moonming commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
moonming commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611265320



##########
File path: web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js
##########
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* eslint-disable no-undef */
+
+context('Create and delete consumer with limit-count plugin form', () => {
+  beforeEach(() => {
+    cy.login();
+
+    cy.fixture('selector.json').as('domSelector');
+    cy.fixture('data.json').as('data');
+  });
+
+  const selector = {
+    count: '#count',
+    time_window: '#time_window',
+    redis_timeout: '#time_window',
+    key: '#key',
+    rejected_code: '#rejected_code',
+    policy: '#policy',
+    redis_host: '#redis_host',
+    redis_port: '#redis_port',
+    redis_password: '#redis_password',
+    redis_database: '#redis_database',
+    redis_timeout: '#redis_timeout',
+    redis_cluster_name: '#redis_cluster_name',
+    redis_cluster_nodes_0: '#redis_cluster_nodes_0',
+    redis_cluster_nodes_1: '#redis_cluster_nodes_1',
+  }
+
+  const data = {
+    count: 1,
+    time_window: 1,
+    redis_timeout: 10,
+    rejected_code: 500,
+    redis_host: '127.0.0.1',
+    redis_password: 'redis_password',
+    redis_cluster_name: 'redis_cluster_name',
+    redis_cluster_nodes_0: "redis.cluster1",
+    redis_cluster_nodes_1: "redis.cluster1",

Review comment:
       What are these default values?

##########
File path: web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js
##########
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* eslint-disable no-undef */
+
+context('Create and delete consumer with limit-count plugin form', () => {
+  beforeEach(() => {
+    cy.login();
+
+    cy.fixture('selector.json').as('domSelector');
+    cy.fixture('data.json').as('data');
+  });
+
+  const selector = {
+    count: '#count',
+    time_window: '#time_window',
+    redis_timeout: '#time_window',
+    key: '#key',
+    rejected_code: '#rejected_code',
+    policy: '#policy',
+    redis_host: '#redis_host',
+    redis_port: '#redis_port',
+    redis_password: '#redis_password',
+    redis_database: '#redis_database',
+    redis_timeout: '#redis_timeout',
+    redis_cluster_name: '#redis_cluster_name',
+    redis_cluster_nodes_0: '#redis_cluster_nodes_0',
+    redis_cluster_nodes_1: '#redis_cluster_nodes_1',

Review comment:
       why we need these two fields?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit 432530075be58eac60ea5cf06ad9119249f4ed64
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611447380



##########
File path: web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js
##########
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* eslint-disable no-undef */
+
+context('Create and delete consumer with limit-count plugin form', () => {
+  beforeEach(() => {
+    cy.login();
+
+    cy.fixture('selector.json').as('domSelector');
+    cy.fixture('data.json').as('data');
+  });
+
+  const selector = {
+    count: '#count',
+    time_window: '#time_window',
+    redis_timeout: '#time_window',
+    key: '#key',
+    rejected_code: '#rejected_code',
+    policy: '#policy',
+    redis_host: '#redis_host',
+    redis_port: '#redis_port',
+    redis_password: '#redis_password',
+    redis_database: '#redis_database',
+    redis_timeout: '#redis_timeout',
+    redis_cluster_name: '#redis_cluster_name',
+    redis_cluster_nodes_0: '#redis_cluster_nodes_0',
+    redis_cluster_nodes_1: '#redis_cluster_nodes_1',

Review comment:
       Because limit-count plugin schema rule:  must be two redis_cluster_nodes




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] liuxiran commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
liuxiran commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611380644



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required

Review comment:
       ```suggestion
           rules={[{ required: true, message: 'Please input count' }]}
   ```




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r613095922



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      rules={[
+        { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` },
+        { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }
+      ]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password` }]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />

Review comment:
       min = 1

##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      rules={[
+        { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` },
+        { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }
+      ]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password` }]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name` }]}
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                style={{ marginBottom: 0 }}
+                required
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        noStyle
+                        validateTrigger={['onChange', 'onBlur', 'onClick']}
+                        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name` }, { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }]}
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: ['', ''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} count` }]}
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        validateTrigger={['onChange', 'onBlur', 'onClick']}
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} time_window` }]}
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        validateTrigger={['onChange', 'onBlur', 'onClick']}
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="key"
+        name="key"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.key.tooltip' })}
+      >
+        <Select>
+          {["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for", "consumer_name", "service_id"].map(item => (<Select.Option value={item} key={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      <Form.Item
+        label="rejected_code"
+        name="rejected_code"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.rejected_code.tooltip' })}

Review comment:
       default value is 503

##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"

Review comment:
       emmm would better have `i18n` for those fields, for users may not know what's it

##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      rules={[
+        { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` },
+        { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }
+      ]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />

Review comment:
       ```suggestion
         <InputNumber min={1} max={65535} />
   ```

##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      rules={[
+        { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` },
+        { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }
+      ]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password` }]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {

Review comment:
       What do these Props for?

##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      rules={[
+        { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` },
+        { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }
+      ]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password` }]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item

Review comment:
       missing two fields: redis_timeout & redis_password.
   
   https://github.com/apache/apisix/blob/master/apisix/plugins/limit-count.lua#L37

##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,229 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      rules={[
+        { required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_host` },
+        { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }
+      ]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_password` }]}
+      validateTrigger={['onChange', 'onBlur', 'onClick']}
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name` }]}
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                style={{ marginBottom: 0 }}
+                required
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        noStyle
+                        validateTrigger={['onChange', 'onBlur', 'onClick']}
+                        rules={[{ required: true, message: `${formatMessage({ id: 'component.global.pleaseEnter' })} redis_cluster_name` }, { min: 2, message: formatMessage({ id: 'component.pluginForm.limit-count.atLeast2Characters.rule' }) }]}
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: ['', ''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}

Review comment:
       When you submit data and use local policy, will redis_port be 6379?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit 2cf677e5db70fc42489e6798d397ec47603bfa38
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/60740a90b682710008195d54


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit 432530075be58eac60ea5cf06ad9119249f4ed64
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/6076538f5aaa0e0007f256e1


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817605077


   > redist Doms lost when edited once again
   
   > 1. click `enable` button to edit it again, you will get the trouble
   > 
   > @LiteSun
   
   Tks for your report. I will check it.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611285742



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="key"
+        name="key"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.key.tooltip' })}
+      >
+        <Select>
+          {["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for", "consumer_name", "service_id"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      <Form.Item
+        label="rejected_code"
+        name="rejected_code"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.rejected_code.tooltip' })}
+      >
+        <InputNumber min={200} max={599} />
+      </Form.Item>
+      <Form.Item
+        label="policy"
+        name="policy"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.policy.tooltip' })}
+      >
+        <Select onChange={(e: PolicyProps) => { setPoicy(e) }}>
+          {["local", "redis", "redis-cluster"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      { Boolean(policy === 'redis') && <RedisForm />}

Review comment:
       ![image](https://user-images.githubusercontent.com/2106987/114331048-baa84180-9b75-11eb-9687-f1620bebc981.png)
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit bcb2ad0682f790299a9e56a853817bfab324a92a
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/60740ee3d96cf30007070e3c


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611456776



##########
File path: web/src/components/Plugin/locales/zh-CN.ts
##########
@@ -21,4 +21,18 @@ export default {
   'component.step.select.pluginTemplate.select.option': '手动配置',
   'component.plugin.pluginTemplate.tip1': '1. 若路由已配置插件,则插件模板数据将与已配置的插件数据合并。',
   'component.plugin.pluginTemplate.tip2': '2. 插件模板相同的插件会覆盖掉原有的插件。',
+
+  // limit-count
+  'component.pluginForm.limit-count.count.tooltip': '指定时间窗口内的请求数量阈值。',
+  'component.pluginForm.limit-count.time_window.tooltip': '时间窗口的大小(以秒为单位),超过这个时间就会重置。',
+  'component.pluginForm.limit-count.key.tooltip': '用来做请求计数的有效值。例如,可以使用主机名(或服务器区域)作为关键字,以便限制每个主机名规定时间内的请求次数。我们也可以使用客户端地址作为关键字,这样我们就可以避免单个客户端规定时间内多次的连接我们的服务。当前接受的 key 有:"remote_addr"(客户端 IP 地址), "server_addr"(服务端 IP 地址), 请求头中的"X-Forwarded-For" 或 "X-Real-IP", "consumer_name"(consumer 的 username), "service_id" 。',

Review comment:
       refer info![image](https://user-images.githubusercontent.com/31329157/114370167-bd288c80-9bb1-11eb-8c6c-b2fe51eefa7a.png)
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] commented on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] commented on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit 88bd2e48580e83db6cac9ada6e0e966a71f31ff5
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/6072d4bbba496a000855e896


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611195925



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="key"
+        name="key"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.key.tooltip' })}
+      >
+        <Select>
+          {["remote_addr", "server_addr", "http_x_real_ip", "http_x_forwarded_for", "consumer_name", "service_id"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      <Form.Item
+        label="rejected_code"
+        name="rejected_code"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.rejected_code.tooltip' })}
+      >
+        <InputNumber min={200} max={599} />
+      </Form.Item>
+      <Form.Item
+        label="policy"
+        name="policy"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.policy.tooltip' })}
+      >
+        <Select onChange={(e: PolicyProps) => { setPoicy(e) }}>
+          {["local", "redis", "redis-cluster"].map(item => (<Select.Option value={item}>{item}</Select.Option>))}
+        </Select>
+      </Form.Item>
+      { Boolean(policy === 'redis') && <RedisForm />}

Review comment:
       ?
   




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit d8967058b4a81d27075964d6114e3521e3ee2b4b
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] juzhiyuan commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
juzhiyuan commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611386303



##########
File path: web/src/components/Plugin/UI/limit-count.tsx
##########
@@ -0,0 +1,215 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import React, { useState } from 'react';
+import type { FormInstance } from 'antd/es/form';
+import { Button, Col, Form, Input, InputNumber, Row, Select } from 'antd';
+import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons';
+import { useIntl } from 'umi';
+
+type Props = {
+  form: FormInstance;
+};
+
+type PolicyProps = "local" | "redis" | "redis-cluster"
+
+const FORM_ITEM_LAYOUT = {
+  labelCol: {
+    span: 7,
+  },
+  wrapperCol: {
+    span: 10
+  },
+};
+
+const FORM_ITEM_WITHOUT_LABEL = {
+  wrapperCol: {
+    span: 10, offset: 7,
+  },
+};
+
+const removeBtnStyle = {
+  marginLeft: 20,
+  display: 'flex',
+  alignItems: 'center',
+};
+
+const RedisForm: React.FC = () => {
+  const { formatMessage } = useIntl();
+
+  return (<>
+    <Form.Item
+      label="redis_host"
+      name="redis_host"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_host.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_port"
+      name="redis_port"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_port.tooltip' })}
+    >
+      <InputNumber min={1} />
+    </Form.Item>
+    <Form.Item
+      label="redis_password"
+      name="redis_password"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_password.tooltip' })}
+      required
+    >
+      <Input />
+    </Form.Item>
+    <Form.Item
+      label="redis_database"
+      name="redis_database"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_database.tooltip' })}
+    >
+      <InputNumber min={0} />
+    </Form.Item>
+    <Form.Item
+      label="redis_timeout"
+      name="redis_timeout"
+      tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_timeout.tooltip' })}
+    >
+      <InputNumber />
+    </Form.Item>
+  </>)
+}
+
+const RedisClusterForm: React.FC<Props> = () => {
+  const { formatMessage } = useIntl();
+
+  return (
+    <>
+      <Form.Item
+        label="redis_cluster_name"
+        name="redis_cluster_name"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_name.tooltip' })}
+        required
+      >
+        <Input />
+      </Form.Item>
+      <Form.List name="redis_cluster_nodes">
+        {(fields, { add, remove }) => {
+          return (
+            <div>
+              <Form.Item
+                label='redis_cluster_nodes'
+                tooltip={formatMessage({ id: 'component.pluginForm.limit-count.redis_cluster_nodes.tooltip' })}
+                style={{ marginBottom: 0 }}
+              >
+                {fields.map((field, index) => (
+                  <Row style={{ marginBottom: 10 }} gutter={16} key={index}>
+                    <Col>
+                      <Form.Item
+                        {...field}
+                        validateTrigger={['onChange', 'onBlur']}
+                        noStyle
+                      >
+                        <Input />
+                      </Form.Item>
+                    </Col>
+                    <Col style={{ ...removeBtnStyle, marginLeft: -10 }}>
+                      {fields.length > 1 ? (
+                        <MinusCircleOutlined
+                          className="dynamic-delete-button"
+                          onClick={() => {
+                            remove(field.name);
+                          }}
+                        />
+                      ) : null}
+                    </Col>
+                  </Row>
+                ))}
+              </Form.Item>
+
+              <Form.Item {...FORM_ITEM_WITHOUT_LABEL}>
+                <Button
+                  type="dashed"
+                  onClick={() => {
+                    add();
+                  }}
+                >
+                  <PlusOutlined /> {formatMessage({ id: 'component.global.add' })}
+                </Button>
+              </Form.Item>
+            </div>
+          );
+        }}
+      </Form.List>
+    </>)
+}
+
+const LimitCount: React.FC<Props> = ({ form }) => {
+  const [policy, setPoicy] = useState<PolicyProps>('local');
+  const { formatMessage } = useIntl()
+
+  return (
+    <Form
+      form={form}
+      {...FORM_ITEM_LAYOUT}
+      initialValues={{ key: 'remote_addr', redis_cluster_nodes: [''], policy, redis_port: 6379, redis_database: 0, redis_timeout: 1000 }}
+    >
+      <Form.Item
+        label="count"
+        name="count"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.count.tooltip' })}
+        required
+      >
+        <InputNumber min={1} />
+      </Form.Item>
+      <Form.Item
+        label="time_window"
+        name="time_window"
+        tooltip={formatMessage({ id: 'component.pluginForm.limit-count.time_window.tooltip' })}
+        required

Review comment:
       @LiteSun Don't forget to add i18n for those tooltips.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit a1b87a6e5aab37fee1b1b3e3342c7f4f5aa8e2ec
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit edc362b3bdb1167433ae54a867603fcc5db2fe99
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/60755206f96b5b000831b8d7


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit a1b87a6e5aab37fee1b1b3e3342c7f4f5aa8e2ec
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/60754ba889d8b70007123728


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817646820


   > redist Doms lost when edited once again
   
    @liuxiran fixed.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] codecov-io commented on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
codecov-io commented on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817236136


   # [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=h1) Report
   > Merging [#1739](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=desc) (3eb2053) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/30d98afeb9e3e59d28e9a417fc3f7a799de317f1?el=desc) (30d98af) will **decrease** coverage by `19.86%`.
   > The diff coverage is `n/a`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P)](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=tree)
   
   ```diff
   @@             Coverage Diff             @@
   ##           master    #1739       +/-   ##
   ===========================================
   - Coverage   72.15%   52.29%   -19.87%     
   ===========================================
     Files         132       38       -94     
     Lines        5721     2660     -3061     
     Branches      649        0      -649     
   ===========================================
   - Hits         4128     1391     -2737     
   + Misses       1349     1081      -268     
   + Partials      244      188       -56     
   ```
   
   | Flag | Coverage Δ | |
   |---|---|---|
   | backend-e2e-test | `?` | |
   | backend-e2e-test-ginkgo | `?` | |
   | backend-unit-test | `52.29% <ø> (+0.03%)` | :arrow_up: |
   | frontend-e2e-test | `?` | |
   
   Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags#carryforward-flags-in-the-pull-request-comment) to find out more.
   
   | [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=tree) | Coverage Δ | |
   |---|---|---|
   | [api/internal/utils/version.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3V0aWxzL3ZlcnNpb24uZ28=) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
   | [api/internal/filter/request\_id.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9yZXF1ZXN0X2lkLmdv) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
   | [api/internal/core/entity/entity.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvZW50aXR5L2VudGl0eS5nbw==) | `0.00% <0.00%> (-100.00%)` | :arrow_down: |
   | [api/internal/core/store/storehub.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2NvcmUvc3RvcmUvc3RvcmVodWIuZ28=) | `0.00% <0.00%> (-71.03%)` | :arrow_down: |
   | [api/internal/filter/cors.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9jb3JzLmdv) | `0.00% <0.00%> (-66.67%)` | :arrow_down: |
   | [api/internal/filter/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2ZpbHRlci9zY2hlbWEuZ28=) | `0.00% <0.00%> (-55.47%)` | :arrow_down: |
   | [api/internal/utils/consts/api\_error.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL3V0aWxzL2NvbnN0cy9hcGlfZXJyb3IuZ28=) | `0.00% <0.00%> (-50.00%)` | :arrow_down: |
   | [api/internal/handler/data\_loader/route\_import.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvZGF0YV9sb2FkZXIvcm91dGVfaW1wb3J0Lmdv) | `27.41% <0.00%> (-37.50%)` | :arrow_down: |
   | [api/internal/handler/handler.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvaGFuZGxlci5nbw==) | `42.59% <0.00%> (-35.19%)` | :arrow_down: |
   | [api/internal/handler/schema/schema.go](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree#diff-YXBpL2ludGVybmFsL2hhbmRsZXIvc2NoZW1hL3NjaGVtYS5nbw==) | `66.66% <0.00%> (-33.34%)` | :arrow_down: |
   | ... and [117 more](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree-more) | |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=continue).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=footer). Last update [30d98af...3eb2053](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit 80c3e3e5795db751e2f30ca8ba8e63c0208a3270
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/607411ef23458b0007b9cd5f


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] codecov-io edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
codecov-io edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817236136


   # [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) Report
   > Merging [#1739](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (4325300) into [master](https://codecov.io/gh/apache/apisix-dashboard/commit/419128df29cde091554c469a3b4d20a9e1e1e929?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) (419128d) will **increase** coverage by `0.21%`.
   > The diff coverage is `84.84%`.
   
   [![Impacted file tree graph](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/graphs/tree.svg?width=650&height=150&src=pr&token=Q1HERXN96P&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
   
   ```diff
   @@            Coverage Diff             @@
   ##           master    #1739      +/-   ##
   ==========================================
   + Coverage   72.57%   72.79%   +0.21%     
   ==========================================
     Files         113      114       +1     
     Lines        2695     2727      +32     
     Branches      650      655       +5     
   ==========================================
   + Hits         1956     1985      +29     
   - Misses        739      742       +3     
   ```
   
   | Flag | Coverage Δ | |
   |---|---|---|
   | frontend-e2e-test | `72.79% <84.84%> (+0.21%)` | :arrow_up: |
   
   Flags with carried forward coverage won't be shown. [Click here](https://docs.codecov.io/docs/carryforward-flags?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#carryforward-flags-in-the-pull-request-comment) to find out more.
   
   | [Impacted Files](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation) | Coverage Δ | |
   |---|---|---|
   | [web/src/components/Plugin/UI/limit-count.tsx](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-d2ViL3NyYy9jb21wb25lbnRzL1BsdWdpbi9VSS9saW1pdC1jb3VudC50c3g=) | `83.33% <83.33%> (ø)` | |
   | [web/src/components/Plugin/UI/plugin.tsx](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-d2ViL3NyYy9jb21wb25lbnRzL1BsdWdpbi9VSS9wbHVnaW4udHN4) | `69.23% <100.00%> (+5.59%)` | :arrow_up: |
   | [...ages/Route/components/DebugViews/DebugDrawView.tsx](https://codecov.io/gh/apache/apisix-dashboard/pull/1739/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation#diff-d2ViL3NyYy9wYWdlcy9Sb3V0ZS9jb21wb25lbnRzL0RlYnVnVmlld3MvRGVidWdEcmF3Vmlldy50c3g=) | `79.86% <0.00%> (+1.34%)` | :arrow_up: |
   
   ------
   
   [Continue to review full report at Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
   > **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation)
   > `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
   > Powered by [Codecov](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Last update [419128d...4325300](https://codecov.io/gh/apache/apisix-dashboard/pull/1739?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=The+Apache+Software+Foundation).
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* processing.
   
   Building with commit c173197f5659aaa6ed96fc4752c0308382e66f43
   
   https://app.netlify.com/sites/apisix-dashboard/deploys/6072f5d1b55ce1000743ea34


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] netlify[bot] edited a comment on pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
netlify[bot] edited a comment on pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#issuecomment-817287287


   Deploy preview for *apisix-dashboard* ready!
   
   Built with commit bcb2ad0682f790299a9e56a853817bfab324a92a
   
   https://deploy-preview-1739--apisix-dashboard.netlify.app


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [apisix-dashboard] LiteSun commented on a change in pull request #1739: feat: add limit-count plugin

Posted by GitBox <gi...@apache.org>.
LiteSun commented on a change in pull request #1739:
URL: https://github.com/apache/apisix-dashboard/pull/1739#discussion_r611445780



##########
File path: web/cypress/integration/consumer/create-consumer-with-limit-count-plugin-form.spec.js
##########
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/* eslint-disable no-undef */
+
+context('Create and delete consumer with limit-count plugin form', () => {
+  beforeEach(() => {
+    cy.login();
+
+    cy.fixture('selector.json').as('domSelector');
+    cy.fixture('data.json').as('data');
+  });
+
+  const selector = {
+    count: '#count',
+    time_window: '#time_window',
+    redis_timeout: '#time_window',
+    key: '#key',
+    rejected_code: '#rejected_code',
+    policy: '#policy',
+    redis_host: '#redis_host',
+    redis_port: '#redis_port',
+    redis_password: '#redis_password',
+    redis_database: '#redis_database',
+    redis_timeout: '#redis_timeout',
+    redis_cluster_name: '#redis_cluster_name',
+    redis_cluster_nodes_0: '#redis_cluster_nodes_0',
+    redis_cluster_nodes_1: '#redis_cluster_nodes_1',
+  }
+
+  const data = {
+    count: 1,
+    time_window: 1,
+    redis_timeout: 10,
+    rejected_code: 500,
+    redis_host: '127.0.0.1',
+    redis_password: 'redis_password',
+    redis_cluster_name: 'redis_cluster_name',
+    redis_cluster_nodes_0: "redis.cluster1",
+    redis_cluster_nodes_1: "redis.cluster1",

Review comment:
       Not a good default values, will update later




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org