This is an automated email from the ASF dual-hosted git repository.
shuai pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/incubator-answer.git
The following commit(s) were added to refs/heads/dev by this push:
new 9249dd06 Added isInvalid styles for forms (#935)
9249dd06 is described below
commit 9249dd0679a5818d76b324c7c68a81db8a8f6974
Author: Nayan Thulkar <[email protected]>
AuthorDate: Tue May 28 08:59:08 2024 +0530
Added isInvalid styles for forms (#935)
## This PR includes, fixing css style for some of the forms when clicked
is invalid.
Issue:- #927
### Question/ask page

### Question/details page

---------
Co-authored-by: Nayan <[email protected]>
---
cmd/wire_gen.go | 5 +-
ui/pnpm-lock.yaml | 650 ---------------------
.../components/Comment/components/Form/index.tsx | 1 +
.../components/Comment/components/Reply/index.tsx | 195 ++++---
ui/src/components/TagSelector/index.tsx | 6 +
ui/src/components/TextArea/index.tsx | 121 ++--
ui/src/pages/Questions/Ask/index.tsx | 20 +-
.../Detail/components/WriteAnswer/index.tsx | 1 +
8 files changed, 181 insertions(+), 818 deletions(-)
diff --git a/cmd/wire_gen.go b/cmd/wire_gen.go
index 07b7a324..1fa655d8 100644
--- a/cmd/wire_gen.go
+++ b/cmd/wire_gen.go
@@ -1,6 +1,3 @@
-//go:build !wireinject
-// +build !wireinject
-
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -23,6 +20,8 @@
// Code generated by Wire. DO NOT EDIT.
//go:generate go run github.com/google/wire/cmd/wire
+//go:build !wireinject
+// +build !wireinject
package answercmd
diff --git a/ui/pnpm-lock.yaml b/ui/pnpm-lock.yaml
index 638da37d..66974ab7 100644
--- a/ui/pnpm-lock.yaml
+++ b/ui/pnpm-lock.yaml
@@ -1,20 +1,3 @@
-# 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.
-
lockfileVersion: '6.0'
settings:
@@ -243,64 +226,6 @@ importers:
specifier: ^0.8.0
version: 0.8.0
- src/plugins/captcha-basic:
- devDependencies:
- '@typescript-eslint/eslint-plugin':
- specifier: ^6.0.0
- version:
6.11.0(@typescript-eslint/[email protected])([email protected])([email protected])
- '@typescript-eslint/parser':
- specifier: ^6.0.0
- version: 6.11.0([email protected])([email protected])
- '@vitejs/plugin-react-swc':
- specifier: ^3.3.2
- version: 3.5.0([email protected])
- eslint:
- specifier: ^8.45.0
- version: 8.53.0
- eslint-plugin-react-hooks:
- specifier: ^4.6.0
- version: 4.6.0([email protected])
- eslint-plugin-react-refresh:
- specifier: ^0.4.3
- version: 0.4.5([email protected])
- typescript:
- specifier: ^5.0.2
- version: 5.3.2
- vite:
- specifier: ^4.4.5
- version: 4.5.0(@types/[email protected])([email protected])
-
- src/plugins/captcha-google-v2:
- dependencies:
- react-google-recaptcha:
- specifier: ^3.1.0
- version: 3.1.0([email protected])
- devDependencies:
- '@typescript-eslint/eslint-plugin':
- specifier: ^6.0.0
- version:
6.11.0(@typescript-eslint/[email protected])([email protected])([email protected])
- '@typescript-eslint/parser':
- specifier: ^6.0.0
- version: 6.11.0([email protected])([email protected])
- '@vitejs/plugin-react-swc':
- specifier: ^3.3.2
- version: 3.5.0([email protected])
- eslint:
- specifier: ^8.45.0
- version: 8.53.0
- eslint-plugin-react-hooks:
- specifier: ^4.6.0
- version: 4.6.0([email protected])
- eslint-plugin-react-refresh:
- specifier: ^0.4.3
- version: 0.4.5([email protected])
- typescript:
- specifier: ^5.0.2
- version: 5.3.2
- vite:
- specifier: ^4.4.5
- version: 4.5.0(@types/[email protected])([email protected])
-
packages:
/@aashutoshrathi/[email protected]:
@@ -2263,204 +2188,6 @@ packages:
postcss: 8.4.16
postcss-selector-parser: 6.0.10
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [android]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [freebsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==}
- engines: {node: '>=12'}
- cpu: [arm]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==}
- engines: {node: '>=12'}
- cpu: [loong64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==}
- engines: {node: '>=12'}
- cpu: [mips64el]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==}
- engines: {node: '>=12'}
- cpu: [ppc64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==}
- engines: {node: '>=12'}
- cpu: [riscv64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==}
- engines: {node: '>=12'}
- cpu: [s390x]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [linux]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [netbsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [openbsd]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [sunos]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==}
- engines: {node: '>=12'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==}
- engines: {node: '>=12'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /@esbuild/[email protected]:
- resolution: {integrity:
sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==}
- engines: {node: '>=12'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
/@eslint-community/[email protected]([email protected]):
resolution: {integrity:
sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -3262,129 +2989,12 @@ packages:
transitivePeerDependencies:
- supports-color
- /@swc/[email protected]:
- resolution: {integrity:
sha512-XVWFsKe6ei+SsDbwmsuRkYck1SXRpO60Hioa4hoLwR8fxbA9eVp6enZtMxzVVMBi8ej5seZ4HZQeAWepbukiBw==}
- engines: {node: '>=10'}
- cpu: [arm64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-KF/MXrnH1nakm1wbt4XV8FS7kvqD9TGmVxeJ0U4bbvxXMvzeYUurzg3AJUTXYmXDhH/VXOYJE5N5RkwZZPs5iA==}
- engines: {node: '>=10'}
- cpu: [x64]
- os: [darwin]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-p8hikNnAEJrw5vHCtKiFT4hdlQxk1V7vqPmvUDgL/qe2menQDK/i12tbz7/3BEQ4UqUPnvwpmVn2d19RdEMNxw==}
- engines: {node: '>=10'}
- cpu: [arm64]
- os: [linux]
- libc: [glibc]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-BWx/0EeY89WC4q3AaIaBSGfQxkYxIlS3mX19dwy2FWJs/O+fMvF9oLk/CyJPOZzbp+1DjGeeoGFuDYpiNO91JA==}
- engines: {node: '>=10'}
- cpu: [arm64]
- os: [linux]
- libc: [musl]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-XUdGu3dxAkjsahLYnm8WijPfKebo+jHgHphDxaW0ovI6sTdmEGFDew7QzKZRlbYL2jRkUuuKuDGvD6lO5frmhA==}
- engines: {node: '>=10'}
- cpu: [x64]
- os: [linux]
- libc: [glibc]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-PhoXKf+f0OaNW/GCuXjJ0/KfK9EJX7z2gko+7nVnEA0p3aaPtbP6cq1Ubbl6CMoPL+Ci3gZ7nYumDqXNc3CtLQ==}
- engines: {node: '>=10'}
- cpu: [x64]
- os: [linux]
- libc: [musl]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-PwLADZN6F9cXn4Jw52FeP/MCLVHm8vwouZZSOoOScDtihjY495SSjdPnlosMaRSR4wJQssGwiD/4MbpgQPqbAw==}
- engines: {node: '>=10'}
- cpu: [arm64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-0f6nicKSLlDKlyPRl2JEmkpBV4aeDfRQg6n8mPqgL7bliZIcDahG0ej+HxgNjZfS3e0yjDxsNRa6sAqWU2Z60A==}
- engines: {node: '>=10'}
- cpu: [ia32]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-b7J0rPoMkRTa3XyUGt8PwCaIBuYWsL2DqbirrQKRESzgCvif5iNpqaM6kjIjI/5y5q1Ycv564CB51YDpiS8EtQ==}
- engines: {node: '>=10'}
- cpu: [x64]
- os: [win32]
- requiresBuild: true
- dev: true
- optional: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-7dKgTyxJjlrMwFZYb1auj3Xq0D8ZBe+5oeIgfMlRU05doXZypYJe0LAk0yjj3WdbwYzpF+T1PLxwTWizI0pckw==}
- engines: {node: '>=10'}
- requiresBuild: true
- peerDependencies:
- '@swc/helpers': ^0.5.0
- peerDependenciesMeta:
- '@swc/helpers':
- optional: true
- dependencies:
- '@swc/counter': 0.1.2
- '@swc/types': 0.1.5
- optionalDependencies:
- '@swc/core-darwin-arm64': 1.3.100
- '@swc/core-darwin-x64': 1.3.100
- '@swc/core-linux-arm64-gnu': 1.3.100
- '@swc/core-linux-arm64-musl': 1.3.100
- '@swc/core-linux-x64-gnu': 1.3.100
- '@swc/core-linux-x64-musl': 1.3.100
- '@swc/core-win32-arm64-msvc': 1.3.100
- '@swc/core-win32-ia32-msvc': 1.3.100
- '@swc/core-win32-x64-msvc': 1.3.100
- dev: true
-
- /@swc/[email protected]:
- resolution: {integrity:
sha512-9F4ys4C74eSTEUNndnER3VJ15oru2NumfQxS8geE+f3eB5xvfxpWyqE5XlVnxb/R14uoXi6SLbBwwiDSkv+XEw==}
- dev: true
-
/@swc/[email protected]:
resolution: {integrity:
sha512-FaruWX6KdudYloq1AHD/4nU+UsMTdNE8CKyrseXWEcgjDAbvkwJg2QGPAnfIJLIWsjZOSPLOAykK6fuYp4vp4A==}
dependencies:
tslib: 2.6.2
dev: false
- /@swc/[email protected]:
- resolution: {integrity:
sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==}
- dev: true
-
/@testing-library/[email protected]:
resolution: {integrity:
sha512-oEvsm2B/WtcHKE+IcEeeCqNU/ltFGaVyGbpcm4g/2ytuT49jrlH9x5qRKL/H3A6yfM4YAbSbC0ceT5+9CEXnLg==}
engines: {node: '>=12'}
@@ -3813,35 +3423,6 @@ packages:
- supports-color
dev: true
-
/@typescript-eslint/[email protected](@typescript-eslint/[email protected])([email protected])([email protected]):
- resolution: {integrity:
sha512-uXnpZDc4VRjY4iuypDBKzW1rz9T5YBBK0snMn8MaTSNd2kMlj50LnLBABELjJiOL5YHk7ZD8hbSpI9ubzqYI0w==}
- engines: {node: ^16.0.0 || >=18.0.0}
- peerDependencies:
- '@typescript-eslint/parser': ^6.0.0 || ^6.0.0-alpha
- eslint: ^7.0.0 || ^8.0.0
- typescript: '*'
- peerDependenciesMeta:
- typescript:
- optional: true
- dependencies:
- '@eslint-community/regexpp': 4.10.0
- '@typescript-eslint/parser': 6.11.0([email protected])([email protected])
- '@typescript-eslint/scope-manager': 6.11.0
- '@typescript-eslint/type-utils': 6.11.0([email protected])([email protected])
- '@typescript-eslint/utils': 6.11.0([email protected])([email protected])
- '@typescript-eslint/visitor-keys': 6.11.0
- debug: 4.3.4
- eslint: 8.53.0
- graphemer: 1.4.0
- ignore: 5.2.4
- natural-compare: 1.4.0
- semver: 7.5.4
- ts-api-utils: 1.0.3([email protected])
- typescript: 5.3.2
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@typescript-eslint/[email protected]([email protected])([email protected]):
resolution: {integrity:
sha512-kzXBRfvGlicgGk4CYuRUqKvwc2s3wHXNssUWWJU18bhMRxriFm3BZWyQ6vEHBRpEIMKB6b7MIQHO+9lYlts19w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -3894,27 +3475,6 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/[email protected]([email protected])([email protected]):
- resolution: {integrity:
sha512-+whEdjk+d5do5nxfxx73oanLL9ghKO3EwM9kBCkUtWMRwWuPaFv9ScuqlYfQ6pAD6ZiJhky7TZ2ZYhrMsfMxVQ==}
- engines: {node: ^16.0.0 || >=18.0.0}
- peerDependencies:
- eslint: ^7.0.0 || ^8.0.0
- typescript: '*'
- peerDependenciesMeta:
- typescript:
- optional: true
- dependencies:
- '@typescript-eslint/scope-manager': 6.11.0
- '@typescript-eslint/types': 6.11.0
- '@typescript-eslint/typescript-estree': 6.11.0([email protected])
- '@typescript-eslint/visitor-keys': 6.11.0
- debug: 4.3.4
- eslint: 8.53.0
- typescript: 5.3.2
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@typescript-eslint/[email protected]:
resolution: {integrity:
sha512-ByhHIuNyKD9giwkkLqzezZ9y5bALW8VNY6xXcP+VxoH4JBDKjU5WNnsiD4HJdglHECdV+lyaxhvQjTUbRboiTA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -3969,26 +3529,6 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/[email protected]([email protected])([email protected]):
- resolution: {integrity:
sha512-nA4IOXwZtqBjIoYrJcYxLRO+F9ri+leVGoJcMW1uqr4r1Hq7vW5cyWrA43lFbpRvQ9XgNrnfLpIkO3i1emDBIA==}
- engines: {node: ^16.0.0 || >=18.0.0}
- peerDependencies:
- eslint: ^7.0.0 || ^8.0.0
- typescript: '*'
- peerDependenciesMeta:
- typescript:
- optional: true
- dependencies:
- '@typescript-eslint/typescript-estree': 6.11.0([email protected])
- '@typescript-eslint/utils': 6.11.0([email protected])([email protected])
- debug: 4.3.4
- eslint: 8.53.0
- ts-api-utils: 1.0.3([email protected])
- typescript: 5.3.2
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@typescript-eslint/[email protected]:
resolution: {integrity:
sha512-HHu4yMjJ7i3Cb+8NUuRCdOGu2VMkfmKyIJsOr9PfkBVYLYrtMCK/Ap50Rpov+iKpxDTfnqvDbuPLgBE5FwUNfA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -4039,27 +3579,6 @@ packages:
- supports-color
dev: true
- /@typescript-eslint/[email protected]([email protected]):
- resolution: {integrity:
sha512-Aezzv1o2tWJwvZhedzvD5Yv7+Lpu1by/U1LZ5gLc4tCx8jUmuSCMioPFRjliN/6SJIvY6HpTtJIWubKuYYYesQ==}
- engines: {node: ^16.0.0 || >=18.0.0}
- peerDependencies:
- typescript: '*'
- peerDependenciesMeta:
- typescript:
- optional: true
- dependencies:
- '@typescript-eslint/types': 6.11.0
- '@typescript-eslint/visitor-keys': 6.11.0
- debug: 4.3.4
- globby: 11.1.0
- is-glob: 4.0.3
- semver: 7.5.4
- ts-api-utils: 1.0.3([email protected])
- typescript: 5.3.2
- transitivePeerDependencies:
- - supports-color
- dev: true
-
/@typescript-eslint/[email protected]([email protected])([email protected]):
resolution: {integrity:
sha512-6sdeYaBgk9Fh7N2unEXGz+D+som2QCQGPAf1SxrkEr+Z32gMreQ0rparXTNGRRfYUWk/JzbGdcM8NSSd6oqnTA==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -4096,25 +3615,6 @@ packages:
- typescript
dev: true
- /@typescript-eslint/[email protected]([email protected])([email protected]):
- resolution: {integrity:
sha512-p23ibf68fxoZy605dc0dQAEoUsoiNoP3MD9WQGiHLDuTSOuqoTsa4oAy+h3KDkTcxbbfOtUjb9h3Ta0gT4ug2g==}
- engines: {node: ^16.0.0 || >=18.0.0}
- peerDependencies:
- eslint: ^7.0.0 || ^8.0.0
- dependencies:
- '@eslint-community/eslint-utils': 4.4.0([email protected])
- '@types/json-schema': 7.0.15
- '@types/semver': 7.5.5
- '@typescript-eslint/scope-manager': 6.11.0
- '@typescript-eslint/types': 6.11.0
- '@typescript-eslint/typescript-estree': 6.11.0([email protected])
- eslint: 8.53.0
- semver: 7.5.4
- transitivePeerDependencies:
- - supports-color
- - typescript
- dev: true
-
/@typescript-eslint/[email protected]:
resolution: {integrity:
sha512-MxnrdIyArnTi+XyFLR+kt/uNAcdOnmT+879os7qDRI+EYySR4crXJq9BXPfRzzLGq0wgxkwidrCJ9WCAoacm1w==}
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -4133,17 +3633,6 @@ packages:
/@ungap/[email protected]:
resolution: {integrity:
sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
- /@vitejs/[email protected]([email protected]):
- resolution: {integrity:
sha512-1PrOvAaDpqlCV+Up8RkAh9qaiUjoDUcjtttyhXDKw53XA6Ve16SOp6cCOpRs8Dj8DqUQs6eTW5YkLcLJjrXAig==}
- peerDependencies:
- vite: ^4 || ^5
- dependencies:
- '@swc/core': 1.3.100
- vite: 4.5.0(@types/[email protected])([email protected])
- transitivePeerDependencies:
- - '@swc/helpers'
- dev: true
-
/@webassemblyjs/[email protected]:
resolution: {integrity:
sha512-ukBh14qFLjxTQNTXocdyksN5QdM28S1CxHt2rdskFyL+xFV7VremuBLVbmCePj+URalXBENx/9Lm7lnhihtCSw==}
dependencies:
@@ -6243,36 +5732,6 @@ packages:
is-date-object: 1.0.5
is-symbol: 1.0.4
- /[email protected]:
- resolution: {integrity:
sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==}
- engines: {node: '>=12'}
- hasBin: true
- requiresBuild: true
- optionalDependencies:
- '@esbuild/android-arm': 0.18.20
- '@esbuild/android-arm64': 0.18.20
- '@esbuild/android-x64': 0.18.20
- '@esbuild/darwin-arm64': 0.18.20
- '@esbuild/darwin-x64': 0.18.20
- '@esbuild/freebsd-arm64': 0.18.20
- '@esbuild/freebsd-x64': 0.18.20
- '@esbuild/linux-arm': 0.18.20
- '@esbuild/linux-arm64': 0.18.20
- '@esbuild/linux-ia32': 0.18.20
- '@esbuild/linux-loong64': 0.18.20
- '@esbuild/linux-mips64el': 0.18.20
- '@esbuild/linux-ppc64': 0.18.20
- '@esbuild/linux-riscv64': 0.18.20
- '@esbuild/linux-s390x': 0.18.20
- '@esbuild/linux-x64': 0.18.20
- '@esbuild/netbsd-x64': 0.18.20
- '@esbuild/openbsd-x64': 0.18.20
- '@esbuild/sunos-x64': 0.18.20
- '@esbuild/win32-arm64': 0.18.20
- '@esbuild/win32-ia32': 0.18.20
- '@esbuild/win32-x64': 0.18.20
- dev: true
-
/[email protected]:
resolution: {integrity:
sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==}
engines: {node: '>=6'}
@@ -6685,14 +6144,6 @@ packages:
dependencies:
eslint: 8.53.0
- /[email protected]([email protected]):
- resolution: {integrity:
sha512-D53FYKJa+fDmZMtriODxvhwrO+IOqrxoEo21gMA0sjHdU6dPVH4OhyFip9ypl8HOF5RV5KdTo+rBQLvnY2cO8w==}
- peerDependencies:
- eslint: '>=7'
- dependencies:
- eslint: 8.53.0
- dev: true
-
/[email protected]([email protected]):
resolution: {integrity:
sha512-73QQMKALArI8/7xGLNI/3LylrEYrlKZSb5C9+q3OtOewTnMQi5cT+aE9E41sLCmli3I9PGGmD1yiZydyo4FEPw==}
engines: {node: '>=4'}
@@ -7433,12 +6884,6 @@ packages:
resolution: {integrity:
sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==}
hasBin: true
- /[email protected]:
- resolution: {integrity:
sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==}
- dependencies:
- react-is: 16.13.1
- dev: false
-
/[email protected]:
resolution: {integrity:
sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==}
engines: {node: '>= 6.0.0'}
@@ -9070,12 +8515,6 @@ packages:
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
hasBin: true
- /[email protected]:
- resolution: {integrity:
sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
- dev: true
-
/[email protected]:
resolution: {integrity:
sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
@@ -10193,15 +9632,6 @@ packages:
picocolors: 1.0.0
source-map-js: 1.0.2
- /[email protected]:
- resolution: {integrity:
sha512-D/kj5JNu6oo2EIy+XL/26JEDTlIbB8hw85G8StOE6L74RQAVVP5rej6wxCNqyMbR4RkPfqvezVbPw81Ngd6Kcw==}
- engines: {node: ^10 || ^12 || >=14}
- dependencies:
- nanoid: 3.3.7
- picocolors: 1.0.0
- source-map-js: 1.0.2
- dev: true
-
/[email protected]:
resolution: {integrity:
sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==}
engines: {node: '>= 0.8.0'}
@@ -10417,16 +9847,6 @@ packages:
semver: 5.7.1
dev: true
- /[email protected]([email protected]):
- resolution: {integrity:
sha512-bCpkbm9JiAuMGhkqoAiC0lLkb40DJ0HOEJIku+9JDjxX3Rcs+ztEOG13wbrOskt3n2DTrjshhaQ/iay+SnGg5Q==}
- peerDependencies:
- react: '>=16.4.1'
- dependencies:
- hoist-non-react-statics: 3.3.2
- prop-types: 15.8.1
- react: 18.2.0
- dev: false
-
/[email protected](@types/[email protected])([email protected])([email protected]):
resolution: {integrity:
sha512-87gRP69VAfeU2yKgp8RI3HvzhPNrnYIV2QNranYXataz3ef+k7OhvKGGdxQLQfUsQ2RTmlY66tn4pdFrZ94hNg==}
peerDependencies:
@@ -10511,16 +9931,6 @@ packages:
resolution: {integrity:
sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==}
dev: false
- /[email protected]([email protected]):
- resolution: {integrity:
sha512-cYW2/DWas8nEKZGD7SCu9BSuVz8iOcOLHChHyi7upUuVhkpkhYG/6N3KDiTQ3XAiZ2UAZkfvYKMfAHOzBOcGEg==}
- peerDependencies:
- react: '>=16.4.1'
- dependencies:
- prop-types: 15.8.1
- react: 18.2.0
- react-async-script: 1.2.0([email protected])
- dev: false
-
/[email protected]([email protected])([email protected]):
resolution: {integrity:
sha512-9jZ57/dAn9t3q6hneQS0wukqC2ENOBgMNVEhb/ZG9ZSxUetzVIw4iAmEU38IaVg3QGYauQPhSeUTuIUtFglWpg==}
peerDependencies:
@@ -10995,14 +10405,6 @@ packages:
optionalDependencies:
fsevents: 2.3.3
- /[email protected]:
- resolution: {integrity:
sha512-oWzmBZwvYrU0iJHtDmhsm662rC15FRXmcjCk1xD771dFDx5jJ02ufAQQTn0etB2emNk4J9EZg/yWKpsn9BWGRw==}
- engines: {node: '>=14.18.0', npm: '>=8.0.0'}
- hasBin: true
- optionalDependencies:
- fsevents: 2.3.3
- dev: true
-
/[email protected]:
resolution: {integrity:
sha512-XcT5rBksx1QdIhlFOCtgZkB99ZEouFZ1E2Kc2LHqNW13U3/74YGdkQRmThTwxy4QIyookibDKYZOPqX//6BlAg==}
engines: {node: '>=12'}
@@ -11970,15 +11372,6 @@ packages:
typescript: 4.9.5
dev: true
- /[email protected]([email protected]):
- resolution: {integrity:
sha512-wNMeqtMz5NtwpT/UZGY5alT+VoKdSsOOP/kqHFcUW1P/VRhH2wJ48+DN2WwUliNbQ976ETwDL0Ifd2VVvgonvg==}
- engines: {node: '>=16.13.0'}
- peerDependencies:
- typescript: '>=4.2.0'
- dependencies:
- typescript: 5.3.2
- dev: true
-
/[email protected](@types/[email protected])([email protected]):
resolution: {integrity:
sha512-NtVysVPkxxrwFGUUxGYhfux8k78pQB3JqYBXlLRZgdGUqTO5wU/UyHop5p70iEbGhB7q5KmiZiU0Y3KlJrScEw==}
hasBin: true
@@ -12131,12 +11524,6 @@ packages:
engines: {node: '>=4.2.0'}
hasBin: true
- /[email protected]:
- resolution: {integrity:
sha512-6l+RyNy7oAHDfxC4FzSJcz9vnjTKxrLpDG5M2Vu4SHRVNg6xzqZp6LYSR9zjqQTu8DU/f5xwxUdADOkbrIX2gQ==}
- engines: {node: '>=14.17'}
- hasBin: true
- dev: true
-
/[email protected]:
resolution: {integrity:
sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==}
dependencies:
@@ -12303,43 +11690,6 @@ packages:
resolution: {integrity:
sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==}
engines: {node: '>= 0.8'}
- /[email protected](@types/[email protected])([email protected]):
- resolution: {integrity:
sha512-ulr8rNLA6rkyFAlVWw2q5YJ91v098AFQ2R0PRFwPzREXOUJQPtFUG0t+/ZikhaOCDqFoDhN6/v8Sq0o4araFAw==}
- engines: {node: ^14.18.0 || >=16.0.0}
- hasBin: true
- peerDependencies:
- '@types/node': '>= 14'
- less: '*'
- lightningcss: ^1.21.0
- sass: '*'
- stylus: '*'
- sugarss: '*'
- terser: ^5.4.0
- peerDependenciesMeta:
- '@types/node':
- optional: true
- less:
- optional: true
- lightningcss:
- optional: true
- sass:
- optional: true
- stylus:
- optional: true
- sugarss:
- optional: true
- terser:
- optional: true
- dependencies:
- '@types/node': 16.11.59
- esbuild: 0.18.20
- postcss: 8.4.32
- rollup: 3.29.4
- sass: 1.54.9
- optionalDependencies:
- fsevents: 2.3.3
- dev: true
-
/[email protected]:
resolution: {integrity:
sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
engines: {node: '>=0.10.0'}
diff --git a/ui/src/components/Comment/components/Form/index.tsx
b/ui/src/components/Comment/components/Form/index.tsx
index 12368193..ea1835eb 100644
--- a/ui/src/components/Comment/components/Form/index.tsx
+++ b/ui/src/components/Comment/components/Form/index.tsx
@@ -84,6 +84,7 @@ const Index = ({
size="sm"
value={type === 'edit' ? parseEditMentionUser(value) : value}
onChange={handleChange}
+ isInvalid={validationErrorMsg !== ''}
/>
</Mentions>
<div className="form-text">{t(`tip_${mode}`)}</div>
diff --git a/ui/src/components/Comment/components/Reply/index.tsx
b/ui/src/components/Comment/components/Reply/index.tsx
index 2bd722f2..fcf9532b 100644
--- a/ui/src/components/Comment/components/Reply/index.tsx
+++ b/ui/src/components/Comment/components/Reply/index.tsx
@@ -1,95 +1,100 @@
-/*
- * 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 { useState, memo } from 'react';
-import { Button, Form } from 'react-bootstrap';
-import { useTranslation } from 'react-i18next';
-
-import classNames from 'classnames';
-
-import { TextArea, Mentions } from '@/components';
-import { usePageUsers, usePromptWithUnload } from '@/hooks';
-
-const Index = ({ userName, onSendReply, onCancel, mode }) => {
- const [value, setValue] = useState('');
- const pageUsers = usePageUsers();
- const { t } = useTranslation('translation', { keyPrefix: 'comment' });
- const [validationErrorMsg, setValidationErrorMsg] = useState('');
-
- usePromptWithUnload({
- when: Boolean(value),
- });
-
- const handleChange = (e) => {
- setValue(e.target.value);
- };
- const handleSelected = (val) => {
- setValue(val);
- };
- const handleSendReply = () => {
- onSendReply(value).catch((ex) => {
- if (ex.isError) {
- setValidationErrorMsg(ex.msg);
- }
- });
- };
-
- return (
- <div className="mb-2">
- <div className="small mb-2">
- {t('reply_to')} {userName}
- </div>
- <div className="d-flex mb-1 align-items-start flex-column flex-md-row">
- <div className="w-100">
- <div
- className={classNames('custom-form-control', {
- 'is-invalid': validationErrorMsg,
- })}>
- <Mentions
- pageUsers={pageUsers.getUsers()}
- onSelected={handleSelected}>
- <TextArea size="sm" value={value} onChange={handleChange} />
- </Mentions>
- <div className="form-text">{t(`tip_${mode}`)}</div>
- </div>
- <Form.Control.Feedback type="invalid">
- {validationErrorMsg}
- </Form.Control.Feedback>
- </div>
- <div className="d-flex flex-row flex-md-column ms-0 ms-md-2 mt-2
mt-md-0">
- <Button
- size="sm"
- className="text-nowrap"
- onClick={() => handleSendReply()}>
- {t('btn_add_comment')}
- </Button>
- <Button
- variant="link"
- size="sm"
- className="text-nowrap btn-no-border ms-2 ms-md-0"
- onClick={onCancel}>
- {t('btn_cancel')}
- </Button>
- </div>
- </div>
- </div>
- );
-};
-
-export default memo(Index);
+/*
+ * 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 { useState, memo } from 'react';
+import { Button, Form } from 'react-bootstrap';
+import { useTranslation } from 'react-i18next';
+
+import classNames from 'classnames';
+
+import { TextArea, Mentions } from '@/components';
+import { usePageUsers, usePromptWithUnload } from '@/hooks';
+
+const Index = ({ userName, onSendReply, onCancel, mode }) => {
+ const [value, setValue] = useState('');
+ const pageUsers = usePageUsers();
+ const { t } = useTranslation('translation', { keyPrefix: 'comment' });
+ const [validationErrorMsg, setValidationErrorMsg] = useState('');
+
+ usePromptWithUnload({
+ when: Boolean(value),
+ });
+
+ const handleChange = (e) => {
+ setValue(e.target.value);
+ };
+ const handleSelected = (val) => {
+ setValue(val);
+ };
+ const handleSendReply = () => {
+ onSendReply(value).catch((ex) => {
+ if (ex.isError) {
+ setValidationErrorMsg(ex.msg);
+ }
+ });
+ };
+
+ return (
+ <div className="mb-2">
+ <div className="small mb-2">
+ {t('reply_to')} {userName}
+ </div>
+ <div className="d-flex mb-1 align-items-start flex-column flex-md-row">
+ <div className="w-100">
+ <div
+ className={classNames('custom-form-control', {
+ 'is-invalid': validationErrorMsg,
+ })}>
+ <Mentions
+ pageUsers={pageUsers.getUsers()}
+ onSelected={handleSelected}>
+ <TextArea
+ size="sm"
+ value={value}
+ onChange={handleChange}
+ isInvalid={validationErrorMsg !== ''}
+ />
+ </Mentions>
+ <div className="form-text">{t(`tip_${mode}`)}</div>
+ </div>
+ <Form.Control.Feedback type="invalid">
+ {validationErrorMsg}
+ </Form.Control.Feedback>
+ </div>
+ <div className="d-flex flex-row flex-md-column ms-0 ms-md-2 mt-2
mt-md-0">
+ <Button
+ size="sm"
+ className="text-nowrap"
+ onClick={() => handleSendReply()}>
+ {t('btn_add_comment')}
+ </Button>
+ <Button
+ variant="link"
+ size="sm"
+ className="text-nowrap btn-no-border ms-2 ms-md-0"
+ onClick={onCancel}>
+ {t('btn_cancel')}
+ </Button>
+ </div>
+ </div>
+ </div>
+ );
+};
+
+export default memo(Index);
diff --git a/ui/src/components/TagSelector/index.tsx
b/ui/src/components/TagSelector/index.tsx
index de82599e..25ec293d 100644
--- a/ui/src/components/TagSelector/index.tsx
+++ b/ui/src/components/TagSelector/index.tsx
@@ -40,6 +40,8 @@ interface IProps {
maxTagLength?: number;
showRequiredTag?: boolean;
autoFocus?: boolean;
+ isInvalid?: boolean;
+ errMsg?: string;
}
let timer;
@@ -52,6 +54,8 @@ const TagSelector: FC<IProps> = ({
maxTagLength = 0,
showRequiredTag = false,
autoFocus = false,
+ isInvalid = false,
+ errMsg = '',
}) => {
const containerRef = useRef<HTMLDivElement>(null);
const inputRef = useRef<HTMLInputElement>(null);
@@ -341,6 +345,7 @@ const TagSelector: FC<IProps> = ({
className={classNames(
'tag-selector-wrap form-control position-relative p-0',
focusState ? 'tag-selector-wrap--focus' : '',
+ isInvalid ? 'is-invalid' : '',
)}
onFocus={handleTagSelectorFocus}
onKeyDown={handleKeyDown}>
@@ -423,6 +428,7 @@ const TagSelector: FC<IProps> = ({
</Dropdown.Menu>
</div>
{!hiddenDescription && <Form.Text>{t('hint')}</Form.Text>}
+ <Form.Control.Feedback type="invalid">{errMsg}</Form.Control.Feedback>
</div>
);
};
diff --git a/ui/src/components/TextArea/index.tsx
b/ui/src/components/TextArea/index.tsx
index 5976d0d2..b0c6d9a1 100644
--- a/ui/src/components/TextArea/index.tsx
+++ b/ui/src/components/TextArea/index.tsx
@@ -1,56 +1,65 @@
-/*
- * 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 { FC, useRef, useEffect, memo } from 'react';
-import { FormControl, FormControlProps } from 'react-bootstrap';
-
-const TextArea: FC<
- FormControlProps & { rows?: number; autoFocus?: boolean }
-> = ({ value, onChange, size, rows = 1, autoFocus = true, ...rest }) => {
- const ref = useRef<HTMLTextAreaElement>(null);
-
- const autoGrow = () => {
- if (ref.current) {
- ref.current.style.height = 'auto';
- ref.current.style.height = `${ref.current.scrollHeight}px`;
- }
- };
-
- useEffect(() => {
- if (ref.current && value) {
- autoGrow();
- }
- }, [ref, value]);
-
- return (
- <FormControl
- as="textarea"
- className="resize-none font-monospace"
- rows={rows}
- size={size}
- value={value}
- onChange={onChange}
- autoFocus={autoFocus}
- ref={ref}
- onInput={autoGrow}
- {...rest}
- />
- );
-};
-export default memo(TextArea);
+/*
+ * 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 { FC, useRef, useEffect, memo } from 'react';
+import { FormControl, FormControlProps } from 'react-bootstrap';
+
+const TextArea: FC<
+ FormControlProps & { rows?: number; autoFocus?: boolean }
+> = ({
+ value,
+ onChange,
+ size,
+ rows = 1,
+ autoFocus = true,
+ isInvalid,
+ ...rest
+}) => {
+ const ref = useRef<HTMLTextAreaElement>(null);
+
+ const autoGrow = () => {
+ if (ref.current) {
+ ref.current.style.height = 'auto';
+ ref.current.style.height = `${ref.current.scrollHeight}px`;
+ }
+ };
+
+ useEffect(() => {
+ if (ref.current && value) {
+ autoGrow();
+ }
+ }, [ref, value]);
+
+ return (
+ <FormControl
+ as="textarea"
+ className="resize-none font-monospace"
+ rows={rows}
+ size={size}
+ value={value}
+ onChange={onChange}
+ autoFocus={autoFocus}
+ ref={ref}
+ onInput={autoGrow}
+ isInvalid={isInvalid}
+ {...rest}
+ />
+ );
+};
+export default memo(TextArea);
diff --git a/ui/src/pages/Questions/Ask/index.tsx
b/ui/src/pages/Questions/Ask/index.tsx
index 1bc92cc7..bf06d1a3 100644
--- a/ui/src/pages/Questions/Ask/index.tsx
+++ b/ui/src/pages/Questions/Ask/index.tsx
@@ -446,25 +446,21 @@ const Ask = () => {
autoFocus
contentEditable
/>
-
<Form.Control.Feedback type="invalid">
{formData.title.errorMsg}
</Form.Control.Feedback>
{bool && <SearchQuestion similarQuestions={similarQuestions} />}
</Form.Group>
+
<Form.Group controlId="content">
<Form.Label>{t('form.fields.body.label')}</Form.Label>
- <Form.Control
- defaultValue={formData.content.value}
- isInvalid={formData.content.isInvalid}
- hidden
- />
<Editor
value={formData.content.value}
onChange={handleContentChange}
className={classNames(
'form-control p-0',
focusType === 'content' && 'focus',
+ formData.content.isInvalid && 'is-invalid',
)}
onFocus={() => {
setForceType('content');
@@ -478,23 +474,19 @@ const Ask = () => {
{formData.content.errorMsg}
</Form.Control.Feedback>
</Form.Group>
+
<Form.Group controlId="tags" className="my-3">
<Form.Label>{t('form.fields.tags.label')}</Form.Label>
- <Form.Control
- defaultValue={JSON.stringify(formData.tags.value)}
- isInvalid={formData.tags.isInvalid}
- hidden
- />
<TagSelector
value={formData.tags.value}
onChange={handleTagsChange}
showRequiredTag
maxTagLength={5}
+ isInvalid={formData.tags.isInvalid}
+ errMsg={formData.tags.errorMsg}
/>
- <Form.Control.Feedback type="invalid">
- {formData.tags.errorMsg}
- </Form.Control.Feedback>
</Form.Group>
+
{isEdit && (
<Form.Group controlId="edit_summary" className="my-3">
<Form.Label>{t('form.fields.edit_summary.label')}</Form.Label>
diff --git a/ui/src/pages/Questions/Detail/components/WriteAnswer/index.tsx
b/ui/src/pages/Questions/Detail/components/WriteAnswer/index.tsx
index 456fbe37..5627231d 100644
--- a/ui/src/pages/Questions/Detail/components/WriteAnswer/index.tsx
+++ b/ui/src/pages/Questions/Detail/components/WriteAnswer/index.tsx
@@ -266,6 +266,7 @@ const Index: FC<Props> = ({ visible = false, data, callback
}) => {
className={classNames(
'form-control p-0',
focusType === 'answer' && 'focus',
+ formData.content.isInvalid && 'is-invalid',
)}
value={formData.content.value}
autoFocus={editorFocusState}