/* globals wipPrefixes */ /* exported timeAddManual, toggleStopwatch, cancelStopwatch */ /* exported toggleDeadlineForm, setDeadline, updateDeadline, deleteDependencyModal, cancelCodeComment, onOAuthLoginClick */ import "./publicpath.js"; import "./polyfills.js"; import "./features/letteravatar.js"; import Vue from "vue"; import "element-ui/lib/theme-chalk/index.css"; import localeEn from 'element-ui/lib/locale/lang/en'; import localeZh from 'element-ui/lib/locale/lang/zh-CN'; import ElementUI from "element-ui"; import axios from "axios"; import qs from "qs"; import Cookies from "js-cookie"; import "jquery.are-you-sure"; import "./vendor/semanticdropdown.js"; import { svg } from "./utils.js"; import echarts from "echarts"; import initContextPopups from "./features/contextpopup.js"; import initGitGraph from "./features/gitgraph.js"; import initClipboard from "./features/clipboard.js"; import initUserHeatmap from "./features/userheatmap.js"; import initDateTimePicker from "./features/datetimepicker.js"; import initContextMenu from "./features/contexmenu.js"; import { initTribute, issuesTribute, emojiTribute, } from "./features/tribute.js"; import createDropzone from "./features/dropzone.js"; import highlight from "./features/highlight.js"; import ActivityTopAuthors from "./components/ActivityTopAuthors.vue"; import { initNotificationsTable, initNotificationCount, } from "./features/notification.js"; import { createCodeEditor } from "./features/codeeditor.js"; import MinioUploader from "./components/MinioUploader.vue"; import EditAboutInfo from "./components/EditAboutInfo.vue"; // import Images from './components/Images.vue'; import EditTopics from "./components/EditTopics.vue"; import DataAnalysis from "./components/DataAnalysis.vue"; import Contributors from "./components/Contributors.vue"; import Model from "./components/Model.vue"; import WxAutorize from "./components/WxAutorize.vue"; import initCloudrain from "./features/cloudrbanin.js"; import initCloudrainSow from "./features/cloudbrainShow.js"; import initImage from "./features/images.js"; import selectDataset from "./components/dataset/selectDataset.vue"; import referenceDataset from "./components/dataset/referenceDataset.vue"; // import $ from 'jquery.js' import router from "./router/index.js"; import { Message } from "element-ui"; import { i18nVue } from "./features/i18nVue.js"; import './features/ad.js'; import { Fancybox } from "./vendor/fancybox.esm.js"; Vue.prototype.$axios = axios; Vue.prototype.$Cookies = Cookies; Vue.prototype.qs = qs; Vue.prototype.$message = Message; Vue.prototype.$locale = i18nVue; const lang = document.querySelector('html').getAttribute('lang'); window.i18n = i18nVue[lang == 'zh-CN' ? 'CN' : 'US']; const { AppSubUrl, StaticUrlPrefix, csrf } = window.config; Vue.use(ElementUI, { locale: lang === 'zh-CN' ? localeZh : localeEn, }); Object.defineProperty(Vue.prototype, "$echarts", { value: echarts, }); window.echarts = echarts; function htmlEncode(text) { return jQuery("
").text(text).html(); } let previewFileModes; const commentMDEditors = {}; // Silence fomantic's error logging when tabs are used without a target content element $.fn.tab.settings.silent = true; function initCommentPreviewTab($form) { const $tabMenu = $form.find(".tabular.menu"); $tabMenu.find(".item").tab(); $tabMenu .find(`.item[data-tab="${$tabMenu.data("preview")}"]`) .on("click", function () { const $this = $(this); $.post( $this.data("url"), { _csrf: csrf, mode: "gfm", context: $this.data("context"), text: $form .find(`.tab[data-tab="${$tabMenu.data("write")}"] textarea`) .val(), }, (data) => { const $previewPanel = $form.find( `.tab[data-tab="${$tabMenu.data("preview")}"]` ); $previewPanel.html(data); $("pre code", $previewPanel[0]).each(function () { highlight(this); }); } ); }); buttonsClickOnEnter(); } function initEditPreviewTab($form) { const $tabMenu = $form.find(".tabular.menu"); $tabMenu.find(".item").tab(); const $previewTab = $tabMenu.find( `.item[data-tab="${$tabMenu.data("preview")}"]` ); if ($previewTab.length) { previewFileModes = $previewTab.data("preview-file-modes").split(","); $previewTab.on("click", function () { const $this = $(this); let context = `${$this.data("context")}/`; const treePathEl = $form.find("input#tree_path"); if (treePathEl.length > 0) { context += treePathEl.val(); } context = context.substring(0, context.lastIndexOf("/")); $.post( $this.data("url"), { _csrf: csrf, mode: "gfm", context, text: $form .find(`.tab[data-tab="${$tabMenu.data("write")}"] textarea`) .val(), }, (data) => { const $previewPanel = $form.find( `.tab[data-tab="${$tabMenu.data("preview")}"]` ); $previewPanel.html(data); $("pre code", $previewPanel[0]).each(function () { highlight(this); }); } ); }); } } function initEditDiffTab($form) { const $tabMenu = $form.find(".tabular.menu"); $tabMenu.find(".item").tab(); $tabMenu .find(`.item[data-tab="${$tabMenu.data("diff")}"]`) .on("click", function () { const $this = $(this); $.post( $this.data("url"), { _csrf: csrf, context: $this.data("context"), content: $form .find(`.tab[data-tab="${$tabMenu.data("write")}"] textarea`) .val(), }, (data) => { const $diffPreviewPanel = $form.find( `.tab[data-tab="${$tabMenu.data("diff")}"]` ); $diffPreviewPanel.html(data); } ); }); } function initEditForm() { if ($(".edit.form").length === 0) { return; } initEditPreviewTab($(".edit.form")); initEditDiffTab($(".edit.form")); } function initBranchSelector() { const $selectBranch = $(".ui.select-branch"); const $branchMenu = $selectBranch.find(".reference-list-menu"); $branchMenu.find(".item:not(.no-select)").click(function () { $($(this).data("id-selector")).val($(this).data("id")); $selectBranch.find(".ui .branch-name").text($(this).data("name")); }); $selectBranch.find(".reference.column").on("click", function () { $selectBranch.find(".scrolling.reference-list-menu").css("display", "none"); $selectBranch.find(".reference .text").addClass("black"); $($(this).data("target")).css("display", "block"); $(this).find(".text.black").removeClass("black"); return false; }); } function initLabelEdit() { // Create label const $newLabelPanel = $(".new-label.segment"); $(".new-label.button").on("click", () => { $newLabelPanel.show(); }); $(".new-label.segment .cancel").on("click", () => { $newLabelPanel.hide(); }); $(".color-picker").each(function () { $(this).minicolors(); }); $(".precolors .color").on("click", function () { const color_hex = $(this).data("color-hex"); $(".color-picker").val(color_hex); $(".minicolors-swatch-color").css("background-color", color_hex); }); $(".edit-label-button").on("click", function () { $("#label-modal-id").val($(this).data("id")); $(".edit-label .new-label-input").val($(this).data("title")); $(".edit-label .new-label-desc-input").val($(this).data("description")); $(".edit-label .color-picker").val($(this).data("color")); $(".minicolors-swatch-color").css( "background-color", $(this).data("color") ); $(".edit-label.modal") .modal({ onApprove() { $(".edit-label.form").trigger("submit"); }, }) .modal("show"); return false; }); } function updateIssuesMeta(url, action, issueIds, elementId, isAdd) { return new Promise((resolve) => { $.ajax({ type: "POST", url, data: { _csrf: csrf, action, issue_ids: issueIds, id: elementId, is_add: isAdd, }, success: resolve, }); }); } function initRepoStatusChecker() { const migrating = $("#repo_migrating"); $("#repo_migrating_failed").hide(); if (migrating) { const repo_name = migrating.attr("repo"); if (typeof repo_name === "undefined") { return; } $.ajax({ type: "GET", url: `${AppSubUrl}/${repo_name}/status`, data: { _csrf: csrf, }, complete(xhr) { if (xhr.status === 200) { if (xhr.responseJSON) { if (xhr.responseJSON.status === 0) { window.location.reload(); return; } setTimeout(() => { initRepoStatusChecker(); }, 2000); return; } } $("#repo_migrating_progress").hide(); $("#repo_migrating_failed").show(); }, }); } } function initReactionSelector(parent) { let reactions = ""; if (!parent) { parent = $(document); reactions = ".reactions > "; } parent.find(`${reactions}a.label`).popup({ position: "bottom left", metadata: { content: "title", title: "none" }, }); parent .find(`.select-reaction > .menu > .item, ${reactions}a.label`) .on("click", function (e) { const vm = this; e.preventDefault(); if ($(this).hasClass("disabled")) return; const actionURL = $(this).hasClass("item") ? $(this).closest(".select-reaction").data("action-url") : $(this).data("action-url"); const url = `${actionURL}/${ $(this).hasClass("blue") ? "unreact" : "react" }`; $.ajax({ type: "POST", url, data: { _csrf: csrf, content: $(this).data("content"), }, }).done((resp) => { if (resp && (resp.html || resp.empty)) { const content = $(vm).closest(".content"); let react = content.find(".segment.reactions"); if (!resp.empty && react.length > 0) { react.remove(); } if (!resp.empty) { react = $('
'); const attachments = content.find(".segment.bottom:first"); if (attachments.length > 0) { react.insertBefore(attachments); } else { react.appendTo(content); } react.html(resp.html); react.find(".dropdown").dropdown(); initReactionSelector(react); } } }); }); } function insertAtCursor(field, value) { if (field.selectionStart || field.selectionStart === 0) { const startPos = field.selectionStart; const endPos = field.selectionEnd; field.value = field.value.substring(0, startPos) + value + field.value.substring(endPos, field.value.length); field.selectionStart = startPos + value.length; field.selectionEnd = startPos + value.length; } else { field.value += value; } } function replaceAndKeepCursor(field, oldval, newval) { if (field.selectionStart || field.selectionStart === 0) { const startPos = field.selectionStart; const endPos = field.selectionEnd; field.value = field.value.replace(oldval, newval); field.selectionStart = startPos + newval.length - oldval.length; field.selectionEnd = endPos + newval.length - oldval.length; } else { field.value = field.value.replace(oldval, newval); } } function retrieveImageFromClipboardAsBlob(pasteEvent, callback) { if (!pasteEvent.clipboardData) { return; } const { items } = pasteEvent.clipboardData; if (typeof items === "undefined") { return; } for (let i = 0; i < items.length; i++) { if (!items[i].type.includes("image")) continue; const blob = items[i].getAsFile(); if (typeof callback === "function") { pasteEvent.preventDefault(); pasteEvent.stopPropagation(); callback(blob); } } } function uploadFile(file, callback) { const xhr = new XMLHttpRequest(); xhr.addEventListener("load", () => { if (xhr.status === 200) { callback(xhr.responseText); } }); xhr.open("post", `${AppSubUrl}/attachments`, true); xhr.setRequestHeader("X-Csrf-Token", csrf); const formData = new FormData(); formData.append("file", file, file.name); xhr.send(formData); } function reload() { window.location.reload(); } function initImagePaste(target) { target.each(function () { const field = this; field.addEventListener( "paste", (event) => { retrieveImageFromClipboardAsBlob(event, (img) => { const name = img.name.substr(0, img.name.lastIndexOf(".")); insertAtCursor(field, `![${name}]()`); uploadFile(img, (res) => { const data = JSON.parse(res); replaceAndKeepCursor( field, `![${name}]()`, `![${name}](${AppSubUrl}/attachments/${data.uuid})` ); const input = $( `` ).val(data.uuid); $(".files").append(input); }); }); }, false ); }); } function initSimpleMDEImagePaste(simplemde, files) { simplemde.codemirror.on("paste", (_, event) => { retrieveImageFromClipboardAsBlob(event, (img) => { const name = img.name.substr(0, img.name.lastIndexOf(".")); uploadFile(img, (res) => { const data = JSON.parse(res); const pos = simplemde.codemirror.getCursor(); simplemde.codemirror.replaceRange( `![${name}](${AppSubUrl}/attachments/${data.uuid})`, pos ); const input = $( `` ).val(data.uuid); files.append(input); }); }); }); } let autoSimpleMDE; function initCommentForm() { if ($(".comment.form").length === 0) { return; } autoSimpleMDE = setCommentSimpleMDE( $(".comment.form textarea:not(.review-textarea)") ); initBranchSelector(); initCommentPreviewTab($(".comment.form")); initImagePaste($(".comment.form textarea")); // Listsubmit function initListSubmits(selector, outerSelector) { const $list = $(`.ui.${outerSelector}.list`); const $noSelect = $list.find(".no-select"); const $listMenu = $(`.${selector} .menu`); let hasLabelUpdateAction = $listMenu.data("action") === "update"; const labels = {}; $(`.${selector}`).dropdown("setting", "onHide", () => { hasLabelUpdateAction = $listMenu.data("action") === "update"; // Update the var if (hasLabelUpdateAction) { const promises = []; Object.keys(labels).forEach((elementId) => { const label = labels[elementId]; console.log("label:", label); const promise = updateIssuesMeta( label["update-url"], label.action, label["issue-id"], elementId, label["is-checked"] ); promises.push(promise); }); Promise.all(promises).then(reload); } }); $listMenu.find(".item:not(.no-select)").on("click", function () { // we don't need the action attribute when updating assignees if ( selector === "select-assignees-modify" || selector === "select-reviewers-modify" ) { // UI magic. We need to do this here, otherwise it would destroy the functionality of // adding/removing labels if ($(this).data("can-change") === "block") { return false; } if ($(this).hasClass("checked")) { $(this).removeClass("checked"); $(this).find(".octicon-check").addClass("invisible"); $(this).data("is-checked", "remove"); } else { $(this).addClass("checked"); $(this).find(".octicon-check").removeClass("invisible"); $(this).data("is-checked", "add"); } updateIssuesMeta( $listMenu.data("update-url"), "", $listMenu.data("issue-id"), $(this).data("id"), $(this).data("is-checked") ); $listMenu.data("action", "update"); // Update to reload the page when we updated items return false; } if ($(this).hasClass("checked")) { $(this).removeClass("checked"); $(this).find(".octicon-check").addClass("invisible"); if (hasLabelUpdateAction) { if (!($(this).data("id") in labels)) { labels[$(this).data("id")] = { "update-url": $listMenu.data("update-url"), action: "detach", "issue-id": $listMenu.data("issue-id"), }; } else { delete labels[$(this).data("id")]; } } } else { $(this).addClass("checked"); $(this).find(".octicon-check").removeClass("invisible"); if (hasLabelUpdateAction) { if (!($(this).data("id") in labels)) { labels[$(this).data("id")] = { "update-url": $listMenu.data("update-url"), action: "attach", "issue-id": $listMenu.data("issue-id"), }; } else { delete labels[$(this).data("id")]; } } } const listIds = []; $(this) .parent() .find(".item") .each(function () { if ($(this).hasClass("checked")) { listIds.push($(this).data("id")); $($(this).data("id-selector")).removeClass("hide"); } else { $($(this).data("id-selector")).addClass("hide"); } }); if (listIds.length === 0) { $noSelect.removeClass("hide"); } else { $noSelect.addClass("hide"); } $($(this).parent().data("id")).val(listIds.join(",")); return false; }); $listMenu.find(".no-select.item").on("click", function () { if (hasLabelUpdateAction || selector === "select-assignees-modify") { updateIssuesMeta( $listMenu.data("update-url"), "clear", $listMenu.data("issue-id"), "", "" ).then(reload); } $(this) .parent() .find(".item") .each(function () { $(this).removeClass("checked"); $(this).find(".octicon").addClass("invisible"); $(this).data("is-checked", "remove"); }); $list.find(".item").each(function () { $(this).addClass("hide"); }); $noSelect.removeClass("hide"); $($(this).parent().data("id")).val(""); }); } // Init labels and assignees initListSubmits("select-label", "labels"); initListSubmits("select-assignees", "assignees"); initListSubmits("select-assignees-modify", "assignees"); initListSubmits("select-reviewers-modify", "assignees"); function selectItem(select_id, input_id) { let $menu; if (select_id == ".select-branch") { $menu = $(`${select_id} .menu`).eq(1); } else { $menu = $(`${select_id} .menu`); } const $list = $(`.ui${select_id}.list`); const hasUpdateAction = $menu.data("action") === "update"; $menu.find(".item:not(.no-select)").on("click", function () { $(this) .parent() .find(".item") .each(function () { $(this).removeClass("selected active"); }); $(this).addClass("selected active"); if (hasUpdateAction) { //let ref = '' //if (select_id=='.select-branch'){ // ref = $(this).data('name'); // } updateIssuesMeta( $menu.data("update-url"), "", $menu.data("issue-id"), $(this).data("id"), $(this).data("is-checked") ).then(reload); } switch (input_id) { case "#milestone_id": $list .find(".selected") .html( `${htmlEncode( $(this).text() )}` ); break; case "#assignee_id": $list .find(".selected") .html( `` + `${htmlEncode($(this).text())}` ); } $(`.ui${select_id}.list .no-select`).addClass("hide"); $(input_id).val($(this).data("id")); }); $menu.find(".no-select.item").on("click", function () { $(this) .parent() .find(".item:not(.no-select)") .each(function () { $(this).removeClass("selected active"); }); if (hasUpdateAction) { updateIssuesMeta( $menu.data("update-url"), "", $menu.data("issue-id"), $(this).data("id"), $(this).data("is-checked") ).then(reload); } $list.find(".selected").html(""); $list.find(".no-select").removeClass("hide"); $(input_id).val(""); }); } // Milestone and assignee selectItem(".select-milestone", "#milestone_id"); selectItem(".select-assignee", "#assignee_id"); selectItem(".select-branch", ""); } function initInstall() { if ($(".install").length === 0) { return; } if ($("#db_host").val() === "") { $("#db_host").val("127.0.0.1:3306"); $("#db_user").val("gitea"); $("#db_name").val("gitea"); } // Database type change detection. $("#db_type").on("change", function () { const sqliteDefault = "data/gitea.db"; const tidbDefault = "data/gitea_tidb"; const dbType = $(this).val(); if (dbType === "SQLite3") { $("#sql_settings").hide(); $("#pgsql_settings").hide(); $("#mysql_settings").hide(); $("#sqlite_settings").show(); if (dbType === "SQLite3" && $("#db_path").val() === tidbDefault) { $("#db_path").val(sqliteDefault); } return; } const dbDefaults = { MySQL: "127.0.0.1:3306", PostgreSQL: "127.0.0.1:5432", MSSQL: "127.0.0.1:1433", }; $("#sqlite_settings").hide(); $("#sql_settings").show(); $("#pgsql_settings").toggle(dbType === "PostgreSQL"); $("#mysql_settings").toggle(dbType === "MySQL"); $.each(dbDefaults, (_type, defaultHost) => { if ($("#db_host").val() === defaultHost) { $("#db_host").val(dbDefaults[dbType]); return false; } }); }); // TODO: better handling of exclusive relations. $("#offline-mode input").on("change", function () { if ($(this).is(":checked")) { $("#disable-gravatar").checkbox("check"); $("#federated-avatar-lookup").checkbox("uncheck"); } }); $("#disable-gravatar input").on("change", function () { if ($(this).is(":checked")) { $("#federated-avatar-lookup").checkbox("uncheck"); } else { $("#offline-mode").checkbox("uncheck"); } }); $("#federated-avatar-lookup input").on("change", function () { if ($(this).is(":checked")) { $("#disable-gravatar").checkbox("uncheck"); $("#offline-mode").checkbox("uncheck"); } }); $("#enable-openid-signin input").on("change", function () { if ($(this).is(":checked")) { if (!$("#disable-registration input").is(":checked")) { $("#enable-openid-signup").checkbox("check"); } } else { $("#enable-openid-signup").checkbox("uncheck"); } }); $("#disable-registration input").on("change", function () { if ($(this).is(":checked")) { $("#enable-captcha").checkbox("uncheck"); $("#enable-openid-signup").checkbox("uncheck"); } else { $("#enable-openid-signup").checkbox("check"); } }); $("#enable-captcha input").on("change", function () { if ($(this).is(":checked")) { $("#disable-registration").checkbox("uncheck"); } }); } function initIssueComments() { if ($(".repository.view.issue .timeline").length === 0) return; $(".re-request-review").on("click", function (event) { const url = $(this).data("update-url"); const issueId = $(this).data("issue-id"); const id = $(this).data("id"); const isChecked = $(this).data("is-checked"); //const ref = $(this).data('name'); event.preventDefault(); updateIssuesMeta(url, "", issueId, id, isChecked).then(reload); }); $(document).on("click", (event) => { const urlTarget = $(":target"); if (urlTarget.length === 0) return; const urlTargetId = urlTarget.attr("id"); if (!urlTargetId) return; if (!/^(issue|pull)(comment)?-\d+$/.test(urlTargetId)) return; const $target = $(event.target); if ($target.closest(`#${urlTargetId}`).length === 0) { const scrollPosition = $(window).scrollTop(); window.location.hash = ""; $(window).scrollTop(scrollPosition); window.history.pushState(null, null, " "); } }); } async function initRepository() { if ($(".repository").length === 0) { return; } function initFilterSearchDropdown(selector) { const $dropdown = $(selector); $dropdown.dropdown({ fullTextSearch: true, selectOnKeydown: false, onChange(_text, _value, $choice) { if ($choice.data("url")) { window.location.href = $choice.data("url"); } }, message: { noResults: $dropdown.data("no-results") }, }); } // File list and commits if ( $(".repository.file.list").length > 0 || ".repository.commits".length > 0 ) { initFilterBranchTagDropdown(".choose.reference .dropdown"); } // Wiki if ($(".repository.wiki.view").length > 0) { initFilterSearchDropdown(".choose.page .dropdown"); } // Options if ($(".repository.settings.options").length > 0) { // Enable or select internal/external wiki system and issue tracker. $(".enable-system").on("change", function () { if (this.checked) { $($(this).data("target")).removeClass("disabled"); if (!$(this).data("context")) { $($(this).data("context")).addClass("disabled"); } } else { $($(this).data("target")).addClass("disabled"); if (!$(this).data("context")) { $($(this).data("context")).removeClass("disabled"); } } }); $(".enable-system-radio").on("change", function () { if (this.value === "false") { $($(this).data("target")).addClass("disabled"); if (typeof $(this).data("context") !== "undefined") { $($(this).data("context")).removeClass("disabled"); } } else if (this.value === "true") { $($(this).data("target")).removeClass("disabled"); if (typeof $(this).data("context") !== "undefined") { $($(this).data("context")).addClass("disabled"); } } }); } // Labels if ($(".repository.labels").length > 0) { initLabelEdit(); } // Milestones if ($(".repository.new.milestone").length > 0) { const $datepicker = $(".milestone.datepicker"); await initDateTimePicker($datepicker.data("lang")); $datepicker.datetimepicker({ inline: true, timepicker: false, startDate: $datepicker.data("start-date"), onSelectDate(date) { $("#deadline").val(date.toISOString().substring(0, 10)); }, }); $("#clear-date").on("click", () => { $("#deadline").val(""); return false; }); } // Issues if ($(".repository.view.issue").length > 0) { // Edit issue title const $issueTitle = $("#issue-title"); const $editInput = $("#edit-title-input input"); const editTitleToggle = function () { $issueTitle.toggle(); $(".not-in-edit").toggle(); $("#edit-title-input").toggle(); $("#pull-desc").toggle(); $("#pull-desc-edit").toggle(); $(".in-edit").toggle(); $editInput.focus(); return false; }; const changeBranchSelect = function () { const selectionTextField = $("#pull-target-branch"); const baseName = selectionTextField.data("basename"); const branchNameNew = $(this).data("branch"); const branchNameOld = selectionTextField.data("branch"); // Replace branch name to keep translation from HTML template selectionTextField.html( selectionTextField .html() .replace( `${baseName}:${branchNameOld}`, `${baseName}:${branchNameNew}` ) ); selectionTextField.data("branch", branchNameNew); // update branch name in setting }; $("#branch-select > .item").on("click", changeBranchSelect); $("#edit-title").on("click", editTitleToggle); $("#cancel-edit-title").on("click", editTitleToggle); $("#save-edit-title") .on("click", editTitleToggle) .on("click", function () { const pullrequest_targetbranch_change = function (update_url) { const targetBranch = $("#pull-target-branch").data("branch"); const $branchTarget = $("#branch_target"); if (targetBranch === $branchTarget.text()) { return false; } $.post(update_url, { _csrf: csrf, target_branch: targetBranch, }) .done((data) => { $branchTarget.text(data.base_branch); }) .always(() => { reload(); }); }; const pullrequest_target_update_url = $(this).data("target-update-url"); if ( $editInput.val().length === 0 || $editInput.val() === $issueTitle.text() ) { $editInput.val($issueTitle.text()); pullrequest_targetbranch_change(pullrequest_target_update_url); } else { $.post( $(this).data("update-url"), { _csrf: csrf, title: $editInput.val(), }, (data) => { $editInput.val(data.title); $issueTitle.text(data.title); pullrequest_targetbranch_change(pullrequest_target_update_url); reload(); } ); } return false; }); // Issue Comments initIssueComments(); // Issue/PR Context Menus $(".context-dropdown").dropdown({ action: "hide", }); // Quote reply $(".quote-reply").on("click", function (event) { $(this).closest(".dropdown").find(".menu").toggle("visible"); const target = $(this).data("target"); const quote = $(`#comment-${target}`).text().replace(/\n/g, "\n> "); const content = `> ${quote}\n\n`; let $content; if ($(this).hasClass("quote-reply-diff")) { const $parent = $(this).closest(".comment-code-cloud"); $parent.find("button.comment-form-reply").trigger("click"); $content = $parent.find('[name="content"]'); if ($content.val() !== "") { $content.val(`${$content.val()}\n\n${content}`); } else { $content.val(`${content}`); } $content.focus(); } else if (autoSimpleMDE !== null) { if (autoSimpleMDE.value() !== "") { autoSimpleMDE.value(`${autoSimpleMDE.value()}\n\n${content}`); } else { autoSimpleMDE.value(`${content}`); } } event.preventDefault(); }); // Edit issue or comment content $(".edit-content").on("click", async function (event) { $(this).closest(".dropdown").find(".menu").toggle("visible"); const $segment = $(this).closest(".header").next(); const $editContentZone = $segment.find(".edit-content-zone"); const $renderContent = $segment.find(".render-content"); const $rawContent = $segment.find(".raw-content"); let $textarea; let $simplemde; // Setup new form if ($editContentZone.html().length === 0) { $editContentZone.html($("#edit-content-form").html()); $textarea = $editContentZone.find("textarea"); issuesTribute.attach($textarea.get()); emojiTribute.attach($textarea.get()); let dz; const $dropzone = $editContentZone.find(".dropzone"); const $files = $editContentZone.find(".comment-files"); if ($dropzone.length > 0) { $dropzone.data("saved", false); const filenameDict = {}; dz = await createDropzone($dropzone[0], { url: $dropzone.data("upload-url"), headers: { "X-Csrf-Token": csrf }, maxFiles: $dropzone.data("max-file"), maxFilesize: $dropzone.data("max-size"), acceptedFiles: $dropzone.data("accepts") === "*/*" ? null : $dropzone.data("accepts"), addRemoveLinks: true, dictDefaultMessage: $dropzone.data("default-message"), dictInvalidFileType: $dropzone.data("invalid-input-type"), dictFileTooBig: $dropzone.data("file-too-big"), dictRemoveFile: $dropzone.data("remove-file"), init() { this.on("success", (file, data) => { filenameDict[file.name] = { uuid: data.uuid, submitted: false, }; const input = $( `` ).val(data.uuid); $files.append(input); }); this.on("removedfile", (file) => { if (!(file.name in filenameDict)) { return; } $(`#${filenameDict[file.name].uuid}`).remove(); if ( $dropzone.data("remove-url") && $dropzone.data("csrf") && !filenameDict[file.name].submitted ) { $.post($dropzone.data("remove-url"), { file: filenameDict[file.name].uuid, _csrf: $dropzone.data("csrf"), }); } }); this.on("submit", () => { $.each(filenameDict, (name) => { filenameDict[name].submitted = true; }); }); this.on("reload", () => { $.getJSON($editContentZone.data("attachment-url"), (data) => { dz.removeAllFiles(true); $files.empty(); $.each(data, function () { const imgSrc = `${$dropzone.data("upload-url")}/${ this.uuid }`; dz.emit("addedfile", this); dz.emit("thumbnail", this, imgSrc); dz.emit("complete", this); dz.files.push(this); filenameDict[this.name] = { submitted: true, uuid: this.uuid, }; $dropzone .find(`img[src='${imgSrc}']`) .css("max-width", "100%"); const input = $( `` ).val(this.uuid); $files.append(input); }); }); }); }, }); dz.emit("reload"); } // Give new write/preview data-tab name to distinguish from others const $editContentForm = $editContentZone.find(".ui.comment.form"); const $tabMenu = $editContentForm.find(".tabular.menu"); $tabMenu.attr("data-write", $editContentZone.data("write")); $tabMenu.attr("data-preview", $editContentZone.data("preview")); $tabMenu .find(".write.item") .attr("data-tab", $editContentZone.data("write")); $tabMenu .find(".preview.item") .attr("data-tab", $editContentZone.data("preview")); $editContentForm .find(".write") .attr("data-tab", $editContentZone.data("write")); $editContentForm .find(".preview") .attr("data-tab", $editContentZone.data("preview")); $simplemde = setCommentSimpleMDE($textarea); commentMDEditors[$editContentZone.data("write")] = $simplemde; initCommentPreviewTab($editContentForm); initSimpleMDEImagePaste($simplemde, $files); $editContentZone.find(".cancel.button").on("click", () => { $renderContent.show(); $editContentZone.hide(); dz.emit("reload"); }); $editContentZone.find(".save.button").on("click", () => { $renderContent.show(); $editContentZone.hide(); const $attachments = $files .find("[name=files]") .map(function () { return $(this).val(); }) .get(); $.post( $editContentZone.data("update-url"), { _csrf: csrf, content: $textarea.val(), context: $editContentZone.data("context"), files: $attachments, }, (data) => { if (data.length === 0 || data.content === "") { $renderContent.html($("#no-content").html()); } else { $renderContent.html(data.content); $("pre code", $renderContent[0]).each(function () { highlight(this); }); } let imageShow = ""; const $content = $segment.parent(); if (!$content.find(".ui.small.images").length) { if (data.attachments !== "" && data.attachments) { if ($content.find(".ui.middle.aligned").length === 0) { imageShow += '
'; imageShow += '
'; imageShow += data.attachments; imageShow += "
"; $content.find(".ui.attached.segment").append(imageShow); } else { $content.find(".ui.middle.aligned").html(data.attachments); } } } else if (data.attachments === "") { $content.find(".ui.small.images").parent().remove(); } else { $content.find(".ui.small.images").html(data.attachments); } dz.emit("submit"); dz.emit("reload"); } ); }); } else { $textarea = $segment.find("textarea"); $simplemde = commentMDEditors[$editContentZone.data("write")]; } // Show write/preview tab and copy raw content as needed $editContentZone.show(); $renderContent.hide(); if ($textarea.val().length === 0) { $textarea.val($rawContent.text()); $simplemde.value($rawContent.text()); } $textarea.focus(); $simplemde.codemirror.focus(); event.preventDefault(); }); // Delete comment $(".delete-comment").on("click", function () { const $this = $(this); if (window.confirm($this.data("locale"))) { $.post($this.data("url"), { _csrf: csrf, }).done(() => { $(`#${$this.data("comment-id")}`).remove(); }); } return false; }); // Change status const $statusButton = $("#status-button"); $("#comment-form .edit_area").on("keyup", function () { if ($(this).val().length === 0) { $statusButton.text($statusButton.data("status")); } else { $statusButton.text($statusButton.data("status-and-comment")); } }); $statusButton.on("click", () => { $("#status").val($statusButton.data("status-val")); $("#comment-form").trigger("submit"); }); // Pull Request merge button const $mergeButton = $(".merge-button > button"); $mergeButton.on("click", function (e) { e.preventDefault(); $(`.${$(this).data("do")}-fields`).show(); $(this).parent().hide(); }); $(".merge-button > .dropdown").dropdown({ onChange(_text, _value, $choice) { if ($choice.data("do")) { $mergeButton.find(".button-text").text($choice.text()); $mergeButton.data("do", $choice.data("do")); } }, }); $(".merge-cancel").on("click", function (e) { e.preventDefault(); $(this).closest(".form").hide(); $mergeButton.parent().show(); }); initReactionSelector(); } // Datasets if ($(".repository.dataset-list.view").length > 0) { const editContentToggle = function () { $("#dataset-content").toggle(); $("#dataset-content-edit").toggle(); $("#dataset-content input").focus(); return false; }; $("[data-dataset-status]").on("click", function () { const $this = $(this); const $private = $this.data("private"); const $is_private = $this.data("is-private"); if ($is_private === $private) { return; } const $uuid = $this.data("uuid"); $.post($this.data("url"), { _csrf: $this.data("csrf"), file: $uuid, is_private: $private, }) .done((_data) => { $(`[data-uuid='${$uuid}']`).removeClass("positive active"); $(`[data-uuid='${$uuid}']`).data("is-private", $private); $this.addClass("positive active"); }) .fail(() => { window.location.reload(); }); }); $("[data-dataset-delete]").on("click", function () { const $this = $(this); $("#data-dataset-delete-modal") .modal({ closable: false, onApprove() { $.post($this.data("remove-url"), { _csrf: $this.data("csrf"), file: $this.data("uuid"), }) .done((_data) => { $(`#${$this.data("uuid")}`).hide(); }) .fail(() => { window.location.reload(); }); }, }) .modal("show"); }); $("[data-category-id]").on("click", function () { const category = $(this).data("category-id"); $("#category").val(category); $("#submit").click(); }); $("[data-task-id]").on("click", function () { const task = $(this).data("task-id"); $("#task").val(task); $("#submit").click(); }); $("[data-license-id]").on("click", function () { const license = $(this).data("license-id"); $("#license").val(license); $("#submit").click(); }); $("#dataset-edit").on("click", editContentToggle); $("#cancel").on("click", editContentToggle); } // Diff if ($(".repository.diff").length > 0) { $(".diff-counter").each(function () { const $item = $(this); const addLine = $item.find("span[data-line].add").data("line"); const delLine = $item.find("span[data-line].del").data("line"); const addPercent = (parseFloat(addLine) / (parseFloat(addLine) + parseFloat(delLine))) * 100; $item.find(".bar .add").css("width", `${addPercent}%`); }); } // Quick start and repository home $("#repo-clone-ssh").on("click", function () { $(".clone-url").text($(this).data("link")); $("#repo-clone-url").val($(this).data("link")); $(this).addClass("blue"); $("#repo-clone-https").removeClass("blue"); localStorage.setItem("repo-clone-protocol", "ssh"); }); $("#repo-clone-https").on("click", function () { $(".clone-url").text($(this).data("link")); $("#repo-clone-url").val($(this).data("link")); $(this).addClass("blue"); $("#repo-clone-ssh").removeClass("blue"); localStorage.setItem("repo-clone-protocol", "https"); }); $("#repo-clone-url").on("click", function () { $(this).select(); }); // Pull request const $repoComparePull = $(".repository.compare.pull"); if ($repoComparePull.length > 0) { initFilterSearchDropdown(".choose.branch .dropdown"); // show pull request form $repoComparePull.find("button.show-form").on("click", function (e) { e.preventDefault(); $repoComparePull.find(".pullrequest-form").show(); autoSimpleMDE.codemirror.refresh(); $(this).parent().hide(); }); } // Branches if ($(".repository.settings.branches").length > 0) { initFilterSearchDropdown(".protected-branches .dropdown"); $(".enable-protection, .enable-whitelist, .enable-statuscheck").on( "change", function () { if (this.checked) { $($(this).data("target")).removeClass("disabled"); } else { $($(this).data("target")).addClass("disabled"); } } ); $(".disable-whitelist").on("change", function () { if (this.checked) { $($(this).data("target")).addClass("disabled"); } }); } // Language stats if ($(".language-stats").length > 0) { $(".language-stats").on("click", (e) => { e.preventDefault(); $(".language-stats-details, .repository-menu").slideToggle(); }); } } function initMigration() { const toggleMigrations = function () { const authUserName = $("#auth_username").val(); const cloneAddr = $("#clone_addr").val(); if ( !$("#mirror").is(":checked") && authUserName && authUserName.length > 0 && cloneAddr !== undefined && (cloneAddr.startsWith("https://github.com") || cloneAddr.startsWith("http://github.com") || cloneAddr.startsWith("http://gitlab.com") || cloneAddr.startsWith("https://gitlab.com")) ) { $("#migrate_items").show(); } else { $("#migrate_items").hide(); } }; toggleMigrations(); $("#clone_addr").on("input", toggleMigrations); $("#auth_username").on("input", toggleMigrations); $("#mirror").on("change", toggleMigrations); } function initPullRequestReview() { $(".show-outdated").on("click", function (e) { e.preventDefault(); const id = $(this).data("comment"); $(this).addClass("hide"); $(`#code-comments-${id}`).removeClass("hide"); $(`#code-preview-${id}`).removeClass("hide"); $(`#hide-outdated-${id}`).removeClass("hide"); }); $(".hide-outdated").on("click", function (e) { e.preventDefault(); const id = $(this).data("comment"); $(this).addClass("hide"); $(`#code-comments-${id}`).addClass("hide"); $(`#code-preview-${id}`).addClass("hide"); $(`#show-outdated-${id}`).removeClass("hide"); }); $("button.comment-form-reply").on("click", function (e) { e.preventDefault(); $(this).hide(); const form = $(this).parent().find(".comment-form"); form.removeClass("hide"); assingMenuAttributes(form.find(".menu")); }); // The following part is only for diff views if ($(".repository.pull.diff").length === 0) { return; } $(".diff-detail-box.ui.sticky").sticky(); $(".btn-review") .on("click", function (e) { e.preventDefault(); $(this).closest(".dropdown").find(".menu").toggle("visible"); }) .closest(".dropdown") .find(".link.close") .on("click", function (e) { e.preventDefault(); $(this).closest(".menu").toggle("visible"); }); $(".code-view .lines-code,.code-view .lines-num") .on("mouseenter", function () { const parent = $(this).closest("td"); $(this) .closest("tr") .addClass( parent.hasClass("lines-num-old") || parent.hasClass("lines-code-old") ? "focus-lines-old" : "focus-lines-new" ); }) .on("mouseleave", function () { $(this).closest("tr").removeClass("focus-lines-new focus-lines-old"); }); $(".add-code-comment").on("click", function (e) { // https://github.com/go-gitea/gitea/issues/4745 if ($(e.target).hasClass("btn-add-single")) { return; } e.preventDefault(); const isSplit = $(this).closest(".code-diff").hasClass("code-diff-split"); const side = $(this).data("side"); const idx = $(this).data("idx"); const path = $(this).data("path"); const form = $("#pull_review_add_comment").html(); const tr = $(this).closest("tr"); let ntr = tr.next(); if (!ntr.hasClass("add-comment")) { ntr = $( `${ isSplit ? '' : '' }` ); tr.after(ntr); } const td = ntr.find(`.add-comment-${side}`); let commentCloud = td.find(".comment-code-cloud"); if (commentCloud.length === 0) { td.html(form); commentCloud = td.find(".comment-code-cloud"); assingMenuAttributes(commentCloud.find(".menu")); td.find("input[name='line']").val(idx); td.find("input[name='side']").val( side === "left" ? "previous" : "proposed" ); td.find("input[name='path']").val(path); } commentCloud.find("textarea").focus(); }); } function assingMenuAttributes(menu) { const id = Math.floor(Math.random() * Math.floor(1000000)); menu.attr("data-write", menu.attr("data-write") + id); menu.attr("data-preview", menu.attr("data-preview") + id); menu.find(".item").each(function () { const tab = $(this).attr("data-tab") + id; $(this).attr("data-tab", tab); }); menu.parent().find("*[data-tab='write']").attr("data-tab", `write${id}`); menu.parent().find("*[data-tab='preview']").attr("data-tab", `preview${id}`); initCommentPreviewTab(menu.parent(".form")); return id; } function initRepositoryCollaboration() { // Change collaborator access mode $(".access-mode.menu .item").on("click", function () { const $menu = $(this).parent(); $.post($menu.data("url"), { _csrf: csrf, uid: $menu.data("uid"), mode: $(this).data("value"), }); }); } function initTeamSettings() { // Change team access mode $(".organization.new.team input[name=permission]").on("change", () => { const val = $( "input[name=permission]:checked", ".organization.new.team" ).val(); if (val === "admin") { $(".organization.new.team .team-units").hide(); } else { $(".organization.new.team .team-units").show(); } }); } function initWikiForm() { const $editArea = $(".repository.wiki textarea#edit_area"); let sideBySideChanges = 0; let sideBySideTimeout = null; if ($editArea.length > 0) { const simplemde = new SimpleMDE({ autoDownloadFontAwesome: false, element: $editArea[0], forceSync: true, previewRender(plainText, preview) { // Async method setTimeout(() => { // FIXME: still send render request when return back to edit mode const render = function () { sideBySideChanges = 0; if (sideBySideTimeout !== null) { clearTimeout(sideBySideTimeout); sideBySideTimeout = null; } $.post( $editArea.data("url"), { _csrf: csrf, mode: "gfm", context: $editArea.data("context"), text: plainText, }, (data) => { preview.innerHTML = `
${data}
`; $(preview) .find("pre code") .each((_, e) => { highlight(e); }); } ); }; if (!simplemde.isSideBySideActive()) { render(); } else { // delay preview by keystroke counting sideBySideChanges++; if (sideBySideChanges > 10) { render(); } // or delay preview by timeout if (sideBySideTimeout !== null) { clearTimeout(sideBySideTimeout); sideBySideTimeout = null; } sideBySideTimeout = setTimeout(render, 600); } }, 0); if (!simplemde.isSideBySideActive()) { return "Loading..."; } return preview.innerHTML; }, renderingConfig: { singleLineBreaks: false, }, indentWithTabs: false, tabSize: 4, spellChecker: false, toolbar: [ "bold", "italic", "strikethrough", "|", "heading-1", "heading-2", "heading-3", "heading-bigger", "heading-smaller", "|", { name: "code-inline", action(e) { const cm = e.codemirror; const selection = cm.getSelection(); cm.replaceSelection(`\`${selection}\``); if (!selection) { const cursorPos = cm.getCursor(); cm.setCursor(cursorPos.line, cursorPos.ch - 1); } cm.focus(); }, className: "fa fa-angle-right", title: "Add Inline Code", }, "code", "quote", "|", { name: "checkbox-empty", action(e) { const cm = e.codemirror; cm.replaceSelection(`\n- [ ] ${cm.getSelection()}`); cm.focus(); }, className: "fa fa-square-o", title: "Add Checkbox (empty)", }, { name: "checkbox-checked", action(e) { const cm = e.codemirror; cm.replaceSelection(`\n- [x] ${cm.getSelection()}`); cm.focus(); }, className: "fa fa-check-square-o", title: "Add Checkbox (checked)", }, "|", "unordered-list", "ordered-list", "|", "link", "image", "table", "horizontal-rule", "|", "clean-block", "preview", "fullscreen", "side-by-side", "|", { name: "revert-to-textarea", action(e) { e.toTextArea(); }, className: "fa fa-file", title: "Revert to simple textarea", }, ], }); $(simplemde.codemirror.getInputField()).addClass("js-quick-submit"); setTimeout(() => { const $bEdit = $('.repository.wiki.new .previewtabs a[data-tab="write"]'); const $bPrev = $( '.repository.wiki.new .previewtabs a[data-tab="preview"]' ); const $toolbar = $(".editor-toolbar"); const $bPreview = $(".editor-toolbar a.fa-eye"); const $bSideBySide = $(".editor-toolbar a.fa-columns"); $bEdit.on("click", () => { if ($toolbar.hasClass("disabled-for-preview")) { $bPreview.trigger("click"); } }); $bPrev.on("click", () => { if (!$toolbar.hasClass("disabled-for-preview")) { $bPreview.trigger("click"); } }); $bPreview.on("click", () => { setTimeout(() => { if ($toolbar.hasClass("disabled-for-preview")) { if ($bEdit.hasClass("active")) { $bEdit.removeClass("active"); } if (!$bPrev.hasClass("active")) { $bPrev.addClass("active"); } } else { if (!$bEdit.hasClass("active")) { $bEdit.addClass("active"); } if ($bPrev.hasClass("active")) { $bPrev.removeClass("active"); } } }, 0); }); $bSideBySide.on("click", () => { sideBySideChanges = 10; }); }, 0); } } // Adding function to get the cursor position in a text field to jQuery object. $.fn.getCursorPosition = function () { const el = $(this).get(0); let pos = 0; if ("selectionStart" in el) { pos = el.selectionStart; } else if ("selection" in document) { el.focus(); const Sel = document.selection.createRange(); const SelLength = document.selection.createRange().text.length; Sel.moveStart("character", -el.value.length); pos = Sel.text.length - SelLength; } return pos; }; function setCommentSimpleMDE($editArea) { const simplemde = new SimpleMDE({ autoDownloadFontAwesome: false, element: $editArea[0], forceSync: true, renderingConfig: { singleLineBreaks: false, }, indentWithTabs: false, tabSize: 4, spellChecker: false, toolbar: [ "bold", "italic", "strikethrough", "|", "heading-1", "heading-2", "heading-3", "heading-bigger", "heading-smaller", "|", "code", "quote", "|", "unordered-list", "ordered-list", "|", "link", "image", "table", "horizontal-rule", "|", "clean-block", "|", { name: "revert-to-textarea", action(e) { e.toTextArea(); }, className: "fa fa-file", title: "Revert to simple textarea", }, ], }); $(simplemde.codemirror.getInputField()).addClass("js-quick-submit"); simplemde.codemirror.setOption("extraKeys", { Enter: () => { if (!(issuesTribute.isActive || emojiTribute.isActive)) { return CodeMirror.Pass; } }, Backspace: (cm) => { if (cm.getInputField().trigger) { cm.getInputField().trigger("input"); } cm.execCommand("delCharBefore"); }, }); issuesTribute.attach(simplemde.codemirror.getInputField()); emojiTribute.attach(simplemde.codemirror.getInputField()); return simplemde; } async function initEditor() { $(".js-quick-pull-choice-option").on("change", function () { if ($(this).val() === "commit-to-new-branch") { $(".quick-pull-branch-name").show(); $(".quick-pull-branch-name input").prop("required", true); } else { $(".quick-pull-branch-name").hide(); $(".quick-pull-branch-name input").prop("required", false); } $("#commit-button").text($(this).attr("button_text")); }); const $editFilename = $("#file-name"); $editFilename .on("keyup", function (e) { const $section = $(".breadcrumb span.section"); const $divider = $(".breadcrumb div.divider"); let value; let parts; if (e.keyCode === 8) { if ($(this).getCursorPosition() === 0) { if ($section.length > 0) { value = $section.last().find("a").text(); $(this).val(value + $(this).val()); $(this)[0].setSelectionRange(value.length, value.length); $section.last().remove(); $divider.last().remove(); } } } if (e.keyCode === 191) { parts = $(this).val().split("/"); for (let i = 0; i < parts.length; ++i) { value = parts[i]; if (i < parts.length - 1) { if (value.length) { $( `${value}` ).insertBefore($(this)); $('
/
').insertBefore($(this)); } } else { $(this).val(value); } $(this)[0].setSelectionRange(0, 0); } } parts = []; $(".breadcrumb span.section").each(function () { const element = $(this); if (element.find("a").length) { parts.push(element.find("a").text()); } else { parts.push(element.text()); } }); if ($(this).val()) parts.push($(this).val()); $("#tree_path").val(parts.join("/")); }) .trigger("keyup"); const $editArea = $(".repository.editor textarea#edit_area"); if (!$editArea.length) return; await createCodeEditor($editArea[0], $editFilename[0], previewFileModes); // Using events from https://github.com/codedance/jquery.AreYouSure#advanced-usage // to enable or disable the commit button const $commitButton = $("#commit-button"); const $editForm = $(".ui.edit.form"); const dirtyFileClass = "dirty-file"; // Disabling the button at the start $commitButton.prop("disabled", true); // Registering a custom listener for the file path and the file content $editForm.areYouSure({ silent: true, dirtyClass: dirtyFileClass, fieldSelector: ":input:not(.commit-form-wrapper :input)", change() { const dirty = $(this).hasClass(dirtyFileClass); $commitButton.prop("disabled", !dirty); }, }); $commitButton.on("click", (event) => { // A modal which asks if an empty file should be committed if ($editArea.val().length === 0) { $("#edit-empty-content-modal") .modal({ onApprove() { $(".edit.form").trigger("submit"); }, }) .modal("show"); event.preventDefault(); } }); } function initOrganization() { if ($(".organization").length === 0) { return; } // Options if ($(".organization.settings.options").length > 0) { $("#org_name").on("keyup", function () { const $prompt = $("#org-name-change-prompt"); if ( $(this).val().toString().toLowerCase() !== $(this).data("org-name").toString().toLowerCase() ) { $prompt.show(); } else { $prompt.hide(); } }); } // Labels if ($(".organization.settings.labels").length > 0) { initLabelEdit(); } } function initUserSettings() { // Options if ($(".user.settings.profile").length > 0) { $("#username").on("keyup", function () { const $prompt = $("#name-change-prompt"); if ( $(this).val().toString().toLowerCase() !== $(this).data("name").toString().toLowerCase() ) { $prompt.show(); } else { $prompt.hide(); } }); } } function initGithook() { if ($(".edit.githook").length === 0) { return; } CodeMirror.autoLoadMode( CodeMirror.fromTextArea($("#content")[0], { lineNumbers: true, mode: "shell", }), "shell" ); } function initWebhook() { if ($(".new.webhook").length === 0) { return; } $(".events.checkbox input").on("change", function () { if ($(this).is(":checked")) { $(".events.fields").show(); } }); $(".non-events.checkbox input").on("change", function () { if ($(this).is(":checked")) { $(".events.fields").hide(); } }); const updateContentType = function () { const visible = $("#http_method").val() === "POST"; $("#content_type").parent().parent()[visible ? "show" : "hide"](); }; updateContentType(); $("#http_method").on("change", () => { updateContentType(); }); // Test delivery $("#test-delivery").on("click", function () { const $this = $(this); $this.addClass("loading disabled"); $.post($this.data("link"), { _csrf: csrf, }).done( setTimeout(() => { window.location.href = $this.data("redirect"); }, 5000) ); }); } function initAdmin() { if ($(".admin").length === 0) { return; } // New user if ($(".admin.new.user").length > 0 || $(".admin.edit.user").length > 0) { $("#login_type").on("change", function () { if ($(this).val().substring(0, 1) === "0") { $("#login_name").removeAttr("required"); $(".non-local").hide(); $(".local").show(); $("#user_name").focus(); if ($(this).data("password") === "required") { $("#password").attr("required", "required"); } } else { $("#login_name").attr("required", "required"); $(".non-local").show(); $(".local").hide(); $("#login_name").focus(); $("#password").removeAttr("required"); } }); } function onSecurityProtocolChange() { if ($("#security_protocol").val() > 0) { $(".has-tls").show(); } else { $(".has-tls").hide(); } } function onUsePagedSearchChange() { if ($("#use_paged_search").prop("checked")) { $(".search-page-size").show().find("input").attr("required", "required"); } else { $(".search-page-size").hide().find("input").removeAttr("required"); } } function onOAuth2Change() { $(".open_id_connect_auto_discovery_url, .oauth2_use_custom_url").hide(); $(".open_id_connect_auto_discovery_url input[required]").removeAttr( "required" ); const provider = $("#oauth2_provider").val(); switch (provider) { case "github": case "gitlab": case "gitea": case "nextcloud": $(".oauth2_use_custom_url").show(); break; case "openidConnect": $(".open_id_connect_auto_discovery_url input").attr( "required", "required" ); $(".open_id_connect_auto_discovery_url").show(); break; } onOAuth2UseCustomURLChange(); } function onOAuth2UseCustomURLChange() { const provider = $("#oauth2_provider").val(); $(".oauth2_use_custom_url_field").hide(); $(".oauth2_use_custom_url_field input[required]").removeAttr("required"); if ($("#oauth2_use_custom_url").is(":checked")) { $("#oauth2_token_url").val($(`#${provider}_token_url`).val()); $("#oauth2_auth_url").val($(`#${provider}_auth_url`).val()); $("#oauth2_profile_url").val($(`#${provider}_profile_url`).val()); $("#oauth2_email_url").val($(`#${provider}_email_url`).val()); switch (provider) { case "github": $( ".oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input, .oauth2_email_url input" ).attr("required", "required"); $( ".oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url, .oauth2_email_url" ).show(); break; case "nextcloud": case "gitea": case "gitlab": $( ".oauth2_token_url input, .oauth2_auth_url input, .oauth2_profile_url input" ).attr("required", "required"); $(".oauth2_token_url, .oauth2_auth_url, .oauth2_profile_url").show(); $("#oauth2_email_url").val(""); break; } } } // New authentication if ($(".admin.new.authentication").length > 0) { $("#auth_type").on("change", function () { $( ".ldap, .dldap, .smtp, .pam, .oauth2, .has-tls, .search-page-size, .sspi" ).hide(); $( ".ldap input[required], .binddnrequired input[required], .dldap input[required], .smtp input[required], .pam input[required], .oauth2 input[required], .has-tls input[required], .sspi input[required]" ).removeAttr("required"); $(".binddnrequired").removeClass("required"); const authType = $(this).val(); switch (authType) { case "2": // LDAP $(".ldap").show(); $(".binddnrequired input, .ldap div.required:not(.dldap) input").attr( "required", "required" ); $(".binddnrequired").addClass("required"); break; case "3": // SMTP $(".smtp").show(); $(".has-tls").show(); $(".smtp div.required input, .has-tls").attr("required", "required"); break; case "4": // PAM $(".pam").show(); $(".pam input").attr("required", "required"); break; case "5": // LDAP $(".dldap").show(); $(".dldap div.required:not(.ldap) input").attr( "required", "required" ); break; case "6": // OAuth2 $(".oauth2").show(); $( ".oauth2 div.required:not(.oauth2_use_custom_url,.oauth2_use_custom_url_field,.open_id_connect_auto_discovery_url) input" ).attr("required", "required"); onOAuth2Change(); break; case "7": // SSPI $(".sspi").show(); $(".sspi div.required input").attr("required", "required"); break; } if (authType === "2" || authType === "5") { onSecurityProtocolChange(); } if (authType === "2") { onUsePagedSearchChange(); } }); $("#auth_type").trigger("change"); $("#security_protocol").on("change", onSecurityProtocolChange); $("#use_paged_search").on("change", onUsePagedSearchChange); $("#oauth2_provider").on("change", onOAuth2Change); $("#oauth2_use_custom_url").on("change", onOAuth2UseCustomURLChange); } // Edit authentication if ($(".admin.edit.authentication").length > 0) { const authType = $("#auth_type").val(); if (authType === "2" || authType === "5") { $("#security_protocol").on("change", onSecurityProtocolChange); if (authType === "2") { $("#use_paged_search").on("change", onUsePagedSearchChange); } } else if (authType === "6") { $("#oauth2_provider").on("change", onOAuth2Change); $("#oauth2_use_custom_url").on("change", onOAuth2UseCustomURLChange); onOAuth2Change(); } } // Notice if ($(".admin.notice")) { const $detailModal = $("#detail-modal"); // Attach view detail modals $(".view-detail").on("click", function () { $detailModal.find(".content pre").text($(this).data("content")); $detailModal.modal("show"); return false; }); // Select actions const $checkboxes = $(".select.table .ui.checkbox"); $(".select.action").on("click", function () { switch ($(this).data("action")) { case "select-all": $checkboxes.checkbox("check"); break; case "deselect-all": $checkboxes.checkbox("uncheck"); break; case "inverse": $checkboxes.checkbox("toggle"); break; } }); $("#delete-selection").on("click", function () { const $this = $(this); $this.addClass("loading disabled"); const ids = []; $checkboxes.each(function () { if ($(this).checkbox("is checked")) { ids.push($(this).data("id")); } }); $.post($this.data("link"), { _csrf: csrf, ids, }).done(() => { window.location.href = $this.data("redirect"); }); }); } } function buttonsClickOnEnter() { $(".ui.button").on("keypress", function (e) { if (e.keyCode === 13 || e.keyCode === 32) { // enter key or space bar $(this).trigger("click"); } }); } function searchUsers() { const $searchUserBox = $("#search-user-box"); $searchUserBox.search({ minCharacters: 2, apiSettings: { url: `${AppSubUrl}/api/v1/users/search?q={query}`, onResponse(response) { const items = []; $.each(response.data, (_i, item) => { let title = item.login; if (item.full_name && item.full_name.length > 0) { title += ` (${htmlEncode(item.full_name)})`; } items.push({ title, image: item.avatar_url, }); }); return { results: items }; }, }, searchFields: ["login", "full_name"], showNoResults: false, }); } function searchTeams() { const $searchTeamBox = $("#search-team-box"); $searchTeamBox.search({ minCharacters: 2, apiSettings: { url: `${AppSubUrl}/api/v1/orgs/${$searchTeamBox.data( "org" )}/teams/search?q={query}`, headers: { "X-Csrf-Token": csrf }, onResponse(response) { const items = []; $.each(response.data, (_i, item) => { const title = `${item.name} (${item.permission} access)`; items.push({ title, }); }); return { results: items }; }, }, searchFields: ["name", "description"], showNoResults: false, }); } function searchRepositories() { const $searchRepoBox = $("#search-repo-box"); $searchRepoBox.search({ minCharacters: 2, apiSettings: { url: `${AppSubUrl}/api/v1/repos/search?q={query}&uid=${$searchRepoBox.data( "uid" )}`, onResponse(response) { const items = []; $.each(response.data, (_i, item) => { items.push({ title: item.full_display_name.split("/")[1], description: item.full_display_name, }); }); return { results: items }; }, }, searchFields: ["full_name"], showNoResults: false, }); } function initCodeView() { if ($(".code-view .linenums").length > 0) { $(document).on("click", ".lines-num span", function (e) { const $select = $(this); const $list = $select .parent() .siblings(".lines-code") .find("ol.linenums > li"); selectRange( $list, $list.filter(`[rel=${$select.attr("id")}]`), e.shiftKey ? $list.filter(".active").eq(0) : null ); deSelect(); }); $(window) .on("hashchange", () => { let m = window.location.hash.match(/^#(L\d+)-(L\d+)$/); const $list = $(".code-view ol.linenums > li"); let $first; if (m) { $first = $list.filter(`.${m[1]}`); selectRange($list, $first, $list.filter(`.${m[2]}`)); $("html, body").scrollTop($first.offset().top - 200); return; } m = window.location.hash.match(/^#(L|n)(\d+)$/); if (m) { $first = $list.filter(`.L${m[2]}`); selectRange($list, $first); $("html, body").scrollTop($first.offset().top - 200); } }) .trigger("hashchange"); } $(".fold-code").on("click", ({ target }) => { const box = target.closest(".file-content"); const folded = box.dataset.folded !== "true"; target.classList.add(`fa-chevron-${folded ? "right" : "down"}`); target.classList.remove(`fa-chevron-${folded ? "down" : "right"}`); box.dataset.folded = String(folded); }); function insertBlobExcerpt(e) { const $blob = $(e.target); const $row = $blob.parent().parent(); $.get( `${$blob.data("url")}?${$blob.data("query")}&anchor=${$blob.data( "anchor" )}`, (blob) => { $row.replaceWith(blob); $(`[data-anchor="${$blob.data("anchor")}"]`).on("click", (e) => { insertBlobExcerpt(e); }); $(".diff-detail-box.ui.sticky").sticky(); } ); } $(".ui.blob-excerpt").on("click", (e) => { insertBlobExcerpt(e); }); } function initU2FAuth() { if ($("#wait-for-key").length === 0) { return; } u2fApi .ensureSupport() .then(() => { $.getJSON(`${AppSubUrl}/user/u2f/challenge`).done((req) => { u2fApi .sign(req.appId, req.challenge, req.registeredKeys, 30) .then(u2fSigned) .catch((err) => { if (err === undefined) { u2fError(1); return; } u2fError(err.metaData.code); }); }); }) .catch(() => { // Fallback in case browser do not support U2F window.location.href = `${AppSubUrl}/user/two_factor`; }); } function u2fSigned(resp) { $.ajax({ url: `${AppSubUrl}/user/u2f/sign`, type: "POST", headers: { "X-Csrf-Token": csrf }, data: JSON.stringify(resp), contentType: "application/json; charset=utf-8", }) .done((res) => { window.location.replace(res); }) .fail(() => { u2fError(1); }); } function u2fRegistered(resp) { if (checkError(resp)) { return; } $.ajax({ url: `${AppSubUrl}/user/settings/security/u2f/register`, type: "POST", headers: { "X-Csrf-Token": csrf }, data: JSON.stringify(resp), contentType: "application/json; charset=utf-8", success() { reload(); }, fail() { u2fError(1); }, }); } function checkError(resp) { if (!("errorCode" in resp)) { return false; } if (resp.errorCode === 0) { return false; } u2fError(resp.errorCode); return true; } function u2fError(errorType) { const u2fErrors = { browser: $("#unsupported-browser"), 1: $("#u2f-error-1"), 2: $("#u2f-error-2"), 3: $("#u2f-error-3"), 4: $("#u2f-error-4"), 5: $(".u2f-error-5"), }; u2fErrors[errorType].removeClass("hide"); Object.keys(u2fErrors).forEach((type) => { if (type !== errorType) { u2fErrors[type].addClass("hide"); } }); $("#u2f-error").modal("show"); } function initU2FRegister() { $("#register-device").modal({ allowMultiple: false }); $("#u2f-error").modal({ allowMultiple: false }); $("#register-security-key").on("click", (e) => { e.preventDefault(); u2fApi .ensureSupport() .then(u2fRegisterRequest) .catch(() => { u2fError("browser"); }); }); } function u2fRegisterRequest() { $.post(`${AppSubUrl}/user/settings/security/u2f/request_register`, { _csrf: csrf, name: $("#nickname").val(), }) .done((req) => { $("#nickname").closest("div.field").removeClass("error"); $("#register-device").modal("show"); if (req.registeredKeys === null) { req.registeredKeys = []; } u2fApi .register(req.appId, req.registerRequests, req.registeredKeys, 30) .then(u2fRegistered) .catch((reason) => { if (reason === undefined) { u2fError(1); return; } u2fError(reason.metaData.code); }); }) .fail((xhr) => { if (xhr.status === 409) { $("#nickname").closest("div.field").addClass("error"); } }); } function initWipTitle() { $(".title_wip_desc > a").on("click", (e) => { e.preventDefault(); const $issueTitle = $("#issue_title"); $issueTitle.focus(); const value = $issueTitle.val().trim().toUpperCase(); for (const i in wipPrefixes) { if (value.startsWith(wipPrefixes[i].toUpperCase())) { return; } } $issueTitle.val(`${wipPrefixes[0]} ${$issueTitle.val()}`); }); } function initTemplateSearch() { const $repoTemplate = $("#repo_template"); const checkTemplate = function () { const $templateUnits = $("#template_units"); const $nonTemplate = $("#non_template"); if ($repoTemplate.val() !== "" && $repoTemplate.val() !== "0") { $templateUnits.show(); $nonTemplate.hide(); } else { $templateUnits.hide(); $nonTemplate.show(); } }; $repoTemplate.on("change", checkTemplate); checkTemplate(); const changeOwner = function () { $("#repo_template_search").dropdown({ apiSettings: { url: `${AppSubUrl}/api/v1/repos/search?q={query}&template=true&priority_owner_id=${$( "#uid" ).val()}`, onResponse(response) { const filteredResponse = { success: true, results: [] }; filteredResponse.results.push({ name: "", value: "", }); // Parse the response from the api to work with our dropdown $.each(response.data, (_r, repo) => { filteredResponse.results.push({ name: htmlEncode(repo.full_display_name), value: repo.id, }); }); return filteredResponse; }, cache: false, }, fullTextSearch: true, }); }; $("#uid").on("change", changeOwner); changeOwner(); } $(document).ready(async () => { // Show exact time $(".time-since").each(function () { $(this) .addClass("poping up") .attr("data-content", $(this).attr("title")) .attr("data-variation", "inverted tiny") .attr("title", ""); }); // Semantic UI modules. $(".dropdown:not(.custom)").dropdown(); $(".jump.dropdown").dropdown({ action: "hide", onShow() { $(".poping.up").popup("hide"); }, }); $(".slide.up.dropdown").dropdown({ transition: "slide up", }); $(".upward.dropdown").dropdown({ direction: "upward", }); $(".ui.accordion").accordion(); $(".ui.checkbox").checkbox(); $(".ui.progress").progress({ showActivity: false, }); $(".poping.up").popup(); $(".top.menu .poping.up").popup({ onShow() { if ($(".top.menu .menu.transition").hasClass("visible")) { return false; } }, }); $(".tabular.menu .item").tab(); $(".tabable.menu .item").tab(); $(".toggle.button").on("click", function () { $($(this).data("target")).slideToggle(100); }); // make table element clickable like a link $("tr[data-href]").on("click", function () { window.location = $(this).data("href"); }); // make table element clickable like a link $("td[data-href]").click(function () { window.location = $(this).data("href"); }); // 在String原型对象上添加format方法 String.prototype.format = function () { let str = this; if (arguments.length == 0) { return str; } else { Object.keys(arguments).forEach((item, index) => { str = str.replace(/\?/, arguments[item]); }); return str; } }; // Dropzone const $dropzone = $("#dropzone"); if ($dropzone.length > 0) { const filenameDict = {}; let maxFileTooltips; let maxSizeTooltips; if ( $dropzone.data("max-file-tooltips") && $dropzone.data("max-size-tooltips") ) { maxFileTooltips = $dropzone .data("max-file-tooltips") .format($dropzone.data("max-file"), $dropzone.data("max-size")); maxSizeTooltips = $dropzone .data("max-size-tooltips") .format($dropzone.data("max-file")); } await createDropzone("#dropzone", { url: $dropzone.data("upload-url"), headers: { "X-Csrf-Token": csrf }, maxFiles: $dropzone.data("max-file"), maxFilesize: $dropzone.data("max-size"), acceptedFiles: $dropzone.data("accepts") === "*/*" ? null : $dropzone.data("accepts"), addRemoveLinks: true, dictDefaultMessage: $dropzone.data("default-message"), dictInvalidFileType: $dropzone.data("invalid-input-type"), dictFileTooBig: $dropzone.data("file-too-big"), dictRemoveFile: $dropzone.data("remove-file"), init() { this.on("success", (file, data) => { filenameDict[file.name] = data.uuid; const input = $( `` ).val(data.uuid); $(".files").append(input); }); this.on("removedfile", (file) => { if (file.name in filenameDict) { $(`#${filenameDict[file.name]}`).remove(); } if ($dropzone.data("remove-url") && $dropzone.data("csrf")) { $.post($dropzone.data("remove-url"), { file: filenameDict[file.name], _csrf: $dropzone.data("csrf"), }); } }); this.on("addedfile", (file) => { if (file.size / (1000 * 1000) > $dropzone.data("max-size")) { this.removeFile(file); if (maxFileTooltips) { $(".maxfilesize.ui.red.message").text(maxFileTooltips); $(".maxfilesize.ui.red.message").css("display", "block"); } } else { if (maxFileTooltips) { $(".maxfilesize.ui.red.message").css("display", "none"); } } }); this.on("maxfilesexceeded", (file) => { this.removeFile(file); if (maxSizeTooltips) { $(".maxfilesize.ui.red.message").text(maxSizeTooltips); $(".maxfilesize.ui.red.message").css("display", "block"); } }); }, }); } // Helpers. $(".delete-button").on("click", showDeletePopup); $(".add-all-button").on("click", showAddAllPopup); $(".link-action").on("click", linkAction); $(".link-email-action").on("click", linkEmailAction); $(".delete-branch-button").on("click", showDeletePopup); $(".undo-button").on("click", function () { const $this = $(this); $.post($this.data("url"), { _csrf: csrf, id: $this.data("id"), }).done((data) => { window.location.href = data.redirect; }); }); $(".show-panel.button").on("click", function () { $($(this).data("panel")).show(); }); $(".show-modal.button").on("click", function () { $($(this).data("modal")).modal("show"); }); $(".delete-post.button").on("click", function () { const $this = $(this); $.post($this.data("request-url"), { _csrf: csrf, }).done(() => { window.location.href = $this.data("done-url"); }); }); // Set anchor. $(".markdown").each(function () { $(this) .find("h1, h2, h3, h4, h5, h6") .each(function () { let node = $(this); node = node.wrap('
'); node.append( `${svg("octicon-link", 16)}` ); }); }); $(".issue-checkbox").on("click", () => { const numChecked = $(".issue-checkbox").children("input:checked").length; if (numChecked > 0) { $("#issue-filters").addClass("hide"); $("#issue-actions").removeClass("hide"); } else { $("#issue-filters").removeClass("hide"); $("#issue-actions").addClass("hide"); } }); $(".issue-action").on("click", function () { let { action } = this.dataset; let { elementId } = this.dataset; const issueIDs = $(".issue-checkbox") .children("input:checked") .map(function () { return this.dataset.issueId; }) .get() .join(); console.log("this:", this); const { url } = this.dataset; if (elementId === "0" && url.substr(-9) === "/assignee") { elementId = ""; action = "clear"; } updateIssuesMeta(url, action, issueIDs, elementId, "").then(() => { // NOTICE: This reset of checkbox state targets Firefox caching behaviour, as the checkboxes stay checked after reload if (action === "close" || action === "open") { // uncheck all checkboxes $('.issue-checkbox input[type="checkbox"]').each((_, e) => { e.checked = false; }); } reload(); }); }); // NOTICE: This event trigger targets Firefox caching behaviour, as the checkboxes stay checked after reload // trigger ckecked event, if checkboxes are checked on load $('.issue-checkbox input[type="checkbox"]:checked') .first() .each((_, e) => { e.checked = false; $(e).trigger("click"); }); $(".resolve-conversation").on("click", function (e) { e.preventDefault(); const id = $(this).data("comment-id"); const action = $(this).data("action"); const url = $(this).data("update-url"); $.post(url, { _csrf: csrf, action, comment_id: id, }).then(reload); }); buttonsClickOnEnter(); searchUsers(); searchTeams(); searchRepositories(); initCommentForm(); initInstall(); initRepository(); initMigration(); initWikiForm(); initEditForm(); initEditor(); initOrganization(); initGithook(); initWebhook(); initAdmin(); initCodeView(); initVueApp(); initVueUploader(); initVueDataset(); initVueEditAbout(); initVueEditTopic(); initVueContributors(); // initVueImages(); initVueModel(); initVueDataAnalysis(); initVueWxAutorize(); initVueselectDataset(); initVuereferenceDataset(); initTeamSettings(); initCtrlEnterSubmit(); initNavbarContentToggle(); // initTopicbar();vim // closeTopicbar(); initU2FAuth(); initU2FRegister(); initIssueList(); initWipTitle(); initPullRequestReview(); initRepoStatusChecker(); initTemplateSearch(); initContextPopups(); initNotificationsTable(); initNotificationCount(); initTribute(); initDropDown(); initCloudrain(); initCloudrainSow(); initImage(); initContextMenu(); // Repo clone url. if ($("#repo-clone-url").length > 0) { switch (localStorage.getItem("repo-clone-protocol")) { case "ssh": if ($("#repo-clone-ssh").length === 0) { $("#repo-clone-https").trigger("click"); } break; default: $("#repo-clone-https").trigger("click"); break; } } const routes = { "div.user.settings": initUserSettings, "div.repository.settings.collaboration": initRepositoryCollaboration, }; let selector; for (selector in routes) { if ($(selector).length > 0) { routes[selector](); break; } } const $cloneAddr = $("#clone_addr"); $cloneAddr.on("input change", () => { const $repoName = $("#alias"); const $owner = $("#ownerDropdown div.text").attr("title"); const $urlAdd = location.href.split("/")[0] + "//" + location.href.split("/")[2]; if ($cloneAddr.val().length > 0 /* && $repoName.val().length === 0 */) { // modify when clone address change const repoValue = $cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]; $repoName.val($cloneAddr.val().match(/^(.*\/)?((.+?)(\.git)?)$/)[3]); $.get( `${window.config.AppSubUrl}/repo/check_name?q=${repoValue}&owner=${$owner}`, (data) => { const repo_name = data.name; $("#repo_name").val(repo_name); repo_name && $("#repo_name").parent().removeClass("error"); $("#repoAdress").css("display", "flex"); $("#repoAdress span").text( $urlAdd + "/" + $owner + "/" + $("#repo_name").val() + ".git" ); $("#repo_name").attr("placeholder", ""); } ); } }); // parallel init of lazy-loaded features await Promise.all([ highlight(document.querySelectorAll("pre code")), initGitGraph(), initClipboard(), initUserHeatmap(), ]); }); function changeHash(hash) { if (window.history.pushState) { window.history.pushState(null, null, hash); } else { window.location.hash = hash; } } function deSelect() { if (window.getSelection) { window.getSelection().removeAllRanges(); } else { document.selection.empty(); } } function selectRange($list, $select, $from) { $list.removeClass("active"); if ($from) { let a = parseInt($select.attr("rel").substr(1)); let b = parseInt($from.attr("rel").substr(1)); let c; if (a !== b) { if (a > b) { c = a; a = b; b = c; } const classes = []; for (let i = a; i <= b; i++) { classes.push(`.L${i}`); } $list.filter(classes.join(",")).addClass("active"); changeHash(`#L${a}-L${b}`); return; } } $select.addClass("active"); changeHash(`#${$select.attr("rel")}`); } $(() => { // Warn users that try to leave a page after entering data into a form. // Except on sign-in pages, and for forms marked as 'ignore-dirty'. if ($(".user.signin").length === 0) { $("form:not(.ignore-dirty)").areYouSure(); } // Parse SSH Key $("#ssh-key-content").on("change paste keyup", function () { const arrays = $(this).val().split(" "); const $title = $("#ssh-key-title"); if ($title.val() === "" && arrays.length === 3 && arrays[2] !== "") { $title.val(arrays[2]); } }); }); function showDeletePopup() { const $this = $(this); let filter = ""; if ($this.attr("id")) { filter += `#${$this.attr("id")}`; } const dialog = $(`.delete.modal${filter}`); dialog.find(".name").text($this.data("name")); dialog .modal({ closable: false, onApprove() { if ($this.data("type") === "form") { $($this.data("form")).trigger("submit"); return; } $.post($this.data("url"), { _csrf: csrf, id: $this.data("id"), }).done((data) => { window.location.href = data.redirect; }); }, }) .modal("show"); return false; } function showAddAllPopup() { const $this = $(this); let filter = ""; if ($this.attr("id")) { filter += `#${$this.attr("id")}`; } const dialog = $(`.addall.modal${filter}`); dialog.find(".name").text($this.data("name")); dialog .modal({ closable: false, onApprove() { if ($this.data("type") === "form") { $($this.data("form")).trigger("submit"); return; } $.post($this.data("url"), { _csrf: csrf, id: $this.data("id"), }).done((data) => { window.location.href = data.redirect; }); }, }) .modal("show"); return false; } function linkAction(e) { e.preventDefault(); const $this = $(this); const redirect = $this.data("redirect"); $.post($this.data("url"), { _csrf: csrf, }).done((data) => { if (data.redirect) { window.location.href = data.redirect; } else if (redirect) { window.location.href = redirect; } else { window.location.reload(); } }); } function linkEmailAction(e) { const $this = $(this); $("#form-uid").val($this.data("uid")); $("#form-email").val($this.data("email")); $("#form-primary").val($this.data("primary")); $("#form-activate").val($this.data("activate")); $("#form-uid").val($this.data("uid")); $("#change-email-modal").modal("show"); e.preventDefault(); } function initVueComponents() { const vueDelimeters = ["${", "}"]; Vue.component("repo-search", { delimiters: vueDelimeters, props: { searchLimit: { type: Number, default: 10, }, suburl: { type: String, required: true, }, uid: { type: Number, required: true, }, organizations: { type: Array, default: [], }, isOrganization: { type: Boolean, default: true, }, canCreateOrganization: { type: Boolean, default: false, }, organizationsTotalCount: { type: Number, default: 0, }, moreReposLink: { type: String, default: "", }, }, data() { const params = new URLSearchParams(window.location.search); let tab = params.get("repo-search-tab"); if (!tab) { tab = "repos"; } let reposFilter = params.get("repo-search-filter"); if (!reposFilter) { reposFilter = "all"; } let privateFilter = params.get("repo-search-private"); if (!privateFilter) { privateFilter = "both"; } let archivedFilter = params.get("repo-search-archived"); if (!archivedFilter) { archivedFilter = "unarchived"; } let searchQuery = params.get("repo-search-query"); if (!searchQuery) { searchQuery = ""; } let page = 1; try { page = parseInt(params.get("repo-search-page")); } catch { // noop } if (!page) { page = 1; } return { tab, repos: [], reposTotalCount: 0, reposFilter, archivedFilter, privateFilter, page, finalPage: 1, searchQuery, isLoading: false, staticPrefix: StaticUrlPrefix, counts: {}, repoTypes: { all: { searchMode: "", }, forks: { searchMode: "fork", }, mirrors: { searchMode: "mirror", }, sources: { searchMode: "source", }, collaborative: { searchMode: "collaborative", }, }, }; }, computed: { showMoreReposLink() { return ( this.repos.length > 0 && this.repos.length < this.counts[ `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}` ] ); }, searchURL() { return `${ this.suburl }/api/v1/repos/search?sort=updated&order=desc&uid=${this.uid}&q=${ this.searchQuery }&page=${this.page}&limit=${this.searchLimit}&mode=${ this.repoTypes[this.reposFilter].searchMode }${this.reposFilter !== "all" ? "&exclusive=1" : ""}${ this.archivedFilter === "archived" ? "&archived=true" : "" }${this.archivedFilter === "unarchived" ? "&archived=false" : ""}${ this.privateFilter === "private" ? "&onlyPrivate=true" : "" }${this.privateFilter === "public" ? "&private=false" : ""}`; }, repoTypeCount() { return this.counts[ `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}` ]; }, }, mounted() { this.searchRepos(this.reposFilter); $(this.$el).find(".poping.up").popup(); $(this.$el).find(".dropdown").dropdown(); this.setCheckboxes(); const self = this; Vue.nextTick(() => { self.$refs.search.focus(); }); }, methods: { changeTab(t) { this.tab = t; this.updateHistory(); }, setCheckboxes() { switch (this.archivedFilter) { case "unarchived": $("#archivedFilterCheckbox").checkbox("set unchecked"); break; case "archived": $("#archivedFilterCheckbox").checkbox("set checked"); break; case "both": $("#archivedFilterCheckbox").checkbox("set indeterminate"); break; default: this.archivedFilter = "unarchived"; $("#archivedFilterCheckbox").checkbox("set unchecked"); break; } switch (this.privateFilter) { case "public": $("#privateFilterCheckbox").checkbox("set unchecked"); break; case "private": $("#privateFilterCheckbox").checkbox("set checked"); break; case "both": $("#privateFilterCheckbox").checkbox("set indeterminate"); break; default: this.privateFilter = "both"; $("#privateFilterCheckbox").checkbox("set indeterminate"); break; } }, changeReposFilter(filter) { this.reposFilter = filter; this.repos = []; this.page = 1; Vue.set( this.counts, `${filter}:${this.archivedFilter}:${this.privateFilter}`, 0 ); this.searchRepos(); }, updateHistory() { const params = new URLSearchParams(window.location.search); if (this.tab === "repos") { params.delete("repo-search-tab"); } else { params.set("repo-search-tab", this.tab); } if (this.reposFilter === "all") { params.delete("repo-search-filter"); } else { params.set("repo-search-filter", this.reposFilter); } if (this.privateFilter === "both") { params.delete("repo-search-private"); } else { params.set("repo-search-private", this.privateFilter); } if (this.archivedFilter === "unarchived") { params.delete("repo-search-archived"); } else { params.set("repo-search-archived", this.archivedFilter); } if (this.searchQuery === "") { params.delete("repo-search-query"); } else { params.set("repo-search-query", this.searchQuery); } if (this.page === 1) { params.delete("repo-search-page"); } else { params.set("repo-search-page", `${this.page}`); } window.history.replaceState({}, "", `?${params.toString()}`); }, toggleArchivedFilter() { switch (this.archivedFilter) { case "both": this.archivedFilter = "unarchived"; break; case "unarchived": this.archivedFilter = "archived"; break; case "archived": this.archivedFilter = "both"; break; default: this.archivedFilter = "unarchived"; break; } this.page = 1; this.repos = []; this.setCheckboxes(); Vue.set( this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0 ); this.searchRepos(); }, togglePrivateFilter() { switch (this.privateFilter) { case "both": this.privateFilter = "public"; break; case "public": this.privateFilter = "private"; break; case "private": this.privateFilter = "both"; break; default: this.privateFilter = "both"; break; } this.page = 1; this.repos = []; this.setCheckboxes(); Vue.set( this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0 ); this.searchRepos(); }, changePage(page) { this.page = page; if (this.page > this.finalPage) { this.page = this.finalPage; } if (this.page < 1) { this.page = 1; } this.repos = []; Vue.set( this.counts, `${this.reposFilter}:${this.archivedFilter}:${this.privateFilter}`, 0 ); this.searchRepos(); }, showArchivedRepo(repo) { switch (this.archivedFilter) { case "both": return true; case "unarchived": return !repo.archived; case "archived": return repo.archived; default: return !repo.archived; } }, showPrivateRepo(repo) { switch (this.privateFilter) { case "both": return true; case "public": return !repo.private; case "private": return repo.private; default: return true; } }, showFilteredRepo(repo) { switch (this.reposFilter) { case "sources": return repo.owner.id === this.uid && !repo.mirror && !repo.fork; case "forks": return repo.owner.id === this.uid && !repo.mirror && repo.fork; case "mirrors": return repo.mirror; case "collaborative": return repo.owner.id !== this.uid && !repo.mirror; default: return true; } }, showRepo(repo) { return ( this.showArchivedRepo(repo) && this.showPrivateRepo(repo) && this.showFilteredRepo(repo) ); }, searchRepos() { const self = this; this.isLoading = true; const searchedMode = this.repoTypes[this.reposFilter].searchMode; const searchedURL = this.searchURL; const searchedQuery = this.searchQuery; $.getJSON(searchedURL, (result, _textStatus, request) => { if (searchedURL === self.searchURL) { self.repos = result.data; const count = request.getResponseHeader("X-Total-Count"); if ( searchedQuery === "" && searchedMode === "" && self.archivedFilter === "both" ) { self.reposTotalCount = count; } Vue.set( self.counts, `${self.reposFilter}:${self.archivedFilter}:${self.privateFilter}`, count ); self.finalPage = Math.ceil(count / self.searchLimit); self.updateHistory(); } }).always(() => { if (searchedURL === self.searchURL) { self.isLoading = false; } }); }, repoClass(repo) { if (repo.fork) { return "octicon-repo-forked"; } if (repo.mirror) { return "octicon-repo-clone"; } if (repo.template) { return `octicon-repo-template${repo.private ? "-private" : ""}`; } if (repo.private) { return "octicon-lock"; } return "octicon-repo"; }, }, }); } function initCtrlEnterSubmit() { $(".js-quick-submit").on("keydown", function (e) { if ( ((e.ctrlKey && !e.altKey) || e.metaKey) && (e.keyCode === 13 || e.keyCode === 10) ) { $(this).closest("form").trigger("submit"); } }); } function initVueApp() { const el = document.getElementById("app"); if (!el) { return; } initVueComponents(); new Vue({ delimiters: ["${", "}"], el, data: { page: parseInt(new URLSearchParams(window.location.search).get("page")), searchLimit: Number( (document.querySelector("meta[name=_search_limit]") || {}).content ), page: 1, suburl: AppSubUrl, uid: Number( (document.querySelector("meta[name=_context_uid]") || {}).content ), activityTopAuthors: window.ActivityTopAuthors || [], localHref: "", }, components: { ActivityTopAuthors, }, mounted() { this.page = parseInt( new URLSearchParams(window.location.search).get("page") ); this.localHref = location.href; }, methods: { handleCurrentChange: function (val) { const searchParams = new URLSearchParams(window.location.search); if (!window.location.search) { window.location.href = this.localHref + "?page=" + val; } else if (searchParams.has("page")) { window.location.href = this.localHref.replace( /page=[0-9]+/g, "page=" + val ); } else { window.location.href = location.href + "&page=" + val; } this.page = val; }, }, }); } function initVueUploader() { const el = document.getElementById("minioUploader"); if (!el) { return; } new Vue({ el: "#minioUploader", components: { MinioUploader }, template: "", }); } function initVueEditAbout() { const el = document.getElementById("about-desc"); if (!el) { return; } new Vue({ el: "#about-desc", render: (h) => h(EditAboutInfo), }); } function initVueDataset() { if ($("#dataset_check").length) { if (location.search.indexOf("recommend=true") !== -1) { $("#dataset_check").checkbox("set checked"); } else { $("#dataset_check").checkbox("set unchecked"); } $("#dataset_check").checkbox({ onChecked: function () { if (location.search) { const params = new URLSearchParams(location.search); if (params.has("recommend")) { params.delete("recommend"); location.href = AppSubUrl + location.pathname + "?" + params.toString() + "&recommend=true"; } else { location.href = `${window.config.AppSubUrl}/admin/datasets${location.search}&recommend=true`; } } else { location.href = `${window.config.AppSubUrl}/admin/datasets?recommend=true`; } }, onUnchecked: function () { if (location.search == "?recommend=true") { location.href = AppSubUrl + location.pathname; } else { const params = new URLSearchParams(location.search); params.delete("recommend"); location.href = AppSubUrl + location.pathname + "?" + params.toString(); } }, }); } $(".set_dataset").on("click", function () { const $this = $(this); let link = $this.data("url"); $.ajax({ url: link, type: "PUT", success: function (res) { console.log(res); if (res.Code == 0) { window.location.href = "/admin/datasets"; } else { $(".ui.negative.message") .text(res.Message) .show() .delay(1500) .fadeOut(); } }, error: function (xhr) { // 隐藏 loading // 只有请求不正常(状态码不为200)才会执行 $(".ui.negative.message") .html(xhr.responseText) .show() .delay(1500) .fadeOut(); console.log(xhr); }, complete: function (xhr) { // $("#mask").css({"display":"none","z-index":"1"}) }, }); }); const el = document.getElementById("dataset-base"); if (!el) { return; } let link = $("#square-link").data("link"); let repolink = $(".dataset-repolink").data("repolink"); let datasetType = $(".dataset-repolink").data("dataset-type"); const clearBtn = document.getElementsByClassName("clear_dataset_value"); const params = new URLSearchParams(location.search); for (let i = 0; i < clearBtn.length; i++) { clearBtn[i].addEventListener("click", function (e) { let searchType = e.target.getAttribute("data-clear-value"); if (params.has(searchType)) { params.delete(searchType); let clearSearch = params.toString(); location.href = link + "?" + clearSearch; } }); } const items = []; const zipStatus = []; $("#dataset-range-value") .find(".item") .each(function () { items.push($(this).data("private")); zipStatus.push($(this).data("decompress-state")); }); let num_stars = $("#dataset-range-value").data("num-stars"); let star_active = $("#dataset-range-value").data("star-active"); const ruleForm = {}; if (document.getElementById("dataset-edit-value")) { let $this = $("#dataset-edit-value"); ruleForm.title = $this.data("edit-title") || ""; ruleForm.description = $this.data("edit-description") || ""; ruleForm.category = $this.data("edit-category") || ""; ruleForm.task = $this.data("edit-task") || ""; ruleForm.license = $this.data("edit-license") || ""; ruleForm.id = $this.data("edit-id") || ""; ruleForm._csrf = csrf; } const starItems = []; const starActives = []; $("#datasets-square-range-value") .find(".item") .each(function () { starItems.push($(this).data("num-stars")); starActives.push($(this).data("star-active")); }); const taskLists = []; const licenseLists = []; $("#task-square-range-value") .find(".item") .each(function () { taskLists.push($(this).data("task")); }); $("#task-square-range-value") .find(".item") .each(function () { licenseLists.push($(this).data("license")); }); let dataset_file_desc; if (document.getElementById("dataset-file-desc")) { dataset_file_desc = document.getElementById("dataset-file-desc").value; } new Vue({ delimiters: ["${", "}"], el, data: { suburl: AppSubUrl, url: "", checked: false, clusterFlag: false, type: 0, desc: "", descfile: "", datasetType: "", privates: [], zipStatus: [], starItems: [], starActives: [], taskLists: [], taskShow: [], licenseLists: [], licenseShow: [], hasMoreBthHis: false, showMoreHis: false, star_active: false, num_stars: 0, dialogVisible: false, activeName: "first", searchDataItem: "", currentRepoDataset: [], myDataset: [], publicDataset: [], myFavoriteDataset: [], page: 1, totalnums: 0, repolink: "", datasetType: 0, dataset_uuid: "", dataset_name: "", loadingDataIndex: false, timer: null, ruleForm: { title: "", description: "", category: "", task: "", license: "", _csrf: csrf, }, ruleForm1: { title: "", description: "", category: "", task: "", license: "", _csrf: "", id: "", }, rules: { title: [ { required: true, message: "请输入数据集名称", trigger: "blur" }, { min: 1, max: 100, message: "长度在 1 到 100 个字符", trigger: "blur", }, // {required:true,message:'test',pattern:'/^[a-zA-Z0-9-_]{1,100}[^-]$/',trigger:'blur'}, { validator: (rule, value, callback) => { if (/^[a-zA-Z0-9-_.]{0,100}$/.test(value) == false) { callback(new Error("输入不符合数据集名称规则")); } else { callback(); } }, trigger: "blur", }, ], description: [ { required: true, message: "请输入数据集描述详情", trigger: "blur" }, ], category: [ { required: true, message: "请选择分类", trigger: "change" }, ], task: [ { required: true, message: "请选择研究方向/应用领域", trigger: "change", }, ], // license: [ // { required: true, message: '请选择活动区域', trigger: 'change' } // ] }, }, components: { MinioUploader, }, mounted() { if (document.getElementById("fail_dataset_name")) { this.dataset_name = document.getElementById("fail_dataset_name").value; this.dataset_uuid = document.getElementById("fail_dataset_uuid").value; } this.getTypeList(); if (!!document.getElementById("dataset-repolink-init")) { // this.datasetType = location.href.indexOf('cloudbrain') !== -1 ? 0 : 1 this.datasetType = $("#dataset-repolink-init").data("dataset-type"); this.getCurrentRepoDataset(this.repolink, this.datasetType); } const params = new URLSearchParams(location.search); if (params.has("recommend") && params.get("recommend") == "true") { this.checked = true; } else { this.checked = false; } }, created() { if (document.getElementById("postPath")) { this.url = document.getElementById("postPath").value; } this.privates = items; this.zipStatus = zipStatus; this.num_stars = num_stars; this.star_active = star_active; this.ruleForm1 = ruleForm; // this.getEditInit() this.starItems = starItems; this.starActives = starActives; this.taskLists = taskLists; this.licenseLists = licenseLists; this.descfile = dataset_file_desc; this.repolink = repolink; this.datasetType = datasetType; }, methods: { copyUrl(url) { const cInput = document.createElement("input"); cInput.value = url; document.body.appendChild(cInput); cInput.select(); document.execCommand("Copy"); cInput.remove(); $("body").toast({ message: "复制成功!", showProgress: "bottom", showIcon: "check circle", class: "info", position: "top right", }); }, handleCurrentChange(val) { this.page = val; switch (this.activeName) { case "first": this.getCurrentRepoDataset(this.repolink, this.datasetType); break; case "second": this.getMyDataset(this.repolink, this.datasetType); break; case "third": this.getPublicDataset(this.repolink, this.datasetType); break; case "fourth": this.getStarDataset(this.repolink, this.datasetType); break; } }, handleCheckedChange(val) { if (val) { if (location.search) { const params = new URLSearchParams(location.search); if (params.has("recommend")) { params.delete("recommend"); let search = params.toString(); location.href = `${AppSubUrl}/explore/datasets?${search}&recommend=${val}`; } else { location.href = `${AppSubUrl}/explore/datasets${location.search}&recommend=${val}`; } } else { location.href = `${AppSubUrl}/explore/datasets?recommend=${val}`; } } else { if (location.search == "?recommend=true") { location.href = AppSubUrl + location.pathname; } else { const params = new URLSearchParams(location.search); params.delete("recommend"); location.href = AppSubUrl + location.pathname + "?" + params.toString(); } } }, createDataset(formName) { let _this = this; this.$refs[formName].validate((valid) => { if (valid) { document.getElementById("mask").style.display = "block"; _this.$axios .post(_this.url, _this.qs.stringify(_this.ruleForm)) .then((res) => { if (res.data.Code === 0) { document.getElementById("mask").style.display = "none"; location.href = _this.url.split("/create")[0] + "?type=-1"; } else { console.log(res.data.Message); } document.getElementById("mask").style.display = "none"; }) .catch((error) => { console.log(error); }); } else { return false; } }); }, cancelDataset(getpage, attachment) { if (getpage && !attachment) { if (getpage === "create") { location.href = this.url.split("/create")[0] + "?type=-1"; } else if (getpage === "edit") { location.href = this.url.split("/edit")[0] + "?type=-1"; } else { location.href = "/"; } } else { location.href = `${AppSubUrl}${attachment}/datasets`; } }, gotoUpload(repolink, datsetId) { // location.href = `${AppSubUrl}${repolink}/datasets/attachments/upload?datasetId=${datsetId}` window.open( `${AppSubUrl}${repolink}/datasets/attachments/upload?datasetId=${datsetId}`, "_blank" ); }, gotoDataset(datsetUrl) { location.href = datsetUrl; }, gotoAnnotate(repolink, uuid, type) { location.href = `${AppSubUrl}${repolink}/datasets/label/${uuid}?type=${type}`; }, setcluster(val) { this.clusterFlag = val; }, uploadGpu() { this.type = 0; }, uploadNpu() { this.type = 1; }, sortAble(dom) { const params = new URLSearchParams(location.search); if (params.toString() === "") { location.href = `${location.href}?sort=${dom}Asc`; } else if (!params.get("sort")) { location.href = `${location.href}&sort=${dom}Asc`; } else if ( params.get("sort") === `${dom}Desc` || params.get("sort").indexOf(`${dom}`) === -1 ) { params.set("sort", `${dom}Asc`); let asc = params.toString(); location.search = asc; } else { params.set("sort", `${dom}Desc`); let desc = params.toString(); location.search = desc; } }, sortIcon(dom, sort) { const params = new URLSearchParams(location.search); if (sort === "up") { if (params.toString() === "") { location.href = `${location.href}?sort=${dom}Asc`; } else if (!params.get("sort")) { location.href = `${location.href}&sort=${dom}Asc`; } else if ( params.get("sort") && params.get("sort").indexOf(`${dom}Asc`) !== -1 ) { params.delete("sort"); location.search = params.toString(); } else { params.set("sort", `${dom}Asc`); let asc = params.toString(); location.search = asc; } } else if (sort === "down") { if (params.toString() === "") { location.href = `${location.href}?sort=${dom}Desc`; } else if (!params.get("sort")) { location.href = `${location.href}&sort=${dom}Desc`; } else if ( params.get("sort") && params.get("sort").indexOf(`${dom}Desc`) !== -1 ) { params.delete("sort"); location.search = params.toString(); } else { params.set("sort", `${dom}Desc`); let asc = params.toString(); location.search = asc; } } }, setPrivate(uuid, privateFlag, index) { const params = { _csrf: csrf, file: uuid, is_private: privateFlag }; this.$axios .post("/attachments/private", this.qs.stringify(params)) .then((res) => { this.$set(this.privates, index, privateFlag); }) .catch((error) => { console.log(error); }); }, delDataset(uuid) { let _this = this; const params = { _csrf: csrf, file: uuid }; $("#data-dataset-delete-modal") .modal({ closable: false, onApprove() { _this.$axios .post("/attachments/delete", _this.qs.stringify(params)) .then((res) => { // $('#'+uuid).hide() location.reload(); }) .catch((error) => { console.log(error); }); }, }) .modal("show"); }, // getEditInit(){ // if($('#dataset-edit-value')){ // $this = $('#dataset-edit-value') // this.ruleForm.title = $this.data('edit-title') || '' // this.ruleForm.description = $this.data('edit-description') || '' // this.ruleForm.category = $this.data('edit-category') || '' // this.ruleForm.task = $this.data('edit-task') || '' // this.ruleForm.license = $this.data('edit-license') || '' // this.ruleForm.id = $this.data('edit-id')|| '' // } // }, editDataset(formName, id) { let _this = this; this.url = this.url.split(`/${id}`)[0]; this.$refs[formName].validate((valid) => { if (valid) { document.getElementById("mask").style.display = "block"; _this.$axios .post(_this.url, _this.qs.stringify(_this.ruleForm1)) .then((res) => { if (res.data.Code === 0) { document.getElementById("mask").style.display = "none"; location.href = _this.url.split("/edit")[0] + "?type=-1"; } else { console.log(res.data.Message); } document.getElementById("mask").style.display = "none"; }) .catch((err) => { console.log(err); }); } else { return false; } }); }, editDatasetFile(id, backurl) { let url = "/attachments/edit"; const params = { id: id, description: this.descfile, _csrf: csrf }; // document.getElementById("mask").style.display = "block" this.$axios .post(url, this.qs.stringify(params)) .then((res) => { if (res.data.Code === 0) { location.href = `${AppSubUrl}${backurl}/datasets`; } else { console.log(res.data.Message); } }) .catch((err) => { console.log(err); }); }, postStar(id, link) { if (this.star_active) { let url = link + "/" + id + "/unstar"; this.$axios.put(url).then((res) => { if (res.data.Code === 0) { this.star_active = false; this.num_stars = this.num_stars - 1; } }); } else { let url = link + "/" + id + "/star"; this.$axios.put(url).then((res) => { if (res.data.Code === 0) { this.star_active = true; this.num_stars = this.num_stars + 1; } }); } }, postSquareStar(id, link, index) { if (this.starActives[index]) { let url = link + "/" + id + "/unstar"; this.$axios.put(url).then((res) => { if (res.data.Code === 0) { this.$set(this.starActives, index, false); this.$set(this.starItems, index, this.starItems[index] - 1); } }); } else { let url = link + "/" + id + "/star"; this.$axios.put(url).then((res) => { if (res.data.Code === 0) { this.$set(this.starActives, index, true); this.$set(this.starItems, index, this.starItems[index] + 1); } }); } }, getTypeList() { const params = new URLSearchParams(window.location.search); if (window.location.search && params.has("type")) { if (params.get("type") == 0) { this.datasetType = "0"; } if (params.get("type") == 1) { this.datasetType = "1"; } if (params.get("type") == -1) { this.datasetType = "-1"; } } else { this.datasetType = "-1"; } }, changeDatasetType(val) { const searchParams = new URLSearchParams(window.location.search); if (!window.location.search) { window.location.href = window.location.href + "?type=" + val; } else if (searchParams.has("type")) { window.location.href = window.location.href.replace( /type=([0-9]|-[0-9])/g, "type=" + val ); } else { window.location.href = window.location.href + "&type=" + val; } }, gotoDatasetEidt(repolink, id) { location.href = `${repolink}/datasets/attachments/edit/${id}`; }, handleClick(repoLink, tabName, type) { if (tabName == "first") { this.page = 1; this.searchDataItem = ""; this.getCurrentRepoDataset(repoLink, type); } if (tabName == "second") { this.page = 1; this.searchDataItem = ""; this.getMyDataset(repoLink, type); } if (tabName == "third") { this.page = 1; this.searchDataItem = ""; this.getPublicDataset(repoLink, type); } if (tabName == "fourth") { this.page = 1; this.searchDataItem = ""; this.getStarDataset(repoLink, type); } }, polling(checkStatuDataset, repoLink) { this.timer = window.setInterval(() => { setTimeout(() => { this.getDatasetStatus(checkStatuDataset, repoLink); }, 0); }, 15000); }, getDatasetStatus(checkStatuDataset, repoLink) { const getmap = checkStatuDataset.map((item) => { let url = `${AppSubUrl}${repolink}/datasets/status/${item.UUID}`; return this.$axios.get(url); }); this.$axios.all(getmap).then((res) => { let flag = res.some((item) => { return item.data.AttachmentStatus == 1; }); flag && clearInterval(this.timer); flag && this.refreshStatusDataset(); }); }, refreshStatusDataset() { switch (this.activeName) { case "first": this.getCurrentRepoDataset(this.repolink, this.datasetType); break; case "second": this.getMyDataset(this.repolink, this.datasetType); break; case "third": this.getPublicDataset(this.repolink, this.datasetType); break; case "fourth": this.getStarDataset(this.repolink, this.datasetType); break; } }, getCurrentRepoDataset(repoLink, type) { clearInterval(this.timer); this.loadingDataIndex = true; let url = repoLink + "/datasets/current_repo"; this.$axios .get(url, { params: { type: type, page: this.page, q: this.searchDataItem, }, }) .then((res) => { if (res.data.result_code == "0") { this.currentRepoDataset = JSON.parse(res.data.data); const checkStatuDataset = this.currentRepoDataset.filter( (item) => item.DecompressState === 2 ); if (checkStatuDataset.length > 0) { this.polling(checkStatuDataset, repoLink); } this.totalnums = parseInt(res.data.count); } else { this.totalnums = 0; } this.loadingDataIndex = false; }); }, getMyDataset(repoLink, type) { clearInterval(this.timer); this.loadingDataIndex = true; let url = repoLink + "/datasets/my_datasets"; this.$axios .get(url, { params: { type: type, page: this.page, q: this.searchDataItem, }, }) .then((res) => { this.myDataset = JSON.parse(res.data.data); const checkStatuDataset = this.myDataset.filter( (item) => item.DecompressState === 2 ); if (checkStatuDataset.length > 0) { this.polling(checkStatuDataset, repoLink); } this.totalnums = parseInt(res.data.count); this.loadingDataIndex = false; }); }, getPublicDataset(repoLink, type) { clearInterval(this.timer); this.loadingDataIndex = true; let url = repoLink + "/datasets/public_datasets"; this.$axios .get(url, { params: { type: type, page: this.page, q: this.searchDataItem, }, }) .then((res) => { this.publicDataset = JSON.parse(res.data.data); const checkStatuDataset = this.publicDataset.filter( (item) => item.DecompressState === 2 ); if (checkStatuDataset.length > 0) { this.polling(checkStatuDataset, repoLink); } this.totalnums = parseInt(res.data.count); this.loadingDataIndex = false; }); }, getStarDataset(repoLink, type) { clearInterval(this.timer); this.loadingDataIndex = true; let url = repoLink + "/datasets/my_favorite"; this.$axios .get(url, { params: { type: type, page: this.page, q: this.searchDataItem, }, }) .then((res) => { this.myFavoriteDataset = JSON.parse(res.data.data); const checkStatuDataset = this.myFavoriteDataset.filter( (item) => item.DecompressState === 2 ); if (checkStatuDataset.length > 0) { this.polling(checkStatuDataset, repoLink); } this.totalnums = parseInt(res.data.count); this.loadingDataIndex = false; }); }, selectDataset(uuid, name) { this.dataset_uuid = uuid; this.dataset_name = name; this.dialogVisible = false; }, searchDataset() { switch (this.activeName) { case "first": this.page = 1; this.getCurrentRepoDataset(this.repolink, this.datasetType); break; case "second": this.page = 1; this.getMyDataset(this.repolink, this.datasetType); break; case "third": this.page = 1; this.getPublicDataset(this.repolink, this.datasetType); break; case "fourth": this.page = 1; this.getStarDataset(this.repolink, this.datasetType); break; } }, }, watch: { searchDataItem() { switch (this.activeName) { case "first": this.page = 1; this.getCurrentRepoDataset(this.repolink, this.datasetType); break; case "second": this.page = 1; this.getMyDataset(this.repolink, this.datasetType); break; case "third": this.page = 1; this.getPublicDataset(this.repolink, this.datasetType); break; case "fourth": this.page = 1; this.getStarDataset(this.repolink, this.datasetType); break; } }, }, }); } function initVueEditTopic() { const el = document.getElementById("topic_edit1"); if (!el) { return; } new Vue({ el: "#topic_edit1", render: (h) => h(EditTopics), }); } function initVueContributors() { const el = document.getElementById("Contributors"); if (!el) { return; } new Vue({ el: "#Contributors", render: (h) => h(Contributors), }); } // function initVueImages() { // const el = document.getElementById('images'); // if (!el) { // return; // } // new Vue({ // el: '#images', // render: h => h(Images) // }); // } function initVueModel() { const el = document.getElementById("model_list"); if (!el) { return; } new Vue({ el: el, render: (h) => h(Model), }); } function initVueDataAnalysis() { const el = document.getElementById("data_analysis"); if (!el) { return; } new Vue({ el: "#data_analysis", router, render: (h) => h(DataAnalysis), }); } function initVueWxAutorize() { const el = document.getElementById("WxAutorize"); if (!el) { return; } new Vue({ el: el, render: (h) => h(WxAutorize), }); } function initVueselectDataset() { const el = document.getElementById("select-multi-dataset"); if (!el) { return; } new Vue({ el: el, render: (h) => h(selectDataset), }); } function initVuereferenceDataset() { const el = document.getElementById("reference-dataset"); if (!el) { return; } new Vue({ el: el, render: (h) => h(referenceDataset), }); } window.timeAddManual = function () { $(".mini.modal") .modal({ duration: 200, onApprove() { $("#add_time_manual_form").trigger("submit"); }, }) .modal("show"); }; window.toggleStopwatch = function () { $("#toggle_stopwatch_form").trigger("submit"); }; window.cancelStopwatch = function () { $("#cancel_stopwatch_form").trigger("submit"); }; function initFilterBranchTagDropdown(selector) { $(selector).each(function () { const $dropdown = $(this); const $data = $dropdown.find(".data"); const data = { items: [], mode: $data.data("mode"), searchTerm: "", noResults: "", canCreateBranch: false, menuVisible: false, active: 0, }; $data.find(".item").each(function () { data.items.push({ name: $(this).text(), url: $(this).data("url"), branch: $(this).hasClass("branch"), tag: $(this).hasClass("tag"), selected: $(this).hasClass("selected"), }); }); $data.remove(); new Vue({ delimiters: ["${", "}"], el: this, data, beforeMount() { const vm = this; this.noResults = vm.$el.getAttribute("data-no-results"); this.canCreateBranch = vm.$el.getAttribute("data-can-create-branch") === "true"; document.body.addEventListener("click", (event) => { if (vm.$el.contains(event.target)) { return; } if (vm.menuVisible) { Vue.set(vm, "menuVisible", false); } }); }, watch: { menuVisible(visible) { if (visible) { this.focusSearchField(); } }, }, computed: { filteredItems() { const vm = this; const items = vm.items.filter((item) => { return ( ((vm.mode === "branches" && item.branch) || (vm.mode === "tags" && item.tag)) && (!vm.searchTerm || item.name.toLowerCase().includes(vm.searchTerm.toLowerCase())) ); }); vm.active = items.length === 0 && vm.showCreateNewBranch ? 0 : -1; return items; }, showNoResults() { return this.filteredItems.length === 0 && !this.showCreateNewBranch; }, showCreateNewBranch() { const vm = this; if (!this.canCreateBranch || !vm.searchTerm || vm.mode === "tags") { return false; } return ( vm.items.filter( (item) => item.name.toLowerCase() === vm.searchTerm.toLowerCase() ).length === 0 ); }, }, methods: { selectItem(item) { const prev = this.getSelected(); if (prev !== null) { prev.selected = false; } item.selected = true; window.location.href = item.url; }, createNewBranch() { if (!this.showCreateNewBranch) { return; } $(this.$refs.newBranchForm).trigger("submit"); }, focusSearchField() { const vm = this; Vue.nextTick(() => { vm.$refs.searchField.focus(); }); }, getSelected() { for (let i = 0, j = this.items.length; i < j; ++i) { if (this.items[i].selected) return this.items[i]; } return null; }, getSelectedIndexInFiltered() { for (let i = 0, j = this.filteredItems.length; i < j; ++i) { if (this.filteredItems[i].selected) return i; } return -1; }, scrollToActive() { let el = this.$refs[`listItem${this.active}`]; if (!el || el.length === 0) { return; } if (Array.isArray(el)) { el = el[0]; } const cont = this.$refs.scrollContainer; if (el.offsetTop < cont.scrollTop) { cont.scrollTop = el.offsetTop; } else if ( el.offsetTop + el.clientHeight > cont.scrollTop + cont.clientHeight ) { cont.scrollTop = el.offsetTop + el.clientHeight - cont.clientHeight; } }, keydown(event) { const vm = this; if (event.keyCode === 40) { // arrow down event.preventDefault(); if (vm.active === -1) { vm.active = vm.getSelectedIndexInFiltered(); } if ( vm.active + (vm.showCreateNewBranch ? 0 : 1) >= vm.filteredItems.length ) { return; } vm.active++; vm.scrollToActive(); } if (event.keyCode === 38) { // arrow up event.preventDefault(); if (vm.active === -1) { vm.active = vm.getSelectedIndexInFiltered(); } if (vm.active <= 0) { return; } vm.active--; vm.scrollToActive(); } if (event.keyCode === 13) { // enter event.preventDefault(); if (vm.active >= vm.filteredItems.length) { vm.createNewBranch(); } else if (vm.active >= 0) { vm.selectItem(vm.filteredItems[vm.active]); } } if (event.keyCode === 27) { // escape event.preventDefault(); vm.menuVisible = false; } }, }, }); }); } $(".commit-button").on("click", function (e) { e.preventDefault(); $(this).parent().find(".commit-body").toggle(); }); function initNavbarContentToggle() { const content = $("#navbar"); const toggle = $("#navbar-expand-toggle"); let isExpanded = false; toggle.on("click", () => { isExpanded = !isExpanded; if (isExpanded) { content.addClass("shown"); toggle.addClass("active"); } else { content.removeClass("shown"); toggle.removeClass("active"); } }); } window.toggleDeadlineForm = function () { $("#deadlineForm").fadeToggle(150); }; window.setDeadline = function () { const deadline = $("#deadlineDate").val(); window.updateDeadline(deadline); }; window.updateDeadline = function (deadlineString) { $("#deadline-err-invalid-date").hide(); $("#deadline-loader").addClass("loading"); let realDeadline = null; if (deadlineString !== "") { const newDate = Date.parse(deadlineString); if (Number.isNaN(newDate)) { $("#deadline-loader").removeClass("loading"); $("#deadline-err-invalid-date").show(); return false; } realDeadline = new Date(newDate); } $.ajax(`${$("#update-issue-deadline-form").attr("action")}/deadline`, { data: JSON.stringify({ due_date: realDeadline, }), headers: { "X-Csrf-Token": csrf, "X-Remote": true, }, contentType: "application/json", type: "POST", success() { reload(); }, error() { $("#deadline-loader").removeClass("loading"); $("#deadline-err-invalid-date").show(); }, }); }; window.deleteDependencyModal = function (id, type) { $(".remove-dependency") .modal({ closable: false, duration: 200, onApprove() { $("#removeDependencyID").val(id); $("#dependencyType").val(type); $("#removeDependencyForm").trigger("submit"); }, }) .modal("show"); }; function initIssueList() { const repolink = $("#repolink").val(); const repoId = $("#repoId").val(); const crossRepoSearch = $("#crossRepoSearch").val(); const tp = $("#type").val(); let issueSearchUrl = `${AppSubUrl}/api/v1/repos/${repolink}/issues?q={query}&type=${tp}`; if (crossRepoSearch === "true") { issueSearchUrl = `${AppSubUrl}/api/v1/repos/issues/search?q={query}&priority_repo_id=${repoId}&type=${tp}`; } $("#new-dependency-drop-list").dropdown({ apiSettings: { url: issueSearchUrl, onResponse(response) { const filteredResponse = { success: true, results: [] }; const currIssueId = $("#new-dependency-drop-list").data("issue-id"); // Parse the response from the api to work with our dropdown $.each(response, (_i, issue) => { // Don't list current issue in the dependency list. if (issue.id === currIssueId) { return; } filteredResponse.results.push({ name: `#${issue.number} ${htmlEncode( issue.title )}
${htmlEncode( issue.repository.full_name )}
`, value: issue.id, }); }); return filteredResponse; }, cache: false, }, fullTextSearch: true, }); $(".menu a.label-filter-item").each(function () { $(this).on("click", function (e) { if (e.altKey) { e.preventDefault(); const href = $(this).attr("href"); const id = $(this).data("label-id"); const regStr = `labels=(-?[0-9]+%2c)*(${id})(%2c-?[0-9]+)*&`; const newStr = "labels=$1-$2$3&"; window.location = href.replace(new RegExp(regStr), newStr); } }); }); $(".menu .ui.dropdown.label-filter").on("keydown", (e) => { if (e.altKey && e.keyCode === 13) { const selectedItems = $( ".menu .ui.dropdown.label-filter .menu .item.selected" ); if (selectedItems.length > 0) { const item = $(selectedItems[0]); const href = item.attr("href"); const id = item.data("label-id"); const regStr = `labels=(-?[0-9]+%2c)*(${id})(%2c-?[0-9]+)*&`; const newStr = "labels=$1-$2$3&"; window.location = href.replace(new RegExp(regStr), newStr); } } }); } window.cancelCodeComment = function (btn) { const form = $(btn).closest("form"); if (form.length > 0 && form.hasClass("comment-form")) { form.addClass("hide"); form.parent().find("button.comment-form-reply").show(); } else { form.closest(".comment-code-cloud").remove(); } }; window.submitReply = function (btn) { const form = $(btn).closest("form"); if (form.length > 0 && form.hasClass("comment-form")) { form.trigger("submit"); } }; window.onOAuthLoginClick = function () { const oauthLoader = $("#oauth2-login-loader"); const oauthNav = $("#oauth2-login-navigator"); oauthNav.hide(); oauthLoader.removeClass("disabled"); setTimeout(() => { // recover previous content to let user try again // usually redirection will be performed before this action oauthLoader.addClass("disabled"); oauthNav.show(); }, 5000); }; // Pull SVGs via AJAX to workaround CORS issues with tags // https://css-tricks.com/ajaxing-svg-sprite/ $.get(`${window.config.StaticUrlPrefix}/img/svg/icons.svg`, (data) => { const div = document.createElement("div"); div.style.display = "none"; div.innerHTML = new XMLSerializer().serializeToString(data.documentElement); document.body.insertBefore(div, document.body.childNodes[0]); }); function initDropDown() { $("#dropdown_PageHome").dropdown({ on: "hover", //鼠标悬浮显示,默认值是click }); $("#dropdown_explore").dropdown({ on: "hover", //鼠标悬浮显示,默认值是click }); } //云脑提示 $(".question.circle.icon.cloudbrain-question").hover(function () { $(this).popup("show"); $(".ui.popup.mini.top.center").css({ "border-color": "rgba(50, 145, 248, 100)", color: "rgba(3, 102, 214, 100)", "border-radius": "5px", "border-shadow": "none", }); }); //云脑详情页面跳转回上一个页面 // $(".section.backTodeBug").attr("href",localStorage.getItem('all')) //新建调试取消跳转 // $(".ui.button.cancel").attr("href",localStorage.getItem('all')) function initcreateRepo() { let timeout; let keydown_flag = false; const urlAdd = location.href.split("/")[0] + "//" + location.href.split("/")[2]; let owner = $("#ownerDropdown div.text").attr("title"); $(document).ready(function () { $("#ownerDropdown").dropdown({ onChange: function (value, text, $choice) { owner = $choice[0].getAttribute("title"); $("#repoAdress").css("display", "flex"); $("#repoAdress span").text( urlAdd + "/" + owner + "/" + $("#repo_name").val() + ".git" ); }, }); }); $("#repo_name").keyup(function () { keydown_flag = $("#repo_name").val() ? true : false; if (keydown_flag) { $("#repoAdress").css("display", "flex"); $("#repoAdress span").text( urlAdd + "/" + owner + "/" + $("#repo_name").val() + ".git" ); } else { $("#repoAdress").css("display", "none"); $("#repo_name").attr("placeholder", ""); } }); $("#create_repo_form").form({ on: "blur", // inline:true, fields: { alias: { identifier: "alias", rules: [ { type: "regExp[/^[\u4E00-\u9FA5A-Za-z0-9_.-]{1,100}$/]", }, ], }, repo_name: { identifier: "repo_name", rules: [ { type: "regExp[/^[A-Za-z0-9_.-]{1,100}$/]", }, ], }, }, onFailure: function (e) { return false; }, }); $("#alias").bind("input propertychange", function (event) { clearTimeout(timeout); timeout = setTimeout(() => { //在此处写调用的方法,可以实现仅最后一次操作生效 const aliasValue = $("#alias").val(); if (keydown_flag) { $("#repo_name").attr("placeholder", ""); } else if (aliasValue) { $("#repo_name").attr("placeholder", "正在获取路径..."); $.get( `${window.config.AppSubUrl}/repo/check_name?q=${aliasValue}&owner=${owner}`, (data) => { const repo_name = data.name; $("#repo_name").val(repo_name); repo_name && $("#repo_name").parent().removeClass("error"); $("#repoAdress").css("display", "flex"); $("#repoAdress span").text( urlAdd + "/" + owner + "/" + $("#repo_name").val() + ".git" ); $("#repo_name").attr("placeholder", ""); } ); } else { $("#repo_name").val(""); $("#repo_name").attr("placeholder", ""); $("#repoAdress").css("display", "none"); } }, 500); }); } initcreateRepo(); function initChartsNpu() { const repoPath = $('.metric_chart').data('path') let options = { legend: { data: [], }, grid: { top: "35%", bottom: "2%", x: "2%", containLabel: true, }, tooltip: { trigger: "axis", backgroundColor: "rgb(51, 56, 84)", borderColor: "rgb(51, 51, 51)", borderWidth: 0, textStyle: { color: "#fff", }, axisPointer: { type: "line", }, }, xAxis: { type: "category", data: [], boundaryGap: false, axisLabel: { interval: "auto", }, name: "", }, yAxis: { show: true, name: "占有率(%)", axisLine: { show: true, }, axisTick: { show: true }, }, series: [], }; const sortBy = (arr, k) => arr.concat().sort((a, b) => (a[k] > b[k] ? 1 : a[k] < b[k] ? -1 : 0)); $(".metric_chart").click(function (e) { let versionName = $(this).data("version"); let myCharts = echarts.init( document.getElementById(`metric-${versionName}`) ); $.get( `${window.config.AppSubUrl}/api/v1/repos/${repoPath}`, (res) => { let filterDta = res.MetricsInfo.filter((item) => { return ![ "recvBytesRate", "diskWriteRate", "sendBytesRate", "diskReadRate", ].includes(item.metric); }); filterDta = sortBy(filterDta, "metric"); let legenData = filterDta.map((item) => { return item.metric; }); let seriesData = filterDta.map((item) => { let value = item.value.map((item) => { return item > 0 ? item : "0"; }); let seriesOption = { name: item.metric, type: "line", symbol: "circle", symbolSize: 10, smooth: true, showSymbol: false, lineStyle: { width: 2, shadowColor: "rgba(0,0,0,0.3)", shadowBlur: 10, shadowOffsetY: 8, }, data: value, }; return seriesOption; }); let xAxisValue = res.Interval === 1 ? "时间(min)" : "时间(hour)"; let xLength = res.MetricsInfo[0].value.length; options.xAxis.name = xAxisValue; options.xAxis.data = Array.from( { length: xLength }, (_, index) => index ); options.legend.data = legenData; options.series = seriesData; options && myCharts.setOption(options); } ); options && myCharts.setOption(options); }); } initChartsNpu(); Fancybox.bind('.gallery img', { // Do not create a gallery groupAttr: null, // Do not hide page scrollbars hideScrollbar: false, // Disable drag to close guesture dragToClose: false, // Hide close button closeButton: false, // Disable toolbar Toolbar: false, // Disable zoom animation; close on click and wheel events Image: { zoom: false, click: "close", wheel: "close", }, // Custom animations showClass: "fancybox-zoomIn", hideClass: "fancybox-zoomOut", }); function initTopToHome() { const topToHomeEl = $('.__go-top'); $(window).scroll(function (e) { const scrollTop = $(document).scrollTop(); const winHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; if (scrollTop > winHeight * 1.2) { topToHomeEl.fadeIn(); } else { topToHomeEl.fadeOut(); } }); topToHomeEl.on('click', function() { $('html').animate({ scrollTop: 0 }, 'slow', 'swing'); }); } initTopToHome();