Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Split index.js to separate files #17315

Merged
merged 12 commits into from
Oct 16, 2021
7 changes: 0 additions & 7 deletions docs/content/doc/developers/guidelines-frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,6 @@ We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/h
6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}`
7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future).

## Legacy Problems and Solutions

### Too much code in `web_src/index.js`

Previously, most JavaScript code was written into `web_src/index.js` directly, making the file unmaintainable.
Try to keep this file small by creating new modules instead. These modules can be put in the `web_src/js/features` directory for now.

### Vue2/Vue3 and JSX

Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.
2 changes: 1 addition & 1 deletion templates/repo/branch/list.tmpl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@
{{if .IsDeleted}}
<a class="ui basic jump button icon poping up undo-button" href data-url="{{$.Link}}/restore?branch_id={{.DeletedBranch.ID | urlquery}}&name={{.DeletedBranch.Name | urlquery}}" data-content="{{$.i18n.Tr "repo.branch.restore" (.Name)}}" data-variation="tiny inverted" data-position="top right"><span class="text blue">{{svg "octicon-reply"}}</span></a>
{{else}}
<a class="ui basic jump button icon poping up delete-branch-button" href data-url="{{$.Link}}/delete?name={{.Name | urlquery}}" data-content="{{$.i18n.Tr "repo.branch.delete" (.Name)}}" data-variation="tiny inverted" data-position="top right" data-name="{{.Name}}">
<a class="ui basic jump button icon poping up delete-button delete-branch-button" href data-url="{{$.Link}}/delete?name={{.Name | urlquery}}" data-content="{{$.i18n.Tr "repo.branch.delete" (.Name)}}" data-variation="tiny inverted" data-position="top right" data-name="{{.Name}}">
{{svg "octicon-trash"}}
</a>
{{end}}
Expand Down
11 changes: 0 additions & 11 deletions web_src/js/code/linebutton.js

This file was deleted.

4 changes: 1 addition & 3 deletions web_src/js/components/DashboardRepoList.js
Original file line number Diff line number Diff line change
Expand Up @@ -348,7 +348,7 @@ function initVueComponents() {
}


function initDashboardRepoList() {
export function initDashboardRepoList() {
const el = document.getElementById('dashboard-repo-list');
const dashboardRepoListData = pageData.dashboardRepoList || null;
if (!el || !dashboardRepoListData) return;
Expand All @@ -366,5 +366,3 @@ function initDashboardRepoList() {
},
});
}

export {initDashboardRepoList};
5 changes: 2 additions & 3 deletions web_src/js/components/RepoActivityTopAuthors.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,9 @@ const sfc = {
}
};

function initRepoActivityTopAuthorsChart() {
export function initRepoActivityTopAuthorsChart() {
initVueApp('#repo-activity-top-authors-chart', sfc);
}

export default sfc;
export {initRepoActivityTopAuthorsChart};
export default sfc; // this line is necessary to activate the IDE's Vue plugin
</script>
7 changes: 3 additions & 4 deletions web_src/js/components/RepoBranchTagDropdown.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import Vue from 'vue';
import {vueDelimiters} from './VueComponentLoader.js';

function initRepoBranchTagDropdown(selector) {
export function initRepoBranchTagDropdown(selector) {
$(selector).each(function () {
const $dropdown = $(this);
const $data = $dropdown.find('.data');
Expand All @@ -26,7 +27,7 @@ function initRepoBranchTagDropdown(selector) {
$data.remove();
new Vue({
el: this,
delimiters: ['${', '}'],
delimiters: vueDelimiters,
data,
computed: {
filteredItems() {
Expand Down Expand Up @@ -157,5 +158,3 @@ function initRepoBranchTagDropdown(selector) {
});
});
}

export {initRepoBranchTagDropdown};
11 changes: 4 additions & 7 deletions web_src/js/components/VueComponentLoader.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import Vue from 'vue';
import {svgs} from '../svg.js';

const vueDelimiters = ['${', '}'];
export const vueDelimiters = ['${', '}'];

let vueEnvInited = false;
function initVueEnv() {
export function initVueEnv() {
if (vueEnvInited) return;
vueEnvInited = true;

Expand All @@ -14,7 +14,7 @@ function initVueEnv() {
}

let vueSvgInited = false;
function initVueSvg() {
export function initVueSvg() {
if (vueSvgInited) return;
vueSvgInited = true;

Expand All @@ -36,8 +36,7 @@ function initVueSvg() {
}
}


function initVueApp(el, opts = {}) {
export function initVueApp(el, opts = {}) {
if (typeof el === 'string') {
el = document.querySelector(el);
}
Expand All @@ -48,5 +47,3 @@ function initVueApp(el, opts = {}) {
delimiters: vueDelimiters,
}, opts));
}

export {vueDelimiters, initVueEnv, initVueSvg, initVueApp};
214 changes: 214 additions & 0 deletions web_src/js/features/admin-common.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,214 @@
const {csrf} = window.config;

export function initAdminCommon() {
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') {
$('#user_name').removeAttr('disabled');
$('#login_name').removeAttr('required');
$('.non-local').hide();
$('.local').show();
$('#user_name').focus();

if ($(this).data('password') === 'required') {
$('#password').attr('required', 'required');
}
} else {
if ($('.admin.edit.user').length > 0) {
$('#user_name').attr('disabled', 'disabled');
}
$('#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(applyDefaultValues) {
$('.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 'openidConnect':
$('.open_id_connect_auto_discovery_url input').attr('required', 'required');
$('.open_id_connect_auto_discovery_url').show();
break;
default:
if ($(`#${provider}_customURLSettings`).data('required')) {
$('#oauth2_use_custom_url').attr('checked', 'checked');
}
if ($(`#${provider}_customURLSettings`).data('available')) {
$('.oauth2_use_custom_url').show();
}
}
onOAuth2UseCustomURLChange(applyDefaultValues);
}

