From 3fef5e66dba055e32dda1ccc887ad630d1e61c87 Mon Sep 17 00:00:00 2001 From: Filipa Lacerda <filipa@gitlab.com> Date: Wed, 9 Nov 2016 10:55:00 +0000 Subject: [PATCH] Adds template functions Adds commit component --- .../components/environment_item.js.es6 | 185 +++++++++++++++++- .../environments/environments_bundle.js.es6 | 4 +- .../vue_common_component/commit.js.es6 | 173 ++++++++++++++++ .../projects/environments/index.html.haml | 6 +- .../environments_store_spec.js.es6 | 2 +- 5 files changed, 358 insertions(+), 12 deletions(-) create mode 100644 app/assets/javascripts/vue_common_component/commit.js.es6 diff --git a/app/assets/javascripts/environments/components/environment_item.js.es6 b/app/assets/javascripts/environments/components/environment_item.js.es6 index 633a71ea9a1..29c0316228e 100644 --- a/app/assets/javascripts/environments/components/environment_item.js.es6 +++ b/app/assets/javascripts/environments/components/environment_item.js.es6 @@ -1,4 +1,6 @@ +/*= require vue_common_component/commit /* globals Vue */ + (() => { /** * Envrionment Item Component @@ -16,7 +18,9 @@ gl.environmentsList.EnvironmentItem = Vue.component('environment-item', { - template: '#environment-item-template', + components: { + 'commit-component': window.gl.commitComponent, + }, props: { model: Object, @@ -25,6 +29,9 @@ data() { return { open: false, + rowClass: { + 'children-row': this.model['vue-isChildren'], + }, }; }, @@ -38,7 +45,8 @@ * @returns {Boolean} */ isFolder() { - return this.$options.hasKey(this.model, 'children') && this.model.children.length > 0; + return this.$options.hasKey(this.model, 'children') && + this.model.children.length > 0; }, /** @@ -58,7 +66,8 @@ * @returns {Boolean} The number of environments for the current folder */ childrenCounter() { - return this.$options.hasKey(this.model, 'children') && this.model.children.length; + return this.$options.hasKey(this.model, 'children') && + this.model.children.length; }, /** @@ -68,7 +77,8 @@ * @returns {Boolean} */ isLast() { - return this.$options.hasKey(this.model, 'last_deployment') && this.model.last_deployment['last?']; + return this.$options.hasKey(this.model, 'last_deployment') && + this.model.last_deployment['last?']; }, /** @@ -89,7 +99,8 @@ * @returns {Boolean} */ hasManualActions() { - return this.$options.hasKey(this.model, 'manual_actions') && this.model.manual_actions.length; + return this.$options.hasKey(this.model, 'manual_actions') && + this.model.manual_actions.length; }, /** @@ -108,7 +119,9 @@ * @returns {Boolean} */ canRetry() { - return this.hasLastDeploymentKey && this.model.last_deployment && this.$options.hasKey(this.model.last_deployment, 'deployable'); + return this.hasLastDeploymentKey && + this.model.last_deployment && + this.$options.hasKey(this.model.last_deployment, 'deployable'); }, /** @@ -134,6 +147,85 @@ return parsedAction; }); }, + + userImageAltDescription() { + return `${this.model.last_deployment.user.username}'s avatar'`; + }, + + + /** + * If provided, returns the commit tag. + * + * @returns {String|Undefined} + */ + commitTag() { + if (this.model.last_deployment && this.model.last_deployment.tag) { + return this.model.last_deployment.tag; + } + }, + + /** + * If provided, returns the commit ref. + * + * @returns {Object|Undefined} + */ + commitRef() { + if (this.model.last_deployment && this.model.last_deployment.ref) { + return this.model.last_deployment.ref + } + }, + + /** + * If provided, returns the commit url. + * + * @returns {String|Undefined} + */ + commitUrl() { + if (this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.commit_url) { + return this.model.last_deployment.commit.commit_url; + } + }, + + /** + * If provided, returns the commit short sha. + * + * @returns {String|Undefined} + */ + commitShortSha() { + if (this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.short_id) { + return this.model.last_deployment.commit.short_id + } + }, + + /** + * If provided, returns the commit title. + * + * @returns {String|Undefined} + */ + commitTitle(){ + if (this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.title) { + return this.model.last_deployment.commit.title + } + }, + + /** + * If provided, returns the commit tag. + * + * @returns {Object|Undefined} + */ + commitAuthor(){ + if (this.model.last_deployment && + this.model.last_deployment.commit && + this.model.last_deployment.commit.author) { + return this.model.last_deployment.commit.author; + } + }, }, /** @@ -149,7 +241,6 @@ }, methods: { - /** * Toggles the visibility of a folders' children. */ @@ -159,5 +250,85 @@ } }, }, + + template: ` + <tr> + <td v-bind:class="rowClass"> + <a v-if="!isFolder" class="environment-name" :href="model.environment_url"> + {{model.name}} + </a> + <span v-else v-on:click="toggle" class="folder-name"> + <span class="folder-icon"> + <i v-show="open" class="fa fa-caret-down"></i> + <i v-show="!open" class="fa fa-caret-right"></i> + </span> + + {{model.name}} + + <span class="badge"> + {{childrenCounter}} + </span> + </span> + </td> + + <td class="deployment-column"> + <span v-if="!isFolder && model.last_deployment && model.last_deployment.iid"> + #{{model.last_deployment.iid}} + + <span v-if="model.last_deployment.user"> + by + <a :href="model.last_deployment.user.web_url"> + <img class="avatar has-tooltip s20" + :src="model.last_deployment.user.avatar_url" + :alt="userImageAltDescription" + :title="model.last_deployment.user.username" /> + </a> + </span> + </span> + </td> + + <td> + <a v-if="!isFolder && model.last_deployment && model.last_deployment.deployable" + class="build-link" + :href="model.last_deployment.deployable.build_url"> + {{model.last_deployment.deployable.name}} #{{model.last_deployment.deployable.id}} + </a> + </td> + + <td> + <div v-if="!isFolder && model.last_deployment"> + <commit-component + :tag="commitTag" + :ref="commitRef" + :commit_url="commitUrl" + :short_sha="commitShortSha" + :title="commitTitle" + :author="commitAuthor"> + </commit-component> + </div> + <p v-if="!isFolder && !model.last_deployment" class="commit-title"> + No deployments yet + </p> + </td> + + <td> + <span v-if="!isFolder && model.last_deployment" class="environment-created-date-timeago"> + {{createdDate}} + </span> + </td> + + <td class="hidden-xs"> + <div v-if="!isFolder"> + + </div> + </td> + </tr> + + <tr v-if="open && isFolder" + is="environment-item" + v-for="model in model.children" + :model="model"> + </tr> + `, }); })(); diff --git a/app/assets/javascripts/environments/environments_bundle.js.es6 b/app/assets/javascripts/environments/environments_bundle.js.es6 index 645274a8666..1192f3e5bfb 100644 --- a/app/assets/javascripts/environments/environments_bundle.js.es6 +++ b/app/assets/javascripts/environments/environments_bundle.js.es6 @@ -68,8 +68,8 @@ $(() => { * Toggles loading property. */ ready() { - gl.environmentsService.all().then((resp) => { - Store.storeEnvironments(resp.json()); + gl.environmentsService.all().then(resp => resp.json()).then((json) => { + Store.storeEnvironments(json); this.loading = false; }); }, diff --git a/app/assets/javascripts/vue_common_component/commit.js.es6 b/app/assets/javascripts/vue_common_component/commit.js.es6 new file mode 100644 index 00000000000..8847d1d0184 --- /dev/null +++ b/app/assets/javascripts/vue_common_component/commit.js.es6 @@ -0,0 +1,173 @@ +/*= require vue +/* global Vue */ +(() => { + window.gl = window.gl || {}; + + window.gl.commitComponent = Vue.component('commit-component', { + + props: { + /** + * Indicates the existance of a tag. + * Used to render the correct icon, if true will render `fa-tag` icon, + * if false will render `fa-code-fork` icon. + */ + tag: { + type: Boolean, + required: false, + default: false, + }, + + /** + * If provided is used to render the branch name and url. + * Should contain the following properties: + * name + * ref_url + */ + ref: { + type: Object, + required: false, + default: () => {}, + }, + + /** + * Used to link to the commit sha. + */ + commit_url: { + type: String, + required: false, + default: '', + }, + + /** + * Used to show the commit short_sha that links to the commit url. + */ + short_sha: { + type: String, + required: false, + default: '', + }, + + /** + * If provided shows the commit tile. + */ + title: { + type: String, + required: false, + default: '', + }, + + /** + * If provided renders information about the author of the commit. + * When provided should include: + * `avatar_url` to render the avatar icon + * `web_url` to link to user profile + * `username` to render alt and title tags + */ + author: { + type: Object, + required: false, + default: () => {}, + }, + }, + + computed: { + /** + * Used to verify if all the properties needed to render the commit + * ref section were provided. + * + * TODO: Improve this! Use lodash _.has when we have it. + * + * @returns {Boolean} + */ + hasRef() { + return this.ref && this.ref.name && this.ref.ref_url; + }, + + /** + * Used to verify if all the properties needed to render the commit + * author section were provided. + * + * TODO: Improve this! Use lodash _.has when we have it. + * + * @returns {Boolean} + */ + hasAuthor() { + return this.author && + this.author.avatar_url && + this.author.web_url && + this.author.username; + }, + + /** + * If information about the author is provided will return a string + * to be rendered as the alt attribute of the img tag. + * + * @returns {String} + */ + userImageAltDescription() { + return this.author && + this.author.username ? `${this.author.username}'s avatar` : null; + }, + }, + + /** + * In order to reuse the svg instead of copy and paste in this template the html_safe + * we need to render it outside this component using =custom_icon partial. + * Make sure it has this structure: + * .commit-icon-svg.hidden + * svg + * + * TODO: Find a better way to include SVG + */ + ready() { + const commitIconContainer = document.querySelector('.branch-commit .commit-icon-container'); + const commitIcon = document.querySelector('.commit-icon-svg.hidden svg'); + + if (commitIconContainer && commitIcon) { + commitIconContainer.appendChild(commitIcon); + } + }, + + template: ` + <div class="branch-commit"> + + <div v-if="hasRef" class="icon-container"> + <i v-if="tag" class="fa fa-tag"></i> + <i v-else class="fa fa-code-fork"></i> + </div> + + <a v-if="hasRef" class="monospace branch-name" :href="ref.ref_url"> + {{ref.name}} + </a> + + <div class="icon-container commit-icon commit-icon-container"> + <!-- svg goes here --> + </div> + + <a class="commit-id monospace" :href="commit_url"> + {{short_sha}} + </a> + + <p class="commit-title"> + <span v-if="title"> + <!-- commit author info--> + <a v-if="hasAuthor" class="avatar-image-container" :href="author.web_url"> + <img + class="avatar has-tooltip s20" + :src="author.avatar_url" + :alt="userImageAltDescription" + :title="author.username" /> + </a> + + <a class="commit-row-message" :href="commit_url"> + {{title}} + </a> + </span> + <span v-else> + Cant find HEAD commit for this branch + </span> + </p> + </div> + `, + }); +})(); diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml index fa88d59e3ca..61a3d76274e 100644 --- a/app/views/projects/environments/index.html.haml +++ b/app/views/projects/environments/index.html.haml @@ -40,7 +40,10 @@ - if can?(current_user, :create_environment, @project) = link_to new_namespace_project_environment_path(@project.namespace, @project), class: 'btn btn-create' do New environment - + + .commit-icon-svg.hidden + = custom_icon("icon_commit") + .table-holder{ "v-if" => "!loading && state.environments.length" } %table.table.ci-table.environments %thead @@ -53,4 +56,3 @@ %tbody %tr{"is" => "environment-item", "v-for" => "model in filteredEnvironments", ":model" => "model"} -=render "projects/environments/components/environment" diff --git a/spec/javascripts/environments/environments_store_spec.js.es6 b/spec/javascripts/environments/environments_store_spec.js.es6 index bc16c90e9be..5e35949ac9c 100644 --- a/spec/javascripts/environments/environments_store_spec.js.es6 +++ b/spec/javascripts/environments/environments_store_spec.js.es6 @@ -47,7 +47,7 @@ expect(environments[1].name).toBe('review'); expect(environments[1].children[0].name).toBe('test-environment'); expect(environments[1].children[1].name).toBe('test-environment-1'); - expect(environments[2].name).toBe('review_app') + expect(environments[2].name).toBe('review_app'); }); }); }); -- GitLab