forked from forgejo/forgejo
Split index.js
to separate files (#17315)
* split `index.js` to separate files * tune clipboard * fix promise * fix document * remove intermediate empty file * fix async event listener * use `export function` instead of `export {}`, add more comments Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com> Co-authored-by: 6543 <6543@obermui.de>
This commit is contained in:
parent
3728f1daa0
commit
1a7473ff45
42 changed files with 3686 additions and 3501 deletions
180
web_src/js/features/repo-home.js
Normal file
180
web_src/js/features/repo-home.js
Normal file
|
@ -0,0 +1,180 @@
|
|||
import {stripTags} from '../utils.js';
|
||||
|
||||
const {AppSubUrl, csrf} = window.config;
|
||||
|
||||
export function initRepoTopicBar() {
|
||||
const mgrBtn = $('#manage_topic');
|
||||
const editDiv = $('#topic_edit');
|
||||
const viewDiv = $('#repo-topics');
|
||||
const saveBtn = $('#save_topic');
|
||||
const topicDropdown = $('#topic_edit .dropdown');
|
||||
const topicForm = $('#topic_edit.ui.form');
|
||||
const topicPrompts = getPrompts();
|
||||
|
||||
mgrBtn.on('click', () => {
|
||||
viewDiv.hide();
|
||||
editDiv.css('display', ''); // show Semantic UI Grid
|
||||
});
|
||||
|
||||
function getPrompts() {
|
||||
const hidePrompt = $('div.hide#validate_prompt');
|
||||
const prompts = {
|
||||
countPrompt: hidePrompt.children('#count_prompt').text(),
|
||||
formatPrompt: hidePrompt.children('#format_prompt').text()
|
||||
};
|
||||
hidePrompt.remove();
|
||||
return prompts;
|
||||
}
|
||||
|
||||
saveBtn.on('click', () => {
|
||||
const topics = $('input[name=topics]').val();
|
||||
|
||||
$.post(saveBtn.data('link'), {
|
||||
_csrf: csrf,
|
||||
topics
|
||||
}, (_data, _textStatus, xhr) => {
|
||||
if (xhr.responseJSON.status === 'ok') {
|
||||
viewDiv.children('.topic').remove();
|
||||
if (topics.length) {
|
||||
const topicArray = topics.split(',');
|
||||
|
||||
const last = viewDiv.children('a').last();
|
||||
for (let i = 0; i < topicArray.length; i++) {
|
||||
const link = $('<a class="ui repo-topic large label topic"></a>');
|
||||
link.attr('href', `${AppSubUrl}/explore/repos?q=${encodeURIComponent(topicArray[i])}&topic=1`);
|
||||
link.text(topicArray[i]);
|
||||
link.insertBefore(last);
|
||||
}
|
||||
}
|
||||
editDiv.css('display', 'none');
|
||||
viewDiv.show();
|
||||
}
|
||||
}).fail((xhr) => {
|
||||
if (xhr.status === 422) {
|
||||
if (xhr.responseJSON.invalidTopics.length > 0) {
|
||||
topicPrompts.formatPrompt = xhr.responseJSON.message;
|
||||
|
||||
const {invalidTopics} = xhr.responseJSON;
|
||||
const topicLables = topicDropdown.children('a.ui.label');
|
||||
|
||||
topics.split(',').forEach((value, index) => {
|
||||
for (let i = 0; i < invalidTopics.length; i++) {
|
||||
if (invalidTopics[i] === value) {
|
||||
topicLables.eq(index).removeClass('green').addClass('red');
|
||||
}
|
||||
}
|
||||
});
|
||||
} else {
|
||||
topicPrompts.countPrompt = xhr.responseJSON.message;
|
||||
}
|
||||
}
|
||||
}).always(() => {
|
||||
topicForm.form('validate form');
|
||||
});
|
||||
});
|
||||
|
||||
topicDropdown.dropdown({
|
||||
allowAdditions: true,
|
||||
forceSelection: false,
|
||||
fullTextSearch: 'exact',
|
||||
fields: {name: 'description', value: 'data-value'},
|
||||
saveRemoteData: false,
|
||||
label: {
|
||||
transition: 'horizontal flip',
|
||||
duration: 200,
|
||||
variation: false,
|
||||
blue: true,
|
||||
basic: true,
|
||||
},
|
||||
className: {
|
||||
label: 'ui small label'
|
||||
},
|
||||
apiSettings: {
|
||||
url: `${AppSubUrl}/api/v1/topics/search?q={query}`,
|
||||
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 = [];
|
||||
topicDropdown.find('div.label.visible.topic,a.label.visible').each((_, e) => { current_topics.push(e.dataset.value) });
|
||||
|
||||
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);
|
||||
}
|
||||
});
|
||||
|
||||
$.fn.form.settings.rules.validateTopic = function (_values, regExp) {
|
||||
const topics = topicDropdown.children('a.ui.label');
|
||||
const status = topics.length === 0 || topics.last().attr('data-value').match(regExp);
|
||||
if (!status) {
|
||||
topics.last().removeClass('green').addClass('red');
|
||||
}
|
||||
return status && topicDropdown.children('a.ui.label.red').length === 0;
|
||||
};
|
||||
|
||||
topicForm.form({
|
||||
on: 'change',
|
||||
inline: true,
|
||||
fields: {
|
||||
topics: {
|
||||
identifier: 'topics',
|
||||
rules: [
|
||||
{
|
||||
type: 'validateTopic',
|
||||
value: /^[a-z0-9][a-z0-9-]{0,35}$/,
|
||||
prompt: topicPrompts.formatPrompt
|
||||
},
|
||||
{
|
||||
type: 'maxCount[25]',
|
||||
prompt: topicPrompts.countPrompt
|
||||
}
|
||||
]
|
||||
},
|
||||
}
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue