Add basic user interface for application repos
Adds support for creating app repos, viewing app repos and seeing the list of app repos in the Quay UI.
This commit is contained in:
parent
3dd6e6919d
commit
f9e6110f73
47 changed files with 1009 additions and 106 deletions
40
static/js/directives/ui/cor-table/cor-table-col.component.ts
Normal file
40
static/js/directives/ui/cor-table/cor-table-col.component.ts
Normal file
|
@ -0,0 +1,40 @@
|
|||
import { Input, Component } from 'angular-ts-decorators';
|
||||
import { CorTableComponent } from './cor-table.component';
|
||||
|
||||
/**
|
||||
* Defines a column (optionally sortable) in the table.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'corTableCol',
|
||||
template: '',
|
||||
require: {
|
||||
parent: '^^corTable'
|
||||
},
|
||||
})
|
||||
export class CorTableColumn implements ng.IComponentController {
|
||||
@Input('@') public title: string;
|
||||
@Input('@') public templateurl: string;
|
||||
|
||||
@Input('@') public datafield: string;
|
||||
@Input('@') public sortfield: string;
|
||||
@Input('@') public selected: string;
|
||||
@Input('@') public dataKind: string;
|
||||
|
||||
private parent: CorTableComponent;
|
||||
|
||||
public $onInit(): void {
|
||||
this.parent.addColumn(this);
|
||||
}
|
||||
|
||||
public isNumeric(): boolean {
|
||||
return this.dataKind == 'datetime';
|
||||
}
|
||||
|
||||
public processColumnForOrdered(tableService: any, value: any): any {
|
||||
if (this.dataKind == 'datetime') {
|
||||
return tableService.getReversedTimestamp(value);
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
42
static/js/directives/ui/cor-table/cor-table.component.html
Normal file
42
static/js/directives/ui/cor-table/cor-table.component.html
Normal file
|
@ -0,0 +1,42 @@
|
|||
<div class="cor-table-element">
|
||||
<span ng-transclude/>
|
||||
|
||||
<!-- Filter -->
|
||||
<div class="co-top-bar" ng-if="$ctrl.compact != 'true'">
|
||||
<span class="co-filter-box with-options" ng-if="$ctrl.tableData.length && $ctrl.filterFields.length">
|
||||
<span class="filter-message" ng-if="$ctrl.options.filter">
|
||||
Showing {{ $ctrl.orderedData.entries.length }} of {{ $ctrl.tableData.length }} {{ $ctrl.tableItemTitle }}
|
||||
</span>
|
||||
<input class="form-control" type="text" ng-model="$ctrl.options.filter"
|
||||
placeholder="Filter {{ $ctrl.tableItemTitle }}..." ng-change="$ctrl.refreshOrder()">
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<!-- Empty -->
|
||||
<div class="empty" ng-if="!$ctrl.tableData.length && $ctrl.compact != 'true'">
|
||||
<div class="empty-primary-msg">No {{ $ctrl.tableItemTitle }} found.</div>
|
||||
</div>
|
||||
|
||||
<!-- Table -->
|
||||
<table class="co-table" ng-show="$ctrl.tableData.length">
|
||||
<thead>
|
||||
<td ng-repeat="col in $ctrl.columns" ng-class="$ctrl.tablePredicateClass(col, $ctrl.options)">
|
||||
<a ng-click="$ctrl.setOrder(col)">{{ col.title }}</a>
|
||||
</td>
|
||||
</thead>
|
||||
<tbody ng-repeat="item in $ctrl.orderedData.visibleEntries | limitTo:$ctrl.maxDisplayCount">
|
||||
<tr>
|
||||
<td ng-repeat="col in $ctrl.columns">
|
||||
<div ng-include="col.templateurl" ng-if="col.templateurl"></div>
|
||||
<div ng-if="!col.templateurl">{{ item[col.datafield] }}</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<div class="empty" ng-if="!$ctrl.orderedData.entries.length && $ctrl.tableData.length"
|
||||
style="margin-top: 20px;">
|
||||
<div class="empty-primary-msg">No matching {{ $ctrl.tableItemTitle }} found.</div>
|
||||
<div class="empty-secondary-msg">Try adjusting your filter above.</div>
|
||||
</div>
|
||||
</div>
|
82
static/js/directives/ui/cor-table/cor-table.component.ts
Normal file
82
static/js/directives/ui/cor-table/cor-table.component.ts
Normal file
|
@ -0,0 +1,82 @@
|
|||
import { Input, Component } from 'angular-ts-decorators';
|
||||
import { CorTableColumn } from './cor-table-col.component';
|
||||
|
||||
/**
|
||||
* A component that displays a table of information, with optional filtering and automatic sorting.
|
||||
*/
|
||||
@Component({
|
||||
selector: 'corTable',
|
||||
templateUrl: '/static/js/directives/ui/cor-table/cor-table.component.html',
|
||||
transclude: true,
|
||||
})
|
||||
export class CorTableComponent implements ng.IComponentController {
|
||||
@Input('=') public tableData: any[];
|
||||
@Input('@') public tableItemTitle: string;
|
||||
@Input('<') public filterFields: string[];
|
||||
@Input('@') public compact: string;
|
||||
@Input('<') public maxDisplayCount: number;
|
||||
|
||||
private columns: CorTableColumn[];
|
||||
private orderedData: any;
|
||||
private options: any;
|
||||
|
||||
constructor(private TableService: any) {
|
||||
this.columns = [];
|
||||
this.options = {
|
||||
'filter': '',
|
||||
'reverse': false,
|
||||
'predicate': '',
|
||||
'page': 0,
|
||||
};
|
||||
}
|
||||
|
||||
public addColumn(col: CorTableColumn): void {
|
||||
this.columns.push(col);
|
||||
|
||||
if (col.selected == 'true') {
|
||||
this.options['predicate'] = col.datafield;
|
||||
}
|
||||
|
||||
this.refreshOrder();
|
||||
}
|
||||
|
||||
private setOrder(col: CorTableColumn): void {
|
||||
this.TableService.orderBy(col.datafield, this.options);
|
||||
this.refreshOrder();
|
||||
}
|
||||
|
||||
private tablePredicateClass(col: CorTableColumn, options: any) {
|
||||
return this.TableService.tablePredicateClass(col.datafield, this.options.predicate,
|
||||
this.options.reverse);
|
||||
}
|
||||
|
||||
private refreshOrder(): void {
|
||||
var columnMap = {};
|
||||
this.columns.forEach(function(col) {
|
||||
columnMap[col.datafield] = col;
|
||||
});
|
||||
|
||||
var filterCols = this.columns.filter(function(col) {
|
||||
return !!col.sortfield;
|
||||
}).map((col) => (col.datafield));
|
||||
|
||||
var numericCols = this.columns.filter(function(col) {
|
||||
return col.isNumeric();
|
||||
}).map((col) => (col.datafield));
|
||||
|
||||
var processed = this.tableData.map((item) => {
|
||||
var keys = Object.keys(item);
|
||||
var newObj = {};
|
||||
for (var i = 0; i < keys.length; ++i) {
|
||||
var key = keys[i];
|
||||
if (columnMap[key]) {
|
||||
newObj[key] = columnMap[key].processColumnForOrdered(this.TableService, item[key]);
|
||||
}
|
||||
}
|
||||
return newObj;
|
||||
});
|
||||
|
||||
this.orderedData = this.TableService.buildOrderedItems(processed, this.options,
|
||||
filterCols, numericCols);
|
||||
}
|
||||
}
|
Reference in a new issue