Commit 7c7f5266 authored by Filipa Lacerda's avatar Filipa Lacerda

[ci skip] Fix more rules

parent 1525b005
...@@ -89,6 +89,7 @@ export default { ...@@ -89,6 +89,7 @@ export default {
:issue="issue" :issue="issue"
:issue-link-base="issueLinkBase" :issue-link-base="issueLinkBase"
:root-path="rootPath" :root-path="rootPath"
:update-filters="true" /> :update-filters="true"
/>
</li> </li>
</template> </template>
...@@ -77,12 +77,12 @@ which incur additional costs. See %{pricingLink}`)), ...@@ -77,12 +77,12 @@ which incur additional costs. See %{pricingLink}`)),
return sprintf( return sprintf(
_.escape(s__(`ClusterIntegration|Prometheus is an open-source monitoring system _.escape(s__(`ClusterIntegration|Prometheus is an open-source monitoring system
with %{gitlabIntegrationLink} to monitor deployed applications.`)), with %{gitlabIntegrationLink} to monitor deployed applications.`)),
{ {
gitlabIntegrationLink: `<a href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html" gitlabIntegrationLink: `<a href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html"
target="_blank" rel="noopener noreferrer"> target="_blank" rel="noopener noreferrer">
${_.escape(s__('ClusterIntegration|Gitlab Integration'))} ${_.escape(s__('ClusterIntegration|Gitlab Integration'))}
</a>`, </a>`,
}, },
false, false,
); );
}, },
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
props: { props: {
items: { items: {
type: Array, type: Array,
default: [] default: () => [],
}, },
stage: { stage: {
type: Object, type: Object,
......
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
props: { props: {
items: { items: {
type: Array, type: Array,
default: [] default: () => [],
}, },
stage: { stage: {
type: Object, type: Object,
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
props: { props: {
items: { items: {
type: Array, type: Array,
default: [] default: () => [],
}, },
stage: { stage: {
type: Object, type: Object,
...@@ -81,8 +81,7 @@ ...@@ -81,8 +81,7 @@
name="fork" name="fork"
:size="16" :size="16"
/> />
<a <a :href="mergeRequest.branch.url">
:href="mergeRequest.branch.url">
{{ mergeRequest.branch.name }} {{ mergeRequest.branch.name }}
</a> </a>
</span> </span>
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
props: { props: {
items: { items: {
type: Array, type: Array,
default: [] default: () => [],
}, },
stage: { stage: {
type: Object, type: Object,
...@@ -69,7 +69,7 @@ ...@@ -69,7 +69,7 @@
<a <a
:href="build.commitUrl" :href="build.commitUrl"
class="commit-sha" class="commit-sha"
> >
{{ build.shortSha }} {{ build.shortSha }}
</a> </a>
</h5> </h5>
...@@ -77,7 +77,7 @@ ...@@ -77,7 +77,7 @@
<a <a
:href="build.url" :href="build.url"
class="build-date" class="build-date"
> >
{{ build.date }} {{ build.date }}
</a> </a>
{{ s__('ByAuthor|by') }} {{ s__('ByAuthor|by') }}
......
...@@ -6,15 +6,21 @@ ...@@ -6,15 +6,21 @@
import icon from '../../vue_shared/components/icon.vue'; import icon from '../../vue_shared/components/icon.vue';
export default { export default {
props: {
items: Array,
stage: Object,
},
components: { components: {
totalTime, totalTime,
limitWarning, limitWarning,
icon, icon,
}, },
props: {
items: {
type: Array,
default: () => [],
},
stage: {
type: Object,
default: () => ({}),
},
},
computed: { computed: {
iconBuildStatus() { iconBuildStatus() {
return iconBuildStatus; return iconBuildStatus;
...@@ -35,29 +41,59 @@ ...@@ -35,29 +41,59 @@
<li <li
v-for="(build, i) in items" v-for="(build, i) in items"
:key="i" :key="i"
class="stage-event-item item-build-component"> class="stage-event-item item-build-component"
>
<div class="item-details"> <div class="item-details">
<h5 class="item-title"> <h5 class="item-title">
<span class="icon-build-status" v-html="iconBuildStatus"></span> <span
<a :href="build.url" class="item-build-name">{{ build.name }}</a> class="icon-build-status"
v-html="iconBuildStatus"
>
</span>
<a
:href="build.url"
class="item-build-name"
>
{{ build.name }}
</a>
&middot; &middot;
<a :href="build.url" class="pipeline-id">#{{ build.id }}</a> <a
:href="build.url"
class="pipeline-id"
>
#{{ build.id }}
</a>
<icon <icon
name="fork" name="fork"
:size="16"> :size="16"
</icon> />
<a :href="build.branch.url" class="ref-name">{{ build.branch.name }}</a> <a
<span class="icon-branch" v-html="iconBranch"></span> :href="build.branch.url"
<a :href="build.commitUrl" class="commit-sha">{{ build.shortSha }}</a> class="ref-name"
>
{{ build.branch.name }}
</a>
<span
class="icon-branch"
v-html="iconBranch"
>
</span>
<a
:href="build.commitUrl"
class="commit-sha">
{{ build.shortSha }}
</a>
</h5> </h5>
<span> <span>
<a :href="build.url" class="issue-date"> <a
:href="build.url"
class="issue-date">
{{ build.date }} {{ build.date }}
</a> </a>
</span> </span>
</div> </div>
<div class="item-time"> <div class="item-time">
<total-time :time="build.totalTime"/> <total-time :time="build.totalTime" />
</div> </div>
</li> </li>
</ul> </ul>
......
...@@ -17,10 +17,30 @@ ...@@ -17,10 +17,30 @@
<template> <template>
<span class="total-time"> <span class="total-time">
<template v-if="hasData"> <template v-if="hasData">
<template v-if="time.days">{{ time.days }} <span>{{ n__('day', 'days', time.days) }}</span></template> <template v-if="time.days">
<template v-if="time.hours">{{ time.hours }} <span>{{ n__('Time|hr', 'Time|hrs', time.hours) }}</span></template> {{ time.days }}
<template v-if="time.mins && !time.days">{{ time.mins }} <span>{{ n__('Time|min', 'Time|mins', time.mins) }}</span></template> <span>
<template v-if="time.seconds && hasData === 1 || time.seconds === 0">{{ time.seconds }} <span>{{ s__('Time|s') }}</span></template> {{ n__('day', 'days', time.days) }}
</span>
</template>
<template v-if="time.hours">
{{ time.hours }}
<span>
{{ n__('Time|hr', 'Time|hrs', time.hours) }}
</span>
</template>
<template v-if="time.mins && !time.days">
{{ time.mins }}
<span>
{{ n__('Time|min', 'Time|mins', time.mins) }}
</span>
</template>
<template v-if="time.seconds && hasData === 1 || time.seconds === 0">
{{ time.seconds }}
<span>
{{ s__('Time|s') }}
</span>
</template>
</template> </template>
<template v-else> <template v-else>
-- --
......
...@@ -3,10 +3,8 @@ ...@@ -3,10 +3,8 @@
import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import loadingIcon from '../../vue_shared/components/loading_icon.vue';
export default { export default {
data() { components: {
return { loadingIcon,
isLoading: false,
};
}, },
props: { props: {
deployKey: { deployKey: {
...@@ -23,11 +21,16 @@ ...@@ -23,11 +21,16 @@
default: 'btn-default', default: 'btn-default',
}, },
}, },
data() {
components: { return {
loadingIcon, isLoading: false,
};
},
computed: {
text() {
return `${this.type.charAt(0).toUpperCase()}${this.type.slice(1)}`;
},
}, },
methods: { methods: {
doAction() { doAction() {
this.isLoading = true; this.isLoading = true;
...@@ -37,11 +40,6 @@ ...@@ -37,11 +40,6 @@
}); });
}, },
}, },
computed: {
text() {
return `${this.type.charAt(0).toUpperCase()}${this.type.slice(1)}`;
},
},
}; };
</script> </script>
......
...@@ -7,11 +7,9 @@ ...@@ -7,11 +7,9 @@
import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import loadingIcon from '../../vue_shared/components/loading_icon.vue';
export default { export default {
data() { components: {
return { keysPanel,
isLoading: false, loadingIcon,
store: new DeployKeysStore(),
};
}, },
props: { props: {
endpoint: { endpoint: {
...@@ -19,6 +17,12 @@ ...@@ -19,6 +17,12 @@
required: true, required: true,
}, },
}, },
data() {
return {
isLoading: false,
store: new DeployKeysStore(),
};
},
computed: { computed: {
hasKeys() { hasKeys() {
return Object.keys(this.keys).length; return Object.keys(this.keys).length;
...@@ -27,9 +31,20 @@ ...@@ -27,9 +31,20 @@
return this.store.keys; return this.store.keys;
}, },
}, },
components: { created() {
keysPanel, this.service = new DeployKeysService(this.endpoint);
loadingIcon,
eventHub.$on('enable.key', this.enableKey);
eventHub.$on('remove.key', this.disableKey);
eventHub.$on('disable.key', this.disableKey);
},
mounted() {
this.fetchKeys();
},
beforeDestroy() {
eventHub.$off('enable.key', this.enableKey);
eventHub.$off('remove.key', this.disableKey);
eventHub.$off('disable.key', this.disableKey);
}, },
methods: { methods: {
fetchKeys() { fetchKeys() {
...@@ -59,21 +74,6 @@ ...@@ -59,21 +74,6 @@
} }
}, },
}, },
created() {
this.service = new DeployKeysService(this.endpoint);
eventHub.$on('enable.key', this.enableKey);
eventHub.$on('remove.key', this.disableKey);
eventHub.$on('disable.key', this.disableKey);
},
mounted() {
this.fetchKeys();
},
beforeDestroy() {
eventHub.$off('enable.key', this.enableKey);
eventHub.$off('remove.key', this.disableKey);
eventHub.$off('disable.key', this.disableKey);
},
}; };
</script> </script>
......
...@@ -3,6 +3,9 @@ ...@@ -3,6 +3,9 @@
import { getTimeago } from '../../lib/utils/datetime_utility'; import { getTimeago } from '../../lib/utils/datetime_utility';
export default { export default {
components: {
actionBtn,
},
props: { props: {
deployKey: { deployKey: {
type: Object, type: Object,
...@@ -17,9 +20,6 @@ ...@@ -17,9 +20,6 @@
required: true, required: true,
}, },
}, },
components: {
actionBtn,
},
computed: { computed: {
timeagoDate() { timeagoDate() {
return getTimeago().format(this.deployKey.created_at); return getTimeago().format(this.deployKey.created_at);
...@@ -61,9 +61,10 @@ ...@@ -61,9 +61,10 @@
</div> </div>
<div class="deploy-key-content prepend-left-default deploy-key-projects"> <div class="deploy-key-content prepend-left-default deploy-key-projects">
<a <a
v-for="project in deployKey.projects" v-for="(project, i) in deployKey.projects"
class="label deploy-project-label" class="label deploy-project-label"
:href="project.full_path" :href="project.full_path"
:key="i"
> >
{{ project.full_name }} {{ project.full_name }}
</a> </a>
......
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
import key from './key.vue'; import key from './key.vue';
export default { export default {
components: {
key,
},
props: { props: {
title: { title: {
type: String, type: String,
...@@ -25,9 +28,6 @@ ...@@ -25,9 +28,6 @@
required: true, required: true,
}, },
}, },
components: {
key,
},
}; };
</script> </script>
...@@ -37,12 +37,14 @@ ...@@ -37,12 +37,14 @@
{{ title }} {{ title }}
({{ keys.length }}) ({{ keys.length }})
</h5> </h5>
<ul class="well-list" <ul
class="well-list"
v-if="keys.length" v-if="keys.length"
> >
<li <li
v-for="deployKey in keys" v-for="deployKey in keys"
:key="deployKey.id"> :key="deployKey.id"
>
<key <key
:deploy-key="deployKey" :deploy-key="deployKey"
:store="store" :store="store"
......
...@@ -4,6 +4,11 @@ ...@@ -4,6 +4,11 @@
import environmentTable from '../components/environments_table.vue'; import environmentTable from '../components/environments_table.vue';
export default { export default {
components: {
environmentTable,
loadingIcon,
tablePagination,
},
props: { props: {
isLoading: { isLoading: {
type: Boolean, type: Boolean,
...@@ -26,12 +31,6 @@ ...@@ -26,12 +31,6 @@
required: true, required: true,
}, },
}, },
components: {
environmentTable,
loadingIcon,
tablePagination,
},
methods: { methods: {
onChangePage(page) { onChangePage(page) {
this.$emit('onChangePage', page); this.$emit('onChangePage', page);
...@@ -47,7 +46,7 @@ ...@@ -47,7 +46,7 @@
label="Loading environments" label="Loading environments"
v-if="isLoading" v-if="isLoading"
size="3" size="3"
/> />
<slot name="emptyState"></slot> <slot name="emptyState"></slot>
...@@ -59,13 +58,13 @@ ...@@ -59,13 +58,13 @@
:environments="environments" :environments="environments"
:can-create-deployment="canCreateDeployment" :can-create-deployment="canCreateDeployment"
:can-read-environment="canReadEnvironment" :can-read-environment="canReadEnvironment"
/> />
<table-pagination <table-pagination
v-if="pagination && pagination.totalPages > 1" v-if="pagination && pagination.totalPages > 1"
:change="onChangePage" :change="onChangePage"
:pageInfo="pagination" :page-info="pagination"
/> />
</div> </div>
</div> </div>
</template> </template>
<script> <script>
export default { export default {
name: 'environmentsEmptyState', name: 'EnvironmentsEmptyState',
props: { props: {
newPath: { newPath: {
type: String, type: String,
...@@ -21,21 +21,22 @@ ...@@ -21,21 +21,22 @@
<div class="blank-state-row"> <div class="blank-state-row">
<div class="blank-state-center"> <div class="blank-state-center">
<h2 class="blank-state-title js-blank-state-title"> <h2 class="blank-state-title js-blank-state-title">
{{s__("Environments|You don't have any environments right now.")}} {{ s__("Environments|You don't have any environments right now.") }}
</h2> </h2>
<p class="blank-state-text"> <p class="blank-state-text">
{{s__("Environments|Environments are places where code gets deployed, such as staging or production.")}} {{ s__("Environments|Environments are places where code gets deployed, such as staging or production.") }}
<br /> <br />
<a :href="helpPath"> <a :href="helpPath">
{{s__("Environments|Read more about environments")}} {{ s__("Environments|Read more about environments") }}
</a> </a>
</p> </p>
<a <a
v-if="canCreateEnvironment" v-if="canCreateEnvironment"
:href="newPath" :href="newPath"
class="btn btn-create js-new-environment-button"> class="btn btn-create js-new-environment-button"
{{s__("Environments|New environment")}} >
{{ s__("Environments|New environment") }}
</a> </a>
</div> </div>
</div> </div>
......
<script> <script>
import playIconSvg from 'icons/_icon_play.svg'; import playIconSvg from 'icons/_icon_play.svg';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import loadingIcon from '../../vue_shared/components/loading_icon.vue'; import loadingIcon from '../../vue_shared/components/loading_icon.vue';
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
export default { export default {
props: { directives: {
actions: { tooltip,
type: Array,
required: false,
default: () => [],
}, },
},
directives: { components: {
tooltip, loadingIcon,
}, },
props: {
components: { actions: {
loadingIcon, type: Array,
}, required: false,
default: () => [],
},
},
data() { data() {
return { return {
playIconSvg, playIconSvg,
isLoading: false, isLoading: false,
}; };
}, },
computed: { computed: {
title() { title() {
return 'Deploy to...'; return 'Deploy to...';
},
}, },
},
methods: { methods: {
onClickAction(endpoint) { onClickAction(endpoint) {
this.isLoading = true; this.isLoading = true;
eventHub.$emit('postAction', endpoint); eventHub.$emit('postAction', endpoint);
}, },
isActionDisabled(action) { isActionDisabled(action) {
if (action.playable === undefined) { if (action.playable === undefined) {
return false; return false;
} }
return !action.playable; return !action.playable;
},
}, },
}, };
};
</script> </script>
<template> <template>
<div <div
...@@ -63,27 +62,32 @@ export default { ...@@ -63,27 +62,32 @@ export default {
data-toggle="dropdown" data-toggle="dropdown"
:title="title" :title="title"
:aria-label="title" :aria-label="title"
:disabled="isLoading"> :disabled="isLoading"
>
<span> <span>
<span v-html="playIconSvg"></span> <span v-html="playIconSvg"></span>
<i <i
class="fa fa-caret-down" class="fa fa-caret-down"
aria-hidden="true"/> aria-hidden="true"
/>
<loading-icon v-if="isLoading" /> <loading-icon v-if="isLoading" />
</span> </span>
</button> </button>
<ul class="dropdown-menu dropdown-menu-align-right"> <ul class="dropdown-menu dropdown-menu-align-right">
<li v-for="action in actions"> <li
v-for="(action, i) in actions"
:key="i">
<button <button
type="button" type="button"
class="js-manual-action-link no-btn btn" class="js-manual-action-link no-btn btn"
@click="onClickAction(action.play_path)" @click="onClickAction(action.play_path)"
:class="{ disabled: isActionDisabled(action) }" :class="{ disabled: isActionDisabled(action) }"
:disabled="isActionDisabled(action)"> :disabled="isActionDisabled(action)"
>
<span v-html="playIconSvg"></span> <span v-html="playIconSvg"></span>
<span> <span>
{{action.name}} {{ action.name }}
</span> </span>
</button> </button>
</li> </li>
......
<script> <script>
import tooltip from '../../vue_shared/directives/tooltip'; import tooltip from '../../vue_shared/directives/tooltip';
import { s__ } from '../../locale'; import { s__ } from '../../locale';
/** /**
* Renders the external url link in environments table. * Renders the external url link in environments table.
*/ */
export default { export default {
props: { directives: {
externalUrl: { tooltip,
type: String, },
required: true, props: {
externalUrl: {
type: String,
required: true,
},
}, },
},
directives: {
tooltip,
},
computed: { computed: {
title() { title() {
return s__('Environments|Open'); return s__('Environments|Open');
},
}, },
}, };
};
</script> </script>
<template> <template>
<a <a
...@@ -33,9 +32,12 @@ export default { ...@@ -33,9 +32,12 @@ export default {
rel="noopener noreferrer nofollow" rel="noopener noreferrer nofollow"
:title="title" :title="title"
:aria-label="title" :aria-label="title"
:href="externalUrl"> :href="externalUrl"
>
<i <i
class="fa fa-external-link" class="fa fa-external-link"
aria-hidden="true" /> aria-hidden="true"
>
</i>
</a> </a>
</template> </template>
<script> <script>
import Timeago from 'timeago.js'; import Timeago from 'timeago.js';
import _ from 'underscore'; import _ from 'underscore';
import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue';
import { humanize } from '../../lib/utils/text_utility'; import { humanize } from '../../lib/utils/text_utility';
import ActionsComponent from './environment_actions.vue'; import ActionsComponent from './environment_actions.vue';
import ExternalUrlComponent from './environment_external_url.vue'; import ExternalUrlComponent from './environment_external_url.vue';
import StopComponent from './environment_stop.vue'; import StopComponent from './environment_stop.vue';
import RollbackComponent from './environment_rollback.vue'; import RollbackComponent from './environment_rollback.vue';
import TerminalButtonComponent from './environment_terminal_button.vue'; import TerminalButtonComponent from './environment_terminal_button.vue';
import MonitoringButtonComponent from './environment_monitoring.vue'; import MonitoringButtonComponent from './environment_monitoring.vue';
import CommitComponent from '../../vue_shared/components/commit.vue'; import CommitComponent from '../../vue_shared/components/commit.vue';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
/** /**
* Envrionment Item Component * Envrionment Item Component
* *
* Renders a table row for each environment. * Renders a table row for each environment.
*/ */
const timeagoInstance = new Timeago(); const timeagoInstance = new Timeago();
export default { export default {
components: { components: {
userAvatarLink, userAvatarLink,
'commit-component': CommitComponent, 'commit-component': CommitComponent,
'actions-component': ActionsComponent, 'actions-component': ActionsComponent,
'external-url-component': ExternalUrlComponent, 'external-url-component': ExternalUrlComponent,
'stop-component': StopComponent, 'stop-component': StopComponent,
'rollback-component': RollbackComponent, 'rollback-component': RollbackComponent,
'terminal-button-component': TerminalButtonComponent, 'terminal-button-component': TerminalButtonComponent,
'monitoring-button-component': MonitoringButtonComponent, 'monitoring-button-component': MonitoringButtonComponent,
},
props: {
model: {
type: Object,
required: true,
default: () => ({}),
}, },
canCreateDeployment: { props: {
type: Boolean, model: {
required: false, type: Object,
default: false, required: true,
default: () => ({}),
},
canCreateDeployment: {
type: Boolean,
required: false,
default: false,
},
canReadEnvironment: {
type: Boolean,
required: false,
default: false,
},
}, },
canReadEnvironment: { computed: {
type: Boolean, /**
required: false, * Verifies if `last_deployment` key exists in the current Envrionment.
default: false, * This key is required to render most of the html - this method works has
}, * an helper.
}, *
* @returns {Boolean}
computed: { */
/** hasLastDeploymentKey() {
* Verifies if `last_deployment` key exists in the current Envrionment. if (this.model &&
* This key is required to render most of the html - this method works has this.model.last_deployment &&
* an helper. !_.isEmpty(this.model.last_deployment)) {
* return true;
* @returns {Boolean} }
*/ return false;
hasLastDeploymentKey() { },
if (this.model &&
this.model.last_deployment && /**
!_.isEmpty(this.model.last_deployment)) { * Verifies is the given environment has manual actions.
return true; * Used to verify if we should render them or nor.
} *
return false; * @returns {Boolean|Undefined}
}, */
hasManualActions() {
/** return this.model &&
* Verifies is the given environment has manual actions. this.model.last_deployment &&
* Used to verify if we should render them or nor. this.model.last_deployment.manual_actions &&
* this.model.last_deployment.manual_actions.length > 0;
* @returns {Boolean|Undefined} },
*/
hasManualActions() { /**
return this.model && * Returns the value of the `stop_action?` key provided in the response.
this.model.last_deployment && *
this.model.last_deployment.manual_actions && * @returns {Boolean}
this.model.last_deployment.manual_actions.length > 0; */
}, hasStopAction() {
return this.model && this.model['stop_action?'];
/** },
* Returns the value of the `stop_action?` key provided in the response.
* /**
* @returns {Boolean} * Verifies if the `deployable` key is present in `last_deployment` key.
*/ * Used to verify whether we should or not render the rollback partial.
hasStopAction() { *
return this.model && this.model['stop_action?']; * @returns {Boolean|Undefined}
}, */
canRetry() {
/** return this.model &&
* Verifies if the `deployable` key is present in `last_deployment` key. this.hasLastDeploymentKey &&
* Used to verify whether we should or not render the rollback partial. this.model.last_deployment &&
* this.model.last_deployment.deployable;
* @returns {Boolean|Undefined} },
*/
canRetry() { /**
return this.model && * Verifies if the date to be shown is present.
this.hasLastDeploymentKey && *
this.model.last_deployment && * @returns {Boolean|Undefined}
this.model.last_deployment.deployable; */
}, canShowDate() {
return this.model &&
/** this.model.last_deployment &&
* Verifies if the date to be shown is present. this.model.last_deployment.deployable &&
* this.model.last_deployment.deployable !== undefined;
* @returns {Boolean|Undefined} },
*/
canShowDate() { /**
return this.model && * Human readable date.
this.model.last_deployment && *
this.model.last_deployment.deployable && * @returns {String}
this.model.last_deployment.deployable !== undefined; */
}, createdDate() {
if (this.model &&
/** this.model.last_deployment &&
* Human readable date. this.model.last_deployment.deployable &&
* this.model.last_deployment.deployable.created_at) {
* @returns {String} return timeagoInstance.format(this.model.last_deployment.deployable.created_at);
*/ }
createdDate() { return '';
if (this.model && },
this.model.last_deployment &&
this.model.last_deployment.deployable && /**
this.model.last_deployment.deployable.created_at) { * Returns the manual actions with the name parsed.
return timeagoInstance.format(this.model.last_deployment.deployable.created_at); *
} * @returns {Array.<Object>|Undefined}
return ''; */
}, manualActions() {
if (this.hasManualActions) {
/** return this.model.last_deployment.manual_actions.map((action) => {
* Returns the manual actions with the name parsed. const parsedAction = {
* name: humanize(action.name),
* @returns {Array.<Object>|Undefined} play_path: action.play_path,
*/ playable: action.playable,
manualActions() { };
if (this.hasManualActions) { return parsedAction;
return this.model.last_deployment.manual_actions.map((action) => { });
const parsedAction = { }
name: humanize(action.name), return [];
play_path: action.play_path, },
playable: action.playable,
}; /**
return parsedAction; * Builds the string used in the user image alt attribute.
}); *
} * @returns {String}
return []; */
}, userImageAltDescription() {
if (this.model &&
/** this.model.last_deployment &&
* Builds the string used in the user image alt attribute. this.model.last_deployment.user &&
* this.model.last_deployment.user.username) {
* @returns {String} return `${this.model.last_deployment.user.username}'s avatar'`;
*/ }
userImageAltDescription() { return '';
if (this.model && },
this.model.last_deployment &&
this.model.last_deployment.user && /**
this.model.last_deployment.user.username) { * If provided, returns the commit tag.
return `${this.model.last_deployment.user.username}'s avatar'`; *
} * @returns {String|Undefined}
return ''; */
}, commitTag() {
if (this.model &&
/** this.model.last_deployment &&
* If provided, returns the commit tag. this.model.last_deployment.tag) {
* return this.model.last_deployment.tag;
* @returns {String|Undefined} }
*/ return undefined;
commitTag() { },
if (this.model &&
this.model.last_deployment && /**
this.model.last_deployment.tag) { * If provided, returns the commit ref.
return this.model.last_deployment.tag; *
} * @returns {Object|Undefined}
return undefined; */
}, commitRef() {
if (this.model &&
/** this.model.last_deployment &&
* If provided, returns the commit ref. this.model.last_deployment.ref) {
* return this.model.last_deployment.ref;
* @returns {Object|Undefined} }
*/ return undefined;
commitRef() { },
if (this.model &&
this.model.last_deployment && /**
this.model.last_deployment.ref) { * If provided, returns the commit url.
return this.model.last_deployment.ref; *
} * @returns {String|Undefined}
return undefined; */
}, commitUrl() {
if (this.model &&
/** this.model.last_deployment &&
* If provided, returns the commit url. this.model.last_deployment.commit &&
* this.model.last_deployment.commit.commit_path) {
* @returns {String|Undefined} return this.model.last_deployment.commit.commit_path;
*/ }
commitUrl() { return undefined;
if (this.model && },
this.model.last_deployment &&
this.model.last_deployment.commit && /**
this.model.last_deployment.commit.commit_path) { * If provided, returns the commit short sha.
return this.model.last_deployment.commit.commit_path; *
} * @returns {String|Undefined}
return undefined; */
}, commitShortSha() {
if (this.model &&
/** this.model.last_deployment &&
* If provided, returns the commit short sha. this.model.last_deployment.commit &&
* this.model.last_deployment.commit.short_id) {
* @returns {String|Undefined} return this.model.last_deployment.commit.short_id;
*/ }
commitShortSha() { return undefined;
if (this.model && },
this.model.last_deployment &&
this.model.last_deployment.commit && /**
this.model.last_deployment.commit.short_id) { * If provided, returns the commit title.
return this.model.last_deployment.commit.short_id; *
} * @returns {String|Undefined}
return undefined; */
}, commitTitle() {
if (this.model &&
/** this.model.last_deployment &&
* If provided, returns the commit title. this.model.last_deployment.commit &&
* this.model.last_deployment.commit.title) {
* @returns {String|Undefined} return this.model.last_deployment.commit.title;
*/ }
commitTitle() { return undefined;
if (this.model && },
this.model.last_deployment &&
this.model.last_deployment.commit && /**
this.model.last_deployment.commit.title) { * If provided, returns the commit tag.
return this.model.last_deployment.commit.title; *
} * @returns {Object|Undefined}
return undefined; */
}, commitAuthor() {
if (this.model &&
/** this.model.last_deployment &&
* If provided, returns the commit tag. this.model.last_deployment.commit &&
* this.model.last_deployment.commit.author) {
* @returns {Object|Undefined} return this.model.last_deployment.commit.author;
*/ }
commitAuthor() {
if (this.model && return undefined;
this.model.last_deployment && },
this.model.last_deployment.commit &&
this.model.last_deployment.commit.author) { /**
return this.model.last_deployment.commit.author; * Verifies if the `retry_path` key is present and returns its value.
} *
* @returns {String|Undefined}
return undefined; */
}, retryUrl() {
if (this.model &&
/** this.model.last_deployment &&
* Verifies if the `retry_path` key is present and returns its value. this.model.last_deployment.deployable &&
* this.model.last_deployment.deployable.retry_path) {
* @returns {String|Undefined} return this.model.last_deployment.deployable.retry_path;
*/ }
retryUrl() { return undefined;
if (this.model && },
this.model.last_deployment &&
this.model.last_deployment.deployable && /**
this.model.last_deployment.deployable.retry_path) { * Verifies if the `last?` key is present and returns its value.
return this.model.last_deployment.deployable.retry_path; *
} * @returns {Boolean|Undefined}
return undefined; */
}, isLastDeployment() {
return this.model && this.model.last_deployment &&
/** this.model.last_deployment['last?'];
* Verifies if the `last?` key is present and returns its value. },
*
* @returns {Boolean|Undefined} /**
*/ * Builds the name of the builds needed to display both the name and the id.
isLastDeployment() { *
return this.model && this.model.last_deployment && * @returns {String}
this.model.last_deployment['last?']; */
}, buildName() {
if (this.model &&
/** this.model.last_deployment &&
* Builds the name of the builds needed to display both the name and the id. this.model.last_deployment.deployable) {
* const deployable = this.model.last_deployment.deployable;
* @returns {String} return `${deployable.name} #${deployable.id}`;
*/ }
buildName() { return '';
if (this.model && },
this.model.last_deployment &&
this.model.last_deployment.deployable) { /**
const deployable = this.model.last_deployment.deployable; * Builds the needed string to show the internal id.
return `${deployable.name} #${deployable.id}`; *
} * @returns {String}
return ''; */
deploymentInternalId() {
if (this.model &&
this.model.last_deployment &&
this.model.last_deployment.iid) {
return `#${this.model.last_deployment.iid}`;
}
return '';
},
/**
* Verifies if the user object is present under last_deployment object.
*
* @returns {Boolean}
*/
deploymentHasUser() {
return this.model &&
!_.isEmpty(this.model.last_deployment) &&
!_.isEmpty(this.model.last_deployment.user);
},
/**
* Returns the user object nested with the last_deployment object.
* Used to render the template.
*
* @returns {Object}
*/
deploymentUser() {
if (this.model &&
!_.isEmpty(this.model.last_deployment) &&
!_.isEmpty(this.model.last_deployment.user)) {
return this.model.last_deployment.user;
}
return {};
},
/**
* Verifies if the build name column should be rendered by verifing
* if all the information needed is present
* and if the environment is not a folder.
*
* @returns {Boolean}
*/
shouldRenderBuildName() {
return !this.model.isFolder &&
!_.isEmpty(this.model.last_deployment) &&
!_.isEmpty(this.model.last_deployment.deployable);
},
/**
* Verifies the presence of all the keys needed to render the buil_path.
*
* @return {String}
*/
buildPath() {
if (this.model &&
this.model.last_deployment &&
this.model.last_deployment.deployable &&
this.model.last_deployment.deployable.build_path) {
return this.model.last_deployment.deployable.build_path;
}
return '';
},
/**
* Verifies the presence of all the keys needed to render the external_url.
*
* @return {String}
*/
externalURL() {
if (this.model && this.model.external_url) {
return this.model.external_url;
}
return '';
},
/**
* Verifies if deplyment internal ID should be rendered by verifing
* if all the information needed is present
* and if the environment is not a folder.
*
* @returns {Boolean}
*/
shouldRenderDeploymentID() {
return !this.model.isFolder &&
!_.isEmpty(this.model.last_deployment) &&
this.model.last_deployment.iid !== undefined;
},
environmentPath() {
if (this.model && this.model.environment_path) {
return this.model.environment_path;
}
return '';
},
monitoringUrl() {
if (this.model && this.model.metrics_path) {
return this.model.metrics_path;
}
return '';
},
displayEnvironmentActions() {
return this.hasManualActions ||
this.externalURL ||
this.monitoringUrl ||
this.hasStopAction ||
this.canRetry;
},
}, },
/** methods: {
* Builds the needed string to show the internal id. onClickFolder() {
* eventHub.$emit('toggleFolder', this.model);
* @returns {String} },
*/
deploymentInternalId() {
if (this.model &&
this.model.last_deployment &&
this.model.last_deployment.iid) {
return `#${this.model.last_deployment.iid}`;
}
return '';
}, },
};
/**
* Verifies if the user object is present under last_deployment object.
*
* @returns {Boolean}
*/
deploymentHasUser() {
return this.model &&
!_.isEmpty(this.model.last_deployment) &&
!_.isEmpty(this.model.last_deployment.user);
},
/**
* Returns the user object nested with the last_deployment object.
* Used to render the template.
*
* @returns {Object}
*/
deploymentUser() {
if (this.model &&
!_.isEmpty(this.model.last_deployment) &&
!_.isEmpty(this.model.last_deployment.user)) {
return this.model.last_deployment.user;
}
return {};
},
/**
* Verifies if the build name column should be rendered by verifing
* if all the information needed is present
* and if the environment is not a folder.
*
* @returns {Boolean}
*/
shouldRenderBuildName() {
return !this.model.isFolder &&
!_.isEmpty(this.model.last_deployment) &&
!_.isEmpty(this.model.last_deployment.deployable);
},
/**
* Verifies the presence of all the keys needed to render the buil_path.
*
* @return {String}
*/
buildPath() {
if (this.model &&
this.model.last_deployment &&
this.model.last_deployment.deployable &&
this.model.last_deployment.deployable.build_path) {
return this.model.last_deployment.deployable.build_path;
}
return '';
},
/**
* Verifies the presence of all the keys needed to render the external_url.
*
* @return {String}
*/
externalURL() {
if (this.model && this.model.external_url) {
return this.model.external_url;
}
return '';
},
/**
* Verifies if deplyment internal ID should be rendered by verifing
* if all the information needed is present
* and if the environment is not a folder.
*
* @returns {Boolean}
*/
shouldRenderDeploymentID() {
return !this.model.isFolder &&
!_.isEmpty(this.model.last_deployment) &&
this.model.last_deployment.iid !== undefined;
},
environmentPath() {
if (this.model && this.model.environment_path) {
return this.model.environment_path;
}
return '';
},
monitoringUrl() {
if (this.model && this.model.metrics_path) {
return this.model.metrics_path;
}
return '';
},
displayEnvironmentActions() {
return this.hasManualActions ||
this.externalURL ||
this.monitoringUrl ||
this.hasStopAction ||
this.canRetry;
},
},
methods: {
onClickFolder() {
eventHub.$emit('toggleFolder', this.model);
},
},
};
</script> </script>
<template> <template>
<div <div
...@@ -428,18 +428,22 @@ export default { ...@@ -428,18 +428,22 @@ export default {
'folder-row': model.isFolder, 'folder-row': model.isFolder,
}" }"
role="row"> role="row">
<div class="table-section section-10" role="gridcell"> <div
class="table-section section-10"
role="gridcell"
>
<div <div
v-if="!model.isFolder" v-if="!model.isFolder"
class="table-mobile-header" class="table-mobile-header"
role="rowheader"> role="rowheader"
{{s__("Environments|Environment")}} >
{{ s__("Environments|Environment") }}
</div> </div>
<a <a
v-if="!model.isFolder" v-if="!model.isFolder"
class="environment-name flex-truncate-parent table-mobile-content" class="environment-name flex-truncate-parent table-mobile-content"
:href="environmentPath"> :href="environmentPath">
<span class="flex-truncate-child">{{model.name}}</span> <span class="flex-truncate-child">{{ model.name }}</span>
</a> </a>
<span <span
v-else v-else
...@@ -451,17 +455,22 @@ export default { ...@@ -451,17 +455,22 @@ export default {
<i <i
v-show="model.isOpen" v-show="model.isOpen"
class="fa fa-caret-down" class="fa fa-caret-down"
aria-hidden="true" /> aria-hidden="true"
>
</i>
<i <i
v-show="!model.isOpen" v-show="!model.isOpen"
class="fa fa-caret-right" class="fa fa-caret-right"
aria-hidden="true"/> aria-hidden="true"
>
</i>
</span> </span>
<span class="folder-icon"> <span class="folder-icon">
<i <i
class="fa fa-folder" class="fa fa-folder"
aria-hidden="true" /> aria-hidden="true">
</i>
</span> </span>
<span> <span>
...@@ -491,22 +500,29 @@ export default { ...@@ -491,22 +500,29 @@ export default {
</span> </span>
</div> </div>
<div class="table-section section-15 hidden-xs hidden-sm" role="gridcell"> <div
class="table-section section-15 hidden-xs hidden-sm"
role="gridcell"
>
<a <a
v-if="shouldRenderBuildName" v-if="shouldRenderBuildName"
class="build-link flex-truncate-parent" class="build-link flex-truncate-parent"
:href="buildPath"> :href="buildPath"
<span class="flex-truncate-child">{{buildName}}</span> >
<span class="flex-truncate-child">{{ buildName }}</span>
</a> </a>
</div> </div>
<div <div
v-if="!model.isFolder" v-if="!model.isFolder"
class="table-section section-25" role="gridcell"> class="table-section section-25"
role="gridcell"
>
<div <div
role="rowheader" role="rowheader"
class="table-mobile-header"> class="table-mobile-header"
{{s__("Environments|Commit")}} >
{{ s__("Environments|Commit") }}
</div> </div>
<div <div
v-if="hasLastDeploymentKey" v-if="hasLastDeploymentKey"
...@@ -522,22 +538,24 @@ export default { ...@@ -522,22 +538,24 @@ export default {
<div <div
v-if="!hasLastDeploymentKey" v-if="!hasLastDeploymentKey"
class="commit-title table-mobile-content"> class="commit-title table-mobile-content">
{{s__("Environments|No deployments yet")}} {{ s__("Environments|No deployments yet") }}
</div> </div>
</div> </div>
<div <div
v-if="!model.isFolder" v-if="!model.isFolder"
class="table-section section-10" role="gridcell"> class="table-section section-10"
role="gridcell"
>
<div <div
role="rowheader" role="rowheader"
class="table-mobile-header"> class="table-mobile-header">
{{s__("Environments|Updated")}} {{ s__("Environments|Updated") }}
</div> </div>
<span <span
v-if="canShowDate" v-if="canShowDate"
class="environment-created-date-timeago table-mobile-content"> class="environment-created-date-timeago table-mobile-content">
{{createdDate}} {{ createdDate }}
</span> </span>
</div> </div>
...@@ -553,33 +571,33 @@ export default { ...@@ -553,33 +571,33 @@ export default {
<actions-component <actions-component
v-if="hasManualActions && canCreateDeployment" v-if="hasManualActions && canCreateDeployment"
:actions="manualActions" :actions="manualActions"
/> />
<external-url-component <external-url-component
v-if="externalURL && canReadEnvironment" v-if="externalURL && canReadEnvironment"
:external-url="externalURL" :external-url="externalURL"
/> />
<monitoring-button-component <monitoring-button-component
v-if="monitoringUrl && canReadEnvironment" v-if="monitoringUrl && canReadEnvironment"
:monitoring-url="monitoringUrl" :monitoring-url="monitoringUrl"
/> />
<terminal-button-component <terminal-button-component
v-if="model && model.terminal_path" v-if="model && model.terminal_path"
:terminal-path="model.terminal_path" :terminal-path="model.terminal_path"
/> />
<stop-component <stop-component
v-if="hasStopAction && canCreateDeployment" v-if="hasStopAction && canCreateDeployment"
:stop-url="model.stop_path" :stop-url="model.stop_path"
/> />
<rollback-component <rollback-component
v-if="canRetry && canCreateDeployment" v-if="canRetry && canCreateDeployment"
:is-last-deployment="isLastDeployment" :is-last-deployment="isLastDeployment"
:retry-url="retryUrl" :retry-url="retryUrl"
/> />
</div> </div>
</div> </div>
</div> </div>
......
...@@ -56,7 +56,10 @@ ...@@ -56,7 +56,10 @@
this.updateTaskStatusText(); this.updateTaskStatusText();
}, },
}, },
mounted() {
this.renderGFM();
this.updateTaskStatusText();
},
methods: { methods: {
renderGFM() { renderGFM() {
$(this.$refs['gfm-content']).renderGFM(); $(this.$refs['gfm-content']).renderGFM();
...@@ -91,7 +94,7 @@ ...@@ -91,7 +94,7 @@
$tasksShort.text( $tasksShort.text(
`${taskRegexMatches[1]}/${taskRegexMatches[2]} task${taskRegexMatches[2] > 1 ? `${taskRegexMatches[1]}/${taskRegexMatches[2]} task${taskRegexMatches[2] > 1 ?
's' : 's' :
''}` ''}`,
); );
} else { } else {
$tasks.text(''); $tasks.text('');
...@@ -99,10 +102,6 @@ ...@@ -99,10 +102,6 @@
} }
}, },
}, },
mounted() {
this.renderGFM();
this.updateTaskStatusText();
},
}; };
</script> </script>
...@@ -112,7 +111,8 @@ ...@@ -112,7 +111,8 @@
class="description" class="description"
:class="{ :class="{
'js-task-list-container': canUpdate 'js-task-list-container': canUpdate
}"> }"
>
<div <div
class="wiki" class="wiki"
:class="{ :class="{
......
<script> <script>
import timeAgoTooltip from '../../vue_shared/components/time_ago_tooltip.vue'; import timeAgoTooltip from '../../vue_shared/components/time_ago_tooltip.vue';
export default { export default {
props: { components: {
updatedAt: { timeAgoTooltip,
type: String,
required: false,
default: '',
}, },
updatedByName: { props: {
type: String, updatedAt: {
required: false, type: String,
default: '', required: false,
default: '',
},
updatedByName: {
type: String,
required: false,
default: '',
},
updatedByPath: {
type: String,
required: false,
default: '',
},
}, },
updatedByPath: { computed: {
type: String, hasUpdatedBy() {
required: false, return this.updatedByName && this.updatedByPath;
default: '', },
}, },
}, };
components: {
timeAgoTooltip,
},
computed: {
hasUpdatedBy() {
return this.updatedByName && this.updatedByPath;
},
},
};
</script> </script>
<template> <template>
...@@ -48,7 +48,7 @@ export default { ...@@ -48,7 +48,7 @@ export default {
class="author_link" class="author_link"
:href="updatedByPath" :href="updatedByPath"
> >
<span>{{updatedByName}}</span> <span>{{ updatedByName }}</span>
</a> </a>
</span> </span>
</small> </small>
......
...@@ -4,6 +4,9 @@ ...@@ -4,6 +4,9 @@
export default { export default {
mixins: [updateMixin], mixins: [updateMixin],
components: {
markdownField,
},
props: { props: {
formState: { formState: {
type: Object, type: Object,
...@@ -28,9 +31,6 @@ ...@@ -28,9 +31,6 @@
default: true, default: true,
}, },
}, },
components: {
markdownField,
},
mounted() { mounted() {
this.$refs.textarea.focus(); this.$refs.textarea.focus();
}, },
......
...@@ -6,6 +6,13 @@ ...@@ -6,6 +6,13 @@
import descriptionTemplate from './fields/description_template.vue'; import descriptionTemplate from './fields/description_template.vue';
export default { export default {
components: {
lockedWarning,
titleField,
descriptionField,
descriptionTemplate,
editActions,
},
props: { props: {
canDestroy: { canDestroy: {
type: Boolean, type: Boolean,
...@@ -52,13 +59,6 @@ ...@@ -52,13 +59,6 @@
default: true, default: true,
}, },
}, },
components: {
lockedWarning,
titleField,
descriptionField,
descriptionTemplate,
editActions,
},
computed: { computed: {
hasIssuableTemplates() { hasIssuableTemplates() {
return this.issuableTemplates.length; return this.issuableTemplates.length;
...@@ -78,16 +78,19 @@ ...@@ -78,16 +78,19 @@
:form-state="formState" :form-state="formState"
:issuable-templates="issuableTemplates" :issuable-templates="issuableTemplates"
:project-path="projectPath" :project-path="projectPath"
:project-namespace="projectNamespace" /> :project-namespace="projectNamespace"
/>
</div> </div>
<div <div
:class="{ :class="{
'col-sm-8 col-lg-9': hasIssuableTemplates, 'col-sm-8 col-lg-9': hasIssuableTemplates,
'col-xs-12': !hasIssuableTemplates, 'col-xs-12': !hasIssuableTemplates,
}"> }"
>
<title-field <title-field
:form-state="formState" :form-state="formState"
:issuable-templates="issuableTemplates" /> :issuable-templates="issuableTemplates"
/>
</div> </div>
</div> </div>
<description-field <description-field
...@@ -100,6 +103,7 @@ ...@@ -100,6 +103,7 @@
<edit-actions <edit-actions
:form-state="formState" :form-state="formState"
:can-destroy="canDestroy" :can-destroy="canDestroy"
:show-delete-button="showDeleteButton" /> :show-delete-button="showDeleteButton"
/>
</form> </form>
</template> </template>
...@@ -6,12 +6,8 @@ ...@@ -6,12 +6,8 @@
export default { export default {
mixins: [animateMixin], mixins: [animateMixin],
data() { directives: {
return { tooltip,
preAnimation: false,
pulseAnimation: false,
titleEl: document.querySelector('title'),
};
}, },
props: { props: {
issuableRef: { issuableRef: {
...@@ -37,8 +33,17 @@ ...@@ -37,8 +33,17 @@
default: false, default: false,
}, },
}, },
directives: { data() {
tooltip, return {
preAnimation: false,
pulseAnimation: false,
titleEl: document.querySelector('title'),
};
},
computed: {
pencilIcon() {
return spriteIcon('pencil', 'link-highlight');
},
}, },
watch: { watch: {
titleHtml() { titleHtml() {
...@@ -46,11 +51,6 @@ ...@@ -46,11 +51,6 @@
this.animateChange(); this.animateChange();
}, },
}, },
computed: {
pencilIcon() {
return spriteIcon('pencil', 'link-highlight');
},
},
methods: { methods: {
setPageTitle() { setPageTitle() {
const currentPageTitleScope = this.titleEl.innerText.split('·'); const currentPageTitleScope = this.titleEl.innerText.split('·');
...@@ -85,7 +85,7 @@ ...@@ -85,7 +85,7 @@
data-placement="bottom" data-placement="bottom"
data-container="body" data-container="body"
@click="edit" @click="edit"
> >
</button> </button>
</div> </div>
</template> </template>
...@@ -4,6 +4,10 @@ ...@@ -4,6 +4,10 @@
export default { export default {
name: 'jobHeaderSection', name: 'jobHeaderSection',
components: {
ciHeader,
loadingIcon,
},
props: { props: {
job: { job: {
type: Object, type: Object,
...@@ -14,10 +18,6 @@ ...@@ -14,10 +18,6 @@
required: true, required: true,
}, },
}, },
components: {
ciHeader,
loadingIcon,
},
data() { data() {
return { return {
actions: this.getActions(), actions: this.getActions(),
...@@ -31,6 +31,11 @@ ...@@ -31,6 +31,11 @@
return !this.isLoading && Object.keys(this.job).length; return !this.isLoading && Object.keys(this.job).length;
}, },
}, },
watch: {
job() {
this.actions = this.getActions();
},
},
methods: { methods: {
getActions() { getActions() {
const actions = []; const actions = [];
...@@ -46,11 +51,6 @@ ...@@ -46,11 +51,6 @@
return actions; return actions;
}, },
}, },
watch: {
job() {
this.actions = this.getActions();
},
},
}; };
</script> </script>
<template> <template>
...@@ -63,11 +63,11 @@ ...@@ -63,11 +63,11 @@
:time="job.created_at" :time="job.created_at"
:user="job.user" :user="job.user"
:actions="actions" :actions="actions"
:hasSidebarButton="true" :has-sidebar-button="true"
/> />
<loading-icon <loading-icon
v-if="isLoading" v-if="isLoading"
size="2" size="2"
/> />
</div> </div>
</template> </template>
...@@ -23,9 +23,10 @@ ...@@ -23,9 +23,10 @@
<p class="build-detail-row"> <p class="build-detail-row">
<span <span
v-if="hasTitle" v-if="hasTitle"
class="build-light-text"> class="build-light-text"
{{title}}: >
{{ title }}:
</span> </span>
{{value}} {{ value }}
</p> </p>
</template> </template>
...@@ -6,6 +6,13 @@ ...@@ -6,6 +6,13 @@
export default { export default {
name: 'SidebarDetailsBlock', name: 'SidebarDetailsBlock',
components: {
detailRow,
loadingIcon,
},
mixins: [
timeagoMixin,
],
props: { props: {
job: { job: {
type: Object, type: Object,
...@@ -16,13 +23,6 @@ ...@@ -16,13 +23,6 @@
required: true, required: true,
}, },
}, },
mixins: [
timeagoMixin,
],
components: {
detailRow,
loadingIcon,
},
computed: { computed: {
shouldRenderContent() { shouldRenderContent() {
return !this.isLoading && Object.keys(this.job).length > 0; return !this.isLoading && Object.keys(this.job).length > 0;
...@@ -58,11 +58,13 @@ ...@@ -58,11 +58,13 @@
<template v-if="shouldRenderContent"> <template v-if="shouldRenderContent">
<div <div
class="block retry-link" class="block retry-link"
v-if="job.retry_path || job.new_issue_path"> v-if="job.retry_path || job.new_issue_path"
>
<a <a
v-if="job.new_issue_path" v-if="job.new_issue_path"
class="js-new-issue btn btn-new btn-inverted" class="js-new-issue btn btn-new btn-inverted"
:href="job.new_issue_path"> :href="job.new_issue_path"
>
New issue New issue
</a> </a>
<a <a
...@@ -70,20 +72,21 @@ ...@@ -70,20 +72,21 @@
class="js-retry-job btn btn-inverted-secondary" class="js-retry-job btn btn-inverted-secondary"
:href="job.retry_path" :href="job.retry_path"
data-method="post" data-method="post"
rel="nofollow"> rel="nofollow"
>
Retry Retry
</a> </a>
</div> </div>
<div :class="{block : renderBlock }"> <div :class="{block : renderBlock }">
<p <p
class="build-detail-row js-job-mr" class="build-detail-row js-job-mr"
v-if="job.merge_request"> v-if="job.merge_request"
<span >
class="build-light-text"> <span class="build-light-text">
Merge Request: Merge Request:
</span> </span>
<a :href="job.merge_request.path"> <a :href="job.merge_request.path">
!{{job.merge_request.iid}} !{{ job.merge_request.iid }}
</a> </a>
</p> </p>
...@@ -92,49 +95,49 @@ ...@@ -92,49 +95,49 @@
v-if="job.duration" v-if="job.duration"
title="Duration" title="Duration"
:value="duration" :value="duration"
/> />
<detail-row <detail-row
class="js-job-finished" class="js-job-finished"
v-if="job.finished_at" v-if="job.finished_at"
title="Finished" title="Finished"
:value="timeFormated(job.finished_at)" :value="timeFormated(job.finished_at)"
/> />
<detail-row <detail-row
class="js-job-erased" class="js-job-erased"
v-if="job.erased_at" v-if="job.erased_at"
title="Erased" title="Erased"
:value="timeFormated(job.erased_at)" :value="timeFormated(job.erased_at)"
/> />
<detail-row <detail-row
class="js-job-queued" class="js-job-queued"
v-if="job.queued" v-if="job.queued"
title="Queued" title="Queued"
:value="queued" :value="queued"
/> />
<detail-row <detail-row
class="js-job-runner" class="js-job-runner"
v-if="job.runner" v-if="job.runner"
title="Runner" title="Runner"
:value="runnerId" :value="runnerId"
/> />
<detail-row <detail-row
class="js-job-coverage" class="js-job-coverage"
v-if="job.coverage" v-if="job.coverage"
title="Coverage" title="Coverage"
:value="coverage" :value="coverage"
/> />
<p <p
class="build-detail-row js-job-tags" class="build-detail-row js-job-tags"
v-if="job.tags.length"> v-if="job.tags.length"
<span >
class="build-light-text"> <span class="build-light-text">
Tags: Tags:
</span> </span>
<span <span
v-for="tag in job.tags" v-for="(tag, i) in job.tags"
key="tag" :key="i"
class="label label-primary"> class="label label-primary">
{{tag}} {{ tag }}
</span> </span>
</p> </p>
...@@ -146,7 +149,8 @@ ...@@ -146,7 +149,8 @@
class="js-cancel-job btn btn-sm btn-default" class="js-cancel-job btn btn-sm btn-default"
:href="job.cancel_path" :href="job.cancel_path"
data-method="post" data-method="post"
rel="nofollow"> rel="nofollow"
>
Cancel Cancel
</a> </a>
</div> </div>
...@@ -156,6 +160,6 @@ ...@@ -156,6 +160,6 @@
class="prepend-top-10" class="prepend-top-10"
v-if="isLoading" v-if="isLoading"
size="2" size="2"
/> />
</div> </div>
</template> </template>
...@@ -11,6 +11,12 @@ ...@@ -11,6 +11,12 @@
export default { export default {
components: {
Graph,
GraphGroup,
EmptyState,
},
data() { data() {
const metricsData = document.querySelector('#prometheus-graphs').dataset; const metricsData = document.querySelector('#prometheus-graphs').dataset;
const store = new MonitoringStore(); const store = new MonitoringStore();
...@@ -36,12 +42,30 @@ ...@@ -36,12 +42,30 @@
}; };
}, },
components: { created() {
Graph, this.service = new MonitoringService({
GraphGroup, metricsEndpoint: this.metricsEndpoint,
EmptyState, deploymentEndpoint: this.deploymentEndpoint,
});
eventHub.$on('toggleAspectRatio', this.toggleAspectRatio);
eventHub.$on('hoverChanged', this.hoverChanged);
},
beforeDestroy() {
eventHub.$off('toggleAspectRatio', this.toggleAspectRatio);
eventHub.$off('hoverChanged', this.hoverChanged);
window.removeEventListener('resize', this.resizeThrottled, false);
}, },
mounted() {
this.resizeThrottled = _.throttle(this.resize, 600);
if (!this.hasMetrics) {
this.state = 'gettingStarted';
} else {
this.getGraphsData();
window.addEventListener('resize', this.resizeThrottled, false);
}
},
methods: { methods: {
getGraphsData() { getGraphsData() {
this.state = 'loading'; this.state = 'loading';
...@@ -72,36 +96,14 @@ ...@@ -72,36 +96,14 @@
this.hoverData = data; this.hoverData = data;
}, },
}, },
created() {
this.service = new MonitoringService({
metricsEndpoint: this.metricsEndpoint,
deploymentEndpoint: this.deploymentEndpoint,
});
eventHub.$on('toggleAspectRatio', this.toggleAspectRatio);
eventHub.$on('hoverChanged', this.hoverChanged);
},
beforeDestroy() {
eventHub.$off('toggleAspectRatio', this.toggleAspectRatio);
eventHub.$off('hoverChanged', this.hoverChanged);
window.removeEventListener('resize', this.resizeThrottled, false);
},
mounted() {
this.resizeThrottled = _.throttle(this.resize, 600);
if (!this.hasMetrics) {
this.state = 'gettingStarted';
} else {
this.getGraphsData();
window.addEventListener('resize', this.resizeThrottled, false);
}
},
}; };
</script> </script>
<template> <template>
<div v-if="!showEmptyState" class="prometheus-graphs"> <div
v-if="!showEmptyState"
class="prometheus-graphs"
>
<graph-group <graph-group
v-for="(groupData, index) in store.groups" v-for="(groupData, index) in store.groups"
:key="index" :key="index"
......
...@@ -76,20 +76,26 @@ If this takes a long time, ensure that data is available.`, ...@@ -76,20 +76,26 @@ If this takes a long time, ensure that data is available.`,
<template> <template>
<div class="prometheus-state"> <div class="prometheus-state">
<div class="state-svg svg-content"> <div class="state-svg svg-content">
<img :src="currentState.svgUrl"/> <img :src="currentState.svgUrl" />
</div> </div>
<h4 class="state-title"> <h4 class="state-title">
{{currentState.title}} {{ currentState.title }}
</h4> </h4>
<p class="state-description"> <p class="state-description">
{{currentState.description}} {{ currentState.description }}
<a v-if="showButtonDescription" :href="settingsPath"> <a
v-if="showButtonDescription"
:href="settingsPath"
>
Prometheus server Prometheus server
</a> </a>
</p> </p>
<div class="state-button"> <div class="state-button">
<a class="btn btn-success" :href="buttonPath"> <a
{{currentState.buttonText}} class="btn btn-success"
:href="buttonPath"
>
{{ currentState.buttonText }}
</a> </a>
</div> </div>
</div> </div>
......
...@@ -3,10 +3,10 @@ ...@@ -3,10 +3,10 @@
import { axisLeft, axisBottom } from 'd3-axis'; import { axisLeft, axisBottom } from 'd3-axis';
import { max, extent } from 'd3-array'; import { max, extent } from 'd3-array';
import { select } from 'd3-selection'; import { select } from 'd3-selection';
import GraphLegend from './graph/legend.vue'; import graphLegend from './graph/legend.vue';
import GraphFlag from './graph/flag.vue'; import graphFlag from './graph/flag.vue';
import GraphDeployment from './graph/deployment.vue'; import graphDeployment from './graph/deployment.vue';
import GraphPath from './graph/path.vue'; import graphPath from './graph/path.vue';
import MonitoringMixin from '../mixins/monitoring_mixins'; import MonitoringMixin from '../mixins/monitoring_mixins';
import eventHub from '../event_hub'; import eventHub from '../event_hub';
import measurements from '../utils/measurements'; import measurements from '../utils/measurements';
...@@ -17,6 +17,16 @@ ...@@ -17,6 +17,16 @@
const d3 = { scaleLinear, scaleTime, axisLeft, axisBottom, max, extent, select }; const d3 = { scaleLinear, scaleTime, axisLeft, axisBottom, max, extent, select };
export default { export default {
components: {
graphLegend,
graphFlag,
graphDeployment,
graphPath,
},
mixins: [MonitoringMixin],
props: { props: {
graphData: { graphData: {
type: Object, type: Object,
...@@ -45,8 +55,6 @@ ...@@ -45,8 +55,6 @@
}, },
}, },
mixins: [MonitoringMixin],
data() { data() {
return { return {
baseGraphHeight: 450, baseGraphHeight: 450,
...@@ -74,13 +82,6 @@ ...@@ -74,13 +82,6 @@
}; };
}, },
components: {
GraphLegend,
GraphFlag,
GraphDeployment,
GraphPath,
},
computed: { computed: {
outerViewBox() { outerViewBox() {
return `0 0 ${this.baseGraphWidth} ${this.baseGraphHeight}`; return `0 0 ${this.baseGraphWidth} ${this.baseGraphHeight}`;
...@@ -104,6 +105,26 @@ ...@@ -104,6 +105,26 @@
}, },
}, },
watch: {
updateAspectRatio() {
if (this.updateAspectRatio) {
this.graphHeight = 450;
this.graphWidth = 600;
this.measurements = measurements.large;
this.draw();
eventHub.$emit('toggleAspectRatio');
}
},
hoverData() {
this.positionFlag();
},
},
mounted() {
this.draw();
},
methods: { methods: {
draw() { draw() {
const breakpointSize = bp.getBreakpointSize(); const breakpointSize = bp.getBreakpointSize();
...@@ -192,36 +213,16 @@ ...@@ -192,36 +213,16 @@
}); // This will select all of the ticks once they're rendered }); // This will select all of the ticks once they're rendered
}, },
}, },
watch: {
updateAspectRatio() {
if (this.updateAspectRatio) {
this.graphHeight = 450;
this.graphWidth = 600;
this.measurements = measurements.large;
this.draw();
eventHub.$emit('toggleAspectRatio');
}
},
hoverData() {
this.positionFlag();
},
},
mounted() {
this.draw();
},
}; };
</script> </script>
<template> <template>
<div <div
class="prometheus-graph" class="prometheus-graph"
@mouseover="showFlagContent = true" @mouseover="showFlagContent = true"
@mouseleave="showFlagContent = false"> @mouseleave="showFlagContent = false">
<h5 class="text-center graph-title"> <h5 class="text-center graph-title">
{{graphData.title}} {{ graphData.title }}
</h5> </h5>
<div <div
class="prometheus-svg-container" class="prometheus-svg-container"
...@@ -231,12 +232,12 @@ ...@@ -231,12 +232,12 @@
ref="baseSvg"> ref="baseSvg">
<g <g
class="x-axis" class="x-axis"
:transform="axisTransform"> :transform="axisTransform"
</g> />
<g <g
class="y-axis" class="y-axis"
transform="translate(70, 20)"> transform="translate(70, 20)"
</g> />
<graph-legend <graph-legend
:graph-width="graphWidth" :graph-width="graphWidth"
:graph-height="graphHeight" :graph-height="graphHeight"
...@@ -251,40 +252,41 @@ ...@@ -251,40 +252,41 @@
<svg <svg
class="graph-data" class="graph-data"
:viewBox="innerViewBox" :viewBox="innerViewBox"
ref="graphData"> ref="graphData"
<graph-path >
v-for="(path, index) in timeSeries" <graph-path
:key="index" v-for="(path, index) in timeSeries"
:generated-line-path="path.linePath" :key="index"
:generated-area-path="path.areaPath" :generated-line-path="path.linePath"
:line-style="path.lineStyle" :generated-area-path="path.areaPath"
:line-color="path.lineColor" :line-style="path.lineStyle"
:area-color="path.areaColor" :line-color="path.lineColor"
/> :area-color="path.areaColor"
<rect />
class="prometheus-graph-overlay" <rect
:width="(graphWidth - 70)" class="prometheus-graph-overlay"
:height="(graphHeight - 100)" :width="(graphWidth - 70)"
transform="translate(-5, 20)" :height="(graphHeight - 100)"
ref="graphOverlay" transform="translate(-5, 20)"
@mousemove="handleMouseOverGraph($event)"> ref="graphOverlay"
</rect> @mousemove="handleMouseOverGraph($event)"
<graph-deployment />
:show-deploy-info="showDeployInfo" <graph-deployment
:deployment-data="reducedDeploymentData" :show-deploy-info="showDeployInfo"
:graph-width="graphWidth" :deployment-data="reducedDeploymentData"
:graph-height="graphHeight" :graph-width="graphWidth"
:graph-height-offset="graphHeightOffset" :graph-height="graphHeight"
/> :graph-height-offset="graphHeightOffset"
<graph-flag />
v-if="showFlag" <graph-flag
:current-x-coordinate="currentXCoordinate" v-if="showFlag"
:current-data="currentData" :current-x-coordinate="currentXCoordinate"
:current-flag-position="currentFlagPosition" :current-data="currentData"
:graph-height="graphHeight" :current-flag-position="currentFlagPosition"
:graph-height-offset="graphHeightOffset" :graph-height="graphHeight"
:show-flag-content="showFlagContent" :graph-height-offset="graphHeightOffset"
/> :show-flag-content="showFlagContent"
/>
</svg> </svg>
</svg> </svg>
</div> </div>
......
<script> <script>
import { dateFormatWithName, timeFormat } from '../../utils/date_time_formatters'; import { dateFormatWithName, timeFormat } from '../../utils/date_time_formatters';
import Icon from '../../../vue_shared/components/icon.vue'; import icon from '../../../vue_shared/components/icon.vue';
export default { export default {
components: {
icon,
},
props: { props: {
showDeployInfo: { showDeployInfo: {
type: Boolean, type: Boolean,
...@@ -26,10 +29,6 @@ ...@@ -26,10 +29,6 @@
}, },
}, },
components: {
Icon,
},
computed: { computed: {
calculatedHeight() { calculatedHeight() {
return this.graphHeight - this.graphHeightOffset; return this.graphHeight - this.graphHeightOffset;
...@@ -83,51 +82,55 @@ ...@@ -83,51 +82,55 @@
v-for="(deployment, index) in deploymentData" v-for="(deployment, index) in deploymentData"
:key="index" :key="index"
:class="nameDeploymentClass(deployment)" :class="nameDeploymentClass(deployment)"
:transform="transformDeploymentGroup(deployment)"> :transform="transformDeploymentGroup(deployment)"
>
<rect <rect
x="0" x="0"
y="0" y="0"
:height="calculatedHeight" :height="calculatedHeight"
width="3" width="3"
fill="url(#shadow-gradient)"> fill="url(#shadow-gradient)"
</rect> />
<line <line
class="deployment-line" class="deployment-line"
x1="0" x1="0"
y1="0" y1="0"
x2="0" x2="0"
:y2="calculatedHeight" :y2="calculatedHeight"
stroke="#000"> stroke="#000"
</line> />
<svg <svg
v-if="deployment.showDeploymentFlag" v-if="deployment.showDeploymentFlag"
class="js-deploy-info-box" class="js-deploy-info-box"
:x="positionFlag(deployment)" :x="positionFlag(deployment)"
y="0" y="0"
width="134" width="134"
:height="svgContainerHeight(deployment.tag)"> :height="svgContainerHeight(deployment.tag)"
>
<rect <rect
class="rect-text-metric deploy-info-rect rect-metric" class="rect-text-metric deploy-info-rect rect-metric"
x="1" x="1"
y="1" y="1"
rx="2" rx="2"
width="132" width="132"
:height="svgContainerHeight(deployment.tag) - 2"> :height="svgContainerHeight(deployment.tag) - 2"
</rect> />
<text <text
class="deploy-info-text text-metric-bold" class="deploy-info-text text-metric-bold"
transform="translate(5, 2)"> transform="translate(5, 2)"
>
Deployed Deployed
</text> </text>
<!--The date info--> <!--The date info-->
<g transform="translate(5, 20)"> <g transform="translate(5, 20)">
<text class="deploy-info-text"> <text class="deploy-info-text">
{{formatDate(deployment.time)}} {{ formatDate(deployment.time) }}
</text> </text>
<text <text
class="deploy-info-text text-metric-bold" class="deploy-info-text text-metric-bold"
x="62"> x="62"
{{formatTime(deployment.time)}} >
{{ formatTime(deployment.time) }}
</text> </text>
</g> </g>
<line <line
...@@ -136,40 +139,41 @@ ...@@ -136,40 +139,41 @@
y1="38" y1="38"
x2="132" x2="132"
:y2="38" :y2="38"
stroke="#000"> stroke="#000"
</line> />
<!--Commit information--> <!--Commit information-->
<g transform="translate(5, 40)"> <g transform="translate(5, 40)">
<icon <icon
name="commit" name="commit"
:width="12" :width="12"
:height="12" :height="12"
:y="3"> :y="3"
</icon> />
<a :xlink:href="deployment.commitUrl"> <a :xlink:href="deployment.commitUrl">
<text <text
class="deploy-info-text deploy-info-text-link" class="deploy-info-text deploy-info-text-link"
transform="translate(20, 2)"> transform="translate(20, 2)">
{{refText(deployment)}} {{ refText(deployment) }}
</text> </text>
</a> </a>
</g> </g>
<!--Tag information--> <!--Tag information-->
<g <g
transform="translate(5, 55)" transform="translate(5, 55)"
v-if="deployment.tag"> v-if="deployment.tag">
<icon <icon
name="label" name="label"
:width="12" :width="12"
:height="12" :height="12"
:y="5"> :y="5"
</icon> />
<a :xlink:href="deployment.tagUrl"> <a :xlink:href="deployment.tagUrl">
<text <text
class="deploy-info-text deploy-info-text-link" class="deploy-info-text deploy-info-text-link"
transform="translate(20, 2)" transform="translate(20, 2)"
y="2"> y="2"
{{deployment.tag}} >
{{ deployment.tag }}
</text> </text>
</a> </a>
</g> </g>
...@@ -177,20 +181,20 @@ ...@@ -177,20 +181,20 @@
</g> </g>
<svg <svg
height="0" height="0"
width="0"> width="0"
>
<defs> <defs>
<linearGradient <linearGradient id="shadow-gradient">
id="shadow-gradient">
<stop <stop
offset="0%" offset="0%"
stop-color="#000" stop-color="#000"
stop-opacity="0.4"> stop-opacity="0.4"
</stop> />
<stop <stop
offset="100%" offset="100%"
stop-color="#000" stop-color="#000"
stop-opacity="0"> stop-opacity="0"
</stop> />
</linearGradient> </linearGradient>
</defs> </defs>
</svg> </svg>
......
...@@ -58,13 +58,14 @@ ...@@ -58,13 +58,14 @@
:y1="0" :y1="0"
:x2="currentXCoordinate" :x2="currentXCoordinate"
:y2="calculatedHeight" :y2="calculatedHeight"
transform="translate(-5, 20)"> transform="translate(-5, 20)"
</line> />
<svg <svg
v-if="showFlagContent" v-if="showFlagContent"
class="rect-text-metric" class="rect-text-metric"
:x="currentFlagPosition" :x="currentFlagPosition"
y="0"> y="0"
>
<rect <rect
class="rect-metric" class="rect-metric"
x="4" x="4"
...@@ -72,21 +73,23 @@ ...@@ -72,21 +73,23 @@
rx="2" rx="2"
width="90" width="90"
height="40" height="40"
transform="translate(-3, 20)"> transform="translate(-3, 20)"
</rect> />
<text <text
class="text-metric text-metric-bold" class="text-metric text-metric-bold"
x="16" x="16"
y="35" y="35"
transform="translate(-5, 20)"> transform="translate(-5, 20)"
{{formatTime}} >
{{ formatTime }}
</text> </text>
<text <text
class="text-metric" class="text-metric"
x="16" x="16"
y="15" y="15"
transform="translate(-5, 20)"> transform="translate(-5, 20)"
{{formatDate}} >
{{ formatDate }}
</text> </text>
</svg> </svg>
</g> </g>
......
...@@ -73,6 +73,21 @@ ...@@ -73,6 +73,21 @@
}, },
}, },
mounted() {
this.$nextTick(() => {
const bbox = this.$refs.ylabel.getBBox();
this.metricUsageXPosition = 0;
this.seriesXPosition = 0;
if (this.$refs.legendTitleSvg != null) {
this.seriesXPosition = this.$refs.legendTitleSvg[0].getBBox().width;
}
if (this.$refs.seriesTitleSvg != null) {
this.metricUsageXPosition = this.$refs.seriesTitleSvg[0].getBBox().width;
}
this.yLabelWidth = bbox.width + 10; // Added some padding
this.yLabelHeight = bbox.height + 5;
});
},
methods: { methods: {
translateLegendGroup(index) { translateLegendGroup(index) {
return `translate(0, ${12 * (index)})`; return `translate(0, ${12 * (index)})`;
...@@ -100,26 +115,10 @@ ...@@ -100,26 +115,10 @@
return null; return null;
}, },
}, },
mounted() {
this.$nextTick(() => {
const bbox = this.$refs.ylabel.getBBox();
this.metricUsageXPosition = 0;
this.seriesXPosition = 0;
if (this.$refs.legendTitleSvg != null) {
this.seriesXPosition = this.$refs.legendTitleSvg[0].getBBox().width;
}
if (this.$refs.seriesTitleSvg != null) {
this.metricUsageXPosition = this.$refs.seriesTitleSvg[0].getBBox().width;
}
this.yLabelWidth = bbox.width + 10; // Added some padding
this.yLabelHeight = bbox.height + 5;
});
},
}; };
</script> </script>
<template> <template>
<g <g class="axis-label-container">
class="axis-label-container">
<line <line
class="label-x-axis-line" class="label-x-axis-line"
stroke="#000000" stroke="#000000"
...@@ -127,8 +126,8 @@ ...@@ -127,8 +126,8 @@
x1="10" x1="10"
:y1="yPosition" :y1="yPosition"
:x2="graphWidth + 20" :x2="graphWidth + 20"
:y2="yPosition"> :y2="yPosition"
</line> />
<line <line
class="label-y-axis-line" class="label-y-axis-line"
stroke="#000000" stroke="#000000"
...@@ -136,39 +135,43 @@ ...@@ -136,39 +135,43 @@
x1="10" x1="10"
y1="0" y1="0"
:x2="10" :x2="10"
:y2="yPosition"> :y2="yPosition"
</line> />
<rect <rect
class="rect-axis-text" class="rect-axis-text"
:transform="rectTransform" :transform="rectTransform"
:width="yLabelWidth" :width="yLabelWidth"
:height="yLabelHeight"> :height="yLabelHeight"
</rect> />
<text <text
class="label-axis-text y-label-text" class="label-axis-text y-label-text"
text-anchor="middle" text-anchor="middle"
:transform="textTransform" :transform="textTransform"
ref="ylabel"> ref="ylabel"
{{yAxisLabel}} >
{{ yAxisLabel }}
</text> </text>
<rect <rect
class="rect-axis-text" class="rect-axis-text"
:x="xPosition + 60" :x="xPosition + 60"
:y="graphHeight - 80" :y="graphHeight - 80"
width="35" width="35"
height="50"> height="50"
</rect> />
<text <text
class="label-axis-text x-label-text" class="label-axis-text x-label-text"
:x="xPosition + 60" :x="xPosition + 60"
:y="yPosition" :y="yPosition"
dy=".35em"> dy=".35em"
>
Time Time
</text> </text>
<g class="legend-group" <g
class="legend-group"
v-for="(series, index) in timeSeries" v-for="(series, index) in timeSeries"
:key="index" :key="index"
:transform="translateLegendGroup(index)"> :transform="translateLegendGroup(index)"
>
<line <line
:stroke="series.lineColor" :stroke="series.lineColor"
:stroke-width="measurements.legends.height" :stroke-width="measurements.legends.height"
...@@ -176,23 +179,25 @@ ...@@ -176,23 +179,25 @@
:x1="measurements.legends.offsetX" :x1="measurements.legends.offsetX"
:x2="measurements.legends.offsetX + measurements.legends.width" :x2="measurements.legends.offsetX + measurements.legends.width"
:y1="graphHeight - measurements.legends.offsetY" :y1="graphHeight - measurements.legends.offsetY"
:y2="graphHeight - measurements.legends.offsetY"> :y2="graphHeight - measurements.legends.offsetY"
</line> />
<text <text
v-if="timeSeries.length > 1" v-if="timeSeries.length > 1"
class="legend-metric-title" class="legend-metric-title"
ref="legendTitleSvg" ref="legendTitleSvg"
x="38" x="38"
:y="graphHeight - 30"> :y="graphHeight - 30"
{{createSeriesString(index, series)}} >
{{ createSeriesString(index, series) }}
</text> </text>
<text <text
v-else v-else
class="legend-metric-title" class="legend-metric-title"
ref="legendTitleSvg" ref="legendTitleSvg"
x="38" x="38"
:y="graphHeight - 30"> :y="graphHeight - 30"
{{legendTitle}} {{formatMetricUsage(series)}} >
{{ legendTitle }} {{ formatMetricUsage(series) }}
</text> </text>
</g> </g>
</g> </g>
......
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
lineStyle: { lineStyle: {
type: String, type: String,
required: false, required: false,
default: '',
}, },
lineColor: { lineColor: {
type: String, type: String,
...@@ -37,8 +38,8 @@ ...@@ -37,8 +38,8 @@
class="metric-area" class="metric-area"
:d="generatedAreaPath" :d="generatedAreaPath"
:fill="areaColor" :fill="areaColor"
transform="translate(-5, 20)"> transform="translate(-5, 20)"
</path> />
<path <path
class="metric-line" class="metric-line"
:d="generatedLinePath" :d="generatedLinePath"
...@@ -46,7 +47,7 @@ ...@@ -46,7 +47,7 @@
fill="none" fill="none"
stroke-width="1" stroke-width="1"
:stroke-dasharray="strokeDashArray" :stroke-dasharray="strokeDashArray"
transform="translate(-5, 20)"> transform="translate(-5, 20)"
</path> />
</g> </g>
</template> </template>
<script> <script>
export default { export default {
props: { props: {
name: { name: {
type: String, type: String,
required: true, required: true,
},
}, },
}, };
};
</script> </script>
<template> <template>
<div class="panel panel-default prometheus-panel"> <div class="panel panel-default prometheus-panel">
<div class="panel-heading"> <div class="panel-heading">
<h4>{{name}}</h4> <h4>{{ name }}</h4>
</div> </div>
<div class="panel-body prometheus-graph-group"> <div class="panel-body prometheus-graph-group">
<slot /> <slot />
......
...@@ -64,6 +64,13 @@ ...@@ -64,6 +64,13 @@
return this.getUserDataByProp('id'); return this.getUserDataByProp('id');
}, },
}, },
created() {
this.emojiSmiling = emojiSmiling;
this.emojiSmile = emojiSmile;
this.emojiSmiley = emojiSmiley;
this.editSvg = editSvg;
this.ellipsisSvg = ellipsisSvg;
},
methods: { methods: {
onEdit() { onEdit() {
this.$emit('handleEdit'); this.$emit('handleEdit');
...@@ -72,13 +79,6 @@ ...@@ -72,13 +79,6 @@
this.$emit('handleDelete'); this.$emit('handleDelete');
}, },
}, },
created() {
this.emojiSmiling = emojiSmiling;
this.emojiSmile = emojiSmile;
this.emojiSmiley = emojiSmiley;
this.editSvg = editSvg;
this.ellipsisSvg = ellipsisSvg;
},
}; };
</script> </script>
...@@ -86,7 +86,9 @@ ...@@ -86,7 +86,9 @@
<div class="note-actions"> <div class="note-actions">
<span <span
v-if="accessLevel" v-if="accessLevel"
class="note-role user-access-role">{{accessLevel}}</span> class="note-role user-access-role">
{{ accessLevel }}
</span>
<div <div
v-if="canAddAwardEmoji" v-if="canAddAwardEmoji"
class="note-actions-item"> class="note-actions-item">
...@@ -126,10 +128,10 @@ ...@@ -126,10 +128,10 @@
class="note-action-button js-note-edit btn btn-transparent" class="note-action-button js-note-edit btn btn-transparent"
data-container="body" data-container="body"
data-placement="bottom"> data-placement="bottom">
<span <span
v-html="editSvg" v-html="editSvg"
class="link-highlight"> class="link-highlight">
</span> </span>
</button> </button>
</div> </div>
<div <div
...@@ -143,10 +145,10 @@ ...@@ -143,10 +145,10 @@
data-toggle="dropdown" data-toggle="dropdown"
data-container="body" data-container="body"
data-placement="bottom"> data-placement="bottom">
<span <span
class="icon" class="icon"
v-html="ellipsisSvg"> v-html="ellipsisSvg">
</span> </span>
</button> </button>
<ul class="dropdown-menu more-actions-dropdown dropdown-open-left"> <ul class="dropdown-menu more-actions-dropdown dropdown-open-left">
<li v-if="canReportAsAbuse"> <li v-if="canReportAsAbuse">
......
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