Commit 14ff3ef3 authored by Zack Cuddy's avatar Zack Cuddy

Add Geo Replication Empty States

Currently only some of Geo Replicable
Views has empty states.

This MR remedies that by adding them to
the two legacy views (Projects and Uploads).

As well as the new generic Geo Replicables.
parent ad3904e5
......@@ -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
......@@ -26,6 +26,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
......@@ -41,6 +42,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"
......@@ -9751,6 +9751,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 ""
......@@ -9871,6 +9874,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 ""
......@@ -11093,9 +11099,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 ""
......@@ -13762,9 +13765,6 @@ msgstr ""
msgid "No %{providerTitle} repositories found"
msgstr ""
msgid "No %{replicableType} match this filter"
msgstr ""
msgid "No Epic"
msgstr ""
......@@ -20881,6 +20881,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 ""
......@@ -25567,6 +25570,9 @@ msgstr[1] ""
msgid "project avatar"
msgstr ""
msgid "projects"
msgstr ""
msgid "push to your repository, create pipelines, create issues or add comments. To reduce storage capacity, delete unused repositories, artifacts, wikis, issues, and pipelines."
msgstr ""
......@@ -25743,6 +25749,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