Commit cf7ddfb0 authored by Peter Hegman's avatar Peter Hegman Committed by Markus Koller

Bootstrap admin deploy keys Vue application

Initial setup for converting admin deploy keys table from HAML to Vue
parent 5e88a37a
<script>
import { GlTable, GlButton } from '@gitlab/ui';
import { __ } from '~/locale';
export default {
name: 'DeployKeysTable',
i18n: {
pageTitle: __('Public deploy keys'),
newDeployKeyButtonText: __('New deploy key'),
},
fields: [
{
key: 'title',
label: __('Title'),
},
{
key: 'fingerprint',
label: __('Fingerprint'),
},
{
key: 'projects',
label: __('Projects with write access'),
},
{
key: 'created',
label: __('Created'),
},
{
key: 'actions',
label: __('Actions'),
},
],
components: {
GlTable,
GlButton,
},
inject: ['editPath', 'deletePath', 'createPath', 'emptyStateSvgPath'],
};
</script>
<template>
<div>
<div class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-py-5">
<h4 class="gl-m-0">
{{ $options.i18n.pageTitle }}
</h4>
<gl-button variant="confirm" :href="createPath">{{
$options.i18n.newDeployKeyButtonText
}}</gl-button>
</div>
<gl-table :fields="$options.fields" data-testid="deploy-keys-list" />
</div>
</template>
import Vue from 'vue';
import DeployKeysTable from './components/table.vue';
export const initAdminDeployKeysTable = () => {
const el = document.getElementById('js-admin-deploy-keys-table');
if (!el) return false;
const { editPath, deletePath, createPath, emptyStateSvgPath } = el.dataset;
return new Vue({
el,
provide: {
editPath,
deletePath,
createPath,
emptyStateSvgPath,
},
render(createElement) {
return createElement(DeployKeysTable);
},
});
};
import { initAdminDeployKeysTable } from '~/admin/deploy_keys';
initAdminDeployKeysTable();
# frozen_string_literal: true
module Admin
module DeployKeyHelper
def admin_deploy_keys_data
{
edit_path: edit_admin_deploy_key_path(':id'),
delete_path: admin_deploy_key_path(':id'),
create_path: new_admin_deploy_key_path,
empty_state_svg_path: image_path('illustrations/empty-state/empty-deploy-keys-lg.svg')
}
end
end
end
- page_title _('Deploy Keys')
- if @deploy_keys.any?
%h3.page-title.deploy-keys-title
= _('Public deploy keys (%{deploy_keys_count})') % { deploy_keys_count: @deploy_keys.load.size }
= link_to _('New deploy key'), new_admin_deploy_key_path, class: 'float-right btn gl-button btn-confirm btn-md gl-button'
.table-holder.deploy-keys-list
%table.table
%thead
%tr
%th.col-sm-2= _('Title')
%th.col-sm-4= _('Fingerprint')
%th.col-sm-2= _('Projects with write access')
%th.col-sm-2= _('Added at')
%th.col-sm-2
%tbody
- @deploy_keys.each do |deploy_key|
%tr
%td
%strong= deploy_key.title
%td
%code.key-fingerprint= deploy_key.fingerprint
%td
- deploy_key.projects_with_write_access.each do |project|
= link_to project.full_name, admin_project_path(project), class: 'label deploy-project-label'
%td
%span.cgray
= _('added %{created_at_timeago}').html_safe % { created_at_timeago: time_ago_with_tooltip(deploy_key.created_at) }
%td
.float-right
= link_to _('Edit'), edit_admin_deploy_key_path(deploy_key), class: 'btn gl-button btn-sm'
= link_to _('Remove'), admin_deploy_key_path(deploy_key), data: { confirm: _('Are you sure?') }, method: :delete, class: 'gl-button btn btn-sm btn-danger delete-key'
- if Feature.enabled?(:admin_deploy_keys_vue, default_enabled: :yaml)
#js-admin-deploy-keys-table{ data: admin_deploy_keys_data }
- else
= render 'shared/empty_states/deploy_keys'
- if @deploy_keys.any?
%h3.page-title.deploy-keys-title
= _('Public deploy keys (%{deploy_keys_count})') % { deploy_keys_count: @deploy_keys.load.size }
= link_to _('New deploy key'), new_admin_deploy_key_path, class: 'float-right btn gl-button btn-confirm btn-md gl-button'
.table-holder.deploy-keys-list
%table.table
%thead
%tr
%th.col-sm-2= _('Title')
%th.col-sm-4= _('Fingerprint')
%th.col-sm-2= _('Projects with write access')
%th.col-sm-2= _('Added at')
%th.col-sm-2
%tbody
- @deploy_keys.each do |deploy_key|
%tr
%td
%strong= deploy_key.title
%td
%code.key-fingerprint= deploy_key.fingerprint
%td
- deploy_key.projects_with_write_access.each do |project|
= link_to project.full_name, admin_project_path(project), class: 'label deploy-project-label'
%td
%span.cgray
= _('added %{created_at_timeago}').html_safe % { created_at_timeago: time_ago_with_tooltip(deploy_key.created_at) }
%td
.float-right
= link_to _('Edit'), edit_admin_deploy_key_path(deploy_key), class: 'btn gl-button btn-sm'
= link_to _('Remove'), admin_deploy_key_path(deploy_key), data: { confirm: _('Are you sure?') }, method: :delete, class: 'gl-button btn btn-sm btn-danger delete-key'
- else
= render 'shared/empty_states/deploy_keys'
---
name: admin_deploy_keys_vue
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/73580
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/344855
milestone: '14.5'
type: development
group: group::access
default_enabled: false
......@@ -28062,6 +28062,9 @@ msgstr ""
msgid "Public Access Help"
msgstr ""
msgid "Public deploy keys"
msgstr ""
msgid "Public deploy keys (%{deploy_keys_count})"
msgstr ""
......
......@@ -3,11 +3,13 @@
require 'spec_helper'
RSpec.describe 'admin deploy keys' do
let_it_be(:admin) { create(:admin) }
let!(:deploy_key) { create(:deploy_key, public: true) }
let!(:another_deploy_key) { create(:another_deploy_key, public: true) }
before do
admin = create(:admin)
stub_feature_flags(admin_deploy_keys_vue: false)
sign_in(admin)
gitlab_enable_admin_mode_sign_in(admin)
end
......@@ -84,4 +86,18 @@ RSpec.describe 'admin deploy keys' do
end
end
end
context 'when `admin_deploy_keys_vue` feature flag is enabled', :js do
before do
stub_feature_flags(admin_deploy_keys_vue: true)
visit admin_deploy_keys_path
end
it 'renders the Vue app', :aggregate_failures do
expect(page).to have_content('Public deploy keys')
expect(page).to have_selector('[data-testid="deploy-keys-list"]')
expect(page).to have_link('New deploy key', href: new_admin_deploy_key_path)
end
end
end
import { merge } from 'lodash';
import { GlTable, GlButton } from '@gitlab/ui';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import DeployKeysTable from '~/admin/deploy_keys/components/table.vue';
describe('DeployKeysTable', () => {
let wrapper;
const defaultProvide = {
createPath: '/admin/deploy_keys/new',
deletePath: '/admin/deploy_keys/:id',
editPath: '/admin/deploy_keys/:id/edit',
emptyStateSvgPath: '/assets/illustrations/empty-state/empty-deploy-keys.svg',
};
const createComponent = (provide = {}) => {
wrapper = mountExtended(DeployKeysTable, {
provide: merge({}, defaultProvide, provide),
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders page title', () => {
createComponent();
expect(wrapper.findByText(DeployKeysTable.i18n.pageTitle).exists()).toBe(true);
});
it('renders table', () => {
createComponent();
expect(wrapper.findComponent(GlTable).exists()).toBe(true);
});
it('renders `New deploy key` button', () => {
createComponent();
const newDeployKeyButton = wrapper.findComponent(GlButton);
expect(newDeployKeyButton.text()).toBe(DeployKeysTable.i18n.newDeployKeyButtonText);
expect(newDeployKeyButton.attributes('href')).toBe(defaultProvide.createPath);
});
});
# frozen_string_literal: true
require "spec_helper"
RSpec.describe Admin::DeployKeyHelper do
describe '#admin_deploy_keys_data' do
let_it_be(:edit_path) { '/admin/deploy_keys/:id/edit' }
let_it_be(:delete_path) { '/admin/deploy_keys/:id' }
let_it_be(:create_path) { '/admin/deploy_keys/new' }
let_it_be(:empty_state_svg_path) { '/assets/illustrations/empty-state/empty-deploy-keys-lg.svg' }
subject(:result) { helper.admin_deploy_keys_data }
it 'returns correct hash' do
expect(helper).to receive(:edit_admin_deploy_key_path).with(':id').and_return(edit_path)
expect(helper).to receive(:admin_deploy_key_path).with(':id').and_return(delete_path)
expect(helper).to receive(:new_admin_deploy_key_path).and_return(create_path)
expect(helper).to receive(:image_path).with('illustrations/empty-state/empty-deploy-keys-lg.svg').and_return(empty_state_svg_path)
expect(result).to eq({
edit_path: edit_path,
delete_path: delete_path,
create_path: create_path,
empty_state_svg_path: empty_state_svg_path
})
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment