Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/javascripts/pages/sessions/new/index.js2
-rw-r--r--app/assets/javascripts/pages/sessions/new/username_validator.js148
-rw-r--r--app/models/clusters/applications/knative.rb2
-rw-r--r--app/services/git/wiki_push_service.rb9
-rw-r--r--app/views/devise/shared/_signup_box.html.haml8
-rw-r--r--app/workers/post_receive.rb23
6 files changed, 77 insertions, 115 deletions
diff --git a/app/assets/javascripts/pages/sessions/new/index.js b/app/assets/javascripts/pages/sessions/new/index.js
index 3f5a3e15c2c..55bc93a2b13 100644
--- a/app/assets/javascripts/pages/sessions/new/index.js
+++ b/app/assets/javascripts/pages/sessions/new/index.js
@@ -7,8 +7,8 @@ import OAuthRememberMe from './oauth_remember_me';
import preserveUrlFragment from './preserve_url_fragment';
document.addEventListener('DOMContentLoaded', () => {
- new LengthValidator(); // eslint-disable-line no-new
new UsernameValidator(); // eslint-disable-line no-new
+ new LengthValidator(); // eslint-disable-line no-new
new SigninTabsMemoizer(); // eslint-disable-line no-new
new NoEmojiValidator(); // eslint-disable-line no-new
diff --git a/app/assets/javascripts/pages/sessions/new/username_validator.js b/app/assets/javascripts/pages/sessions/new/username_validator.js
index 7a41805bada..36d1e773134 100644
--- a/app/assets/javascripts/pages/sessions/new/username_validator.js
+++ b/app/assets/javascripts/pages/sessions/new/username_validator.js
@@ -1,133 +1,79 @@
-/* eslint-disable consistent-return, class-methods-use-this */
+import InputValidator from '~/validators/input_validator';
-import $ from 'jquery';
import _ from 'underscore';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
const debounceTimeoutDuration = 1000;
+const rootUrl = gon.relative_url_root;
const invalidInputClass = 'gl-field-error-outline';
const successInputClass = 'gl-field-success-outline';
-const unavailableMessageSelector = '.username .validation-error';
-const successMessageSelector = '.username .validation-success';
-const pendingMessageSelector = '.username .validation-pending';
-const invalidMessageSelector = '.username .gl-field-error';
+const successMessageSelector = '.validation-success';
+const pendingMessageSelector = '.validation-pending';
+const unavailableMessageSelector = '.validation-error';
-export default class UsernameValidator {
- constructor() {
- this.inputElement = $('#new_user_username');
- this.inputDomElement = this.inputElement.get(0);
- this.state = {
- available: false,
- valid: false,
- pending: false,
- empty: true,
- };
+export default class UsernameValidator extends InputValidator {
+ constructor(opts = {}) {
+ super();
- const debounceTimeout = _.debounce(username => {
- this.validateUsername(username);
- }, debounceTimeoutDuration);
-
- this.inputElement.on('keyup.username_check', () => {
- const username = this.inputElement.val();
-
- this.state.valid = this.inputDomElement.validity.valid;
- this.state.empty = !username.length;
+ const container = opts.container || '';
+ const validateLengthElements = document.querySelectorAll(`${container} .js-validate-username`);
- if (this.state.valid) {
- return debounceTimeout(username);
- }
-
- this.renderState();
- });
+ this.debounceValidateInput = _.debounce(inputDomElement => {
+ UsernameValidator.validateUsernameInput(inputDomElement);
+ }, debounceTimeoutDuration);
- // Override generic field validation
- this.inputElement.on('invalid', this.interceptInvalid.bind(this));
+ validateLengthElements.forEach(element =>
+ element.addEventListener('input', this.eventHandler.bind(this)),
+ );
}
- renderState() {
- // Clear all state
- this.clearFieldValidationState();
-
- if (this.state.valid && this.state.available) {
- return this.setSuccessState();
- }
-
- if (this.state.empty) {
- return this.clearFieldValidationState();
- }
-
- if (this.state.pending) {
- return this.setPendingState();
- }
+ eventHandler(event) {
+ const inputDomElement = event.target;
- if (!this.state.valid) {
- return this.setInvalidState();
- }
-
- if (!this.state.available) {
- return this.setUnavailableState();
- }
- }
-
- interceptInvalid(event) {
- event.preventDefault();
- event.stopPropagation();
+ UsernameValidator.resetInputState(inputDomElement);
+ this.debounceValidateInput(inputDomElement);
}
- validateUsername(username) {
- if (this.state.valid) {
- this.state.pending = true;
- this.state.available = false;
- this.renderState();
- axios
- .get(`${gon.relative_url_root}/users/${username}/exists`)
- .then(({ data }) => this.setAvailabilityState(data.exists))
+ static validateUsernameInput(inputDomElement) {
+ const username = inputDomElement.value;
+
+ if (inputDomElement.checkValidity() && username.length > 0) {
+ UsernameValidator.setMessageVisibility(inputDomElement, pendingMessageSelector);
+ UsernameValidator.fetchUsernameAvailability(username)
+ .then(usernameTaken => {
+ UsernameValidator.setInputState(inputDomElement, !usernameTaken);
+ UsernameValidator.setMessageVisibility(inputDomElement, pendingMessageSelector, false);
+ UsernameValidator.setMessageVisibility(
+ inputDomElement,
+ usernameTaken ? unavailableMessageSelector : successMessageSelector,
+ );
+ })
.catch(() => flash(__('An error occurred while validating username')));
}
}
- setAvailabilityState(usernameTaken) {
- if (usernameTaken) {
- this.state.available = false;
- } else {
- this.state.available = true;
- }
- this.state.pending = false;
- this.renderState();
+ static fetchUsernameAvailability(username) {
+ return axios.get(`${rootUrl}/users/${username}/exists`).then(({ data }) => data.exists);
}
- clearFieldValidationState() {
- this.inputElement.siblings('p').hide();
-
- this.inputElement.removeClass(invalidInputClass).removeClass(successInputClass);
+ static setMessageVisibility(inputDomElement, messageSelector, isVisible = true) {
+ const messageElement = inputDomElement.parentElement.querySelector(messageSelector);
+ messageElement.classList.toggle('hide', !isVisible);
}
- setUnavailableState() {
- const $usernameUnavailableMessage = this.inputElement.siblings(unavailableMessageSelector);
- this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
- $usernameUnavailableMessage.show();
+ static setInputState(inputDomElement, success = true) {
+ inputDomElement.classList.toggle(successInputClass, success);
+ inputDomElement.classList.toggle(invalidInputClass, !success);
}
- setSuccessState() {
- const $usernameSuccessMessage = this.inputElement.siblings(successMessageSelector);
- this.inputElement.addClass(successInputClass).removeClass(invalidInputClass);
- $usernameSuccessMessage.show();
- }
+ static resetInputState(inputDomElement) {
+ UsernameValidator.setMessageVisibility(inputDomElement, successMessageSelector, false);
+ UsernameValidator.setMessageVisibility(inputDomElement, unavailableMessageSelector, false);
- setPendingState() {
- const $usernamePendingMessage = $(pendingMessageSelector);
- if (this.state.pending) {
- $usernamePendingMessage.show();
- } else {
- $usernamePendingMessage.hide();
+ if (inputDomElement.checkValidity()) {
+ inputDomElement.classList.remove(successInputClass, invalidInputClass);
}
}
-
- setInvalidState() {
- const $inputErrorMessage = $(invalidMessageSelector);
- this.inputElement.addClass(invalidInputClass).removeClass(successInputClass);
- $inputErrorMessage.show();
- }
}
diff --git a/app/models/clusters/applications/knative.rb b/app/models/clusters/applications/knative.rb
index d5a3bd62e3d..5df4812bd25 100644
--- a/app/models/clusters/applications/knative.rb
+++ b/app/models/clusters/applications/knative.rb
@@ -3,7 +3,7 @@
module Clusters
module Applications
class Knative < ApplicationRecord
- VERSION = '0.5.0'.freeze
+ VERSION = '0.6.0'.freeze
REPOSITORY = 'https://storage.googleapis.com/triggermesh-charts'.freeze
METRICS_CONFIG = 'https://storage.googleapis.com/triggermesh-charts/istio-metrics.yaml'.freeze
FETCH_IP_ADDRESS_DELAY = 30.seconds
diff --git a/app/services/git/wiki_push_service.rb b/app/services/git/wiki_push_service.rb
new file mode 100644
index 00000000000..a053f133016
--- /dev/null
+++ b/app/services/git/wiki_push_service.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+module Git
+ class WikiPushService < ::BaseService
+ def execute
+ # This is used in EE
+ end
+ end
+end
diff --git a/app/views/devise/shared/_signup_box.html.haml b/app/views/devise/shared/_signup_box.html.haml
index 5eba819172b..eae3ee6339f 100644
--- a/app/views/devise/shared/_signup_box.html.haml
+++ b/app/views/devise/shared/_signup_box.html.haml
@@ -10,10 +10,10 @@
= f.text_field :name, class: "form-control top qa-new-user-name js-block-emoji js-validate-length", :data => { :max_length => max_name_length, :max_length_message => s_("SignUp|Name is too long (maximum is %{max_length} characters).") % { max_length: max_name_length } }, required: true, title: _("This field is required.")
.username.form-group
= f.label :username, class: 'label-bold'
- = f.text_field :username, class: "form-control middle qa-new-user-username js-block-emoji js-validate-length", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length } }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
- %p.validation-error.field-validation.hide= _('Username is already taken.')
- %p.validation-success.field-validation.hide= _('Username is available.')
- %p.validation-pending.field-validation.hide= _('Checking username availability...')
+ = f.text_field :username, class: "form-control middle qa-new-user-username js-block-emoji js-validate-length js-validate-username", :data => { :max_length => max_username_length, :max_length_message => s_("SignUp|Username is too long (maximum is %{max_length} characters).") % { max_length: max_username_length } }, pattern: Gitlab::PathRegex::NAMESPACE_FORMAT_REGEX_JS, required: true, title: _("Please create a username with only alphanumeric characters.")
+ %p.validation-error.gl-field-error-ignore.field-validation.hide= _('Username is already taken.')
+ %p.validation-success.gl-field-error-ignore.field-validation.hide= _('Username is available.')
+ %p.validation-pending.gl-field-error-ignore.field-validation.hide= _('Checking username availability...')
.form-group
= f.label :email, class: 'label-bold'
= f.email_field :email, class: "form-control middle qa-new-user-email", required: true, title: _("Please provide a valid email address.")
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 3f1639ec2ed..dba7837bd12 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -30,15 +30,17 @@ class PostReceive
private
+ def identify_user(post_received)
+ post_received.identify.tap do |user|
+ log("Triggered hook for non-existing user \"#{post_received.identifier}\"") unless user
+ end
+ end
+
def process_project_changes(post_received)
changes = []
refs = Set.new
- @user = post_received.identify
-
- unless @user
- log("Triggered hook for non-existing user \"#{post_received.identifier}\"")
- return false
- end
+ user = identify_user(post_received)
+ return false unless user
post_received.enum_for(:changes_refs).with_index do |(oldrev, newrev, ref), index|
service_klass =
@@ -51,7 +53,7 @@ class PostReceive
if service_klass
service_klass.new(
post_received.project,
- @user,
+ user,
oldrev: oldrev,
newrev: newrev,
ref: ref,
@@ -64,7 +66,7 @@ class PostReceive
refs << ref
end
- after_project_changes_hooks(post_received, @user, refs.to_a, changes)
+ after_project_changes_hooks(post_received, user, refs.to_a, changes)
end
def after_project_changes_hooks(post_received, user, refs, changes)
@@ -76,6 +78,11 @@ class PostReceive
post_received.project.touch(:last_activity_at, :last_repository_updated_at)
post_received.project.wiki.repository.expire_statistics_caches
ProjectCacheWorker.perform_async(post_received.project.id, [], [:wiki_size])
+
+ user = identify_user(post_received)
+ return false unless user
+
+ ::Git::WikiPushService.new(post_received.project, user, changes: post_received.enum_for(:changes_refs)).execute
end
def log(message)