Commit 1a93abaa authored by Nathan Friend's avatar Nathan Friend

Merge branch '200014-update-geo-replication-empty' into 'master'

Add Geo Replication Empty States

Closes #200014

See merge request gitlab-org/gitlab!31010
parents 4ae6f414 14ff3ef3
......@@ -14,11 +14,7 @@ export default {
GeoReplicableEmptyState,
},
props: {
geoSvgPath: {
type: String,
required: true,
},
issuesSvgPath: {
geoReplicableEmptySvgPath: {
type: String,
required: true,
},
......@@ -50,7 +46,7 @@ export default {
<geo-replicable v-if="hasReplicableItems" />
<geo-replicable-empty-state
v-else
:issues-svg-path="issuesSvgPath"
:geo-replicable-empty-svg-path="geoReplicableEmptySvgPath"
:geo-troubleshooting-link="geoTroubleshootingLink"
/>
</template>
......
......@@ -9,7 +9,7 @@ export default {
GlEmptyState,
},
props: {
issuesSvgPath: {
geoReplicableEmptySvgPath: {
type: String,
required: true,
},
......@@ -23,7 +23,7 @@ export default {
linkText() {
return sprintf(
s__(
'If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information.',
'Geo|Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information.',
),
{
linkStart: `<a href="${this.geoTroubleshootingLink}" target="_blank">`,
......@@ -38,12 +38,11 @@ export default {
<template>
<gl-empty-state
:title="sprintf(__('No %{replicableType} match this filter'), { replicableType })"
:svg-path="issuesSvgPath"
:title="sprintf(__('There are no %{replicableType} to show'), { replicableType })"
:svg-path="geoReplicableEmptySvgPath"
>
<template #description>
<div class="text-center">
<p>{{ __('Adjust your filters/search criteria above.') }}</p>
<div>
<p v-html="linkText"></p>
</div>
</template>
......
......@@ -17,22 +17,20 @@ export default () => {
},
data() {
const {
dataset: { geoSvgPath, issuesSvgPath, geoTroubleshootingLink },
dataset: { geoTroubleshootingLink, geoReplicableEmptySvgPath },
} = this.$options.el;
return {
geoSvgPath,
issuesSvgPath,
geoTroubleshootingLink,
geoReplicableEmptySvgPath,
};
},
render(createElement) {
return createElement('geo-replicable-app', {
props: {
geoSvgPath: this.geoSvgPath,
issuesSvgPath: this.issuesSvgPath,
geoTroubleshootingLink: this.geoTroubleshootingLink,
geoReplicableEmptySvgPath: this.geoReplicableEmptySvgPath,
},
});
},
......
- page_title _('Geo Designs')
#js-geo-replicable{ data: { "geo-svg-path" => image_path('illustrations/empty-state/geo-empty.svg'),
"issues-svg-path" => image_path('illustrations/issues.svg'),
#js-geo-replicable{ data: { "geo-replicable-empty-svg-path" => image_path('illustrations/empty-state/geo-replication-empty.svg'),
"geo-troubleshooting-link" => help_page_path('administration/geo/replication/troubleshooting.html'),
"replicable-type" => 'designs' } }
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- unless project_registry.pending_verification?
= link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Reverify')
- unless project_registry.resync_repository?
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
- if @registries.any?
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- unless project_registry.pending_verification?
= link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Reverify')
- unless project_registry.resync_repository?
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
= render partial: "registry_#{project_registry.synchronization_state}", locals: { project_registry: project_registry }
= render partial: "registry_#{project_registry.synchronization_state}", locals: { project_registry: project_registry }
= paginate @registries, theme: 'gitlab'
= paginate @registries, theme: 'gitlab'
- else
= render 'shared/empty_states/geo_replication', replicable_type: _('projects')
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- if project_registry.candidate_for_redownload?
= link_to(force_redownload_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Redownload')
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
- if @registries.any?
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- if project_registry.candidate_for_redownload?
= link_to(force_redownload_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Redownload')
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
= render partial: 'registry_failed', locals: { project_registry: project_registry }
= render partial: 'registry_failed', locals: { project_registry: project_registry }
= paginate @registries, theme: 'gitlab'
= paginate @registries, theme: 'gitlab'
- else
= render 'shared/empty_states/geo_replication', replicable_type: _('projects')
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- unless project_registry.pending_verification?
= link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Reverify')
- unless project_registry.resync_repository?
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
- if @registries.any?
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
- unless project_registry.pending_verification?
= link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Reverify')
- unless project_registry.resync_repository?
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
= render partial: 'registry_pending', locals: { project_registry: project_registry }
= render partial: 'registry_pending', locals: { project_registry: project_registry }
= paginate @registries, theme: 'gitlab'
= paginate @registries, theme: 'gitlab'
- else
= render 'shared/empty_states/geo_replication', replicable_type: _('projects')
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
= link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Reverify')
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
- if @registries.any?
- @registries.each do |project_registry|
.card.project-card.prepend-top-15
.card-header{ id: "project-#{project_registry.project_id}-header" }
.d-flex.align-items-center
- if project_registry.project.nil?
= render partial: 'removed', locals: { project_registry: project_registry }
- else
%strong.text-truncate.flex-fill
= link_to project_registry.project.full_name, admin_namespace_project_path(project_registry.project.namespace, project_registry.project)
= link_to(reverify_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default btn-sm mr-2') do
= s_('Geo|Reverify')
= link_to(resync_admin_geo_project_path(project_registry), method: :post, class: 'btn btn-default-primary btn-sm') do
= s_('Geo|Resync')
= render partial: 'registry_synced', locals: { project_registry: project_registry }
= render partial: 'registry_synced', locals: { project_registry: project_registry }
= paginate @registries, theme: 'gitlab'
= paginate @registries, theme: 'gitlab'
- else
= render 'shared/empty_states/geo_replication', replicable_type: _('projects')
......@@ -19,7 +19,10 @@
.nav-controls
= render(partial: 'shared/projects/search_form', autofocus: true)
- @registries.each do |upload_registry|
= render partial: 'registry', locals: { upload_registry: upload_registry }
- if @registries.any?
- @registries.each do |upload_registry|
= render partial: 'registry', locals: { upload_registry: upload_registry }
= paginate @registries, theme: 'gitlab'
= paginate @registries, theme: 'gitlab'
- else
= render 'shared/empty_states/geo_replication', replicable_type: _('uploads')
- geo_troubleshooting_link = help_page_path('administration/geo/replication/troubleshooting.html')
.row.empty-state
.col-12
.svg-content.svg-250
= image_tag 'illustrations/empty-state/geo-replication-empty.svg'
.col-12
.text-content
%h4.text-center= sprintf(s_('Geo|There are no %{replicable_type} to show'), { replicable_type: replicable_type })
%p
= sprintf(s_('Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information.') , { linkStart: "<a href=\"#{geo_troubleshooting_link}\" target=\"_blank\">", linkEnd: "</a>", }).html_safe;
---
title: Geo - Add Empty States
merge_request: 31010
author:
type: changed
......@@ -30,6 +30,7 @@ describe 'admin Geo Projects', :js, :geo do
expect(page).to have_content(sync_pending_registry.project.full_name)
expect(page).to have_content(sync_failed_registry.project.full_name)
expect(page).to have_content(never_synced_registry.project.full_name)
expect(page).not_to have_content('There are no projects to show')
end
end
......@@ -45,6 +46,24 @@ describe 'admin Geo Projects', :js, :geo do
expect(page).not_to have_content(sync_pending_registry.project.full_name)
expect(page).not_to have_content(sync_failed_registry.project.full_name)
expect(page).not_to have_content(never_synced_registry.project.full_name)
expect(page).not_to have_content('There are no projects to show')
end
end
end
describe 'with no registries', :geo_fdw do
it 'shows empty state' do
fill_in :name, with: 'asdfasdf'
find('#project-filter-form-field').native.send_keys(:enter)
wait_for_requests
page.within(find('#content-body', match: :first)) do
expect(page).not_to have_content(synced_registry.project.full_name)
expect(page).not_to have_content(sync_pending_registry.project.full_name)
expect(page).not_to have_content(sync_failed_registry.project.full_name)
expect(page).not_to have_content(never_synced_registry.project.full_name)
expect(page).to have_content('There are no projects to show')
end
end
end
......
......@@ -11,6 +11,48 @@ describe 'admin Geo Uploads', :js, :geo do
sign_in(create(:admin))
end
describe 'visiting geo uploads initial page' do
before do
visit(admin_geo_uploads_path)
wait_for_requests
end
it 'shows all uploads in the registry' do
page.within(find('#content-body', match: :first)) do
expect(page).to have_content(synced_registry.file)
expect(page).not_to have_content('There are no uploads to show')
end
end
describe 'searching for a geo upload', :geo_fdw do
it 'filters out uploads with the search term' do
fill_in :name, with: synced_registry.file
find('#project-filter-form-field').native.send_keys(:enter)
wait_for_requests
page.within(find('#content-body', match: :first)) do
expect(page).to have_content(synced_registry.file)
expect(page).not_to have_content('There are no uploads to show')
end
end
end
describe 'with no registries', :geo_fdw do
it 'shows empty state' do
fill_in :name, with: 'asdfasdf'
find('#project-filter-form-field').native.send_keys(:enter)
wait_for_requests
page.within(find('#content-body', match: :first)) do
expect(page).not_to have_content(synced_registry.file)
expect(page).to have_content('There are no uploads to show')
end
end
end
end
describe 'remove an orphaned Tracking Entry' do
before do
synced_registry.upload.destroy!
......
......@@ -7,8 +7,7 @@ import GeoReplicable from 'ee/geo_replicable/components/geo_replicable.vue';
import GeoReplicableEmptyState from 'ee/geo_replicable/components/geo_replicable_empty_state.vue';
import GeoReplicableFilterBar from 'ee/geo_replicable/components/geo_replicable_filter_bar.vue';
import {
MOCK_GEO_SVG_PATH,
MOCK_ISSUES_SVG_PATH,
MOCK_GEO_REPLICATION_SVG_PATH,
MOCK_GEO_TROUBLESHOOTING_LINK,
MOCK_BASIC_FETCH_DATA_MAP,
} from '../mock_data';
......@@ -20,9 +19,8 @@ describe('GeoReplicableApp', () => {
let wrapper;
const propsData = {
geoSvgPath: MOCK_GEO_SVG_PATH,
issuesSvgPath: MOCK_ISSUES_SVG_PATH,
geoTroubleshootingLink: MOCK_GEO_TROUBLESHOOTING_LINK,
geoReplicableEmptySvgPath: MOCK_GEO_REPLICATION_SVG_PATH,
};
const actionSpies = {
......
import Vuex from 'vuex';
import { createLocalVue, mount } from '@vue/test-utils';
import { createLocalVue, shallowMount } from '@vue/test-utils';
import { GlEmptyState } from '@gitlab/ui';
import store from 'ee/geo_replicable/store';
import GeoReplicableEmptyState from 'ee/geo_replicable/components/geo_replicable_empty_state.vue';
import { MOCK_ISSUES_SVG_PATH, MOCK_GEO_TROUBLESHOOTING_LINK } from '../mock_data';
import { MOCK_GEO_REPLICATION_SVG_PATH, MOCK_GEO_TROUBLESHOOTING_LINK } from '../mock_data';
const localVue = createLocalVue();
localVue.use(Vuex);
......@@ -12,12 +12,12 @@ describe('GeoReplicableEmptyState', () => {
let wrapper;
const propsData = {
issuesSvgPath: MOCK_ISSUES_SVG_PATH,
geoTroubleshootingLink: MOCK_GEO_TROUBLESHOOTING_LINK,
geoReplicableEmptySvgPath: MOCK_GEO_REPLICATION_SVG_PATH,
};
const createComponent = () => {
wrapper = mount(GeoReplicableEmptyState, {
wrapper = shallowMount(GeoReplicableEmptyState, {
localVue,
store,
propsData,
......@@ -29,19 +29,20 @@ describe('GeoReplicableEmptyState', () => {
});
const findGlEmptyState = () => wrapper.find(GlEmptyState);
const findLink = () => findGlEmptyState().find('a');
describe('template', () => {
beforeEach(() => {
createComponent();
});
it('renders GlEmptyState', () => {
expect(findGlEmptyState().exists()).toBe(true);
});
describe('GlEmptyState', () => {
it('renders always', () => {
expect(findGlEmptyState().exists()).toBe(true);
});
it('Link renders', () => {
expect(findLink().exists()).toBe(true);
it('sets correct svg', () => {
expect(findGlEmptyState().attributes('svgpath')).toBe(MOCK_GEO_REPLICATION_SVG_PATH);
});
});
});
});
import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
export const MOCK_GEO_SVG_PATH = 'illustrations/empty-state/geo-empty.svg';
export const MOCK_ISSUES_SVG_PATH = 'illustrations/issues.svg';
export const MOCK_GEO_REPLICATION_SVG_PATH = 'illustrations/empty-state/geo-replication-empty.svg';
export const MOCK_GEO_TROUBLESHOOTING_LINK =
'https://docs.gitlab.com/ee/administration/geo/replication/troubleshooting.html';
......
......@@ -1356,7 +1356,7 @@ msgstr ""
msgid "Adds an issue to an epic."
msgstr ""
msgid "Adjust your filters/search criteria above."
msgid "Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
msgstr ""
msgid "Admin Area"
......@@ -9790,6 +9790,9 @@ msgstr ""
msgid "Geo|%{name} is scheduled for re-verify"
msgstr ""
msgid "Geo|Adjust your filters/search criteria above. If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
msgstr ""
msgid "Geo|All"
msgstr ""
......@@ -9913,6 +9916,9 @@ msgstr ""
msgid "Geo|The node is currently %{minutes_behind} behind the primary node."
msgstr ""
msgid "Geo|There are no %{replicable_type} to show"
msgstr ""
msgid "Geo|Tracking database entry will be removed. Are you sure?"
msgstr ""
......@@ -11132,9 +11138,6 @@ msgstr ""
msgid "If using GitHub, you’ll see pipeline statuses on GitHub for your commits and pull requests. %{more_info_link}"
msgstr ""
msgid "If you believe this may be an error, please refer to the %{linkStart}Geo Troubleshooting%{linkEnd} documentation for more information."
msgstr ""
msgid "If you lose your recovery codes you can generate new ones, invalidating all previous codes."
msgstr ""
......@@ -13798,9 +13801,6 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
msgid "No %{replicableType} match this filter"
msgstr ""
msgid "No Epic"
msgstr ""
......@@ -20962,6 +20962,9 @@ msgstr ""
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
msgstr ""
msgid "There are no %{replicableType} to show"
msgstr ""
msgid "There are no GPG keys associated with this account."
msgstr ""
......@@ -25821,6 +25824,9 @@ msgstr ""
msgid "updated %{time_ago}"
msgstr ""
msgid "uploads"
msgstr ""
msgid "user avatar"
msgstr ""
......
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