0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-20 19:51:23 -05:00

♻️ Remove new-css-system from dashboard

This commit is contained in:
Eva 2024-01-03 14:17:17 +01:00
parent 3f151f16ce
commit af99bf05e2
52 changed files with 1917 additions and 9738 deletions

View file

@ -216,6 +216,7 @@
.button-disabled {
@include buttonStyle;
@include flexCenter;
height: $s-32;
background-color: var(--button-background-color-disabled);
border: $s-1 solid var(--button-border-color-disabled);
color: var(--button-foreground-color-disabled);
@ -738,7 +739,6 @@
@include titleTipography;
color: var(--color-foreground-primary);
text-align: left;
display: grid;
grid-template-columns: 1fr 22px;
grid-template-areas: "name button";

View file

@ -44,7 +44,6 @@
//#################################################
@import "common/framework";
@import "main/partials/modal";
@import "main/partials/forms";
@import "main/partials/texts";
@import "main/partials/context-menu";
@ -58,13 +57,6 @@
@import "main/partials/viewer-header";
@import "main/partials/viewer-thumbnails";
@import "main/partials/activity-bar";
@import "main/partials/dashboard";
@import "main/partials/dashboard-header";
@import "main/partials/dashboard-grid";
@import "main/partials/dashboard-sidebar";
@import "main/partials/dashboard-team";
@import "main/partials/dashboard-settings";
@import "main/partials/dashboard-fonts";
@import "main/partials/debug-icons-preview";
@import "main/partials/editable-label";
@import "main/partials/loader";
@ -74,9 +66,7 @@
@import "main/partials/tool-bar";
@import "main/partials/user-settings";
@import "main/partials/workspace";
@import "main/partials/comments";
@import "main/partials/color-bullet";
@import "main/partials/inspect";
@import "main/partials/exception-page";
@import "main/partials/share-link";
@import "main/partials/signup-questions";

View file

@ -1,467 +0,0 @@
.comments-section {
.thread-bubble {
position: absolute;
display: flex;
transform: translate(-15px, -15px);
cursor: pointer;
pointer-events: auto;
background-color: $color-gray-10;
color: $color-gray-60;
border: 1px solid #b1b2b5;
box-sizing: border-box;
box-shadow: 0px 4px 4px rgba($color-black, 0.25);
font-size: $fs12;
width: 30px;
height: 30px;
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
&.resolved {
color: $color-gray-10;
background-color: $color-gray-50;
}
&.unread {
background-color: $color-primary;
}
span {
user-select: none;
}
}
.thread-content {
position: absolute;
pointer-events: auto;
margin-left: 10px;
background: $color-white;
border: 1px solid $color-gray-20;
box-sizing: border-box;
box-shadow: 0px 2px 8px rgba($color-black, 0.25);
border-radius: $br2;
min-width: 280px;
max-width: 280px;
user-select: text;
.comments {
max-height: 420px;
min-height: 105px;
overflow-y: auto;
}
hr {
border: 0;
height: 1px;
background-color: $color-gray-20;
margin: 0px 10px;
}
}
.reply-form {
display: flex;
padding: 10px;
flex-direction: column;
&.edit-form {
padding-bottom: 0px;
}
textarea {
font-family: "worksans", sans-serif;
font-size: $fs12;
min-height: 32px;
outline: none;
overflow: hidden;
padding: $size-2;
resize: none;
width: 100%;
border-radius: $br2;
border: 1px solid $color-gray-20;
max-height: 4rem;
}
.buttons {
margin-top: 10px;
display: flex;
justify-content: flex-end;
input {
margin: 0px;
font-size: $fs14;
&:not(:last-child) {
margin-right: 6px;
}
}
}
}
.comment-container {
position: relative;
}
.comment {
display: flex;
flex-direction: column;
padding: $size-4 $size-2;
.author {
display: flex;
align-items: center;
height: 26px;
max-height: 26px;
position: relative;
.name {
display: flex;
flex-direction: column;
.fullname {
font-weight: $fw700;
color: $color-gray-60;
font-size: $fs12;
@include text-ellipsis;
width: 174px;
}
.timeago {
margin-top: -2px;
font-size: $fs12;
color: $color-gray-30;
}
}
.avatar {
display: flex;
align-items: center;
padding-right: 6px;
img {
border-radius: 50%;
flex-shrink: 0;
height: 24px;
width: 24px;
}
}
.options-resolve {
position: absolute;
right: 20px;
top: 0px;
width: 16px;
height: 16px;
cursor: pointer;
svg {
width: 16px;
height: 16px;
fill: $color-gray-30;
}
}
.options {
position: absolute;
right: -2px;
top: 2px;
height: 16px;
display: flex;
align-items: center;
cursor: pointer;
.options-icon {
svg {
width: 14px;
height: 14px;
fill: $color-black;
}
}
}
}
.content {
margin: $size-4 0;
font-size: $fs14;
color: $color-black;
.text {
margin: 0 $size-2 0 26px;
white-space: pre-wrap;
display: inline-block;
word-break: break-word;
}
}
}
.comment-options-dropdown {
top: 7px;
right: 7px;
width: 150px;
border: 1px solid #b1b2b5;
}
}
.workspace-comment-threads-sidebar-header {
display: flex;
background-color: $color-black;
height: 34px;
align-items: center;
padding: 0px 9px;
color: $color-gray-10;
font-size: $fs12;
justify-content: space-between;
.options {
display: flex;
margin-right: 3px;
cursor: pointer;
.label {
padding-right: 8px;
}
.icon {
display: flex;
align-items: center;
}
svg {
fill: $color-gray-10;
width: 10px;
height: 10px;
}
}
.dropdown {
top: 80px;
right: 7px;
}
}
.comment-threads-section {
pointer-events: auto;
.thread-groups {
height: calc(100% - 34px);
overflow-y: scroll;
hr {
border: 0;
height: 1px;
background-color: $color-gray-30;
margin: 0px 0px;
}
}
.thread-group {
display: flex;
flex-direction: column;
font-size: $fs12;
.section-title {
margin: 0px 10px;
margin-top: 15px;
.icon {
margin-right: 4px;
}
.label {
&.filename {
font-weight: $fw700;
}
}
svg {
fill: $color-gray-10;
height: 10px;
width: 10px;
}
}
}
.thread-bubble {
position: unset;
transform: unset;
width: 24px;
height: 24px;
margin-right: 6px;
box-shadow: unset;
}
.comment {
cursor: pointer;
.author {
margin-bottom: $size-4;
.name {
display: flex;
.fullname {
width: unset;
max-width: 170px;
color: $color-gray-20;
padding-right: 3px;
}
.timeago {
margin-top: unset;
color: $color-gray-20;
}
}
}
.content {
margin-top: 0px;
color: $color-white;
&.replies {
margin: 0 $size-2 0 26px;
display: flex;
.total-replies {
margin-right: 9px;
color: $color-info;
}
.new-replies {
color: $color-primary;
}
}
}
}
}
.viewer-comments-container {
width: 100%;
height: 100%;
z-index: 1;
position: absolute;
top: 0px;
left: 0px;
}
.workspace-comments-container {
width: 100%;
height: 100%;
grid-column: 1 / span 2;
grid-row: 1 / span 2;
z-index: 1000;
pointer-events: none;
overflow: hidden;
user-select: text;
.threads {
position: absolute;
top: 0px;
left: 0px;
}
}
.dashboard-comments-section {
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
background-color: $color-dashboard;
border-radius: $br3;
position: relative;
.button {
width: 25px;
height: 25px;
display: flex;
align-items: center;
justify-content: center;
background-color: $color-dashboard;
border-radius: $br3;
svg {
width: 15px;
height: 15px;
}
&.unread {
background-color: $color-warning;
}
&.open {
background-color: $color-black;
svg {
fill: $color-primary;
}
}
}
.dropdown {
width: 280px;
bottom: 35px;
left: 0px;
border-radius: $br3;
}
.header {
display: flex;
height: 40px;
align-items: center;
padding: 0px 11px;
h3 {
font-weight: $fw400;
color: $color-black;
font-size: $fs14;
line-height: $lh-128; // Original value was $fs18 => 1.125rem = 18px; 18px/14px = 128.571428571% => $lh-128 (rounded)
flex-grow: 1;
}
.close {
display: flex;
align-items: center;
}
svg {
width: 15px;
height: 15px;
transform: rotate(45deg);
}
}
.thread-groups {
max-height: calc(30rem - 40px);
overflow: auto;
hr {
background-color: $color-gray-10;
}
}
.thread-group .section-title {
color: $color-black;
}
.comment {
.author .name .fullname {
color: $color-gray-40;
}
.content {
color: $color-black;
}
}
}
.thread-groups-placeholder {
align-items: center;
display: flex;
flex-direction: column;
font-size: $fs12;
padding: $size-5;
text-align: center;
svg {
fill: $color-gray-20;
height: 24px;
margin-bottom: $size-5;
width: 24px;
}
}

View file

@ -1,254 +0,0 @@
.dashboard-fonts {
display: flex;
flex-direction: column;
align-items: center;
.dashboard-installed-fonts {
max-width: 1000px;
width: 100%;
display: flex;
margin-top: $size-5;
flex-direction: column;
h3 {
font-size: $fs14;
color: $color-gray-30;
margin: $size-1;
}
.font-item {
color: $color-black;
}
}
.installed-fonts-header {
color: $color-gray-40;
display: flex;
height: 40px;
font-size: $fs12;
background-color: $color-white;
align-items: center;
padding: 0px $size-5;
> .family {
min-width: 200px;
width: 200px;
}
> .variants {
padding-left: 12px;
}
.search-input {
display: flex;
flex-grow: 1;
justify-content: flex-end;
input {
font-size: $fs12;
border: 1px solid $color-gray-30;
border-radius: $br3;
width: 130px;
padding: $size-1;
margin: 0px;
}
}
}
.font-item {
color: $color-gray-40;
font-size: $fs14;
background-color: $color-white;
display: flex;
max-width: 1000px;
width: 100%;
min-height: 97px;
align-items: center;
padding: $size-5;
justify-content: space-between;
&:not(:first-child) {
border-top: 1px solid $color-gray-10;
}
input {
border: 1px solid $color-gray-30;
border-radius: $br3;
margin: 0px;
padding: $size-2;
font-size: $fs12;
}
> .family {
min-width: 200px;
width: 200px;
}
> .filenames {
min-width: 200px;
}
> .variants {
font-size: $fs14;
display: flex;
flex-wrap: wrap;
flex-grow: 1;
.variant {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 12px;
cursor: pointer;
.icon {
display: flex;
height: 16px;
width: 16px;
margin-left: 6px;
align-items: center;
svg {
fill: transparent;
width: 12px;
height: 12px;
transform: rotate(45deg);
}
}
&:hover {
.icon svg {
fill: $color-gray-30;
}
}
}
}
.filenames {
display: flex;
flex-direction: column;
font-size: $fs12;
}
.options {
display: flex;
justify-content: flex-end;
min-width: 180px;
.icon {
width: $size-5;
cursor: pointer;
display: flex;
margin-left: 10px;
justify-content: center;
align-items: center;
&.failure {
margin-right: 10px;
svg {
fill: $color-warning;
}
}
svg {
width: 16px;
height: 16px;
}
&.close {
svg {
transform: rotate(45deg);
}
}
}
}
}
.dashboard-fonts-upload {
max-width: 1000px;
width: 100%;
display: flex;
flex-direction: column;
.upload-button {
width: 100px;
}
.btn-secondary {
margin-left: 10px;
}
}
.dashboard-fonts-hero {
font-size: $fs14;
padding: $size-6;
background-color: $color-white;
margin-top: $size-6;
display: flex;
justify-content: space-between;
.banner {
background-color: $color-info-lighter;
display: grid;
grid-template-columns: 40px 1fr;
&:not(:last-child) {
margin-bottom: 10px;
}
.icon {
display: flex;
align-items: flex-start;
justify-content: center;
padding-top: 10px;
background-color: $color-info;
svg {
fill: $color-white;
}
}
.content {
margin: 10px;
}
&.warning {
background-color: $color-warning-lighter;
.icon {
background-color: $color-warning;
}
}
}
.desc {
h2 {
margin-bottom: $size-4;
color: $color-black;
}
width: 80%;
color: $color-gray-40;
}
.btn-primary {
flex-shrink: 0;
}
}
.fonts-placeholder {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
max-width: 1000px;
width: 100%;
height: 161px;
border: 1px dashed $color-gray-20;
margin-top: 16px;
.icon {
svg {
fill: $color-gray-40;
width: 32px;
height: 32px;
}
}
.label {
color: $color-gray-40;
font-size: $fs14;
}
}
}

View file

@ -1,527 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
.dashboard-grid {
font-size: $fs14;
height: 100%;
overflow: hidden;
overflow-y: auto;
margin-bottom: 0;
.grid-row {
display: grid;
width: 99%;
margin-left: 13px;
}
.grid-item {
align-items: center;
cursor: pointer;
display: flex;
flex-direction: column;
flex: 1 0 260px;
height: 230px;
margin: $size-3 $size-4 $size-4 $size-2;
position: relative;
text-align: center;
a,
button {
width: 100%;
font-weight: $fw400;
}
button {
background-color: transparent;
border: none;
}
@media #{$bp-max-1366} {
height: 200px;
flex: 1 0 230px;
}
&:hover {
.grid-item-th {
border: 2px solid $color-primary;
}
}
.grid-item-th {
border-radius: $br3;
border: 2px solid lighten($color-gray-20, 15%);
text-align: initial;
img {
object-fit: contain;
}
}
&.dragged {
border-radius: $br3;
border: 2px solid lighten($color-gray-20, 15%);
text-align: initial;
max-height: 160px;
}
&.placeholder {
min-width: 115px;
max-width: 115px;
display: flex;
flex-direction: column;
justify-content: center;
.placeholder-icon {
svg {
transform: rotate(-90deg);
width: 20px;
height: 20px;
fill: $color-gray-30;
}
}
.placeholder-label {
font-size: $fs14;
}
}
&.overlay {
border-radius: $br4;
border: 2px solid $color-primary;
height: 100%;
opacity: 0;
pointer-events: none;
position: absolute;
width: 100%;
z-index: 1;
}
&:hover .overlay {
display: block;
opacity: 1;
}
&.small-item {
max-width: 12%;
min-width: 190px;
padding: $size-4;
justify-content: center;
}
.grid-item-icon {
width: 90px;
height: 90px;
}
.info-wrapper {
display: grid;
grid-template-columns: 1fr auto;
}
.item-info {
display: grid;
padding: $size-2;
text-align: left;
width: 100%;
font-size: $fs12;
h3 {
border: 1px solid transparent;
color: $color-gray-60;
font-size: $fs14;
font-weight: $fw500;
overflow: hidden;
padding: 0;
height: 27px;
padding-right: $size-2;
text-overflow: ellipsis;
width: 100%;
white-space: nowrap;
line-height: $lh-192; // Original value was 27px; 27px/14px = 192.857142857% => $lh-192 (rounded)
max-width: 260px;
@media #{$bp-max-1366} {
max-width: 230px;
}
}
span.date {
color: $color-gray-30;
overflow: hidden;
text-overflow: ellipsis;
width: 100%;
white-space: nowrap;
max-width: 260px;
&::first-letter {
text-transform: capitalize;
}
@media #{$bp-max-1366} {
max-width: 230px;
}
}
.edit-wrapper {
.element-title {
padding: 0px;
height: 25px;
color: $color-gray-60;
font-size: $fs14;
font-weight: $fw400;
}
}
}
.item-badge {
background-color: $color-white;
border: 1px solid $color-gray-20;
border-radius: $br2;
position: absolute;
top: $size-2;
right: $size-2;
height: 32px;
width: 32px;
display: flex;
align-items: center;
justify-content: center;
svg {
fill: $color-gray-30;
height: 16px;
width: 16px;
}
}
&.add-file {
border: 1px dashed $color-gray-20;
justify-content: center;
box-shadow: none;
span {
color: $color-gray-60;
font-size: $fs14;
}
&:hover {
background-color: $color-white;
border: 2px solid $color-primary;
}
}
// PROJECTS, ELEMENTS & ICONS GRID
&.project-th {
background-color: $color-white;
&:hover,
&:focus,
&:focus-within {
.project-th-actions {
opacity: 1;
}
a {
text-decoration: none;
}
}
.selected {
.grid-item-th {
border: 2px solid $color-primary;
}
}
.project-th-actions {
align-items: center;
opacity: 0;
display: flex;
right: 5px;
justify-content: center;
width: 30px;
height: 100%;
span {
color: $color-black;
}
.project-th-icon {
align-items: center;
display: flex;
margin-right: $size-2;
&.menu {
margin-right: 0;
display: flex;
justify-content: center;
align-items: flex-end;
flex-direction: column;
width: 100%;
height: 30px;
margin-top: 20px;
> svg {
fill: $color-gray-60;
margin-right: 0;
height: 18px;
width: 18px;
}
&:hover,
&:focus {
> svg {
fill: $color-primary-dark;
}
}
}
}
}
.project-th-actions.force-display {
opacity: 1;
}
}
// IMAGES SECTION
&.images-th {
border: 1px dashed $color-gray-20;
border-bottom: 2px solid lighten($color-gray-20, 12%);
&:hover {
border-color: $color-primary;
}
}
.grid-item-image {
svg {
max-height: 100px;
max-width: 100px;
min-height: 40px;
min-width: 40px;
width: 8vw;
}
}
.color-swatch {
border-top-left-radius: $br5;
border-top-right-radius: $br5;
height: 25%;
left: 0;
position: absolute;
top: 0;
width: 100%;
}
.color-data {
color: $color-gray-30;
margin-top: 15px;
}
.drag-counter {
position: absolute;
top: 5px;
left: 4px;
width: 32px;
height: 32px;
background-color: $color-primary;
border-radius: 50%;
color: $color-black;
font-size: $fs18;
display: flex;
justify-content: center;
align-items: center;
}
}
.grid-item-th {
background-position: center;
background-size: auto 80%;
background-repeat: no-repeat;
border-top-left-radius: $br3;
border-top-right-radius: $br3;
height: 230px;
max-height: 160px;
overflow: hidden;
position: relative;
width: 100%;
background-color: $color-canvas;
display: flex;
justify-content: center;
flex-direction: row;
.img-th {
height: auto;
width: 100%;
}
svg {
height: 100%;
width: 100%;
}
svg#loader-pencil {
fill: $color-gray-20;
}
}
// LIBRARY VIEW
.grid-item {
.library {
height: 580px;
}
&.project-th.library {
height: 610px;
width: 300px;
}
.grid-item-th.library {
background-color: $color-gray-50;
flex-direction: column;
height: 90%;
justify-content: flex-start;
max-height: 550px;
padding: $size-6;
.asset-section {
font-size: $fs12;
color: $color-gray-20;
&:not(:first-child) {
margin-top: $size-4;
}
}
.asset-title {
display: flex;
font-size: $fs12;
text-transform: uppercase;
& .num-assets {
color: $color-gray-30;
}
}
.asset-list-item {
display: flex;
align-items: center;
border: 1px solid transparent;
border-radius: $br3;
margin-top: $size-1;
padding: 2px;
font-size: $fs12;
color: $color-white;
position: relative;
& .name-block {
color: $color-gray-20;
width: calc(100% - 24px - #{$size-2});
}
& .item-name {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: block;
}
& svg {
background-color: $color-canvas;
border-radius: $br4;
border: 2px solid transparent;
height: 24px;
width: 24px;
margin-right: $size-2;
}
& .color-name {
color: $color-white;
}
& .color-value {
margin-left: $size-1;
color: $color-gray-30;
text-transform: uppercase;
}
& .typography-sample {
height: 20px;
margin-right: $size-1;
width: 20px;
}
}
}
}
}
.grid-empty-placeholder {
border-radius: $br12;
display: grid;
background-color: rgba(227, 227, 227, 0.3);
padding: 13px;
margin-right: 13px;
height: 230px;
&.loader {
justify-items: center;
}
.icon {
display: flex;
align-items: center;
justify-content: center;
}
&.libs {
background-image: url(/images/ph-left.svg), url(/images/ph-right.svg);
background-position:
15% bottom,
85% top;
background-repeat: no-repeat;
align-items: center;
border: 1px dashed #b1b2b5;
border-radius: $br3;
display: flex;
flex-direction: column;
height: 200px;
margin: 1rem;
padding: 3rem;
justify-content: center;
.text {
p {
max-width: 360px;
text-align: center;
font-size: $fs16;
}
}
}
.create-new {
background-color: white;
border: 2px solid $color-gray-10;
border-radius: $br3;
color: $color-black;
cursor: pointer;
height: 158px;
font-family: "worksans", sans-serif;
margin: 0.5rem;
&:hover {
border: 2px solid $color-primary;
}
}
&.search {
align-items: center;
display: flex;
justify-content: center;
flex-direction: column;
height: 200px;
background: $color-white;
border: 1px dashed #e3e3e3;
border-radius: $br0;
}
svg {
width: 36px;
height: 36px;
fill: $color-gray-20;
}
.text {
margin-top: 10px;
color: $color-gray-30;
font-size: $fs16;
}
}

View file

@ -1,139 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
.dashboard-header {
display: flex;
align-items: center;
justify-content: space-between;
background-color: $color-white;
height: 63px;
padding: $size-1 $size-4 $size-1 $size-2;
position: relative;
z-index: 10;
user-select: none;
&.team {
display: grid;
grid-template-columns: 20% 1fr 20%;
}
.element-name {
margin-right: $size-2;
}
.btn-secondary {
flex-shrink: 0;
z-index: 10;
height: 32px;
}
svg {
fill: $color-black;
height: 14px;
margin-right: $size-1;
width: 14px;
}
nav {
display: flex;
align-items: flex-end;
justify-content: center;
z-index: 1;
ul {
display: flex;
font-size: $fs14;
justify-content: center;
margin: 0;
}
li {
a {
display: flex;
align-items: center;
flex-basis: 140px;
border-bottom: 3px solid transparent;
color: $color-gray-30;
height: 40px;
padding: $size-1 $size-5;
font-weight: $fw400;
&:hover {
color: $color-black;
text-decoration: none;
}
}
&.active {
a {
color: $color-black;
border-color: $color-primary;
}
}
}
}
.dashboard-title {
display: flex;
align-items: center;
margin-left: 13px;
h1 {
color: $color-black;
display: flex;
flex-shrink: 0;
font-size: $fs22;
font-weight: $fw600;
z-index: 10;
user-select: all;
}
.context-menu.is-open {
margin-top: 10px;
}
}
.icon {
display: flex;
align-items: center;
cursor: pointer;
margin-left: $size-2;
z-index: 10;
svg {
fill: $color-gray-40;
width: 15px;
height: 15px;
&:hover {
fill: $color-primary-dark;
}
}
}
.dashboard-buttons {
display: flex;
justify-content: flex-end;
align-items: center;
}
.dashboard-header-actions {
display: flex;
}
.pin-icon {
margin: 0 $size-2 0 $size-5;
background-color: transparent;
border: none;
svg {
fill: $color-gray-20;
}
&.active {
svg {
fill: $color-gray-50;
}
}
}
}

View file

@ -1,303 +0,0 @@
// Copyright (c) 2020 KALEIDOS INC
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
.dashboard-sidebar {
&.settings {
.back-to-dashboard {
padding: 12px 18px;
font-size: $fs14;
cursor: pointer;
display: flex;
.icon {
display: flex;
align-items: center;
margin-right: 14px;
}
.text {
color: $color-gray-60;
}
svg {
fill: $color-gray-60;
transform: rotate(90deg);
width: 12px;
height: 12px;
}
}
}
}
.dashboard-settings {
display: flex;
width: 100%;
justify-content: center;
align-items: center;
.form-container {
margin-top: 50px;
display: flex;
max-width: 368px;
margin-bottom: 2rem;
width: 100%;
&.two-columns {
max-width: 536px;
justify-content: space-between;
flex-direction: row;
}
h2 {
margin-bottom: 1rem;
}
}
.avatar-form {
display: flex;
flex-direction: column;
width: 120px;
min-width: 120px;
img {
border-radius: 50%;
flex-shrink: 0;
height: 120px;
margin-right: $size-4;
width: 120px;
}
.image-change-field {
position: relative;
width: 120px;
height: 120px;
.update-overlay {
opacity: 0;
cursor: pointer;
position: absolute;
width: 121px;
height: 121px;
border-radius: 50%;
font-size: $fs24;
color: $color-white;
line-height: $lh-500; // Original value was 120px; 120px/24px = 500% => $lh-500
text-align: center;
background: $color-primary-dark;
z-index: 14;
}
input[type="file"] {
width: 120px;
height: 120px;
position: absolute;
opacity: 0;
cursor: pointer;
top: 0;
z-index: 15;
}
&:hover {
.update-overlay {
opacity: 0.8;
}
}
}
}
.profile-form {
display: flex;
flex-direction: column;
max-width: 368px;
width: 100%;
.newsletter-subs {
border-bottom: 1px solid $color-gray-20;
border-top: 1px solid $color-gray-20;
padding: 30px 0;
margin-bottom: 31px;
.newsletter-title {
font-family: "worksans", sans-serif;
color: $color-gray-30;
font-size: $fs14;
}
label {
font-family: "worksans", sans-serif;
color: $color-gray-60;
font-size: $fs12;
margin-right: -17px;
margin-bottom: 13px;
}
.info {
font-family: "worksans", sans-serif;
color: $color-gray-30;
font-size: $fs12;
margin-bottom: 8px;
}
.input-checkbox label {
align-items: flex-start;
}
}
}
.options-form,
.password-form {
h2 {
font-size: $fs14;
margin-bottom: 20px;
}
}
}
.dashboard-access-tokens {
display: flex;
flex-direction: column;
align-items: center;
.access-tokens-hero-container {
max-width: 1000px;
width: 100%;
display: flex;
flex-direction: column;
}
.access-tokens-hero {
font-size: $fs14;
padding: $size-6;
background-color: $color-white;
margin-top: $size-6;
display: flex;
justify-content: space-between;
.desc {
width: 80%;
color: $color-gray-40;
h2 {
margin-bottom: $size-4;
color: $color-black;
}
p {
font-size: $fs16;
}
}
.btn-primary {
flex-shrink: 0;
}
}
.access-tokens-empty {
text-align: center;
max-width: 1000px;
width: 100%;
padding: $size-6;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1px dashed $color-gray-20;
color: $color-gray-40;
margin-top: 12px;
min-height: 136px;
}
.table-row {
background-color: $color-white;
display: grid;
grid-template-columns: 1fr 43% 12px;
height: 63px;
&:not(:first-child) {
margin-top: 8px;
}
}
.table-field {
&.name {
color: $color-gray-60;
}
&.expiration-date {
color: $color-gray-40;
font-size: $fs14;
.content {
padding: 2px 5px;
&.expired {
background-color: $color-warning-lighter;
border-radius: $br4;
color: $color-gray-40;
}
}
}
&.access-token-created {
word-break: break-all;
}
&.actions {
position: relative;
}
}
}
.access-tokens-modal {
.action-buttons {
gap: 10px;
.cancel-button {
border: 1px solid $color-gray-30;
background: $color-canvas;
border-radius: $br3;
padding: 0.5rem 1rem;
cursor: pointer;
margin-right: 8px;
&:hover {
background: $color-gray-20;
}
}
}
.access-token-created {
position: relative;
word-break: break-all;
.custom-input input {
background-color: $color-success-lighter;
border: 0;
padding: 0 0 0 15px;
}
}
.help-icon {
border: none;
height: 40px;
width: 40px;
position: absolute;
top: 0;
right: 0;
cursor: pointer;
background-color: $color-success-lighter;
svg {
fill: $color-gray-30;
}
&:hover {
svg {
fill: $color-gray-60;
}
}
}
.token-created-info {
font-size: $fs12;
color: $color-gray-40;
}
}

View file

