mirror of
https://github.com/tdurieux/anonymous_github.git
synced 2026-05-15 14:38:03 +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 {
|
||||
background-color: var(--main-bg-color);
|
||||
padding: 8px 6px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
background-color: var(--canvas-bg-color);
|
||||
padding: 10px 14px;
|
||||
margin: 0;
|
||||
border-bottom: 1px solid var(--border-color);
|
||||
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 {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: initial;
|
||||
border: none;
|
||||
border-radius: 0;
|
||||
align-items: center;
|
||||
overflow-x: auto;
|
||||
white-space: nowrap;
|
||||
flex-wrap: nowrap;
|
||||
}
|
||||
.paths::-webkit-scrollbar { display: none; }
|
||||
|
||||
.paths a {
|
||||
color: var(--color);
|
||||
@@ -1988,22 +2020,27 @@ code {
|
||||
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;
|
||||
gap: 6px;
|
||||
padding: 8px 10px;
|
||||
}
|
||||
|
||||
.status-bar .btn {
|
||||
font-size: 12px;
|
||||
padding: 3px 8px;
|
||||
min-height: 28px;
|
||||
padding: 4px 10px;
|
||||
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 */
|
||||
@@ -2155,27 +2192,160 @@ code {
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile toggle for file explorer sidebar */
|
||||
.sidebar-toggle {
|
||||
display: none;
|
||||
/* ===== Explorer page (paper) ===== */
|
||||
.explorer-page {
|
||||
display: flex;
|
||||
height: 100%;
|
||||
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;
|
||||
background: var(--canvas-bg-color);
|
||||
position: relative;
|
||||
}
|
||||
.explorer-main {
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
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) {
|
||||
.sidebar-toggle {
|
||||
display: block;
|
||||
}
|
||||
.leftCol-head,
|
||||
.leftCol-foot,
|
||||
.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 {
|
||||
display: none !important;
|
||||
.paper-inline-warning {
|
||||
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) ===== */
|
||||
|
||||
@@ -1,85 +1,99 @@
|
||||
<div class="container-fluid h-100">
|
||||
<div class="row h-100">
|
||||
<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}"
|
||||
>
|
||||
<div class="explorer-page" ng-init="sidebarCollapsed = window.matchMedia && window.matchMedia('(max-width: 767px)').matches">
|
||||
<button
|
||||
class="sidebar-toggle"
|
||||
ng-show="files.length"
|
||||
ng-click="sidebarCollapsed = !sidebarCollapsed"
|
||||
aria-label="{{sidebarCollapsed ? 'Show files' : 'Hide files'}}"
|
||||
>
|
||||
<i class="fas" ng-class="sidebarCollapsed ? 'fa-folder-open' : 'fa-times'"></i>
|
||||
<span ng-bind="sidebarCollapsed ? 'Files' : 'Close'"></span>
|
||||
</button>
|
||||
|
||||
<div class="leftCol" ng-show="files.length" ng-class="{'collapsed': sidebarCollapsed}">
|
||||
<div class="leftCol-head">
|
||||
<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
|
||||
ng-if="options.truncatedFolders.length > 0"
|
||||
class="alert alert-warning small p-2 mb-2"
|
||||
class="paper-inline-warning"
|
||||
role="alert"
|
||||
>
|
||||
<i class="fas fa-exclamation-triangle"></i>
|
||||
{{ 'WARNINGS.repo_truncated' | translate }}
|
||||
</div>
|
||||
<tree class="files" file="files"></tree>
|
||||
<div class="bottom column">
|
||||
<div
|
||||
class="last-update"
|
||||
data-toggle="tooltip"
|
||||
data-placement="top"
|
||||
title="{{options.lastUpdateDate}}"
|
||||
</div>
|
||||
<div class="leftCol-foot">
|
||||
<span
|
||||
class="last-update"
|
||||
data-toggle="tooltip"
|
||||
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 class="col-md h-100 overflow-auto p-0 d-flex flex-column">
|
||||
<div class="d-flex align-content-between status-bar shadow">
|
||||
<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 class="explorer-content">
|
||||
<ng-include src="'./partials/pageView.htm'"></ng-include>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
+58
-6
@@ -18,7 +18,8 @@ angular
|
||||
$scope.repositories = [];
|
||||
$scope.total = -1;
|
||||
$scope.totalPage = 0;
|
||||
$scope.query = {
|
||||
const reposAdminPrefsKey = "admin.repos.filterPrefs";
|
||||
const reposAdminDefaults = {
|
||||
page: 1,
|
||||
limit: 25,
|
||||
sort: "lastView",
|
||||
@@ -29,6 +30,11 @@ angular
|
||||
error: true,
|
||||
preparing: true,
|
||||
};
|
||||
const savedReposAdminPrefs = loadFilterPrefs(reposAdminPrefsKey) || {};
|
||||
$scope.query = Object.assign({}, reposAdminDefaults, savedReposAdminPrefs, {
|
||||
page: 1,
|
||||
search: "",
|
||||
});
|
||||
|
||||
$scope.removeCache = (repo) => {
|
||||
$http.delete("/api/admin/repos/" + repo.repoId).then(
|
||||
@@ -85,6 +91,8 @@ angular
|
||||
() => {
|
||||
clearTimeout(timeClear);
|
||||
timeClear = setTimeout(getRepositories, 500);
|
||||
const { page, search, ...persisted } = $scope.query;
|
||||
saveFilterPrefs(reposAdminPrefsKey, persisted);
|
||||
},
|
||||
true
|
||||
);
|
||||
@@ -108,12 +116,18 @@ angular
|
||||
$scope.users = [];
|
||||
$scope.total = -1;
|
||||
$scope.totalPage = 0;
|
||||
$scope.query = {
|
||||
const usersAdminPrefsKey = "admin.users.filterPrefs";
|
||||
const usersAdminDefaults = {
|
||||
page: 1,
|
||||
limit: 25,
|
||||
sort: "username",
|
||||
search: "",
|
||||
};
|
||||
const savedUsersAdminPrefs = loadFilterPrefs(usersAdminPrefsKey) || {};
|
||||
$scope.query = Object.assign({}, usersAdminDefaults, savedUsersAdminPrefs, {
|
||||
page: 1,
|
||||
search: "",
|
||||
});
|
||||
|
||||
function getUsers() {
|
||||
$http.get("/api/admin/users", { params: $scope.query }).then(
|
||||
@@ -136,6 +150,8 @@ angular
|
||||
() => {
|
||||
clearTimeout(timeClear);
|
||||
timeClear = setTimeout(getUsers, 500);
|
||||
const { page, search, ...persisted } = $scope.query;
|
||||
saveFilterPrefs(usersAdminPrefsKey, persisted);
|
||||
},
|
||||
true
|
||||
);
|
||||
@@ -159,10 +175,38 @@ angular
|
||||
$scope.userInfo;
|
||||
$scope.repositories = [];
|
||||
$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) => {
|
||||
if ($scope.filters.status[repo.status] == false) return false;
|
||||
@@ -311,12 +355,18 @@ angular
|
||||
$scope.conferences = [];
|
||||
$scope.total = -1;
|
||||
$scope.totalPage = 0;
|
||||
$scope.query = {
|
||||
const confAdminPrefsKey = "admin.conferences.filterPrefs";
|
||||
const confAdminDefaults = {
|
||||
page: 1,
|
||||
limit: 25,
|
||||
sort: "name",
|
||||
search: "",
|
||||
};
|
||||
const savedConfAdminPrefs = loadFilterPrefs(confAdminPrefsKey) || {};
|
||||
$scope.query = Object.assign({}, confAdminDefaults, savedConfAdminPrefs, {
|
||||
page: 1,
|
||||
search: "",
|
||||
});
|
||||
|
||||
function getConferences() {
|
||||
$http.get("/api/admin/conferences", { params: $scope.query }).then(
|
||||
@@ -339,6 +389,8 @@ angular
|
||||
() => {
|
||||
clearTimeout(timeClear);
|
||||
timeClear = setTimeout(getConferences, 500);
|
||||
const { page, search, ...persisted } = $scope.query;
|
||||
saveFilterPrefs(confAdminPrefsKey, persisted);
|
||||
},
|
||||
true
|
||||
);
|
||||
|
||||
+69
-7
@@ -861,11 +861,45 @@ angular
|
||||
|
||||
$scope.items = [];
|
||||
$scope.search = "";
|
||||
$scope.typeFilter = "all";
|
||||
$scope.filters = {
|
||||
status: { ready: true, expired: true, removed: false },
|
||||
|
||||
const dashboardPrefsKey = "dashboard.filterPrefs";
|
||||
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() {
|
||||
$http.get("/api/user/quota").then((res) => {
|
||||
@@ -2030,10 +2064,38 @@ angular
|
||||
|
||||
$scope.conferences = [];
|
||||
$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) {
|
||||
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) {
|
||||
const thresh = si ? 1000 : 1024;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user