mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-06-05 23:26:37 +02:00
Improve mobile layout and redesign admin interface (#665)
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+693
-2
@@ -21,6 +21,10 @@
|
|||||||
--primary-color: #ffffff;
|
--primary-color: #ffffff;
|
||||||
--primary-active-color: #dddddd;
|
--primary-active-color: #dddddd;
|
||||||
|
|
||||||
|
--admin-nav-bg: rgb(35, 40, 46);
|
||||||
|
--admin-nav-active: rgba(255, 255, 255, 0.1);
|
||||||
|
--admin-stat-bg: rgb(45, 50, 56);
|
||||||
|
|
||||||
background-color: var(--canvas-bg-color);
|
background-color: var(--canvas-bg-color);
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
}
|
}
|
||||||
@@ -47,6 +51,10 @@ body {
|
|||||||
--primary-color: #ffffff;
|
--primary-color: #ffffff;
|
||||||
--primary-active-color: #dddddd;
|
--primary-active-color: #dddddd;
|
||||||
|
|
||||||
|
--admin-nav-bg: #f1f3f5;
|
||||||
|
--admin-nav-active: rgba(74, 80, 123, 0.1);
|
||||||
|
--admin-stat-bg: #f8f9fa;
|
||||||
|
|
||||||
background-color: var(--canvas-bg-color);
|
background-color: var(--canvas-bg-color);
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
}
|
}
|
||||||
@@ -169,7 +177,13 @@ a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#navbarSupportedContent {
|
#navbarSupportedContent {
|
||||||
padding-right: 200px;
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 992px) {
|
||||||
|
#navbarSupportedContent {
|
||||||
|
padding-right: 200px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.generalMessage {
|
.generalMessage {
|
||||||
@@ -431,7 +445,12 @@ notebook {
|
|||||||
display: block;
|
display: block;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
padding-left: 100px;
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
notebook {
|
||||||
|
padding-left: 100px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nb-output th,
|
.nb-output th,
|
||||||
@@ -605,4 +624,676 @@ code {
|
|||||||
|
|
||||||
.diff-remove {
|
.diff-remove {
|
||||||
background: rgba(200, 100, 100, 0.5);
|
background: rgba(200, 100, 100, 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Anonymize Page Layout ===== */
|
||||||
|
|
||||||
|
.anonymize-page .sidePanel {
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-section-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin: 16px 0 10px 0;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
border-bottom: 2px solid var(--primary-bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-section-title i {
|
||||||
|
color: var(--primary-bg);
|
||||||
|
margin-right: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-submit-bar {
|
||||||
|
padding: 12px 0 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-submit-bar .btn {
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .form-check {
|
||||||
|
padding-top: 4px;
|
||||||
|
padding-bottom: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .form-check-label {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .accordion .card-header {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .accordion .btn {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Preview column on desktop */
|
||||||
|
.anonymize-preview-col {
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PR diff overflow */
|
||||||
|
.pr-diff pre {
|
||||||
|
overflow-x: auto;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.anonymize-form-col {
|
||||||
|
height: 100%;
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-preview-col {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Mobile Responsive Improvements ===== */
|
||||||
|
|
||||||
|
/* Mobile-friendly touch targets */
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.btn {
|
||||||
|
min-height: 38px;
|
||||||
|
padding: 6px 14px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.btn-sm {
|
||||||
|
min-height: 34px;
|
||||||
|
padding: 5px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav-link {
|
||||||
|
padding: 8px 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.navbar .nav-link .fa,
|
||||||
|
.navbar .nav-link .fab {
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container.page {
|
||||||
|
padding-left: 10px;
|
||||||
|
padding-right: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 { font-size: 1.6rem; }
|
||||||
|
h2 { font-size: 1.35rem; }
|
||||||
|
h3 { font-size: 1.15rem; }
|
||||||
|
|
||||||
|
/* Dashboard list items */
|
||||||
|
.col-12.d-flex.px-0.py-3 {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-12.d-flex.px-0.py-3 > .d-flex:last-child {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dropdown menus right-aligned on mobile */
|
||||||
|
.dropdown-menu {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Form controls spacing */
|
||||||
|
.form-group {
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
font-size: 16px; /* Prevents iOS zoom */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* File explorer mobile layout */
|
||||||
|
.leftCol {
|
||||||
|
max-height: 40vh;
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status bar wrapping */
|
||||||
|
.status-bar {
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-bar .btn {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 3px 8px;
|
||||||
|
min-height: 28px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Home hero section */
|
||||||
|
#home .display-4 {
|
||||||
|
font-size: 1.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#home h4.subtext-header {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Progress bars on dashboard */
|
||||||
|
.progress {
|
||||||
|
min-width: 120px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Badge readability */
|
||||||
|
.badge {
|
||||||
|
font-size: 55%;
|
||||||
|
padding: 3px 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Search & filter toolbar */
|
||||||
|
.col-2.input-group {
|
||||||
|
width: 100% !important;
|
||||||
|
max-width: 100%;
|
||||||
|
flex: 0 0 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Metadata spans wrapping */
|
||||||
|
.color-text-secondary span {
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Ko-fi widget hidden on mobile */
|
||||||
|
.floatingchat-container-wrap {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Metrics cards on home */
|
||||||
|
.col-md-4 h3 {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ---- Anonymize page mobile ---- */
|
||||||
|
|
||||||
|
.anonymize-page > .row {
|
||||||
|
height: auto !important;
|
||||||
|
min-height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .sidePanel {
|
||||||
|
height: auto !important;
|
||||||
|
overflow: visible !important;
|
||||||
|
border-bottom: 2px solid var(--border-color);
|
||||||
|
padding-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .sidePanel .card,
|
||||||
|
.anonymize-page .sidePanel .container {
|
||||||
|
max-width: 100%;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-form-col {
|
||||||
|
max-width: 100% !important;
|
||||||
|
flex: 0 0 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-preview-col {
|
||||||
|
height: auto !important;
|
||||||
|
max-height: none;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
padding-top: 12px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-section-title {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
margin: 12px 0 8px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-submit-bar {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
background: var(--sidebar-bg-color);
|
||||||
|
padding: 10px 0;
|
||||||
|
margin: 0 -8px;
|
||||||
|
padding-left: 8px;
|
||||||
|
padding-right: 8px;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
z-index: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-submit-bar .btn {
|
||||||
|
font-size: 1rem;
|
||||||
|
padding: 12px 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .card-title {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Compact checkboxes on mobile */
|
||||||
|
.anonymize-page .form-check {
|
||||||
|
padding-top: 6px;
|
||||||
|
padding-bottom: 6px;
|
||||||
|
min-height: 36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .form-check-label {
|
||||||
|
font-size: 0.95rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.anonymize-page .card-body {
|
||||||
|
padding: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* PR preview on mobile */
|
||||||
|
.pr-title {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-diff pre {
|
||||||
|
font-size: 0.75rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pr-comment .mb-1 h5 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs .nav-link {
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tablet tweaks */
|
||||||
|
@media (min-width: 768px) and (max-width: 991px) {
|
||||||
|
.container.page {
|
||||||
|
max-width: 100%;
|
||||||
|
padding-left: 15px;
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftCol {
|
||||||
|
flex: 0 0 250px;
|
||||||
|
width: 250px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile toggle for file explorer sidebar */
|
||||||
|
.sidebar-toggle {
|
||||||
|
display: none;
|
||||||
|
width: 100%;
|
||||||
|
padding: 8px;
|
||||||
|
text-align: center;
|
||||||
|
background: var(--sidebar-bg-color);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--color);
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.sidebar-toggle {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.leftCol.collapsed {
|
||||||
|
display: none !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ===== Admin Interface Improvements ===== */
|
||||||
|
|
||||||
|
/* Admin navigation tabs */
|
||||||
|
.admin-nav {
|
||||||
|
display: flex;
|
||||||
|
background: var(--admin-nav-bg);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 4px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
gap: 4px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-nav a {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 4px;
|
||||||
|
color: var(--color);
|
||||||
|
text-decoration: none;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 500;
|
||||||
|
transition: background-color 0.15s, color 0.15s;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-nav a:hover {
|
||||||
|
background: var(--admin-nav-active);
|
||||||
|
color: var(--color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-nav a.active {
|
||||||
|
background: var(--primary-bg);
|
||||||
|
color: var(--primary-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-nav a i {
|
||||||
|
font-size: 14px;
|
||||||
|
width: 16px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.admin-nav {
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
.admin-nav a {
|
||||||
|
justify-content: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin stat cards */
|
||||||
|
.admin-stats {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
|
||||||
|
gap: 12px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-stat-card {
|
||||||
|
background: var(--admin-stat-bg);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 14px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-stat-card .stat-value {
|
||||||
|
font-size: 1.5rem;
|
||||||
|
font-weight: 700;
|
||||||
|
line-height: 1.2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-stat-card .stat-label {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.5px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin toolbar */
|
||||||
|
.admin-toolbar {
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
align-items: center;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
margin-bottom: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-toolbar .form-control {
|
||||||
|
max-width: 300px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.admin-toolbar .form-control {
|
||||||
|
max-width: 100%;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-toolbar .pagination-compact {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-toolbar .pagination-compact input {
|
||||||
|
width: 60px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-toolbar .pagination-compact .btn {
|
||||||
|
padding: 4px 10px;
|
||||||
|
min-height: 34px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin list items */
|
||||||
|
.admin-list-item {
|
||||||
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 12px;
|
||||||
|
padding: 12px 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-list-item:last-child {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-list-item .item-main {
|
||||||
|
flex: 1;
|
||||||
|
min-width: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-list-item .item-title {
|
||||||
|
font-size: 1rem;
|
||||||
|
font-weight: 600;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-list-item .item-meta {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-list-item .item-meta span {
|
||||||
|
margin-right: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-list-item .item-actions {
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.admin-list-item {
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
.admin-list-item .item-actions {
|
||||||
|
align-self: flex-start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Status badge improvements */
|
||||||
|
.status-badge {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 11px;
|
||||||
|
font-weight: 600;
|
||||||
|
padding: 2px 8px;
|
||||||
|
border-radius: 10px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-ready {
|
||||||
|
background: #28a745;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-error {
|
||||||
|
background: #dc3545;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-preparing,
|
||||||
|
.status-badge.status-download {
|
||||||
|
background: #17a2b8;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-expired,
|
||||||
|
.status-badge.status-removed,
|
||||||
|
.status-badge.status-removing,
|
||||||
|
.status-badge.status-expiring {
|
||||||
|
background: #ffc107;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-badge.status-active {
|
||||||
|
background: #28a745;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin queue job cards */
|
||||||
|
.queue-job-card {
|
||||||
|
background: var(--admin-stat-bg);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 12px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-job-card .job-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-job-card .job-id {
|
||||||
|
font-weight: 600;
|
||||||
|
font-size: 0.95rem;
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-job-card .job-timestamps {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
gap: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-job-card .job-actions {
|
||||||
|
display: flex;
|
||||||
|
gap: 6px;
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.queue-job-card .job-actions .btn {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 3px 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Admin section headers */
|
||||||
|
.admin-section-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 10px 0;
|
||||||
|
margin-top: 12px;
|
||||||
|
border-bottom: 2px solid var(--primary-bg);
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-section-header h2 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.15rem;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
.admin-section-header .section-count {
|
||||||
|
background: var(--primary-bg);
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding: 2px 10px;
|
||||||
|
border-radius: 10px;
|
||||||
|
font-weight: 600;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* User detail card */
|
||||||
|
.user-detail-card {
|
||||||
|
background: var(--admin-stat-bg);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-detail-card .user-header {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 16px;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-detail-card .user-header img {
|
||||||
|
border-radius: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-detail-card .user-header h1 {
|
||||||
|
margin: 0;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-detail-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 1fr;
|
||||||
|
gap: 8px 16px;
|
||||||
|
font-size: 0.9rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-detail-grid .detail-label {
|
||||||
|
font-weight: 600;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-detail-grid .detail-value {
|
||||||
|
word-break: break-all;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 767px) {
|
||||||
|
.user-detail-grid {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
.user-detail-grid .detail-label {
|
||||||
|
margin-top: 8px;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
padding-top: 8px;
|
||||||
|
}
|
||||||
|
.user-detail-grid .detail-label:first-child {
|
||||||
|
border-top: none;
|
||||||
|
margin-top: 0;
|
||||||
|
padding-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Empty state */
|
||||||
|
.empty-state {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40px 20px;
|
||||||
|
opacity: 0.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.empty-state i {
|
||||||
|
font-size: 2rem;
|
||||||
|
margin-bottom: 10px;
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
@@ -1,290 +1,196 @@
|
|||||||
<div class="container page">
|
<div class="container page">
|
||||||
<div class="row">
|
<!-- Admin Navigation -->
|
||||||
<div class="border-bottom color-border-secondary py-3 w-100">
|
<nav class="admin-nav">
|
||||||
<div class="d-flex flex-items-start w-100">
|
<a href="/admin/">
|
||||||
<form class="w-100" aria-label="Conferences" accept-charset="UTF-8">
|
<i class="fas fa-code-branch"></i> Repositories
|
||||||
<div class="d-flex flex-column flex-lg-row flex-auto">
|
</a>
|
||||||
<div class="mb-1 mb-md-0 mr-md-3">
|
<a href="/admin/users">
|
||||||
<input
|
<i class="fas fa-users"></i> Users
|
||||||
type="search"
|
</a>
|
||||||
id="search"
|
<a href="/admin/conferences" class="active">
|
||||||
class="form-control"
|
<i class="fas fa-chalkboard-teacher"></i> Conferences
|
||||||
aria-label="Find a conference…"
|
</a>
|
||||||
placeholder="Find a conference…"
|
<a href="/admin/queues">
|
||||||
autocomplete="off"
|
<i class="fas fa-tasks"></i> Queues
|
||||||
ng-model="query.search"
|
</a>
|
||||||
/>
|
</nav>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-1 mb-md-0 mr-md-3 col-2 input-group">
|
<!-- Summary Stats -->
|
||||||
<input
|
<div class="admin-stats">
|
||||||
type="number"
|
<div class="admin-stat-card">
|
||||||
id="page"
|
<div class="stat-value" ng-bind="total >= 0 ? (total | number) : '...'"></div>
|
||||||
class="form-control"
|
<div class="stat-label">Total Conferences</div>
|
||||||
autocomplete="off"
|
</div>
|
||||||
ng-model="query.page"
|
<div class="admin-stat-card">
|
||||||
min="1"
|
<div class="stat-value">{{query.page}}/{{totalPage || '...'}}</div>
|
||||||
max="{{totalPage}}"
|
<div class="stat-label">Current Page</div>
|
||||||
/>
|
</div>
|
||||||
<div class="input-group-append">
|
</div>
|
||||||
<span class="input-group-text">/{{totalPage}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex flex-wrap">
|
<!-- Toolbar -->
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
<div class="admin-toolbar">
|
||||||
<button
|
<input
|
||||||
class="btn btn-secondary dropdown-toggle"
|
type="search"
|
||||||
type="button"
|
class="form-control"
|
||||||
id="dropdownSort"
|
aria-label="Search conferences..."
|
||||||
data-toggle="dropdown"
|
placeholder="Search conferences..."
|
||||||
aria-haspopup="true"
|
autocomplete="off"
|
||||||
aria-expanded="false"
|
ng-model="query.search"
|
||||||
>
|
/>
|
||||||
Sort
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
|
||||||
<h6 class="dropdown-header">Select order</h6>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortFullName"
|
|
||||||
value="source.conferenceName"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortFullName">
|
|
||||||
Conference
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortAnonymizeDate"
|
|
||||||
value="anonymizeDate"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortAnonymizeDate">
|
|
||||||
Anonymize Date
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortStatus"
|
|
||||||
value="status"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortStatus">
|
|
||||||
Status
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortLastView"
|
|
||||||
value="lastView"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortLastView">
|
|
||||||
Last View
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortPageView"
|
|
||||||
value="pageView"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortPageView">
|
|
||||||
Page View
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
<div class="pagination-compact">
|
||||||
<button
|
<button class="btn btn-sm" ng-click="query.page = Math.max(1, query.page - 1)" ng-disabled="query.page <= 1">
|
||||||
class="btn btn-secondary dropdown-toggle"
|
<i class="fas fa-chevron-left"></i>
|
||||||
type="button"
|
</button>
|
||||||
id="dropdownStatus"
|
<input
|
||||||
data-toggle="dropdown"
|
type="number"
|
||||||
aria-haspopup="true"
|
class="form-control form-control-sm"
|
||||||
aria-expanded="false"
|
ng-model="query.page"
|
||||||
>
|
min="1"
|
||||||
Status
|
max="{{totalPage}}"
|
||||||
</button>
|
/>
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownStatus">
|
<span>/{{totalPage}}</span>
|
||||||
<h6 class="dropdown-header">Select status</h6>
|
<button class="btn btn-sm" ng-click="query.page = Math.min(totalPage, query.page + 1)" ng-disabled="query.page >= totalPage">
|
||||||
<div class="form-check dropdown-item">
|
<i class="fas fa-chevron-right"></i>
|
||||||
<input
|
</button>
|
||||||
class="form-check-input"
|
</div>
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
<div class="dropdown">
|
||||||
id="statusReady"
|
<button
|
||||||
value="ready"
|
class="btn btn-sm dropdown-toggle"
|
||||||
ng-model="query.ready"
|
type="button"
|
||||||
/>
|
id="dropdownSort"
|
||||||
<label class="form-check-label" for="statusReady">
|
data-toggle="dropdown"
|
||||||
Ready
|
>
|
||||||
</label>
|
<i class="fas fa-sort"></i> Sort
|
||||||
</div>
|
</button>
|
||||||
<div class="form-check dropdown-item">
|
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
||||||
<input
|
<h6 class="dropdown-header">Sort by</h6>
|
||||||
class="form-check-input"
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'source.conferenceName'">
|
||||||
type="checkbox"
|
<i class="fas fa-check" ng-show="query.sort == 'source.conferenceName'"></i> Conference
|
||||||
name="sort"
|
</a>
|
||||||
id="statusExpired"
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'anonymizeDate'">
|
||||||
value="expired"
|
<i class="fas fa-check" ng-show="query.sort == 'anonymizeDate'"></i> Anonymize Date
|
||||||
ng-model="query.expired"
|
</a>
|
||||||
/>
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'status'">
|
||||||
<label class="form-check-label" for="statusExpired">
|
<i class="fas fa-check" ng-show="query.sort == 'status'"></i> Status
|
||||||
Expired
|
</a>
|
||||||
</label>
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'lastView'">
|
||||||
</div>
|
<i class="fas fa-check" ng-show="query.sort == 'lastView'"></i> Last View
|
||||||
<div class="form-check dropdown-item">
|
</a>
|
||||||
<input
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'pageView'">
|
||||||
class="form-check-input"
|
<i class="fas fa-check" ng-show="query.sort == 'pageView'"></i> Page Views
|
||||||
type="checkbox"
|
</a>
|
||||||
name="sort"
|
|
||||||
id="statusExpired"
|
|
||||||
value="expired"
|
|
||||||
ng-model="query.preparing"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusExpired">
|
|
||||||
Preparing
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusRemoved"
|
|
||||||
value="removed"
|
|
||||||
ng-model="query.removed"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusRemoved">
|
|
||||||
Removed
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusRemoved"
|
|
||||||
value="removed"
|
|
||||||
ng-model="query.error"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusRemoved">
|
|
||||||
Error
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="p-0 m-0 w-100">
|
|
||||||
<li
|
<div class="dropdown">
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<button
|
||||||
ng-class="{'expired': conference.status == 'expired','removed': conference.status == 'removed','error': conference.status == 'error' }"
|
class="btn btn-sm dropdown-toggle"
|
||||||
ng-repeat="conference in conferences| filter:conferenceFiler| orderBy:orderBy as filteredConferences"
|
type="button"
|
||||||
|
id="dropdownStatus"
|
||||||
|
data-toggle="dropdown"
|
||||||
>
|
>
|
||||||
<div class="w-100">
|
<i class="fas fa-filter"></i> Status
|
||||||
<div class="">
|
</button>
|
||||||
<h3>
|
<div class="dropdown-menu" aria-labelledby="dropdownStatus">
|
||||||
<a
|
<h6 class="dropdown-header">Filter by status</h6>
|
||||||
ng-href="/conference/{{conference.conferenceID}}"
|
<label class="dropdown-item mb-0">
|
||||||
ng-bind="conference.name"
|
<input type="checkbox" ng-model="query.ready" /> Ready
|
||||||
></a>
|
</label>
|
||||||
<span
|
<label class="dropdown-item mb-0">
|
||||||
class="badge"
|
<input type="checkbox" ng-model="query.preparing" /> Preparing
|
||||||
ng-class="{'badge-warning': conference.status == 'removed' || conference.status == 'expired', 'badge-success': conference.status == 'ready', 'badge-danger': ''}"
|
</label>
|
||||||
ng-bind="conference.status | title"
|
<label class="dropdown-item mb-0">
|
||||||
></span>
|
<input type="checkbox" ng-model="query.expired" /> Expired
|
||||||
</h3>
|
</label>
|
||||||
<span class="color-text-secondary mb-1 ng-binding">
|
<label class="dropdown-item mb-0">
|
||||||
Conference ID: '{{conference.conferenceID}}'
|
<input type="checkbox" ng-model="query.removed" /> Removed
|
||||||
</span>
|
</label>
|
||||||
</div>
|
<label class="dropdown-item mb-0">
|
||||||
<div class="color-text-secondary mt-2">
|
<input type="checkbox" ng-model="query.error" /> Error
|
||||||
<span
|
</label>
|
||||||
class="ml-0 mr-3"
|
</div>
|
||||||
title="# conference: {{conference.nbConference || 0 | number}}"
|
</div>
|
||||||
data-toggle="tooltip"
|
</div>
|
||||||
data-placement="bottom"
|
|
||||||
>
|
<!-- Conference List -->
|
||||||
<i class="fas fa-table"></i>
|
<div
|
||||||
{{::conference.repositories.length || 0 | number}}</span
|
class="admin-list-item"
|
||||||
>
|
ng-repeat="conference in conferences | filter:conferenceFiler | orderBy:orderBy as filteredConferences"
|
||||||
<span class="ml-0 mr-3">
|
>
|
||||||
<i class="fas fa-euro-sign"></i>
|
<div class="item-main">
|
||||||
Total: {{conference.price || 0 | number}} €
|
<div class="item-title">
|
||||||
</span>
|
<a
|
||||||
<span class="ml-0 mr-3">
|
ng-href="/conference/{{conference.conferenceID}}"
|
||||||
<i class="fas fa-calendar-alt"></i>
|
ng-bind="conference.name"
|
||||||
From {{conference.startDate | date}} to {{conference.endDate |
|
></a>
|
||||||
date}}</span
|
<span
|
||||||
>
|
class="status-badge"
|
||||||
</div>
|
ng-class="'status-' + conference.status"
|
||||||
|
>{{conference.status | title}}</span>
|
||||||
|
</div>
|
||||||
|
<div class="item-meta">
|
||||||
|
<span>
|
||||||
|
<i class="fas fa-fingerprint"></i> ID: {{conference.conferenceID}}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<i class="fas fa-table"></i> {{::conference.repositories.length || 0 | number}} repos
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<i class="fas fa-euro-sign"></i> {{conference.price || 0 | number}} €
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<i class="fas fa-calendar-alt"></i>
|
||||||
|
{{conference.startDate | date}} – {{conference.endDate | date}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-actions">
|
||||||
|
<div class="dropdown">
|
||||||
|
<button
|
||||||
|
class="btn dropdown-toggle btn-sm"
|
||||||
|
type="button"
|
||||||
|
data-toggle="dropdown"
|
||||||
|
>
|
||||||
|
Actions
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<a class="dropdown-item" href="/conference/{{conference.conferenceID}}/edit">
|
||||||
|
<i class="far fa-edit"></i> Edit
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-item" href="/conference/{{conference.conferenceID}}/">
|
||||||
|
<i class="fa fa-eye"></i> View
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a
|
||||||
|
class="dropdown-item text-danger"
|
||||||
|
href="#"
|
||||||
|
ng-show="conference.status != 'removed'"
|
||||||
|
ng-click="removeConference(conference)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-trash-alt"></i> Remove
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex">
|
</div>
|
||||||
<div class="dropdown">
|
</div>
|
||||||
<button
|
</div>
|
||||||
class="btn black_border dropdown-toggle btn-sm"
|
|
||||||
type="button"
|
<div class="empty-state" ng-if="filteredConferences.length == 0">
|
||||||
id="dropdownMenuButton"
|
<i class="fas fa-chalkboard-teacher"></i>
|
||||||
data-toggle="dropdown"
|
No conferences match the current filters.
|
||||||
aria-haspopup="true"
|
</div>
|
||||||
aria-expanded="false"
|
|
||||||
>
|
<!-- Bottom pagination -->
|
||||||
Actions
|
<div class="admin-toolbar" ng-if="totalPage > 1" style="justify-content: center; border-bottom: none;">
|
||||||
</button>
|
<div class="pagination-compact">
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
<button class="btn btn-sm" ng-click="query.page = Math.max(1, query.page - 1)" ng-disabled="query.page <= 1">
|
||||||
<a
|
<i class="fas fa-chevron-left"></i> Previous
|
||||||
class="dropdown-item"
|
</button>
|
||||||
href="/conference/{{conference.conferenceID}}/edit"
|
<span>Page {{query.page}} of {{totalPage}}</span>
|
||||||
>
|
<button class="btn btn-sm" ng-click="query.page = Math.min(totalPage, query.page + 1)" ng-disabled="query.page >= totalPage">
|
||||||
<i class="far fa-edit" aria-hidden="true"></i> Edit
|
Next <i class="fas fa-chevron-right"></i>
|
||||||
</a>
|
</button>
|
||||||
<a
|
</div>
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="conference.status != 'removed'"
|
|
||||||
ng-click="removeConference(conference)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-trash-alt"></i> Remove
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="/conference/{{conference.conferenceID}}/"
|
|
||||||
>
|
|
||||||
<i class="fa fa-eye" aria-hidden="true"></i> View conference
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
|
||||||
ng-if="filteredConferences.length == 0"
|
|
||||||
>
|
|
||||||
There is no conference to display.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+192
-223
@@ -1,226 +1,195 @@
|
|||||||
<div class="container page">
|
<div class="container page">
|
||||||
<div class="row">
|
<!-- Admin Navigation -->
|
||||||
<h1>Download jobs</h1>
|
<nav class="admin-nav">
|
||||||
<ul class="p-0 m-0 w-100">
|
<a href="/admin/">
|
||||||
<li
|
<i class="fas fa-code-branch"></i> Repositories
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
</a>
|
||||||
ng-repeat="job in downloadJobs as filteredDownloadJobs"
|
<a href="/admin/users">
|
||||||
>
|
<i class="fas fa-users"></i> Users
|
||||||
<div class="w-100">
|
</a>
|
||||||
<div class="">
|
<a href="/admin/conferences">
|
||||||
<h3>
|
<i class="fas fa-chalkboard-teacher"></i> Conferences
|
||||||
<a target="__blank" ng-href="/r/{{job.id}}" ng-bind="job.id"></a>
|
</a>
|
||||||
<span class="badge" ng-bind="job.progress.status | title"></span>
|
<a href="/admin/queues" class="active">
|
||||||
</h3>
|
<i class="fas fa-tasks"></i> Queues
|
||||||
</div>
|
</a>
|
||||||
<div class="color-text-secondary mb-1">
|
</nav>
|
||||||
<span ng-if="job.timestamp">
|
|
||||||
Created on:
|
<!-- Summary Stats -->
|
||||||
<span ng-bind="job.timestamp | humanTime"></span>
|
<div class="admin-stats">
|
||||||
</span>
|
<div class="admin-stat-card">
|
||||||
<span ng-if="job.finishedOn">
|
<div class="stat-value">{{downloadJobs.length || 0}}</div>
|
||||||
Finished on:
|
<div class="stat-label">Download Jobs</div>
|
||||||
<span ng-bind="job.finishedOn | humanTime"></span>
|
</div>
|
||||||
</span>
|
<div class="admin-stat-card">
|
||||||
<span ng-if="job.processedOn">
|
<div class="stat-value">{{removeJobs.length || 0}}</div>
|
||||||
Processed on:
|
<div class="stat-label">Remove Jobs</div>
|
||||||
<span ng-bind="job.processedOn | humanTime"></span>
|
</div>
|
||||||
</span>
|
<div class="admin-stat-card">
|
||||||
</div>
|
<div class="stat-value">{{removeCaches.length || 0}}</div>
|
||||||
<div>
|
<div class="stat-label">Cache Jobs</div>
|
||||||
<pre
|
</div>
|
||||||
ng-repeat="stack in job.stacktrace track by $index"
|
</div>
|
||||||
><code ng-bind="stack"></code></pre>
|
|
||||||
</div>
|
<!-- Download Jobs -->
|
||||||
</div>
|
<div class="admin-section-header">
|
||||||
<div class="d-flex">
|
<h2><i class="fas fa-download mr-1"></i> Download Jobs</h2>
|
||||||
<div class="dropdown">
|
<span class="section-count">{{downloadJobs.length || 0}}</span>
|
||||||
<button
|
</div>
|
||||||
class="btn black_border dropdown-toggle btn-sm"
|
|
||||||
type="button"
|
<div
|
||||||
id="dropdownMenuButton"
|
class="queue-job-card"
|
||||||
data-toggle="dropdown"
|
ng-repeat="job in downloadJobs as filteredDownloadJobs"
|
||||||
aria-haspopup="true"
|
>
|
||||||
aria-expanded="false"
|
<div class="job-header">
|
||||||
>
|
<div class="job-id">
|
||||||
Actions
|
<a target="_blank" ng-href="/r/{{job.id}}" ng-bind="job.id"></a>
|
||||||
</button>
|
<span
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
class="status-badge"
|
||||||
<a
|
ng-class="'status-' + job.progress.status"
|
||||||
class="dropdown-item"
|
>{{job.progress.status | title}}</span>
|
||||||
href="#"
|
</div>
|
||||||
ng-click="removeJob('download', job)"
|
</div>
|
||||||
>
|
<div class="job-timestamps">
|
||||||
<i class="fas fa-trash-alt"></i> Remove
|
<span ng-if="job.timestamp">
|
||||||
</a>
|
<i class="fas fa-clock"></i> Created: {{job.timestamp | humanTime}}
|
||||||
<a
|
</span>
|
||||||
class="dropdown-item"
|
<span ng-if="job.processedOn">
|
||||||
href="#"
|
<i class="fas fa-cog"></i> Processed: {{job.processedOn | humanTime}}
|
||||||
ng-click="retryJob('download', job)"
|
</span>
|
||||||
>
|
<span ng-if="job.finishedOn">
|
||||||
<i class="fas fa-sync"></i> Retry
|
<i class="fas fa-check"></i> Finished: {{job.finishedOn | humanTime}}
|
||||||
</a>
|
</span>
|
||||||
<a class="dropdown-item" href="/anonymize/{{job.id}}">
|
</div>
|
||||||
<i class="far fa-edit" aria-hidden="true"></i> Edit
|
<div ng-if="job.stacktrace.length">
|
||||||
</a>
|
<pre
|
||||||
</div>
|
ng-repeat="stack in job.stacktrace track by $index"
|
||||||
</div>
|
style="font-size: 0.8rem; max-height: 100px; overflow: auto; margin: 6px 0 0 0"
|
||||||
</div>
|
><code ng-bind="stack"></code></pre>
|
||||||
</li>
|
</div>
|
||||||
<li
|
<div class="job-actions">
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<button class="btn btn-sm" ng-click="retryJob('download', job)">
|
||||||
ng-if="filteredDownloadJobs.length == 0"
|
<i class="fas fa-sync"></i> Retry
|
||||||
>
|
</button>
|
||||||
There is no job to display.
|
<button class="btn btn-sm" ng-click="removeJob('download', job)">
|
||||||
</li>
|
<i class="fas fa-trash-alt"></i> Remove
|
||||||
</ul>
|
</button>
|
||||||
<h1>Remove jobs</h1>
|
<a class="btn btn-sm" href="/anonymize/{{job.id}}">
|
||||||
<ul class="p-0 m-0 w-100">
|
<i class="far fa-edit"></i> Edit
|
||||||
<li
|
</a>
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
</div>
|
||||||
ng-repeat="job in removeJobs as filteredRemoveJobs"
|
</div>
|
||||||
>
|
|
||||||
<div class="w-100">
|
<div class="empty-state" ng-if="filteredDownloadJobs.length == 0" style="padding: 20px">
|
||||||
<div class="">
|
<i class="fas fa-check-circle"></i>
|
||||||
<h3>
|
No download jobs in the queue.
|
||||||
<a target="__blank" ng-href="/r/{{job.id}}" ng-bind="job.id"></a>
|
</div>
|
||||||
<span class="badge" ng-bind="job.progress.status | title"></span>
|
|
||||||
</h3>
|
<!-- Remove Jobs -->
|
||||||
</div>
|
<div class="admin-section-header">
|
||||||
<div class="color-text-secondary mb-1">
|
<h2><i class="fas fa-trash mr-1"></i> Remove Jobs</h2>
|
||||||
<span ng-if="job.timestamp">
|
<span class="section-count">{{removeJobs.length || 0}}</span>
|
||||||
Created on:
|
</div>
|
||||||
<span ng-bind="job.timestamp | humanTime"></span>
|
|
||||||
</span>
|
<div
|
||||||
<span ng-if="job.finishedOn">
|
class="queue-job-card"
|
||||||
Finished on:
|
ng-repeat="job in removeJobs as filteredRemoveJobs"
|
||||||
<span ng-bind="job.finishedOn | humanTime"></span>
|
>
|
||||||
</span>
|
<div class="job-header">
|
||||||
<span ng-if="job.processedOn">
|
<div class="job-id">
|
||||||
Processed on:
|
<a target="_blank" ng-href="/r/{{job.id}}" ng-bind="job.id"></a>
|
||||||
<span ng-bind="job.processedOn | humanTime"></span>
|
<span
|
||||||
</span>
|
class="status-badge"
|
||||||
</div>
|
ng-class="'status-' + job.progress.status"
|
||||||
<div>
|
>{{job.progress.status | title}}</span>
|
||||||
<pre
|
</div>
|
||||||
ng-repeat="stack in job.stacktrace track by $index"
|
</div>
|
||||||
><code ng-bind="stack"></code></pre>
|
<div class="job-timestamps">
|
||||||
</div>
|
<span ng-if="job.timestamp">
|
||||||
</div>
|
<i class="fas fa-clock"></i> Created: {{job.timestamp | humanTime}}
|
||||||
<div class="d-flex">
|
</span>
|
||||||
<div class="dropdown">
|
<span ng-if="job.processedOn">
|
||||||
<button
|
<i class="fas fa-cog"></i> Processed: {{job.processedOn | humanTime}}
|
||||||
class="btn black_border dropdown-toggle btn-sm"
|
</span>
|
||||||
type="button"
|
<span ng-if="job.finishedOn">
|
||||||
id="dropdownMenuButton"
|
<i class="fas fa-check"></i> Finished: {{job.finishedOn | humanTime}}
|
||||||
data-toggle="dropdown"
|
</span>
|
||||||
aria-haspopup="true"
|
</div>
|
||||||
aria-expanded="false"
|
<div ng-if="job.stacktrace.length">
|
||||||
>
|
<pre
|
||||||
Actions
|
ng-repeat="stack in job.stacktrace track by $index"
|
||||||
</button>
|
style="font-size: 0.8rem; max-height: 100px; overflow: auto; margin: 6px 0 0 0"
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
><code ng-bind="stack"></code></pre>
|
||||||
<a
|
</div>
|
||||||
class="dropdown-item"
|
<div class="job-actions">
|
||||||
href="#"
|
<button class="btn btn-sm" ng-click="retryJob('remove', job)">
|
||||||
ng-click="removeJob('remove', job)"
|
<i class="fas fa-sync"></i> Retry
|
||||||
>
|
</button>
|
||||||
<i class="fas fa-trash-alt"></i> Remove
|
<button class="btn btn-sm" ng-click="removeJob('remove', job)">
|
||||||
</a>
|
<i class="fas fa-trash-alt"></i> Remove
|
||||||
<a
|
</button>
|
||||||
class="dropdown-item"
|
<a class="btn btn-sm" href="/anonymize/{{job.id}}">
|
||||||
href="#"
|
<i class="far fa-edit"></i> Edit
|
||||||
ng-click="retryJob('remove', job)"
|
</a>
|
||||||
>
|
</div>
|
||||||
<i class="fas fa-sync"></i> Retry
|
</div>
|
||||||
</a>
|
|
||||||
<a class="dropdown-item" href="/anonymize/{{job.id}}">
|
<div class="empty-state" ng-if="filteredRemoveJobs.length == 0" style="padding: 20px">
|
||||||
<i class="far fa-edit" aria-hidden="true"></i> Edit
|
<i class="fas fa-check-circle"></i>
|
||||||
</a>
|
No remove jobs in the queue.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
<!-- Cache Jobs -->
|
||||||
</li>
|
<div class="admin-section-header">
|
||||||
<li
|
<h2><i class="fas fa-broom mr-1"></i> Cache Cleanup Jobs</h2>
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<span class="section-count">{{removeCaches.length || 0}}</span>
|
||||||
ng-if="filteredRemoveJobs.length == 0"
|
</div>
|
||||||
>
|
|
||||||
There is no job to display.
|
<div
|
||||||
</li>
|
class="queue-job-card"
|
||||||
</ul>
|
ng-repeat="job in removeCaches as filteredRemoveCache"
|
||||||
<h1>Remove Cache</h1>
|
>
|
||||||
<ul class="p-0 m-0 w-100">
|
<div class="job-header">
|
||||||
<li
|
<div class="job-id">
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<a target="_blank" ng-href="/r/{{job.id}}" ng-bind="job.id"></a>
|
||||||
ng-repeat="job in removeCaches as filteredRemoveCache"
|
<span
|
||||||
>
|
class="status-badge"
|
||||||
<div class="w-100">
|
ng-class="'status-' + job.progress.status"
|
||||||
<div class="">
|
>{{job.progress.status | title}}</span>
|
||||||
<h3>
|
</div>
|
||||||
<a target="__blank" ng-href="/r/{{job.id}}" ng-bind="job.id"></a>
|
</div>
|
||||||
<span class="badge" ng-bind="job.progress.status | title"></span>
|
<div class="job-timestamps">
|
||||||
</h3>
|
<span ng-if="job.timestamp">
|
||||||
</div>
|
<i class="fas fa-clock"></i> Created: {{job.timestamp | humanTime}}
|
||||||
<div class="color-text-secondary mb-1">
|
</span>
|
||||||
<span ng-if="job.timestamp">
|
<span ng-if="job.processedOn">
|
||||||
Created on:
|
<i class="fas fa-cog"></i> Processed: {{job.processedOn | humanTime}}
|
||||||
<span ng-bind="job.timestamp | humanTime"></span>
|
</span>
|
||||||
</span>
|
<span ng-if="job.finishedOn">
|
||||||
<span ng-if="job.finishedOn">
|
<i class="fas fa-check"></i> Finished: {{job.finishedOn | humanTime}}
|
||||||
Finished on:
|
</span>
|
||||||
<span ng-bind="job.finishedOn | humanTime"></span>
|
</div>
|
||||||
</span>
|
<div ng-if="job.stacktrace.length">
|
||||||
<span ng-if="job.processedOn">
|
<pre
|
||||||
Processed on:
|
ng-repeat="stack in job.stacktrace track by $index"
|
||||||
<span ng-bind="job.processedOn | humanTime"></span>
|
style="font-size: 0.8rem; max-height: 100px; overflow: auto; margin: 6px 0 0 0"
|
||||||
</span>
|
><code ng-bind="stack"></code></pre>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div class="job-actions">
|
||||||
<pre
|
<button class="btn btn-sm" ng-click="retryJob('cache', job)">
|
||||||
ng-repeat="stack in job.stacktrace track by $index"
|
<i class="fas fa-sync"></i> Retry
|
||||||
><code ng-bind="stack"></code></pre>
|
</button>
|
||||||
</div>
|
<button class="btn btn-sm" ng-click="removeJob('cache', job)">
|
||||||
</div>
|
<i class="fas fa-trash-alt"></i> Remove
|
||||||
<div class="d-flex">
|
</button>
|
||||||
<div class="dropdown">
|
<a class="btn btn-sm" href="/anonymize/{{job.id}}">
|
||||||
<button
|
<i class="far fa-edit"></i> Edit
|
||||||
class="btn black_border dropdown-toggle btn-sm"
|
</a>
|
||||||
type="button"
|
</div>
|
||||||
id="dropdownMenuButton"
|
</div>
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
<div class="empty-state" ng-if="filteredRemoveCache.length == 0" style="padding: 20px">
|
||||||
aria-expanded="false"
|
<i class="fas fa-check-circle"></i>
|
||||||
>
|
No cache cleanup jobs in the queue.
|
||||||
Actions
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-click="removeJob('cache', job)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-trash-alt"></i> Remove
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-click="retryJob('cache', job)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-sync"></i> Retry
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item" href="/anonymize/{{job.id}}">
|
|
||||||
<i class="far fa-edit" aria-hidden="true"></i> Edit
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
|
||||||
ng-if="filteredRemoveCache.length == 0"
|
|
||||||
>
|
|
||||||
There is no job to display.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,370 +1,260 @@
|
|||||||
<div class="container page">
|
<div class="container page">
|
||||||
<div class="row">
|
<!-- Admin Navigation -->
|
||||||
<div class="border-bottom color-border-secondary py-3 w-100">
|
<nav class="admin-nav">
|
||||||
<div class="d-flex flex-items-start w-100">
|
<a href="/admin/" class="active">
|
||||||
<form class="w-100" aria-label="Repositories" accept-charset="UTF-8">
|
<i class="fas fa-code-branch"></i> Repositories
|
||||||
<div class="d-flex flex-column flex-lg-row flex-auto">
|
</a>
|
||||||
<div class="mb-1 mb-md-0 mr-md-3">
|
<a href="/admin/users">
|
||||||
<input
|
<i class="fas fa-users"></i> Users
|
||||||
type="search"
|
</a>
|
||||||
id="search"
|
<a href="/admin/conferences">
|
||||||
class="form-control"
|
<i class="fas fa-chalkboard-teacher"></i> Conferences
|
||||||
aria-label="Find a repository…"
|
</a>
|
||||||
placeholder="Find a repository…"
|
<a href="/admin/queues">
|
||||||
autocomplete="off"
|
<i class="fas fa-tasks"></i> Queues
|
||||||
ng-model="query.search"
|
</a>
|
||||||
/>
|
</nav>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-1 mb-md-0 mr-md-3 col-2 input-group">
|
<!-- Summary Stats -->
|
||||||
<input
|
<div class="admin-stats">
|
||||||
type="number"
|
<div class="admin-stat-card">
|
||||||
id="page"
|
<div class="stat-value" ng-bind="total >= 0 ? (total | number) : '...'"></div>
|
||||||
class="form-control"
|
<div class="stat-label">Total Repos</div>
|
||||||
autocomplete="off"
|
</div>
|
||||||
ng-model="query.page"
|
<div class="admin-stat-card">
|
||||||
min="1"
|
<div class="stat-value">{{query.page}}/{{totalPage || '...'}}</div>
|
||||||
max="{{totalPage}}"
|
<div class="stat-label">Current Page</div>
|
||||||
/>
|
</div>
|
||||||
<div class="input-group-append">
|
</div>
|
||||||
<span class="input-group-text">/{{totalPage}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex flex-wrap">
|
<!-- Toolbar -->
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
<div class="admin-toolbar">
|
||||||
<button
|
<input
|
||||||
class="btn btn-secondary dropdown-toggle"
|
type="search"
|
||||||
type="button"
|
class="form-control"
|
||||||
id="dropdownSort"
|
aria-label="Search repositories..."
|
||||||
data-toggle="dropdown"
|
placeholder="Search repositories..."
|
||||||
aria-haspopup="true"
|
autocomplete="off"
|
||||||
aria-expanded="false"
|
ng-model="query.search"
|
||||||
>
|
/>
|
||||||
Sort
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
|
||||||
<h6 class="dropdown-header">Select order</h6>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortFullName"
|
|
||||||
value="source.repositoryName"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortFullName">
|
|
||||||
Repository
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortAnonymizeDate"
|
|
||||||
value="anonymizeDate"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortAnonymizeDate">
|
|
||||||
Anonymize Date
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortStatus"
|
|
||||||
value="status"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortStatus">
|
|
||||||
Status
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortLastView"
|
|
||||||
value="lastView"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortLastView">
|
|
||||||
Last View
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortPageView"
|
|
||||||
value="pageView"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortPageView">
|
|
||||||
Page View
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
<div class="pagination-compact">
|
||||||
<button
|
<button class="btn btn-sm" ng-click="query.page = Math.max(1, query.page - 1)" ng-disabled="query.page <= 1">
|
||||||
class="btn btn-secondary dropdown-toggle"
|
<i class="fas fa-chevron-left"></i>
|
||||||
type="button"
|
</button>
|
||||||
id="dropdownStatus"
|
<input
|
||||||
data-toggle="dropdown"
|
type="number"
|
||||||
aria-haspopup="true"
|
class="form-control form-control-sm"
|
||||||
aria-expanded="false"
|
ng-model="query.page"
|
||||||
>
|
min="1"
|
||||||
Status
|
max="{{totalPage}}"
|
||||||
</button>
|
/>
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownStatus">
|
<span>/{{totalPage}}</span>
|
||||||
<h6 class="dropdown-header">Select status</h6>
|
<button class="btn btn-sm" ng-click="query.page = Math.min(totalPage, query.page + 1)" ng-disabled="query.page >= totalPage">
|
||||||
<div class="form-check dropdown-item">
|
<i class="fas fa-chevron-right"></i>
|
||||||
<input
|
</button>
|
||||||
class="form-check-input"
|
</div>
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
<div class="dropdown">
|
||||||
id="statusReady"
|
<button
|
||||||
value="ready"
|
class="btn btn-sm dropdown-toggle"
|
||||||
ng-model="query.ready"
|
type="button"
|
||||||
/>
|
id="dropdownSort"
|
||||||
<label class="form-check-label" for="statusReady">
|
data-toggle="dropdown"
|
||||||
Ready
|
aria-haspopup="true"
|
||||||
</label>
|
aria-expanded="false"
|
||||||
</div>
|
>
|
||||||
<div class="form-check dropdown-item">
|
<i class="fas fa-sort"></i> Sort
|
||||||
<input
|
</button>
|
||||||
class="form-check-input"
|
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
||||||
type="checkbox"
|
<h6 class="dropdown-header">Sort by</h6>
|
||||||
name="sort"
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'source.repositoryName'">
|
||||||
id="statusExpired"
|
<i class="fas fa-check" ng-show="query.sort == 'source.repositoryName'"></i> Repository
|
||||||
value="expired"
|
</a>
|
||||||
ng-model="query.expired"
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'anonymizeDate'">
|
||||||
/>
|
<i class="fas fa-check" ng-show="query.sort == 'anonymizeDate'"></i> Anonymize Date
|
||||||
<label class="form-check-label" for="statusExpired">
|
</a>
|
||||||
Expired
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'status'">
|
||||||
</label>
|
<i class="fas fa-check" ng-show="query.sort == 'status'"></i> Status
|
||||||
</div>
|
</a>
|
||||||
<div class="form-check dropdown-item">
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'lastView'">
|
||||||
<input
|
<i class="fas fa-check" ng-show="query.sort == 'lastView'"></i> Last View
|
||||||
class="form-check-input"
|
</a>
|
||||||
type="checkbox"
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'pageView'">
|
||||||
name="sort"
|
<i class="fas fa-check" ng-show="query.sort == 'pageView'"></i> Page Views
|
||||||
id="statusExpired"
|
</a>
|
||||||
value="expired"
|
|
||||||
ng-model="query.preparing"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusExpired">
|
|
||||||
Preparing
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusRemoved"
|
|
||||||
value="removed"
|
|
||||||
ng-model="query.removed"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusRemoved">
|
|
||||||
Removed
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusRemoved"
|
|
||||||
value="removed"
|
|
||||||
ng-model="query.error"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusRemoved">
|
|
||||||
Error
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="p-0 m-0 w-100">
|
|
||||||
<li
|
<div class="dropdown">
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<button
|
||||||
ng-class="{'expired': repo.status == 'expired','removed': repo.status == 'removed','error': repo.status == 'error' }"
|
class="btn btn-sm dropdown-toggle"
|
||||||
ng-repeat="repo in repositories| filter:repoFiler| orderBy:orderBy as filteredRepositories"
|
type="button"
|
||||||
|
id="dropdownStatus"
|
||||||
|
data-toggle="dropdown"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
<div class="w-100">
|
<i class="fas fa-filter"></i> Status
|
||||||
<div class="">
|
</button>
|
||||||
<h3>
|
<div class="dropdown-menu" aria-labelledby="dropdownStatus">
|
||||||
<a
|
<h6 class="dropdown-header">Filter by status</h6>
|
||||||
target="__blank"
|
<label class="dropdown-item mb-0">
|
||||||
ng-href="/r/{{repo.repoId}}"
|
<input type="checkbox" ng-model="query.ready" /> Ready
|
||||||
ng-bind="repo.repoId"
|
</label>
|
||||||
></a>
|
<label class="dropdown-item mb-0">
|
||||||
<span
|
<input type="checkbox" ng-model="query.preparing" /> Preparing
|
||||||
class="badge"
|
</label>
|
||||||
ng-class="{'badge-warning': repo.status == 'removed' || repo.status == 'expired' || repo.status == 'removing' || repo.status == 'expiring', 'badge-info': repo.status == 'preparing' || repo.status == 'download', 'badge-success': repo.status == 'ready', 'badge-danger': repo.status == 'error'}"
|
<label class="dropdown-item mb-0">
|
||||||
><span ng-bind="repo.status | title"></span>
|
<input type="checkbox" ng-model="query.expired" /> Expired
|
||||||
<span
|
</label>
|
||||||
ng-if="repo.status == 'error'"
|
<label class="dropdown-item mb-0">
|
||||||
ng-bind="': ' + repo.statusMessage"
|
<input type="checkbox" ng-model="query.removed" /> Removed
|
||||||
></span
|
</label>
|
||||||
></span>
|
<label class="dropdown-item mb-0">
|
||||||
</h3>
|
<input type="checkbox" ng-model="query.error" /> Error
|
||||||
<span class="color-text-secondary mb-1">
|
</label>
|
||||||
<span class="repository">
|
</div>
|
||||||
<i class="fab fa-github" aria-hidden="true"></i>
|
</div>
|
||||||
<a
|
</div>
|
||||||
href="https://github.com/{{repo.source.repositoryName}}/"
|
|
||||||
class="fullName"
|
<!-- Repository List -->
|
||||||
ng-bind="repo.source.repositoryName"
|
<div
|
||||||
></a>
|
class="admin-list-item"
|
||||||
</span>
|
ng-repeat="repo in repositories | filter:repoFiler | orderBy:orderBy as filteredRepositories"
|
||||||
<span class="branch" ng-if="repo.options.update">
|
>
|
||||||
<i class="fas fa-code-branch" aria-hidden="true"></i>
|
<div class="item-main">
|
||||||
<a
|
<div class="item-title">
|
||||||
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.branch}}"
|
<a target="_blank" ng-href="/r/{{repo.repoId}}" ng-bind="repo.repoId"></a>
|
||||||
class="branch"
|
<span
|
||||||
ng-bind="repo.source.branch"
|
class="status-badge"
|
||||||
></a>
|
ng-class="'status-' + repo.status"
|
||||||
</span>
|
>{{repo.status | title}}</span>
|
||||||
<span class="commit" ng-if="!repo.options.update">
|
<span
|
||||||
@<a
|
ng-if="repo.status == 'error'"
|
||||||
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.commit}}"
|
style="font-size: 0.8rem; color: #dc3545;"
|
||||||
class="commit"
|
ng-bind="repo.statusMessage"
|
||||||
ng-bind="repo.source.commit.substring(0, 8)"
|
></span>
|
||||||
></a>
|
</div>
|
||||||
</span>
|
<div class="item-meta">
|
||||||
anonymized {{repo.anonymizeDate | humanTime}}
|
<span>
|
||||||
</span>
|
<i class="fab fa-github"></i>
|
||||||
</div>
|
<a
|
||||||
<div class="color-text-secondary mt-2">
|
href="https://github.com/{{repo.source.repositoryName}}/"
|
||||||
<span class="ml-0 mr-3" ng-if="::repo.conference">
|
ng-bind="repo.source.repositoryName"
|
||||||
<i class="fas fa-chalkboard-teacher"></i>
|
></a>
|
||||||
{{repo.conference}}
|
</span>
|
||||||
</span>
|
<span ng-if="repo.options.update">
|
||||||
<span
|
<i class="fas fa-code-branch"></i>
|
||||||
class="ml-0 mr-3"
|
<a
|
||||||
class="terms"
|
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.branch}}"
|
||||||
title="Terms: {{::repo.options.terms.join(', ')}}"
|
ng-bind="repo.source.branch"
|
||||||
data-toggle="tooltip"
|
></a>
|
||||||
data-placement="bottom"
|
</span>
|
||||||
>
|
<span ng-if="!repo.options.update">
|
||||||
<i class="fas fa-shield-alt"></i>
|
@<a
|
||||||
{{::repo.options.terms.length | number}}
|
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.commit}}"
|
||||||
</span>
|
ng-bind="repo.source.commit.substring(0, 8)"
|
||||||
<span
|
></a>
|
||||||
class="ml-0 mr-3"
|
</span>
|
||||||
title="Size: {{::repo.size.storage | humanFileSize}}"
|
<span>anonymized {{repo.anonymizeDate | humanTime}}</span>
|
||||||
data-toggle="tooltip"
|
</div>
|
||||||
data-placement="bottom"
|
<div class="item-meta" style="margin-top: 4px">
|
||||||
>
|
<span ng-if="::repo.conference">
|
||||||
<i class="fas fa-database"></i> {{::repo.size.storage |
|
<i class="fas fa-chalkboard-teacher"></i> {{repo.conference}}
|
||||||
humanFileSize}}</span
|
</span>
|
||||||
>
|
<span title="Terms: {{::repo.options.terms.join(', ')}}">
|
||||||
<span
|
<i class="fas fa-shield-alt"></i> {{::repo.options.terms.length | number}} terms
|
||||||
class="ml-0 mr-3"
|
</span>
|
||||||
title="View: {{::repo.pageView || 0 | number}}"
|
<span title="Size: {{::repo.size.storage | humanFileSize}}">
|
||||||
data-toggle="tooltip"
|
<i class="fas fa-database"></i> {{::repo.size.storage | humanFileSize}}
|
||||||
data-placement="bottom"
|
</span>
|
||||||
>
|
<span>
|
||||||
<i class="far fa-eye" aria-hidden="true"></i>
|
<i class="far fa-eye"></i> {{::repo.pageView || 0 | number}} views
|
||||||
{{::repo.pageView || 0 | number}}
|
</span>
|
||||||
</span>
|
<span>
|
||||||
<span
|
<i class="far fa-calendar-alt"></i> Last: {{::repo.lastView | humanTime}}
|
||||||
class="ml-0 mr-3"
|
</span>
|
||||||
title="Last view: {{::repo.lastView | date}}"
|
<span ng-if="repo.options.expirationMode != 'never' && repo.status == 'ready'">
|
||||||
data-toggle="tooltip"
|
<i class="far fa-clock"></i> Expire: {{repo.options.expirationDate | humanTime}}
|
||||||
data-placement="bottom"
|
</span>
|
||||||
>
|
</div>
|
||||||
<i class="far fa-calendar-alt" aria-hidden="true"></i>
|
</div>
|
||||||
Last view: {{::repo.lastView | humanTime}}</span
|
<div class="item-actions">
|
||||||
>
|
<div class="dropdown">
|
||||||
<span
|
<button
|
||||||
class="ml-0 mr-3"
|
class="btn dropdown-toggle btn-sm"
|
||||||
ng-if="repo.options.expirationMode!='never' && repo.status == 'ready'"
|
type="button"
|
||||||
>
|
data-toggle="dropdown"
|
||||||
<i class="far fa-clock" aria-hidden="true"></i>
|
aria-haspopup="true"
|
||||||
Expire: {{repo.options.expirationDate | humanTime}}</span
|
aria-expanded="false"
|
||||||
>
|
>
|
||||||
</div>
|
Actions
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<a class="dropdown-item" href="/anonymize/{{repo.repoId}}">
|
||||||
|
<i class="far fa-edit"></i> Edit
|
||||||
|
</a>
|
||||||
|
<a class="dropdown-item" href="/r/{{repo.repoId}}/">
|
||||||
|
<i class="fa fa-eye"></i> View Repo
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="/w/{{repo.repoId}}/"
|
||||||
|
target="_self"
|
||||||
|
ng-if="repo.options.page && repo.status == 'ready'"
|
||||||
|
>
|
||||||
|
<i class="fas fa-globe"></i> View Page
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
ng-show="repo.status == 'ready' || repo.status == 'error'"
|
||||||
|
ng-click="updateRepository(repo)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-sync"></i> Force Update
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
ng-show="repo.status == 'removed'"
|
||||||
|
ng-click="updateRepository(repo)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-check-circle"></i> Enable
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="#" ng-click="removeCache(repo)">
|
||||||
|
<i class="fas fa-broom"></i> Remove Cache
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item text-danger"
|
||||||
|
href="#"
|
||||||
|
ng-show="repo.status == 'ready'"
|
||||||
|
ng-click="removeRepository(repo)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-trash-alt"></i> Remove
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex">
|
</div>
|
||||||
<div class="dropdown">
|
</div>
|
||||||
<button
|
</div>
|
||||||
class="btn black_border dropdown-toggle btn-sm"
|
|
||||||
type="button"
|
<div class="empty-state" ng-if="filteredRepositories.length == 0">
|
||||||
id="dropdownMenuButton"
|
<i class="fas fa-code-branch"></i>
|
||||||
data-toggle="dropdown"
|
No repositories match the current filters.
|
||||||
aria-haspopup="true"
|
</div>
|
||||||
aria-expanded="false"
|
|
||||||
>
|
<!-- Bottom pagination -->
|
||||||
Actions
|
<div class="admin-toolbar" ng-if="totalPage > 1" style="justify-content: center; border-bottom: none;">
|
||||||
</button>
|
<div class="pagination-compact">
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
<button class="btn btn-sm" ng-click="query.page = Math.max(1, query.page - 1)" ng-disabled="query.page <= 1">
|
||||||
<a class="dropdown-item" href="#" ng-click="removeCache(repo)">
|
<i class="fas fa-chevron-left"></i> Previous
|
||||||
<i class="fas fa-trash-alt"></i> Remove Cache
|
</button>
|
||||||
</a>
|
<span>Page {{query.page}} of {{totalPage}}</span>
|
||||||
<a class="dropdown-item" href="/anonymize/{{repo.repoId}}">
|
<button class="btn btn-sm" ng-click="query.page = Math.min(totalPage, query.page + 1)" ng-disabled="query.page >= totalPage">
|
||||||
<i class="far fa-edit" aria-hidden="true"></i> Edit
|
Next <i class="fas fa-chevron-right"></i>
|
||||||
</a>
|
</button>
|
||||||
<a
|
</div>
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="repo.status == 'ready' || repo.status == 'error'"
|
|
||||||
ng-click="updateRepository(repo)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-sync"></i> Force update
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="repo.status == 'removed'"
|
|
||||||
ng-click="updateRepository(repo)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-check-circle"></i>
|
|
||||||
Enable
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="repo.status == 'ready'"
|
|
||||||
ng-click="removeRepository(repo)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-trash-alt"></i> Remove
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item" href="/r/{{repo.repoId}}/">
|
|
||||||
<i class="fa fa-eye" aria-hidden="true"></i> View Repo
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="/w/{{repo.repoId}}/"
|
|
||||||
target="_self"
|
|
||||||
ng-if="repo.options.page && repo.status == 'ready'"
|
|
||||||
>
|
|
||||||
<i class="fas fa-globe"></i> View Page
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
|
||||||
ng-if="filteredRepositories.length == 0"
|
|
||||||
>
|
|
||||||
There is no repository to display.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+253
-335
@@ -1,356 +1,274 @@
|
|||||||
<div class="container page">
|
<div class="container page">
|
||||||
<div class="row">
|
<!-- Admin Navigation -->
|
||||||
<h1>
|
<nav class="admin-nav">
|
||||||
|
<a href="/admin/">
|
||||||
|
<i class="fas fa-code-branch"></i> Repositories
|
||||||
|
</a>
|
||||||
|
<a href="/admin/users" class="active">
|
||||||
|
<i class="fas fa-users"></i> Users
|
||||||
|
</a>
|
||||||
|
<a href="/admin/conferences">
|
||||||
|
<i class="fas fa-chalkboard-teacher"></i> Conferences
|
||||||
|
</a>
|
||||||
|
<a href="/admin/queues">
|
||||||
|
<i class="fas fa-tasks"></i> Queues
|
||||||
|
</a>
|
||||||
|
</nav>
|
||||||
|
|
||||||
|
<!-- User Detail Card -->
|
||||||
|
<div class="user-detail-card" ng-if="userInfo">
|
||||||
|
<div class="user-header">
|
||||||
<img
|
<img
|
||||||
ng-src="{{userInfo.photo}}"
|
ng-src="{{userInfo.photo}}"
|
||||||
ng-if="userInfo.photo"
|
ng-if="userInfo.photo"
|
||||||
width="30"
|
width="48"
|
||||||
height="30"
|
height="48"
|
||||||
class="rounded-circle ng-scope"
|
|
||||||
/>
|
/>
|
||||||
{{userInfo.username}}
|
<div>
|
||||||
<span class="badge"><span ng-bind="userInfo.status | title"></span></span>
|
<h1>
|
||||||
</h1>
|
{{userInfo.username}}
|
||||||
<div class="row mb-3 m-0 py-2 border">
|
<span
|
||||||
<div class="col-2 font-weight-bold">ID</div>
|
class="status-badge"
|
||||||
<div class="col-10">{{userInfo._id}}</div>
|
ng-class="'status-' + userInfo.status"
|
||||||
|
>{{userInfo.status | title}}</span>
|
||||||
|
<span
|
||||||
|
class="status-badge status-active"
|
||||||
|
ng-if="userInfo.isAdmin"
|
||||||
|
>Admin</span>
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-2 font-weight-bold">Email</div>
|
<div class="user-detail-grid">
|
||||||
<div class="col-10">{{userInfo.emails[0].email}}</div>
|
<div class="detail-label">ID</div>
|
||||||
|
<div class="detail-value">{{userInfo._id}}</div>
|
||||||
|
|
||||||
<div class="col-2 font-weight-bold">accessTokens</div>
|
<div class="detail-label">Email</div>
|
||||||
<div class="col-10">{{userInfo.accessTokens.github}}</div>
|
<div class="detail-value">{{userInfo.emails[0].email}}</div>
|
||||||
|
|
||||||
<div class="col-2 font-weight-bold">Github</div>
|
<div class="detail-label">Access Token</div>
|
||||||
<div class="col-10">
|
<div class="detail-value" style="font-family: monospace; font-size: 0.85rem;">{{userInfo.accessTokens.github}}</div>
|
||||||
<a ng-href="https://github.com/{{userInfo.username}}"
|
|
||||||
>{{userInfo.username}}</a
|
<div class="detail-label">GitHub</div>
|
||||||
|
<div class="detail-value">
|
||||||
|
<a ng-href="https://github.com/{{userInfo.username}}" target="_blank">
|
||||||
|
<i class="fab fa-github"></i> {{userInfo.username}}
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="detail-label">GitHub Repos</div>
|
||||||
|
<div class="detail-value">
|
||||||
|
{{userInfo.repositories.length}} repositories
|
||||||
|
<button
|
||||||
|
class="btn btn-sm ml-2"
|
||||||
|
ng-click="showRepos = !showRepos"
|
||||||
>
|
>
|
||||||
|
{{showRepos ? 'Hide' : 'Show'}}
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-primary btn-sm ml-1"
|
||||||
|
ng-click="getGitHubRepositories()"
|
||||||
|
>
|
||||||
|
<i class="fas fa-sync"></i> Refresh
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="col-2 font-weight-bold">Github Repositories</div>
|
<!-- GitHub repos expandable list -->
|
||||||
<div class="col-10" ng-click="showRepos =!showRepos">
|
<div ng-if="showRepos" style="margin-top: 16px">
|
||||||
{{userInfo.repositories.length}}
|
<div
|
||||||
|
class="admin-list-item"
|
||||||
|
ng-repeat="repo in userInfo.repositories"
|
||||||
|
>
|
||||||
|
<div class="item-main">
|
||||||
|
<div class="item-title" style="font-size: 0.9rem">{{repo.name}}</div>
|
||||||
|
<div class="item-meta">
|
||||||
|
<span title="Size">
|
||||||
|
<i class="fas fa-database"></i> {{::repo.size | humanFileSize}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Repositories Section -->
|
||||||
|
<div class="admin-section-header">
|
||||||
|
<h2><i class="fas fa-code-branch mr-1"></i> Anonymized Repositories</h2>
|
||||||
|
<span class="section-count">{{repositories.length}}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- Toolbar -->
|
||||||
|
<div class="admin-toolbar">
|
||||||
|
<input
|
||||||
|
type="search"
|
||||||
|
class="form-control"
|
||||||
|
aria-label="Search repositories..."
|
||||||
|
placeholder="Search repositories..."
|
||||||
|
autocomplete="off"
|
||||||
|
ng-model="search"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<div class="dropdown">
|
||||||
<button
|
<button
|
||||||
class="btn btn-primary m-1 mx-3"
|
class="btn btn-sm dropdown-toggle"
|
||||||
ng-click="getGitHubRepositories()"
|
type="button"
|
||||||
|
id="dropdownSort"
|
||||||
|
data-toggle="dropdown"
|
||||||
>
|
>
|
||||||
Regresh Repositories
|
<i class="fas fa-sort"></i> Sort
|
||||||
</button>
|
</button>
|
||||||
<ul class="m-0 col-12" ng-if="showRepos">
|
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
||||||
<li
|
<h6 class="dropdown-header">Sort by</h6>
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<a class="dropdown-item" href="#" ng-click="orderBy = '-anonymizeDate'">
|
||||||
ng-repeat="repo in userInfo.repositories"
|
<i class="fas fa-check" ng-show="orderBy == '-anonymizeDate'"></i> Anonymize Date
|
||||||
>
|
</a>
|
||||||
<div class="w-100">
|
<a class="dropdown-item" href="#" ng-click="orderBy = 'repoId'">
|
||||||
<div class="">
|
<i class="fas fa-check" ng-show="orderBy == 'repoId'"></i> ID
|
||||||
{{repo.name}}
|
</a>
|
||||||
</div>
|
<a class="dropdown-item" href="#" ng-click="orderBy = '-status'">
|
||||||
<div class="color-text-secondary mt-2">
|
<i class="fas fa-check" ng-show="orderBy == '-status'"></i> Status
|
||||||
<span
|
</a>
|
||||||
class="ml-0 mr-3"
|
|
||||||
title="Size: {{::repo.size | humanFileSize}}"
|
|
||||||
data-toggle="tooltip"
|
|
||||||
data-placement="bottom"
|
|
||||||
>
|
|
||||||
<i class="fas fa-database"></i> {{::repo.size |
|
|
||||||
humanFileSize}}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3>Repositories {{repositories.length}}</h3>
|
|
||||||
<div class="border-bottom color-border-secondary py-3 w-100">
|
|
||||||
<div class="d-flex flex-items-start w-100">
|
|
||||||
<form class="w-100" aria-label="Repositories" accept-charset="UTF-8">
|
|
||||||
<div class="d-flex flex-column flex-lg-row flex-auto">
|
|
||||||
<div class="mb-1 mb-md-0 mr-md-3">
|
|
||||||
<input
|
|
||||||
type="search"
|
|
||||||
id="search"
|
|
||||||
class="form-control"
|
|
||||||
aria-label="Find repositories"
|
|
||||||
placeholder="Find repositories"
|
|
||||||
autocomplete="off"
|
|
||||||
ng-model="search"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex flex-wrap">
|
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary dropdown-toggle"
|
|
||||||
type="button"
|
|
||||||
id="dropdownSort"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
Sort
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
|
||||||
<h6 class="dropdown-header">Select order</h6>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="anonymizeDate"
|
|
||||||
value="-anonymizeDate"
|
|
||||||
ng-model="orderBy"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="anonymizeDate">
|
|
||||||
Anonymize Date
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortID"
|
|
||||||
value="repoId"
|
|
||||||
ng-model="orderBy"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortID"> ID </label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="sortStatus"
|
|
||||||
value="-status"
|
|
||||||
ng-model="orderBy"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="sortStatus">
|
|
||||||
Status
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
|
||||||
<button
|
|
||||||
class="btn btn-secondary dropdown-toggle"
|
|
||||||
type="button"
|
|
||||||
id="dropdownStatus"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
Status
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownStatus">
|
|
||||||
<h6 class="dropdown-header">Select status</h6>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusReady"
|
|
||||||
value="ready"
|
|
||||||
ng-model="filters.status.ready"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusReady">
|
|
||||||
Ready
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusExpired"
|
|
||||||
value="expired"
|
|
||||||
ng-model="filters.status.expired"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusExpired">
|
|
||||||
Expired
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusRemoved"
|
|
||||||
value="removed"
|
|
||||||
ng-model="filters.status.removed"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusRemoved">
|
|
||||||
Removed
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
<div
|
|
||||||
class="d-none d-md-flex flex-md-items-center flex-md-justify-end"
|
|
||||||
></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="p-0 m-0 w-100">
|
|
||||||
<li
|
<div class="dropdown">
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<button
|
||||||
ng-class="{'expired': repo.status == 'expired','removed': repo.status == 'removed' }"
|
class="btn btn-sm dropdown-toggle"
|
||||||
ng-repeat="repo in repositories| filter:repoFiler| orderBy:orderBy as filteredRepositories"
|
type="button"
|
||||||
|
id="dropdownStatus"
|
||||||
|
data-toggle="dropdown"
|
||||||
>
|
>
|
||||||
<div class="w-100">
|
<i class="fas fa-filter"></i> Status
|
||||||
<div class="">
|
</button>
|
||||||
<h3>
|
<div class="dropdown-menu" aria-labelledby="dropdownStatus">
|
||||||
<a ng-href="/r/{{repo.repoId}}" ng-bind="repo.repoId"></a>
|
<label class="dropdown-item mb-0">
|
||||||
<span
|
<input type="checkbox" ng-model="filters.status.ready" /> Ready
|
||||||
class="badge"
|
</label>
|
||||||
ng-class="{'badge-warning': repo.status == 'removed' || repo.status == 'expired', 'badge-success': repo.status == 'ready', 'badge-danger': ''}"
|
<label class="dropdown-item mb-0">
|
||||||
ng-bind="repo.status | title"
|
<input type="checkbox" ng-model="filters.status.expired" /> Expired
|
||||||
></span>
|
</label>
|
||||||
</h3>
|
<label class="dropdown-item mb-0">
|
||||||
<span class="color-text-secondary mb-1">
|
<input type="checkbox" ng-model="filters.status.removed" /> Removed
|
||||||
<span class="repository">
|
</label>
|
||||||
<i class="fab fa-github" aria-hidden="true"></i>
|
</div>
|
||||||
<a
|
</div>
|
||||||
href="https://github.com/{{repo.source.fullName}}/"
|
</div>
|
||||||
class="fullName"
|
|
||||||
ng-bind="repo.source.fullName"
|
<!-- Repository List -->
|
||||||
></a>
|
<div
|
||||||
</span>
|
class="admin-list-item"
|
||||||
<span class="branch" ng-if="repo.options.update">
|
ng-repeat="repo in repositories | filter:repoFiler | orderBy:orderBy as filteredRepositories"
|
||||||
<i class="fas fa-code-branch" aria-hidden="true"></i>
|
>
|
||||||
<a
|
<div class="item-main">
|
||||||
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.branch}}"
|
<div class="item-title">
|
||||||
class="branch"
|
<a ng-href="/r/{{repo.repoId}}" ng-bind="repo.repoId"></a>
|
||||||
ng-bind="repo.source.branch"
|
<span
|
||||||
></a>
|
class="status-badge"
|
||||||
</span>
|
ng-class="'status-' + repo.status"
|
||||||
<span class="commit" ng-if="!repo.options.update">
|
>{{repo.status | title}}</span>
|
||||||
@<a
|
</div>
|
||||||
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.commit}}"
|
<div class="item-meta">
|
||||||
class="commit"
|
<span>
|
||||||
ng-bind="repo.source.commit.substring(0, 8)"
|
<i class="fab fa-github"></i>
|
||||||
></a>
|
<a
|
||||||
</span>
|
href="https://github.com/{{repo.source.fullName}}/"
|
||||||
anonymized {{repo.anonymizeDate | humanTime}}
|
ng-bind="repo.source.fullName"
|
||||||
</span>
|
></a>
|
||||||
</div>
|
</span>
|
||||||
<div class="color-text-secondary mt-2">
|
<span ng-if="repo.options.update">
|
||||||
<span
|
<i class="fas fa-code-branch"></i>
|
||||||
class="ml-0 mr-3"
|
<a
|
||||||
class="terms"
|
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.branch}}"
|
||||||
title="Terms: {{::repo.options.terms.join(', ')}}"
|
ng-bind="repo.source.branch"
|
||||||
data-toggle="tooltip"
|
></a>
|
||||||
data-placement="bottom"
|
</span>
|
||||||
>
|
<span ng-if="!repo.options.update">
|
||||||
<i class="fas fa-shield-alt"></i>
|
@<a
|
||||||
{{::repo.options.terms.length | number}}
|
href="https://github.com/{{repo.source.fullName}}/tree/{{repo.source.commit}}"
|
||||||
</span>
|
ng-bind="repo.source.commit.substring(0, 8)"
|
||||||
<span
|
></a>
|
||||||
class="ml-0 mr-3"
|
</span>
|
||||||
title="Size: {{::repo.size | humanFileSize}}"
|
<span>anonymized {{repo.anonymizeDate | humanTime}}</span>
|
||||||
data-toggle="tooltip"
|
</div>
|
||||||
data-placement="bottom"
|
<div class="item-meta" style="margin-top: 4px">
|
||||||
>
|
<span title="Terms: {{::repo.options.terms.join(', ')}}">
|
||||||
<i class="fas fa-database"></i> {{::repo.size.storage |
|
<i class="fas fa-shield-alt"></i> {{::repo.options.terms.length | number}}
|
||||||
humanFileSize}}</span
|
</span>
|
||||||
>
|
<span title="Size">
|
||||||
<span
|
<i class="fas fa-database"></i> {{::repo.size.storage | humanFileSize}}
|
||||||
class="ml-0 mr-3"
|
</span>
|
||||||
title="View: {{::repo.pageView | number}}"
|
<span>
|
||||||
data-toggle="tooltip"
|
<i class="far fa-eye"></i> {{::repo.pageView | number}}
|
||||||
data-placement="bottom"
|
</span>
|
||||||
>
|
<span>
|
||||||
<i class="far fa-eye" aria-hidden="true"></i>
|
<i class="far fa-calendar-alt"></i> Last: {{::repo.lastView | humanTime}}
|
||||||
{{::repo.pageView | number}}
|
</span>
|
||||||
</span>
|
<span ng-if="repo.options.expirationMode != 'never' && repo.status == 'ready'">
|
||||||
<span
|
<i class="far fa-clock"></i> Expire: {{repo.options.expirationDate | humanTime}}
|
||||||
class="ml-0 mr-3"
|
</span>
|
||||||
title="Last view: {{::repo.lastView | date}}"
|
</div>
|
||||||
data-toggle="tooltip"
|
</div>
|
||||||
data-placement="bottom"
|
<div class="item-actions">
|
||||||
>
|
<div class="dropdown">
|
||||||
<i class="far fa-calendar-alt" aria-hidden="true"></i>
|
<button
|
||||||
Last view: {{::repo.lastView | humanTime}}</span
|
class="btn dropdown-toggle btn-sm"
|
||||||
>
|
type="button"
|
||||||
<span
|
data-toggle="dropdown"
|
||||||
class="ml-0 mr-3"
|
>
|
||||||
ng-if="repo.options.expirationMode!='never' && repo.status == 'ready'"
|
Actions
|
||||||
>
|
</button>
|
||||||
<i class="far fa-clock" aria-hidden="true"></i>
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
Expire: {{repo.options.expirationDate | humanTime}}</span
|
<a class="dropdown-item" href="/anonymize/{{repo.repoId}}">
|
||||||
>
|
<i class="far fa-edit"></i> Edit
|
||||||
</div>
|
</a>
|
||||||
|
<a class="dropdown-item" href="/r/{{repo.repoId}}/">
|
||||||
|
<i class="fa fa-eye"></i> View Repo
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="/w/{{repo.repoId}}/"
|
||||||
|
target="_self"
|
||||||
|
ng-if="repo.options.page && repo.status == 'ready'"
|
||||||
|
>
|
||||||
|
<i class="fas fa-globe"></i> View Page
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
ng-show="repo.status == 'ready' || repo.status == 'error'"
|
||||||
|
ng-click="updateRepository(repo)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-sync"></i> Force Update
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
ng-show="repo.status == 'removed'"
|
||||||
|
ng-click="updateRepository(repo)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-check-circle"></i> Enable
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a class="dropdown-item" href="#" ng-click="removeCache(repo)">
|
||||||
|
<i class="fas fa-broom"></i> Remove Cache
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item text-danger"
|
||||||
|
href="#"
|
||||||
|
ng-show="repo.status == 'ready'"
|
||||||
|
ng-click="removeRepository(repo)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-trash-alt"></i> Remove
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex">
|
</div>
|
||||||
<div class="dropdown">
|
</div>
|
||||||
<button
|
</div>
|
||||||
class="btn black_border dropdown-toggle btn-sm"
|
|
||||||
type="button"
|
<div class="empty-state" ng-if="filteredRepositories.length == 0">
|
||||||
id="dropdownMenuButton"
|
<i class="fas fa-code-branch"></i>
|
||||||
data-toggle="dropdown"
|
No repositories to display.
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
>
|
|
||||||
Actions
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
|
||||||
<a class="dropdown-item" href="#" ng-click="removeCache(repo)">
|
|
||||||
<i class="fas fa-trash-alt"></i> Remove Cache
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item" href="/anonymize/{{repo.repoId}}">
|
|
||||||
<i class="far fa-edit" aria-hidden="true"></i> Edit
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="repo.status == 'ready' || repo.status == 'error'"
|
|
||||||
ng-click="updateRepository(repo)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-sync"></i> Force update
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="repo.status == 'removed'"
|
|
||||||
ng-click="updateRepository(repo)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-check-circle"></i>
|
|
||||||
Enable
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="repo.status == 'ready'"
|
|
||||||
ng-click="removeRepository(repo)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-trash-alt"></i> Remove
|
|
||||||
</a>
|
|
||||||
<a class="dropdown-item" href="/r/{{repo.repoId}}/">
|
|
||||||
<i class="fa fa-eye" aria-hidden="true"></i> View Repo
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="/w/{{repo.repoId}}/"
|
|
||||||
target="_self"
|
|
||||||
ng-if="repo.options.page && repo.status == 'ready'"
|
|
||||||
>
|
|
||||||
<i class="fas fa-globe"></i> View Page
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
|
||||||
ng-if="filteredRepositories.length == 0"
|
|
||||||
>
|
|
||||||
There is no repository to display.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+160
-204
@@ -1,213 +1,169 @@
|
|||||||
<div class="container page">
|
<div class="container page">
|
||||||
<div class="row">
|
<!-- Admin Navigation -->
|
||||||
<div class="border-bottom color-border-secondary py-3 w-100">
|
<nav class="admin-nav">
|
||||||
<div class="d-flex flex-items-start w-100">
|
<a href="/admin/">
|
||||||
<form class="w-100" aria-label="Users" accept-charset="UTF-8">
|
<i class="fas fa-code-branch"></i> Repositories
|
||||||
<div class="d-flex flex-column flex-lg-row flex-auto">
|
</a>
|
||||||
<div class="mb-1 mb-md-0 mr-md-3">
|
<a href="/admin/users" class="active">
|
||||||
<input
|
<i class="fas fa-users"></i> Users
|
||||||
type="search"
|
</a>
|
||||||
id="search"
|
<a href="/admin/conferences">
|
||||||
class="form-control"
|
<i class="fas fa-chalkboard-teacher"></i> Conferences
|
||||||
aria-label="Find a user…"
|
</a>
|
||||||
placeholder="Find a user…"
|
<a href="/admin/queues">
|
||||||
autocomplete="off"
|
<i class="fas fa-tasks"></i> Queues
|
||||||
ng-model="query.search"
|
</a>
|
||||||
/>
|
</nav>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="mb-1 mb-md-0 mr-md-3 col-2 input-group">
|
<!-- Summary Stats -->
|
||||||
<input
|
<div class="admin-stats">
|
||||||
type="number"
|
<div class="admin-stat-card">
|
||||||
id="page"
|
<div class="stat-value" ng-bind="total >= 0 ? (total | number) : '...'"></div>
|
||||||
class="form-control"
|
<div class="stat-label">Total Users</div>
|
||||||
autocomplete="off"
|
</div>
|
||||||
ng-model="query.page"
|
<div class="admin-stat-card">
|
||||||
min="1"
|
<div class="stat-value">{{query.page}}/{{totalPage || '...'}}</div>
|
||||||
max="{{totalPage}}"
|
<div class="stat-label">Current Page</div>
|
||||||
/>
|
</div>
|
||||||
<div class="input-group-append">
|
</div>
|
||||||
<span class="input-group-text">/{{totalPage}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="d-flex flex-wrap">
|
<!-- Toolbar -->
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
<div class="admin-toolbar">
|
||||||
<button
|
<input
|
||||||
class="btn btn-secondary dropdown-toggle"
|
type="search"
|
||||||
type="button"
|
class="form-control"
|
||||||
id="dropdownSort"
|
aria-label="Search users..."
|
||||||
data-toggle="dropdown"
|
placeholder="Search users..."
|
||||||
aria-haspopup="true"
|
autocomplete="off"
|
||||||
aria-expanded="false"
|
ng-model="query.search"
|
||||||
>
|
/>
|
||||||
Sort
|
|
||||||
</button>
|
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
|
||||||
<h6 class="dropdown-header">Select order</h6>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="radio"
|
|
||||||
name="sort"
|
|
||||||
id="username"
|
|
||||||
value="username"
|
|
||||||
ng-model="query.sort"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="username">
|
|
||||||
Username
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="dropdown mt-1 mt-lg-0 mr-1">
|
<div class="pagination-compact">
|
||||||
<button
|
<button class="btn btn-sm" ng-click="query.page = Math.max(1, query.page - 1)" ng-disabled="query.page <= 1">
|
||||||
class="btn btn-secondary dropdown-toggle"
|
<i class="fas fa-chevron-left"></i>
|
||||||
type="button"
|
</button>
|
||||||
id="dropdownStatus"
|
<input
|
||||||
data-toggle="dropdown"
|
type="number"
|
||||||
aria-haspopup="true"
|
class="form-control form-control-sm"
|
||||||
aria-expanded="false"
|
ng-model="query.page"
|
||||||
>
|
min="1"
|
||||||
Status
|
max="{{totalPage}}"
|
||||||
</button>
|
/>
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownStatus">
|
<span>/{{totalPage}}</span>
|
||||||
<h6 class="dropdown-header">Select status</h6>
|
<button class="btn btn-sm" ng-click="query.page = Math.min(totalPage, query.page + 1)" ng-disabled="query.page >= totalPage">
|
||||||
<div class="form-check dropdown-item">
|
<i class="fas fa-chevron-right"></i>
|
||||||
<input
|
</button>
|
||||||
class="form-check-input"
|
</div>
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
<div class="dropdown">
|
||||||
id="statusReady"
|
<button
|
||||||
value="ready"
|
class="btn btn-sm dropdown-toggle"
|
||||||
ng-model="query.ready"
|
type="button"
|
||||||
/>
|
id="dropdownSort"
|
||||||
<label class="form-check-label" for="statusReady">
|
data-toggle="dropdown"
|
||||||
Active
|
aria-haspopup="true"
|
||||||
</label>
|
aria-expanded="false"
|
||||||
</div>
|
>
|
||||||
<div class="form-check dropdown-item">
|
<i class="fas fa-sort"></i> Sort
|
||||||
<input
|
</button>
|
||||||
class="form-check-input"
|
<div class="dropdown-menu" aria-labelledby="dropdownSort">
|
||||||
type="checkbox"
|
<h6 class="dropdown-header">Sort by</h6>
|
||||||
name="sort"
|
<a class="dropdown-item" href="#" ng-click="query.sort = 'username'">
|
||||||
id="statusExpired"
|
<i class="fas fa-check" ng-show="query.sort == 'username'"></i> Username
|
||||||
value="expired"
|
</a>
|
||||||
ng-model="query.expired"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusExpired">
|
|
||||||
Expired
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusExpired"
|
|
||||||
value="expired"
|
|
||||||
ng-model="query.preparing"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusExpired">
|
|
||||||
Preparing
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusRemoved"
|
|
||||||
value="removed"
|
|
||||||
ng-model="query.removed"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusRemoved">
|
|
||||||
Removed
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div class="form-check dropdown-item">
|
|
||||||
<input
|
|
||||||
class="form-check-input"
|
|
||||||
type="checkbox"
|
|
||||||
name="sort"
|
|
||||||
id="statusRemoved"
|
|
||||||
value="removed"
|
|
||||||
ng-model="query.error"
|
|
||||||
/>
|
|
||||||
<label class="form-check-label" for="statusRemoved">
|
|
||||||
Error
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ul class="p-0 m-0 w-100">
|
</div>
|
||||||
<li
|
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
<!-- User List -->
|
||||||
ng-class="{'expired': user.status == 'expired','removed': user.status == 'removed','error': user.status == 'error' }"
|
<div
|
||||||
ng-repeat="user in users| filter:userFiler| orderBy:orderBy as filteredUsers"
|
class="admin-list-item"
|
||||||
>
|
ng-repeat="u in users | filter:userFiler | orderBy:orderBy as filteredUsers"
|
||||||
<div class="w-100">
|
>
|
||||||
<div class="">
|
<div class="item-main">
|
||||||
<h3>
|
<div class="item-title">
|
||||||
<a ng-href="/admin/users/{{user.username}}" ng-bind="user.username"></a>
|
<a ng-href="/admin/users/{{u.username}}">
|
||||||
<span
|
<img
|
||||||
class="badge"
|
ng-src="{{u.photo}}"
|
||||||
ng-class="{'badge-warning': user.status == 'removed' || user.status == 'expired' || user.status == 'removing' || user.status == 'expiring', 'badge-info': user.status == 'preparing' || user.status == 'download', 'badge-success': user.status == 'active', 'badge-danger': user.status == 'error'}"
|
ng-if="u.photo"
|
||||||
><span ng-bind="user.status | title"></span>
|
width="20"
|
||||||
</span>
|
height="20"
|
||||||
</h3>
|
class="rounded-circle mr-1"
|
||||||
</div>
|
style="vertical-align: text-bottom"
|
||||||
<div class="color-text-secondary mt-2"></div>
|
/>
|
||||||
|
{{u.username}}
|
||||||
|
</a>
|
||||||
|
<span
|
||||||
|
class="status-badge"
|
||||||
|
ng-class="'status-' + u.status"
|
||||||
|
>{{u.status | title}}</span>
|
||||||
|
<span
|
||||||
|
class="status-badge status-active"
|
||||||
|
ng-if="u.isAdmin"
|
||||||
|
>Admin</span>
|
||||||
|
</div>
|
||||||
|
<div class="item-meta">
|
||||||
|
<span ng-if="u.emails[0].email">
|
||||||
|
<i class="fas fa-envelope"></i> {{u.emails[0].email}}
|
||||||
|
</span>
|
||||||
|
<span>
|
||||||
|
<i class="fab fa-github"></i>
|
||||||
|
<a ng-href="https://github.com/{{u.username}}" target="_blank">{{u.username}}</a>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="item-actions">
|
||||||
|
<div class="dropdown">
|
||||||
|
<button
|
||||||
|
class="btn dropdown-toggle btn-sm"
|
||||||
|
type="button"
|
||||||
|
data-toggle="dropdown"
|
||||||
|
aria-haspopup="true"
|
||||||
|
aria-expanded="false"
|
||||||
|
>
|
||||||
|
Actions
|
||||||
|
</button>
|
||||||
|
<div class="dropdown-menu dropdown-menu-right">
|
||||||
|
<a class="dropdown-item" href="/admin/users/{{u.username}}">
|
||||||
|
<i class="far fa-eye"></i> View Details
|
||||||
|
</a>
|
||||||
|
<div class="dropdown-divider"></div>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
ng-show="u.status == 'active'"
|
||||||
|
ng-click="banUser(u)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-ban"></i> Ban
|
||||||
|
</a>
|
||||||
|
<a
|
||||||
|
class="dropdown-item"
|
||||||
|
href="#"
|
||||||
|
ng-show="u.status == 'removed' || u.status == 'banned'"
|
||||||
|
ng-click="activateUser(u)"
|
||||||
|
>
|
||||||
|
<i class="fas fa-check-circle"></i> Activate
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex">
|
</div>
|
||||||
<div class="dropdown">
|
</div>
|
||||||
<button
|
</div>
|
||||||
class="btn black_border dropdown-toggle btn-sm"
|
|
||||||
type="button"
|
<div class="empty-state" ng-if="filteredUsers.length == 0">
|
||||||
id="dropdownMenuButton"
|
<i class="fas fa-users"></i>
|
||||||
data-toggle="dropdown"
|
No users match the current filters.
|
||||||
aria-haspopup="true"
|
</div>
|
||||||
aria-expanded="false"
|
|
||||||
>
|
<!-- Bottom pagination -->
|
||||||
Actions
|
<div class="admin-toolbar" ng-if="totalPage > 1" style="justify-content: center; border-bottom: none;">
|
||||||
</button>
|
<div class="pagination-compact">
|
||||||
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
|
<button class="btn btn-sm" ng-click="query.page = Math.max(1, query.page - 1)" ng-disabled="query.page <= 1">
|
||||||
<a class="dropdown-item" href="/admin/user/{{user._id}}">
|
<i class="fas fa-chevron-left"></i> Previous
|
||||||
<i class="far fa-edit" aria-hidden="true"></i> Edit
|
</button>
|
||||||
</a>
|
<span>Page {{query.page}} of {{totalPage}}</span>
|
||||||
<a
|
<button class="btn btn-sm" ng-click="query.page = Math.min(totalPage, query.page + 1)" ng-disabled="query.page >= totalPage">
|
||||||
class="dropdown-item"
|
Next <i class="fas fa-chevron-right"></i>
|
||||||
href="#"
|
</button>
|
||||||
ng-show="user.status == 'ready' || user.status == 'error'"
|
</div>
|
||||||
ng-click="banUser(user)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-sync"></i> Ban
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
class="dropdown-item"
|
|
||||||
href="#"
|
|
||||||
ng-show="user.status == 'removed'"
|
|
||||||
ng-click="activateUser(user)"
|
|
||||||
>
|
|
||||||
<i class="fas fa-check-circle"></i>
|
|
||||||
Activate
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<li
|
|
||||||
class="col-12 d-flex px-0 py-3 border-bottom color-border-secondary"
|
|
||||||
ng-if="filteredUsers.length == 0"
|
|
||||||
>
|
|
||||||
There is no user to display.
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class="container-fluid h-100">
|
<div class="container-fluid h-100 anonymize-page">
|
||||||
<div class="row h-100">
|
<div class="row h-100 flex-column flex-md-row">
|
||||||
<div
|
<div
|
||||||
class="col sidePanel shadow overflow-auto h-100 d-flex align-content-end"
|
class="col-md sidePanel shadow overflow-auto anonymize-form-col"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="p-0 py-2 m-auto"
|
class="p-0 py-2 m-auto"
|
||||||
@@ -127,11 +127,14 @@
|
|||||||
[a-fA-Z0-9]{6,}.
|
[a-fA-Z0-9]{6,}.
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2>Conference ID</h2>
|
|
||||||
|
<h5 class="anonymize-section-title">
|
||||||
|
<i class="fas fa-chalkboard-teacher"></i> Conference ID
|
||||||
|
</h5>
|
||||||
<!-- Conference -->
|
<!-- Conference -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="conference"
|
<label for="conference"
|
||||||
>Conference ID<span class="text-muted">Optional</span></label
|
>Conference ID <span class="text-muted">(Optional)</span></label
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
class="form-control"
|
class="form-control"
|
||||||
@@ -159,10 +162,13 @@
|
|||||||
conference preferences.
|
conference preferences.
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<h2>Anonymization Options</h2>
|
|
||||||
|
<h5 class="anonymize-section-title">
|
||||||
|
<i class="fas fa-shield-alt"></i> Anonymization Options
|
||||||
|
</h5>
|
||||||
<!-- Repo ID -->
|
<!-- Repo ID -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="repoId">Anonymize repository id</label>
|
<label for="repoId">Anonymized repository id</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
@@ -281,7 +287,7 @@
|
|||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="collapseOne"
|
aria-controls="collapseOne"
|
||||||
>
|
>
|
||||||
Advance options
|
<i class="fas fa-cog mr-1"></i> Advanced options
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -384,31 +390,31 @@
|
|||||||
ng-if="error"
|
ng-if="error"
|
||||||
ng-bind="error"
|
ng-bind="error"
|
||||||
></div>
|
></div>
|
||||||
<button
|
<div class="anonymize-submit-bar" ng-show="repoUrl">
|
||||||
id="submit"
|
<button
|
||||||
type="submit"
|
id="submit"
|
||||||
class="btn btn-primary"
|
type="submit"
|
||||||
ng-click="anonymizeRepo($event)"
|
class="btn btn-primary btn-block"
|
||||||
ng-show="repoUrl"
|
ng-click="anonymizeRepo($event)"
|
||||||
ng-if="!isUpdate"
|
ng-if="!isUpdate"
|
||||||
>
|
>
|
||||||
Anonymize
|
<i class="fas fa-user-secret mr-1"></i> Anonymize
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
id="submit"
|
id="submit"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary btn-block"
|
||||||
ng-click="updateRepo($event)"
|
ng-click="updateRepo($event)"
|
||||||
ng-show="repoUrl"
|
ng-if="isUpdate"
|
||||||
ng-if="isUpdate"
|
>
|
||||||
>
|
<i class="fas fa-save mr-1"></i> Update
|
||||||
Update
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="col-9 p-2 h-100 overflow-auto markdown-body body"
|
class="col-md-8 p-2 overflow-auto markdown-body body anonymize-preview-col"
|
||||||
ng-bind-html="html_readme"
|
ng-bind-html="html_readme"
|
||||||
ng-if="html_readme"
|
ng-if="html_readme"
|
||||||
></div>
|
></div>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<div class="container-fluid h-100">
|
<div class="container-fluid h-100 anonymize-page">
|
||||||
<div class="row h-100">
|
<div class="row h-100 flex-column flex-md-row">
|
||||||
<div
|
<div
|
||||||
class="col sidePanel shadow overflow-auto h-100 d-flex align-content-end"
|
class="col-md sidePanel shadow overflow-auto anonymize-form-col"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="p-0 py-2 m-auto"
|
class="p-0 py-2 m-auto"
|
||||||
@@ -13,15 +13,18 @@
|
|||||||
name="anonymizeForm"
|
name="anonymizeForm"
|
||||||
novalidate
|
novalidate
|
||||||
>
|
>
|
||||||
<h5 class="card-title">Anonymize a pull request</h5>
|
<h5 class="card-title mb-2">Anonymize a pull request</h5>
|
||||||
<h6 class="card-subtitle mb-2 text-muted">
|
<p class="text-muted mb-3" style="font-size: 0.9rem">
|
||||||
Fill the information to anonymize! It will only take 5min.
|
Fill the information to anonymize! It will only take 5min.
|
||||||
</h6>
|
</p>
|
||||||
<h2>Source</h2>
|
|
||||||
|
<h5 class="anonymize-section-title">
|
||||||
|
<i class="fab fa-github"></i> Source
|
||||||
|
</h5>
|
||||||
<!-- pullRequestUrl -->
|
<!-- pullRequestUrl -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pullRequestUrl"
|
<label for="pullRequestUrl"
|
||||||
>Type the url of your pull request</label
|
>URL of your pull request</label
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -30,6 +33,7 @@
|
|||||||
id="pullRequestUrl"
|
id="pullRequestUrl"
|
||||||
ng-class="{'is-invalid': anonymize.pullRequestUrl.$invalid}"
|
ng-class="{'is-invalid': anonymize.pullRequestUrl.$invalid}"
|
||||||
ng-model="pullRequestUrl"
|
ng-model="pullRequestUrl"
|
||||||
|
placeholder="https://github.com/owner/repo/pull/123"
|
||||||
ng-model-options="{ debounce: {default: 1000, blur: 0, click: 0}, updateOn: 'default blur click' }"
|
ng-model-options="{ debounce: {default: 1000, blur: 0, click: 0}, updateOn: 'default blur click' }"
|
||||||
ng-change="pullRequestSelected()"
|
ng-change="pullRequestSelected()"
|
||||||
/>
|
/>
|
||||||
@@ -71,11 +75,14 @@
|
|||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2>Conference ID</h2>
|
|
||||||
|
<h5 class="anonymize-section-title">
|
||||||
|
<i class="fas fa-chalkboard-teacher"></i> Conference ID
|
||||||
|
</h5>
|
||||||
<!-- Conference -->
|
<!-- Conference -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="conference"
|
<label for="conference"
|
||||||
>Conference ID<span class="text-muted">Optional</span></label
|
>Conference ID <span class="text-muted">(Optional)</span></label
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
class="form-control"
|
class="form-control"
|
||||||
@@ -103,10 +110,13 @@
|
|||||||
conference preferences.
|
conference preferences.
|
||||||
</small>
|
</small>
|
||||||
</div>
|
</div>
|
||||||
<h2>Anonymization Options</h2>
|
|
||||||
|
<h5 class="anonymize-section-title">
|
||||||
|
<i class="fas fa-shield-alt"></i> Anonymization Options
|
||||||
|
</h5>
|
||||||
<!-- Pull Request ID -->
|
<!-- Pull Request ID -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="pullRequestId">Anonymize pull request id</label>
|
<label for="pullRequestId">Anonymized pull request id</label>
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
class="form-control"
|
class="form-control"
|
||||||
@@ -218,7 +228,7 @@
|
|||||||
aria-expanded="true"
|
aria-expanded="true"
|
||||||
aria-controls="collapseOne"
|
aria-controls="collapseOne"
|
||||||
>
|
>
|
||||||
Advance options
|
<i class="fas fa-cog mr-1"></i> Advanced options
|
||||||
</button>
|
</button>
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
@@ -230,7 +240,7 @@
|
|||||||
data-parent="#options"
|
data-parent="#options"
|
||||||
>
|
>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
<div class="form-group">
|
<div class="form-group mb-0">
|
||||||
<div class="form-check">
|
<div class="form-check">
|
||||||
<input
|
<input
|
||||||
class="form-check-input"
|
class="form-check-input"
|
||||||
@@ -242,7 +252,7 @@
|
|||||||
<label class="form-check-label" for="link"
|
<label class="form-check-label" for="link"
|
||||||
>Keep links</label
|
>Keep links</label
|
||||||
>
|
>
|
||||||
<small id="termsHelp" class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
>Keep or remove all the links.</small
|
>Keep or remove all the links.</small
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -257,7 +267,7 @@
|
|||||||
<label class="form-check-label" for="image"
|
<label class="form-check-label" for="image"
|
||||||
>Display images</label
|
>Display images</label
|
||||||
>
|
>
|
||||||
<small id="termsHelp" class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
>Images are not anonymized</small
|
>Images are not anonymized</small
|
||||||
>
|
>
|
||||||
</div>
|
</div>
|
||||||
@@ -272,7 +282,7 @@
|
|||||||
<label class="form-check-label" for="date"
|
<label class="form-check-label" for="date"
|
||||||
>Display dates</label
|
>Display dates</label
|
||||||
>
|
>
|
||||||
<small id="termsHelp" class="form-text text-muted"
|
<small class="form-text text-muted"
|
||||||
>Display the date of the Pull Request and the date of
|
>Display the date of the Pull Request and the date of
|
||||||
the comments.</small
|
the comments.</small
|
||||||
>
|
>
|
||||||
@@ -361,32 +371,32 @@
|
|||||||
ng-if="error"
|
ng-if="error"
|
||||||
ng-bind="error"
|
ng-bind="error"
|
||||||
></div>
|
></div>
|
||||||
<button
|
<div class="anonymize-submit-bar" ng-show="pullRequestUrl">
|
||||||
id="submit"
|
<button
|
||||||
type="submit"
|
id="submit"
|
||||||
class="btn btn-primary"
|
type="submit"
|
||||||
ng-click="anonymizePullRequest($event)"
|
class="btn btn-primary btn-block"
|
||||||
ng-show="pullRequestUrl"
|
ng-click="anonymizePullRequest($event)"
|
||||||
ng-if="!isUpdate"
|
ng-if="!isUpdate"
|
||||||
>
|
>
|
||||||
Anonymize
|
<i class="fas fa-user-secret mr-1"></i> Anonymize
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
id="submit"
|
id="submit"
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-primary"
|
class="btn btn-primary btn-block"
|
||||||
ng-click="updatePullRequest($event)"
|
ng-click="updatePullRequest($event)"
|
||||||
ng-show="pullRequestUrl"
|
ng-if="isUpdate"
|
||||||
ng-if="isUpdate"
|
>
|
||||||
>
|
<i class="fas fa-save mr-1"></i> Update
|
||||||
Update
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-9 p-2 h-100 overflow-auto" ng-if="details">
|
<div class="col-md-8 p-2 overflow-auto anonymize-preview-col" ng-if="details">
|
||||||
<div class="d-flex w-100 justify-content-between align-items-center">
|
<div class="d-flex w-100 justify-content-between align-items-center flex-wrap">
|
||||||
<h2 class="pr-title">
|
<h2 class="pr-title mb-1">
|
||||||
<span ng-if="options.title"
|
<span ng-if="options.title"
|
||||||
>{{anonymize(details.pullRequest.title)}}</span
|
>{{anonymize(details.pullRequest.title)}}</span
|
||||||
>
|
>
|
||||||
@@ -407,7 +417,8 @@
|
|||||||
>Pull Request on {{details.pullRequest.baseRepositoryFullName}}</small
|
>Pull Request on {{details.pullRequest.baseRepositoryFullName}}</small
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="pr-body shadow-sm p-3 mb-5 bg-white rounded"
|
class="pr-body shadow-sm p-3 mb-4 rounded"
|
||||||
|
style="background: var(--sidebar-bg-color)"
|
||||||
ng-if="options.body"
|
ng-if="options.body"
|
||||||
>
|
>
|
||||||
<markdown
|
<markdown
|
||||||
@@ -461,10 +472,11 @@
|
|||||||
aria-labelledby="pills-diff-tab"
|
aria-labelledby="pills-diff-tab"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="pr-diff shadow-sm p-3 mb-5 bg-white rounded"
|
class="pr-diff shadow-sm p-3 mb-4 rounded"
|
||||||
|
style="background: var(--sidebar-bg-color)"
|
||||||
ng-if="options.diff"
|
ng-if="options.diff"
|
||||||
>
|
>
|
||||||
<pre><code ng-bind-html="anonymize(details.pullRequest.diff) | diff"></code></pre>
|
<pre style="overflow-x: auto"><code ng-bind-html="anonymize(details.pullRequest.diff) | diff"></code></pre>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
@@ -479,7 +491,7 @@
|
|||||||
class="pr-comment list-group-item"
|
class="pr-comment list-group-item"
|
||||||
ng-repeat="comment in details.pullRequest.comments"
|
ng-repeat="comment in details.pullRequest.comments"
|
||||||
>
|
>
|
||||||
<div class="d-flex w-100 justify-content-between">
|
<div class="d-flex w-100 justify-content-between flex-wrap">
|
||||||
<h5 class="mb-1" ng-if="options.username">
|
<h5 class="mb-1" ng-if="options.username">
|
||||||
@{{anonymize(comment.author)}}
|
@{{anonymize(comment.author)}}
|
||||||
</h5>
|
</h5>
|
||||||
|
|||||||
@@ -227,13 +227,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div class="d-none d-md-flex flex-md-items-center flex-md-justify-end">
|
<div class="d-flex flex-wrap mt-2 mt-md-0" style="gap: 6px">
|
||||||
<a href="/anonymize" class="text-center btn btn-primary ml-3">
|
<a href="/anonymize" class="text-center btn btn-primary btn-sm">
|
||||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize Repo
|
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize Repo
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="/pull-request-anonymize"
|
href="/pull-request-anonymize"
|
||||||
class="text-center btn btn-primary ml-3"
|
class="text-center btn btn-primary btn-sm"
|
||||||
>
|
>
|
||||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize PR
|
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize PR
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -1,6 +1,18 @@
|
|||||||
<div class="container-fluid h-100">
|
<div class="container-fluid h-100">
|
||||||
<div class="row h-100">
|
<div class="row h-100">
|
||||||
<div class="leftCol shadow p-1 overflow-auto" ng-show="files.length">
|
<button
|
||||||
|
class="sidebar-toggle"
|
||||||
|
ng-show="files.length"
|
||||||
|
ng-click="sidebarCollapsed = !sidebarCollapsed"
|
||||||
|
>
|
||||||
|
<i class="fas" ng-class="sidebarCollapsed ? 'fa-folder-open' : 'fa-times'"></i>
|
||||||
|
{{sidebarCollapsed ? 'Show Files' : 'Hide Files'}}
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
class="leftCol shadow p-1 overflow-auto"
|
||||||
|
ng-show="files.length"
|
||||||
|
ng-class="{'collapsed': sidebarCollapsed}"
|
||||||
|
>
|
||||||
<tree class="files" file="files"></tree>
|
<tree class="files" file="files"></tree>
|
||||||
<div class="bottom column">
|
<div class="bottom column">
|
||||||
<div
|
<div
|
||||||
@@ -20,7 +32,7 @@
|
|||||||
Loading...
|
Loading...
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
<div class="">
|
<div class="d-flex flex-wrap" style="gap: 4px">
|
||||||
<a
|
<a
|
||||||
ng-if="options.isAdmin || options.isOwner"
|
ng-if="options.isAdmin || options.isOwner"
|
||||||
ng-href="/anonymize/{{repoId}}"
|
ng-href="/anonymize/{{repoId}}"
|
||||||
@@ -32,21 +44,21 @@
|
|||||||
ng-href="{{url}}"
|
ng-href="{{url}}"
|
||||||
target="__self"
|
target="__self"
|
||||||
class="btn btn-outline-primary btn-sm"
|
class="btn btn-outline-primary btn-sm"
|
||||||
>View raw</a
|
>Raw</a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
ng-show="content != null"
|
ng-show="content != null"
|
||||||
ng-href="{{url}}&download=true"
|
ng-href="{{url}}&download=true"
|
||||||
target="__self"
|
target="__self"
|
||||||
class="btn btn-outline-primary btn-sm"
|
class="btn btn-outline-primary btn-sm"
|
||||||
>Download file</a
|
><i class="fas fa-download"></i><span class="d-none d-md-inline"> Download</span></a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
ng-if="options.download"
|
ng-if="options.download"
|
||||||
ng-href="/api/repo/{{repoId}}/zip"
|
ng-href="/api/repo/{{repoId}}/zip"
|
||||||
target="__self"
|
target="__self"
|
||||||
class="btn btn-outline-primary btn-sm"
|
class="btn btn-outline-primary btn-sm"
|
||||||
>Download Repository</a
|
><i class="fas fa-file-archive"></i><span class="d-none d-md-inline"> ZIP</span></a
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
ng-if="options.hasWebsite"
|
ng-if="options.hasWebsite"
|
||||||
|
|||||||
+28
-27
@@ -28,6 +28,7 @@
|
|||||||
ng-class="{'active': path == '/dashboard'}"
|
ng-class="{'active': path == '/dashboard'}"
|
||||||
href="/dashboard"
|
href="/dashboard"
|
||||||
>
|
>
|
||||||
|
<i class="fas fa-code-branch d-lg-none mr-1"></i>
|
||||||
Repositories
|
Repositories
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -37,6 +38,7 @@
|
|||||||
ng-class="{'active': path == '/pr-dashboard'}"
|
ng-class="{'active': path == '/pr-dashboard'}"
|
||||||
href="/pr-dashboard"
|
href="/pr-dashboard"
|
||||||
>
|
>
|
||||||
|
<i class="fas fa-code-branch d-lg-none mr-1"></i>
|
||||||
Pull Requests
|
Pull Requests
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
@@ -45,47 +47,40 @@
|
|||||||
class="nav-link"
|
class="nav-link"
|
||||||
ng-class="{'active':path == '/conferences'}"
|
ng-class="{'active':path == '/conferences'}"
|
||||||
href="/conferences"
|
href="/conferences"
|
||||||
>Conferences</a
|
|
||||||
>
|
>
|
||||||
|
<i class="fas fa-chalkboard-teacher d-lg-none mr-1"></i>
|
||||||
|
Conferences
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" ng-if="user">
|
<li class="nav-item" ng-if="user">
|
||||||
<a
|
<a
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
ng-class="{'active':path == '/anonymize'}"
|
ng-class="{'active':path == '/anonymize'}"
|
||||||
href="/anonymize"
|
href="/anonymize"
|
||||||
>Anonymize</a
|
|
||||||
>
|
>
|
||||||
|
<i class="fas fa-user-secret d-lg-none mr-1"></i>
|
||||||
|
Anonymize
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item" ng-if="user">
|
<li class="nav-item" ng-if="user">
|
||||||
<a
|
<a
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
ng-class="{'active':path == '/pull-request-anonymize'}"
|
ng-class="{'active':path == '/pull-request-anonymize'}"
|
||||||
href="/pull-request-anonymize"
|
href="/pull-request-anonymize"
|
||||||
>Anonymize PR</a
|
|
||||||
>
|
>
|
||||||
|
<i class="fas fa-user-secret d-lg-none mr-1"></i>
|
||||||
|
Anonymize PR
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown" ng-if="user">
|
<li class="nav-item" ng-if="user && user.isAdmin">
|
||||||
<a
|
<a
|
||||||
class="nav-link dropdown-toggle"
|
class="nav-link"
|
||||||
href="#"
|
ng-class="{'active':path.indexOf('/admin') === 0}"
|
||||||
id="navbarDropdownMenuLink"
|
href="/admin/"
|
||||||
role="button"
|
|
||||||
data-toggle="dropdown"
|
|
||||||
aria-haspopup="true"
|
|
||||||
aria-expanded="false"
|
|
||||||
ng-if="user.isAdmin"
|
|
||||||
>
|
>
|
||||||
|
<i class="fas fa-cog d-lg-none mr-1"></i>
|
||||||
Admin
|
Admin
|
||||||
</a>
|
</a>
|
||||||
<div
|
|
||||||
class="dropdown-menu"
|
|
||||||
aria-labelledby="navbarDropdownMenuLink"
|
|
||||||
>
|
|
||||||
<a class="dropdown-item" href="/admin/">Repositories</a>
|
|
||||||
<a class="dropdown-item" href="/admin/users">Users</a>
|
|
||||||
<a class="dropdown-item" href="/admin/conferences">Conferences</a>
|
|
||||||
<a class="dropdown-item" href="/admin/queues">Queues</a>
|
|
||||||
</div>
|
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="navbar-nav">
|
<ul class="navbar-nav">
|
||||||
@@ -103,7 +98,7 @@
|
|||||||
>FAQ</a
|
>FAQ</a
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item">
|
<li class="nav-item d-none d-lg-block">
|
||||||
<a
|
<a
|
||||||
class="nav-link"
|
class="nav-link"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@@ -114,16 +109,23 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item" ng-if="!isDarkMode">
|
<li class="nav-item" ng-if="!isDarkMode">
|
||||||
<a class="nav-link" href="#" ng-click="darkMode(true);">Dark Mode</a>
|
<a class="nav-link" href="#" ng-click="darkMode(true);">
|
||||||
|
<i class="fas fa-moon d-lg-none mr-1"></i>
|
||||||
|
Dark Mode
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item" ng-if="isDarkMode">
|
<li class="nav-item" ng-if="isDarkMode">
|
||||||
<a class="nav-link" href="#" ng-click="darkMode(false);">Light Mode</a>
|
<a class="nav-link" href="#" ng-click="darkMode(false);">
|
||||||
|
<i class="fas fa-sun d-lg-none mr-1"></i>
|
||||||
|
Light Mode
|
||||||
|
</a>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li class="nav-item" ng-if="!user">
|
<li class="nav-item" ng-if="!user">
|
||||||
<a class="nav-link" target="_self" href="/github/login" data-offset="30"
|
<a class="nav-link" target="_self" href="/github/login" data-offset="30"
|
||||||
>Login
|
><i class="fab fa-github d-lg-none mr-1"></i>
|
||||||
|
Login
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li class="nav-item dropdown" ng-if="user">
|
<li class="nav-item dropdown" ng-if="user">
|
||||||
@@ -144,9 +146,8 @@
|
|||||||
class="rounded-circle"
|
class="rounded-circle"
|
||||||
/>
|
/>
|
||||||
{{user.username}}
|
{{user.username}}
|
||||||
<!-- <span ng-bind="user.username"></span> -->
|
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
|
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdownMenuLink">
|
||||||
<a class="dropdown-item" href="/profile">Default settings</a>
|
<a class="dropdown-item" href="/profile">Default settings</a>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item" href="/api/user/logout" target="__self"
|
<a class="dropdown-item" href="/api/user/logout" target="__self"
|
||||||
|
|||||||
@@ -155,13 +155,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<div class="d-none d-md-flex flex-md-items-center flex-md-justify-end">
|
<div class="d-flex flex-wrap mt-2 mt-md-0" style="gap: 6px">
|
||||||
<a href="/anonymize" class="text-center btn btn-primary ml-3">
|
<a href="/anonymize" class="text-center btn btn-primary btn-sm">
|
||||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize Repo
|
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize Repo
|
||||||
</a>
|
</a>
|
||||||
<a
|
<a
|
||||||
href="/pull-request-anonymize"
|
href="/pull-request-anonymize"
|
||||||
class="text-center btn btn-primary ml-3"
|
class="text-center btn btn-primary btn-sm"
|
||||||
>
|
>
|
||||||
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize PR
|
<i class="fa fa-plus-circle" aria-hidden="true"></i> Anonymize PR
|
||||||
</a>
|
</a>
|
||||||
@@ -170,7 +170,7 @@
|
|||||||
data-toggle="tooltip"
|
data-toggle="tooltip"
|
||||||
data-placement="bottom"
|
data-placement="bottom"
|
||||||
href="/claim"
|
href="/claim"
|
||||||
class="text-center btn btn-secondary ml-3"
|
class="text-center btn btn-secondary btn-sm"
|
||||||
>
|
>
|
||||||
Claim
|
Claim
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ angular
|
|||||||
"$http",
|
"$http",
|
||||||
"$location",
|
"$location",
|
||||||
function ($scope, $http, $location) {
|
function ($scope, $http, $location) {
|
||||||
|
$scope.Math = Math;
|
||||||
$scope.$watch("user.status", () => {
|
$scope.$watch("user.status", () => {
|
||||||
if ($scope.user == null) {
|
if ($scope.user == null) {
|
||||||
$location.url("/");
|
$location.url("/");
|
||||||
@@ -94,6 +95,7 @@ angular
|
|||||||
"$http",
|
"$http",
|
||||||
"$location",
|
"$location",
|
||||||
function ($scope, $http, $location) {
|
function ($scope, $http, $location) {
|
||||||
|
$scope.Math = Math;
|
||||||
$scope.$watch("user.status", () => {
|
$scope.$watch("user.status", () => {
|
||||||
if ($scope.user == null) {
|
if ($scope.user == null) {
|
||||||
$location.url("/");
|
$location.url("/");
|
||||||
@@ -259,6 +261,7 @@ angular
|
|||||||
"$http",
|
"$http",
|
||||||
"$location",
|
"$location",
|
||||||
function ($scope, $http, $location) {
|
function ($scope, $http, $location) {
|
||||||
|
$scope.Math = Math;
|
||||||
$scope.$watch("user.status", () => {
|
$scope.$watch("user.status", () => {
|
||||||
if ($scope.user == null) {
|
if ($scope.user == null) {
|
||||||
$location.url("/");
|
$location.url("/");
|
||||||
|
|||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user