refactoring repo-state components

This commit is contained in:
alecmerdler 2019-11-21 15:32:08 -05:00
parent 73bab07baf
commit afcf902436
7 changed files with 135 additions and 26 deletions

View file

@ -70,21 +70,13 @@
<i class="fa fa-refresh lock-icon" quay-show="Features.REPO_MIRROR && repository.state == 'MIRROR'" ng-show="repository.state == 'MIRROR'"></i> <i class="fa fa-refresh lock-icon" quay-show="Features.REPO_MIRROR && repository.state == 'MIRROR'" ng-show="repository.state == 'MIRROR'"></i>
<div> <div>
This <span class="repository-title" repository="repository"></span> state is currently <b>{{ repository.state }}</b>. This <span class="repository-title" repository="repository"></span> state is currently <b>{{ selectedState.title }}</b>.
<span ng-show="repository.state == 'NORMAL'">Standard permissions apply.</span> <span ng-show="repository.state == 'NORMAL'">Standard permissions apply.</span>
<span ng-show="repository.state == 'READ_ONLY'">Users will not be able to push or modify images.</span> <span ng-show="repository.state == 'READ_ONLY'">Users will not be able to push or modify images.</span>
<span ng-show="repository.state == 'MIRROR'" quay-show="Features.REPO_MIRROR && repository.state == 'MIRROR'">The images and tags are maintained by Quay and Users can not push or modify them.</span> <span ng-show="repository.state == 'MIRROR'" quay-show="Features.REPO_MIRROR && repository.state == 'MIRROR'">The images and tags are maintained by Quay and Users can not push or modify them.</span>
</div> </div>
<!-- TODO: Enhance the appearance of this. Move style to .css file. --> <repo-state options="repoStates" selected-state="selectedState" on-change="changeState($event)"></repo-state>
<div style="margin-top: 1em">
<form>
<select ng-options="option for option in repoStates"
ng-model="selectedState"
ng-change="changeState()"></select>
</form>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -96,24 +96,20 @@ angular.module('quay').directive('repoPanelSettings', function () {
}, ApiService.errorDisplay('Could not change visibility')); }, ApiService.errorDisplay('Could not change visibility'));
}; };
// Hide State, for now, if mirroring feature-flag is not enabled.
if (Features.REPO_MIRROR) { if (Features.REPO_MIRROR) {
$scope.repoStates = ['NORMAL', 'READ_ONLY']; $scope.repoStates = [
} {value: 'NORMAL', title: 'Normal', description: 'Standard permissions apply.'},
{value: 'READ_ONLY', title: 'Readonly', description: 'Users will not be able to push or modify images.'},
// Only show MIRROR as an option if the feature-flag is enabled. {value: 'MIRROR', title: 'Mirror', description: 'The images and tags are maintained by Quay and Users can not push or modify them.'},
if (Features.REPO_MIRROR) { $scope.repoStates.push('MIRROR'); } ];
$scope.selectedState = $scope.repoStates.find(s => s.value === $scope.repository.state);
// Hide State, for now, if mirroring feature-flag is not enabled. $scope.changeState = function(event) {
if (Features.REPO_MIRROR) { ApiService.changeRepoState({state: event.state.value},
$scope.selectedState = $scope.repository.state; {repository: [$scope.repository.namespace, $scope.repository.name].join('/')})
$scope.changeState = function() {
let state = {'state': $scope.selectedState};
let params = {'repository': $scope.repository.namespace + '/' + $scope.repository.name};
ApiService.changeRepoState(state, params)
.then(function() { .then(function() {
$scope.repository.state = $scope.selectedState; $scope.repository.state = $scope.selectedState.value;
$route.reload(); // State will eventually affect many UI elements. Reload the view. // State will eventually affect many UI elements. Reload the view.
$route.reload();
}, ApiService.errorDisplay('Could not change state')); }, ApiService.errorDisplay('Could not change state'));
} }
} }

View file

