You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

WordsetEditPage.js 8.7 kB

3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // Copyright 2023 The casbin Authors. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. import React from "react";
  15. import {Button, Card, Col, Input, InputNumber, Row, Select} from "antd";
  16. import * as WordsetBackend from "./backend/WordsetBackend";
  17. import * as Setting from "./Setting";
  18. import i18next from "i18next";
  19. import VectorTable from "./VectorTable";
  20. import WordsetGraph from "./WordsetGraph";
  21. import * as VectorsetBackend from "./backend/VectorsetBackend";
  22. const {Option} = Select;
  23. class WordsetEditPage extends React.Component {
  24. constructor(props) {
  25. super(props);
  26. this.state = {
  27. classes: props,
  28. wordsetName: props.match.params.wordsetName,
  29. wordset: null,
  30. vectorsets: null,
  31. matchLoading: false,
  32. };
  33. }
  34. UNSAFE_componentWillMount() {
  35. this.getWordset();
  36. this.getVectorsets();
  37. }
  38. getWordset() {
  39. WordsetBackend.getWordset(this.props.account.name, this.state.wordsetName)
  40. .then((wordset) => {
  41. if (wordset.status === "ok") {
  42. this.setState({
  43. wordset: wordset.data,
  44. });
  45. } else {
  46. Setting.showMessage("error", `Failed to get wordset: ${wordset.msg}`);
  47. }
  48. });
  49. }
  50. getVectorsets() {
  51. VectorsetBackend.getVectorsets(this.props.account.name)
  52. .then((res) => {
  53. if (res.status === "ok") {
  54. this.setState({
  55. vectorsets: res.data,
  56. });
  57. } else {
  58. Setting.showMessage("error", `Failed to get vectorsets: ${res.msg}`);
  59. }
  60. });
  61. }
  62. parseWordsetField(key, value) {
  63. if (["score"].includes(key)) {
  64. value = Setting.myParseInt(value);
  65. }
  66. return value;
  67. }
  68. updateWordsetField(key, value) {
  69. value = this.parseWordsetField(key, value);
  70. const wordset = this.state.wordset;
  71. wordset[key] = value;
  72. this.setState({
  73. wordset: wordset,
  74. });
  75. }
  76. renderWordset() {
  77. const allWords = this.state.wordset?.vectors.length;
  78. const validWords = this.state.wordset?.vectors.filter(vector => vector.data.length !== 0).length;
  79. return (
  80. <Card size="small" title={
  81. <div>
  82. {i18next.t("wordset:Edit Wordset")}&nbsp;&nbsp;&nbsp;&nbsp;
  83. <Button type="primary" onClick={this.submitWordsetEdit.bind(this)}>{i18next.t("general:Save")}</Button>
  84. </div>
  85. } style={{marginLeft: "5px"}} type="inner">
  86. <Row style={{marginTop: "10px"}} >
  87. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  88. {i18next.t("general:Name")}:
  89. </Col>
  90. <Col span={22} >
  91. <Input value={this.state.wordset.name} onChange={e => {
  92. this.updateWordsetField("name", e.target.value);
  93. }} />
  94. </Col>
  95. </Row>
  96. <Row style={{marginTop: "20px"}} >
  97. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  98. {i18next.t("general:Display name")}:
  99. </Col>
  100. <Col span={22} >
  101. <Input value={this.state.wordset.displayName} onChange={e => {
  102. this.updateWordsetField("displayName", e.target.value);
  103. }} />
  104. </Col>
  105. </Row>
  106. <Row style={{marginTop: "20px"}} >
  107. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  108. {i18next.t("wordset:Vectorset")}:
  109. </Col>
  110. <Col span={22} >
  111. <Select virtual={false} style={{width: "100%"}} value={this.state.wordset.vectorset} onChange={(value => {this.updateWordsetField("vectorset", value);})}>
  112. {
  113. this.state.vectorsets?.map((vectorset, index) => <Option key={index} value={vectorset.name}>{vectorset.name}</Option>)
  114. }
  115. </Select>
  116. </Col>
  117. </Row>
  118. <Row style={{marginTop: "20px"}} >
  119. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  120. {i18next.t("wordset:Match")}:
  121. </Col>
  122. <Col span={22} >
  123. <Button loading={this.state.matchLoading} type="primary" onClick={() => {
  124. this.setState({
  125. matchLoading: true,
  126. });
  127. WordsetBackend.getWordsetMatch(this.props.account.name, this.state.wordsetName)
  128. .then((wordset) => {
  129. if (wordset.status === "ok") {
  130. this.setState({
  131. wordset: wordset.data,
  132. matchLoading: false,
  133. });
  134. } else {
  135. Setting.showMessage("error", `Failed to get wordset: ${wordset.msg}`);
  136. }
  137. });
  138. }}>{i18next.t("wordset:Match")}</Button>
  139. </Col>
  140. </Row>
  141. <Row style={{marginTop: "20px"}} >
  142. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  143. {i18next.t("wordset:Matched")}:
  144. </Col>
  145. <Col span={22} >
  146. <Input value={`${Setting.getPercentage(allWords === 0 ? 0 : validWords / allWords)}% (${validWords} / ${allWords})`} />
  147. </Col>
  148. </Row>
  149. <Row style={{marginTop: "20px"}} >
  150. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  151. {i18next.t("wordset:Distance limit")}:
  152. </Col>
  153. <Col span={22} >
  154. <InputNumber value={this.state.wordset.distanceLimit} onChange={value => {
  155. this.updateWordsetField("distanceLimit", value);
  156. }} />
  157. </Col>
  158. </Row>
  159. <Row style={{marginTop: "20px"}} >
  160. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  161. {i18next.t("wordset:Words")}:
  162. </Col>
  163. <Col span={22} >
  164. <VectorTable
  165. title={i18next.t("wordset:Words")}
  166. table={this.state.wordset.vectors}
  167. wordset={this.state.wordset}
  168. onUpdateTable={(value) => {this.updateWordsetField("vectors", value);}}
  169. />
  170. </Col>
  171. </Row>
  172. <Row style={{marginTop: "20px"}} >
  173. <Col style={{marginTop: "5px"}} span={(Setting.isMobile()) ? 22 : 2}>
  174. {i18next.t("general:Preview")}:
  175. </Col>
  176. <Col span={22} >
  177. <WordsetGraph wordset={this.state.wordset} wordsetName={this.state.wordset.name} />
  178. </Col>
  179. </Row>
  180. </Card>
  181. );
  182. }
  183. submitWordsetEdit() {
  184. const wordset = Setting.deepCopy(this.state.wordset);
  185. WordsetBackend.updateWordset(this.state.wordset.owner, this.state.wordsetName, wordset)
  186. .then((res) => {
  187. if (res.status === "ok") {
  188. if (res.data) {
  189. Setting.showMessage("success", "Successfully saved");
  190. this.setState({
  191. wordsetName: this.state.wordset.name,
  192. });
  193. this.props.history.push(`/wordsets/${this.state.wordset.name}`);
  194. } else {
  195. Setting.showMessage("error", "failed to save: server side failure");
  196. this.updateWordsetField("name", this.state.wordsetName);
  197. }
  198. } else {
  199. Setting.showMessage("error", `failed to save: ${res.msg}`);
  200. }
  201. })
  202. .catch(error => {
  203. Setting.showMessage("error", `failed to save: ${error}`);
  204. });
  205. }
  206. render() {
  207. return (
  208. <div>
  209. <Row style={{width: "100%"}}>
  210. <Col span={1}>
  211. </Col>
  212. <Col span={22}>
  213. {
  214. this.state.wordset !== null ? this.renderWordset() : null
  215. }
  216. </Col>
  217. <Col span={1}>
  218. </Col>
  219. </Row>
  220. <Row style={{margin: 10}}>
  221. <Col span={2}>
  222. </Col>
  223. <Col span={18}>
  224. <Button type="primary" size="large" onClick={this.submitWordsetEdit.bind(this)}>{i18next.t("general:Save")}</Button>
  225. </Col>
  226. </Row>
  227. </div>
  228. );
  229. }
  230. }
  231. export default WordsetEditPage;

基于Casbin的开源AI领域知识库平台