diff options
34 files changed, 1035 insertions, 920 deletions
diff --git a/app/assets/javascripts/boards/components/board_card.vue b/app/assets/javascripts/boards/components/board_card.vue index 7e0e0a13a46..23fec503586 100644 --- a/app/assets/javascripts/boards/components/board_card.vue +++ b/app/assets/javascripts/boards/components/board_card.vue @@ -89,6 +89,7 @@ export default { :issue="issue" :issue-link-base="issueLinkBase" :root-path="rootPath" - :update-filters="true" /> + :update-filters="true" + /> </li> </template> diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue index 38fcc006831..25cef44c1b8 100644 --- a/app/assets/javascripts/clusters/components/applications.vue +++ b/app/assets/javascripts/clusters/components/applications.vue @@ -77,12 +77,12 @@ which incur additional costs. See %{pricingLink}`)), return sprintf( _.escape(s__(`ClusterIntegration|Prometheus is an open-source monitoring system with %{gitlabIntegrationLink} to monitor deployed applications.`)), - { - gitlabIntegrationLink: `<a href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html" - target="_blank" rel="noopener noreferrer"> - ${_.escape(s__('ClusterIntegration|Gitlab Integration'))} - </a>`, - }, + { + gitlabIntegrationLink: `<a href="https://docs.gitlab.com/ce/user/project/integrations/prometheus.html" +target="_blank" rel="noopener noreferrer"> + ${_.escape(s__('ClusterIntegration|Gitlab Integration'))} + </a>`, + }, false, ); }, diff --git a/app/assets/javascripts/cycle_analytics/components/stage_code_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_code_component.vue index e06f803b30b..a71dcf78103 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_code_component.vue +++ b/app/assets/javascripts/cycle_analytics/components/stage_code_component.vue @@ -12,7 +12,7 @@ props: { items: { type: Array, - default: [] + default: () => [], }, stage: { type: Object, diff --git a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.vue index 4f2c8256277..cee294b4ac2 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_plan_component.vue +++ b/app/assets/javascripts/cycle_analytics/components/stage_plan_component.vue @@ -13,7 +13,7 @@ props: { items: { type: Array, - default: [] + default: () => [], }, stage: { type: Object, diff --git a/app/assets/javascripts/cycle_analytics/components/stage_review_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_review_component.vue index c419347d219..39b699a6395 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_review_component.vue +++ b/app/assets/javascripts/cycle_analytics/components/stage_review_component.vue @@ -14,7 +14,7 @@ props: { items: { type: Array, - default: [] + default: () => [], }, stage: { type: Object, @@ -81,8 +81,7 @@ name="fork" :size="16" /> - <a - :href="mergeRequest.branch.url"> + <a :href="mergeRequest.branch.url"> {{ mergeRequest.branch.name }} </a> </span> diff --git a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.vue index 26ee5a8c69d..92f2a95a66a 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_staging_component.vue +++ b/app/assets/javascripts/cycle_analytics/components/stage_staging_component.vue @@ -15,7 +15,7 @@ props: { items: { type: Array, - default: [] + default: () => [], }, stage: { type: Object, @@ -69,7 +69,7 @@ <a :href="build.commitUrl" class="commit-sha" - > + > {{ build.shortSha }} </a> </h5> @@ -77,7 +77,7 @@ <a :href="build.url" class="build-date" - > + > {{ build.date }} </a> {{ s__('ByAuthor|by') }} diff --git a/app/assets/javascripts/cycle_analytics/components/stage_test_component.vue b/app/assets/javascripts/cycle_analytics/components/stage_test_component.vue index 88fa6b073ca..c0f6c9ae573 100644 --- a/app/assets/javascripts/cycle_analytics/components/stage_test_component.vue +++ b/app/assets/javascripts/cycle_analytics/components/stage_test_component.vue @@ -6,15 +6,21 @@ import icon from '../../vue_shared/components/icon.vue'; export default { - props: { - items: Array, - stage: Object, - }, components: { totalTime, limitWarning, icon, }, + props: { + items: { + type: Array, + default: () => [], + }, + stage: { + type: Object, + default: () => ({}), + }, + }, computed: { iconBuildStatus() { return iconBuildStatus; @@ -35,29 +41,59 @@ <li v-for="(build, i) in items" :key="i" - class="stage-event-item item-build-component"> + class="stage-event-item item-build-component" + > <div class="item-details"> <h5 class="item-title"> - <span class="icon-build-status" v-html="iconBuildStatus"></span> - <a :href="build.url" class="item-build-name">{{ build.name }}</a> + <span + class="icon-build-status" + v-html="iconBuildStatus" + > + </span> + <a + :href="build.url" + class="item-build-name" + > + {{ build.name }} + </a> · - <a :href="build.url" class="pipeline-id">#{{ build.id }}</a> + <a + :href="build.url" + class="pipeline-id" + > + #{{ build.id }} + </a> <icon name="fork" - :size="16"> - </icon> - <a :href="build.branch.url" 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> + :size="16" + /> + <a + :href="build.branch.url" + 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> <span> - <a :href="build.url" class="issue-date"> + <a + :href="build.url" + class="issue-date"> {{ build.date }} </a> </span> </div> <div class="item-time"> - <total-time :time="build.totalTime"/> + <total-time :time="build.totalTime" /> </div> </li> </ul> diff --git a/app/assets/javascripts/cycle_analytics/components/total_time_component.vue b/app/assets/javascripts/cycle_analytics/components/total_time_component.vue index 62efd4f9c28..08d158314b3 100644 --- a/app/assets/javascripts/cycle_analytics/components/total_time_component.vue +++ b/app/assets/javascripts/cycle_analytics/components/total_time_component.vue @@ -17,10 +17,30 @@ <template> <span class="total-time"> <template v-if="hasData"> - <template v-if="time.days">{{ time.days }} <span>{{ 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 v-if="time.days"> + {{ time.days }} + <span> + {{ 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 v-else> -- diff --git a/app/assets/javascripts/deploy_keys/components/action_btn.vue b/app/assets/javascripts/deploy_keys/components/action_btn.vue index f9f2f9bf693..b839b9f286f 100644 --- a/app/assets/javascripts/deploy_keys/components/action_btn.vue +++ b/app/assets/javascripts/deploy_keys/components/action_btn.vue @@ -3,10 +3,8 @@ import loadingIcon from '../../vue_shared/components/loading_icon.vue'; export default { - data() { - return { - isLoading: false, - }; + components: { + loadingIcon, }, props: { deployKey: { @@ -23,11 +21,16 @@ default: 'btn-default', }, }, - - components: { - loadingIcon, + data() { + return { + isLoading: false, + }; + }, + computed: { + text() { + return `${this.type.charAt(0).toUpperCase()}${this.type.slice(1)}`; + }, }, - methods: { doAction() { this.isLoading = true; @@ -37,11 +40,6 @@ }); }, }, - computed: { - text() { - return `${this.type.charAt(0).toUpperCase()}${this.type.slice(1)}`; - }, - }, }; </script> diff --git a/app/assets/javascripts/deploy_keys/components/app.vue b/app/assets/javascripts/deploy_keys/components/app.vue index fe046449054..7b68b19de75 100644 --- a/app/assets/javascripts/deploy_keys/components/app.vue +++ b/app/assets/javascripts/deploy_keys/components/app.vue @@ -7,11 +7,9 @@ import loadingIcon from '../../vue_shared/components/loading_icon.vue'; export default { - data() { - return { - isLoading: false, - store: new DeployKeysStore(), - }; + components: { + keysPanel, + loadingIcon, }, props: { endpoint: { @@ -19,6 +17,12 @@ required: true, }, }, + data() { + return { + isLoading: false, + store: new DeployKeysStore(), + }; + }, computed: { hasKeys() { return Object.keys(this.keys).length; @@ -27,9 +31,20 @@ return this.store.keys; }, }, - components: { - keysPanel, - loadingIcon, + 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); }, methods: { fetchKeys() { @@ -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> diff --git a/app/assets/javascripts/deploy_keys/components/key.vue b/app/assets/javascripts/deploy_keys/components/key.vue index 2a05c6f001e..a9e819b8a3c 100644 --- a/app/assets/javascripts/deploy_keys/components/key.vue +++ b/app/assets/javascripts/deploy_keys/components/key.vue @@ -3,6 +3,9 @@ import { getTimeago } from '../../lib/utils/datetime_utility'; export default { + components: { + actionBtn, + }, props: { deployKey: { type: Object, @@ -17,9 +20,6 @@ required: true, }, }, - components: { - actionBtn, - }, computed: { timeagoDate() { return getTimeago().format(this.deployKey.created_at); @@ -61,9 +61,10 @@ </div> <div class="deploy-key-content prepend-left-default deploy-key-projects"> <a - v-for="project in deployKey.projects" + v-for="(project, i) in deployKey.projects" class="label deploy-project-label" :href="project.full_path" + :key="i" > {{ project.full_name }} </a> diff --git a/app/assets/javascripts/deploy_keys/components/keys_panel.vue b/app/assets/javascripts/deploy_keys/components/keys_panel.vue index 9e6fb244af6..822b0323156 100644 --- a/app/assets/javascripts/deploy_keys/components/keys_panel.vue +++ b/app/assets/javascripts/deploy_keys/components/keys_panel.vue @@ -2,6 +2,9 @@ import key from './key.vue'; export default { + components: { + key, + }, props: { title: { type: String, @@ -25,9 +28,6 @@ required: true, }, }, - components: { - key, - }, }; </script> @@ -37,12 +37,14 @@ {{ title }} ({{ keys.length }}) </h5> - <ul class="well-list" + <ul + class="well-list" v-if="keys.length" > <li v-for="deployKey in keys" - :key="deployKey.id"> + :key="deployKey.id" + > <key :deploy-key="deployKey" :store="store" diff --git a/app/assets/javascripts/environments/components/container.vue b/app/assets/javascripts/environments/components/container.vue index 3236077c3cf..dbee81fa320 100644 --- a/app/assets/javascripts/environments/components/container.vue +++ b/app/assets/javascripts/environments/components/container.vue @@ -4,6 +4,11 @@ import environmentTable from '../components/environments_table.vue'; export default { + components: { + environmentTable, + loadingIcon, + tablePagination, + }, props: { isLoading: { type: Boolean, @@ -26,12 +31,6 @@ required: true, }, }, - components: { - environmentTable, - loadingIcon, - tablePagination, - }, - methods: { onChangePage(page) { this.$emit('onChangePage', page); @@ -47,7 +46,7 @@ label="Loading environments" v-if="isLoading" size="3" - /> + /> <slot name="emptyState"></slot> @@ -59,13 +58,13 @@ :environments="environments" :can-create-deployment="canCreateDeployment" :can-read-environment="canReadEnvironment" - /> + /> <table-pagination v-if="pagination && pagination.totalPages > 1" :change="onChangePage" - :pageInfo="pagination" - /> + :page-info="pagination" + /> </div> </div> </template> diff --git a/app/assets/javascripts/environments/components/empty_state.vue b/app/assets/javascripts/environments/components/empty_state.vue index 2646f08c8e6..c7ae1fe8cf0 100644 --- a/app/assets/javascripts/environments/components/empty_state.vue +++ b/app/assets/javascripts/environments/components/empty_state.vue @@ -1,6 +1,6 @@ <script> export default { - name: 'environmentsEmptyState', + name: 'EnvironmentsEmptyState', props: { newPath: { type: String, @@ -21,21 +21,22 @@ <div class="blank-state-row"> <div class="blank-state-center"> <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> <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 /> <a :href="helpPath"> - {{s__("Environments|Read more about environments")}} + {{ s__("Environments|Read more about environments") }} </a> </p> <a v-if="canCreateEnvironment" :href="newPath" - class="btn btn-create js-new-environment-button"> - {{s__("Environments|New environment")}} + class="btn btn-create js-new-environment-button" + > + {{ s__("Environments|New environment") }} </a> </div> </div> diff --git a/app/assets/javascripts/environments/components/environment_actions.vue b/app/assets/javascripts/environments/components/environment_actions.vue index e7495677e7c..61b684a8fc6 100644 --- a/app/assets/javascripts/environments/components/environment_actions.vue +++ b/app/assets/javascripts/environments/components/environment_actions.vue @@ -1,55 +1,54 @@ <script> -import playIconSvg from 'icons/_icon_play.svg'; -import eventHub from '../event_hub'; -import loadingIcon from '../../vue_shared/components/loading_icon.vue'; -import tooltip from '../../vue_shared/directives/tooltip'; + import playIconSvg from 'icons/_icon_play.svg'; + import eventHub from '../event_hub'; + import loadingIcon from '../../vue_shared/components/loading_icon.vue'; + import tooltip from '../../vue_shared/directives/tooltip'; -export default { - props: { - actions: { - type: Array, - required: false, - default: () => [], + export default { + directives: { + tooltip, }, - }, - directives: { - tooltip, - }, - - components: { - loadingIcon, - }, + components: { + loadingIcon, + }, + props: { + actions: { + type: Array, + required: false, + default: () => [], + }, + }, - data() { - return { - playIconSvg, - isLoading: false, - }; - }, + data() { + return { + playIconSvg, + isLoading: false, + }; + }, - computed: { - title() { - return 'Deploy to...'; + computed: { + title() { + return 'Deploy to...'; + }, }, - }, - methods: { - onClickAction(endpoint) { - this.isLoading = true; + methods: { + onClickAction(endpoint) { + this.isLoading = true; - eventHub.$emit('postAction', endpoint); - }, + eventHub.$emit('postAction', endpoint); + }, - isActionDisabled(action) { - if (action.playable === undefined) { - return false; - } + isActionDisabled(action) { + if (action.playable === undefined) { + return false; + } - return !action.playable; + return !action.playable; + }, }, - }, -}; + }; </script> <template> <div @@ -63,27 +62,32 @@ export default { data-toggle="dropdown" :title="title" :aria-label="title" - :disabled="isLoading"> + :disabled="isLoading" + > <span> <span v-html="playIconSvg"></span> <i class="fa fa-caret-down" - aria-hidden="true"/> + aria-hidden="true" + /> <loading-icon v-if="isLoading" /> </span> </button> <ul class="dropdown-menu dropdown-menu-align-right"> - <li v-for="action in actions"> + <li + v-for="(action, i) in actions" + :key="i"> <button type="button" class="js-manual-action-link no-btn btn" @click="onClickAction(action.play_path)" :class="{ disabled: isActionDisabled(action) }" - :disabled="isActionDisabled(action)"> + :disabled="isActionDisabled(action)" + > <span v-html="playIconSvg"></span> <span> - {{action.name}} + {{ action.name }} </span> </button> </li> diff --git a/app/assets/javascripts/environments/components/environment_external_url.vue b/app/assets/javascripts/environments/components/environment_external_url.vue index 520c3ac8ace..c9a68cface6 100644 --- a/app/assets/javascripts/environments/components/environment_external_url.vue +++ b/app/assets/javascripts/environments/components/environment_external_url.vue @@ -1,28 +1,27 @@ <script> -import tooltip from '../../vue_shared/directives/tooltip'; -import { s__ } from '../../locale'; + import tooltip from '../../vue_shared/directives/tooltip'; + import { s__ } from '../../locale'; -/** - * Renders the external url link in environments table. - */ -export default { - props: { - externalUrl: { - type: String, - required: true, + /** + * Renders the external url link in environments table. + */ + export default { + directives: { + tooltip, + }, + props: { + externalUrl: { + type: String, + required: true, + }, }, - }, - - directives: { - tooltip, - }, - computed: { - title() { - return s__('Environments|Open'); + computed: { + title() { + return s__('Environments|Open'); + }, }, - }, -}; + }; </script> <template> <a @@ -33,9 +32,12 @@ export default { rel="noopener noreferrer nofollow" :title="title" :aria-label="title" - :href="externalUrl"> + :href="externalUrl" + > <i class="fa fa-external-link" - aria-hidden="true" /> + aria-hidden="true" + > + </i> </a> </template> diff --git a/app/assets/javascripts/environments/components/environment_item.vue b/app/assets/javascripts/environments/components/environment_item.vue index f647eed6952..e139a1d6b17 100644 --- a/app/assets/javascripts/environments/components/environment_item.vue +++ b/app/assets/javascripts/environments/components/environment_item.vue @@ -1,424 +1,424 @@ <script> -import Timeago from 'timeago.js'; -import _ from 'underscore'; -import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; -import { humanize } from '../../lib/utils/text_utility'; -import ActionsComponent from './environment_actions.vue'; -import ExternalUrlComponent from './environment_external_url.vue'; -import StopComponent from './environment_stop.vue'; -import RollbackComponent from './environment_rollback.vue'; -import TerminalButtonComponent from './environment_terminal_button.vue'; -import MonitoringButtonComponent from './environment_monitoring.vue'; -import CommitComponent from '../../vue_shared/components/commit.vue'; -import eventHub from '../event_hub'; - -/** - * Envrionment Item Component - * - * Renders a table row for each environment. - */ -const timeagoInstance = new Timeago(); - -export default { - components: { - userAvatarLink, - 'commit-component': CommitComponent, - 'actions-component': ActionsComponent, - 'external-url-component': ExternalUrlComponent, - 'stop-component': StopComponent, - 'rollback-component': RollbackComponent, - 'terminal-button-component': TerminalButtonComponent, - 'monitoring-button-component': MonitoringButtonComponent, - }, - - props: { - model: { - type: Object, - required: true, - default: () => ({}), + import Timeago from 'timeago.js'; + import _ from 'underscore'; + import userAvatarLink from '../../vue_shared/components/user_avatar/user_avatar_link.vue'; + import { humanize } from '../../lib/utils/text_utility'; + import ActionsComponent from './environment_actions.vue'; + import ExternalUrlComponent from './environment_external_url.vue'; + import StopComponent from './environment_stop.vue'; + import RollbackComponent from './environment_rollback.vue'; + import TerminalButtonComponent from './environment_terminal_button.vue'; + import MonitoringButtonComponent from './environment_monitoring.vue'; + import CommitComponent from '../../vue_shared/components/commit.vue'; + import eventHub from '../event_hub'; + + /** + * Envrionment Item Component + * + * Renders a table row for each environment. + */ + const timeagoInstance = new Timeago(); + + export default { + components: { + userAvatarLink, + 'commit-component': CommitComponent, + 'actions-component': ActionsComponent, + 'external-url-component': ExternalUrlComponent, + 'stop-component': StopComponent, + 'rollback-component': RollbackComponent, + 'terminal-button-component': TerminalButtonComponent, + 'monitoring-button-component': MonitoringButtonComponent, }, - canCreateDeployment: { - type: Boolean, - required: false, - default: false, + props: { + model: { + type: Object, + required: true, + default: () => ({}), + }, + + canCreateDeployment: { + type: Boolean, + required: false, + default: false, + }, + + canReadEnvironment: { + type: Boolean, + required: false, + default: false, + }, }, - canReadEnvironment: { - type: Boolean, - required: false, - default: false, - }, - }, - - computed: { - /** - * Verifies if `last_deployment` key exists in the current Envrionment. - * This key is required to render most of the html - this method works has - * an helper. - * - * @returns {Boolean} - */ - hasLastDeploymentKey() { - if (this.model && - this.model.last_deployment && - !_.isEmpty(this.model.last_deployment)) { - return true; - } - return false; - }, - - /** - * Verifies is the given environment has manual actions. - * Used to verify if we should render them or nor. - * - * @returns {Boolean|Undefined} - */ - hasManualActions() { - return this.model && - this.model.last_deployment && - this.model.last_deployment.manual_actions && - this.model.last_deployment.manual_actions.length > 0; - }, - - /** - * Returns the value of the `stop_action?` key provided in the response. - * - * @returns {Boolean} - */ - hasStopAction() { - return this.model && this.model['stop_action?']; - }, - - /** - * Verifies if the `deployable` key is present in `last_deployment` key. - * Used to verify whether we should or not render the rollback partial. - * - * @returns {Boolean|Undefined} - */ - canRetry() { - return this.model && - this.hasLastDeploymentKey && - this.model.last_deployment && - this.model.last_deployment.deployable; - }, - - /** - * Verifies if the date to be shown is present. - * - * @returns {Boolean|Undefined} - */ - canShowDate() { - return this.model && - this.model.last_deployment && - this.model.last_deployment.deployable && - this.model.last_deployment.deployable !== undefined; - }, - - /** - * Human readable date. - * - * @returns {String} - */ - createdDate() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.deployable && - this.model.last_deployment.deployable.created_at) { - return timeagoInstance.format(this.model.last_deployment.deployable.created_at); - } - return ''; - }, - - /** - * Returns the manual actions with the name parsed. - * - * @returns {Array.<Object>|Undefined} - */ - manualActions() { - if (this.hasManualActions) { - return this.model.last_deployment.manual_actions.map((action) => { - const parsedAction = { - name: humanize(action.name), - play_path: action.play_path, - playable: action.playable, - }; - return parsedAction; - }); - } - return []; - }, - - /** - * Builds the string used in the user image alt attribute. - * - * @returns {String} - */ - userImageAltDescription() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.user && - this.model.last_deployment.user.username) { - return `${this.model.last_deployment.user.username}'s avatar'`; - } - return ''; - }, - - /** - * If provided, returns the commit tag. - * - * @returns {String|Undefined} - */ - commitTag() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.tag) { - return this.model.last_deployment.tag; - } - return undefined; - }, - - /** - * If provided, returns the commit ref. - * - * @returns {Object|Undefined} - */ - commitRef() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.ref) { - return this.model.last_deployment.ref; - } - return undefined; - }, - - /** - * If provided, returns the commit url. - * - * @returns {String|Undefined} - */ - commitUrl() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.commit_path) { - return this.model.last_deployment.commit.commit_path; - } - return undefined; - }, - - /** - * If provided, returns the commit short sha. - * - * @returns {String|Undefined} - */ - commitShortSha() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.short_id) { - return this.model.last_deployment.commit.short_id; - } - return undefined; - }, - - /** - * If provided, returns the commit title. - * - * @returns {String|Undefined} - */ - commitTitle() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.title) { - return this.model.last_deployment.commit.title; - } - return undefined; - }, - - /** - * If provided, returns the commit tag. - * - * @returns {Object|Undefined} - */ - commitAuthor() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.commit && - this.model.last_deployment.commit.author) { - return this.model.last_deployment.commit.author; - } - - return undefined; - }, - - /** - * Verifies if the `retry_path` key is present and returns its value. - * - * @returns {String|Undefined} - */ - retryUrl() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.deployable && - this.model.last_deployment.deployable.retry_path) { - return this.model.last_deployment.deployable.retry_path; - } - return undefined; - }, - - /** - * Verifies if the `last?` key is present and returns its value. - * - * @returns {Boolean|Undefined} - */ - isLastDeployment() { - return this.model && this.model.last_deployment && - this.model.last_deployment['last?']; - }, - - /** - * Builds the name of the builds needed to display both the name and the id. - * - * @returns {String} - */ - buildName() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.deployable) { - const deployable = this.model.last_deployment.deployable; - return `${deployable.name} #${deployable.id}`; - } - return ''; + computed: { + /** + * Verifies if `last_deployment` key exists in the current Envrionment. + * This key is required to render most of the html - this method works has + * an helper. + * + * @returns {Boolean} + */ + hasLastDeploymentKey() { + if (this.model && + this.model.last_deployment && + !_.isEmpty(this.model.last_deployment)) { + return true; + } + return false; + }, + + /** + * Verifies is the given environment has manual actions. + * Used to verify if we should render them or nor. + * + * @returns {Boolean|Undefined} + */ + hasManualActions() { + return this.model && + this.model.last_deployment && + this.model.last_deployment.manual_actions && + this.model.last_deployment.manual_actions.length > 0; + }, + + /** + * Returns the value of the `stop_action?` key provided in the response. + * + * @returns {Boolean} + */ + hasStopAction() { + return this.model && this.model['stop_action?']; + }, + + /** + * Verifies if the `deployable` key is present in `last_deployment` key. + * Used to verify whether we should or not render the rollback partial. + * + * @returns {Boolean|Undefined} + */ + canRetry() { + return this.model && + this.hasLastDeploymentKey && + this.model.last_deployment && + this.model.last_deployment.deployable; + }, + + /** + * Verifies if the date to be shown is present. + * + * @returns {Boolean|Undefined} + */ + canShowDate() { + return this.model && + this.model.last_deployment && + this.model.last_deployment.deployable && + this.model.last_deployment.deployable !== undefined; + }, + + /** + * Human readable date. + * + * @returns {String} + */ + createdDate() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.deployable && + this.model.last_deployment.deployable.created_at) { + return timeagoInstance.format(this.model.last_deployment.deployable.created_at); + } + return ''; + }, + + /** + * Returns the manual actions with the name parsed. + * + * @returns {Array.<Object>|Undefined} + */ + manualActions() { + if (this.hasManualActions) { + return this.model.last_deployment.manual_actions.map((action) => { + const parsedAction = { + name: humanize(action.name), + play_path: action.play_path, + playable: action.playable, + }; + return parsedAction; + }); + } + return []; + }, + + /** + * Builds the string used in the user image alt attribute. + * + * @returns {String} + */ + userImageAltDescription() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.user && + this.model.last_deployment.user.username) { + return `${this.model.last_deployment.user.username}'s avatar'`; + } + return ''; + }, + + /** + * If provided, returns the commit tag. + * + * @returns {String|Undefined} + */ + commitTag() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.tag) { + return this.model.last_deployment.tag; + } + return undefined; + }, + + /** + * If provided, returns the commit ref. + * + * @returns {Object|Undefined} + */ + commitRef() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.ref) { + return this.model.last_deployment.ref; + } + return undefined; + }, + + /** + * If provided, returns the commit url. + * + * @returns {String|Undefined} + */ + commitUrl() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.commit_path) { + return this.model.last_deployment.commit.commit_path; + } + return undefined; + }, + + /** + * If provided, returns the commit short sha. + * + * @returns {String|Undefined} + */ + commitShortSha() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.short_id) { + return this.model.last_deployment.commit.short_id; + } + return undefined; + }, + + /** + * If provided, returns the commit title. + * + * @returns {String|Undefined} + */ + commitTitle() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.title) { + return this.model.last_deployment.commit.title; + } + return undefined; + }, + + /** + * If provided, returns the commit tag. + * + * @returns {Object|Undefined} + */ + commitAuthor() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.author) { + return this.model.last_deployment.commit.author; + } + + return undefined; + }, + + /** + * Verifies if the `retry_path` key is present and returns its value. + * + * @returns {String|Undefined} + */ + retryUrl() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.deployable && + this.model.last_deployment.deployable.retry_path) { + return this.model.last_deployment.deployable.retry_path; + } + return undefined; + }, + + /** + * Verifies if the `last?` key is present and returns its value. + * + * @returns {Boolean|Undefined} + */ + isLastDeployment() { + return this.model && this.model.last_deployment && + this.model.last_deployment['last?']; + }, + + /** + * Builds the name of the builds needed to display both the name and the id. + * + * @returns {String} + */ + buildName() { + if (this.model && + this.model.last_deployment && + this.model.last_deployment.deployable) { + const deployable = this.model.last_deployment.deployable; + return `${deployable.name} #${deployable.id}`; + } + return ''; + }, + + /** + * Builds the needed string to show the internal id. + * + * @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; + }, }, - /** - * Builds the needed string to show the internal id. - * - * @returns {String} - */ - deploymentInternalId() { - if (this.model && - this.model.last_deployment && - this.model.last_deployment.iid) { - return `#${this.model.last_deployment.iid}`; - } - return ''; + methods: { + onClickFolder() { + eventHub.$emit('toggleFolder', this.model); + }, }, - - /** - * 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> <template> <div @@ -428,18 +428,22 @@ export default { 'folder-row': model.isFolder, }" role="row"> - <div class="table-section section-10" role="gridcell"> + <div + class="table-section section-10" + role="gridcell" + > <div v-if="!model.isFolder" class="table-mobile-header" - role="rowheader"> - {{s__("Environments|Environment")}} + role="rowheader" + > + {{ s__("Environments|Environment") }} </div> <a v-if="!model.isFolder" class="environment-name flex-truncate-parent table-mobile-content" :href="environmentPath"> - <span class="flex-truncate-child">{{model.name}}</span> + <span class="flex-truncate-child">{{ model.name }}</span> </a> <span v-else @@ -451,17 +455,22 @@ export default { <i v-show="model.isOpen" class="fa fa-caret-down" - aria-hidden="true" /> + aria-hidden="true" + > + </i> <i v-show="!model.isOpen" class="fa fa-caret-right" - aria-hidden="true"/> + aria-hidden="true" + > + </i> </span> <span class="folder-icon"> <i class="fa fa-folder" - aria-hidden="true" /> + aria-hidden="true"> + </i> </span> <span> @@ -491,22 +500,29 @@ export default { </span> </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 v-if="shouldRenderBuildName" class="build-link flex-truncate-parent" - :href="buildPath"> - <span class="flex-truncate-child">{{buildName}}</span> + :href="buildPath" + > + <span class="flex-truncate-child">{{ buildName }}</span> </a> </div> <div v-if="!model.isFolder" - class="table-section section-25" role="gridcell"> + class="table-section section-25" + role="gridcell" + > <div role="rowheader" - class="table-mobile-header"> - {{s__("Environments|Commit")}} + class="table-mobile-header" + > + {{ s__("Environments|Commit") }} </div> <div v-if="hasLastDeploymentKey" @@ -522,22 +538,24 @@ export default { <div v-if="!hasLastDeploymentKey" class="commit-title table-mobile-content"> - {{s__("Environments|No deployments yet")}} + {{ s__("Environments|No deployments yet") }} </div> </div> <div v-if="!model.isFolder" - class="table-section section-10" role="gridcell"> + class="table-section section-10" + role="gridcell" + > <div role="rowheader" class="table-mobile-header"> - {{s__("Environments|Updated")}} + {{ s__("Environments|Updated") }} </div> <span v-if="canShowDate" class="environment-created-date-timeago table-mobile-content"> - {{createdDate}} + {{ createdDate }} </span> </div> @@ -553,33 +571,33 @@ export default { <actions-component v-if="hasManualActions && canCreateDeployment" :actions="manualActions" - /> + /> <external-url-component v-if="externalURL && canReadEnvironment" :external-url="externalURL" - /> + /> <monitoring-button-component v-if="monitoringUrl && canReadEnvironment" :monitoring-url="monitoringUrl" - /> + /> <terminal-button-component v-if="model && model.terminal_path" :terminal-path="model.terminal_path" - /> + /> <stop-component v-if="hasStopAction && canCreateDeployment" :stop-url="model.stop_path" - /> + /> <rollback-component v-if="canRetry && canCreateDeployment" :is-last-deployment="isLastDeployment" :retry-url="retryUrl" - /> + /> </div> </div> </div> diff --git a/app/assets/javascripts/issue_show/components/description.vue b/app/assets/javascripts/issue_show/components/description.vue index 317020f25eb..9afa9dea126 100644 --- a/app/assets/javascripts/issue_show/components/description.vue +++ b/app/assets/javascripts/issue_show/components/description.vue @@ -56,7 +56,10 @@ this.updateTaskStatusText(); }, }, - + mounted() { + this.renderGFM(); + this.updateTaskStatusText(); + }, methods: { renderGFM() { $(this.$refs['gfm-content']).renderGFM(); @@ -91,7 +94,7 @@ $tasksShort.text( `${taskRegexMatches[1]}/${taskRegexMatches[2]} task${taskRegexMatches[2] > 1 ? 's' : - ''}` + ''}`, ); } else { $tasks.text(''); @@ -99,10 +102,6 @@ } }, }, - mounted() { - this.renderGFM(); - this.updateTaskStatusText(); - }, }; </script> @@ -112,7 +111,8 @@ class="description" :class="{ 'js-task-list-container': canUpdate - }"> + }" + > <div class="wiki" :class="{ diff --git a/app/assets/javascripts/issue_show/components/edited.vue b/app/assets/javascripts/issue_show/components/edited.vue index 992b7064c13..01097b5b35e 100644 --- a/app/assets/javascripts/issue_show/components/edited.vue +++ b/app/assets/javascripts/issue_show/components/edited.vue @@ -1,33 +1,33 @@ <script> -import timeAgoTooltip from '../../vue_shared/components/time_ago_tooltip.vue'; + import timeAgoTooltip from '../../vue_shared/components/time_ago_tooltip.vue'; -export default { - props: { - updatedAt: { - type: String, - required: false, - default: '', + export default { + components: { + timeAgoTooltip, }, - updatedByName: { - type: String, - required: false, - default: '', + props: { + updatedAt: { + type: String, + required: false, + default: '', + }, + updatedByName: { + type: String, + required: false, + default: '', + }, + updatedByPath: { + type: String, + required: false, + default: '', + }, }, - updatedByPath: { - type: String, - required: false, - default: '', + computed: { + hasUpdatedBy() { + return this.updatedByName && this.updatedByPath; + }, }, - }, - components: { - timeAgoTooltip, - }, - computed: { - hasUpdatedBy() { - return this.updatedByName && this.updatedByPath; - }, - }, -}; + }; </script> <template> @@ -48,7 +48,7 @@ export default { class="author_link" :href="updatedByPath" > - <span>{{updatedByName}}</span> + <span>{{ updatedByName }}</span> </a> </span> </small> diff --git a/app/assets/javascripts/issue_show/components/fields/description.vue b/app/assets/javascripts/issue_show/components/fields/description.vue index 4e577546551..7cfdefa0eb6 100644 --- a/app/assets/javascripts/issue_show/components/fields/description.vue +++ b/app/assets/javascripts/issue_show/components/fields/description.vue @@ -4,6 +4,9 @@ export default { mixins: [updateMixin], + components: { + markdownField, + }, props: { formState: { type: Object, @@ -28,9 +31,6 @@ default: true, }, }, - components: { - markdownField, - }, mounted() { this.$refs.textarea.focus(); }, diff --git a/app/assets/javascripts/issue_show/components/form.vue b/app/assets/javascripts/issue_show/components/form.vue index 0fa19022336..779705e19ac 100644 --- a/app/assets/javascripts/issue_show/components/form.vue +++ b/app/assets/javascripts/issue_show/components/form.vue @@ -6,6 +6,13 @@ import descriptionTemplate from './fields/description_template.vue'; export default { + components: { + lockedWarning, + titleField, + descriptionField, + descriptionTemplate, + editActions, + }, props: { canDestroy: { type: Boolean, @@ -52,13 +59,6 @@ default: true, }, }, - components: { - lockedWarning, - titleField, - descriptionField, - descriptionTemplate, - editActions, - }, computed: { hasIssuableTemplates() { return this.issuableTemplates.length; @@ -78,16 +78,19 @@ :form-state="formState" :issuable-templates="issuableTemplates" :project-path="projectPath" - :project-namespace="projectNamespace" /> + :project-namespace="projectNamespace" + /> </div> <div :class="{ 'col-sm-8 col-lg-9': hasIssuableTemplates, 'col-xs-12': !hasIssuableTemplates, - }"> + }" + > <title-field :form-state="formState" - :issuable-templates="issuableTemplates" /> + :issuable-templates="issuableTemplates" + /> </div> </div> <description-field @@ -100,6 +103,7 @@ <edit-actions :form-state="formState" :can-destroy="canDestroy" - :show-delete-button="showDeleteButton" /> + :show-delete-button="showDeleteButton" + /> </form> </template> diff --git a/app/assets/javascripts/issue_show/components/title.vue b/app/assets/javascripts/issue_show/components/title.vue index b7e6eadd440..982c72e0fd1 100644 --- a/app/assets/javascripts/issue_show/components/title.vue +++ b/app/assets/javascripts/issue_show/components/title.vue @@ -6,12 +6,8 @@ export default { mixins: [animateMixin], - data() { - return { - preAnimation: false, - pulseAnimation: false, - titleEl: document.querySelector('title'), - }; + directives: { + tooltip, }, props: { issuableRef: { @@ -37,8 +33,17 @@ default: false, }, }, - directives: { - tooltip, + data() { + return { + preAnimation: false, + pulseAnimation: false, + titleEl: document.querySelector('title'), + }; + }, + computed: { + pencilIcon() { + return spriteIcon('pencil', 'link-highlight'); + }, }, watch: { titleHtml() { @@ -46,11 +51,6 @@ this.animateChange(); }, }, - computed: { - pencilIcon() { - return spriteIcon('pencil', 'link-highlight'); - }, - }, methods: { setPageTitle() { const currentPageTitleScope = this.titleEl.innerText.split('ยท'); @@ -85,7 +85,7 @@ data-placement="bottom" data-container="body" @click="edit" - > + > </button> </div> </template> diff --git a/app/assets/javascripts/jobs/components/header.vue b/app/assets/javascripts/jobs/components/header.vue index 6d671845f8e..39696976952 100644 --- a/app/assets/javascripts/jobs/components/header.vue +++ b/app/assets/javascripts/jobs/components/header.vue @@ -4,6 +4,10 @@ export default { name: 'jobHeaderSection', + components: { + ciHeader, + loadingIcon, + }, props: { job: { type: Object, @@ -14,10 +18,6 @@ required: true, }, }, - components: { - ciHeader, - loadingIcon, - }, data() { return { actions: this.getActions(), @@ -31,6 +31,11 @@ return !this.isLoading && Object.keys(this.job).length; }, }, + watch: { + job() { + this.actions = this.getActions(); + }, + }, methods: { getActions() { const actions = []; @@ -46,11 +51,6 @@ return actions; }, }, - watch: { - job() { - this.actions = this.getActions(); - }, - }, }; </script> <template> @@ -63,11 +63,11 @@ :time="job.created_at" :user="job.user" :actions="actions" - :hasSidebarButton="true" - /> + :has-sidebar-button="true" + /> <loading-icon v-if="isLoading" size="2" - /> + /> </div> </template> diff --git a/app/assets/javascripts/jobs/components/sidebar_detail_row.vue b/app/assets/javascripts/jobs/components/sidebar_detail_row.vue index ab2bcd728a8..a6819aaeb12 100644 --- a/app/assets/javascripts/jobs/components/sidebar_detail_row.vue +++ b/app/assets/javascripts/jobs/components/sidebar_detail_row.vue @@ -23,9 +23,10 @@ <p class="build-detail-row"> <span v-if="hasTitle" - class="build-light-text"> - {{title}}: + class="build-light-text" + > + {{ title }}: </span> - {{value}} + {{ value }} </p> </template> diff --git a/app/assets/javascripts/jobs/components/sidebar_details_block.vue b/app/assets/javascripts/jobs/components/sidebar_details_block.vue index d0145fed396..56814a52525 100644 --- a/app/assets/javascripts/jobs/components/sidebar_details_block.vue +++ b/app/assets/javascripts/jobs/components/sidebar_details_block.vue @@ -6,6 +6,13 @@ export default { name: 'SidebarDetailsBlock', + components: { + detailRow, + loadingIcon, + }, + mixins: [ + timeagoMixin, + ], props: { job: { type: Object, @@ -16,13 +23,6 @@ required: true, }, }, - mixins: [ - timeagoMixin, - ], - components: { - detailRow, - loadingIcon, - }, computed: { shouldRenderContent() { return !this.isLoading && Object.keys(this.job).length > 0; @@ -58,11 +58,13 @@ <template v-if="shouldRenderContent"> <div class="block retry-link" - v-if="job.retry_path || job.new_issue_path"> + v-if="job.retry_path || job.new_issue_path" + > <a v-if="job.new_issue_path" class="js-new-issue btn btn-new btn-inverted" - :href="job.new_issue_path"> + :href="job.new_issue_path" + > New issue </a> <a @@ -70,20 +72,21 @@ class="js-retry-job btn btn-inverted-secondary" :href="job.retry_path" data-method="post" - rel="nofollow"> + rel="nofollow" + > Retry </a> </div> <div :class="{block : renderBlock }"> <p class="build-detail-row js-job-mr" - v-if="job.merge_request"> - <span - class="build-light-text"> + v-if="job.merge_request" + > + <span class="build-light-text"> Merge Request: </span> <a :href="job.merge_request.path"> - !{{job.merge_request.iid}} + !{{ job.merge_request.iid }} </a> </p> @@ -92,49 +95,49 @@ v-if="job.duration" title="Duration" :value="duration" - /> + /> <detail-row class="js-job-finished" v-if="job.finished_at" title="Finished" :value="timeFormated(job.finished_at)" - /> + /> <detail-row class="js-job-erased" v-if="job.erased_at" title="Erased" :value="timeFormated(job.erased_at)" - /> + /> <detail-row class="js-job-queued" v-if="job.queued" title="Queued" :value="queued" - /> + /> <detail-row class="js-job-runner" v-if="job.runner" title="Runner" :value="runnerId" - /> + /> <detail-row class="js-job-coverage" v-if="job.coverage" title="Coverage" :value="coverage" - /> + /> <p class="build-detail-row js-job-tags" - v-if="job.tags.length"> - <span - class="build-light-text"> + v-if="job.tags.length" + > + <span class="build-light-text"> Tags: </span> <span - v-for="tag in job.tags" - key="tag" + v-for="(tag, i) in job.tags" + :key="i" class="label label-primary"> - {{tag}} + {{ tag }} </span> </p> @@ -146,7 +149,8 @@ class="js-cancel-job btn btn-sm btn-default" :href="job.cancel_path" data-method="post" - rel="nofollow"> + rel="nofollow" + > Cancel </a> </div> @@ -156,6 +160,6 @@ class="prepend-top-10" v-if="isLoading" size="2" - /> + /> </div> </template> diff --git a/app/assets/javascripts/monitoring/components/dashboard.vue b/app/assets/javascripts/monitoring/components/dashboard.vue index 8da723ced03..025e38ea99a 100644 --- a/app/assets/javascripts/monitoring/components/dashboard.vue +++ b/app/assets/javascripts/monitoring/components/dashboard.vue @@ -11,6 +11,12 @@ export default { + components: { + Graph, + GraphGroup, + EmptyState, + }, + data() { const metricsData = document.querySelector('#prometheus-graphs').dataset; const store = new MonitoringStore(); @@ -36,12 +42,30 @@ }; }, - components: { - Graph, - GraphGroup, - EmptyState, + 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); + } + }, methods: { getGraphsData() { this.state = 'loading'; @@ -72,36 +96,14 @@ 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> <template> - <div v-if="!showEmptyState" class="prometheus-graphs"> + <div + v-if="!showEmptyState" + class="prometheus-graphs" + > <graph-group v-for="(groupData, index) in store.groups" :key="index" diff --git a/app/assets/javascripts/monitoring/components/empty_state.vue b/app/assets/javascripts/monitoring/components/empty_state.vue index 9df7094b6ab..87d1975d5ad 100644 --- a/app/assets/javascripts/monitoring/components/empty_state.vue +++ b/app/assets/javascripts/monitoring/components/empty_state.vue @@ -76,20 +76,26 @@ If this takes a long time, ensure that data is available.`, <template> <div class="prometheus-state"> <div class="state-svg svg-content"> - <img :src="currentState.svgUrl"/> + <img :src="currentState.svgUrl" /> </div> <h4 class="state-title"> - {{currentState.title}} + {{ currentState.title }} </h4> <p class="state-description"> - {{currentState.description}} - <a v-if="showButtonDescription" :href="settingsPath"> + {{ currentState.description }} + <a + v-if="showButtonDescription" + :href="settingsPath" + > Prometheus server </a> </p> <div class="state-button"> - <a class="btn btn-success" :href="buttonPath"> - {{currentState.buttonText}} + <a + class="btn btn-success" + :href="buttonPath" + > + {{ currentState.buttonText }} </a> </div> </div> diff --git a/app/assets/javascripts/monitoring/components/graph.vue b/app/assets/javascripts/monitoring/components/graph.vue index eede04a06cd..72925ec6d23 100644 --- a/app/assets/javascripts/monitoring/components/graph.vue +++ b/app/assets/javascripts/monitoring/components/graph.vue @@ -3,10 +3,10 @@ import { axisLeft, axisBottom } from 'd3-axis'; import { max, extent } from 'd3-array'; import { select } from 'd3-selection'; - import GraphLegend from './graph/legend.vue'; - import GraphFlag from './graph/flag.vue'; - import GraphDeployment from './graph/deployment.vue'; - import GraphPath from './graph/path.vue'; + import graphLegend from './graph/legend.vue'; + import graphFlag from './graph/flag.vue'; + import graphDeployment from './graph/deployment.vue'; + import graphPath from './graph/path.vue'; import MonitoringMixin from '../mixins/monitoring_mixins'; import eventHub from '../event_hub'; import measurements from '../utils/measurements'; @@ -17,6 +17,16 @@ const d3 = { scaleLinear, scaleTime, axisLeft, axisBottom, max, extent, select }; export default { + components: { + graphLegend, + graphFlag, + graphDeployment, + graphPath, + }, + + mixins: [MonitoringMixin], + + props: { graphData: { type: Object, @@ -45,8 +55,6 @@ }, }, - mixins: [MonitoringMixin], - data() { return { baseGraphHeight: 450, @@ -74,13 +82,6 @@ }; }, - components: { - GraphLegend, - GraphFlag, - GraphDeployment, - GraphPath, - }, - computed: { outerViewBox() { return `0 0 ${this.baseGraphWidth} ${this.baseGraphHeight}`; @@ -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: { draw() { const breakpointSize = bp.getBreakpointSize(); @@ -192,36 +213,16 @@ }); // 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> <template> - <div + <div class="prometheus-graph" @mouseover="showFlagContent = true" @mouseleave="showFlagContent = false"> <h5 class="text-center graph-title"> - {{graphData.title}} + {{ graphData.title }} </h5> <div class="prometheus-svg-container" @@ -231,12 +232,12 @@ ref="baseSvg"> <g class="x-axis" - :transform="axisTransform"> - </g> + :transform="axisTransform" + /> <g class="y-axis" - transform="translate(70, 20)"> - </g> + transform="translate(70, 20)" + /> <graph-legend :graph-width="graphWidth" :graph-height="graphHeight" @@ -251,40 +252,41 @@ <svg class="graph-data" :viewBox="innerViewBox" - ref="graphData"> - <graph-path - v-for="(path, index) in timeSeries" - :key="index" - :generated-line-path="path.linePath" - :generated-area-path="path.areaPath" - :line-style="path.lineStyle" - :line-color="path.lineColor" - :area-color="path.areaColor" - /> - <rect - class="prometheus-graph-overlay" - :width="(graphWidth - 70)" - :height="(graphHeight - 100)" - transform="translate(-5, 20)" - ref="graphOverlay" - @mousemove="handleMouseOverGraph($event)"> - </rect> - <graph-deployment - :show-deploy-info="showDeployInfo" - :deployment-data="reducedDeploymentData" - :graph-width="graphWidth" - :graph-height="graphHeight" - :graph-height-offset="graphHeightOffset" - /> - <graph-flag - v-if="showFlag" - :current-x-coordinate="currentXCoordinate" - :current-data="currentData" - :current-flag-position="currentFlagPosition" - :graph-height="graphHeight" - :graph-height-offset="graphHeightOffset" - :show-flag-content="showFlagContent" - /> + ref="graphData" + > + <graph-path + v-for="(path, index) in timeSeries" + :key="index" + :generated-line-path="path.linePath" + :generated-area-path="path.areaPath" + :line-style="path.lineStyle" + :line-color="path.lineColor" + :area-color="path.areaColor" + /> + <rect + class="prometheus-graph-overlay" + :width="(graphWidth - 70)" + :height="(graphHeight - 100)" + transform="translate(-5, 20)" + ref="graphOverlay" + @mousemove="handleMouseOverGraph($event)" + /> + <graph-deployment + :show-deploy-info="showDeployInfo" + :deployment-data="reducedDeploymentData" + :graph-width="graphWidth" + :graph-height="graphHeight" + :graph-height-offset="graphHeightOffset" + /> + <graph-flag + v-if="showFlag" + :current-x-coordinate="currentXCoordinate" + :current-data="currentData" + :current-flag-position="currentFlagPosition" + :graph-height="graphHeight" + :graph-height-offset="graphHeightOffset" + :show-flag-content="showFlagContent" + /> </svg> </svg> </div> diff --git a/app/assets/javascripts/monitoring/components/graph/deployment.vue b/app/assets/javascripts/monitoring/components/graph/deployment.vue index 026e2fd0c49..0ce5464dd1e 100644 --- a/app/assets/javascripts/monitoring/components/graph/deployment.vue +++ b/app/assets/javascripts/monitoring/components/graph/deployment.vue @@ -1,8 +1,11 @@ <script> 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 { + components: { + icon, + }, props: { showDeployInfo: { type: Boolean, @@ -26,10 +29,6 @@ }, }, - components: { - Icon, - }, - computed: { calculatedHeight() { return this.graphHeight - this.graphHeightOffset; @@ -83,51 +82,55 @@ v-for="(deployment, index) in deploymentData" :key="index" :class="nameDeploymentClass(deployment)" - :transform="transformDeploymentGroup(deployment)"> + :transform="transformDeploymentGroup(deployment)" + > <rect x="0" y="0" :height="calculatedHeight" width="3" - fill="url(#shadow-gradient)"> - </rect> + fill="url(#shadow-gradient)" + /> <line class="deployment-line" x1="0" y1="0" x2="0" :y2="calculatedHeight" - stroke="#000"> - </line> + stroke="#000" + /> <svg v-if="deployment.showDeploymentFlag" class="js-deploy-info-box" :x="positionFlag(deployment)" y="0" width="134" - :height="svgContainerHeight(deployment.tag)"> + :height="svgContainerHeight(deployment.tag)" + > <rect class="rect-text-metric deploy-info-rect rect-metric" x="1" y="1" rx="2" width="132" - :height="svgContainerHeight(deployment.tag) - 2"> - </rect> + :height="svgContainerHeight(deployment.tag) - 2" + /> <text class="deploy-info-text text-metric-bold" - transform="translate(5, 2)"> + transform="translate(5, 2)" + > Deployed </text> <!--The date info--> <g transform="translate(5, 20)"> <text class="deploy-info-text"> - {{formatDate(deployment.time)}} + {{ formatDate(deployment.time) }} </text> - <text + <text class="deploy-info-text text-metric-bold" - x="62"> - {{formatTime(deployment.time)}} + x="62" + > + {{ formatTime(deployment.time) }} </text> </g> <line @@ -136,40 +139,41 @@ y1="38" x2="132" :y2="38" - stroke="#000"> - </line> + stroke="#000" + /> <!--Commit information--> <g transform="translate(5, 40)"> <icon name="commit" :width="12" :height="12" - :y="3"> - </icon> + :y="3" + /> <a :xlink:href="deployment.commitUrl"> <text class="deploy-info-text deploy-info-text-link" transform="translate(20, 2)"> - {{refText(deployment)}} + {{ refText(deployment) }} </text> </a> </g> <!--Tag information--> <g - transform="translate(5, 55)" + transform="translate(5, 55)" v-if="deployment.tag"> <icon name="label" :width="12" :height="12" - :y="5"> - </icon> + :y="5" + /> <a :xlink:href="deployment.tagUrl"> <text class="deploy-info-text deploy-info-text-link" transform="translate(20, 2)" - y="2"> - {{deployment.tag}} + y="2" + > + {{ deployment.tag }} </text> </a> </g> @@ -177,20 +181,20 @@ </g> <svg height="0" - width="0"> + width="0" + > <defs> - <linearGradient - id="shadow-gradient"> + <linearGradient id="shadow-gradient"> <stop offset="0%" stop-color="#000" - stop-opacity="0.4"> - </stop> + stop-opacity="0.4" + /> <stop offset="100%" stop-color="#000" - stop-opacity="0"> - </stop> + stop-opacity="0" + /> </linearGradient> </defs> </svg> diff --git a/app/assets/javascripts/monitoring/components/graph/flag.vue b/app/assets/javascripts/monitoring/components/graph/flag.vue index 10fb7ff6803..f57dc787d3a 100644 --- a/app/assets/javascripts/monitoring/components/graph/flag.vue +++ b/app/assets/javascripts/monitoring/components/graph/flag.vue @@ -58,13 +58,14 @@ :y1="0" :x2="currentXCoordinate" :y2="calculatedHeight" - transform="translate(-5, 20)"> - </line> - <svg + transform="translate(-5, 20)" + /> + <svg v-if="showFlagContent" class="rect-text-metric" :x="currentFlagPosition" - y="0"> + y="0" + > <rect class="rect-metric" x="4" @@ -72,21 +73,23 @@ rx="2" width="90" height="40" - transform="translate(-3, 20)"> - </rect> + transform="translate(-3, 20)" + /> <text class="text-metric text-metric-bold" x="16" y="35" - transform="translate(-5, 20)"> - {{formatTime}} + transform="translate(-5, 20)" + > + {{ formatTime }} </text> <text class="text-metric" x="16" y="15" - transform="translate(-5, 20)"> - {{formatDate}} + transform="translate(-5, 20)" + > + {{ formatDate }} </text> </svg> </g> diff --git a/app/assets/javascripts/monitoring/components/graph/legend.vue b/app/assets/javascripts/monitoring/components/graph/legend.vue index 440b1b12631..c6e8d726ffc 100644 --- a/app/assets/javascripts/monitoring/components/graph/legend.vue +++ b/app/assets/javascripts/monitoring/components/graph/legend.vue @@ -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: { translateLegendGroup(index) { return `translate(0, ${12 * (index)})`; @@ -100,26 +115,10 @@ 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> <template> - <g - class="axis-label-container"> + <g class="axis-label-container"> <line class="label-x-axis-line" stroke="#000000" @@ -127,8 +126,8 @@ x1="10" :y1="yPosition" :x2="graphWidth + 20" - :y2="yPosition"> - </line> + :y2="yPosition" + /> <line class="label-y-axis-line" stroke="#000000" @@ -136,39 +135,43 @@ x1="10" y1="0" :x2="10" - :y2="yPosition"> - </line> + :y2="yPosition" + /> <rect class="rect-axis-text" :transform="rectTransform" :width="yLabelWidth" - :height="yLabelHeight"> - </rect> + :height="yLabelHeight" + /> <text class="label-axis-text y-label-text" text-anchor="middle" :transform="textTransform" - ref="ylabel"> - {{yAxisLabel}} + ref="ylabel" + > + {{ yAxisLabel }} </text> <rect class="rect-axis-text" :x="xPosition + 60" :y="graphHeight - 80" width="35" - height="50"> - </rect> + height="50" + /> <text class="label-axis-text x-label-text" :x="xPosition + 60" :y="yPosition" - dy=".35em"> + dy=".35em" + > Time </text> - <g class="legend-group" + <g + class="legend-group" v-for="(series, index) in timeSeries" :key="index" - :transform="translateLegendGroup(index)"> + :transform="translateLegendGroup(index)" + > <line :stroke="series.lineColor" :stroke-width="measurements.legends.height" @@ -176,23 +179,25 @@ :x1="measurements.legends.offsetX" :x2="measurements.legends.offsetX + measurements.legends.width" :y1="graphHeight - measurements.legends.offsetY" - :y2="graphHeight - measurements.legends.offsetY"> - </line> + :y2="graphHeight - measurements.legends.offsetY" + /> <text v-if="timeSeries.length > 1" class="legend-metric-title" ref="legendTitleSvg" x="38" - :y="graphHeight - 30"> - {{createSeriesString(index, series)}} + :y="graphHeight - 30" + > + {{ createSeriesString(index, series) }} </text> <text v-else class="legend-metric-title" ref="legendTitleSvg" x="38" - :y="graphHeight - 30"> - {{legendTitle}} {{formatMetricUsage(series)}} + :y="graphHeight - 30" + > + {{ legendTitle }} {{ formatMetricUsage(series) }} </text> </g> </g> diff --git a/app/assets/javascripts/monitoring/components/graph/path.vue b/app/assets/javascripts/monitoring/components/graph/path.vue index 5e6d409033a..c9721c4cb01 100644 --- a/app/assets/javascripts/monitoring/components/graph/path.vue +++ b/app/assets/javascripts/monitoring/components/graph/path.vue @@ -12,6 +12,7 @@ lineStyle: { type: String, required: false, + default: '', }, lineColor: { type: String, @@ -37,8 +38,8 @@ class="metric-area" :d="generatedAreaPath" :fill="areaColor" - transform="translate(-5, 20)"> - </path> + transform="translate(-5, 20)" + /> <path class="metric-line" :d="generatedLinePath" @@ -46,7 +47,7 @@ fill="none" stroke-width="1" :stroke-dasharray="strokeDashArray" - transform="translate(-5, 20)"> - </path> + transform="translate(-5, 20)" + /> </g> </template> diff --git a/app/assets/javascripts/monitoring/components/graph_group.vue b/app/assets/javascripts/monitoring/components/graph_group.vue index 958f537d31b..c52bbf56af9 100644 --- a/app/assets/javascripts/monitoring/components/graph_group.vue +++ b/app/assets/javascripts/monitoring/components/graph_group.vue @@ -1,18 +1,18 @@ <script> -export default { - props: { - name: { - type: String, - required: true, + export default { + props: { + name: { + type: String, + required: true, + }, }, - }, -}; + }; </script> <template> <div class="panel panel-default prometheus-panel"> <div class="panel-heading"> - <h4>{{name}}</h4> + <h4>{{ name }}</h4> </div> <div class="panel-body prometheus-graph-group"> <slot /> diff --git a/app/assets/javascripts/notes/components/note_actions.vue b/app/assets/javascripts/notes/components/note_actions.vue index b96d4db8848..46ffb60aa60 100644 --- a/app/assets/javascripts/notes/components/note_actions.vue +++ b/app/assets/javascripts/notes/components/note_actions.vue @@ -64,6 +64,13 @@ return this.getUserDataByProp('id'); }, }, + created() { + this.emojiSmiling = emojiSmiling; + this.emojiSmile = emojiSmile; + this.emojiSmiley = emojiSmiley; + this.editSvg = editSvg; + this.ellipsisSvg = ellipsisSvg; + }, methods: { onEdit() { this.$emit('handleEdit'); @@ -72,13 +79,6 @@ this.$emit('handleDelete'); }, }, - created() { - this.emojiSmiling = emojiSmiling; - this.emojiSmile = emojiSmile; - this.emojiSmiley = emojiSmiley; - this.editSvg = editSvg; - this.ellipsisSvg = ellipsisSvg; - }, }; </script> @@ -86,7 +86,9 @@ <div class="note-actions"> <span v-if="accessLevel" - class="note-role user-access-role">{{accessLevel}}</span> + class="note-role user-access-role"> + {{ accessLevel }} + </span> <div v-if="canAddAwardEmoji" class="note-actions-item"> @@ -126,10 +128,10 @@ class="note-action-button js-note-edit btn btn-transparent" data-container="body" data-placement="bottom"> - <span - v-html="editSvg" - class="link-highlight"> - </span> + <span + v-html="editSvg" + class="link-highlight"> + </span> </button> </div> <div @@ -143,10 +145,10 @@ data-toggle="dropdown" data-container="body" data-placement="bottom"> - <span - class="icon" - v-html="ellipsisSvg"> - </span> + <span + class="icon" + v-html="ellipsisSvg"> + </span> </button> <ul class="dropdown-menu more-actions-dropdown dropdown-open-left"> <li v-if="canReportAsAbuse"> |