@ -1,476 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
.dashboard-sidebar {
background-color: $color-white;
z-index: 1;
display: flex;
flex-direction: column;
height: 100%;
padding-top: $size-2;
.sidebar-content {
display: flex;
flex-direction: column;
height: 100%;
overflow-y: auto;
padding: 0;
hr {
border-color: $color-gray-10;
margin: 1rem 15px;
}
}
.sidebar-team-switch {
position: relative;
display: flex;
margin: 5px 15px;
.teams-dropdown {
left: 0;
top: 50px;
z-index: 12;
max-height: 30rem;
min-width: 234px;
overflow-y: auto;
}
.options-dropdown {
right: 2px;
top: 50px;
z-index: 12;
max-height: 30rem;
min-width: 162px;
}
.switch-content {
height: 40px;
display: flex;
width: 100%;
border: 1px solid $color-gray-10;
border-radius: $br5;
align-items: center;
}
.switch-options {
display: flex;
max-width: 22px;
min-width: 28px;
border-left: 1px solid $color-gray-10;
justify-content: center;
align-items: center;
cursor: pointer;
background-color: transparent;
border: none;
svg {
width: 15px;
height: 13px;
fill: $color-gray-60;
}
}
.current-team {
cursor: pointer;
display: flex;
align-items: center;
flex-grow: 1;
font-size: $fs14;
padding: 0px 10px;
background-color: transparent;
border: none;
}
.team-name {
flex-grow: 1;
display: flex;
height: 40px;
align-items: center;
&.action {
.team-icon {
border-radius: 50%;
background-color: $color-gray-10;
height: 24px;
margin-right: 10px;
padding: 6px;
width: 24px;
svg {
height: 12px;
width: 12px;
}
}
&:hover {
.team-icon {
background-color: $color-primary;
}
}
.team-text {
width: 150px;
}
}
.team-icon {
display: flex;
align-items: center;
padding-right: 10px;
svg {
width: 23px;
height: 23px;
fill: $color-gray-60;
}
img {
border-radius: 50%;
flex-shrink: 0;
height: 23px;
width: 23px;
}
}
.team-text {
color: $color-gray-60;
@include text-ellipsis;
width: 130px;
text-align: left;
}
.icon {
margin-left: auto;
svg {
fill: $color-gray-60;
}
}
}
.switch-icon {
display: flex;
align-items: center;
justify-content: center;
svg {
width: 10px;
height: 10px;
fill: $color-gray-60;
}
}
}
.sidebar-empty-placeholder {
padding: 10px 12px;
color: $color-gray-30;
display: flex;
align-items: flex-start;
.icon {
padding: 0px 10px;
svg {
fill: $color-gray-30;
width: 12px;
height: 12px;
}
}
.text {
font-size: $fs12;
}
}
.sidebar-nav {
display: flex;
flex-direction: column;
overflow-y: auto;
margin: 0;
user-select: none;
// TODO: should be deprecated / unclear name
&.dashboard-common {
overflow: unset;
}
&.no-overflow {
overflow: unset;
}
& > li {
align-items: center;
cursor: pointer;
display: flex;
flex-shrink: 0;
padding: $size-2;
a {
font-weight: $fw400;
width: 100%;
&:hover {
text-decoration: none;
}
}
svg {
fill: $color-black;
margin-right: 8px;
height: $size-3;
width: $size-3;
}
span.element-title {
color: $color-gray-60;
font-size: $fs14;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
&::before {
background-color: transparent;
border-radius: $br3;
content: "";
height: 26px;
margin-right: $size-2;
width: 4px;
}
&.recent-projects {
svg {
fill: $color-white;
}
}
& .edit-wrapper {
border: 1px solid $color-gray-10;
border-radius: $br3;
display: flex;
width: 100%;
}
input.element-title {
border: 0;
height: 30px;
padding: 5px;
margin: 0;
width: 100%;
background-color: $color-white;
}
.close {
background-color: $color-white;
cursor: pointer;
padding-left: 5px;
svg {
fill: $color-gray-30;
height: 15px;
transform: rotate(45deg) translateY(7px);
width: 15px;
margin: 0;
}
}
.element-subtitle {
color: $color-gray-20;
font-style: italic;
}
&:hover {
&::before {
background-color: $color-gray-10;
}
}
&.current {
a {
font-weight: $fw700;
}
&::before {
background-color: $color-primary;
}
}
&.dragging {
background-color: color.adjust($color-primary, $alpha: -0.69);
}
}
}
.sidebar-search {
align-items: center;
background-color: $color-white;
border: 1px solid $color-gray-10;
border-radius: $br5;
display: flex;
margin: 5px 15px;
.input-text {
background: transparent;
border: 0;
color: $color-gray-60;
font-size: $fs14;
padding: 6px;
margin: 0;
max-width: 195px;
width: 100%;
height: 40px;
}
&:focus,
&:focus-within {
border-color: $color-black;
}
.search,
.clear-search {
align-items: center;
cursor: pointer;
display: flex;
height: 22px;
margin-left: auto;
padding: 0 $size-2;
width: 32px;
svg {
fill: $color-gray-30;
height: 15px;
width: 15px;
}
}
.clear-search svg {
transform: rotate(45deg);
&:hover {
fill: $color-danger;
}
}
}
&.profile-bar {
background-color: $color-gray-10;
.dashboard-sidebar-inside {
display: none;
}
}
}
.projects-row {
align-items: center;
display: flex;
margin-top: 1rem;
padding: $size-2;
position: relative;
span {
color: $color-gray-30;
font-size: $fs14;
}
.btn-icon-light {
margin-left: auto;
}
&::before {
background-color: $color-gray-10;
content: "";
height: 1px;
left: 4%;
position: absolute;
right: 4%;
top: -5px;
width: 92%;
}
}
.team-form-modal {
h2 {
font-weight: $fw400;
color: $color-gray-40;
font-size: 28px;
margin-bottom: 30px;
}
.buttons-row {
margin-top: 20px;
display: flex;
justify-content: center;
}
input[type="submit"] {
margin-bottom: 0px;
}
}
.profile-section {
align-items: center;
cursor: pointer;
display: flex;
padding: 10px 15px;
position: relative;
.profile {
align-items: center;
cursor: pointer;
display: flex;
flex-grow: 1;
span {
@include text-ellipsis;
color: $color-black;
margin: 10px;
font-size: $fs14;
max-width: 160px;
}
img {
border-radius: 50%;
flex-shrink: 0;
height: 25px;
width: 25px;
}
svg {
height: 10px;
margin-left: auto;
margin-right: $size-2;
width: 10px;
}
}
.dropdown {
left: 15px;
bottom: 45px;
min-width: 189px;
@include animation(0, 0.2s, fadeInUp);
li {
font-size: $fs14;
padding: $size-2 $size-4;
svg {
fill: $color-gray-20;
margin-right: $size-2;
height: 12px;
width: 12px;
}
&.separator {
border-top: 1px solid $color-gray-10;
}
}
}
}
.primary-badge {
border: 1px solid $color-primary;
border-radius: $br2;
font-size: $fs9 !important;
font-weight: $fw500;
color: $color-primary !important;
padding: 2px 4px;
}

View file

@ -1,605 +0,0 @@
.dashboard-invite-modal {
top: 72px;
right: 13px;
padding: 32px;
box-shadow: 0px 4px 8px rgba($color-black, 0.25);
border-radius: $br8;
width: 400px;
position: fixed;
z-index: 16;
&.hero {
top: 218px;
right: 35px;
}
form {
width: 100%;
}
.form-row {
display: flex;
justify-content: space-between;
margin: 4px 0px;
.label {
margin-bottom: 0;
display: flex;
align-items: center;
}
}
.custom-input {
width: 100%;
min-height: 116px;
max-height: 176px;
overflow-y: hidden;
input {
&.no-padding {
padding-top: 12px;
height: 50px;
}
min-height: 40px;
}
.selected-items {
gap: 8px;
padding: 8px;
max-height: 132px;
overflow-y: scroll;
.selected-item {
.around {
height: 24px;
display: flex;
align-items: center;
justify-content: flex-start;
width: fit-content;
.icon {
display: flex;
align-items: center;
justify-content: center;
}
}
}
}
}
.custom-select {
width: 180px;
overflow: hidden;
justify-content: normal;
select {
height: auto;
}
}
.action-buttons {
display: flex;
margin-top: 16px;
input[type="submit"] {
margin-bottom: 0px;
}
}
.title {
color: $color-black;
font-weight: $fw700;
margin-bottom: 16px;
}
.hint {
font-size: $fs12;
&.hidden {
display: none;
}
}
svg {
width: 12px;
height: 12px;
fill: $color-gray-20;
}
.error,
.warning {
width: 100%;
display: flex;
.icon {
text-align: center;
padding: 5px;
svg {
fill: $color-white;
width: 20px;
height: 20px;
margin: 5px;
}
}
.text {
color: $color-black;
padding: 5px;
font-size: $fs12;
}
}
.error {
background-color: #ffd9e0;
.icon {
background-color: $color-danger;
}
}
.warning {
background-color: #ffeaca;
.icon {
background-color: $color-warning;
}
}
}
.dashboard-team-members,
.dashboard-team-invitations,
.dashboard-team-webhooks {
.empty-invitations {
height: 156px;
max-width: 1040px;
width: 100%;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
border: 1px dashed $color-gray-20;
margin-top: 16px;
}
.table-header {
user-select: none;
}
.table-row {
background-color: $color-white;
height: 63px;
&:not(:first-child) {
margin-top: 16px;
}
}
.table-field {
&.name {
width: 43%;
min-width: 300px;
display: flex;
.member-info {
display: flex;
flex-direction: column;
margin-left: 16px;
.member-name {
font-size: $fs16;
.you {
color: $color-gray-30;
margin-left: 5px;
}
}
.member-email {
color: $color-gray-30;
font-size: $fs12;
}
}
.member-image {
height: 32px;
width: 32px;
img {
border-radius: 50%;
}
}
}
&.roles {
flex-grow: 1;
cursor: default;
position: relative;
.rol-label {
user-select: none;
}
.rol-selector {
&.has-priv {
border: 1px solid $color-gray-20;
cursor: pointer;
}
min-width: 160px;
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
border-radius: $br2;
padding: 3px 8px;
font-size: $fs14;
}
}
&.actions {
position: relative;
.actions-dropdown {
max-height: 30rem;
min-width: 180px;
}
}
&.status {
.status-badge {
color: $color-white;
border-radius: $br12;
min-width: 74px;
height: 24px;
display: flex;
justify-content: center;
align-items: center;
&.pending {
background-color: $color-warning;
}
&.expired {
background-color: $color-gray-20;
}
.status-label {
font-size: $fs12;
}
}
}
&.uri {
flex-grow: 1;
}
&.active {
min-width: 100px;
}
&.last-delivery {
display: flex;
justify-content: center;
width: 50px;
position: relative;
.success svg {
fill: $color-primary;
width: 16px;
height: 16px;
}
.failure svg {
fill: $color-warning;
width: 16px;
height: 16px;
}
.icon-container {
width: 16px;
height: 16px;
overflow-x: visible;
}
.icon {
padding: 0;
}
}
.tooltip {
display: none;
position: absolute;
top: -58px;
left: 50%;
transform: translate(-50%, 0);
text-align: center;
.label {
border-radius: $br3;
color: $color-white;
background-color: $color-black;
white-space: nowrap;
padding: 12px 20px;
}
.arrow-down {
margin: 0 auto;
width: 0;
height: 0;
border-left: 8px solid transparent;
border-right: 8px solid transparent;
border-top: 8px solid $color-black;
}
}
.last-delivery-icon:hover {
.tooltip {
display: block;
}
}
}
.dropdown {
position: absolute;
max-height: 30rem;
overflow-y: auto;
background-color: $color-white;
border-radius: $br4;
box-shadow: 0px 2px 8px rgba(0, 0, 0, 0.25);
z-index: 12;
top: 30px;
left: -151px;
width: 155px;
hr {
margin: 0;
border-color: $color-gray-10;
}
li {
display: flex;
align-items: center;
color: $color-gray-60;
cursor: pointer;
font-size: $fs14;
height: 31px;
padding: 5px 16px;
&.title {
font-weight: $fw600;
cursor: default;
}
&:hover {
background-color: $color-primary-lighter;
}
}
}
}
.dashboard-team-settings {
.team-settings {
display: flex;
justify-content: center;
margin-top: 16px;
svg {
width: 20px;
height: 20px;
}
.horizontal-blocks {
display: flex;
max-width: 1010px;
justify-content: space-between;
width: 100%;
}
.block {
display: flex;
max-width: 324px;
width: 324px;
background-color: $color-white;
flex-direction: column;
padding: 12px;
.label {
font-size: $fs13;
color: $color-gray-30;
}
}
.info-block {
position: relative;
.name {
margin-top: 10px;
font-size: $fs24;
color: $color-black;
@include text-ellipsis;
margin-right: 90px;
}
.icon {
position: absolute;
padding: 15px;
width: 100px;
height: 100px;
right: 0px;
top: 0px;
img {
border-radius: 50%;
width: 70px;
height: 70px;
}
.update-overlay {
opacity: 0;
cursor: pointer;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
width: 71px;
height: 71px;
border-radius: 50%;
color: $color-white;
background: $color-primary-dark;
z-index: 14;
svg {
fill: $color-white;
}
}
&:hover {
.update-overlay {
opacity: 1;
width: 72px;
height: 72px;
top: 14px;
left: 14px;
}
}
}
}
.owner-block {
img {
width: 30px;
height: 30px;
border-radius: 50%;
}
svg {
width: 12px;
height: 12px;
fill: $color-black;
}
.owner {
margin-top: 5px;
display: flex;
align-items: center;
color: $color-black;
.icon {
margin-right: 12px;
}
}
.summary {
margin-top: 5px;
color: $color-black;
.icon {
padding: 0px 10px;
margin-right: 12px;
}
}
}
.stats-block {
svg {
fill: $color-black;
}
.projects,
.files {
margin-top: 7px;
display: flex;
align-items: center;
color: $color-black;
.icon {
display: flex;
align-items: center;
padding: 0px 2px;
margin-right: 14px;
}
}
}
}
}
.dashboard-team-webhooks {
display: flex;
flex-direction: column;
align-items: center;
.webhooks-hero-container {
max-width: 1000px;
width: 100%;
display: flex;
flex-direction: column;
.upload-button {
width: 100px;
}
.btn-secondary {
margin-left: 10px;
}
}
.webhooks-hero {
font-size: $fs14;
padding: $size-6;
background-color: $color-white;
margin-top: $size-6;
display: flex;
justify-content: space-between;
.banner {
background-color: unset;
display: flex;
.icon {
display: flex;
align-items: center;
padding-left: 0px;
padding-right: 10px;
svg {
fill: $color-info;
}
}
}
.desc {
h2 {
margin-bottom: $size-4;
color: $color-black;
}
width: 80%;
color: $color-gray-40;
p {
font-size: $fs16;
}
}
.btn-primary {
flex-shrink: 0;
}
}
.webhooks-empty {
text-align: center;
max-width: 1000px;
width: 100%;
padding: $size-6;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
border: 1px dashed $color-gray-20;
color: $color-gray-40;
margin-top: 12px;
min-height: 136px;
}
}
.webhooks-modal {
.action-buttons {
gap: 10px;
.cancel-button {
border: 1px solid $color-gray-30;
background: $color-canvas;
border-radius: $br3;
padding: 0.5rem 1rem;
cursor: pointer;
margin-right: 8px;
&:hover {
background: $color-gray-20;
}
}
}
.input-checkbox label {
font-size: $fs14;
color: $color-black;
}
.explain {
font-size: $fs12;
color: $color-gray-40;
}
}

View file

@ -1,638 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
.team-hero {
display: flex;
position: relative;
border: 2px solid $color-gray-10;
border-radius: $br8;
padding: 20px;
margin: 0 1rem 0 21px;
height: 154px;
.text {
flex-grow: 1;
padding-left: 20px;
.title {
font-size: $fs24;
font-weight: $fw700;
color: $color-black;
}
.info {
span {
color: $color-gray-30;
display: block;
}
padding-top: 10px;
}
}
.close {
position: absolute;
top: 20px;
right: 20px;
background-color: transparent;
border: none;
cursor: pointer;
svg {
transform: rotate(45deg);
width: 16px;
height: 16px;
}
}
.invite {
align-self: flex-end;
height: 40px;
font-family: "worksans", sans-serif;
width: 180px;
}
img {
width: 274px;
margin-bottom: -19px;
@media (max-width: 1200px) {
display: none;
width: 0;
}
}
}
.hero-projects {
display: grid;
grid-template-columns: 1fr 1fr;
grid-gap: 30px;
margin: 0 1rem 1rem 1.2rem;
.tutorial,
.walkthrough {
display: grid;
grid-template-columns: 1fr 1fr;
position: relative;
border: 2px solid $color-gray-10;
border-radius: $br8;
min-height: 211px;
.thumbnail {
border-top-left-radius: $br6;
border-bottom-left-radius: $br6;
padding: 30px;
display: block;
background-color: #e0e4e9;
}
.text {
padding: 30px;
.title {
color: $color-black;
font-size: $fs24;
font-weight: $fw700;
margin-bottom: 8px;
}
.info {
color: $color-gray-50;
margin-bottom: 20px;
font-size: $fs14;
}
}
.action {
font-family: "worksans", sans-serif;
width: 180px;
height: 40px;
}
.close {
position: absolute;
top: 0;
right: 0;
width: $size-5;
cursor: pointer;
display: flex;
margin: 20px;
justify-content: center;
align-items: center;
background-color: transparent;
border: none;
.icon {
svg {
fill: $color-gray-30;
height: 16px;
width: 16px;
transform: rotate(45deg);
&:hover {
fill: $color-primary;
}
}
}
}
@media (max-width: 1846px) {
grid-template-columns: 190px 1fr;
}
@media (max-width: 1526px) {
grid-template-columns: 1fr;
.img {
display: none;
width: 0;
}
}
}
.walkthrough {
.thumbnail {
background-image: url("/images/walkthrough-cover.png");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
}
.tutorial {
.thumbnail {
background-image: url("/images/hands-on-tutorial.png");
background-position: center;
background-repeat: no-repeat;
background-size: cover;
}
.loader {
display: flex;
svg#loader-pencil {
width: 31px;
}
}
}
}
.dashboard-container {
background-color: $color-dashboard;
flex: 1 0 0;
margin-right: $size-4;
overflow-y: auto;
width: 100%;
&.dashboard-projects {
user-select: none;
}
&.no-bg {
background-color: transparent;
}
&.dashboard-shared {
width: calc(100vw - 320px);
margin-right: 50px;
}
&.search {
margin-top: 10px;
}
}
.dashboard-project-row {
margin-bottom: $size-5;
position: relative;
.project {
align-items: center;
background: $color-white;
border-radius: $br3;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
margin-top: $size-4;
padding: $size-2 $size-2 $size-2 $size-4;
width: 99%;
max-height: 40px;
gap: $size-2;
.project-name-wrapper {
display: flex;
align-items: center;
justify-content: flex-start;
min-height: 32px;
margin-left: $size-2;
}
.show-more {
align-items: center;
color: $color-gray-30;
display: flex;
font-size: $fs14;
justify-content: space-between;
cursor: pointer;
background-color: transparent;
border: none;
.placeholder-icon {
transform: rotate(-90deg);
margin-left: 10px;
svg {
height: 14px;
width: 14px;
fill: $color-gray-30;
}
}
&:hover {
color: $color-primary-dark;
svg {
fill: $color-primary-dark;
}
}
}
.btn-secondary {
border: none;
padding: $size-2;
}
h2 {
cursor: pointer;
font-size: $fs18;
line-height: $lh-088; // Original value was 1rem = 16px; 16px/18px = 88.88888% => $lh-088
font-weight: $fw600;
color: $color-black;
margin-right: $size-1;
}
.edit-wrapper {
margin-right: $size-4;
}
.info {
font-size: $fs14;
line-height: $lh-115; // Original value was 1rem = 16px; 16px/14px = 114.285714286% => $lh-115 (rounded)
font-weight: $fw400;
color: $color-gray-60;
margin-left: 0.75rem;
@media (max-width: 760px) {
display: none;
}
}
.project-actions {
display: flex;
opacity: 0;
margin-left: $size-6;
.btn-small {
height: 32px;
margin: 0 $size-2;
width: 32px;
}
}
.pin-icon {
cursor: pointer;
display: flex;
align-items: center;
margin-right: 14px;
background-color: transparent;
border: none;
svg {
width: 15px;
height: 15px;
fill: $color-gray-20;
}
&.active {
svg {
fill: $color-gray-50;
}
}
}
}
&:hover,
&:focus,
&:focus-within {
.project-actions {
opacity: 1;
}
}
.show-more {
align-items: center;
color: $color-gray-30;
display: flex;
font-size: $fs14;
justify-content: space-between;
cursor: pointer;
background-color: transparent;
border: none;
position: absolute;
top: 9px;
right: 53px;
.placeholder-icon {
transform: rotate(-90deg);
margin-left: 10px;
svg {
height: 14px;
width: 14px;
fill: $color-gray-30;
}
}
&:hover {
color: $color-primary-dark;
svg {
fill: $color-primary-dark;
}
}
}
}
.recent-files-row-title-info {
color: $color-gray-60;
line-height: $lh-115; // Original value was 1rem = 16px; 16px/14px = 114.285714286% => $lh-115
font-size: $fs14;
font-weight: $fw400;
@media (max-width: 880px) {
display: none;
}
}
.dashboard-table {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 20px;
font-size: $fs16;
&.team-members {
margin-bottom: 52px;
}
&.invitations {
.table-row {
display: grid;
grid-template-columns: 43% 1fr 109px 12px;
}
}
.table-header {
display: grid;
grid-template-columns: 43% 1fr 109px 12px;
max-width: 1040px;
background-color: $color-white;
color: $color-gray-30;
width: 100%;
height: 40px;
padding: 0px 16px;
}
.table-rows {
display: flex;
flex-direction: column;
max-width: 1040px;
width: 100%;
margin-top: 16px;
color: $color-black;
}
.table-row {
display: flex;
width: 100%;
height: 45px;
align-items: center;
padding: 0px 16px;
}
.table-field {
display: flex;
align-items: center;
.icon {
padding-left: 10px;
cursor: pointer;
}
}
svg {
width: 10px;
height: 10px;
fill: $color-black;
}
}
.edit-wrapper {
border: 1px solid $color-gray-10;
border-radius: $br3;
display: flex;
padding-right: $size-5;
position: relative;
input.element-title {
border: 0;
height: 30px;
padding: 5px;
margin: 0;
width: 100%;
background-color: $color-white;
}
.close {
cursor: pointer;
position: absolute;
top: 1px;
right: 2px;
svg {
fill: $color-gray-30;
height: 15px;
transform: rotate(45deg) translateY(7px);
width: 15px;
margin: 0;
}
}
}
.import-file-btn {
align-items: center;
display: flex;
flex-direction: column;
height: 2rem;
justify-content: center;
overflow: hidden;
padding: 4px;
width: 2rem;
background: none;
border: 1px solid $color-gray-20;
border-radius: $br2;
cursor: pointer;
transition: all 0.4s;
margin-left: 1rem;
&:hover {
background: $color-primary;
}
svg {
width: 16px;
height: 16px;
}
}
.dashboard-templates-section {
position: absolute;
display: flex;
flex-direction: column;
justify-content: flex-end;
bottom: 0;
width: 100%;
height: 228px;
transition: bottom 300ms;
pointer-events: none;
&.collapsed {
bottom: -228px;
transition: bottom 300ms;
}
.title {
pointer-events: all;
width: fit-content;
top: -56px;
right: -28px;
text-align: right;
height: 56px;
position: absolute;
button {
border: none;
cursor: pointer;
height: 58px;
display: inline-flex;
align-items: center;
border-top: 2px solid #e4e4e4;
border-left: 2px solid #e4e4e4;
border-right: 2px solid #e4e4e4;
border-top-left-radius: $br10;
border-top-right-radius: $br10;
margin-right: 30px;
background-color: $color-white;
position: relative;
z-index: 1;
span {
display: inline-block;
vertical-align: middle;
line-height: $lh-normal;
font-size: $fs18;
font-weight: $fw600;
color: $color-black;
margin-left: 18px;
margin-right: 10px;
&.icon {
margin-left: 10px;
margin-right: 16px;
}
}
svg {
width: 12px;
height: 12px;
}
}
}
.button {
position: absolute;
top: 133px;
border: 2px solid #e0e4e9;
border-radius: 50%;
text-align: center;
width: 35px;
height: 35px;
cursor: pointer;
background-color: $color-white;
display: flex;
align-items: center;
justify-content: center;
pointer-events: all;
svg {
width: 12px;
height: 12px;
}
&.left {
left: 0;
margin-left: 43px;
}
&.right {
right: 0;
margin-right: 43px;
}
&:hover {
border: 2px solid $color-primary;
}
}
.content {
pointer-events: all;
background-color: $color-white;
width: 200%;
height: 229px;
border-top: 2px solid #e4e4e4;
border-left: 2px solid #e4e4e4;
margin-left: 5px;
position: absolute;
.card-container {
width: 275px;
margin-top: 20px;
display: inline-block;
text-align: center;
vertical-align: top;
background-color: transparent;
border: none;
padding: 0;
}
.template-card {
display: inline-block;
width: 255px;
font-size: $fs16;
color: #181a22;
cursor: pointer;
.img-container {
width: 100%;
height: 135px;
margin-bottom: 15px;
border-radius: $br5;
border: 2px solid #e0e4e9;
display: flex;
justify-content: center;
flex-direction: column;
}
.card-name {
padding: 0 5px;
display: flex;
justify-content: space-between;
height: 23px;
svg {
width: 16px;
height: 16px;
}
span {
font-weight: $fw500;
font-size: $fs14;
}
}
.template-link {
border: 2px solid transparent;
margin: 30px;
padding: 32px 0;
}
.template-link-title {
font-size: $fs14;
font-weight: $fw600;
color: $color-gray-60;
}
.template-link-text {
font-size: $fs12;
margin-top: $size-2;
color: $color-gray-50;
}
&:hover {
.img-container {
border: 2px solid $color-primary;
}
}
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,243 +0,0 @@
.share-modal {
background: none;
display: block;
top: 50px;
left: calc(100vw - 500px);
.share-link-dialog {
width: 480px;
background-color: $color-white;
box-shadow: 0px 2px 8px 0px rgb(0 0 0 / 20%);
.modal-content {
padding: 16px 32px;
&:first-child {
border-top: 0px;
padding: 0;
height: 50px;
display: flex;
justify-content: center;
}
.title {
display: flex;
justify-content: space-between;
align-items: center;
height: 100%;
margin-left: 32px;
h2 {
font-size: $fs18;
color: $color-black;
}
.modal-close-button {
margin-right: 16px;
}
}
.share-link-section {
.custom-input {
display: flex;
flex-direction: row;
margin-bottom: 15px;
border: 1px solid $color-gray-20;
input {
padding: 0 0 0 15px;
border: none;
}
}
.hint-wrapper {
display: flex;
justify-content: space-between;
align-items: center;
.hint {
font-size: $fs12;
color: $color-gray-40;
}
.confirm-dialog {
display: flex;
flex-direction: column;
background-color: unset;
.actions {
display: flex;
justify-content: flex-end;
gap: 16px;
}
.description {
font-size: $fs12;
margin-bottom: 16px;
color: $color-black;
}
.btn-primary,
.btn-secondary,
.btn-warning,
.btn-danger {
width: 126px;
margin-bottom: 0px;
&:not(:last-child) {
margin-right: 10px;
}
}
}
}
label {
font-size: $fs12;
color: $color-black;
}
.help-icon {
height: 40px;
width: 40px;
display: flex;
justify-content: center;
align-items: center;
cursor: pointer;
position: relative;
right: 0;
top: 0;
background-color: $color-gray-10;
border-left: 1px solid $color-gray-20;
svg {
fill: $color-gray-30;
}
&:hover {
background-color: $color-primary;
svg {
fill: $color-gray-60;
}
}
}
input {
margin: 0;
}
}
&.ops-section {
.manage-permissions {
display: flex;
color: $color-primary-dark;
font-size: $fs12;
cursor: pointer;
.icon {
svg {
height: 16px;
width: 16px;
fill: $color-primary-dark;
}
}
.title {
margin-left: 8px;
}
}
.view-mode {
min-height: 34px;
.subtitle {
height: 32px;
}
.row {
display: flex;
justify-content: space-between;
align-items: center;
.count-pages {
font-size: $fs12;
color: $color-gray-30;
}
}
.current-tag {
font-size: $fs12;
color: $color-gray-30;
}
label {
color: $color-black;
}
}
.access-mode,
.inspect-mode {
display: grid;
grid-template-columns: auto 1fr;
.items {
display: flex;
justify-content: flex-end;
align-items: center;
}
}
.view-mode,
.access-mode,
.inspect-mode {
margin: 8px 0;
.subtitle {
display: flex;
justify-content: flex-start;
align-items: center;
color: $color-black;
font-size: $fs16;
.icon {
display: flex;
justify-content: center;
align-items: center;
margin-right: 10px;
svg {
height: 16px;
width: 16px;
}
}
}
.items {
.input-select {
background-image: url("/images/icons/arrow-down.svg");
margin: 0;
padding-right: 28px;
border: 1px solid $color-gray-10;
max-width: 227px;
text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap;
}
> .input-radio {
display: flex;
user-select: none;
margin-top: 0;
margin-bottom: 0;
label {
display: flex;
align-items: center;
color: $color-black;
max-width: 115px;
&::before {
height: 16px;
width: 16px;
}
.hint {
margin-left: 5px;
color: $color-gray-30;
}
}
&.disabled {
label {
color: $color-gray-30;
}
}
}
}
}
.pages-selection {
border-top: 1px solid $color-gray-10;
border-bottom: 1px solid $color-gray-10;
padding-left: 20px;
max-height: 200px;
overflow-y: scroll;
user-select: none;
label {
color: $color-black;
}
}
}
}
}
}

View file

@ -1,139 +0,0 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) KALEIDOS INC
// .history-debug-overlay {
// background: $color-gray-50;
// bottom: 0;
// max-height: 500px;
// overflow-y: auto;
// position: absolute;
// width: 500px;
// z-index: 1000;
// }
// .history-toolbox {
// display: flex;
// flex-direction: column;
// }
// .history-toolbox-title {
// color: $color-gray-10;
// font-size: $fs14;
// padding: 0.5rem;
// }
// .history-entry-empty {
// display: flex;
// flex-direction: column;
// align-items: center;
// padding: 1rem;
// .history-entry-empty-icon {
// margin-bottom: 1rem;
// svg {
// width: 32px;
// height: 32px;
// fill: $color-gray-40;
// }
// }
// .history-entry-empty-msg {
// color: $color-gray-30;
// font-size: $fs12;
// }
// }
// .history-entries {
// font-size: $fs12;
// color: $color-gray-20;
// fill: $color-gray-20;
// height: 100%;
// overflow-x: hidden;
// overflow-y: auto;
// }
// .history-entry {
// border: 1px solid $color-gray-60;
// border-radius: $br4;
// margin: 0.5rem;
// display: flex;
// flex-direction: column;
// padding: 0.5rem;
// cursor: pointer;
// transition: border 0.2s;
// &.disabled {
// opacity: 0.5;
// }
// &.current {
// background-color: $color-gray-60;
// }
// &.hover {
// border-color: $color-primary;
// }
// }
// .history-entry-summary {
// display: flex;
// flex-direction: row;
// align-items: center;
// * {
// display: flex;
// }
// }
// .history-entry-summary-icon {
// svg {
// width: 16px;
// height: 16px;
// }
// }
// .history-entry-summary-text {
// flex: 1;
// margin: 0 0.5rem;
// margin-top: 2px;
// }
// .history-entry-summary-button {
// opacity: 0;
// transition: transform 0.2s;
// svg {
// width: 12px;
// height: 12px;
// }
// .show-detail &,
// .hover & {
// opacity: 1;
// }
// .show-detail & {
// transform: rotate(90deg);
// }
// }
// .history-entry-detail {
// display: none;
// .show-detail & {
// display: block;
// padding: 1rem 0 0.5rem 0;
// }
// .history-entry-details-list {
// margin: 0;
// li {
// margin-bottom: 0.5rem;
// }
// }
// }

View file

@ -12,7 +12,6 @@
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[cljs.spec.alpha :as s]
@ -57,73 +56,41 @@
(mf/defc recovery-form
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (fm/use-form :spec ::recovery-form
(let [form (fm/use-form :spec ::recovery-form
:validators [password-equality
(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))]
:initial params)]
(if new-css-system
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "password"
:name :password-1
:show-success? true
:label (tr "auth.new-password")
:class (stl/css :form-field)}]]
[:& fm/form {:on-submit on-submit :form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "password"
:name :password-1
:show-success? true
:label (tr "auth.new-password")
:class (stl/css :form-field)}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "password"
:name :password-2
:show-success? true
:label (tr "auth.confirm-password")
:class (stl/css :form-field)}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input {:type "password"
:name :password-2
:show-success? true
:label (tr "auth.confirm-password")
:class (stl/css :form-field)}]]
[:> fm/submit-button*
{:label (tr "auth.recovery-submit")
:class (stl/css :submit-btn)}]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form}
[:div.fields-row
[:& fm/input {:type "password"
:name :password-1
:label (tr "auth.new-password")}]]
[:div.fields-row
[:& fm/input {:type "password"
:name :password-2
:label (tr "auth.confirm-password")}]]
[:> fm/submit-button*
{:label (tr "auth.recovery-submit")}]])))
[:> fm/submit-button*
{:label (tr "auth.recovery-submit")
:class (stl/css :submit-btn)}]]))
;; --- Recovery Request Page
(mf/defc recovery-page
[{:keys [params] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)} "Forgot your password?"]
[:div {:class (stl/css :auth-subtitle)} "Please enter your new password"]
[:hr {:class (stl/css :separator)}]
[:& recovery-form {:params params}]
[:div {:class (stl/css :auth-form)}
[:h1 {:class (stl/css :auth-title)} "Forgot your password?"]
[:div {:class (stl/css :auth-subtitle)} "Please enter your new password"]
[:hr {:class (stl/css :separator)}]
[:& recovery-form {:params params}]
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry)}
[:a {:on-click #(st/emit! (rt/nav :auth-login))}
(tr "profile.recovery.go-to-login")]]]]
;; TODO
[:section.generic-form
[:div.form-container
[:h1 "Forgot your password?"]
[:div.subtitle "Please enter your new password"]
[:& recovery-form {:params params}]
[:div.links
[:div.link-entry
[:a {:on-click #(st/emit! (rt/nav :auth-login))}
(tr "profile.recovery.go-to-login")]]]]])))
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-entry)}
[:a {:on-click #(st/emit! (rt/nav :auth-login))}
(tr "profile.recovery.go-to-login")]]]])

View file

