Commit 99d7917a authored by Illya Klymov's avatar Illya Klymov

Merge branch '208470_03-package-file-ui' into 'master'

Geo Package Files - Setup UI

See merge request gitlab-org/gitlab!33987
parents 6c349487 b7c836e5
...@@ -24,9 +24,9 @@ export default { ...@@ -24,9 +24,9 @@ export default {
}, },
}, },
computed: { computed: {
...mapState(['isLoading', 'paginationData']), ...mapState(['isLoading', 'replicableItems', 'useGraphQl']),
hasReplicableItems() { hasReplicableItems() {
return this.paginationData.total > 0; return this.replicableItems.length > 0;
}, },
}, },
created() { created() {
...@@ -40,7 +40,8 @@ export default { ...@@ -40,7 +40,8 @@ export default {
<template> <template>
<article class="geo-replicable-container"> <article class="geo-replicable-container">
<geo-replicable-filter-bar class="mb-3" /> <!-- Filtering not currently supported via GraphQl -->
<geo-replicable-filter-bar v-if="!useGraphQl" class="mb-3" />
<gl-loading-icon v-if="isLoading" size="xl" /> <gl-loading-icon v-if="isLoading" size="xl" />
<template v-else> <template v-else>
<geo-replicable v-if="hasReplicableItems" /> <geo-replicable v-if="hasReplicableItems" />
......
...@@ -10,7 +10,7 @@ export default { ...@@ -10,7 +10,7 @@ export default {
GeoReplicableItem, GeoReplicableItem,
}, },
computed: { computed: {
...mapState(['replicableItems', 'paginationData']), ...mapState(['replicableItems', 'paginationData', 'useGraphQl']),
page: { page: {
get() { get() {
return this.paginationData.page; return this.paginationData.page;
...@@ -20,12 +20,15 @@ export default { ...@@ -20,12 +20,15 @@ export default {
this.fetchReplicableItems(); this.fetchReplicableItems();
}, },
}, },
hasReplicableItems() { showRestfulPagination() {
return this.paginationData.total > 0; return !this.useGraphQl && this.paginationData.total > 0;
}, },
}, },
methods: { methods: {
...mapActions(['setPage', 'fetchReplicableItems']), ...mapActions(['setPage', 'fetchReplicableItems']),
buildName(item) {
return item.name ? item.name : item.id;
},
}, },
}; };
</script> </script>
...@@ -35,15 +38,15 @@ export default { ...@@ -35,15 +38,15 @@ export default {
<geo-replicable-item <geo-replicable-item
v-for="item in replicableItems" v-for="item in replicableItems"
:key="item.id" :key="item.id"
:name="item.name" :name="buildName(item)"
:project-id="item.projectId" :project-id="item.projectId"
:sync-status="item.state" :sync-status="item.state.toLowerCase()"
:last-synced="item.lastSyncedAt" :last-synced="item.lastSyncedAt"
:last-verified="item.lastVerifiedAt" :last-verified="item.lastVerifiedAt"
:last-checked="item.lastCheckedAt" :last-checked="item.lastCheckedAt"
/> />
<gl-pagination <gl-pagination
v-if="hasReplicableItems" v-if="showRestfulPagination"
v-model="page" v-model="page"
:per-page="paginationData.perPage" :per-page="paginationData.perPage"
:total-items="paginationData.total" :total-items="paginationData.total"
......
...@@ -21,7 +21,8 @@ export default { ...@@ -21,7 +21,8 @@ export default {
}, },
projectId: { projectId: {
type: Number, type: Number,
required: true, required: false,
default: null,
}, },
syncStatus: { syncStatus: {
type: String, type: String,
...@@ -65,6 +66,11 @@ export default { ...@@ -65,6 +66,11 @@ export default {
], ],
}; };
}, },
computed: {
hasProject() {
return Boolean(this.projectId);
},
},
methods: { methods: {
...mapActions(['initiateReplicableSync']), ...mapActions(['initiateReplicableSync']),
}, },
...@@ -74,7 +80,7 @@ export default { ...@@ -74,7 +80,7 @@ export default {
<template> <template>
<div class="card"> <div class="card">
<div class="card-header d-flex align-center"> <div v-if="hasProject" class="card-header d-flex align-center">
<gl-link class="font-weight-bold" :href="`/${name}`" target="_blank">{{ name }}</gl-link> <gl-link class="font-weight-bold" :href="`/${name}`" target="_blank">{{ name }}</gl-link>
<div class="ml-auto"> <div class="ml-auto">
<gl-button <gl-button
...@@ -84,6 +90,9 @@ export default { ...@@ -84,6 +90,9 @@ export default {
> >
</div> </div>
</div> </div>
<div v-else class="card-header">
<span class="font-weight-bold">{{ name }}</span>
</div>
<div class="card-body"> <div class="card-body">
<div class="d-flex flex-column flex-md-row"> <div class="d-flex flex-column flex-md-row">
<div class="flex-grow-1"> <div class="flex-grow-1">
......
...@@ -52,82 +52,59 @@ describe('GeoReplicableApp', () => { ...@@ -52,82 +52,59 @@ describe('GeoReplicableApp', () => {
const findGeoReplicableFilterBar = () => const findGeoReplicableFilterBar = () =>
findGeoReplicableContainer().find(GeoReplicableFilterBar); findGeoReplicableContainer().find(GeoReplicableFilterBar);
describe('template', () => { describe.each`
beforeEach(() => { isLoading | useGraphQl | replicableItems | showReplicableItems | showEmptyState | showFilterBar | showLoader
createComponent(); ${false} | ${false} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${true} | ${false} | ${true} | ${false}
}); ${false} | ${false} | ${[]} | ${false} | ${true} | ${true} | ${false}
${false} | ${true} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${true} | ${false} | ${false} | ${false}
it('renders the replicable container', () => { ${false} | ${true} | ${[]} | ${false} | ${true} | ${false} | ${false}
expect(findGeoReplicableContainer().exists()).toBe(true); ${true} | ${false} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${false} | ${false} | ${true} | ${true}
}); ${true} | ${false} | ${[]} | ${false} | ${false} | ${true} | ${true}
${true} | ${true} | ${MOCK_BASIC_FETCH_DATA_MAP} | ${false} | ${false} | ${false} | ${true}
it('renders the filter bar', () => { ${true} | ${true} | ${[]} | ${false} | ${false} | ${false} | ${true}
expect(findGeoReplicableFilterBar().exists()).toBe(true); `(
}); `template`,
({
describe('when isLoading = true', () => { isLoading,
beforeEach(() => { useGraphQl,
wrapper.vm.$store.state.isLoading = true; replicableItems,
}); showReplicableItems,
showEmptyState,
it('hides replicable items', () => { showFilterBar,
expect(findGeoReplicable().exists()).toBe(false); showLoader,
}); }) => {
it('hides empty state', () => {
expect(findGeoReplicableEmptyState().exists()).toBe(false);
});
it('shows loader', () => {
expect(findGlLoadingIcon().exists()).toBe(true);
});
});
describe('when isLoading = false', () => {
beforeEach(() => { beforeEach(() => {
wrapper.vm.$store.state.isLoading = false; createComponent();
}); });
describe('with replicableItems', () => { describe(`when isLoading is ${isLoading} and useGraphQl is ${useGraphQl}, ${
replicableItems.length ? 'with' : 'without'
} replicableItems`, () => {
beforeEach(() => { beforeEach(() => {
wrapper.vm.$store.state.replicableItems = MOCK_BASIC_FETCH_DATA_MAP; wrapper.vm.$store.state.isLoading = isLoading;
wrapper.vm.$store.state.paginationData.total = wrapper.vm.$store.state.useGraphQl = useGraphQl;
wrapper.vm.$store.state.replicableItems.length; wrapper.vm.$store.state.replicableItems = replicableItems;
}); wrapper.vm.$store.state.paginationData.total = replicableItems.length;
it('shows replicable items', () => {
expect(findGeoReplicable().exists()).toBe(true);
});
it('hides empty state', () => {
expect(findGeoReplicableEmptyState().exists()).toBe(false);
}); });
it('hides loader', () => { it(`${showReplicableItems ? 'shows' : 'hides'} the replicable items`, () => {
expect(findGlLoadingIcon().exists()).toBe(false); expect(findGeoReplicable().exists()).toBe(showReplicableItems);
}); });
});
describe('with no replicableItems', () => { it(`${showEmptyState ? 'shows' : 'hides'} the empty state`, () => {
beforeEach(() => { expect(findGeoReplicableEmptyState().exists()).toBe(showEmptyState);
wrapper.vm.$store.state.replicableItems = [];
wrapper.vm.$store.state.paginationData.total = 0;
}); });
it('hides replicable items', () => { it(`${showFilterBar ? 'shows' : 'hides'} the filter bar`, () => {
expect(findGeoReplicable().exists()).toBe(false); expect(findGeoReplicableFilterBar().exists()).toBe(showFilterBar);
}); });
it('shows empty state', () => { it(`${showLoader ? 'shows' : 'hides'} the loader`, () => {
expect(findGeoReplicableEmptyState().exists()).toBe(true); expect(findGlLoadingIcon().exists()).toBe(showLoader);
});
it('hides loader', () => {
expect(findGlLoadingIcon().exists()).toBe(false);
}); });
}); });
}); },
}); );
describe('onCreate', () => { describe('onCreate', () => {
beforeEach(() => { beforeEach(() => {
......
...@@ -17,7 +17,7 @@ describe('GeoReplicableItem', () => { ...@@ -17,7 +17,7 @@ describe('GeoReplicableItem', () => {
initiateReplicableSync: jest.fn(), initiateReplicableSync: jest.fn(),
}; };
const propsData = { const defaultProps = {
name: mockReplicable.name, name: mockReplicable.name,
projectId: mockReplicable.projectId, projectId: mockReplicable.projectId,
syncStatus: mockReplicable.state, syncStatus: mockReplicable.state,
...@@ -26,11 +26,14 @@ describe('GeoReplicableItem', () => { ...@@ -26,11 +26,14 @@ describe('GeoReplicableItem', () => {
lastChecked: null, lastChecked: null,
}; };
const createComponent = () => { const createComponent = (props = {}) => {
wrapper = mount(GeoReplicableItem, { wrapper = mount(GeoReplicableItem, {
localVue, localVue,
store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }), store: createStore({ replicableType: MOCK_REPLICABLE_TYPE, useGraphQl: false }),
propsData, propsData: {
...defaultProps,
...props,
},
methods: { methods: {
...actionSpies, ...actionSpies,
}, },
...@@ -45,6 +48,7 @@ describe('GeoReplicableItem', () => { ...@@ -45,6 +48,7 @@ describe('GeoReplicableItem', () => {
const findGlLink = () => findCard().find(GlLink); const findGlLink = () => findCard().find(GlLink);
const findGlButton = () => findCard().find(GlButton); const findGlButton = () => findCard().find(GlButton);
const findCardHeader = () => findCard().find('.card-header'); const findCardHeader = () => findCard().find('.card-header');
const findTextTitle = () => findCardHeader().find('span');
const findCardBody = () => findCard().find('.card-body'); const findCardBody = () => findCard().find('.card-body');
describe('template', () => { describe('template', () => {
...@@ -64,22 +68,44 @@ describe('GeoReplicableItem', () => { ...@@ -64,22 +68,44 @@ describe('GeoReplicableItem', () => {
expect(findCardBody().exists()).toBe(true); expect(findCardBody().exists()).toBe(true);
}); });
it('GlLink renders', () => { describe('with projectId', () => {
expect(findGlLink().exists()).toBe(true); it('GlLink renders correctly', () => {
expect(findGlLink().exists()).toBe(true);
expect(findGlLink().text()).toBe(mockReplicable.name);
});
describe('ReSync Button', () => {
it('renders', () => {
expect(findGlButton().exists()).toBe(true);
});
it('calls initiateReplicableSync when clicked', () => {
findGlButton().trigger('click');
expect(actionSpies.initiateReplicableSync).toHaveBeenCalledWith({
projectId: mockReplicable.projectId,
name: mockReplicable.name,
action: ACTION_TYPES.RESYNC,
});
});
});
}); });
describe('ReSync Button', () => { describe('without projectId', () => {
it('renders', () => { beforeEach(() => {
expect(findGlButton().exists()).toBe(true); createComponent({ projectId: null });
}); });
it('calls initiateReplicableSync when clicked', () => { it('Text title renders correctly', () => {
findGlButton().trigger('click'); expect(findTextTitle().exists()).toBe(true);
expect(actionSpies.initiateReplicableSync).toHaveBeenCalledWith({ expect(findTextTitle().text()).toBe(mockReplicable.name);
projectId: propsData.projectId, });
name: propsData.name,
action: ACTION_TYPES.RESYNC, it('GlLink does not render', () => {
}); expect(findGlLink().exists()).toBe(false);
});
it('ReSync Button does not render', () => {
expect(findGlButton().exists()).toBe(false);
}); });
}); });
}); });
......
...@@ -44,27 +44,40 @@ describe('GeoReplicable', () => { ...@@ -44,27 +44,40 @@ describe('GeoReplicable', () => {
expect(findGeoReplicableContainer().exists()).toBe(true); expect(findGeoReplicableContainer().exists()).toBe(true);
}); });
describe('GlPagination', () => { describe('when useGraphQl is false', () => {
describe('when perPage >= total', () => { describe('GlPagination', () => {
beforeEach(() => { describe('when perPage >= total', () => {
wrapper.vm.$store.state.paginationData.perPage = 2; beforeEach(() => {
wrapper.vm.$store.state.paginationData.total = 1; wrapper.vm.$store.state.paginationData.perPage = 2;
wrapper.vm.$store.state.paginationData.total = 1;
});
it('is hidden', () => {
expect(findGlPagination().isEmpty()).toBe(true);
});
}); });
it('is hidden', () => { describe('when perPage < total', () => {
expect(findGlPagination().isEmpty()).toBe(true); beforeEach(() => {
wrapper.vm.$store.state.paginationData.perPage = 1;
wrapper.vm.$store.state.paginationData.total = 2;
});
it('renders', () => {
expect(findGlPagination().html()).not.toBeUndefined();
});
}); });
}); });
});
describe('when perPage < total', () => { describe('when useGraphQl is true', () => {
beforeEach(() => { beforeEach(() => {
wrapper.vm.$store.state.paginationData.perPage = 1; createComponent();
wrapper.vm.$store.state.paginationData.total = 2; wrapper.vm.$store.state.useGraphQl = true;
}); });
it('renders', () => { it('does not render GlPagination', () => {
expect(findGlPagination().html()).not.toBeUndefined(); expect(findGlPagination().exists()).toBeFalsy();
});
}); });
}); });
...@@ -85,17 +98,19 @@ describe('GeoReplicable', () => { ...@@ -85,17 +98,19 @@ describe('GeoReplicable', () => {
}); });
describe('changing the page', () => { describe('changing the page', () => {
beforeEach(() => { describe('when useGraphQl is false', () => {
createComponent(); beforeEach(() => {
wrapper.vm.page = 2; createComponent();
}); wrapper.vm.page = 2;
});
it('should call setPage', () => { it('should call setPage', () => {
expect(actionSpies.setPage).toHaveBeenCalledWith(2); expect(actionSpies.setPage).toHaveBeenCalledWith(2);
}); });
it('should call fetchReplicableItems', () => { it('should call fetchReplicableItems', () => {
expect(actionSpies.fetchReplicableItems).toHaveBeenCalled(); expect(actionSpies.fetchReplicableItems).toHaveBeenCalled();
});
}); });
}); });
}); });
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