Commit 4695b311 authored by Mike Greiling's avatar Mike Greiling

Prettify registry and reports modules

parent c0d26698
<script> <script>
import { mapGetters, mapActions } from 'vuex'; import { mapGetters, mapActions } from 'vuex';
import Flash from '../../flash'; import Flash from '../../flash';
import store from '../stores'; import store from '../stores';
import collapsibleContainer from './collapsible_container.vue'; import collapsibleContainer from './collapsible_container.vue';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
export default { export default {
name: 'RegistryListApp', name: 'RegistryListApp',
components: { components: {
collapsibleContainer, collapsibleContainer,
},
props: {
endpoint: {
type: String,
required: true,
}, },
props: { },
endpoint: { store,
type: String, computed: {
required: true, ...mapGetters(['isLoading', 'repos']),
}, },
}, created() {
store, this.setMainEndpoint(this.endpoint);
computed: { },
...mapGetters([ mounted() {
'isLoading', this.fetchRepos().catch(() => Flash(errorMessages[errorMessagesTypes.FETCH_REPOS]));
'repos', },
]), methods: {
}, ...mapActions(['setMainEndpoint', 'fetchRepos']),
created() { },
this.setMainEndpoint(this.endpoint); };
},
mounted() {
this.fetchRepos()
.catch(() => Flash(errorMessages[errorMessagesTypes.FETCH_REPOS]));
},
methods: {
...mapActions([
'setMainEndpoint',
'fetchRepos',
]),
},
};
</script> </script>
<template> <template>
<div> <div>
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import Flash from '../../flash'; import Flash from '../../flash';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import tableRegistry from './table_registry.vue'; import tableRegistry from './table_registry.vue';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
import { __ } from '../../locale'; import { __ } from '../../locale';
export default { export default {
name: 'CollapsibeContainerRegisty', name: 'CollapsibeContainerRegisty',
components: { components: {
clipboardButton, clipboardButton,
tableRegistry, tableRegistry,
},
directives: {
tooltip,
},
props: {
repo: {
type: Object,
required: true,
}, },
directives: { },
tooltip, data() {
}, return {
props: { isOpen: false,
repo: { };
type: Object, },
required: true, methods: {
}, ...mapActions(['fetchRepos', 'fetchList', 'deleteRepo']),
},
data() {
return {
isOpen: false,
};
},
methods: {
...mapActions([
'fetchRepos',
'fetchList',
'deleteRepo',
]),
toggleRepo() { toggleRepo() {
this.isOpen = !this.isOpen; this.isOpen = !this.isOpen;
if (this.isOpen) { if (this.isOpen) {
this.fetchList({ repo: this.repo }) this.fetchList({ repo: this.repo }).catch(() =>
.catch(() => this.showError(errorMessagesTypes.FETCH_REGISTRY)); this.showError(errorMessagesTypes.FETCH_REGISTRY),
} );
}, }
},
handleDeleteRepository() { handleDeleteRepository() {
this.deleteRepo(this.repo) this.deleteRepo(this.repo)
.then(() => { .then(() => {
Flash(__('This container registry has been scheduled for deletion.'), 'notice'); Flash(__('This container registry has been scheduled for deletion.'), 'notice');
this.fetchRepos(); this.fetchRepos();
}) })
.catch(() => this.showError(errorMessagesTypes.DELETE_REPO)); .catch(() => this.showError(errorMessagesTypes.DELETE_REPO));
}, },
showError(message) { showError(message) {
Flash(errorMessages[message]); Flash(errorMessages[message]);
},
}, },
}; },
};
</script> </script>
<template> <template>
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
import { n__ } from '../../locale'; import { n__ } from '../../locale';
import Flash from '../../flash'; import Flash from '../../flash';
import clipboardButton from '../../vue_shared/components/clipboard_button.vue'; import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
import tablePagination from '../../vue_shared/components/table_pagination.vue'; import tablePagination from '../../vue_shared/components/table_pagination.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import timeagoMixin from '../../vue_shared/mixins/timeago'; import timeagoMixin from '../../vue_shared/mixins/timeago';
import { errorMessages, errorMessagesTypes } from '../constants'; import { errorMessages, errorMessagesTypes } from '../constants';
import { numberToHumanSize } from '../../lib/utils/number_utils'; import { numberToHumanSize } from '../../lib/utils/number_utils';
export default { export default {
components: { components: {
clipboardButton, clipboardButton,
tablePagination, tablePagination,
},
directives: {
tooltip,
},
mixins: [timeagoMixin],
props: {
repo: {
type: Object,
required: true,
}, },
directives: { },
tooltip, computed: {
shouldRenderPagination() {
return this.repo.pagination.total > this.repo.pagination.perPage;
}, },
mixins: [ },
timeagoMixin, methods: {
], ...mapActions(['fetchList', 'deleteRegistry']),
props: {
repo: {
type: Object,
required: true,
},
},
computed: {
shouldRenderPagination() {
return this.repo.pagination.total > this.repo.pagination.perPage;
},
},
methods: {
...mapActions([
'fetchList',
'deleteRegistry',
]),
layers(item) { layers(item) {
return item.layers ? n__('%d layer', '%d layers', item.layers) : ''; return item.layers ? n__('%d layer', '%d layers', item.layers) : '';
}, },
formatSize(size) { formatSize(size) {
return numberToHumanSize(size); return numberToHumanSize(size);
}, },
handleDeleteRegistry(registry) { handleDeleteRegistry(registry) {
this.deleteRegistry(registry) this.deleteRegistry(registry)
.then(() => this.fetchList({ repo: this.repo })) .then(() => this.fetchList({ repo: this.repo }))
.catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY)); .catch(() => this.showError(errorMessagesTypes.DELETE_REGISTRY));
}, },
onPageChange(pageNumber) { onPageChange(pageNumber) {
this.fetchList({ repo: this.repo, page: pageNumber }) this.fetchList({ repo: this.repo, page: pageNumber }).catch(() =>
.catch(() => this.showError(errorMessagesTypes.FETCH_REGISTRY)); this.showError(errorMessagesTypes.FETCH_REGISTRY),
}, );
},
showError(message) { showError(message) {
Flash(errorMessages[message]); Flash(errorMessages[message]);
},
}, },
}; },
};
</script> </script>
<template> <template>
<div> <div>
......
...@@ -4,22 +4,23 @@ import Translate from '../vue_shared/translate'; ...@@ -4,22 +4,23 @@ import Translate from '../vue_shared/translate';
Vue.use(Translate); Vue.use(Translate);
export default () => new Vue({ export default () =>
el: '#js-vue-registry-images', new Vue({
components: { el: '#js-vue-registry-images',
registryApp, components: {
}, registryApp,
data() { },
const { dataset } = document.querySelector(this.$options.el); data() {
return { const { dataset } = document.querySelector(this.$options.el);
endpoint: dataset.endpoint, return {
}; endpoint: dataset.endpoint,
}, };
render(createElement) { },
return createElement('registry-app', { render(createElement) {
props: { return createElement('registry-app', {
endpoint: this.endpoint, props: {
}, endpoint: this.endpoint,
}); },
}, });
}); },
});
...@@ -2,7 +2,6 @@ import * as types from './mutation_types'; ...@@ -2,7 +2,6 @@ import * as types from './mutation_types';
import { parseIntPagination, normalizeHeaders } from '../../lib/utils/common_utils'; import { parseIntPagination, normalizeHeaders } from '../../lib/utils/common_utils';
export default { export default {
[types.SET_MAIN_ENDPOINT](state, endpoint) { [types.SET_MAIN_ENDPOINT](state, endpoint) {
Object.assign(state, { endpoint }); Object.assign(state, { endpoint });
}, },
......
<script> <script>
import { mapActions, mapGetters, mapState } from 'vuex'; import { mapActions, mapGetters, mapState } from 'vuex';
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import { componentNames } from './issue_body'; import { componentNames } from './issue_body';
import ReportSection from './report_section.vue'; import ReportSection from './report_section.vue';
import SummaryRow from './summary_row.vue'; import SummaryRow from './summary_row.vue';
import IssuesList from './issues_list.vue'; import IssuesList from './issues_list.vue';
import Modal from './modal.vue'; import Modal from './modal.vue';
import createStore from '../store'; import createStore from '../store';
import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils'; import { summaryTextBuilder, reportTextBuilder, statusIcon } from '../store/utils';
export default { export default {
name: 'GroupedTestReportsApp', name: 'GroupedTestReportsApp',
store: createStore(), store: createStore(),
components: { components: {
ReportSection, ReportSection,
SummaryRow, SummaryRow,
IssuesList, IssuesList,
Modal, Modal,
},
props: {
endpoint: {
type: String,
required: true,
}, },
props: { },
endpoint: { componentNames,
type: String, computed: {
required: true, ...mapState(['reports', 'isLoading', 'hasError', 'summary']),
}, ...mapState({
}, modalTitle: state => state.modal.title || '',
componentNames, modalData: state => state.modal.data || {},
computed: { }),
...mapState([ ...mapGetters(['summaryStatus']),
'reports', groupedSummaryText() {
'isLoading', if (this.isLoading) {
'hasError', return s__('Reports|Test summary results are being parsed');
'summary', }
]),
...mapState({
modalTitle: state => state.modal.title || '',
modalData: state => state.modal.data || {},
}),
...mapGetters([
'summaryStatus',
]),
groupedSummaryText() {
if (this.isLoading) {
return s__('Reports|Test summary results are being parsed');
}
if (this.hasError) { if (this.hasError) {
return s__('Reports|Test summary failed loading results'); return s__('Reports|Test summary failed loading results');
} }
return summaryTextBuilder(s__('Reports|Test summary'), this.summary); return summaryTextBuilder(s__('Reports|Test summary'), this.summary);
},
}, },
created() { },
this.setEndpoint(this.endpoint); created() {
this.setEndpoint(this.endpoint);
this.fetchReports(); this.fetchReports();
},
methods: {
...mapActions(['setEndpoint', 'fetchReports']),
reportText(report) {
const summary = report.summary || {};
return reportTextBuilder(report.name, summary);
},
getReportIcon(report) {
return statusIcon(report.status);
}, },
methods: { shouldRenderIssuesList(report) {
...mapActions(['setEndpoint', 'fetchReports']), return (
reportText(report) { report.existing_failures.length > 0 ||
const summary = report.summary || {}; report.new_failures.length > 0 ||
return reportTextBuilder(report.name, summary); report.resolved_failures.length > 0
}, );
getReportIcon(report) {
return statusIcon(report.status);
},
shouldRenderIssuesList(report) {
return (
report.existing_failures.length > 0 ||
report.new_failures.length > 0 ||
report.resolved_failures.length > 0
);
},
}, },
}; },
};
</script> </script>
<template> <template>
<report-section <report-section
......
<script> <script>
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import { import { STATUS_FAILED, STATUS_NEUTRAL, STATUS_SUCCESS } from '../constants';
STATUS_FAILED,
STATUS_NEUTRAL,
STATUS_SUCCESS,
} from '../constants';
export default { export default {
name: 'IssueStatusIcon', name: 'IssueStatusIcon',
......
<script> <script>
import IssuesBlock from '~/reports/components/report_issues.vue'; import IssuesBlock from '~/reports/components/report_issues.vue';
import { import { STATUS_SUCCESS, STATUS_FAILED, STATUS_NEUTRAL } from '~/reports/constants';
STATUS_SUCCESS,
STATUS_FAILED,
STATUS_NEUTRAL,
} from '~/reports/constants';
/** /**
* Renders block of issues * Renders block of issues
......
<script> <script>
import Modal from '~/vue_shared/components/gl_modal.vue'; import Modal from '~/vue_shared/components/gl_modal.vue';
import LoadingButton from '~/vue_shared/components/loading_button.vue'; import LoadingButton from '~/vue_shared/components/loading_button.vue';
import CodeBlock from '~/vue_shared/components/code_block.vue'; import CodeBlock from '~/vue_shared/components/code_block.vue';
import { fieldTypes } from '../constants'; import { fieldTypes } from '../constants';
export default { export default {
components: { components: {
Modal, Modal,
LoadingButton, LoadingButton,
CodeBlock, CodeBlock,
},
props: {
title: {
type: String,
required: true,
}, },
props: { modalData: {
title: { type: Object,
type: String, required: true,
required: true,
},
modalData: {
type: Object,
required: true,
},
}, },
fieldTypes, },
}; fieldTypes,
};
</script> </script>
<template> <template>
<modal <modal
......
<script> <script>
import { mapActions } from 'vuex'; import { mapActions } from 'vuex';
export default { export default {
name: 'TestIssueBody', name: 'TestIssueBody',
props: { props: {
issue: { issue: {
type: Object, type: Object,
required: true, required: true,
},
// failed || success
status: {
type: String,
required: true,
},
isNew: {
type: Boolean,
required: false,
default: false,
},
}, },
methods: { // failed || success
...mapActions(['openModal']), status: {
type: String,
required: true,
}, },
}; isNew: {
type: Boolean,
required: false,
default: false,
},
},
methods: {
...mapActions(['openModal']),
},
};
</script> </script>
<template> <template>
<div class="report-block-list-issue-description prepend-top-5 append-bottom-5"> <div class="report-block-list-issue-description prepend-top-5 append-bottom-5">
......
...@@ -43,9 +43,11 @@ export const fetchReports = ({ state, dispatch }) => { ...@@ -43,9 +43,11 @@ export const fetchReports = ({ state, dispatch }) => {
}, },
data: state.endpoint, data: state.endpoint,
method: 'getReports', method: 'getReports',
successCallback: ({ data, status }) => dispatch('receiveReportsSuccess', { successCallback: ({ data, status }) =>
data, status, dispatch('receiveReportsSuccess', {
}), data,
status,
}),
errorCallback: () => dispatch('receiveReportsError'), errorCallback: () => dispatch('receiveReportsError'),
}); });
......
...@@ -7,9 +7,10 @@ import state from './state'; ...@@ -7,9 +7,10 @@ import state from './state';
Vue.use(Vuex); Vue.use(Vuex);
export default () => new Vuex.Store({ export default () =>
actions, new Vuex.Store({
mutations, actions,
getters, mutations,
state: state(), getters,
}); state: state(),
});
...@@ -4,4 +4,3 @@ export const REQUEST_REPORTS = 'REQUEST_REPORTS'; ...@@ -4,4 +4,3 @@ export const REQUEST_REPORTS = 'REQUEST_REPORTS';
export const RECEIVE_REPORTS_SUCCESS = 'RECEIVE_REPORTS_SUCCESS'; export const RECEIVE_REPORTS_SUCCESS = 'RECEIVE_REPORTS_SUCCESS';
export const RECEIVE_REPORTS_ERROR = 'RECEIVE_REPORTS_ERROR'; export const RECEIVE_REPORTS_ERROR = 'RECEIVE_REPORTS_ERROR';
export const SET_ISSUE_MODAL_DATA = 'SET_ISSUE_MODAL_DATA'; export const SET_ISSUE_MODAL_DATA = 'SET_ISSUE_MODAL_DATA';
...@@ -19,7 +19,6 @@ export default { ...@@ -19,7 +19,6 @@ export default {
state.status = response.status; state.status = response.status;
state.reports = response.suites; state.reports = response.suites;
}, },
[types.RECEIVE_REPORTS_ERROR](state) { [types.RECEIVE_REPORTS_ERROR](state) {
state.isLoading = false; state.isLoading = false;
...@@ -36,7 +35,7 @@ export default { ...@@ -36,7 +35,7 @@ export default {
[types.SET_ISSUE_MODAL_DATA](state, payload) { [types.SET_ISSUE_MODAL_DATA](state, payload) {
state.modal.title = payload.issue.name; state.modal.title = payload.issue.name;
Object.keys(payload.issue).forEach((key) => { Object.keys(payload.issue).forEach(key => {
if (Object.prototype.hasOwnProperty.call(state.modal.data, key)) { if (Object.prototype.hasOwnProperty.call(state.modal.data, key)) {
state.modal.data[key] = { state.modal.data[key] = {
...state.modal.data[key], ...state.modal.data[key],
......
...@@ -57,5 +57,4 @@ export default () => ({ ...@@ -57,5 +57,4 @@ export default () => ({
}, },
}, },
}, },
}); });
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