Commit 74096b27 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch '211672-maintenance-mode-alpha' into 'master'

Maintenance Mode - First Iteration

Closes #211672

See merge request gitlab-org/gitlab!28158
parents 45cadbf9 0f94c261
<script>
import { GlToggle, GlFormGroup, GlFormTextarea, GlButton } from '@gitlab/ui';
export default {
name: 'MaintenanceModeSettingsApp',
components: {
GlToggle,
GlFormGroup,
GlFormTextarea,
GlButton,
},
data() {
return {
inMaintenanceMode: false,
bannerMessage: '',
};
},
};
</script>
<template>
<article>
<div class="d-flex align-items-center mb-3">
<gl-toggle v-model="inMaintenanceMode" class="mb-0" />
<div class="ml-2">
<p class="mb-0">{{ __('Enable maintenance mode') }}</p>
<p class="mb-0 text-secondary-500">
{{
__('Non-admin users can sign in with read-only access and make read-only API requests.')
}}
</p>
</div>
</div>
<gl-form-group label="Banner Message" label-for="maintenanceBannerMessage">
<gl-form-textarea
id="maintenanceBannerMessage"
v-model="bannerMessage"
:placeholder="__(`GitLab is undergoing maintenance and is operating in a read-only mode.`)"
/>
</gl-form-group>
<div class="mt-4">
<gl-button variant="success">{{ __('Save changes') }}</gl-button>
</div>
</article>
</template>
import Vue from 'vue';
import Translate from '~/vue_shared/translate';
import MaintenanceModeSettingsApp from './components/app.vue';
Vue.use(Translate);
export default () => {
const el = document.getElementById('js-maintenance-mode-settings');
return new Vue({
el,
components: {
MaintenanceModeSettingsApp,
},
render(createElement) {
return createElement('maintenance-mode-settings-app');
},
});
};
import initSettingsPanels from '~/settings_panels'; import initSettingsPanels from '~/settings_panels';
import projectSelect from '~/project_select'; import projectSelect from '~/project_select';
import selfMonitor from '~/self_monitor'; import selfMonitor from '~/self_monitor';
import maintenanceModeSettings from '~/maintenance_mode_settings';
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
selfMonitor(); selfMonitor();
maintenanceModeSettings();
// Initialize expandable settings panels // Initialize expandable settings panels
initSettingsPanels(); initSettingsPanels();
projectSelect(); projectSelect();
......
...@@ -104,6 +104,18 @@ ...@@ -104,6 +104,18 @@
= f.submit _('Save changes'), class: "btn btn-success" = f.submit _('Save changes'), class: "btn btn-success"
- if Feature.enabled?(:maintenance_mode)
%section.settings.no-animate#js-maintenance-mode-toggle{ class: ('expanded' if expanded_by_default?) }
.settings-header
%h4
= _('Maintenance mode')
%button.btn.btn-default.js-settings-toggle{ type: 'button' }
= expanded_by_default? ? _('Collapse') : _('Expand')
%p
= _('Prevent users from performing write operations on GitLab while performing maintenance.')
.settings-content
#js-maintenance-mode-settings
- if Feature.enabled?(:instance_level_integrations) - if Feature.enabled?(:instance_level_integrations)
= render_if_exists 'admin/application_settings/elasticsearch_form' = render_if_exists 'admin/application_settings/elasticsearch_form'
= render 'admin/application_settings/plantuml' = render 'admin/application_settings/plantuml'
......
...@@ -7491,6 +7491,9 @@ msgstr "" ...@@ -7491,6 +7491,9 @@ msgstr ""
msgid "Enable header and footer in emails" msgid "Enable header and footer in emails"
msgstr "" msgstr ""
msgid "Enable maintenance mode"
msgstr ""
msgid "Enable mirror configuration" msgid "Enable mirror configuration"
msgstr "" msgstr ""
...@@ -9633,6 +9636,9 @@ msgstr "" ...@@ -9633,6 +9636,9 @@ msgstr ""
msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later." msgid "GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later."
msgstr "" msgstr ""
msgid "GitLab is undergoing maintenance and is operating in a read-only mode."
msgstr ""
msgid "GitLab member or Email address" msgid "GitLab member or Email address"
msgstr "" msgstr ""
...@@ -12139,6 +12145,9 @@ msgstr "" ...@@ -12139,6 +12145,9 @@ msgstr ""
msgid "Made this issue confidential." msgid "Made this issue confidential."
msgstr "" msgstr ""
msgid "Maintenance mode"
msgstr ""
msgid "Make and review changes in the browser with the Web IDE" msgid "Make and review changes in the browser with the Web IDE"
msgstr "" msgstr ""
...@@ -13489,6 +13498,9 @@ msgstr "" ...@@ -13489,6 +13498,9 @@ msgstr ""
msgid "Nodes" msgid "Nodes"
msgstr "" msgstr ""
msgid "Non-admin users can sign in with read-only access and make read-only API requests."
msgstr ""
msgid "None" msgid "None"
msgstr "" msgstr ""
...@@ -14862,6 +14874,9 @@ msgstr "" ...@@ -14862,6 +14874,9 @@ msgstr ""
msgid "Prevent users from modifing merge request approvers list" msgid "Prevent users from modifing merge request approvers list"
msgstr "" msgstr ""
msgid "Prevent users from performing write operations on GitLab while performing maintenance."
msgstr ""
msgid "Preview" msgid "Preview"
msgstr "" msgstr ""
......
import { shallowMount } from '@vue/test-utils';
import MaintenanceModeSettingsApp from '~/maintenance_mode_settings/components/app.vue';
import { GlToggle, GlFormTextarea, GlButton } from '@gitlab/ui';
describe('MaintenanceModeSettingsApp', () => {
let wrapper;
const createComponent = () => {
wrapper = shallowMount(MaintenanceModeSettingsApp);
};
afterEach(() => {
wrapper.destroy();
});
const findMaintenanceModeSettingsContainer = () => wrapper.find('article');
const findGlToggle = () => wrapper.find(GlToggle);
const findGlFormTextarea = () => wrapper.find(GlFormTextarea);
const findGlButton = () => wrapper.find(GlButton);
describe('template', () => {
beforeEach(() => {
createComponent();
});
it('renders the Maintenance Mode Settings container', () => {
expect(findMaintenanceModeSettingsContainer().exists()).toBe(true);
});
it('renders the GlToggle', () => {
expect(findGlToggle().exists()).toBe(true);
});
it('renders the GlFormTextarea', () => {
expect(findGlFormTextarea().exists()).toBe(true);
});
it('renders the GlButton', () => {
expect(findGlButton().exists()).toBe(true);
});
});
});
...@@ -33,4 +33,32 @@ describe 'admin/application_settings/general.html.haml' do ...@@ -33,4 +33,32 @@ describe 'admin/application_settings/general.html.haml' do
end end
end end
end end
describe 'Maintenance mode' do
let(:maintenance_mode_flag) { true }
before do
assign(:application_setting, app_settings)
stub_feature_flags(maintenance_mode: maintenance_mode_flag)
allow(view).to receive(:current_user).and_return(user)
end
context 'when maintenance_mode feature is enabled' do
it 'show the Maintenance mode section' do
render
expect(rendered).to have_css('#js-maintenance-mode-toggle')
end
end
context 'when maintenance_mode feature is disabled' do
let(:maintenance_mode_flag) { false }
it 'hide the Maintenance mode section' do
render
expect(rendered).not_to have_css('#js-maintenance-mode-toggle')
end
end
end
end end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment