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

Commit

Permalink
repositories: migrated to vue and exposed on menu
Browse files Browse the repository at this point in the history
The default pagination limit was also changed to `10`.
  • Loading branch information
vitoravelino committed Oct 4, 2017
1 parent 9f8150f commit 1103a1a
Show file tree
Hide file tree
Showing 14 changed files with 273 additions and 18 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import moment from 'moment';

export default {
template: '#js-repository-table-row-tmpl',

props: ['repository', 'repositoriesPath', 'namespacesPath'],

computed: {
scopeClass() {
return `repository_${this.repository.id}`;
},

repositoryPath() {
return `${this.repositoriesPath}/${this.repository.id}`;
},

namespacePath() {
return `${this.namespacesPath}/${this.repository.namespace.id}`;
},

updatedAt() {
return moment(this.repository.updated_at).format('MMMM DD, YYYY HH:mm');
},
},
};
57 changes: 57 additions & 0 deletions app/assets/javascripts/modules/repositories/components/table.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import getProperty from 'lodash/get';

import Comparator from '~/utils/comparator';

import TableSortableMixin from '~/shared/mixins/table-sortable';
import TablePaginatedMixin from '~/shared/mixins/table-paginated';

import RepositoryTableRow from './table-row';

export default {
template: '#js-repositories-table-tmpl',

props: {
repositories: {
type: Array,
},
repositoriesPath: {
type: String,
},
namespacesPath: {
type: String,
},
prefix: {
type: String,
default: '',
},
},

mixins: [TableSortableMixin, TablePaginatedMixin],

components: {
RepositoryTableRow,
},

computed: {
filteredRepositories() {
const order = this.sorting.asc ? 1 : -1;
const sortedRepositories = [...this.repositories];
const sample = sortedRepositories[0];
const value = getProperty(sample, this.sorting.by);
const comparator = Comparator.of(value);

// sorting
sortedRepositories.sort((a, b) => {
const aValue = getProperty(a, this.sorting.by);
const bValue = getProperty(b, this.sorting.by);

return order * comparator(aValue, bValue);
});

// pagination
const slicedTeams = sortedRepositories.slice(this.offset, this.limit * this.currentPage);

return slicedTeams;
},
},
};
1 change: 1 addition & 0 deletions app/assets/javascripts/modules/repositories/index.js
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
import './pages/index';
import './pages/show';
24 changes: 24 additions & 0 deletions app/assets/javascripts/modules/repositories/pages/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Vue from 'vue';

import RepositoriesTable from '../components/table';

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

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

components: {
RepositoriesTable,
},

data() {
return {
repositories: window.repositories,
};
},
});
});
2 changes: 1 addition & 1 deletion app/assets/javascripts/shared/mixins/table-paginated.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default {
props: {
limit: {
type: Number,
default: 3,
default: 10,
},
},

Expand Down
5 changes: 5 additions & 0 deletions app/controllers/repositories_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ class RepositoriesController < ApplicationController
# GET /repositories.json
def index
@repositories = policy_scope(Repository).all
@repositories_serialized = API::Entities::Repositories.represent(
@repositories,
current_user: current_user,
type: :internal
).to_json
respond_with(@repositories)
end

Expand Down
41 changes: 41 additions & 0 deletions app/views/repositories/components/_table.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
.table-responsive
table.table.table-striped.table-hover :class=="{'table-sortable': sortable}"
thead
tr
th @click=="sort('name')"
i.fa.fa-fw.fa-sort{
:class=="{
'fa-sort-amount-asc': sorting.by === 'name' && sorting.asc,
'fa-sort-amount-desc': sorting.by === 'name' && !sorting.asc,
}"
}
| Repository

th @click=="sort('namespace.name')"
i.fa.fa-fw.fa-sort{
:class=="{
'fa-sort-amount-asc': sorting.by === 'namespace.name' && sorting.asc,
'fa-sort-amount-desc': sorting.by === 'namespace.name' && !sorting.asc,
}"
}
| Namespace
th @click=="sort('tags_count')"
i.fa.fa-fw.fa-sort{
:class=="{
'fa-sort-amount-asc': sorting.by === 'tags_count' && sorting.asc,
'fa-sort-amount-desc': sorting.by === 'tags_count' && !sorting.asc,
}"
}
| # Tags
th @click=="sort('updated_at')"
i.fa.fa-fw.fa-sort{
:class=="{
'fa-sort-amount-asc': sorting.by === 'updated_at' && sorting.asc,
'fa-sort-amount-desc': sorting.by === 'updated_at' && !sorting.asc,
}"
}
| Updated at
tbody
<repository-table-row v-for="repository in filteredRepositories" :key="repository.id" :repository="repository" :repositories-path="repositoriesPath" :namespaces-path="namespacesPath"></repository-table-row>

<table-pagination :total.sync="repositories.length" :current-page="currentPage" :itens-per-page.sync="limit" @update="updateCurrentPage"></table-pagination>
11 changes: 11 additions & 0 deletions app/views/repositories/components/_table_row.html.slim
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
tr :class="scopeClass"
td
a :href="repositoryPath"
| {{ repository.name }}
td
a :href="namespacePath"
| {{ repository.namespace.name }}
td
| {{ repository.tags_count }}
td
| {{ updatedAt }}
27 changes: 14 additions & 13 deletions app/views/repositories/index.html.slim
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
.panel.panel-default
.panel.panel-default.repositories-panel
.panel-heading
| Repositories
h5 Repositories
.panel-body
.table-responsive
table.table.table-striped.table-hover
thead
tr
th Namespace
th Repository
tbody
- @repositories.each do |repository|
tr
td= link_to repository.namespace.clean_name, repository.namespace
td= link_to repository.name, repository
<repositories-table :repositories="repositories" repositories-path="#{repositories_path}" namespaces-path="#{namespaces_path}" :sortable="true" sort-by="name"></repositories-table>

- content_for :js_body do
script#js-repositories-table-tmpl type="text/x-template"
= render "repositories/components/table"

script#js-repository-table-row-tmpl type="text/x-template"
= render "repositories/components/table_row"

- content_for :js_header do
javascript:
window.repositories = #{raw @repositories_serialized};
6 changes: 6 additions & 0 deletions app/views/shared/_aside.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,12 @@ aside
| Namespaces
- if current_page?(url_for namespaces_path)
.list-selected
li.active
= link_to repositories_path
i[class="fa fa-archive"]
| Repositories
- if current_page?(url_for repositories_path)
.list-selected
li.active
= link_to teams_path
i[class="fa fa-users"]
Expand Down
4 changes: 4 additions & 0 deletions lib/api/entities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ class Repositories < Grape::Entity
type: Integer,
desc: "The number of stars for this repository"
} { |repository| repository.stars.count }
expose :tags_count, documentation: {
type: Integer,
desc: "The number of tags for this repository"
} { |repository| repository.tags.count }
expose :tags, documentation: {
is_array: true,
desc: "The repository's tags grouped by digest"
Expand Down
4 changes: 2 additions & 2 deletions spec/features/namespaces_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@
end

scenario "Namespace table pagination is reachable through url", js: true do
create_list(:namespace, 5, team: team, registry: registry)
create_list(:namespace, 15, team: team, registry: registry)

# page 2
visit namespaces_path(ns_page: 2)
Expand All @@ -219,7 +219,7 @@
end

scenario "URL is updated when page is changed", js: true do
create_list(:namespace, 5, team: team, registry: registry)
create_list(:namespace, 15, team: team, registry: registry)

visit namespaces_path

Expand Down
80 changes: 80 additions & 0 deletions spec/features/repositories_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,86 @@
login_as user, scope: :user
end

describe "repository#index", js: true do
before do
create_list(:repository, 15, namespace: namespace)
end

scenario "Repositories table sorting is reachable through url" do
# sort asc
visit repositories_path(sort_asc: true)

expect(page).to have_css(".fa-sort-amount-asc")

# sort desc
visit repositories_path(sort_asc: false)

expect(page).to have_css(".fa-sort-amount-desc")

# sort asc & namespace.name
visit repositories_path(sort_asc: true, sort_by: "namespace.name")

expect(page).to have_css("th:nth-child(2) .fa-sort-amount-asc")

# sort desc & namespace.name
visit repositories_path(sort_asc: false, sort_by: "namespace.name")

expect(page).to have_css("th:nth-child(2) .fa-sort-amount-desc")
end

scenario "URL is updated when repositories column is sorted" do
visit repositories_path

expect(page).to have_css(".repositories-panel:last-of-type th:nth-child(2)")

# sort asc & namespace.name
find(".repositories-panel:last-of-type th:nth-child(2)").click

expect(page).to have_css(".repositories-panel th:nth-child(2) .fa-sort-amount-asc")
path = repositories_path(sort_asc: true, sort_by: "namespace.name")
expect(page).to have_current_path(path)

# sort desc & namespace.name
find(".repositories-panel:last-of-type th:nth-child(2)").click

expect(page).to have_css(".repositories-panel th:nth-child(2) .fa-sort-amount-desc")
path = repositories_path(sort_asc: false, sort_by: "namespace.name")
expect(page).to have_current_path(path)
end

scenario "Repositories table pagination is reachable through url" do
# page 2
visit repositories_path(page: 2)

expect(page).to have_css(".repositories-panel .pagination li.active:nth-child(3)")

# page 1
visit repositories_path(page: 1)

expect(page).to have_css(".repositories-panel .pagination li.active:nth-child(2)")
end

scenario "URL is updated when page is changed" do
visit repositories_path

expect(page).to have_css(".repositories-panel:last-of-type .pagination li:nth-child(3)")

# page 2
find(".repositories-panel:last-of-type .pagination li:nth-child(3) a").click

selector = ".repositories-panel:last-of-type .pagination li.active:nth-child(3)"
expect(page).to have_css(selector)
expect(page).to have_current_path(repositories_path(page: 2))

# page 1
find(".repositories-panel:last-of-type .pagination li:nth-child(2) a").click

selector = ".repositories-panel:last-of-type .pagination li.active:nth-child(2)"
expect(page).to have_css(selector)
expect(page).to have_current_path(repositories_path(page: 1))
end
end

describe "repository#show" do
scenario "Visual aid for each role is shown properly" do
visit repository_path(repository)
Expand Down
4 changes: 2 additions & 2 deletions spec/features/teams_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@
end

scenario "Namespace table pagination is reachable through url", js: true do
create_list(:namespace, 5, team: team, registry: registry)
create_list(:namespace, 15, team: team, registry: registry)

# page 2
visit team_path(team, ns_page: 2)
Expand All @@ -209,7 +209,7 @@
end

scenario "URL is updated when page is changed", js: true do
create_list(:namespace, 5, team: team, registry: registry)
create_list(:namespace, 15, team: team, registry: registry)

visit team_path(team)

Expand Down

0 comments on commit 1103a1a

Please sign in to comment.