mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-05-15 06:30:26 +02:00
fix admin
This commit is contained in:
Vendored
+1
-1
File diff suppressed because one or more lines are too long
+199
-29
@@ -1037,21 +1037,53 @@ a:hover {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.status-bar {
|
.status-bar {
|
||||||
background-color: var(--main-bg-color);
|
display: flex;
|
||||||
padding: 8px 6px;
|
align-items: center;
|
||||||
|
gap: 12px;
|
||||||
|
background-color: var(--canvas-bg-color);
|
||||||
|
padding: 10px 14px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border-bottom: 1px solid var(--border-color);
|
border-bottom: 1px solid var(--border-color);
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.status-bar-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
.status-bar-actions .btn {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
background: var(--paper-card);
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
color: var(--color);
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 4px 10px;
|
||||||
|
font-size: 12.5px;
|
||||||
|
min-height: 30px;
|
||||||
|
}
|
||||||
|
.status-bar-actions .btn:hover {
|
||||||
|
background: var(--hover-bg-color);
|
||||||
|
color: var(--color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.paths {
|
.paths {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-width: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
background-color: initial;
|
background-color: initial;
|
||||||
border: none;
|
border: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
overflow-x: auto;
|
||||||
|
white-space: nowrap;
|
||||||
|
flex-wrap: nowrap;
|
||||||
}
|
}
|
||||||
|
.paths::-webkit-scrollbar { display: none; }
|
||||||
|
|
||||||
.paths a {
|
.paths a {
|
||||||
color: var(--color);
|
color: var(--color);
|
||||||
@@ -1988,22 +2020,27 @@ code {
|
|||||||
font-size: 16px; /* Prevents iOS zoom */
|
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 wrapping */
|
||||||
.status-bar {
|
.status-bar {
|
||||||
flex-wrap: wrap;
|
gap: 6px;
|
||||||
gap: 4px;
|
padding: 8px 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.status-bar .btn {
|
.status-bar .btn {
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
padding: 3px 8px;
|
padding: 4px 10px;
|
||||||
min-height: 28px;
|
min-height: 32px;
|
||||||
|
}
|
||||||
|
.status-bar .paths {
|
||||||
|
font-size: 11.5px;
|
||||||
|
overflow-x: auto;
|
||||||
|
flex-wrap: nowrap;
|
||||||
|
white-space: nowrap;
|
||||||
|
-webkit-overflow-scrolling: touch;
|
||||||
|
}
|
||||||
|
.status-bar .paths::-webkit-scrollbar { display: none; }
|
||||||
|
.status-bar-actions {
|
||||||
|
flex-shrink: 0;
|
||||||
|
gap: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Home hero section */
|
/* Home hero section */
|
||||||
@@ -2155,27 +2192,160 @@ code {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Mobile toggle for file explorer sidebar */
|
/* ===== Explorer page (paper) ===== */
|
||||||
.sidebar-toggle {
|
.explorer-page {
|
||||||
display: none;
|
display: flex;
|
||||||
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 8px;
|
background: var(--canvas-bg-color);
|
||||||
text-align: center;
|
position: relative;
|
||||||
background: var(--sidebar-bg-color);
|
}
|
||||||
border: 1px solid var(--border-color);
|
.explorer-main {
|
||||||
color: var(--color);
|
flex: 1 1 auto;
|
||||||
cursor: pointer;
|
min-width: 0;
|
||||||
font-size: 14px;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
overflow: hidden;
|
||||||
|
background: var(--canvas-bg-color);
|
||||||
|
}
|
||||||
|
.explorer-content {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 767px) {
|
.leftCol-head,
|
||||||
.sidebar-toggle {
|
.leftCol-foot,
|
||||||
display: block;
|
.leftCol-close {
|
||||||
}
|
display: none;
|
||||||
|
}
|
||||||
|
.leftCol-body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
overflow: auto;
|
||||||
|
}
|
||||||
|
.leftCol-foot {
|
||||||
|
padding: 8px 12px;
|
||||||
|
border-top: 1px solid var(--border-color);
|
||||||
|
background: var(--paper-bg-alt);
|
||||||
|
}
|
||||||
|
.leftCol-foot .last-update {
|
||||||
|
border-top: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
.leftCol-backdrop { display: none; }
|
||||||
|
|
||||||
.leftCol.collapsed {
|
.paper-inline-warning {
|
||||||
display: none !important;
|
display: flex;
|
||||||
|
align-items: flex-start;
|
||||||
|
gap: 8px;
|
||||||
|
margin: 8px;
|
||||||
|
padding: 10px 12px;
|
||||||
|
background: rgba(138, 107, 30, 0.08);
|
||||||
|
border: 1px solid rgba(138, 107, 30, 0.35);
|
||||||
|
border-radius: 8px;
|
||||||
|
color: var(--color);
|
||||||
|
font-size: 12.5px;
|
||||||
|
line-height: 1.4;
|
||||||
|
}
|
||||||
|
.paper-inline-warning i { color: #8A6B1E; margin-top: 2px; flex-shrink: 0; }
|
||||||
|
.dark-mode .paper-inline-warning i { color: #FFD37A; }
|
||||||
|
|
||||||
|
@media (min-width: 768px) {
|
||||||
|
.leftCol-body { padding: 8px 4px; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Mobile / tablet toggle */
|
||||||
|
.sidebar-toggle {
|
||||||
|
display: none;
|
||||||
|
align-items: center;
|
||||||
|
gap: 8px;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 18px;
|
||||||
|
left: 18px;
|
||||||
|
z-index: 1100;
|
||||||
|
padding: 10px 14px;
|
||||||
|
background: var(--color);
|
||||||
|
color: var(--canvas-bg-color);
|
||||||
|
border: 1px solid var(--color);
|
||||||
|
border-radius: 999px;
|
||||||
|
font-family: var(--font-sans);
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: 500;
|
||||||
|
box-shadow: 0 6px 20px rgba(0,0,0,0.15);
|
||||||
|
cursor: pointer;
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
.sidebar-toggle:hover { background: var(--primary-hover-bg); }
|
||||||
|
.sidebar-toggle:focus,
|
||||||
|
.sidebar-toggle:focus-visible { outline: none; box-shadow: 0 6px 20px rgba(0,0,0,0.15); }
|
||||||
|
|
||||||
|
@media (max-width: 991px) {
|
||||||
|
.sidebar-toggle { display: inline-flex; }
|
||||||
|
|
||||||
|
/* Sidebar becomes a slide-in drawer */
|
||||||
|
.leftCol {
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
bottom: 0;
|
||||||
|
width: min(86vw, 340px);
|
||||||
|
max-width: 340px;
|
||||||
|
z-index: 1200;
|
||||||
|
border: none;
|
||||||
|
border-right: 1px solid var(--border-color);
|
||||||
|
transform: translateX(0);
|
||||||
|
transition: transform 0.22s ease;
|
||||||
|
box-shadow: 4px 0 24px rgba(0,0,0,0.18);
|
||||||
|
background: var(--sidebar-bg-color);
|
||||||
}
|
}
|
||||||
|
.leftCol.collapsed {
|
||||||
|
transform: translateX(-105%);
|
||||||
|
box-shadow: none;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
.leftCol-head {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 12px 14px;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
background: var(--paper-bg-alt);
|
||||||
|
}
|
||||||
|
.leftCol-eyebrow {
|
||||||
|
font-family: var(--font-mono);
|
||||||
|
font-size: 11px;
|
||||||
|
letter-spacing: 0.14em;
|
||||||
|
text-transform: uppercase;
|
||||||
|
color: var(--ink-muted);
|
||||||
|
}
|
||||||
|
.leftCol-close {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
padding: 0;
|
||||||
|
background: transparent;
|
||||||
|
border: 1px solid var(--border-color);
|
||||||
|
border-radius: 8px;
|
||||||
|
color: var(--ink-muted);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.leftCol-close:hover { color: var(--color); border-color: var(--color); }
|
||||||
|
.leftCol-foot { display: block; }
|
||||||
|
.leftCol-body { padding: 4px 0; }
|
||||||
|
|
||||||
|
.leftCol-backdrop {
|
||||||
|
display: block;
|
||||||
|
position: fixed;
|
||||||
|
inset: 0;
|
||||||
|
background: rgba(0,0,0,0.32);
|
||||||
|
z-index: 1150;
|
||||||
|
backdrop-filter: blur(2px);
|
||||||
|
}
|
||||||
|
.dark-mode .leftCol-backdrop { background: rgba(0,0,0,0.5); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ===== Admin Interface (Paper style) ===== */
|
/* ===== Admin Interface (Paper style) ===== */
|
||||||
|
|||||||
@@ -1,85 +1,99 @@
|
|||||||
<div class="container-fluid h-100">
|
<div class="explorer-page" ng-init="sidebarCollapsed = window.matchMedia && window.matchMedia('(max-width: 767px)').matches">
|
||||||
<div class="row h-100">
|
<button
|
||||||
<button
|
class="sidebar-toggle"
|
||||||
class="sidebar-toggle"
|
ng-show="files.length"
|
||||||
ng-show="files.length"
|
ng-click="sidebarCollapsed = !sidebarCollapsed"
|
||||||
ng-click="sidebarCollapsed = !sidebarCollapsed"
|
aria-label="{{sidebarCollapsed ? 'Show files' : 'Hide files'}}"
|
||||||
>
|
>
|
||||||
<i class="fas" ng-class="sidebarCollapsed ? 'fa-folder-open' : 'fa-times'"></i>
|
<i class="fas" ng-class="sidebarCollapsed ? 'fa-folder-open' : 'fa-times'"></i>
|
||||||
{{sidebarCollapsed ? 'Show Files' : 'Hide Files'}}
|
<span ng-bind="sidebarCollapsed ? 'Files' : 'Close'"></span>
|
||||||
</button>
|
</button>
|
||||||
<div
|
|
||||||
class="leftCol shadow p-1 overflow-auto"
|
<div class="leftCol" ng-show="files.length" ng-class="{'collapsed': sidebarCollapsed}">
|
||||||
ng-show="files.length"
|
<div class="leftCol-head">
|
||||||
ng-class="{'collapsed': sidebarCollapsed}"
|
<span class="leftCol-eyebrow">Files</span>
|
||||||
>
|
<button class="leftCol-close" ng-click="sidebarCollapsed = true" aria-label="Close files">
|
||||||
|
<i class="fas fa-times"></i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="leftCol-body">
|
||||||
<div
|
<div
|
||||||
ng-if="options.truncatedFolders.length > 0"
|
ng-if="options.truncatedFolders.length > 0"
|
||||||
class="alert alert-warning small p-2 mb-2"
|
class="paper-inline-warning"
|
||||||
role="alert"
|
role="alert"
|
||||||
>
|
>
|
||||||
<i class="fas fa-exclamation-triangle"></i>
|
<i class="fas fa-exclamation-triangle"></i>
|
||||||
{{ 'WARNINGS.repo_truncated' | translate }}
|
{{ 'WARNINGS.repo_truncated' | translate }}
|
||||||
</div>
|
</div>
|
||||||
<tree class="files" file="files"></tree>
|
<tree class="files" file="files"></tree>
|
||||||
<div class="bottom column">
|
</div>
|
||||||
<div
|
<div class="leftCol-foot">
|
||||||
class="last-update"
|
<span
|
||||||
data-toggle="tooltip"
|
class="last-update"
|
||||||
data-placement="top"
|
data-toggle="tooltip"
|
||||||
title="{{options.lastUpdateDate}}"
|
data-placement="top"
|
||||||
|
title="{{options.lastUpdateDate}}"
|
||||||
|
>
|
||||||
|
Updated {{options.lastUpdateDate|date}}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="leftCol-backdrop"
|
||||||
|
ng-show="files.length && !sidebarCollapsed"
|
||||||
|
ng-click="sidebarCollapsed = true"
|
||||||
|
></div>
|
||||||
|
|
||||||
|
<div class="explorer-main">
|
||||||
|
<div class="status-bar">
|
||||||
|
<ol class="breadcrumb paths" aria-label="Path">
|
||||||
|
<li class="breadcrumb-item" ng-repeat="p in paths" ng-bind="p"></li>
|
||||||
|
</ol>
|
||||||
|
<div class="status-bar-actions">
|
||||||
|
<a
|
||||||
|
ng-if="options.isAdmin || options.isOwner"
|
||||||
|
ng-href="/anonymize/{{repoId}}"
|
||||||
|
class="btn btn-sm"
|
||||||
|
aria-label="Edit"
|
||||||
|
><i class="far fa-edit"></i><span class="d-none d-md-inline"> Edit</span></a
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
ng-show="content != null"
|
||||||
|
ng-href="{{url}}"
|
||||||
|
target="__self"
|
||||||
|
class="btn btn-sm"
|
||||||
|
aria-label="Raw"
|
||||||
|
><i class="fas fa-file-alt"></i><span class="d-none d-md-inline"> Raw</span></a
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
ng-show="content != null"
|
||||||
|
ng-href="{{url}}&download=true"
|
||||||
|
target="__self"
|
||||||
|
class="btn btn-sm"
|
||||||
|
aria-label="Download"
|
||||||
|
><i class="fas fa-download"></i><span class="d-none d-md-inline"> Download</span></a
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
ng-if="options.download"
|
||||||
|
ng-href="/api/repo/{{repoId}}/zip"
|
||||||
|
target="__self"
|
||||||
|
class="btn btn-sm"
|
||||||
|
aria-label="Download ZIP"
|
||||||
|
><i class="fas fa-file-archive"></i><span class="d-none d-md-inline"> ZIP</span></a
|
||||||
|
>
|
||||||
|
<a
|
||||||
|
ng-if="options.hasWebsite"
|
||||||
|
ng-href="/w/{{repoId}}/"
|
||||||
|
target="__self"
|
||||||
|
class="btn btn-sm"
|
||||||
|
aria-label="Website"
|
||||||
|
><i class="fas fa-globe"></i><span class="d-none d-md-inline"> Website</span></a
|
||||||
>
|
>
|
||||||
Last Update: {{options.lastUpdateDate|date}}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md h-100 overflow-auto p-0 d-flex flex-column">
|
<div class="explorer-content">
|
||||||
<div class="d-flex align-content-between status-bar shadow">
|
<ng-include src="'./partials/pageView.htm'"></ng-include>
|
||||||
<ol class="flex-grow-1 breadcrumb paths">
|
|
||||||
<li class="breadcrumb-item" ng-repeat="p in paths" ng-bind="p">
|
|
||||||
Loading...
|
|
||||||
</li>
|
|
||||||
</ol>
|
|
||||||
<div class="d-flex flex-wrap" style="gap: 4px">
|
|
||||||
<a
|
|
||||||
ng-if="options.isAdmin || options.isOwner"
|
|
||||||
ng-href="/anonymize/{{repoId}}"
|
|
||||||
class="btn btn-sm"
|
|
||||||
>Edit</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
ng-show="content != null"
|
|
||||||
ng-href="{{url}}"
|
|
||||||
target="__self"
|
|
||||||
class="btn btn-sm"
|
|
||||||
>Raw</a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
ng-show="content != null"
|
|
||||||
ng-href="{{url}}&download=true"
|
|
||||||
target="__self"
|
|
||||||
class="btn btn-sm"
|
|
||||||
><i class="fas fa-download"></i><span class="d-none d-md-inline"> Download</span></a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
ng-if="options.download"
|
|
||||||
ng-href="/api/repo/{{repoId}}/zip"
|
|
||||||
target="__self"
|
|
||||||
class="btn btn-sm"
|
|
||||||
><i class="fas fa-file-archive"></i><span class="d-none d-md-inline"> ZIP</span></a
|
|
||||||
>
|
|
||||||
<a
|
|
||||||
ng-if="options.hasWebsite"
|
|
||||||
ng-href="/w/{{repoId}}/"
|
|
||||||
target="__self"
|
|
||||||
class="btn btn-sm"
|
|
||||||
>Website</a
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="align-items-stretch h-100 w-100 overflow-auto">
|
|
||||||
<ng-include src="'./partials/pageView.htm'"></ng-include>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+58
-6
@@ -18,7 +18,8 @@ angular
|
|||||||
$scope.repositories = [];
|
$scope.repositories = [];
|
||||||
$scope.total = -1;
|
$scope.total = -1;
|
||||||
$scope.totalPage = 0;
|
$scope.totalPage = 0;
|
||||||
$scope.query = {
|
const reposAdminPrefsKey = "admin.repos.filterPrefs";
|
||||||
|
const reposAdminDefaults = {
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 25,
|
limit: 25,
|
||||||
sort: "lastView",
|
sort: "lastView",
|
||||||
@@ -29,6 +30,11 @@ angular
|
|||||||
error: true,
|
error: true,
|
||||||
preparing: true,
|
preparing: true,
|
||||||
};
|
};
|
||||||
|
const savedReposAdminPrefs = loadFilterPrefs(reposAdminPrefsKey) || {};
|
||||||
|
$scope.query = Object.assign({}, reposAdminDefaults, savedReposAdminPrefs, {
|
||||||
|
page: 1,
|
||||||
|
search: "",
|
||||||
|
});
|
||||||
|
|
||||||
$scope.removeCache = (repo) => {
|
$scope.removeCache = (repo) => {
|
||||||
$http.delete("/api/admin/repos/" + repo.repoId).then(
|
$http.delete("/api/admin/repos/" + repo.repoId).then(
|
||||||
@@ -85,6 +91,8 @@ angular
|
|||||||
() => {
|
() => {
|
||||||
clearTimeout(timeClear);
|
clearTimeout(timeClear);
|
||||||
timeClear = setTimeout(getRepositories, 500);
|
timeClear = setTimeout(getRepositories, 500);
|
||||||
|
const { page, search, ...persisted } = $scope.query;
|
||||||
|
saveFilterPrefs(reposAdminPrefsKey, persisted);
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@@ -108,12 +116,18 @@ angular
|
|||||||
$scope.users = [];
|
$scope.users = [];
|
||||||
$scope.total = -1;
|
$scope.total = -1;
|
||||||
$scope.totalPage = 0;
|
$scope.totalPage = 0;
|
||||||
$scope.query = {
|
const usersAdminPrefsKey = "admin.users.filterPrefs";
|
||||||
|
const usersAdminDefaults = {
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 25,
|
limit: 25,
|
||||||
sort: "username",
|
sort: "username",
|
||||||
search: "",
|
search: "",
|
||||||
};
|
};
|
||||||
|
const savedUsersAdminPrefs = loadFilterPrefs(usersAdminPrefsKey) || {};
|
||||||
|
$scope.query = Object.assign({}, usersAdminDefaults, savedUsersAdminPrefs, {
|
||||||
|
page: 1,
|
||||||
|
search: "",
|
||||||
|
});
|
||||||
|
|
||||||
function getUsers() {
|
function getUsers() {
|
||||||
$http.get("/api/admin/users", { params: $scope.query }).then(
|
$http.get("/api/admin/users", { params: $scope.query }).then(
|
||||||
@@ -136,6 +150,8 @@ angular
|
|||||||
() => {
|
() => {
|
||||||
clearTimeout(timeClear);
|
clearTimeout(timeClear);
|
||||||
timeClear = setTimeout(getUsers, 500);
|
timeClear = setTimeout(getUsers, 500);
|
||||||
|
const { page, search, ...persisted } = $scope.query;
|
||||||
|
saveFilterPrefs(usersAdminPrefsKey, persisted);
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@@ -159,10 +175,38 @@ angular
|
|||||||
$scope.userInfo;
|
$scope.userInfo;
|
||||||
$scope.repositories = [];
|
$scope.repositories = [];
|
||||||
$scope.search = "";
|
$scope.search = "";
|
||||||
$scope.filters = {
|
|
||||||
status: { ready: true, expired: false, removed: false },
|
const adminUserPrefsKey = "admin.user.filterPrefs";
|
||||||
|
const adminUserDefaults = {
|
||||||
|
filters: { status: { ready: true, expired: false, removed: false } },
|
||||||
|
orderBy: "-anonymizeDate",
|
||||||
};
|
};
|
||||||
$scope.orderBy = "-anonymizeDate";
|
const savedAdminUserPrefs = loadFilterPrefs(adminUserPrefsKey) || {};
|
||||||
|
$scope.filters = {
|
||||||
|
status: Object.assign(
|
||||||
|
{},
|
||||||
|
adminUserDefaults.filters.status,
|
||||||
|
(savedAdminUserPrefs.filters && savedAdminUserPrefs.filters.status) || {}
|
||||||
|
),
|
||||||
|
};
|
||||||
|
$scope.orderBy = savedAdminUserPrefs.orderBy || adminUserDefaults.orderBy;
|
||||||
|
|
||||||
|
$scope.$watch("orderBy", () => {
|
||||||
|
saveFilterPrefs(adminUserPrefsKey, {
|
||||||
|
filters: $scope.filters,
|
||||||
|
orderBy: $scope.orderBy,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$scope.$watch(
|
||||||
|
"filters",
|
||||||
|
() => {
|
||||||
|
saveFilterPrefs(adminUserPrefsKey, {
|
||||||
|
filters: $scope.filters,
|
||||||
|
orderBy: $scope.orderBy,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
$scope.repoFiler = (repo) => {
|
$scope.repoFiler = (repo) => {
|
||||||
if ($scope.filters.status[repo.status] == false) return false;
|
if ($scope.filters.status[repo.status] == false) return false;
|
||||||
@@ -311,12 +355,18 @@ angular
|
|||||||
$scope.conferences = [];
|
$scope.conferences = [];
|
||||||
$scope.total = -1;
|
$scope.total = -1;
|
||||||
$scope.totalPage = 0;
|
$scope.totalPage = 0;
|
||||||
$scope.query = {
|
const confAdminPrefsKey = "admin.conferences.filterPrefs";
|
||||||
|
const confAdminDefaults = {
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 25,
|
limit: 25,
|
||||||
sort: "name",
|
sort: "name",
|
||||||
search: "",
|
search: "",
|
||||||
};
|
};
|
||||||
|
const savedConfAdminPrefs = loadFilterPrefs(confAdminPrefsKey) || {};
|
||||||
|
$scope.query = Object.assign({}, confAdminDefaults, savedConfAdminPrefs, {
|
||||||
|
page: 1,
|
||||||
|
search: "",
|
||||||
|
});
|
||||||
|
|
||||||
function getConferences() {
|
function getConferences() {
|
||||||
$http.get("/api/admin/conferences", { params: $scope.query }).then(
|
$http.get("/api/admin/conferences", { params: $scope.query }).then(
|
||||||
@@ -339,6 +389,8 @@ angular
|
|||||||
() => {
|
() => {
|
||||||
clearTimeout(timeClear);
|
clearTimeout(timeClear);
|
||||||
timeClear = setTimeout(getConferences, 500);
|
timeClear = setTimeout(getConferences, 500);
|
||||||
|
const { page, search, ...persisted } = $scope.query;
|
||||||
|
saveFilterPrefs(confAdminPrefsKey, persisted);
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
|
|||||||
+69
-7
@@ -861,11 +861,45 @@ angular
|
|||||||
|
|
||||||
$scope.items = [];
|
$scope.items = [];
|
||||||
$scope.search = "";
|
$scope.search = "";
|
||||||
$scope.typeFilter = "all";
|
|
||||||
$scope.filters = {
|
const dashboardPrefsKey = "dashboard.filterPrefs";
|
||||||
status: { ready: true, expired: true, removed: false },
|
const dashboardPrefDefaults = {
|
||||||
|
typeFilter: "all",
|
||||||
|
filters: { status: { ready: true, expired: true, removed: false } },
|
||||||
|
orderBy: "-anonymizeDate",
|
||||||
};
|
};
|
||||||
$scope.orderBy = "-anonymizeDate";
|
const savedDashboardPrefs = loadFilterPrefs(dashboardPrefsKey) || {};
|
||||||
|
$scope.typeFilter = savedDashboardPrefs.typeFilter || dashboardPrefDefaults.typeFilter;
|
||||||
|
$scope.filters = {
|
||||||
|
status: Object.assign(
|
||||||
|
{},
|
||||||
|
dashboardPrefDefaults.filters.status,
|
||||||
|
(savedDashboardPrefs.filters && savedDashboardPrefs.filters.status) || {}
|
||||||
|
),
|
||||||
|
};
|
||||||
|
$scope.orderBy = savedDashboardPrefs.orderBy || dashboardPrefDefaults.orderBy;
|
||||||
|
|
||||||
|
$scope.$watchGroup(
|
||||||
|
["typeFilter", "orderBy"],
|
||||||
|
() => {
|
||||||
|
saveFilterPrefs(dashboardPrefsKey, {
|
||||||
|
typeFilter: $scope.typeFilter,
|
||||||
|
filters: $scope.filters,
|
||||||
|
orderBy: $scope.orderBy,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
|
$scope.$watch(
|
||||||
|
"filters",
|
||||||
|
() => {
|
||||||
|
saveFilterPrefs(dashboardPrefsKey, {
|
||||||
|
typeFilter: $scope.typeFilter,
|
||||||
|
filters: $scope.filters,
|
||||||
|
orderBy: $scope.orderBy,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
function getQuota() {
|
function getQuota() {
|
||||||
$http.get("/api/user/quota").then((res) => {
|
$http.get("/api/user/quota").then((res) => {
|
||||||
@@ -2030,10 +2064,38 @@ angular
|
|||||||
|
|
||||||
$scope.conferences = [];
|
$scope.conferences = [];
|
||||||
$scope.search = "";
|
$scope.search = "";
|
||||||
$scope.filters = {
|
|
||||||
status: { ready: true, expired: false, removed: false },
|
const conferencesPrefsKey = "conferences.filterPrefs";
|
||||||
|
const conferencesPrefDefaults = {
|
||||||
|
filters: { status: { ready: true, expired: false, removed: false } },
|
||||||
|
orderBy: "name",
|
||||||
};
|
};
|
||||||
$scope.orderBy = "name";
|
const savedConferencesPrefs = loadFilterPrefs(conferencesPrefsKey) || {};
|
||||||
|
$scope.filters = {
|
||||||
|
status: Object.assign(
|
||||||
|
{},
|
||||||
|
conferencesPrefDefaults.filters.status,
|
||||||
|
(savedConferencesPrefs.filters && savedConferencesPrefs.filters.status) || {}
|
||||||
|
),
|
||||||
|
};
|
||||||
|
$scope.orderBy = savedConferencesPrefs.orderBy || conferencesPrefDefaults.orderBy;
|
||||||
|
|
||||||
|
$scope.$watch("orderBy", () => {
|
||||||
|
saveFilterPrefs(conferencesPrefsKey, {
|
||||||
|
filters: $scope.filters,
|
||||||
|
orderBy: $scope.orderBy,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
$scope.$watch(
|
||||||
|
"filters",
|
||||||
|
() => {
|
||||||
|
saveFilterPrefs(conferencesPrefsKey, {
|
||||||
|
filters: $scope.filters,
|
||||||
|
orderBy: $scope.orderBy,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
|
|
||||||
$scope.removeConference = function (conf) {
|
$scope.removeConference = function (conf) {
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -1,3 +1,20 @@
|
|||||||
|
function loadFilterPrefs(key) {
|
||||||
|
try {
|
||||||
|
const raw = localStorage.getItem(key);
|
||||||
|
return raw ? JSON.parse(raw) : null;
|
||||||
|
} catch (e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveFilterPrefs(key, value) {
|
||||||
|
try {
|
||||||
|
localStorage.setItem(key, JSON.stringify(value));
|
||||||
|
} catch (e) {
|
||||||
|
/* localStorage unavailable or quota exceeded */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function humanFileSize(bytes, si = false, dp = 1) {
|
function humanFileSize(bytes, si = false, dp = 1) {
|
||||||
const thresh = si ? 1000 : 1024;
|
const thresh = si ? 1000 : 1024;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user