@ -11,7 +11,6 @@
[app.main.data.users :as du]
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.static :as static]
[app.util.dom :as dom]
@ -62,8 +61,7 @@
(mf/defc verify-token
[{:keys [route] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
token (get-in route [:query-params :token])
(let [token (get-in route [:query-params :token])
bad-token (mf/use-state false)]
(mf/with-effect []
@ -96,6 +94,5 @@
(if @bad-token
[:> static/invalid-token {}]
[:div {:class (stl/css-case :verify-token new-css-system
:global/verify-token (not new-css-system))}
[:div {:class (stl/css :verify-token)}
i/loader-pencil])))

View file

@ -8,7 +8,6 @@
(:require-macros [app.main.style :as stl])
(:require
[app.common.data.macros :as dm]
[app.main.ui.context :as ctx]
[cuerdas.core :as str]
[promesa.core :as p]
[rumext.v2 :as mf]
@ -20,8 +19,7 @@
(mf/defc code-block
{::mf/wrap-props false}
[{:keys [code type]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
block-ref (mf/use-ref)
(let [block-ref (mf/use-ref)
code (str/trim code)]
(mf/with-effect [code type]
@ -29,7 +27,5 @@
(p/let [highlight-fn (lazy/load highlight-fn)]
(highlight-fn node))))
(if new-css-system
[:pre {:class (dm/str type " " (stl/css :code-display)) :ref block-ref} code]
[:pre {:class (dm/str type " " "code-display") :ref block-ref} code])))
[:pre {:class (dm/str type " " (stl/css :code-display)) :ref block-ref} code]))

View file

@ -11,7 +11,6 @@
[app.common.data.macros :as dm]
[app.main.refs :as refs]
[app.main.ui.components.dropdown :refer [dropdown']]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -68,7 +67,6 @@
min-width? (gobj/get props "min-width?" false)
origin (gobj/get props "origin")
route (mf/deref refs/route)
new-css-system (mf/use-ctx ctx/new-css-system)
in-dashboard? (= :dashboard-projects (:name (:data route)))
local (mf/use-state {:offset-y 0
:offset-x 0
@ -191,149 +189,79 @@
(tm/schedule-on-idle
#(dom/focus! (dom/get-element (first ids)))))
(if new-css-system
(when (and open? (some? (:levels @local)))
[:> dropdown' props
(let [level (-> @local :levels peek)
original-options (:options level)
parent-original (:parent-option level)]
[:div {:class (stl/css-case :is-selectable is-selectable
:context-menu true
:is-open open?
:fixed fixed?)
:style {:top (+ top (:offset-y @local))
:left (+ left (:offset-x @local))}
:on-key-down (on-key-down original-options parent-original)}
(let [level (-> @local :levels peek)]
[:ul {:class (stl/css-case :min-width min-width?
:context-menu-items true)
:role "menu"
:ref check-menu-offscreen}
(when-let [parent-option (:parent-option level)]
[:*
[:& context-menu-a11y-item
{:id "go-back-sub-option"
:class (stl/css :context-menu-item)
:tab-index "0"
:on-key-down (fn [event]
(dom/prevent-default event))}
[:button {:class (stl/css :context-menu-action :submenu-back)
(when (and open? (some? (:levels @local)))
[:> dropdown' props
(let [level (-> @local :levels peek)
original-options (:options level)
parent-original (:parent-option level)]
[:div {:class (stl/css-case :is-selectable is-selectable
:context-menu true
:is-open open?
:fixed fixed?)
:style {:top (+ top (:offset-y @local))
:left (+ left (:offset-x @local))}
:on-key-down (on-key-down original-options parent-original)}
(let [level (-> @local :levels peek)]
[:ul {:class (stl/css-case :min-width min-width?
:context-menu-items true)
:role "menu"
:ref check-menu-offscreen}
(when-let [parent-option (:parent-option level)]
[:*
[:& context-menu-a11y-item
{:id "go-back-sub-option"
:class (stl/css :context-menu-item)
:tab-index "0"
:on-key-down (fn [event]
(dom/prevent-default event))}
[:button {:class (stl/css :context-menu-action :submenu-back)
:data-no-close true
:on-click exit-submenu}
[:span {:class (stl/css :submenu-icon-back)} i/arrow-refactor]
parent-option]]
[:li {:class (stl/css :separator)}]])
(for [[index option] (d/enumerate (:options level))]
(let [option-name (:option-name option)
id (:id option)
sub-options (:sub-options option)
option-handler (:option-handler option)
data-test (:data-test option)]
(when option-name
(if (= option-name :separator)
[:li {:key (dm/str "context-item-" index)
:class (stl/css :separator)}]
[:& context-menu-a11y-item
{:id id
:key id
:class (stl/css-case
:is-selected (and selected (= option-name selected))
:selected (and selected (= data-test selected))
:context-menu-item true)
:key-index (dm/str "context-item-" index)
:tab-index "0"
:on-key-down (fn [event]
(dom/prevent-default event))}
(if-not sub-options
[:a {:class (stl/css :context-menu-action)
:on-click #(do (dom/stop-propagation %)
(on-close)
(option-handler %))
:data-test data-test}
(if (and in-dashboard? (= option-name "Default"))
(tr "dashboard.default-team-name")
option-name)
(when (and selected (= data-test selected))
[:span {:class (stl/css :selected-icon)} i/tick-refactor])]
[:a {:class (stl/css :context-menu-action :submenu)
:data-no-close true
:on-click exit-submenu}
[:span {:class (stl/css :submenu-icon-back)} i/arrow-refactor]
parent-option]]
[:li {:class (stl/css :separator)}]])
(for [[index option] (d/enumerate (:options level))]
(let [option-name (:option-name option)
id (:id option)
sub-options (:sub-options option)
option-handler (:option-handler option)
data-test (:data-test option)]
(when option-name
(if (= option-name :separator)
[:li {:key (dm/str "context-item-" index)
:class (stl/css :separator)}]
[:& context-menu-a11y-item
{:id id
:key id
:class (stl/css-case
:is-selected (and selected (= option-name selected))
:selected (and selected (= data-test selected))
:context-menu-item true)
:key-index (dm/str "context-item-" index)
:tab-index "0"
:on-key-down (fn [event]
(dom/prevent-default event))}
(if-not sub-options
[:a {:class (stl/css :context-menu-action)
:on-click #(do (dom/stop-propagation %)
(on-close)
(option-handler %))
:data-test data-test}
(if (and in-dashboard? (= option-name "Default"))
(tr "dashboard.default-team-name")
option-name)
(when (and selected (= data-test selected))
[:span {:class (stl/css :selected-icon)} i/tick-refactor])]
[:a {:class (stl/css :context-menu-action :submenu)
:data-no-close true
:on-click (enter-submenu option-name sub-options)
:data-test data-test}
option-name
[:span {:class (stl/css :submenu-icon)} i/arrow-refactor]])]))))])])])
;; OLD
(when (and open? (some? (:levels @local)))
[:> dropdown' props
(let [level (-> @local :levels peek)
original-options (:options level)
parent-original (:parent-option level)]
[:div {:class (dom/classnames :is-selectable is-selectable
:context-menu true
:is-open open?
:fixed fixed?)
:style {:top (+ top (:offset-y @local))
:left (+ left (:offset-x @local))}
:on-key-down (on-key-down original-options parent-original)}
(let [level (-> @local :levels peek)]
[:ul {:class (dom/classnames :min-width min-width?
:context-menu-items true)
:role "menu"
:ref check-menu-offscreen}
(when-let [parent-option (:parent-option level)]
[:*
[:& context-menu-a11y-item
{:id "go-back-sub-option"
:tab-index "0"
:on-key-down (fn [event]
(dom/prevent-default event))}
[:div {:class (dom/classnames :context-menu-action true
:submenu-back true)
:data-no-close true
:on-click exit-submenu}
[:span i/arrow-slide]
parent-option]]
[:li.separator]])
(for [[index option] (d/enumerate (:options level))]
(let [option-name (:option-name option)
id (:id option)
sub-options (:sub-options option)
option-handler (:option-handler option)
data-test (:data-test option)]
(when option-name
(if (= option-name :separator)
[:li.separator {:key (dm/str "context-item-" index)}]
[:& context-menu-a11y-item
{:id id
:key id
:class (dom/classnames :is-selected (and selected (= option-name selected)))
:key-index (dm/str "context-item-" index)
:tab-index "0"
:on-key-down (fn [event]
(dom/prevent-default event))}
(if-not sub-options
[:a {:class (dom/classnames :context-menu-action true)
:on-click #(do (dom/stop-propagation %)
(on-close)
(option-handler %))
:data-test data-test}
(if (and in-dashboard? (= option-name "Default"))
(tr "dashboard.default-team-name")
option-name)]
[:a.context-menu-action.submenu
{:data-no-close true
:on-click (enter-submenu option-name sub-options)
:data-test data-test}
option-name
[:span i/arrow-slide]])]))))])])]))))
:on-click (enter-submenu option-name sub-options)
:data-test data-test}
option-name
[:span {:class (stl/css :submenu-icon)} i/arrow-refactor]])]))))])])])))
(mf/defc context-menu-a11y
{::mf/wrap-props false}

View file

@ -386,21 +386,19 @@
(mf/defc submit-button*
{::mf/wrap-props false}
[props]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
form (or (unchecked-get props "form")
(let [form (or (unchecked-get props "form")
(mf/use-ctx form-ctx))
label (unchecked-get props "label")
on-click (unchecked-get props "onClick")
children (unchecked-get props "children")
class (d/nilv (unchecked-get props "className") "btn-primary btn-large")
class (unchecked-get props "className")
name (d/nilv (unchecked-get props "name") "submit")
disabled? (or (and (some? form) (not (:valid @form)))
(true? (unchecked-get props "disabled")))
klass (dm/str class " " (if disabled? "btn-disabled" ""))
new-klass (dm/str class " " (if disabled? (stl/css :btn-disabled) ""))
on-key-down
@ -416,7 +414,7 @@
(obj/set! "onKeyDown" on-key-down)
(obj/set! "name" name)
(obj/set! "label" mf/undefined)
(obj/set! "className" (if new-css-system new-klass klass))
(obj/set! "className" new-klass)
(obj/set! "type" "submit"))]
[:> "button" props

View file

@ -9,7 +9,6 @@
(:require
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :refer [tr]]
@ -19,9 +18,8 @@
(mf/defc tab-element
{::mf/wrap-props false}
[props]
(let [children (unchecked-get props "children")
new-css-system (mf/use-ctx ctx/new-css-system)]
[:div {:class (stl/css new-css-system :tab-element)}
(let [children (unchecked-get props "children")]
[:div {:class (stl/css :tab-element)}
children]))
(mf/defc tab-container

View file

@ -53,8 +53,7 @@
(mf/defc dashboard-content
[{:keys [team projects project section search-term profile] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
container (mf/use-ref)
(let [container (mf/use-ref)
content-width (mf/use-state 0)
project-id (:id project)
team-id (:id team)
@ -82,123 +81,65 @@
(mf/use-effect on-resize)
(if new-css-system
[:div {:class (stl/css :dashboard-content)
:on-click clear-selected-fn :ref container}
(case section
:dashboard-projects
[:*
[:& projects-section
{:team team
:projects projects
:profile profile
:default-project-id default-project-id}]
[:div {:class (stl/css :dashboard-content)
:on-click clear-selected-fn :ref container}
(case section
:dashboard-projects
[:*
[:& projects-section
{:team team
:projects projects
:profile profile
:default-project-id default-project-id}]
(when (contains? cf/flags :dashboard-templates-section)
[:& templates-section {:profile profile
:project-id project-id
:team-id team-id
:default-project-id default-project-id
:content-width @content-width}])]
:dashboard-fonts
[:& fonts-page {:team team}]
:dashboard-font-providers
[:& font-providers-page {:team team}]
:dashboard-files
(when project
[:*
[:& files-section {:team team :project project}]
(when (contains? cf/flags :dashboard-templates-section)
[:& templates-section {:profile profile
:project-id project-id
:team-id team-id
:default-project-id default-project-id
:content-width @content-width}])]
:dashboard-fonts
[:& fonts-page {:team team}]
:dashboard-font-providers
[:& font-providers-page {:team team}]
:dashboard-files
(when project
[:*
[:& files-section {:team team :project project}]
(when (contains? cf/flags :dashboard-templates-section)
[:& templates-section {:profile profile
:team-id team-id
:project-id project-id
:default-project-id default-project-id
:content-width @content-width}])])
:dashboard-search
[:& search-page {:team team
:search-term search-term}]
:dashboard-libraries
[:& libraries-page {:team team}]
:dashboard-team-members
[:& team-members-page {:team team :profile profile}]
:dashboard-team-invitations
[:& team-invitations-page {:team team}]
:dashboard-team-webhooks
[:& team-webhooks-page {:team team}]
:dashboard-team-settings
[:& team-settings-page {:team team :profile profile}]
nil)]
;; OLD
[:div.dashboard-content {:on-click clear-selected-fn :ref container}
(case section
:dashboard-projects
[:*
[:& projects-section
{:team team
:projects projects
:profile profile
:default-project-id default-project-id}]
(when (contains? cf/flags :dashboard-templates-section)
[:& templates-section {:profile profile
:project-id project-id
:team-id team-id
:default-project-id default-project-id
:content-width @content-width}])]
:content-width @content-width}])])
:dashboard-fonts
[:& fonts-page {:team team}]
:dashboard-search
[:& search-page {:team team
:search-term search-term}]
:dashboard-font-providers
[:& font-providers-page {:team team}]
:dashboard-libraries
[:& libraries-page {:team team}]
:dashboard-files
(when project
[:*
[:& files-section {:team team :project project}]
(when (contains? cf/flags :dashboard-templates-section)
[:& templates-section {:profile profile
:team-id team-id
:project-id project-id
:default-project-id default-project-id
:content-width @content-width}])])
:dashboard-team-members
[:& team-members-page {:team team :profile profile}]
:dashboard-search
[:& search-page {:team team
:search-term search-term}]
:dashboard-team-invitations
[:& team-invitations-page {:team team}]
:dashboard-libraries
[:& libraries-page {:team team}]
:dashboard-team-webhooks
[:& team-webhooks-page {:team team}]
:dashboard-team-members
[:& team-members-page {:team team :profile profile}]
:dashboard-team-settings
[:& team-settings-page {:team team :profile profile}]
:dashboard-team-invitations
[:& team-invitations-page {:team team}]
:dashboard-team-webhooks
[:& team-webhooks-page {:team team}]
:dashboard-team-settings
[:& team-settings-page {:team team :profile profile}]
nil)])))
nil)]))
(mf/defc dashboard
[{:keys [route profile] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
section (get-in route [:data :name])
(let [section (get-in route [:data :name])
params (parse-params route)
project-id (:project-id params)
@ -227,59 +168,31 @@
(fn []
(events/unlistenByKey key))))
(if new-css-system
[:& (mf/provider ctx/current-team-id) {:value team-id}
[:& (mf/provider ctx/current-project-id) {:value project-id}
;; NOTE: dashboard events and other related functions assumes
;; that the team is a implicit context variable that is
;; available using react context or accessing
;; the :current-team-id on the state. We set the key to the
;; team-id because we want to completely refresh all the
;; components on team change. Many components assumes that the
;; team is already set so don't put the team into mf/deps.
(when team
[:main {:class (stl/css :dashboard)
:key (:id team)}
[:& sidebar
{:team team
:projects projects
:project project
[:& (mf/provider ctx/current-team-id) {:value team-id}
[:& (mf/provider ctx/current-project-id) {:value project-id}
;; NOTE: dashboard events and other related functions assumes
;; that the team is a implicit context variable that is
;; available using react context or accessing
;; the :current-team-id on the state. We set the key to the
;; team-id because we want to completely refresh all the
;; components on team change. Many components assumes that the
;; team is already set so don't put the team into mf/deps.
(when team
[:main {:class (stl/css :dashboard)
:key (:id team)}
[:& sidebar
{:team team
:projects projects
:project project
:profile profile
:section section
:search-term search-term}]
(when (and team profile (seq projects))
[:& dashboard-content
{:projects projects
:profile profile
:section section
:search-term search-term}]
(when (and team profile (seq projects))
[:& dashboard-content
{:projects projects
:profile profile
:project project
:section section
:search-term search-term
:team team}])])]]
[:& (mf/provider ctx/current-team-id) {:value team-id}
[:& (mf/provider ctx/current-project-id) {:value project-id}
;; NOTE: dashboard events and other related functions assumes
;; that the team is a implicit context variable that is
;; available using react context or accessing
;; the :current-team-id on the state. We set the key to the
;; team-id because we want to completely refresh all the
;; components on team change. Many components assumes that the
;; team is already set so don't put the team into mf/deps.
(when team
[:main {:class (dom/classnames :dashboard-layout true) :key (:id team)}
[:& sidebar
{:team team
:projects projects
:project project
:profile profile
:section section
:search-term search-term}]
(when (and team profile (seq projects))
[:& dashboard-content
{:projects projects
:profile profile
:project project
:section section
:search-term search-term
:team team}])])]])))
:search-term search-term
:team team}])])]]))

View file

@ -14,9 +14,7 @@
[app.main.store :as st]
[app.main.ui.comments :as cmt]
[app.main.ui.components.dropdown :refer [dropdown]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.keyboard :as kbd]
[potok.v2.core :as ptk]
@ -42,21 +40,18 @@
(on-show-comments event))))]
[:div {:class (stl/css :dashboard-comments-section)}
[:button
{:tab-index "0"
:on-click on-show-comments
:on-key-down handle-keydown
:data-test "open-comments"
:class (stl/css-case :button true
:open show?
:unread (boolean (seq tgroups)))}
i/chat]]))
[:button {:tab-index "0"
:on-click on-show-comments
:on-key-down handle-keydown
:data-test "open-comments"
:class (stl/css-case :button true
:open show?
:unread (boolean (seq tgroups)))}
i/comments-refactor]]))
(mf/defc comments-section
[{:keys [profile team show? on-show-comments on-hide-comments]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
threads-map (mf/deref refs/comment-threads)
[{:keys [profile team show? on-hide-comments]}]
(let [threads-map (mf/deref refs/comment-threads)
users (mf/deref refs/current-team-comments-users)
team-id (:id team)
@ -91,79 +86,32 @@
(st/emit! (ptk/event ::ev/event {::ev/name "open-comment-notifications"
::ev/origin "dashboard"})))))
(if new-css-system
[:div {:class (stl/css :dashboard-comments-section)}
[:& dropdown {:show show? :on-close on-hide-comments}
[:div {:class (stl/css :dropdown :comments-section :comment-threads-section)}
[:div {:class (stl/css :header)}
[:h3 (tr "labels.comments")]
[:button
{:class (stl/css :close)
:tab-index (if show? "0" "-1")
:on-click on-hide-comments
:on-key-down handle-keydown} i/close]]
[:div {:class (stl/css :dashboard-comments-section)}
[:& dropdown {:show show? :on-close on-hide-comments}
[:div {:class (stl/css :dropdown :comments-section :comment-threads-section)}
[:div {:class (stl/css :header)}
[:h3 (tr "labels.comments")]
[:button
{:class (stl/css :close)
:tab-index (if show? "0" "-1")
:on-click on-hide-comments
:on-key-down handle-keydown} i/close]]
(if (seq tgroups)
[:div {:class (stl/css :thread-groups)}
(if (seq tgroups)
[:div {:class (stl/css :thread-groups)}
[:& cmt/comment-thread-group
{:group (first tgroups)
:on-thread-click on-navigate
:show-file-name true
:users users}]
(for [tgroup (rest tgroups)]
[:& cmt/comment-thread-group
{:group (first tgroups)
{:group tgroup
:on-thread-click on-navigate
:show-file-name true
:users users}]
(for [tgroup (rest tgroups)]
[:& cmt/comment-thread-group
{:group tgroup
:on-thread-click on-navigate
:show-file-name true
:users users
:key (:page-id tgroup)}])]
:users users
:key (:page-id tgroup)}])]
[:div {:class (stl/css :thread-groups-placeholder)}
i/chat
(tr "labels.no-comments-available")])]]]
;; OLD
[:div.dashboard-comments-section
[:div.button
{:tab-index "0"
:on-click on-show-comments
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-show-comments event)))
:data-test "open-comments"
:class (dom/classnames :open show?
:unread (boolean (seq tgroups)))}
i/chat]
[:& dropdown {:show show? :on-close on-hide-comments}
[:div.dropdown.comments-section.comment-threads-section.
[:div.header
[:h3 (tr "labels.comments")]
[:span.close {:tab-index (if show? "0" "-1")
:on-click on-hide-comments
:on-key-down handle-keydown}
i/close]]
[:hr]
(if (seq tgroups)
[:div.thread-groups
[:& cmt/comment-thread-group
{:group (first tgroups)
:on-thread-click on-navigate
:show-file-name true
:users users}]
(for [tgroup (rest tgroups)]
[:*
[:hr]
[:& cmt/comment-thread-group
{:group tgroup
:on-thread-click on-navigate
:show-file-name true
:users users
:key (:page-id tgroup)}]])]
[:div.thread-groups-placeholder
i/chat
(tr "labels.no-comments-available")])]]])))
[:div {:class (stl/css :thread-groups-placeholder)}
i/comments-refactor
(tr "labels.no-comments-available")])]]]))

View file

@ -47,9 +47,11 @@
font-size: $fs-12;
padding: $s-24;
text-align: center;
color: $df-secondary;
svg {
fill: $df-secondary;
stroke: $df-secondary;
fill: none;
height: $s-24;
margin-bottom: $s-24;
width: $s-24;
@ -65,21 +67,22 @@
width: $s-32;
svg {
width: $s-16;
height: $s-16;
fill: $df-secondary;
min-width: $s-16;
min-height: $s-16;
stroke: $df-secondary;
fill: none;
}
&.unread svg,
&.open svg {
fill: $da-tertiary;
stroke: $da-tertiary;
}
&:hover {
background-color: $db-cuaternary;
svg {
fill: $da-primary;
stroke: $da-primary;
}
}
}

View file

