Skip to content
This repository has been archived by the owner on Apr 17, 2023. It is now read-only.

Commit

Permalink
js: created <tag> component with copy to clipboard
Browse files Browse the repository at this point in the history
Fixes #697
Fixes #1108
  • Loading branch information
vitoravelino committed Sep 6, 2017
1 parent 9d6cc25 commit acad5b6
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 25 deletions.
1 change: 1 addition & 0 deletions app/assets/javascripts/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import './bootstrap';
// new modules structure
import './modules/users';
import './modules/dashboard';
import './modules/explore';
import './modules/repositories';
import './modules/namespaces';
import './modules/teams';
Expand Down
19 changes: 19 additions & 0 deletions app/assets/javascripts/modules/explore/components/result-item.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import moment from 'moment';

import Tag from '~/modules/repositories/components/tag';

export default {
template: '#js-result-item-tmpl',

props: ['repository'],

components: {
Tag,
},

computed: {
updatedAt() {
return moment(this.repository.updated_at).fromNow();
},
},
};
1 change: 1 addition & 0 deletions app/assets/javascripts/modules/explore/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
import './pages/index';
30 changes: 30 additions & 0 deletions app/assets/javascripts/modules/explore/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Vue from 'vue';

import ResultItem from '../components/result-item';

const { set } = Vue;

$(() => {
if (!$('body[data-route="explore/index"]').length) {
return;
}

// eslint-disable-next-line no-new
new Vue({
el: 'body[data-route="explore/index"] .vue-root',

components: {
ResultItem,
},

data() {
return {
repositories: [],
};
},

mounted() {
set(this, 'repositories', window.repositories);
},
});
});
42 changes: 42 additions & 0 deletions app/assets/javascripts/modules/repositories/components/tag.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<style scoped>
.label {
cursor: pointer;
}
</style>

<template>
<div class="label label-success" title="Copy to clipboard" @click="copyToClipboard">
{{ tag.name }}
</div>
</template>

<script>
import Alert from '~/shared/components/alert';
export default {
props: ['tag', 'repository'],
computed: {
commandToPull() {
const hostname = this.repository.registry_hostname;
const repoName = this.repository.full_name;
const tagName = this.tag.name;
return `docker pull ${hostname}/${repoName}:${tagName}`;
},
},
methods: {
copyToClipboard() {
const $temp = $('<input>');
$('body').append($temp);
$temp.val(this.commandToPull).select();
document.execCommand('copy');
$temp.remove();
Alert.show('Copied pull command to clipboard');
},
},
};
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<input type="checkbox" v-model="selected" @change="toggleTag()">
</td>
<td>
<div class="label label-success" v-for="t in tag">{{ t.name }}</div>
<tag v-for="t in tag" :key="t.name" :tag="t" :repository="state.repository"></tag>
</td>

<td>{{ tag[0].author.username }}</td>
Expand All @@ -33,6 +33,8 @@
</template>

