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

Commit

Permalink
ui: added visibility to namespace edit form
Browse files Browse the repository at this point in the history
The visibility change was only possible via namespaces table showed in
the namepace#index page. User can now change the visibility while
editing a namespace.

A <visibility-chooser> component was created to abstract most of the
visibilities options. <namespace-visibility> evolved to be a wrapper of
the previous component that can be used in standalone to change a
namespace remotely.

Signed-off-by: Vítor Avelino <[email protected]>
  • Loading branch information
Vítor Avelino committed May 22, 2018
1 parent 52e5c8d commit c524f37
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 112 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { handleHttpResponseError } from '~/utils/http';

import NamespacesService from '../services/namespaces';

import VisibilityChooser from './visibility-chooser';

const TYPEAHEAD_INPUT = '.remote .typeahead';

const { set } = Vue;
Expand All @@ -16,12 +18,17 @@ export default {

props: ['namespace'],

components: {
VisibilityChooser,
},

data() {
return {
model: {
namespace: {
team: this.namespace.team.name,
description: this.namespace.description,
visibility: this.namespace.visibility,
},
},
timeout: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
<template>
<div class="btn-group">
<button
class="btn btn-default private-btn"
type="button"
:title="privateTitle"
:class="{
'btn-primary': isPrivate,
}"
:disabled="isGlobal || !enabled"
@click="$emit('update:visibility', 'private')"
>
<slot name="privateIcon">
<i class="fa fa-fw fa-lock"></i>
</slot>
</button>

<button
class="btn btn-default protected-btn"
title="Logged-in users can pull images from this namespace"
type="button"
:class="{
'btn-primary': isProtected,
}"
:disabled="!enabled"
@click="$emit('update:visibility', 'protected')"
>
<slot name="protectedIcon">
<i class="fa fa-fw fa-users"></i>
</slot>
</button>

<button
class="btn btn-default public-btn"
title="Anyone can pull images from this namespace"
type="button"
:class="{
'btn-primary': isPublic
}"
:disabled="!enabled"
@click="$emit('update:visibility', 'public')"
>
<slot name="publicIcon">
<i class="fa fa-fw fa-globe"></i>
</slot>
</button>
</div>
</template>

<script>
export default {
props: ['isGlobal', 'visibility', 'canChange', 'locked'],
computed: {
isPrivate() {
return this.visibility === 'private';
},
isProtected() {
return this.visibility === 'protected';
},
isPublic() {
return this.visibility === 'public';
},
enabled() {
return this.canChange && !this.locked;
},
privateTitle() {
if (this.isGlobal) {
return 'The global namespace cannot be private';
}
return 'Team members can pull images from this namespace';
},
},
};
</script>
73 changes: 0 additions & 73 deletions app/assets/javascripts/modules/namespaces/components/visibility.js

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<template>
<visibility-chooser :is-global="namespace.global" :visibility="namespace.visibility" :can-change="namespace.permissions.visibility" :locked="onGoingRequest" @update:visibility="change">
<template slot="privateIcon">
<i class="fa fa-fw fa-spinner fa-spin" v-if="showLoading('private')"></i>
<i class="fa fa-fw fa-lock" v-else></i>
</template>
<template slot="protectedIcon">
<i class="fa fa-fw fa-spinner fa-spin" v-if="showLoading('protected')"></i>
<i class="fa fa-fw fa-users" v-else></i>
</template>
<template slot="publicIcon">
<i class="fa fa-fw fa-spinner fa-spin" v-if="showLoading('public')"></i>
<i class="fa fa-fw fa-globe" v-else></i>
</template>
</visibility-chooser>
</template>

<script>
import Vue from 'vue';
import NamespacesService from '../services/namespaces';
import VisibilityChooser from './visibility-chooser';
const { set } = Vue;
export default {
props: ['namespace'],
components: {
VisibilityChooser,
},
data() {
return {
newVisibility: null,
onGoingRequest: false,
};
},
methods: {
showLoading(visibility) {
return this.onGoingRequest &&
visibility === this.newVisibility;
},
change(visibility) {
const currentVisibility = this.namespace.visibility;
if (visibility === currentVisibility) {
return;
}
set(this, 'onGoingRequest', true);
set(this, 'newVisibility', visibility);
NamespacesService.update(this.namespace.id, { namespace: { visibility } }).then(() => {
set(this.namespace, 'visibility', visibility);
this.$alert.$show(`Visibility of '${this.namespace.name}' namespace updated`);
}).catch(() => {
this.$alert.$show('An error happened while updating namespace visibility');
}).finally(() => {
set(this, 'onGoingRequest', false);
set(this, 'newVisibility', null);
});
},
},
};
</script>
36 changes: 36 additions & 0 deletions app/assets/javascripts/modules/namespaces/mixins/visibility.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export default {
props: ['namespace'],

data() {
return {
onGoingRequest: false,
};
},

computed: {
isPrivate() {
return this.namespace.visibility === 'private';
},

isProtected() {
return this.namespace.visibility === 'protected';
},

isPublic() {
return this.namespace.visibility === 'public';
},

canChangeVibisility() {
return this.namespace.permissions.visibility &&
!this.onGoingRequest;
},

privateTitle() {
if (this.namespace.global) {
return 'The global namespace cannot be private';
}

return 'Team members can pull images from this namespace';
},
},
};
5 changes: 5 additions & 0 deletions app/views/namespaces/components/_edit_form.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@
br
span v-if="!$v.model.namespace.team.available"
| Selected team does not exist
.form-group
= f.label :visibility, class: 'control-label'
div
<visibility-chooser :is-global="namespace.global" :visibility.sync="model.namespace.visibility" :can-change="namespace.permissions.visibility"></visibility-chooser>

.form-group
= f.label :description, class: 'control-label'
= f.text_area :description, class: 'form-control fixed-size', placeholder: "A short description of your namespace", "v-model" => "model.namespace.description"
Expand Down
36 changes: 0 additions & 36 deletions app/views/namespaces/components/_visibility.html.slim

This file was deleted.

3 changes: 0 additions & 3 deletions app/views/namespaces/partials/_components_templates.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,3 @@

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

script#js-namespace-visibility-tmpl type="text/x-template"
= render "namespaces/components/visibility"

0 comments on commit c524f37

Please sign in to comment.