@ -11,7 +11,6 @@
[app.main.data.events :as ev]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.grid :refer [grid]]
[app.main.ui.dashboard.inline-edition :refer [inline-edition]]
[app.main.ui.dashboard.project-menu :refer [project-menu]]
@ -26,8 +25,7 @@
(mf/defc header
[{:keys [project create-fn] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
local (mf/use-state
(let [local (mf/use-state
{:menu-open false
:edition false})
@ -64,137 +62,75 @@
(dd/clear-selected-files))))]
(if new-css-system
[:header {:class (stl/css :dashboard-header)}
(if (:is-default project)
[:div#dashboard-drafts-title {:class (stl/css :dashboard-title)}
[:h1 (tr "labels.drafts")]]
[:header {:class (stl/css :dashboard-header)}
(if (:is-default project)
[:div#dashboard-drafts-title {:class (stl/css :dashboard-title)}
[:h1 (tr "labels.drafts")]]
(if (:edition @local)
[:& inline-edition
{:content (:name project)
:on-end (fn [name]
(let [name (str/trim name)]
(when-not (str/empty? name)
(st/emit! (-> (dd/rename-project (assoc project :name name))
(with-meta {::ev/origin "project"}))))
(swap! local assoc :edition false)))}]
[:div {:class (stl/css :dashboard-title)}
[:h1 {:on-double-click on-edit
:data-test "project-title"
:id (:id project)}
(:name project)]]))
(if (:edition @local)
[:& inline-edition
{:content (:name project)
:on-end (fn [name]
(let [name (str/trim name)]
(when-not (str/empty? name)
(st/emit! (-> (dd/rename-project (assoc project :name name))
(with-meta {::ev/origin "project"}))))
(swap! local assoc :edition false)))}]
[:div {:class (stl/css :dashboard-title)}
[:h1 {:on-double-click on-edit
:data-test "project-title"
:id (:id project)}
(:name project)]]))
[:& project-menu {:project project
:show? (:menu-open @local)
:left (- (:x (:menu-pos @local)) 180)
:top (:y (:menu-pos @local))
:on-edit on-edit
:on-menu-close on-menu-close
:on-import on-import}]
[:& project-menu {:project project
:show? (:menu-open @local)
:left (- (:x (:menu-pos @local)) 180)
:top (:y (:menu-pos @local))
:on-edit on-edit
:on-menu-close on-menu-close
:on-import on-import}]
[:div {:class (stl/css :dashboard-header-actions)}
[:a
{:class (stl/css :btn-secondary :btn-small)
[:div {:class (stl/css :dashboard-header-actions)}
[:a
{:class (stl/css :btn-secondary :btn-small)
:tab-index "0"
:on-click on-create-click
:data-test "new-file"
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-create-click event)))}
(tr "dashboard.new-file")]
(when-not (:is-default project)
[:button
{:class (stl/css-case :icon true
:pin-icon true
:tooltip true
:tooltip-bottom true
:active (:is-pinned project))
:tab-index "0"
:on-click on-create-click
:data-test "new-file"
:on-click toggle-pin
:alt (tr "dashboard.pin-unpin")
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-create-click event)))}
(tr "dashboard.new-file")]
(toggle-pin event)))}
(if (:is-pinned project)
i/pin-fill
i/pin)])
(when-not (:is-default project)
[:button
{:class (stl/css-case :icon true
:pin-icon true
:tooltip true
:tooltip-bottom true
:active (:is-pinned project))
:tab-index "0"
:on-click toggle-pin
:alt (tr "dashboard.pin-unpin")
:on-key-down (fn [event]
(when (kbd/enter? event)
(toggle-pin event)))}
(if (:is-pinned project)
i/pin-fill
i/pin)])
[:div
{:class (stl/css :icon :tooltip :tooltip-bottom-left)
:tab-index "0"
:on-click on-menu-click
:alt (tr "dashboard.options")
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-menu-click event)))}
i/actions]]]
;; OLD
[:header.dashboard-header
(if (:is-default project)
[:div.dashboard-title#dashboard-drafts-title
[:h1 (tr "labels.drafts")]]
(if (:edition @local)
[:& inline-edition {:content (:name project)
:on-end (fn [name]
(let [name (str/trim name)]
(when-not (str/empty? name)
(st/emit! (-> (dd/rename-project (assoc project :name name))
(with-meta {::ev/origin "project"}))))
(swap! local assoc :edition false)))}]
[:div.dashboard-title
[:h1 {:on-double-click on-edit
:data-test "project-title"
:id (:id project)}
(:name project)]]))
[:& project-menu {:project project
:show? (:menu-open @local)
:left (- (:x (:menu-pos @local)) 180)
:top (:y (:menu-pos @local))
:on-edit on-edit
:on-menu-close on-menu-close
:on-import on-import}]
[:div.dashboard-header-actions
[:a.btn-secondary.btn-small
{:tab-index "0"
:on-click on-create-click
:data-test "new-file"
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-create-click event)))}
(tr "dashboard.new-file")]
(when-not (:is-default project)
[:button.icon.pin-icon.tooltip.tooltip-bottom
{:tab-index "0"
:class (when (:is-pinned project) "active")
:on-click toggle-pin
:alt (tr "dashboard.pin-unpin")
:on-key-down (fn [event]
(when (kbd/enter? event)
(toggle-pin event)))}
(if (:is-pinned project)
i/pin-fill
i/pin)])
[:div.icon.tooltip.tooltip-bottom-left
{:tab-index "0"
:on-click on-menu-click
:alt (tr "dashboard.options")
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-menu-click event)))}
i/actions]]])))
[:div
{:class (stl/css :icon :tooltip :tooltip-bottom-left)
:tab-index "0"
:on-click on-menu-click
:alt (tr "dashboard.options")
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-menu-click event)))}
i/actions]]]))
(mf/defc files-section
[{:keys [project team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
files-map (mf/deref refs/dashboard-files)
(let [files-map (mf/deref refs/dashboard-files)
project-id (:id project)
[rowref limit] (hooks/use-dynamic-grid-item-width)
@ -233,28 +169,15 @@
(st/emit! (dd/fetch-files {:project-id project-id})
(dd/clear-selected-files)))
(if new-css-system
[:*
[:& header {:team team
:project project
:create-fn create-file}]
[:section {:class (stl/css :dashboard-container :no-bg)
:ref rowref}
[:& grid {:project project
:files files
:origin :files
:create-fn create-file
:limit limit}]]]
;; OLD
[:*
[:& header {:team team
:project project
:create-fn create-file}]
[:section.dashboard-container.no-bg {:ref rowref}
[:& grid {:project project
:files files
:origin :files
:create-fn create-file
:limit limit}]]])))
[:*
[:& header {:team team
:project project
:create-fn create-file}]
[:section {:class (stl/css :dashboard-container :no-bg)
:ref rowref}
[:& grid {:project project
:files files
:origin :files
:create-fn create-file
:limit limit}]]]))

View file

@ -15,7 +15,6 @@
[app.main.store :as st]
[app.main.ui.components.context-menu :refer [context-menu]]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
@ -40,17 +39,10 @@
(mf/defc header
{::mf/wrap [mf/memo]}
[{:keys [section team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(use-set-page-title team section)
(if new-css-system
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-fonts-title {:class (stl/css :dashboard-title)}
[:h1 (tr "labels.fonts")]]]
;; OLD
[:header.dashboard-header
[:div.dashboard-title#dashboard-fonts-title
[:h1 (tr "labels.fonts")]]])))
(use-set-page-title team section)
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-fonts-title {:class (stl/css :dashboard-title)}
[:h1 (tr "labels.fonts")]]])
(mf/defc font-variant-display-name
[{:keys [variant]}]
@ -61,8 +53,7 @@
(mf/defc fonts-upload
[{:keys [team installed-fonts] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
fonts (mf/use-state {})
(let [fonts (mf/use-state {})
input-ref (mf/use-ref)
uploading (mf/use-state #{})
@ -121,151 +112,82 @@
handle-dismiss-all
(mf/use-callback (mf/deps @fonts) #(on-dismiss-all (vals @fonts)))]
(if new-css-system
[:div {:class (stl/css :dashboard-fonts-upload)}
[:div {:class (stl/css :dashboard-fonts-hero)}
[:div {:class (stl/css :desc)}
[:h2 (tr "labels.upload-custom-fonts")]
[:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}]
[:div {:class (stl/css :dashboard-fonts-upload)}
[:div {:class (stl/css :dashboard-fonts-hero)}
[:div {:class (stl/css :desc)}
[:h2 (tr "labels.upload-custom-fonts")]
[:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}]
[:button
{:class (stl/css :btn-primary)
:on-click on-click
:tab-index "0"}
[:span (tr "labels.add-custom-font")]
[:& file-uploader {:input-id "font-upload"
:accept cm/str-font-types
:multi true
:ref input-ref
:on-selected on-selected}]]
[:button
{:class (stl/css :btn-primary)
:on-click on-click
:tab-index "0"}
[:span (tr "labels.add-custom-font")]
[:& file-uploader {:input-id "font-upload"
:accept cm/str-font-types
:multi true
:ref input-ref
:on-selected on-selected}]]
[:div {:class (stl/css :banner)}
[:div {:class (stl/css :icon)} i/msg-info]
[:div {:class (stl/css :banner)}
[:div {:class (stl/css :icon)} i/msg-info]
[:div {:class (stl/css :content)}
[:& i18n/tr-html {:tag-name "span"
:label "dashboard.fonts.hero-text2"}]]]
(when problematic-fonts?
[:div {:class (stl/css :banner :warning)}
[:div {:class (stl/css :icon)} i/msg-warning]
[:div {:class (stl/css :content)}
[:& i18n/tr-html {:tag-name "span"
:label "dashboard.fonts.hero-text2"}]]]
:label "dashboard.fonts.warning-text"}]]])]]
(when problematic-fonts?
[:div {:class (stl/css :banner :warning)}
[:div {:class (stl/css :icon)} i/msg-warning]
[:div {:class (stl/css :content)}
[:& i18n/tr-html {:tag-name "span"
:label "dashboard.fonts.warning-text"}]]])]]
[:*
(when (some? (vals @fonts))
[:div {:class (stl/css :font-item :table-row)}
[:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals @fonts))))]
[:div {:class (stl/css :table-field :options)}
[:button {:class (stl/css :btn-primary)
:on-click handle-upload-all :data-test "upload-all"}
[:span (tr "dashboard.fonts.upload-all")]]
[:button {:class (stl/css :btn-secondary)
:on-click handle-dismiss-all :data-test "dismiss-all"}
[:span (tr "dashboard.fonts.dismiss-all")]]]])
(for [item (sort-by :font-family (vals @fonts))]
(let [uploading? (contains? @uploading (:id item))]
[:div {:class (stl/css :font-item :table-row) :key (:id item)}
[:div {:class (stl/css :table-field :family)}
[:input {:type "text"
:on-blur #(on-blur-name (:id item) %)
:default-value (:font-family item)}]]
[:div {:class (stl/css :table-field :variants)}
[:span {:class (stl/css :label)}
[:& font-variant-display-name {:variant item}]]]
[:div {:class (stl/css :table-field :filenames)}
(for [item (:names item)]
[:span item])]
[:*
(when (some? (vals @fonts))
[:div {:class (stl/css :font-item :table-row)}
[:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals @fonts))))]
[:div {:class (stl/css :table-field :options)}
[:button {:class (stl/css :btn-primary)
:on-click handle-upload-all :data-test "upload-all"}
[:span (tr "dashboard.fonts.upload-all")]]
[:button {:class (stl/css :btn-secondary)
:on-click handle-dismiss-all :data-test "dismiss-all"}
[:span (tr "dashboard.fonts.dismiss-all")]]]])
(when (:height-warning? item)
[:span {:class (stl/css :icon :failure)} i/msg-warning])
(for [item (sort-by :font-family (vals @fonts))]
(let [uploading? (contains? @uploading (:id item))]
[:div {:class (stl/css :font-item :table-row) :key (:id item)}
[:div {:class (stl/css :table-field :family)}
[:input {:type "text"
:on-blur #(on-blur-name (:id item) %)
:default-value (:font-family item)}]]
[:div {:class (stl/css :table-field :variants)}
[:span {:class (stl/css :label)}
[:& font-variant-display-name {:variant item}]]]
[:div {:class (stl/css :table-field :filenames)}
(for [item (:names item)]
[:span item])]
[:div {:class (stl/css :table-field :options)}
(when (:height-warning? item)
[:span {:class (stl/css :icon :failure)} i/msg-warning])
[:button
{:on-click #(on-upload item)
:class (stl/css-case :btn-primary true
:upload-button true
:disabled uploading?)
:disabled uploading?}
(if uploading?
(tr "labels.uploading")
(tr "labels.upload"))]
[:span {:class (stl/css :icon :close)
:on-click #(on-delete item)} i/close]]]))]]
;; OLD
[:div.dashboard-fonts-upload
[:div.dashboard-fonts-hero
[:div.desc
[:h2 (tr "labels.upload-custom-fonts")]
[:& i18n/tr-html {:label "dashboard.fonts.hero-text1"}]
[:div.banner
[:div.icon i/msg-info]
[:div.content
[:& i18n/tr-html {:tag-name "span"
:label "dashboard.fonts.hero-text2"}]]]
(when problematic-fonts?
[:div.banner.warning
[:div.icon i/msg-warning]
[:div.content
[:& i18n/tr-html {:tag-name "span"
:label "dashboard.fonts.warning-text"}]]])]
[:button.btn-primary
{:on-click on-click
:tab-index "0"}
[:span (tr "labels.add-custom-font")]
[:& file-uploader {:input-id "font-upload"
:accept cm/str-font-types
:multi true
:ref input-ref
:on-selected on-selected}]]]
[:*
(when (some? (vals @fonts))
[:div.font-item.table-row
[:span (tr "dashboard.fonts.fonts-added" (i18n/c (count (vals @fonts))))]
[:div.table-field.options
[:div.btn-primary
{:on-click #(on-upload-all (vals @fonts)) :data-test "upload-all"}
[:span (tr "dashboard.fonts.upload-all")]]
[:div.btn-secondary
{:on-click #(on-dismiss-all (vals @fonts)) :data-test "dismiss-all"}
[:span (tr "dashboard.fonts.dismiss-all")]]]])
(for [item (sort-by :font-family (vals @fonts))]
(let [uploading? (contains? @uploading (:id item))]
[:div.font-item.table-row {:key (:id item)}
[:div.table-field.family
[:input {:type "text"
:on-blur #(on-blur-name (:id item) %)
:default-value (:font-family item)}]]
[:div.table-field.variants
[:span.label
[:& font-variant-display-name {:variant item}]]]
[:div.table-field.filenames
(for [item (:names item)]
[:span item])]
[:div.table-field.options
(when (:height-warning? item)
[:span.icon.failure i/msg-warning])
[:button.btn-primary.upload-button
{:on-click #(on-upload item)
:class (dom/classnames :disabled uploading?)
:disabled uploading?}
(if uploading?
(tr "labels.uploading")
(tr "labels.upload"))]
[:span.icon.close {:on-click #(on-delete item)} i/close]]]))]])))
[:button
{:on-click #(on-upload item)
:class (stl/css-case :btn-primary true
:upload-button true
:disabled uploading?)
:disabled uploading?}
(if uploading?
(tr "labels.uploading")
(tr "labels.upload"))]
[:span {:class (stl/css :icon :close)
:on-click #(on-delete item)} i/close]]]))]]))
(mf/defc installed-font
[{:keys [font-id variants] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
font (first variants)
(let [font (first variants)
variants (sort-by (fn [item]
[(:font-weight item)
@ -324,94 +246,52 @@
:on-accept (fn [_props]
(delete-variant-fn id))})))]
(if new-css-system
[:div {:class (stl/css :font-item :table-row)}
[:div {:class (stl/css :table-field :family)}
(if @edit?
[:input {:type "text"
:default-value @state
:on-key-down on-key-down
:on-change on-change}]
[:span (:font-family font)])]
[:div {:class (stl/css :font-item :table-row)}
[:div {:class (stl/css :table-field :family)}
(if @edit?
[:input {:type "text"
:default-value @state
:on-key-down on-key-down
:on-change on-change}]
[:span (:font-family font)])]
[:div {:class (stl/css :table-field :variants)}
(for [item variants]
[:div {:class (stl/css :variant)}
[:span {:class (stl/css :label)}
[:& font-variant-display-name {:variant item}]]
[:span
{:class (stl/css :icon :close)
:on-click #(on-delete-variant (:id item))}
i/plus]])]
[:div {:class (stl/css :table-field :variants)}
(for [item variants]
[:div {:class (stl/css :variant)}
[:span {:class (stl/css :label)}
[:& font-variant-display-name {:variant item}]]
[:span
{:class (stl/css :icon :close)
:on-click #(on-delete-variant (:id item))}
i/plus]])]
(if @edit?
[:div {:class (stl/css :table-field :options)}
[:button
{:disabled (str/blank? @state)
:on-click on-save
:class (stl/css-case :btn-primary true
:btn-disabled (str/blank? @state))}
(tr "labels.save")]
[:button {:class (stl/css :icon :close)
:on-click on-cancel} i/close]]
(if @edit?
[:div {:class (stl/css :table-field :options)}
[:button
{:disabled (str/blank? @state)
:on-click on-save
:class (stl/css-case :btn-primary true
:btn-disabled (str/blank? @state))}
(tr "labels.save")]
[:button {:class (stl/css :icon :close)
:on-click on-cancel} i/close]]
[:div {:class (stl/css :table-field :options)}
[:span {:class (stl/css :icon)
:on-click #(reset! open-menu? true)} i/actions]
[:& context-menu
{:on-close #(reset! open-menu? false)
:show @open-menu?
:fixed? false
:top -15
:left -115
:options [[(tr "labels.edit") #(reset! edit? true) nil "font-edit"]
[(tr "labels.delete") on-delete nil "font-delete"]]}]])]
;;OLD
[:div.font-item.table-row
[:div.table-field.family
(if @edit?
[:input {:type "text"
:default-value @state
:on-key-down on-key-down
:on-change on-change}]
[:span (:font-family font)])]
[:div.table-field.variants
(for [item variants]
[:div.variant
[:span.label
[:& font-variant-display-name {:variant item}]]
[:span.icon.close
{:on-click #(on-delete-variant (:id item))}
i/plus]])]
[:div]
(if @edit?
[:div.table-field.options
[:button.btn-primary
{:disabled (str/blank? @state)
:on-click on-save
:class (dom/classnames :btn-disabled (str/blank? @state))}
(tr "labels.save")]
[:span.icon.close {:on-click on-cancel} i/close]]
[:div.table-field.options
[:span.icon {:on-click #(reset! open-menu? true)} i/actions]
[:& context-menu
{:on-close #(reset! open-menu? false)
:show @open-menu?
:fixed? false
:top -15
:left -115
:options [[(tr "labels.edit") #(reset! edit? true) nil "font-edit"]
[(tr "labels.delete") on-delete nil "font-delete"]]}]])])))
[:div {:class (stl/css :table-field :options)}
[:span {:class (stl/css :icon)
:on-click #(reset! open-menu? true)} i/actions]
[:& context-menu
{:on-close #(reset! open-menu? false)
:show @open-menu?
:fixed? false
:top -15
:left -115
:options [[(tr "labels.edit") #(reset! edit? true) nil "font-edit"]
[(tr "labels.delete") on-delete nil "font-delete"]]}]])]))
(mf/defc installed-fonts
[{:keys [fonts] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
sterm (mf/use-state "")
(let [sterm (mf/use-state "")
matches?
#(str/includes? (str/lower (:font-family %)) @sterm)
@ -422,98 +302,49 @@
(let [val (dom/get-target-val event)]
(reset! sterm (str/lower val)))))]
(if new-css-system
[:div {:class (stl/css :dashboard-installed-fonts)}
[:h3 (tr "labels.installed-fonts")]
[:div {:class (stl/css :installed-fonts-header)}
[:div {:class (stl/css :table-field :family)} (tr "labels.font-family")]
[:div {:class (stl/css :table-field :variants)} (tr "labels.font-variants")]
[:div {:class (stl/css :table-field :search-input)}
[:input {:placeholder (tr "labels.search-font")
:default-value ""
:on-change on-change}]]]
[:div {:class (stl/css :dashboard-installed-fonts)}
[:h3 (tr "labels.installed-fonts")]
[:div {:class (stl/css :installed-fonts-header)}
[:div {:class (stl/css :table-field :family)} (tr "labels.font-family")]
[:div {:class (stl/css :table-field :variants)} (tr "labels.font-variants")]
[:div {:class (stl/css :table-field :search-input)}
[:input {:placeholder (tr "labels.search-font")
:default-value ""
:on-change on-change}]]]
(cond
(seq fonts)
(for [[font-id variants] (->> (vals fonts)
(filter matches?)
(group-by :font-id))]
[:& installed-font {:key (str font-id)
:font-id font-id
:variants variants}])
(cond
(seq fonts)
(for [[font-id variants] (->> (vals fonts)
(filter matches?)
(group-by :font-id))]
[:& installed-font {:key (str font-id)
:font-id font-id
:variants variants}])
(nil? fonts)
[:div {:class (stl/css :fonts-placeholder)}
[:div {:class (stl/css :icon)} i/loader]
[:div {:class (stl/css :label)} (tr "dashboard.loading-fonts")]]
(nil? fonts)
[:div {:class (stl/css :fonts-placeholder)}
[:div {:class (stl/css :icon)} i/loader]
[:div {:class (stl/css :label)} (tr "dashboard.loading-fonts")]]
:else
[:div {:class (stl/css :fonts-placeholder)}
[:div {:class (stl/css :icon)} i/text]
[:div {:class (stl/css :label)} (tr "dashboard.fonts.empty-placeholder")]])]
;; OLD
[:div.dashboard-installed-fonts
[:h3 (tr "labels.installed-fonts")]
[:div.installed-fonts-header
[:div.table-field.family (tr "labels.font-family")]
[:div.table-field.variants (tr "labels.font-variants")]
[:div]
[:div.table-field.search-input
[:input {:placeholder (tr "labels.search-font")
:default-value ""
:on-change on-change}]]]
(cond
(seq fonts)
(for [[font-id variants] (->> (vals fonts)
(filter matches?)
(group-by :font-id))]
[:& installed-font {:key (str font-id)
:font-id font-id
:variants variants}])
(nil? fonts)
[:div.fonts-placeholder
[:div.icon i/loader]
[:div.label (tr "dashboard.loading-fonts")]]
:else
[:div.fonts-placeholder
[:div.icon i/text]
[:div.label (tr "dashboard.fonts.empty-placeholder")]])])))
:else
[:div {:class (stl/css :fonts-placeholder)}
[:div {:class (stl/css :icon)} i/text]
[:div {:class (stl/css :label)} (tr "dashboard.fonts.empty-placeholder")]])]))
(mf/defc fonts-page
[{:keys [team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
fonts (mf/deref refs/dashboard-fonts)]
(if new-css-system
[:*
[:& header {:team team :section :fonts}]
[:section {:class (stl/css :dashboard-container :dashboard-fonts)}
[:& fonts-upload {:team team :installed-fonts fonts}]
[:& installed-fonts {:team team :fonts fonts}]]]
;; OLD
[:*
[:& header {:team team :section :fonts}]
[:section.dashboard-container.dashboard-fonts
[:& fonts-upload {:team team :installed-fonts fonts}]
[:& installed-fonts {:team team :fonts fonts}]]])))
(let [fonts (mf/deref refs/dashboard-fonts)]
[:*
[:& header {:team team :section :fonts}]
[:section {:class (stl/css :dashboard-container :dashboard-fonts)}
[:& fonts-upload {:team team :installed-fonts fonts}]
[:& installed-fonts {:team team :fonts fonts}]]]))
(mf/defc font-providers-page
[{:keys [team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:*
[:& header {:team team :section :providers}]
[:section {:class (stl/css :dashboard-container)}
[:span "font providers"]]]
;; OLD
[:*
[:& header {:team team :section :providers}]
[:section.dashboard-container
[:span "font providers"]]])))
[:*
[:& header {:team team :section :providers}]
[:section {:class (stl/css :dashboard-container)}
[:span "font providers"]]])

View file

@ -20,7 +20,6 @@
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.components.color-bullet :as bc]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.file-menu :refer [file-menu]]
[app.main.ui.dashboard.import :refer [use-import-file]]
[app.main.ui.dashboard.inline-edition :refer [inline-edition]]
@ -68,8 +67,7 @@
(mf/defc grid-item-thumbnail
{::mf/wrap-props false}
[{:keys [file-id revn thumbnail-uri background-color]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
container (mf/use-ref)
(let [container (mf/use-ref)
visible? (h/use-visible container :once? true)]
(mf/with-effect [file-id revn visible? thumbnail-uri]
@ -83,28 +81,16 @@
:revn revn
:message (ex-message cause)))))))
(if new-css-system
[:div {:class (stl/css :grid-item-th)
:style {:background-color background-color}
:ref container}
(when visible?
(if thumbnail-uri
[:img {:class (stl/css :grid-item-thumbnail-image)
:src thumbnail-uri
:loading "lazy"
:decoding "async"}]
i/loader-pencil))]
;; OLD
[:div.grid-item-th
{:style {:background-color background-color}
:ref container}
(when visible?
(if thumbnail-uri
[:img.grid-item-thumbnail-image {:src thumbnail-uri
:loading "lazy"
:decoding "async"}]
i/loader-pencil))])))
[:div {:class (stl/css :grid-item-th)
:style {:background-color background-color}
:ref container}
(when visible?
(if thumbnail-uri
[:img {:class (stl/css :grid-item-thumbnail-image)
:src thumbnail-uri
:loading "lazy"
:decoding "async"}]
i/loader-pencil))]))
;; --- Grid Item Library
@ -112,228 +98,125 @@
{::mf/wrap [mf/memo]}
[{:keys [file] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(mf/with-effect [file]
(when file
(let [font-ids (map :font-id (get-in file [:library-summary :typographies :sample] []))]
(run! fonts/ensure-loaded! font-ids))))
(mf/with-effect [file]
(when file
(let [font-ids (map :font-id (get-in file [:library-summary :typographies :sample] []))]
(run! fonts/ensure-loaded! font-ids))))
(if new-css-system
[:div {:class (stl/css :grid-item-th :library)}
(if (nil? file)
i/loader-pencil
(let [summary (:library-summary file)
components (:components summary)
colors (:colors summary)
typographies (:typographies summary)]
[:*
(when (and (zero? (:count components)) (zero? (:count colors)) (zero? (:count typographies)))
[:*
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.components")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.colors")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.typography")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]]]) ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :grid-item-th :library)}
(if (nil? file)
i/loader-pencil
(let [summary (:library-summary file)
components (:components summary)
colors (:colors summary)
typographies (:typographies summary)]
[:*
(when (and (zero? (:count components)) (zero? (:count colors)) (zero? (:count typographies)))
[:*
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.components")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.colors")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.typography")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") 0 ")"]]]]) ;; Unicode 00A0 is non-breaking space
(when (pos? (:count components))
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.components")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count components) ")"]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-list)}
(for [component (:sample components)]
(let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library
[:div {:class (stl/css :asset-list-item)
:key (str "assets-component-" (:id component))}
[:& component-svg {:root-shape (get-in component [:objects root-id])
:objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)
:title (:name component)}
(:name component)]]]))
(when (> (:count components) (count (:sample components)))
[:div {:class (stl/css :asset-list-item)}
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)} "(...)"]]])]])
(when (pos? (:count components))
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.components")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count components) ")"]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-list)}
(for [component (:sample components)]
(let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library
[:div {:class (stl/css :asset-list-item)
:key (str "assets-component-" (:id component))}
[:& component-svg {:root-shape (get-in component [:objects root-id])
:objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)
:title (:name component)}
(:name component)]]]))
(when (> (:count components) (count (:sample components)))
[:div {:class (stl/css :asset-list-item)}
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)} "(...)"]]])]])
(when (pos? (:count colors))
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.colors")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count colors) ")"]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-list)}
(for [color (:sample colors)]
(let [default-name (cond
(:gradient color) (uc/gradient-type->string (get-in color [:gradient :type]))
(:color color) (:color color)
:else (:value color))]
[:div {:class (stl/css :asset-list-item)
:key (str "assets-color-" (:id color))}
[:& bc/color-bullet {:color {:color (:color color)
:opacity (:opacity color)}}]
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :color-name)} (:name color)]
(when-not (= (:name color) default-name)
[:span {:class (stl/css :color-value)} (:color color)])]]))
(when (pos? (:count colors))
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.colors")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count colors) ")"]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-list)}
(for [color (:sample colors)]
(let [default-name (cond
(:gradient color) (uc/gradient-type->string (get-in color [:gradient :type]))
(:color color) (:color color)
:else (:value color))]
[:div {:class (stl/css :asset-list-item)
:key (str "assets-color-" (:id color))}
[:& bc/color-bullet {:color {:color (:color color)
:opacity (:opacity color)}}]
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :color-name)} (:name color)]
(when-not (= (:name color) default-name)
[:span {:class (stl/css :color-value)} (:color color)])]]))
(when (> (:count colors) (count (:sample colors)))
[:div {:class (stl/css :asset-list-item)}
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)} "(...)"]]])]])
(when (> (:count colors) (count (:sample colors)))
[:div {:class (stl/css :asset-list-item)}
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)} "(...)"]]])]])
(when (pos? (:count typographies))
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.typography")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count typographies) ")"]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-list)}
(for [typography (:sample typographies)]
[:div {:class (stl/css :asset-list-item)
:key (str "assets-typography-" (:id typography))}
[:div {:class (stl/css :typography-sample)
:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")]
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)
:title (:name typography)}
(:name typography)]]])
(when (pos? (:count typographies))
[:div {:class (stl/css :asset-section)}
[:div {:class (stl/css :asset-title)}
[:span (tr "workspace.assets.typography")]
[:span {:class (stl/css :num-assets)} (str "\u00A0(") (:count typographies) ")"]] ;; Unicode 00A0 is non-breaking space
[:div {:class (stl/css :asset-list)}
(for [typography (:sample typographies)]
[:div {:class (stl/css :asset-list-item)
:key (str "assets-typography-" (:id typography))}
[:div {:class (stl/css :typography-sample)
:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")]
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)
:title (:name typography)}
(:name typography)]]])
(when (> (:count typographies) (count (:sample typographies)))
[:div {:class (stl/css :asset-list-item)}
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)} "(...)"]]])]])]))]
;; OLD
[:div.grid-item-th.library
(if (nil? file)
i/loader-pencil
(let [summary (:library-summary file)
components (:components summary)
colors (:colors summary)
typographies (:typographies summary)]
[:*
(when (and (zero? (:count components)) (zero? (:count colors)) (zero? (:count typographies)))
[:*
[:div.asset-section
[:div.asset-title
[:span (tr "workspace.assets.components")]
[:span.num-assets (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space
[:div.asset-section
[:div.asset-title
[:span (tr "workspace.assets.colors")]
[:span.num-assets (str "\u00A0(") 0 ")"]]] ;; Unicode 00A0 is non-breaking space
[:div.asset-section
[:div.asset-title
[:span (tr "workspace.assets.typography")]
[:span.num-assets (str "\u00A0(") 0 ")"]]]]) ;; Unicode 00A0 is non-breaking space
(when (pos? (:count components))
[:div.asset-section
[:div.asset-title
[:span (tr "workspace.assets.components")]
[:span.num-assets (str "\u00A0(") (:count components) ")"]] ;; Unicode 00A0 is non-breaking space
[:div.asset-list
(for [component (:sample components)]
(let [root-id (or (:main-instance-id component) (:id component))] ;; Check for components-v2 in library
[:div.asset-list-item {:key (str "assets-component-" (:id component))}
[:& component-svg {:root-shape (get-in component [:objects root-id])
:objects (:objects component)}] ;; Components in the summary come loaded with objects, even in v2
[:div.name-block
[:span.item-name {:title (:name component)}
(:name component)]]]))
(when (> (:count components) (count (:sample components)))
[:div.asset-list-item
[:div.name-block
[:span.item-name "(...)"]]])]])
(when (pos? (:count colors))
[:div.asset-section
[:div.asset-title
[:span (tr "workspace.assets.colors")]
[:span.num-assets (str "\u00A0(") (:count colors) ")"]] ;; Unicode 00A0 is non-breaking space
[:div.asset-list
(for [color (:sample colors)]
(let [default-name (cond
(:gradient color) (uc/gradient-type->string (get-in color [:gradient :type]))
(:color color) (:color color)
:else (:value color))]
[:div.asset-list-item {:key (str "assets-color-" (:id color))}
[:& bc/color-bullet {:color {:color (:color color)
:opacity (:opacity color)}}]
[:div.name-block
[:span.color-name (:name color)]
(when-not (= (:name color) default-name)
[:span.color-value (:color color)])]]))
(when (> (:count colors) (count (:sample colors)))
[:div.asset-list-item
[:div.name-block
[:span.item-name "(...)"]]])]])
(when (pos? (:count typographies))
[:div.asset-section
[:div.asset-title
[:span (tr "workspace.assets.typography")]
[:span.num-assets (str "\u00A0(") (:count typographies) ")"]] ;; Unicode 00A0 is non-breaking space
[:div.asset-list
(for [typography (:sample typographies)]
[:div.asset-list-item {:key (str "assets-typography-" (:id typography))}
[:div.typography-sample
{:style {:font-family (:font-family typography)
:font-weight (:font-weight typography)
:font-style (:font-style typography)}}
(tr "workspace.assets.typography.sample")]
[:div.name-block
[:span.item-name {:title (:name typography)}
(:name typography)]]])
(when (> (:count typographies) (count (:sample typographies)))
[:div.asset-list-item
[:div.name-block
[:span.item-name "(...)"]]])]])]))])))
(when (> (:count typographies) (count (:sample typographies)))
[:div {:class (stl/css :asset-list-item)}
[:div {:class (stl/css :name-block)}
[:span {:class (stl/css :item-name)} "(...)"]]])]])]))])
;; --- Grid Item
(mf/defc grid-item-metadata
[{:keys [modified-at]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
locale (mf/deref i18n/locale)
(let [locale (mf/deref i18n/locale)
time (dt/timeago modified-at {:locale locale})]
(if new-css-system
[:span {:class (stl/css :date)} time]
;; OLD
[:span.date time])))
[:span {:class (stl/css :date)} time]))
(defn create-counter-element
[_element file-count new-css-system]
(if new-css-system
(let [counter-el (dom/create-element "div")]
(dom/set-property! counter-el "class" (stl/css :drag-counter))
(dom/set-text! counter-el (str file-count))
counter-el)
(let [counter-el (dom/create-element "div")]
(dom/set-property! counter-el "class" "drag-counter")
(dom/set-text! counter-el (str file-count))
counter-el)))
[_element file-count]
(let [counter-el (dom/create-element "div")]
(dom/set-property! counter-el "class" (stl/css :drag-counter))
(dom/set-text! counter-el (str file-count))
counter-el))
(mf/defc grid-item
{:wrap [mf/memo]}
[{:keys [file navigate? origin library-view?] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
file-id (:id file)
(let [file-id (:id file)
local (mf/use-state {:menu-open false
:menu-pos nil
:edition false})
@ -380,8 +263,7 @@
item-el
(if select-current?
1
(count selected-files))
new-css-system)]
(count selected-files)))]
(when select-current?
(st/emit! (dd/clear-selected-files))
(st/emit! (dd/toggle-file-select file)))
@ -453,132 +335,67 @@
(when (and (not selected?) (:menu-open @local))
(swap! local assoc :menu-open false)))
(if new-css-system
[:li
{:class (stl/css-case :grid-item true :project-th true :library library-view?)}
[:button
{:class (stl/css-case :selected selected? :library library-view?)
:ref node-ref
:title (:name file)
:draggable true
:on-click on-select
:on-key-down handle-key-down
:on-double-click on-navigate
:on-drag-start on-drag-start
:on-context-menu on-menu-click}
[:li
{:class (stl/css-case :grid-item true :project-th true :library library-view?)}
[:button
{:class (stl/css-case :selected selected? :library library-view?)
:ref node-ref
:title (:name file)
:draggable true
:on-click on-select
:on-key-down handle-key-down
:on-double-click on-navigate
:on-drag-start on-drag-start
:on-context-menu on-menu-click}
[:div {:class (stl/css :overlay)}]
[:div {:class (stl/css :overlay)}]
(if library-view?
[:& grid-item-library {:file file}]
[:& grid-item-thumbnail
{:file-id (:id file)
:revn (:revn file)
:thumbnail-uri (:thumbnail-uri file)
:background-color (dm/get-in file [:data :options :background])}])
(if library-view?
[:& grid-item-library {:file file}]
[:& grid-item-thumbnail
{:file-id (:id file)
:revn (:revn file)
:thumbnail-uri (:thumbnail-uri file)
:background-color (dm/get-in file [:data :options :background])}])
(when (and (:is-shared file) (not library-view?))
[:div {:class (stl/css :item-badge)} i/library])
(when (and (:is-shared file) (not library-view?))
[:div {:class (stl/css :item-badge)} i/library])
[:div {:class (stl/css :info-wrapper)}
[:div {:class (stl/css :item-info)}
(if (:edition @local)
[:& inline-edition {:content (:name file)
:on-end edit}]
[:h3 (:name file)])
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
[:div {:class (stl/css :info-wrapper)}
[:div {:class (stl/css :item-info)}
(if (:edition @local)
[:& inline-edition {:content (:name file)
:on-end edit}]
[:h3 (:name file)])
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
[:div {:class (stl/css-case :project-th-actions true :force-display (:menu-open @local))}
[:div
{:class (stl/css :project-th-icon :menu)
:tab-index "0"
:ref menu-ref
:id (str file-id "-action-menu")
:on-click on-menu-click
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/stop-propagation event)
(on-menu-click event)))}
i/actions
(when selected?
[:& file-menu {:files (vals selected-files)
:show? (:menu-open @local)
:left (+ 24 (:x (:menu-pos @local)))
:top (:y (:menu-pos @local))
:navigate? navigate?
:on-edit on-edit
:on-menu-close on-menu-close
:origin origin
:dashboard-local dashboard-local
:parent-id (str file-id "-action-menu")}])]]]]]
;; OLD
[:li.grid-item.project-th {:class (dom/classnames :library library-view?)}
[:button
{:tab-index "0"
:class (dom/classnames :selected selected?
:library library-view?)
:ref node-ref
:draggable true
:on-click on-select
:on-key-down (fn [event]
(dom/stop-propagation event)
(when (kbd/enter? event)
(on-navigate event))
(when (kbd/shift? event)
(when (or (kbd/down-arrow? event) (kbd/left-arrow? event) (kbd/up-arrow? event) (kbd/right-arrow? event))
(on-select event)) ;; TODO Fix this
))
:on-double-click on-navigate
:on-drag-start on-drag-start
:on-context-menu on-menu-click}
[:div.overlay]
(if library-view?
[:& grid-item-library {:file file}]
[:& grid-item-thumbnail
{:file-id (:id file)
:revn (:revn file)
:thumbnail-uri (:thumbnail-uri file)
:background-color (dm/get-in file [:data :options :background])}])
(when (and (:is-shared file) (not library-view?))
[:div.item-badge i/library])
[:div.info-wrapper
[:div.item-info
(if (:edition @local)
[:& inline-edition {:content (:name file)
:on-end edit}]
[:h3 (:name file)])
[:& grid-item-metadata {:modified-at (:modified-at file)}]]
[:div.project-th-actions {:class (dom/classnames
:force-display (:menu-open @local))}
[:div.project-th-icon.menu
{:tab-index "0"
:ref menu-ref
:id (str file-id "-action-menu")
:on-click on-menu-click
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/stop-propagation event)
(on-menu-click event)))}
i/actions
(when selected?
[:& file-menu {:files (vals selected-files)
:show? (:menu-open @local)
:left (+ 24 (:x (:menu-pos @local)))
:top (:y (:menu-pos @local))
:navigate? navigate?
:on-edit on-edit
:on-menu-close on-menu-close
:origin origin
:dashboard-local dashboard-local
:parent-id (str file-id "-action-menu")}])]]]]])))
[:div {:class (stl/css-case :project-th-actions true :force-display (:menu-open @local))}
[:div
{:class (stl/css :project-th-icon :menu)
:tab-index "0"
:ref menu-ref
:id (str file-id "-action-menu")
:on-click on-menu-click
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/stop-propagation event)
(on-menu-click event)))}
i/actions
(when selected?
[:& file-menu {:files (vals selected-files)
:show? (:menu-open @local)
:left (+ 24 (:x (:menu-pos @local)))
:top (:y (:menu-pos @local))
:navigate? navigate?
:on-edit on-edit
:on-menu-close on-menu-close
:origin origin
:dashboard-local dashboard-local
:parent-id (str file-id "-action-menu")}])]]]]]))
(mf/defc grid
[{:keys [files project origin limit library-view? create-fn] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
dragging? (mf/use-state false)
(let [dragging? (mf/use-state false)
project-id (:id project)
node-ref (mf/use-var nil)
@ -621,109 +438,58 @@
(reset! dragging? false)
(import-files (.-files (.-dataTransfer e))))))]
(if new-css-system
[:div
{:class (stl/css :dashboard-grid)
:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop
:ref node-ref}
[:div {:class (stl/css :dashboard-grid)
:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop
:ref node-ref}
(cond
(nil? files)
[:& loading-placeholder]
(seq files)
(for [slice (partition-all limit files)]
[:ul {:class (stl/css :grid-row)}
(when @dragging?
[:li {:class (stl/css :grid-item)}])
(for [item slice]
[:& grid-item
{:file item
:key (:id item)
:navigate? true
:origin origin
:library-view? library-view?}])])
:else
[:& empty-placeholder
{:limit limit
:create-fn create-fn
:origin origin}])]
;; OLD
[:div.dashboard-grid
{:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop
:ref node-ref}
(cond
(nil? files)
[:& loading-placeholder]
(seq files)
[:ul.grid-row
{:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}}
(cond
(nil? files)
[:& loading-placeholder]
(seq files)
(for [slice (partition-all limit files)]
[:ul {:class (stl/css :grid-row)}
(when @dragging?
[:li.grid-item])
(for [item files]
[:li {:class (stl/css :grid-item)}])
(for [item slice]
[:& grid-item
{:file item
:key (:id item)
:navigate? true
:origin origin
:library-view? library-view?}])]
:library-view? library-view?}])])
:else
[:& empty-placeholder
{:limit limit
:create-fn create-fn
:origin origin}])])))
:else
[:& empty-placeholder
{:limit limit
:create-fn create-fn
:origin origin}])]))
(mf/defc line-grid-row
[{:keys [files selected-files dragging? limit] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
elements limit
(let [elements limit
limit (if dragging? (dec limit) limit)]
(if new-css-system
[:ul
{:class (stl/css :grid-row :no-wrap)
:style {:grid-template-columns (dm/str "repeat(" elements ", 1fr)")}}
[:ul
{:class (stl/css :grid-row :no-wrap)
:style {:grid-template-columns (dm/str "repeat(" elements ", 1fr)")}}
(when dragging?
[:li {:class (stl/css :grid-item :dragged)}])
(when dragging?
[:li {:class (stl/css :grid-item :dragged)}])
(for [item (take limit files)]
[:& grid-item
{:id (:id item)
:file item
:selected-files selected-files
:key (:id item)
:navigate? false}])]
;; OLD
[:ul.grid-row.no-wrap
{:style {:grid-template-columns (dm/str "repeat(" elements ", 1fr)")}}
(when dragging?
[:li.grid-item.dragged])
(for [item (take limit files)]
[:& grid-item
{:id (:id item)
:file item
:selected-files selected-files
:key (:id item)
:navigate? false}])])))
(for [item (take limit files)]
[:& grid-item
{:id (:id item)
:file item
:selected-files selected-files
:key (:id item)
:navigate? false}])]))
(mf/defc line-grid
[{:keys [project team files limit create-fn] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
dragging? (mf/use-state false)
(let [dragging? (mf/use-state false)
project-id (:id project)
team-id (:id team)
@ -799,47 +565,24 @@
(reset! dragging? false)
(import-files (.-files (.-dataTransfer e)))))))]
(if new-css-system
[:div {:class (stl/css :dashboard-grid)
:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop}
(cond
(nil? files)
[:& loading-placeholder]
[:div {:class (stl/css :dashboard-grid)
:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop}
(cond
(nil? files)
[:& loading-placeholder]
(seq files)
[:& line-grid-row {:files files
:team-id team-id
:selected-files selected-files
:dragging? @dragging?
:limit limit}]
(seq files)
[:& line-grid-row {:files files
:team-id team-id
:selected-files selected-files
:dragging? @dragging?
:limit limit}]
:else
[:& empty-placeholder
{:dragging? @dragging?
:limit limit
:create-fn create-fn}])]
;; OLD
[:div.dashboard-grid {:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop}
(cond
(nil? files)
[:& loading-placeholder]
(seq files)
[:& line-grid-row {:files files
:team-id team-id
:selected-files selected-files
:dragging? @dragging?
:limit limit}]
:else
[:& empty-placeholder
{:dragging? @dragging?
:limit limit
:create-fn create-fn}])])))
:else
[:& empty-placeholder
{:dragging? @dragging?
:limit limit
:create-fn create-fn}])]))

View file

@ -7,7 +7,6 @@
(ns app.main.ui.dashboard.inline-edition
(:require-macros [app.main.style :as stl])
(:require
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
@ -15,8 +14,7 @@
(mf/defc inline-edition
[{:keys [content on-end] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
name (mf/use-state content)
(let [name (mf/use-state content)
input-ref (mf/use-ref)
on-input
@ -62,25 +60,14 @@
(dom/focus! node)
(dom/select-text! node))))
(if new-css-system
[:div {:class (stl/css :edit-wrapper)}
[:input {:class (stl/css :element-title)
:value @name
:ref input-ref
:on-click on-click
:on-change on-input
:on-key-down on-keyup
:on-blur on-blur}]
[:span {:class (stl/css :close)
:on-click on-cancel} i/close]]
;; OLD
[:div.edit-wrapper
[:input.element-title {:value @name
:ref input-ref
:on-click on-click
:on-change on-input
:on-key-down on-keyup
:on-blur on-blur}]
[:span.close {:on-click on-cancel} i/close]])))
[:div {:class (stl/css :edit-wrapper)}
[:input {:class (stl/css :element-title)
:value @name
:ref input-ref
:on-click on-click
:on-change on-input
:on-key-down on-keyup
:on-blur on-blur}]
[:span {:class (stl/css :close)
:on-click on-cancel} i/close-refactor]]))

View file

@ -12,42 +12,42 @@
padding-right: $s-24;
position: relative;
margin-right: $s-24;
}
input.element-title {
background-color: $db-primary;
border-radius: $br-8;
color: $df-primary;
font-size: $fs-16;
height: $s-32;
margin: 0;
border: none;
padding: $s-6;
width: 100%;
input.element-title {
background-color: $db-primary;
border-radius: $br-8;
color: $df-primary;
font-size: $fs-16;
height: $s-32;
margin: 0;
border: none;
padding: $s-6;
width: 100%;
&:focus-visible {
border: $s-1 solid $da-primary;
outline: none;
}
&:focus-visible {
border: $s-1 solid $da-primary;
outline: none;
}
}
.close {
cursor: pointer;
position: absolute;
.close {
cursor: pointer;
position: absolute;
top: $s-1;
right: calc(-1 * $s-8);
top: $s-1;
right: calc(-1 * $s-8);
svg {
fill: $df-secondary;
height: $s-16;
transform: rotate(45deg) translateY(7px);
width: $s-16;
margin: 0;
}
&:hover {
svg {
fill: $df-secondary;
height: $s-16;
transform: rotate(45deg) translateY(7px);
width: $s-16;
margin: 0;
}
&:hover {
svg {
fill: var(--warning-color);
}
fill: var(--warning-color);
}
}
}

View file

@ -12,7 +12,6 @@
[app.main.features :as features]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.grid :refer [grid]]
[app.main.ui.hooks :as hooks]
[app.util.dom :as dom]
@ -21,8 +20,7 @@
(mf/defc libraries-page
[{:keys [team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
files-map (mf/deref refs/dashboard-shared-files)
(let [files-map (mf/deref refs/dashboard-shared-files)
projects (mf/deref refs/dashboard-projects)
default-project (->> projects vals (d/seek :is-default))
@ -49,27 +47,14 @@
(st/emit! (dd/fetch-shared-files (:id team))
(dd/clear-selected-files)))
(if new-css-system
[:*
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-libraries-title {:class (stl/css :dashboard-title)}
[:h1 (tr "dashboard.libraries-title")]]]
[:section {:class (stl/css :dashboard-container :no-bg :dashboard-shared) :ref rowref}
[:& grid {:files files
:project default-project
:origin :libraries
:limit limit
:library-view? components-v2}]]]
;; OLD
[:*
[:header.dashboard-header {:ref rowref}
[:div.dashboard-title#dashboard-libraries-title
[:h1 (tr "dashboard.libraries-title")]]]
[:section.dashboard-container.no-bg.dashboard-shared
[:& grid {:files files
:project default-project
:origin :libraries
:limit limit
:library-view? components-v2}]]])))
[:*
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-libraries-title {:class (stl/css :dashboard-title)}
[:h1 (tr "dashboard.libraries-title")]]]
[:section {:class (stl/css :dashboard-container :no-bg :dashboard-shared) :ref rowref}
[:& grid {:files files
:project default-project
:origin :libraries
:limit limit
:library-view? components-v2}]]]))

View file

@ -7,65 +7,39 @@
(ns app.main.ui.dashboard.placeholder
(:require-macros [app.main.style :as stl])
(:require
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
[rumext.v2 :as mf]))
(mf/defc empty-placeholder
[{:keys [dragging? limit origin create-fn] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-click
(let [on-click
(mf/use-fn
(mf/deps create-fn)
(fn [_]
(create-fn "dashboard:empty-folder-placeholder")))]
(if new-css-system
(cond
(true? dragging?)
[:ul
{:class (stl/css :grid-row :no-wrap)
:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}}
[:li {:class (stl/css :grid-item :grid-empty-placeholder :dragged)}]]
(cond
(true? dragging?)
[:ul
{:class (stl/css :grid-row :no-wrap)
:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}}
[:li {:class (stl/css :grid-item :grid-empty-placeholder :dragged)}]]
(= :libraries origin)
[:div {:class (stl/css :grid-empty-placeholder :libs)
:data-test "empty-placeholder"}
[:div {:class (stl/css :text)}
[:& i18n/tr-html {:label "dashboard.empty-placeholder-drafts"}]]]
(= :libraries origin)
[:div {:class (stl/css :grid-empty-placeholder :libs)
:data-test "empty-placeholder"}
[:div {:class (stl/css :text)}
[:& i18n/tr-html {:label "dashboard.empty-placeholder-drafts"}]]]
:else
[:div
{:class (stl/css :grid-empty-placeholder)}
[:button {:class (stl/css :create-new)
:on-click on-click}
i/add-refactor]])
;; OLD
(cond
(true? dragging?)
[:ul.grid-row.no-wrap
{:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}}
[:li.grid-item]]
(= :libraries origin)
[:div.grid-empty-placeholder.libs {:data-test "empty-placeholder"}
[:div.text
[:& i18n/tr-html {:label "dashboard.empty-placeholder-drafts"}]]]
:else
[:div.grid-empty-placeholder
{:style {:grid-template-columns (str "repeat(" limit ", 1fr)")}}
[:button.create-new {:on-click on-click} (tr "dashboard.new-file")]]))))
:else
[:div
{:class (stl/css :grid-empty-placeholder)}
[:button {:class (stl/css :create-new)
:on-click on-click}
i/add-refactor]])))
(mf/defc loading-placeholder
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :grid-empty-placeholder :loader)}
[:div {:class (stl/css :icon)} i/loader]
[:div {:class (stl/css :text)} (tr "dashboard.loading-files")]]
[:div.grid-empty-placeholder.loader
[:div.icon i/loader]
[:div.text (tr "dashboard.loading-files")]])))
[:div {:class (stl/css :grid-empty-placeholder :loader)}
[:div {:class (stl/css :icon)} i/loader]
[:div {:class (stl/css :text)} (tr "dashboard.loading-files")]])

View file

