diff options
Diffstat (limited to 'app/assets/javascripts/pages/admin')
20 files changed, 575 insertions, 99 deletions
diff --git a/app/assets/javascripts/pages/admin/abuse_reports/index.js b/app/assets/javascripts/pages/admin/abuse_reports/index.js index 0a4311ec73a..a88d35796f7 100644 --- a/app/assets/javascripts/pages/admin/abuse_reports/index.js +++ b/app/assets/javascripts/pages/admin/abuse_reports/index.js @@ -1,5 +1,8 @@ +import initDeprecatedRemoveRowBehavior from '~/behaviors/deprecated_remove_row_behavior'; import UsersSelect from '~/users_select'; import AbuseReports from './abuse_reports'; new AbuseReports(); /* eslint-disable-line no-new */ new UsersSelect(); /* eslint-disable-line no-new */ + +document.addEventListener('DOMContentLoaded', initDeprecatedRemoveRowBehavior); diff --git a/app/assets/javascripts/pages/admin/admin.js b/app/assets/javascripts/pages/admin/admin.js index 2732fc191be..6b7bfbf217d 100644 --- a/app/assets/javascripts/pages/admin/admin.js +++ b/app/assets/javascripts/pages/admin/admin.js @@ -1,16 +1,6 @@ import $ from 'jquery'; import { refreshCurrentPage } from '../../lib/utils/url_utility'; -function showDenylistType() { - if ($('input[name="denylist_type"]:checked').val() === 'file') { - $('.js-denylist-file').show(); - $('.js-denylist-raw').hide(); - } else { - $('.js-denylist-file').hide(); - $('.js-denylist-raw').show(); - } -} - export default function adminInit() { $('input#user_force_random_password').on('change', function randomPasswordClick() { const $elems = $('#user_password, #user_password_confirmation'); @@ -27,7 +17,4 @@ export default function adminInit() { }); $('li.project_member, li.group_member').on('ajax:success', refreshCurrentPage); - - $("input[name='denylist_type']").on('click', showDenylistType); - showDenylistType(); } diff --git a/app/assets/javascripts/pages/admin/application_settings/general/components/signup_checkbox.vue b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_checkbox.vue new file mode 100644 index 00000000000..2217792d7f3 --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_checkbox.vue @@ -0,0 +1,50 @@ +<script> +import { GlFormCheckbox } from '@gitlab/ui'; + +export default { + components: { + GlFormCheckbox, + }, + props: { + name: { + type: String, + required: true, + }, + helpText: { + type: String, + required: false, + default: '', + }, + label: { + type: String, + required: true, + }, + value: { + type: Boolean, + required: true, + }, + dataQaSelector: { + type: String, + required: false, + default: '', + }, + }, +}; +</script> + +<template> + <div> + <input :name="name" type="hidden" :value="value ? '1' : '0'" data-testid="input" /> + + <gl-form-checkbox + :checked="value" + :data-qa-selector="dataQaSelector" + @input="$emit('input', $event)" + > + <span data-testid="label">{{ label }}</span> + <template v-if="helpText" #help> + <span data-testid="helpText">{{ helpText }}</span> + </template> + </gl-form-checkbox> + </div> +</template> diff --git a/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue new file mode 100644 index 00000000000..9850113d4be --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/general/components/signup_form.vue @@ -0,0 +1,417 @@ +<script> +import { + GlButton, + GlFormGroup, + GlFormInput, + GlFormRadio, + GlFormRadioGroup, + GlSprintf, + GlLink, + GlModal, +} from '@gitlab/ui'; +import { toSafeInteger } from 'lodash'; +import csrf from '~/lib/utils/csrf'; +import { __, s__, sprintf } from '~/locale'; +import SignupCheckbox from './signup_checkbox.vue'; + +const DENYLIST_TYPE_RAW = 'raw'; +const DENYLIST_TYPE_FILE = 'file'; + +export default { + csrf, + DENYLIST_TYPE_RAW, + DENYLIST_TYPE_FILE, + components: { + GlButton, + GlFormGroup, + GlFormInput, + GlFormRadio, + GlFormRadioGroup, + GlSprintf, + GlLink, + SignupCheckbox, + GlModal, + }, + inject: [ + 'host', + 'settingsPath', + 'signupEnabled', + 'requireAdminApprovalAfterUserSignup', + 'sendUserConfirmationEmail', + 'minimumPasswordLength', + 'minimumPasswordLengthMin', + 'minimumPasswordLengthMax', + 'minimumPasswordLengthHelpLink', + 'domainAllowlistRaw', + 'newUserSignupsCap', + 'domainDenylistEnabled', + 'denylistTypeRawSelected', + 'domainDenylistRaw', + 'emailRestrictionsEnabled', + 'supportedSyntaxLinkUrl', + 'emailRestrictions', + 'afterSignUpText', + ], + data() { + return { + showModal: false, + form: { + signupEnabled: this.signupEnabled, + requireAdminApproval: this.requireAdminApprovalAfterUserSignup, + sendConfirmationEmail: this.sendUserConfirmationEmail, + minimumPasswordLength: this.minimumPasswordLength, + minimumPasswordLengthMin: this.minimumPasswordLengthMin, + minimumPasswordLengthMax: this.minimumPasswordLengthMax, + minimumPasswordLengthHelpLink: this.minimumPasswordLengthHelpLink, + domainAllowlistRaw: this.domainAllowlistRaw, + userCap: this.newUserSignupsCap, + domainDenylistEnabled: this.domainDenylistEnabled, + denylistType: this.denylistTypeRawSelected + ? this.$options.DENYLIST_TYPE_RAW + : this.$options.DENYLIST_TYPE_FILE, + domainDenylistRaw: this.domainDenylistRaw, + emailRestrictionsEnabled: this.emailRestrictionsEnabled, + supportedSyntaxLinkUrl: this.supportedSyntaxLinkUrl, + emailRestrictions: this.emailRestrictions, + afterSignUpText: this.afterSignUpText, + }, + }; + }, + computed: { + isOldUserCapUnlimited() { + // User cap is set to unlimited if no value is provided in the field + return this.newUserSignupsCap === ''; + }, + isNewUserCapUnlimited() { + // User cap is set to unlimited if no value is provided in the field + return this.form.userCap === ''; + }, + hasUserCapChangedFromUnlimitedToLimited() { + return this.isOldUserCapUnlimited && !this.isNewUserCapUnlimited; + }, + hasUserCapChangedFromLimitedToUnlimited() { + return !this.isOldUserCapUnlimited && this.isNewUserCapUnlimited; + }, + hasUserCapBeenIncreased() { + if (this.hasUserCapChangedFromUnlimitedToLimited) { + return false; + } + + const oldValueAsInteger = toSafeInteger(this.newUserSignupsCap); + const newValueAsInteger = toSafeInteger(this.form.userCap); + + return this.hasUserCapChangedFromLimitedToUnlimited || newValueAsInteger > oldValueAsInteger; + }, + canUsersBeAccidentallyApproved() { + const hasUserCapBeenToggledOff = + this.requireAdminApprovalAfterUserSignup && !this.form.requireAdminApproval; + + return this.hasUserCapBeenIncreased || hasUserCapBeenToggledOff; + }, + signupEnabledHelpText() { + const text = sprintf( + s__( + 'ApplicationSettings|When enabled, any user visiting %{host} will be able to create an account.', + ), + { + host: this.host, + }, + ); + + return text; + }, + requireAdminApprovalHelpText() { + const text = sprintf( + s__( + 'ApplicationSettings|When enabled, any user visiting %{host} and creating an account will have to be explicitly approved by an admin before they can sign in. This setting is effective only if sign-ups are enabled.', + ), + { + host: this.host, + }, + ); + + return text; + }, + }, + watch: { + showModal(value) { + if (value === true) { + this.$refs[this.$options.modal.id].show(); + } else { + this.$refs[this.$options.modal.id].hide(); + } + }, + }, + methods: { + submitButtonHandler() { + if (this.canUsersBeAccidentallyApproved) { + this.showModal = true; + + return; + } + + this.submitForm(); + }, + submitForm() { + this.$refs.form.submit(); + }, + modalHideHandler() { + this.showModal = false; + }, + }, + i18n: { + buttonText: s__('ApplicationSettings|Save changes'), + signupEnabledLabel: s__('ApplicationSettings|Sign-up enabled'), + requireAdminApprovalLabel: s__('ApplicationSettings|Require admin approval for new sign-ups'), + sendConfirmationEmailLabel: s__('ApplicationSettings|Send confirmation email on sign-up'), + minimumPasswordLengthLabel: s__( + 'ApplicationSettings|Minimum password length (number of characters)', + ), + domainAllowListLabel: s__('ApplicationSettings|Allowed domains for sign-ups'), + domainAllowListDescription: s__( + 'ApplicationSettings|ONLY users with e-mail addresses that match these domain(s) will be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com', + ), + userCapLabel: s__('ApplicationSettings|User cap'), + userCapDescription: s__( + 'ApplicationSettings|Once the instance reaches the user cap, any user who is added or requests access will have to be approved by an admin. Leave the field empty for unlimited.', + ), + domainDenyListGroupLabel: s__('ApplicationSettings|Domain denylist'), + domainDenyListLabel: s__('ApplicationSettings|Enable domain denylist for sign ups'), + domainDenyListTypeFileLabel: s__('ApplicationSettings|Upload denylist file'), + domainDenyListTypeRawLabel: s__('ApplicationSettings|Enter denylist manually'), + domainDenyListFileLabel: s__('ApplicationSettings|Denylist file'), + domainDenyListFileDescription: s__( + 'ApplicationSettings|Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines or commas for multiple entries.', + ), + domainDenyListListLabel: s__('ApplicationSettings|Denied domains for sign-ups'), + domainDenyListListDescription: s__( + 'ApplicationSettings|Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com', + ), + domainPlaceholder: s__('ApplicationSettings|domain.com'), + emailRestrictionsEnabledGroupLabel: s__('ApplicationSettings|Email restrictions'), + emailRestrictionsEnabledLabel: s__( + 'ApplicationSettings|Enable email restrictions for sign ups', + ), + emailRestrictionsGroupLabel: s__('ApplicationSettings|Email restrictions for sign-ups'), + afterSignUpTextGroupLabel: s__('ApplicationSettings|After sign up text'), + afterSignUpTextGroupDescription: s__('ApplicationSettings|Markdown enabled'), + }, + modal: { + id: 'signup-settings-modal', + actionPrimary: { + text: s__('ApplicationSettings|Approve users'), + attributes: { + variant: 'confirm', + }, + }, + actionCancel: { + text: __('Cancel'), + }, + title: s__('ApplicationSettings|Approve all users in the pending approval status?'), + text: s__( + 'ApplicationSettings|By making this change, you will automatically approve all users in pending approval status.', + ), + }, +}; +</script> + +<template> + <form + ref="form" + accept-charset="UTF-8" + data-testid="form" + method="post" + :action="settingsPath" + enctype="multipart/form-data" + > + <input type="hidden" name="utf8" value="✓" /> + <input type="hidden" name="_method" value="patch" /> + <input type="hidden" name="authenticity_token" :value="$options.csrf.token" /> + + <section class="gl-mb-8"> + <signup-checkbox + v-model="form.signupEnabled" + class="gl-mb-5" + name="application_setting[signup_enabled]" + :help-text="signupEnabledHelpText" + :label="$options.i18n.signupEnabledLabel" + data-qa-selector="signup_enabled_checkbox" + /> + + <signup-checkbox + v-model="form.requireAdminApproval" + class="gl-mb-5" + name="application_setting[require_admin_approval_after_user_signup]" + :help-text="requireAdminApprovalHelpText" + :label="$options.i18n.requireAdminApprovalLabel" + data-qa-selector="require_admin_approval_after_user_signup_checkbox" + data-testid="require-admin-approval-checkbox" + /> + + <signup-checkbox + v-model="form.sendConfirmationEmail" + class="gl-mb-5" + name="application_setting[send_user_confirmation_email]" + :label="$options.i18n.sendConfirmationEmailLabel" + /> + + <gl-form-group + :label="$options.i18n.userCapLabel" + :description="$options.i18n.userCapDescription" + > + <gl-form-input + v-model="form.userCap" + type="text" + name="application_setting[new_user_signups_cap]" + data-testid="user-cap-input" + /> + </gl-form-group> + + <gl-form-group :label="$options.i18n.minimumPasswordLengthLabel"> + <gl-form-input + v-model="form.minimumPasswordLength" + :min="form.minimumPasswordLengthMin" + :max="form.minimumPasswordLengthMax" + type="number" + name="application_setting[minimum_password_length]" + /> + + <gl-sprintf + :message=" + s__( + 'ApplicationSettings|See GitLab\'s %{linkStart}Password Policy Guidelines%{linkEnd}', + ) + " + > + <template #link="{ content }"> + <gl-link :href="form.minimumPasswordLengthHelpLink" target="_blank">{{ + content + }}</gl-link> + </template> + </gl-sprintf> + </gl-form-group> + + <gl-form-group + :description="$options.i18n.domainAllowListDescription" + :label="$options.i18n.domainAllowListLabel" + > + <textarea + v-model="form.domainAllowlistRaw" + :placeholder="$options.i18n.domainPlaceholder" + rows="8" + class="form-control gl-form-input" + name="application_setting[domain_allowlist_raw]" + ></textarea> + </gl-form-group> + + <gl-form-group :label="$options.i18n.domainDenyListGroupLabel"> + <signup-checkbox + v-model="form.domainDenylistEnabled" + name="application_setting[domain_denylist_enabled]" + :label="$options.i18n.domainDenyListLabel" + /> + </gl-form-group> + + <gl-form-radio-group v-model="form.denylistType" name="denylist_type" class="gl-mb-5"> + <gl-form-radio :value="$options.DENYLIST_TYPE_FILE">{{ + $options.i18n.domainDenyListTypeFileLabel + }}</gl-form-radio> + <gl-form-radio :value="$options.DENYLIST_TYPE_RAW">{{ + $options.i18n.domainDenyListTypeRawLabel + }}</gl-form-radio> + </gl-form-radio-group> + + <gl-form-group + v-if="form.denylistType === $options.DENYLIST_TYPE_FILE" + :description="$options.i18n.domainDenyListFileDescription" + :label="$options.i18n.domainDenyListFileLabel" + label-for="domain-denylist-file-input" + data-testid="domain-denylist-file-input-group" + > + <input + id="domain-denylist-file-input" + class="form-control gl-form-input" + type="file" + accept=".txt,.conf" + name="application_setting[domain_denylist_file]" + /> + </gl-form-group> + + <gl-form-group + v-if="form.denylistType !== $options.DENYLIST_TYPE_FILE" + :description="$options.i18n.domainDenyListListDescription" + :label="$options.i18n.domainDenyListListLabel" + data-testid="domain-denylist-raw-input-group" + > + <textarea + v-model="form.domainDenylistRaw" + :placeholder="$options.i18n.domainPlaceholder" + rows="8" + class="form-control gl-form-input" + name="application_setting[domain_denylist_raw]" + ></textarea> + </gl-form-group> + + <gl-form-group :label="$options.i18n.emailRestrictionsEnabledGroupLabel"> + <signup-checkbox + v-model="form.emailRestrictionsEnabled" + name="application_setting[email_restrictions_enabled]" + :label="$options.i18n.emailRestrictionsEnabledLabel" + /> + </gl-form-group> + + <gl-form-group :label="$options.i18n.emailRestrictionsGroupLabel"> + <textarea + v-model="form.emailRestrictions" + rows="4" + class="form-control gl-form-input" + name="application_setting[email_restrictions]" + ></textarea> + + <gl-sprintf + :message=" + s__( + 'ApplicationSettings|Restricts sign-ups for email addresses that match the given regex. See the %{linkStart}supported syntax%{linkEnd} for more information.', + ) + " + > + <template #link="{ content }"> + <gl-link :href="form.supportedSyntaxLinkUrl" target="_blank">{{ content }}</gl-link> + </template> + </gl-sprintf> + </gl-form-group> + + <gl-form-group + :label="$options.i18n.afterSignUpTextGroupLabel" + :description="$options.i18n.afterSignUpTextGroupDescription" + > + <textarea + v-model="form.afterSignUpText" + rows="4" + class="form-control gl-form-input" + name="application_setting[after_sign_up_text]" + ></textarea> + </gl-form-group> + </section> + + <gl-button + data-qa-selector="save_changes_button" + variant="confirm" + @click.prevent="submitButtonHandler" + > + {{ $options.i18n.buttonText }} + </gl-button> + + <gl-modal + :ref="$options.modal.id" + :modal-id="$options.modal.id" + :action-cancel="$options.modal.actionCancel" + :action-primary="$options.modal.actionPrimary" + :title="$options.modal.title" + @primary="submitForm" + @hide="modalHideHandler" + > + {{ $options.modal.text }} + </gl-modal> + </form> +</template> diff --git a/app/assets/javascripts/pages/admin/application_settings/general/index.js b/app/assets/javascripts/pages/admin/application_settings/general/index.js index eda1a9d3599..c48d99da990 100644 --- a/app/assets/javascripts/pages/admin/application_settings/general/index.js +++ b/app/assets/javascripts/pages/admin/application_settings/general/index.js @@ -1,27 +1,9 @@ -import Vue from 'vue'; -import IntegrationHelpText from '~/vue_shared/components/integrations_help_text.vue'; import initUserInternalRegexPlaceholder from '../account_and_limits'; +import initGitpod from '../gitpod'; +import initSignupRestrictions from '../signup_restrictions'; (() => { initUserInternalRegexPlaceholder(); - - const el = document.querySelector('#js-gitpod-settings-help-text'); - if (!el) { - return; - } - - const { message, messageUrl } = el.dataset; - - // eslint-disable-next-line no-new - new Vue({ - el, - render(createElement) { - return createElement(IntegrationHelpText, { - props: { - message, - messageUrl, - }, - }); - }, - }); + initGitpod(); + initSignupRestrictions(); })(); diff --git a/app/assets/javascripts/pages/admin/application_settings/gitpod.js b/app/assets/javascripts/pages/admin/application_settings/gitpod.js new file mode 100644 index 00000000000..74e46617d52 --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/gitpod.js @@ -0,0 +1,24 @@ +import Vue from 'vue'; +import IntegrationHelpText from '~/vue_shared/components/integrations_help_text.vue'; + +export default function initGitpod() { + const el = document.querySelector('#js-gitpod-settings-help-text'); + + if (!el) { + return false; + } + + const { message, messageUrl } = el.dataset; + + return new Vue({ + el, + render(createElement) { + return createElement(IntegrationHelpText, { + props: { + message, + messageUrl, + }, + }); + }, + }); +} diff --git a/app/assets/javascripts/pages/admin/application_settings/index.js b/app/assets/javascripts/pages/admin/application_settings/index.js index e3c6b0f6f5b..a6e3a7dc08a 100644 --- a/app/assets/javascripts/pages/admin/application_settings/index.js +++ b/app/assets/javascripts/pages/admin/application_settings/index.js @@ -4,9 +4,7 @@ import initSearchSettings from '~/search_settings'; import selfMonitor from '~/self_monitor'; import initSettingsPanels from '~/settings_panels'; -if (gon.features?.ciInstanceVariablesUi) { - initVariableList('js-instance-variables'); -} +initVariableList('js-instance-variables'); selfMonitor(); // Initialize expandable settings panels initSettingsPanels(); diff --git a/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js new file mode 100644 index 00000000000..70b896f6372 --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/signup_restrictions.js @@ -0,0 +1,31 @@ +import Vue from 'vue'; +import SignupForm from './general/components/signup_form.vue'; +import { getParsedDataset } from './utils'; + +export default function initSignupRestrictions(elementSelector = '#js-signup-form') { + const el = document.querySelector(elementSelector); + + if (!el) { + return false; + } + + const parsedDataset = getParsedDataset({ + dataset: el.dataset, + booleanAttributes: [ + 'signupEnabled', + 'requireAdminApprovalAfterUserSignup', + 'sendUserConfirmationEmail', + 'domainDenylistEnabled', + 'denylistTypeRawSelected', + 'emailRestrictionsEnabled', + ], + }); + + return new Vue({ + el, + provide: { + ...parsedDataset, + }, + render: (createElement) => createElement(SignupForm), + }); +} diff --git a/app/assets/javascripts/pages/admin/application_settings/utils.js b/app/assets/javascripts/pages/admin/application_settings/utils.js new file mode 100644 index 00000000000..5462a13d523 --- /dev/null +++ b/app/assets/javascripts/pages/admin/application_settings/utils.js @@ -0,0 +1,21 @@ +import { includes } from 'lodash'; +import { parseBoolean } from '~/lib/utils/common_utils'; + +/** + * Returns a new dataset that has all the values of keys indicated in + * booleanAttributes transformed by the parseBoolean() helper function + * + * @param {Object} + * @returns {Object} + */ +export const getParsedDataset = ({ dataset = {}, booleanAttributes = [] } = {}) => { + const parsedDataset = {}; + + Object.keys(dataset).forEach((key) => { + parsedDataset[key] = includes(booleanAttributes, key) + ? parseBoolean(dataset[key]) + : dataset[key]; + }); + + return parsedDataset; +}; diff --git a/app/assets/javascripts/pages/admin/broadcast_messages/index.js b/app/assets/javascripts/pages/admin/broadcast_messages/index.js index d6cc6a850eb..b7db6443658 100644 --- a/app/assets/javascripts/pages/admin/broadcast_messages/index.js +++ b/app/assets/javascripts/pages/admin/broadcast_messages/index.js @@ -1,3 +1,7 @@ +import initDeprecatedRemoveRowBehavior from '~/behaviors/deprecated_remove_row_behavior'; import initBroadcastMessagesForm from './broadcast_message'; -document.addEventListener('DOMContentLoaded', initBroadcastMessagesForm); +document.addEventListener('DOMContentLoaded', () => { + initBroadcastMessagesForm(); + initDeprecatedRemoveRowBehavior(); +}); diff --git a/app/assets/javascripts/pages/admin/groups/new/index.js b/app/assets/javascripts/pages/admin/groups/new/index.js index 94f7cfd55be..1630cfb8253 100644 --- a/app/assets/javascripts/pages/admin/groups/new/index.js +++ b/app/assets/javascripts/pages/admin/groups/new/index.js @@ -2,9 +2,9 @@ import initFilePickers from '~/file_pickers'; import BindInOut from '../../../../behaviors/bind_in_out'; import Group from '../../../../group'; -document.addEventListener('DOMContentLoaded', () => { +(() => { BindInOut.initAll(); initFilePickers(); return new Group(); -}); +})(); diff --git a/app/assets/javascripts/pages/admin/labels/edit/index.js b/app/assets/javascripts/pages/admin/labels/edit/index.js index 5de1d4d6344..f7c25347e75 100644 --- a/app/assets/javascripts/pages/admin/labels/edit/index.js +++ b/app/assets/javascripts/pages/admin/labels/edit/index.js @@ -1,3 +1,3 @@ import Labels from '../../../../labels'; -document.addEventListener('DOMContentLoaded', () => new Labels()); +new Labels(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/pages/admin/labels/index/index.js b/app/assets/javascripts/pages/admin/labels/index/index.js new file mode 100644 index 00000000000..e5ab5d43bbf --- /dev/null +++ b/app/assets/javascripts/pages/admin/labels/index/index.js @@ -0,0 +1,3 @@ +import initDeprecatedRemoveRowBehavior from '~/behaviors/deprecated_remove_row_behavior'; + +document.addEventListener('DOMContentLoaded', initDeprecatedRemoveRowBehavior); diff --git a/app/assets/javascripts/pages/admin/labels/new/index.js b/app/assets/javascripts/pages/admin/labels/new/index.js index 5de1d4d6344..f7c25347e75 100644 --- a/app/assets/javascripts/pages/admin/labels/new/index.js +++ b/app/assets/javascripts/pages/admin/labels/new/index.js @@ -1,3 +1,3 @@ import Labels from '../../../../labels'; -document.addEventListener('DOMContentLoaded', () => new Labels()); +new Labels(); // eslint-disable-line no-new diff --git a/app/assets/javascripts/pages/admin/runners/index.js b/app/assets/javascripts/pages/admin/runners/index/index.js index 45ed3ac6bd8..45ed3ac6bd8 100644 --- a/app/assets/javascripts/pages/admin/runners/index.js +++ b/app/assets/javascripts/pages/admin/runners/index/index.js diff --git a/app/assets/javascripts/pages/admin/runners/show/index.js b/app/assets/javascripts/pages/admin/runners/show/index.js new file mode 100644 index 00000000000..d1853772fda --- /dev/null +++ b/app/assets/javascripts/pages/admin/runners/show/index.js @@ -0,0 +1,3 @@ +import { initRunnerDetail } from '~/runner/runner_details'; + +initRunnerDetail(); diff --git a/app/assets/javascripts/pages/admin/services/edit/index.js b/app/assets/javascripts/pages/admin/services/edit/index.js index 3d692ef4dcc..b8080ddff77 100644 --- a/app/assets/javascripts/pages/admin/services/edit/index.js +++ b/app/assets/javascripts/pages/admin/services/edit/index.js @@ -1,6 +1,4 @@ import IntegrationSettingsForm from '~/integrations/integration_settings_form'; -document.addEventListener('DOMContentLoaded', () => { - const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); - integrationSettingsForm.init(); -}); +const integrationSettingsForm = new IntegrationSettingsForm('.js-integration-settings-form'); +integrationSettingsForm.init(); diff --git a/app/assets/javascripts/pages/admin/spam_logs/index.js b/app/assets/javascripts/pages/admin/spam_logs/index.js new file mode 100644 index 00000000000..e5ab5d43bbf --- /dev/null +++ b/app/assets/javascripts/pages/admin/spam_logs/index.js @@ -0,0 +1,3 @@ +import initDeprecatedRemoveRowBehavior from '~/behaviors/deprecated_remove_row_behavior'; + +document.addEventListener('DOMContentLoaded', initDeprecatedRemoveRowBehavior); diff --git a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue index d2b83f980d7..20407334b3f 100644 --- a/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue +++ b/app/assets/javascripts/pages/admin/users/components/delete_user_modal.vue @@ -119,8 +119,8 @@ export default { <gl-button @click="onCancel">{{ s__('Cancel') }}</gl-button> <gl-button :disabled="!canSubmit" - category="primary" - variant="warning" + category="secondary" + variant="danger" @click="onSecondaryAction" > {{ secondaryAction }} diff --git a/app/assets/javascripts/pages/admin/users/new/index.js b/app/assets/javascripts/pages/admin/users/new/index.js index 7b7d4c169ef..34c10e44f4c 100644 --- a/app/assets/javascripts/pages/admin/users/new/index.js +++ b/app/assets/javascripts/pages/admin/users/new/index.js @@ -1,51 +1,3 @@ -import $ from 'jquery'; +import { setupInternalUserRegexHandler } from '~/admin/users/new'; -export default class UserInternalRegexHandler { - constructor() { - this.regexPattern = $('[data-user-internal-regex-pattern]').data('user-internal-regex-pattern'); - if (this.regexPattern && this.regexPattern !== '') { - this.regexOptions = $('[data-user-internal-regex-options]').data( - 'user-internal-regex-options', - ); - this.external = $('#user_external'); - this.warningMessage = $('#warning_external_automatically_set'); - this.addListenerToEmailField(); - this.addListenerToUserExternalCheckbox(); - } - } - - addListenerToEmailField() { - $('#user_email').on('input', (event) => { - this.setExternalCheckbox(event.currentTarget.value); - }); - } - - addListenerToUserExternalCheckbox() { - this.external.on('click', () => { - this.warningMessage.addClass('hidden'); - }); - } - - isEmailInternal(email) { - const regex = new RegExp(this.regexPattern, this.regexOptions); - return regex.test(email); - } - - setExternalCheckbox(email) { - const isChecked = this.external.prop('checked'); - if (this.isEmailInternal(email)) { - if (isChecked) { - this.external.prop('checked', false); - this.warningMessage.removeClass('hidden'); - } - } else if (!isChecked) { - this.external.prop('checked', true); - this.warningMessage.addClass('hidden'); - } - } -} - -document.addEventListener('DOMContentLoaded', () => { - // eslint-disable-next-line - new UserInternalRegexHandler(); -}); +setupInternalUserRegexHandler(); |