@ -0,0 +1,72 @@
.new-repo-state .btn {
width: 95px;
position: relative;
text-align: left;
padding: 4px;
padding-left: 10px;
}
.repo-state.small .btn {
padding: 2px;
padding-left: 10px;
}
.new-repo-state .btn .caret {
position: absolute;
top: 13px;
right: 7px;
}
.repo-state.small .btn .caret {
top: 11px;
}
.new-repo-state .repo-state-help-text {
font-size: 12px;
color: #ccc;
margin-top: 4px;
margin-bottom: 2px;
}
.new-repo-state .btn {
border-left: 4px solid #ccc;
}
.new-repo-state .btn.NORMAL {
border-left-color: #5cb85c;
}
.new-repo-state .btn.READ_ONLY {
border-left-color: #5cb85c;
}
.new-repo-state .btn.MIRROR {
border-left-color: #337ab7;
}
.new-repo-state li a {
vertical-align: middle;
}
.new-repo-state li a:before {
content: "";
border-radius: 50%;
width: 10px;
height: 10px;
background: #ccc;
display: inline-block;
margin-right: 6px;
}
.new-repo-state li.NORMAL a:before {
background-color: #5cb85c;
}
.new-repo-state li.READ_ONLY a:before {
background-color: #5cb85c;
}
.new-repo-state li.MIRROR a:before {
background-color: #337ab7;
}

View file

@ -0,0 +1,16 @@
<div class="new-repo-state btn-group btn-group-sm">
<div class="dropdown" style="text-align: left;">
<button class="btn btn-default" ng-class="$ctrl.selectedState.value" data-toggle="dropdown">
<span ng-if="$ctrl.selectedState" class="repo-state-title">{{ $ctrl.selectedState.title }}</span>
<span ng-if="!$ctrl.selectedState">(Select)</span>
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li ng-repeat="option in $ctrl.options" ng-class="option.value">
<a ng-click="$ctrl.onChange.emit({state: option})">{{ option.title }}
<div class="repo-state-help-text">{{ option.description }}</div>
</a>
</li>
</ul>
</div>
</div>

View file

@ -0,0 +1,21 @@
import { Component, Input, Output, EventEmitter } from 'ng-metadata/core';
import * as template from './repo-state.component.html';
import * as styleUrl from './repo-state.component.css';
type RepoStateOption = {
value: string;
title: string;
description: string;
};
@Component({
selector: 'repo-state',
templateUrl: template,
styleUrls: [styleUrl],
})
export class RepoStateComponent {
@Input('<') public options: RepoStateOption[];
@Input('<') public selectedState: RepoStateOption;
@Output() public onChange = new EventEmitter<RepoStateOption>();
}

View file

@ -43,6 +43,7 @@ import { AppSpecificTokenManagerComponent } from './directives/ui/app-specific-t
import { ManifestLinkComponent } from './directives/ui/manifest-link/manifest-link.component'; import { ManifestLinkComponent } from './directives/ui/manifest-link/manifest-link.component';
import { ManifestSecurityView } from './directives/ui/manifest-security-view/manifest-security-view.component'; import { ManifestSecurityView } from './directives/ui/manifest-security-view/manifest-security-view.component';
import { MarkdownModule } from './directives/ui/markdown/markdown.module'; import { MarkdownModule } from './directives/ui/markdown/markdown.module';
import { RepoStateComponent } from './directives/ui/repo-state/repo-state.component';
import * as Clipboard from 'clipboard'; import * as Clipboard from 'clipboard';
@ -89,6 +90,7 @@ import * as Clipboard from 'clipboard';
AppSpecificTokenManagerComponent, AppSpecificTokenManagerComponent,
ManifestLinkComponent, ManifestLinkComponent,
ManifestSecurityView, ManifestSecurityView,
RepoStateComponent,
], ],
providers: [ providers: [
ViewArrayImpl, ViewArrayImpl,

View file

@ -1,3 +1,13 @@
declare var System: { declare var System: {
import: (module: string) => Promise<any>; import: (module: string) => Promise<any>;
}; };
declare module "*.html" {
const value: string;
export = value;
}
declare module "*.css" {
const value: string;
export = value;
}