@ -18,7 +18,6 @@
[app.main.errors :as errors]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.grid :refer [line-grid]]
[app.main.ui.dashboard.inline-edition :refer [inline-edition]]
[app.main.ui.dashboard.project-menu :refer [project-menu]]
@ -37,32 +36,20 @@
(mf/defc header
{::mf/wrap [mf/memo]}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-click (mf/use-fn #(st/emit! (dd/create-project)))]
(if new-css-system
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-projects-title {:class (stl/css :dashboard-title)}
[:h1 (tr "dashboard.projects-title")]]
[:button
{:class (stl/css :btn-secondary :btn-small)
:on-click on-click
:data-test "new-project-button"}
(tr "dashboard.new-project")]]
;; OLD
[:header.dashboard-header
[:div.dashboard-title#dashboard-projects-title
[:h1 (tr "dashboard.projects-title")]]
[:button.btn-secondary.btn-small
{:on-click on-click
:data-test "new-project-button"}
(tr "dashboard.new-project")]])))
(let [on-click (mf/use-fn #(st/emit! (dd/create-project)))]
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-projects-title {:class (stl/css :dashboard-title)}
[:h1 (tr "dashboard.projects-title")]]
[:button
{:class (stl/css :btn-secondary :btn-small)
:on-click on-click
:data-test "new-project-button"}
(tr "dashboard.new-project")]]))
(mf/defc team-hero
{::mf/wrap [mf/memo]}
[{:keys [team close-fn] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-nav-members-click (mf/use-fn #(st/emit! (dd/go-to-team-members)))
(let [on-nav-members-click (mf/use-fn #(st/emit! (dd/go-to-team-members)))
on-invite-click
(mf/use-fn
@ -78,52 +65,33 @@
(dom/prevent-default event)
(close-fn)))]
(if new-css-system
[:div {:class (stl/css :team-hero)}
[:div {:class (stl/css :img-wrapper)}
[:img {:src "images/deco-team-banner.png"
:border "0"
:role "presentation"}]]
[:div {:class (stl/css :text)}
[:div {:class (stl/css :title)} (tr "dasboard.team-hero.title")]
[:div {:class (stl/css :info)}
[:span (tr "dasboard.team-hero.text")]
[:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]]
[:button
{:class (stl/css :btn-primary :invite)
:on-click on-invite-click}
(tr "onboarding.choice.team-up.invite-members")]]
[:div {:class (stl/css :team-hero)}
[:div {:class (stl/css :img-wrapper)}
[:img {:src "images/deco-team-banner.png"
:border "0"
:role "presentation"}]]
[:div {:class (stl/css :text)}
[:div {:class (stl/css :title)} (tr "dasboard.team-hero.title")]
[:div {:class (stl/css :info)}
[:span (tr "dasboard.team-hero.text")]
[:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]]
[:button
{:class (stl/css :btn-primary :invite)
:on-click on-invite-click}
(tr "onboarding.choice.team-up.invite-members")]]
[:button
{:class (stl/css :close)
:on-click on-close-click
:aria-label (tr "labels.close")}
[:span i/close]]]
;; OLD
[:div.team-hero
[:img {:src "images/deco-team-banner.png" :border "0"
:role "presentation"}]
[:div.text
[:div.title (tr "dasboard.team-hero.title")]
[:div.info
[:span (tr "dasboard.team-hero.text")]
[:a {:on-click on-nav-members-click} (tr "dasboard.team-hero.management")]]]
[:button.btn-primary.invite
{:on-click on-invite-click}
(tr "onboarding.choice.team-up.invite-members")]
[:button.close
{:on-click on-close-click
:aria-label (tr "labels.close")}
[:span i/close]]])))
[:button
{:class (stl/css :close)
:on-click on-close-click
:aria-label (tr "labels.close")}
[:span i/close]]]))
(def builtin-templates
(l/derived :builtin-templates st/state))
(mf/defc tutorial-project
[{:keys [close-tutorial default-project-id] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
state (mf/use-state {:status :waiting
(let [state (mf/use-state {:status :waiting
:file nil})
templates (mf/deref builtin-templates)
@ -155,88 +123,51 @@
(swap! state #(assoc % :status :importing))
(st/emit! (with-meta (dd/clone-template (with-meta params mdata))
{::ev/origin "get-started-hero-block"})))))]
(if new-css-system
[:article {:class (stl/css :tutorial)}
[:div {:class (stl/css :thumbnail)}]
[:div {:class (stl/css :text)}
[:h2 {:class (stl/css :title)} (tr "dasboard.tutorial-hero.title")]
[:p {:class (stl/css :info)} (tr "dasboard.tutorial-hero.info")]
[:button {:class (stl/css :btn-primary :action)
:on-click download-tutorial}
(case (:status @state)
:waiting (tr "dasboard.tutorial-hero.start")
:importing [:span.loader i/loader-pencil]
:success "")]]
[:article {:class (stl/css :tutorial)}
[:div {:class (stl/css :thumbnail)}]
[:div {:class (stl/css :text)}
[:h2 {:class (stl/css :title)} (tr "dasboard.tutorial-hero.title")]
[:p {:class (stl/css :info)} (tr "dasboard.tutorial-hero.info")]
[:button {:class (stl/css :btn-primary :action)
:on-click download-tutorial}
(case (:status @state)
:waiting (tr "dasboard.tutorial-hero.start")
:importing [:span.loader i/loader-pencil]
:success "")]]
[:button
{:class (stl/css :close)
:on-click close-tutorial
:aria-label (tr "labels.close")}
[:span {:class (stl/css :icon)} i/close]]]
;; OLD
[:article.tutorial
[:div.thumbnail]
[:div.text
[:h2.title (tr "dasboard.tutorial-hero.title")]
[:p.info (tr "dasboard.tutorial-hero.info")]
[:button.btn-primary.action {:on-click download-tutorial}
(case (:status @state)
:waiting (tr "dasboard.tutorial-hero.start")
:importing [:span.loader i/loader-pencil]
:success "")]]
[:button.close
{:on-click close-tutorial
:aria-label (tr "labels.close")}
[:span.icon i/close]]])))
[:button
{:class (stl/css :close)
:on-click close-tutorial
:aria-label (tr "labels.close")}
[:span {:class (stl/css :icon)} i/close]]]))
(mf/defc interface-walkthrough
{::mf/wrap [mf/memo]}
[{:keys [close-walkthrough] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
handle-walkthrough-link
(let [handle-walkthrough-link
(fn []
(st/emit! (ptk/event ::ev/event {::ev/name "show-walkthrough"
::ev/origin "get-started-hero-block"
:section "dashboard"})))]
(if new-css-system
[:article {:class (stl/css :walkthrough)}
[:div {:class (stl/css :thumbnail)}]
[:div {:class (stl/css :text)}
[:h2 {:class (stl/css :title)} (tr "dasboard.walkthrough-hero.title")]
[:p {:class (stl/css :info)} (tr "dasboard.walkthrough-hero.info")]
[:a {:class (stl/css :btn-primary :action)
:href " https://design.penpot.app/walkthrough"
:target "_blank"
:on-click handle-walkthrough-link}
(tr "dasboard.walkthrough-hero.start")]]
[:button
{:class (stl/css :close)
:on-click close-walkthrough
:aria-label (tr "labels.close")}
[:span {:class (stl/css :icon)} i/close]]]
;; OLD
[:article.walkthrough
[:div.thumbnail]
[:div.text
[:h2.title (tr "dasboard.walkthrough-hero.title")]
[:p.info (tr "dasboard.walkthrough-hero.info")]
[:a.btn-primary.action
{:href " https://design.penpot.app/walkthrough"
:target "_blank"
:on-click handle-walkthrough-link}
(tr "dasboard.walkthrough-hero.start")]]
[:button.close
{:on-click close-walkthrough
:aria-label (tr "labels.close")}
[:span.icon i/close]]])))
[:article {:class (stl/css :walkthrough)}
[:div {:class (stl/css :thumbnail)}]
[:div {:class (stl/css :text)}
[:h2 {:class (stl/css :title)} (tr "dasboard.walkthrough-hero.title")]
[:p {:class (stl/css :info)} (tr "dasboard.walkthrough-hero.info")]
[:a {:class (stl/css :btn-primary :action)
:href " https://design.penpot.app/walkthrough"
:target "_blank"
:on-click handle-walkthrough-link}
(tr "dasboard.walkthrough-hero.start")]]
[:button
{:class (stl/css :close)
:on-click close-walkthrough
:aria-label (tr "labels.close")}
[:span {:class (stl/css :icon)} i/close]]]))
(mf/defc project-item
[{:keys [project first? team files] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
locale (mf/deref i18n/locale)
(let [locale (mf/deref i18n/locale)
file-count (or (:count project) 0)
project-id (:id project)
team-id (:id team)
@ -344,166 +275,85 @@
(dom/stop-propagation event)
(on-menu-click event))))]
(if new-css-system
[:article {:class (stl/css-case :dashboard-project-row true :first first?)}
[:header {:class (stl/css :project)}
[:div {:class (stl/css :project-name-wrapper)}
(if (:edition? @local)
[:& inline-edition {:content (:name project)
:on-end on-edit}]
[:h2 {:on-click on-nav
:on-context-menu on-menu-click}
(if (:is-default project)
(tr "labels.drafts")
(:name project))])
[:article {:class (stl/css-case :dashboard-project-row true :first first?)}
[:header {:class (stl/css :project)}
[:div {:class (stl/css :project-name-wrapper)}
(if (:edition? @local)
[:& inline-edition {:content (:name project)
:on-end on-edit}]
[:h2 {:on-click on-nav
:on-context-menu on-menu-click}
(if (:is-default project)
(tr "labels.drafts")
(:name project))])
[:& project-menu
{:project project
:show? (:menu-open @local)
:left (+ 24 (:x (:menu-pos @local)))
:top (:y (:menu-pos @local))
:on-edit on-edit-open
:on-menu-close on-menu-close
:on-import on-import}]
[:span {:class (stl/css :info)} (str (tr "labels.num-of-files" (i18n/c file-count)))]
(let [time (-> (:modified-at project)
(dt/timeago {:locale locale}))]
[:span {:class (stl/css :recent-files-row-title-info)} (str ", " time)])
[:div {:class (stl/css :project-actions)}
(when-not (:is-default project)
[:button
{:class (stl/css-case :pin-icon true
:tooltip true
:tooltip-bottom true
:active (:is-pinned project))
:on-click toggle-pin
:alt (tr "dashboard.pin-unpin")
:aria-label (tr "dashboard.pin-unpin")
:tab-index "0"}
(if (:is-pinned project)
i/pin-fill
i/pin)])
[:button
{:class (stl/css :btn-secondary :btn-small :tooltip :tooltip-bottom)
:on-click on-create-click
:alt (tr "dashboard.new-file")
:aria-label (tr "dashboard.new-file")
:data-test "project-new-file"
:on-key-down handle-create-click}
i/close]
[:button
{:class (stl/css :btn-secondary :btn-small :tooltip :tooltip-bottom)
:on-click on-menu-click
:alt (tr "dashboard.options")
:aria-label (tr "dashboard.options")
:data-test "project-options"
:on-key-down handle-menu-click}
i/actions]]]]
[:div {:class (stl/css :grid-container) :ref rowref}
[:& line-grid
{:project project
:team team
:files files
:create-fn create-file
:limit limit}]]
(when (and (> limit 0)
(> file-count limit))
[:button
{:class (stl/css :show-more)
:on-click on-nav
:tab-index "0"
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-nav)))}
[:div {:class (stl/css :placeholder-label)} (tr "dashboard.show-all-files")]
[:div {:class (stl/css :placeholder-icon)} i/arrow-down]])]
;; OLD
[:article.dashboard-project-row
{:class (when first? "first")}
[:header.project {:ref rowref}
[:div.project-name-wrapper
(if (:edition? @local)
[:& inline-edition {:content (:name project)
:on-end on-edit}]
[:h2 {:on-click on-nav
:on-context-menu on-menu-click}
(if (:is-default project)
(tr "labels.drafts")
(:name project))])
[:& project-menu
{:project project
:show? (:menu-open @local)
:left (+ 24 (:x (:menu-pos @local)))
:top (:y (:menu-pos @local))
:on-edit on-edit-open
:on-menu-close on-menu-close
:on-import on-import}]
[:span.info (str (tr "labels.num-of-files" (i18n/c file-count)))]
(let [time (-> (:modified-at project)
(dt/timeago {:locale locale}))]
[:span.recent-files-row-title-info (str ", " time)])
[:div.project-actions
(when-not (:is-default project)
[:button.pin-icon.tooltip.tooltip-bottom
{:class (when (:is-pinned project) "active")
:on-click toggle-pin
:alt (tr "dashboard.pin-unpin")
:aria-label (tr "dashboard.pin-unpin")
:tab-index "0"}
(if (:is-pinned project)
i/pin-fill
i/pin)])
[:button.btn-secondary.btn-small.tooltip.tooltip-bottom
{:on-click on-create-click
:alt (tr "dashboard.new-file")
:aria-label (tr "dashboard.new-file")
:data-test "project-new-file"
:tab-index "0"
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-create-click event)))}
i/close]
[:button.btn-secondary.btn-small.tooltip.tooltip-bottom
{:on-click on-menu-click
:alt (tr "dashboard.options")
:aria-label (tr "dashboard.options")
:data-test "project-options"
:tab-index "0"
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/stop-propagation event)
(on-menu-click event)))}
i/actions]]]]
[:& line-grid
[:& project-menu
{:project project
:team team
:files files
:create-fn create-file
:limit limit}]
:show? (:menu-open @local)
:left (+ 24 (:x (:menu-pos @local)))
:top (:y (:menu-pos @local))
:on-edit on-edit-open
:on-menu-close on-menu-close
:on-import on-import}]
(when (and (> limit 0)
(> file-count limit))
[:button.show-more {:on-click on-nav
:tab-index "0"
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-nav)))}
[:div.placeholder-label
(tr "dashboard.show-all-files")]
[:div.placeholder-icon i/arrow-down]])])))
[:span {:class (stl/css :info)} (str (tr "labels.num-of-files" (i18n/c file-count)))]
(let [time (-> (:modified-at project)
(dt/timeago {:locale locale}))]
[:span {:class (stl/css :recent-files-row-title-info)} (str ", " time)])
[:div {:class (stl/css :project-actions)}
(when-not (:is-default project)
[:button
{:class (stl/css-case :pin-icon true
:tooltip true
:tooltip-bottom true
:active (:is-pinned project))
:on-click toggle-pin
:alt (tr "dashboard.pin-unpin")
:aria-label (tr "dashboard.pin-unpin")
:tab-index "0"}
(if (:is-pinned project)
i/pin-fill
i/pin)])
[:button
{:class (stl/css :btn-secondary :btn-small :tooltip :tooltip-bottom)
:on-click on-create-click
:alt (tr "dashboard.new-file")
:aria-label (tr "dashboard.new-file")
:data-test "project-new-file"
:on-key-down handle-create-click}
i/close]
[:button
{:class (stl/css :btn-secondary :btn-small :tooltip :tooltip-bottom)
:on-click on-menu-click
:alt (tr "dashboard.options")
:aria-label (tr "dashboard.options")
:data-test "project-options"
:on-key-down handle-menu-click}
i/actions]]]]
[:div {:class (stl/css :grid-container) :ref rowref}
[:& line-grid
{:project project
:team team
:files files
:create-fn create-file
:limit limit}]]
(when (and (> limit 0)
(> file-count limit))
[:button
{:class (stl/css :show-more)
:on-click on-nav
:tab-index "0"
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-nav)))}
[:div {:class (stl/css :placeholder-label)} (tr "dashboard.show-all-files")]
[:div {:class (stl/css :placeholder-icon)} i/arrow-down]])]))
(def recent-files-ref
@ -511,8 +361,7 @@
(mf/defc projects-section
[{:keys [team projects profile default-project-id] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
projects (->> (vals projects)
(let [projects (->> (vals projects)
(sort-by :modified-at)
(reverse))
recent-map (mf/deref recent-files-ref)
@ -562,68 +411,34 @@
(st/emit! (dd/fetch-recent-files team-id)
(dd/clear-selected-files)))
(if new-css-system
(when (seq projects)
[:*
[:& header]
(when (seq projects)
[:*
[:& header]
(when team-hero?
[:& team-hero {:team team :close-fn close-banner}])
(when team-hero?
[:& team-hero {:team team :close-fn close-banner}])
(when (and (contains? cf/flags :dashboard-templates-section)
(or (not tutorial-viewed?)
(not walkthrough-viewed?)))
[:div {:class (stl/css :hero-projects)}
(when (and (not tutorial-viewed?) (:is-default team))
[:& tutorial-project
{:close-tutorial close-tutorial
:default-project-id default-project-id}])
(when (and (contains? cf/flags :dashboard-templates-section)
(or (not tutorial-viewed?)
(not walkthrough-viewed?)))
[:div {:class (stl/css :hero-projects)}
(when (and (not tutorial-viewed?) (:is-default team))
[:& tutorial-project
{:close-tutorial close-tutorial
:default-project-id default-project-id}])
(when (and (not walkthrough-viewed?) (:is-default team))
[:& interface-walkthrough
{:close-walkthrough close-walkthrough}])])
(when (and (not walkthrough-viewed?) (:is-default team))
[:& interface-walkthrough
{:close-walkthrough close-walkthrough}])])
[:div {:class (stl/css :dashboard-container :no-bg :dashboard-projects)}
(for [{:keys [id] :as project} projects]
(let [files (when recent-map
(->> (vals recent-map)
(filterv #(= id (:project-id %)))
(sort-by :modified-at #(compare %2 %1))))]
[:& project-item {:project project
:team team
:files files
:first? (= project (first projects))
:key id}]))]])
;; OLD
(when (seq projects)
[:*
[:& header]
(when team-hero?
[:& team-hero {:team team :close-fn close-banner}])
(when (and (contains? cf/flags :dashboard-templates-section)
(or (not tutorial-viewed?)
(not walkthrough-viewed?)))
[:div.hero-projects
(when (and (not tutorial-viewed?) (:is-default team))
[:& tutorial-project
{:close-tutorial close-tutorial
:default-project-id default-project-id}])
(when (and (not walkthrough-viewed?) (:is-default team))
[:& interface-walkthrough
{:close-walkthrough close-walkthrough}])])
[:div.dashboard-container.no-bg.dashboard-projects
(for [{:keys [id] :as project} projects]
(let [files (when recent-map
(->> (vals recent-map)
(filterv #(= id (:project-id %)))
(sort-by :modified-at #(compare %2 %1))))]
[:& project-item {:project project
:team team
:files files
:first? (= project (first projects))
:key id}]))]]))))
[:div {:class (stl/css :dashboard-container :no-bg :dashboard-projects)}
(for [{:keys [id] :as project} projects]
(let [files (when recent-map
(->> (vals recent-map)
(filterv #(= id (:project-id %)))
(sort-by :modified-at #(compare %2 %1))))]
[:& project-item {:project project
:team team
:files files
:first? (= project (first projects))
:key id}]))]])))

View file

@ -10,7 +10,6 @@
[app.main.data.dashboard :as dd]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.grid :refer [grid]]
[app.main.ui.hooks :as hooks]
[app.main.ui.icons :as i]
@ -20,8 +19,7 @@
(mf/defc search-page
[{:keys [team search-term] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
result (mf/deref refs/dashboard-search-result)
(let [result (mf/deref refs/dashboard-search-result)
[rowref limit] (hooks/use-dynamic-grid-item-width)]
(mf/use-effect
@ -38,61 +36,31 @@
(fn []
(st/emit! (dd/search {:search-term search-term})
(dd/clear-selected-files))))
(if new-css-system
[:*
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-search-title {:class (stl/css :dashboard-title)}
[:h1 (tr "dashboard.title-search")]]]
[:*
[:header {:class (stl/css :dashboard-header)}
[:div#dashboard-search-title {:class (stl/css :dashboard-title)}
[:h1 (tr "dashboard.title-search")]]]
[:section {:class (stl/css :dashboard-container :search :no-bg)
:ref rowref}
(cond
(empty? search-term)
[:div {:class (stl/css :grid-empty-placeholder :search)}
[:div {:class (stl/css :icon)} i/search]
[:div {:class (stl/css :text)} (tr "dashboard.type-something")]]
[:section {:class (stl/css :dashboard-container :search :no-bg)
:ref rowref}
(cond
(empty? search-term)
[:div {:class (stl/css :grid-empty-placeholder :search)}
[:div {:class (stl/css :icon)} i/search]
[:div {:class (stl/css :text)} (tr "dashboard.type-something")]]
(nil? result)
[:div {:class (stl/css :grid-empty-placeholder :search)}
[:div {:class (stl/css :icon)} i/search]
[:div {:class (stl/css :text)} (tr "dashboard.searching-for" search-term)]]
(nil? result)
[:div {:class (stl/css :grid-empty-placeholder :search)}
[:div {:class (stl/css :icon)} i/search]
[:div {:class (stl/css :text)} (tr "dashboard.searching-for" search-term)]]
(empty? result)
[:div {:class (stl/css :grid-empty-placeholder :search)}
[:div {:class (stl/css :icon)} i/search]
[:div {:class (stl/css :text)} (tr "dashboard.no-matches-for" search-term)]]
(empty? result)
[:div {:class (stl/css :grid-empty-placeholder :search)}
[:div {:class (stl/css :icon)} i/search]
[:div {:class (stl/css :text)} (tr "dashboard.no-matches-for" search-term)]]
:else
[:& grid {:files result
:hide-new? true
:origin :search
:limit limit}])]]
;; OLD
[:*
[:header.dashboard-header
[:div.dashboard-title#dashboard-search-title
[:h1 (tr "dashboard.title-search")]]]
[:section.dashboard-container.search.no-bg {:ref rowref}
(cond
(empty? search-term)
[:div.grid-empty-placeholder.search
[:div.icon i/search]
[:div.text (tr "dashboard.type-something")]]
(nil? result)
[:div.grid-empty-placeholder.search
[:div.icon i/search]
[:div.text (tr "dashboard.searching-for" search-term)]]
(empty? result)
[:div.grid-empty-placeholder.search
[:div.icon i/search]
[:div.text (tr "dashboard.no-matches-for" search-term)]]
:else
[:& grid {:files result
:hide-new? true
:origin :search
:limit limit}])]])))
:else
[:& grid {:files result
:hide-new? true
:origin :search
:limit limit}])]]))

View file

@ -20,7 +20,6 @@
[app.main.store :as st]
[app.main.ui.components.dropdown-menu :refer [dropdown-menu dropdown-menu-item*]]
[app.main.ui.components.link :refer [link]]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.comments :refer [comments-icon comments-section]]
[app.main.ui.dashboard.inline-edition :refer [inline-edition]]
[app.main.ui.dashboard.project-menu :refer [project-menu]]
@ -41,8 +40,7 @@
(mf/defc sidebar-project
[{:keys [item selected?] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
dstate (mf/deref refs/dashboard-local)
(let [dstate (mf/deref refs/dashboard-local)
selected-files (:selected-files dstate)
selected-project (:selected-project dstate)
edit-id (:project-for-edit dstate)
@ -136,59 +134,33 @@
mdata {:on-success on-drop-success}]
(st/emit! (dd/move-files (with-meta data mdata)))))))]
(if new-css-system
[:*
[:li {:tab-index "0"
:class (stl/css-case :project-element true
:current selected?
:dragging (:dragging? local))
:on-click on-click
:on-key-down on-key-down
:on-double-click on-edit-open
:on-context-menu on-menu-click
:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop}
(if (:edition? local)
[:& inline-edition {:content (:name item)
:on-end on-edit}]
[:span {:class (stl/css :element-title)} (:name item)])]
[:& project-menu {:project item
:show? (:menu-open local)
:left (:x (:menu-pos local))
:top (:y (:menu-pos local))
:on-edit on-edit-open
:on-menu-close on-menu-close}]]
;; OLD
[:*
[:li {:tab-index "0"
:class (if selected? "current"
(when (:dragging? local) "dragging"))
:on-click on-click
:on-key-down on-key-down
:on-double-click on-edit-open
:on-context-menu on-menu-click
:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop}
(if (:edition? local)
[:& inline-edition {:content (:name item)
:on-end on-edit}]
[:span.element-title (:name item)])]
[:& project-menu {:project item
:show? (:menu-open local)
:left (:x (:menu-pos local))
:top (:y (:menu-pos local))
:on-edit on-edit-open
:on-menu-close on-menu-close}]])))
[:*
[:li {:tab-index "0"
:class (stl/css-case :project-element true
:current selected?
:dragging (:dragging? local))
:on-click on-click
:on-key-down on-key-down
:on-double-click on-edit-open
:on-context-menu on-menu-click
:on-drag-enter on-drag-enter
:on-drag-over on-drag-over
:on-drag-leave on-drag-leave
:on-drop on-drop}
(if (:edition? local)
[:& inline-edition {:content (:name item)
:on-end on-edit}]
[:span {:class (stl/css :element-title)} (:name item)])]
[:& project-menu {:project item
:show? (:menu-open local)
:left (:x (:menu-pos local))
:top (:y (:menu-pos local))
:on-edit on-edit-open
:on-menu-close on-menu-close}]]))
(mf/defc sidebar-search
[{:keys [search-term team-id] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
search-term (or search-term "")
(let [search-term (or search-term "")
focused? (mf/use-state false)
emit! (mf/use-memo #(f/debounce st/emit! 500))
@ -236,70 +208,39 @@
(when (kbd/enter? event)
(on-clear-click event))))]
(if new-css-system
[:form {:class (stl/css :sidebar-search)}
[:input
{:class (stl/css :input-text)
:key "images-search-box"
:id "search-input"
:type "text"
:aria-label (tr "dashboard.search-placeholder")
:placeholder (tr "dashboard.search-placeholder")
:default-value search-term
:auto-complete "off"
;; :on-focus on-search-focus
:on-blur on-search-blur
:on-change on-search-change
:on-key-press on-key-press
:ref #(when % (set! (.-value %) search-term))}]
[:form {:class (stl/css :sidebar-search)}
[:input
{:class (stl/css :input-text)
:key "images-search-box"
:id "search-input"
:type "text"
:aria-label (tr "dashboard.search-placeholder")
:placeholder (tr "dashboard.search-placeholder")
:default-value search-term
:auto-complete "off"
;; :on-focus on-search-focus
:on-blur on-search-blur
:on-change on-search-change
:on-key-press on-key-press
:ref #(when % (set! (.-value %) search-term))}]
(if (or @focused? (seq search-term))
[:div
{:class (stl/css :clear-search)
:tab-index "0"
:on-click on-clear-click
:on-key-down handle-clear-search}
i/close]
(if (or @focused? (seq search-term))
[:div
{:class (stl/css :clear-search)
:tab-index "0"
:on-click on-clear-click
:on-key-down handle-clear-search}
i/close]
[:div
{:class (stl/css :search)
:on-click on-clear-click}
i/search])]
;; OLD
[:form.sidebar-search
[:input.input-text
{:key "images-search-box"
:id "search-input"
:type "text"
:aria-label (tr "dashboard.search-placeholder")
:placeholder (tr "dashboard.search-placeholder")
:default-value search-term
:auto-complete "off"
;; :on-focus on-search-focus
:on-blur on-search-blur
:on-change on-search-change
:on-key-press on-key-press
:ref #(when % (set! (.-value %) search-term))}]
(if (or @focused? (seq search-term))
[:div.clear-search
{:tab-index "0"
:on-click on-clear-click
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-clear-click event)))}
i/close]
[:div.search
{:on-click on-clear-click}
i/search])])))
[:div
{:class (stl/css :search)
:on-click on-clear-click}
i/search])]))
(mf/defc teams-selector-dropdown-items
{::mf/wrap-props false}
[{:keys [team profile teams] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-create-clicked
(let [on-create-clicked
(mf/use-callback
#(st/emit! (modal/show :team-form {})))
@ -318,76 +259,38 @@
(when (kbd/enter? event)
(team-selected id event)))]
(if new-css-system
[:*
[:> dropdown-menu-item* {:on-click (partial team-selected (:default-team-id profile))
:on-key-down handle-select-default
:id "teams-selector-default-team"
:class (stl/css :team-name)}
[:span {:class (stl/css :team-icon)} i/logo-icon]
[:span {:class (stl/css :team-text)} (tr "dashboard.your-penpot")]
(when (= (:default-team-id profile) (:id team))
[:span {:class (stl/css :icon)} i/tick])]
[:*
[:> dropdown-menu-item* {:on-click (partial team-selected (:default-team-id profile))
:on-key-down handle-select-default
:id "teams-selector-default-team"
:class (stl/css :team-name)}
[:span {:class (stl/css :team-icon)} i/logo-icon]
[:span {:class (stl/css :team-text)} (tr "dashboard.your-penpot")]
(when (= (:default-team-id profile) (:id team))
[:span {:class (stl/css :icon)} i/tick])]
(for [team-item (remove :is-default (vals teams))]
[:> dropdown-menu-item* {:on-click (partial team-selected (:id team-item))
:on-key-down (partial handle-select-team (:id team-item))
:id (str "teams-selector-" (:id team-item))
:class (stl/css :team-name)
:key (str "teams-selector-" (:id team-item))}
[:span {:class (stl/css :team-icon)}
[:img {:src (cf/resolve-team-photo-url team-item)
:alt (:name team-item)}]]
[:span {:class (stl/css :team-text)
:title (:name team-item)} (:name team-item)]
(when (= (:id team-item) (:id team))
[:span {:class (stl/css :icon)} i/tick])])
[:hr {:role "separator"}]
[:> dropdown-menu-item* {:on-click on-create-clicked
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-create-clicked event)))
:id "teams-selector-create-team"
:class (stl/css :team-name :action)}
[:span {:class (stl/css :team-icon :new-team)} i/close]
[:span {:class (stl/css :team-text)} (tr "dashboard.create-new-team")]]]
;; OLD
[:*
[:> dropdown-menu-item* {:on-click (partial team-selected (:default-team-id profile))
:on-key-down (fn [event]
(when (kbd/enter? event)
(team-selected (:default-team-id profile) event)))
:id "teams-selector-default-team"
:class "team-name"}
[:span.team-icon i/logo-icon]
[:span.team-text (tr "dashboard.your-penpot")]
(when (= (:default-team-id profile) (:id team))
[:span.icon i/tick])]
(for [team-item (remove :is-default (vals teams))]
[:> dropdown-menu-item* {:on-click (partial team-selected (:id team-item))
:on-key-down (fn [event]
(when (kbd/enter? event)
(team-selected (:id team-item) event)))
:id (str "teams-selector-" (:id team-item))
:class "team-name"
:key (str "teams-selector-" (:id team-item))}
[:span.team-icon
[:img {:src (cf/resolve-team-photo-url team-item)
:alt (:name team-item)}]]
[:span.team-text {:title (:name team-item)} (:name team-item)]
(when (= (:id team-item) (:id team))
[:span.icon i/tick])])
[:hr {:role "separator"}]
[:> dropdown-menu-item* {:on-click on-create-clicked
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-create-clicked event)))
:id "teams-selector-create-team"
:class "team-name action"}
[:span.team-icon.new-team i/close]
[:span.team-text (tr "dashboard.create-new-team")]]])))
(for [team-item (remove :is-default (vals teams))]
[:> dropdown-menu-item* {:on-click (partial team-selected (:id team-item))
:on-key-down (partial handle-select-team (:id team-item))
:id (str "teams-selector-" (:id team-item))
:class (stl/css :team-name)
:key (str "teams-selector-" (:id team-item))}
[:span {:class (stl/css :team-icon)}
[:img {:src (cf/resolve-team-photo-url team-item)
:alt (:name team-item)}]]
[:span {:class (stl/css :team-text)
:title (:name team-item)} (:name team-item)]
(when (= (:id team-item) (:id team))
[:span {:class (stl/css :icon)} i/tick])])
[:hr {:role "separator"}]
[:> dropdown-menu-item* {:on-click on-create-clicked
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-create-clicked event)))
:id "teams-selector-create-team"
:class (stl/css :team-name :action)}
[:span {:class (stl/css :team-icon :new-team)} i/close]
[:span {:class (stl/css :team-text)} (tr "dashboard.create-new-team")]]]))
(s/def ::member-id ::us/uuid)
(s/def ::leave-modal-form
@ -395,8 +298,7 @@
(mf/defc team-options-dropdown
[{:keys [team profile] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
go-members #(st/emit! (dd/go-to-team-members))
(let [go-members #(st/emit! (dd/go-to-team-members))
go-invitations #(st/emit! (dd/go-to-team-invitations))
go-webhooks #(st/emit! (dd/go-to-team-webhooks))
go-settings #(st/emit! (dd/go-to-team-settings))
@ -549,15 +451,13 @@
(when (kbd/enter? event)
(on-delete-clicked)))
:id "teams-options-delete-team"
:class (if new-css-system (stl/css :warning) "warning")
:class (stl/css :warning)
:data-test "delete-team"}
(tr "dashboard.delete-team")])]))
(mf/defc sidebar-team-switch
[{:keys [team profile] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
teams (mf/deref refs/teams)
(let [teams (mf/deref refs/teams)
teams-without-default (into {} (filter (fn [[_ v]] (= false (:is-default v))) teams))
team-ids (map #(str "teams-selector-" %) (keys teams-without-default))
ids (concat ["teams-selector-default-team"] team-ids ["teams-selector-create-team"])
@ -615,119 +515,55 @@
(fn []
(reset! show-teams-ddwn? false))]
(if new-css-system
[:div {:class (stl/css :sidebar-team-switch)}
[:div {:class (stl/css :switch-content)}
[:div {:class (stl/css :sidebar-team-switch)}
[:div {:class (stl/css :switch-content)}
[:button
{:class (stl/css :current-team)
:tab-index "0"
:on-click handle-show-team-click
:on-key-down handle-show-team-keydown}
(if (:is-default team)
[:div {:class (stl/css :team-name)}
[:span {:class (stl/css :team-icon)} i/logo-icon]
[:span {:class (stl/css :team-text)} (tr "dashboard.default-team-name")]]
[:div {:class (stl/css :team-name)}
[:span {:class (stl/css :team-icon)}
[:img {:src (cf/resolve-team-photo-url team)
:alt (:name team)}]]
[:span {:class (stl/css :team-text) :title (:name team)} (:name team)]])
[:span {:class (stl/css :switch-icon)} i/arrow-down]]
(when-not (:is-default team)
[:button
{:class (stl/css :current-team)
{:class (stl/css :switch-options)
:on-click handle-show-opts-click
:tab-index "0"
:on-click handle-show-team-click
:on-key-down handle-show-team-keydown}
:on-key-down handle-show-opts-keydown}
i/actions])]
;; Teams Dropdown
[:& dropdown-menu {:show @show-teams-ddwn?
:on-close handle-close-team
:ids ids
:list-class (stl/css :dropdown :teams-dropdown)}
[:& teams-selector-dropdown-items {:ids ids
:team team
:profile profile
:teams teams}]]
(if (:is-default team)
[:div {:class (stl/css :team-name)}
[:span {:class (stl/css :team-icon)} i/logo-icon]
[:span {:class (stl/css :team-text)} (tr "dashboard.default-team-name")]]
[:div {:class (stl/css :team-name)}
[:span {:class (stl/css :team-icon)}
[:img {:src (cf/resolve-team-photo-url team)
:alt (:name team)}]]
[:span {:class (stl/css :team-text) :title (:name team)} (:name team)]])
[:span {:class (stl/css :switch-icon)} i/arrow-down]]
(when-not (:is-default team)
[:button
{:class (stl/css :switch-options)
:on-click handle-show-opts-click
:tab-index "0"
:on-key-down handle-show-opts-keydown}
i/actions])]
;; Teams Dropdown
[:& dropdown-menu {:show @show-teams-ddwn?
:on-close handle-close-team
:ids ids
:list-class (stl/css :dropdown :teams-dropdown)}
[:& teams-selector-dropdown-items {:ids ids
:team team
:profile profile
:teams teams}]]
[:& dropdown-menu {:show @show-team-opts-ddwn?
:on-close #(reset! show-team-opts-ddwn? false)
:ids options-ids
:list-class (stl/css :dropdown :options-dropdown)}
[:& team-options-dropdown {:team team
:profile profile}]]]
;; Old css
[:div.sidebar-team-switch
[:div.switch-content
[:button.current-team {:tab-index "0"
:on-click (fn [event]
(dom/stop-propagation event)
(reset! show-teams-ddwn? true))
:on-key-down (fn [event]
(when (or (kbd/space? event) (kbd/enter? event))
(dom/prevent-default event)
(reset! show-teams-ddwn? true)
(ts/schedule-on-idle
(fn []
(let [first-element (dom/get-element (first ids))]
(when first-element
(dom/focus! first-element)))))))}
(if (:is-default team)
[:div.team-name
[:span.team-icon i/logo-icon]
[:span.team-text (tr "dashboard.default-team-name")]]
[:div.team-name
[:span.team-icon
[:img {:src (cf/resolve-team-photo-url team)
:alt (:name team)}]]
[:span.team-text {:title (:name team)} (:name team)]])
[:span.switch-icon
i/arrow-down]]
(when-not (:is-default team)
[:button.switch-options {:on-click (fn [event]
(dom/stop-propagation event)
(reset! show-team-opts-ddwn? true))
:tab-index "0"
:on-key-down (fn [event]
(when (or (kbd/space? event) (kbd/enter? event))
(dom/prevent-default event)
(reset! show-team-opts-ddwn? true)
(ts/schedule-on-idle
(fn []
(let [first-element (dom/get-element (first options-ids))]
(when first-element
(dom/focus! first-element)))))))}
i/actions])]
;; Teams Dropdown
[:& dropdown-menu {:show @show-teams-ddwn?
:on-close #(reset! show-teams-ddwn? false)
:ids ids
:list-class "dropdown teams-dropdown"}
[:& teams-selector-dropdown-items {:ids ids
:team team
:profile profile
:teams teams}]]
[:& dropdown-menu {:show @show-team-opts-ddwn?
:on-close #(reset! show-team-opts-ddwn? false)
:ids options-ids
:list-class "dropdown options-dropdown"}
[:& team-options-dropdown {:team team
:profile profile}]]])))
[:& dropdown-menu {:show @show-team-opts-ddwn?
:on-close #(reset! show-team-opts-ddwn? false)
:ids options-ids
:list-class (stl/css :dropdown :options-dropdown)}
[:& team-options-dropdown {:team team
:profile profile}]]]))
(mf/defc sidebar-content
[{:keys [projects profile section team project search-term] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
default-project-id
(let [default-project-id
(->> (vals projects)
(d/seek :is-default)
(:id))
@ -813,115 +649,61 @@
(remove :is-default)
(filter :is-pinned))]
(if new-css-system
[:div {:class (stl/css :sidebar-content)}
[:& sidebar-team-switch {:team team :profile profile}]
[:hr]
[:& sidebar-search {:search-term search-term
:team-id (:id team)}]
[:div {:class (stl/css :sidebar-content)}
[:& sidebar-team-switch {:team team :profile profile}]
[:hr]
[:& sidebar-search {:search-term search-term
:team-id (:id team)}]
[:div {:class (stl/css :sidebar-content-section)}
[:ul {:class (stl/css :sidebar-nav :no-overflow)}
[:li
{:class (stl/css :recent-projects)
:class-name (when projects? (stl/css :current))}
[:& link {:action go-projects
:keyboard-action go-projects-with-key}
[:span {:class (stl/css :element-title)} (tr "labels.projects")]]]
[:div {:class (stl/css :sidebar-content-section)}
[:ul {:class (stl/css :sidebar-nav :no-overflow)}
[:li
{:class (stl/css :recent-projects)
:class-name (when projects? (stl/css :current))}
[:& link {:action go-projects
:keyboard-action go-projects-with-key}
[:span {:class (stl/css :element-title)} (tr "labels.projects")]]]
[:li {:class-name (when drafts? (stl/css :current))}
[:& link {:action go-drafts
:keyboard-action go-drafts-with-key}
[:span {:class (stl/css :element-title)} (tr "labels.drafts")]]]
[:li {:class-name (when drafts? (stl/css :current))}
[:& link {:action go-drafts
:keyboard-action go-drafts-with-key}
[:span {:class (stl/css :element-title)} (tr "labels.drafts")]]]
[:li {:class-name (when libs? (stl/css :current))}
[:& link {:action go-libs
:keyboard-action go-libs-with-key}
[:span {:class (stl/css :element-title)} (tr "labels.shared-libraries")]]]]]
[:li {:class-name (when libs? (stl/css :current))}
[:& link {:action go-libs
:keyboard-action go-libs-with-key}
[:span {:class (stl/css :element-title)} (tr "labels.shared-libraries")]]]]]
[:hr]
[:hr]
[:div {:class (stl/css :sidebar-content-section)}
[:ul {:class (stl/css :sidebar-nav :no-overflow)}
[:li {:class-name (when fonts? (stl/css :current))}
[:& link {:action go-fonts
:keyboard-action go-fonts-with-key
:data-test "fonts"}
[:span {:class (stl/css :element-title)} (tr "labels.fonts")]]]]]
[:hr]
[:div {:class (stl/css :sidebar-content-section)
:data-test "pinned-projects"}
(if (seq pinned-projects)
[:ul {:class (stl/css :sidebar-nav)}
(for [item pinned-projects]
[:& sidebar-project
{:item item
:key (dm/str (:id item))
:id (:id item)
:team-id (:id team)
:selected? (= (:id item) (:id project))}])]
[:div {:class (stl/css :sidebar-empty-placeholder)}
[:span {:class (stl/css :icon)} i/pin]
[:span {:class (stl/css :text)} (tr "dashboard.no-projects-placeholder")]])]]
;; OLD STYLES
[:div.sidebar-content
[:& sidebar-team-switch {:team team :profile profile}]
[:hr]
[:& sidebar-search {:search-term search-term
:team-id (:id team)}]
[:div.sidebar-content-section
[:ul.sidebar-nav.no-overflow
[:li.recent-projects
{:class-name (when projects? "current")}
[:& link {:action go-projects
:keyboard-action go-projects-with-key}
[:span.element-title (tr "labels.projects")]]]
[:li {:class-name (when drafts? "current")}
[:& link {:action go-drafts
:keyboard-action go-drafts-with-key}
[:span.element-title (tr "labels.drafts")]]]
[:li {:class-name (when libs? "current")}
[:& link {:action go-libs
:keyboard-action go-libs-with-key}
[:span.element-title (tr "labels.shared-libraries")]]]]]
[:hr]
[:div.sidebar-content-section
[:ul.sidebar-nav.no-overflow
[:li {:class-name (when fonts? "current")}
[:& link {:action go-fonts
:keyboard-action go-fonts-with-key
:data-test "fonts"}
[:span.element-title (tr "labels.fonts")]]]]]
[:hr]
[:div.sidebar-content-section {:data-test "pinned-projects"}
(if (seq pinned-projects)
[:ul.sidebar-nav
(for [item pinned-projects]
[:& sidebar-project
{:item item
:key (dm/str (:id item))
:id (:id item)
:team-id (:id team)
:selected? (= (:id item) (:id project))}])]
[:div.sidebar-empty-placeholder
[:span.icon i/pin]
[:span.text (tr "dashboard.no-projects-placeholder")]])]])))
[:div {:class (stl/css :sidebar-content-section)}
[:ul {:class (stl/css :sidebar-nav :no-overflow)}
[:li {:class-name (when fonts? (stl/css :current))}
[:& link {:action go-fonts
:keyboard-action go-fonts-with-key
:data-test "fonts"}
[:span {:class (stl/css :element-title)} (tr "labels.fonts")]]]]]
[:hr]
[:div {:class (stl/css :sidebar-content-section)
:data-test "pinned-projects"}
(if (seq pinned-projects)
[:ul {:class (stl/css :sidebar-nav)}
(for [item pinned-projects]
[:& sidebar-project
{:item item
:key (dm/str (:id item))
:id (:id item)
:team-id (:id team)
:selected? (= (:id item) (:id project))}])]
[:div {:class (stl/css :sidebar-empty-placeholder)}
[:span {:class (stl/css :icon)} i/pin]
[:span {:class (stl/css :text)} (tr "dashboard.no-projects-placeholder")]])]]))
(mf/defc profile-section
[{:keys [profile team] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
show (mf/use-state false)
(let [show (mf/use-state false)
photo (cf/resolve-profile-photo-url profile)
on-click
@ -1024,236 +806,110 @@
(fn [event]
(when (kbd/enter? event)
(on-click (du/logout) event))))]
(if new-css-system
[:*
(when (and team profile)
[:& comments-section
{:profile profile
:team team
:show? show-comments?
:on-show-comments handle-show-comments
:on-hide-comments handle-hide-comments}])
[:div {:class (stl/css :profile-section)}
[:div {:class (stl/css :profile)
:tab-index "0"
:on-click handle-click
:on-key-down handle-key-down
:data-test "profile-btn"}
[:img {:src photo
:alt (:fullname profile)}]
[:span (:fullname profile)]]
[:*
(when (and team profile)
[:& comments-section
{:profile profile
:team team
:show? show-comments?
:on-show-comments handle-show-comments
:on-hide-comments handle-hide-comments}])
[:& dropdown-menu {:on-close handle-close :show @show}
[:ul {:class (stl/css :dropdown)}
[:li {:tab-index (if @show "0" "-1")
:on-click (partial on-click :settings-profile)
:on-key-down handle-key-down-profile
:data-test "profile-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.your-account")]]
[:div {:class (stl/css :profile-section)}
[:div {:class (stl/css :profile)
:tab-index "0"
:on-click handle-click
:on-key-down handle-key-down
:data-test "profile-btn"}
[:img {:src photo
:alt (:fullname profile)}]
[:span (:fullname profile)]]
[:& dropdown-menu {:on-close handle-close :show @show}
[:ul {:class (stl/css :dropdown)}
[:li {:tab-index (if @show "0" "-1")
:on-click (partial on-click :settings-profile)
:on-key-down handle-key-down-profile
:data-test "profile-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.your-account")]]
[:li {:class (stl/css :separator)
:tab-index (if @show "0" "-1")
:data-url "https://help.penpot.app"
:on-click handle-click-url
:on-key-down handle-keydown-url
:data-test "help-center-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.help-center")]]
[:li {:tab-index (if @show "0" "-1")
:data-url "https://community.penpot.app"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "labels.community")]]
[:li {:tab-index (if @show "0" "-1")
:data-url "https://www.youtube.com/c/Penpot"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "labels.tutorials")]]
[:li {:tab-index (if @show "0" "-1")
:on-click show-release-notes
:on-key-down handle-show-release-notes}
[:span {:class (stl/css :text)} (tr "labels.release-notes")]]
[:li {:class (stl/css :separator)
:tab-index (if @show "0" "-1")
:data-url "https://penpot.app/libraries-templates"
:on-click handle-click-url
:on-key-down handle-keydown-url
:data-test "libraries-templates-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.libraries-and-templates")]]
[:li {:tab-index (if @show "0" "-1")
:data-url "https://github.com/penpot/penpot"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "labels.github-repo")]]
[:li {:tab-index (if @show "0" "-1")
:data-url "https://penpot.app/terms"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "auth.terms-of-service")]]
(when (contains? cf/flags :user-feedback)
[:li {:class (stl/css :separator)
:tab-index (if @show "0" "-1")
:data-url "https://help.penpot.app"
:on-click handle-click-url
:on-key-down handle-keydown-url
:data-test "help-center-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.help-center")]]
:on-click handle-feedback-click
:on-key-down handle-feedback-keydown
:data-test "feedback-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.give-feedback")]])
[:li {:tab-index (if @show "0" "-1")
:data-url "https://community.penpot.app"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "labels.community")]]
[:li {:class (stl/css :separator)
:tab-index (if @show "0" "-1")
:on-click handle-logout-click
:on-key-down handle-logout-keydown
:data-test "logout-profile-opt"}
[:span {:class (stl/css :icon)} i/exit]
[:span {:class (stl/css :text)} (tr "labels.logout")]]]]
[:li {:tab-index (if @show "0" "-1")
:data-url "https://www.youtube.com/c/Penpot"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "labels.tutorials")]]
[:li {:tab-index (if @show "0" "-1")
:on-click show-release-notes
:on-key-down handle-show-release-notes}
[:span {:class (stl/css :text)} (tr "labels.release-notes")]]
[:li {:class (stl/css :separator)
:tab-index (if @show "0" "-1")
:data-url "https://penpot.app/libraries-templates"
:on-click handle-click-url
:on-key-down handle-keydown-url
:data-test "libraries-templates-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.libraries-and-templates")]]
[:li {:tab-index (if @show "0" "-1")
:data-url "https://github.com/penpot/penpot"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "labels.github-repo")]]
[:li {:tab-index (if @show "0" "-1")
:data-url "https://penpot.app/terms"
:on-click handle-click-url
:on-key-down handle-keydown-url}
[:span {:class (stl/css :text)} (tr "auth.terms-of-service")]]
(when (contains? cf/flags :user-feedback)
[:li {:class (stl/css :separator)
:tab-index (if @show "0" "-1")
:on-click handle-feedback-click
:on-key-down handle-feedback-keydown
:data-test "feedback-profile-opt"}
[:span {:class (stl/css :text)} (tr "labels.give-feedback")]])
[:li {:class (stl/css :separator)
:tab-index (if @show "0" "-1")
:on-click handle-logout-click
:on-key-down handle-logout-keydown
:data-test "logout-profile-opt"}
[:span {:class (stl/css :icon)} i/exit]
[:span {:class (stl/css :text)} (tr "labels.logout")]]]]
(when (and team profile)
[:& comments-icon
{:profile profile
:show? show-comments?
:on-show-comments handle-show-comments}])]]
;; OLD
[:div.profile-section
[:div.profile {:tab-index "0"
:on-click (fn [event]
(dom/stop-propagation event)
(reset! show true))
:on-key-down (fn [event]
(when (kbd/enter? event)
(reset! show true)))
:data-test "profile-btn"}
[:img {:src photo
:alt (:fullname profile)}]
[:span (:fullname profile)]]
[:& dropdown-menu {:on-close (fn [event]
(dom/stop-propagation event)
(reset! show false))
:show @show}
[:ul.dropdown
[:li {:tab-index (if show
"0"
"-1")
:on-click (partial on-click :settings-profile)
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-click :settings-profile event)))
:data-test "profile-profile-opt"}
[:span.text (tr "labels.your-account")]]
[:li.separator {:tab-index (if show
"0"
"-1")
:on-click #(dom/open-new-window "https://help.penpot.app")
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/open-new-window "https://help.penpot.app")))
:data-test "help-center-profile-opt"}
[:span.text (tr "labels.help-center")]]
[:li {:tab-index (if show
"0"
"-1")
:on-click #(dom/open-new-window "https://community.penpot.app")
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/open-new-window "https://community.penpot.app")))}
[:span.text (tr "labels.community")]]
[:li {:tab-index (if show
"0"
"-1")
:on-click #(dom/open-new-window "https://www.youtube.com/c/Penpot")
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/open-new-window "https://www.youtube.com/c/Penpot")))}
[:span.text (tr "labels.tutorials")]]
[:li {:tab-index (if show
"0"
"-1")
:on-click show-release-notes
:on-key-down (fn [event]
(when (kbd/enter? event)
(show-release-notes)))}
[:span (tr "labels.release-notes")]]
[:li.separator {:tab-index (if show
"0"
"-1")
:on-click #(dom/open-new-window "https://penpot.app/libraries-templates")
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/open-new-window "https://penpot.app/libraries-templates")))
:data-test "libraries-templates-profile-opt"}
[:span.text (tr "labels.libraries-and-templates")]]
[:li {:tab-index (if show
"0"
"-1")
:on-click #(dom/open-new-window "https://github.com/penpot/penpot")
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/open-new-window "https://github.com/penpot/penpot")))}
[:span (tr "labels.github-repo")]]
[:li {:tab-index (if show
"0"
"-1")
:on-click #(dom/open-new-window "https://penpot.app/terms")
:on-key-down (fn [event]
(when (kbd/enter? event)
(dom/open-new-window "https://penpot.app/terms")))}
[:span (tr "auth.terms-of-service")]]
(when (contains? cf/flags :user-feedback)
[:li.separator {:tab-index (if show
"0"
"-1")
:on-click (partial on-click :settings-feedback)
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-click :settings-feedback event)))
:data-test "feedback-profile-opt"}
[:span.text (tr "labels.give-feedback")]])
[:li.separator {:tab-index (if show
"0"
"-1")
:on-click #(on-click (du/logout) %)
:on-key-down (fn [event]
(when (kbd/enter? event)
(on-click (du/logout) event)))
:data-test "logout-profile-opt"}
[:span.icon i/exit]
[:span.text (tr "labels.logout")]]]]
(when (and team profile)
[:& comments-section
{:profile profile
:team team
:show? show-comments?
:on-show-comments handle-show-comments
:on-hide-comments handle-hide-comments}])])))
(when (and team profile)
[:& comments-icon
{:profile profile
:show? show-comments?
:on-show-comments handle-show-comments}])]]))
(mf/defc sidebar
{::mf/wrap-props false
::mf/wrap [mf/memo]}
[props]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
team (obj/get props "team")
(let [team (obj/get props "team")
profile (obj/get props "profile")]
(if new-css-system
[:nav {:class (stl/css :dashboard-sidebar)}
[:> sidebar-content props]
[:& profile-section
{:profile profile
:team team}]]
[:nav.dashboard-sidebar
[:> sidebar-content props]
[:& profile-section
{:profile profile
:team team}]])))
[:nav {:class (stl/css :dashboard-sidebar)}
[:> sidebar-content props]
[:& profile-section
{:profile profile
:team team}]]))