<script>
import Tag from './tag';
import VulnerabilitiesParser from '../services/vulnerabilities-parser';
export default {
Expand All @@ -43,6 +45,10 @@
state: Object,
},
components: {
Tag,
},
data() {
return {
tagsPath: '/tags',
Expand Down
1 change: 1 addition & 0 deletions app/assets/javascripts/modules/repositories/pages/show.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ $(() => {
const id = this.$refs.repoLink.dataset.id;

RepositoriesService.get(id).then((response) => {
set(this.state, 'repository', response.body);
set(this, 'tags', response.body.tags);
set(this, 'notLoaded', false);
set(this, 'unableToFetchBefore', false);
Expand Down
2 changes: 1 addition & 1 deletion app/assets/stylesheets/pages/explore.scss
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
}

.result-item {
background: rgba(255, 255, 255, 0.7);
background: rgba(255, 255, 255, 0.85);
border-radius: 5px;
margin-bottom: 10px;
padding: 15px;
Expand Down
4 changes: 4 additions & 0 deletions app/models/repository.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Repository < ActiveRecord::Base
has_many :stars, dependent: :delete_all
has_many :comments, dependent: :delete_all

delegate :registry, to: :namespace
# We don't validate the format because we get that from the registry, and
# it's guaranteed to be well-formatted there.
validates :name, presence: true, uniqueness: { scope: "namespace_id" }
Expand Down Expand Up @@ -73,6 +74,9 @@ def as_json(options = {})

super(options).tap do |json|
json["full_name"] = full_name
json["registry_hostname"] = registry.hostname
json["stars"] = stars.count
json["updated_at"] = updated_at
json["namespace"] = namespace.as_json(only: [:id, :name])
json["team"] = namespace.team.as_json(only: [:id, :name])
json["tags"] = groupped_tags
Expand Down
16 changes: 16 additions & 0 deletions app/views/explore/components/_result_item.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
li.result-item.text-left
.clearfix
h4.result-item-name.pull-left
| {{ repository.full_name }}

.result-item-stars.pull-right
| {{ repository.stars }}
| &nbsp;
i.fa.fa-star

.clearfix
.tags.pull-left
<tag :tag="tag" v-for="tag in repository.tags[0]" :key="tag.id" :repository="repository"></tag>

.pull-right
| Updated {{ updatedAt }}
1 change: 0 additions & 1 deletion app/views/explore/index.slim
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@ section.row-0
.col-md-4.col-sm-3.col-xs-1
.col-md-4.col-sm-6.col-xs-10.text-center
= render 'explore/partials/top'
= render 'explore/partials/form'
= render 'explore/partials/result'
12 changes: 10 additions & 2 deletions app/views/explore/partials/_result.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,16 @@
- repo_count = @repositories.count
| #{pluralize(repo_count, 'repository')} #{repo_count == 1 ? "was" : "were"} found
ul.result-list
- @repositories.each do |r|
= render partial: 'explore/partials/result_item', locals: { repository: r }
<result-item :repository="repository" v-for="repository in repositories" :key="repository.full_name"></result-item>

- if params[:explore] && [email protected]?
h2 Your search did not match any repositories.

- content_for :js_header do
javascript:
window.repositories = #{raw @repositories.to_json};
- content_for :js_body do
- cache "explore/components/templates" do
script#js-result-item-tmpl type="text/x-template"
= render "explore/components/result_item"
18 changes: 0 additions & 18 deletions app/views/explore/partials/_result_item.slim

This file was deleted.

2 changes: 2 additions & 0 deletions app/views/explore/partials/_top.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@
= image_tag 'layout/portus-logo-login-page.png', class: 'login-picture'

.text-center = link_to 'Go back to the login page', new_user_session_path, class: 'btn btn-link'

= render 'explore/partials/form'
10 changes: 8 additions & 2 deletions app/views/layouts/authentication.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ html
head
title Portus
= stylesheet_link_tag 'application', media: 'all'
= javascript_include_tag(*webpack_asset_paths("application"))
= csrf_meta_tags
meta content="width=device-width, initial-scale=1" name="viewport"
link href="/favicon/apple-touch-icon-57x57.png" rel="apple-touch-icon" sizes="57x57"
Expand All @@ -28,6 +27,13 @@ html
meta content="/favicon/mstile-144x144.png" name="msapplication-TileImage"
meta content="/favicon/browserconfig.xml" name="msapplication-config"
meta content="#205683" name="theme-color"

script src="//cdn.polyfill.io/v2/polyfill.js?features=Array.prototype.some,Array.prototype.findIndex,Array.from"
= javascript_include_tag(*webpack_asset_paths("application"))
= yield :js_header

body.login data-route="#{js_route}"
.container-fluid
.container-fluid.vue-root
= yield

= yield :js_body

0 comments on commit acad5b6

Please sign in to comment.