mirror of
https://github.com/goharbor/harbor.git
synced 2025-02-17 04:11:24 +01:00
updates for cookies storage processing, and other refinements.
This commit is contained in:
parent
4f34bba18f
commit
09db2d04d0
@ -20,8 +20,6 @@
|
||||
}
|
||||
|
||||
vm.retrieve = retrieve;
|
||||
vm.retrieve();
|
||||
|
||||
vm.checkProjectMember = checkProjectMember;
|
||||
|
||||
$scope.$watch('vm.selectedProject', function(current, origin) {
|
||||
@ -34,7 +32,7 @@
|
||||
vm.selectItem = selectItem;
|
||||
|
||||
$scope.$watch('vm.publicity', function(current, origin) {
|
||||
vm.publicity = current ? 1 : 0;
|
||||
vm.publicity = current ? true : false;
|
||||
vm.isPublic = vm.publicity ? 1 : 0;
|
||||
vm.projectType = (vm.isPublic === 1) ? 'public_projects' : 'my_projects';
|
||||
vm.retrieve();
|
||||
@ -65,9 +63,8 @@
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
$location.search('project_id', vm.selectedProject.ProjectId);
|
||||
vm.checkProjectMember(vm.selectedProject.ProjectId);
|
||||
$location.search('project_id', vm.selectedProject.ProjectId);
|
||||
vm.resultCount = vm.projects.length;
|
||||
|
||||
$scope.$watch('vm.filterInput', function(current, origin) {
|
||||
|
@ -1,16 +1,6 @@
|
||||
<div ng-if="!vm.isLoggedIn" class="dropdown">
|
||||
<a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-link" data-target="#" href="">
|
||||
<span class="glyphicon glyphicon-globe"></span> //vm.languageName//
|
||||
</a>
|
||||
<ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
|
||||
<li><a href="javascript:void(0);" ng-click="vm.setLanguage('en-US')">English</a></li>
|
||||
<li><a href="javascript:void(0);" ng-click="vm.setLanguage('zh-CN')">中文</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div ng-if="vm.isLoggedIn" class="dropdown">
|
||||
<a id="dLabel" role="button" data-toggle="dropdown" class="btn btn-link" data-target="#" href="">
|
||||
<span class="glyphicon glyphicon-user"></span> //vm.username//
|
||||
<a role="button" data-toggle="dropdown" class="btn btn-link" data-target="#" href="">
|
||||
<span class="glyphicon glyphicon-user"></span> //vm.user.username//
|
||||
</a>
|
||||
<ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
|
||||
<li><a href="/ng/account_setting"><span class="glyphicon glyphicon-pencil"></span> // 'account_setting' | tr //</a></li>
|
||||
@ -24,4 +14,13 @@
|
||||
<li class="divider"></li>
|
||||
<li><a href="javascript:void(0)" ng-click="vm.logOut()"><span class="glyphicon glyphicon-log-out"></span> // 'log_out' | tr //</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div ng-if="!vm.isLoggedIn" class="dropdown">
|
||||
<a role="button" data-toggle="dropdown" class="btn btn-link" data-target="#" href="">
|
||||
<span class="glyphicon glyphicon-globe"></span> //vm.languageName//
|
||||
</a>
|
||||
<ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu">
|
||||
<li><a href="javascript:void(0);" ng-click="vm.setLanguage('en-US')">English</a></li>
|
||||
<li><a href="javascript:void(0);" ng-click="vm.setLanguage('zh-CN')">中文</a></li>
|
||||
</ul>
|
||||
</div>
|
@ -6,15 +6,24 @@
|
||||
.module('harbor.optional.menu')
|
||||
.directive('optionalMenu', optionalMenu);
|
||||
|
||||
OptionalMenuController.$inject = ['$scope', '$window', '$cookies', 'I18nService', 'LogOutService'];
|
||||
OptionalMenuController.$inject = ['$window', 'I18nService', 'LogOutService', 'currentUser', '$timeout'];
|
||||
|
||||
function OptionalMenuController($scope, $window, $cookies, I18nService, LogOutService) {
|
||||
function OptionalMenuController($window, I18nService, LogOutService, currentUser, $timeout) {
|
||||
var vm = this;
|
||||
|
||||
vm.currentLanguage = I18nService().getCurrentLanguage();
|
||||
vm.setLanguage = setLanguage;
|
||||
vm.languageName = I18nService().getLanguageName(vm.currentLanguage);
|
||||
console.log('current language:' + I18nService().getCurrentLanguage());
|
||||
|
||||
|
||||
vm.isLoggedIn = false;
|
||||
$timeout(function() {
|
||||
vm.user = currentUser.get();
|
||||
if(angular.isDefined(vm.user)) {
|
||||
vm.isLoggedIn = true;
|
||||
}
|
||||
});
|
||||
|
||||
vm.setLanguage = setLanguage;
|
||||
vm.logOut = logOut;
|
||||
|
||||
function setLanguage(name) {
|
||||
@ -28,6 +37,7 @@
|
||||
.error(logOutFailed);
|
||||
}
|
||||
function logOutSuccess(data, status) {
|
||||
currentUser.unset();
|
||||
$window.location.href= '/ng';
|
||||
}
|
||||
function logOutFailed(data, status) {
|
||||
@ -39,23 +49,12 @@
|
||||
var directive = {
|
||||
'restrict': 'E',
|
||||
'templateUrl': '/static/ng/resources/js/components/optional-menu/optional-menu.directive.html',
|
||||
'link': link,
|
||||
'scope': true,
|
||||
'controller': OptionalMenuController,
|
||||
'controllerAs': 'vm',
|
||||
'bindToController': true
|
||||
};
|
||||
return directive;
|
||||
function link(scope, element, attrs, ctrl) {
|
||||
ctrl.isLoggedIn = false;
|
||||
scope.$on('currentUser', function(e, val) {
|
||||
if(val != null) {
|
||||
ctrl.isLoggedIn = true;
|
||||
ctrl.username = val.username;
|
||||
}
|
||||
scope.$apply();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -74,16 +74,11 @@
|
||||
'projectId': '=',
|
||||
'reload': '&'
|
||||
},
|
||||
'link': link,
|
||||
'controller': EditProjectMemberController,
|
||||
'controllerAs': 'vm',
|
||||
'bindToController': true
|
||||
};
|
||||
return directive;
|
||||
|
||||
function link(scope, element, attrs, ctrl) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -18,7 +18,7 @@
|
||||
<th width="30%">// 'username' | tr //</th><th width="40%">// 'role' | tr //</th><th width="30%">// 'operation' | tr //</th>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr ng-repeat="pr in vm.projectMembers" edit-project-member username="pr.username" project-id="vm.projectId" user-id="pr.UserId" current-user-id="vm.currentUser.UserId" role-name="pr.Rolename" reload='vm.search({projectId: vm.projectId, username: vm.username})'></tr>
|
||||
<tr ng-repeat="pr in vm.projectMembers" edit-project-member username="pr.username" project-id="vm.projectId" user-id="pr.UserId" current-user-id="vm.user.UserId" role-name="pr.Rolename" reload='vm.search({projectId: vm.projectId, username: vm.username})'></tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
@ -10,24 +10,19 @@
|
||||
|
||||
function ListProjectMemberController($scope, ListProjectMemberService, $routeParams, currentUser) {
|
||||
var vm = this;
|
||||
|
||||
|
||||
vm.isOpen = false;
|
||||
|
||||
|
||||
vm.isOpen = false;
|
||||
vm.search = search;
|
||||
vm.addProjectMember = addProjectMember;
|
||||
vm.retrieve = retrieve;
|
||||
|
||||
vm.projectId = $routeParams.project_id;
|
||||
vm.username = "";
|
||||
vm.currentUser = {};
|
||||
|
||||
|
||||
vm.retrieve();
|
||||
|
||||
function search(e) {
|
||||
vm.projectId = e.projectId;
|
||||
vm.username = e.username;
|
||||
console.log('project_id:' + e.projectId);
|
||||
retrieve();
|
||||
}
|
||||
|
||||
@ -46,7 +41,7 @@
|
||||
}
|
||||
|
||||
function getProjectMemberComplete(response) {
|
||||
vm.currentUser = currentUser.get();
|
||||
vm.user = currentUser.get();
|
||||
vm.projectMembers = response.data;
|
||||
}
|
||||
|
||||
@ -62,17 +57,11 @@
|
||||
templateUrl: '/static/ng/resources/js/components/project-member/list-project-member.directive.html',
|
||||
replace: true,
|
||||
scope: true,
|
||||
link: link,
|
||||
controller: ListProjectMemberController,
|
||||
controllerAs: 'vm',
|
||||
bindToController: true
|
||||
}
|
||||
|
||||
}
|
||||
return directive;
|
||||
|
||||
function link(scope, element, attrs, ctrl) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -95,18 +95,13 @@
|
||||
restrict: 'E',
|
||||
templateUrl: '/static/ng/resources/js/components/repository/list-repository.directive.html',
|
||||
replace: true,
|
||||
link: 'link',
|
||||
controller: ListRepositoryController,
|
||||
controllerAs: 'vm',
|
||||
bindToController: true
|
||||
}
|
||||
|
||||
return directive;
|
||||
|
||||
function link(scope, element, attrs, ctrl) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
})();
|
@ -1,7 +1,7 @@
|
||||
<form name="form" class="form-horizontal css-form" ng-submit="form.$valid" novalidate>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-1 col-sm-10">
|
||||
<input id="username" type="text" class="form-control" placeholder="// 'username_email' | tr //" name="uPrincipal" ng-model-options="{ debounce: 250 }" ng-change="vm.reset()" ng-model="user.principal" required>
|
||||
<input id="username" type="text" class="form-control" placeholder="// 'username_email' | tr //" name="uPrincipal" ng-change="vm.reset()" ng-model="user.principal" required>
|
||||
<div class="error-message">
|
||||
<div ng-messages="form.uPrincipal.$error" ng-if="form.uPrincipal.$touched">
|
||||
<span ng-message="required">// 'username_is_required' | tr //</span>
|
||||
@ -11,7 +11,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-1 col-sm-10">
|
||||
<input type="password" class="form-control" placeholder="// 'password' | tr //" name="uPassword" ng-model-options="{ debounce: 250 }" ng-change="vm.reset()" ng-model="user.password" required>
|
||||
<input type="password" class="form-control" placeholder="// 'password' | tr //" name="uPassword" ng-change="vm.reset()" ng-model="user.password" required>
|
||||
<div class="error-message">
|
||||
<div ng-messages="form.uPassword.$error" ng-if="form.uPassword.$touched">
|
||||
<span ng-message="required">// 'password_is_required' | tr //</span>
|
||||
@ -23,7 +23,7 @@
|
||||
<div class="form-group">
|
||||
<div class="col-sm-offset-1 col-sm-10">
|
||||
<div class="pull-right">
|
||||
<button class="btn btn-default" ng-disabled="form.$invalid" ng-click="vm.doSignIn(user)">// 'sign_in' | tr //</button>
|
||||
<button class="btn btn-default" ng-click="vm.doSignIn(user)">// 'sign_in' | tr //</button>
|
||||
<button class="btn btn-success" ng-click="vm.doSignUp()">// 'sign_up' | tr //</button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,36 +1,40 @@
|
||||
(function() {
|
||||
|
||||
'use strict';
|
||||
|
||||
angular
|
||||
.module('harbor.app')
|
||||
.module('harbor.app')
|
||||
.factory('currentUser', currentUser)
|
||||
.factory('projectMember', projectMember);
|
||||
|
||||
function currentUser() {
|
||||
var currentUser;
|
||||
.factory('currentProjectMember', currentProjectMember);
|
||||
|
||||
currentUser.$inject = ['$cookies', '$timeout'];
|
||||
|
||||
function currentUser($cookies, $timeout) {
|
||||
return {
|
||||
set: function(user) {
|
||||
currentUser = user;
|
||||
console.log('set currentUser:' + currentUser);
|
||||
$cookies.putObject('user', user, {'path': '/'});
|
||||
},
|
||||
get: function() {
|
||||
console.log('get currentUser:' + currentUser);
|
||||
return currentUser;
|
||||
return $cookies.getObject('user');
|
||||
},
|
||||
unset: function() {
|
||||
$cookies.remove('user', {'path': '/'});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function projectMember() {
|
||||
var projectMember;
|
||||
currentProjectMember.$inject = ['$cookies'];
|
||||
|
||||
function currentProjectMember($cookies) {
|
||||
return {
|
||||
set: function(member) {
|
||||
projectMember = member;
|
||||
console.log('set projectMember:');
|
||||
console.log(projectMember);
|
||||
$cookies.putObject('member', member, {'path': '/'});
|
||||
},
|
||||
get: function() {
|
||||
console.log('get projectMember:');
|
||||
console.log(projectMember);
|
||||
return projectMember;
|
||||
return $cookies.getObject('member');
|
||||
},
|
||||
unset: function() {
|
||||
$cookies.remove('member', {'path': '/'});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,23 +5,17 @@
|
||||
angular
|
||||
.module('harbor.details')
|
||||
.controller('DetailsController', DetailsController);
|
||||
|
||||
DetailsController.$inject = ['$scope', '$location', '$routeParams'];
|
||||
|
||||
function DetailsController($scope, $location, $routeParams) {
|
||||
|
||||
function DetailsController() {
|
||||
var vm = this;
|
||||
vm.isOpen = false;
|
||||
|
||||
vm.publicity = false;
|
||||
vm.isProjectMember = true;
|
||||
vm.closeRetrievePane = closeRetrievePane;
|
||||
vm.isProjectMember = false;
|
||||
|
||||
vm.togglePublicity = togglePublicity;
|
||||
|
||||
function closeRetrievePane() {
|
||||
$scope.$broadcast('isOpen', false);
|
||||
}
|
||||
function togglePublicity(e) {
|
||||
vm.publicity = e.publicity;
|
||||
console.log('current project publicity:' + vm.publicity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -6,22 +6,24 @@
|
||||
.module('harbor.layout.navigation')
|
||||
.directive('navigationHeader', navigationHeader);
|
||||
|
||||
NavigationHeaderController.$inject = ['$window', '$scope'];
|
||||
NavigationHeaderController.$inject = ['$window', '$scope', 'currentUser', '$timeout'];
|
||||
|
||||
function NavigationHeaderController($window, $scope) {
|
||||
function NavigationHeaderController($window, $scope, currentUser, $timeout) {
|
||||
var vm = this;
|
||||
vm.url = $window.location.pathname;
|
||||
vm.isAdmin = false;
|
||||
|
||||
vm.isShow = false;
|
||||
$scope.$on('currentUser', function(e, val) {
|
||||
if(val) {
|
||||
vm.isShow = true;
|
||||
vm.isAdmin = false;
|
||||
|
||||
$timeout(function() {
|
||||
vm.user = currentUser.get();
|
||||
if(angular.isDefined(vm.user)) {
|
||||
vm.isShow = true;
|
||||
if(vm.user.HasAdminRole === 1) {
|
||||
vm.isAdmin = true;
|
||||
}
|
||||
}
|
||||
if(val.HasAdminRole === 1) {
|
||||
vm.isAdmin = true;
|
||||
}
|
||||
$scope.$apply();
|
||||
});
|
||||
vm.url = $window.location.pathname;
|
||||
}
|
||||
|
||||
function navigationHeader() {
|
||||
|
@ -5,9 +5,7 @@
|
||||
angular
|
||||
.module('harbor.layout.project.member')
|
||||
.controller('ProjectMemberController', ProjectMemberController);
|
||||
|
||||
ProjectMemberController.$inject = ['$scope'];
|
||||
|
||||
|
||||
function ProjectMemberController($scope) {
|
||||
|
||||
}
|
||||
|
@ -6,9 +6,9 @@
|
||||
.module('harbor.layout.project')
|
||||
.controller('ProjectController', ProjectController);
|
||||
|
||||
ProjectController.$inject = ['$scope', 'ListProjectService'];
|
||||
ProjectController.$inject = ['$scope', 'ListProjectService', '$timeout', 'currentUser'];
|
||||
|
||||
function ProjectController($scope, ListProjectService) {
|
||||
function ProjectController($scope, ListProjectService, $timeout, currentUser) {
|
||||
var vm = this;
|
||||
|
||||
vm.isOpen = false;
|
||||
@ -21,8 +21,8 @@
|
||||
vm.showAddButton = showAddButton;
|
||||
vm.togglePublicity = togglePublicity;
|
||||
|
||||
$scope.$on('currentUser', function(e, val) {
|
||||
vm.currentUser = val;
|
||||
$timeout(function() {
|
||||
vm.user = currentUser.get();
|
||||
});
|
||||
|
||||
vm.retrieve();
|
||||
|
@ -12,28 +12,32 @@
|
||||
|
||||
var vm = this;
|
||||
|
||||
CurrentUserService()
|
||||
.then(getCurrentUserComplete)
|
||||
.catch(getCurrentUserFailed);
|
||||
if(!angular.isDefined(currentUser.get())) {
|
||||
CurrentUserService()
|
||||
.then(getCurrentUserComplete)
|
||||
.catch(getCurrentUserFailed);
|
||||
}
|
||||
|
||||
function getCurrentUserComplete(response) {
|
||||
console.log('Successful logged in.');
|
||||
$timeout(function(){
|
||||
$scope.$broadcast('currentUser', response.data);
|
||||
currentUser.set(response.data);
|
||||
}, 50);
|
||||
currentUser.set(response.data);
|
||||
}
|
||||
|
||||
function getCurrentUserFailed(e){
|
||||
var url = location.pathname;
|
||||
var exclusions = ['/ng', '/ng/forgot_password', '/ng/sign_up', '/ng/reset_password', '/ng/search', '/ng/repository'];
|
||||
var exclusions = [
|
||||
'/ng',
|
||||
'/ng/forgot_password',
|
||||
'/ng/sign_up',
|
||||
'/ng/reset_password',
|
||||
'/ng/search'
|
||||
];
|
||||
for(var i = 0; i < exclusions.length; i++) {
|
||||
if(exclusions[i]===url) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
$window.location.href = '/ng';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
})();
|
@ -35,7 +35,7 @@
|
||||
<td>N/A</td>
|
||||
<td>N/A</td>
|
||||
<td>//p.CreationTime | dateL : 'YYYY-MM-DD HH:mm:ss'//</td>
|
||||
<td><publicity-button is-public="p.Public" owned="p.OwnerId == vm.currentUser.UserId" project-id="p.ProjectId"></publicity-button></td>
|
||||
<td><publicity-button is-public="p.Public" owned="p.OwnerId == vm.user.UserId" project-id="p.ProjectId"></publicity-button></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
@ -10,7 +10,7 @@
|
||||
</div>
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
||||
<div class="collapse navbar-collapse" id="bs-harbor-navbar-collapse-1">
|
||||
<optional-menu></optional-menu>
|
||||
<optional-menu login-status="//vm.loginStatus//"></optional-menu>
|
||||
<ul class="nav navbar-nav navbar-right">
|
||||
<li>
|
||||
<navigation-header></navigation-header>
|
||||
|
@ -13,16 +13,16 @@
|
||||
<script src="/static/ng/vendors/zc/v2.2.0/ZeroClipboard.js"></script>
|
||||
|
||||
<!-- Latest compiled and minified CSS -->
|
||||
<!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">-->
|
||||
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous">
|
||||
<!--<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap.min.css" integrity="sha384-1q8mTJOASx8j1Au+a5WDVnPi2lkFfwwEAa8hDDdjZlpLegxhjVME1fgjWPGmkzs7" crossorigin="anonymous"--->
|
||||
|
||||
<!-- Optional theme -->
|
||||
<!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">-->
|
||||
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous">
|
||||
<!--<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.6/css/bootstrap-theme.min.css" integrity="sha384-fLW2N01lMqjakBkx3l/M9EahuwpSfeNvV63J5ezn3uZzapT0u7EYsXMjQV+0En5r" crossorigin="anonymous"-->
|
||||
|
||||
<!-- Latest compiled and minified JavaScript -->
|
||||
<!--<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>-->
|
||||
<script src="https://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
|
||||
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js" integrity="sha384-0mSbJDEHialfmuBBQP6A4Qrprq5OVfW37PRR3j5ELqxss1yVqOtnepnHVP9aJ7xS" crossorigin="anonymous"></script>
|
||||
<!--<script src="https://cdn.bootcss.com/bootstrap/3.3.6/js/bootstrap.min.js"></script-->
|
||||
|
||||
<link rel="stylesheet" href="/static/ng/resources/css/header.css">
|
||||
<link rel="stylesheet" href="/static/ng/resources/css/footer.css">
|
||||
|
Loading…
Reference in New Issue
Block a user