View file

@ -102,7 +102,7 @@
}
}
.btn-primary {
@extends .button-primary;
@extend .button-primary;
height: $s-32;
}
}
@ -650,6 +650,7 @@
color: var(--modal-title-foreground-color);
}
}
.invitation-row {
margin-top: $s-8;
margin-bottom: $s-24;
@ -671,48 +672,56 @@
.modal-overlay {
@extend .modal-overlay-base;
.modal-container {
@extend .modal-container-base;
border: $s-1 solid var(--modal-border-color);
.modal-header {
margin-bottom: $s-24;
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
}
.modal-content {
@include flexColumn;
gap: $s-24;
@include titleTipography;
margin-bottom: $s-24;
.modal-container {
@extend .modal-container-base;
border: $s-1 solid var(--modal-border-color);
}
.fields-row {
@include flexColumn;
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
.custom-input-checkbox {
align-items: flex-start;
}
}
}
.modal-header {
margin-bottom: $s-24;
}
.modal-footer {
.action-buttons {
@extend .modal-action-btns;
button {
@extend .modal-accept-btn;
}
.cancel-button {
@extend .modal-cancel-btn;
}
}
}
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
.modal-content {
@include flexColumn;
gap: $s-24;
@include titleTipography;
margin-bottom: $s-24;
}
.fields-row {
@include flexColumn;
}
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
.custom-input-checkbox {
align-items: flex-start;
}
.hint {
color: var(--modal-text-foreground-color);
}
.action-buttons {
@extend .modal-action-btns;
button {
@extend .modal-accept-btn;
}
.cancel-button {
@extend .modal-cancel-btn;
}
}

View file

@ -16,7 +16,6 @@
[app.main.data.users :as du]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :refer [tr]]
@ -59,8 +58,7 @@
(mf/defc title
{::mf/wrap-props false}
[{:keys [collapsed]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
on-click
(let [on-click
(mf/use-fn
(mf/deps collapsed)
(fn [_event]
@ -76,27 +74,17 @@
(dom/prevent-default event)
(on-click event))))]
(if new-css-system
[:div {:class (stl/css :title)}
[:button {:tab-index "0"
:on-click on-click
:on-key-down on-key-down}
[:span (tr "dashboard.libraries-and-templates")]
[:span {:class (stl/css :icon)} (if ^boolean collapsed i/arrow-up i/arrow-down)]]]
;; OLD
[:div.title
[:button {:tab-index "0"
:on-click on-click
:on-key-down on-key-down}
[:span (tr "dashboard.libraries-and-templates")]
[:span.icon (if ^boolean collapsed i/arrow-up i/arrow-down)]]])))
[:div {:class (stl/css :title)}
[:button {:tab-index "0"
:on-click on-click
:on-key-down on-key-down}
[:span (tr "dashboard.libraries-and-templates")]
[:span {:class (stl/css :icon)} (if ^boolean collapsed i/arrow-up i/arrow-down)]]]))
(mf/defc card-item
{::mf/wrap-props false}
[{:keys [item index is-visible collapsed on-import]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
id (dm/str "card-container-" index)
(let [id (dm/str "card-container-" index)
thb (assoc cf/public-uri :path (dm/str "/images/thumbnails/template-" (:id item) ".jpg"))
on-click
@ -113,41 +101,24 @@
(dom/stop-propagation event)
(on-import item event))))]
(if new-css-system
[:a
{:class (stl/css :card-container)
:tab-index (if (or (not is-visible) collapsed) "-1" "0")
:id id
:data-index index
:on-click on-click
:on-key-down on-key-down}
[:div {:class (stl/css :template-card)}
[:div {:class (stl/css :img-container)}
[:img {:src (dm/str thb)
:alt (:name item)}]]
[:div {:class (stl/css :card-name)}
[:span (:name item)]
[:span {:class (stl/css :icon)} i/download]]]]
;; OLD
[:a.card-container
{:tab-index (if (or (not is-visible) collapsed) "-1" "0")
:id id
:data-index index
:on-click on-click
:on-key-down on-key-down}
[:div.template-card
[:div.img-container
[:img {:src (dm/str thb)
:alt (:name item)}]]
[:div.card-name [:span (:name item)]
[:span.icon i/download]]]])))
[:a {:class (stl/css :card-container)
:tab-index (if (or (not is-visible) collapsed) "-1" "0")
:id id
:data-index index
:on-click on-click
:on-key-down on-key-down}
[:div {:class (stl/css :template-card)}
[:div {:class (stl/css :img-container)}
[:img {:src (dm/str thb)
:alt (:name item)}]]
[:div {:class (stl/css :card-name)}
[:span (:name item)]
[:span {:class (stl/css :icon)} i/download]]]]))
(mf/defc card-item-link
{::mf/wrap-props false}
[{:keys [total is-visible collapsed section]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
id (dm/str "card-container-" total)
(let [id (dm/str "card-container-" total)
on-click
(mf/use-fn
@ -165,39 +136,23 @@
(dom/stop-propagation event)
(on-click event))))]
(if new-css-system
[:div {:class (stl/css :card-container)}
[:div {:class (stl/css :template-card)}
[:div {:class (stl/css :img-container)}
[:a {:id id
:tab-index (if (or (not is-visible) collapsed) "-1" "0")
:href "https://penpot.app/libraries-templates.html"
:target "_blank"
:on-click on-click
:on-key-down on-key-down}
[:div {:class (stl/css :template-link)}
[:div {:class (stl/css :template-link-title)} (tr "dashboard.libraries-and-templates")]
[:div {:class (stl/css :template-link-text)} (tr "dashboard.libraries-and-templates.explore")]]]]]]
;; OLD
[:div.card-container
[:div.template-card
[:div.img-container
[:a {:id id
:tab-index (if (or (not is-visible) collapsed) "-1" "0")
:href "https://penpot.app/libraries-templates.html"
:target "_blank"
:on-click on-click
:on-key-down on-key-down}
[:div.template-link
[:div.template-link-title (tr "dashboard.libraries-and-templates")]
[:div.template-link-text (tr "dashboard.libraries-and-templates.explore")]]]]]])))
[:div {:class (stl/css :card-container)}
[:div {:class (stl/css :template-card)}
[:div {:class (stl/css :img-container)}
[:a {:id id
:tab-index (if (or (not is-visible) collapsed) "-1" "0")
:href "https://penpot.app/libraries-templates.html"
:target "_blank"
:on-click on-click
:on-key-down on-key-down}
[:div {:class (stl/css :template-link)}
[:div {:class (stl/css :template-link-title)} (tr "dashboard.libraries-and-templates")]
[:div {:class (stl/css :template-link-text)} (tr "dashboard.libraries-and-templates.explore")]]]]]]))
(mf/defc templates-section
{::mf/wrap-props false}
[{:keys [default-project-id profile project-id team-id content-width]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
templates (mf/deref builtin-templates)
(let [templates (mf/deref builtin-templates)
templates (mf/with-memo [templates]
(filterv #(not= (:id %) "tutorial-for-beginners") templates))
@ -273,94 +228,50 @@
(mf/use-fn
(mf/deps default-project-id project-id section templates team-id)
(fn [template _event]
(import-template! template team-id project-id default-project-id section)))
]
(import-template! template team-id project-id default-project-id section)))]
(mf/with-effect [profile collapsed]
(when (and profile (not collapsed))
(st/emit! (dd/fetch-builtin-templates))))
(if new-css-system
[:div
{:class (stl/css-case :dashboard-templates-section true
:collapsed collapsed)}
[:& title {:collapsed collapsed}]
[:div {:class (stl/css-case :dashboard-templates-section true
:collapsed collapsed)}
[:& title {:collapsed collapsed}]
[:div {:class (stl/css :content)
:ref content-ref
:style {:left card-offset
:width (dm/str container-size "px")}}
[:div {:class (stl/css :content)
:ref content-ref
:style {:left card-offset
:width (dm/str container-size "px")}}
(for [index (range (count templates))]
[:& card-item
{:on-import on-import-template
:item (nth templates index)
:index index
:key index
:is-visible (and (>= index first-card)
(<= index last-card))
:collapsed collapsed}])
(for [index (range (count templates))]
[:& card-item
{:on-import on-import-template
:item (nth templates index)
:index index
:key index
:is-visible (and (>= index first-card)
(<= index last-card))
:collapsed collapsed}])
[:& card-item-link
{:is-visible (and (>= total first-card) (<= total last-card))
:collapsed collapsed
:section section
:total total}]]
[:& card-item-link
{:is-visible (and (>= total first-card) (<= total last-card))
:collapsed collapsed
:section section
:total total}]]
(when (< card-offset 0)
[:button
{:class (stl/css :button :left)
:tab-index (if ^boolean collapsed "-1" "0")
:on-click on-move-left
:on-key-down on-move-left-key-down}
i/go-prev])
(when (< card-offset 0)
[:button
{:class (stl/css :button :left)
:tab-index (if ^boolean collapsed "-1" "0")
:on-click on-move-left
:on-key-down on-move-left-key-down}
i/go-prev])
(when more-cards
[:button
{:class (stl/css :button :right)
:tab-index (if collapsed "-1" "0")
:on-click on-move-right
:aria-label (tr "labels.next")
:on-key-down on-move-right-key-down}
i/go-next])]
;; OLD
[:div.dashboard-templates-section
{:class (when ^boolean collapsed "collapsed")}
[:& title {:collapsed collapsed}]
[:div.content {:ref content-ref
:style {:left card-offset
:width (dm/str container-size "px")}}
(for [index (range (count templates))]
[:& card-item
{:on-import on-import-template
:item (nth templates index)
:index index
:key index
:is-visible (and (>= index first-card)
(<= index last-card))
:collapsed collapsed}])
[:& card-item-link
{:is-visible (and (>= total first-card) (<= total last-card))
:collapsed collapsed
:section section
:total total}]]
(when (< card-offset 0)
[:button.button.left
{:tab-index (if ^boolean collapsed "-1" "0")
:on-click on-move-left
:on-key-down on-move-left-key-down}
i/go-prev])
(when more-cards
[:button.button.right
{:tab-index (if collapsed "-1" "0")
:on-click on-move-right
:aria-label (tr "labels.next")
:on-key-down on-move-right-key-down}
i/go-next])])))
(when more-cards
[:button
{:class (stl/css :button :right)
:tab-index (if collapsed "-1" "0")
:on-click on-move-right
:aria-label (tr "labels.next")
:on-key-down on-move-right-key-down}
i/go-next])]))

View file

@ -13,7 +13,6 @@
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.util.i18n :as i18n :refer [tr]]
[cljs.spec.alpha :as s]
[cuerdas.core :as str]
@ -22,139 +21,75 @@
(mf/defc step-container
[{:keys [form step on-next on-prev children] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
[:& fm/form {:form form :on-submit on-next}
[:div {:class (stl/css :paginator)} (str/ffmt "%/4" step)]
(if new-css-system
[:& fm/form {:form form :on-submit on-next}
[:div {:class (stl/css :paginator)} (str/ffmt "%/4" step)]
children
children
[:div {:class (stl/css :action-buttons)}
[:div {:class (stl/css :action-buttons)}
(when on-prev
[:button {:class (stl/css :prev-button)
:on-click on-prev} (tr "questions.previous")])
(when on-prev
[:button {:class (stl/css :prev-button)
:on-click on-prev} (tr "questions.previous")])
[:> fm/submit-button*
{:label (if (< step 4) (tr "questions.next") (tr "questions.start"))
:class (stl/css :next-button)}]]]
[:& fm/form {:form form :on-submit on-next}
[:div.step-header
[:div.step-number (str/ffmt "%/4" step)]]
children
[:div.buttons
[:div.step-next
[:> fm/submit-button*
{:label (if (< step 4) (tr "questions.next") (tr "questions.start"))
:class "step-next"}]]
(when on-prev
[:div.step-prev
[:button {:on-click on-prev} (tr "questions.previous")]])]])))
[:> fm/submit-button*
{:label (if (< step 4) (tr "questions.next") (tr "questions.start"))
:class (stl/css :next-button)}]]])
(s/def ::questions-form-step-1
(s/keys :req-un [::planning]))
(mf/defc step-1
[{:keys [on-next form] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:& step-container {:form form :step 1 :on-next on-next}
[:img {:class (stl/css :header-image)
:src "images/form/use-for-1.png" :alt (tr "questions.lets-get-started")}]
[:h1 {:class (stl/css :modal-title)} (tr "questions.lets-get-started")]
[:p {:class (stl/css :modal-text)} (tr "questions.your-feedback-will-help-us")]
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.questions-how-are-you-planning-to-use-penpot")]
[:& fm/select {:options [{:label (tr "questions.select-option") :value "" :key "questions-how-are-you-planning-to-use-penpot" :disabled true}
{:label (tr "questions.discover-more-about-penpot") :value "discover-more-about-penpot" :key "discover-more-about-penpot"}
{:label (tr "questions.test-penpot-to-see-if-its-a-fit-for-team") :value "test-penpot-to-see-if-its-a-fit-for-team" :key "test-penpot-to-see-if-its-a-fit-for-team"}
{:label (tr "questions.start-to-work-on-my-project") :value "start-to-work-on-my-project" :key "start-to-work-on-my-project"}
{:label (tr "questions.get-the-code-from-my-team-project") :value "get-the-code-from-my-team-project" :key "get-the-code-from-my-team-project"}
{:label (tr "questions.leave-feedback-for-my-team-project") :value "leave-feedback-for-my-team-project" :key "leave-feedback-for-my-team-project"}
{:label (tr "questions.work-in-concept-ideas") :value "work-in-concept-ideas" :key "work-in-concept-ideas"}
{:label (tr "questions.try-out-before-using-penpot-on-premise") :value "try-out-before-using-penpot-on-premise" :key "try-out-before-using-penpot-on-premise"}]
:default ""
:name :planning}]]
[:& step-container {:form form :step 1 :on-next on-next}
[:img.header-image {:src "images/form/use-for-1.png" :alt (tr "questions.lets-get-started")}]
[:h1 (tr "questions.lets-get-started")]
[:p.intro (tr "questions.your-feedback-will-help-us")]
[:h3 (tr "questions.questions-how-are-you-planning-to-use-penpot")]
[:& fm/select {:options [{:label (tr "questions.select-option") :value "" :key "questions-how-are-you-planning-to-use-penpot" :disabled true}
{:label (tr "questions.discover-more-about-penpot") :value "discover-more-about-penpot" :key "discover-more-about-penpot"}
{:label (tr "questions.test-penpot-to-see-if-its-a-fit-for-team") :value "test-penpot-to-see-if-its-a-fit-for-team" :key "test-penpot-to-see-if-its-a-fit-for-team"}
{:label (tr "questions.start-to-work-on-my-project") :value "start-to-work-on-my-project" :key "start-to-work-on-my-project"}
{:label (tr "questions.get-the-code-from-my-team-project") :value "get-the-code-from-my-team-project" :key "get-the-code-from-my-team-project"}
{:label (tr "questions.leave-feedback-for-my-team-project") :value "leave-feedback-for-my-team-project" :key "leave-feedback-for-my-team-project"}
{:label (tr "questions.work-in-concept-ideas") :value "work-in-concept-ideas" :key "work-in-concept-ideas"}
{:label (tr "questions.try-out-before-using-penpot-on-premise") :value "try-out-before-using-penpot-on-premise" :key "try-out-before-using-penpot-on-premise"}]
:default ""
:name :planning}]])))
[:& step-container {:form form :step 1 :on-next on-next}
[:img {:class (stl/css :header-image)
:src "images/form/use-for-1.png" :alt (tr "questions.lets-get-started")}]
[:h1 {:class (stl/css :modal-title)} (tr "questions.lets-get-started")]
[:p {:class (stl/css :modal-text)} (tr "questions.your-feedback-will-help-us")]
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.questions-how-are-you-planning-to-use-penpot")]
[:& fm/select {:options [{:label (tr "questions.select-option") :value "" :key "questions-how-are-you-planning-to-use-penpot" :disabled true}
{:label (tr "questions.discover-more-about-penpot") :value "discover-more-about-penpot" :key "discover-more-about-penpot"}
{:label (tr "questions.test-penpot-to-see-if-its-a-fit-for-team") :value "test-penpot-to-see-if-its-a-fit-for-team" :key "test-penpot-to-see-if-its-a-fit-for-team"}
{:label (tr "questions.start-to-work-on-my-project") :value "start-to-work-on-my-project" :key "start-to-work-on-my-project"}
{:label (tr "questions.get-the-code-from-my-team-project") :value "get-the-code-from-my-team-project" :key "get-the-code-from-my-team-project"}
{:label (tr "questions.leave-feedback-for-my-team-project") :value "leave-feedback-for-my-team-project" :key "leave-feedback-for-my-team-project"}
{:label (tr "questions.work-in-concept-ideas") :value "work-in-concept-ideas" :key "work-in-concept-ideas"}
{:label (tr "questions.try-out-before-using-penpot-on-premise") :value "try-out-before-using-penpot-on-premise" :key "try-out-before-using-penpot-on-premise"}]
:default ""
:name :planning}]])
(s/def ::questions-form-step-2
(s/keys :req-un [::experience-branding-illustrations-marketing-pieces ::experience-interface-design-visual-assets-design-systems ::experience-interface-wireframes-user-journeys-flows-navigation-trees]))
(mf/defc step-2
[{:keys [on-next on-prev form] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:& step-container {:form form :step 2 :on-next on-next :on-prev on-prev}
[:h3 {:class (stl/css :modal-subtitle)}
(tr "questions.describe-your-experience-working-on")]
[:& step-container {:form form :step 2 :on-next on-next :on-prev on-prev}
[:h3 {:class (stl/css :modal-subtitle)}
(tr "questions.describe-your-experience-working-on")]
[:div {:class (stl/css :modal-question)}
[:div {:class (stl/css :modal-text)}
(tr "branding-illustrations-marketing-pieces")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-branding-illustrations-marketing-pieces}]]
[:div {:class (stl/css :modal-question)}
[:div {:class (stl/css :modal-text)}
(tr "branding-illustrations-marketing-pieces")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-branding-illustrations-marketing-pieces}]]
[:div {:class (stl/css :modal-question)}
[:div {:class (stl/css :modal-text)}
(tr "questions.interface-design-visual-assets-design-systems")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-interface-design-visual-assets-design-systems}]]
[:div {:class (stl/css :modal-question)}
[:div {:class (stl/css :modal-text)}
(tr "questions.interface-design-visual-assets-design-systems")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-interface-design-visual-assets-design-systems}]]
[:div {:class (stl/css :modal-question)}
[:div {:class (stl/css :modal-text)}
(tr "questions.wireframes-user-journeys-flows-navigation-trees")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-interface-wireframes-user-journeys-flows-navigation-trees}]]]
[:& step-container {:form form :step 2 :on-next on-next :on-prev on-prev}
[:h3 (tr "questions.describe-your-experience-working-on")]
[:div.section (tr "branding-illustrations-marketing-pieces")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-branding-illustrations-marketing-pieces}]
[:div.section (tr "questions.interface-design-visual-assets-design-systems")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-interface-design-visual-assets-design-systems}]
[:div.section (tr "questions.wireframes-user-journeys-flows-navigation-trees")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-interface-wireframes-user-journeys-flows-navigation-trees}]])))
[:div {:class (stl/css :modal-question)}
[:div {:class (stl/css :modal-text)}
(tr "questions.wireframes-user-journeys-flows-navigation-trees")]
[:& fm/radio-buttons {:options [{:label (tr "questions.none") :value "none"}
{:label (tr "questions.some") :value "some"}
{:label (tr "questions.a-lot") :value "a-lot"}]
:name :experience-interface-wireframes-user-journeys-flows-navigation-trees}]]])
(s/def ::questions-form-step-3
(s/keys :req-un [::experience-design-tool]
@ -170,8 +105,7 @@
(mf/defc step-3
[{:keys [on-next on-prev form] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])
(let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])
on-design-tool-change
(fn [_ _]
(let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])]
@ -180,40 +114,23 @@
(swap! form d/dissoc-in [:data :experience-design-tool-other])
(swap! form d/dissoc-in [:errors :experience-design-tool-other])))))]
(if new-css-system
[:& step-container {:form form :step 3 :on-next on-next :on-prev on-prev}
[:h3 {:class (stl/css :modal-subtitle)}
(tr "question.design-tool-more-experienced-with")]
[:& fm/radio-buttons {:options [{:label (tr "questions.figma") :value "figma" :image "images/form/figma.png"}
{:label (tr "questions.sketch") :value "sketch" :image "images/form/sketch.png"}
{:label (tr "questions.adobe-xd") :value "adobe-xd" :image "images/form/adobe-xd.png"}
{:label (tr "questions.canva") :value "canva" :image "images/form/canva.png"}
{:label (tr "questions.invision") :value "invision" :image "images/form/invision.png"}
{:label (tr "questions.never-used-a-tool") :value "never-used-a-tool" :image "images/form/never-used.png"}
{:label (tr "questions.other") :value "other"}]
:name :experience-design-tool
:on-change on-design-tool-change}]
[:& step-container {:form form :step 3 :on-next on-next :on-prev on-prev}
[:h3 {:class (stl/css :modal-subtitle)}
(tr "question.design-tool-more-experienced-with")]
[:& fm/radio-buttons {:options [{:label (tr "questions.figma") :value "figma" :image "images/form/figma.png"}
{:label (tr "questions.sketch") :value "sketch" :image "images/form/sketch.png"}
{:label (tr "questions.adobe-xd") :value "adobe-xd" :image "images/form/adobe-xd.png"}
{:label (tr "questions.canva") :value "canva" :image "images/form/canva.png"}
{:label (tr "questions.invision") :value "invision" :image "images/form/invision.png"}
{:label (tr "questions.never-used-a-tool") :value "never-used-a-tool" :image "images/form/never-used.png"}
{:label (tr "questions.other") :value "other"}]
:name :experience-design-tool
:on-change on-design-tool-change}]
[:& fm/input {:name :experience-design-tool-other
:placeholder (tr "questions.other")
:label ""
:disabled (not= experience-design-tool "other")}]]
[:& step-container {:form form :step 3 :on-next on-next :on-prev on-prev}
[:h3 (tr "question.design-tool-more-experienced-with")]
[:& fm/radio-buttons {:options [{:label (tr "questions.figma") :value "figma" :image "images/form/figma.png"}
{:label (tr "questions.sketch") :value "sketch" :image "images/form/sketch.png"}
{:label (tr "questions.adobe-xd") :value "adobe-xd" :image "images/form/adobe-xd.png"}
{:label (tr "questions.canva") :value "canva" :image "images/form/canva.png"}
{:label (tr "questions.invision") :value "invision" :image "images/form/invision.png"}
{:label (tr "questions.never-used-a-tool") :value "never-used-a-tool" :image "images/form/never-used.png"}
{:label (tr "questions.other") :value "other"}]
:name :experience-design-tool
:on-change on-design-tool-change}]
[:div.other
[:label (tr "questions.other")]
[:& fm/input {:name :experience-design-tool-other :label (tr "questions.other") :disabled (not= experience-design-tool "other")}]]])))
[:& fm/input {:name :experience-design-tool-other
:placeholder (tr "questions.other")
:label ""
:disabled (not= experience-design-tool "other")}]]))
(s/def ::questions-form-step-4
(s/keys :req-un [::team-size ::role]
@ -229,8 +146,7 @@
(mf/defc step-4
[{:keys [on-next on-prev form] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
role (dm/get-in @form [:data :role])
(let [role (dm/get-in @form [:data :role])
on-role-change
(fn [_ _]
(let [experience-design-tool (dm/get-in @form [:clean-data :experience-design-tool])]
@ -239,63 +155,34 @@
(swap! form d/dissoc-in [:data :role-other])
(swap! form d/dissoc-in [:errors :role-other])))))]
(if new-css-system
[:& step-container {:form form :step 4 :on-next on-next :on-prev on-prev}
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.role")]
[:& fm/radio-buttons {:options [{:label (tr "questions.designer") :value "designer"}
{:label (tr "questions.developer") :value "developer"}
{:label (tr "questions.manager") :value "manager"}
{:label (tr "questions.founder") :value "founder"}
{:label (tr "questions.marketing") :value "marketing"}
{:label (tr "questions.student-teacher") :value "student-teacher"}
{:label (tr "questions.other") :value "other"}]
:name :role
:on-change on-role-change}]
[:& fm/input {:name :role-other :label "" :placeholder (tr "questions.other") :disabled (not= role "other")}]
[:& step-container {:form form :step 4 :on-next on-next :on-prev on-prev}
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.role")]
[:& fm/radio-buttons {:options [{:label (tr "questions.designer") :value "designer"}
{:label (tr "questions.developer") :value "developer"}
{:label (tr "questions.manager") :value "manager"}
{:label (tr "questions.founder") :value "founder"}
{:label (tr "questions.marketing") :value "marketing"}
{:label (tr "questions.student-teacher") :value "student-teacher"}
{:label (tr "questions.other") :value "other"}]
:name :role
:on-change on-role-change}]
[:& fm/input {:name :role-other :label "" :placeholder (tr "questions.other") :disabled (not= role "other")}]
[:div {:class (stl/css :modal-question)}
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.team-size")]
[:& fm/select {:options [{:label (tr "questions.select-option") :value "" :key "team-size" :disabled true}
{:label (tr "questions.more-than-50") :value "more-than-50" :key "more-than-50"}
{:label (tr "questions.31-50") :value "31-50" :key "31-50"}
{:label (tr "questions.11-30") :value "11-30" :key "11-30"}
{:label (tr "questions.2-10") :value "2-10" :key "2-10"}
{:label (tr "questions.freelancer") :value "freelancer" :key "freelancer"}
{:label (tr "questions.personal-project") :value "personal-project" :key "personal-project"}]
:default ""
:name :team-size}]]]
[:& step-container {:form form :step 4 :on-next on-next :on-prev on-prev}
[:h3 (tr "questions.role")]
[:& fm/radio-buttons {:options [{:label (tr "questions.designer") :value "designer"}
{:label (tr "questions.developer") :value "developer"}
{:label (tr "questions.manager") :value "manager"}
{:label (tr "questions.founder") :value "founder"}
{:label (tr "questions.marketing") :value "marketing"}
{:label (tr "questions.student-teacher") :value "student-teacher"}
{:label (tr "questions.other") :value "other"}]
:name :role
:on-change on-role-change}]
[:div.other
[:label (tr "questions.other")]
[:& fm/input {:name :role-other :label (tr "questions.other") :disabled (not= role "other")}]]
[:h3 (tr "questions.team-size")]
[:& fm/select {:options [{:label (tr "questions.select-option") :value "" :key "team-size" :disabled true}
{:label (tr "questions.more-than-50") :value "more-than-50" :key "more-than-50"}
{:label (tr "questions.31-50") :value "31-50" :key "31-50"}
{:label (tr "questions.11-30") :value "11-30" :key "11-30"}
{:label (tr "questions.2-10") :value "2-10" :key "2-10"}
{:label (tr "questions.freelancer") :value "freelancer" :key "freelancer"}
{:label (tr "questions.personal-project") :value "personal-project" :key "personal-project"}]
:default ""
:name :team-size}]])))
[:div {:class (stl/css :modal-question)}
[:h3 {:class (stl/css :modal-subtitle)} (tr "questions.team-size")]
[:& fm/select {:options [{:label (tr "questions.select-option") :value "" :key "team-size" :disabled true}
{:label (tr "questions.more-than-50") :value "more-than-50" :key "more-than-50"}
{:label (tr "questions.31-50") :value "31-50" :key "31-50"}
{:label (tr "questions.11-30") :value "11-30" :key "11-30"}
{:label (tr "questions.2-10") :value "2-10" :key "2-10"}
{:label (tr "questions.freelancer") :value "freelancer" :key "freelancer"}
{:label (tr "questions.personal-project") :value "personal-project" :key "personal-project"}]
:default ""
:name :team-size}]]]))
(mf/defc questions
[{:keys []}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
container (mf/use-ref)
(let [container (mf/use-ref)
step (mf/use-state 1)
clean-data (mf/use-state {})
@ -336,25 +223,11 @@
(reset! clean-data questionnaire)
(st/emit! (du/mark-questions-as-answered questionnaire)))))]
(if new-css-system
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)
:ref container}
(case @step
1 [:& step-1 {:on-next on-next :on-prev on-prev :form step-1-form}]
2 [:& step-2 {:on-next on-next :on-prev on-prev :form step-2-form}]
3 [:& step-3 {:on-next on-next :on-prev on-prev :form step-3-form}]
4 [:& step-4 {:on-next on-submit :on-prev on-prev :form step-4-form}])]]
[:div.modal-wrapper.questions-form
[:div.modal-overlay
[:div.modal-container.onboarding.onboarding-v2 {:ref container}
[:img.deco.left {:src "images/deco-left.png" :border 0}]
[:img.deco.right {:src "images/deco-right.png" :border 0}]
[:div.signup-questions
(case @step
1 [:& step-1 {:on-next on-next :on-prev on-prev :form step-1-form}]
2 [:& step-2 {:on-next on-next :on-prev on-prev :form step-2-form}]
3 [:& step-3 {:on-next on-next :on-prev on-prev :form step-3-form}]
4 [:& step-4 {:on-next on-submit :on-prev on-prev :form step-4-form}])]]]])))
[:div {:class (stl/css :modal-overlay)}
[:div {:class (stl/css :modal-container)
:ref container}
(case @step
1 [:& step-1 {:on-next on-next :on-prev on-prev :form step-1-form}]
2 [:& step-2 {:on-next on-next :on-prev on-prev :form step-2-form}]
3 [:& step-3 {:on-next on-next :on-prev on-prev :form step-3-form}]
4 [:& step-4 {:on-next on-submit :on-prev on-prev :form step-4-form}])]]))

View file

@ -10,7 +10,6 @@
[app.main.data.dashboard.shortcuts :as sc]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.hooks :as hooks]
[app.main.ui.settings.access-tokens :refer [access-tokens-page]]
[app.main.ui.settings.change-email]
@ -20,7 +19,6 @@
[app.main.ui.settings.password :refer [password-page]]
[app.main.ui.settings.profile :refer [profile-page]]
[app.main.ui.settings.sidebar :refer [sidebar]]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[app.util.router :as rt]
[rumext.v2 :as mf]))
@ -28,21 +26,13 @@
(mf/defc header
{::mf/wrap [mf/memo]}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:header {:class (stl/css :dashboard-header)}
[:div {:class (stl/css :dashboard-title)}
[:h1 {:data-test "account-title"} (tr "dashboard.your-account-title")]]]
;; OLD
[:header.dashboard-header
[:div.dashboard-title
[:h1 {:data-test "account-title"} (tr "dashboard.your-account-title")]]])))
[:header {:class (stl/css :dashboard-header)}
[:div {:class (stl/css :dashboard-title)}
[:h1 {:data-test "account-title"} (tr "dashboard.your-account-title")]]])
(mf/defc settings
[{:keys [route] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
section (get-in route [:data :name])
(let [section (get-in route [:data :name])
profile (mf/deref refs/profile)
locale (mf/deref i18n/locale)]
@ -52,53 +42,26 @@
#(when (nil? profile)
(st/emit! (rt/nav :auth-login))))
(if new-css-system
[:section {:class (stl/css :dashboard-layout-refactor :dashboard)}
[:& sidebar {:profile profile
:locale locale
:section section}]
[:section {:class (stl/css :dashboard-layout-refactor :dashboard)}
[:& sidebar {:profile profile
:locale locale
:section section}]
[:div {:class (stl/css :dashboard-content)}
[:& header]
[:section {:class (stl/css :dashboard-container)}
(case section
:settings-profile
[:& profile-page {:locale locale}]
[:div {:class (stl/css :dashboard-content)}
[:& header]
[:section {:class (stl/css :dashboard-container)}
(case section
:settings-profile
[:& profile-page {:locale locale}]
:settings-feedback
[:& feedback-page]
:settings-feedback
[:& feedback-page]
:settings-password
[:& password-page {:locale locale}]
:settings-password
[:& password-page {:locale locale}]
:settings-options
[:& options-page {:locale locale}]
:settings-options
[:& options-page {:locale locale}]
:settings-access-tokens
[:& access-tokens-page])]]]
;; OLD
[:section {:class (dom/classnames :dashboard-layout (not new-css-system)
:dashboard-layout-refactor new-css-system)}
[:& sidebar {:profile profile
:locale locale
:section section}]
[:div.dashboard-content
[:& header]
[:section.dashboard-container
(case section
:settings-profile
[:& profile-page {:locale locale}]
:settings-feedback
[:& feedback-page]
:settings-password
[:& password-page {:locale locale}]
:settings-options
[:& options-page {:locale locale}]
:settings-access-tokens
[:& access-tokens-page])]]])))
:settings-access-tokens
[:& access-tokens-page])]]]))

View file

@ -137,7 +137,7 @@
:disabled @created?
:name :expiration-date}]
(when @created?
[:span.token-created-info
[:span {:class (stl/css :token-created-info)}
(if (:expires-at created)
(tr "dashboard.access-tokens.token-will-expire" (dt/format-date-locale (:expires-at created) {:locale locale}))
(tr "dashboard.access-tokens.token-will-not-expire"))])]

View file

@ -12,6 +12,11 @@
font-size: $fs-16;
margin-top: $s-20;
width: $s-800;
svg {
width: $s-12;
height: $s-12;
fill: $df-primary;
}
}
.table-header {
@ -95,12 +100,6 @@
}
}
svg {
width: $s-12;
height: $s-12;
fill: $df-primary;
}
.dashboard-access-tokens {
display: flex;
flex-direction: column;
@ -171,75 +170,85 @@ svg {
.modal-overlay {
@extend .modal-overlay-base;
.modal-container {
@extend .modal-container-base;
min-width: $s-408;
border: $s-1 solid var(--modal-border-color);
.modal-header {
margin-bottom: $s-24;
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
}
.modal-content {
@include flexColumn;
gap: $s-24;
@include titleTipography;
margin-bottom: $s-24;
.modal-container {
@extend .modal-container-base;
min-width: $s-408;
border: $s-1 solid var(--modal-border-color);
}
.fields-row {
@include flexColumn;
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
.custon-input-wrapper {
@include flexRow;
border-radius: $br-8;
height: $s-32;
background-color: var(--input-background-color);
}
.custom-input-token {
@extend .input-element;
margin: 0;
flex-grow: 1;
&:focus {
outline: none;
border: $s-1 solid var(--input-border-color-active);
}
}
.token-value {
@include textEllipsis;
@include titleTipography;
flex-grow: 1;
}
.copy-btn {
@include flexCenter;
@extend .button-secondary;
height: $s-28;
width: $s-28;
svg {
@extend .button-icon-small;
}
}
}
}
.modal-footer {
.action-buttons {
@extend .modal-action-btns;
button {
@extend .modal-accept-btn;
}
.cancel-button {
@extend .modal-cancel-btn;
}
}
}
.modal-header {
margin-bottom: $s-24;
.modal-title {
@include tabTitleTipography;
color: var(--modal-title-foreground-color);
}
.modal-close-btn {
@extend .modal-close-btn-base;
}
}
.modal-content {
@include flexColumn;
gap: $s-24;
@include titleTipography;
margin-bottom: $s-24;
}
.fields-row {
@include flexColumn;
}
.select-title {
@include titleTipography;
color: var(--modal-title-foreground-color);
}
.custon-input-wrapper {
@include flexRow;
border-radius: $br-8;
height: $s-32;
background-color: var(--input-background-color);
}
.custom-input-token {
@extend .input-element;
margin: 0;
flex-grow: 1;
&:focus {
outline: none;
border: $s-1 solid var(--input-border-color-active);
}
}
.token-value {
@include textEllipsis;
@include titleTipography;
flex-grow: 1;
}
.copy-btn {
@include flexCenter;
@extend .button-secondary;
height: $s-28;
width: $s-28;
svg {
@extend .button-icon-small;
}
}
.token-created-info {
color: var(--modal-text-foreground-color);
}
.action-buttons {
@extend .modal-action-btns;
button {
@extend .modal-accept-btn;
}
}
.cancel-button {
@extend .modal-cancel-btn;
}

View file

@ -14,7 +14,6 @@
[app.main.repo :as rp]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[beicon.v2.core :as rx]
@ -29,8 +28,7 @@
(mf/defc feedback-form
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
profile (mf/deref refs/profile)
(let [profile (mf/deref refs/profile)
form (fm/use-form :spec ::feedback-form
:validators [(fm/validate-length :subject fm/max-length-allowed (tr "auth.name.too-long"))
(fm/validate-not-empty :subject (tr "auth.name.not-all-space"))])
@ -62,101 +60,54 @@
(->> (rp/cmd! :send-user-feedback data)
(rx/subs! on-succes on-error)))))]
(if new-css-system
[:& fm/form {:class (stl/css :feedback-form)
:on-submit on-submit
:form form}
[:& fm/form {:class (stl/css :feedback-form)
:on-submit on-submit
:form form}
;; --- Feedback section
[:h2 {:class (stl/css :field-title)} (tr "feedback.title")]
[:p {:class (stl/css :field-text)} (tr "feedback.subtitle")]
[:h2 {:class (stl/css :field-title)} (tr "feedback.title")]
[:p {:class (stl/css :field-text)} (tr "feedback.subtitle")]
[:div {:class (stl/css :fields-row)}
[:& fm/input {:label (tr "feedback.subject")
:name :subject
:show-success? true}]]
[:div {:class (stl/css :fields-row :description)}
[:& fm/textarea
{:label (tr "feedback.description")
:name :content
:rows 5}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input {:label (tr "feedback.subject")
:name :subject
:show-success? true}]]
[:div {:class (stl/css :fields-row :description)}
[:& fm/textarea
{:label (tr "feedback.description")
:name :content
:rows 5}]]
[:> fm/submit-button*
{:label (if @loading (tr "labels.sending") (tr "labels.send"))
:disabled @loading}]
[:> fm/submit-button*
{:label (if @loading (tr "labels.sending") (tr "labels.send"))
:disabled @loading}]
[:hr]
[:hr]
[:h2 {:class (stl/css :field-title)} (tr "feedback.discourse-title")]
[:p {:class (stl/css :field-text)} (tr "feedback.discourse-subtitle1")]
[:h2 {:class (stl/css :field-title)} (tr "feedback.discourse-title")]
[:p {:class (stl/css :field-text)} (tr "feedback.discourse-subtitle1")]
[:a
{:class (stl/css :btn-secondary :btn-large)
:href "https://community.penpot.app"
:target "_blank"}
(tr "feedback.discourse-go-to")]
[:hr]
[:a
{:class (stl/css :btn-secondary :btn-large)
:href "https://community.penpot.app"
:target "_blank"}
(tr "feedback.discourse-go-to")]
[:hr]
[:h2 {:class (stl/css :field-title)} (tr "feedback.twitter-title")]
[:p {:class (stl/css :field-text)} (tr "feedback.twitter-subtitle1")]
[:h2 {:class (stl/css :field-title)} (tr "feedback.twitter-title")]
[:p {:class (stl/css :field-text)} (tr "feedback.twitter-subtitle1")]
[:a
{:class (stl/css :btn-secondary :btn-large)
:href "https://twitter.com/penpotapp"
:target "_blank"}
(tr "feedback.twitter-go-to")]]
;; OLD
[:& fm/form {:class "feedback-form"
:on-submit on-submit
:form form}
;; --- Feedback section
[:h2.field-title (tr "feedback.title")]
[:p.field-text (tr "feedback.subtitle")]
[:div.fields-row
[:& fm/input {:label (tr "feedback.subject")
:name :subject}]]
[:div.fields-row
[:& fm/textarea
{:label (tr "feedback.description")
:name :content
:rows 5}]]
[:> fm/submit-button*
{:label (if @loading (tr "labels.sending") (tr "labels.send"))
:disabled @loading}]
[:hr]
[:h2.field-title (tr "feedback.discourse-title")]
[:p.field-text (tr "feedback.discourse-subtitle1")]
[:a.btn-secondary.btn-large
{:href "https://community.penpot.app" :target "_blank"}
(tr "feedback.discourse-go-to")]
[:hr]
[:h2.field-title (tr "feedback.twitter-title")]
[:p.field-text (tr "feedback.twitter-subtitle1")]
[:a.btn-secondary.btn-large
{:href "https://twitter.com/penpotapp" :target "_blank"}
(tr "feedback.twitter-go-to")]])))
[:a
{:class (stl/css :btn-secondary :btn-large)
:href "https://twitter.com/penpotapp"
:target "_blank"}
(tr "feedback.twitter-go-to")]]))
(mf/defc feedback-page
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(mf/use-effect
#(dom/set-html-title (tr "title.settings.feedback")))
(mf/use-effect
#(dom/set-html-title (tr "title.settings.feedback")))
(if new-css-system
[:div {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container)}
[:& feedback-form]]]
;; OLD
[:div.dashboard-settings
[:div.form-container
[:& feedback-form]]])))
[:div {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container)}
[:& feedback-form]]])

View file

@ -13,7 +13,6 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[cljs.spec.alpha :as s]
@ -38,78 +37,49 @@
(mf/defc options-form
{::mf/wrap-props false}
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
profile (mf/deref refs/profile)
(let [profile (mf/deref refs/profile)
initial (mf/with-memo [profile]
(update profile :lang #(or % "")))
form (fm/use-form :spec ::options-form
:initial initial)]
(if new-css-system
[:& fm/form {:class (stl/css :options-form)
:on-submit on-submit
:form form}
[:& fm/form {:class (stl/css :options-form)
:on-submit on-submit
:form form}
[:h3 (tr "labels.language")]
[:h3 (tr "labels.language")]
[:div {:class (stl/css :fields-row)}
[:& fm/select {:options (into [{:label "Auto (browser)" :value ""}]
i18n/supported-locales)
:label (tr "dashboard.select-ui-language")
:default ""
:name :lang
:data-test "setting-lang"}]]
[:div {:class (stl/css :fields-row)}
[:& fm/select {:options (into [{:label "Auto (browser)" :value ""}]
i18n/supported-locales)
:label (tr "dashboard.select-ui-language")
:default ""
:name :lang
:data-test "setting-lang"}]]
[:h3 (tr "dashboard.theme-change")]
[:div {:class (stl/css :fields-row)}
[:& fm/select {:label (tr "dashboard.select-ui-theme")
:name :theme
:default "default"
:options [{:label "Penpot Dark (default)" :value "default"}
{:label "Penpot Light" :value "light"}]
:data-test "setting-theme"}]]
[:h3 (tr "dashboard.theme-change")]
[:div {:class (stl/css :fields-row)}
[:& fm/select {:label (tr "dashboard.select-ui-theme")
:name :theme
:default "default"
:options [{:label "Penpot Dark (default)" :value "default"}
{:label "Penpot Light" :value "light"}]
:data-test "setting-theme"}]]
[:> fm/submit-button*
{:label (tr "dashboard.update-settings")
:data-test "submit-lang-change"
:class (stl/css :btn-primary)}]]
;; OLD
[:& fm/form {:class "options-form"
:on-submit on-submit
:form form}
[:h2 (tr "labels.language")]
[:div.fields-row
[:& fm/select {:options (into [{:label "Auto (browser)" :value ""}]
i18n/supported-locales)
:label (tr "dashboard.select-ui-language")
:default ""
:name :lang
:data-test "setting-lang"}]]
[:> fm/submit-button*
{:label (tr "dashboard.update-settings")
:data-test "submit-lang-change"}]])))
[:> fm/submit-button*
{:label (tr "dashboard.update-settings")
:data-test "submit-lang-change"
:class (stl/css :btn-primary)}]]))
;; --- Password Page
(mf/defc options-page
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(mf/use-effect
#(dom/set-html-title (tr "title.settings.options")))
(mf/use-effect
#(dom/set-html-title (tr "title.settings.options")))
(if new-css-system
[:div {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container) :data-test "settings-form"}
[:h2 (tr "labels.settings")]
[:& options-form {}]]]
;; OLD
[:div.dashboard-settings
[:div.form-container
{:data-test "settings-form"}
[:& options-form {}]]])))
[:div {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container) :data-test "settings-form"}
[:h2 (tr "labels.settings")]
[:& options-form {}]]])

View file

@ -12,7 +12,6 @@
[app.main.data.users :as udu]
[app.main.store :as st]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [t tr]]
[cljs.spec.alpha :as s]
@ -71,88 +70,51 @@
(mf/defc password-form
[{:keys [locale] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
initial (mf/use-memo (constantly {:password-old nil}))
(let [initial (mf/use-memo (constantly {:password-old nil}))
form (fm/use-form :spec ::password-form
:validators [(fm/validate-not-all-spaces :password-old (tr "auth.password-not-empty"))
(fm/validate-not-empty :password-1 (tr "auth.password-not-empty"))
(fm/validate-not-empty :password-2 (tr "auth.password-not-empty"))
password-equality]
:initial initial)]
(if new-css-system
[:& fm/form {:class (stl/css :password-form)
:on-submit on-submit
:form form}
[:& fm/form {:class (stl/css :password-form)
:on-submit on-submit
:form form}
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "password"
:name :password-old
:auto-focus? true
:label (t locale "labels.old-password")}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "password"
:name :password-old
:auto-focus? true
:label (t locale "labels.old-password")}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "password"
:name :password-1
:show-success? true
:label (t locale "labels.new-password")}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "password"
:name :password-1
:show-success? true
:label (t locale "labels.new-password")}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "password"
:name :password-2
:show-success? true
:label (t locale "labels.confirm-password")}]]
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "password"
:name :password-2
:show-success? true
:label (t locale "labels.confirm-password")}]]
[:> fm/submit-button*
{:label (t locale "dashboard.update-settings")
:data-test "submit-password"
:class (stl/css :update-btn)}]]
;; OLD
[:& fm/form {:class "password-form"
:on-submit on-submit
:form form}
[:h2 (t locale "dashboard.password-change")]
[:div.fields-row
[:& fm/input
{:type "password"
:name :password-old
:auto-focus? true
:label (t locale "labels.old-password")}]]
[:div.fields-row
[:& fm/input
{:type "password"
:name :password-1
:label (t locale "labels.new-password")}]]
[:div.fields-row
[:& fm/input
{:type "password"
:name :password-2
:label (t locale "labels.confirm-password")}]]
[:> fm/submit-button*
{:label (t locale "dashboard.update-settings")
:data-test "submit-password"}]])))
[:> fm/submit-button*
{:label (t locale "dashboard.update-settings")
:data-test "submit-password"
:class (stl/css :update-btn)}]]))
;; --- Password Page
(mf/defc password-page
[{:keys [locale]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(mf/use-effect
#(dom/set-html-title (tr "title.settings.password")))
(mf/use-effect
#(dom/set-html-title (tr "title.settings.password")))
(if new-css-system
[:section {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container)}
[:h2 (t locale "dashboard.password-change")]
[:& password-form {:locale locale}]]]
;; old
[:section.dashboard-settings.form-container
[:div.form-container
[:& password-form {:locale locale}]]])))
[:section {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container)}
[:h2 (t locale "dashboard.password-change")]
[:& password-form {:locale locale}]]])

View file

@ -16,8 +16,6 @@
[app.main.store :as st]
[app.main.ui.components.file-uploader :refer [file-uploader]]
[app.main.ui.components.forms :as fm]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.util.dom :as dom]
[app.util.i18n :as i18n :refer [tr]]
[cljs.spec.alpha :as s]
@ -43,9 +41,7 @@
(mf/defc profile-form
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
profile (mf/deref refs/profile)
(let [profile (mf/deref refs/profile)
form (fm/use-form :spec ::profile-form
:initial profile
:validators [(fm/validate-length :fullname fm/max-length-allowed (tr "auth.name.too-long"))
@ -59,78 +55,43 @@
(mf/use-callback
#(modal/show! :delete-account {}))]
(if new-css-system
[:& fm/form {:on-submit on-submit
:form form
:class (stl/css :profile-form)}
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "text"
:name :fullname
:label (tr "dashboard.your-name")}]]
[:& fm/form {:on-submit on-submit
:form form
:class (stl/css :profile-form)}
[:div {:class (stl/css :fields-row)}
[:& fm/input
{:type "text"
:name :fullname
:label (tr "dashboard.your-name")}]]
[:div {:class (stl/css :fields-row)
:on-click handle-show-change-email}
[:& fm/input
{:type "email"
:name :email
:disabled true
:label (tr "dashboard.your-email")}]
[:div {:class (stl/css :fields-row)
:on-click handle-show-change-email}
[:& fm/input
{:type "email"
:name :email
:disabled true
:label (tr "dashboard.your-email")}]
[:div {:class (stl/css :options)}
[:div.change-email
[:a {:on-click handle-show-change-email}
(tr "dashboard.change-email")]]]]
[:div {:class (stl/css :options)}
[:div.change-email
[:a {:on-click handle-show-change-email}
(tr "dashboard.change-email")]]]]
[:> fm/submit-button*
{:label (tr "dashboard.save-settings")
:disabled (empty? (:touched @form))
:className (stl/css :btn-primary)}]
[:> fm/submit-button*
{:label (tr "dashboard.save-settings")
:disabled (empty? (:touched @form))
:className (stl/css :btn-primary)}]
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-item)}
[:a {:on-click handle-show-delete-account
:data-test "remove-acount-btn"}
(tr "dashboard.remove-account")]]]]
;; OLD
[:& fm/form {:on-submit on-submit
:form form
:class "profile-form"}
[:div.fields-row
[:& fm/input
{:type "text"
:name :fullname
:label (tr "dashboard.your-name")}]]
[:div.fields-row
[:& fm/input
{:type "email"
:name :email
:disabled true
:help-icon i/at
:label (tr "dashboard.your-email")}]
[:div.options
[:div.change-email
[:a {:on-click #(modal/show! :change-email {})}
(tr "dashboard.change-email")]]]]
[:> fm/submit-button*
{:label (tr "dashboard.save-settings")
:disabled (empty? (:touched @form))}]
[:div.links
[:div.link-item
[:a {:on-click #(modal/show! :delete-account {})
:data-test "remove-acount-btn"}
(tr "dashboard.remove-account")]]]])))
[:div {:class (stl/css :links)}
[:div {:class (stl/css :link-item)}
[:a {:on-click handle-show-delete-account
:data-test "remove-acount-btn"}
(tr "dashboard.remove-account")]]]]))
;; --- Profile Photo Form
(mf/defc profile-photo-form []
(let [new-css-system (mf/use-ctx ctx/new-css-system)
file-input (mf/use-ref nil)
(let [file-input (mf/use-ref nil)
profile (mf/deref refs/profile)
photo (cf/resolve-profile-photo-url profile)
on-image-click #(dom/click (mf/ref-val file-input))
@ -139,44 +100,25 @@
(fn [file]
(st/emit! (du/update-photo file)))]
(if new-css-system
[:form {:class (stl/css :avatar-form)}
[:div {:class (stl/css :image-change-field)}
[:span {:class (stl/css :update-overlay)
:on-click on-image-click} (tr "labels.update")]
[:img {:src photo}]
[:& file-uploader {:accept "image/jpeg,image/png"
:multi false
:ref file-input
:on-selected on-file-selected
:data-test "profile-image-input"}]]]
;; OLD
[:form.avatar-form
[:div.image-change-field
[:span.update-overlay {:on-click on-image-click} (tr "labels.update")]
[:img {:src photo}]
[:& file-uploader {:accept "image/jpeg,image/png"
:multi false
:ref file-input
:on-selected on-file-selected
:data-test "profile-image-input"}]]])))
[:form {:class (stl/css :avatar-form)}
[:div {:class (stl/css :image-change-field)}
[:span {:class (stl/css :update-overlay)
:on-click on-image-click} (tr "labels.update")]
[:img {:src photo}]
[:& file-uploader {:accept "image/jpeg,image/png"
:multi false
:ref file-input
:on-selected on-file-selected
:data-test "profile-image-input"}]]]))
;; --- Profile Page
(mf/defc profile-page []
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(mf/with-effect []
(dom/set-html-title (tr "title.settings.profile")))
(if new-css-system
[:div {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container)}
[:h2 (tr "labels.profile")]
[:& profile-photo-form]
[:& profile-form]]]
;; OLD
[:div.dashboard-settings
[:div.form-container.two-columns
[:& profile-photo-form]
[:& profile-form]]])))
(mf/with-effect []
(dom/set-html-title (tr "title.settings.profile")))
[:div {:class (stl/css :dashboard-settings)}
[:div {:class (stl/css :form-container)}
[:h2 (tr "labels.profile")]
[:& profile-photo-form]
[:& profile-form]]])

View file

