Improve panel components naming

This commit is contained in:
Giuseppe Criscione 2024-02-19 22:38:42 +01:00
parent 09ebb4510a
commit 1b5952e2fe
48 changed files with 595 additions and 619 deletions

View File

@ -28,13 +28,13 @@ class DashboardController extends AbstractController
return new Response($this->view('dashboard.index', [
'title' => $this->translate('panel.dashboard.dashboard'),
'lastModifiedPages' => $this->view('pages.list', [
'pages' => $this->site()->descendants()->sort(direction: SORT_DESC, sortBy: $timestamps->toArray())->limit(5),
'subpages' => false,
'class' => 'pages-list-root',
'parent' => null,
'orderable' => false,
'headers' => true,
'lastModifiedPages' => $this->view('pages.tree', [
'pages' => $this->site()->descendants()->sort(direction: SORT_DESC, sortBy: $timestamps->toArray())->limit(5),
'includeChildren' => false,
'class' => 'pages-tree-root',
'parent' => null,
'orderable' => false,
'headers' => true,
]),
'statistics' => Json::encode($statistics->getChartData()),
]));

View File

@ -64,13 +64,13 @@ class PagesController extends AbstractController
return new Response($this->view('pages.index', [
'title' => $this->translate('panel.pages.pages'),
'pagesList' => $this->view('pages.list', [
'pages' => $pages,
'subpages' => true,
'class' => 'pages-list-root',
'parent' => '.',
'orderable' => $this->user()->permissions()->has('pages.reorder'),
'headers' => true,
'pagesTree' => $this->view('pages.tree', [
'pages' => $pages,
'includeChildren' => true,
'class' => 'pages-tree-root',
'parent' => '.',
'orderable' => $this->user()->permissions()->has('pages.reorder'),
'headers' => true,
]),
]));
}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -9,7 +9,7 @@ export class ArrayInput {
$$(".form-input-array-row", input).forEach((element) => bindRowEvents(element));
Sortable.create(input, {
handle: ".sort-handle",
handle: ".sortable-handle",
forceFallback: true,
});

View File

@ -26,7 +26,7 @@ export class SelectInput {
labelInput.classList.add("form-select");
labelInput.dataset.for = select.id;
const selectLabel = $(`label[for="${ select.id }"]`);
const selectLabel = $(`label[for="${select.id}"]`);
if (selectLabel) {
labelInput.setAttribute("aria-label", selectLabel.innerText);

View File

@ -2,8 +2,8 @@ import { $ } from "../utils/selectors";
export class Navigation {
constructor() {
if ($(".toggle-navigation")) {
$(".toggle-navigation").addEventListener("click", () => {
if ($(".sidebar-toggle")) {
$(".sidebar-toggle").addEventListener("click", () => {
if ($(".sidebar").classList.toggle("show")) {
if (!$(".sidebar-backdrop")) {
const backdrop = document.createElement("div");

View File

@ -18,14 +18,14 @@ export class Pages {
const newPageModal = document.getElementById("newPageModal");
const slugModal = document.getElementById("slugModal");
$$(".pages-list").forEach((element) => {
$$(".pages-tree").forEach((element) => {
if (element.dataset.orderableChildren === "true") {
initSortable(element);
}
});
$$(".page-details").forEach((element) => {
if ($(".page-children-toggle", element)) {
if ($(".pages-tree-children-toggle", element)) {
element.addEventListener("click", (event) => {
togglePageItem(element);
event.stopPropagation();
@ -39,7 +39,7 @@ export class Pages {
});
});
$$(".pages-list .sort-handle").forEach((element) => {
$$(".pages-tree .sortable-handle").forEach((element) => {
element.addEventListener("click", (event) => {
event.stopPropagation();
});
@ -62,14 +62,14 @@ export class Pages {
if (commandReorderPages) {
commandReorderPages.addEventListener("click", () => {
commandReorderPages.classList.toggle("active");
$(".pages-list").classList.toggle("is-reordering");
$(".pages-tree").classList.toggle("is-reordering");
commandReorderPages.blur();
});
}
if (searchInput) {
searchInput.addEventListener("focus", () => {
$$(".pages-item").forEach((element) => {
$$(".pages-tree-item").forEach((element) => {
element.dataset.expanded = element.classList.contains("expanded") ? "true" : "false";
});
});
@ -77,23 +77,23 @@ export class Pages {
const handleSearch = (event) => {
const value = event.target.value;
if (value.length === 0) {
$(".pages-list-root").classList.remove("is-filtered");
$(".pages-tree-root").classList.remove("is-filtered");
$$(".pages-item").forEach((element) => {
$$(".pages-tree-item").forEach((element) => {
const title = $(".page-title a", element);
title.innerHTML = title.textContent;
$(".pages-item-row", element).style.display = "";
$(".pages-tree-row", element).style.display = "";
element.classList.toggle("is-expanded", element.dataset.expanded === "true");
});
} else {
$(".pages-list-root").classList.add("is-filtered");
$(".pages-tree-root").classList.add("is-filtered");
const regexp = new RegExp(makeDiacriticsRegExp(escapeRegExp(value)), "gi");
$$(".pages-item").forEach((element) => {
$$(".pages-tree-item").forEach((element) => {
const title = $(".page-title a", element);
const text = title.textContent;
const pagesItem = $(".pages-item-row", element);
const pagesItem = $(".pages-tree-row", element);
if (text.match(regexp) !== null) {
title.innerHTML = text.replace(regexp, "<mark>$&</mark>");
@ -225,19 +225,19 @@ export class Pages {
});
function expandAllPages() {
$$(".pages-item").forEach((element) => {
$$(".pages-tree-item").forEach((element) => {
element.classList.add("is-expanded");
});
}
function collapseAllPages() {
$$(".pages-item").forEach((element) => {
$$(".pages-tree-item").forEach((element) => {
element.classList.remove("is-expanded");
});
}
function togglePageItem(list) {
const element = list.closest(".pages-item");
const element = list.closest(".pages-tree-item");
element.classList.toggle("is-expanded");
}
@ -245,7 +245,7 @@ export class Pages {
let originalOrder = [];
const sortable = Sortable.create(element, {
handle: ".sort-handle",
handle: ".sortable-handle",
filter: ".is-not-orderable",
forceFallback: true,
swapThreshold: 0.75,

View File

@ -0,0 +1,6 @@
.caption {
font-size: $caption-font-size;
font-weight: 600;
letter-spacing: $caption-letter-spacing;
text-transform: uppercase;
}

View File

@ -0,0 +1,30 @@
@use "sass:map";
.header {
position: sticky;
z-index: 9;
top: 3.5rem;
display: flex;
min-height: 5.5rem;
align-items: center;
padding: 1rem;
border-bottom: 1px solid $color-base-600;
margin-bottom: 2rem;
background-color: $color-base-800;
white-space: nowrap;
@media (min-width: map.get($responsive-breakpoints, "s")) {
padding: 1rem 1.5rem;
margin-right: -1.5rem;
margin-left: -1.5rem;
}
}
.header-title {
overflow: hidden;
flex-grow: 1;
font-size: $h5-font-size;
font-weight: 600;
text-overflow: ellipsis;
white-space: nowrap;
}

View File

@ -0,0 +1,8 @@
.icon {
display: inline-block;
width: 1em;
min-width: 16px;
height: 1em;
min-height: 16px;
vertical-align: -0.125rem;
}

View File

@ -0,0 +1,24 @@
@use "sass:map";
.logo {
margin-bottom: $logo-margin-bottom;
color: $color-base-100;
font-size: $logo-font-size;
font-weight: 600;
line-height: $logo-line-height;
text-align: center;
@media (min-width: map.get($responsive-breakpoints, "s")) {
text-align: left;
}
}
.logo img {
height: $logo-image-height;
margin-right: $logo-image-margin-right;
vertical-align: $logo-image-vertical-align;
}
.logo a {
padding-top: $focusring-width;
color: $color-base-100;
}

View File

@ -0,0 +1,191 @@
@use "sass:color";
@use "sass:map";
@mixin make-pages-tree-levels($levels) {
@for $i from 2 through $levels {
$indent: 0.5rem;
@if $i == 2 {
$indent: 0.625rem;
} @else {
$indent: $indent + $pages-tree-level-padding * ($i - 2);
}
.pages-tree-level-#{$i} {
&::before,
&::after {
left: $indent;
content: "";
}
.page-details {
padding-left: $pages-tree-level-padding * ($i - 1);
}
}
}
}
.pages-tree {
padding: 0;
margin: 0;
list-style-type: none;
@include user-select-none;
}
.pages-tree .pages-tree {
display: none;
}
.pages-tree-root {
border-top: 1px solid $color-base-600;
}
.pages-tree-headers {
display: flex;
align-items: center;
padding: $pages-tree-headers-padding-v $pages-tree-headers-padding-h;
font-weight: 600;
@include user-select-none;
}
.pages-tree-row {
display: flex;
align-items: center;
padding: $pages-tree-item-padding-v $pages-tree-item-padding-h;
border-bottom: 1px solid $color-base-600;
&:hover {
background-color: $color-base-800;
}
}
.pages-tree-item {
position: relative;
&::before {
position: absolute;
z-index: 1;
top: -2.125rem;
width: 1.625rem;
height: 3.625rem;
border-bottom: 2px solid $color-base-600;
border-left: 2px solid $color-base-600;
}
&::after {
position: absolute;
z-index: 1;
top: -2.125rem;
width: 1.625rem;
height: 100%;
border-left: 2px solid $color-base-600;
}
.is-filtered &::before,
.is-filtered &::after {
display: none;
}
&:last-child::after,
.is-dragging > &:nth-last-child(2)::after {
display: none;
}
&.has-children::before,
&.has-children::after,
.is-reordering &.is-orderable::before,
.is-reordering &.is-orderable::after {
width: 0.875rem;
}
.is-reordering &:not(.is-orderable, .has-children)::before,
.is-reordering &:not(.is-orderable, .has-children)::after {
width: 2.375rem;
}
}
@include make-pages-tree-levels(10);
.pages-tree-item-cell,
.pages-tree-headers-cell {
padding: $pages-tree-item-cell-padding-v $pages-tree-item-cell-padding-h;
font-size: $font-size-s;
}
.pages-tree-icon {
min-width: 1rem;
}
.pages-tree-children-toggle {
padding: 0;
border: 0;
color: $color-base-300;
cursor: pointer;
& .icon {
margin-right: 0;
transition:
transform $transition-time-s,
color $transition-time-s;
}
}
.pages-tree-row .sortable-handle {
display: none;
}
.pages-tree.is-filtered .sortable-handle {
display: none;
}
.pages-tree.is-filtered .pages-tree-children-toggle {
display: none;
}
.pages-tree.is-reordering .sortable-handle {
display: block;
}
.pages-tree-children {
display: none;
}
.sortable-chosen .pages-tree-item-cell {
background-color: transparent;
opacity: 0.5;
}
.sortable-chosen .pages-tree-children,
.sortable-fallback .pages-tree-children {
display: none !important;
}
.sortable-chosen .pages-tree-children-toggle .icon,
.sortable-fallback .pages-tree-children-toggle .icon {
transform: none !important;
}
.sortable-fallback .pages-tree-item-cell {
opacity: 1;
}
.pages-tree-item.is-expanded > .pages-tree-children {
display: block;
}
.pages-tree-item.is-expanded > .pages-tree-row .pages-tree-children-toggle .icon {
transform: rotate(-180deg);
}
.is-dragging {
cursor: grab !important;
}
.is-dragging > .is-not-orderable * {
cursor: no-drop !important;
}
.is-dragging > .is-not-orderable .pages-tree-row:hover {
background-color: $color-error-900;
}

View File

@ -1,83 +1,27 @@
@use "sass:color";
@use "sass:map";
.pages-list {
padding: 0;
margin: 0;
list-style-type: none;
@include user-select-none;
}
.pages-list .pages-list {
display: none;
}
.pages-list-headers {
display: flex;
align-items: center;
padding: $pages-list-headers-padding-v $pages-list-headers-padding-h;
font-weight: 600;
@include user-select-none;
}
.page-children-toggle {
padding: 0;
color: $color-base-300;
cursor: pointer;
}
.pages-item-row {
display: flex;
align-items: center;
padding: $pages-item-padding-v $pages-item-padding-h;
border-bottom: 1px solid $color-base-600;
&:hover {
background-color: $color-base-800;
}
}
.page-details {
flex: 1;
}
.pages-item-row .sort-handle {
display: none;
}
.pages-list.is-filtered .sort-handle {
display: none;
}
.pages-list.is-filtered .page-children-toggle {
display: none;
}
.pages-list.is-filtered .pages-item .page-details {
padding-left: 0;
}
.pages-list.is-reordering .sort-handle {
display: block;
}
.pages-list-root {
border-top: 1px solid $color-base-600;
}
.pages-item-cell,
.pages-headers-cell {
padding: $pages-item-cell-padding-v $pages-item-cell-padding-h;
font-size: $font-size-s;
}
.page-title {
padding: $focusring-width;
margin: -$focusring-width;
font-size: $font-size-m;
}
.page-route {
color: $color-base-300;
font-size: $font-size-s;
}
.page-route-changeable {
padding: $focusring-width;
margin: -$focusring-width;
}
.button .page-language {
font-size: $font-size-xs;
}
.page-date {
max-width: 20%;
flex: 0 0 20%;
@ -89,39 +33,11 @@
text-align: center;
}
.page-actions {
flex: 0 0 15%;
text-align: center;
white-space: nowrap;
}
button .page-language,
.button .page-language {
font-size: $font-size-xs;
}
.page-route {
color: $color-base-300;
font-size: $font-size-s;
}
.page-route-changeable {
padding: $focusring-width;
margin: -$focusring-width;
}
.page-status .icon {
display: inline-block;
margin-right: $page-status-label-margin-right;
}
.page-children-toggle .icon {
margin-right: 0;
transition:
transform $transition-time-s,
color $transition-time-s;
}
.page-status-published .icon {
color: $color-success-500;
}
@ -134,81 +50,16 @@ button .page-language,
color: $color-warning-500;
}
.page-actions {
flex: 0 0 15%;
text-align: center;
white-space: nowrap;
}
.page-actions .button-link {
font-size: $font-size-m;
}
.pages-item {
position: relative;
&::before {
position: absolute;
z-index: 1;
top: -2.125rem;
width: 1.625rem;
height: 3.625rem;
border-bottom: 2px solid $color-base-600;
border-left: 2px solid $color-base-600;
}
&::after {
position: absolute;
z-index: 1;
top: -2.125rem;
width: 1.625rem;
height: 100%;
border-left: 2px solid $color-base-600;
}
.is-filtered &::before,
.is-filtered &::after {
display: none;
}
&:last-child::after,
.is-dragging > &:nth-last-child(2)::after {
display: none;
}
&.has-children::before,
&.has-children::after,
.is-reordering &.is-orderable::before,
.is-reordering &.is-orderable::after {
width: 0.875rem;
}
.is-reordering &:not(.is-orderable, .has-children)::before,
.is-reordering &:not(.is-orderable, .has-children)::after {
width: 2.375rem;
}
}
@mixin make-page-levels($levels) {
@for $i from 2 through $levels {
$indent: 0.5rem;
@if $i == 2 {
$indent: 0.625rem;
} @else {
$indent: $indent + $pages-level-padding * ($i - 2);
}
.pages-level-#{$i} {
&::before,
&::after {
left: $indent;
content: "";
}
.page-details {
padding-left: $pages-level-padding * ($i - 1);
}
}
}
}
@include make-page-levels(10);
.page-info {
padding: $page-info-padding-v $page-info-padding-h;
margin-bottom: $page-info-margin-bottom;
@ -248,54 +99,10 @@ button .page-language,
}
}
.pages-children {
display: none;
}
.sortable-fallback::before,
.sortable-fallback::after {
display: none;
}
.sortable-chosen .pages-item-cell {
background-color: transparent;
opacity: 0.5;
}
.sortable-chosen .pages-children,
.sortable-fallback .pages-children {
display: none !important;
}
.sortable-chosen .page-children-toggle .icon,
.sortable-fallback .page-children-toggle .icon {
transform: none !important;
}
.sortable-fallback .pages-item-cell {
opacity: 1;
}
.pages-item.is-expanded > .pages-children {
display: block;
}
.pages-item.is-expanded > .pages-item-row .page-children-toggle .icon {
transform: rotate(-180deg);
}
.is-dragging {
cursor: grab !important;
}
.is-dragging .page-title {
pointer-events: none;
}
.is-dragging > .is-not-orderable * {
cursor: no-drop !important;
}
.is-dragging > .is-not-orderable .pages-item-row:hover {
background-color: $color-error-900;
.pages-tree.is-filtered .pages-tree-item .page-details {
padding-left: 0;
}

View File

@ -1,139 +1,26 @@
@use "sass:map";
.title-bar {
.panel-header {
position: fixed;
z-index: 10;
top: 0;
right: 0;
left: 0;
padding: $title-bar-padding;
padding-left: $title-bar-padding-left + $toggle-navigation-width + 2 * $toggle-navigation-left;
display: flex;
align-items: center;
padding: $panel-header-padding;
padding-left: $panel-header-padding-left + $sidebar-toggle-width + 2 * $sidebar-toggle-left;
background-color: $color-base-600;
box-shadow: $component-box-shadow;
color: $color-base-100;
font-weight: 500;
@include user-select-none;
@include ellipsis;
@media (min-width: map.get($responsive-breakpoints, "s")) {
left: $sidebar-width;
padding-left: $title-bar-padding-left;
padding-left: $panel-header-padding-left;
}
}
.panel-title {
float: left;
}
.view-site {
color: $color-base-100;
float: right;
&:hover {
color: $color-accent-500;
}
}
.view-site i {
margin-left: 0.5rem;
}
.sidebar {
position: fixed;
z-index: 12;
top: 0;
bottom: 0;
left: 0;
width: $sidebar-width;
padding: $sidebar-padding-h $sidebar-padding-v;
background: $sidebar-background-gradient;
background-color: $sidebar-background-gradient-color-0;
box-shadow: $component-box-shadow;
@include user-select-none;
}
.sidebar.show {
display: block;
}
.sidebar-wrapper {
height: calc(100% - 9rem);
overflow-y: auto;
}
.sidebar-backdrop {
position: fixed;
z-index: 11;
background-color: $backdrop-background-color;
inset: 0;
}
.toggle-navigation {
position: fixed;
z-index: 13;
top: $toggle-navigation-top;
left: $toggle-navigation-left;
cursor: pointer;
}
.logo {
margin-bottom: $logo-margin-bottom;
color: $color-base-100;
font-size: $logo-font-size;
font-weight: 600;
line-height: $logo-line-height;
text-align: center;
@media (min-width: map.get($responsive-breakpoints, "s")) {
text-align: left;
}
}
.logo img {
height: $logo-image-height;
margin-right: $logo-image-margin-right;
vertical-align: $logo-image-vertical-align;
}
.logo a {
padding-top: $focusring-width;
color: $color-base-100;
}
.sidebar-navigation {
padding: 0;
margin: 0;
margin-bottom: $sidebar-navigation-margin-bottom;
list-style-type: none;
&:last-child {
margin-bottom: 0;
}
}
.sidebar-navigation > li {
position: relative;
padding: $sidebar-navigation-li-padding-v $sidebar-navigation-li-padding-h;
padding-left: $sidebar-navigation-li-padding-left;
margin: 0;
margin-bottom: $sidebar-navigation-li-margin-bottom;
}
.sidebar-navigation > li a {
color: $color-base-100;
}
.sidebar-navigation > .active {
font-weight: 600;
}
.sidebar-navigation > .active::before {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: $sidebar-navigation-notch-width;
background-color: $color-accent-500;
content: " ";
}
.panel-user-card {
display: flex;
align-items: center;
@ -168,127 +55,11 @@
font-size: $font-size-s;
}
.header {
position: sticky;
z-index: 9;
top: 3.5rem;
display: flex;
min-height: 5.5rem;
align-items: center;
padding: 1rem;
border-bottom: 1px solid $color-base-600;
margin-bottom: 2rem;
background-color: $color-base-800;
white-space: nowrap;
.panel-main {
padding-top: $panel-main-margin-top;
@media (min-width: map.get($responsive-breakpoints, "s")) {
padding: 1rem 1.5rem;
margin-right: -1.5rem;
margin-left: -1.5rem;
padding: $panel-main-margin;
padding-top: $panel-main-margin-top;
padding-left: $panel-main-margin-left;
}
}
.header-title {
overflow: hidden;
flex-grow: 1;
font-size: $h5-font-size;
font-weight: 600;
text-overflow: ellipsis;
white-space: nowrap;
}
.main {
padding-top: $main-margin-top;
@media (min-width: map.get($responsive-breakpoints, "s")) {
padding: $main-margin;
padding-top: $main-margin-top;
padding-left: $main-margin-left;
}
}
.caption {
margin-bottom: 0;
font-size: $caption-font-size;
font-weight: 600;
letter-spacing: $caption-letter-spacing;
text-transform: uppercase;
@include user-select-none;
}
.separator {
height: $separator-height;
}
.separator-l {
height: $separator-height-l;
}
.section {
padding: 1.5rem 1.75rem;
border-radius: $border-radius;
margin-bottom: $section-margin-bottom;
background-color: $color-base-900;
box-shadow: $component-box-shadow;
}
.section-header {
margin-bottom: $section-header-margin-bottom;
font-size: $font-size-m;
font-weight: 600;
@include user-select-none;
}
.section.collapsed .section-header {
margin-bottom: 0;
}
.icon {
display: inline-block;
width: 1em;
min-width: 16px;
height: 1em;
min-height: 16px;
vertical-align: -0.125rem;
}
.sort-handle .icon {
display: inline-block;
margin-bottom: 0;
color: $color-base-300;
cursor: grab;
}
.section-toggle {
padding: 0;
color: $color-base-300;
cursor: pointer;
}
.section-toggle .icon {
margin-right: 0;
transition:
transform $transition-time-s,
color $transition-time-s;
}
.section.collapsed .section-toggle .icon {
transform: rotate(180deg);
}
.section.collapsed .section-content {
display: none;
}
.sortable-chosen,
.sortable-ghost {
background-color: $color-base-900;
cursor: grabbing;
}
.sortable-chosen * {
cursor: grabbing;
}
.sortable-fallback {
box-shadow: $sortable-fallback-box-shadow;
}

View File

@ -0,0 +1,39 @@
.section {
padding: 1.5rem 1.75rem;
border-radius: $border-radius;
margin-bottom: $section-margin-bottom;
background-color: $color-base-900;
box-shadow: $component-box-shadow;
}
.section-header {
margin-bottom: $section-header-margin-bottom;
font-size: $font-size-m;
font-weight: 600;
@include user-select-none;
}
.section.collapsed .section-header {
margin-bottom: 0;
}
.section-toggle {
padding: 0;
color: $color-base-300;
cursor: pointer;
}
.section-toggle .icon {
margin-right: 0;
transition:
transform $transition-time-s,
color $transition-time-s;
}
.section.collapsed .section-toggle .icon {
transform: rotate(180deg);
}
.section.collapsed .section-content {
display: none;
}

View File

@ -0,0 +1,74 @@
.sidebar {
position: fixed;
z-index: 12;
top: 0;
bottom: 0;
left: 0;
width: $sidebar-width;
padding: $sidebar-padding-h $sidebar-padding-v;
background: $sidebar-background-gradient;
background-color: $sidebar-background-gradient-color-0;
box-shadow: $component-box-shadow;
@include user-select-none;
}
.sidebar.show {
display: block;
}
.sidebar-wrapper {
height: calc(100% - 9rem);
overflow-y: auto;
}
.sidebar-backdrop {
position: fixed;
z-index: 11;
background-color: $backdrop-background-color;
inset: 0;
}
.sidebar-toggle {
position: fixed;
z-index: 13;
top: $sidebar-toggle-top;
left: $sidebar-toggle-left;
cursor: pointer;
}
.sidebar-navigation {
padding: 0;
margin: 0;
margin-bottom: $sidebar-navigation-margin-bottom;
list-style-type: none;
&:last-child {
margin-bottom: 0;
}
}
.sidebar-navigation > li {
position: relative;
padding: $sidebar-navigation-li-padding-v $sidebar-navigation-li-padding-h;
padding-left: $sidebar-navigation-li-padding-left;
margin: 0;
margin-bottom: $sidebar-navigation-li-margin-bottom;
}
.sidebar-navigation > li a {
color: $color-base-100;
}
.sidebar-navigation > .active {
font-weight: 600;
}
.sidebar-navigation > .active::before {
position: absolute;
top: 0;
bottom: 0;
left: 0;
width: $sidebar-navigation-notch-width;
background-color: $color-accent-500;
content: " ";
}

View File

@ -0,0 +1,25 @@
.sortable-handle .icon {
display: inline-block;
margin-bottom: 0;
color: $color-base-300;
cursor: grab;
}
.sortable-chosen,
.sortable-ghost {
background-color: $color-base-900;
cursor: grabbing;
}
.sortable-chosen * {
cursor: grabbing;
}
.sortable-fallback {
box-shadow: $sortable-fallback-box-shadow;
}
.sortable-fallback::before,
.sortable-fallback::after {
display: none;
}

View File

@ -26,3 +26,7 @@
.caption + .tabs {
margin-top: -$tabs-tab-padding-v;
}
.header + .tabs {
margin-top: -1.5rem;
}

View File

@ -1,60 +1,53 @@
h1,
.h1,
h2,
.h2,
h3,
.h3,
h4,
.h4,
h5,
.h5,
h6,
.h6 {
margin-top: 0;
margin-bottom: $headings-margin-bottom;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
}
@if $large-headings-letter-spacing != 0 {
h1,
.h1,
h2,
.h2,
h3,
.h3 {
letter-spacing: $large-headings-letter-spacing;
}
}
h1,
.h1 {
font-size: $h1-font-size;
@extend %heading;
@if $large-headings-letter-spacing != 0 {
letter-spacing: $large-headings-letter-spacing;
}
}
h2,
.h2 {
font-size: $h2-font-size;
@extend %heading;
@if $large-headings-letter-spacing != 0 {
letter-spacing: $large-headings-letter-spacing;
}
}
h3,
.h3 {
font-size: $h3-font-size;
@extend %heading;
@if $large-headings-letter-spacing != 0 {
letter-spacing: $large-headings-letter-spacing;
}
}
h4,
.h4 {
font-size: $h4-font-size;
@extend %heading;
}
h5,
.h5 {
font-size: $h5-font-size;
@extend %heading;
}
h6,
.h6 {
font-size: $h6-font-size;
@extend %heading;
}
%heading {
margin-top: 0;
margin-bottom: $headings-margin-bottom;
font-weight: $headings-font-weight;
line-height: $headings-line-height;
}
strong {

View File

@ -1,10 +1,12 @@
@use "sass:map";
@include make-util("m", "margin", $spacers);
@include make-util("mt", "margin-top", $spacers);
@include make-util("ml", "margin-left", $spacers);
@include make-util("mb", "margin-bottom", $spacers);
@include make-util("mr", "margin-right", $spacers);
@include make-util("p", "padding", $spacers);
@include make-util("pt", "padding-top", $spacers);
@include make-util("pl", "padding-left", $spacers);
@include make-util("pb", "padding-bottom", $spacers);

View File

@ -430,8 +430,8 @@ $login-modal-notification-padding-right: 2rem;
// Panel
// ===
$title-bar-padding: 1rem;
$title-bar-padding-left: 1.5rem;
$panel-header-padding: 0.75rem;
$panel-header-padding-left: 1.5rem;
$sidebar-width: 16rem;
@ -441,9 +441,9 @@ $sidebar-background-gradient-color-0: $color-base-900;
$sidebar-background-gradient-color-100: $color-base-800;
$sidebar-background-gradient: linear-gradient(to bottom, #{$sidebar-background-gradient-color-0} 0%, #{$sidebar-background-gradient-color-100} 100%);
$toggle-navigation-top: 0.75rem;
$toggle-navigation-left: 0.75rem;
$toggle-navigation-width: 1rem;
$sidebar-toggle-top: 0.75rem;
$sidebar-toggle-left: 0.75rem;
$sidebar-toggle-width: 1rem;
$sidebar-navigation-li-margin-bottom: 0.5rem;
$sidebar-navigation-li-padding-v: 0.25rem;
@ -469,9 +469,9 @@ $panel-user-avatar-width: 48px;
$panel-user-details-padding-v: 0;
$panel-user-details-padding-h: 0.75rem;
$main-margin: 1.875rem;
$main-margin-top: 4.5rem;
$main-margin-left: $main-margin + $sidebar-width;
$panel-main-margin: 1.875rem;
$panel-main-margin-top: 4.5rem;
$panel-main-margin-left: $panel-main-margin + $sidebar-width;
$component-margin-bottom: 1rem;
$component-padding: 1.5rem;
@ -504,14 +504,14 @@ $dashboard-chart-height: 14rem;
// Pages
// ===
$pages-list-headers-padding-v: 0.25rem;
$pages-list-headers-padding-h: 0;
$pages-tree-headers-padding-v: 0.25rem;
$pages-tree-headers-padding-h: 0;
$pages-item-padding-v: 0.5rem;
$pages-item-padding-h: 0;
$pages-tree-item-padding-v: 0.5rem;
$pages-tree-item-padding-h: 0;
$pages-item-cell-padding-v: 0.25rem;
$pages-item-cell-padding-h: 0.25rem;
$pages-tree-item-cell-padding-v: 0.25rem;
$pages-tree-item-cell-padding-h: 0.25rem;
$page-language-padding-v: 0.125rem;
$page-language-padding-h: 0.25rem;
@ -519,8 +519,8 @@ $page-language-min-width: 1.125rem;
$page-status-label-margin-right: 0.375rem;
$pages-levels: 10;
$pages-level-padding: 1.75rem;
$pages-tree-levels: 10;
$pages-tree-level-padding: 1.75rem;
$page-info-margin-bottom: 0.75rem;
$page-info-padding-v: 0;

View File

@ -3,7 +3,7 @@
@include user-select-none;
}
.form-input-array .sort-handle .icon {
.form-input-array .sortable-handle .icon {
vertical-align: middle;
}

View File

@ -6,26 +6,34 @@
@import "components/base";
@import "components/typography";
@import "components/table";
@import "components/columns";
@import "components/buttons";
@import "components/animations";
@import "components/badges";
@import "components/forms";
@import "components/buttons";
@import "components/caption";
@import "components/charts";
@import "components/columns";
@import "components/dropdowns";
@import "components/files-list";
@import "components/tabs";
@import "components/forms";
@import "components/header";
@import "components/icon";
@import "components/logo";
@import "components/modals";
@import "components/notifications";
@import "components/tooltip";
@import "components/spinner";
@import "components/charts";
@import "components/animations";
@import "components/login";
@import "components/pages-tree";
@import "components/panel";
@import "components/pages";
@import "components/options";
@import "components/users";
@import "components/section";
@import "components/sidebar";
@import "components/sortable";
@import "components/spinner";
@import "components/table";
@import "components/tabs";
@import "components/tooltip";
@import "components/errors";
@import "components/login";
@import "components/options";
@import "components/pages";
@import "components/users";
@import "components/utils";

View File

@ -6,6 +6,5 @@
<label class="form-label" for="password"><?= $this->translate('panel.login.password') ?>:</label>
<input class="form-input" <?php if (!empty($error)): ?>class="form-input-invalid" autofocus <?php endif ?>id="password" type="password" required name="password">
<input type="hidden" name="csrf-token" value="<?= $csrfToken ?>">
<div class="separator"></div>
<button type="submit" class="button button-accent"><?= $this->icon('arrow-right-circle') ?> <?= $this->translate('panel.login.login') ?></button>
<button type="submit" class="button button-accent mt-8"><?= $this->icon('arrow-right-circle') ?> <?= $this->translate('panel.login.login') ?></button>
</form>

View File

@ -12,7 +12,7 @@
</section>
<section class="section">
<div class="section-header">
<h3 class="caption"><?= $this->translate('panel.dashboard.quickActions') ?></h3>
<div class="caption"><?= $this->translate('panel.dashboard.quickActions') ?></div>
</div>
<?php if ($panel->user()->permissions()->has('pages.create')): ?>
<button type="button" class="button button-secondary mb-4" data-modal="newPageModal"><?= $this->icon('plus-circle') ?> <?= $this->translate('panel.pages.newPage') ?></button>
@ -33,7 +33,7 @@
<div class="row">
<div class="col-xs-1-2">
<div class="section-header">
<h3 class="caption"><?= $this->translate('panel.dashboard.statistics') ?></h3>
<div class="caption"><?= $this->translate('panel.dashboard.statistics') ?></div>
</div>
</div>
<div class="col-xs-1-2">
@ -49,7 +49,7 @@
</div>
<section class="section">
<div class="section-header">
<h3 class="caption"><?= $this->translate('panel.dashboard.lastModifiedPages') ?></h3>
<div class="caption"><?= $this->translate('panel.dashboard.lastModifiedPages') ?></div>
</div>
<?= $lastModifiedPages ?>
</section>

View File

@ -7,7 +7,7 @@
]) ?>>
<?php foreach ($field->value() ?: ['' => ''] as $key => $value): ?>
<div class="form-input-array-row">
<span class="sort-handle" title="<?= $this->translate('panel.dragToReorder') ?>"><?= $this->icon('grabber') ?></span>
<span class="sortable-handle" title="<?= $this->translate('panel.dragToReorder') ?>"><?= $this->icon('grabber') ?></span>
<?php if ($field->get('associative')): ?>
<input <?= $this->attr([
'type' => 'text',

View File

@ -18,11 +18,11 @@
<body>
<?php $this->insert('partials.sidebar') ?>
<div class="title-bar">
<span class="panel-title"><?= $this->translate('panel.panel') ?></span>
<a href="<?= $site->uri() ?>" class="view-site" target="formwork-view-site"><span class="show-from-xs"><?= $this->translate('panel.viewSite') ?></span> <?= $this->icon('arrow-right-up-box') ?></a>
</div>
<main class="main">
<header class="panel-header">
<span class="flex-grow-1"><?= $this->translate('panel.panel') ?></span>
<a href="<?= $site->uri() ?>" class="button button-link text-size-m" target="formwork-view-site"><span class="show-from-xs"><?= $this->translate('panel.viewSite') ?></span> <?= $this->icon('arrow-right-up-box') ?></a>
</header>
<main class="panel-main">
<div class="container">
<?= $this->content() ?>
</div>

View File

@ -1,7 +1,7 @@
<div id="changesModal" class="modal" aria-labelledby="changesModalLabel">
<div class="modal-container">
<div class="modal-header">
<h3 class="caption" id="changesModalLabel"><?= $this->translate('panel.pages.changes.detected') ?></h3>
<div class="caption" id="changesModalLabel"><?= $this->translate('panel.pages.changes.detected') ?></div>
</div>
<div class="modal-content">
<p class="modal-text"><?= $this->translate('panel.pages.changes.detected.prompt') ?></p>

View File

@ -2,7 +2,7 @@
<div class="modal-container">
<form action="" method="post">
<div class="modal-header">
<h3 class="caption" id="deleteFileModalLabel"><?= $this->translate('panel.pages.deleteFile') ?></h3>
<div class="caption" id="deleteFileModalLabel"><?= $this->translate('panel.pages.deleteFile') ?></div>
</div>
<div class="modal-content">
<p class="modal-text"><?= $this->translate('panel.pages.deleteFile.prompt') ?></p>

View File

@ -2,7 +2,7 @@
<div class="modal-container">
<form action="" method="post">
<div class="modal-header">
<h3 class="caption" id="deletePageModalLabel"><?= $this->translate('panel.pages.deletePage') ?></h3>
<div class="caption" id="deletePageModalLabel"><?= $this->translate('panel.pages.deletePage') ?></div>
</div>
<div class="modal-content">
<p class="modal-text"><?= $this->translate('panel.pages.deletePage.prompt') ?></p>

View File

@ -2,7 +2,7 @@
<div class="modal-container">
<form action="" method="post">
<div class="modal-header">
<h3 class="caption" id="deleteUserModalLabel"><?= $this->translate('panel.users.deleteUser') ?></h3>
<div class="caption" id="deleteUserModalLabel"><?= $this->translate('panel.users.deleteUser') ?></div>
</div>
<div class="modal-content">
<p class="modal-text"><?= $this->translate('panel.users.deleteUser.prompt') ?></p>

View File

@ -1,7 +1,7 @@
<div id="imagesModal" class="modal" aria-labelledby="imagesModalLabel">
<div class="modal-container modal-size-large">
<div class="modal-header">
<h3 class="caption" id="imagesModalLabel"><?= $this->translate('panel.modal.images.title') ?></h3>
<div class="caption" id="imagesModalLabel"><?= $this->translate('panel.modal.images.title') ?></div>
</div>
<div class="modal-content">
<div class="image-picker-empty-state">

View File

@ -2,7 +2,7 @@
<div class="modal-container">
<form action="<?= $panel->uri('/pages/new/') ?>" method="post">
<div class="modal-header">
<h3 class="caption" id="newPageModalLabel"><?= $this->translate('panel.pages.newPage') ?></h3>
<div class="caption" id="newPageModalLabel"><?= $this->translate('panel.pages.newPage') ?></div>
</div>
<div class="modal-content">
<label class="form-label form-label-required" for="page-title"><?= $this->translate('panel.pages.newPage.title') ?>:</label>

View File

@ -2,7 +2,7 @@
<div class="modal-container">
<form action="<?= $panel->uri('/users/new/') ?>" method="post">
<div class="modal-header">
<h3 class="caption" id="newUserModalLabel"><?= $this->translate('panel.users.newUser') ?>
<div class="caption" id="newUserModalLabel"><?= $this->translate('panel.users.newUser') ?>
</div>
<div class="modal-content">
<label class="form-label form-label-required" for="fullname"><?= $this->translate('panel.user.fullname') ?>:</label>

View File

@ -2,7 +2,7 @@
<div class="modal-container">
<form action="" method="post">
<div class="modal-header">
<h3 class="caption" id="renameFileModalLabel"><?= $this->translate('panel.pages.renameFile') ?></h3>
<div class="caption" id="renameFileModalLabel"><?= $this->translate('panel.pages.renameFile') ?></div>
</div>
<div class="modal-content">
<label class="form-label form-label-required" for="filename"><?= $this->translate('panel.pages.renameFile.name') ?>:</label>

View File

@ -1,6 +1,6 @@
<div id="slugModal" class="modal" aria-labelledby="slugModalLabel">
<div class="modal-container">
<div class="modal-header"><h3 class="caption" id="slugModalLabel"><?= $this->translate('panel.pages.changeSlug') ?></h3></div>
<div class="modal-header"><div class="caption" id="slugModalLabel"><?= $this->translate('panel.pages.changeSlug') ?></div></div>
<div class="modal-content">
<label class="form-label" for="page-slug"><?= $this->translate('panel.pages.newPage.slug') ?>:</label>
<span class="form-label-suggestion">(<?= $this->translate('panel.pages.newPage.slugSuggestion') ?>)</span>

View File

@ -1,4 +1,4 @@
<div class="tabs" style="margin-top:-1.5rem">
<div class="tabs">
<?php foreach ($tabs as $tab): ?>
<?php if ($panel->user()->permissions()->has('options.' . $tab)): ?>
<a class="tabs-tab<?= ($tab === $current) ? ' active' : '' ?>" href="<?= $panel->uri('/options/' . $tab . '/') ?>"><?= $this->translate('panel.options.' . $tab) ?></a>

View File

@ -20,5 +20,5 @@
<button type="button" class="button button-secondary mb-4" data-command="reorder-pages"><?= $this->icon('reorder-v') ?> <?= $this->translate('panel.pages.pages.reorder') ?></button>
</div>
</div>
<?= $pagesList ?>
<?= $pagesTree ?>
</section>

View File

@ -1,33 +1,33 @@
<?php if ($headers): ?>
<div class="pages-list-headers" aria-hidden="true">
<div class="pages-headers-cell page-details truncate"><?= $this->translate('panel.pages.page.title') ?></div>
<div class="pages-headers-cell page-date truncate show-from-m"><?= $this->translate('panel.pages.page.lastModified') ?></div>
<div class="pages-headers-cell page-status truncate show-from-xs"><?= $this->translate('panel.pages.page.status') ?></div>
<div class="pages-headers-cell page-actions"><?= $this->translate('panel.pages.page.actions') ?></div>
<div class="pages-tree-headers" aria-hidden="true">
<div class="pages-tree-headers-cell page-details truncate"><?= $this->translate('panel.pages.page.title') ?></div>
<div class="pages-tree-headers-cell page-date truncate show-from-m"><?= $this->translate('panel.pages.page.lastModified') ?></div>
<div class="pages-tree-headers-cell page-status truncate show-from-xs"><?= $this->translate('panel.pages.page.status') ?></div>
<div class="pages-tree-headers-cell page-actions"><?= $this->translate('panel.pages.page.actions') ?></div>
</div>
<?php endif ?>
<ul class="pages-list <?= $class ?>" data-orderable-children="<?= $orderable ? 'true' : 'false' ?>" <?php if ($parent): ?> data-parent="<?= $parent ?>" <?php endif ?>>
<ul class="pages-tree <?= $class ?>" data-orderable-children="<?= $orderable ? 'true' : 'false' ?>" <?php if ($parent): ?> data-parent="<?= $parent ?>" <?php endif ?>>
<?php foreach ($pages as $page): ?>
<?php $routable = $page->published() && $page->routable() ?>
<?php $date = $this->datetime($page->contentFile()->lastModifiedTime()) ?>
<li class="pages-item <?php if ($subpages): ?>pages-level-<?= $page->level() ?> <?php endif ?><?php if ($page->hasChildren()): ?>has-children <?php endif ?><?= $page->orderable() ? 'is-orderable' : 'is-not-orderable' ?>" data-route="<?= $page->route() ?>">
<div class="pages-item-row">
<div class="pages-item-cell page-details">
<li class="pages-tree-item <?php if ($includeChildren): ?>pages-tree-level-<?= $page->level() ?> <?php endif ?><?php if ($page->hasChildren()): ?>has-children <?php endif ?><?= $page->orderable() ? 'is-orderable' : 'is-not-orderable' ?>" data-route="<?= $page->route() ?>">
<div class="pages-tree-row">
<div class="pages-tree-item-cell page-details">
<div class="page-title flex">
<div class="sort-handle" style="min-width: 1rem" class="mr-2">
<div class="pages-tree-icon sortable-handle mr-2">
<?php if ($orderable && $page->orderable()): ?>
<span title="<?= $this->translate('panel.dragToReorder') ?>"><?= $this->icon('grabber') ?></span>
<?php endif ?>
</div>
<?php if ($subpages): ?>
<div style="min-width: 1rem" class="mr-2">
<?php if ($includeChildren): ?>
<div class="pages-tree-icon mr-2">
<?php if ($page->hasChildren()): ?>
<button type="button" class="button page-children-toggle" title="<?= $this->translate('panel.pages.toggleChildren') ?>" aria-label="<?= $this->translate('panel.pages.toggleChildren') ?>"><?= $this->icon('chevron-down') ?></button>
<button type="button" class="button pages-tree-children-toggle" title="<?= $this->translate('panel.pages.toggleChildren') ?>" aria-label="<?= $this->translate('panel.pages.toggleChildren') ?>"><?= $this->icon('chevron-down') ?></button>
<?php endif ?>
</div>
<?php endif ?>
<div class="mr-2" style="min-width: 1rem"><?= $this->icon($page->get('icon', 'page')) ?></div>
<div class="mr-2" class="pages-tree-icon"><?= $this->icon($page->get('icon', 'page')) ?></div>
<div class="min-w-0">
<div class="truncate text-color-accent"><a href="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/edit/') ?>"><?= $this->escape($page->title()) ?></a></div>
<?php foreach ($page->languages()->available() as $language): ?>
@ -39,26 +39,26 @@
</div>
</div>
</div>
<div class="pages-item-cell page-date truncate show-from-m"><?= $date ?></div>
<div class="pages-item-cell page-status page-status-<?= $page->status() ?> truncate show-from-xs">
<div class="pages-tree-item-cell page-date truncate show-from-m"><?= $date ?></div>
<div class="pages-tree-item-cell page-status page-status-<?= $page->status() ?> truncate show-from-xs">
<?= $this->icon('circle-small-fill') ?>
<span class="page-status-label"><?= $this->translate('panel.pages.status.' . $page->status()) ?></span>
</div>
<div class="pages-item-cell page-actions">
<div class="pages-tree-item-cell page-actions">
<a class="button button-link<?php if (!$page->published() || !$page->routable()): ?> disabled<?php endif ?>" role="button" <?php if ($page->published() && $page->routable()): ?>href="<?= $page->uri(includeLanguage: false) ?>" <?php endif ?> target="formwork-preview-<?= $page->uid() ?>" title="<?= $this->translate('panel.pages.preview') ?>" aria-label="<?= $this->translate('panel.pages.preview') ?>"><?= $this->icon('eye') ?></a>
<?php if ($panel->user()->permissions()->has('pages.delete')): ?>
<button type="button" class="button button-link" data-modal="deletePageModal" data-modal-action="<?= $panel->uri('/pages/' . trim($page->route(), '/') . '/delete/') ?>" title="<?= $this->translate('panel.pages.deletePage') ?>" aria-label="<?= $this->translate('panel.pages.deletePage') ?>" <?php if (!$page->isDeletable()): ?> disabled<?php endif ?>><?= $this->icon('trash') ?></button>
<?php endif ?>
</div>
</div>
<?php if ($subpages && $page->hasChildren()): ?>
<?php $this->insert('pages.list', [
'pages' => $page->scheme()->options()->get('children.reverse', false) ? $page->children()->reverse() : $page->children(),
'subpages' => true,
'class' => 'pages-children',
'parent' => $page->route(),
'orderable' => $orderable && $page->scheme()->options()->get('children.orderable', true),
'headers' => false,
<?php if ($includeChildren && $page->hasChildren()): ?>
<?php $this->insert('pages.tree', [
'pages' => $page->scheme()->options()->get('children.reverse', false) ? $page->children()->reverse() : $page->children(),
'includeChildren' => true,
'class' => 'pages-tree-children',
'parent' => $page->route(),
'orderable' => $orderable && $page->scheme()->options()->get('children.orderable', true),
'headers' => false,
]) ?>
<?php endif ?>
</li>

View File

@ -1,4 +1,4 @@
<button type="button" class="button button-link toggle-navigation hide-from-s" aria-label="<?= $this->translate('panel.navigation.toggle') ?>"><?= $this->icon('bars') ?></button>
<button type="button" class="button button-link sidebar-toggle hide-from-s" aria-label="<?= $this->translate('panel.navigation.toggle') ?>"><?= $this->icon('bars') ?></button>
<div class="sidebar show-from-s">
<div class="logo"><a href="<?= $panel->uri('/dashboard/') ?>"><img src="<?= $this->assets()->uri('images/icon.svg') ?>" alt=""> Formwork</a> <span class="show-from-s text-color-gray-medium text-size-xs"><?= $app::VERSION ?></span></div>
<a href="<?= $panel->uri('/users/' . $panel->user()->username() . '/profile/') ?>">
@ -12,8 +12,8 @@
</div>
</div>
</a>
<div class="sidebar-wrapper">
<h3 class="caption mb-8"><?= $this->translate('panel.manage') ?></h3>
<nav class="sidebar-wrapper">
<div class="caption mb-8"><?= $this->translate('panel.manage') ?></div>
<ul class="sidebar-navigation">
<?php foreach ($navigation as $id => ['label' => $label, 'uri' => $uri, 'permissions' => $permissions, 'badge' => $badge]): ?>
<?php if ($panel->user()->permissions()->has($permissions)): ?>
@ -26,5 +26,5 @@
<?php endif ?>
<?php endforeach ?>
</ul>
</div>
</nav>
</div>

View File

@ -1,7 +1,6 @@
<?php $this->layout('login') ?>
<div class="caption"><?= $this->translate('panel.register.register') ?></div>
<p><?= $this->translate('panel.register.createUser') ?></p>
<div class="separator"></div>
<p class="mb-8"><?= $this->translate('panel.register.createUser') ?></p>
<form action="<?= $panel->uri('/register/') ?>" method="post">
<label class="form-label form-label-required" for="fullname"><?= $this->translate('panel.user.fullname') ?>:</label>
<input class="form-input" id="fullname" type="text" required name="fullname">
@ -20,6 +19,5 @@
<?php endforeach ?>
</select>
<input type="hidden" name="csrf-token" value="<?= $csrfToken ?>">
<div class="separator"></div>
<button type="submit" class="button button-accent"><?= $this->icon('check-circle') ?> <?= $this->translate('panel.modal.action.continue') ?></button>
<button type="submit" class="button button-accent mt-8"><?= $this->icon('check-circle') ?> <?= $this->translate('panel.modal.action.continue') ?></button>
</form>

View File

@ -8,7 +8,7 @@
<div class="row">
<div class="col-xs-1-2">
<div class="section-header">
<h3 class="caption"><?= $this->translate('panel.dashboard.statistics') ?></h3>
<div class="caption"><?= $this->translate('panel.dashboard.statistics') ?></div>
</div>
</div>
<div class="col-xs-1-2">
@ -43,7 +43,7 @@
<section class="section">
<div class="section-header">
<h3 class="caption"><?= $this->translate('panel.statistics.totalVisits') ?></h3>
<div class="caption"><?= $this->translate('panel.statistics.totalVisits') ?></div>
</div>
<table class="table table-bordered table-striped table-hoverable text-size-s">
<thead>

View File

@ -13,7 +13,7 @@
<section class="section">
<div class="section-header">
<h3 class="caption"><?= $this->translate('panel.tools.latestBackups') ?></h3>
<div class="caption"><?= $this->translate('panel.tools.latestBackups') ?></div>
</div>
<table id="backups-table" class="table table-bordered table-hoverable text-size-s">
<thead>

View File

@ -1,4 +1,4 @@
<div class="tabs" style="margin-top:-1.5rem">
<div class="tabs">
<?php foreach ($tabs as $tab): ?>
<?php if ($panel->user()->permissions()->has('tools.' . $tab)): ?>
<a class="tabs-tab<?= ($tab === $current) ? ' active' : '' ?>" href="<?= $panel->uri('/tools/' . $tab . '/') ?>"><?= $this->translate('panel.tools.' . $tab) ?></a>

View File

@ -12,17 +12,14 @@
<div class="checker"><span class="spinner"></span><span class="update-status" data-checking-text="<?= $this->translate('panel.updates.status.checking') ?>" data-installing-text="<?= $this->translate('panel.updates.status.installing') ?>"><?= $this->translate('panel.updates.status.checking') ?></span></div>
</div>
</div>
<div class="row new-version" style="display: none;">
<div class="separator-l"></div>
<div class="row new-version mt-9" style="display: none;">
<div class="col-m-1-1">
<p><strong class="new-version-name">Formwork x.x.x</strong> <?= $this->translate('panel.updates.availableForInstall') ?></p>
<div><?= $this->translate('panel.updates.installPrompt') ?></div>
<div class="separator"></div>
<div class="mb-8"><?= $this->translate('panel.updates.installPrompt') ?></div>
<button type="button" class="button" data-command="install-updates"><?= $this->translate('panel.updates.install') ?></button>
</div>
</div>
<div class="row current-version" style="display: none;">
<div class="separator-l"></div>
<div class="row current-version mt-9" style="display: none;">
<div class="col-m-1-1">
<p><strong class="current-version-name">Formwork <?= $currentVersion ?></strong> <?= $this->translate('panel.updates.latestVersionAvailable') ?></p>
</div>

View File

@ -15,7 +15,7 @@
<img src="<?= $user->image()->uri() ?>" alt="<? $panel->user()->username() ?>">
</div>
<div class="user-summary-data">
<h3><?= $this->escape($user->fullname()) ?></h3>
<div class="h3"><?= $this->escape($user->fullname()) ?></div>
<?= $this->escape($user->username()) ?><br>
<a href="mailto:<?= $user->email() ?>"><?= $this->escape($user->email()) ?></a><br>
<?= $this->translate('panel.user.lastAccess') ?>: <?= is_null($user->lastAccess()) ? '&infin;' : $this->datetime($user->lastAccess()) ?>