function onOAuth2UseCustomURLChange(applyDefaultValues) {
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')) {
for (const custom of ['token_url', 'auth_url', 'profile_url', 'email_url', 'tenant']) {
if (applyDefaultValues) {
$(`#oauth2_${custom}`).val($(`#${provider}_${custom}`).val());
}
if ($(`#${provider}_${custom}`).data('available')) {
$(`.oauth2_${custom} input`).attr('required', 'required');
$(`.oauth2_${custom}`).show();
}
}
}
}

function onVerifyGroupMembershipChange() {
if ($('#groups_enabled').is(':checked')) {
$('#groups_enabled_change').show();
} else {
$('#groups_enabled_change').hide();
}
}

// 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(true);
break;
case '7': // SSPI
$('.sspi').show();
$('.sspi div.required input').attr('required', 'required');
break;
}
if (authType === '2' || authType === '5') {
onSecurityProtocolChange();
onVerifyGroupMembershipChange();
}
if (authType === '2') {
onUsePagedSearchChange();
}
});
$('#auth_type').trigger('change');
$('#security_protocol').on('change', onSecurityProtocolChange);
$('#use_paged_search').on('change', onUsePagedSearchChange);
$('#oauth2_provider').on('change', () => onOAuth2Change(true));
$('#oauth2_use_custom_url').on('change', () => onOAuth2UseCustomURLChange(true));
$('#groups_enabled').on('change', onVerifyGroupMembershipChange);
}
// Edit authentication
if ($('.admin.edit.authentication').length > 0) {
const authType = $('#auth_type').val();
if (authType === '2' || authType === '5') {
$('#security_protocol').on('change', onSecurityProtocolChange);
$('#groups_enabled').on('change', onVerifyGroupMembershipChange);
onVerifyGroupMembershipChange();
if (authType === '2') {
$('#use_paged_search').on('change', onUsePagedSearchChange);
}
} else if (authType === '6') {
$('#oauth2_provider').on('change', () => onOAuth2Change(true));
$('#oauth2_use_custom_url').on('change', () => onOAuth2UseCustomURLChange(false));
onOAuth2Change(false);
}
}

// Notice
if ($('.admin.notice')) {
const $detailModal = $('#detail-modal');

// Attach view detail modals
$('.view-detail').on('click', function () {
$detailModal.find('.content pre').text($(this).parents('tr').find('.notice-description').text());
$detailModal.find('.sub.header').text($(this).parents('tr').find('.notice-created-time').text());
$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');
});
});
}
}
12 changes: 12 additions & 0 deletions web_src/js/features/admin-emails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export function initAdminEmails() {
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'));
$('#change-email-modal').modal('show');
e.preventDefault();
}
$('.link-email-action').on('click', linkEmailAction);
}
Loading