2022-01-29 00:00:11 +03:00
import $ from 'jquery' ;
2021-10-16 20:28:04 +03:00
import { stripTags } from '../utils.js' ;
2023-02-19 07:06:14 +03:00
import { hideElem , showElem } from '../utils/dom.js' ;
2024-03-02 12:29:04 +03:00
import { POST } from '../modules/fetch.js' ;
2021-10-16 20:28:04 +03:00
2024-03-02 12:29:04 +03:00
const { appSubUrl } = window . config ;
2021-10-16 20:28:04 +03:00
export function initRepoTopicBar ( ) {
2024-03-16 15:22:16 +03:00
const $mgrBtn = $ ( '#manage_topic' ) ;
if ( ! $mgrBtn . length ) return ;
const $editDiv = $ ( '#topic_edit' ) ;
const $viewDiv = $ ( '#repo-topics' ) ;
const $saveBtn = $ ( '#save_topic' ) ;
const $topicDropdown = $ ( '#topic_edit .dropdown' ) ;
const $topicForm = $editDiv ; // the old logic, $editDiv is topicForm
const $topicDropdownSearch = $topicDropdown . find ( 'input.search' ) ;
Fine tune more downdrop settings, use SVG for labels, improve Repo Topic Edit form (#23626)
Although it seems that some different purposes are mixed in this PR,
however, they are all related, and can be tested together, so I put them
together to save everyone's time.
Diff: `+79 −84`, everything becomes much better.
### Improve the dropdown settings.
Move all fomantic-init related code into our `fomantic.js`
Fine-tune some dropdown global settings, see the comments.
Also help to fix the first problem in #23625 , cc: @yp05327
The "language" menu has been simplified, and it works with small-height
window better.
### Use SVG instead of `<i class="delete icon">`
It's also done by `$.fn.dropdown.settings.templates.label` , cc:
@silverwind
### Remove incorrect `tabable` CSS class
It doesn't have CSS styles, and it was only in Vue. So it's totally
unnecessary, remove it by the way.
### Improve the Repo Topic Edit form
* Simplify the code
* Add a "Cancel" button
* Align elements
Before:
<details>
![image](https://user-images.githubusercontent.com/2114189/223325782-f09532de-0c38-4742-ba86-ed35cc9a858d.png)
</details>
After:
![image](https://user-images.githubusercontent.com/2114189/226796347-207feb0a-b3cd-4820-8a3e-01930bab1069.png)
2023-03-26 14:31:26 +03:00
const topicPrompts = {
2024-03-16 15:22:16 +03:00
countPrompt : $topicDropdown . attr ( 'data-text-count-prompt' ) ,
formatPrompt : $topicDropdown . attr ( 'data-text-format-prompt' ) ,
Fine tune more downdrop settings, use SVG for labels, improve Repo Topic Edit form (#23626)
Although it seems that some different purposes are mixed in this PR,
however, they are all related, and can be tested together, so I put them
together to save everyone's time.
Diff: `+79 −84`, everything becomes much better.
### Improve the dropdown settings.
Move all fomantic-init related code into our `fomantic.js`
Fine-tune some dropdown global settings, see the comments.
Also help to fix the first problem in #23625 , cc: @yp05327
The "language" menu has been simplified, and it works with small-height
window better.
### Use SVG instead of `<i class="delete icon">`
It's also done by `$.fn.dropdown.settings.templates.label` , cc:
@silverwind
### Remove incorrect `tabable` CSS class
It doesn't have CSS styles, and it was only in Vue. So it's totally
unnecessary, remove it by the way.
### Improve the Repo Topic Edit form
* Simplify the code
* Add a "Cancel" button
* Align elements
Before:
<details>
![image](https://user-images.githubusercontent.com/2114189/223325782-f09532de-0c38-4742-ba86-ed35cc9a858d.png)
</details>
After:
![image](https://user-images.githubusercontent.com/2114189/226796347-207feb0a-b3cd-4820-8a3e-01930bab1069.png)
2023-03-26 14:31:26 +03:00
} ;
2021-10-16 20:28:04 +03:00
2024-03-16 15:22:16 +03:00
$mgrBtn . on ( 'click' , ( ) => {
hideElem ( $viewDiv ) ;
showElem ( $editDiv ) ;
$topicDropdownSearch . trigger ( 'focus' ) ;
2021-10-16 20:28:04 +03:00
} ) ;
Fine tune more downdrop settings, use SVG for labels, improve Repo Topic Edit form (#23626)
Although it seems that some different purposes are mixed in this PR,
however, they are all related, and can be tested together, so I put them
together to save everyone's time.
Diff: `+79 −84`, everything becomes much better.
### Improve the dropdown settings.
Move all fomantic-init related code into our `fomantic.js`
Fine-tune some dropdown global settings, see the comments.
Also help to fix the first problem in #23625 , cc: @yp05327
The "language" menu has been simplified, and it works with small-height
window better.
### Use SVG instead of `<i class="delete icon">`
It's also done by `$.fn.dropdown.settings.templates.label` , cc:
@silverwind
### Remove incorrect `tabable` CSS class
It doesn't have CSS styles, and it was only in Vue. So it's totally
unnecessary, remove it by the way.
### Improve the Repo Topic Edit form
* Simplify the code
* Add a "Cancel" button
* Align elements
Before:
<details>
![image](https://user-images.githubusercontent.com/2114189/223325782-f09532de-0c38-4742-ba86-ed35cc9a858d.png)
</details>
After:
![image](https://user-images.githubusercontent.com/2114189/226796347-207feb0a-b3cd-4820-8a3e-01930bab1069.png)
2023-03-26 14:31:26 +03:00
$ ( '#cancel_topic_edit' ) . on ( 'click' , ( ) => {
2024-03-16 15:22:16 +03:00
hideElem ( $editDiv ) ;
showElem ( $viewDiv ) ;
$mgrBtn . trigger ( 'focus' ) ;
Fine tune more downdrop settings, use SVG for labels, improve Repo Topic Edit form (#23626)
Although it seems that some different purposes are mixed in this PR,
however, they are all related, and can be tested together, so I put them
together to save everyone's time.
Diff: `+79 −84`, everything becomes much better.
### Improve the dropdown settings.
Move all fomantic-init related code into our `fomantic.js`
Fine-tune some dropdown global settings, see the comments.
Also help to fix the first problem in #23625 , cc: @yp05327
The "language" menu has been simplified, and it works with small-height
window better.
### Use SVG instead of `<i class="delete icon">`
It's also done by `$.fn.dropdown.settings.templates.label` , cc:
@silverwind
### Remove incorrect `tabable` CSS class
It doesn't have CSS styles, and it was only in Vue. So it's totally
unnecessary, remove it by the way.
### Improve the Repo Topic Edit form
* Simplify the code
* Add a "Cancel" button
* Align elements
Before:
<details>
![image](https://user-images.githubusercontent.com/2114189/223325782-f09532de-0c38-4742-ba86-ed35cc9a858d.png)
</details>
After:
![image](https://user-images.githubusercontent.com/2114189/226796347-207feb0a-b3cd-4820-8a3e-01930bab1069.png)
2023-03-26 14:31:26 +03:00
} ) ;
2021-10-16 20:28:04 +03:00
2024-03-16 15:22:16 +03:00
$saveBtn . on ( 'click' , async ( ) => {
2021-10-16 20:28:04 +03:00
const topics = $ ( 'input[name=topics]' ) . val ( ) ;
2024-03-02 12:29:04 +03:00
const data = new FormData ( ) ;
data . append ( 'topics' , topics ) ;
2024-03-16 15:22:16 +03:00
const response = await POST ( $saveBtn . attr ( 'data-link' ) , { data } ) ;
2024-03-02 12:29:04 +03:00
if ( response . ok ) {
const responseData = await response . json ( ) ;
if ( responseData . status === 'ok' ) {
2024-03-16 15:22:16 +03:00
$viewDiv . children ( '.topic' ) . remove ( ) ;
2021-10-16 20:28:04 +03:00
if ( topics . length ) {
const topicArray = topics . split ( ',' ) ;
2023-04-14 22:29:05 +03:00
topicArray . sort ( ) ;
2024-03-02 12:29:04 +03:00
for ( const topic of topicArray ) {
Migrate margin and padding helpers to tailwind (#30043)
This will conclude the refactor of 1:1 class replacements to tailwind,
except `gt-hidden`. Commands ran:
```bash
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-0#tw-$1$2-0#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-1#tw-$1$2-0.5#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-2#tw-$1$2-1#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-3#tw-$1$2-2#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-4#tw-$1$2-4#g' {web_src/js,templates,routers,services}/**/*
perl -p -i -e 's#gt-(p|m)([lrtbxy])?-5#tw-$1$2-8#g' {web_src/js,templates,routers,services}/**/*
```
2024-03-24 19:42:49 +03:00
const $link = $ ( '<a class="ui repo-topic large label topic tw-m-0"></a>' ) ;
2024-03-16 15:22:16 +03:00
$link . attr ( 'href' , ` ${ appSubUrl } /explore/repos?q= ${ encodeURIComponent ( topic ) } &topic=1 ` ) ;
$link . text ( topic ) ;
$link . insertBefore ( $mgrBtn ) ; // insert all new topics before manage button
2021-10-16 20:28:04 +03:00
}
}
2024-03-16 15:22:16 +03:00
hideElem ( $editDiv ) ;
showElem ( $viewDiv ) ;
2021-10-16 20:28:04 +03:00
}
2024-03-02 12:29:04 +03:00
} else if ( response . status === 422 ) {
const responseData = await response . json ( ) ;
if ( responseData . invalidTopics . length > 0 ) {
topicPrompts . formatPrompt = responseData . message ;
2021-10-16 20:28:04 +03:00
2024-03-02 12:29:04 +03:00
const { invalidTopics } = responseData ;
2024-03-16 15:22:16 +03:00
const $topicLabels = $topicDropdown . children ( 'a.ui.label' ) ;
2024-03-02 12:29:04 +03:00
for ( const [ index , value ] of topics . split ( ',' ) . entries ( ) ) {
if ( invalidTopics . includes ( value ) ) {
2024-03-16 15:22:16 +03:00
$topicLabels . eq ( index ) . removeClass ( 'green' ) . addClass ( 'red' ) ;
2021-11-22 11:19:01 +03:00
}
2021-10-16 20:28:04 +03:00
}
2024-03-02 12:29:04 +03:00
} else {
topicPrompts . countPrompt = responseData . message ;
2021-10-16 20:28:04 +03:00
}
2024-03-02 12:29:04 +03:00
}
// Always validate the form
2024-03-16 15:22:16 +03:00
$topicForm . form ( 'validate form' ) ;
2021-10-16 20:28:04 +03:00
} ) ;
2024-03-16 15:22:16 +03:00
$topicDropdown . dropdown ( {
2021-10-16 20:28:04 +03:00
allowAdditions : true ,
forceSelection : false ,
fullTextSearch : 'exact' ,
fields : { name : 'description' , value : 'data-value' } ,
saveRemoteData : false ,
label : {
transition : 'horizontal flip' ,
duration : 200 ,
variation : false ,
} ,
apiSettings : {
2022-04-07 21:59:56 +03:00
url : ` ${ appSubUrl } /explore/topics/search?q={query} ` ,
2021-10-16 20:28:04 +03:00
throttle : 500 ,
cache : false ,
onResponse ( res ) {
const formattedResponse = {
success : false ,
results : [ ] ,
} ;
const query = stripTags ( this . urlData . query . trim ( ) ) ;
let found _query = false ;
const current _topics = [ ] ;
2024-03-16 15:22:16 +03:00
$topicDropdown . find ( 'a.label.visible' ) . each ( ( _ , el ) => {
2021-11-22 11:19:01 +03:00
current _topics . push ( el . getAttribute ( 'data-value' ) ) ;
} ) ;
2021-10-16 20:28:04 +03:00
if ( res . topics ) {
let found = false ;
for ( let i = 0 ; i < res . topics . length ; i ++ ) {
// skip currently added tags
if ( current _topics . includes ( res . topics [ i ] . topic _name ) ) {
continue ;
}
if ( res . topics [ i ] . topic _name . toLowerCase ( ) === query . toLowerCase ( ) ) {
found _query = true ;
}
formattedResponse . results . push ( { description : res . topics [ i ] . topic _name , 'data-value' : res . topics [ i ] . topic _name } ) ;
found = true ;
}
formattedResponse . success = found ;
}
if ( query . length > 0 && ! found _query ) {
formattedResponse . success = true ;
formattedResponse . results . unshift ( { description : query , 'data-value' : query } ) ;
} else if ( query . length > 0 && found _query ) {
formattedResponse . results . sort ( ( a , b ) => {
if ( a . description . toLowerCase ( ) === query . toLowerCase ( ) ) return - 1 ;
if ( b . description . toLowerCase ( ) === query . toLowerCase ( ) ) return 1 ;
if ( a . description > b . description ) return - 1 ;
if ( a . description < b . description ) return 1 ;
return 0 ;
} ) ;
}
return formattedResponse ;
} ,
} ,
onLabelCreate ( value ) {
value = value . toLowerCase ( ) . trim ( ) ;
this . attr ( 'data-value' , value ) . contents ( ) . first ( ) . replaceWith ( value ) ;
return $ ( this ) ;
} ,
onAdd ( addedValue , _addedText , $addedChoice ) {
addedValue = addedValue . toLowerCase ( ) . trim ( ) ;
$ ( $addedChoice ) . attr ( 'data-value' , addedValue ) ;
$ ( $addedChoice ) . attr ( 'data-text' , addedValue ) ;
2024-03-22 17:06:53 +03:00
} ,
2021-10-16 20:28:04 +03:00
} ) ;
$ . fn . form . settings . rules . validateTopic = function ( _values , regExp ) {
2024-03-16 15:22:16 +03:00
const $topics = $topicDropdown . children ( 'a.ui.label' ) ;
const status = $topics . length === 0 || $topics . last ( ) . attr ( 'data-value' ) . match ( regExp ) ;
2021-10-16 20:28:04 +03:00
if ( ! status ) {
2024-03-16 15:22:16 +03:00
$topics . last ( ) . removeClass ( 'green' ) . addClass ( 'red' ) ;
2021-10-16 20:28:04 +03:00
}
2024-03-16 15:22:16 +03:00
return status && $topicDropdown . children ( 'a.ui.label.red' ) . length === 0 ;
2021-10-16 20:28:04 +03:00
} ;
2024-03-16 15:22:16 +03:00
$topicForm . form ( {
2021-10-16 20:28:04 +03:00
on : 'change' ,
inline : true ,
fields : {
topics : {
identifier : 'topics' ,
rules : [
{
type : 'validateTopic' ,
2023-08-03 12:18:06 +03:00
value : /^\s*[a-z0-9][-.a-z0-9]{0,35}\s*$/ ,
2024-03-22 17:06:53 +03:00
prompt : topicPrompts . formatPrompt ,
2021-10-16 20:28:04 +03:00
} ,
{
type : 'maxCount[25]' ,
2024-03-22 17:06:53 +03:00
prompt : topicPrompts . countPrompt ,
} ,
] ,
2021-10-16 20:28:04 +03:00
} ,
2024-03-22 17:06:53 +03:00
} ,
2021-10-16 20:28:04 +03:00
} ) ;
}