@ -12,7 +12,6 @@
[app.main.data.modal :as modal]
[app.main.data.users :as du]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.dashboard.sidebar :refer [profile-section]]
[app.main.ui.icons :as i]
[app.util.i18n :as i18n :refer [tr]]
@ -23,8 +22,7 @@
(mf/defc sidebar-content
[{:keys [profile section] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
profile? (= section :settings-profile)
(let [profile? (= section :settings-profile)
password? (= section :settings-password)
options? (= section :settings-options)
feedback? (= section :settings-feedback)
@ -69,107 +67,52 @@
(st/emit! (modal/show {:type :onboarding}))
(st/emit! (modal/show {:type :release-notes :version version}))))))]
(if new-css-system
[:div {:class (stl/css :sidebar-content)}
[:div {:class (stl/css :sidebar-content-section)}
[:div {:class (stl/css :back-to-dashboard)
:on-click go-dashboard}
[:span {:class (stl/css :icon)} i/arrow-down]
[:span {:class (stl/css :text)} (tr "labels.dashboard")]]]
[:div {:class (stl/css :sidebar-content)}
[:div {:class (stl/css :sidebar-content-section)}
[:div {:class (stl/css :back-to-dashboard)
:on-click go-dashboard}
[:span {:class (stl/css :icon)} i/arrow-down]
[:span {:class (stl/css :text)} (tr "labels.dashboard")]]]
[:hr]
[:div {:class (stl/css :sidebar-content-section)}
[:ul {:class (stl/css :sidebar-nav :no-overflow)}
[:li {:class (when profile? (stl/css :current))
:on-click go-settings-profile}
[:span {:class (stl/css :element-title)} (tr "labels.profile")]]
[:li {:class (when password? (stl/css :current))
:on-click go-settings-password}
[:span {:class (stl/css :element-title)} (tr "labels.password")]]
[:li {:class (when options? (stl/css :current))
:on-click go-settings-options
:data-test "settings-profile"}
[:span {:class (stl/css :element-title)} (tr "labels.settings")]]
(when (contains? cf/flags :access-tokens)
[:li {:class (when access-tokens? (stl/css :current))
:on-click go-settings-access-tokens
:data-test "settings-access-tokens"}
[:span {:class (stl/css :element-title)} (tr "labels.access-tokens")]])
[:hr]
[:div {:class (stl/css :sidebar-content-section)}
[:ul {:class (stl/css :sidebar-nav :no-overflow)}
[:li {:class (when profile? (stl/css :current))
:on-click go-settings-profile}
[:span {:class (stl/css :element-title)} (tr "labels.profile")]]
[:li {:on-click show-release-notes :data-test "release-notes"}
[:span {:class (stl/css :element-title)} (tr "labels.release-notes")]]
[:li {:class (when password? (stl/css :current))
:on-click go-settings-password}
[:span {:class (stl/css :element-title)} (tr "labels.password")]]
[:li {:class (when options? (stl/css :current))
:on-click go-settings-options
:data-test "settings-profile"}
[:span {:class (stl/css :element-title)} (tr "labels.settings")]]
(when (contains? cf/flags :access-tokens)
[:li {:class (when access-tokens? (stl/css :current))
:on-click go-settings-access-tokens
:data-test "settings-access-tokens"}
[:span {:class (stl/css :element-title)} (tr "labels.access-tokens")]])
[:hr]
[:li {:on-click show-release-notes :data-test "release-notes"}
[:span {:class (stl/css :element-title)} (tr "labels.release-notes")]]
(when (contains? cf/flags :user-feedback)
[:li {:class (when feedback? (stl/css :current))
:on-click go-settings-feedback}
i/msg-info
[:span {:class (stl/css :element-title)} (tr "labels.give-feedback")]])]]]
;; OLD
[:div.sidebar-content
[:div.sidebar-content-section
[:div.back-to-dashboard {:on-click go-dashboard}
[:span.icon i/arrow-down]
[:span.text (tr "labels.dashboard")]]]
[:hr]
[:div.sidebar-content-section
[:ul.sidebar-nav.no-overflow
[:li {:class (when profile? "current")
:on-click go-settings-profile}
i/user
[:span.element-title (tr "labels.profile")]]
[:li {:class (when password? "current")
:on-click go-settings-password}
i/lock
[:span.element-title (tr "labels.password")]]
[:li {:class (when options? "current")
:on-click go-settings-options
:data-test "settings-profile"}
i/tree
[:span.element-title (tr "labels.settings")]]
(when (contains? cf/flags :access-tokens)
[:li {:class (when access-tokens? "current")
:on-click go-settings-access-tokens
:data-test "settings-access-tokens"}
i/icon-key
[:span.element-title (tr "labels.access-tokens")]])
[:hr]
[:li {:on-click show-release-notes :data-test "release-notes"}
i/pencil
[:span.element-title (tr "labels.release-notes")]]
(when (contains? cf/flags :user-feedback)
[:li {:class (when feedback? "current")
:on-click go-settings-feedback}
i/msg-info
[:span.element-title (tr "labels.give-feedback")]])]]])))
(when (contains? cf/flags :user-feedback)
[:li {:class (when feedback? (stl/css :current))
:on-click go-settings-feedback}
i/msg-info
[:span {:class (stl/css :element-title)} (tr "labels.give-feedback")]])]]]))
(mf/defc sidebar
{::mf/wrap [mf/memo]}
[{:keys [profile locale section]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :dashboard-sidebar :settings)}
[:& sidebar-content {:profile profile
:section section}]
[:& profile-section {:profile profile
:locale locale}]]
;; OLD
[:div.dashboard-sidebar.settings
[:& sidebar-content {:profile profile
:section section}]
[:& profile-section {:profile profile
:locale locale}]])))
[:div {:class (stl/css :dashboard-sidebar :settings)}
[:& sidebar-content {:profile profile
:section section}]
[:& profile-section {:profile profile
:locale locale}]])

View file

@ -20,112 +20,64 @@
(mf/defc static-header
{::mf/wrap-props false}
[props]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
children (obj/get props "children")
(let [children (obj/get props "children")
on-click (mf/use-callback #(set! (.-href globals/location) "/"))]
(if new-css-system
[:section {:class (stl/css :exception-layout)}
[:button
{:class (stl/css :exception-header)
:on-click on-click}
i/logo-icon]
[:div {:class (stl/css :deco-before)} i/logo-error-screen]
[:section {:class (stl/css :exception-layout)}
[:button
{:class (stl/css :exception-header)
:on-click on-click}
i/logo-icon]
[:div {:class (stl/css :deco-before)} i/logo-error-screen]
[:div {:class (stl/css :exception-content)}
[:div {:class (stl/css :container)} children]]
[:div {:class (stl/css :exception-content)}
[:div {:class (stl/css :container)} children]]
[:div {:class (stl/css :deco-after)} i/logo-error-screen]]
[:section.exception-layout
[:div.exception-header
{:on-click on-click}
i/logo]
[:div.exception-content
[:div.container children]]])))
[:div {:class (stl/css :deco-after)} i/logo-error-screen]]))
(mf/defc invalid-token
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "errors.invite-invalid")]
[:div {:class (stl/css :desc-message)} (tr "errors.invite-invalid.info")]]
[:> static-header {}
[:div.image i/unchain]
[:div.main-message (tr "errors.invite-invalid")]
[:div.desc-message (tr "errors.invite-invalid.info")]])))
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "errors.invite-invalid")]
[:div {:class (stl/css :desc-message)} (tr "errors.invite-invalid.info")]])
(mf/defc not-found
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.not-found.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.not-found.desc-message")]]
[:> static-header {}
[:div.image i/icon-empty]
[:div.main-message (tr "labels.not-found.main-message")]
[:div.desc-message (tr "labels.not-found.desc-message")]])))
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.not-found.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.not-found.desc-message")]])
(mf/defc bad-gateway
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
handle-retry
(let [handle-retry
(mf/use-callback
(fn [] (st/emit! (rt/assign-exception nil))))]
(if new-css-system
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.bad-gateway.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.bad-gateway.desc-message")]
[:div {:class (stl/css :sign-info)}
[:button {:on-click handle-retry} (tr "labels.retry")]]]
[:> static-header {}
[:div.image i/icon-empty]
[:div.main-message (tr "labels.bad-gateway.main-message")]
[:div.desc-message (tr "labels.bad-gateway.desc-message")]
[:div.sign-info
[:a.btn-primary.btn-small {:on-click handle-retry} (tr "labels.retry")]]])))
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.bad-gateway.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.bad-gateway.desc-message")]
[:div {:class (stl/css :sign-info)}
[:button {:on-click handle-retry} (tr "labels.retry")]]]))
(mf/defc service-unavailable
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
handle-retry
(let [handle-retry
(mf/use-callback
(fn [] (st/emit! (rt/assign-exception nil))))]
(if new-css-system
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.service-unavailable.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.service-unavailable.desc-message")]
[:div {:class (stl/css :sign-info)}
[:button {:on-click handle-retry} (tr "labels.retry")]]]
[:> static-header {}
[:div.main-message (tr "labels.service-unavailable.main-message")]
[:div.desc-message (tr "labels.service-unavailable.desc-message")]
[:div.sign-info
[:a.btn-primary.btn-small {:on-click handle-retry} (tr "labels.retry")]]])))
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.service-unavailable.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.service-unavailable.desc-message")]
[:div {:class (stl/css :sign-info)}
[:button {:on-click handle-retry} (tr "labels.retry")]]]))
(mf/defc internal-error
[]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
handle-retry
(let [handle-retry
(mf/use-callback
(fn [] (st/emit! (rt/assign-exception nil))))]
(if new-css-system
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.internal-error.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.internal-error.desc-message")]
[:div {:class (stl/css :sign-info)}
[:button {:on-click handle-retry} (tr "labels.retry")]]]
[:> static-header {}
[:div.image i/icon-empty]
[:div.main-message (tr "labels.internal-error.main-message")]
[:div.desc-message (tr "labels.internal-error.desc-message")]
[:div.sign-info
[:a.btn-primary.btn-small {:on-click handle-retry} (tr "labels.retry")]]])))
[:> static-header {}
[:div {:class (stl/css :main-message)} (tr "labels.internal-error.main-message")]
[:div {:class (stl/css :desc-message)} (tr "labels.internal-error.desc-message")]
[:div {:class (stl/css :sign-info)}
[:button {:on-click handle-retry} (tr "labels.retry")]]]))
(mf/defc exception-page
[{:keys [data] :as props}]

View file

@ -48,6 +48,7 @@
}
.hint {
flex-grow: 1;
color: var(--modal-text-foreground-color);
}
.custon-input-wrapper {
@include flexRow;
@ -68,6 +69,7 @@
border: $s-1 solid var(--input-border-color-active);
}
}
.copy-button {
@extend .button-secondary;
@include flexRow;
@ -93,9 +95,11 @@
.button-active {
@extend .modal-accept-btn;
}
.button-cancel {
@extend .modal-cancel-btn;
}
.button-danger {
@extend .modal-danger-btn;
}
@ -126,12 +130,20 @@
transform: rotate(90deg);
}
}
.view-mode,
.access-mode,
.inspect-mode {
display: flex;
width: 100%;
}
.view-mode {
max-height: $s-248;
overflow: hidden auto;
scrollbar-gutter: stable;
}
.subtitle {
color: var(--modal-text-foreground-color);
display: flex;

View file

@ -10,7 +10,6 @@
[app.common.colors :as cc]
[app.common.data :as d]
[app.common.math :as mth]
[app.main.ui.context :as ctx]
[app.util.dom :as dom]
[rumext.v2 :as mf]))
@ -29,8 +28,7 @@
(* (/ val 255) 100))
(mf/defc color-inputs [{:keys [type color disable-opacity on-change]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
{red :r green :g blue :b
(let [{red :r green :g blue :b
hue :h saturation :s value :v
hex :hex alpha :alpha} color
@ -115,133 +113,52 @@
property-val)]
(dom/set-value! node new-val))))))))
(if new-css-system
[:div {:class (stl/css-case :color-values true
:disable-opacity disable-opacity)}
[:div {:class (stl/css-case :color-values true
:disable-opacity disable-opacity)}
[:div {:class (stl/css :colors-row)}
(if (= type :rgb)
[:*
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "R"]
[:input {:id "red-value"
:ref (:r refs)
:type "number"
:min 0
:max 255
:default-value red
:on-change (on-change-property :r 255)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "G"]
[:input {:id "green-value"
:ref (:g refs)
:type "number"
:min 0
:max 255
:default-value green
:on-change (on-change-property :g 255)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "B"]
[:input {:id "blue-value"
:ref (:b refs)
:type "number"
:min 0
:max 255
:default-value blue
:on-change (on-change-property :b 255)}]]]
[:*
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "H"]
[:input {:id "hue-value"
:ref (:h refs)
:type "number"
:min 0
:max 360
:default-value hue
:on-change (on-change-property :h 360)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "S"]
[:input {:id "saturation-value"
:ref (:s refs)
:type "number"
:min 0
:max 100
:step 1
:default-value saturation
:on-change (on-change-property :s 100)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "V"]
[:input {:id "value-value"
:ref (:v refs)
:type "number"
:min 0
:max 100
:default-value value
:on-change (on-change-property :v 100)}]]])]
[:div {:class (stl/css :hex-alpha-wrapper)}
[:div {:class (stl/css-case :input-wrapper true
:hex true)}
[:span {:class (stl/css :input-label)} "HEX"]
[:input {:id "hex-value"
:ref (:hex refs)
:default-value hex
:on-change on-change-hex
:on-blur on-blur-hex}]]
(when (not disable-opacity)
[:div {:class (stl/css-case :input-wrapper true)}
[:span {:class (stl/css :input-label)} "A"]
[:input {:id "alpha-value"
:ref (:alpha refs)
:type "number"
:min 0
:step 1
:max 100
:default-value (if (= alpha :multiple) "" alpha)
:on-change on-change-opacity}]])]]
[:div.color-values
{:class (when disable-opacity "disable-opacity")}
[:input {:id "hex-value"
:ref (:hex refs)
:default-value hex
:on-change on-change-hex
:on-blur on-blur-hex}]
(if (= type :rgb)
[:*
[:div {:class (stl/css :colors-row)}
(if (= type :rgb)
[:*
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "R"]
[:input {:id "red-value"
:ref (:r refs)
:type "number"
:min 0
:max 255
:default-value red
:on-change (on-change-property :r 255)}]
:on-change (on-change-property :r 255)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "G"]
[:input {:id "green-value"
:ref (:g refs)
:type "number"
:min 0
:max 255
:default-value green
:on-change (on-change-property :g 255)}]
:on-change (on-change-property :g 255)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "B"]
[:input {:id "blue-value"
:ref (:b refs)
:type "number"
:min 0
:max 255
:default-value blue
:on-change (on-change-property :b 255)}]]
[:*
:on-change (on-change-property :b 255)}]]]
[:*
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "H"]
[:input {:id "hue-value"
:ref (:h refs)
:type "number"
:min 0
:max 360
:default-value hue
:on-change (on-change-property :h 360)}]
:on-change (on-change-property :h 360)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "S"]
[:input {:id "saturation-value"
:ref (:s refs)
:type "number"
@ -249,35 +166,33 @@
:max 100
:step 1
:default-value saturation
:on-change (on-change-property :s 100)}]
:on-change (on-change-property :s 100)}]]
[:div {:class (stl/css :input-wrapper)}
[:span {:class (stl/css :input-label)} "V"]
[:input {:id "value-value"
:ref (:v refs)
:type "number"
:min 0
:max 100
:default-value value
:on-change (on-change-property :v 100)}]])
(when (not disable-opacity)
[:input.alpha-value {:id "alpha-value"
:ref (:alpha refs)
:type "number"
:min 0
:step 1
:max 100
:default-value (if (= alpha :multiple) "" alpha)
:on-change on-change-opacity}])
[:label.hex-label {:for "hex-value"} "HEX"]
(if (= type :rgb)
[:*
[:label.red-label {:for "red-value"} "R"]
[:label.green-label {:for "green-value"} "G"]
[:label.blue-label {:for "blue-value"} "B"]]
[:*
[:label.red-label {:for "hue-value"} "H"]
[:label.green-label {:for "saturation-value"} "S"]
[:label.blue-label {:for "value-value"} "V"]])
(when (not disable-opacity)
[:label.alpha-label {:for "alpha-value"} "A"])])))
:on-change (on-change-property :v 100)}]]])]
[:div {:class (stl/css :hex-alpha-wrapper)}
[:div {:class (stl/css-case :input-wrapper true
:hex true)}
[:span {:class (stl/css :input-label)} "HEX"]
[:input {:id "hex-value"
:ref (:hex refs)
:default-value hex
:on-change on-change-hex
:on-blur on-blur-hex}]]
(when (not disable-opacity)
[:div {:class (stl/css-case :input-wrapper true)}
[:span {:class (stl/css :input-label)} "A"]
[:input {:id "alpha-value"
:ref (:alpha refs)
:type "number"
:min 0
:step 1
:max 100
:default-value (if (= alpha :multiple) "" alpha)
:on-change on-change-opacity}]])]]))

View file

@ -115,7 +115,7 @@
.history-entry-detail {
display: block;
padding-top: $s-16;
color: var(--modal-text-foreground-color);
.history-entry-details-list {
margin: 0;
}

View file

@ -12,15 +12,13 @@
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.comments :as cmt]
[app.main.ui.context :as ctx]
[cuerdas.core :as str]
[okulary.core :as l]
[rumext.v2 :as mf]))
(mf/defc comments-layer
[{:keys [vbox vport zoom file-id page-id drawing] :as props}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
pos-x (* (- (:x vbox)) zoom)
(let [pos-x (* (- (:x vbox)) zoom)
pos-y (* (- (:y vbox)) zoom)
profile (mf/deref refs/profile)
@ -57,54 +55,29 @@
(st/emit! (dwcm/initialize-comments file-id))
(fn []
(st/emit! ::dwcm/finalize))))
(if new-css-system
[:div {:class (stl/css :comments-section)}
[:div
{:class (stl/css :workspace-comments-container)
:style {:width (str (:width vport) "px")
:height (str (:height vport) "px")}}
[:div {:class (stl/css :threads)
:style {:transform (str/format "translate(%spx, %spx)" pos-x pos-y)}}
(for [item threads]
[:& cmt/thread-bubble {:thread item
:zoom zoom
:open? (= (:id item) (:open local))
:key (:seqn item)}])
[:div {:class (stl/css :comments-section)}
[:div
{:class (stl/css :workspace-comments-container)
:style {:width (str (:width vport) "px")
:height (str (:height vport) "px")}}
[:div {:class (stl/css :threads)
:style {:transform (str/format "translate(%spx, %spx)" pos-x pos-y)}}
(for [item threads]
[:& cmt/thread-bubble {:thread item
:zoom zoom
:open? (= (:id item) (:open local))
:key (:seqn item)}])
(when-let [id (:open local)]
(when-let [thread (get threads-map id)]
[:& cmt/thread-comments {:thread (update-thread-position thread)
:users users
:zoom zoom}]))
(when-let [id (:open local)]
(when-let [thread (get threads-map id)]
[:& cmt/thread-comments {:thread (update-thread-position thread)
:users users
:zoom zoom}]))
(when-let [draft (:comment drawing)]
[:& cmt/draft-thread {:draft draft
:on-cancel on-draft-cancel
:on-submit on-draft-submit
:zoom zoom}])]]]
;; OLD
[:div.comments-section
[:div.workspace-comments-container
{:style {:width (str (:width vport) "px")
:height (str (:height vport) "px")}}
[:div.threads {:style {:transform (str/format "translate(%spx, %spx)" pos-x pos-y)}}
(for [item threads]
[:& cmt/thread-bubble {:thread item
:zoom zoom
:open? (= (:id item) (:open local))
:key (:seqn item)}])
(when-let [id (:open local)]
(when-let [thread (get threads-map id)]
[:& cmt/thread-comments {:thread (update-thread-position thread)
:users users
:zoom zoom}]))
(when-let [draft (:comment drawing)]
[:& cmt/draft-thread {:draft draft
:on-cancel on-draft-cancel
:on-submit on-draft-submit
:zoom zoom}])]]])
(when-let [draft (:comment drawing)]
[:& cmt/draft-thread {:draft draft
:on-cancel on-draft-cancel
:on-submit on-draft-submit
:zoom zoom}])]]]
))

View file

@ -25,7 +25,6 @@
[app.main.data.workspace.shape-layout :as dwsl]
[app.main.refs :as refs]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.css-cursors :as cur]
[app.main.ui.formats :as fmt]
[app.main.ui.hooks :as hooks]
@ -54,28 +53,16 @@
(mf/defc grid-edition-actions
{::mf/wrap-props false}
[{:keys [shape]}]
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
(if new-css-system
[:div {:class (stl/css :grid-actions)}
[:div {:class (stl/css :grid-actions-container)}
[:div {:class (stl/css :grid-actions-title)}
(tr "workspace.layout_grid.editor.title") " " [:span {:stl/css :board-name} (:name shape)]]
[:button {:class (stl/css :locate-btn)
:on-click #(st/emit! (dwge/locate-board (:id shape)))}
(tr "workspace.layout_grid.editor.top-bar.locate")]
[:button {:class (stl/css :done-btn)
:on-click #(st/emit! dw/clear-edition-mode)}
(tr "workspace.layout_grid.editor.top-bar.done")]]]
[:div.viewport-actions
[:div.viewport-actions-container
[:div.viewport-actions-title
(tr "workspace.layout_grid.editor.title") " " [:span.grid-edit-board-name (:name shape)]]
[:button.btn-secondary {:on-click #(st/emit! (dwge/locate-board (:id shape)))}
(tr "workspace.layout_grid.editor.top-bar.locate")]
[:button.btn-primary {:on-click #(st/emit! dw/clear-edition-mode)}
(tr "workspace.layout_grid.editor.top-bar.done")]
[:button.btn-icon-basic {:on-click #(st/emit! dw/clear-edition-mode)} i/close]]])))
[:div {:class (stl/css :grid-actions)}
[:div {:class (stl/css :grid-actions-container)}
[:div {:class (stl/css :grid-actions-title)}
(tr "workspace.layout_grid.editor.title") " " [:span {:stl/css :board-name} (:name shape)]]
[:button {:class (stl/css :locate-btn)
:on-click #(st/emit! (dwge/locate-board (:id shape)))}
(tr "workspace.layout_grid.editor.top-bar.locate")]
[:button {:class (stl/css :done-btn)
:on-click #(st/emit! dw/clear-edition-mode)}
(tr "workspace.layout_grid.editor.top-bar.done")]]])
(mf/defc grid-editor-frame
{::mf/wrap-props false}

View file

@ -10,7 +10,6 @@
[app.main.data.workspace.path :as drp]
[app.main.data.workspace.path.shortcuts :as sc]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.icons :as i]
[app.main.ui.workspace.shapes.path.common :as pc]
[app.util.i18n :as i18n :refer [tr]]
@ -40,7 +39,6 @@
(mf/defc path-actions [{:keys [shape]}]
(let [{:keys [edit-mode selected-points snap-toggled] :as all} (mf/deref pc/current-edit-path-ref)
content (:content shape)
new-css-system (mf/use-ctx ctx/new-css-system)
enabled-buttons
(mf/use-memo
@ -111,160 +109,80 @@
(fn [_]
(st/emit! (drp/toggle-snap))))]
(if new-css-system
[:div {:class (stl/css :sub-actions)}
[:div {:class (stl/css :sub-actions-group)}
[:div {:class (stl/css :sub-actions)}
[:div {:class (stl/css :sub-actions-group)}
;; Draw Mode
[:button
{:class (stl/css-case :is-toggled (= edit-mode :draw))
:title (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes))
:on-click on-select-draw-mode}
i/pentool-refactor]
;; Draw Mode
[:button
{:class (stl/css-case :is-toggled (= edit-mode :draw))
:title (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes))
:on-click on-select-draw-mode}
i/pentool-refactor]
;; Edit mode
[:button
{:class (stl/css-case :is-toggled (= edit-mode :move))
:title (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes))
:on-click on-select-edit-mode}
i/move-refactor]]
;; Edit mode
[:button
{:class (stl/css-case :is-toggled (= edit-mode :move))
:title (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes))
:on-click on-select-edit-mode}
i/move-refactor]]
[:div {:class (stl/css :sub-actions-group)}
;; Add Node
[:button
{:disabled (not (:add-node enabled-buttons))
:title (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node))
:on-click on-add-node}
i/add-refactor]
[:div {:class (stl/css :sub-actions-group)}
;; Add Node
[:button
{:disabled (not (:add-node enabled-buttons))
:title (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node))
:on-click on-add-node}
i/add-refactor]
;; Remove node
[:button
{:disabled (not (:remove-node enabled-buttons))
:title (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node))
:on-click on-remove-node}
i/remove-refactor]]
;; Remove node
[:button
{:disabled (not (:remove-node enabled-buttons))
:title (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node))
:on-click on-remove-node}
i/remove-refactor]]
[:div {:class (stl/css :sub-actions-group)}
;; Merge Nodes
[:button
{:disabled (not (:merge-nodes enabled-buttons))
:title (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes))
:on-click on-merge-nodes}
i/merge-nodes-refactor]
[:div {:class (stl/css :sub-actions-group)}
;; Merge Nodes
[:button
{:disabled (not (:merge-nodes enabled-buttons))
:title (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes))
:on-click on-merge-nodes}
i/merge-nodes-refactor]
;; Join Nodes
[:button
{:disabled (not (:join-nodes enabled-buttons))
:title (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes))
:on-click on-join-nodes}
i/join-nodes-refactor]
;; Join Nodes
[:button
{:disabled (not (:join-nodes enabled-buttons))
:title (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes))
:on-click on-join-nodes}
i/join-nodes-refactor]
;; Separate Nodes
[:button
{:disabled (not (:separate-nodes enabled-buttons))
:title (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes))
:on-click on-separate-nodes}
i/separate-nodes-refactor]]
;; Separate Nodes
[:button
{:disabled (not (:separate-nodes enabled-buttons))
:title (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes))
:on-click on-separate-nodes}
i/separate-nodes-refactor]]
;; Make Corner
[:div {:class (stl/css :sub-actions-group)}
[:button
{:disabled (not (:make-corner enabled-buttons))
:title (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner))
:on-click on-make-corner}
i/to-corner-refactor]
;; Make Corner
[:div {:class (stl/css :sub-actions-group)}
[:button
{:disabled (not (:make-corner enabled-buttons))
:title (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner))
:on-click on-make-corner}
i/to-corner-refactor]
;; Make Curve
[:button
{:disabled (not (:make-curve enabled-buttons))
:title (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve))
:on-click on-make-curve}
i/to-curve-refactor]]
;; Make Curve
[:button
{:disabled (not (:make-curve enabled-buttons))
:title (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve))
:on-click on-make-curve}
i/to-curve-refactor]]
;; Toggle snap
[:div {:class (stl/css :sub-actions-group)}
[:button
{:class (stl/css-case :is-toggled snap-toggled)
:title (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes))
:on-click on-toggle-snap}
i/snap-nodes-refactor]]]
[:div.path-actions
[:div.viewport-actions-group
;; Draw Mode
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when (= edit-mode :draw) "is-toggled")
:alt (tr "workspace.path.actions.draw-nodes" (sc/get-tooltip :draw-nodes))
:on-click on-select-draw-mode}
i/pen]
;; Edit mode
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when (= edit-mode :move) "is-toggled")
:alt (tr "workspace.path.actions.move-nodes" (sc/get-tooltip :move-nodes))
:on-click on-select-edit-mode}
i/pointer-inner]]
[:div.viewport-actions-group
;; Add Node
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:add-node enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.add-node" (sc/get-tooltip :add-node))
:on-click on-add-node}
i/nodes-add]
;; Remove node
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:remove-node enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.delete-node" (sc/get-tooltip :delete-node))
:on-click on-remove-node}
i/nodes-remove]]
[:div.viewport-actions-group
;; Merge Nodes
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:merge-nodes enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.merge-nodes" (sc/get-tooltip :merge-nodes))
:on-click on-merge-nodes}
i/nodes-merge]
;; Join Nodes
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:join-nodes enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.join-nodes" (sc/get-tooltip :join-nodes))
:on-click on-join-nodes}
i/nodes-join]
;; Separate Nodes
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:separate-nodes enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.separate-nodes" (sc/get-tooltip :separate-nodes))
:on-click on-separate-nodes}
i/nodes-separate]]
;; Make Corner
[:div.viewport-actions-group
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:make-corner enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.make-corner" (sc/get-tooltip :make-corner))
:on-click on-make-corner}
i/nodes-corner]
;; Make Curve
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when-not (:make-curve enabled-buttons) "is-disabled")
:alt (tr "workspace.path.actions.make-curve" (sc/get-tooltip :make-curve))
:on-click on-make-curve}
i/nodes-curve]]
;; Toggle snap
[:div.viewport-actions-group
[:div.viewport-actions-entry.tooltip.tooltip-bottom
{:class (when snap-toggled "is-toggled")
:alt (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes))
:on-click on-toggle-snap}
i/nodes-snap]]])))
;; Toggle snap
[:div {:class (stl/css :sub-actions-group)}
[:button
{:class (stl/css-case :is-toggled snap-toggled)
:title (tr "workspace.path.actions.snap-nodes" (sc/get-tooltip :snap-nodes))
:on-click on-toggle-snap}
i/snap-nodes-refactor]]]))

View file

@ -13,7 +13,6 @@
[app.main.fonts :as fonts]
[app.main.rasterizer :as thr]
[app.main.store :as st]
[app.main.ui.context :as ctx]
[app.main.ui.css-cursors :as cur]
[app.util.dom :as dom]
[app.util.keyboard :as kbd]
@ -51,8 +50,7 @@
(mf/defc pixel-overlay
{::mf/wrap-props false}
[props]
(let [new-css-system (mf/use-ctx ctx/new-css-system)
vport (unchecked-get props "vport")
(let [vport (unchecked-get props "vport")
viewport-ref (unchecked-get props "viewport-ref")
viewport-node (mf/ref-val viewport-ref)
@ -81,8 +79,8 @@
(when-let [zoom-view-node (dom/get-element "picker-detail")]
(when-not (mf/ref-val zoom-view-context)
(mf/set-ref-val! zoom-view-context (.getContext zoom-view-node "2d")))
(let [canvas-width (if new-css-system 260 200)
canvas-height (if new-css-system 140 160)
(let [canvas-width 260
canvas-height 140
{brx :left bry :top} (dom/get-bounding-rect viewport-node)
x (mth/floor (- (.-clientX event) brx))
@ -100,10 +98,10 @@
;; I don't know why, but the zoom view is offset by 24px
;; instead of 25.
sx (- x (if new-css-system 32 24))
sy (- y (if new-css-system 17 20))
sw (if new-css-system 65 50)
sh (if new-css-system 35 40)
sx (- x 32)
sy (- y 17)
sw 65
sh 35
dx 0
dy 0
dw canvas-width

View file

@ -6,12 +6,10 @@
(ns app.main.ui.workspace.viewport.rules
(:require
[app.common.colors :as colors]
[app.common.data :as d]
[app.common.data.macros :as dm]
[app.common.geom.shapes :as gsh]
[app.common.math :as mth]
[app.main.ui.context :as ctx]
[app.main.ui.formats :as fmt]
[app.main.ui.hooks :as hooks]
[app.util.object :as obj]
@ -22,8 +20,7 @@
(def rules-width 1)
(def rule-area-size 22)
(def rule-area-half-size (/ rule-area-size 2))
(def rules-background "var(--color-gray-50)")
(def new-css-rules-background "var(--panel-background-color)")
(def rules-background "var(--panel-background-color)")
(def selection-area-color "var(--color-primary)")
(def selection-area-opacity 0.3)
(def over-number-size 50)
@ -31,9 +28,8 @@
(def font-size 12)
(def font-family "worksans")
(def font-color colors/gray-30)
(def new-css-font-color "var(--layer-row-foreground-color)")
(def new-css-canvas-border-radius 12)
(def font-color "var(--layer-row-foreground-color)")
(def canvas-border-radius 12)
;; ----------------
;; RULES
@ -156,9 +152,8 @@
(let [rules-width (* rules-width zoom-inverse)
step (calculate-step-size zoom)
clip-id (str "clip-rule-" (d/name axis))
new-css-system (mf/use-ctx ctx/new-css-system)
font-color (if new-css-system new-css-font-color font-color)
rules-background (if new-css-system new-css-rules-background rules-background)]
font-color font-color
rules-background rules-background]
[:*
(let [{:keys [x y width height]} (get-background-area vbox zoom-inverse axis)]
@ -207,8 +202,7 @@
(mf/defc selection-area
[{:keys [vbox zoom-inverse selection-rect offset-x offset-y]}]
;; When using the format-number callls we consider if the guide is associated to a frame and we show the position relative to it with the offset
(let [new-css-system (mf/use-ctx ctx/new-css-system)
rules-background (if new-css-system new-css-rules-background rules-background)]
(let [rules-background rules-background]
[:g.selection-area
[:g
[:rect {:x (:x selection-rect)
@ -306,9 +300,8 @@
(hooks/use-equal-memo))
show-rules? (obj/get props "show-rules?")
new-css-system (mf/use-ctx ctx/new-css-system)
rules-background (if new-css-system new-css-rules-background rules-background)
border-radius (/ new-css-canvas-border-radius zoom)
rules-background rules-background
border-radius (/ canvas-border-radius zoom)
selection-rect
(mf/use-memo
@ -324,21 +317,20 @@
[:& rules-axis {:zoom zoom :zoom-inverse zoom-inverse :vbox vbox :axis :y :offset offset-y}]])
;; Draw the rules' rounded corners in the viewport corners
(when new-css-system
(let [{:keys [x y width height]} vbox
rule-area-size (if show-rules? (/ rule-area-size zoom) 0)]
[:*
[:path {:d (round-corner-path-tl (+ x rule-area-size) (+ y rule-area-size) border-radius)
:style {:fill rules-background}}]
(let [{:keys [x y width height]} vbox
rule-area-size (if show-rules? (/ rule-area-size zoom) 0)]
[:*
[:path {:d (round-corner-path-tl (+ x rule-area-size) (+ y rule-area-size) border-radius)
:style {:fill rules-background}}]
[:path {:d (round-corner-path-tr (+ x width (- border-radius)) (+ y rule-area-size) border-radius)
:style {:fill rules-background}}]
[:path {:d (round-corner-path-tr (+ x width (- border-radius)) (+ y rule-area-size) border-radius)
:style {:fill rules-background}}]
[:path {:d (round-corner-path-bl (+ x rule-area-size) (+ y height (- border-radius)) border-radius)
:style {:fill rules-background}}]
[:path {:d (round-corner-path-bl (+ x rule-area-size) (+ y height (- border-radius)) border-radius)
:style {:fill rules-background}}]
[:path {:d (round-corner-path-br (+ x (:width vbox) (- border-radius)) (+ y height (- border-radius)) border-radius)
:style {:fill rules-background}}]]))
[:path {:d (round-corner-path-br (+ x (:width vbox) (- border-radius)) (+ y height (- border-radius)) border-radius)
:style {:fill rules-background}}]])
(when (and show-rules? (some? selection-rect))
[:& selection-area {:zoom zoom