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.

EditTopics.vue 14 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
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
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494
  1. <template>
  2. <div>
  3. <div class="input-search">
  4. <el-input v-model="input" clearable :autofocus="true" @input="changeValue" id="topics_input" @keyup.enter.native="postTopic" :placeholder="$i18n['searchOrCreateTopics']">
  5. </el-input>
  6. <div class="scrolling-menu">
  7. <div v-if="showSearchTopic" class="item-text" v-for="(arr,i) in array" @click="addTopics(i,arr)">
  8. <div class="icon-wrapper">
  9. <i style="line-height: 1.5;color: #303643;font-weight: 900;" v-if="showInitTopic[i]" class="el-icon-check" ></i>
  10. </div>
  11. <div class="text">{{arr.topic_name.toLowerCase()}} </div>
  12. </div>
  13. <div v-if="showInputValue" class="addition item-text" @click="postTopic">
  14. {{$i18n['clickOrEnterToAdd']}}<b class="user-add-label-text">{{input.toLowerCase()}}</b>{{$i18n['topic']}}
  15. </div>
  16. <div v-if="showAddTopic" class="item-text" @click="addPostTopic">
  17. <div class="icon-wrapper">
  18. <i style="line-height: 1.5;color: #303643;font-weight: 900;" v-if="showAddFlage" class="el-icon-check" ></i>
  19. </div>
  20. <div class="text">{{input.toLowerCase()}}</div>
  21. </div>
  22. </div>
  23. </div>
  24. </div>
  25. </template>
  26. <script>
  27. const {AppSubUrl, StaticUrlPrefix, csrf} = window.config;
  28. import $ from 'jquery'
  29. export default {
  30. data() {
  31. return {
  32. input:'',
  33. params:{},
  34. showInputValue:false,
  35. showFlag:-1,
  36. array:[],
  37. showAddTopic:false,
  38. showAddFlage:false,
  39. showSearchTopic:true,
  40. postUrl:'',
  41. arrayTopics:[],
  42. showInitTopic:[],
  43. };
  44. },
  45. methods: {
  46. addTopics(item,array){
  47. if(!this.showInitTopic[item]){
  48. if(this.arrayTopics.includes(array.topic_name)){
  49. return
  50. }
  51. else{
  52. this.arrayTopics.push(array.topic_name)
  53. let topics = this.arrayTopics
  54. let strTopics = topics.join(',')
  55. let data = this.qs.stringify({
  56. _csrf:csrf,
  57. topics:strTopics
  58. })
  59. this.Post(data,topics)
  60. this.$set(this.showInitTopic,item,true)
  61. $('#repo-topics1').children('span').remove()
  62. }
  63. }else{
  64. this.arrayTopics=this.arrayTopics.filter(ele=>{
  65. return ele !== array.topic_name
  66. })
  67. let topics = this.arrayTopics
  68. let strTopics = topics.join(',')
  69. let data = this.qs.stringify({
  70. _csrf:csrf,
  71. topics:strTopics
  72. })
  73. this.Post(data,topics)
  74. this.$set(this.showInitTopic,item,false)
  75. if(this.arrayTopics.length===0){
  76. $('#repo-topics1').append(`<span class="no-description text-italic">${this.$i18n['noTopics']}</span>`)
  77. }else{
  78. $('#repo-topics1').children('span').remove()
  79. }
  80. }
  81. },
  82. changeValue(){
  83. if (this.input === ''){
  84. this.array = this.arrayTopics
  85. let data = []
  86. this.showInitTopic = []
  87. this.array.forEach((element,index) => {
  88. let item = {}
  89. item.topic_name = element
  90. data.push(item)
  91. this.showInitTopic.push(true)
  92. });
  93. this.array = data
  94. this.showInputValue = false
  95. this.showSearchTopic = true
  96. }
  97. else if(this.arrayTopics.indexOf(this.input.toLowerCase())>-1){
  98. this.showInputValue = false
  99. this.showSearchTopic = false
  100. }else{
  101. this.showInitTopic = []
  102. let timestamp=new Date().getTime()
  103. this.params.q = this.input.toLowerCase()
  104. this.params._ = timestamp
  105. this.$axios.get('/api/v1/topics/search',{
  106. params:this.params
  107. }).then((res)=>{
  108. this.array = res.data.topics
  109. this.array.forEach((element,index) => {
  110. if (this.arrayTopics.indexOf(element.topic_name)>-1){
  111. this.showInitTopic.push(true)
  112. }
  113. else{
  114. this.showInitTopic.push(false)
  115. }
  116. this.showInputValue = true
  117. });
  118. let findelement = this.array.some((item)=>{
  119. return item.topic_name===this.input.toLowerCase()
  120. })
  121. this.showInputValue = !findelement
  122. })
  123. this.showSearchTopic = true
  124. }
  125. this.showAddTopic = false
  126. },
  127. Post(data,topics){
  128. this.$axios.post(this.postUrl,data).then(res=>{
  129. const viewDiv = $('#repo-topics1');
  130. viewDiv.children('.topic').remove();
  131. if (topics.length) {
  132. const topicArray = topics;
  133. const last = viewDiv.children('a').last();
  134. for (let i = 0; i < topicArray.length; i++) {
  135. const link = $('<a class="ui repo-topic small label topic"></a>');
  136. link.attr(
  137. 'href',
  138. `${AppSubUrl}/explore/repos?q=${encodeURIComponent(
  139. topicArray[i]
  140. )}&topic=`
  141. );
  142. link.text(topicArray[i]);
  143. // link.insertBefore(last);
  144. viewDiv.append(link)
  145. }
  146. }
  147. viewDiv.show();
  148. })
  149. },
  150. postTopic(){
  151. if(!this.showInputValue){
  152. return
  153. }
  154. const patter = /^[\u4e00-\u9fa5a-zA-Z0-9][\u4e00-\u9fa5a-zA-Z0-9-]{0,34}$/
  155. let regexp = patter.test(this.input)
  156. if(!regexp){
  157. this.$notify({
  158. message: '标签名必须以中文、字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符',
  159. duration: 3000,
  160. type:'error'
  161. });
  162. return
  163. }else{
  164. let topic = this.input
  165. if(this.arrayTopics.includes(topic.toLowerCase())){
  166. return
  167. }
  168. else{
  169. this.arrayTopics.push(topic.toLowerCase())
  170. let topics = this.arrayTopics
  171. let strTopics = topics.join(',')
  172. let data = this.qs.stringify({
  173. _csrf:csrf,
  174. topics:strTopics
  175. })
  176. this.Post(data,topics)
  177. $('#repo-topics1').children('span').remove()
  178. this.showInputValue = false
  179. this.showAddTopic = true
  180. this.showAddFlage = true
  181. }
  182. }
  183. },
  184. addPostTopic(){
  185. if(this.showAddFlage){
  186. // this.arrayTopics.pop()
  187. let cancleIndex = this.arrayTopics.indexOf(this.input)
  188. this.arrayTopics.splice(cancleIndex,1)
  189. let topics = this.arrayTopics
  190. let strTopics = topics.join(',')
  191. let data = this.qs.stringify({
  192. _csrf:csrf,
  193. topics:strTopics
  194. })
  195. this.Post(data,topics)
  196. if(this.arrayTopics.length===0){
  197. $('#repo-topics1').append(`<span class="no-description text-italic">${this.$i18n['noTopics']}</span>`)
  198. }else{
  199. $('#repo-topics1').children('span').remove()
  200. }
  201. }
  202. else if(!this.showAddFlage){
  203. let topic = this.input
  204. this.arrayTopics.push(topic.toLowerCase())
  205. let topics = this.arrayTopics
  206. let strTopics = topics.join(',')
  207. let data = this.qs.stringify({
  208. _csrf:csrf,
  209. topics:strTopics
  210. })
  211. this.Post(data,topics)
  212. $('#repo-topics1').children('span').remove()
  213. }
  214. this.showAddFlage = !this.showAddFlage
  215. },
  216. initTopics(){
  217. const mgrBtn = $('#manage_topic');
  218. const editDiv = $('#topic_edit');
  219. mgrBtn.on('click', (e) => {
  220. // viewDiv.hide();
  221. editDiv.css('display', ''); // show Semantic UI Grid
  222. this.input = ''
  223. if (this.input === ''){
  224. this.array = this.arrayTopics
  225. let data = []
  226. this.showInitTopic = []
  227. this.array.forEach((element,index) => {
  228. let item = {}
  229. item.topic_name = element
  230. data.push(item)
  231. this.showInitTopic.push(true)
  232. });
  233. this.array = data
  234. this.showInputValue = false
  235. this.showSearchTopic = true
  236. this.showAddTopic = false
  237. }
  238. stopPropagation(e);
  239. });
  240. $(document).bind('click',function(){
  241. editDiv.css('display','none');
  242. })
  243. editDiv.click(function(e){
  244. stopPropagation(e);
  245. })
  246. function stopPropagation(e) {
  247. var ev = e || window.event;
  248. if (ev.stopPropagation) {
  249. ev.stopPropagation();
  250. }
  251. else if (window.event) {
  252. window.event.cancelBubble = true;//兼容IE
  253. }
  254. }
  255. }
  256. },
  257. computed:{
  258. },
  259. watch: {
  260. // input(newValue){
  261. // if (newValue === ''){
  262. // this.array = this.arrayTopics
  263. // let data = []
  264. // this.showInitTopic = []
  265. // this.array.forEach((element,index) => {
  266. // let item = {}
  267. // item.topic_name = element
  268. // data.push(item)
  269. // this.showInitTopic.push(true)
  270. // });
  271. // this.array = data
  272. // this.showInputValue = false
  273. // this.showSearchTopic = true
  274. // }
  275. // }
  276. },
  277. mounted() {
  278. const context = this
  279. this.postUrl = `${window.location.pathname}/topics`;
  280. $('#repo-topics1').children('a').each(function(){
  281. context.arrayTopics.push($(this).text())
  282. });
  283. if(this.arrayTopics.length===0){
  284. $('#repo-topics1').append(`<span class="no-description text-italic">${this.$i18n['noTopics']}</span>`)
  285. }
  286. this.changeValue()
  287. } ,
  288. created(){
  289. this.$i18n = window.i18n;
  290. this.initTopics();
  291. this.input=''
  292. }
  293. };
  294. </script>
  295. <style scoped>
  296. .input-search {
  297. width: 100%;
  298. display: -webkit-box;
  299. display: -ms-flexbox;
  300. display: flex;
  301. min-width: 10rem;
  302. white-space: nowrap;
  303. font-size: 1rem;
  304. position: relative;
  305. display: inline-block;
  306. color: rgba(0,0,0,0.8);
  307. padding: 8px;
  308. }
  309. /deep/ .el-input__inner{
  310. border-color: #409eff;
  311. }
  312. .scrolling-menu{
  313. border-top: none !important;
  314. padding-top: 0 !important;
  315. padding-bottom: 0 !important;
  316. display: block;
  317. position: static;
  318. overflow-y: auto;
  319. border: none;
  320. -webkit-box-shadow: none !important;
  321. box-shadow: none !important;
  322. border-radius: 0 !important;
  323. margin: 0 !important;
  324. min-width: 100% !important;
  325. width: auto !important;
  326. border-top: 1px solid rgba(34,36,38,0.15);
  327. }
  328. .item-text{
  329. border-top: none;
  330. padding-right: calc(1.14285714rem + 17px ) !important;
  331. line-height: 1.333;
  332. padding-top: 0.7142857rem !important;
  333. padding-bottom: 0.7142857rem !important;
  334. position: relative;
  335. cursor: pointer;
  336. display: block;
  337. border: none;
  338. height: auto;
  339. text-align: left;
  340. border-top: none;
  341. line-height: 1em;
  342. color: rgba(0,0,0,0.87);
  343. padding: 0.78571429rem 1.14285714rem !important;
  344. font-size: 1rem;
  345. text-transform: none;
  346. font-weight: normal;
  347. -webkit-box-shadow: none;
  348. box-shadow: none;
  349. -webkit-touch-callout: none;
  350. display: -webkit-box;
  351. display: -ms-flexbox;
  352. display: flex;
  353. -webkit-box-align: center;
  354. -ms-flex-align: center;
  355. align-items: center;
  356. display: -webkit-box !important;
  357. display: -ms-flexbox !important;
  358. display: flex !important;
  359. }
  360. .icon-wrapper{
  361. text-align: left;
  362. width: 24px;
  363. height: 20px;
  364. -ms-flex-negative: 0;
  365. flex-shrink: 0;
  366. }
  367. .text{
  368. max-width: 80%;
  369. overflow: hidden;
  370. text-overflow: ellipsis;
  371. white-space: nowrap;
  372. font-size: 12px;
  373. font-weight: 400;
  374. color: #40485b;
  375. }
  376. .addition{
  377. background: #f6f6f6;
  378. }
  379. .user-add-label-text{
  380. max-width: 80%;
  381. overflow: hidden;
  382. text-overflow: ellipsis;
  383. white-space: nowrap;
  384. margin: 0 4px;
  385. }
  386. </style>