Commit e11a702a authored by Phil Hughes's avatar Phil Hughes

Re-wrote to match our docs - still not 100% sure but closer than it was

parent 79e2a524
<script>
import eventHub from '../eventhub';
export default {
data() {
return {
isLoading: false,
};
},
props: {
deployKey: {
type: Object,
required: true,
},
type: {
type: String,
required: true,
},
btnCssClass: {
type: String,
required: false,
default: 'btn-default',
},
},
methods: {
doAction() {
this.isLoading = true;
eventHub.$emit(`${this.type}.key`, this.deployKey);
},
},
computed: {
text() {
return `${this.type.charAt(0).toUpperCase()}${this.type.slice(1)}`;
},
},
};
</script>
<template>
<button
class="btn btn-sm prepend-left-10"
:class="[{ disabled: isLoading }, btnCssClass]"
:disabled="isLoading"
@click="doAction">
{{ text }}
<i
v-if="isLoading"
class="fa fa-spinner fa-spin"
aria-hidden="true">
</i>
</button>
</template>
<script>
/* global Flash */
import eventHub from '../eventhub';
import DeployKeysService from '../service';
import DeployKeysStore from '../store';
import keysPanel from './keys.vue';
export default {
data() {
const store = new DeployKeysStore();
return {
isLoading: false,
store,
};
},
props: {
endpoint: {
type: String,
required: true,
},
},
computed: {
hasKeys() {
return Object.keys(this.keys).length;
},
keys() {
return this.store.keys;
},
},
components: {
keysPanel,
},
methods: {
fetchKeys() {
this.isLoading = true;
this.store.keys = {};
this.service.getKeys()
.then((data) => {
this.isLoading = false;
this.store.keys = data;
})
.catch(() => new Flash('Error getting deploy keys'));
},
enableKey(deployKey) {
this.service.enableKey(deployKey.id)
.then(() => this.fetchKeys())
.catch(() => new Flash('Error enabling deploy key'));
},
removeKey(deployKey) {
this.disableKey(deployKey);
},
disableKey(deployKey) {
// eslint-disable-next-line no-alert
if (confirm('You are going to remove this deploy key. Are you sure?')) {
this.service.disableKey(deployKey.id)
.then(() => this.fetchKeys())
.catch(() => new Flash('Error removing deploy key'));
}
},
},
created() {
this.service = new DeployKeysService(this.endpoint);
eventHub.$on('enable.key', this.enableKey);
eventHub.$on('remove.key', this.removeKey);
eventHub.$on('disable.key', this.disableKey);
},
mounted() {
this.fetchKeys();
},
beforeDestroy() {
eventHub.$off('enable.key', this.enableKey);
eventHub.$off('remove.key', this.removeKey);
eventHub.$off('disable.key', this.disableKey);
},
};
</script>
<template>
<div class="col-lg-9 col-lg-offset-3 append-bottom-default">
<div
class="text-center"
v-if="isLoading && !hasKeys">
<i
class="fa fa-spinner fa-spin fa-2x">
</i>
</div>
<div v-else-if="hasKeys">
<keys-panel
title="Enabled deploy keys for this project"
:keys="keys.enabled_keys"
:store="store" />
<keys-panel
title="Deploy keys from projects you have access to"
:keys="keys.available_project_keys"
:store="store" />
<keys-panel
title="Public deploy keys available to any project"
:keys="keys.public_keys"
:store="store" />
</div>
</div>
</template>
<script>
import actionBtn from './action_btn.vue';
export default {
props: {
deployKey: {
type: Object,
required: true,
},
enabled: {
type: Boolean,
required: false,
default: true,
},
store: {
type: Object,
required: true,
},
},
components: {
actionBtn,
},
computed: {
timeagoDate() {
return gl.utils.getTimeago().format(this.deployKey.created_at);
},
},
methods: {
isEnabled(id) {
return this.store.findEnabledKey(id) !== undefined;
},
},
};
</script>
<template>
<div>
<div class="pull-left append-right-10 hidden-xs">
<i
aria-hidden="true"
class="fa fa-key key-icon">
</i>
</div>
<div class="deploy-key-content key-list-item-info">
<strong class="title">
{{ deployKey.title }}
</strong>
<div class="description">
{{ deployKey.fingerprint }}
</div>
<div
v-if="deployKey.can_push"
class="write-access-allowed">
Write access allowed
</div>
</div>
<div class="deploy-key-content prepend-left-default deploy-key-projects">
<a
class="label deploy-project-label"
:href="project.full_path"
v-for="project in deployKey.projects">
{{ project.full_name }}
</a>
</div>
<div class="deploy-key-content">
<span class="key-created-at">
created {{ timeagoDate }}
</span>
<action-btn
v-if="!isEnabled(deployKey.id)"
:deploy-key="deployKey"
type="enable"/>
<action-btn
v-else-if="deployKey.destroyed_when_orphaned && deployKey.almost_orphaned"
:deploy-key="deployKey"
btn-css-class="btn-warning"
type="remove" />
<action-btn
v-else
:deploy-key="deployKey"
btn-css-class="btn-warning"
type="disable" />
</div>
</div>
</template>
<script>
import key from './key.vue';
export default {
props: {
title: {
type: String,
required: true,
},
keys: {
type: Array,
required: true,
},
showHelpBox: {
type: Boolean,
required: false,
default: true,
},
store: {
type: Object,
required: true,
},
},
components: {
key,
},
};
</script>
<template>
<div>
<h5>
{{ title }}
({{ keys.length }})
</h5>
<ul class="well-list"
v-if="keys.length">
<li
v-for="deployKey in keys"
key="deployKey.id">
<key
:deploy-key="deployKey"
:store="store" />
</li>
</ul>
<div
class="settings-message text-center"
v-else-if="showHelpBox">
No deploy keys found. Create one with the form above.
</div>
</div>
</template>
import Vue from 'vue';
export default new Vue();
import Vue from 'vue';
import deployKeysApp from './components/app.vue';
document.addEventListener('DOMContentLoaded', () => new Vue({
el: document.getElementById('js-deploy-keys'),
data() {
return {
endpoint: this.$options.el.dataset.endpoint,
};
},
components: {
deployKeysApp,
},
render(createElement) {
return createElement('deploy-keys-app', {
props: {
endpoint: this.endpoint,
},
});
},
}));
import Vue from 'vue';
import VueResource from 'vue-resource';
Vue.use(VueResource);
export default class DeployKeysService {
constructor(endpoint) {
this.endpoint = endpoint;
this.resource = Vue.resource(`${this.endpoint}{/id}`, {}, {
enable: {
method: 'PUT',
url: `${this.endpoint}{/id}/enable`,
},
disable: {
method: 'PUT',
url: `${this.endpoint}{/id}/disable`,
},
});
}
getKeys() {
return this.resource.get()
.then(response => response.json());
}
enableKey(id) {
return this.resource.enable({ id }, {});
}
disableKey(id) {
return this.resource.disable({ id }, {});
}
}
export default class DeployKeysStore {
constructor() {
this.keys = {};
}
findEnabledKey(id) {
return this.keys.enabled_keys.find(key => key.id === id);
}
removeKeyForType(deployKey, type) {
this.keys[type] = this.keys[type].filter(key => key.id !== deployKey.id);
}
}
......@@ -48,7 +48,6 @@ import BlobForkSuggestion from './blob/blob_fork_suggestion';
import UserCallout from './user_callout';
import { ProtectedTagCreate, ProtectedTagEditList } from './protected_tags';
import ShortcutsWiki from './shortcuts_wiki';
import SettingsDeployKeys from './settings/settings_repository';
import BlobViewer from './blob/viewer/index';
const ShortcutsBlob = require('./shortcuts_blob');
......@@ -346,8 +345,6 @@ const ShortcutsBlob = require('./shortcuts_blob');
// Initialize Protected Tag Settings
new ProtectedTagCreate();
new ProtectedTagEditList();
// Initialize deploy key ajax call
new SettingsDeployKeys();
break;
case 'projects:ci_cd:show':
new gl.ProjectVariables();
......
/* eslint-disable no-new */
import Vue from 'vue';
import VueResource from 'vue-resource';
Vue.use(VueResource);
export default class SettingsDeployKeys {
constructor() {
this.initVue();
}
deployKeyRowTemplate() {
return `
<li>
<div class="pull-left append-right-10 hidden-xs">
<i aria-hidden="true" class="fa fa-key key-icon"></i>
</div>
<div class="deploy-key-content key-list-item-info">
<strong class="title">
{{deployKey.title}}
</strong>
<div class="description">
{{deployKey.fingerprint}}
</div>
</div>
<div class="deploy-key-content prepend-left-default deploy-key-projects">
<a class="label deploy-project-label" :href="project.full_path" v-for="project in deployKey.projects">{{project.full_name}}</a>
</div>
<div class="deploy-key-content">
<span class="key-created-at">
created {{timeagoDate}}
</span>
<div class="visible-xs-block visible-sm-block"></div>
<a v-if="!enabled" class="btn btn-sm prepend-left-10" rel="nofollow" data-method="put" href="enableURL">Enable
</a>
<a v-else-if="deployKey.destroyed_when_orphaned && deployKey.almost_orphaned" class="btn btn-warning btn-sm prepend-left-10" rel="nofollow" data-method="put" :href="disableURL">Remove</a>
<a v-else class="btn btn-warning btn-sm prepend-left-10" rel="nofollow" data-method="put" :href="disableURL">Disable</a>
</div>
</li>`
}
deployKeyRowComponent() {
const self = this;
return {
props: {
deployKey: Object,
enabled: Boolean
},
computed: {
timeagoDate() {
return gl.utils.getTimeago().format(this.deployKey.createdAt, 'gl_en');
},
disableURL() {
return self.disableEndpoint.replace(':id', this.deployKey.id);
},
enableURL() {
return self.enableEndpoint.replace(':id', this.deployKey.id);
}
},
template: this.deployKeyRowTemplate()
}
}
initVue() {
const self = this;
const el = document.getElementById('js-deploy-keys');
const endpoint = el.dataset.endpoint;
this.jsonEndpoint = `${endpoint}.json`;
this.disableEndpoint = `${endpoint}/:id/disable`;
this.enableEndpoint = `${endpoint}/:id/enable`;
new Vue({
el: el,
components: {
deployKeyRow: self.deployKeyRowComponent()
},
data () {
return {
enabledKeys: [],
availableKeys: []
}
},
created () {
this.$http.get(self.jsonEndpoint)
.then((res) => {
const keys = JSON.parse(res.body);
this.enabledKeys = keys.enabled_keys;
this.availableKeys = keys.available_project_keys;
});
}
})
}
}
\ No newline at end of file
......@@ -32,7 +32,10 @@ class Projects::DeployKeysController < Projects::ApplicationController
def enable
Projects::EnableDeployKeyService.new(@project, current_user, params).execute
redirect_to_repository_settings(@project)
respond_to do |format|
format.html { redirect_to_repository_settings(@project) }
format.json { head :ok }
end
end
def disable
......@@ -40,7 +43,11 @@ class Projects::DeployKeysController < Projects::ApplicationController
return render_404 unless deploy_key_project
deploy_key_project.destroy!
redirect_to_repository_settings(@project)
respond_to do |format|
format.html { redirect_to_repository_settings(@project) }
format.json { head :ok }
end
end
protected
......
class ProjectEntity < Grape::Entity
include RequestAwareEntity
expose :id
expose :name
expose :full_path do |project|
project.full_path
namespace_project_path(project.namespace, project)
end
expose :full_name do |project|
......
......@@ -10,16 +10,4 @@
= render @deploy_keys.form_partial_path
.col-lg-9.col-lg-offset-3
%hr
#js-deploy-keys.col-lg-9.col-lg-offset-3.append-bottom-default{data:{endpoint: namespace_project_deploy_keys_path}}
%h5.prepend-top-0
Enabled deploy keys for this project ({{enabledKeys.length}})
%ul.well-list{"v-if" => "enabledKeys.length"}
%deploy-key-row{"v-for" => "deployKey in enabledKeys", ":deploy-key" => "deployKey", ":enabled" =>"true"}
.settings-message.text-center{"v-else" => true}
No deploy keys found. Create one with the form above.
%h5.prepend-top-0
Deploy keys from projects you have access to ({{availableKeys.length}})
%ul.well-list{"v-if" => "availableKeys.length"}
%deploy-key-row{"v-for" => "deployKey in availableKeys", ":deploy-key" => "deployKey", ":enabled" =>"false"}
.settings-message.text-center{"v-else" => true}
No deploy keys found. Create one with the form above.
#js-deploy-keys{ data: { endpoint: namespace_project_deploy_keys_path } }
- page_title "Repository"
= render "projects/settings/head"
- content_for :page_specific_javascripts do
= page_specific_javascript_bundle_tag('common_vue')
= page_specific_javascript_bundle_tag('deploy_keys')
= render @deploy_keys
= render "projects/protected_branches/index"
= render "projects/protected_tags/index"
......@@ -26,6 +26,7 @@ var config = {
common_d3: ['d3'],
cycle_analytics: './cycle_analytics/cycle_analytics_bundle.js',
commit_pipelines: './commit/pipelines/pipelines_bundle.js',
deploy_keys: './deploy_keys/index.js',
diff_notes: './diff_notes/diff_notes_bundle.js',
environments: './environments/environments_bundle.js',
environments_folder: './environments/folder/environments_folder_bundle.js',
......
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