Tweak: small visual tweaks / improvements & fixes (#13700)

This commit is contained in:
shamoon authored and GitHub committed 2026-08-15 23:12:51 -07:00
1 parent 8ad5e8cca3
commit 8446036777
4 files changed
+134 -76

No files matched your search

@@ -19,6 +19,11 @@
height: 0.8em;
}
.sidebar-heading,
.text-uppercase {
letter-spacing: 0.06em;
}
.view-name {
max-width: calc(100% - 50px)
}
@@ -81,7 +86,7 @@ main {
.sidebar li.nav-item span,
.sidebar .sidebar-heading span {
transition: all .1s ease;
transition: opacity .1s ease;
}
@media(min-width: 768px) {
@@ -149,7 +154,7 @@ main {
z-index: 996;
--bs-btn-padding-x: 0.35rem;
--bs-btn-padding-y: 0.125rem;
transition: all .2s ease;
transition: left .2s ease;
}
.sidebar.slim .sidebar-slim-toggler {
@@ -181,6 +186,8 @@ main {
.sidebar .nav-link {
font-weight: 500;
white-space: nowrap;
border-left: 2px solid transparent;
transition: color .15s ease-in-out;
&:hover, &.active, &:focus {
color: var(--bs-primary);
@@ -193,6 +200,7 @@ main {
&.active {
font-weight: bold;
border-left-color: var(--bs-primary);
}
i-bs {
@@ -201,6 +209,17 @@ main {
}
}
// sub-page gets marker only
.nav-item:has(.attributes-submenu.show .nav-link.active) > .attributes-row > .nav-link.active {
border-left-color: transparent;
}
// bring sub-menu markers back out to L edge
.attributes-submenu .nav-link {
margin-left: -0.5rem;
padding-left: calc(var(--bs-nav-link-padding-x) + 0.5rem);
}
.attributes-row .attributes-expand-btn {
opacity: 0.2;
transition: opacity 0.15s ease-in-out;
@@ -21,45 +21,47 @@
<div class="col d-flex align-items-center"><button class="btn btn-link p-0 text-start" type="button" (click)="editField(field)" [disabled]="!permissionsService.currentUserCan(PermissionAction.Change, PermissionType.CustomField)">{{field.name}}</button></div>
<div class="col d-flex align-items-center">{{getDataType(field)}}</div>
<div class="col">
<div class="btn-group d-block d-sm-none">
<div ngbDropdown container="body" class="d-inline-block">
<button type="button" class="btn btn-link" id="actionsMenuMobile" (click)="$event.stopPropagation()" ngbDropdownToggle>
<i-bs name="three-dots-vertical"></i-bs>
</button>
<div ngbDropdownMenu aria-labelledby="actionsMenuMobile">
<button (click)="editField(field)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.CustomField }" ngbDropdownItem i18n>Edit</button>
<button class="text-danger" (click)="deleteField(field)" *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.CustomField }" ngbDropdownItem i18n>Delete</button>
@if (field.document_count > 0) {
<a
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Document }"
ngbDropdownItem
[routerLink]="getDocumentFilterUrl(field)"
i18n
>Filter Documents ({{ field.document_count }})</a
>
}
<div class="btn-toolbar gap-2">
<div class="btn-group d-block d-sm-none">
<div ngbDropdown container="body" class="d-inline-block">
<button type="button" class="btn btn-link" id="actionsMenuMobile" (click)="$event.stopPropagation()" ngbDropdownToggle>
<i-bs name="three-dots-vertical"></i-bs>
</button>
<div ngbDropdownMenu aria-labelledby="actionsMenuMobile">
<button (click)="editField(field)" *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.CustomField }" ngbDropdownItem i18n>Edit</button>
<button class="text-danger" (click)="deleteField(field)" *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.CustomField }" ngbDropdownItem i18n>Delete</button>
@if (field.document_count > 0) {
<a
*pngxIfPermissions="{ action: PermissionAction.View, type: PermissionType.Document }"
ngbDropdownItem
[routerLink]="getDocumentFilterUrl(field)"
i18n
>Filter Documents ({{ field.document_count }})</a
>
}
</div>
</div>
</div>
</div>
<div class="btn-group d-none d-sm-inline-block">
<button *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.CustomField }" class="btn btn-sm btn-outline-secondary" type="button" (click)="editField(field)">
<i-bs width="1em" height="1em" name="pencil" class="me-1"></i-bs><ng-container i18n>Edit</ng-container>
</button>
<button *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.CustomField }" class="btn btn-sm btn-outline-danger" type="button" (click)="deleteField(field)">
<i-bs width="1em" height="1em" name="trash" class="me-1"></i-bs><ng-container i18n>Delete</ng-container>
</button>
</div>
@if (field.document_count > 0) {
<div class="btn-group d-none d-sm-inline-block ms-2">
<a
class="btn btn-sm btn-outline-secondary"
[routerLink]="getDocumentFilterUrl(field)"
>
<i-bs width="1em" height="1em" name="filter" class="me-1"></i-bs><ng-container i18n>Documents</ng-container
><span class="badge bg-light text-secondary ms-2">{{ field.document_count }}</span>
</a>
<div class="btn-group d-none d-sm-inline-block">
<button *pngxIfPermissions="{ action: PermissionAction.Change, type: PermissionType.CustomField }" class="btn btn-sm btn-outline-secondary" type="button" (click)="editField(field)">
<i-bs width="1em" height="1em" name="pencil" class="me-1"></i-bs><ng-container i18n>Edit</ng-container>
</button>
<button *pngxIfPermissions="{ action: PermissionAction.Delete, type: PermissionType.CustomField }" class="btn btn-sm btn-outline-danger" type="button" (click)="deleteField(field)">
<i-bs width="1em" height="1em" name="trash" class="me-1"></i-bs><ng-container i18n>Delete</ng-container>
</button>
</div>
}
@if (field.document_count > 0) {
<div class="btn-group d-none d-sm-inline-block">
<a
class="btn btn-sm btn-outline-secondary"
[routerLink]="getDocumentFilterUrl(field)"
>
<i-bs width="1em" height="1em" name="filter" class="me-1"></i-bs><ng-container i18n>Documents</ng-container
><span class="badge bg-light text-secondary ms-2">{{ field.document_count }}</span>
</a>
</div>
}
</div>
</div>
</div>
</li>
+66 -26
View File
@@ -127,6 +127,28 @@ table .btn-link {
background-color: var(--bs-body-bg);
}
html {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
h1, h2, h3, h4, h5, h6,
.h1, .h2, .h3, .h4, .h5, .h6 {
font-weight: 600;
letter-spacing: -0.021em;
}
pngx-page-header h3 {
font-size: 1.5rem;
}
table,
.badge,
.card-info,
.pagination {
font-variant-numeric: tabular-nums;
}
.bg-primary {
background-color: var(--bs-primary) !important;
color: var(--pngx-primary-text-contrast);
@@ -213,7 +235,8 @@ table .btn-link {
}
.form-switch .form-check-input:focus {
background-image: escape-svg(url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='3' fill='#bbb'/></svg>"));
// neutral knob in place of bootstrap's blue, which clashes with the theme colour
--bs-form-switch-bg: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='3' fill='%23bbb'/%3e%3c/svg%3e");
}
.nav-item a:focus-visible {
@@ -269,33 +292,44 @@ a.btn-link:focus-visible,
box-shadow: 0 0 0 3px rgba(255, 255, 255, .25);
}
.asc {
background-color: #f8f9fa!important;
}
// Sortable table headers
th[pngxSortable] {
cursor: pointer;
user-select: none;
white-space: nowrap;
.asc:after {
content: '';
transform: rotate(180deg);
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAmxJREFUeAHtmksrRVEUx72fH8CIGQNJkpGUUmakDEiZSJRIZsRQmCkTJRmZmJgQE0kpX0D5DJKJgff7v+ru2u3O3vvc67TOvsdatdrnnP1Y///v7HvvubdbUiIhBISAEBACQkAICAEhIAQ4CXSh2DnyDfmCPEG2Iv9F9MPlM/LHyAecdyMzHYNwR3fdNK/OH9HXl1UCozD24TCvILxizEDWIEzA0FcM8woCgRrJCoS5PIwrANQSMAJX1LEI9bqpQo4JYNFFKRSvIgsxHDVnqZgIkPnNBM0rIGtYk9YOOsqgbgepRCfdbmFtqhFkVEDVPjJp0+Z6e6hRHhqBKgg6ZDCvYBygVmUoEGoh5JTRvIJwhJo1aUOoh4CLPMyvxxi7EWOMgnCGsXXI1GIXlZUYX7ucU+kbR8NW8lh3O7cue0Pk32MKndfUxQFAwxdirk3fHappAnc0oqDPzDfGTBrCfHP04dM4oTV8cxr0SVzH9FF07xD3ib6xCDE+M+aUcVygtWzzbtGX2rPBrEUYfecfQkaFzYi6HjVnGBdtL7epqAlc1+jRdAap74RrnPc4BCijttY2tRcdN0g17w7HqZrXhdJTYAuS3hd8z+vKgK3V1zWPae0mZDMykadBn1hTQBLnZNwVrJpSe/NwEeDsEwCctEOsJTsgxLvCqUl2ACftEGvJDgjxrnBqkh3ASTvEWrIDQrwrnJpkB3DSDrGW7IAQ7wqnJtkBnLRztejXXVu4+mxz/nQ9jR1w5VB86ejLTFcnnDwhzV+F6T+CHZlx6THSjn76eyyBIOPHyDakhBAQAkJACAgBISAEhIAQYCLwC8JxpAmsEGt6AAAAAElFTkSuQmCC") no-repeat;
height: 1rem;
width: 1rem;
display: block;
background-size: 1rem;
float: right;
&::after {
content: '';
display: inline-block;
vertical-align: -0.15em;
width: 0.8rem;
height: 0.8rem;
margin-left: 0.25rem;
// chevron, matched to the bootstrap-icons set used elsewhere in the app
mask: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3e%3cpath fill-rule='evenodd' d='M1.646 4.646a.5.5 0 0 1 .708 0L8 10.293l5.646-5.647a.5.5 0 0 1 .708.708l-6 6a.5.5 0 0 1-.708 0l-6-6a.5.5 0 0 1 0-.708z'/%3e%3c/svg%3e") no-repeat center / 0.8rem;
background-color: currentColor;
opacity: 0;
transition: opacity 0.15s ease-in-out;
}
// hint that an unsorted column can be sorted
&:hover::after {
opacity: 0.35;
}
}
.asc,
.des {
background-color: #f8f9fa!important;
color: var(--bs-primary);
--bs-table-color-state: var(--bs-primary); // bootstrap sets cell color at higher specificity
&::after {
opacity: 1 !important;
}
}
.des:after {
content: '';
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAAAXNSR0IArs4c6QAAAmxJREFUeAHtmksrRVEUx72fH8CIGQNJkpGUUmakDEiZSJRIZsRQmCkTJRmZmJgQE0kpX0D5DJKJgff7v+ru2u3O3vvc67TOvsdatdrnnP1Y///v7HvvubdbUiIhBISAEBACQkAICAEhIAQ4CXSh2DnyDfmCPEG2Iv9F9MPlM/LHyAecdyMzHYNwR3fdNK/OH9HXl1UCozD24TCvILxizEDWIEzA0FcM8woCgRrJCoS5PIwrANQSMAJX1LEI9bqpQo4JYNFFKRSvIgsxHDVnqZgIkPnNBM0rIGtYk9YOOsqgbgepRCfdbmFtqhFkVEDVPjJp0+Z6e6hRHhqBKgg6ZDCvYBygVmUoEGoh5JTRvIJwhJo1aUOoh4CLPMyvxxi7EWOMgnCGsXXI1GIXlZUYX7ucU+kbR8NW8lh3O7cue0Pk32MKndfUxQFAwxdirk3fHappAnc0oqDPzDfGTBrCfHP04dM4oTV8cxr0SVzH9FF07xD3ib6xCDE+M+aUcVygtWzzbtGX2rPBrEUYfecfQkaFzYi6HjVnGBdtL7epqAlc1+jRdAap74RrnPc4BCijttY2tRcdN0g17w7HqZrXhdJTYAuS3hd8z+vKgK3V1zWPae0mZDMykadBn1hTQBLnZNwVrJpSe/NwEeDsEwCctEOsJTsgxLvCqUl2ACftEGvJDgjxrnBqkh3ASTvEWrIDQrwrnJpkB3DSDrGW7IAQ7wqnJtkBnLRztejXXVu4+mxz/nQ9jR1w5VB86ejLTFcnnDwhzV+F6T+CHZlx6THSjn76eyyBIOPHyDakhBAQAkJACAgBISAEhIAQYCLwC8JxpAmsEGt6AAAAAElFTkSuQmCC") no-repeat;
height: 1rem;
width: 1rem;
display: block;
background-size: 1rem;
float: right;
.asc::after {
transform: rotate(180deg);
}
.paperless-input-select {
@@ -564,10 +598,6 @@ ul.pagination {
table.table {
--bs-table-color: var(--bs-body-color);
--bs-table-bg: var(--bs-light-rgb);
.des,.asc {
background-color: var(--bs-body-bg) !important;
}
}
.close {
@@ -776,6 +806,16 @@ canvas.hiddenCanvasElement {
.document-card {
overflow: hidden;
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
&:hover:not(.card-selected) {
border-color: var(--pngx-card-hover-border);
box-shadow: 0 0.125rem 0.5rem rgba(0, 0, 0, 0.1);
}
.document-card-check {
border-color: var(--pngx-card-hover-border) !important;
}
.card-footer i-bs svg {
vertical-align: middle;
+9 -12
View File
@@ -23,6 +23,7 @@
--pngx-bg-darker: var(--bs-gray-100);
--pngx-bg-alt2: var(--bs-gray-200); // #e9ecef
--pngx-bg-disabled: #f7f7f7;
--pngx-card-hover-border: var(--bs-tertiary-color);
--pngx-focus-alpha: 0.3;
--pngx-toast-max-width: 340px;
--bs-info: var(--pngx-bg-alt2);
@@ -36,20 +37,22 @@
$text-color-light-bg: #212529;
$text-color-dark-bg: #abb2bf;
$text-color-dark-bg-accent: color.adjust($text-color-dark-bg, $lightness: 10%);
// Taken from bootstrap
$form-check-input-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path fill='none' stroke='#{$text-color-light-bg}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/></svg>");
$form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'><circle r='2' fill='#{$text-color-light-bg}'/></svg>");
// url-encoded $text-color-light-bg
$text-color-light-bg-esc: "%23212529";
// Taken from bootstrap, pre-encoded
$form-check-input-checked-bg-image-dark: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'%3e%3cpath fill='none' stroke='#{$text-color-light-bg-esc}' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' d='M6 10l3 3l6-6'/%3e%3c/svg%3e");
$form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3e%3ccircle r='2' fill='#{$text-color-light-bg-esc}'/%3e%3c/svg%3e");
.primary-light {
--pngx-primary-text-contrast: #{$text-color-light-bg} !important;
.form-check:not(.form-switch) {
.form-check-input:checked[type=checkbox] {
background-image: escape-svg($form-check-input-checked-bg-image-dark);
--bs-form-check-bg-image: #{$form-check-input-checked-bg-image-dark};
}
.form-check-input:checked[type=radio] {
background-image: escape-svg($form-check-radio-checked-bg-image-dark);
--bs-form-check-bg-image: #{$form-check-radio-checked-bg-image-dark};
}
}
@@ -90,6 +93,7 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt
--pngx-bg-alt2: #232323;
--pngx-bg-darker: #101216;
--pngx-bg-disabled: var(--pngx-bg-alt);
--pngx-card-hover-border: var(--bs-border-color);
--pngx-focus-alpha: 0.6;
--pngx-primary-faded: var(--pngx-primary-darken-15);
--pngx-primary-text-contrast: var(--bs-body-color);
@@ -249,13 +253,6 @@ $form-check-radio-checked-bg-image-dark: url("data:image/svg+xml,<svg xmlns='htt
}
table {
.des,
.asc {
&::after {
filter: invert(0.8); /* arrow is a black inline png bkgd image (!) so use filter */
}
}
&.table-hover > tbody > tr:hover > * {
background-color: var(--bs-light);
color: var(--pngx-body-color-accent);